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
* feat(providers): add ACP provider for orchestrating external coding agents (#189)
Implement native Go ACP (Agent Client Protocol) client as a new Provider.
Enables GoClaw to orchestrate any ACP-compatible agent (Claude Code, Codex
CLI, Gemini CLI) as a subprocess via JSON-RPC 2.0 over stdio.
- Add bidirectional JSON-RPC 2.0 transport over stdio pipes
- Add subprocess process pool with idle TTL reaping and crash recovery
- Add ACP session lifecycle (initialize, session/new, session/prompt)
- Add tool bridge for agent-initiated fs/terminal/permission requests
- Add workspace sandboxing, shell deny patterns, and env var filtering
- Wire config-based and DB-based provider registration paths
- Export DefaultDenyPatterns from tools package for reuse
* feat(providers): add changelog entry for ACP provider integration
* fix(tools): prevent workspace traversal bypass via /tmp/ fallback in resolveMediaPath
Reject paths containing ".." in the isInTempDir fallback to prevent
workspace escape where traversal path still resolves inside /tmp/.
* fix(tools): block workspace-sibling paths in resolveMediaPath /tmp/ fallback
When workspace is inside /tmp/, traversal paths like workspace/../X
resolve to /tmp/ siblings that pass isInTempDir. Reject paths inside
the workspace parent directory to prevent this escape.
* feat(providers): add ACP provider web UI and live reload via pubsub
Web UI for creating/editing ACP providers with dedicated form fields
(binary, args, idle TTL, permission mode, work directory). ACP providers
now update immediately without gateway restart via cache invalidation
pubsub pattern.
Frontend:
- New ACPSection form component with i18n (en/vi/zh)
- Provider form dialog integration with ACP state management
- ACP type badge on providers list page
- Settings field added to provider TypeScript types
Backend:
- ACP models handler (claude/codex/gemini) without API key requirement
- Binary path validation + LookPath verification in verify handler
- Provider CRUD emits cache.invalidate events via msgBus
- Subscriber in gateway_managed.go re-registers ACP providers from DB
- ACP core improvements from code review (helpers, jsonrpc, process,
terminal, tool_bridge)
---------
Co-authored-by: viettranx <viettranx@gmail.com>
* 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>
- Add hasKG flag to MemorySearchTool, inject hint in results when KG is enabled
- Wire SetHasKG(true) in gateway when KG store is available
- Improve knowledge_graph_search tool description with concrete use cases
- Update system prompt KG guidance to be more actionable
The embedding provider resolution only matched 3 hardcoded names
(openai, openrouter, gemini), silently failing for DB-stored providers
like "openai-embedding". This caused memory chunks to be stored
without vectors even when a valid embedding provider was configured.
Changes:
- resolveEmbeddingProvider: fallback to provider registry for DB-stored
provider names when hardcoded match fails
- gateway startup: read per-agent memory config from DB (priority over
config file defaults) for embedding provider resolution
- memory IndexDocument: log embedding errors instead of swallowing them
- memory admin ListChunks: return full chunk text instead of truncating
to 200 chars, avoiding confusing partial content in the UI
Co-authored-by: Luvu182 <208665161+Luvu182@users.noreply.github.com>
- A1+C2: Include token usage in run.completed event payload for WS clients
- A2: Cost tracking with model pricing config, cost calculation, and cost summary API
- A3: Budget enforcement per agent with monthly budget limits (migration 000015)
- C1: External wake/trigger API (POST /v1/agents/{id}/wake) for orchestrators
- C3: Activity audit trail with structured logging and queryable API
- UI: Activity page, cost stat card on overview, budget section in agent detail
- i18n: Complete en/vi/zh translations for all new features
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.
- Add read_audio tool with Gemini File API, OpenAI input_audio, and fallback support
- Add read_video tool with Gemini File API and base64 fallback for video analysis
- Add create_video tool with Gemini Veo and OpenRouter chat completions support
- Add shared gemini_file_api.go for upload → poll → generateContent pipeline
- Add shared openai_compat_call.go for custom JSON chat completions
- Fix system prompt showing denied tools: use filteredToolNames() instead of tools.List()
- Wire audio/video MediaRef context propagation in agent loop
- Register new tools in seed data, policy groups, and web UI settings
- Enforce duration (max 30s) and aspect_ratio limits on create_video
- 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
Add optional Redis cache support via `go build -tags redis`, following
the same paired-stub pattern as OTel and Tailscale. The Cache[V] interface
is unchanged; Redis and in-memory implementations are injected at startup
without altering usage logic.
- Add RedisCache[V] implementation with JSON serialization, fail-open on errors
- Add gateway_redis.go / gateway_redis_noop.go paired wiring files
- Refactor GroupWriterCache and ContextFileInterceptor to accept injected caches
- Add GOCLAW_REDIS_DSN env var, docker-compose.redis.yml overlay
- Update Dockerfile and GitHub Actions with ENABLE_REDIS build arg
- Add Redis variant to CI matrix (5 variants: latest, otel, tsnet, redis, full)
MCP tool search mode: when an agent has >30 MCP tools, tools are
deferred and a single mcp_tool_search meta-tool is registered instead.
Uses BM25 index for keyword search, activating matched tools on demand.
Shared connection pool: introduces Pool that maintains one physical
connection per MCP server name, shared across all agents via refcount.
Eliminates N×M duplicate connections (N agents × M servers).
Backend:
- Add POST /v1/mcp/servers/test endpoint reusing DiscoverTools()
- Add GET /v1/mcp/servers/{id}/tools for discovered tool listing
- Add MCPToolLister interface and wire through gateway
Frontend:
- Add Test Connection button with success/error feedback in MCP form
- Replace agent ID text input with agent select dropdown in grants dialog
- Replace tool allow/deny text inputs with multi-select from server tools
- Add MCP tools dialog for viewing connected server tools
- Widen MCP dialogs to sm:max-w-xl
Add Claude CLI as an LLM provider (subscription-based, no API key needed).
The CLI manages session history, tool execution, and context while GoClaw
forwards messages and streams responses.
Key features:
- Claude CLI provider with session persistence (--resume)
- MCP bridge server exposing GoClaw tools to CLI via streamable-http
- Security hooks (shell deny patterns, workspace path restrictions)
- Per-session mutex preventing concurrent CLI calls
- Onboard wizard for Claude CLI setup and auth verification
- Web UI for adding/managing Claude CLI provider with auth status
- Provider registry Close() for proper shutdown cleanup
Security:
- CLI path validation (only "claude" or absolute paths from DB)
- Token auth middleware for MCP bridge endpoint
- Shell injection prevention in hook scripts (single-quoted paths)
- Relative path resolution before workspace boundary checks
- Resource leak prevention on provider replace/unregister
Co-authored-by: nhokboo <nhokboo@users.noreply.github.com>
Add 16 new event constants and typed payload structs for full WS
visibility into team agent operations. Enrich AgentEvent with delegation
and routing context (delegationId, teamId, parentAgentId, userId,
channel, chatId). Emit thinking/chunk events for non-streaming runs
so delegate member agents also produce WS events.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The memory interceptor handled read_file/write_file for memory paths
but list_files hit the filesystem, returning "Directory does not exist".
Now list_files queries memory_documents from PostgreSQL via the existing
ListDocuments store method.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Security: fix cross-agent MCP tool leak by cloning tool registry before MCP registration.
MCP: enforce mcp_ prefix on all tool names, add cache invalidation on server/grant changes,
add grant management endpoints, add group:mcp policy support for per-agent allowlisting.
Skills: persist full YAML frontmatter, auto-promote/demote visibility on grant/revoke,
simplify versioning, handle ZIP wrapper directories, expand tilde in skillsDir path.
Fixes: wrap DeleteSkill cascade in transaction, use atomic NOT EXISTS for revoke-demote,
create cancel context before storing server in map.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add CancelTask store method: guards against completed tasks, unblocks dependents, transitions blocked→pending
- Cancel running delegation when team task is cancelled via CancelByTeamTaskID
- Prevent delegate agents from completing/cancelling tasks directly
- Wire DelegateManager into TeamToolManager for task-delegation lifecycle
- Remove BOOTSTRAP.md from predefined agent seed (predefined agents already have full context)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
DelegateAsync creates detached contexts (context.Background()) and runs
outside the scheduler, so /stopall's CancelSession() couldn't reach them.
Now /stopall also calls DelegateManager.CancelForOrigin() to cancel
active delegate tasks matching the origin channel+chatID.
Also silences context.Canceled errors in subagent/delegate announce
handlers to avoid sending spurious error messages after cancellation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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>
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>
* fix(store): expand tilde in skills storage directory path
The default skillsDir (~/.goclaw/skills-store) was not expanded,
causing os.MkdirAll to fail when creating skill upload directories.
* feat(skills): per-agent skill filtering with grant-based access control (#42)
Wire skill_agent_grants into the agent resolver so each agent only sees
skills explicitly granted to it. Add Skills tab to the web UI for
managing per-agent skill grants with toggle switches.
- Add SkillAccessStore interface to avoid import cycles
- Filter skills in resolver via ListAccessible + filesystem union
- Add GET /v1/agents/:id/skills endpoint with grant status
- Invoke onGrantChange callback to invalidate agent caches on grant/revoke
- Add agent-skills-tab React component with Switch toggles
- Allow read_file access to managed skills-store directory
- Fix rows.Err() propagation in ListAccessible/ListWithGrantStatus
Closes#42
- 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>
* fix: invalidate ContextFileInterceptor cache on agents.files.set
When agents.files.set (or agents.update) wrote context files to
agent_context_files in Postgres, only the agent router cache was
invalidated via agents.InvalidateAgent(). The ContextFileInterceptor
maintains its own separate in-memory cache with a 5-minute TTL which
was never cleared, causing the agent to serve stale file content
(e.g. wizard-written SOUL.md/IDENTITY.md) for up to 5 minutes.
Fix: inject *tools.ContextFileInterceptor into AgentsMethods and call
intc.InvalidateAgent(ag.ID) immediately after each successful DB write
in handleFilesSet and handleUpdate.
Wire path: wireManagedExtras now returns the interceptor it creates;
gateway.go captures it and passes it through registerAllMethods →
NewAgentsMethods. The interceptor is nil in standalone mode so all
nil guards are in place.
* test: add unit tests for ContextFileInterceptor cache invalidation
Covers:
- Cache hit: second read does not call store again
- InvalidateAgent clears agent cache → fresh content served from store
- InvalidateAgent clears user cache for that agent
- InvalidateAgent does not affect other agents' cache entries
- TTL expiry causes re-fetch from store
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>
Implement group file writer allowlist system with Telegram commands (/addwriter, /removewriter, /writers) for managing who can edit protected files in group chats. Wire AgentStore through Telegram factory, inject SenderID context for permission checks, and auto-bootstrap first group member as writer. Only existing writers can manage the list, preventing removal of the last writer.
Register edit tool (sandboxed + non-sandboxed variants) with context file and memory interceptors in managed mode. Add cron tool for agent-facing job management. Register session tools (list, status, history, send) and message tool with proper SessionStoreAware, BusAware, and ChannelSenderAware wiring. Harden exec approval system to always be active with deny patterns + safe bins, defaulting to full
Multi-agent AI gateway with WebSocket RPC, HTTP API, and messaging channel integrations.
Go port of OpenClaw with multi-tenant PostgreSQL, per-user isolation, security hardening,
and production observability.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>