Commit Graph
55 Commits
Author SHA1 Message Date
8cbd30f1ab fix(channels): harden error handling and type safety across Telegram, Zalo, Feishu (#247)
Telegram:
- Fix context cancellation in reaction timer callbacks — use context.Background()
  so emoji reactions still work after request context is cancelled
- Add comma-ok safety on sync.Map type assertions in OnReactionEvent/ClearReaction

Zalo:
- Add comma-ok safety on sync.Map type assertions for typing controllers
- Validate non-empty senderID before processing text/image messages

Feishu/Lark:
- Handle json.Unmarshal errors in all 7 LarkClient messaging methods instead of
  silently returning empty values
- Add 30s HTTP timeout for WebSocket endpoint request (was using DefaultClient)
- Eliminate double decryption in webhook handler — cache first result
- Replace goroutine+sleep with time.AfterFunc for dedup cleanup
- Add comma-ok safety on pairing debounce type assertion
- Use json.Marshal instead of fmt.Sprintf for image/file key JSON construction

Co-authored-by: Luvu182 <208665161+Luvu182@users.noreply.github.com>
2026-03-18 07:39:03 +07:00
d46061405f fix(telegram): enforce transport policy and SSRF guard for media downloads
* fix(telegram): thread transport policy into media downloads with SSRF guard

* fix(telegram): trust configured APIServer during media downloads

* fix(telegram): use proper download timeout and clone DefaultTransport

- Clone http.DefaultTransport when proxy is configured to preserve
  connection pool, TLS handshake timeout, and keep-alive defaults
- Use dedicated 5-minute context timeout for media downloads instead
  of the shared 30s client timeout, preventing large file timeouts
  (local Bot API supports up to 200 MB)

---------

Co-authored-by: viettranx <viettranx@gmail.com>
2026-03-17 18:21:45 +07:00
viettranx b231878a85 feat(teams): add limit param to ListTasks + lightweight get-light endpoint
- Add limit parameter to ListTasks interface (dashboard=200, agent=30)
- Add teams.tasks.get-light WS method returning task only (no comments/events)
- Truncate dashboard response to exact limit (fix off-by-one from limit+1)
- Update all 7 ListTasks callers with explicit limit values
2026-03-17 18:03:10 +07:00
1c4dce0ccf feat(telegram): implement robust message splitting and dynamic HTML retry logic (#236)
* feat(telegram): implement robust message splitting and dynamic HTML retry logic

* fix(telegram): fix sendHTML error chain regression and add split depth limit

- Re-check err.Error() in thread-not-found handler instead of stale errStr,
  restoring the original chained fallback behavior
- Add maxSplitDepth (5) to prevent unbounded recursion when Telegram
  repeatedly rejects split chunks
- Rename misleading test case to reflect actual monolithic fallback behavior

---------

Co-authored-by: viettranx <viettranx@gmail.com>
2026-03-17 13:01:20 +07:00
viettranx 1b876231a1 fix(telegram): default draft_transport to false to prevent reply-deleted artifacts
sendMessageDraft causes "reply to deleted message" artifacts on some
Telegram clients (tdesktop#10315). Disable by default so content
streaming uses message transport (same as reasoning stream).
2026-03-17 09:26:34 +07:00
viettranx 8d6729e959 feat(teams): improve task dispatch, concurrency, and tool ergonomics
- Move task dispatch from mid-turn to post-turn to prevent dependent
  tasks from completing before the current agent's run finishes
- Add team create lock to serialize list→create flows across concurrent
  group chat sessions, preventing duplicate task creation
- Require list-before-create gate: agents must call team_tasks(list)
  before creating tasks
- Make assignee required on task creation
- Add pagination (50 per page) to task list with offset support
- Slim task list/get/search responses with dedicated structs to reduce
  context token usage
- Add task board snapshot in announce messages to leader
- Workspace: allow subdirectory paths in read/delete, show directories
  in list output
- UI: reduce kanban card title font size for better visual balance
2026-03-16 15:26:25 +07:00
Viet TranandGitHub 9a9744077e refactor(teams): v2 system cleanup — remove legacy tools, fix followup, add events API (#210)
Major refactoring of the team system with multiple improvements:

## Removed legacy delegation tools
- Delete `delegate.go`, `delegate_async.go`, `delegate_sync.go`, `delegate_events.go`,
  `delegate_policy.go`, `delegate_prep.go`, `delegate_state.go`, `delegate_search_tool.go`
- Delete `evaluate_loop_tool.go`, `handoff_tool.go`
- Remove all references and registrations from tool manager and policy
- Clean up TEAM_PLAYBOOK_IDEAS.md and TEAM_SYSTEM.md (moved to docs)

## Rename await_reply → ask_user
- Rename action `await_reply` → `ask_user`, `clear_followup` → `clear_ask_user`
- Rename functions `executeAwaitReply` → `executeAskUser`, `executeClearFollowup` → `executeClearAskUser`
- Update system prompt with stronger wording to prevent model misuse
- Model was confusing "await_reply" with general waiting; "ask_user" is unambiguous

## Fix auto-followup false positives
- Add `HasActiveMemberTasks(ctx, teamID, excludeAgentID)` store method
- Guard `autoSetFollowup()` in consumer: skip when lead has active member tasks
- Prevents auto-followup when lead is orchestrating teammates (not waiting for user)

## Task identifier zero-padding
- Change format from `T-1-xxxx` → `T-001-xxxx` (3-digit minimum)

## Refactor workspace WS handlers to filesystem-only
- Rewrite `teams.workspace.list/read/delete` to use pure filesystem (os.ReadDir/ReadFile/Remove)
- Remove DB dependency from workspace WS handlers
- Consistent with storage handler and workspace tools
- Simplify TeamWorkspaceFile type and frontend hook

## Add team events listing API
- New WS method `teams.events.list` with team_id, limit, offset params
- New HTTP endpoint `GET /v1/teams/{id}/events` with bearer auth
- New `ListTeamEvents(ctx, teamID, limit, offset)` store method
- JOIN with team_tasks for team-wide event filtering

## Extract team access policy
- New `team_access_policy.go` — centralized team tool access control

## Migration 000019: team_id columns
- Add team_id foreign key columns to relevant tables

## Other improvements
- Add team_id propagation through agent loop, tracing, sessions
- Update i18n locale files (en/vi/zh) for new tool labels
- Update frontend builtin-tools page and require-setup component
- Bump RequiredSchemaVersion for migration 000019
2026-03-15 14:53:19 +07:00
viettranx 06b4eb912e feat(channels): add i18n for channel config fields and enable DM streaming by default
Add complete i18n support for channel config tab — field labels, help text,
and select option translations for en/vi/zh. Enable DM streaming by default
for Telegram and Slack channels.
2026-03-14 13:08:57 +07:00
1a42dc93a6 feat(teams): team system v2 with bug fixes, workspace scope, versioning, and prompt optimization (#183)
* feat(workspace): add team shared workspace for file collaboration

- Add workspace_write and workspace_read tools for agents to share files across team members
- Create team_workspaces DB table with migration 000017 (file metadata, pinning, tags)
- Implement PostgreSQL store layer for workspace CRUD operations
- Add RPC handlers for workspace list/read/delete from web UI
- Build React workspace tab with file listing, content preview, and delete
- Propagate workspace channel/chatID scope through delegation chain
- Auto-allow workspace tools in agent tool policy when agent belongs to a team
- Inject team workspace guidance into system prompt for team agents
- Add /reset command handler for clearing session history
- Harden MCP bridge context middleware to reject headers when no gateway token
- Add i18n strings for workspace UI in en/vi/zh locales

* feat(teams): add comprehensive task management with followup reminders and recovery

- Add task followup/reminder system with auto-set on lead agent reply and auto-clear when user responds on channel
- Add task recovery ticker to re-dispatch stale/pending tasks periodically
- Add task scopes, filtering by status/channel/chatID, and task events
- Add WS RPC handlers for task CRUD, assignments, comments, events, and bulk operations (teams_tasks.go)
- Add task detail dialog, settings UI for followup config, and scope filtering in web dashboard
- Add migrations 000018 (team_tasks_v2) and 000019 (task_followup)
- Extend team_tasks_tool with await_reply, clear_followup actions
- Auto-complete/fail team tasks when delegate agent finishes
- Add workspace file listing and team tool manager enhancements

* docs(teams): add team system architecture and playbook ideas documentation

- Add TEAM_SYSTEM.md with full architecture design covering task management, shared workspace, and delegation engine subsystems
- Add TEAM_PLAYBOOK_IDEAS.md outlining future team coordination layers (playbook, member capabilities, auto-learned patterns)
- Document data models, status flows, tool actions, followup reminder system, task ticker, execution locking, and workspace scope model

* fix(teams): resolve 6 critical bugs in team task system

- Fix unblock SQL: check array_length after array_remove (not before)
- Enforce single-team leadership in team creation
- Add requireLead() for approve/reject tool actions
- Validate cross-team dependency references in blocked_by
- Add team_id to handoff route for multi-team isolation
- Set blocked_by DEFAULT '{}' to prevent NULL array issues

* refactor(workspace): use stable userID as scope key instead of connection UUID

Workspace scope changed from (team_id, channel, chat_id) to (team_id, userID).
Fixes workspace fragmentation across WS tab refreshes and reconnections.

* feat(teams): add V1/V2 versioning with feature gating and optimized prompts

- IsTeamV2() helper gates advanced features (locking, followup, review, audit)
- V2 tool actions rejected for V1 teams with clear error message
- Ticker, gateway consumer, delegation hooks respect version flag
- TEAM.md renders v1/v2 sections conditionally
- Tool descriptions and params optimized (~38% token reduction)
- UI: version toggle in settings, V2 Beta badge, conditional rendering
- i18n: version modal keys for en/vi/zh

* fix(migration): use VARCHAR(255) for user ID columns and add metadata JSONB

- assignee_user_id, user_id, actor_id: TEXT → VARCHAR(255)
- Add metadata JSONB to team_task_comments and team_task_attachments

---------

Co-authored-by: Nam Nguyen Ngoc <namnn.0911@gmail.com>
2026-03-13 22:41:32 +07:00
viettranx 7bde3f2f7c fix(pairing): handle transient DB errors in IsPaired to prevent spurious pair requests
IsPaired() silently returned false on DB query failures (connection
timeout, pool exhaustion), causing the system to treat already-paired
users/groups as unpaired and create spurious pairing requests.

Changed IsPaired signature to return (bool, error). All 13 callers
across all channels (Telegram, Discord, Slack, Feishu, WhatsApp, Zalo)
and gateway (browser WS, pairing method) now fail-open on DB errors:
log a warning and assume paired, avoiding false rejections.
2026-03-13 17:29:28 +07:00
viettranx a75e977dca fix(telegram): simplify pairing messages for friendlier UX
Remove verbose CLI instructions and Telegram user ID from pairing
replies. Show only the pairing code with a friendly message.
2026-03-12 10:46:32 +07:00
e5eca5d0f0 feat(telegram): support custom Bot API server URL (#157)
* feat(telegram): support custom Bot API server URL

Add api_server credential field for Telegram channels to allow
using a self-hosted Telegram Bot API server (e.g. for 2GB upload
limits). Uses telego.WithAPIServer() option.

* feat(telegram): local Bot API media download + config improvements

- Support local Bot API --local mode: detect absolute file paths and
  copy directly from filesystem (requires shared volume mount)
- Fall back to HTTP download via custom API server URL for non-local mode
- Move api_server/proxy from credentials to config (non-secret fields);
  credentials still accepted for backward compat
- Add media_max_mb config field (friendlier than media_max_bytes);
  deprecated media_max_bytes still works
- Default to 200 MB max when local Bot API is configured (vs 20 MB cloud)
- UI: move api_server/proxy to config section, use MB for media size

* fix: use 127.0.0.1 instead of localhost in API server placeholder

Docker containers cannot resolve localhost to the host machine.
127.0.0.1 works reliably with Docker's default bridge network.

---------

Co-authored-by: Luvu182 <208665161+Luvu182@users.noreply.github.com>
2026-03-12 09:29:14 +07:00
a4f2d02a80 fix(channels): annotate DM messages with sender identity (#120)
* fix(channels): annotate DM messages with sender identity

Telegram and Zalo group messages already include [From: sender] prefix
so the agent knows who is talking, but DM messages were sent without
any sender context — the agent had no way to address the user by name.

- Telegram DM: add [From: @username] (or FirstName if no username)
- Zalo DM: add [From: displayName] when dName is present in payload

* fix(tests): add missing EnsureUserProfile to test stubs

AgentStore interface gained EnsureUserProfile in 4fce731 but the test
stub implementations were not updated, breaking CI on main.

---------

Co-authored-by: Luvu182 <208665161+Luvu182@users.noreply.github.com>
2026-03-10 19:25:55 +07:00
viettranx 23f1957c56 feat(channels): wire contact auto-collector across all channel handlers
Pass contactCollector through channel manager to all channel handlers
(Telegram, Discord, Feishu, Slack, Zalo) so contacts are automatically
collected when users interact with the agent.
2026-03-10 18:46:44 +07:00
viettranx 9181eebcea fix(channels): defer media download, fix compaction status & context cancel
- Defer Telegram media download until after mention gate — pending
  history now uses lightweight tags (no download) saving bandwidth
  and avoiding errors on large files
- Fix compaction status query: has_summary now false when new messages
  arrive after last compaction, re-enabling the compact button
- Fix HTTP compact endpoint: detach context from request so LLM
  summarization isn't cancelled when browser closes connection
2026-03-10 17:12:13 +07:00
viettranx 3b6bf645f3 feat(channels): pending message compaction — fix provider, wire auto-compact, add global config & UI
- Fix compact endpoint using random provider instead of agent's configured provider+model
- Wire auto-compaction for all 5 channel types (telegram, discord, slack, feishu, zalo_personal)
  via PendingCompactable interface and InstanceLoader
- Add global PendingCompactionConfig (threshold, keep_recent) to ChannelsConfig
- Wire global config through InstanceLoader and PendingMessagesHandler
- Increase compaction timeout from 45s to 180s for slow providers
- Add pending compaction config card to Behavior tab in config page
- Add HowItWorksCard (expanded by default) and toast notifications to pending messages page
- Add i18n support for all new strings (en/vi/zh)
2026-03-10 12:49:12 +07:00
viettranx bdb60de7ae chore: upgrade Go 1.25 → 1.26 and apply go fix modernizations
- Update go.mod and Dockerfile to Go 1.26
- Apply `go fix ./...` stdlib modernizations across 170+ files
- Add `go fix` to post-implementation checklist in CLAUDE.md
- Fix go fix misapplied rewrite in loop_history.go
2026-03-10 00:09:15 +07:00
viettranx 5f7ca84876 feat(channels): persist pending messages to PostgreSQL with Web UI
- Add channel_pending_messages table with UUID v7 PK, sender_id tracking
- Implement PendingMessageStore interface with batched flush (3s/20 msgs)
- Add LLM-based auto-compaction when entries exceed threshold (50)
- Wire persistent history into all channel factories (Telegram, Discord, Slack, Feishu, Zalo)
- Extract channel type constants (TypeTelegram, TypeDiscord, etc.) to eliminate magic strings
- Add HTTP API endpoints for pending messages management (list, view, compact, clear)
- Add Pending Messages dashboard page with group titles resolved from session metadata
- Track sender_id across entire pipeline (migration → store → history → handlers)
2026-03-09 12:39:43 +07:00
viettranx e85624ce96 refactor: split large Go files into smaller modules for maintainability
Split 11 Go files exceeding 500 lines into smaller, focused files:
- channels/manager.go → manager.go + dispatch.go + runs.go + events.go
- channels/slack/channel.go → channel.go + send.go + utils.go
- channels/slack/handlers.go → handlers.go + handlers_mention.go + handlers_files.go
- channels/telegram/handlers.go → handlers.go + handlers_utils.go
- channels/zalo/personal/channel.go → channel.go + send.go + listen.go + handlers.go
- gateway/methods/agents.go → agents.go + agents_create.go + agents_update.go + agents_delete.go
- http/summoner.go → summoner.go + summoner_regenerate.go + summoner_prompts.go + summoner_utils.go
- http/skills.go → skills.go + skills_upload.go + skills_versions.go + skills_grants.go
- http/mcp.go → mcp.go + mcp_tools.go + mcp_grants.go + mcp_requests.go
- store/pg/cron.go → cron.go + cron_crud.go + cron_update.go + cron_exec.go

No logic changes — pure file reorganization to keep files under 200 lines.
2026-03-09 10:41:54 +07:00
viettranx 62c28e1b3e feat(channels): unified media pipeline for Discord, Feishu, and WebSocket
Extract shared media utilities (MediaInfo, BuildMediaTags, TranscribeAudio,
DetectMIMEType) into internal/channels/media/ and refactor Telegram to use
them. Add full inbound/outbound media support to Discord and Feishu channels
(STT transcription, document extraction, media tags, voice agent routing).
Add WebSocket media upload/serve endpoints and MIME-aware media tags in
chat.send. Split large channel files for maintainability.
2026-03-08 16:39:46 +07:00
viettranx 47cc11bfc0 feat(metadata): add JSONB metadata to sessions, profiles, and pairing
Persist friendly names (display_name, username, chat_title) from channel
handlers into sessions, user profiles, and pairing records. Web UI renders
metadata with graceful fallback to raw IDs.

- Add migration 000011: metadata JSONB columns on sessions,
  user_agent_profiles, pairing_requests, paired_devices
- Extend SessionStore/AgentStore/PairingStore interfaces with metadata ops
- Extract and persist channel metadata in gateway consumer
- Extend sessions.patch and add PATCH instances metadata HTTP endpoint
- Update frontend sessions page, detail page, and instances tab
- Delete legacy file-based internal/pairing/service.go
- Update docs references to reflect DB-backed pairing
2026-03-08 15:42:44 +07:00
viettranx e1a6801a7a fix(tools): correct Veo API, media ref ordering, video tag, and model verify
- Fix create_video: use predictLongRunning API instead of generateContent
  (async polling flow: POST → poll every 10s → download video from URI)
- Fix durationSeconds as int (not string) per actual Gemini API requirement
- Fix MediaRef collection order: historical first, current last, so
  refs[len-1] always returns the most recent file (fixes read_audio
  picking up old file instead of current voice message)
- Remove misleading "video not yet supported" text from Telegram handler
  that prevented LLM from calling read_video tool
- Add isNonChatModel() to skip chat-based verify for generation models
  (veo-*, dall-e-*, imagen-*, gemini-*-image)
2026-03-08 15:21:08 +07:00
viettranx 0f2737ce53 feat(media): persistent media storage, read_document tool, and pipeline refactor
- Add persistent media storage (internal/media/) replacing temp file deletion
- Add MediaRef type for lightweight media references in session messages
- Refactor media pipeline to use bus.MediaFile{Path, MimeType} across all channels
- Add read_document builtin tool for PDF/DOCX/XLSX analysis via Gemini native API
- Move image sanitization from Telegram to shared agent/media layer
- Add media reload for multi-turn conversations (images from last 5 messages)
- Add reply-to-message media resolution for Telegram (re-download on reply)
- Add media inventory to compaction summary to preserve awareness after truncation
- Fix coreToolSummaries for read_image, read_document, create_image tools
- Add real-time trace update events via WebSocket broadcast
- Improve trace detail UI with media refs and tool result display
2026-03-08 14:00:34 +07:00
Songlin YangandGitHub af85b0c354 chore: remove unused code (#78) 2026-03-07 15:58:42 +07:00
viettranx faa47abfb6 feat(block-reply): deliver intermediate text during tool iterations with 2-tier config (#55)
Add block.reply event that delivers intermediate assistant text to non-streaming
channels during multi-tool iterations. Includes 2-tier config toggle:
gateway-level default (disabled) + per-channel override (inherit/on/off).

Backend:
- Emit block.reply events from agent loop between tool iterations
- Add BlockReply *bool to GatewayConfig and all 6 channel config structs
- Add BlockReplyChannel interface with ResolveBlockReply() resolution
- Guard delivery in HandleAgentEvent by RunContext.BlockReplyEnabled
- Resolve config at RegisterRun time, pass to consumer goroutine
- Conditional dedup: skip final message if identical to last block reply

UI:
- Gateway settings: Switch toggle for global default
- Per-channel: tri-state select (Inherit from gateway / Enabled / Disabled)
- Protocol: BLOCK_REPLY constant in AgentEventTypes
- Form: coerceBoolSelects for proper JSON boolean serialization
2026-03-07 01:06:10 +07:00
Viet TranandGitHub 6895e369f6 refactor: remove standalone mode, consolidate to managed-only (PostgreSQL) (#70)
- Remove standalone mode code: file-based stores, standalone gateway,
  heartbeat service, SQLite memory, standalone docker-compose
- Rename docker-compose.managed.yml → docker-compose.postgres.yml
- Clean up ~130 Go comments referencing "managed mode" qualifier
- Simplify docker-compose.yml env vars (providers/channels via web UI)
- Update .env.example to essential vars only (token + encryption key)
- Add setup wizard UI (provider → agent → channel bootstrap flow)
- Add logs.tail WebSocket handler for live log streaming
- Add cursor-pointer to interactive UI components
- Clean up config page (remove standalone-only sections)
- Update README and docs for managed-only architecture
2026-03-06 18:51:11 +07:00
viettranxandClaude Opus 4.6 32f9c99a71 feat(telegram): add draft streaming infrastructure + split dm/group stream config
- Add sendMessageDraft transport (disabled pending Telegram client fix for
  "reply to deleted message" artifact — tdesktop#10315, bugs.telegram.org/c/561)
- Split stream_mode into dm_stream/group_stream boolean flags (both default false)
- DM messages no longer set reply_to_message_id (cleaner UX, matching TS)
- Progressive placeholder editing for DMs: "Thinking..." → stream chunks → final
- Update web UI with separate DM/Group streaming toggles

fix(agent): prevent false MEDIA: detection in tool output

parseMediaResult() used strings.Index to find "MEDIA:" anywhere in tool output,
causing false positives when external content (e.g. GitHub releases page)
contained commit messages like "return MEDIA: path from screenshot".
Changed to strings.HasPrefix to only match at start of output.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 22:12:56 +07:00
viettranxandClaude Opus 4.6 361bca3617 fix(teams): scope ListTasks by userID to prevent cross-group task leaking
Tasks from one Telegram group were being injected into another group's
session because the pending-task hint and /tasks command queried all
tasks team-wide without filtering by the group-scoped userID.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 19:27:23 +07:00
viettranx e8c634f611 fix: Handle bot commands before enriching content to prevent parsing issues with reply/forward context. 2026-03-03 17:07:16 +07:00
viettranxandClaude Opus 4.6 e2debfe49a feat: mid-loop context compaction + team task user scoping
Add mid-loop compaction to prevent context overflow during long-running
delegated agent runs (e.g. 225K+ tokens causing DashScope timeouts).
Uses same threshold as maybeSummarize (contextWindow * historyShare)
with actual PromptTokens from LLM response. Only compacts the in-memory
messages slice; pendingMsgs preserves full history for session flush.

Add user_id/channel columns to team_tasks so end users only see their
own tasks. Delegate/system channels bypass the filter to see all tasks.
Group chats use the group-scoped UserID (group:channel:chatID) so all
members share visibility.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 15:03:28 +07:00
viettranxandClaude Opus 4.6 4387f6b1ba fix: improve spawn tool team_task_id validation and orphan detection
When LLMs call team_tasks create + spawn in parallel, the spawn
tool receives a hallucinated task_id that fails uuid.Parse, causing
a misleading error and bypassing orphan detection.

- Include pending task IDs in spawn error message so LLM can retry
  with the correct UUID
- Move spawn counting to post-execution so failed spawns don't
  increment teamTaskSpawns, allowing orphan detection to fire

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 11:36:46 +07:00
viettranx 15e8f12d5e feat: restrict /reset command to file writers in Telegram group chats. 2026-03-03 10:39:19 +07:00
viettranx 278a98ba74 feat: Add tool allow list configuration and enforcement for Telegram channels, allowing per-group/topic tool restrictions. 2026-03-02 21:17:19 +07:00
viettranxandClaude Opus 4.6 74d85c8dd5 feat(security): enforce group file writer restrictions + harden exec against env/config leaks
Group writer enforcement (managed mode):
- GroupWriterCache with 5min TTL wrapping AgentStore.ListGroupFileWriters
- Tool-level blocking: write_file, edit, read_file (SOUL.md/AGENTS.md), cron mutations
- System prompt injection: non-writers get refusal instructions + filtered context files
- Cache invalidation via bus events on add/remove writer
- Wired through resolver, loop, gateway_managed, gateway_callbacks

Exec security hardening:
- Block /proc/PID/environ and /proc/self/environ reads (env var exfiltration)
- Block strings on /proc files (binary env dump)
- DenyPaths() on ExecTool: block data dir, .goclaw/, config file from exec commands
- Scrub VIRTUAL_* env vars from tool output

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 19:22:21 +07:00
viettranx 53db5165a3 feat: add a hint to bot reply bodies indicating full content is in session history for LLM context. 2026-03-02 16:41:20 +07:00
viettranxandClaude Opus 4.6 5bd486882d feat(telegram): port forum topic features from TS — per-topic config, DM threads, thread fallback, createForumTopic tool, Web UI
Port 4 missing Telegram forum/topic features from TypeScript OpenClaw:

1. Thread-not-found fallback: retry sends without message_thread_id when
   a topic is deleted (sendHTML, sendPhoto, sendVideo, sendAudio,
   sendDocument, stream flush).

2. Per-topic config: hierarchical config resolution (global → wildcard
   group "*" → specific group → specific topic) for groupPolicy,
   requireMention, allowFrom, enabled, skills, systemPrompt.
   New TelegramGroupConfig/TelegramTopicConfig structs, resolveTopicConfig()
   with 10 unit tests.

3. DM topic support: preserve message_thread_id in private chats for
   session isolation. New BuildDMThreadSessionKey, parseRawChatID handles
   🧵 suffix.

4. createForumTopic agent tool: ForumTopicCreator interface decoupled
   from telego, lazy bot resolution via channel manager.

5. Web UI: structured group/topic config form with tri-state booleans
   (Inherit/Yes/No), nested collapsible group and topic entries.

Also fix: forum group pairing reply and approval notification now
correctly set MessageThreadID so messages land in the right topic.
Send() extracts threadID from localKey suffix as fallback for cases
where metadata is absent (e.g. pairing approval via SendToChannel).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 13:45:21 +07:00
viettranxandClaude Opus 4.6 6ed62b8506 feat: channel-isolated workspace, resolvePath fix, create_image workspace, summoner Expertise section, bus Topic constants
- Fix resolvePath for nested non-existent dirs (use resolveThroughExistingAncestors)
- Channel-isolated workspace: user_agent_profiles.workspace stores channel prefix,
  used as source of truth with backward compat for existing users
- Loop caches workspace per-user with CacheKindUserWorkspace invalidation via pubsub
- ContractHome/ExpandHome for portable ~-based paths in DB
- create_image saves to workspace/generated/YYYY-MM-DD/ instead of OS temp dir
- SOUL.md template: add ## Expertise section for domain knowledge
- Summoner buildEditPrompt: section guide, complete file output, frontmatter update
- Bus: Topic* constants for Subscribe/Broadcast keys, CacheKind* for payload kinds
- Teams, delegates, sessions, agent links: various enhancements

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 10:52:32 +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 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
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 4104420d5e feat: ignore commands explicitly addressed to other bots in Telegram group chats. 2026-02-28 13:07:32 +07:00
maemreyoandGitHub 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
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
viettranx 6066adc15a feat: Implement agent delegation, quality gates, and a new hooks evaluation system. 2026-02-26 10:15:07 +07:00
viettranx b365ef5494 feat: Modularize Telegram commands, introduce new scheduler components, and enhance agent management and Feishu integration. 2026-02-26 08:16:06 +07:00
viettranx dfd91556f8 feat: Introduce agent teams, agent linking, and advanced agent orchestration features. 2026-02-25 23:24:52 +07:00
viettranx f5ff96d998 feat: Improve agent concurrency with per-session summarization locks and message buffering, add adaptive scheduler throttling, and introduce Telegram /stop and /stopall commands. 2026-02-24 17:44:50 +07:00
viettranx 3d63e419a5 feat: Only send 'Thinking...' placeholder message in Telegram direct messages. 2026-02-23 18:19:23 +07:00