Commit Graph

15 Commits

Author SHA1 Message Date
viettranx 0df619023c feat(tools): block binary in read_file, add workspace path to read_image
- read_file: reject binary files (images, audio, video, archives) with
  helpful error pointing to the correct specialized tool
- read_image: add optional `path` parameter to analyze workspace/generated
  images via vision API (with workspace restriction + denied path checks)
2026-03-19 13:35:57 +07:00
viettranx 8d7259f637 feat(tools): add team workspace context + WorkspaceInterceptor + file tools access
- Add WithToolTeamWorkspace/ToolTeamWorkspaceFromCtx context key for
  team workspace path (accessible but not necessarily default)
- Create WorkspaceInterceptor for team-specific write validation
  (RBAC, quota, blocked extensions, event broadcasting)
- File tools (read_file, write_file, list_files, edit) allow access
  to team workspace via allowedWithTeamWorkspace() helper
- read_file/list_files hint team workspace path when file not found
- Registry detects empty tool call args and returns actionable hint
  (DashScope/Qwen large-output truncation workaround)
2026-03-16 20:05:42 +07:00
Viet Tran 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 52c56978c5 fix(tools): improve workspace path guidance to reduce LLM path guessing
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
2026-03-13 13:51:37 +07:00
Luan Vu 2fdb791802 fix: honor per-agent DB settings for restrict, subagents, memory, sandbox (#145)
Four per-agent settings stored in the database (and configurable via UI)
were silently ignored at runtime because the tool/system layer always
used the global config defaults instead.

**restrict_to_workspace**: Tools used the global config default baked at
startup. Fix: pass per-agent value through context; tools check context
override before falling back to constructor default.

**subagents_config**: ParseSubagentsConfig() existed but was never called.
All agents shared one SubagentManager with global limits. Fix: resolve
per-agent config in the agent resolver, store it on each spawned task,
and use it for limit checks, deny lists, and system prompt generation.

**memory_config**: Only the enabled toggle was read per-agent; search
weights (vector_weight, text_weight, max_results, min_score) were
hardcoded from PGMemoryStore defaults. Fix: extend MemorySearchOptions
with weight overrides, read per-agent config from context in the
memory_search tool.

**sandbox_config**: Only workspace_access was extracted per-agent; mode,
image, memory, CPU, timeout, network settings were discarded. Fix: pass
full sandbox.Config through context; Manager.Get() accepts an optional
config override for new containers.

Co-authored-by: Luvu182 <208665161+Luvu182@users.noreply.github.com>
2026-03-11 16:05:56 +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
Viet Tran 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
viettranx 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 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
viettranx 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 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 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 67b19e4746 feat: Implement standalone gateway mode with file-based agent storage and add path denial capabilities to filesystem tools. 2026-02-25 10:07:25 +07:00
viettranx 08ced252b2 feat: Introduce agent summoning flow with a dedicated modal and updated bootstrap process for predefined agents. 2026-02-24 10:19:49 +07:00
Viet Tran f3f4c67b36 Initial commit: GoClaw AI agent gateway
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>
2026-02-22 14:58:07 +07:00