- Backend: DeleteTask RPC handler with terminal-status guard (completed/failed/cancelled)
- Frontend: delete button in kanban cards (top-right, hover), task list, and detail dialog
- Show agent emoji from members lookup next to owner name in all task views
- Replace priority colored dot with P-0/P-1/P-2/P-3 labels with hover tooltips
- Auto-reload board on TEAM_TASK_DELETED WebSocket event
- i18n: add delete task strings for en/vi/zh
- Add terminal-state check in executeCreate(): reject blocked_by
referencing completed/cancelled/failed tasks with actionable error
- Add full validation in executeUpdate(): batch query via GetTasksByIDs,
check existence + team membership + terminal state
- Add GetTasksByIDs batch query to TeamStore interface + pg implementation
- Refactor: modularize gateway, skills store, and team tools into
focused files
- Update TEAM.md leader prompt: prefer delegation, plan full task graph
upfront, create tasks in order with blocked_by UUIDs
Show the emoji from other_config.emoji instead of the default Bot icon
in agent-card (grid), agent-list-row (list), and agent-detail-page (header).
Falls back to Bot icon when no emoji is set.
Replace all hardcoded ~/.goclaw path constructions with configurable
sources (cfg.ResolvedDataDir() for service dirs, cfg.Agents.Defaults.Workspace
for agent workspaces). This fixes data persistence issues in Docker
deployments where paths differ from local dev.
- Add DataDir field to Config with ResolvedDataDir() resolver
- Add ResolvedDataDirFromEnv() package-level helper for packages without Config
- Populate StoreConfig.SkillsStorageDir (was never set, caused hardcoded fallback)
- Agent workspaces now use subdirectory format (workspace/{key}) for volume compatibility
- Remove dead GOCLAW_SESSIONS_STORAGE env/config (sessions moved to PostgreSQL)
- Fix deploy-stg.sh trailing space after backslash + remove deprecated GOCLAW_MODE
- Add GOCLAW_SKILLS_DIR override in docker-compose for volume persistence
GPT-5 and o-series models reject the legacy max_tokens parameter and
require max_completion_tokens instead. Additionally, gpt-5-mini,
gpt-5-nano, and o-series models only support the default temperature (1).
This patch adds model-aware branching in buildRequestBody() to:
- Send max_completion_tokens instead of max_tokens for gpt-5*/o1/o3/o4
- Skip temperature parameter for gpt-5-mini/gpt-5-nano/o-series
Co-authored-by: Marcelo Emmerich <marcelo@agenticsystems.de>
- Add card/list view toggle on teams page (matching agents page pattern)
- Card view: member chips with emoji/Bot icon, frontmatter, crown for lead
- List view: comma-separated member names with frontmatter tooltip on hover
- Show version badge from team settings in both views
- Enrich ListTeams API to bulk-fetch members with emoji from other_config
- Add agent emoji field (other_config.emoji) to create/update forms
- Show emoji in team members dialog instead of Bot icon when available
- Force restrict_to_workspace=true system-wide, remove UI toggle
- Add i18n keys for all 3 locales (en/vi/zh)
- Fix storage file listing to skip subtree root when ?path= is used,
preventing duplicate folder nesting in the file browser tree
- Comment out os.Remove calls in persistMedia to keep original workspace
files after persisting to media store
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
When fetched content exceeds the character limit, full content is saved
to a temp file in /tmp with sanitized markers and restrictive permissions,
allowing the agent to read the rest via shell or read_file.
* 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>
Add workspace sharing card selector (isolated/shared) to team settings,
improving on the API-only configuration. Update workspace_read error
message to guide agents toward per-user scope fallback. Mark agent links
as deprecated with amber warning banner pointing to agent teams.
- Remove redundant max-w-* constraints from General, Credentials, Groups,
and Managers tabs so all tabs fill the parent container equally
- Refactor TelegramGroupFields to use ChannelFields with groupOverrideSchema
instead of manually rendered form fields
- Add tristate, textarea, tool-select, and skill-select field types to
ChannelFields renderer
- Create SkillNameSelect multi-select component (mirrors ToolNameSelect)
- Wire listManagerGroups into Groups tab for quick-add known groups
- Add i18n keys for knownGroups and selectOrTypeSkills (en/vi/zh)
Strengthen TEAM.md prompt with WRONG/CORRECT examples and NEVER wording
to stop models from calling `team_tasks create` before `spawn` in V2.
Prompt changes:
- V2 leads: explicit WRONG/CORRECT pattern, NEVER create before spawn
- V1 leads: separate workflow with manual create→spawn instructions
- team_tasks summary: de-emphasize "create", highlight auto-creation
- spawn team_task_id: clarify "omit to auto-create (recommended)"
Backend guards:
- Reject spawn with in-progress team_task_id (prevents reuse)
- Log warning on early claim race instead of silently ignoring
StorageHandler was hardcoded to browse ~/.goclaw/, which is empty in
Docker where volumes mount to separate paths (GOCLAW_WORKSPACE).
Use the already-resolved workspace variable so the Storage page
correctly shows workspace files regardless of deployment layout.
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.
Merge §5 (Memory Recall), §9 (Messaging), §12 (Silent Replies) from
hardcoded system prompt into AGENTS.md — single source of truth.
Add recency reinforcement at §16 to compensate for mid-prompt position.
Clean up SOUL.md and IDENTITY.md template duplication.
Saves ~175 tokens/turn across all LLM calls.
- Add VS Code/GitHub-inspired typography styles for markdown renderer
- Use JetBrains Mono/Fira Code font stack for code blocks and inline code
- Refine code block headers with uppercase labels and subtle borders
- Improve table styling with bordered cells and alternating row colors
- Add custom blockquote, heading, list, and horizontal rule styles
- Polish CSV viewer with consistent border and spacing treatments
Co-authored-by: Nam Nguyen Ngoc <namnn.0911@gmail.com>
* fix(agent): enrich <media:image> tags with persisted media IDs for Discord image attachments
Discord image attachments were downloaded and persisted correctly, but
<media:image> tags in the message content remained bare (no ID attribute),
unlike <media:audio> and <media:video> tags which get enriched with media
IDs. This made it harder for the LLM to confirm image receipt and
reference specific images.
Add enrichImageIDs() that embeds persisted media IDs into <media:image>
tags, matching the existing enrichAudioIDs()/enrichVideoIDs() pattern.
Iterates refs in reverse order to correctly map multiple image refs to
their positional tags when users attach several images at once.
Closes#178https://claude.ai/code/session_01KkE9UxcNB8eXpqRiJHRqeB
* style(agent): add missing continue in enrichImageIDs for consistency with enrichVideoIDs
https://claude.ai/code/session_01KkE9UxcNB8eXpqRiJHRqeB
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Viet Tran <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>
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.
Add card/list view toggle and owner filter dropdown to the agents page.
New AgentListRow component for compact list display. i18n keys added
for en, vi, zh locales.
Message tool prompting now explicitly tells the LLM not to use it for
replying to the user — prevents false activations on phrases like
"gởi lại cho tôi" (send it back to me).
Handoff tool disabled by default since it's rarely used and causes
confusion with spawn. Admins can re-enable via DB/UI if needed.
Agents were guessing absolute paths for file/exec tools, causing failed
tool calls and wasteful retries. Strengthen LLM guidance at three levels:
- System prompt: instruct to use relative paths, not guess absolute paths
- Tool param descriptions: mention workspace-relative resolution
- Subagent prompt: add missing workspace section with path guidance
- 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
Two related fixes:
1. Memory interceptor now resolves workspace from request context
(per-user workspace) instead of using the static global workspace.
This fixes memory writes with absolute paths under per-user
workspaces (e.g. workspace/channel/userID/memory/) being bypassed
and written to disk instead of the database, which also prevented
KG extraction, memory indexing, and cross-session recall.
2. KG extractor: increase max_tokens 4096→8192, add retry on
truncation (finish_reason=length), and support chunking for
long inputs with deduplication on merge.
Inject user follow-up messages into the running agent loop at turn
boundaries instead of queueing them for a new run. This preserves
context so the LLM sees both tool results and user follow-ups together.
- Add InjectedMessage type and drainInjectChannel helper
- Add InjectCh to ActiveRun with buffered channel (cap=5)
- Drain injection channel at two points in agent loop (after tool
results and before no-tool-calls exit)
- Route steer/new_task intents to InjectMessage with scheduler fallback
- WebSocket: inject into running loop when session is busy
- Remove IntentClassify config toggle (always on)
- Web UI: show send + stop buttons side by side during agent run
- i18n: add injection acknowledgment messages (en/vi/zh)
BuildContext() and GetEntries() only read from RAM, so after gateway
restart or LRU eviction the agent never saw pending group messages
despite them existing in the database. Add lazy loadFromDB() that
queries ListByKey on cache miss and populates RAM for subsequent calls.
Agent presets in the setup wizard and create dialog were hardcoded
in Vietnamese. This change moves them into the i18n catalog so they
follow the user's selected language.
- Replace static AGENT_PRESETS array with useAgentPresets() hook
that reads from the i18n catalog via useTranslation
- Add presets.foxSpirit / artisan / astrologer entries to
en/agents.json, vi/agents.json, and zh/agents.json
- Update step-agent.tsx and agent-create-dialog.tsx to use the hook
Co-authored-by: weirguo <weir_guo@foxmial.com>
Tasks can be created with require_approval flag, starting in
pending_approval status. Users approve/reject via tool actions or
WS methods. Approval respects blocked_by dependencies — tasks with
unresolved blockers transition to blocked instead of pending.
Delegate agents are restricted from approving/rejecting.
MessageTool.parseMediaPath() was hardcoded to only allow files in /tmp/,
while all other filesystem tools (read_file, write_file, edit, exec) use
workspace-aware resolvePath() with restrict_to_workspace enforcement.
This meant agents could create files in their workspace via write_file
but couldn't send them as attachments — only /tmp/ files from
create_image/create_audio worked.
Replace parseMediaPath() with resolveMediaPath() that:
- Reuses resolvePath() for consistent security (symlink, hardlink, traversal)
- Honors per-agent workspace + restrict_to_workspace from context
- Still allows /tmp/ as fallback (for create_image, create_audio, etc.)
- Supports relative paths resolved against workspace
- Updates tool description so LLM knows about MEDIA: prefix
Co-authored-by: Luvu182 <208665161+Luvu182@users.noreply.github.com>
Add domain context, coreference rules, controlled relation types (15 predefined),
few-shot example, and dynamic entity count (3-15). Increase max input from 6000
to 12000 chars, reduce max output tokens from 8192 to 4096.
Replace direct ActivityStore injection with event-driven audit system.
Handlers emit audit events via msgBus.Broadcast(), a single subscriber
with buffered channel persists to activity_logs table.
Coverage expanded from 3 agent CRUD actions to ~65 audit points across
all HTTP handlers and WebSocket RPC methods including agents, providers,
skills, MCP servers, cron, sessions, teams, pairing, and more.
Add independent `share_memory` config flag to control memory and
knowledge graph sharing separately from workspace folder isolation.
- Add ShareMemory field to WorkspaceSharingConfig
- Decouple WithSharedMemory(ctx) from shouldShareWorkspace() in loop.go
- Add shouldShareMemory() helper independent of workspace sharing
- Fix KG Traverse CTE to scope user_id in recursive step (pre-existing bug)
- Add memory toggle UI with violet styling in workspace sharing section
- Add i18n translations (en/vi/zh) for new memory sharing controls
- Add unit tests for shouldShareMemory() independence