Commit Graph
82 Commits
Author SHA1 Message Date
therichardngai-code ad82c09720 fix(bootstrap): SeedUserFiles should use agent-level USER.md as seed for predefined agents (#30)
* fix: SeedUserFiles uses agent-level USER.md as seed for predefined agents

For predefined agents, the wizard writes a populated USER.md (owner
name, language, notes) via agents.files.set into agent_context_files
(agent-level). On the first chat message, SeedUserFiles was seeding a
blank embedded template into user_context_files (per-user level).

LoadContextFiles for predefined agents lets per-user content override
agent-level content, so the blank per-user USER.md shadowed the
wizard-written content. The owner profile was stored in the DB but
never served to the agent, triggering unnecessary onboarding.

Fix: before falling back to the embedded template, check whether
agent_context_files already has a non-empty USER.md for the agent.
If it does, use that content as the per-user seed. The check is
conditional (predefined agent + USER.md not yet seeded per-user) so
it adds at most one extra DB read per new user.

The existing "don't overwrite" guard (hasFile check) is unchanged —
personalized per-user content written through conversation is still
never overwritten.

* test: add unit tests for SeedUserFiles agent-level USER.md seeding

Covers:
- Predefined agent: wizard-written USER.md at agent level is used as
  per-user seed (primary regression test for the bug fix)
- Predefined agent: falls back to blank embedded template when no
  agent-level USER.md exists
- Predefined agent: existing per-user content is never overwritten
- Open agent: embedded template path is unaffected
- Predefined agent: BOOTSTRAP.md uses BOOTSTRAP_PREDEFINED.md template
- Idempotency: second SeedUserFiles call seeds nothing

* fix(bootstrap): SeedUserFiles uses agent-level USER.md as seed for predefined agents

Use map[string]string for agent-level files (more general, extensible)
and clean continue-based loop flow, matching the investigation spec
in plans/goclaw-pr/goclaw-pr-seed-user-files.md exactly.

Previous implementation used a single string and if/else structure —
functionally correct but diverged from the spec in variable type,
load condition, and loop exit pattern.
2026-03-01 21:23:38 +07:00
therichardngai-code 3cbdd8d778 fix(agents): predefined agents visible in web UI for channel members (#34)
* fix: SeedUserFiles uses agent-level USER.md as seed for predefined agents

For predefined agents, the wizard writes a populated USER.md (owner
name, language, notes) via agents.files.set into agent_context_files
(agent-level). On the first chat message, SeedUserFiles was seeding a
blank embedded template into user_context_files (per-user level).

LoadContextFiles for predefined agents lets per-user content override
agent-level content, so the blank per-user USER.md shadowed the
wizard-written content. The owner profile was stored in the DB but
never served to the agent, triggering unnecessary onboarding.

Fix: before falling back to the embedded template, check whether
agent_context_files already has a non-empty USER.md for the agent.
If it does, use that content as the per-user seed. The check is
conditional (predefined agent + USER.md not yet seeded per-user) so
it adds at most one extra DB read per new user.

The existing "don't overwrite" guard (hasFile check) is unchanged —
personalized per-user content written through conversation is still
never overwritten.

* test: add unit tests for SeedUserFiles agent-level USER.md seeding

Covers:
- Predefined agent: wizard-written USER.md at agent level is used as
  per-user seed (primary regression test for the bug fix)
- Predefined agent: falls back to blank embedded template when no
  agent-level USER.md exists
- Predefined agent: existing per-user content is never overwritten
- Open agent: embedded template path is unaffected
- Predefined agent: BOOTSTRAP.md uses BOOTSTRAP_PREDEFINED.md template
- Idempotency: second SeedUserFiles call seeds nothing

* fix(bootstrap): SeedUserFiles uses agent-level USER.md as seed for predefined agents

Use map[string]string for agent-level files (more general, extensible)
and clean continue-based loop flow, matching the investigation spec
in plans/goclaw-pr/goclaw-pr-seed-user-files.md exactly.

Previous implementation used a single string and if/else structure —
functionally correct but diverged from the spec in variable type,
load condition, and loop exit pattern.

* fix(agents): predefined agents visible in web UI for channel members

Two bugs combined to make wizard-installed predefined agents invisible
in the web UI for all real users.

Bug 1 — agents.create WS hardcoded owner_id = "system":
- Add `owner_ids []string` to WS params struct (omitempty, backward compat)
- Resolve ownerID: use first entry if provided, fall back to "system"
- Allows external provisioning tools to set a real user as owner

Bug 2 — ListAccessible SQL excluded system-owned predefined agents:
- Extend WHERE clause with 4th OR: predefined agents are visible when
  the requesting user appears in any enabled channel's allow_from list
- Uses EXISTS + jsonb_array_elements_text(ci.config->'allow_from')
- No schema migration needed — allow_from already populated by wizard

Also adds 4 unit tests for Bug 1 (agents_create_owner_test.go):
- UsesProvidedOwnerID, FallsBackToSystem_WhenAbsent,
  FallsBackToSystem_WhenEmpty, MultipleOwnerIDs_UsesFirst
2026-03-01 21:17:32 +07:00
419935b9f9 fix: validate provider API keys during bootstrap using auth-required endpoints (#22)
* fix(channels): start outbound dispatcher before channel check

StartAll() returned early when no channels existed at boot,
skipping the dispatchOutbound goroutine. Channels loaded later
via Reload() assumed the dispatcher was running, causing outbound
messages (agent responses) to never reach Telegram.

Move dispatcher startup before the empty-channel early return so
dynamically loaded channels always have a running consumer.

* feat(ui): add LLM provider warning on overview page and ignore plans dir

Show alert when no providers configured or all disabled, linking to provider settings. Add plans/ to .gitignore.

* feat(onboard): add provider connectivity verification and placeholder seeding

- Add onboard_verify.go: verify API keys via POST to chat/completions
  endpoint (401/403 = fatal, 400/422 = key valid, 5xx = warn)
- Verify all configured providers before seeding in auto-onboard
- Seed disabled placeholder providers (OpenRouter, Synthetic, AliCloud
  API/Sub) for UI discoverability after managed data seeding

* refactor: reuse provider layer for bootstrap key verification

- Replace raw HTTP requests with provider.Chat() calls, matching the
  existing verify pattern in internal/http/provider_verify.go
- Respect config base URL overrides (GOCLAW_ANTHROPIC_BASE_URL, etc.)
- Only block bootstrap if the primary provider key is invalid;
  secondary provider failures are logged as warnings
- Add friendlyProviderError for human-readable error extraction

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

---------

Co-authored-by: ntduc <ntduc@cpp.ai.vn>
Co-authored-by: viettranx <viettranx@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 15:36:13 +07:00
51f8b895a3 feat: Publish pre-built Docker images to GHCR (#23)
* feat: add GitHub Actions workflow to publish Docker images to GHCR

Build and push all 4 variants (latest, otel, tsnet, full) on version
tags with multi-platform support (linux/amd64, linux/arm64).

Closes #19

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

* feat: add web UI image build to GHCR publish workflow

Adds a separate job to build and push the ui/web Dockerfile as
ghcr.io/<repo>-web with the same multi-platform and tagging strategy.

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

---------

Co-authored-by: Bruno Clermont <bruno.clermont@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 15:06:53 +07:00
Duc Nguyenandntduc 1afe721542 feat(ui): add LLM provider warning and fix outbound dispatcher startup (#20)
* fix(channels): start outbound dispatcher before channel check

StartAll() returned early when no channels existed at boot,
skipping the dispatchOutbound goroutine. Channels loaded later
via Reload() assumed the dispatcher was running, causing outbound
messages (agent responses) to never reach Telegram.

Move dispatcher startup before the empty-channel early return so
dynamically loaded channels always have a running consumer.

* feat(ui): add LLM provider warning on overview page and ignore plans dir

Show alert when no providers configured or all disabled, linking to provider settings. Add plans/ to .gitignore.

---------

Co-authored-by: ntduc <ntduc@cpp.ai.vn>
2026-03-01 15:05:02 +07:00
Thieu Nguyen b07159894d fix(mcp): use json.RawMessage for JSONB fields to prevent base64 serialization (#25)
[]byte fields were base64-encoded during JSON serialization, causing
frontend TypeError when calling .join() on non-array values. Added
Array.isArray() guards in UI as defensive fallback.
2026-03-01 15:03:57 +07:00
Duc Nguyenandntduc 27f73cde6a Fix/model name display (#26)
* fix(channels): start outbound dispatcher before channel check

StartAll() returned early when no channels existed at boot,
skipping the dispatchOutbound goroutine. Channels loaded later
via Reload() assumed the dispatcher was running, causing outbound
messages (agent responses) to never reach Telegram.

Move dispatcher startup before the empty-channel early return so
dynamically loaded channels always have a running consumer.

* feat(ui): add LLM provider warning on overview page and ignore plans dir

Show alert when no providers configured or all disabled, linking to provider settings. Add plans/ to .gitignore.

* fix: use model ID as display name in OpenAI-compatible provider list

The `owned_by` field (e.g. "system") was incorrectly used as the model
display name, causing all models to show as "system" in the UI dropdown
for providers like AliCloud DashScope.

---------

Co-authored-by: ntduc <ntduc@cpp.ai.vn>
2026-03-01 14:38:28 +07:00
viettranxandClaude Opus 4.6 0e75c21e55 feat: overhaul team delegation, Telegram resilience, and artifact forwarding
Team delegation:
- Unify spawn/subagent/delegate into single spawn tool
- Sibling-aware announce suppression with artifact accumulation
- Fix auto-complete race (isLastDelegation guard)
- Add team tasks list limit (20) with search guidance
- Multi-round orchestration patterns in TEAM.md
- Communication guidance for initial vs follow-up delegations

Telegram resilience:
- Add retrySend wrapper (3 attempts, escalating delay) for network errors
- Fix HTML fallback: strip tags + unescape entities instead of showing raw HTML
- Pre-process HTML tags in LLM output to markdown before conversion pipeline
- Skip caption truncation entirely when > 1024 bytes, send text separately
- Auto-send large images (>5MB) as documents to avoid compression

Artifact forwarding:
- Fix missing ContentType on forwarded media (mimeFromExt for result.Media/ForwardMedia)
- Add deliver parameter to write_file for file attachment delivery
- Extend mimeFromExt with document MIME types

UI: fix regenerate dialog overflow, improve task list layout, delegation detail view

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 14:34:36 +07:00
viettranx 7613e07e4f docs: expand Docker Compose upgrade instructions to detail both simple and explicit upgrade paths. 2026-02-28 23:39:52 +07:00
viettranx 857262c641 feat: Add copy-to-clipboard functionality for trace IDs and refine task list layouts. 2026-02-28 23:37:13 +07:00
viettranxandClaude Opus 4.6 56827aee11 feat: add team member management (add/remove) and fix UI issues
- Add teams.members.add and teams.members.remove RPC methods with
  bidirectional link management and cache invalidation
- Add DeleteTeamLinksForAgent to AgentLinkStore for link cleanup
- Add member add/remove UI in team detail Members tab
- Widen agent create dialog (sm:max-w-4xl) to fix cramped layout
- Fix combobox dropdown truncation (min-w-full instead of w-full)
- Fix traces refresh button animation using isFetching instead of isLoading

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 23:23:48 +07:00
viettranx 2623c65321 fix: Improve text wrapping in trace and span previews by changing break-words to break-all. 2026-02-28 19:01:47 +07:00
viettranx 26067d2432 feat: enhance agent tool loop detection sensitivity, add Markdown to HTML conversion for Telegram media captions, and refine trace detail dialog UI styling. 2026-02-28 18:58:55 +07:00
viettranx 45ea0ee9a4 feat: Add native Gemini image generation support and refine media path stripping in agent output. 2026-02-28 18:44:51 +07:00
viettranxandClaude Opus 4.6 50a90aa8c6 refactor: split large Go files (>350 lines) into smaller same-package files
Pure file reorganization — no logic changes, no renames, no refactoring.
Functions moved to new files in the same package for maintainability.

Split 13 files across 6 packages into 25 new files:
- store/pg: teams.go → teams_tasks/delegation/messaging.go; mcp_servers.go → mcp_servers_access.go
- tools: delegate.go → delegate_state/policy/events.go; subagent.go → subagent_exec/config.go;
  web_search.go → web_search_brave/ddg.go; web_fetch.go → web_fetch_convert.go;
  sessions.go → sessions_history/send.go
- providers: anthropic.go → anthropic_stream/request.go
- mcp: manager.go → manager_connect/tools/util.go
- channels/feishu: bot.go → bot_parse/policy.go; larkclient.go → larkclient_messaging.go
- cmd: gateway_consumer.go → gateway_cron.go; agent_chat.go → agent_chat_client/standalone.go

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 17:27:28 +07:00
viettranxandClaude Opus 4.6 0655849d3d fix(cron): route jobs through scheduler for concurrency control and parallel execution
- Simplify cron session key to `agent:{agentId}:cron:{jobID}` (remove redundant `:run:{runID}`)
- Route cron jobs through scheduler's cron lane instead of calling loop.Run() directly
- Scheduler enforces per-session maxConcurrent=1, preventing same job from running concurrently
- Parallelize due job execution with goroutines + WaitGroup (PG and file store)
- Move scheduler creation before cron setup in gateway.go initialization order

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 16:53:15 +07:00
viettranxandClaude Opus 4.6 73b46c3634 feat(security): apply upstream TS OpenClaw security and core engine fixes
Port 8 fixes from upstream TypeScript OpenClaw (4 CRITICAL + 4 HIGH):

CRITICAL:
1. Tool call name trimming — add strings.TrimSpace() to all provider
   response parsers (Anthropic 2 locations, OpenAI 3 locations) to
   prevent registry lookup failures from LLM whitespace-padded names
2. Shell env injection deny patterns — block GIT_EXTERNAL_DIFF,
   GIT_DIFF_OPTS, BASH_ENV, and ENV=.*sh to prevent code execution
   via environment variable injection during git/shell operations
3. Broken symlink escape — recursive target resolution via
   resolveThroughExistingAncestors() to catch chained symlinks
   that escape workspace (e.g. link1→link2→/etc/passwd)
4. Mutable parent-symlink TOCTOU check — hasMutableSymlinkParent()
   detects symlinks in writable parent dirs that could be rebound
   between path validation and file operation

HIGH:
5. Model fallback thinking preservation — add ThinkingCapable interface
   to providers/types.go, implement on Anthropic/OpenAI/DashScope,
   check before injecting thinking_level in agent loop, warn on
   fallback when thinking is configured
6. Cron session-key double-prefix guard — prevent agent:X:cron:agent:X
   duplication in BuildCronSessionKey()
7. Webhook rate limiter — bounded WebhookRateLimiter (4096 keys max,
   60s window, 30 hits/window) to prevent memory exhaustion DoS
8. DM policy allowlist validation — warn at startup when
   dmPolicy=allowlist with empty allowFrom (silent message drop)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 16:52:37 +07:00
viettranx d3323352a1 build: Add *.tsbuildinfo to gitignore to prevent tracking generated TypeScript build info files. 2026-02-28 16:27:21 +07:00
viettranxandClaude Opus 4.6 813c602bca feat(ui): migrate to TanStack Query, add server-side pagination, and improve error handling
- Add @tanstack/react-query with shared cache and centralized query keys
- Migrate all 14 CRUD hooks from manual useState/useCallback to useQuery/useMutation
- Add WS event-driven query invalidation (sessions, traces auto-refresh on run completion)
- Consolidate LlmConfigSection to delegate provider/model UI to ProviderModelSelect
- Add server-side pagination for custom-tools and channel-instances (Go store + HTTP handler)
- Extract shared types into dedicated files (provider, custom-tool, mcp, channel, skill, trace)
- Add network error handling in HTTP client and connectivity check on login
- Add disconnect banner in app layout when gateway connection is lost

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 16:25:59 +07:00
viettranxandClaude Opus 4.6 552ddc059e feat(thinking): add per-agent extended thinking with Anthropic, OpenAI, and DashScope support
Implement full thinking mode system: per-agent thinking_level config (off/low/medium/high)
stored in other_config JSONB, per-provider param injection (Anthropic budget_tokens, OpenAI
reasoning_effort, DashScope enable_thinking+thinking_budget), Anthropic extended thinking with
streaming parse and tool use block preservation via RawAssistantContent, thinking token tracking
in trace spans, and Web UI with agent config selector, chat thinking block rendering, and trace
thinking token display. No DB migration needed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 15:45:34 +07:00
viettranxandClaude Opus 4.6 d913f29c69 feat(providers): add DashScope and Bailian Coding providers with reasoning_content support
- Add DashScope (Qwen) native provider with tools+streaming fallback
- Add Bailian Coding provider with hardcoded model list (no /v1/models API)
- Parse reasoning_content in OpenAI-compat streaming/non-streaming responses
- Emit ChatEventThinking events in agent loop for thinking models
- Add vision support for DashScope (qwen3-vl)
- Fix provider form dialog not updating API base URL when switching types
- Update README provider count from 11+ to 13+

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 14:56:14 +07:00
viettranx 2041b7037b feat: Implement timezone support for cron schedules, improve cron job patching, and enhance trace visibility for cron-triggered agent runs. 2026-02-28 14:17:30 +07:00
Michael e76aabb3a4 fix(browser): return MEDIA: path from screenshot instead of truncated base64 (#8)
handleScreenshot returned a truncated base64 string (first 100 chars only),
which meant the screenshot data was effectively lost and never delivered
to channels (Telegram, Discord, etc.) via the media pipeline.

The media pipeline in loop.go looks for "MEDIA:" prefix in tool results
to collect files for channel delivery (e.g. sendPhoto on Telegram).
Without this prefix, screenshots were silently discarded.

Fix: save screenshot bytes to a temp file and return MEDIA:/path,
matching the pattern used by create_image and tts tools.
2026-02-28 13:09:03 +07:00
Michael 370c290642 fix(tools): use /images/generations endpoint for Gemini and OpenAI image gen (#9)
create_image exclusively used /chat/completions with modalities:["image","text"]
which only works on OpenRouter. Gemini returns HTTP 400:
  "Image generation is not yet supported on the chat.completions endpoint"
OpenAI's DALL-E models also require /images/generations, not /chat/completions.

Fix: route OpenRouter through /chat/completions (supports modalities),
route all other providers (Gemini, OpenAI, etc.) through the standard
/images/generations endpoint with response_format:"b64_json".

Also update default Gemini model from deprecated gemini-2.0-flash-exp
to gemini-2.5-flash-image.
2026-02-28 13:08:32 +07:00
viettranx 4104420d5e feat: ignore commands explicitly addressed to other bots in Telegram group chats. 2026-02-28 13:07:32 +07:00
maemreyo eacc481998 feat(telegram): add speech-to-text transcription for voice/audio messages with audio-aware routing (#14)
* feat(telegram): add speech-to-text transcription for voice/audio messages with audio-aware routing

Implement an STT pipeline for inbound voice and audio messages in the Telegram channel:

- Add new STT configuration options (stt_proxy_url, stt_api_key, stt_tenant_id, stt_timeout_seconds)
- Add VoiceAgentID config to route voice messages to a dedicated speaking agent
- New stt.go module handles transcription via configurable STT proxy service
- MediaInfo struct now includes Transcript field for storing transcription results
- buildMediaTags embeds transcript in media tags when available for downstream processing

This enables the pipeline to process voice messages with full transcription rather than falling back to text-only handling.

* test(telegram): add tests for buildMediaTags and transcribeAudio functions
2026-02-28 11:54:33 +07:00
Duc Nguyen 4c67dff24d feat(providers): support custom base URL for Anthropic provider (#16)
Allow overriding the Anthropic API base URL via GOCLAW_ANTHROPIC_BASE_URL
env var, config JSON, or DB provider record. Enables use of Anthropic-
compatible proxies and custom endpoints.

Also adds Makefile shortcuts for docker compose (up/down/logs).
2026-02-28 11:50:00 +07:00
viettranxandClaude Opus 4.6 7450e7014a fix: Correct provider type seeding and add missing env vars for all channels
- Fix seedManagedData() hardcoding openai_compat for all non-Anthropic providers;
  now uses resolveProviderType() mapping to correct store constants (gemini_native,
  minimax_native, etc.) — fixes model listing in web UI for Gemini
- Rename GOCLAW_FEISHU_* env vars to GOCLAW_LARK_* (Lark is the global brand)
- Add WhatsApp env override (GOCLAW_WHATSAPP_BRIDGE_URL) and auto-enable
- Add missing env vars to docker-compose.yml (Cohere, Perplexity, Lark, Zalo, WhatsApp)
- Update .env.example with all providers/channels, remove unnecessary GOCLAW_PROVIDER
- Add Cohere and Perplexity to prepare-env.sh provider detection

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 11:46:59 +07:00
Duc Nguyenandntduc fcaf3531ba fix(channels): start outbound dispatcher before channel check (#15)
StartAll() returned early when no channels existed at boot,
skipping the dispatchOutbound goroutine. Channels loaded later
via Reload() assumed the dispatcher was running, causing outbound
messages (agent responses) to never reach Telegram.

Move dispatcher startup before the empty-channel early return so
dynamically loaded channels always have a running consumer.

Co-authored-by: ntduc <ntduc@cpp.ai.vn>
2026-02-28 11:10:18 +07:00
miken90 4db5259581 fix(memory): update Gemini embedding to gemini-embedding-001 with dimension support (#10)
- Replace deprecated text-embedding-004 with gemini-embedding-001
- Add WithDimensions() to OpenAIEmbeddingProvider for dimension truncation
- Pass dimensions=1536 for Gemini to match pgvector column size
- Allow config override of Gemini embedding model via embedding_model
2026-02-28 09:16:00 +07:00
hiandClaude Opus 4.6 1b1ca2214a feat(discord): support GOCLAW_DISCORD_TOKEN env var for channel config (#6)
Add env var overlay and auto-enable for Discord channel, matching the
existing Telegram pattern. Update .env.example and docker-compose.yml.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 09:14:36 +07:00
viettranxandClaude Opus 4.6 2f44e86ef2 fix: Strip bot self-mention in Discord responses and remove AGENTS.md from summoning modal
Discord: include sender's mention format in [From:] annotation so models
use the correct user ID, and strip the bot's own @mention from message
content to prevent the model from echoing it back.

Summoning modal: remove AGENTS.md from progress list since backend only
generates SOUL.md and IDENTITY.md.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 22:12:15 +07:00
viettranxandClaude Opus 4.6 42263e5cc5 feat: Add tool loop detection, negative context injection, and fix Docker workspace permissions
- Add tool loop detection (toolloop.go): tracks repeated no-progress tool calls
  using SHA256 hashing of args+results. Warning at 5 identical calls, force stop
  at 10. Prevents Gemini models from burning tokens in infinite loops.
- Inject AVAILABILITY.md negative context when agent has no team/delegation
  targets, so models don't waste iterations probing unavailable capabilities.
- Fix Dockerfile: create /app/.goclaw directory so Docker volume initializes
  with correct goclaw:goclaw ownership instead of root:root.
- Update collapseToolCallsWithoutSig comments for clarity.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 22:00:50 +07:00
viettranxandClaude Opus 4.6 40425d3ad2 fix: Fold tool results as user messages instead of imitable text pattern
Gemini 2.5 flash doesn't return thought_signature, causing
collapseToolCallsWithoutSig to convert tool_calls to "(Used tool ...)"
text that Gemini imitates instead of making real tool calls.

Now strips tool_calls and folds results into plain user messages
so the model retains context without an imitable pattern.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 21:03:44 +07:00
viettranxandClaude Opus 4.6 ef3c35a8b5 fix: Drop tool_calls without thought_signature instead of converting to text, fix trace detail word-wrap
Gemini 2.5 flash doesn't return thought_signature in OpenAI-compat responses,
causing collapseToolCallsWithoutSig to convert ALL tool_calls to "(Used tool ...)"
text. Gemini then imitates this pattern instead of making actual tool calls.
Now drops tool_call cycles entirely, preserving only the assistant's text content.

Also fixes word-wrap in trace detail dialog (break-words instead of break-all)
and uses <pre> with whitespace-pre-wrap for trace-level input/output previews.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 20:53:53 +07:00
viettranx 2e5cf4a9c9 fix: Implement Lark bot identity probe and group history for mention detection, fix Discord placeholder chunking.
- Implement `probeBotInfo()` to fetch bot's `open_id` via `/open-apis/bot/v3/info`, fixing group mention detection that was always false due to empty `botOpenID`.
- Add group pending history support to Feishu channel (record/build context/clear) matching Discord pattern.
- Fix Discord placeholder edit to chunk long responses instead of truncating at 2000 chars.
2026-02-27 20:22:08 +07:00
viettranx 2ee39c8483 feat: Add pairing enforcement, group history, and display name resolution for Discord & WhatsApp channels.
- Implement DM pairing flow for Discord and WhatsApp (checkDMPolicy, sendPairingReply with debounce)
- Add "pairing" case to BaseChannel.CheckPolicy() to reject instead of falling through to "open"
- Add group pending history tracking to Discord (record when not mentioned, prepend context when mentioned)
- Resolve Discord display names with priority: server nickname > global name > username
- Fix Gemini collapse format to prevent model from imitating tool call patterns
- Fix formatTokens crash on null/undefined input
2026-02-27 19:59:51 +07:00
viettranx 0844969819 feat: Add thought_signature support for Gemini tool calls, including a compatibility function for old sessions and refactoring OpenAI types. 2026-02-27 18:46:01 +07:00
viettranx f3d2baa0bc feat: Implement agent resummoning, add Discord require_mention setting, and streamline agent file templates by removing TOOLS.md and HEARTBEAT.md. 2026-02-27 18:22:07 +07:00
viettranx 197c15943c feat: Add support for a wider range of LLM provider types with corresponding UI and backend logic. 2026-02-27 18:22:07 +07:00
viettranx 444169860c feat: introduce InfoLabel, ToolNameSelect, ProviderModelSelect, TagInput, and KeyValueEditor components and integrate them into various configuration pages for enhanced user experience. 2026-02-27 18:22:07 +07:00
Michael 0105bab2d5 fix(spawn): resolve parent agent from context in managed mode (#4)
In managed mode, multiple agents share a single tool registry. The spawn
and subagent tools were constructed with a hardcoded parentID of "default",
which does not exist as an agent in managed mode deployments. This caused
subagent announces to fail with "agent default not found" when any
non-default agent (e.g. a secondary agent) tried to spawn a subagent.

Fix: add ctxAgentKey to tool context keys (same pattern as channel/chatID),
inject the calling agent's key from the loop, and read it in spawn/subagent
tools with a fallback to the construction-time default for backward
compatibility with standalone mode.
2026-02-27 16:06:18 +07:00
Michael 406f83160e fix(mcp): treat "method not found" ping responses as healthy (#1)
MCP servers that don't implement the `ping` method return a "method not
found" error. The health loop previously treated this as a failure,
triggering exponential backoff reconnects and making tools temporarily
unavailable.

Now uses case-insensitive matching to detect "method not found" responses
and treats the server as healthy (it did respond, just doesn't support
ping). Resets reconnect attempts and clears error state.
2026-02-27 16:02:53 +07:00
viettranx 99c0d7e445 fix: send empty objects instead of null for tools_config and other_config when disabled or empty. 2026-02-27 12:31:13 +07:00
viettranx a4325e2abe feat: Improve agent context management with new compaction settings, session-level context window tracking, and calibrated token estimation for adaptive throttling. 2026-02-27 12:11:25 +07:00
viettranx 86d58e1021 feat: Introduce a new upgrade command and enhance built-in tool settings with provider and model configuration. 2026-02-27 11:38:04 +07:00
viettranx d65d792646 feat: Implement built-in tool management with persistence, API, and UI. 2026-02-27 10:19:19 +07:00
viettranx 66808850d4 feat: Implement LLM retry notifications in channels via placeholder updates. 2026-02-27 09:53:45 +07:00
viettranx 2ac44ce937 feat: enhance filesystem security with symlink/hardlink protection, implement typing indicators, and improve scheduler queue management for stale requests. 2026-02-26 22:47:59 +07:00
viettranx d5cc5a745d feat: Implement vision capabilities and image generation tools, adding media handling, dedicated configurations, and trace optimization for image data. 2026-02-26 22:28:27 +07:00