- Rewrite README.id.md to match current upstream structure (~250 lines)
- Detailed docs moved to docs/*.md, README is quick-start only
- Sync badges (Go 1.25+, LoongArch), news (v0.2.3), Termux instructions
- Add Bahasa Indonesia + Italiano to language selectors in all 8 READMEs
When both providers and model_list are configured, model_list entries
with empty api_key or api_base now automatically inherit from the
matching provider (matched by protocol prefix in the Model field).
Example: a model_list entry with model='deepseek/deepseek-chat' and
no api_key will inherit from providers.deepseek.api_key.
Explicit model_list values always take precedence.
Changes:
- Add InheritProviderCredentials() in migration.go
- Call it in LoadConfig() after provider-to-model-list conversion
- Add protocolProviderMapping for all 25 supported protocols
- 6 new tests covering inheritance, precedence, and edge cases
Closes#1635
* feat(wecom): add WebSocket long-connection support for WeCom AI Bot
- Introduced WeComAIBotWSChannel to handle WebSocket connections.
- Updated NewWeComAIBotChannel to prioritize WebSocket mode when BotID and Secret are provided.
- Enhanced WeComAIBotConfig to include BotID and Secret for WebSocket mode.
- Implemented message handling for text, image, voice, and mixed messages in WebSocket mode.
- Added tests for WebSocket mode functionality and ensured backward compatibility with webhook mode.
- Refactored existing code to improve clarity and maintainability.
* feat(wecom): implement periodic processing hints and enforce WeCom stream deadline
* feat(wecom): update WeCom AI Bot setup instructions and configuration parameters
* feat(wecom): enhance WeCom AI Bot with image handling and media support
* feat(wecom): refactor WeCom AI Bot task management to use req_id for concurrent message handling
* feat(wecom): refactor WeCom AI Bot to manage request states and late replies
* feat(wecom): add response timeout handling and improve WebSocket command acknowledgment
* fix(wecom): improve error handling for late reply proactive push delivery
* refactor(wecom): reorganize WeCom AI Bot configuration fields for improved readability
* fix(wecom): update error message for websocket delivery failure in late reply proactive push
* feat(wecom): implement shared HTTP clients for WeCom image handling and response URL posting
* refactor(wecom): simplify image download and storage process in storeWSImage
* fix(wecom): improve error logging for WebSocket message handling and proactive push delivery
* fix(wecom): enhance WebSocket connection stability and task cancellation handling
* fix(wecom): improve WS image message handling by ensuring proper error response and initializing mediaRefs
* feat(wecom): enhance WeCom AIBot WebSocket handling with message deduplication and support for file and video messages
* refactor(wecom): rename image handling functions to media handling and enhance media type support
* feat(wecom): implement byte-aware content splitting for WeCom AI Bot stream messages
* refactor(wecom): remove max message length constraint from WeCom AIBot WS channel
* feat(config): support multiple API keys for failover
Add api_keys field to ModelConfig to support multiple API keys with
automatic failover. When multiple keys are configured, they are expanded
into separate model entries with fallbacks set up for key-level failover.
Example config:
{
"model_name": "glm-4.7",
"model": "zhipu/glm-4.7",
"api_keys": ["key1", "key2", "key3"]
}
Expands internally to:
- glm-4.7 (key1) -> fallbacks: [glm-4.7__key_1, glm-4.7__key_2]
- glm-4.7__key_1 (key2)
- glm-4.7__key_2 (key3)
Backward compatible: single api_key still works as before.
* fix(providers): change cooldown tracking from provider to ModelKey
This enables proper key-switching when multiple API keys share the same
provider. Previously, when one key failed, all keys were blocked because
cooldown was tracked per-provider.
Now each (provider, model) combination has independent cooldown, allowing
fallback to alternate keys when one is rate limited.
Includes TestMultiKeyWithModelFallback and related failover tests.
* feat(feishu): add Lark (international) support via IsLark config field
Add IsLark field to FeishuConfig to switch between Feishu and Lark
domains. Also fix domain inconsistency where WS client defaulted to
LarkBaseUrl while HTTP client used FeishuBaseUrl.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs: update documentation and web UI for Lark support
Add is_lark field to config example, feishu docs, i18n translations,
and web frontend form.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix(tools): propagate tool registry to subagents via Clone
SubagentManager was created with an empty ToolRegistry and SetTools()
was never called, causing all subagent tool invocations to fail with
"tool not found". This was a regression from the multi-agent refactor.
Fix: clone the parent agent's tool registry into the subagent manager
after creation but before spawn/spawn_status registration — giving
subagents access to file, exec, web, and other tools while preventing
recursive subagent spawning.
- Add ToolRegistry.Clone() for independent shallow copies
- Call subagentManager.SetTools(agent.Tools.Clone()) in registerSharedTools
- Add tests for Clone isolation, empty clone, and hidden tool state
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(tools): fix cron_test build error and add TTL clone test
- Fix cron_test.go:229 — replace non-existent SubscribeOutbound(ctx)
with select on OutboundChan(), matching the MessageBus channel API
- Add TestToolRegistry_Clone_PreservesTTLValue per reviewer feedback
- Add version reset note to Clone() doc comment
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
When building parameters for Anthropic API calls, tool calls with empty
names would cause 400 Bad Request errors with the message:
'tool_use.name: String should have at least 1 character'
This fix adds a check to skip tool calls that have empty names, preventing
the API error and allowing the conversation to continue normally.
Fixes#1658
The Lark SDK v3's built-in token retry loop does not clear stale tokens
from cache when the server returns error 99991663 (tenant_access_token
invalid), causing all API calls to fail until the token naturally
expires (~2 hours).
- Add tokenCache struct (implementing larkcore.Cache) with
Get/Set/InvalidateAll methods and proper expired-entry cleanup
- Wire custom cache into lark.NewClient via WithTokenCache()
- Add invalidateTokenOnAuthError helper called in all API methods
* Add Novita provider support
- Add 'novita' prefix to normalizeModel switch in openai_compat provider
- Add Novita provider to all_supported_vendors table in README.md
- Add test cases for Novita model prefix stripping
Novita endpoint: https://api.novita.ai/openai
Default models: deepseek/deepseek-v3.2, zai-org/glm-5, minimax/minimax-m2.5
* feat: complete Novita provider integration
* chore: drop README changes from Novita PR
* fix: remove duplicate function declarations in openai_compat provider
The functions buildToolsList, SupportsNativeSearch, and isNativeSearchHost
were declared twice, causing compilation failures in all CI checks.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: break long line in novita test to satisfy golines linter
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix(telegram): improve HTML chunking and preserve word boundaries
* fix(telegram): address copilot feedback, filter empty chunks and add word-boundary regression test
* style(telegram): fix gofmt and gci lint errors in tests
* fix to feedback
* config: add prefer_native and NativeSearchCapable for model-native search
* providers: implement native web search for OpenAI and Codex
* agent: use provider-native search when prefer_native and supported
* tests: add coverage for model-native search
* fix: Golang lint errors
* fix: update the code based on the review
* fix: update codex_provider_test