@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,248 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
closeSync,
|
|
3
|
-
existsSync,
|
|
4
|
-
openSync,
|
|
5
|
-
readdirSync,
|
|
6
|
-
readFileSync,
|
|
7
|
-
readSync,
|
|
8
|
-
} from "node:fs";
|
|
9
|
-
import { basename, dirname, join, resolve } from "node:path";
|
|
10
|
-
|
|
11
|
-
import { FRONTMATTER_REGEX } from "../skills/frontmatter.js";
|
|
12
|
-
import { getLogger } from "../util/logger.js";
|
|
13
|
-
|
|
14
|
-
const log = getLogger("cc-commands");
|
|
15
|
-
|
|
16
|
-
// ─── Types ───────────────────────────────────────────────────────────────────
|
|
17
|
-
|
|
18
|
-
export interface CCCommandEntry {
|
|
19
|
-
/** Command name: basename without .md extension. */
|
|
20
|
-
name: string;
|
|
21
|
-
/** First non-empty line after frontmatter, stripped of heading markers. */
|
|
22
|
-
summary: string;
|
|
23
|
-
/** Absolute path to the .md file. */
|
|
24
|
-
filePath: string;
|
|
25
|
-
/** Directory containing the `.claude/commands/` folder. */
|
|
26
|
-
source: string;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export interface CCCommandRegistry {
|
|
30
|
-
/** Commands keyed by lowercase name. */
|
|
31
|
-
entries: Map<string, CCCommandEntry>;
|
|
32
|
-
/** Timestamp (ms) when discovery was performed. */
|
|
33
|
-
discoveredAt: number;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// ─── Constants ───────────────────────────────────────────────────────────────
|
|
37
|
-
|
|
38
|
-
const COMMAND_NAME_REGEX = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
|
|
39
|
-
const DEFAULT_CACHE_TTL_MS = 30_000;
|
|
40
|
-
const MAX_SUMMARY_LENGTH = 100;
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Maximum bytes to read from each command file during discovery.
|
|
44
|
-
* 1 KiB is enough for frontmatter (typically < 200 B) plus several content
|
|
45
|
-
* lines, which is all we need to extract a one-line summary.
|
|
46
|
-
*/
|
|
47
|
-
const SUMMARY_READ_BYTES = 1024;
|
|
48
|
-
|
|
49
|
-
// ─── Cache ───────────────────────────────────────────────────────────────────
|
|
50
|
-
|
|
51
|
-
const cache = new Map<string, CCCommandRegistry>();
|
|
52
|
-
|
|
53
|
-
/** Clear all cached registries. */
|
|
54
|
-
export function invalidateCCCommandCache(): void {
|
|
55
|
-
cache.clear();
|
|
56
|
-
log.debug("CC command cache invalidated");
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// ─── Partial I/O ─────────────────────────────────────────────────────────────
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Read at most `maxBytes` from the beginning of a file.
|
|
63
|
-
* Uses low-level `openSync`/`readSync` so we never pull the entire file into
|
|
64
|
-
* memory — important when command templates are large but we only need the
|
|
65
|
-
* first few lines for summary extraction.
|
|
66
|
-
*/
|
|
67
|
-
function readFileHead(filePath: string, maxBytes: number): string {
|
|
68
|
-
const fd = openSync(filePath, "r");
|
|
69
|
-
try {
|
|
70
|
-
const buf = Buffer.alloc(maxBytes);
|
|
71
|
-
const bytesRead = readSync(fd, buf, 0, maxBytes, 0);
|
|
72
|
-
return buf.toString("utf-8", 0, bytesRead);
|
|
73
|
-
} finally {
|
|
74
|
-
closeSync(fd);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// ─── Summary extraction ──────────────────────────────────────────────────────
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Extract a one-line summary from the beginning of a markdown file.
|
|
82
|
-
* Skips YAML frontmatter if present, then returns the first non-empty line
|
|
83
|
-
* with leading `#` heading markers stripped. Truncates to 100 chars.
|
|
84
|
-
*/
|
|
85
|
-
function extractSummary(content: string): string {
|
|
86
|
-
// Strip frontmatter if present
|
|
87
|
-
let body = content;
|
|
88
|
-
const fmMatch = content.match(FRONTMATTER_REGEX);
|
|
89
|
-
if (fmMatch) {
|
|
90
|
-
body = content.slice(fmMatch[0].length);
|
|
91
|
-
} else if (/^---\r?\n/.test(content)) {
|
|
92
|
-
if (Buffer.byteLength(content, "utf-8") >= SUMMARY_READ_BYTES) {
|
|
93
|
-
// Content starts with a frontmatter opening delimiter but the closing
|
|
94
|
-
// delimiter was not found. The content length reached SUMMARY_READ_BYTES,
|
|
95
|
-
// so the read was likely truncated — the missing closing `---` is
|
|
96
|
-
// probably just beyond the read boundary. Return empty rather than
|
|
97
|
-
// surfacing partial frontmatter fields as a summary.
|
|
98
|
-
return "";
|
|
99
|
-
}
|
|
100
|
-
// Small file that starts with `---` (thematic break or unclosed
|
|
101
|
-
// frontmatter opener). Skip the leading `---` line and extract the
|
|
102
|
-
// first real content line from the remainder.
|
|
103
|
-
body = content.replace(/^---\r?\n/, "");
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// Find first non-empty line
|
|
107
|
-
const lines = body.split(/\r?\n/);
|
|
108
|
-
for (const line of lines) {
|
|
109
|
-
const trimmed = line.trim();
|
|
110
|
-
if (!trimmed) continue;
|
|
111
|
-
|
|
112
|
-
// Strip leading # heading markers
|
|
113
|
-
const stripped = trimmed.replace(/^#+\s*/, "");
|
|
114
|
-
if (!stripped) continue;
|
|
115
|
-
|
|
116
|
-
// Truncate if needed
|
|
117
|
-
if (stripped.length > MAX_SUMMARY_LENGTH) {
|
|
118
|
-
return stripped.slice(0, MAX_SUMMARY_LENGTH);
|
|
119
|
-
}
|
|
120
|
-
return stripped;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
return "";
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
// ─── Discovery ───────────────────────────────────────────────────────────────
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* Discover `.claude/commands/*.md` files by walking up from `cwd`.
|
|
130
|
-
* Nearest directory wins on name collisions (child overrides parent).
|
|
131
|
-
* Results are cached per cwd with a 30-second TTL.
|
|
132
|
-
*/
|
|
133
|
-
export function discoverCCCommands(
|
|
134
|
-
cwd: string,
|
|
135
|
-
ttlMs: number = DEFAULT_CACHE_TTL_MS,
|
|
136
|
-
): CCCommandRegistry {
|
|
137
|
-
const resolvedCwd = resolve(cwd);
|
|
138
|
-
|
|
139
|
-
// Check cache
|
|
140
|
-
const cached = cache.get(resolvedCwd);
|
|
141
|
-
if (cached && Date.now() - cached.discoveredAt < ttlMs) {
|
|
142
|
-
log.debug({ cwd: resolvedCwd }, "CC command cache hit");
|
|
143
|
-
return cached;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
log.debug(
|
|
147
|
-
{ cwd: resolvedCwd },
|
|
148
|
-
"CC command cache miss, discovering commands",
|
|
149
|
-
);
|
|
150
|
-
|
|
151
|
-
const entries = new Map<string, CCCommandEntry>();
|
|
152
|
-
let current = resolvedCwd;
|
|
153
|
-
|
|
154
|
-
// Walk up the directory tree; collect commands from each level.
|
|
155
|
-
// Since child directories should win on name collisions, we only add entries
|
|
156
|
-
// that haven't been seen yet (first occurrence = nearest ancestor).
|
|
157
|
-
while (true) {
|
|
158
|
-
const commandsDir = join(current, ".claude", "commands");
|
|
159
|
-
|
|
160
|
-
if (existsSync(commandsDir)) {
|
|
161
|
-
try {
|
|
162
|
-
const files = readdirSync(commandsDir, { withFileTypes: true });
|
|
163
|
-
for (const file of files) {
|
|
164
|
-
if (!file.isFile()) continue;
|
|
165
|
-
if (!file.name.endsWith(".md")) continue;
|
|
166
|
-
|
|
167
|
-
const nameWithoutExt = basename(file.name, ".md");
|
|
168
|
-
|
|
169
|
-
// Validate command name
|
|
170
|
-
if (!COMMAND_NAME_REGEX.test(nameWithoutExt)) {
|
|
171
|
-
log.warn(
|
|
172
|
-
{ fileName: file.name, dir: commandsDir },
|
|
173
|
-
"Skipping invalid CC command filename",
|
|
174
|
-
);
|
|
175
|
-
continue;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
const key = nameWithoutExt.toLowerCase();
|
|
179
|
-
|
|
180
|
-
// Child directories win — skip if already discovered from a closer ancestor
|
|
181
|
-
if (entries.has(key)) continue;
|
|
182
|
-
|
|
183
|
-
const filePath = join(commandsDir, file.name);
|
|
184
|
-
|
|
185
|
-
let summary = "";
|
|
186
|
-
try {
|
|
187
|
-
const head = readFileHead(filePath, SUMMARY_READ_BYTES);
|
|
188
|
-
summary = extractSummary(head);
|
|
189
|
-
} catch (err) {
|
|
190
|
-
log.warn(
|
|
191
|
-
{ err, filePath },
|
|
192
|
-
"Failed to read CC command file for summary extraction",
|
|
193
|
-
);
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
entries.set(key, {
|
|
197
|
-
name: nameWithoutExt,
|
|
198
|
-
summary,
|
|
199
|
-
filePath,
|
|
200
|
-
source: current,
|
|
201
|
-
});
|
|
202
|
-
}
|
|
203
|
-
} catch (err) {
|
|
204
|
-
log.warn({ err, commandsDir }, "Failed to read CC commands directory");
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
const parent = dirname(current);
|
|
209
|
-
if (parent === current) break; // reached filesystem root
|
|
210
|
-
current = parent;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
log.debug(
|
|
214
|
-
{ cwd: resolvedCwd, count: entries.size },
|
|
215
|
-
"CC command discovery complete",
|
|
216
|
-
);
|
|
217
|
-
|
|
218
|
-
const registry: CCCommandRegistry = {
|
|
219
|
-
entries,
|
|
220
|
-
discoveredAt: Date.now(),
|
|
221
|
-
};
|
|
222
|
-
|
|
223
|
-
cache.set(resolvedCwd, registry);
|
|
224
|
-
return registry;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
// ─── Lookup ──────────────────────────────────────────────────────────────────
|
|
228
|
-
|
|
229
|
-
/**
|
|
230
|
-
* Look up a single CC command by name (case-insensitive).
|
|
231
|
-
*/
|
|
232
|
-
export function getCCCommand(
|
|
233
|
-
cwd: string,
|
|
234
|
-
name: string,
|
|
235
|
-
): CCCommandEntry | undefined {
|
|
236
|
-
const registry = discoverCCCommands(cwd);
|
|
237
|
-
return registry.entries.get(name.toLowerCase());
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
// ─── Template loading ────────────────────────────────────────────────────────
|
|
241
|
-
|
|
242
|
-
/**
|
|
243
|
-
* Load the full markdown content of a CC command file.
|
|
244
|
-
* This is deferred to execution time to avoid reading full files during discovery.
|
|
245
|
-
*/
|
|
246
|
-
export function loadCCCommandTemplate(entry: CCCommandEntry): string {
|
|
247
|
-
return readFileSync(entry.filePath, "utf-8");
|
|
248
|
-
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: claude-code
|
|
3
|
-
description: Delegate coding tasks to Claude Code
|
|
4
|
-
compatibility: "Designed for Vellum personal assistants"
|
|
5
|
-
metadata:
|
|
6
|
-
emoji: "💻"
|
|
7
|
-
vellum:
|
|
8
|
-
display-name: "Claude Code"
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
You are delegating a coding task to Claude Code, an autonomous AI coding agent. Use this skill when the user needs hands-on software engineering work done.
|
|
12
|
-
|
|
13
|
-
## Capabilities
|
|
14
|
-
|
|
15
|
-
Claude Code can:
|
|
16
|
-
- Read, write, and edit files across a codebase
|
|
17
|
-
- Run shell commands (build, test, lint, deploy scripts)
|
|
18
|
-
- Perform multi-step engineering tasks autonomously (refactoring, implementing features, debugging)
|
|
19
|
-
- Search codebases for patterns, definitions, and usage
|
|
20
|
-
- Work with git repositories (commits, branches, diffs)
|
|
21
|
-
|
|
22
|
-
## When to Delegate
|
|
23
|
-
|
|
24
|
-
Delegate to Claude Code when the task involves:
|
|
25
|
-
- Writing or modifying source code
|
|
26
|
-
- Running build/test/lint commands and iterating on failures
|
|
27
|
-
- Exploring a codebase to answer architectural questions
|
|
28
|
-
- Multi-file refactors or migrations
|
|
29
|
-
- Debugging issues that require reading code and running tests
|
|
30
|
-
- Any task that benefits from direct filesystem and shell access
|
|
31
|
-
|
|
32
|
-
Do NOT delegate when:
|
|
33
|
-
- The user just wants a conversational answer or explanation
|
|
34
|
-
- The task is pure information retrieval with no code changes needed
|
|
35
|
-
- The user explicitly wants to discuss an approach before implementation
|
|
36
|
-
|
|
37
|
-
## Guardrails
|
|
38
|
-
|
|
39
|
-
- Claude Code runs in a sandboxed environment with approval flows for destructive actions
|
|
40
|
-
- File writes, edits, and shell commands that modify state require user confirmation (unless auto-approved by trust rules)
|
|
41
|
-
- Read-only operations (file reads, searches, web fetches) are auto-approved
|
|
42
|
-
- The working directory defaults to the current conversation's working directory but can be overridden
|
|
43
|
-
|
|
44
|
-
## Worker Profiles
|
|
45
|
-
|
|
46
|
-
Claude Code supports scoped worker profiles that restrict tool access:
|
|
47
|
-
|
|
48
|
-
- **general** (default) - Full access to all tools.
|
|
49
|
-
- **researcher** - Read-only access. Can search, read files, and browse the web but cannot write or execute commands.
|
|
50
|
-
- **coder** - Full read/write/execute access optimized for implementation tasks.
|
|
51
|
-
- **reviewer** - Read-only access tailored for code review, with emphasis on analysis and feedback.
|
|
52
|
-
|
|
53
|
-
Select the profile that best matches the task to enforce least-privilege access.
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 1,
|
|
3
|
-
"tools": [
|
|
4
|
-
{
|
|
5
|
-
"name": "claude_code",
|
|
6
|
-
"description": "Delegate a coding task to Claude Code, an AI-powered coding agent that can read, write, and edit files, run shell commands, and perform complex multi-step software engineering tasks autonomously.",
|
|
7
|
-
"category": "coding",
|
|
8
|
-
"risk": "medium",
|
|
9
|
-
"input_schema": {
|
|
10
|
-
"type": "object",
|
|
11
|
-
"properties": {
|
|
12
|
-
"prompt": {
|
|
13
|
-
"type": "string",
|
|
14
|
-
"description": "The coding task or question for Claude Code to work on. Use this for free-form tasks. Mutually exclusive with command."
|
|
15
|
-
},
|
|
16
|
-
"command": {
|
|
17
|
-
"type": "string",
|
|
18
|
-
"description": "Name of a .claude/commands/*.md command template to execute. The template will be loaded and $ARGUMENTS substituted before execution. Use this instead of prompt when invoking a named CC command."
|
|
19
|
-
},
|
|
20
|
-
"arguments": {
|
|
21
|
-
"type": "string",
|
|
22
|
-
"description": "Arguments to substitute into the command template ($ARGUMENTS placeholder). Only used with the command input."
|
|
23
|
-
},
|
|
24
|
-
"working_dir": {
|
|
25
|
-
"type": "string",
|
|
26
|
-
"description": "Working directory for Claude Code (defaults to conversation working directory)"
|
|
27
|
-
},
|
|
28
|
-
"resume": {
|
|
29
|
-
"type": "string",
|
|
30
|
-
"description": "Claude Code session ID to resume a previous session"
|
|
31
|
-
},
|
|
32
|
-
"model": {
|
|
33
|
-
"type": "string",
|
|
34
|
-
"description": "Model to use (defaults to claude-sonnet-4-6)"
|
|
35
|
-
},
|
|
36
|
-
"profile": {
|
|
37
|
-
"type": "string",
|
|
38
|
-
"enum": ["general", "researcher", "coder", "reviewer"],
|
|
39
|
-
"description": "Worker profile that scopes tool access. Defaults to general."
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
},
|
|
43
|
-
"executor": "tools/claude-code.ts",
|
|
44
|
-
"execution_target": "host"
|
|
45
|
-
}
|
|
46
|
-
]
|
|
47
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { claudeCodeTool } from "../../../../tools/claude-code/claude-code.js";
|
|
2
|
-
import type {
|
|
3
|
-
ToolContext,
|
|
4
|
-
ToolExecutionResult,
|
|
5
|
-
} from "../../../../tools/types.js";
|
|
6
|
-
|
|
7
|
-
export async function run(
|
|
8
|
-
input: Record<string, unknown>,
|
|
9
|
-
context: ToolContext,
|
|
10
|
-
): Promise<ToolExecutionResult> {
|
|
11
|
-
return claudeCodeTool.execute(input, context);
|
|
12
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: orchestration
|
|
3
|
-
description: Decompose complex tasks into parallel specialist subtasks
|
|
4
|
-
compatibility: "Designed for Vellum personal assistants"
|
|
5
|
-
metadata:
|
|
6
|
-
emoji: "\U0001F500"
|
|
7
|
-
vellum:
|
|
8
|
-
display-name: "Orchestration"
|
|
9
|
-
activation-hints:
|
|
10
|
-
- "Multiple independent work streams that benefit from parallel execution"
|
|
11
|
-
avoid-when:
|
|
12
|
-
- "Single-focus tasks -- work directly"
|
|
13
|
-
---
|
|
14
|
-
|
|
15
|
-
Use `swarm_delegate` when facing complex multi-part tasks that benefit from parallel execution. The tool decomposes an objective into independent specialist subtasks, runs them concurrently, and synthesises the results.
|
|
16
|
-
|
|
17
|
-
## When to use
|
|
18
|
-
|
|
19
|
-
- The request involves **multiple independent work streams** (e.g. research + coding + review).
|
|
20
|
-
- Tasks can run in parallel without sequential dependencies.
|
|
21
|
-
- The combined work would take significantly longer if done serially.
|
|
22
|
-
|
|
23
|
-
## When NOT to use
|
|
24
|
-
|
|
25
|
-
- Simple single-step requests - just do them directly.
|
|
26
|
-
- Tasks that are inherently sequential (each step depends on the previous result).
|
|
27
|
-
- Requests where the user is asking for a quick answer, not a deep workflow.
|
|
28
|
-
|
|
29
|
-
## Tips
|
|
30
|
-
|
|
31
|
-
- Provide a clear, specific `objective`. The planner uses it to decompose the work.
|
|
32
|
-
- Pass relevant `context` about the codebase or project when available.
|
|
33
|
-
- The `max_workers` parameter caps concurrency (1-6); the default comes from config.
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 1,
|
|
3
|
-
"tools": [
|
|
4
|
-
{
|
|
5
|
-
"name": "swarm_delegate",
|
|
6
|
-
"description": "Decompose a complex task into parallel specialist subtasks and execute them concurrently. Use this for multi-part tasks that benefit from parallel research, coding, and review.",
|
|
7
|
-
"category": "orchestration",
|
|
8
|
-
"risk": "medium",
|
|
9
|
-
"input_schema": {
|
|
10
|
-
"type": "object",
|
|
11
|
-
"properties": {
|
|
12
|
-
"objective": {
|
|
13
|
-
"type": "string",
|
|
14
|
-
"description": "The complex task to decompose and execute in parallel"
|
|
15
|
-
},
|
|
16
|
-
"context": {
|
|
17
|
-
"type": "string",
|
|
18
|
-
"description": "Optional additional context about the task or codebase"
|
|
19
|
-
},
|
|
20
|
-
"max_workers": {
|
|
21
|
-
"type": "number",
|
|
22
|
-
"description": "Maximum concurrent workers (1-6, default from config)"
|
|
23
|
-
},
|
|
24
|
-
"activity": {
|
|
25
|
-
"type": "string",
|
|
26
|
-
"description": "Brief non-technical explanation of what you are doing and why, shown to the user as a status update. Use simple language a non-technical person would understand."
|
|
27
|
-
}
|
|
28
|
-
},
|
|
29
|
-
"required": ["objective"]
|
|
30
|
-
},
|
|
31
|
-
"executor": "tools/swarm-delegate.ts",
|
|
32
|
-
"execution_target": "host"
|
|
33
|
-
}
|
|
34
|
-
]
|
|
35
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { swarmDelegateTool } from "../../../../tools/swarm/delegate.js";
|
|
2
|
-
import type {
|
|
3
|
-
ToolContext,
|
|
4
|
-
ToolExecutionResult,
|
|
5
|
-
} from "../../../../tools/types.js";
|
|
6
|
-
|
|
7
|
-
export async function run(
|
|
8
|
-
input: Record<string, unknown>,
|
|
9
|
-
context: ToolContext,
|
|
10
|
-
): Promise<ToolExecutionResult> {
|
|
11
|
-
return swarmDelegateTool.execute(input, context);
|
|
12
|
-
}
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
|
|
3
|
-
export const SwarmConfigSchema = z
|
|
4
|
-
.object({
|
|
5
|
-
enabled: z
|
|
6
|
-
.boolean({ error: "swarm.enabled must be a boolean" })
|
|
7
|
-
.default(true)
|
|
8
|
-
.describe("Whether swarm (parallel multi-agent) execution is enabled"),
|
|
9
|
-
maxWorkers: z
|
|
10
|
-
.number({ error: "swarm.maxWorkers must be a number" })
|
|
11
|
-
.int("swarm.maxWorkers must be an integer")
|
|
12
|
-
.positive("swarm.maxWorkers must be a positive integer")
|
|
13
|
-
.max(6, "swarm.maxWorkers must be at most 6")
|
|
14
|
-
.default(3)
|
|
15
|
-
.describe("Maximum number of concurrent swarm workers"),
|
|
16
|
-
maxTasks: z
|
|
17
|
-
.number({ error: "swarm.maxTasks must be a number" })
|
|
18
|
-
.int("swarm.maxTasks must be an integer")
|
|
19
|
-
.positive("swarm.maxTasks must be a positive integer")
|
|
20
|
-
.max(20, "swarm.maxTasks must be at most 20")
|
|
21
|
-
.default(8)
|
|
22
|
-
.describe("Maximum number of tasks a single swarm can execute"),
|
|
23
|
-
maxRetriesPerTask: z
|
|
24
|
-
.number({ error: "swarm.maxRetriesPerTask must be a number" })
|
|
25
|
-
.int("swarm.maxRetriesPerTask must be an integer")
|
|
26
|
-
.nonnegative("swarm.maxRetriesPerTask must be a non-negative integer")
|
|
27
|
-
.max(3, "swarm.maxRetriesPerTask must be at most 3")
|
|
28
|
-
.default(1)
|
|
29
|
-
.describe("Maximum number of retries for a failed swarm task"),
|
|
30
|
-
workerTimeoutSec: z
|
|
31
|
-
.number({ error: "swarm.workerTimeoutSec must be a number" })
|
|
32
|
-
.int("swarm.workerTimeoutSec must be an integer")
|
|
33
|
-
.positive("swarm.workerTimeoutSec must be a positive integer")
|
|
34
|
-
.default(900)
|
|
35
|
-
.describe("Timeout for a single swarm worker in seconds"),
|
|
36
|
-
roleTimeoutsSec: z
|
|
37
|
-
.object({
|
|
38
|
-
router: z
|
|
39
|
-
.number()
|
|
40
|
-
.int()
|
|
41
|
-
.positive()
|
|
42
|
-
.optional()
|
|
43
|
-
.describe("Timeout override for router workers (seconds)"),
|
|
44
|
-
researcher: z
|
|
45
|
-
.number()
|
|
46
|
-
.int()
|
|
47
|
-
.positive()
|
|
48
|
-
.optional()
|
|
49
|
-
.describe("Timeout override for researcher workers (seconds)"),
|
|
50
|
-
coder: z
|
|
51
|
-
.number()
|
|
52
|
-
.int()
|
|
53
|
-
.positive()
|
|
54
|
-
.optional()
|
|
55
|
-
.describe("Timeout override for coder workers (seconds)"),
|
|
56
|
-
reviewer: z
|
|
57
|
-
.number()
|
|
58
|
-
.int()
|
|
59
|
-
.positive()
|
|
60
|
-
.optional()
|
|
61
|
-
.describe("Timeout override for reviewer workers (seconds)"),
|
|
62
|
-
})
|
|
63
|
-
.default({})
|
|
64
|
-
.describe("Per-role timeout overrides for swarm workers"),
|
|
65
|
-
plannerModelIntent: z
|
|
66
|
-
.enum(["latency-optimized", "quality-optimized", "vision-optimized"], {
|
|
67
|
-
error: "swarm.plannerModelIntent must be a valid model intent",
|
|
68
|
-
})
|
|
69
|
-
.default("latency-optimized")
|
|
70
|
-
.describe("Model selection strategy for the swarm planning phase"),
|
|
71
|
-
synthesizerModelIntent: z
|
|
72
|
-
.enum(["latency-optimized", "quality-optimized", "vision-optimized"], {
|
|
73
|
-
error: "swarm.synthesizerModelIntent must be a valid model intent",
|
|
74
|
-
})
|
|
75
|
-
.default("quality-optimized")
|
|
76
|
-
.describe(
|
|
77
|
-
"Model selection strategy for the swarm synthesis (result-combining) phase",
|
|
78
|
-
),
|
|
79
|
-
})
|
|
80
|
-
.describe("Swarm configuration — parallel multi-agent task execution");
|
|
81
|
-
|
|
82
|
-
export type SwarmConfig = z.infer<typeof SwarmConfigSchema>;
|
package/src/logfire.ts
DELETED
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
import { getLogfireToken } from "./config/env.js";
|
|
2
|
-
import type {
|
|
3
|
-
Message,
|
|
4
|
-
Provider,
|
|
5
|
-
ProviderResponse,
|
|
6
|
-
SendMessageOptions,
|
|
7
|
-
ToolDefinition,
|
|
8
|
-
} from "./providers/types.js";
|
|
9
|
-
import { getLogger } from "./util/logger.js";
|
|
10
|
-
import { APP_VERSION } from "./version.js";
|
|
11
|
-
|
|
12
|
-
const log = getLogger("logfire");
|
|
13
|
-
|
|
14
|
-
type LogfireModule = typeof import("@pydantic/logfire-node");
|
|
15
|
-
|
|
16
|
-
let logfireEnabled: boolean = !!getLogfireToken();
|
|
17
|
-
|
|
18
|
-
let logfireInstance: LogfireModule | null = null;
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Initialize Logfire for LLM observability.
|
|
22
|
-
* Dynamically imports @pydantic/logfire-node only when enabled.
|
|
23
|
-
* Non-fatal on failure (logs warning and continues).
|
|
24
|
-
*/
|
|
25
|
-
export async function initLogfire(): Promise<void> {
|
|
26
|
-
if (!logfireEnabled) return;
|
|
27
|
-
|
|
28
|
-
try {
|
|
29
|
-
const logfire = await import("@pydantic/logfire-node");
|
|
30
|
-
logfire.configure({
|
|
31
|
-
token: getLogfireToken(),
|
|
32
|
-
serviceName: "vellum-assistant",
|
|
33
|
-
serviceVersion: APP_VERSION,
|
|
34
|
-
});
|
|
35
|
-
logfireInstance = logfire;
|
|
36
|
-
log.info("Logfire initialized");
|
|
37
|
-
} catch (err) {
|
|
38
|
-
log.warn(
|
|
39
|
-
{ err },
|
|
40
|
-
"Failed to initialize Logfire — LLM observability disabled",
|
|
41
|
-
);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Disable Logfire after early initialization. Called when the user has opted
|
|
47
|
-
* out via the feature flag. Nulls out the instance so future wrapWithLogfire
|
|
48
|
-
* calls become no-ops.
|
|
49
|
-
*/
|
|
50
|
-
export function disableLogfire(): void {
|
|
51
|
-
logfireEnabled = false;
|
|
52
|
-
logfireInstance = null;
|
|
53
|
-
log.info("Logfire disabled by feature flag");
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Wraps a provider with Logfire tracing spans.
|
|
58
|
-
* When logfireEnabled is false, returns the provider as-is (no wrapper allocated).
|
|
59
|
-
*/
|
|
60
|
-
export function wrapWithLogfire(provider: Provider): Provider {
|
|
61
|
-
if (!logfireEnabled) return provider;
|
|
62
|
-
return new LogfireProvider(provider);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Wrapper provider that instruments each sendMessage call with a Logfire span.
|
|
67
|
-
* When Logfire is not initialized, acts as a pure pass-through with zero overhead.
|
|
68
|
-
*/
|
|
69
|
-
class LogfireProvider implements Provider {
|
|
70
|
-
public readonly name: string;
|
|
71
|
-
|
|
72
|
-
constructor(private readonly inner: Provider) {
|
|
73
|
-
this.name = inner.name;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
async sendMessage(
|
|
77
|
-
messages: Message[],
|
|
78
|
-
tools?: ToolDefinition[],
|
|
79
|
-
systemPrompt?: string,
|
|
80
|
-
options?: SendMessageOptions,
|
|
81
|
-
): Promise<ProviderResponse> {
|
|
82
|
-
if (!logfireInstance) {
|
|
83
|
-
return this.inner.sendMessage(messages, tools, systemPrompt, options);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
const start = Date.now();
|
|
87
|
-
|
|
88
|
-
return logfireInstance.span(
|
|
89
|
-
`llm.${this.name}`,
|
|
90
|
-
{
|
|
91
|
-
"llm.provider": this.name,
|
|
92
|
-
"llm.message_count": messages.length,
|
|
93
|
-
"llm.tool_count": tools?.length ?? 0,
|
|
94
|
-
},
|
|
95
|
-
{},
|
|
96
|
-
async (span) => {
|
|
97
|
-
try {
|
|
98
|
-
const response = await this.inner.sendMessage(
|
|
99
|
-
messages,
|
|
100
|
-
tools,
|
|
101
|
-
systemPrompt,
|
|
102
|
-
options,
|
|
103
|
-
);
|
|
104
|
-
const durationMs = Date.now() - start;
|
|
105
|
-
|
|
106
|
-
span.setAttributes({
|
|
107
|
-
"llm.model": response.model,
|
|
108
|
-
"llm.stop_reason": response.stopReason,
|
|
109
|
-
"llm.usage.input_tokens": response.usage.inputTokens,
|
|
110
|
-
"llm.usage.output_tokens": response.usage.outputTokens,
|
|
111
|
-
"llm.usage.cache_creation_input_tokens":
|
|
112
|
-
response.usage.cacheCreationInputTokens ?? 0,
|
|
113
|
-
"llm.usage.cache_read_input_tokens":
|
|
114
|
-
response.usage.cacheReadInputTokens ?? 0,
|
|
115
|
-
"llm.duration_ms": durationMs,
|
|
116
|
-
"llm.success": true,
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
return response;
|
|
120
|
-
} catch (error) {
|
|
121
|
-
const durationMs = Date.now() - start;
|
|
122
|
-
span.setAttributes({
|
|
123
|
-
"llm.duration_ms": durationMs,
|
|
124
|
-
"llm.success": false,
|
|
125
|
-
"llm.error.type":
|
|
126
|
-
error instanceof Error ? error.constructor.name : "Unknown",
|
|
127
|
-
"llm.error.message":
|
|
128
|
-
error instanceof Error ? error.message : String(error),
|
|
129
|
-
});
|
|
130
|
-
throw error;
|
|
131
|
-
}
|
|
132
|
-
},
|
|
133
|
-
);
|
|
134
|
-
}
|
|
135
|
-
}
|