Files
HadTavern/docs/VARIABLES.md
2025-09-07 22:33:51 +03:00

182 lines
8.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Переменные и макросы AgentUI
Этот файл — простая шпаргалка по переменным/макросам, которые можно использовать в шаблонах узла ProviderCall и в Prompt Blocks.
Правила ввода:
- Квадратные макросы [[...]] — простая подстановка. Хорошо подходят для строк и для URL/заголовков.
- Фигурные {{ ... }} — «джинджа‑лайт»: умеют фильтр |default(...), корректно вставляют объекты и массивы внутрь JSON без лишних кавычек.
- Любые значения, вставляемые в JSON через макросы, приводятся к корректному JSON когда это возможно.
Служебные файлы/строки реализации:
- Рендеринг и макросы: [render_template_simple()](agentui/pipeline/executor.py:125)
- Провайдерный узел с формированием PROMPT: [ProviderCallNode.run()](agentui/pipeline/executor.py:565)
---
## Общие переменные контекста
- [[model]] — активная модель (строка)
- [[vendor_format]] — openai | gemini | claude | unknown
- [[system]] — системный текст, если был во входящем запросе
- [[params.temperature]], [[params.max_tokens]], [[params.top_p]], [[params.stop]]
- [[chat.last_user]] — последнее userсообщение
- [[chat.messages]] — массив унифицированных сообщений
- [[incoming.path]] — путь входящего HTTPзапроса
- [[incoming.query]] — строка query (?a=1&b=2)
- [[incoming.query_params]] — объект query, например {"key":"..."}
- [[incoming.headers]] — заголовки входящего запроса
- [[incoming.json]] — JSONтело входящего запроса клиента
- [[incoming.api_keys.authorization]] — значение Authorization (если есть)
- [[incoming.api_keys.key]] — значение ?key=... в URL (удобно для Gemini)
- [[incoming.api_keys.secret]] — запасной слот
Те же поля доступны через {{ ... }}: например {{ params.temperature|default(0.7) }}, {{ incoming.json }} и т.д.
---
## Макросы OUT (выходы нод)
Доступ к выходам нод возможен в двух формах:
### 1) Короткая форма (besteffort текст)
- [[OUT1]] — «текст» из ноды n1
- [[OUT2]] — из ноды n2 и т.д.
Что делает «besteffort текст»:
- Если нода вернула response_text или text — берётся он
- Если нода вернула объект провайдера:
- OpenAI: choices[0].message.content
- Gemini: candidates[0].content.parts[0].text
- Claude: content[].text (склейка)
- Если ничего из выше не подошло — выполняется глубокий поиск текстовых полей ("text"/"content")
Реализация: [_best_text_from_outputs()](agentui/pipeline/executor.py:45) и подстановка коротких OUT: [render_template_simple()](agentui/pipeline/executor.py:155)
### 2) Полная форма (точный путь)
- [[OUT:n1.result]] — целиком результат ноды n1
- [[OUT:n1.result.candidates.0.content.parts.0.text]] — конкретный путь
- Эквивалент через фигурные скобки: {{ OUT.n1.result.candidates.0.content.parts.0.text }}
Совет: используйте короткий [[OUTx]] если нужно «просто текст». Используйте полную форму, если нужен конкретный фрагмент/массив.
---
## Единый фрагмент [[PROMPT]]
[[PROMPT]] — это уже собранный JSONфрагмент из ваших Prompt Blocks. Он зависит от выбранного провайдера ноды:
- OpenAI → "messages": [...]
- Gemini → "contents": [...], "systemInstruction": {...}
- Claude → "system": "...", "messages": [...]
Как использовать внутри JSONшаблона:
{
"model": "{{ model }}",
[[PROMPT]],
"temperature": {{ params.temperature|default(0.7) }}
}
Вы также можете использовать сырьевые структуры:
- {{ pm.messages }}
- {{ pm.contents }}
- {{ pm.systemInstruction }}
- {{ pm.system_text }}
Но рекомендуемый путь — [[PROMPT]]: меньше шансов сломать JSON.
---
## Примеры по провайдерам
### OpenAI (/v1/chat/completions)
{
"model": "{{ model }}",
[[PROMPT]],
"temperature": {{ incoming.json.temperature|default(params.temperature|default(0.7)) }},
"top_p": {{ incoming.json.top_p|default(params.top_p|default(1)) }},
"max_tokens": {{ incoming.json.max_tokens|default(params.max_tokens|default(256)) }},
"stop": {{ incoming.json.stop|default(params.stop|default([])) }}
}
### Gemini (/v1beta/models/{model}:generateContent?key=...)
{
"model": "{{ model }}",
[[PROMPT]],
"safetySettings": {{ incoming.json.safetySettings|default([]) }},
"generationConfig": {
"temperature": {{ incoming.json.generationConfig.temperature|default(params.temperature|default(0.7)) }},
"topP": {{ incoming.json.generationConfig.topP|default(params.top_p|default(1)) }},
"maxOutputTokens": {{ incoming.json.generationConfig.maxOutputTokens|default(params.max_tokens|default(256)) }},
"stopSequences": {{ incoming.json.generationConfig.stopSequences|default(params.stop|default([])) }}
}
}
### Claude (/v1/messages)
{
"model": "{{ model }}",
[[PROMPT]],
"temperature": {{ incoming.json.temperature|default(params.temperature|default(0.7)) }},
"top_p": {{ incoming.json.top_p|default(params.top_p|default(1)) }},
"max_tokens": {{ incoming.json.max_tokens|default(params.max_tokens|default(256)) }}
}
---
## Частые кейсы
1) Взять текст пользователя из входящего запроса и передать в Prompt Blocks
- Gemini: [[VAR:incoming.json.contents.0.parts.0.text]]
- OpenAI: [[VAR:incoming.json.messages.0.content]]
- Claude: [[VAR:incoming.json.messages.0.content.0.text]]
2) Переписать ответ предыдущей ноды «как текст»
- [[OUT1]] — если предыдущая нода имеет id n1
3) Добавить ключ Gemini из query в endpoint
- /v1beta/models/{{ model }}:generateContent?key=[[VAR:incoming.api_keys.key]]
---
## Почему местами нужны {{ ... }}
Внутри JSON нам важно вставлять объекты/массивы без кавычек и иметь дефолты:
- {{ pm.contents }} — вставит массив как массив
- {{ params.temperature|default(0.7) }} — если нет значения, подставится 0.7
Квадратные [[...]] хорошо подходят для строк/простых значений и для URL/заголовков.
---
## Отладка
- Проверьте лог DEBUG в консоли: ProviderCallNode показывает провайдера, URL и первые 400 символов тела запроса.
- Если «ничего не подставилось»:
- убедитесь, что не подаёте входной payload в ProviderCall (иначе шаблон игнорируется);
- проверьте валидность JSON после подстановок;
- проверьте, что макрос написан корректно (OUT против OUTn).
---
## МиниFAQ
В: Почему [[OUT1]] пустой?
О: Возможно, нода n1 не вернула текстового поля, и глубокий поиск не нашёл текста. Уточните путь через полную форму [[OUT:n1....]].
В: Можно ли получить весь «сырой» ответ?
О: [[OUT:n1.result]] — вернёт весь JSON результата ноды n1.
В: Почему фигурные скобки иногда обязательны?
О: Они умеют |default(...) и корректно вставляют объекты/массивы внутрь JSON.
---
## Ссылки на реализацию
- Макросы/рендер: [render_template_simple()](agentui/pipeline/executor.py:125)
- Единый [[PROMPT]]: [ProviderCallNode.run()](agentui/pipeline/executor.py:604)
- Короткий [[OUTx]] и извлечение текста: [render_template_simple()](agentui/pipeline/executor.py:155), [_best_text_from_outputs()](agentui/pipeline/executor.py:45)
Удачного редактирования!