Commit Graph

1154 Commits

Author SHA1 Message Date
afjcjsbx 34b9d5d6fa fix(telegram): preserve raw OAuth links in HTML rendering 2026-04-12 10:44:09 +02:00
Guoguo 748ac58dd1 fix(chat): keep tool-call summary and assistant output in sync (#2449)
* fix(chat): keep tool summaries and assistant output together

* fix(pico): stream assistant text between tool calls

* fix(pico): avoid duplicate final websocket message

* fix(review): align tool feedback reconstruction with runtime behavior

* style(lint): satisfy gci and golines for review fixes

* fix(agent): gate pico interim publish for internal turns
2026-04-10 15:08:30 +08:00
winterfx 187189ad4a fix(seahorse): sanitize user input for FTS5 MATCH queries (#2436)
User input containing FTS5 operators (-, +, *, OR, NOT, :, quotes,
parentheses) could cause query errors or unexpected search results.
Wrap each token in double quotes to force literal matching while
preserving user-quoted phrases.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-10 11:59:50 +08:00
Mauro 491418775b fix(gateway): log startup errors before exit (#2414)
* fix(gateway): log startup errors before exit

* preserve deferred startup failure logging
2026-04-10 10:10:45 +08:00
Mauro dde61365d4 Merge pull request #2420 from lahuman/docs/tool-escape-semantics
docs(tool): use provider-agnostic JSON escaping guidance
2026-04-09 20:50:06 +02:00
lc6464 bd88385923 fix(agent): gate pico interim publish for internal turns 2026-04-10 00:19:45 +08:00
lc6464 58f634b582 style(lint): satisfy gci and golines for review fixes 2026-04-10 00:02:20 +08:00
lc6464 bd13092831 fix(review): align tool feedback reconstruction with runtime behavior 2026-04-09 23:52:02 +08:00
lc6464 9982ee29a8 fix(pico): avoid duplicate final websocket message 2026-04-09 22:59:36 +08:00
lc6464 2aeed8fb3a fix(pico): stream assistant text between tool calls 2026-04-09 22:32:35 +08:00
lc6464 5b596ed2f0 fix(chat): keep tool summaries and assistant output together 2026-04-09 22:16:36 +08:00
wenjie a9720daa45 fix(test): skip TestPrepareCommand_AppliesUserEnv on unsupported operating systems (#2434) 2026-04-09 10:14:08 +08:00
美電球 3e3b6aed90 fix(tools): message tool no longer suppresses reply to originating chat (#2180)
When the message tool sent to a different chat (e.g., a group), the
agent's final response to the originating chat was incorrectly skipped
because HasSentInRound() was a simple bool that didn't distinguish
targets. Replace with HasSentTo(channel, chatID) that tracks all
send targets per round and only suppresses when the target matches.

Fixes cross-conversation message causing "Processing..." to hang.
2026-04-08 21:40:12 +08:00
k 1dc25e7cf5 test(agent): remove unused respondWithMediaHook field 2026-04-08 19:44:07 +09:00
lxowalle 51eecde01e Feat/support isolation (#2423)
* * completed

* * optimzie

* * fix format

* * fix pr check

* try to fix ci

* * Indicates that Windows does not support expos_paths, adding more mount paths for the Linux platform.

* fix isolation startup lifecycle and MCP transport wrapping

* fix isolation startup cleanup and optional Linux mounts

* fix isolation path handling for relative hooks

Preserve relative command and working-directory semantics when Linux isolation wraps subprocesses, and restore absolute argv path exposure to avoid startup regressions. Add hook coverage and docs updates so isolation-enabled process hooks keep working as configured.

* * fix ci
2026-04-08 18:15:42 +08:00
ywj 8b3e502690 fix(feishu): enrich reply context for card and file replies (#2144)
* fix(feishu): enrich reply context for card and file replies

* refactor(feishu): extract reply functions to feishu_reply.go

- Move reply-related functions to new feishu_reply.go
- Move corresponding tests to feishu_reply_test.go
- Extract magic number 600 to maxReplyContextLen constant
- Unify replyTargetID/replyTargetFromMessage (prefer parent_id, fallback root_id)
- Add source comment for containsFeishuUpgradePlaceholder

* fix(feishu): skip API fallback for non-thread messages, prepend replied media refs

- resolveReplyTargetMessageID: only call fetchMessageByID fallback when
  ThreadId is set, avoiding unnecessary API calls for non-reply messages
- prependReplyContext: prepend replied media refs before current media refs
  to maintain correct ordering

* fix(feishu): add message cache for fetchMessageByID to avoid repeated downloads

- Add messageCache (sync.Map) to FeishuChannel struct
- Cache fetched messages with 30s TTL to avoid re-downloading attachments
  when multiple users reply to the same parent message in a thread
- Cleanup expired entries on read access (no background goroutine needed)

* fix(feishu): early-return for non-reply messages, add cache and fetchMessageByID comment

* fix: remove duplicate test and fix gci import order

* fix(feishu): remove duplicate prependReplyContext call
2026-04-08 14:26:17 +08:00
wenjie 7d16764674 fix(gateway): validate PID ownership and clean stale pid files (#2422)
* fix(gateway): validate PID ownership and clean stale pid files

- include `pid` in health responses for runtime PID verification
- add `RemovePidFileIfPID` to safely delete PID files only on PID match
- sanitize gateway PID data via process-command checks with health fallback
- ignore and remove stale/non-gateway PID files before gateway operations
- refuse stop/restart actions when the attached process is not a gateway
- update gateway and websocket tests to cover PID validation and safety paths

* test(seahorse): use shared in-memory SQLite DB in tests to fix async compaction failures

* test: remove unused sendMediaErr field from hook test mock
2026-04-08 14:23:21 +08:00
k 8f7eae8b37 docs(tool): use provider-agnostic JSON escaping guidance 2026-04-08 14:19:11 +09:00
Harmoon ee29aaa871 Enhance hooks with respond action and comprehensive documentation (#2215)
* feat(hooks): add respond action for tool execution bypass

Add a new HookActionRespond that allows hooks to return tool results directly, skipping actual tool execution. This enables plugin tool injection, caching, and mocking capabilities.

- Add HookActionRespond constant and support in HookManager
- Extend ToolCallHookRequest with HookResult field
- Implement respond action handling in process hooks and agent loop
- Add comprehensive tests for respond and deny_tool actions
- Update documentation with hook actions table and examples

* docs(hooks): add JSON-RPC protocol and plugin tool injection documentation

Add comprehensive documentation for hook JSON-RPC protocol and plugin tool injection capabilities:

- Add "Hook Actions" section to README.zh.md explaining respond action for tool execution bypass
- Create hook-json-protocol.md/.zh.md detailing JSON-RPC 2.0 protocol for all hook methods
- Create plugin-tool-injection.md/.zh.md with complete examples for external tool implementation
- Document how hooks can inject tool definitions and return results via respond action
- Include Python and Go examples for weather query plugin implementation

* feat(agent): emit tool events and feedback for hook results

Add ToolExecStart event emission and tool feedback for hook results to ensure consistent behavior between normal tool execution and hook bypass scenarios. This maintains parity in event tracking and user feedback when tools are executed via hooks.

* style(agent): format whitespace in hook structs and constants

Remove trailing whitespace and standardize spacing in JSON struct tags, constants, and test data for improved code consistency.

* feat(hooks): add media support for plugin tool injection

Extend the hook respond action to support media file handling:
- Add `media` field for returning images and files from hooks
- Add `response_handled` field to control turn completion behavior
- When response_handled=true, media is automatically delivered to user
- When response_handled=false, media is passed to LLM for vision requests

This enables plugins to directly return generated images, downloaded
files, and other media content either to users or for LLM analysis.

* docs(hooks): document security implications of respond action

Add security boundary documentation explaining that the respond action
bypasses ApproveTool checks, allowing hooks to return results for any
tool without approval. Include recommendations for secure hook
implementation and code comments marking the security considerations.

Changes:
- Add "Security Boundaries" section to plugin-tool-injection docs
- Document bypass of approval checks and associated risks
- Provide security recommendations and example code
- Add inline security comments in hooks.go and loop.go

* refactor(agent): improve completeness of tool result cloning and hook processing

Extend cloneToolResult to properly copy ArtifactTags and Messages fields,
ensuring deep copies of all ToolResult data. Consolidate event emission
and user message handling to match the normal tool execution flow.

* fix(agent): align hook respond path with normal tool execution flow

The hook respond code path was missing several critical behaviors that
existed in normal tool execution:

- Add logging for tool calls with arguments preview
- Add is_tool_call metadata to user-facing messages
- Handle attachment delivery failures by setting error state and
  notifying LLM
- Set ResponseHandled=false when using bus for media delivery
- Check for steering messages and graceful interrupts after tool
  execution, skipping remaining tools when appropriate
- Poll for SubTurn results that arrived during tool execution

This ensures consistent behavior between hook-responded tool calls and
normally executed tool calls.

* test(agent): add tests for hook respond media error handling

Add comprehensive tests for the hook respond code path when media
delivery fails. Tests cover error media channel scenarios and verify
proper error state handling.

Also document that AfterTool is not called when using respond action,
as it provides the final answer directly (design decision).
2026-04-08 11:47:02 +08:00
wenjie 330de0c382 fix(agent): disable seahorse context manager on freebsd/arm (#2417)
* fix(agent): disable seahorse context manager on freebsd/arm

Exclude freebsd/arm from the seahorse-enabled build and route it to the
unsupported stub implementation.

This avoids freebsd/arm build failures caused by modernc sqlite/libc while
keeping picoclaw buildable on that target.

* build: bump Go version from 1.25.8 to 1.25.9

* ci: install and run govulncheck directly in PR workflow
2026-04-08 10:57:22 +08:00
corevibe555 6ce0306c66 fix: use per candidate provider for model_fallbacks (#2143)
* fix: use per-candidate provider for model_fallbacks

Each fallback model now uses its own api_base and api_key from
model_list instead of inheriting the primary model's provider config.

Previously, a single LLMProvider was created from the primary model's
ModelConfig and reused for all fallback candidates — only the model ID
string was swapped. This caused all fallback requests to be routed to
the primary provider's endpoint, making cross-provider fallback chains
non-functional (e.g., OpenRouter primary with Gemini fallback would
send the Gemini request to OpenRouter's API).

Fix: pre-create a per-candidate LLMProvider at agent initialization
time by looking up each candidate's ModelConfig from model_list. The
fallback run closure now selects the correct provider per candidate
via CandidateProviders map, falling back to agent.Provider when no
override is found.

Fixes #2140

Made-with: Cursor

test: add test for instance.go

fix: fix test

refactor: optimize

fix: fix Golang lint issues

chore: comment cleanup

* refactor: use resolvedModelConfig() instead of buildModelIndex()

* fix
2026-04-07 20:07:56 +08:00
Andy Lo-A-Foe 1fc2710999 feat(channels): add teams_webhook output-only channel (#2244)
Add Microsoft Teams webhook integration via Power Automate workflows.

Features:
- Output-only channel for sending notifications to Teams
- Multiple webhook targets with named configuration
- Required "default" target with automatic fallback
- Rich Adaptive Card formatting with full-width rendering
- Markdown table conversion to native Adaptive Card Tables
- Column widths based on header content length
- HTTPS-only webhook URL validation
- Proper error classification for retry behavior

Configuration:
- channels.teams_webhook.enabled: bool
- channels.teams_webhook.webhooks: map of named targets
  - Each target has webhook_url (SecureString) and optional title

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-07 19:24:27 +08:00
wenjie 7bf6cbe1fa fix(gateway): harden PID liveness handling and websocket proxy state (#2403)
- treat `EPERM` from `signal(0)` as “process exists” on Unix
- classify malformed PID files as invalid and auto-remove them during read
- keep cached `pidData` only for transient races and downgrade `running` to `stopped` when the tracked process is gone
- refresh PID data on WebSocket proxy requests and reject stale cached gateway state
- add regression tests for invalid PID files, status downgrade, on-demand PID loading, and stale proxy rejection
2026-04-07 16:34:42 +08:00
LC 38a498e202 feat(provider): support custom headers injection for HTTP providers (#2402)
* feat(provider): support custom headers injection for HTTP providers

* fix(provider): resolve lint problem

* fix(provider): align stream user-agent and header precedence docs
2026-04-07 16:05:21 +08:00
eturn 778f939302 fix [BUG] WebUI cannot connect to the gateway started by WebUI (#2267)
#2213
2026-04-07 15:46:45 +08:00
Liu Yuan f0e6b7aa37 fix(seahorse): correct bm25 rank semantics in comments (#2360)
SQLite FTS5 bm25() returns negative values where numerically smaller
(more negative) indicates a better match. The official docs state:

  "The better the match, the numerically smaller the value returned."

Two comments incorrectly stated "closer to 0 = better match" and
"lower = better match". Updated all rank descriptions to use the
unambiguous "more negative = higher relevance" phrasing.

This matters because these comments are used as tool prompt hints
for LLM agents, and incorrect semantics could lead to wrong ranking
decisions.
2026-04-07 12:32:28 +08:00
wenjie 661ce5e311 fix(build): gate seahorse context manager on unsupported platforms (#2384)
- add build tags to exclude context_seahorse.go on mipsle and netbsd
- add context_seahorse_unsupported.go to keep registration and return a clear runtime error
- remove unused indirect dependency github.com/reiver/go-porterstemmer from go.mod and go.sum
2026-04-07 11:49:35 +08:00
Liu Yuan 15a70ac45c feat(seahorse): implement short-term memory engine (LCM) (#2285)
* feat(seahorse): implement short-term memory engine of seahorse

Add pkg/seahorse/ module implementing a SQLite-backed DAG-based summary
hierarchy for context management, ported from lossless-claw's LCM design:

- types.go + short_constants.go: core types (Message, Summary, Conversation,
  ContextItem) and configuration constants (fanout, token targets, thresholds)
- migration.go: idempotent DB schema with FTS5 trigram tokenizer for CJK
- store.go: full SQLite CRUD (conversations, messages, summaries DAG,
  context_items with ordinal gap numbering, FTS5 search)
- short_engine.go: Engine lifecycle (NewEngine, Ingest, Assemble, Compact),
  session pattern filtering (ignore/stateless glob→regex compilation),
  per-session mutex via sync.Map
- short_assembler.go: budget-aware context assembly with fresh tail protection
  (32 messages), oldest-first eviction, summary XML formatting, RebuildContextItems
- short_compaction.go: leaf compaction (messages→summary) and condensed
  compaction (summaries→higher-level summary), 3-level LLM escalation,
  CompactUntilUnder for emergency overflow
- short_retrieval.go: lookupByID, FTS5/LIKE search, recursive expand with
  token cap
- context_seahorse.go: agent.ContextManager adapter, registered as "seahorse",
  provider↔seahorse message type conversion (ToolCalls, tool_result)

* fix(seahorse): correct 3 adapter bugs in context management

- TokenCount: use full message (Content+ToolCalls+Media) instead of Content-only
- Empty Content: rebuild Content from tool_result Parts when stored empty
- Duplicate summaries: summaries only in Summary field, not in History messages
- Grep: fix SearchResult.Snippet→Content for summaries
- Schema: fix FTS5 SQL uses VIRTUAL TABLE not TEMP TABLE
- TestFTS5SQLConstants: verify FTS5 SQL syntax correctness
- Test: fix flaky TestCompactLeaf

* fix(agent): ingest steering messages into seahorse SQLite

Steering messages were only persisted to session JSONL but not ingested
into seahorse SQLite, causing them to be missing from context assembly.

Added `ts.ingestMessage(turnCtx, al, pm)` call in the steering message
injection block alongside the existing JSONL persistence.

Test: TestSeahorseSteeringMessageIngested verifies steering messages
appear in seahorse SQLite DB after being processed.

* fix(seahorse): address 3 blocking bugs from code review

- Fix resequenceContextItemsTx scan error handling (store.go:850)
  Changed `return err` to `return scanErr` to properly propagate scan errors
  instead of returning nil (which silently corrupts data)

- Fix sql.NullString for INTEGER column (store.go:847)
  Changed `mid` from sql.NullString to sql.NullInt64 since message_id
  is INTEGER in schema. Removed unnecessary strconv.ParseInt call.

- Fix compactCondensed fallback deleting non-candidate items
  Added ReplaceContextItemsWithSummary method for per-item deletion
  when candidates are not contiguous in ordinal space.
  Optimized to use range deletion when candidates are consecutive.

* fix(seahorse): pass Budget to Compact for correct condensed threshold

Issue #4 from PR review: When Budget was not passed to seahorse.Compact,
it defaulted to `tokensBefore * 0.75`, making `tokensBefore > budget`
always true and causing condensed compaction to trigger unnecessarily.

Changes:
- context_seahorse.go: Forward Budget from CompactRequest to CompactInput
- loop.go: Pass Budget (ContextWindow) in all 3 Compact calls
- Add test verifying condensed is skipped when tokens < threshold
- Fix lint issues in store.go and store_test.go

* fix(seahorse): add mutex for assembler lazy initialization

Issue #5 from PR review: The check-then-create pattern for e.assembler
was a data race when multiple goroutines called Assemble() concurrently:
    if e.assembler == nil {
        e.assembler = &Assembler{...}
    }

Changes:
- Add assemblerMu sync.Mutex to Engine struct
- Add initAssemblerOnce() using double-checked locking (same pattern as initCompactionOnce)
- Add TestAssemblerLazyInitRace to verify thread-safety

* fix(seahorse): handle non-consecutive depths in selectShallowestCondensationCandidate

Issue #8 from PR review: the loop iterated depth 0, 1, 2... assuming
consecutive keys, but break when key was missing caused deeper depths
to never be checked.

Fix: collect all existing depth keys, sort, then iterate in order.

* fix(seahorse): wrap DeleteMessagesAfterID and appendContextItems in transactions

- DeleteMessagesAfterID: wrap all DELETE operations in a transaction for
  atomicity, remove redundant manual FTS delete (handled by trigger)
- appendContextItems: use transaction to fix read-then-write race condition
- Add GetMaxOrdinalTx and resolveItemTokenCountTx for transaction-scoped queries
- Remove unused resolveItemTokenCount function

Fixes PR review issues 6 and 7.

* fix(seahorse): derive readable content from Parts and cap CompactUntilUnder iterations

- Derive readable content from MessageParts in AddMessageWithParts so
  FTS5 indexing and summary formatting can access tool call information
- formatMessagesForSummary and truncateSummary now fall back to Parts
  when Content is empty, fixing blank summaries for Part-based messages
- Add MaxCompactIterations (20) to prevent CompactUntilUnder infinite
  loops; exceeded iterations are logged as warnings
2026-04-05 09:05:16 +08:00
LC 71337b6f52 fix(tool): clarify write_file nested-JSON escape semantics and add tests (#2320)
* fix(tool): clarify write_file nested-JSON escape semantics and add tests

* fix(tool): improve formatting of escaping rules in CLI tool prompt

* fix(tool): align escape notation with function.arguments layer
2026-04-04 17:56:49 +08:00
Mauro d8c5183d9a feat(mcp): store oversized text results as artifacts (#2308)
* feat(mcp): store oversized text results as artifacts

* feat(mcp): fix doc

* fix(mcp): preserve raw MCP payload in text artifacts

* fix(mcp): avoid leaking large text when artifact persistence fails

* chore(mcp): clarify inline text limit and cover artifact edge cases
2026-04-04 01:30:36 +08:00
wenjie f2a19ab947 feat(web): support image messages in pico chat (#2299) 2026-04-03 14:15:20 +08:00
linhaolin1 b5ce6209fd feat: add VK channel support (#2276)
* feat: add VK channel support

- Add VK channel implementation using vksdk
- Support text messages and media attachments
- Implement Long Poll API for real-time messaging
- Add group chat support with trigger prefixes
- Add user whitelist (allow_from) configuration
- Add VK channel documentation

Files:
- pkg/channels/vk/: VK channel implementation
- pkg/config/config.go: Add VKConfig structure
- pkg/channels/manager.go: Register VK channel
- pkg/gateway/gateway.go: Import VK channel package
- docs/channels/vk/: Usage documentation

* test: add unit tests for VK channel

- Test channel initialization with various configurations
- Test allow_from whitelist functionality
- Test group trigger configuration
- Test max message length (4000 chars)
- Test message splitting logic
- Test attachment processing

All tests passing ✓

* fix: resolve linting issues in VK channel

- Format VKConfig struct tags to comply with golines
- Remove unused mu sync.Mutex field
- Remove unused stripPrefix method

All tests passing ✓

* style: format VKConfig with golines

- Align struct tags to match project style
- Match formatting with other channel configs (Telegram, etc.)
- Fix golines linting error

* style: fix struct tag formatting in config.go

* docs: update VK channel docs to use secure token storage

* feat(vk): add voice capabilities support

- Implement VoiceCapabilities() method for VK channel
- Add audio_message attachment handling in processAttachments
- Add comprehensive tests for voice capabilities
- Support both ASR (speech-to-text) and TTS (text-to-speech)

* docs: add VK channel to documentation and update voice support

- Add VK channel to README.md and README.zh.md channel lists
- Update VK channel documentation with voice message support
- Document ASR and TTS capabilities for VK channel
- Add voice transcription configuration reference
2026-04-03 10:56:26 +08:00
Mauro b114dcaeb1 feat(model): llm rate limiting (#2198)
* feat(model): rate limiting

* fix(agent): preserve per-model identity in rate limiting and fallback

* fix test
2026-04-02 19:26:26 +08:00
wenjie dad5dcc30f refactor(web): load channel configs without exposing secret values (#2277)
* refactor(web): load channel configs without exposing secret values

- add a dedicated channel config API that returns sanitized config plus
  configured secret metadata
- update channel config pages and forms to use secret presence for
  placeholders, validation, reset, and save behavior
- refresh the channel settings layout and clean up related i18n copy
- add backend tests for the new channel config endpoint

* fix(config): restore missing strings import
2026-04-02 19:09:33 +08:00
Mauro bae4342af1 Feat/tool read_file by lines (#1981)
* feat(tool): read_file tool by lines

* fix test

* restore old bytes read_file tool

* unified read_file tool

* revert

* fix doc

* fix test

* fix doc

* fix offset

* fix default start_line

* fix line format

* fix bug

* removed legacy test

* enhanced infos

* improvements

* feat(tool): read_file tool by lines
2026-04-02 18:49:08 +08:00
SakoroYou 257aa0ff57 fix(channels): fail fast when all channel startups fail (#2262)
* fix(channels): fail fast when all channel startups fail

* fix(channels): preserve startup errors and cover fail-fast semantics
2026-04-02 14:14:47 +08:00
Cytown 2c446e1e07 feat: add userAgent config for ModelConfig (#2242)
* feat: add userAgent config for ModelConfig

* update docs for ModelConfig.userAgent

* make defaut userAgent to PicoClaw and add test case
2026-04-02 11:44:13 +08:00
Badgerbees 33ce6ed482 resolve conflicts 2026-04-02 04:33:08 +07:00
Liu Yuan 7eba27c3c4 feat: add ContextManager abstraction for pluggable context management (#2203)
- Define ContextManager interface with Assemble/Compact/Ingest methods
- Implement legacyContextManager wrapping existing summarization logic
- Wire Assemble (before BuildMessages), Compact (post-turn + overflow),
  and Ingest (after message persistence) into agent loop
- Add ContextManager config field and factory registry with config passthrough
- Remove old maybeSummarize/summarizeSession/summarizeBatch/etc from loop.go
- All existing tests pass with default (legacy) config

Co-authored-by: Liu Yuan <namei.unix@gmail.com>
2026-04-02 00:08:15 +08:00
LC bbcfeaa361 feat(provider): add Venice AI support and update related documentation (#2238)
* feat(provider): add Venice AI support and update related documentation

* revert(asr): restore asr files to previous commit

* feat(config): add Venice API base URL and local LM Studio configuration

* fix(config): update Venice API base URL to correct endpoint
2026-04-01 23:50:29 +08:00
Cytown 9ac21c5908 add missing recover panic in subturn.go (#2253) 2026-04-01 23:44:41 +08:00
sky5454 49e61fa07f feat(updater): robust self-update selection & extraction (nightly default) (#2201)
* feat(updater): add web self-update endpoint and updater package

* feat(selfupgrade): when url empty, using GetTestReleaseAPIURL for test .

* feat(selfupgrade):  only GetTestReleaseAPIURL  .

* feat(upgrade): cli  $0 update work well!

* fix(ci): fix ci err

* fix(test): fix ci test

* fix(ci): fix ci  lint fmt err

* test(updater): add test for updater

* fix(ci): fix ci  lint var copy err

* fix(ci): retry ci

* updater: require checksum verification, prefer API digest, verify SHA256, fix zip extraction, update tests

* fix(lint): lint fixed

* fix(lint): lint fixed2

* updater: stream download and verify sha256; add http client timeout and progress

Avoid double-download by streaming asset into temp file while computing SHA256 and verifying against checksum; replace http.Get with shared httpClient (2m timeout) to prevent hangs; add simple stderr progress display; remove unused helpers.
2026-04-01 23:41:32 +08:00
Cytown e2a9bb97c7 unify all panic event to panic log file (#2250) 2026-04-01 23:26:49 +08:00
reusu 31afad6e87 feat: add load_image tool for local file vision (#2116)
* feat: add load_image tool for local file vision

* 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

* feat: enable load_image for subagents via MediaResolver in RunToolLoop

Instead of removing load_image from sub-agent tools (28f69e71), inject a
MediaResolver into the legacy RunToolLoop fallback path so media:// refs
are resolved to base64 before each LLM call — matching the main agent
loop behavior.

- Add MediaResolver field to ToolLoopConfig and call it on iteration > 1
- Add SubagentManager.SetMediaResolver() and wire it through runTask
- Remove ToolRegistry.Unregister() (no longer needed)
- Restore load_image in sub-agent tool set (revert Clone+Unregister)
- Add TestSubagentManager_SetMediaResolver_StoresResolver

* refactor(load_image): remove prompt parameter from tool schema

* test(tools): add success-path test for LoadImageTool

Add TestLoadImage_SuccessPath that creates a real PNG file with valid
magic bytes, calls Execute with WithToolContext, and verifies:
- result.IsError == false
- ToolResult.Media contains a media:// ref
- ToolResult.ForLLM contains the [image: marker
- media ref is resolvable in the store

Add explanatory comment in loop.go for why Media and ArtifactTags
coexist on non-ResponseHandled tool results (e.g. load_image).

* fix: preallocate slice in tests and add ResponseHandled guard in toolloop

Fix prealloc linter failure in load_image_test.go.

Prevent double-resolving media by checking ResponseHandled in toolloop.go.

* Register TTS tool if provider is available

---------

Co-authored-by: Reusu <admin@yumao.name>
Co-authored-by: 美電球 <hoshina@evaz.org>
2026-04-01 21:32:10 +08:00
Cytown a9c76eca21 bug: fix picoToken is empty when gateway started by launcher (#2241) 2026-04-01 14:59:18 +08:00
Hua Audio 0f395ce110 Refactor/asr tts (#1939)
* refactor: update ASR and TTS implementations

* fix lint

* Integrating asr/tts models w/ new security config

* update documents

* add arbitrary whisper transcriptor support

* update documents

* fix lint

* add mimo tts
2026-04-01 12:21:21 +08:00
Badgerbees b90a6d12ea fix(telegram): refine duplicate-message protection with narrow error classification
Addresses reviewer concerns regarding silent message loss by narrowing the
error swallowing logic in EditMessage:
- Excludes context.DeadlineExceeded and context.Canceled from being swallowed,
  ensuring local timeouts before transmission still trigger a fallback send.
- Adds an explicit check for the 'message is not modified' error to safely
  identify edits that have already landed on Telegram's servers.
- Narrowly targets confirmed post-connect dropouts (e.g., connection reset)
  instead of broad network-ish string matching.
- Fixes the missing isPostConnectError definition and required errors import.
2026-04-01 03:13:34 +07:00
wenjie 2bf842e460 feat(web): add service log level controls (#2227)
- centralize gateway log level resolution and normalization
- propagate debug flags to spawned launcher and gateway processes
- add a log level selector to the logs page
- cover the new behavior with backend and config tests
2026-03-31 20:32:42 +08:00
Badgerbees 1a44752dc5 fix(agent): prevent double-counting system message tokens in estimator
Treat SystemParts as an alternative representation of message Content
rather than an additive one. This prevents systematic overestimation
of system message tokens which could trigger premature context
pruning or summarization.
- Picks the maximum of Content vs. SystemParts to stay conservative.
- Adds a per-part overhead (20 chars) to account for JSON metadata.
- Streamlines the ReasoningContent counting logic.
Fixes a deficiency where structured blocks for cache-aware adapters
caused overestimated budgets or hidden overflows.
2026-03-31 17:09:01 +07:00
Badgerbees 93f391a6bf fix(agent): include SystemParts in token estimation and add reasoning guards 2026-03-31 16:33:24 +07:00