Files
yatulandClaude Fable 5.1 60cf79de51 feat(teams): let a human cancel and retry stuck team tasks from the dashboard (#1559)
* feat(teams): let a human cancel and retry stuck team tasks from the dashboard

A task that ended up blocked, stale, failed or cancelled could not be
recovered from the UI: the dashboard only deletes terminal tasks and
approves/rejects in_review ones. CancelTask and ResetTaskStatus existed
in the store but were reachable only through the lead agent's team_tasks
tool, which needs the full task UUID the dashboard never shows (#506).

Two WS RPCs, wired to Retry / Cancel buttons in the task detail dialog:

- teams.tasks.cancel — any task not yet completed/cancelled. Optional
  reason is stored as the result and posted as a comment so the lead
  sees it on the board. Dependents are unblocked by the store; they are
  not dispatched here because the dashboard has no agent turn.
- teams.tasks.retry — stale / failed / cancelled / in_review, plus
  blocked tasks that nothing blocks any more. A human comment is
  required: it is posted on the task and appended to the assignment
  prompt, so the assignee gets the missing answer in the same message.
  Optional agentId reassigns; the lead is refused as assignee (same
  guard as teams.tasks.assign).

ResetTaskStatus (pg + sqlite) now also accepts blocked, guarded on the
handler side by an empty blocked_by. Handler tests cover both actions
with a stub store: reason/comment persistence, required comment,
status gating, blocked_by guard, lead guard, cross-team IDOR.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* fix(permissions): classify teams.tasks.cancel and teams.tasks.retry as write methods

Every WS method must be classified in internal/permissions/policy.go,
otherwise the router answers UNAUTHORIZED for every role. Caught on a
live gateway (the drift test TestMethodRole_DriftCoverage… flags it, I
had not run that package). Both sit next to approve/reject/assign as
operator-level write methods; the write-methods test now pins them.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* feat(teams): let the retry dialog pick the assignee

A cancelled or stale task may have no owner (created unassigned, or the
member was removed). teams.tasks.retry then needs agentId, which the
dialog did not send, so Retry would fail with "task has no assignee".
The retry dialog now shows an assignee select (team members minus the
lead, defaulting to the current owner) and passes agentId only when it
differs from the owner. Retry is offered only when there is someone to
pick.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-09 13:30:48 +07:00

17 KiB

Changelog

All notable changes to GoClaw are documented here. For full documentation, see docs.goclaw.sh.

Unreleased

Changed

  • Bitrix24 channel migrated to imbot v2 messaging API — outbound text now uses imbot.v2.Chat.Message.send (replacing imbot.message.add); bot verification/lookup uses imbot.v2.Bot.list (replacing imbot.bot.list + the legacy imbot.list fallback); bot teardown uses imbot.v2.Bot.unregister (replacing imbot.unregister). Bot registration intentionally stays on v1 imbot.register — v2 imbot.v2.Bot.register changes the event-delivery model (per-event handler URLs → eventMode), which would require rewriting the inbound event parser. No user-facing behavior change.

Added

  • Task detail dialog shows the full task UUID with one-click copy — the short identifier (T-015-cc8e) carries only the last four hex characters of the UUID, while the agent-facing team_tasks tool and RPCs take the full UUID, so a human had no way to name a task to the lead from the dashboard.

  • Dashboard can cancel and retry stuck team tasks — new WS RPCs teams.tasks.cancel (any task not yet completed/cancelled; optional reason is posted as a comment) and teams.tasks.retry (stale / failed / cancelled / in_review, and blocked tasks that nothing blocks any more; a human comment is required and is both posted on the task and appended to the assignment prompt). Task detail dialog gets Retry and Cancel buttons. Previously these transitions were reachable only through the lead agent's team_tasks tool, so a task that ended up blocked or stale could not be recovered from the UI (#506).

  • Behavior UX sidecar delivery overrides — Adds sidecar-generated Quick Acknowledgement and Intermediate Replies with provider/model, timeout, token, and char caps. Effective config resolves Channel > Agent > Workspace, with agent overrides stored in other_config.delivery_behavior.

  • Built-in skill workspace-organizing — closes #71. Discipline skill that teaches agents to keep personal, team, and delegate workspaces tidy. Enforces a purpose-based folder convention with two modes: flat (notes/, data/, outputs/, scripts/, archive/) for ad-hoc work and project (projects/<slug>/{docs,assets,source,reports,research}/) for named multi-file work. Per-agent namespacing under shared/<agent_key>/ prevents collisions in team workspaces. Integrates pre-write discovery via vault_search, memory_search, and knowledge_graph_search to surface related files before writing and avoid duplicates; documents Vault scope mirroring and id-routing rules.

  • Bitrix24 channel 2-way media (file) transfer — Inbound media downloads via imbot.v2.File.download (one-time authenticated URL) with MIME preservation for images, PDFs, audio, and video. Outbound uploads via imbot.v2.File.upload (base64). Shared media_max_mb config knob (default 20 MB) caps both directions. Requires imbot OAuth scope (no disk scope needed). Inbound handled by new internal/channels/bitrix24/download.go; outbound by send_media.go. New BaseChannel.HandleMessageMedia() method centralizes media-aware message handling. See docs/05-channels-messaging.md § 16 (Bitrix24) for configuration.

  • Skill agent manage grants — Adds per-agent skill edit/delete grants with backend checks, HTTP/WS support, SQLite and PostgreSQL schema updates, and web dashboard controls for granting and revoking manage access.

  • Packages Update Flow (Phase 2a: pip + npm) — closes #900 (Phase 2a). Extends Phase 1 update infrastructure to pip and npm package sources. /v1/packages/updates now returns mixed-source results with an availability: {github, pip, npm} map. Multi-source UI with per-source filter pills; unavailable sources (binary not on PATH or Lite edition) hidden automatically. apk deferred to Phase 2b. See docs/packages-pip-npm.md for command matrix, runbook, and min versions.

  • Packages Update Flow (Phase 1: GitHub binaries) — closes #900. Proactive "N updates available" badge + per-row [Update] + [Update All] on the Runtime & Packages page. Backend endpoints under /v1/packages/updates* (master-scope). ETag-aware polling (304 responses don't burn rate limit), stale-while-revalidate cache, atomic two-phase .bak swap with rollback. Pre-release detection via regex + GitHub API flag; semver ordering via golang.org/x/mod/semver; non-semver tags use string-inequality fallback with downgrade protection. WebSocket events package.update.* for owner clients. See docs/packages-github.md § "Updating Installed Packages".

Changed

  • Behavior UX simplification — Retires user-facing Tool Status Messages and deterministic tool-status channel text. Show Reasoning remains separate for debugging/testing, while Quick Acknowledgement and Intermediate Replies are delivery-only sidecar messages. Legacy block_reply config remains readable as an inherited Intermediate Replies default but is no longer exposed as a separate Web UI control.

  • ChatGPT Subscription (OAuth) — default model and backend-owned model catalog now prefer gpt-5.5, with reasoning metadata and context-window defaults updated for provider-first model selection.

Fixed

  • Quick Acknowledgement generated mode — Generated acknowledgements now use the sidecar delivery generator instead of always falling back to fixed templates. Sidecar failures stay non-blocking and fall back to templates.

  • Intermediate Replies are sidecar-generated — Tool-call progress no longer appends fixed "I'll use ..." text or relies on main-pipeline assistant content. Visible progress is generated from bounded delivery metadata and is kept out of session history.

  • Multi-attachment messages no longer trigger N agent replies (#63). Three coalescing surfaces hardened so a single user action produces ONE agent run regardless of how the platform delivers attachments:

    1. Bus debouncer — removed the media-bypass shortcut that fired immediately for any message with attachments; media now goes through the same per-(channel, chatID, senderID, agentID) silence window as text. Media-floor (max(configured, mediaFloor)) guarantees a minimum window when attachments are present so multi-file uploads coalesce. Dedup seed prevents the same MessageID from being buffered twice on bursty arrivals.
    2. Web Chat debouncer (internal/gateway/methods/chat_debounce.go) — parallel structure for /v1/chat/completions streaming: per-session buffer + media floor + Take/Discard semantics for flush/cancel control. Merges queued payloads at flush time (latest params win; text concatenated newline-separated).
    3. Telegram album aggregator (internal/channels/telegram/album_aggregator.go) — channel-layer coalescing for albums. Telegram delivers a media-group (multiple photos/videos shared as one user action) as N separate Message updates sharing a MediaGroupID. The aggregator buffers by (chatID, MediaGroupID) after all access gates pass, pins the sender on first arrival as a security tripwire, and dispatches ONE processResolvedMessage call with all members on a 500ms silence window. Stop() synchronously drains pending buffers before pollCancel so in-flight albums always publish.

    Cross-surface invariants (see CONTRIBUTING.md → "Multi-attachment coalescing"): no media bypass, media floor on every surface, drop-and-log dual caps, no time.Timer.Reset (use AfterFunc + Stop), sender pin on first arrival, post-stop pushes rejected with warn log.

  • Upstream critical security remediation — hardens gateway no-token fallback, Feishu/Lark and Pancake webhooks, sandbox path/write handling, tenant-admin checks for mutable HTTP surfaces, and Lite hook schema migration verification.

  • SecureCLI runtime npm binaries — binary discovery and credentialed exec now resolve tools installed under the GoClaw runtime directories, including {runtimeDir}/npm-global/bin, and support single-binary npm package aliases such as openrouter-cli exposing orc.

Breaking Changes

  • Context pruning now opt-in. Previously tool-result trimming ran by default for all providers; now requires explicit contextPruning.mode: "cache-ttl" in config.agents.defaults to enable. Matches upstream TS design and prevents silent prompt-cache invalidation on Anthropic.

    Migration — add to config.json5:

    agents: {
      defaults: {
        contextPruning: { mode: "cache-ttl" }
      }
    }
    

New Features

  • Pancake private-reply (comment → DM). Enables a one-time DM to commenters after the public reply. Stateless on GoClaw side — no DB dedup table, no in-memory state:
    • Config: features.private_reply (bool) + private_reply_message (text).
    • Template variables {{commenter_name}} and {{post_title}} with literal-replace semantics (pre-sanitizes {{/}} from var values to prevent var-in-var substitution).
    • Empty private_reply_message → English fallback constant.
    • Dedup strategy: webhook-level comment_id dedup (already in comment_handler.go) + Facebook's per-comment idempotent private_replies endpoint handle duplicates platform-side. No GoClaw state required.
    • No DB migration.

Improvements

  • Context pruning cleanup. Removed redundant Pass 0 (per-result 30% guard), deduplicated double prune call per iteration, added SanitizeHistory to PruneStage for broken tool_use/tool_result pair cleanup.
  • Context pruning config backfill (migration). Agents with existing custom context_pruning config (e.g., softTrimRatio, keepLastAssistants) but missing a mode field get auto-backfilled with mode: "cache-ttl" to preserve their intent after the opt-in flip. Rows with NULL config stay NULL (new opt-in default applies). PG migration 51; SQLite schema v19.
  • Pancake channel metadata routing. Whitelist in internal/channels/routing_metadata.go now preserves post_id and display_name across the inbound → outbound hop so the private-reply template variables survive the agent pipeline round-trip.

Fixed

  • Skill grant tenant isolation. Agent skill grants now validate both the skill and agent tenant scope before insert, revoke, grant listing, or can-manage checks. Visibility auto-promote/auto-demote updates are scoped to the calling tenant or system skills so one tenant cannot mutate another tenant's skill.

  • Agent provider switching. Saving an agent after changing provider/model now handles cleared ChatGPT OAuth routing config without writing SQL NULL into NOT NULL JSON config columns.

Project Status

Implemented & Tested in Production

  • Agent management & configuration — Create, update, delete agents via API and web dashboard. Agent types (open / predefined), agent routing, and lazy resolution all tested.
  • Telegram channel — Full integration tested: message handling, streaming responses, rich formatting (HTML, tables, code blocks), reactions, media, chunked long messages.
  • Seed data & bootstrapping — Auto-onboard, DB seeding, migration pipeline tested end-to-end.
  • User-scope & content files — Per-user context files (user_context_files), agent-level context files (agent_context_files), virtual FS interceptors, per-user seeding (SeedUserFiles), and user-agent profile tracking all implemented and tested.
  • Core built-in tools — File system tools (read_file, write_file, edit_file, list_files, search, glob), shell execution (exec), web tools (web_search, web_fetch), and session management tools tested in real agent loops.
  • Memory system — Long-term memory with pgvector hybrid search (FTS + vector) implemented and tested with real conversations.
  • Agent loop — Think-act-observe cycle, tool use, session history, auto-summarization, and subagent spawning tested in production.
  • WebSocket RPC protocol (v3) — Connect handshake, chat streaming, event push all tested with web dashboard and integration tests.
  • Store layer (PostgreSQL) — All PG stores (sessions, agents, providers, skills, cron, pairing, tracing, memory, teams) implemented and running.
  • Browser automation — Rod/CDP integration for headless Chrome, tested in production agent workflows.
  • Lane-based scheduler — Main/subagent/team/cron lane isolation with concurrent execution tested. Group chats support up to 3 concurrent agent runs per session with adaptive throttle and deferred session writes for history isolation.
  • Security hardening — Rate limiting, prompt injection detection, CORS, shell deny patterns, SSRF protection, credential scrubbing all implemented and verified.
  • Web dashboard — Channel management, agent management, pairing approval, traces & spans viewer, skills, MCP, cron, sessions, teams, and config pages all implemented and working.
  • Prompt caching — Anthropic (explicit cache_control), OpenAI/MiniMax/OpenRouter (automatic). Cache metrics tracked in trace spans and displayed in web dashboard.
  • Agent delegation — Inter-agent task delegation with permission links, sync/async modes, per-user restrictions, concurrency limits, and hybrid agent search. Tested in production.
  • Agent teams — Team creation with lead/member roles, shared task board (create, claim, complete, search, blocked_by dependencies), team mailbox (send, broadcast, read). Tested in production.
  • Evaluate loop — Generator-evaluator feedback cycles with configurable max rounds and pass criteria. Tested in production.
  • Delegation history — Queryable audit trail of inter-agent delegations. Tested in production.
  • Skill system — BM25 search, ZIP upload, SKILL.md parsing, and embedding hybrid search. Tested in production.
  • MCP integration — stdio, SSE, and streamable-http transports with per-agent/per-user grants. Tested in production.
  • Cron scheduling — at, every, and cron expression scheduling. Tested in production.
  • Docker sandbox — Isolated code execution in containers. Tested in production.
  • Text-to-Speech — OpenAI, ElevenLabs, Edge, MiniMax providers. Tested in production.
  • HTTP API — /v1/chat/completions, /v1/agents, /v1/skills, etc. Tested in production. Interactive Swagger UI at /docs.
  • API key management — Multi-key auth with RBAC scopes, SHA-256 hashed storage, show-once pattern, optional expiry, revocation. HTTP + WebSocket CRUD. Web UI for management.
  • Hooks system — Event-driven hooks with command evaluators (shell exit code) and agent evaluators (delegate to reviewer). Blocking gates with auto-retry and recursion-safe evaluation.
  • Media tools — create_image (DashScope, MiniMax), create_audio (OpenAI, ElevenLabs, MiniMax, Suno), create_video (MiniMax, Veo), read_document (Gemini File API), read_image, read_audio, read_video. Persistent media storage with lazy-loaded MediaRef.
  • Additional provider modes — Claude CLI (Anthropic via stdio + MCP bridge), Codex (OpenAI gpt-5.3-codex via OAuth).
  • Google Cloud Vertex AI provider — Enterprise GCP integration via Vertex OpenAI-compatible endpoint. OAuth2 service account auth (inline JSON or file path) with automatic token refresh, plus Application Default Credentials (ADC) for GKE/Cloud Run/Compute Engine. Regional endpoints for data residency (e.g. asia-southeast1, us-central1). Addresses #576.
  • Knowledge graph — LLM-powered entity extraction, graph traversal, force-directed visualization, and knowledge_graph_search agent tool.
  • Memory management — Admin dashboard for memory documents (CRUD, semantic search, chunk/embedding details, bulk re-indexing).
  • Persistent pending messages — Channel messages persisted to PostgreSQL with auto-compaction (LLM summarization) and monitoring dashboard.
  • Heartbeat system — Periodic agent check-ins via HEARTBEAT.md checklists with suppress-on-OK, active hours, retry logic, and channel delivery.

Implemented but Not Fully Tested

  • Slack — Channel integration implemented, not yet validated with real users.
  • Other messaging channels — Discord, Zalo OA, Zalo Personal, Feishu/Lark, WhatsApp channel adapters are implemented but have not been tested end-to-end in production. Only Telegram has been validated with real users.
  • OpenTelemetry export — OTLP gRPC/HTTP exporter implemented (build-tag gated). In-app tracing works; external OTel export not validated in production.
  • Tailscale integration — tsnet listener implemented (build-tag gated). Not tested in a real deployment.
  • Redis cache — Optional distributed cache backend (build-tag gated). Not tested in production.
  • Browser pairing — Pairing code flow implemented with CLI and web UI approval. Basic flow tested but not validated at scale.