Commit Graph

244 Commits

Author SHA1 Message Date
reusu 28f69e71cc fix: address load_image PR review feedback
- Exclude load_image from sub-agent tools via Unregister after Clone,
  since RunToolLoop does not call resolveMediaRefs
- Add ToolRegistry.Unregister() method
- Fix scope collision: use channel:chatID instead of filename
- Add channel/chatID context resolution matching send_file pattern
- Add comment explaining iteration > 1 guard on resolveMediaRefs
- Remove emoji from ForUser for consistency with send_file
- Add load_image_test.go
2026-03-28 22:49:54 +08:00
Reusu 66924457bc feat: add load_image tool for local file vision 2026-03-28 16:05:30 +08:00
xiwuqi e011284d8f fix(agent): use light provider for routed model calls (#2038) 2026-03-28 15:25:23 +08:00
Mauro 60d7ec20a5 feat(log): prompt tokens (#2047) 2026-03-28 02:00:12 +08:00
Cytown b646d3b8fe refactor config and security to simplified the structure (#2068) 2026-03-28 00:03:34 +08:00
Badgerbees 97dec16769 fix(providers): improve context overflow detection and classification 2026-03-26 01:07:56 +07:00
xiwuqi 85dfb341a8 fix(agent): suppress heartbeat tool feedback (#1937) 2026-03-25 14:22:41 +08:00
Mauro 2a0efb6e52 Merge pull request #1889 from afjcjsbx/fix/binary-tool-output-handling
fix(tool): route binary outputs through the media pipeline
2026-03-24 15:37:06 +01:00
daming大铭 2c48cd3461 Merge pull request #1907 from xiwuqi/wuxi/fix-reasoning-channel-content
fix(agent): route reasoning_content to reasoning channel
2026-03-24 01:24:14 +08:00
afjcjsbx 5d5536a1a6 fix delivery and steering 2026-03-23 14:09:52 +01:00
uiyzzi 16d23d8cdc feat(security): add sensitive data filtering for tool results sent to
LLM

Prevent LLM from seeing its own credentials (API keys, tokens, secrets)
by filtering sensitive values from tool call results before sending to
the
model. Values are collected from .security.yml and replaced with
[FILTERED] using an efficient strings.Replacer (O(n+m)).

- Add FilterSensitiveData and FilterMinLength to ToolsConfig
- Implement SensitiveDataReplacer() with sync.Once caching in
  SecurityConfig
- Use reflection to collect all sensitive values (Model API keys,
  channel
  tokens, web tool API keys, skills tokens)
- Apply filtering in agent loop at 4 tool result locations
- Add comprehensive tests covering all token types
2026-03-23 20:55:41 +08:00
afjcjsbx 8ed171dbe6 resolved conflicts 2026-03-23 13:43:02 +01:00
afjcjsbx fddfd56b50 Merge branch 'main' into fix/binary-tool-output-handling
# Conflicts:
#	pkg/agent/loop.go
#	pkg/agent/loop_test.go
#	pkg/commands/builtin_test.go
#	pkg/tools/send_file_test.go
2026-03-23 13:16:23 +01:00
Mauro 054b55fdfc Merge pull request #1893 from afjcjsbx/feat/skill-channel-commands
feat(skills): add channel commands to list and force installed skills
2026-03-23 09:04:06 +01:00
Cytown 5a8aab8143 Merge branch 'main' into version 2026-03-23 11:41:36 +08:00
Cytown 7bf4831059 Merge branch 'main' into version 2026-03-23 10:54:08 +08:00
xiwuqi 336d5d4c07 fix(agent): route reasoning_content to reasoning channel 2026-03-22 19:57:47 -05:00
afjcjsbx 1e98f86fa9 fix Ooutboundmedia 2026-03-23 00:08:43 +01:00
afjcjsbx f735b0551c fix 2026-03-22 23:46:10 +01:00
afjcjsbx 388505d7e0 fix lint 2026-03-22 23:39:33 +01:00
afjcjsbx b90c5007f6 resolve conflicts 2026-03-22 23:36:25 +01:00
afjcjsbx 14a4983af3 Merge branch 'main' into fix/binary-tool-output-handling
# Conflicts:
#	pkg/agent/loop.go
#	pkg/tools/result.go
2026-03-22 23:08:27 +01:00
afjcjsbx be59133ce9 resolve conflicts 2026-03-22 20:58:46 +01:00
afjcjsbx d3ba40090b Merge branch 'main' into feat/skill-channel-commands
# Conflicts:
#	pkg/agent/loop.go
2026-03-22 20:51:16 +01:00
BeaconCat 60a7098fd3 feat(search): add Baidu Qianfan AI Search provider with i18n docs
- Add BaiduSearchConfig struct and register in WebToolsConfig/defaults
- Insert Baidu Search in priority chain: DuckDuckGo > Baidu > GLM Search
- Use perplexityTimeout (30s) — Qianfan is LLM-based
- Fix response parsing: use references[] field per API spec
- Add baidu_search block to config.example.json

docs: sync configuration.md and README Documentation table across all languages

- Complete truncated configuration.md for fr/ja/pt-br/vi/zh: add Spawn
  async flow diagram, Providers table, Model Configuration (all vendors,
  examples, load balancing, migration), Provider Architecture, Scheduled
  Tasks, and Advanced Topics links
- Add Hooks/Steering/SubTurn entries to Documentation table in all 8
  READMEs (en/zh/fr/id/it/ja/pt-br/vi), ordered before Troubleshooting
- Add Baidu Search row to web search table in all 8 READMEs and
  tools_configuration.md (en + 5 i18n); zh README reorders search
  engines with China-friendly options first
- Add Matrix channel docs translations (fr/ja/pt-br/vi)
- Add Weixin channel to chat-apps.md and all README Channels tables

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 00:51:27 +08:00
afjcjsbx d7d2bf69bf feat(skills): add channel commands to list and force installed skills 2026-03-22 15:33:25 +01:00
Administrator 7868c5811a fix(agent): fix subturn panic result, hard abort rollback, and drain bus exit
- spawnSubTurn: set result=nil on panic instead of constructing a non-nil ToolResult
- HardAbort: roll back session history to initialHistoryLength after Finish()
- drainBusToSteering: switch to non-blocking reads after first message so function
  returns promptly when the inbound channel is empty
- remove obsolete documentation files
2026-03-22 20:35:14 +08:00
Administrator 7ba8682ac5 Merge branch 'refactor/agent' into feat/subturn-poc 2026-03-22 19:51:43 +08:00
Administrator f7f27e237a merge: resolve conflicts between refactor/agent and main 2026-03-22 19:21:58 +08:00
afjcjsbx df4f322f09 fix(tool): route binary outputs through the media pipeline. 2026-03-22 12:05:28 +01:00
daming大铭 0432facffc Merge pull request #1863 from alexhoshina/feat/hook-manager
Feat/hook manager
2026-03-22 14:36:07 +08:00
Cytown 7c854fe6d7 Merge branch 'main' into version 2026-03-22 02:53:55 +08:00
Cytown e455eb5e67 refactor: seperate security.yml for store keys 2026-03-22 01:55:00 +08:00
Hoshina 337e43e5a5 feat(agent): add configurable hook mounting 2026-03-21 19:46:16 +08:00
Hoshina cf68c91eca feat(agent): add hook manager foundation 2026-03-21 19:15:10 +08:00
Administrator 670b433f1a refactor: replace interface{} with any for improved type clarity 2026-03-21 18:24:56 +08:00
Administrator 1bd144ac13 Merge branch 'upstream-main' into feat/subturn-poc 2026-03-21 17:13:26 +08:00
Mauro 100720bb74 Merge pull request #1818 from Alix-007/fix/issue-1815-empty-response-message
fix(agent): separate empty-response and tool-limit fallbacks
2026-03-20 23:23:48 +01:00
afjcjsbx 9e344594a2 fix logic 2026-03-20 21:07:07 +01:00
afjcjsbx 827449aff3 fix lint 2026-03-20 20:12:55 +01:00
afjcjsbx 1c6586681d fix(agent) scope steering 2026-03-20 19:44:00 +01:00
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
Hoshina 0e075f7300 feat(agent): centralize turn lifecycle and continue queued steering
Refactor agent loop execution around runTurn, add explicit turn state and interrupt semantics, and automatically continue queued steering that misses the current turn boundary.
2026-03-20 17:28:12 +08:00
Hoshina 57cde73b36 feat(agent): expand event bus coverage 2026-03-20 15:29:52 +08:00
Hoshina 50cc7100ce feat(agent): make event logs show event kind clearly 2026-03-20 15:06:43 +08:00
Hoshina af61d0bca7 feat(agent): add event bus foundation 2026-03-20 14:53:22 +08:00
Alix-007 82d574eb7b fix(agent): separate empty-response and tool-limit fallbacks 2026-03-20 14:37:47 +08:00
Administrator 4f646ef2b8 Merge branch 'main' into feat/subturn-poc 2026-03-20 11:51:25 +08:00
Mauro bd4317f1f4 Merge pull request #1390 from kiannidev/fix/1323-telegram-endless-typing
fix(telegram): stop typing indicator when LLM fails or hangs
2026-03-19 21:52:10 +01:00
Administrator c18d8a2ecc Merge branch 'upstream-main' into feat/subturn-poc 2026-03-19 22:12:51 +08:00