Commit Graph

12 Commits

Author SHA1 Message Date
aab630661f Fix MiniMax MCP startup handling 2026-05-18 15:46:44 +02:00
7356a1812e Collapse blockquote and strip <think> blocks from AI responses
- blockquote expandable: replies are collapsed by default in Telegram
- strip <think>...</think> sections (chain-of-thought from reasoning
  models like DeepSeek R1 / QwQ) before sending the response

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 14:40:33 +02:00
42472dc91c Fix file tool sandbox: prompts/ was unreachable and workspace paths were doubly nested
The workspace root matched every relative path, so prompts/ was never reached,
and paths like workspace/notes.txt landed at workspace/workspace/notes.txt.

Fix: _resolve_sandboxed_path now treats allowed_roots[0] as the resolution base
(project root) and allowed_roots[1:] as permitted subdirectories. _get_allowed_roots
returns (project_root, workspace_dir, prompts_root). Paths are now correctly routed:
workspace/notes.txt -> workspace/notes.txt, prompts/ai/parts/x.md -> prompts/ai/parts/x.md.
app/ and other project dirs remain blocked.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 14:24:35 +02:00
f04ab527b8 Add user_template to wrap user messages with sender context (name, id, username)
Configure via ai.prompt.user_template in config.json using {text}, {full_name},
{user_id}, {first_name}, {last_name}, {username} placeholders. Applied to both
history user messages and the current prompt. No-op when unset.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 14:19:13 +02:00
c85af7c54d Add python_exec tool: run Python code in subprocess with ctx injection and timeout
Executes code in a fresh python3 subprocess (max 30s, default 10s).
Pre-injects a 'ctx' dict with: chat_id, message_id, message_text, args,
from_user, replied_message. stdout+stderr returned; output capped at 3000 chars.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 14:16:12 +02:00
95cac39fcf Add send_file tool to send workspace files to Telegram chat
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 13:59:40 +02:00
6ffb769b95 Eagerly initialize MCP tools at startup so loading is logged to console
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 13:22:31 +02:00
3932e44495 Log MCP tool loading outcome (fetching, loaded names, or failure with traceback)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 12:16:22 +02:00
9a3b7aa4f5 Add OpenAI tool-calling agentic loop with file tools and MiniMax MCP integration
- AIService.generate() now runs an agentic loop: sends tools to the API,
  handles tool_calls responses, executes tools, appends results, and repeats
  until a text response (up to tool_max_rounds, default 10)
- New app/ai/tools.py: six sandboxed file tools (write/read/create/modify/delete/list),
  OpenAI JSON schemas, path sandbox validator, and MCP→OpenAI schema converter
- Paths are sandboxed to workspace/ (project root) and prompts/ai/; traversal blocked
- MinimaxImageUnderstandClient gains list_tools() and call_tool() methods; MCP tool
  schemas are lazily fetched once per session and forwarded to the AI as callable tools
- AIConfig gains workspace_dir (Path, default workspace/) and tool_max_rounds (int, default 10)
- MCP client opened lazily only when an MCP tool is actually called during a loop

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 09:55:45 +02:00
e4e47c4649 Fix UTF-8 decode error for providers returning invalid encoding (Ollama)
Some providers (e.g. Ollama) may return response bytes that aren't valid
UTF-8. json.loads() raises UnicodeDecodeError in that case. Add an httpx
response event hook that replaces invalid bytes before the SDK parses the
response body.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 15:14:27 +02:00
Codex
86f7827802 Refine AI image context handling 2026-05-14 18:34:40 +02:00
Codex
2a731600e0 Add dual-prefix AI command 2026-05-14 13:24:47 +02:00