Skip to content

fix: рецепт assembler не влиял на LLM + логи вход→выход по всему тракту#13

Merged
AntonDot merged 2 commits into
mainfrom
fix/recipe-system-and-logging
Jul 24, 2026
Merged

fix: рецепт assembler не влиял на LLM + логи вход→выход по всему тракту#13
AntonDot merged 2 commits into
mainfrom
fix/recipe-system-and-logging

Conversation

@AntonDot

Copy link
Copy Markdown
Member

Что

Два независимых изменения:

1. Баг: рецепт ассемблера не влиял на перевод/суммаризацию

Выбор «Переводчик на английский» в дропдауне ничего не менял — станок отдавал тот же текст. Причина двойная:

  • UI: onChange рецепта обновлял только config.recipe, а config.system (реально идёт в LLM) оставался дефолтным — блок подстановки был пустой заглушкой с комментарием.
  • Корень: demo.json / Import грузят ассемблер с config:{recipe:...} без ключа system, а loadWorld не заполняет дефолты схемы (в отличие от постановки мышью) → handler слал пустой system → модель просто эхом отдавала текст.

Фикс: ConfigPanel пишет recipe+system одним обновлением при выборе пресета; assemblerHandler резолвит system из recipe, если он не задан явно. Регресс-тест AC1b.

Подтверждено сквозняком: system='Переведи текст на английский…' реально доезжает до LLM, модель переводит ("Hi, I'm Anton, I'm a student.").

2. Логи вход→выход по всему тракту

  • Сервер (main.py): единый log() формата [tag] k=v с усечением. /llm (in/out/ERR, mock+реальный), /proxy (in/out/ERR), /webhook (in). url в /proxy усекается (может нести секрет в пути).
  • Клиент (runtime.ts): I/O каждого станка → панель «Логи» + консоль (IN «..» → OUT «..»), ошибки узлов и падения пакетов. Cap панели 50→200.

Проверка

  • pnpm typecheck ✓, pnpm check ✓ (13 AC движка + stress + AC1b)
  • Серверные логи протестированы curl'ом на всех 3 эндпоинтах
  • python-синтаксис ✓

🤖 Generated with Claude Code

dotsenko-rgb and others added 2 commits July 25, 2026 00:30
Два слоя одного бага:
1. Дропдаун рецепта в ConfigPanel обновлял только config.recipe, а
   config.system (который реально идёт в LLM) оставался дефолтным —
   блок подстановки был пустой заглушкой. Теперь при выборе пресета
   пишем recipe+system одним обновлением (для 'custom' system не трогаем).
2. Корень: demo.json/Import грузят ассемблер без ключа system (loadWorld
   не заполняет дефолты схемы) → handler слал пустой system, модель эхом
   отдавала текст. Теперь assemblerHandler резолвит system из recipe,
   если он не задан явно. +AC1b регресс-тест.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Сервер (main.py): единый log() формата [tag] k=v с усечением длинных
значений — /llm (in/out/ERR, mock и реальный), /proxy (in/out/ERR),
/webhook (in). url в /proxy усекается (может нести секрет в пути).

Клиент (runtime.ts): I/O каждого станка → панель Логи + консоль
(node-io: IN «..» → OUT «..»), ошибки узлов и падения пакетов тоже.
Cap панели логов 50 → 200 (store.ts), чтобы история не вымывалась.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 24, 2026 16:31
@AntonDot
AntonDot merged commit 27e3713 into main Jul 24, 2026
1 check passed
@AntonDot
AntonDot deleted the fix/recipe-system-and-logging branch July 24, 2026 16:31

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

PR исправляет сценарий с assembler-пресетами, чтобы выбранный рецепт реально влиял на system-промпт, и добавляет сквозные логи вход→выход по узлам и серверным эндпоинтам, облегчая отладку всего тракта (UI → engine → server → LLM/proxy/webhook).

Changes:

  • Обновление UI/handler для assembler: system теперь корректно подставляется из recipe (включая fallback при загрузке мира без config.system) + регресс-чек AC1b.
  • Логи I/O узлов на клиенте (панель логов + консоль), расширение cap логов/тостов.
  • Единый формат серверных логов для /llm, /proxy, /webhook с усечением значений.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
web/src/ui/ConfigPanel.tsx При выборе recipe для assembler выставляет system пресета вместе с recipe.
web/src/state/store.ts Увеличивает лимит хранимых логов/тостов с 50 до 200.
web/src/state/runtime.ts Добавляет форматирование и вывод I/O/ошибок узлов в логи/консоль.
web/src/core/nodes/assembler.ts Делает fallback: если config.system отсутствует, берёт system из recipe.
web/src/core/checks/nodes.ts Добавляет регресс-чек AC1b на fallback system из recipe.
server/main.py Добавляет единый helper логирования и логирует in/out/ERR для /llm, /proxy, /webhook.
Comments suppressed due to low confidence (1)

server/main.py:222

  • В обработке ошибок /proxy также логируется url целиком, что может утечь в логи вместе с секретами в пути/параметрах. Стоит редактировать/убрать URL и тут.
        log("proxy←ERR", url=url, error=str(e))
        return err(502, f"Proxy error: {str(e)}")

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 160 to +165
if (field.key === 'recipe' && entity.kind === 'assembler') {
const selectedOption = field.options?.find((opt) => opt.value === value);
if (selectedOption?.label) {
// Извлекаем system из опции (это лучше сделать в NODE_DEFS если поддерживается)
// Пока просто обновляем рецепт
const recipe = RECIPES.find((r) => r.value === value);
if (recipe && recipe.value !== 'custom') {
setConfig(entity.id, { ...entity.config, recipe: value, system: recipe.system });
} else {
handleConfigChange('recipe', value);
Comment thread web/src/state/runtime.ts
Comment on lines +113 to +118
function logPreview(value: unknown, max = 160): string {
if (value === undefined) return '∅';
const s = typeof value === 'string' ? value : JSON.stringify(value);
const oneLine = s.replace(/\s+/g, ' ').trim();
return oneLine.length > max ? oneLine.slice(0, max) + '…' : oneLine;
}
Comment thread web/src/state/runtime.ts
Comment on lines +163 to +166
if (parts.length > 0) {
store.toast(`${label}: ${parts.join(' → ')}`);
console.log('[io]', label, { in: event.lastIn, out: event.lastOut });
}
Comment thread server/main.py
Comment on lines +41 to +44
def log(tag: str, **fields) -> None:
"""Единый формат логов эндпоинтов: [tag] k=v k=v ... (flush — сразу в /tmp/server.log)."""
parts = " ".join(f"{k}={_short(v)}" for k, v in fields.items())
print(f"[{tag}] {parts}", flush=True)
Comment thread server/main.py
Comment on lines +193 to +195
# url может содержать секрет (напр. bot-token telegram в пути) — усекается _short'ом.
log("proxy→in", method=method, url=url, body=req_body)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants