@vellumai/assistant 0.5.1 → 0.5.3
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/ARCHITECTURE.md +163 -54
- package/docs/architecture/integrations.md +62 -67
- package/docs/credential-execution-service.md +3 -3
- package/docs/skills.md +100 -0
- package/package.json +1 -1
- package/src/__tests__/agent-loop.test.ts +111 -0
- package/src/__tests__/always-loaded-tools-guard.test.ts +3 -4
- package/src/__tests__/app-builder-tool-scripts.test.ts +13 -151
- package/src/__tests__/app-dir-path-guard.test.ts +78 -0
- package/src/__tests__/app-executors.test.ts +1 -291
- package/src/__tests__/app-git-history.test.ts +4 -4
- package/src/__tests__/app-routes-csp.test.ts +1 -0
- package/src/__tests__/app-store-dir-names.test.ts +426 -0
- package/src/__tests__/attachments-store.test.ts +169 -21
- package/src/__tests__/attachments.test.ts +115 -1
- package/src/__tests__/btw-routes.test.ts +1 -0
- package/src/__tests__/canonical-guardian-store.test.ts +38 -0
- package/src/__tests__/channel-reply-delivery.test.ts +55 -0
- package/src/__tests__/checker.test.ts +54 -0
- package/src/__tests__/claude-code-skill-regression.test.ts +2 -0
- package/src/__tests__/claude-code-tool-profiles.test.ts +2 -0
- package/src/__tests__/compaction.benchmark.test.ts +2 -1
- package/src/__tests__/config-schema-cmd.test.ts +68 -21
- package/src/__tests__/config-schema.test.ts +1 -1
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +156 -5
- package/src/__tests__/conversation-agent-loop.test.ts +297 -2
- package/src/__tests__/conversation-attachments.test.ts +17 -19
- package/src/__tests__/conversation-disk-view-integration.test.ts +277 -0
- package/src/__tests__/conversation-disk-view.test.ts +810 -0
- package/src/__tests__/conversation-error.test.ts +1 -1
- package/src/__tests__/conversation-fork-crud.test.ts +551 -0
- package/src/__tests__/conversation-fork-route.test.ts +386 -0
- package/src/__tests__/conversation-history-web-search.test.ts +1 -1
- package/src/__tests__/conversation-key-store-disk-view.test.ts +130 -0
- package/src/__tests__/conversation-media-retry.test.ts +8 -2
- package/src/__tests__/conversation-memory-dirty-tail.test.ts +150 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +7 -0
- package/src/__tests__/conversation-queue.test.ts +36 -1
- package/src/__tests__/conversation-routes-disk-view.test.ts +439 -0
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +2 -2
- package/src/__tests__/conversation-routes-slash-commands.test.ts +2 -7
- package/src/__tests__/conversation-runtime-assembly.test.ts +17 -2
- package/src/__tests__/conversation-skill-tools.test.ts +4 -9
- package/src/__tests__/conversation-slash-commands.test.ts +149 -0
- package/src/__tests__/conversation-store.test.ts +24 -21
- package/src/__tests__/conversation-surfaces-state-update.test.ts +246 -0
- package/src/__tests__/conversation-surfaces-task-progress.test.ts +1 -0
- package/src/__tests__/conversation-title-service.test.ts +137 -0
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +25 -315
- package/src/__tests__/conversation-tool-setup-memory-scope.test.ts +1 -0
- package/src/__tests__/conversation-tool-setup-side-effect-flag.test.ts +1 -0
- package/src/__tests__/conversation-wipe.test.ts +226 -0
- package/src/__tests__/conversation-workspace-cache-state.test.ts +44 -2
- package/src/__tests__/conversation-workspace-injection.test.ts +11 -0
- package/src/__tests__/credential-security-invariants.test.ts +3 -0
- package/src/__tests__/credential-vault-unit.test.ts +5 -10
- package/src/__tests__/cu-unified-flow.test.ts +1 -0
- package/src/__tests__/db-conversation-fork-lineage-migration.test.ts +241 -0
- package/src/__tests__/db-llm-request-log-provider-migration.test.ts +214 -0
- package/src/__tests__/db-memory-archive-migration.test.ts +372 -0
- package/src/__tests__/db-memory-brief-state-migration.test.ts +213 -0
- package/src/__tests__/db-memory-reducer-checkpoints.test.ts +273 -0
- package/src/__tests__/diagnostics-export.test.ts +70 -1
- package/src/__tests__/first-greeting.test.ts +80 -0
- package/src/__tests__/gateway-only-guard.test.ts +1 -0
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +3 -7
- package/src/__tests__/history-repair.test.ts +32 -10
- package/src/__tests__/http-conversation-lineage.test.ts +251 -0
- package/src/__tests__/image-source-path-reinject.test.ts +136 -0
- package/src/__tests__/inline-command-runner.test.ts +311 -0
- package/src/__tests__/inline-skill-authoring-guard.test.ts +220 -0
- package/src/__tests__/inline-skill-load-permissions.test.ts +435 -0
- package/src/__tests__/list-messages-attachments.test.ts +96 -0
- package/src/__tests__/llm-context-normalization.test.ts +1116 -0
- package/src/__tests__/llm-context-route-provider.test.ts +217 -0
- package/src/__tests__/llm-request-log-turn-query.test.ts +270 -0
- package/src/__tests__/media-generate-image.test.ts +47 -94
- package/src/__tests__/memory-brief-open-loops.test.ts +530 -0
- package/src/__tests__/memory-brief-time.test.ts +285 -0
- package/src/__tests__/memory-brief-wrapper.test.ts +311 -0
- package/src/__tests__/memory-chunk-archive.test.ts +400 -0
- package/src/__tests__/memory-chunk-dual-write.test.ts +453 -0
- package/src/__tests__/memory-episode-archive.test.ts +370 -0
- package/src/__tests__/memory-episode-dual-write.test.ts +626 -0
- package/src/__tests__/memory-lifecycle-e2e.test.ts +3 -1
- package/src/__tests__/memory-observation-archive.test.ts +375 -0
- package/src/__tests__/memory-observation-dual-write.test.ts +318 -0
- package/src/__tests__/memory-recall-quality.test.ts +7 -7
- package/src/__tests__/memory-reducer-store.test.ts +728 -0
- package/src/__tests__/memory-reducer-types.test.ts +699 -0
- package/src/__tests__/memory-reducer.test.ts +698 -0
- package/src/__tests__/memory-regressions.test.ts +6 -4
- package/src/__tests__/memory-simplified-config.test.ts +281 -0
- package/src/__tests__/migration-cross-version-compatibility.test.ts +4 -1
- package/src/__tests__/migration-export-http.test.ts +3 -1
- package/src/__tests__/migration-import-commit-http.test.ts +18 -4
- package/src/__tests__/migration-import-preflight-http.test.ts +1 -3
- package/src/__tests__/mime-builder.test.ts +3 -2
- package/src/__tests__/non-member-access-request.test.ts +12 -1
- package/src/__tests__/notification-decision-identity.test.ts +52 -0
- package/src/__tests__/oauth-apps-routes.test.ts +103 -0
- package/src/__tests__/oauth-store.test.ts +115 -0
- package/src/__tests__/parse-identity-fields.test.ts +129 -0
- package/src/__tests__/provider-error-scenarios.test.ts +1 -3
- package/src/__tests__/provider-failover-actual-provider.test.ts +66 -0
- package/src/__tests__/recording-handler.test.ts +17 -0
- package/src/__tests__/registry.test.ts +3 -8
- package/src/__tests__/relay-server.test.ts +1 -1
- package/src/__tests__/runtime-attachment-metadata.test.ts +7 -3
- package/src/__tests__/schema-transforms.test.ts +165 -5
- package/src/__tests__/server-history-render.test.ts +2 -2
- package/src/__tests__/skill-load-inline-command.test.ts +598 -0
- package/src/__tests__/skill-load-inline-includes.test.ts +644 -0
- package/src/__tests__/skills-inline-command-expansions.test.ts +301 -0
- package/src/__tests__/skills-transitive-hash.test.ts +333 -0
- package/src/__tests__/slack-app-setup-skill-regression.test.ts +3 -1
- package/src/__tests__/slack-inbound-verification.test.ts +2 -2
- package/src/__tests__/starter-task-flow.test.ts +1 -0
- package/src/__tests__/suggestion-routes.test.ts +443 -0
- package/src/__tests__/swarm-conversation-integration.test.ts +1 -0
- package/src/__tests__/swarm-recursion.test.ts +1 -0
- package/src/__tests__/swarm-tool.test.ts +1 -0
- package/src/__tests__/tool-execution-abort-cleanup.test.ts +1 -0
- package/src/__tests__/tool-preview-lifecycle.test.ts +32 -5
- package/src/__tests__/top-level-renderer.test.ts +22 -0
- package/src/__tests__/turn-boundary-resolution.test.ts +243 -0
- package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +320 -0
- package/src/__tests__/web-fetch.test.ts +6 -2
- package/src/__tests__/workspace-migration-006-services-config.test.ts +335 -0
- package/src/__tests__/workspace-migration-007-web-search-provider-rename.test.ts +312 -0
- package/src/__tests__/workspace-migration-009-backfill-conversation-disk-view.test.ts +278 -0
- package/src/__tests__/workspace-migration-010-app-dir-rename.test.ts +275 -0
- package/src/__tests__/workspace-migration-012-rename-conversation-disk-view-dirs.test.ts +77 -0
- package/src/__tests__/workspace-migration-013-repair-conversation-disk-view.test.ts +401 -0
- package/src/__tests__/workspace-migration-backfill-installation-id.test.ts +328 -0
- package/src/__tests__/workspace-migration-seed-device-id.test.ts +6 -10
- package/src/agent/attachments.ts +27 -1
- package/src/agent/loop.ts +29 -1
- package/src/avatar/traits-png-sync.ts +80 -25
- package/src/bundler/app-bundler.ts +4 -4
- package/src/calls/call-domain.ts +1 -0
- package/src/calls/voice-session-bridge.ts +1 -0
- package/src/cli/commands/auth.ts +92 -0
- package/src/cli/commands/avatar.ts +7 -6
- package/src/cli/commands/config.ts +2 -0
- package/src/cli/commands/oauth/providers.ts +29 -0
- package/src/cli/program.ts +12 -0
- package/src/cli.ts +15 -48
- package/src/config/bundled-skills/app-builder/SKILL.md +103 -28
- package/src/config/bundled-skills/app-builder/TOOLS.json +5 -199
- package/src/config/bundled-skills/app-builder/tools/{app-query.ts → app-refresh.ts} +2 -2
- package/src/config/bundled-skills/contacts/tools/google-contacts.ts +2 -3
- package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +6 -9
- package/src/config/bundled-skills/gmail/tools/gmail-attachments.ts +4 -6
- package/src/config/bundled-skills/gmail/tools/gmail-draft.ts +2 -3
- package/src/config/bundled-skills/gmail/tools/gmail-filters.ts +2 -3
- package/src/config/bundled-skills/gmail/tools/gmail-follow-up.ts +2 -3
- package/src/config/bundled-skills/gmail/tools/gmail-forward.ts +2 -3
- package/src/config/bundled-skills/gmail/tools/gmail-label.ts +4 -6
- package/src/config/bundled-skills/gmail/tools/gmail-outreach-scan.ts +2 -3
- package/src/config/bundled-skills/gmail/tools/gmail-send-draft.ts +2 -3
- package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +2 -3
- package/src/config/bundled-skills/gmail/tools/gmail-trash.ts +2 -3
- package/src/config/bundled-skills/gmail/tools/gmail-unsubscribe.ts +2 -3
- package/src/config/bundled-skills/gmail/tools/gmail-vacation.ts +2 -3
- package/src/config/bundled-skills/google-calendar/tools/shared.ts +1 -1
- package/src/config/bundled-skills/image-studio/SKILL.md +2 -2
- package/src/config/bundled-skills/image-studio/TOOLS.json +2 -2
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +45 -72
- package/src/config/bundled-skills/media-processing/tools/extract-keyframes.ts +2 -2
- package/src/config/bundled-skills/messaging/tools/shared.ts +1 -1
- package/src/config/bundled-skills/settings/tools/voice-config-update.ts +19 -3
- package/src/config/bundled-skills/skill-management/SKILL.md +1 -1
- package/src/config/bundled-skills/skill-management/TOOLS.json +2 -2
- package/src/config/bundled-skills/slack/tools/shared.ts +19 -4
- package/src/config/bundled-skills/slack/tools/slack-scan-digest.ts +2 -3
- package/src/config/bundled-skills/transcribe/SKILL.md +1 -1
- package/src/config/bundled-skills/transcribe/TOOLS.json +2 -6
- package/src/config/bundled-skills/transcribe/tools/transcribe-media.ts +19 -83
- package/src/config/bundled-tool-registry.ts +2 -14
- package/src/config/feature-flag-registry.json +24 -0
- package/src/config/loader.ts +65 -0
- package/src/config/raw-config-utils.ts +58 -0
- package/src/config/schema-utils.ts +28 -7
- package/src/config/schema.ts +20 -0
- package/src/config/schemas/elevenlabs.ts +18 -0
- package/src/config/schemas/memory-lifecycle.ts +4 -2
- package/src/config/schemas/memory-simplified.ts +101 -0
- package/src/config/schemas/memory-storage.ts +1 -1
- package/src/config/schemas/memory.ts +4 -0
- package/src/config/schemas/services.ts +8 -6
- package/src/config/skills.ts +50 -4
- package/src/contacts/contact-store.ts +13 -6
- package/src/contacts/contacts-write.ts +0 -1
- package/src/context/window-manager.ts +13 -2
- package/src/daemon/conversation-agent-loop-handlers.ts +54 -8
- package/src/daemon/conversation-agent-loop.ts +127 -20
- package/src/daemon/conversation-attachments.ts +18 -36
- package/src/daemon/conversation-error.ts +2 -1
- package/src/daemon/conversation-history.ts +18 -4
- package/src/daemon/conversation-lifecycle.ts +50 -16
- package/src/daemon/conversation-messaging.ts +70 -26
- package/src/daemon/conversation-process.ts +58 -34
- package/src/daemon/conversation-runtime-assembly.ts +22 -38
- package/src/daemon/conversation-slash.ts +121 -256
- package/src/daemon/conversation-surfaces.ts +170 -24
- package/src/daemon/conversation-tool-setup.ts +0 -6
- package/src/daemon/conversation-workspace.ts +21 -1
- package/src/daemon/conversation.ts +69 -30
- package/src/daemon/first-greeting.ts +35 -0
- package/src/daemon/handlers/config-embeddings.ts +156 -0
- package/src/daemon/handlers/config-model.ts +62 -26
- package/src/daemon/handlers/conversations.ts +0 -23
- package/src/daemon/handlers/identity.ts +12 -1
- package/src/daemon/handlers/recording.ts +26 -21
- package/src/daemon/host-cu-proxy.ts +2 -2
- package/src/daemon/lifecycle.ts +115 -65
- package/src/daemon/message-protocol.ts +3 -0
- package/src/daemon/message-types/conversations.ts +18 -0
- package/src/daemon/message-types/messages.ts +1 -0
- package/src/daemon/message-types/shared.ts +2 -0
- package/src/daemon/message-types/surfaces.ts +2 -0
- package/src/daemon/message-types/upgrades.ts +23 -0
- package/src/daemon/server.ts +83 -12
- package/src/daemon/shutdown-handlers.ts +8 -5
- package/src/daemon/startup-error.ts +9 -0
- package/src/daemon/tool-side-effects.ts +11 -28
- package/src/events/tool-permission-telemetry-listener.ts +1 -3
- package/src/followups/followup-store.ts +47 -1
- package/src/instrument.ts +0 -4
- package/src/media/app-icon-generator.ts +2 -2
- package/src/memory/app-git-service.ts +28 -16
- package/src/memory/app-store.ts +230 -41
- package/src/memory/archive-store.ts +400 -0
- package/src/memory/attachments-store.ts +558 -130
- package/src/memory/brief-formatting.ts +33 -0
- package/src/memory/brief-open-loops.ts +266 -0
- package/src/memory/brief-time.ts +161 -0
- package/src/memory/brief.ts +75 -0
- package/src/memory/conversation-attention-store.ts +70 -0
- package/src/memory/conversation-crud.ts +591 -8
- package/src/memory/conversation-directories.ts +125 -0
- package/src/memory/conversation-disk-view.ts +390 -0
- package/src/memory/conversation-key-store.ts +17 -5
- package/src/memory/conversation-queries.ts +5 -1
- package/src/memory/conversation-title-service.ts +21 -49
- package/src/memory/db-init.ts +40 -0
- package/src/memory/embedding-backend.ts +42 -53
- package/src/memory/embedding-gemini.test.ts +4 -4
- package/src/memory/embedding-local.ts +1 -3
- package/src/memory/embedding-ollama.ts +1 -3
- package/src/memory/embedding-openai.ts +1 -3
- package/src/memory/indexer.ts +114 -21
- package/src/memory/items-extractor.ts +42 -13
- package/src/memory/job-handlers/conversation-starters.ts +6 -1
- package/src/memory/job-handlers/embedding.test.ts +2 -4
- package/src/memory/job-handlers/embedding.ts +83 -0
- package/src/memory/job-utils.ts +1 -1
- package/src/memory/jobs-store.ts +6 -0
- package/src/memory/jobs-worker.ts +12 -0
- package/src/memory/llm-request-log-store.ts +100 -1
- package/src/memory/migrations/102-alter-table-columns.ts +5 -0
- package/src/memory/migrations/146-schedule-oneshot-routing.ts +3 -3
- package/src/memory/migrations/147-migrate-reminders-to-schedules.ts +66 -70
- package/src/memory/migrations/148-drop-reminders-table.ts +5 -9
- package/src/memory/migrations/160-drop-loopback-port-column.ts +1 -3
- package/src/memory/migrations/174-rename-thread-starters-table.ts +0 -7
- package/src/memory/migrations/178-oauth-providers-managed-service-config-key.ts +15 -0
- package/src/memory/migrations/179-llm-request-log-message-id.ts +16 -0
- package/src/memory/migrations/180-backfill-inline-attachments-to-disk.ts +66 -0
- package/src/memory/migrations/181-rename-thread-starters-checkpoints.ts +46 -0
- package/src/memory/migrations/182-oauth-providers-display-metadata.ts +20 -0
- package/src/memory/migrations/183-add-conversation-fork-lineage.ts +22 -0
- package/src/memory/migrations/184-llm-request-log-provider.ts +12 -0
- package/src/memory/migrations/185-memory-brief-state.ts +52 -0
- package/src/memory/migrations/186-memory-archive.ts +109 -0
- package/src/memory/migrations/187-memory-reducer-checkpoints.ts +19 -0
- package/src/memory/migrations/index.ts +10 -0
- package/src/memory/migrations/registry.ts +13 -0
- package/src/memory/qdrant-client.ts +23 -4
- package/src/memory/reducer-store.ts +271 -0
- package/src/memory/reducer-types.ts +99 -0
- package/src/memory/reducer.ts +453 -0
- package/src/memory/retriever.test.ts +601 -2
- package/src/memory/retriever.ts +85 -9
- package/src/memory/schema/conversations.ts +9 -0
- package/src/memory/schema/index.ts +2 -0
- package/src/memory/schema/infrastructure.ts +13 -7
- package/src/memory/schema/memory-archive.ts +121 -0
- package/src/memory/schema/memory-brief.ts +55 -0
- package/src/memory/schema/oauth.ts +6 -0
- package/src/memory/search/semantic.ts +17 -4
- package/src/messaging/providers/gmail/mime-builder.ts +3 -1
- package/src/notifications/copy-composer.ts +26 -0
- package/src/notifications/decision-engine.ts +14 -1
- package/src/notifications/emit-signal.ts +1 -1
- package/src/notifications/signal.ts +36 -0
- package/src/oauth/byo-connection.test.ts +1 -45
- package/src/oauth/byo-connection.ts +2 -8
- package/src/oauth/connect-orchestrator.ts +15 -11
- package/src/oauth/connection-resolver.test.ts +191 -0
- package/src/oauth/connection-resolver.ts +66 -38
- package/src/oauth/connection.ts +0 -1
- package/src/oauth/oauth-store.ts +99 -47
- package/src/oauth/platform-connection.test.ts +0 -1
- package/src/oauth/platform-connection.ts +11 -3
- package/src/oauth/seed-providers.ts +78 -3
- package/src/oauth/token-persistence.ts +16 -10
- package/src/permissions/checker.ts +160 -14
- package/src/permissions/defaults.ts +14 -0
- package/src/prompts/templates/BOOTSTRAP.md +2 -0
- package/src/providers/anthropic/client.ts +8 -1
- package/src/providers/failover.ts +4 -1
- package/src/providers/gemini/client.ts +50 -0
- package/src/providers/model-catalog.ts +92 -0
- package/src/providers/model-intents.ts +29 -20
- package/src/providers/openai/client.ts +49 -0
- package/src/providers/types.ts +2 -0
- package/src/runtime/access-request-helper.ts +16 -7
- package/src/runtime/auth/credential-service.ts +3 -1
- package/src/runtime/auth/route-policy.ts +14 -1
- package/src/runtime/btw-sidechain.ts +101 -0
- package/src/runtime/channel-reply-delivery.ts +17 -1
- package/src/runtime/http-router.ts +3 -1
- package/src/runtime/http-server.ts +196 -141
- package/src/runtime/http-types.ts +1 -0
- package/src/runtime/migrations/vbundle-builder.ts +5 -1
- package/src/runtime/routes/access-request-decision.ts +41 -0
- package/src/runtime/routes/app-management-routes.ts +6 -3
- package/src/runtime/routes/app-routes.ts +7 -3
- package/src/runtime/routes/approval-routes.ts +1 -0
- package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +34 -2
- package/src/runtime/routes/attachment-routes.ts +45 -15
- package/src/runtime/routes/btw-routes.ts +21 -61
- package/src/runtime/routes/conversation-management-routes.ts +74 -0
- package/src/runtime/routes/conversation-query-routes.ts +187 -10
- package/src/runtime/routes/conversation-routes.ts +269 -28
- package/src/runtime/routes/conversation-starter-routes.ts +9 -11
- package/src/runtime/routes/diagnostics-routes.ts +1 -0
- package/src/runtime/routes/identity-routes.ts +2 -35
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +2 -2
- package/src/runtime/routes/llm-context-normalization.ts +1212 -0
- package/src/runtime/routes/log-export-routes.ts +3 -0
- package/src/runtime/routes/memory-item-routes.test.ts +34 -0
- package/src/runtime/routes/memory-item-routes.ts +94 -5
- package/src/runtime/routes/migration-routes.ts +4 -1
- package/src/runtime/routes/oauth-apps.ts +291 -0
- package/src/runtime/routes/secret-routes.ts +30 -1
- package/src/runtime/routes/settings-routes.ts +14 -0
- package/src/runtime/routes/surface-action-routes.ts +68 -1
- package/src/runtime/routes/trace-event-routes.ts +4 -1
- package/src/schedule/schedule-store.ts +30 -21
- package/src/security/secure-keys.ts +21 -0
- package/src/signals/bash.ts +1 -1
- package/src/skills/inline-command-expansions.ts +204 -0
- package/src/skills/inline-command-render.ts +127 -0
- package/src/skills/inline-command-runner.ts +242 -0
- package/src/skills/transitive-version-hash.ts +88 -0
- package/src/swarm/backend-claude-code.ts +3 -6
- package/src/tasks/task-store.ts +43 -1
- package/src/telemetry/usage-telemetry-reporter.test.ts +3 -2
- package/src/telemetry/usage-telemetry-reporter.ts +3 -1
- package/src/tools/AGENTS.md +6 -10
- package/src/tools/apps/executors.ts +17 -232
- package/src/tools/claude-code/claude-code.ts +2 -3
- package/src/tools/credentials/vault.ts +7 -12
- package/src/tools/host-filesystem/read.ts +13 -10
- package/src/tools/network/__tests__/web-search.test.ts +4 -2
- package/src/tools/permission-checker.ts +8 -1
- package/src/tools/schedule/list.ts +2 -7
- package/src/tools/schema-transforms.ts +5 -0
- package/src/tools/shared/filesystem/format-diff.ts +2 -7
- package/src/tools/skills/execute.ts +1 -1
- package/src/tools/skills/load.ts +140 -6
- package/src/tools/tool-manifest.ts +0 -6
- package/src/tools/ui-surface/definitions.ts +2 -2
- package/src/util/device-id.ts +28 -5
- package/src/util/platform.ts +24 -0
- package/src/util/pricing.ts +1 -0
- package/src/util/retry.ts +1 -3
- package/src/workspace/migrations/003-seed-device-id.ts +3 -4
- package/src/workspace/migrations/006-services-config.ts +5 -0
- package/src/workspace/migrations/008-voice-timeout-and-max-steps.ts +12 -0
- package/src/workspace/migrations/009-backfill-conversation-disk-view.ts +10 -0
- package/src/workspace/migrations/010-app-dir-rename.ts +223 -0
- package/src/workspace/migrations/{002-backfill-installation-id.ts → 011-backfill-installation-id.ts} +24 -13
- package/src/workspace/migrations/012-rename-conversation-disk-view-dirs.ts +64 -0
- package/src/workspace/migrations/013-repair-conversation-disk-view.ts +11 -0
- package/src/workspace/migrations/rebuild-conversation-disk-view.ts +186 -0
- package/src/workspace/migrations/registry.ts +11 -1
- package/src/workspace/top-level-renderer.ts +12 -0
- package/src/__tests__/asset-materialize-tool.test.ts +0 -523
- package/src/__tests__/asset-search-tool.test.ts +0 -536
- package/src/__tests__/fixtures/media-reuse-fixtures.ts +0 -56
- package/src/__tests__/media-reuse-story.e2e.test.ts +0 -762
- package/src/__tests__/media-visibility-policy.test.ts +0 -190
- package/src/config/bundled-skills/app-builder/tools/app-file-edit.ts +0 -14
- package/src/config/bundled-skills/app-builder/tools/app-file-list.ts +0 -13
- package/src/config/bundled-skills/app-builder/tools/app-file-read.ts +0 -21
- package/src/config/bundled-skills/app-builder/tools/app-file-write.ts +0 -14
- package/src/config/bundled-skills/app-builder/tools/app-list.ts +0 -13
- package/src/config/bundled-skills/app-builder/tools/app-update.ts +0 -23
- package/src/daemon/media-visibility-policy.ts +0 -59
- package/src/tools/assets/materialize.ts +0 -248
- package/src/tools/assets/search.ts +0 -400
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sandbox-only runner for inline command expansions (`!\`command\``).
|
|
3
|
+
*
|
|
4
|
+
* Executes the literal command string in the sandbox without going through the
|
|
5
|
+
* general `bash` tool's permission path. Security constraints:
|
|
6
|
+
*
|
|
7
|
+
* - Network mode forced off (no outbound connections)
|
|
8
|
+
* - Sanitized environment variables only (no API keys, tokens, credentials)
|
|
9
|
+
* - No credential proxy, no CES client, no host fallback
|
|
10
|
+
* - Uses the conversation working directory as `cwd` so repo-local commands
|
|
11
|
+
* remain interoperable with externally authored skills that expect project
|
|
12
|
+
* context.
|
|
13
|
+
*
|
|
14
|
+
* Output handling:
|
|
15
|
+
* - Captures stdout only (stderr is discarded)
|
|
16
|
+
* - Strips ANSI escape sequences
|
|
17
|
+
* - Rejects binary-ish output
|
|
18
|
+
* - Clamps output to a fixed cap
|
|
19
|
+
* - Returns deterministic sanitized error results for timeout, non-zero exit,
|
|
20
|
+
* or spawn failures (no raw stderr dumps)
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
import { spawn } from "node:child_process";
|
|
24
|
+
|
|
25
|
+
import { getConfig } from "../config/loader.js";
|
|
26
|
+
import { buildSanitizedEnv } from "../tools/terminal/safe-env.js";
|
|
27
|
+
import { wrapCommand } from "../tools/terminal/sandbox.js";
|
|
28
|
+
import { getLogger } from "../util/logger.js";
|
|
29
|
+
|
|
30
|
+
const log = getLogger("inline-command-runner");
|
|
31
|
+
|
|
32
|
+
// ─── Constants ───────────────────────────────────────────────────────────────
|
|
33
|
+
|
|
34
|
+
/** Maximum wall-clock time for an inline command before it is killed. */
|
|
35
|
+
const DEFAULT_TIMEOUT_MS = 10_000;
|
|
36
|
+
|
|
37
|
+
/** Maximum output characters before truncation. */
|
|
38
|
+
const MAX_OUTPUT_CHARS = 20_000;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* ANSI escape sequence pattern (covers SGR, cursor movement, erase, etc.).
|
|
42
|
+
* Matches: ESC[ ... final_byte and ESC] ... ST (OSC sequences).
|
|
43
|
+
*/
|
|
44
|
+
const ANSI_RE = /\x1b\[[0-9;]*[A-Za-z]|\x1b\][^\x07]*(?:\x07|\x1b\\)/g;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Heuristic for binary output: if more than 10% of the characters are
|
|
48
|
+
* non-printable (control chars excluding \t, \n, \r) then reject.
|
|
49
|
+
*/
|
|
50
|
+
const BINARY_THRESHOLD = 0.1;
|
|
51
|
+
|
|
52
|
+
// ─── Result type ─────────────────────────────────────────────────────────────
|
|
53
|
+
|
|
54
|
+
/** Deterministic result shape returned by the inline command runner. */
|
|
55
|
+
export interface InlineCommandResult {
|
|
56
|
+
/** The sanitized stdout output, or a human-readable error description. */
|
|
57
|
+
output: string;
|
|
58
|
+
/** Whether the command completed successfully. */
|
|
59
|
+
ok: boolean;
|
|
60
|
+
/**
|
|
61
|
+
* Machine-readable failure reason.
|
|
62
|
+
* - `"timeout"` — command exceeded the wall-clock limit
|
|
63
|
+
* - `"non_zero_exit"` — command exited with a non-zero code
|
|
64
|
+
* - `"binary_output"` — stdout contained binary-ish data
|
|
65
|
+
* - `"spawn_failure"` — the subprocess could not be spawned
|
|
66
|
+
* - `undefined` — success
|
|
67
|
+
*/
|
|
68
|
+
failureReason?:
|
|
69
|
+
| "timeout"
|
|
70
|
+
| "non_zero_exit"
|
|
71
|
+
| "binary_output"
|
|
72
|
+
| "spawn_failure";
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// ─── Public API ──────────────────────────────────────────────────────────────
|
|
76
|
+
|
|
77
|
+
export interface InlineCommandRunnerOptions {
|
|
78
|
+
/** Override the default timeout (ms). */
|
|
79
|
+
timeoutMs?: number;
|
|
80
|
+
/** Override the default output cap (chars). */
|
|
81
|
+
maxOutputChars?: number;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Run an inline command expansion in the sandbox.
|
|
86
|
+
*
|
|
87
|
+
* @param command The literal command string from the `!\`...\`` token.
|
|
88
|
+
* @param workingDir The conversation's working directory (repo root).
|
|
89
|
+
* @param options Optional overrides for timeout and output cap.
|
|
90
|
+
*/
|
|
91
|
+
export async function runInlineCommand(
|
|
92
|
+
command: string,
|
|
93
|
+
workingDir: string,
|
|
94
|
+
options?: InlineCommandRunnerOptions,
|
|
95
|
+
): Promise<InlineCommandResult> {
|
|
96
|
+
const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
97
|
+
const maxChars = options?.maxOutputChars ?? MAX_OUTPUT_CHARS;
|
|
98
|
+
|
|
99
|
+
// Build sandbox-wrapped command. Always use the sandbox config with
|
|
100
|
+
// network forced off — inline commands never need network access.
|
|
101
|
+
const config = getConfig();
|
|
102
|
+
const sandboxConfig = { ...config.sandbox, enabled: true };
|
|
103
|
+
|
|
104
|
+
const wrapped = wrapCommand(command, workingDir, sandboxConfig, {
|
|
105
|
+
networkMode: "off",
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
// Build a minimal, sanitized environment. Explicitly exclude gateway URL,
|
|
109
|
+
// workspace dir, and data dir since inline commands have no business calling
|
|
110
|
+
// internal APIs, mutating workspace state, or accessing instance-scoped data.
|
|
111
|
+
const env = buildSanitizedEnv();
|
|
112
|
+
delete env.INTERNAL_GATEWAY_BASE_URL;
|
|
113
|
+
delete env.VELLUM_WORKSPACE_DIR;
|
|
114
|
+
delete env.VELLUM_DATA_DIR;
|
|
115
|
+
|
|
116
|
+
return new Promise<InlineCommandResult>((resolve) => {
|
|
117
|
+
let timedOut = false;
|
|
118
|
+
const stdoutChunks: Buffer[] = [];
|
|
119
|
+
|
|
120
|
+
let child: ReturnType<typeof spawn>;
|
|
121
|
+
try {
|
|
122
|
+
child = spawn(wrapped.command, wrapped.args, {
|
|
123
|
+
cwd: workingDir,
|
|
124
|
+
env,
|
|
125
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
126
|
+
});
|
|
127
|
+
} catch (err) {
|
|
128
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
129
|
+
log.warn({ command, error: message }, "Failed to spawn inline command");
|
|
130
|
+
resolve({
|
|
131
|
+
output: "Inline command could not be started.",
|
|
132
|
+
ok: false,
|
|
133
|
+
failureReason: "spawn_failure",
|
|
134
|
+
});
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const timer = setTimeout(() => {
|
|
139
|
+
timedOut = true;
|
|
140
|
+
child.kill("SIGKILL");
|
|
141
|
+
}, timeoutMs);
|
|
142
|
+
|
|
143
|
+
child.stdout!.on("data", (data: Buffer) => stdoutChunks.push(data));
|
|
144
|
+
|
|
145
|
+
child.on("close", (code) => {
|
|
146
|
+
clearTimeout(timer);
|
|
147
|
+
|
|
148
|
+
// ── Timeout ──────────────────────────────────────────────────────
|
|
149
|
+
if (timedOut) {
|
|
150
|
+
log.debug({ command, timeoutMs }, "Inline command timed out");
|
|
151
|
+
resolve({
|
|
152
|
+
output: `Inline command timed out after ${timeoutMs}ms.`,
|
|
153
|
+
ok: false,
|
|
154
|
+
failureReason: "timeout",
|
|
155
|
+
});
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// ── Non-zero exit ────────────────────────────────────────────────
|
|
160
|
+
if (code !== 0) {
|
|
161
|
+
log.debug(
|
|
162
|
+
{ command, exitCode: code },
|
|
163
|
+
"Inline command exited with non-zero code",
|
|
164
|
+
);
|
|
165
|
+
resolve({
|
|
166
|
+
output: `Inline command failed (exit code ${code}).`,
|
|
167
|
+
ok: false,
|
|
168
|
+
failureReason: "non_zero_exit",
|
|
169
|
+
});
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// ── Process stdout ───────────────────────────────────────────────
|
|
174
|
+
const raw = Buffer.concat(stdoutChunks).toString("utf-8");
|
|
175
|
+
|
|
176
|
+
// Strip ANSI sequences first — these are terminal artifacts, not
|
|
177
|
+
// binary data. Stripping before the binary check prevents legitimate
|
|
178
|
+
// color-coded tool output from being rejected.
|
|
179
|
+
let cleaned = raw.replace(ANSI_RE, "");
|
|
180
|
+
|
|
181
|
+
// Reject binary-ish output (after ANSI stripping)
|
|
182
|
+
if (isBinaryish(cleaned)) {
|
|
183
|
+
log.debug({ command }, "Inline command produced binary-ish output");
|
|
184
|
+
resolve({
|
|
185
|
+
output: "Inline command produced binary output.",
|
|
186
|
+
ok: false,
|
|
187
|
+
failureReason: "binary_output",
|
|
188
|
+
});
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Clamp to max output
|
|
193
|
+
if (cleaned.length > maxChars) {
|
|
194
|
+
cleaned = cleaned.slice(0, maxChars) + "\n[output truncated]";
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Trim trailing whitespace
|
|
198
|
+
cleaned = cleaned.trimEnd();
|
|
199
|
+
|
|
200
|
+
resolve({
|
|
201
|
+
output: cleaned,
|
|
202
|
+
ok: true,
|
|
203
|
+
});
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
child.on("error", (err) => {
|
|
207
|
+
clearTimeout(timer);
|
|
208
|
+
log.warn({ command, error: err.message }, "Inline command spawn error");
|
|
209
|
+
resolve({
|
|
210
|
+
output: "Inline command could not be started.",
|
|
211
|
+
ok: false,
|
|
212
|
+
failureReason: "spawn_failure",
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// ─── Helpers ─────────────────────────────────────────────────────────────────
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Heuristic check for binary output. Returns true if more than
|
|
222
|
+
* {@link BINARY_THRESHOLD} of the characters are non-printable control
|
|
223
|
+
* characters (excluding tab, newline, carriage return).
|
|
224
|
+
*/
|
|
225
|
+
function isBinaryish(text: string): boolean {
|
|
226
|
+
if (text.length === 0) return false;
|
|
227
|
+
|
|
228
|
+
let controlCount = 0;
|
|
229
|
+
for (let i = 0; i < text.length; i++) {
|
|
230
|
+
const code = text.charCodeAt(i);
|
|
231
|
+
// Control characters: 0x00-0x1F (excluding \t=0x09, \n=0x0A, \r=0x0D)
|
|
232
|
+
// and 0x7F (DEL)
|
|
233
|
+
if (
|
|
234
|
+
(code <= 0x1f && code !== 0x09 && code !== 0x0a && code !== 0x0d) ||
|
|
235
|
+
code === 0x7f
|
|
236
|
+
) {
|
|
237
|
+
controlCount++;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
return controlCount / text.length > BINARY_THRESHOLD;
|
|
242
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
|
|
3
|
+
import type { SkillSummary } from "../config/skills.js";
|
|
4
|
+
import { validateIncludes } from "./include-graph.js";
|
|
5
|
+
import { computeSkillVersionHash } from "./version-hash.js";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Error thrown when the include graph is invalid (missing nodes or cycles).
|
|
9
|
+
* The permission layer depends on exact approval candidates, so we fail closed
|
|
10
|
+
* rather than returning a partial or potentially misleading hash.
|
|
11
|
+
*/
|
|
12
|
+
export class TransitiveHashError extends Error {
|
|
13
|
+
constructor(
|
|
14
|
+
message: string,
|
|
15
|
+
public readonly code: "missing" | "cycle",
|
|
16
|
+
) {
|
|
17
|
+
super(message);
|
|
18
|
+
this.name = "TransitiveHashError";
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Compute a transitive version hash for a skill and all its included children.
|
|
24
|
+
*
|
|
25
|
+
* The hash covers:
|
|
26
|
+
* 1. The DFS-ordered list of visited skill IDs (so the graph structure matters)
|
|
27
|
+
* 2. Each visited skill's directory hash (via `computeSkillVersionHash`)
|
|
28
|
+
*
|
|
29
|
+
* This means editing any included child skill invalidates the parent's
|
|
30
|
+
* transitive hash, which is required for version-pinned inline-command
|
|
31
|
+
* approval.
|
|
32
|
+
*
|
|
33
|
+
* Fails closed (throws `TransitiveHashError`) when:
|
|
34
|
+
* - A child referenced in `includes` is missing from the catalog index
|
|
35
|
+
* - The include graph contains a cycle
|
|
36
|
+
*
|
|
37
|
+
* @param rootSkillId The skill ID to start traversal from.
|
|
38
|
+
* @param catalogIndex A `Map<skillId, SkillSummary>` built via `indexCatalogById`.
|
|
39
|
+
* @returns A canonical hash string in the format `tv1:<hex-sha256>`.
|
|
40
|
+
*/
|
|
41
|
+
export function computeTransitiveSkillVersionHash(
|
|
42
|
+
rootSkillId: string,
|
|
43
|
+
catalogIndex: Map<string, SkillSummary>,
|
|
44
|
+
): string {
|
|
45
|
+
// Validate the include graph first — fail closed on any issue.
|
|
46
|
+
const validation = validateIncludes(rootSkillId, catalogIndex);
|
|
47
|
+
|
|
48
|
+
if (!validation.ok) {
|
|
49
|
+
if (validation.error === "cycle") {
|
|
50
|
+
throw new TransitiveHashError(
|
|
51
|
+
`Cycle detected in include graph: ${validation.cyclePath.join(" -> ")}`,
|
|
52
|
+
"cycle",
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
// validation.error === "missing"
|
|
56
|
+
throw new TransitiveHashError(
|
|
57
|
+
`Missing child skill "${validation.missingChildId}" referenced by "${validation.parentId}" (path: ${validation.path.join(" -> ")})`,
|
|
58
|
+
"missing",
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// validation.ok === true, so visited contains all skill IDs in DFS pre-order.
|
|
63
|
+
const { visited } = validation;
|
|
64
|
+
|
|
65
|
+
const hash = createHash("sha256");
|
|
66
|
+
|
|
67
|
+
for (const skillId of visited) {
|
|
68
|
+
// Fold the skill ID into the digest so graph structure matters.
|
|
69
|
+
hash.update(skillId);
|
|
70
|
+
hash.update("\0");
|
|
71
|
+
|
|
72
|
+
const skill = catalogIndex.get(skillId);
|
|
73
|
+
if (!skill) {
|
|
74
|
+
// Should be unreachable after validateIncludes succeeds, but fail closed.
|
|
75
|
+
throw new TransitiveHashError(
|
|
76
|
+
`Skill "${skillId}" disappeared from catalog index after validation`,
|
|
77
|
+
"missing",
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Fold the per-directory content hash so file changes propagate.
|
|
82
|
+
const dirHash = computeSkillVersionHash(skill.directoryPath);
|
|
83
|
+
hash.update(dirHash);
|
|
84
|
+
hash.update("\n");
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return `tv1:${hash.digest("hex")}`;
|
|
88
|
+
}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import { resolveModelIntent } from "../providers/model-intents.js";
|
|
9
9
|
import type { ModelIntent } from "../providers/types.js";
|
|
10
|
-
import {
|
|
10
|
+
import { getProviderKeyAsync } from "../security/secure-keys.js";
|
|
11
11
|
import { getLogger } from "../util/logger.js";
|
|
12
12
|
import type {
|
|
13
13
|
SwarmWorkerBackend,
|
|
@@ -29,8 +29,7 @@ export function createClaudeCodeBackend(): SwarmWorkerBackend {
|
|
|
29
29
|
name: "claude_code",
|
|
30
30
|
|
|
31
31
|
async isAvailable(): Promise<boolean> {
|
|
32
|
-
const apiKey =
|
|
33
|
-
(await getSecureKeyAsync("anthropic")) ?? process.env.ANTHROPIC_API_KEY;
|
|
32
|
+
const apiKey = await getProviderKeyAsync("anthropic");
|
|
34
33
|
return !!apiKey;
|
|
35
34
|
},
|
|
36
35
|
|
|
@@ -39,9 +38,7 @@ export function createClaudeCodeBackend(): SwarmWorkerBackend {
|
|
|
39
38
|
const stderrLines: string[] = [];
|
|
40
39
|
try {
|
|
41
40
|
const { query } = await import("@anthropic-ai/claude-agent-sdk");
|
|
42
|
-
const apiKey =
|
|
43
|
-
(await getSecureKeyAsync("anthropic")) ??
|
|
44
|
-
process.env.ANTHROPIC_API_KEY;
|
|
41
|
+
const apiKey = await getProviderKeyAsync("anthropic");
|
|
45
42
|
if (!apiKey) {
|
|
46
43
|
return {
|
|
47
44
|
success: false,
|
package/src/tasks/task-store.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { desc, eq, inArray } from "drizzle-orm";
|
|
1
|
+
import { asc, desc, eq, inArray, or } from "drizzle-orm";
|
|
2
2
|
|
|
3
3
|
import { getDb } from "../memory/db.js";
|
|
4
4
|
import { taskRuns, tasks, workItems } from "../memory/schema.js";
|
|
@@ -139,3 +139,45 @@ export function getTaskRun(id: string): TaskRun | undefined {
|
|
|
139
139
|
const db = getDb();
|
|
140
140
|
return db.select().from(taskRuns).where(eq(taskRuns.id, id)).get();
|
|
141
141
|
}
|
|
142
|
+
|
|
143
|
+
// ── Brief Helpers ─────────────────────────────────────────────────────
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Lightweight read-only projection of a work item used by the brief compiler.
|
|
147
|
+
* Avoids pulling the full WorkItem type with all its tool/approval fields.
|
|
148
|
+
*/
|
|
149
|
+
export interface ActionableWorkItem {
|
|
150
|
+
id: string;
|
|
151
|
+
taskId: string;
|
|
152
|
+
title: string;
|
|
153
|
+
status: string;
|
|
154
|
+
priorityTier: number;
|
|
155
|
+
updatedAt: number;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Return actionable work items — those that are queued, running, or
|
|
160
|
+
* awaiting review. Ordered by priority (high first) then most-recently-updated.
|
|
161
|
+
*/
|
|
162
|
+
export function getActionableWorkItems(): ActionableWorkItem[] {
|
|
163
|
+
const db = getDb();
|
|
164
|
+
return db
|
|
165
|
+
.select({
|
|
166
|
+
id: workItems.id,
|
|
167
|
+
taskId: workItems.taskId,
|
|
168
|
+
title: workItems.title,
|
|
169
|
+
status: workItems.status,
|
|
170
|
+
priorityTier: workItems.priorityTier,
|
|
171
|
+
updatedAt: workItems.updatedAt,
|
|
172
|
+
})
|
|
173
|
+
.from(workItems)
|
|
174
|
+
.where(
|
|
175
|
+
or(
|
|
176
|
+
eq(workItems.status, "queued"),
|
|
177
|
+
eq(workItems.status, "running"),
|
|
178
|
+
eq(workItems.status, "awaiting_review"),
|
|
179
|
+
),
|
|
180
|
+
)
|
|
181
|
+
.orderBy(asc(workItems.priorityTier), desc(workItems.updatedAt))
|
|
182
|
+
.all();
|
|
183
|
+
}
|
|
@@ -97,6 +97,7 @@ mock.module("../version.js", () => ({
|
|
|
97
97
|
// Production import (after mocks)
|
|
98
98
|
// ---------------------------------------------------------------------------
|
|
99
99
|
|
|
100
|
+
import { DAEMON_INTERNAL_ASSISTANT_ID } from "../runtime/assistant-scope.js";
|
|
100
101
|
import type { UsageEvent } from "../usage/types.js";
|
|
101
102
|
import { UsageTelemetryReporter } from "./usage-telemetry-reporter.js";
|
|
102
103
|
|
|
@@ -434,7 +435,7 @@ describe("UsageTelemetryReporter", () => {
|
|
|
434
435
|
expect(body.user_id).toBeUndefined();
|
|
435
436
|
});
|
|
436
437
|
|
|
437
|
-
test("assistant_id falls back to
|
|
438
|
+
test("assistant_id falls back to DAEMON_INTERNAL_ASSISTANT_ID when getExternalAssistantId returns undefined", async () => {
|
|
438
439
|
mockGetExternalAssistantId.mockReturnValue(undefined);
|
|
439
440
|
const events = [makeUsageEvent()];
|
|
440
441
|
mockQueryUnreportedUsageEvents.mockReturnValue(events);
|
|
@@ -450,7 +451,7 @@ describe("UsageTelemetryReporter", () => {
|
|
|
450
451
|
(mockFetch.mock.calls[0] as [string, RequestInit])[1].body as string,
|
|
451
452
|
);
|
|
452
453
|
expect(body.installation_id).toBe("test-device-id");
|
|
453
|
-
expect(body.assistant_id).toBe(
|
|
454
|
+
expect(body.assistant_id).toBe(DAEMON_INTERNAL_ASSISTANT_ID);
|
|
454
455
|
});
|
|
455
456
|
|
|
456
457
|
test("turn events are included in the events array with type discriminator", async () => {
|
|
@@ -23,6 +23,7 @@ import { queryUnreportedLifecycleEvents } from "../memory/lifecycle-events-store
|
|
|
23
23
|
import { queryUnreportedUsageEvents } from "../memory/llm-usage-store.js";
|
|
24
24
|
import { queryUnreportedTurnEvents } from "../memory/turn-events-store.js";
|
|
25
25
|
import { resolveManagedProxyContext } from "../providers/managed-proxy/context.js";
|
|
26
|
+
import { DAEMON_INTERNAL_ASSISTANT_ID } from "../runtime/assistant-scope.js";
|
|
26
27
|
import { getExternalAssistantId } from "../runtime/auth/external-assistant-id.js";
|
|
27
28
|
import { getDeviceId } from "../util/device-id.js";
|
|
28
29
|
import { getLogger } from "../util/logger.js";
|
|
@@ -187,7 +188,8 @@ export class UsageTelemetryReporter {
|
|
|
187
188
|
),
|
|
188
189
|
];
|
|
189
190
|
|
|
190
|
-
const assistantId =
|
|
191
|
+
const assistantId =
|
|
192
|
+
getExternalAssistantId() ?? DAEMON_INTERNAL_ASSISTANT_ID;
|
|
191
193
|
const organizationId = getPlatformOrganizationId() || undefined;
|
|
192
194
|
const userId = getPlatformUserId() || undefined;
|
|
193
195
|
const payload = {
|
package/src/tools/AGENTS.md
CHANGED
|
@@ -1,18 +1,14 @@
|
|
|
1
1
|
# Tools - Agent Instructions
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## New Non-Skill Tools Are Strongly Discouraged
|
|
4
4
|
|
|
5
|
-
**
|
|
5
|
+
**Prefer skills over new non-skill tool registrations.** Non-skill tools require approval from Team Jarvis.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Skills are the preferred approach for adding new capabilities — they are progressively disclosed into context, more portable, and can be iterated on independently. New non-skill tool registrations (`class ... implements Tool` + `registerTool()`) carry additional costs:
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
1. **Context overhead** — Each registered tool adds to the system prompt and increases token usage for every conversation.
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
2. **Context overhead** - Each registered tool adds to the system prompt and increases token usage for every conversation.
|
|
14
|
-
|
|
15
|
-
3. **Maintenance burden** - Tools require ongoing maintenance, testing, and security review. Skills can be iterated on independently.
|
|
11
|
+
2. **Maintenance burden** — Tools require ongoing maintenance, testing, and security review.
|
|
16
12
|
|
|
17
13
|
## What To Do Instead
|
|
18
14
|
|
|
@@ -26,7 +22,7 @@ Instead of creating a new tool, consider:
|
|
|
26
22
|
|
|
27
23
|
## Approved Exception: Credential Execution Service (CES) Tools
|
|
28
24
|
|
|
29
|
-
The following three CES tools are
|
|
25
|
+
The following three CES tools are approved exceptions that justify tool registrations over skills:
|
|
30
26
|
|
|
31
27
|
| Tool | Purpose |
|
|
32
28
|
| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
|