Files
obsidian-vault/personal/projects/balda/balda-valera.md
T

10 KiB
Raw Blame History

Балда / Валера — эксплуатация & 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.mod replace: 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.gobuildTag константа

Статус: DeepSeek MCP tools — РАБОТАЕТ

Что сделано (openai.go)

Добавлена полная поддержка OpenAI tool_calls:

  • openAIToolDefinition, openAIFunction, openAIToolCall — структуры
  • Tools []openAIToolDefinition в openAIChatRequest
  • openAIToolsFromConfig() — конвертация genai.Tool[] → OpenAI definitions
  • parseChatResponse() — парсинг 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_handler
    • internal/apps/balda/actors/swarm_task_actor.go — TASK-ACTOR: dispatching/dispatch OK/FAILED
    • internal/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/master
  • master — коммит 56a6e1e (тот же, DeepSeek фиксы)

balda:

  • main05159d1 (intermediate status фикс запушен)
  • backup/our-main-before-upstream — старый main
  • feat/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.mod replace: github.com/normahq/norma => ./norma-local
  • go 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`)