1. Media tag enrichment (audio/video/document):
- Add enrichVideoIDs() — video media_id was never injected into
<media:video> tags, causing LLM to hallucinate UUIDs
- Fix all enrich functions to replace the LAST bare tag instead of
the first. When group history prepends older media tags, the first
occurrence belongs to history — injecting the current turn's ID
there causes the LLM to reference the wrong file
2. Gemini File API polling:
- Upload response returns fileURI immediately but file may still be
in PROCESSING state. Check state field; only skip polling when
file is already ACTIVE. Fixes "not in an ACTIVE state" errors
3. Channel instance credential merge:
- Partial credential updates (e.g. updating just token) now merge
with existing credentials instead of wiping other fields
- Loads, decrypts, merges, re-encrypts in a single Update() call
Co-authored-by: Luvu182 <208665161+Luvu182@users.noreply.github.com>
- Update go.mod and Dockerfile to Go 1.26
- Apply `go fix ./...` stdlib modernizations across 170+ files
- Add `go fix` to post-implementation checklist in CLAUDE.md
- Fix go fix misapplied rewrite in loop_history.go
- Add read_audio tool with Gemini File API, OpenAI input_audio, and fallback support
- Add read_video tool with Gemini File API and base64 fallback for video analysis
- Add create_video tool with Gemini Veo and OpenRouter chat completions support
- Add shared gemini_file_api.go for upload → poll → generateContent pipeline
- Add shared openai_compat_call.go for custom JSON chat completions
- Fix system prompt showing denied tools: use filteredToolNames() instead of tools.List()
- Wire audio/video MediaRef context propagation in agent loop
- Register new tools in seed data, policy groups, and web UI settings
- Enforce duration (max 30s) and aspect_ratio limits on create_video