Skip to content

feat(team-work): one-call LLM routing classifier with native DAG orchestration - #1495

Open
nguyenha935 wants to merge 1 commit into
nextlevelbuilder:devfrom
nguyenha935:feat/team-work-native-orchestration
Open

feat(team-work): one-call LLM routing classifier with native DAG orchestration#1495
nguyenha935 wants to merge 1 commit into
nextlevelbuilder:devfrom
nguyenha935:feat/team-work-native-orchestration

Conversation

@nguyenha935

Copy link
Copy Markdown
Contributor

Summary

Complete Team Work orchestration feature: a single LLM routing call classifies each new request (self / single_owner / multi_role, plus an independent-review decision) and executes multi-agent work on GoClaw's native DAG, lease/retry, finalize and exactly-once delivery — with no duplicate scheduler and no embedding requirement. This is the full feature developed and validated across prior phases; the final phase removed the classifier's embedding dependency.

Type

  • Feature
  • Bug fix
  • Hotfix (targeting main)
  • Refactor
  • Docs
  • CI/CD

Target Branch

dev

What's included

Classifier (one LLM call before execution)

  • internal/teamworkclassify/ClassifyRouteWithLLM makes exactly one routing LLM call (routing.go), producing decision (self/team), workflow_mode (self/single_owner/multi_role), and review_required. Roster/tool profiles feed the prompt from stores (context.go, roster.go); planner.go validation and shape.go retained for stored workflows.
  • internal/providerresolve/team_work_classifier.go — per-tenant provider/model override resolution.
  • internal/teamworkconfig/ — per-tenant classifier settings resolver (enable/provider/model/timeout), replacing the cross-tenant shared-cfg overlay.

Native DAG execution (no duplicate scheduler)

  • Migrations 96 (team_workflows), 97 (team_task_notification_policy), 98 (team_work_enforcement); RequiredSchemaVersion bumped to 98.
  • internal/store/pg/ + internal/store/sqlitestore/team_workflows, team_workflows_actions, team_workflows_recovery, team_workflows_attempt, team_work_classification_audits (dual-DB parity).
  • internal/tools/team_tasks_create_dag.go — DAG creation over team_tasks.blocked_by; independent-review enforcement in validateReviewTasks (fail-closed when review_required=false but a review task is declared).
  • cmd/gateway_workflow_finalize.go, cmd/gateway_workflow_recovery.go — finalize and blocker-recovery runs, enqueued onto the native scheduler (scheduler.LaneSubagent), not a private scheduler.

Scheduler / dispatch / finalize integration (changed, accurately described)

  • internal/scheduler/ — added a scheduler-owned PreExecute dequeue hook and a single-pump ordered FIFO admission (queue.go) with lane-submit serialization and a shutdown race guard in lanes.go. These are extensions to the existing Scheduler struct; there is exactly one Scheduler type in the tree — no duplicate scheduler is introduced.
  • internal/pipeline/ — finalize/think/tool/prune stage hooks carrying AbortReason and empty-response fallback so a failed/aborted run cannot wedge an agent.
  • internal/providers/EmptyResponseError invariant, FailoverSummaryError.Unwrap, and retry classification so a dead stream no longer reads as a successful empty answer.
  • internal/channels/dispatch.go + internal/bus/types.goDeliveryAck + EventID for bounded at-least-once transport with receiver dedup; durable retry state stays in the workflow store.
  • Exactly-once: finalize_token/finalize_lease_until/finalized_at and delivery_token/delivery_status/delivered_at CAS columns (migration 98).

Embedding decoupling (final phase)

  • Removed Embedder/Evidence/TeamWorkEmbedder plumbing and dead compatibility fields (SelfScore, CollaborationScore, EmbeddingAvailable/Reason, CloseMargin, TeamThreshold, DefaultCloseMargin, defaultTeamThreshold, defaultEvidenceTimeout) from the classifier and all gateway/cmd wiring.
  • UI: removed the embedding gate on the Team Work switch (behavior-ux-card.tsx, system-settings-modal.tsx).
  • Locales (en/vi/zh/ko/ru, config + system-settings): Team Work now described as one-call LLM routing; removed the embedding-required key.

Retained, intentionally unchanged

  • setupMemoryEmbeddings (memory, KG, vault, skill, semantic task search) and useEmbeddingStatus UI consumers.
  • planner.go stored-workflow validation; the native Scheduler core; dispatch/lease primitives.

UI / config / API / locales / tests

  • Web + desktop team board UI, workflow action dialog, pkg/protocol team events/methods, permissions policy entries, i18n catalogs (5 locales).
  • New focused tests: nil-embedder / enabled-toggle classifier coverage, BehaviorUxCard render+click regression (mutation-verified).

Not included (kept out of this PR)

Dockerfile, go.mod, SHA256SUMS.txt, internal/agent/extractive_memory{,_vi_test}.go, internal/providers/defaults{,_timeout_test}.go — infra/separate-patch files, left untouched in the worktree.

Checklist

  • go build ./... passes
  • go build -tags sqliteonly ./... passes
  • go vet ./... passes
  • Tests pass: go test -race ./...see note below
  • Web UI builds: cd ui/web && pnpm build
  • No hardcoded secrets or credentials
  • SQL queries use parameterized $1, $2
  • New user-facing strings added to all locales (en/vi/zh + ko/ru)
  • Migration version bumped in internal/upgrade/version.go (96→98)

go test -race ./... note (disclosed, not hidden)

-race reports zero DATA RACE anywhere. Three packages did not complete green under -race in the local container:

  1. internal/gateway/methodsTestTurnIntegration_CancelledRunProducesNoResult: timing flake — a fixed 2s wait for the run to reach its agent turn expires under race instrumentation overhead; passes without -race (ok ... 11.0s). No data race.
  2. internal/hooks/handlers: signal: killed (container resource/timeout), unrelated to this feature.
  3. internal/http: 5 Ollama model tests fail on host.docker.internal DNS resolution — environment-only in this container; known to pass on CI.

All non-race builds, go vet, and the feature package tests are green.

Test Plan

  • go build ./..., go build -tags sqliteonly ./..., go vet, targeted go test (teamworkclassify, teamworkconfig, gateway/methods, config, cmd, tools, agent) — all pass.
  • pnpm install --frozen-lockfile (lockfile byte-identical), pnpm test (60 files / 375 tests), pnpm build — all pass.

Immutable deployment + rollback (live host)

  • Built immutable image goclaw-runtime:embedding-decoupled-20260802 (sha256:59261928…) from this worktree with embedded UI; rollback tag goclaw-runtime:rollback-pre-embedding-decoupled-20260802 pinned to the previously running sha256:67ddf3dcce70.
  • Recreated only the GoClaw service (--no-deps); PostgreSQL untouched — container f7d88d07b81b, StartedAt 2026-07-31T11:23:44Z unchanged.
  • Post-deploy gates: health {"status":"ok","protocol":3}, schema 98 | dirty=false, UI GET / → 200.

Live T1–T4 classifier matrix (one decision log per session)

Session effective_mode review decision logs
smoke-embdec-t1 self f 1
smoke-embdec-t2 multi_role t 1
smoke-embdec-t3 single_owner f 1
smoke-embdec-t4 multi_role f 1

Exactly one classifier decision log per session (audit count 293 → 297). DAG review-task proof: T2 has 1 review task / 4 tasks; T4 has 0 review tasks / 3 tasksreview_required=false produces no review task.

@nguyenha935
nguyenha935 force-pushed the feat/team-work-native-orchestration branch from e652d58 to dcc8ad6 Compare August 2, 2026 12:33
@nguyenha935
nguyenha935 marked this pull request as ready for review August 2, 2026 13:37
@clark-cant clark-cant added the pr:oversized PR too large for bounded cron review label Aug 2, 2026
…ution

Team Work enforcement: a single classification call decides self /
single_owner / multi_role plus independent review, executing through the
native GoClaw DAG, lease/retry, finalize and exactly-once delivery. No
duplicate scheduler; no embedding requirement for the classifier.

Rebased onto current dev: SQLite migrations renumbered to 60-62
(schema_version 63), Postgres migrations 000098-100 (live DB migrated
99->100 cleanly, dirty=false).

Delivery fixes validated live (v3.15.0-beta.197-patch.8bf57ec3a4):
- workflow finalize forwards terminal-task attachments as outbound media
  so requested files reach the user channel instead of being dropped;
- terminal integration step returns the full markdown answer with
  newlines/formatting preserved instead of a collapsed one-liner.

Live e2e on bao-an: 3-node gold-price run (research -> draft -> QA)
completed, QA issues fixed by lead, markdown report written and final
answer delivered with correct formatting; all 3 task attachments
recorded in team_task_attachments; health gate and channels OK.
@nguyenha935
nguyenha935 force-pushed the feat/team-work-native-orchestration branch from dcc8ad6 to b91917d Compare August 23, 2026 03:15
@nguyenha935

Copy link
Copy Markdown
Contributor Author

Update: rebased onto current dev + delivery fixes validated live

Head: b91917d (rebased on fc8a35e = dev tip)

What changed in this force-push

  • Rebase onto current dev: SQLite migrations renumbered to 60-62 (schema_version 63); Postgres migrations 000098-000100. Live DB migrated 99 to 100 cleanly (dirty=false).
  • Delivery fix 1 (attachments dropped): workflow finalize now forwards terminal-task attachments as outbound media (workflowDeliveryMedia -> OutboundMessage.Media), so requested files actually reach the user channel.
  • Delivery fix 2 (formatting collapsed): the terminal integration step now returns the full markdown answer with newlines and formatting preserved instead of a flattened one-liner.

Live e2e validation (VPS, v3.15.0-beta.197-patch.8bf57ec3a4)

  • Multi-role request routed through the one-call classifier then executed on the native GoClaw DAG (no duplicate scheduler): research SJC/ring gold prices -> draft markdown report -> independent QA.
  • QA found real issues (product mis-classification, unit mixing, timestamp mismatch); lead fixed them and completed the turn.
  • Final answer delivered with full markdown formatting; report file written to agent workspace; all 3 task attachments recorded in team_task_attachments.
  • Health gate passed after deploy; channels connected; runtime invariants intact (node/npm/python3/pip3/psql/pg_dump).

Verification

  • Patch applies cleanly on pristine dev tip (git apply --check PASS).
  • sqlitestore suite green after migration renumbering; go/web/release-versioning were green on the previous head; this push only rebases + amends the commit message (same tree content as deployed patch, byte-identical diff vs the running build's patch file).

@clark-cant clark-cant left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maintainer reviewnnVerdict: Request changesnnThis PR is clean and the three CI checks are green, but it remains too large to approve safely as one change: 323 files and +40,435/-1,953 lines alter routing, scheduler admission, workflow persistence/recovery, delivery semantics, pipeline lifecycle, gateway behavior, API/protocol, UI, migrations, and locales together. This prevents a reliable review or rollback boundary.nnPlease split it into independently buildable, testable PRs (at minimum: schema/store migrations; classifier/config; native DAG/workflow execution; scheduler/pipeline lifecycle; delivery semantics; UI/protocol). Each PR should carry focused integration tests and a clear compatibility/rollback statement. The current branch should be rebased/sliced without mixing unrelated lifecycle and delivery changes with the Team Work feature.nnMandatory gatesn- Duplicate/prior work: no duplicate found in metadata review.n- Project standards: CI green, but focused reviewability and release safety are not met.n- Strategic necessity: plausible high value, but the combined operational blast radius is too high.nnPosted by github-maintain at 2026-08-23T05:53:19Z

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr:oversized PR too large for bounded cron review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants