Commit Graph

229 Commits

Author SHA1 Message Date
Amir Mamaghani 71134babb9 feat(telegram): stream LLM responses via sendMessageDraft (#1101)
* feat(telegram): stream LLM responses in real-time via sendMessageDraft

Implements real-time token streaming to Telegram using the sendMessageDraft
API (telego v1.6.0). Instead of showing only a "Thinking..." placeholder
until the full response arrives, users now see partial LLM output appear
in the chat as it's generated.

The streaming pipeline threads through all layers:

- StreamingProvider interface (providers/types.go): opt-in ChatStream()
  method that receives an onChunk callback with accumulated text
- OpenAI-compatible SSE streaming (openai_compat/provider.go): parses
  SSE events with stream:true, handles text deltas and tool call assembly
- Anthropic native streaming (anthropic/provider.go): uses SDK's
  NewStreaming() for direct Anthropic API connections
- HTTPProvider delegation (http_provider.go): delegates ChatStream to
  the underlying openai_compat provider
- StreamingCapable + Streamer interfaces (channels/interfaces.go):
  opt-in channel capability like TypingCapable/PlaceholderCapable
- Telegram streamer (telegram/telegram.go): BeginStream returns a
  telegramStreamer that throttles sendMessageDraft calls (3s/200 chars)
  with graceful degradation on API errors
- StreamDelegate bridge (bus/bus.go): decouples agent loop from channel
  manager without tight imports
- Manager integration (manager.go): implements StreamDelegate, tracks
  streamActive state, coordinates with placeholder editing
- Agent loop (loop.go): uses ChatStream when both provider and channel
  support streaming, cancels stream on tool calls, skips PublishOutbound
  when Finalize already delivered the message

Graceful degradation:
- Bots without forum/topics mode: first sendMessageDraft error sets
  failed=true, subsequent Updates become no-ops, Finalize still delivers
  via SendMessage. User sees normal non-streaming behavior.
- Non-streaming providers: type assertion fails, falls back to Chat()
- Config opt-out: streaming.enabled (default true) in telegram config

Closes #1098

* fix(telegram): delete placeholder message when streaming delivers response

When streaming was active, the "Thinking..." placeholder message stayed
in the chat because preSend only deleted the tracking entry without
removing the actual Telegram message. Now preSend deletes the placeholder
via the new MessageDeleter interface when streamActive is set.

* refactor(streaming): remove dead code and simplify streaming wiring

- Delete unused Anthropic ChatStream/parseStream (-131 lines) — factory
  creates HTTPProvider for all OpenAI-compat providers including OpenRouter
- Simplify runLLMIteration from 4 to 3 return values (remove unused
  streamed bool)
- Replace managerStreamer struct with finalizeHookStreamer using embedding
  (Update/Cancel promoted, only Finalize overridden)

* fix(streaming): skip streamer acquisition when SendResponse is false

Heartbeat messages set SendResponse=false but the streaming path
was unconditionally acquiring a streamer, causing HEARTBEAT_OK to
leak to Telegram via streamer.Finalize().

* fix(streaming): guard streamer for non-sendable messages, add streaming config

Skip streamer acquisition for heartbeat (NoHistory=true), preventing
HEARTBEAT_OK from leaking to Telegram via streamer.Finalize().

Add streaming.enabled to Telegram defaults and example config.

* feat(telegram): stream LLM responses in real-time via sendMessageDraft

Implements real-time token streaming to Telegram using the sendMessageDraft
API (telego v1.6.0). Instead of showing only a "Thinking..." placeholder
until the full response arrives, users now see partial LLM output appear
in the chat as it's generated.

The streaming pipeline threads through all layers:

- StreamingProvider interface (providers/types.go): opt-in ChatStream()
  method that receives an onChunk callback with accumulated text
- OpenAI-compatible SSE streaming (openai_compat/provider.go): parses
  SSE events with stream:true, handles text deltas and tool call assembly
- Anthropic native streaming (anthropic/provider.go): uses SDK's
  NewStreaming() for direct Anthropic API connections
- HTTPProvider delegation (http_provider.go): delegates ChatStream to
  the underlying openai_compat provider
- StreamingCapable + Streamer interfaces (channels/interfaces.go):
  opt-in channel capability like TypingCapable/PlaceholderCapable
- Telegram streamer (telegram/telegram.go): BeginStream returns a
  telegramStreamer that throttles sendMessageDraft calls (3s/200 chars)
  with graceful degradation on API errors
- StreamDelegate bridge (bus/bus.go): decouples agent loop from channel
  manager without tight imports
- Manager integration (manager.go): implements StreamDelegate, tracks
  streamActive state, coordinates with placeholder editing
- Agent loop (loop.go): uses ChatStream when both provider and channel
  support streaming, cancels stream on tool calls, skips PublishOutbound
  when Finalize already delivered the message

Graceful degradation:
- Bots without forum/topics mode: first sendMessageDraft error sets
  failed=true, subsequent Updates become no-ops, Finalize still delivers
  via SendMessage. User sees normal non-streaming behavior.
- Non-streaming providers: type assertion fails, falls back to Chat()
- Config opt-out: streaming.enabled (default true) in telegram config

Closes #1098

* fix(telegram): delete placeholder message when streaming delivers response

When streaming was active, the "Thinking..." placeholder message stayed
in the chat because preSend only deleted the tracking entry without
removing the actual Telegram message. Now preSend deletes the placeholder
via the new MessageDeleter interface when streamActive is set.

* refactor(streaming): remove dead code and simplify streaming wiring

- Delete unused Anthropic ChatStream/parseStream (-131 lines) — factory
  creates HTTPProvider for all OpenAI-compat providers including OpenRouter
- Simplify runLLMIteration from 4 to 3 return values (remove unused
  streamed bool)
- Replace managerStreamer struct with finalizeHookStreamer using embedding
  (Update/Cancel promoted, only Finalize overridden)

* fix(streaming): skip streamer acquisition when SendResponse is false

Heartbeat messages set SendResponse=false but the streaming path
was unconditionally acquiring a streamer, causing HEARTBEAT_OK to
leak to Telegram via streamer.Finalize().

* fix(streaming): guard streamer for non-sendable messages, add streaming config

Skip streamer acquisition for heartbeat (NoHistory=true), preventing
HEARTBEAT_OK from leaking to Telegram via streamer.Finalize().

Add streaming.enabled to Telegram defaults and example config.

* fix(picoclaw): add missing closing brace for StreamingProvider interface

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: resolve golangci-lint formatting issues

Fix gci import ordering in telegram and anthropic provider, and break
long function signature in openai_compat provider to satisfy golines.

* fix: address code review feedback on streaming PR

- Deduplicate Streamer interface: alias channels.Streamer to bus.Streamer
  to prevent type drift across packages
- Increase SSE scanner buffer to 10MB max to handle large single-line
  responses that exceed bufio.Scanner's 64KB default
- Switch draftID generation from math/rand to crypto/rand for
  collision-resistant random IDs
- Add context cancellation check in SSE parsing loop so cancelled
  streams stop processing immediately
- Log Finalize failures with chat_id and content length for debugging
  silent message delivery failures

* feat: make streaming throttle interval and min growth configurable

Move hardcoded streamThrottleInterval (3s) and streamMinGrowth (200)
into StreamingConfig so they can be tuned per deployment via config
or environment variables.

* fix(telegram): use parseTelegramChatID in DeleteMessage and BeginStream

These two functions called undefined parseChatID. Use
parseTelegramChatID with _ for the unused threadID instead of adding
a wrapper function. Fixes all three CI checks.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(streaming): set streamActive only after successful Finalize

Move onFinalize hook to run after Streamer.Finalize succeeds, so that
if Finalize fails the streamActive flag stays false and the regular
placeholder fallback path remains available.

Addresses review feedback from @alexhoshina.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 21:04:14 +08:00
Amir Mamaghani 544940807f feat(pico): add pico_client outbound WebSocket channel (#1198)
* feat(pico): add pico_client outbound WebSocket channel

Add a client-mode counterpart to the existing pico server channel.
pico_client connects to a remote Pico Protocol WebSocket server,
enabling picoclaw to bridge messages with external Pico-compatible
services.

Includes config, factory registration, manager wiring, 8 unit tests,
and a minimal echo-server example for interactive testing.

* fix(pico): address PR #1198 review — goroutine leak, race, auth

- Add per-connection context cancel to picoConn to prevent pingLoop
  goroutine leak on disconnect
- Re-acquire mutex in StartTyping stop closure to avoid stale conn race
- Remove query-param token auth from echo server (header-only)
- Move ListenAndServe to main goroutine where log.Fatal is safe

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: replace ConsumeInbound with InboundChan select in client test

MessageBus does not expose a ConsumeInbound method. Use a select on
InboundChan() with context cancellation, matching the pattern used in
the bus package tests.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 20:43:40 +08:00
美電球 75d86721a3 Feat/wecom aibot processing message config (#1785)
* feat(wecom_aibot): make processing message configurable

* docs(wecom): document ai bot processing message

* test(wecom_aibot): adapt webhook tests to channel interface

* fix: lint err
2026-03-20 00:23:40 +08:00
Bijin 38e1fe435a fix(config): model_list inherits api_key/api_base from providers (#1786)
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
2026-03-19 21:24:46 +08:00
ZHANG RUI 9a25fad20a Implement the latest long-connection mode for the WeCom AI Bot. (#1295)
* 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
2026-03-19 20:06:51 +08:00
Mauro 7673b626b3 feat(tool): debug tool usage via channels (#1332)
* feat(tool): debug usage via channel

* set defaults

* fix conflicts
2026-03-19 18:08:50 +08:00
Mauro a4b5a9eec1 feat(mcp): per server deferred mode (#1654)
* feat(mcp): per server deferred mode

* fix deferred behavior
2026-03-19 17:03:17 +08:00
美電球 828971d549 Feat/qq local file upload (#1722)
* feat(qq): support media uploads and inbound attachments

* docs(qq): document media size limit settings

* chore(web): add QQ media size limit hints

* fix(qq): demote botgo heartbeat logs

* style(qq): fix lint issues
2026-03-19 16:27:34 +08:00
Liu Yuan e73d9d959e feat(config): support multiple API keys for failover (#1707)
* 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.
2026-03-19 00:57:20 +08:00
Liqiang Lau 08f305d712 feat: add IsLark field to FeishuConfig to switch between Feishu and Lark domains (#1753)
* 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>
2026-03-19 00:29:55 +08:00
Alexander 12f4029610 feat: telegram use parse mode ModeMarkdownV2 instead of ModeHTML (#1018)
* feat: telegram use parse mode ModeMarkdownV2 instead of ModeHTML

* handle expandable block quotation starts, add test for all md2 formats

* fix: linter issue

* feat: added flag use_markdown_v2, corrected config, updated
documentation

* move parseChatID to parser_markdown_to_html

* fix: tests and linter issues

* fix: case with ~

* test: fixed Test_markdownToTelegramMarkdownV2

* fix: regex block-quote line  >

* fix: linter issues

* fix: send chunk param mismatched, in edit msg use HTML parse mode too

* fix: remove from .gitignore redundant comment
2026-03-18 21:29:21 +08:00
Alex 578f90855e feat: Add Novita provider support (#1677)
* 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>
2026-03-18 18:29:27 +08:00
dev-miro26 c07f5c948f refactor: centralize environment variable key constants (#1730)
* refactor: centralize environment variable key constants

* refactor: update environment variable constants and usage in gateway
2026-03-18 18:03:24 +08:00
dataCenter430 f79469c19d Add model-native search (prefer_native) for OpenAI/Codex (#1618)
* 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
2026-03-18 11:55:30 +08:00
Meng Zhuo cefa140bd2 Merge pull request #1622 from afjcjsbx/feat/markdown-output-format-web-fetch
feat(tool): markdown format in web_fetch tool output
2026-03-18 09:15:13 +08:00
Mauro 513537d230 Merge pull request #1702 from Alix-007/fix/issue-1153-model-round-robin-cleanbase
fix(config): start model round robin from the first match
2026-03-17 22:28:48 +01:00
afjcjsbx 8f460726cc fix lint + error check 2026-03-17 17:14:23 +01:00
Mauro 3791f06faf Merge branch 'main' into feat/markdown-output-format-web-fetch 2026-03-17 16:37:22 +01:00
Alix-007 b4468313e4 feat(web): whitelist private fetch targets (#1688)
* feat(web): whitelist private fetch targets

* test(web): avoid accept error shadowing

---------

Co-authored-by: Alix-007 <267018309+Alix-007@users.noreply.github.com>
2026-03-17 23:22:05 +08:00
Alix-007 fcf406bf2e fix(config): start model round robin from the first match 2026-03-17 21:59:04 +08:00
wenjie 8a44410e37 feat: add web gateway hot reload and polling state sync (#1684)
* feat(gateway): support hot reload and empty startup

- extract gateway runtime into pkg/gateway
- add gateway.hot_reload config with default and example values
- allow starting the gateway without a default model via --allow-empty
- stop treating missing enabled channels as a startup error
- update related tests

* feat: replace gateway SSE updates with polling-based state sync

- remove gateway SSE broadcasting and event endpoint
- add polling-based gateway status refresh with stopping state handling
- detect when gateway restart is required after default model changes
- resolve gateway health and websocket proxy targets from configured host
- update gateway UI labels and add backend/frontend test coverage
2026-03-17 18:46:00 +08:00
Desmond Foo b402888bfa feat(tools): add SpawnStatusTool for reporting subagent statuses (#1540)
* feat(tools): add SpawnStatusTool for reporting subagent statuses

* feat(tools): enhance SpawnStatusTool to restrict task visibility by conversation context

* feat(tests): add Unicode result truncation and channel filtering tests for SpawnStatusTool

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* feat(tools): enhance SpawnStatusTool with task ID validation and sorting by creation timestamp

* feat(tools): update SpawnStatusTool description and parameter documentation for clarity

* refactor(tests): improve comments for clarity in ChannelFiltering test case

* fix(tools): update no subagents message for clarity and remove unnecessary locking in runTask

* fix(tools): improve description clarity for SpawnStatusTool regarding task context

* feat(tools): add spawn_status tool configuration and registration

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* fix(agent): improve subagent management for spawn and spawn_status tools

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* fix(tests): update ResultTruncation_Unicode test to use valid CJK character

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: lxowalle <83055338+lxowalle@users.noreply.github.com>
2026-03-17 14:41:43 +08:00
wenjie fcb69860c4 feat(web): add configurable cron command execution settings (#1647)
- add tools.cron.allow_command config with a default value of true
- require command_confirm only when cron command execution is disabled
- expose cron command permission and timeout settings in the config UI
- add backend tests and update i18n strings
2026-03-17 09:44:32 +08:00
sky5454 2f10b47f59 feat(credential): part1 add AES-GCM encryption, SecureStore, and onboard ke… (#1521)
* feat(credential): add AES-GCM encryption, SecureStore, and onboard keygen

- pkg/credential: new package with AES-256-GCM enc:// credential format,
  HKDF-SHA256 key derivation (passphrase + optional SSH key binding),
  ErrPassphraseRequired / ErrDecryptionFailed sentinel errors,
  and PassphraseProvider hook for runtime passphrase injection

- pkg/credential/store: lock-free SecureStore via atomic.Pointer[string];
  passphrase never written to disk or os.Environ

- pkg/credential/keygen: ed25519 SSH key generation helper used by onboard

- pkg/config: replace os.Getenv(PassphraseEnvVar) with
  credential.PassphraseProvider() at all three call sites so that
  LoadConfig and SaveConfig use whatever passphrase source is active

- cmd/picoclaw/onboard: prompt for passphrase with echo-off, generate
  picoclaw-specific SSH key, re-encrypt existing config on re-onboard

- docs/credential_encryption.md: design doc for the enc:// format

* fix(credential): address Copilot review comments on PR #1521

- credential.go: decouple ErrPassphraseRequired from env var name;
  message is now 'enc:// passphrase required' since PassphraseProvider
  may come from any source, not just os.Environ

- credential.go: Resolver resolves symlinks via EvalSymlinks before the
  isWithinDir containment check, preventing symlink-based path traversal
  for file:// credential references

- store.go: tighten comment to describe only what SecureStore guarantees
  (in-memory only); remove claims about how callers transport the value

- store_test.go: replace the meaningless GetReturnsCopy test (Go strings
  are immutable, equality across two calls proves nothing) with
  TestSecureStore_ConcurrentSetGet that exercises atomic.Pointer under
  10-goroutine concurrent Set/Get load

- config_test.go: update error-message assertion to match new sentinel text

- docs/credential_encryption.md: remove reference to non-existent
  'picoclaw encrypt' subcommand; describe the onboard flow instead

* fix(config): encryptPlaintextAPIKeys: struct-based encryption, fail-fast, remove raw []byte

* fix(credential): require SSH private key for encryption/decryption, remove passphrase-only mode

* lint: fix credential keygen lint, fix test keygen

* onboard: make encryption opt-in via --enc flag

Encryption (passphrase prompt + SSH key generation) is now only
triggered when the user passes --enc to 'picoclaw onboard'.
Without the flag, onboard skips the credential-encryption setup and
writes a plain config + workspace templates directly.

- Add --enc BoolFlag in NewOnboardCommand()
- Pass encrypt bool into onboard()
- Guard passphrase prompt, SSH key generation, and related env-var
  setup behind the encrypt branch
- Adjust 'Next steps' output so the passphrase reminder only appears
  when --enc was used
2026-03-16 14:06:32 +08:00
afjcjsbx d5c2bc538a feat(tool): markdown format in output web_fetch tool 2026-03-15 22:12:03 +01:00
Kunal Karmakar 5fb4b3bedf feat(provider): add support for azure openai provider (#1422)
* Add support for azure openai provider

* Add checks for deployment model name

* Apply suggestion from @Copilot

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Addressing @Copilot suggestion to remove the init() function which seemed redundant

* Fix readme

* Fix linting checks

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-03-14 22:52:34 +08:00
Cytown dfa36f39cb add model command to set default model (#1250)
* add model command to set default model

* fix for ci

* fix test for model

* fix active agent not recognized

* implement test for model command

* fix local-model can not set as default issue

* fix review comment

* fix for comment
2026-03-13 14:10:11 +08:00
leamon 0fb92b21b6 enhance skill installer (#1252)
* enhance skill installer

* enhance install skills v2

* go file formate

* fix:use proxy download skills;many chunck download;simple code

* add default config to config.example.json, download skill from github use proxy and token

---------

Co-authored-by: FantasticCode2019 <1443996278@qq.com>
2026-03-13 14:04:02 +08:00
dataCenter430 b811e9186c feat(provider): add ModelScope as OpenAI-compatible provider (#1486)
* feat(provider): add ModelScope as OpenAI-compatible provider

* test(provider): add ModelScope provider and migration tests

* docs: add ModelScope to README provider tables and free tier sections

* chore: add ModelScope to example config and env template
2026-03-13 14:02:23 +08:00
Guoguo 1e024321c0 refactor: update model name and add VolcEngine coding plan (#1412)
* docs: swap header logo to webp, move meme logo to bottom

Replace header logo with assets/logo.webp across all 6 README
language variants and move the original meme logo (logo.jpg)
to the bottom of each file.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: update GPT model names to gpt-5.4 and refine provider descriptions

Update all 6 language README variants:
- Correct GPT model references from gpt-5.2/gpt4 to gpt-5.4
- Refine provider descriptions in API Key comparison tables

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: update default model to gpt-5.4, codex to gpt-5.3-codex

Update OpenAI default model references from gpt-5.2 to gpt-5.4
across source code, config examples, tests, and docs. Set Codex
default model to gpt-5.3-codex.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 16:10:29 +08:00
LeaderOnePro 9222351871 feat(providers): add LongCat model provider support (#1317)
* feat(providers): add LongCat model provider support

Add LongCat as an OpenAI-compatible provider with base URL
https://api.longcat.chat/openai and default model LongCat-Flash-Thinking.
Includes provider config, migration, factory routing, example config,
tests, and README entries for all 6 locales.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(providers): address LongCat review feedback

- Add dedicated factory routing test for LongCat provider
- Add longcat to DefaultAPIBase test coverage
- Set default api_base in example config providers section

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* test(providers): add ResolveProviderSelection tests for LongCat

Add two test cases to TestResolveProviderSelection:
- Explicit provider selection with api_base default and proxy wiring
- Fallback inference from model name with api_base default

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-12 02:34:42 +08:00
Darren.Zeng 8431fa3e04 fix(config): support Chinese comma separator in allow_from environment variables (#1301)
Add UnmarshalText method to FlexibleStringSlice to support both English
(,) and Chinese (,) comma separators in environment variables.

Includes comprehensive unit tests covering:
- English commas, Chinese commas, mixed commas
- Single values, whitespace trimming
- Empty strings, edge cases

Fixes #1280
2026-03-12 02:33:33 +08:00
Dimitrij Denissenko 39a451d312 Enable rich-text messages in matrix channel (#1370)
* Enable rich-text messages in matrix channel

* Fix lint
2026-03-12 01:25:28 +08:00
wenjie 8949a2575b Add exec allow_remote config support in web settings (#1363)
- default tools.exec.allow_remote to true when omitted in config loading
- preserve allow_remote in OpenClaw config migration and API updates
- expose allow_remote in the web config form with i18n strings
- add backend and config tests covering the new default behavior
2026-03-11 19:57:59 +08:00
wenjie 8c2a9332c6 fix(security): harden unauthenticated tool-exec paths (#1360)
* fix(security): harden unauthenticated tool-exec paths (GHSA-pv8c-p6jf-3fpp)

- Exec tool: channel-based access control (default deny remote)
- Cron tool: command scheduling restricted to internal channels
- Web fetch: SSRF defense-in-depth (pre-flight + dial-time + redirect checks)
- File permissions: session/state dirs 0700, files 0600
- Registry: inject __channel/__chat_id into tool args (replaces racy SetContext)

28 new security regression tests.

(cherry picked from commit 191446ae19021604d3d5b0d9376b9655ab749105)

* fix(exec): revalidate working_dir before command start

* test(web): allow local oversized payload fixture

---------

Co-authored-by: xj <gh-xj@users.noreply.github.com>
2026-03-11 19:22:20 +08:00
afjcjsbx 08cc09e091 resolve conflicts 2026-03-11 00:17:10 +01:00
lxowalle 680e845d61 feat:Modify the location where version is obtained, and insert version information into the context (#1300)
* feat:migrate version info from internal package to pkg/config

* * fix lint issue
2026-03-10 17:42:05 +08:00
yanhool 95716b106b feat(web_search): add load balance and failover for api keys (#982)
* feat(web_search): add load balance and failover for api keys

* feat(web_search): add load balance and failover for api keys

* lint

* new iter to get api key

* deleted conflicts
2026-03-10 19:34:11 +11:00
美電球 2312553286 feat(channels): enhance QQ channel with group/typing/media support and URL sanitization (#1208)
* feat(channels): enhance QQ channel with group support, typing, media, and URL sanitization

Add group message routing alongside existing C2C (direct) support using
chatType sync.Map to track whether a chatID is group or direct. Implement
passive reply with msg_id/msg_seq tracking for multi-part responses.

Add StartTyping (InputNotify msg_type=6 with periodic resend), SendMedia
(RichMediaMessage for HTTP/HTTPS URLs), and configurable Markdown message
support. Replace unbounded dedup map with TTL-based expiry and janitor
goroutine.

Sanitize URLs in group messages by replacing dots in domains with fullwidth
period to avoid QQ's URL blacklist rejection (error 40054010). Add rate
limit config (5 msg/s) and MaxMessageLength/SendMarkdown config fields.

* fix(channels): address review feedback on QQ channel implementation

- Fix goroutine leak: reinitialize done channel and sync.Once in Start()
  to prevent multiple janitor goroutines on restart
- Fix double-close panic: guard close(done) with sync.Once in Stop()
- Fix StartTyping context: use c.ctx (channel lifecycle) instead of
  caller's ctx (request lifecycle) for typing goroutine
- Refactor: extract getChatKind() helper to deduplicate chatType lookup
  across Send(), StartTyping(), and SendMedia()
- Fix: use new(atomic.Uint64) instead of taking address of local var
- Fix: require explicit http(s):// scheme in URL regex to avoid false
  positives on version strings like "1.2.3"
- Optimize: collect expired keys before deleting in dedupJanitor to
  reduce lock hold time
- Fix: remove MaxMessageLength zero-value override in NewQQChannel
  since defaults.go already sets 2000

* fix(channels): address second round of review feedback on QQ channel

- Fix SendMedia: bypass media store for direct http(s) URLs in part.Ref;
  only fall back to store.Resolve for media:// refs; log clear warning
  for local-only paths instead of silently skipping
- Fix chatType routing: default unknown chatIDs to "group" (safer for QQ
  since outbound-only destinations like reasoning_channel_id are groups);
  pre-register reasoning_channel_id as group at Start() time; add debug
  log for untracked chatIDs
- Add dedup hard cap (10000 entries): evict oldest entry when map
  exceeds capacity to prevent unbounded memory growth under high traffic
2026-03-10 12:07:02 +08:00
Mauro b89f6445d1 feat(mcp): tool search tools (#1243)
* feat(mcp): tool search tools

* removed unused call_discovered_tool

* improvements and optimizations

* fix gate mcp enabled

* fix TOCTOU race BM25 cache version check

* fix encapsulation bypass on registry internals

* safety comment on TickTTL

* added more unit tests

* enhanced logs
2026-03-09 18:21:49 +01:00
Meng Zhuo 9a13ed50d0 Merge pull request #1107 from afjcjsbx/fix/deny-reading-binary-files
fix(tool) prevent read huge files in tool
2026-03-09 22:11:27 +08:00
lxowalle abafa3c2aa * add minimax provider (#1273) 2026-03-09 18:43:58 +08:00
afjcjsbx ff54128ab4 refined code 2026-03-09 09:32:21 +01:00
美電球 7ea7bb0717 Merge pull request #1171 from mutezebra/feat/feishu-random-emoji-v2
feat(feishu): add random reaction emoji config
2026-03-08 23:47:45 +08:00
美電球 b767ca9c3c Merge pull request #1220 from horsley/feat/matrix-channel-support
feat: add Matrix channel support
2026-03-08 22:58:16 +08:00
mutezebra 08d668c165 chore(config): gofmt 格式化 FeishuConfig 字段对齐 2026-03-08 17:32:24 +08:00
mutezebra b15cff1266 Merge upstream/main and resolve conflicts in .env.example 2026-03-08 15:32:11 +08:00
Meng Zhuo 81dfdf5f45 Merge pull request #1100 from zihan987/main
feat: add Vivgrid provider support
2026-03-08 11:03:13 +08:00
horsley a66eac42c4 feat: add Matrix channel support 2026-03-07 17:44:24 +00:00
Meng Zhuo aeabbcf2e8 Merge pull request #1138 from amirmamaghani/feat/irc-channel
feat(channels): add IRC channel integration
2026-03-07 20:25:26 +08:00