@vellumai/assistant 0.5.15 → 0.6.0
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 +3 -3
- package/Dockerfile +0 -3
- package/docs/architecture/integrations.md +15 -14
- package/knip.json +4 -1
- package/openapi.yaml +670 -122
- package/package.json +1 -1
- package/src/__tests__/actor-token-service.test.ts +68 -0
- package/src/__tests__/agent-loop.test.ts +0 -32
- package/src/__tests__/always-loaded-tools-guard.test.ts +2 -2
- package/src/__tests__/anthropic-provider.test.ts +57 -3
- package/src/__tests__/app-compiler.test.ts +120 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +5 -377
- package/src/__tests__/call-conversation-messages.test.ts +2 -6
- package/src/__tests__/call-domain.test.ts +2 -6
- package/src/__tests__/call-pointer-messages.test.ts +2 -14
- package/src/__tests__/call-recovery.test.ts +2 -6
- package/src/__tests__/call-routes-http.test.ts +2 -6
- package/src/__tests__/call-store.test.ts +2 -6
- package/src/__tests__/cancel-resolves-conversation-key.test.ts +2 -6
- package/src/__tests__/canonical-guardian-store.test.ts +2 -6
- package/src/__tests__/ces-rpc-credential-backend.test.ts +4 -1
- package/src/__tests__/channel-delivery-store.test.ts +2 -6
- package/src/__tests__/channel-retry-sweep.test.ts +2 -6
- package/src/__tests__/checker.test.ts +84 -3
- package/src/__tests__/clawhub.test.ts +54 -24
- package/src/__tests__/cli-command-risk-guard.test.ts +108 -6
- package/src/__tests__/cli-memory.test.ts +377 -0
- package/src/__tests__/computer-use-skill-manifest-regression.test.ts +12 -2
- package/src/__tests__/config-schema.test.ts +1 -3
- package/src/__tests__/config-set-platform-guard.test.ts +302 -0
- package/src/__tests__/config-watcher-feature-flags.test.ts +211 -0
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +2 -6
- package/src/__tests__/contacts-tools.test.ts +31 -0
- package/src/__tests__/context-overflow-reducer.test.ts +86 -0
- package/src/__tests__/context-token-estimator.test.ts +175 -10
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +9 -0
- package/src/__tests__/conversation-agent-loop.test.ts +9 -0
- package/src/__tests__/conversation-attachments.test.ts +2 -6
- package/src/__tests__/conversation-attention-store.test.ts +2 -6
- package/src/__tests__/conversation-clear-safety.test.ts +2 -6
- package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +4 -10
- package/src/__tests__/conversation-disk-view-integration.test.ts +2 -6
- package/src/__tests__/conversation-disk-view.test.ts +2 -6
- package/src/__tests__/conversation-error.test.ts +33 -2
- package/src/__tests__/conversation-fork-crud.test.ts +2 -6
- package/src/__tests__/conversation-history-web-search.test.ts +5 -0
- package/src/__tests__/conversation-load-history-repair.test.ts +5 -1
- package/src/__tests__/conversation-media-retry.test.ts +91 -0
- package/src/__tests__/conversation-runtime-assembly.test.ts +7 -4
- package/src/__tests__/conversation-slash-commands.test.ts +2 -6
- package/src/__tests__/conversation-starter-routes.test.ts +20 -11
- package/src/__tests__/conversation-store.test.ts +2 -6
- package/src/__tests__/conversation-usage.test.ts +3 -6
- package/src/__tests__/conversation-wipe.test.ts +11 -408
- package/src/__tests__/credential-execution-feature-gates.test.ts +3 -3
- package/src/__tests__/credential-execution-shell-lockdown.test.ts +2 -2
- package/src/__tests__/credential-security-e2e.test.ts +6 -1
- package/src/__tests__/docker-signing-key-bootstrap.test.ts +7 -73
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +6 -7
- package/src/__tests__/followup-tools.test.ts +2 -6
- package/src/__tests__/graph-extraction-event-date.test.ts +186 -0
- package/src/__tests__/guardian-action-conversation-turn.test.ts +2 -6
- package/src/__tests__/guardian-action-followup-executor.test.ts +2 -6
- package/src/__tests__/guardian-action-followup-store.test.ts +2 -6
- package/src/__tests__/guardian-action-grant-mint-consume.test.ts +2 -6
- package/src/__tests__/guardian-action-late-reply.test.ts +2 -6
- package/src/__tests__/guardian-action-store.test.ts +2 -6
- package/src/__tests__/guardian-binding-drift-heal.test.ts +2 -6
- package/src/__tests__/guardian-decision-primitive-canonical.test.ts +8 -8
- package/src/__tests__/guardian-dispatch.test.ts +2 -6
- package/src/__tests__/guardian-grant-minting.test.ts +2 -14
- package/src/__tests__/guardian-principal-id-roundtrip.test.ts +2 -6
- package/src/__tests__/guardian-routing-invariants.test.ts +343 -6
- package/src/__tests__/guardian-routing-state.test.ts +2 -6
- package/src/__tests__/guardian-verification-voice-binding.test.ts +2 -6
- package/src/__tests__/heartbeat-service.test.ts +1 -3
- package/src/__tests__/inbound-invite-redemption.test.ts +2 -6
- package/src/__tests__/injection-block.test.ts +154 -0
- package/src/__tests__/install-meta.test.ts +506 -0
- package/src/__tests__/install-skill-routing.test.ts +292 -0
- package/src/__tests__/intent-routing.test.ts +6 -18
- package/src/__tests__/invite-redemption-service.test.ts +2 -6
- package/src/__tests__/invite-routes-http.test.ts +2 -6
- package/src/__tests__/jobs-store-qdrant-breaker.test.ts +2 -14
- package/src/__tests__/list-messages-attachments.test.ts +2 -6
- package/src/__tests__/llm-context-route-provider.test.ts +2 -6
- package/src/__tests__/llm-request-log-turn-query.test.ts +2 -6
- package/src/__tests__/llm-usage-store.test.ts +2 -6
- package/src/__tests__/log-export-workspace.test.ts +4 -34
- package/src/__tests__/managed-skill-lifecycle.test.ts +7 -37
- package/src/__tests__/managed-store.test.ts +40 -21
- package/src/__tests__/memory-jobs-worker-backoff.test.ts +2 -8
- package/src/__tests__/memory-recall-log-store.test.ts +2 -6
- package/src/__tests__/memory-upsert-concurrency.test.ts +4 -112
- package/src/__tests__/messaging-send-tool.test.ts +6 -6
- package/src/__tests__/migration-cross-version-compatibility.test.ts +1 -29
- package/src/__tests__/migration-export-http.test.ts +3 -34
- package/src/__tests__/migration-import-commit-http.test.ts +1 -29
- package/src/__tests__/migration-import-preflight-http.test.ts +3 -34
- package/src/__tests__/no-domain-routing-in-prompt-guard.test.ts +2 -1
- package/src/__tests__/non-member-access-request.test.ts +2 -6
- package/src/__tests__/notification-guardian-path.test.ts +2 -6
- package/src/__tests__/oauth-apps-routes.test.ts +120 -10
- package/src/__tests__/oauth-cli.test.ts +364 -2
- package/src/__tests__/oauth-connect-orchestrator.test.ts +709 -0
- package/src/__tests__/oauth-provider-serializer.test.ts +2 -1
- package/src/__tests__/oauth-provider-visibility.test.ts +149 -0
- package/src/__tests__/oauth-providers-routes.test.ts +5 -2
- package/src/__tests__/oauth-store.test.ts +0 -5
- package/src/__tests__/oauth2-gateway-transport.test.ts +18 -3
- package/src/__tests__/outlook-attachments.test.ts +301 -0
- package/src/__tests__/outlook-automation-tools.test.ts +425 -0
- package/src/__tests__/outlook-categories.test.ts +212 -0
- package/src/__tests__/outlook-client-automation.test.ts +246 -0
- package/src/__tests__/outlook-compose-tools.test.ts +325 -0
- package/src/__tests__/outlook-declutter-tools.test.ts +585 -0
- package/src/__tests__/outlook-email-watcher.test.ts +322 -0
- package/src/__tests__/outlook-follow-up.test.ts +196 -0
- package/src/__tests__/outlook-messaging-provider.test.ts +1071 -0
- package/src/__tests__/outlook-trash.test.ts +77 -0
- package/src/__tests__/outlook-unsubscribe.test.ts +250 -0
- package/src/__tests__/path-policy.test.ts +2 -17
- package/src/__tests__/permission-types.test.ts +0 -1
- package/src/__tests__/platform-callback-registration.test.ts +7 -11
- package/src/__tests__/playbook-execution.test.ts +76 -80
- package/src/__tests__/playbook-tools.test.ts +5 -7
- package/src/__tests__/provider-commit-message-generator.test.ts +0 -1
- package/src/__tests__/provider-error-scenarios.test.ts +21 -2
- package/src/__tests__/qdrant-manager.test.ts +68 -21
- package/src/__tests__/rebuild-index-graph-nodes.test.ts +273 -0
- package/src/__tests__/registry.test.ts +2 -2
- package/src/__tests__/require-fresh-approval.test.ts +64 -3
- package/src/__tests__/runtime-events-sse-parity.test.ts +2 -6
- package/src/__tests__/runtime-events-sse.test.ts +2 -6
- package/src/__tests__/sandbox-diagnostics.test.ts +20 -29
- package/src/__tests__/scaffold-managed-skill-tool.test.ts +2 -10
- package/src/__tests__/schedule-store.test.ts +2 -6
- package/src/__tests__/schedule-tools.test.ts +2 -6
- package/src/__tests__/scheduler-recurrence.test.ts +1 -5
- package/src/__tests__/scoped-approval-grants.test.ts +2 -6
- package/src/__tests__/scoped-grant-security-matrix.test.ts +2 -6
- package/src/__tests__/search-skills-unified.test.ts +421 -0
- package/src/__tests__/secret-allowlist.test.ts +20 -35
- package/src/__tests__/secret-onetime-send.test.ts +2 -0
- package/src/__tests__/send-endpoint-busy.test.ts +2 -6
- package/src/__tests__/sequence-store.test.ts +2 -6
- package/src/__tests__/server-history-render.test.ts +2 -6
- package/src/__tests__/shell-credential-ref.test.ts +0 -5
- package/src/__tests__/skill-feature-flags-integration.test.ts +38 -31
- package/src/__tests__/skill-feature-flags.test.ts +6 -6
- package/src/__tests__/skill-load-feature-flag.test.ts +13 -54
- package/src/__tests__/skill-load-inline-command.test.ts +3 -65
- package/src/__tests__/skill-load-inline-includes.test.ts +3 -65
- package/src/__tests__/skill-load-tool.test.ts +3 -67
- package/src/__tests__/skill-memory.test.ts +480 -195
- package/src/__tests__/skills-uninstall.test.ts +2 -2
- package/src/__tests__/skills.test.ts +23 -50
- package/src/__tests__/slack-channel-config.test.ts +2 -21
- package/src/__tests__/slack-inbound-verification.test.ts +2 -6
- package/src/__tests__/starter-bundle.test.ts +2 -8
- package/src/__tests__/stt-hints.test.ts +7 -2
- package/src/__tests__/system-prompt.test.ts +25 -45
- package/src/__tests__/task-compiler.test.ts +2 -27
- package/src/__tests__/task-management-tools.test.ts +2 -27
- package/src/__tests__/task-memory-cleanup.test.ts +173 -250
- package/src/__tests__/task-runner.test.ts +2 -27
- package/src/__tests__/task-scheduler.test.ts +2 -27
- package/src/__tests__/terminal-tools.test.ts +1 -17
- package/src/__tests__/test-preload.ts +3 -0
- package/src/__tests__/token-estimator-accuracy.benchmark.test.ts +0 -79
- package/src/__tests__/tool-approval-handler.test.ts +4 -27
- package/src/__tests__/tool-execution-abort-cleanup.test.ts +2 -11
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +1 -25
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +0 -1
- package/src/__tests__/tool-executor.test.ts +0 -1
- package/src/__tests__/tool-grant-request-escalation.test.ts +4 -27
- package/src/__tests__/tool-preview-lifecycle.test.ts +0 -20
- package/src/__tests__/tool-side-effects-slack-dm.test.ts +276 -0
- package/src/__tests__/trust-store.test.ts +10 -42
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +1 -30
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +3 -27
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +2 -28
- package/src/__tests__/trusted-contact-multichannel.test.ts +2 -28
- package/src/__tests__/trusted-contact-verification.test.ts +2 -28
- package/src/__tests__/turn-boundary-resolution.test.ts +2 -34
- package/src/__tests__/twilio-provider.test.ts +0 -16
- package/src/__tests__/twilio-routes-twiml.test.ts +7 -12
- package/src/__tests__/twilio-routes.test.ts +0 -24
- package/src/__tests__/update-bulletin.test.ts +17 -89
- package/src/__tests__/usage-cache-backfill-migration.test.ts +1 -26
- package/src/__tests__/usage-routes.test.ts +2 -27
- package/src/__tests__/user-reference.test.ts +1 -5
- package/src/__tests__/vbundle-pax-and-symlink.test.ts +4 -34
- package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +2 -53
- package/src/__tests__/verification-control-plane-policy.test.ts +0 -2
- package/src/__tests__/voice-invite-redemption.test.ts +2 -27
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +2 -30
- package/src/__tests__/voice-session-bridge.test.ts +2 -27
- package/src/__tests__/volume-security-guard.test.ts +2 -0
- package/src/__tests__/workspace-lifecycle.test.ts +29 -1
- package/src/__tests__/workspace-migration-009-backfill-conversation-disk-view.test.ts +4 -29
- package/src/__tests__/workspace-migration-012-rename-conversation-disk-view-dirs.test.ts +2 -2
- package/src/__tests__/workspace-migration-013-repair-conversation-disk-view.test.ts +4 -29
- package/src/__tests__/workspace-migration-026-backfill-install-meta.test.ts +558 -0
- package/src/__tests__/workspace-migration-down-functions.test.ts +0 -6
- package/src/__tests__/workspace-policy.test.ts +1 -1
- package/src/acp/client-handler.ts +1 -2
- package/src/agent/attachments.ts +7 -2
- package/src/agent/image-optimize.ts +165 -0
- package/src/agent/loop.ts +1 -15
- package/src/bundler/app-compiler.ts +179 -2
- package/src/bundler/package-resolver.ts +3 -5
- package/src/cli/__tests__/notifications.test.ts +1 -24
- package/src/cli/cli-memory.ts +179 -0
- package/src/cli/commands/avatar.ts +3 -3
- package/src/cli/commands/config.ts +26 -13
- package/src/cli/commands/doctor.ts +2 -2
- package/src/cli/commands/memory.ts +41 -55
- package/src/cli/commands/oauth/__tests__/connect.test.ts +2 -2
- package/src/cli/commands/oauth/__tests__/disconnect.test.ts +2 -2
- package/src/cli/commands/oauth/__tests__/mode.test.ts +8 -1
- package/src/cli/commands/oauth/__tests__/providers-update.test.ts +1 -1
- package/src/cli/commands/oauth/__tests__/status.test.ts +2 -2
- package/src/cli/commands/oauth/connect.ts +26 -6
- package/src/cli/commands/oauth/mode.ts +7 -0
- package/src/cli/commands/oauth/providers.ts +49 -42
- package/src/cli/commands/oauth/shared.ts +39 -3
- package/src/cli/commands/platform/__tests__/connect.test.ts +3 -49
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +3 -49
- package/src/cli/commands/platform/__tests__/status.test.ts +5 -55
- package/src/cli/commands/platform/index.ts +16 -16
- package/src/cli/commands/skills.ts +88 -16
- package/src/cli/commands/trust.ts +2 -2
- package/src/cli/lib/daemon-credential-client.ts +2 -3
- package/src/config/bundled-skills/acp/TOOLS.json +1 -1
- package/src/config/bundled-skills/computer-use/TOOLS.json +7 -7
- package/src/config/bundled-skills/contacts/SKILL.md +0 -1
- package/src/config/bundled-skills/contacts/TOOLS.json +0 -8
- package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +0 -4
- package/src/config/bundled-skills/gmail/SKILL.md +2 -10
- package/src/config/bundled-skills/google-calendar/SKILL.md +1 -9
- package/src/config/bundled-skills/messaging/SKILL.md +26 -19
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +40 -33
- package/src/config/bundled-skills/outlook/SKILL.md +189 -0
- package/src/config/bundled-skills/outlook/TOOLS.json +530 -0
- package/src/config/bundled-skills/outlook/tools/outlook-attachments.ts +85 -0
- package/src/config/bundled-skills/outlook/tools/outlook-categories.ts +77 -0
- package/src/config/bundled-skills/outlook/tools/outlook-draft.ts +84 -0
- package/src/config/bundled-skills/outlook/tools/outlook-follow-up.ts +94 -0
- package/src/config/bundled-skills/outlook/tools/outlook-forward.ts +49 -0
- package/src/config/bundled-skills/outlook/tools/outlook-outreach-scan.ts +237 -0
- package/src/config/bundled-skills/outlook/tools/outlook-rules.ts +161 -0
- package/src/config/bundled-skills/outlook/tools/outlook-send-draft.ts +32 -0
- package/src/config/bundled-skills/outlook/tools/outlook-sender-digest.ts +272 -0
- package/src/config/bundled-skills/outlook/tools/outlook-trash.ts +29 -0
- package/src/config/bundled-skills/outlook/tools/outlook-unsubscribe.ts +129 -0
- package/src/config/bundled-skills/outlook/tools/outlook-vacation.ts +87 -0
- package/src/config/bundled-skills/outlook/tools/shared.ts +20 -0
- package/src/config/bundled-skills/outlook-calendar/SKILL.md +51 -0
- package/src/config/bundled-skills/outlook-calendar/TOOLS.json +221 -0
- package/src/config/bundled-skills/outlook-calendar/calendar-client.ts +252 -0
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-check-availability.ts +53 -0
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-create-event.ts +74 -0
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-get-event.ts +18 -0
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-list-events.ts +46 -0
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-rsvp.ts +36 -0
- package/src/config/bundled-skills/outlook-calendar/tools/shared.ts +17 -0
- package/src/config/bundled-skills/outlook-calendar/types.ts +120 -0
- package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +47 -40
- package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +16 -29
- package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +16 -18
- package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +39 -47
- package/src/config/bundled-skills/settings/TOOLS.json +3 -3
- package/src/config/bundled-skills/slack/SKILL.md +1 -7
- package/src/config/bundled-tool-registry.ts +56 -4
- package/src/config/env-registry.ts +15 -8
- package/src/config/feature-flag-registry.json +29 -116
- package/src/config/loader.ts +4 -0
- package/src/config/schemas/platform.ts +8 -0
- package/src/config/schemas/security.ts +0 -6
- package/src/config/schemas/services.ts +8 -0
- package/src/config/schemas/timeouts.ts +1 -1
- package/src/config/skills.ts +18 -7
- package/src/context/token-estimator.ts +25 -18
- package/src/context/window-manager.ts +32 -9
- package/src/credential-execution/approval-bridge.ts +0 -1
- package/src/credential-execution/process-manager.ts +3 -1
- package/src/daemon/config-watcher.ts +51 -0
- package/src/daemon/context-overflow-reducer.ts +46 -2
- package/src/daemon/conversation-agent-loop-handlers.ts +123 -82
- package/src/daemon/conversation-agent-loop.ts +99 -63
- package/src/daemon/conversation-error.ts +31 -8
- package/src/daemon/conversation-lifecycle.ts +33 -0
- package/src/daemon/conversation-media-retry.ts +85 -7
- package/src/daemon/conversation-notifiers.ts +4 -1
- package/src/daemon/conversation-process.ts +1 -0
- package/src/daemon/conversation-runtime-assembly.ts +5 -0
- package/src/daemon/conversation-usage.ts +1 -0
- package/src/daemon/conversation.ts +41 -2
- package/src/daemon/daemon-control.ts +8 -2
- package/src/daemon/handlers/shared.ts +22 -12
- package/src/daemon/handlers/skills.ts +423 -201
- package/src/daemon/lifecycle.ts +52 -4
- package/src/daemon/main.ts +5 -1
- package/src/daemon/message-types/conversations.ts +5 -1
- package/src/daemon/message-types/messages.ts +3 -1
- package/src/daemon/message-types/skills.ts +97 -36
- package/src/daemon/providers-setup.ts +7 -0
- package/src/daemon/server.ts +35 -22
- package/src/daemon/tool-side-effects.ts +27 -5
- package/src/events/domain-events.ts +1 -2
- package/src/heartbeat/heartbeat-service.ts +1 -0
- package/src/hooks/cli.ts +2 -2
- package/src/hooks/runner.ts +15 -38
- package/src/inbound/platform-callback-registration.ts +14 -14
- package/src/memory/admin.ts +11 -45
- package/src/memory/conversation-bootstrap.ts +2 -0
- package/src/memory/conversation-crud.ts +242 -348
- package/src/memory/conversation-group-migration.ts +157 -0
- package/src/memory/conversation-queries.ts +4 -2
- package/src/memory/db-init.ts +39 -3
- package/src/memory/embed.ts +73 -0
- package/src/memory/embedding-backend.ts +8 -14
- package/src/memory/embedding-runtime-manager.ts +12 -114
- package/src/memory/fingerprint.ts +2 -2
- package/src/memory/graph/bootstrap.ts +512 -0
- package/src/memory/graph/capability-seed.ts +297 -0
- package/src/memory/graph/consolidation.ts +691 -0
- package/src/memory/graph/conversation-graph-memory.ts +630 -0
- package/src/memory/graph/decay.test.ts +208 -0
- package/src/memory/graph/decay.ts +195 -0
- package/src/memory/graph/extraction-job.ts +69 -0
- package/src/memory/graph/extraction.test.ts +936 -0
- package/src/memory/graph/extraction.ts +1254 -0
- package/src/memory/graph/graph-search.ts +266 -0
- package/src/memory/graph/image-ref-utils.ts +29 -0
- package/src/memory/graph/injection.test.ts +513 -0
- package/src/memory/graph/injection.ts +439 -0
- package/src/memory/graph/inspect.ts +534 -0
- package/src/memory/graph/narrative.ts +267 -0
- package/src/memory/graph/pattern-scan.ts +269 -0
- package/src/memory/graph/retriever.ts +1008 -0
- package/src/memory/graph/scoring.test.ts +548 -0
- package/src/memory/graph/scoring.ts +232 -0
- package/src/memory/graph/serendipity.ts +65 -0
- package/src/memory/graph/store.test.ts +1050 -0
- package/src/memory/graph/store.ts +699 -0
- package/src/memory/graph/tool-handlers.ts +426 -0
- package/src/memory/graph/tools.ts +141 -0
- package/src/memory/graph/triggers.test.ts +487 -0
- package/src/memory/graph/triggers.ts +223 -0
- package/src/memory/graph/types.ts +271 -0
- package/src/memory/group-crud.ts +191 -0
- package/src/memory/indexer.ts +37 -19
- package/src/memory/job-handlers/cleanup.ts +0 -53
- package/src/memory/job-handlers/conversation-starters.ts +91 -53
- package/src/memory/job-handlers/embedding.test.ts +3 -27
- package/src/memory/job-handlers/embedding.ts +5 -31
- package/src/memory/job-handlers/index-maintenance.ts +23 -11
- package/src/memory/job-handlers/summarization.ts +32 -17
- package/src/memory/job-utils.ts +1 -1
- package/src/memory/jobs-store.ts +50 -70
- package/src/memory/jobs-worker.ts +147 -112
- package/src/memory/llm-usage-store.ts +35 -2
- package/src/memory/message-content.ts +1 -0
- package/src/memory/migrations/201-oauth-providers-feature-flag.ts +11 -0
- package/src/memory/migrations/202-drop-callback-transport-column.ts +13 -0
- package/src/memory/migrations/202-memory-graph-tables.ts +130 -0
- package/src/memory/migrations/203-drop-memory-items-tables.ts +23 -0
- package/src/memory/migrations/204-rename-memory-graph-type-values.ts +46 -0
- package/src/memory/migrations/205-memory-graph-image-refs.ts +11 -0
- package/src/memory/migrations/index.ts +6 -0
- package/src/memory/migrations/registry.ts +8 -0
- package/src/memory/qdrant-client.ts +44 -17
- package/src/memory/qdrant-manager.ts +26 -5
- package/src/memory/schema/index.ts +1 -0
- package/src/memory/schema/memory-graph.ts +139 -0
- package/src/memory/schema/oauth.ts +1 -1
- package/src/memory/search/semantic.ts +47 -91
- package/src/memory/slack-thread-store.ts +17 -0
- package/src/memory/task-memory-cleanup.ts +28 -50
- package/src/messaging/providers/outlook/adapter.ts +200 -0
- package/src/messaging/providers/outlook/client.ts +610 -0
- package/src/messaging/providers/outlook/types.ts +201 -0
- package/src/notifications/adapters/macos.ts +1 -0
- package/src/notifications/adapters/slack.ts +1 -1
- package/src/notifications/copy-composer.ts +9 -0
- package/src/notifications/signal.ts +16 -0
- package/src/oauth/__tests__/identity-verifier.test.ts +1 -1
- package/src/oauth/connect-orchestrator.ts +10 -3
- package/src/oauth/oauth-store.ts +10 -11
- package/src/oauth/provider-serializer.ts +3 -0
- package/src/oauth/provider-visibility.ts +16 -0
- package/src/oauth/seed-providers.ts +50 -17
- package/src/permissions/checker.ts +62 -9
- package/src/permissions/defaults.ts +4 -4
- package/src/permissions/types.ts +2 -4
- package/src/permissions/workspace-policy.ts +1 -1
- package/src/playbooks/playbook-compiler.ts +19 -18
- package/src/playbooks/types.ts +4 -3
- package/src/prompts/system-prompt.ts +6 -93
- package/src/prompts/templates/UPDATES.md +6 -0
- package/src/providers/anthropic/client.ts +47 -19
- package/src/providers/gemini/client.ts +1 -1
- package/src/providers/openai/client.ts +1 -1
- package/src/providers/registry.ts +1 -1
- package/src/providers/retry.ts +19 -3
- package/src/runtime/actor-trust-resolver.ts +5 -1
- package/src/runtime/auth/__tests__/credential-service.test.ts +1 -27
- package/src/runtime/auth/__tests__/token-service.test.ts +1 -25
- package/src/runtime/auth/route-policy.ts +7 -4
- package/src/runtime/guardian-reply-router.ts +10 -2
- package/src/runtime/http-server.ts +23 -3
- package/src/runtime/middleware/auth.ts +20 -0
- package/src/runtime/routes/attachment-routes.test.ts +106 -0
- package/src/runtime/routes/attachment-routes.ts +106 -16
- package/src/runtime/routes/brain-graph-routes.ts +21 -22
- package/src/runtime/routes/btw-routes.ts +8 -0
- package/src/runtime/routes/conversation-management-routes.ts +2 -0
- package/src/runtime/routes/conversation-query-routes.ts +2 -58
- package/src/runtime/routes/conversation-starter-routes.ts +2 -2
- package/src/runtime/routes/debug-routes.ts +1 -1
- package/src/runtime/routes/global-search-routes.ts +21 -19
- package/src/runtime/routes/group-routes.ts +207 -0
- package/src/runtime/routes/guardian-action-routes.ts +21 -10
- package/src/runtime/routes/guardian-bootstrap-routes.ts +23 -19
- package/src/runtime/routes/inbound-message-handler.ts +19 -0
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +43 -2
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.test.ts +292 -0
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +207 -0
- package/src/runtime/routes/memory-item-routes.test.ts +2 -31
- package/src/runtime/routes/memory-item-routes.ts +385 -341
- package/src/runtime/routes/oauth-apps.ts +18 -1
- package/src/runtime/routes/oauth-providers.ts +13 -1
- package/src/runtime/routes/schedule-routes.ts +2 -0
- package/src/runtime/routes/settings-routes.ts +1 -0
- package/src/runtime/routes/skills-routes.ts +103 -37
- package/src/runtime/routes/usage-routes.ts +19 -2
- package/src/runtime/routes/work-items-routes.test.ts +2 -27
- package/src/runtime/routes/workspace-routes.test.ts +3 -27
- package/src/schedule/scheduler.ts +8 -1
- package/src/security/oauth2.ts +1 -1
- package/src/security/secret-allowlist.ts +4 -4
- package/src/security/secure-keys.ts +4 -8
- package/src/shared/provider-env-vars.ts +19 -0
- package/src/skills/catalog-cache.ts +5 -0
- package/src/skills/catalog-install.ts +15 -14
- package/src/skills/clawhub.ts +134 -154
- package/src/skills/install-meta.ts +208 -0
- package/src/skills/managed-store.ts +27 -16
- package/src/skills/skill-memory.ts +210 -96
- package/src/skills/skillssh-registry.ts +19 -17
- package/src/tasks/task-runner.ts +3 -1
- package/src/telemetry/usage-telemetry-reporter.test.ts +3 -5
- package/src/tools/browser/runtime-check.ts +3 -1
- package/src/tools/memory/register.ts +63 -46
- package/src/tools/permission-checker.ts +7 -19
- package/src/tools/shared/filesystem/image-read.ts +22 -85
- package/src/tools/skills/skill-script-runner.ts +1 -1
- package/src/tools/terminal/safe-env.ts +1 -0
- package/src/tools/tool-manifest.ts +3 -3
- package/src/util/browser.ts +25 -10
- package/src/util/bun-runtime.ts +172 -0
- package/src/util/device-id.ts +3 -65
- package/src/watcher/providers/outlook-calendar.ts +343 -0
- package/src/watcher/providers/outlook.ts +198 -0
- package/src/workspace/git-service.ts +27 -6
- package/src/workspace/migrations/025-remove-oauth-app-setup-skills.ts +76 -0
- package/src/workspace/migrations/026-backfill-install-meta.ts +325 -0
- package/src/workspace/migrations/027-remove-orphaned-optimized-images-cache.ts +42 -0
- package/src/workspace/migrations/registry.ts +6 -0
- package/src/__tests__/context-memory-e2e.test.ts +0 -415
- package/src/__tests__/journal-context.test.ts +0 -268
- package/src/__tests__/memory-context-benchmark.benchmark.test.ts +0 -297
- package/src/__tests__/memory-lifecycle-e2e.test.ts +0 -459
- package/src/__tests__/memory-query-builder.test.ts +0 -59
- package/src/__tests__/memory-recall-quality.test.ts +0 -1046
- package/src/__tests__/memory-regressions.experimental.test.ts +0 -629
- package/src/__tests__/memory-regressions.test.ts +0 -3696
- package/src/__tests__/memory-retrieval.benchmark.test.ts +0 -295
- package/src/daemon/conversation-memory.ts +0 -207
- package/src/memory/conversation-starters-cadence.ts +0 -74
- package/src/memory/items-extractor.ts +0 -860
- package/src/memory/job-handlers/batch-extraction.ts +0 -741
- package/src/memory/job-handlers/extraction.ts +0 -40
- package/src/memory/job-handlers/journal-carry-forward.test.ts +0 -383
- package/src/memory/job-handlers/journal-carry-forward.ts +0 -255
- package/src/memory/journal-memory.ts +0 -224
- package/src/memory/query-builder.ts +0 -47
- package/src/memory/query-expansion.ts +0 -83
- package/src/memory/retriever.test.ts +0 -1590
- package/src/memory/retriever.ts +0 -1323
- package/src/memory/search/formatting.test.ts +0 -140
- package/src/memory/search/formatting.ts +0 -262
- package/src/memory/search/mmr.ts +0 -136
- package/src/memory/search/ranking.ts +0 -15
- package/src/memory/search/staleness.ts +0 -40
- package/src/memory/search/tier-classifier.ts +0 -18
- package/src/memory/search/types.ts +0 -121
- package/src/prompts/journal-context.ts +0 -156
- package/src/tools/memory/definitions.ts +0 -69
- package/src/tools/memory/handlers.test.ts +0 -590
- package/src/tools/memory/handlers.ts +0 -434
|
@@ -1,29 +1,80 @@
|
|
|
1
|
-
import { and, eq } from "drizzle-orm";
|
|
1
|
+
import { and, eq, sql } from "drizzle-orm";
|
|
2
2
|
import { v4 as uuid } from "uuid";
|
|
3
3
|
|
|
4
4
|
import { isAssistantFeatureFlagEnabled } from "../config/assistant-feature-flags.js";
|
|
5
5
|
import { getConfig } from "../config/loader.js";
|
|
6
|
+
import { resolveSkillStates } from "../config/skill-state.js";
|
|
7
|
+
import { loadSkillCatalog, type SkillSummary } from "../config/skills.js";
|
|
6
8
|
import { getDb } from "../memory/db.js";
|
|
7
|
-
import { computeMemoryFingerprint } from "../memory/fingerprint.js";
|
|
8
9
|
import { enqueueMemoryJob } from "../memory/jobs-store.js";
|
|
9
|
-
import {
|
|
10
|
+
import { memoryGraphNodes } from "../memory/schema.js";
|
|
10
11
|
import { getLogger } from "../util/logger.js";
|
|
11
|
-
import {
|
|
12
|
+
import { getCachedCatalogSync } from "./catalog-cache.js";
|
|
13
|
+
import type { CatalogSkill } from "./catalog-install.js";
|
|
12
14
|
|
|
13
15
|
const log = getLogger("skill-memory");
|
|
14
16
|
|
|
17
|
+
/** Escape SQL LIKE wildcards so they match literally.
|
|
18
|
+
* Uses backslash as the escape character — callers must pair with ESCAPE '\\'. */
|
|
19
|
+
function escapeLike(s: string): string {
|
|
20
|
+
return s.replace(/\\/g, "\\\\").replace(/%/g, "\\%").replace(/_/g, "\\_");
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Generic input for building capability statements.
|
|
25
|
+
* Decoupled from CatalogSkill so other skill sources (e.g. bundled skills) can
|
|
26
|
+
* produce capability memories without being shoehorned into the catalog type.
|
|
27
|
+
*/
|
|
28
|
+
export interface SkillCapabilityInput {
|
|
29
|
+
id: string;
|
|
30
|
+
displayName: string;
|
|
31
|
+
description: string;
|
|
32
|
+
activationHints?: string[];
|
|
33
|
+
avoidWhen?: string[];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Convert a SkillSummary to a SkillCapabilityInput.
|
|
38
|
+
* SkillSummary already has flat properties, so this is a straightforward mapping.
|
|
39
|
+
*/
|
|
40
|
+
export function fromSkillSummary(entry: SkillSummary): SkillCapabilityInput {
|
|
41
|
+
return {
|
|
42
|
+
id: entry.id,
|
|
43
|
+
displayName: entry.displayName,
|
|
44
|
+
description: entry.description,
|
|
45
|
+
activationHints: entry.activationHints,
|
|
46
|
+
avoidWhen: entry.avoidWhen,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
15
50
|
/**
|
|
16
|
-
*
|
|
51
|
+
* Convert a CatalogSkill to a SkillCapabilityInput.
|
|
52
|
+
* CatalogSkill stores display-name and hints inside nested metadata.
|
|
53
|
+
*/
|
|
54
|
+
export function fromCatalogSkill(entry: CatalogSkill): SkillCapabilityInput {
|
|
55
|
+
return {
|
|
56
|
+
id: entry.id,
|
|
57
|
+
displayName: entry.metadata?.vellum?.["display-name"] ?? entry.name,
|
|
58
|
+
description: entry.description,
|
|
59
|
+
activationHints: entry.metadata?.vellum?.["activation-hints"],
|
|
60
|
+
avoidWhen: entry.metadata?.vellum?.["avoid-when"],
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Build a semantically rich capability statement from a skill capability input.
|
|
17
66
|
* Truncated to 500 chars max (matching the limit used by memory item extraction).
|
|
18
67
|
*/
|
|
19
|
-
export function buildCapabilityStatement(
|
|
20
|
-
const displayName
|
|
21
|
-
const activationHints = entry.metadata?.vellum?.["activation-hints"];
|
|
68
|
+
export function buildCapabilityStatement(input: SkillCapabilityInput): string {
|
|
69
|
+
const { displayName, activationHints, avoidWhen } = input;
|
|
22
70
|
|
|
23
|
-
let statement = `The "${displayName}" skill (${
|
|
71
|
+
let statement = `The "${displayName}" skill (${input.id}) is available. ${input.description}.`;
|
|
24
72
|
if (activationHints && activationHints.length > 0) {
|
|
25
73
|
statement += ` Use when: ${activationHints.join("; ")}.`;
|
|
26
74
|
}
|
|
75
|
+
if (avoidWhen && avoidWhen.length > 0) {
|
|
76
|
+
statement += ` Avoid when: ${avoidWhen.join("; ")}.`;
|
|
77
|
+
}
|
|
27
78
|
|
|
28
79
|
// Truncate to 500 chars max
|
|
29
80
|
if (statement.length > 500) {
|
|
@@ -33,134 +84,140 @@ export function buildCapabilityStatement(entry: CatalogSkill): string {
|
|
|
33
84
|
return statement;
|
|
34
85
|
}
|
|
35
86
|
|
|
87
|
+
/** Default emotional charge for capability graph nodes. */
|
|
88
|
+
const DEFAULT_EMOTIONAL_CHARGE = JSON.stringify({
|
|
89
|
+
valence: 0,
|
|
90
|
+
intensity: 0.1,
|
|
91
|
+
decayCurve: "linear",
|
|
92
|
+
decayRate: 0.05,
|
|
93
|
+
originalIntensity: 0.1,
|
|
94
|
+
});
|
|
95
|
+
|
|
36
96
|
/**
|
|
37
|
-
* Upsert a capability memory
|
|
97
|
+
* Upsert a capability memory graph node for a skill.
|
|
38
98
|
* Best-effort: errors are logged but never thrown.
|
|
39
99
|
*/
|
|
40
100
|
export function upsertSkillCapabilityMemory(
|
|
41
101
|
skillId: string,
|
|
42
|
-
|
|
102
|
+
input: SkillCapabilityInput,
|
|
43
103
|
): void {
|
|
44
104
|
try {
|
|
45
105
|
const db = getDb();
|
|
46
|
-
const
|
|
47
|
-
const
|
|
48
|
-
const kind = "capability";
|
|
106
|
+
const statement = buildCapabilityStatement(input);
|
|
107
|
+
const content = `skill:${skillId}\n${statement}`;
|
|
49
108
|
const scopeId = "default";
|
|
50
|
-
const confidence = 1.0;
|
|
51
|
-
const importance = 0.7;
|
|
52
|
-
const fingerprint = computeMemoryFingerprint(
|
|
53
|
-
scopeId,
|
|
54
|
-
kind,
|
|
55
|
-
subject,
|
|
56
|
-
statement,
|
|
57
|
-
);
|
|
58
109
|
const now = Date.now();
|
|
59
110
|
|
|
60
111
|
const existing = db
|
|
61
112
|
.select()
|
|
62
|
-
.from(
|
|
113
|
+
.from(memoryGraphNodes)
|
|
63
114
|
.where(
|
|
64
115
|
and(
|
|
65
|
-
eq(
|
|
66
|
-
|
|
67
|
-
eq(
|
|
116
|
+
eq(memoryGraphNodes.type, "procedural"),
|
|
117
|
+
sql`${memoryGraphNodes.content} LIKE ${'skill:' + escapeLike(skillId) + '\n%'} ESCAPE '\\'`,
|
|
118
|
+
eq(memoryGraphNodes.scopeId, scopeId),
|
|
68
119
|
),
|
|
69
120
|
)
|
|
70
121
|
.get();
|
|
71
122
|
|
|
72
123
|
if (existing) {
|
|
73
124
|
if (
|
|
74
|
-
existing.
|
|
75
|
-
existing.
|
|
125
|
+
existing.content === content &&
|
|
126
|
+
existing.fidelity !== "gone"
|
|
76
127
|
) {
|
|
77
|
-
// Same content — just touch
|
|
78
|
-
db.update(
|
|
79
|
-
.set({
|
|
80
|
-
.where(eq(
|
|
128
|
+
// Same content — just touch lastAccessed
|
|
129
|
+
db.update(memoryGraphNodes)
|
|
130
|
+
.set({ lastAccessed: now })
|
|
131
|
+
.where(eq(memoryGraphNodes.id, existing.id))
|
|
81
132
|
.run();
|
|
82
133
|
return;
|
|
83
134
|
}
|
|
84
135
|
|
|
85
|
-
if (existing.
|
|
86
|
-
// Content changed — update
|
|
87
|
-
db.update(
|
|
136
|
+
if (existing.fidelity !== "gone") {
|
|
137
|
+
// Content changed — update content
|
|
138
|
+
db.update(memoryGraphNodes)
|
|
88
139
|
.set({
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
lastSeenAt: now,
|
|
140
|
+
content,
|
|
141
|
+
lastAccessed: now,
|
|
92
142
|
})
|
|
93
|
-
.where(eq(
|
|
143
|
+
.where(eq(memoryGraphNodes.id, existing.id))
|
|
94
144
|
.run();
|
|
95
|
-
enqueueMemoryJob("
|
|
145
|
+
enqueueMemoryJob("embed_graph_node", { nodeId: existing.id });
|
|
96
146
|
return;
|
|
97
147
|
}
|
|
98
148
|
|
|
99
|
-
//
|
|
100
|
-
db.update(
|
|
149
|
+
// fidelity === "gone" — reactivate
|
|
150
|
+
db.update(memoryGraphNodes)
|
|
101
151
|
.set({
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
firstSeenAt: now,
|
|
152
|
+
fidelity: "vivid",
|
|
153
|
+
content,
|
|
154
|
+
created: now,
|
|
155
|
+
lastAccessed: now,
|
|
107
156
|
})
|
|
108
|
-
.where(eq(
|
|
157
|
+
.where(eq(memoryGraphNodes.id, existing.id))
|
|
109
158
|
.run();
|
|
110
|
-
enqueueMemoryJob("
|
|
159
|
+
enqueueMemoryJob("embed_graph_node", { nodeId: existing.id });
|
|
160
|
+
log.info({ skillId, nodeId: existing.id }, "Reactivated skill capability memory");
|
|
111
161
|
return;
|
|
112
162
|
}
|
|
113
163
|
|
|
114
|
-
// No existing — insert new
|
|
164
|
+
// No existing — insert new graph node
|
|
115
165
|
const id = uuid();
|
|
116
|
-
db.insert(
|
|
166
|
+
db.insert(memoryGraphNodes)
|
|
117
167
|
.values({
|
|
118
168
|
id,
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
169
|
+
content,
|
|
170
|
+
type: "procedural",
|
|
171
|
+
created: now,
|
|
172
|
+
lastAccessed: now,
|
|
173
|
+
lastConsolidated: now,
|
|
174
|
+
emotionalCharge: DEFAULT_EMOTIONAL_CHARGE,
|
|
175
|
+
fidelity: "vivid",
|
|
176
|
+
confidence: 1.0,
|
|
177
|
+
significance: 0.7,
|
|
178
|
+
stability: 14,
|
|
179
|
+
reinforcementCount: 0,
|
|
180
|
+
lastReinforced: now,
|
|
181
|
+
sourceConversations: JSON.stringify([]),
|
|
182
|
+
sourceType: "inferred",
|
|
183
|
+
narrativeRole: null,
|
|
184
|
+
partOfStory: null,
|
|
127
185
|
scopeId,
|
|
128
|
-
firstSeenAt: now,
|
|
129
|
-
lastSeenAt: now,
|
|
130
186
|
})
|
|
131
187
|
.run();
|
|
132
|
-
enqueueMemoryJob("
|
|
188
|
+
enqueueMemoryJob("embed_graph_node", { nodeId: id });
|
|
189
|
+
log.info({ skillId, nodeId: id }, "Created skill capability memory");
|
|
133
190
|
} catch (err) {
|
|
134
191
|
log.warn({ err, skillId }, "Failed to upsert skill capability memory");
|
|
135
192
|
}
|
|
136
193
|
}
|
|
137
194
|
|
|
138
195
|
/**
|
|
139
|
-
* Soft-delete the capability memory
|
|
196
|
+
* Soft-delete the capability memory graph node for a skill.
|
|
140
197
|
* Best-effort: errors are logged but never thrown.
|
|
141
198
|
*/
|
|
142
199
|
export function deleteSkillCapabilityMemory(skillId: string): void {
|
|
143
200
|
try {
|
|
144
201
|
const db = getDb();
|
|
145
|
-
const subject = `skill:${skillId}`;
|
|
146
202
|
const now = Date.now();
|
|
147
203
|
|
|
148
204
|
const existing = db
|
|
149
205
|
.select()
|
|
150
|
-
.from(
|
|
206
|
+
.from(memoryGraphNodes)
|
|
151
207
|
.where(
|
|
152
208
|
and(
|
|
153
|
-
eq(
|
|
154
|
-
|
|
155
|
-
eq(
|
|
209
|
+
eq(memoryGraphNodes.type, "procedural"),
|
|
210
|
+
sql`${memoryGraphNodes.content} LIKE ${'skill:' + escapeLike(skillId) + '\n%'} ESCAPE '\\'`,
|
|
211
|
+
eq(memoryGraphNodes.scopeId, "default"),
|
|
212
|
+
sql`${memoryGraphNodes.fidelity} != 'gone'`,
|
|
156
213
|
),
|
|
157
214
|
)
|
|
158
215
|
.get();
|
|
159
216
|
|
|
160
|
-
if (existing
|
|
161
|
-
db.update(
|
|
162
|
-
.set({
|
|
163
|
-
.where(eq(
|
|
217
|
+
if (existing) {
|
|
218
|
+
db.update(memoryGraphNodes)
|
|
219
|
+
.set({ fidelity: "gone", lastAccessed: now })
|
|
220
|
+
.where(eq(memoryGraphNodes.id, existing.id))
|
|
164
221
|
.run();
|
|
165
222
|
}
|
|
166
223
|
} catch (err) {
|
|
@@ -169,54 +226,111 @@ export function deleteSkillCapabilityMemory(skillId: string): void {
|
|
|
169
226
|
}
|
|
170
227
|
|
|
171
228
|
/**
|
|
172
|
-
* Seed capability memory
|
|
173
|
-
* Prunes stale entries whose skills are no longer in the
|
|
229
|
+
* Seed capability memory graph nodes for all enabled skills (bundled, managed, workspace, extra).
|
|
230
|
+
* Prunes stale entries whose skills are no longer in the enabled set.
|
|
174
231
|
* Best-effort: errors are logged but never thrown.
|
|
175
232
|
*/
|
|
176
|
-
export
|
|
233
|
+
export function seedCatalogSkillMemories(): void {
|
|
177
234
|
try {
|
|
178
|
-
const catalog =
|
|
235
|
+
const catalog = loadSkillCatalog();
|
|
179
236
|
const config = getConfig();
|
|
237
|
+
const resolved = resolveSkillStates(catalog, config);
|
|
238
|
+
const enabled = resolved.filter((r) => r.state === "enabled");
|
|
239
|
+
|
|
180
240
|
const catalogIds = new Set<string>();
|
|
241
|
+
for (const { summary } of enabled) {
|
|
242
|
+
catalogIds.add(summary.id);
|
|
243
|
+
const input = fromSkillSummary(summary);
|
|
181
244
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
245
|
+
// Enrich mcp-setup description with configured server names
|
|
246
|
+
if (summary.id === "mcp-setup") {
|
|
247
|
+
const servers = config.mcp?.servers;
|
|
248
|
+
if (servers) {
|
|
249
|
+
const names = Object.keys(servers).filter(
|
|
250
|
+
(name) => servers[name]?.enabled !== false,
|
|
251
|
+
);
|
|
252
|
+
if (names.length > 0) {
|
|
253
|
+
input.description += ` Configured: ${names.join(", ")}`;
|
|
254
|
+
}
|
|
188
255
|
}
|
|
189
256
|
}
|
|
190
257
|
|
|
191
|
-
|
|
192
|
-
upsertSkillCapabilityMemory(entry.id, entry);
|
|
258
|
+
upsertSkillCapabilityMemory(summary.id, input);
|
|
193
259
|
}
|
|
194
260
|
|
|
195
|
-
// Prune stale capability memories for skills no longer in
|
|
261
|
+
// Prune stale capability memories for skills no longer in the enabled set
|
|
262
|
+
// and not available in the remote/local catalog.
|
|
196
263
|
const db = getDb();
|
|
197
264
|
const allCapabilities = db
|
|
198
265
|
.select()
|
|
199
|
-
.from(
|
|
266
|
+
.from(memoryGraphNodes)
|
|
200
267
|
.where(
|
|
201
268
|
and(
|
|
202
|
-
eq(
|
|
203
|
-
eq(
|
|
204
|
-
|
|
269
|
+
eq(memoryGraphNodes.type, "procedural"),
|
|
270
|
+
eq(memoryGraphNodes.scopeId, "default"),
|
|
271
|
+
sql`${memoryGraphNodes.fidelity} != 'gone'`,
|
|
205
272
|
),
|
|
206
273
|
)
|
|
207
274
|
.all();
|
|
208
275
|
|
|
276
|
+
const allLocalSkillIds = new Set(catalog.map((s) => s.id));
|
|
277
|
+
const cachedCatalog = getCachedCatalogSync();
|
|
278
|
+
const cachedCatalogIds = new Set(cachedCatalog.map((s) => s.id));
|
|
279
|
+
|
|
209
280
|
const now = Date.now();
|
|
210
281
|
for (const item of allCapabilities) {
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
282
|
+
if (!item.content.startsWith("skill:")) continue;
|
|
283
|
+
const itemSkillId = item.content.split("\n")[0].replace("skill:", "");
|
|
284
|
+
|
|
285
|
+
// Keep enabled skills
|
|
286
|
+
if (catalogIds.has(itemSkillId)) continue;
|
|
287
|
+
|
|
288
|
+
// Keep uninstalled catalog skills that are still in the remote catalog
|
|
289
|
+
if (cachedCatalogIds.has(itemSkillId)) continue;
|
|
290
|
+
|
|
291
|
+
// If the catalog cache is empty (cold start, before async fetch),
|
|
292
|
+
// we can't tell whether an unknown skill is a stale entry or
|
|
293
|
+
// a valid uninstalled catalog skill. Only prune skills we can
|
|
294
|
+
// positively identify as local-but-disabled.
|
|
295
|
+
if (cachedCatalogIds.size === 0 && !allLocalSkillIds.has(itemSkillId)) continue;
|
|
296
|
+
|
|
297
|
+
log.info({ skillId: itemSkillId, nodeId: item.id, catalogSize: catalogIds.size, cacheSize: cachedCatalogIds.size }, "Pruning stale skill capability memory");
|
|
298
|
+
db.update(memoryGraphNodes)
|
|
299
|
+
.set({ fidelity: "gone", lastAccessed: now })
|
|
300
|
+
.where(eq(memoryGraphNodes.id, item.id))
|
|
301
|
+
.run();
|
|
218
302
|
}
|
|
219
303
|
} catch (err) {
|
|
220
304
|
log.warn({ err }, "Failed to seed catalog skill memories");
|
|
221
305
|
}
|
|
222
306
|
}
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* Seed capability memories for catalog skills that are not yet installed.
|
|
310
|
+
* This makes uninstalled skills discoverable via memory injection so the LLM
|
|
311
|
+
* can auto-install them via skill_load when relevant.
|
|
312
|
+
* Best-effort: errors are logged but never thrown.
|
|
313
|
+
*/
|
|
314
|
+
export async function seedUninstalledCatalogSkillMemories(): Promise<void> {
|
|
315
|
+
try {
|
|
316
|
+
const { getCatalog } = await import("./catalog-cache.js");
|
|
317
|
+
const fullCatalog = await getCatalog();
|
|
318
|
+
if (fullCatalog.length === 0) return;
|
|
319
|
+
|
|
320
|
+
const installedCatalog = loadSkillCatalog();
|
|
321
|
+
const installedIds = new Set(installedCatalog.map((s) => s.id));
|
|
322
|
+
|
|
323
|
+
const config = getConfig();
|
|
324
|
+
for (const entry of fullCatalog) {
|
|
325
|
+
if (installedIds.has(entry.id)) continue;
|
|
326
|
+
|
|
327
|
+
const flagKey = entry.metadata?.vellum?.["feature-flag"];
|
|
328
|
+
if (flagKey && !isAssistantFeatureFlagEnabled(flagKey, config)) continue;
|
|
329
|
+
|
|
330
|
+
const input = fromCatalogSkill(entry);
|
|
331
|
+
upsertSkillCapabilityMemory(entry.id, input);
|
|
332
|
+
}
|
|
333
|
+
} catch (err) {
|
|
334
|
+
log.warn({ err }, "Failed to seed uninstalled catalog skill memories");
|
|
335
|
+
}
|
|
336
|
+
}
|
|
@@ -5,6 +5,7 @@ import { dirname, join, resolve, sep } from "node:path";
|
|
|
5
5
|
|
|
6
6
|
import { getWorkspaceSkillsDir } from "../util/platform.js";
|
|
7
7
|
import { upsertSkillsIndex } from "./catalog-install.js";
|
|
8
|
+
import { computeSkillHash, writeInstallMeta } from "./install-meta.js";
|
|
8
9
|
|
|
9
10
|
// ─── Types ───────────────────────────────────────────────────────────────────
|
|
10
11
|
|
|
@@ -434,9 +435,12 @@ export function validateSkillSlug(slug: string): void {
|
|
|
434
435
|
* 1. Validates the skill slug for path safety
|
|
435
436
|
* 2. Fetches all files from `skills/<skillSlug>/` in the source repo
|
|
436
437
|
* 3. Writes them to `<workspace>/skills/<skillSlug>/` with path traversal protection
|
|
437
|
-
* 4. Writes `
|
|
438
|
-
* 5.
|
|
439
|
-
* 6.
|
|
438
|
+
* 4. Writes `install-meta.json` with origin metadata
|
|
439
|
+
* 5. Installs npm dependencies (if package.json exists)
|
|
440
|
+
* 6. Updates SKILLS.md index
|
|
441
|
+
*
|
|
442
|
+
* Auto-enable and memory seeding are handled by the caller (e.g.
|
|
443
|
+
* `postInstallSkill()` in the daemon, or left to the user for CLI installs).
|
|
440
444
|
*/
|
|
441
445
|
export async function installExternalSkill(
|
|
442
446
|
owner: string,
|
|
@@ -444,6 +448,7 @@ export async function installExternalSkill(
|
|
|
444
448
|
skillSlug: string,
|
|
445
449
|
overwrite: boolean,
|
|
446
450
|
ref?: string,
|
|
451
|
+
contactId?: string,
|
|
447
452
|
): Promise<void> {
|
|
448
453
|
// Validate slug before using in filesystem paths
|
|
449
454
|
validateSkillSlug(skillSlug);
|
|
@@ -480,20 +485,19 @@ export async function installExternalSkill(
|
|
|
480
485
|
writeFileSync(destPath, content, "utf-8");
|
|
481
486
|
}
|
|
482
487
|
|
|
483
|
-
// Write
|
|
484
|
-
|
|
485
|
-
origin: "
|
|
486
|
-
|
|
487
|
-
|
|
488
|
+
// Write install metadata
|
|
489
|
+
writeInstallMeta(skillDir, {
|
|
490
|
+
origin: "skillssh",
|
|
491
|
+
slug: skillSlug,
|
|
492
|
+
sourceRepo: `${owner}/${repo}`,
|
|
488
493
|
installedAt: new Date().toISOString(),
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
JSON.stringify(meta, null, 2) + "\n",
|
|
493
|
-
"utf-8",
|
|
494
|
-
);
|
|
494
|
+
...(contactId ? { installedBy: contactId } : {}),
|
|
495
|
+
contentHash: computeSkillHash(skillDir) ?? undefined,
|
|
496
|
+
});
|
|
495
497
|
|
|
496
|
-
//
|
|
498
|
+
// Post-install: install dependencies first, then index the skill.
|
|
499
|
+
// Running bun install before upsertSkillsIndex ensures we don't index a
|
|
500
|
+
// skill whose dependencies failed to install.
|
|
497
501
|
if (existsSync(join(skillDir, "package.json"))) {
|
|
498
502
|
const bunPath = `${homedir()}/.bun/bin`;
|
|
499
503
|
execSync("bun install", {
|
|
@@ -502,7 +506,5 @@ export async function installExternalSkill(
|
|
|
502
506
|
env: { ...process.env, PATH: `${bunPath}:${process.env.PATH}` },
|
|
503
507
|
});
|
|
504
508
|
}
|
|
505
|
-
|
|
506
|
-
// Register in SKILLS.md only after files are written and deps installed
|
|
507
509
|
upsertSkillsIndex(skillSlug);
|
|
508
510
|
}
|
package/src/tasks/task-runner.ts
CHANGED
|
@@ -64,8 +64,10 @@ export async function runTask(
|
|
|
64
64
|
// Scheduled section; non-schedule tasks use "background" to stay out of
|
|
65
65
|
// the main conversation list.
|
|
66
66
|
conversationType: opts.source === "schedule" ? undefined : "background",
|
|
67
|
-
source: opts.source,
|
|
67
|
+
source: opts.source === "schedule" ? "schedule" : "task",
|
|
68
68
|
scheduleJobId: opts.scheduleJobId,
|
|
69
|
+
groupId:
|
|
70
|
+
opts.source === "schedule" ? "system:scheduled" : "system:background",
|
|
69
71
|
origin: "task",
|
|
70
72
|
systemHint: `Task: ${task.title}`,
|
|
71
73
|
});
|
|
@@ -504,17 +504,15 @@ describe("UsageTelemetryReporter", () => {
|
|
|
504
504
|
// No HTTP call should have been made
|
|
505
505
|
expect(mockFetch).not.toHaveBeenCalled();
|
|
506
506
|
|
|
507
|
-
// All
|
|
508
|
-
|
|
507
|
+
// All 3 timestamp watermarks should have been advanced (IDs left untouched
|
|
508
|
+
// so the compound-cursor branch stays active)
|
|
509
|
+
expect(mockSetMemoryCheckpoint).toHaveBeenCalledTimes(3);
|
|
509
510
|
|
|
510
511
|
const calls = mockSetMemoryCheckpoint.mock.calls;
|
|
511
512
|
const keys = calls.map((c) => c[0]);
|
|
512
513
|
expect(keys).toContain("telemetry:usage:last_reported_at");
|
|
513
|
-
expect(keys).toContain("telemetry:usage:last_reported_id");
|
|
514
514
|
expect(keys).toContain("telemetry:turns:last_reported_at");
|
|
515
|
-
expect(keys).toContain("telemetry:turns:last_reported_id");
|
|
516
515
|
expect(keys).toContain("telemetry:lifecycle:last_reported_at");
|
|
517
|
-
expect(keys).toContain("telemetry:lifecycle:last_reported_id");
|
|
518
516
|
});
|
|
519
517
|
|
|
520
518
|
test("events sent normally after re-enabling collectUsageData", async () => {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
|
|
4
|
+
import { ensureBun } from "../../util/bun-runtime.js";
|
|
4
5
|
import { getExternalDir } from "../../util/platform.js";
|
|
5
6
|
|
|
6
7
|
export interface BrowserRuntimeStatus {
|
|
@@ -83,7 +84,8 @@ export async function importPlaywright(): Promise<typeof import("playwright")> {
|
|
|
83
84
|
if (!existsSync(join(externalDir, "package.json"))) {
|
|
84
85
|
writeFileSync(join(externalDir, "package.json"), '{"private":true}\n');
|
|
85
86
|
}
|
|
86
|
-
const
|
|
87
|
+
const bunPath = await ensureBun();
|
|
88
|
+
const proc = Bun.spawn([bunPath, "add", "playwright"], {
|
|
87
89
|
cwd: externalDir,
|
|
88
90
|
stdout: "pipe",
|
|
89
91
|
stderr: "pipe",
|