@vellumai/assistant 0.5.6 → 0.5.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +16 -2
- package/ARCHITECTURE.md +6 -75
- package/Dockerfile +3 -2
- package/README.md +0 -2
- package/bun.lock +0 -414
- package/docker-entrypoint.sh +9 -0
- package/docs/architecture/keychain-broker.md +45 -240
- package/docs/architecture/memory.md +13 -11
- package/docs/architecture/security.md +0 -17
- package/docs/credential-execution-service.md +2 -2
- package/node_modules/@vellumai/ces-contracts/package.json +1 -0
- package/node_modules/@vellumai/ces-contracts/src/error.ts +1 -1
- package/node_modules/@vellumai/ces-contracts/src/grants.ts +1 -1
- package/node_modules/@vellumai/ces-contracts/src/handles.ts +1 -1
- package/node_modules/@vellumai/ces-contracts/src/index.ts +1 -1
- package/node_modules/@vellumai/ces-contracts/src/rpc.ts +120 -1
- package/node_modules/@vellumai/credential-storage/package.json +1 -0
- package/node_modules/@vellumai/egress-proxy/package.json +1 -0
- package/package.json +2 -3
- package/src/__tests__/actor-token-service.test.ts +0 -114
- package/src/__tests__/approval-cascade.test.ts +0 -1
- package/src/__tests__/assistant-feature-flags-integration.test.ts +30 -29
- package/src/__tests__/browser-fill-credential.test.ts +1 -1
- package/src/__tests__/browser-skill-endstate.test.ts +6 -5
- package/src/__tests__/btw-routes.test.ts +0 -39
- package/src/__tests__/call-controller.test.ts +0 -1
- package/src/__tests__/call-domain.test.ts +0 -128
- package/src/__tests__/ces-rpc-credential-backend.test.ts +199 -0
- package/src/__tests__/ces-startup-timeout.test.ts +40 -0
- package/src/__tests__/channel-approval-routes.test.ts +0 -5
- package/src/__tests__/channel-readiness-service.test.ts +1 -60
- package/src/__tests__/checker.test.ts +4 -2
- package/src/__tests__/cli-command-risk-guard.test.ts +112 -0
- package/src/__tests__/config-schema-cmd.test.ts +0 -2
- package/src/__tests__/config-schema.test.ts +3 -1
- package/src/__tests__/conversation-abort-tool-results.test.ts +0 -1
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +0 -2
- package/src/__tests__/conversation-agent-loop.test.ts +2 -4
- package/src/__tests__/conversation-attention-telegram.test.ts +0 -5
- package/src/__tests__/conversation-confirmation-signals.test.ts +0 -1
- package/src/__tests__/conversation-error.test.ts +15 -1
- package/src/__tests__/conversation-init.benchmark.test.ts +0 -2
- package/src/__tests__/conversation-messaging-secret-redirect.test.ts +1 -1
- package/src/__tests__/conversation-pre-run-repair.test.ts +0 -1
- package/src/__tests__/conversation-provider-retry-repair.test.ts +0 -1
- package/src/__tests__/conversation-queue.test.ts +0 -1
- package/src/__tests__/conversation-skill-tools.test.ts +0 -54
- package/src/__tests__/conversation-slash-queue.test.ts +0 -1
- package/src/__tests__/conversation-slash-unknown.test.ts +0 -1
- package/src/__tests__/conversation-title-service.test.ts +87 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +0 -1
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +0 -1
- package/src/__tests__/credential-execution-client.test.ts +5 -2
- package/src/__tests__/credential-execution-feature-gates.test.ts +59 -30
- package/src/__tests__/credential-execution-managed-contract.test.ts +35 -20
- package/src/__tests__/credential-security-e2e.test.ts +1 -67
- package/src/__tests__/credential-security-invariants.test.ts +6 -50
- package/src/__tests__/credentials-cli.test.ts +82 -3
- package/src/__tests__/daemon-credential-client.test.ts +123 -0
- package/src/__tests__/db-migration-rollback.test.ts +2015 -1
- package/src/__tests__/deterministic-verification-control-plane.test.ts +1 -0
- package/src/__tests__/docker-signing-key-bootstrap.test.ts +34 -143
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +6 -4
- package/src/__tests__/gateway-client-managed-outbound.test.ts +79 -1
- package/src/__tests__/guardian-routing-state.test.ts +0 -5
- package/src/__tests__/host-shell-tool.test.ts +6 -7
- package/src/__tests__/http-user-message-parity.test.ts +3 -103
- package/src/__tests__/inbound-invite-redemption.test.ts +0 -4
- package/src/__tests__/inline-skill-load-permissions.test.ts +6 -8
- package/src/__tests__/intent-routing.test.ts +0 -13
- package/src/__tests__/jobs-store-qdrant-breaker.test.ts +178 -0
- package/src/__tests__/journal-context.test.ts +335 -0
- package/src/__tests__/keychain-broker-client.test.ts +161 -22
- package/src/__tests__/memory-context-benchmark.benchmark.test.ts +0 -3
- package/src/__tests__/memory-jobs-worker-backoff.test.ts +150 -0
- package/src/__tests__/memory-lifecycle-e2e.test.ts +70 -25
- package/src/__tests__/memory-recall-quality.test.ts +48 -17
- package/src/__tests__/memory-regressions.test.ts +408 -363
- package/src/__tests__/memory-retrieval.benchmark.test.ts +0 -3
- package/src/__tests__/migration-export-http.test.ts +2 -2
- package/src/__tests__/migration-import-commit-http.test.ts +2 -2
- package/src/__tests__/migration-import-preflight-http.test.ts +2 -2
- package/src/__tests__/migration-validate-http.test.ts +2 -2
- package/src/__tests__/non-member-access-request.test.ts +2 -7
- package/src/__tests__/notification-decision-fallback.test.ts +4 -0
- package/src/__tests__/notification-decision-identity.test.ts +4 -0
- package/src/__tests__/notification-decision-strategy.test.ts +71 -0
- package/src/__tests__/oauth-cli.test.ts +5 -1
- package/src/__tests__/permission-types.test.ts +1 -0
- package/src/__tests__/provider-commit-message-generator.test.ts +0 -37
- package/src/__tests__/provider-error-scenarios.test.ts +0 -267
- package/src/__tests__/provider-managed-proxy-integration.test.ts +5 -6
- package/src/__tests__/provider-streaming.benchmark.test.ts +2 -81
- package/src/__tests__/qdrant-manager.test.ts +28 -2
- package/src/__tests__/registry.test.ts +0 -6
- package/src/__tests__/relay-server.test.ts +1 -2
- package/src/__tests__/runtime-attachment-metadata.test.ts +0 -4
- package/src/__tests__/script-proxy-injection-runtime.test.ts +1 -1
- package/src/__tests__/secret-onetime-send.test.ts +1 -1
- package/src/__tests__/secret-routes-managed-proxy.test.ts +0 -4
- package/src/__tests__/secure-keys.test.ts +95 -272
- package/src/__tests__/shell-identity.test.ts +96 -6
- package/src/__tests__/skill-feature-flags-integration.test.ts +22 -14
- package/src/__tests__/skill-feature-flags.test.ts +46 -45
- package/src/__tests__/skill-load-feature-flag.test.ts +7 -10
- package/src/__tests__/skill-load-inline-command.test.ts +8 -12
- package/src/__tests__/skill-load-inline-includes.test.ts +6 -10
- package/src/__tests__/skill-load-tool.test.ts +0 -2
- package/src/__tests__/skill-memory.test.ts +17 -3
- package/src/__tests__/skill-projection-feature-flag.test.ts +33 -29
- package/src/__tests__/skills.test.ts +0 -2
- package/src/__tests__/slack-inbound-verification.test.ts +0 -4
- package/src/__tests__/stale-approval-dedup.test.ts +171 -0
- package/src/__tests__/stt-hints.test.ts +437 -0
- package/src/__tests__/suggestion-routes.test.ts +1 -32
- package/src/__tests__/system-prompt.test.ts +0 -1
- package/src/__tests__/task-memory-cleanup.test.ts +14 -0
- package/src/__tests__/tool-executor-shell-integration.test.ts +5 -3
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +0 -5
- package/src/__tests__/trusted-contact-multichannel.test.ts +0 -4
- package/src/__tests__/twilio-routes-twiml.test.ts +139 -1
- package/src/__tests__/update-bulletin.test.ts +0 -2
- package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +6 -9
- package/src/__tests__/voice-quality.test.ts +58 -0
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +0 -7
- package/src/__tests__/workspace-migration-015-migrate-credentials-to-keychain.test.ts +252 -0
- package/src/__tests__/workspace-migration-016-migrate-credentials-from-keychain.test.ts +220 -0
- package/src/__tests__/workspace-migration-down-functions.test.ts +1009 -0
- package/src/__tests__/workspace-migrations-runner.test.ts +114 -0
- package/src/acp/agent-process.ts +9 -1
- package/src/agent/loop.ts +1 -1
- package/src/approvals/guardian-request-resolvers.ts +164 -38
- package/src/calls/__tests__/tts-text-sanitizer.test.ts +254 -0
- package/src/calls/audio-store.test.ts +97 -0
- package/src/calls/audio-store.ts +205 -0
- package/src/calls/call-controller.ts +90 -8
- package/src/calls/call-domain.ts +3 -0
- package/src/calls/call-store.ts +10 -3
- package/src/calls/fish-audio-client.ts +129 -0
- package/src/calls/relay-server.ts +27 -0
- package/src/calls/stt-hints.ts +189 -0
- package/src/calls/tts-text-sanitizer.ts +61 -0
- package/src/calls/twilio-routes.ts +34 -5
- package/src/calls/types.ts +1 -0
- package/src/calls/voice-ingress-preflight.ts +0 -42
- package/src/calls/voice-quality.ts +38 -5
- package/src/calls/voice-session-bridge.ts +7 -12
- package/src/cli/commands/avatar.ts +2 -2
- package/src/cli/commands/config.ts +1 -4
- package/src/cli/commands/credentials.ts +128 -82
- package/src/cli/commands/doctor.ts +2 -2
- package/src/cli/commands/keys.ts +7 -7
- package/src/cli/commands/memory.ts +1 -1
- package/src/cli/commands/oauth/connections.ts +11 -29
- package/src/cli/commands/oauth/index.ts +7 -0
- package/src/cli/commands/oauth/platform.ts +525 -0
- package/src/cli/commands/platform.ts +3 -3
- package/src/cli/lib/daemon-credential-client.ts +284 -0
- package/src/cli.ts +1 -1
- package/src/config/assistant-feature-flags.ts +186 -5
- package/src/config/bundled-skills/AGENTS.md +34 -0
- package/src/config/bundled-skills/acp/SKILL.md +10 -0
- package/src/config/bundled-skills/app-builder/SKILL.md +0 -4
- package/src/config/bundled-skills/messaging/SKILL.md +5 -5
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +2 -2
- package/src/config/bundled-skills/phone-calls/TOOLS.json +4 -0
- package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +1 -0
- package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +1 -0
- package/src/config/bundled-skills/settings/SKILL.md +15 -2
- package/src/config/bundled-skills/settings/TOOLS.json +47 -2
- package/src/config/bundled-skills/settings/tools/avatar-remove.ts +59 -0
- package/src/config/bundled-skills/settings/tools/avatar-update.ts +80 -0
- package/src/config/bundled-skills/settings/tools/voice-config-update.ts +42 -0
- package/src/config/bundled-skills/slack/SKILL.md +1 -1
- package/src/config/bundled-tool-registry.ts +5 -11
- package/src/config/defaults.ts +0 -2
- package/src/config/env-registry.ts +5 -5
- package/src/config/env.ts +21 -14
- package/src/config/feature-flag-registry.json +49 -9
- package/src/config/loader.ts +106 -42
- package/src/config/schema.ts +9 -29
- package/src/config/schemas/calls.ts +30 -0
- package/src/config/schemas/fish-audio.ts +39 -0
- package/src/config/schemas/inference.ts +2 -2
- package/src/config/schemas/journal.ts +16 -0
- package/src/config/schemas/memory-processing.ts +2 -2
- package/src/config/schemas/security.ts +0 -4
- package/src/config/types.ts +1 -1
- package/src/contacts/contact-store.ts +39 -0
- package/src/contacts/types.ts +2 -0
- package/src/credential-execution/approval-bridge.ts +1 -0
- package/src/credential-execution/executable-discovery.ts +28 -4
- package/src/credential-execution/feature-gates.ts +16 -0
- package/src/credential-execution/process-manager.ts +38 -0
- package/src/credential-execution/startup-timeout.ts +36 -0
- package/src/daemon/approval-generators.ts +3 -9
- package/src/daemon/assistant-attachments.ts +9 -0
- package/src/daemon/config-watcher.ts +5 -0
- package/src/daemon/conversation-error.ts +13 -1
- package/src/daemon/conversation-memory.ts +1 -2
- package/src/daemon/conversation-process.ts +18 -1
- package/src/daemon/conversation-surfaces.ts +30 -1
- package/src/daemon/conversation-tool-setup.ts +0 -105
- package/src/daemon/conversation.ts +21 -1
- package/src/daemon/guardian-action-generators.ts +3 -9
- package/src/daemon/handlers/config-vercel.ts +92 -0
- package/src/daemon/handlers/skills.ts +2 -15
- package/src/daemon/install-symlink.ts +195 -0
- package/src/daemon/lifecycle.ts +234 -51
- package/src/daemon/message-types/conversations.ts +4 -4
- package/src/daemon/message-types/diagnostics.ts +3 -22
- package/src/daemon/message-types/messages.ts +0 -2
- package/src/daemon/message-types/upgrades.ts +8 -0
- package/src/daemon/server.ts +32 -95
- package/src/events/domain-events.ts +2 -1
- package/src/inbound/platform-callback-registration.ts +3 -3
- package/src/instrument.ts +8 -5
- package/src/memory/app-store.ts +31 -0
- package/src/memory/conversation-title-service.ts +50 -1
- package/src/memory/db-init.ts +16 -0
- package/src/memory/indexer.ts +19 -10
- package/src/memory/items-extractor.ts +328 -321
- package/src/memory/job-handlers/conversation-starters.ts +4 -1
- package/src/memory/job-handlers/summarization.ts +26 -16
- package/src/memory/jobs-store.ts +63 -6
- package/src/memory/jobs-worker.ts +31 -7
- package/src/memory/journal-memory.ts +214 -0
- package/src/memory/migrations/001-job-deferrals.ts +19 -0
- package/src/memory/migrations/004-entity-relation-dedup.ts +10 -0
- package/src/memory/migrations/005-fingerprint-scope-unique.ts +76 -0
- package/src/memory/migrations/006-scope-salted-fingerprints.ts +50 -0
- package/src/memory/migrations/007-assistant-id-to-self.ts +10 -0
- package/src/memory/migrations/008-remove-assistant-id-columns.ts +34 -0
- package/src/memory/migrations/009-llm-usage-events-drop-assistant-id.ts +26 -0
- package/src/memory/migrations/014-backfill-inbox-thread-state.ts +10 -0
- package/src/memory/migrations/015-drop-active-search-index.ts +17 -0
- package/src/memory/migrations/019-notification-tables-schema-migration.ts +12 -0
- package/src/memory/migrations/020-rename-macos-ios-channel-to-vellum.ts +121 -0
- package/src/memory/migrations/024-embedding-vector-blob.ts +74 -0
- package/src/memory/migrations/026a-embeddings-nullable-vector-json.ts +82 -0
- package/src/memory/migrations/036-normalize-phone-identities.ts +11 -0
- package/src/memory/migrations/116-messages-fts.ts +106 -1
- package/src/memory/migrations/126-backfill-guardian-principal-id.ts +52 -0
- package/src/memory/migrations/127-guardian-principal-id-not-null.ts +77 -0
- package/src/memory/migrations/134-contacts-notes-column.ts +13 -0
- package/src/memory/migrations/135-backfill-contact-interaction-stats.ts +20 -0
- package/src/memory/migrations/136-drop-assistant-id-columns.ts +52 -0
- package/src/memory/migrations/140-backfill-usage-cache-accounting.ts +13 -0
- package/src/memory/migrations/141-rename-verification-table.ts +54 -0
- package/src/memory/migrations/142-rename-verification-session-id-column.ts +25 -0
- package/src/memory/migrations/143-rename-guardian-verification-values.ts +35 -0
- package/src/memory/migrations/144-rename-voice-to-phone.ts +136 -0
- package/src/memory/migrations/145-drop-accounts-table.ts +32 -0
- package/src/memory/migrations/147-migrate-reminders-to-schedules.ts +14 -1
- package/src/memory/migrations/148-drop-reminders-table.ts +35 -1
- package/src/memory/migrations/150-oauth-apps-client-secret-path.ts +69 -1
- package/src/memory/migrations/162-guardian-timestamps-epoch-ms.ts +290 -0
- package/src/memory/migrations/169-rename-gmail-provider-key-to-google.ts +51 -1
- package/src/memory/migrations/174-rename-thread-starters-table.ts +47 -1
- package/src/memory/migrations/176-drop-capability-card-state.ts +13 -0
- package/src/memory/migrations/180-backfill-inline-attachments-to-disk.ts +16 -0
- package/src/memory/migrations/181-rename-thread-starters-checkpoints.ts +28 -1
- package/src/memory/migrations/190-call-session-skip-disclosure.ts +15 -0
- package/src/memory/migrations/191-backfill-audio-attachment-mime-types.ts +64 -0
- package/src/memory/migrations/192-contacts-user-file-column.ts +15 -0
- package/src/memory/migrations/193-add-source-type-columns.ts +81 -0
- package/src/memory/migrations/index.ts +5 -0
- package/src/memory/migrations/registry.ts +98 -0
- package/src/memory/migrations/validate-migration-state.ts +137 -11
- package/src/memory/qdrant-circuit-breaker.ts +9 -0
- package/src/memory/qdrant-manager.ts +64 -7
- package/src/memory/retriever.test.ts +37 -25
- package/src/memory/retriever.ts +24 -49
- package/src/memory/schema/calls.ts +1 -0
- package/src/memory/schema/contacts.ts +1 -0
- package/src/memory/schema/memory-core.ts +2 -0
- package/src/memory/search/formatting.ts +7 -44
- package/src/memory/search/staleness.ts +4 -0
- package/src/memory/search/tier-classifier.ts +10 -2
- package/src/memory/search/types.ts +2 -5
- package/src/memory/task-memory-cleanup.ts +4 -3
- package/src/notifications/adapters/slack.ts +168 -6
- package/src/notifications/broadcaster.ts +1 -0
- package/src/notifications/copy-composer.ts +59 -2
- package/src/notifications/decision-engine.ts +4 -1
- package/src/notifications/signal.ts +2 -0
- package/src/notifications/types.ts +2 -0
- package/src/oauth/connection-resolver.ts +6 -4
- package/src/permissions/checker.ts +0 -38
- package/src/permissions/shell-identity.ts +76 -22
- package/src/permissions/types.ts +4 -2
- package/src/platform/client.ts +35 -7
- package/src/prompts/journal-context.ts +133 -0
- package/src/prompts/persona-resolver.ts +194 -0
- package/src/prompts/system-prompt.ts +44 -4
- package/src/prompts/templates/SOUL.md +10 -0
- package/src/prompts/templates/users/default.md +1 -0
- package/src/providers/provider-send-message.ts +3 -32
- package/src/providers/registry.ts +29 -179
- package/src/providers/types.ts +1 -1
- package/src/runtime/access-request-helper.ts +4 -0
- package/src/runtime/auth/__tests__/credential-service.test.ts +0 -1
- package/src/runtime/auth/__tests__/external-assistant-id.test.ts +13 -68
- package/src/runtime/auth/__tests__/guard-tests.test.ts +9 -50
- package/src/runtime/auth/external-assistant-id.ts +13 -59
- package/src/runtime/auth/route-policy.ts +17 -1
- package/src/runtime/auth/token-service.ts +43 -138
- package/src/runtime/channel-readiness-service.ts +1 -16
- package/src/runtime/gateway-client.ts +47 -4
- package/src/runtime/guardian-decision-types.ts +45 -4
- package/src/runtime/http-server.ts +31 -3
- package/src/runtime/middleware/error-handler.ts +1 -9
- package/src/runtime/routes/access-request-decision.ts +2 -2
- package/src/runtime/routes/app-management-routes.ts +2 -1
- package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +219 -30
- package/src/runtime/routes/approval-strategies/guardian-text-engine-strategy.ts +37 -14
- package/src/runtime/routes/audio-routes.ts +40 -0
- package/src/runtime/routes/btw-routes.ts +0 -17
- package/src/runtime/routes/channel-readiness-routes.ts +9 -4
- package/src/runtime/routes/conversation-query-routes.ts +63 -1
- package/src/runtime/routes/conversation-routes.ts +4 -44
- package/src/runtime/routes/debug-routes.ts +12 -9
- package/src/runtime/routes/diagnostics-routes.ts +1 -477
- package/src/runtime/routes/guardian-approval-interception.ts +168 -11
- package/src/runtime/routes/guardian-approval-prompt.ts +6 -1
- package/src/runtime/routes/guardian-approval-reply-helpers.ts +103 -21
- package/src/runtime/routes/identity-routes.ts +19 -30
- package/src/runtime/routes/inbound-message-handler.ts +31 -1
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +64 -5
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +52 -40
- package/src/runtime/routes/inbound-stages/secret-ingress-check.ts +4 -33
- package/src/runtime/routes/inbound-stages/transcribe-audio.test.ts +1 -1
- package/src/runtime/routes/integrations/twilio.ts +52 -10
- package/src/runtime/routes/integrations/vercel.ts +89 -0
- package/src/runtime/routes/log-export-routes.ts +5 -0
- package/src/runtime/routes/memory-item-routes.test.ts +3 -3
- package/src/runtime/routes/memory-item-routes.ts +46 -14
- package/src/runtime/routes/migration-rollback-routes.ts +209 -0
- package/src/runtime/routes/migration-routes.ts +17 -1
- package/src/runtime/routes/notification-routes.ts +58 -0
- package/src/runtime/routes/schedule-routes.ts +65 -0
- package/src/runtime/routes/secret-routes.ts +141 -10
- package/src/runtime/routes/settings-routes.ts +41 -1
- package/src/runtime/routes/tts-routes.ts +96 -0
- package/src/runtime/routes/upgrade-broadcast-routes.ts +26 -2
- package/src/runtime/routes/workspace-commit-routes.ts +62 -0
- package/src/runtime/routes/workspace-routes.test.ts +22 -1
- package/src/runtime/routes/workspace-routes.ts +1 -1
- package/src/runtime/routes/workspace-utils.ts +86 -2
- package/src/security/ces-credential-client.ts +75 -29
- package/src/security/ces-rpc-credential-backend.ts +86 -0
- package/src/security/credential-backend.ts +22 -92
- package/src/security/keychain-broker-client.ts +10 -2
- package/src/security/secure-keys.ts +113 -115
- package/src/skills/catalog-install.ts +6 -32
- package/src/skills/skill-memory.ts +1 -0
- package/src/subagent/manager.ts +2 -5
- package/src/telemetry/usage-telemetry-reporter.ts +4 -2
- package/src/tools/acp/spawn.ts +78 -1
- package/src/tools/calls/call-start.ts +1 -0
- package/src/tools/credentials/vault.ts +5 -3
- package/src/tools/executor.ts +0 -4
- package/src/tools/memory/definitions.ts +3 -2
- package/src/tools/memory/handlers.ts +10 -7
- package/src/tools/network/script-proxy/session-manager.ts +19 -4
- package/src/tools/network/web-fetch.ts +3 -1
- package/src/tools/skills/execute.ts +1 -1
- package/src/tools/terminal/safe-env.ts +1 -0
- package/src/tools/types.ts +0 -8
- package/src/util/browser.ts +15 -0
- package/src/util/errors.ts +0 -12
- package/src/util/platform.ts +4 -51
- package/src/workspace/git-service.ts +5 -2
- package/src/workspace/migrations/001-avatar-rename.ts +15 -0
- package/src/workspace/migrations/003-seed-device-id.ts +17 -1
- package/src/workspace/migrations/004-extract-collect-usage-data.ts +33 -0
- package/src/workspace/migrations/005-add-send-diagnostics.ts +3 -0
- package/src/workspace/migrations/006-services-config.ts +49 -0
- package/src/workspace/migrations/007-web-search-provider-rename.ts +27 -0
- package/src/workspace/migrations/008-voice-timeout-and-max-steps.ts +3 -0
- package/src/workspace/migrations/009-backfill-conversation-disk-view.ts +4 -0
- package/src/workspace/migrations/010-app-dir-rename.ts +78 -0
- package/src/workspace/migrations/011-backfill-installation-id.ts +11 -0
- package/src/workspace/migrations/012-rename-conversation-disk-view-dirs.ts +44 -0
- package/src/workspace/migrations/013-repair-conversation-disk-view.ts +5 -0
- package/src/workspace/migrations/015-migrate-credentials-to-keychain.ts +153 -0
- package/src/workspace/migrations/016-extract-feature-flags-to-protected.ts +156 -0
- package/src/workspace/migrations/016-migrate-credentials-from-keychain.ts +150 -0
- package/src/workspace/migrations/017-seed-persona-dirs.ts +96 -0
- package/src/workspace/migrations/018-rekey-compound-credential-keys.ts +184 -0
- package/src/workspace/migrations/019-scope-journal-to-guardian.ts +103 -0
- package/src/workspace/migrations/migrate-to-workspace-volume.ts +27 -5
- package/src/workspace/migrations/registry.ts +12 -0
- package/src/workspace/migrations/runner.ts +106 -2
- package/src/workspace/migrations/types.ts +4 -0
- package/src/workspace/provider-commit-message-generator.ts +12 -21
- package/src/__tests__/claude-code-skill-regression.test.ts +0 -206
- package/src/__tests__/claude-code-tool-profiles.test.ts +0 -99
- package/src/__tests__/diagnostics-export.test.ts +0 -288
- package/src/__tests__/local-gateway-health.test.ts +0 -209
- package/src/__tests__/provider-fail-open-selection.test.ts +0 -271
- package/src/__tests__/provider-failover-actual-provider.test.ts +0 -66
- package/src/__tests__/secret-ingress-handler.test.ts +0 -120
- package/src/__tests__/swarm-conversation-integration.test.ts +0 -358
- package/src/__tests__/swarm-dag-pathological.test.ts +0 -547
- package/src/__tests__/swarm-orchestrator.test.ts +0 -463
- package/src/__tests__/swarm-plan-validator.test.ts +0 -384
- package/src/__tests__/swarm-recursion.test.ts +0 -197
- package/src/__tests__/swarm-router-planner.test.ts +0 -234
- package/src/__tests__/swarm-tool.test.ts +0 -185
- package/src/__tests__/swarm-worker-backend.test.ts +0 -144
- package/src/__tests__/swarm-worker-runner.test.ts +0 -288
- package/src/commands/__tests__/cc-command-registry.test.ts +0 -396
- package/src/commands/cc-command-registry.ts +0 -248
- package/src/config/bundled-skills/claude-code/SKILL.md +0 -53
- package/src/config/bundled-skills/claude-code/TOOLS.json +0 -47
- package/src/config/bundled-skills/claude-code/tools/claude-code.ts +0 -12
- package/src/config/bundled-skills/orchestration/SKILL.md +0 -33
- package/src/config/bundled-skills/orchestration/TOOLS.json +0 -35
- package/src/config/bundled-skills/orchestration/tools/swarm-delegate.ts +0 -12
- package/src/config/schemas/swarm.ts +0 -82
- package/src/logfire.ts +0 -135
- package/src/memory/search/lexical.ts +0 -48
- package/src/providers/failover.ts +0 -186
- package/src/runtime/local-gateway-health.ts +0 -275
- package/src/security/secret-ingress.ts +0 -68
- package/src/swarm/backend-claude-code.ts +0 -225
- package/src/swarm/checkpoint.ts +0 -137
- package/src/swarm/graph-utils.ts +0 -53
- package/src/swarm/index.ts +0 -55
- package/src/swarm/limits.ts +0 -66
- package/src/swarm/orchestrator.ts +0 -424
- package/src/swarm/plan-validator.ts +0 -117
- package/src/swarm/router-planner.ts +0 -162
- package/src/swarm/router-prompts.ts +0 -39
- package/src/swarm/synthesizer.ts +0 -81
- package/src/swarm/types.ts +0 -72
- package/src/swarm/worker-backend.ts +0 -131
- package/src/swarm/worker-prompts.ts +0 -80
- package/src/swarm/worker-runner.ts +0 -170
- package/src/tools/claude-code/claude-code.ts +0 -610
- package/src/tools/swarm/delegate.ts +0 -205
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* System prompt for the router planner LLM call.
|
|
3
|
-
*/
|
|
4
|
-
export const ROUTER_SYSTEM_PROMPT = `You are a task decomposition planner. Given a user objective, break it down into a set of parallel and sequential tasks that can be executed by specialist workers.
|
|
5
|
-
|
|
6
|
-
Available worker roles:
|
|
7
|
-
- researcher: Can search the web, read files, and gather information. Cannot write or edit files.
|
|
8
|
-
- coder: Can read, write, and edit files, run shell commands, and implement code changes.
|
|
9
|
-
- reviewer: Can read and search files to review code. Cannot write or edit files.
|
|
10
|
-
|
|
11
|
-
Rules:
|
|
12
|
-
1. Output ONLY a valid JSON object. No prose, no markdown, no explanation.
|
|
13
|
-
2. Each task must have a unique "id" (short slug), a "role", an "objective" (clear instruction), and "dependencies" (array of task IDs that must complete first).
|
|
14
|
-
3. Maximize parallelism: only add a dependency if the task truly needs output from another.
|
|
15
|
-
4. Keep the plan minimal — avoid unnecessary tasks. Prefer fewer, well-scoped tasks.
|
|
16
|
-
5. Do not create tasks for the "router" role.
|
|
17
|
-
6. The total number of tasks must not exceed the provided limit.
|
|
18
|
-
|
|
19
|
-
Output schema:
|
|
20
|
-
{
|
|
21
|
-
"tasks": [
|
|
22
|
-
{
|
|
23
|
-
"id": "string",
|
|
24
|
-
"role": "researcher" | "coder" | "reviewer",
|
|
25
|
-
"objective": "string",
|
|
26
|
-
"dependencies": ["task-id", ...]
|
|
27
|
-
}
|
|
28
|
-
]
|
|
29
|
-
}`;
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Build the user message for the router planner.
|
|
33
|
-
*/
|
|
34
|
-
export function buildPlannerUserMessage(
|
|
35
|
-
objective: string,
|
|
36
|
-
maxTasks: number,
|
|
37
|
-
): string {
|
|
38
|
-
return `Objective: ${objective}\n\nMaximum tasks allowed: ${maxTasks}\n\nReturn ONLY the JSON plan.`;
|
|
39
|
-
}
|
package/src/swarm/synthesizer.ts
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import type { Message, ModelIntent, Provider } from "../providers/types.js";
|
|
2
|
-
import type { SwarmTaskResult } from "./types.js";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Synthesize a final answer from all worker results using an LLM.
|
|
6
|
-
* Falls back to a deterministic markdown summary if the LLM call fails.
|
|
7
|
-
*/
|
|
8
|
-
export async function synthesizeResults(opts: {
|
|
9
|
-
objective: string;
|
|
10
|
-
results: SwarmTaskResult[];
|
|
11
|
-
provider: Provider;
|
|
12
|
-
modelIntent?: ModelIntent;
|
|
13
|
-
}): Promise<string> {
|
|
14
|
-
const { objective, results, provider, modelIntent } = opts;
|
|
15
|
-
|
|
16
|
-
// Cap individual summaries and total input to avoid blowing up context on large plans
|
|
17
|
-
const MAX_SUMMARY_CHARS = 500;
|
|
18
|
-
const MAX_TOTAL_CHARS = 12_000;
|
|
19
|
-
|
|
20
|
-
let taskSummaries = results
|
|
21
|
-
.map((r) => {
|
|
22
|
-
const status = r.status === "completed" ? "completed" : "FAILED";
|
|
23
|
-
const summary =
|
|
24
|
-
r.summary.length > MAX_SUMMARY_CHARS
|
|
25
|
-
? r.summary.slice(0, MAX_SUMMARY_CHARS) + "..."
|
|
26
|
-
: r.summary;
|
|
27
|
-
return `[${r.taskId}] (${status}): ${summary}`;
|
|
28
|
-
})
|
|
29
|
-
.join("\n");
|
|
30
|
-
|
|
31
|
-
if (taskSummaries.length > MAX_TOTAL_CHARS) {
|
|
32
|
-
taskSummaries =
|
|
33
|
-
taskSummaries.slice(0, MAX_TOTAL_CHARS) + "\n... (truncated)";
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const systemPrompt =
|
|
37
|
-
"You are a synthesis assistant. Combine the outputs from multiple specialist workers into a coherent, concise final answer. Focus on the user's original objective.";
|
|
38
|
-
|
|
39
|
-
const userMessage = `Original objective: ${objective}
|
|
40
|
-
|
|
41
|
-
Worker results:
|
|
42
|
-
${taskSummaries}
|
|
43
|
-
|
|
44
|
-
Synthesize these results into a clear, complete answer for the user.`;
|
|
45
|
-
|
|
46
|
-
try {
|
|
47
|
-
const messages: Message[] = [
|
|
48
|
-
{ role: "user", content: [{ type: "text", text: userMessage }] },
|
|
49
|
-
];
|
|
50
|
-
|
|
51
|
-
const response = await provider.sendMessage(
|
|
52
|
-
messages,
|
|
53
|
-
undefined,
|
|
54
|
-
systemPrompt,
|
|
55
|
-
{ config: { max_tokens: 4096, modelIntent } },
|
|
56
|
-
);
|
|
57
|
-
|
|
58
|
-
const textBlock = response.content.find((b) => b.type === "text");
|
|
59
|
-
if (textBlock && textBlock.type === "text") {
|
|
60
|
-
return textBlock.text;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
return buildFallbackSynthesis(objective, results);
|
|
64
|
-
} catch {
|
|
65
|
-
return buildFallbackSynthesis(objective, results);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
function buildFallbackSynthesis(
|
|
70
|
-
objective: string,
|
|
71
|
-
results: SwarmTaskResult[],
|
|
72
|
-
): string {
|
|
73
|
-
const lines: string[] = [`## Results: ${objective}`, ""];
|
|
74
|
-
|
|
75
|
-
for (const r of results) {
|
|
76
|
-
const icon = r.status === "completed" ? "OK" : "FAIL";
|
|
77
|
-
lines.push(`- [${icon}] **${r.taskId}**: ${r.summary}`);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
return lines.join("\n");
|
|
81
|
-
}
|
package/src/swarm/types.ts
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Swarm runtime types for multi-worker task orchestration.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
export type SwarmRole = "router" | "researcher" | "coder" | "reviewer";
|
|
6
|
-
|
|
7
|
-
export const VALID_SWARM_ROLES: readonly SwarmRole[] = [
|
|
8
|
-
"router",
|
|
9
|
-
"researcher",
|
|
10
|
-
"coder",
|
|
11
|
-
"reviewer",
|
|
12
|
-
] as const;
|
|
13
|
-
|
|
14
|
-
export interface SwarmTaskNode {
|
|
15
|
-
/** Unique identifier within the plan. */
|
|
16
|
-
id: string;
|
|
17
|
-
/** Role that will execute this task. */
|
|
18
|
-
role: SwarmRole;
|
|
19
|
-
/** Human-readable objective for the worker. */
|
|
20
|
-
objective: string;
|
|
21
|
-
/** IDs of tasks that must complete before this one can start. */
|
|
22
|
-
dependencies: string[];
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export interface SwarmPlan {
|
|
26
|
-
/** Top-level objective that was decomposed into tasks. */
|
|
27
|
-
objective: string;
|
|
28
|
-
/** Ordered list of tasks forming a DAG. */
|
|
29
|
-
tasks: SwarmTaskNode[];
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export type SwarmTaskStatus =
|
|
33
|
-
| "queued"
|
|
34
|
-
| "running"
|
|
35
|
-
| "completed"
|
|
36
|
-
| "failed"
|
|
37
|
-
| "blocked";
|
|
38
|
-
|
|
39
|
-
export interface SwarmTaskResult {
|
|
40
|
-
taskId: string;
|
|
41
|
-
status: "completed" | "failed";
|
|
42
|
-
/** Structured summary from the worker. */
|
|
43
|
-
summary: string;
|
|
44
|
-
/** Artifacts produced (file paths, code snippets, etc.). */
|
|
45
|
-
artifacts: string[];
|
|
46
|
-
/** Issues encountered during execution. */
|
|
47
|
-
issues: string[];
|
|
48
|
-
/** Suggested follow-up steps. */
|
|
49
|
-
nextSteps: string[];
|
|
50
|
-
/** Raw unprocessed output from the worker backend. */
|
|
51
|
-
rawOutput: string;
|
|
52
|
-
/** Wall-clock duration in milliseconds. */
|
|
53
|
-
durationMs: number;
|
|
54
|
-
/** Number of retry attempts before final result. */
|
|
55
|
-
retryCount: number;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export interface SwarmExecutionSummary {
|
|
59
|
-
objective: string;
|
|
60
|
-
plan: SwarmPlan;
|
|
61
|
-
results: SwarmTaskResult[];
|
|
62
|
-
/** Synthesized final answer combining all worker outputs. */
|
|
63
|
-
finalAnswer: string;
|
|
64
|
-
/** Aggregate stats. */
|
|
65
|
-
stats: {
|
|
66
|
-
totalTasks: number;
|
|
67
|
-
completed: number;
|
|
68
|
-
failed: number;
|
|
69
|
-
blocked: number;
|
|
70
|
-
totalDurationMs: number;
|
|
71
|
-
};
|
|
72
|
-
}
|
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
import type { SwarmRole } from "./types.js";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Profile names that scope tool access for worker tasks.
|
|
5
|
-
*/
|
|
6
|
-
export type WorkerProfile = "general" | "researcher" | "coder" | "reviewer";
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Maps swarm roles to worker profiles.
|
|
10
|
-
*/
|
|
11
|
-
export function roleToProfile(role: SwarmRole): WorkerProfile {
|
|
12
|
-
switch (role) {
|
|
13
|
-
case "researcher":
|
|
14
|
-
return "researcher";
|
|
15
|
-
case "coder":
|
|
16
|
-
return "coder";
|
|
17
|
-
case "reviewer":
|
|
18
|
-
return "reviewer";
|
|
19
|
-
case "router":
|
|
20
|
-
return "general";
|
|
21
|
-
default:
|
|
22
|
-
return "general";
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Per-profile tool access policy. The sets are checked in order:
|
|
28
|
-
* 1. If tool is in `deny`, block unconditionally.
|
|
29
|
-
* 2. If tool is in `allow`, auto-approve.
|
|
30
|
-
* 3. If tool is in `approvalRequired`, prompt user.
|
|
31
|
-
* 4. Otherwise follow default approval flow.
|
|
32
|
-
*/
|
|
33
|
-
export interface ProfilePolicy {
|
|
34
|
-
allow: Set<string>;
|
|
35
|
-
deny: Set<string>;
|
|
36
|
-
approvalRequired: Set<string>;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
const READ_ONLY_TOOLS = new Set([
|
|
40
|
-
"Read",
|
|
41
|
-
"Glob",
|
|
42
|
-
"Grep",
|
|
43
|
-
"WebSearch",
|
|
44
|
-
"WebFetch",
|
|
45
|
-
"LS",
|
|
46
|
-
"Bash(grep *)",
|
|
47
|
-
"Bash(rg *)",
|
|
48
|
-
"Bash(find *)",
|
|
49
|
-
]);
|
|
50
|
-
|
|
51
|
-
const WRITE_TOOLS = new Set(["Edit", "Write", "MultiEdit", "NotebookEdit"]);
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Return the tool access policy for a given profile.
|
|
55
|
-
*/
|
|
56
|
-
export function getProfilePolicy(profile: WorkerProfile): ProfilePolicy {
|
|
57
|
-
switch (profile) {
|
|
58
|
-
case "general":
|
|
59
|
-
return {
|
|
60
|
-
allow: new Set(READ_ONLY_TOOLS),
|
|
61
|
-
deny: new Set(),
|
|
62
|
-
approvalRequired: new Set(["Bash", ...WRITE_TOOLS]),
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
case "researcher":
|
|
66
|
-
return {
|
|
67
|
-
allow: new Set(READ_ONLY_TOOLS),
|
|
68
|
-
deny: new Set([...WRITE_TOOLS, "Bash"]),
|
|
69
|
-
approvalRequired: new Set(),
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
case "coder":
|
|
73
|
-
return {
|
|
74
|
-
allow: new Set(READ_ONLY_TOOLS),
|
|
75
|
-
deny: new Set(),
|
|
76
|
-
approvalRequired: new Set(["Bash", ...WRITE_TOOLS]),
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
case "reviewer":
|
|
80
|
-
return {
|
|
81
|
-
allow: new Set(READ_ONLY_TOOLS),
|
|
82
|
-
deny: new Set([...WRITE_TOOLS, "Bash"]),
|
|
83
|
-
approvalRequired: new Set(),
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
default:
|
|
87
|
-
return {
|
|
88
|
-
allow: new Set(READ_ONLY_TOOLS),
|
|
89
|
-
deny: new Set(),
|
|
90
|
-
approvalRequired: new Set(["Bash", ...WRITE_TOOLS]),
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// ---------------------------------------------------------------------------
|
|
96
|
-
// Worker Backend
|
|
97
|
-
// ---------------------------------------------------------------------------
|
|
98
|
-
|
|
99
|
-
export type WorkerFailureReason =
|
|
100
|
-
| "backend_unavailable"
|
|
101
|
-
| "timeout"
|
|
102
|
-
| "cancelled"
|
|
103
|
-
| "malformed_output"
|
|
104
|
-
| "tool_denied";
|
|
105
|
-
|
|
106
|
-
export interface SwarmWorkerBackendResult {
|
|
107
|
-
success: boolean;
|
|
108
|
-
output: string;
|
|
109
|
-
failureReason?: WorkerFailureReason;
|
|
110
|
-
durationMs: number;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
export interface SwarmWorkerBackendInput {
|
|
114
|
-
prompt: string;
|
|
115
|
-
profile: WorkerProfile;
|
|
116
|
-
workingDir: string;
|
|
117
|
-
modelIntent?: string;
|
|
118
|
-
timeoutMs?: number;
|
|
119
|
-
signal?: AbortSignal;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* Abstraction over execution backends for swarm workers.
|
|
124
|
-
*/
|
|
125
|
-
export interface SwarmWorkerBackend {
|
|
126
|
-
readonly name: string;
|
|
127
|
-
/** Check whether the backend is available (e.g. API key present). */
|
|
128
|
-
isAvailable(): boolean | Promise<boolean>;
|
|
129
|
-
/** Run a task with the given input. */
|
|
130
|
-
runTask(input: SwarmWorkerBackendInput): Promise<SwarmWorkerBackendResult>;
|
|
131
|
-
}
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import { parseJsonSafe } from "../util/json.js";
|
|
2
|
-
import { truncate } from "../util/truncate.js";
|
|
3
|
-
import type { SwarmRole, SwarmTaskResult } from "./types.js";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Build a role-specific worker prompt for a swarm task.
|
|
7
|
-
*/
|
|
8
|
-
export function buildWorkerPrompt(opts: {
|
|
9
|
-
role: SwarmRole;
|
|
10
|
-
objective: string;
|
|
11
|
-
upstreamContext?: string;
|
|
12
|
-
dependencyOutputs?: Array<{ taskId: string; summary: string }>;
|
|
13
|
-
}): string {
|
|
14
|
-
const parts: string[] = [];
|
|
15
|
-
|
|
16
|
-
parts.push(
|
|
17
|
-
`You are a ${opts.role} worker in a swarm. Your objective:\n${opts.objective}`,
|
|
18
|
-
);
|
|
19
|
-
|
|
20
|
-
if (opts.upstreamContext) {
|
|
21
|
-
parts.push(`\nContext from the orchestrator:\n${opts.upstreamContext}`);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
if (opts.dependencyOutputs && opts.dependencyOutputs.length > 0) {
|
|
25
|
-
parts.push("\nOutputs from prerequisite tasks:");
|
|
26
|
-
for (const dep of opts.dependencyOutputs) {
|
|
27
|
-
parts.push(`- [${dep.taskId}]: ${dep.summary}`);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
parts.push(WORKER_OUTPUT_CONTRACT);
|
|
32
|
-
|
|
33
|
-
return parts.join("\n");
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const WORKER_OUTPUT_CONTRACT = `
|
|
37
|
-
|
|
38
|
-
When you are finished, output your result as a single fenced JSON block:
|
|
39
|
-
|
|
40
|
-
\`\`\`json
|
|
41
|
-
{
|
|
42
|
-
"summary": "Brief summary of what you accomplished",
|
|
43
|
-
"artifacts": ["list of file paths, code snippets, or other outputs"],
|
|
44
|
-
"issues": ["list of problems encountered, if any"],
|
|
45
|
-
"nextSteps": ["suggested follow-up actions, if any"]
|
|
46
|
-
}
|
|
47
|
-
\`\`\`
|
|
48
|
-
|
|
49
|
-
If you cannot produce valid JSON, just write a plain-text summary.`;
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Parse the worker's raw output into a structured result shape.
|
|
53
|
-
* Scans fenced JSON blocks from last to first, picking the last one that
|
|
54
|
-
* matches the worker-result contract (has a `summary` string field).
|
|
55
|
-
* Falls back to treating the entire output as a plain-text summary.
|
|
56
|
-
*/
|
|
57
|
-
export function parseWorkerOutput(
|
|
58
|
-
raw: string,
|
|
59
|
-
): Pick<SwarmTaskResult, "summary" | "artifacts" | "issues" | "nextSteps"> {
|
|
60
|
-
const jsonBlocks = Array.from(raw.matchAll(/```json\s*\n([\s\S]*?)\n```/g));
|
|
61
|
-
|
|
62
|
-
// Walk backwards to prefer the final valid contract block.
|
|
63
|
-
for (let i = jsonBlocks.length - 1; i >= 0; i--) {
|
|
64
|
-
const parsed = parseJsonSafe<Record<string, unknown>>(jsonBlocks[i][1]);
|
|
65
|
-
if (!parsed || typeof parsed.summary !== "string") continue;
|
|
66
|
-
return {
|
|
67
|
-
summary: parsed.summary,
|
|
68
|
-
artifacts: Array.isArray(parsed.artifacts) ? parsed.artifacts : [],
|
|
69
|
-
issues: Array.isArray(parsed.issues) ? parsed.issues : [],
|
|
70
|
-
nextSteps: Array.isArray(parsed.nextSteps) ? parsed.nextSteps : [],
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
return {
|
|
75
|
-
summary: truncate(raw, 500, ""),
|
|
76
|
-
artifacts: [],
|
|
77
|
-
issues: [],
|
|
78
|
-
nextSteps: [],
|
|
79
|
-
};
|
|
80
|
-
}
|
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
import type { SwarmTaskNode, SwarmTaskResult } from "./types.js";
|
|
2
|
-
import type { SwarmWorkerBackend } from "./worker-backend.js";
|
|
3
|
-
import { roleToProfile } from "./worker-backend.js";
|
|
4
|
-
import { buildWorkerPrompt, parseWorkerOutput } from "./worker-prompts.js";
|
|
5
|
-
|
|
6
|
-
export type WorkerStatusKind = "queued" | "running" | "completed" | "failed";
|
|
7
|
-
|
|
8
|
-
export type WorkerStatusCallback = (
|
|
9
|
-
taskId: string,
|
|
10
|
-
status: WorkerStatusKind,
|
|
11
|
-
) => void;
|
|
12
|
-
|
|
13
|
-
export interface RunWorkerTaskOptions {
|
|
14
|
-
task: SwarmTaskNode;
|
|
15
|
-
/** Top-level objective context passed from the orchestrator. */
|
|
16
|
-
upstreamContext?: string;
|
|
17
|
-
/** Summaries from completed dependency tasks. */
|
|
18
|
-
dependencyOutputs?: Array<{ taskId: string; summary: string }>;
|
|
19
|
-
backend: SwarmWorkerBackend;
|
|
20
|
-
workingDir: string;
|
|
21
|
-
modelIntent?: string;
|
|
22
|
-
timeoutMs: number;
|
|
23
|
-
onStatus?: WorkerStatusCallback;
|
|
24
|
-
signal?: AbortSignal;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function emitStatus(
|
|
28
|
-
onStatus: WorkerStatusCallback | undefined,
|
|
29
|
-
taskId: string,
|
|
30
|
-
status: WorkerStatusKind,
|
|
31
|
-
): void {
|
|
32
|
-
if (!onStatus) return;
|
|
33
|
-
try {
|
|
34
|
-
onStatus(taskId, status);
|
|
35
|
-
} catch {
|
|
36
|
-
// Observer failures must not abort worker execution.
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Execute a single swarm worker task through the given backend.
|
|
42
|
-
* Returns a normalized SwarmTaskResult regardless of success or failure.
|
|
43
|
-
*/
|
|
44
|
-
export async function runWorkerTask(
|
|
45
|
-
opts: RunWorkerTaskOptions,
|
|
46
|
-
): Promise<SwarmTaskResult> {
|
|
47
|
-
const { task, backend, workingDir, timeoutMs, onStatus, signal } = opts;
|
|
48
|
-
|
|
49
|
-
if (signal?.aborted) {
|
|
50
|
-
return {
|
|
51
|
-
taskId: task.id,
|
|
52
|
-
status: "failed",
|
|
53
|
-
summary: "Cancelled",
|
|
54
|
-
artifacts: [],
|
|
55
|
-
issues: ["aborted"],
|
|
56
|
-
nextSteps: [],
|
|
57
|
-
rawOutput: "",
|
|
58
|
-
durationMs: 0,
|
|
59
|
-
retryCount: 0,
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
emitStatus(onStatus, task.id, "queued");
|
|
64
|
-
|
|
65
|
-
// Check backend availability
|
|
66
|
-
if (!(await backend.isAvailable())) {
|
|
67
|
-
emitStatus(onStatus, task.id, "failed");
|
|
68
|
-
return {
|
|
69
|
-
taskId: task.id,
|
|
70
|
-
status: "failed",
|
|
71
|
-
summary: `Backend "${backend.name}" is not available. Check API key and SDK configuration.`,
|
|
72
|
-
artifacts: [],
|
|
73
|
-
issues: [`Backend "${backend.name}" unavailable`],
|
|
74
|
-
nextSteps: ["Configure the backend or use a different one"],
|
|
75
|
-
rawOutput: "",
|
|
76
|
-
durationMs: 0,
|
|
77
|
-
retryCount: 0,
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
emitStatus(onStatus, task.id, "running");
|
|
82
|
-
|
|
83
|
-
const prompt = buildWorkerPrompt({
|
|
84
|
-
role: task.role,
|
|
85
|
-
objective: task.objective,
|
|
86
|
-
upstreamContext: opts.upstreamContext,
|
|
87
|
-
dependencyOutputs: opts.dependencyOutputs,
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
const profile = roleToProfile(task.role);
|
|
91
|
-
|
|
92
|
-
try {
|
|
93
|
-
const backendPromise = backend.runTask({
|
|
94
|
-
prompt,
|
|
95
|
-
profile,
|
|
96
|
-
workingDir,
|
|
97
|
-
modelIntent: opts.modelIntent,
|
|
98
|
-
timeoutMs,
|
|
99
|
-
signal,
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
// Enforce timeout via Promise.race
|
|
103
|
-
const timeoutPromise = new Promise<"timeout">((resolve) => {
|
|
104
|
-
const timer = setTimeout(() => resolve("timeout"), timeoutMs);
|
|
105
|
-
// Don't keep the process alive just for this timer
|
|
106
|
-
if (typeof timer === "object" && "unref" in timer) timer.unref();
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
const raceResult = await Promise.race([backendPromise, timeoutPromise]);
|
|
110
|
-
|
|
111
|
-
if (raceResult === "timeout") {
|
|
112
|
-
emitStatus(onStatus, task.id, "failed");
|
|
113
|
-
return {
|
|
114
|
-
taskId: task.id,
|
|
115
|
-
status: "failed",
|
|
116
|
-
summary: `Worker timed out after ${timeoutMs}ms`,
|
|
117
|
-
artifacts: [],
|
|
118
|
-
issues: ["timeout"],
|
|
119
|
-
nextSteps: [],
|
|
120
|
-
rawOutput: "",
|
|
121
|
-
durationMs: timeoutMs,
|
|
122
|
-
retryCount: 0,
|
|
123
|
-
};
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
const result = raceResult;
|
|
127
|
-
|
|
128
|
-
if (result.success) {
|
|
129
|
-
const parsed = parseWorkerOutput(result.output);
|
|
130
|
-
emitStatus(onStatus, task.id, "completed");
|
|
131
|
-
return {
|
|
132
|
-
taskId: task.id,
|
|
133
|
-
status: "completed",
|
|
134
|
-
...parsed,
|
|
135
|
-
rawOutput: result.output,
|
|
136
|
-
durationMs: result.durationMs,
|
|
137
|
-
retryCount: 0,
|
|
138
|
-
};
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
// Backend returned a failure
|
|
142
|
-
emitStatus(onStatus, task.id, "failed");
|
|
143
|
-
return {
|
|
144
|
-
taskId: task.id,
|
|
145
|
-
status: "failed",
|
|
146
|
-
summary:
|
|
147
|
-
result.output || `Task failed: ${result.failureReason ?? "unknown"}`,
|
|
148
|
-
artifacts: [],
|
|
149
|
-
issues: [result.failureReason ?? "unknown_failure"],
|
|
150
|
-
nextSteps: [],
|
|
151
|
-
rawOutput: result.output,
|
|
152
|
-
durationMs: result.durationMs,
|
|
153
|
-
retryCount: 0,
|
|
154
|
-
};
|
|
155
|
-
} catch (err) {
|
|
156
|
-
emitStatus(onStatus, task.id, "failed");
|
|
157
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
158
|
-
return {
|
|
159
|
-
taskId: task.id,
|
|
160
|
-
status: "failed",
|
|
161
|
-
summary: `Unexpected error: ${message}`,
|
|
162
|
-
artifacts: [],
|
|
163
|
-
issues: [message],
|
|
164
|
-
nextSteps: [],
|
|
165
|
-
rawOutput: "",
|
|
166
|
-
durationMs: 0,
|
|
167
|
-
retryCount: 0,
|
|
168
|
-
};
|
|
169
|
-
}
|
|
170
|
-
}
|