[2026-06-21] eagle: personal/projects/balda/balda-valera.md personal/projects/balda/fix-openaimodel-tools.md

This commit is contained in:
Alexey Martemyanov
2026-06-21 20:50:52 +06:00
parent 5ea0e4ba06
commit 6f911cffb0
2 changed files with 45 additions and 0 deletions
+28
View File
@@ -159,3 +159,31 @@ DOCKER_OPTS={"max_tokens": 2048, "temperature": 0.7}
### composerestart vs compose up -d
- `restart` — не перечитывает `.env`
- `up -d` — пересоздаёт контейнер с обновлённым `.env`
---
## Диагноз: MCP не работают — инструменты не передаются модели
**Статус (2026-06-21):** MCP резолвятся, но не вызываются.
**Установлено через BALDA-DEBUG:**
```
BALDA-DEBUG: mcpServerIDs=[balda obsidian fast-rlm]
resolvedMCP=map[balda:{http http://127.0.0.1:33545/mcp}
fast-rlm:{http http://fast-rlm-mcp:3333/mcp}
obsidian:{sse http://obsidian-mcp:3101/sse}]
```
MCP серверы зарезолвлены, тулсеты переданы в `hostedagent.Config`.
**Почему не работают:**
`OpenAIModel.generate()` → `buildChatRequest()` не читает `req.Config.Tools` (поле `genai.GenerateContentConfig`). ADK кладёт инструменты туда, но `buildChatRequest` сериализует только `model`, `messages`, `temperature`, `top_p`, `max_tokens`, `stop`. DeepSeek получает запрос без `tools` → отвечает текстом.
**Логи подтверждают:** `function_call_part_count=0` в ответе DeepSeek.
**Фикс:** в `pkg/runtime/hostedagent/openai.go`:
1. Добавить поле `Tools` в `openAIChatRequest` + `openAIToolDefinition`
2. В `buildChatRequest` читать `req.Config.Tools` → конвертировать в OpenAI tool definitions
3. В `parseChatResponse` парсить `tool_calls` из ответа (ADK сам выполнит MCP)
**Важно:** upstream `norma` v0.0.10 (`bf2b25d`) уже корректно передаёт MCP тулсеты через `agentfactory.hostedToolsets()`. Проблема только в том, что `OpenAIModel` — кастомная реализация, не умеющая прокидывать tools. Если бы использовался Gemini/ACP provider — MCP бы работали.
@@ -0,0 +1,17 @@
# План: фикс MCP для OpenAIModel
## Что сделать
1. В `openAIChatRequest` добавить поле `Tools []openAIToolDefinition`
2. Структура `openAIToolDefinition` (name, description, input_schema)
3. В `buildChatRequest` — прочитать `req.Config.Tools` из `genai` конфига, сконвертировать в OpenAI tool definitions
4. В `parseChatResponse` — парсить `tool_calls` из ответа (message может содержать и content, и tool_calls)
5. Написать тесты
## Тесты покрывают:
- `buildChatRequest` с tools и без
- `parseChatResponse` с tool_calls, с content, с обоими
- Интеграционный: `OpenAIModel.generate()` с мок-сервером
## Риски
- GenAI `Tool` структура — как конвертировать в OpenAI tool definition
- `tool_calls` формат в ответе DeepSeek