10 KiB
Балда / Валера — эксплуатация & MCP debug
Расположение
- Валера =
balda-agent-valera-1, конфиг:~/Docker/balda-agent/.config/balda/config.yaml - Клавдий =
claudio-agent-claudio-1, конфиг:~/Docker/claudio-agent/.config/balda/config.yaml - Общий образ: собирается из
~/Docker/claudio-agent/Dockerfile.claudio, контекст/Users/admin/Developer - Norma-local (форк с MCP tools):
~/Developer/norma-local/go.modreplace:github.com/normahq/norma => ./norma-local(в~/Developer/balda/go.mod)- Модифицирован
pkg/runtime/hostedagent/openai.go+pkg/runtime/agentfactory/agentfactory.go
- Dockerfile:
~/Docker/claudio-agent/Dockerfile.claudio- Копирует
norma-local/в/src/norma-local/ go mod edit -replace github.com/normahq/norma=./norma-localпередgo mod download
- Копирует
Архитектура
- Валера = DeepSeek (
provider: deepseek, модельdeepseek-chat) - Клавдий = Claude через прокси (
provider: claude,claude-sonnet-4-6) - Валера использует Balda runtime — OpenAIModel из openai.go вызывается (hostedagent провайдер).
agentfactory.goиспользуется обоими — там лог версии на старте.
Версионный лог (norma-tools)
При старте Валеры в логах:
norma-tools version=v0.0.10 build=whale-YYYYMMDD-N
Где:
version— номер версии нормы (изopenAIVersion)build— тег сборки (изbuildTag)
Перед каждым билдом апать buildTag в openai.go:
const openAIVersion = "v0.0.10"
const buildTag = "whale-YYYYMMDD-N" // ← менять!
Файлы где апать:
~/Developer/norma-local/pkg/runtime/hostedagent/openai.go—buildTagконстанта
Статус: DeepSeek MCP tools — РАБОТАЕТ
Что сделано (openai.go)
Добавлена полная поддержка OpenAI tool_calls:
openAIToolDefinition,openAIFunction,openAIToolCall— структурыTools []openAIToolDefinitionвopenAIChatRequestopenAIToolsFromConfig()— конвертация genai.Tool[] → OpenAI definitionsparseChatResponse()— парсинг tool_calls из ответа DeepSeek (ID сохраняется)contentToOpenAI()— конвертация FunctionCall/FunctionResponse в историюgenerate()— TurnComplete=false при tool_calls (ADK делает второй раунд)
Исправленные проблемы
1. DeepSeek возвращает аргументы с двойной сериализацией ✓ 22.06.2026
Симптом: read_note/write_note падали — Obsidian MCP возвращал "Cannot read properties of undefined (reading 'replace')".
Корень: DeepSeek возвращает function.arguments как JSON-строку (экранированную), а не как JSON-объект.
Фикс в parseChatResponse: сперва пробуем распарсить Arguments как строку (json.Unmarshal(&argsStr)), потом эту строку как объект (json.Unmarshal([]byte(argsStr), &args)).
2. Obsidian MCP: get_vault_stats работает, read/write/delete нет ✓ 22.06.2026
Корень: двойная сериализация аргументов (см. проблему 1). После её фикса всё работает.
3. Key output не проверялся в contentToOpenAI ✓ 22.06.2026
Obsidian MCP возвращает response как {"output":"..."} — добавлена проверка на ключ output.
Текущий билд
- buildTag:
whale-20260622-7 - Все фиксы закоммичены в
master(норма-локаль) - OPENAI-DEBUG стэш дропнут — логи в рабочей копии (не коммитятся)
- Replace на норму работает через
go.mod+ Dockerfile norma-toolsлог подтверждён:time=2026-06-22T13:00:37.170Z level=INFO msg=norma-tools version=v0.0.10 build=whale-20260622-7
Промежуточные статусы — ПОЧИНЕНО (23.06.2026)
Статус: работает.
RunSessionTurnPayload(zulip_handler.go) — публикует промежуточный текст и ⚙️ function call статусы для!ev.TurnCompleteивентов черезsendPlain.balda.go(Telegram) — те же промежуточные публикации.handleAutoClaimMention/handleMessage/enqueueTurn— передаютmessageIDдля точного Zulip threading.- Коммит:
05159d1(main), запушен.
Стэши debug-логов (23.06.2026)
Дебаг логи не коммитятся, хранятся в стэшах.
balda (~/Developer/balda):
stash@{0}:debug: whale-20260623 — TASK-ACTOR logging in swarm_task_actor, event count & response_len debug in zulip_handlerinternal/apps/balda/actors/swarm_task_actor.go— TASK-ACTOR: dispatching/dispatch OK/FAILEDinternal/apps/balda/handlers/zulip_handler.go— eventCount, response_len, running session turn log
stash@{1}: WIP on feat/zulip-events-polling
Восстановление balda стэша:
cd ~/Developer/balda && git stash pop stash@{0}
norma-local (~/Developer/norma-local):
- OPENAI-DEBUG стэш дропнут — 9x fmt.Fprintf(os.Stderr, "OPENAI-DEBUG:...") в рабочей копии openai.go
Бранчи (23.06.2026)
norma-local:
feat/hostedagent-mcp-tools— коммит56a6e1e(DeepSeek tool_calls фикс), чистая бранча отorigin/mastermaster— коммит56a6e1e(тот же, DeepSeek фиксы)
balda:
main—05159d1(intermediate status фикс запушен)backup/our-main-before-upstream— старый mainfeat/zulip-transport-intermediate— от коммитаbc5fd03
Сборка
Полный цикл сборки
# 1. Инкремент buildTag в openai.go (строка buildTag)
# ~/Developer/norma-local/pkg/runtime/hostedagent/openai.go
# buildTag = "whale-YYYYMMDD-N"
# 2. Применить OPENAI-DEBUG стэш (если нужно дебажить)
cd ~/Developer/norma-local && git stash pop stash@{0}
# 3. Сборка
docker build --no-cache \
-f ~/Docker/claudio-agent/Dockerfile.claudio \
-t balda-agent-valera:latest \
/Users/admin/Developer
# 4. Деплой
cd ~/Docker/balda-agent && docker-compose up -d --force-recreate
# 5. Проверка версии в логах
docker logs balda-agent-valera-1 2>&1 | grep "norma-tools"
Особенности сборки
- Dockerfile копирует
norma-local/в/src/norma-local/ go.modreplace:github.com/normahq/norma => ./norma-localgo mod edit -replaceприменяется доgo mod download--no-cacheобязателен при изменении norma-local- Образ надо таргетировать под нужное имя:
balda-agent-valeraдля Валеры,claudio-agentдля Клавдия - После сборки
docker-compose up -d --force-recreateчтобы подхватить новый образ
Диагностика молчания / проблем
NORMA-TOOLS не появляется в логах
Причина: агент использует не hostedagent провайдер. openai.go задействован только при provider=deepseek через ADK.
MCP ошибка: failed to list MCP tools: failed to connect: Not Found
Фикс: в config.yaml url должен заканчиваться на /sse: url: http://obsidian-mcp:3101/sse
В логах command running → command handled за секунду, без received provider event
Причина: стухший embedded NATS. Фикс: docker-compose restart или up -d.
Удалён / пустой state.db
Фикс: rm state.db и up -d (balda создаст заново).
Нет owner
Фикс: прописать allowed_owners в config.yaml.
stream_only_with_session
Фикс: написать @Валера <текст> чтобы создать сессию.
Известные грабли
OPENAI_BASE_URL — обязательная env var
Norma не читает base_url из config.yaml для provider: deepseek. Читает env.
DOCKER_OPTS — пустая строка убивает старт
Должен быть валидный JSON: DOCKER_OPTS={"max_tokens": 2048}
docker compose up -d не работает
На этом хосте docker compose (без дефиса) не принимает -d. Использовать docker-compose up -d.
Docker кеш COPY norma-local/
Слой копирования кешируется. --no-cache обязателен при изменении norma-local.
go.mod replace
replace github.com/normahq/norma => ./norma-local — путь относительно /src в контейнере, куда копируется norma-local/.
zulip-router owner-форвард падал с 400 (23.06.2026)
Симптом: Валера не отвечал на сообщения в закреплённых тредах без @mention. Router лог: forward failed (owner) error="post ... status 400 body=bad request". Валера лог: invalid zulip webhook payload error="unsupported message.type \"\"".
Корень: В zulip-router/config.go структура Message не имела поля Type. Zulip Events API присылает message.type ("stream"/"private"), но роутер его не парсил — в вебхук приходил пустой "". Balda-agent валидирует message.type.
Фикс: Добавлен Type string \json:"type,omitempty"`вMessage struct. Коммит 803ae68(локальный, без remote). docker-compose up -d --build. Фикс: messageID int в сигнатуру handleAutoClaimMention, передаётся payload.Message.ID из processMessage. Файл:~/Developer/balda/internal/apps/balda/handlers/zulip_handler.go(в коммите05159d1`)