@vellumai/assistant 0.5.16 → 0.6.1
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/AGENTS.md +4 -0
- package/ARCHITECTURE.md +69 -16
- package/Dockerfile +2 -5
- package/bun.lock +6 -2
- package/docker-entrypoint.sh +32 -1
- package/docs/architecture/integrations.md +1 -1
- package/docs/architecture/memory.md +21 -24
- package/knip.json +2 -1
- package/openapi.yaml +1198 -83
- package/package.json +5 -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 +217 -98
- package/src/__tests__/app-compiler.test.ts +120 -0
- package/src/__tests__/app-dir-path-guard.test.ts +1 -0
- package/src/__tests__/app-executors.test.ts +47 -1
- package/src/__tests__/app-source-watcher.test.ts +159 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +2 -2
- 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__/channel-delivery-store.test.ts +2 -6
- package/src/__tests__/channel-retry-sweep.test.ts +2 -6
- package/src/__tests__/checker.test.ts +63 -9
- package/src/__tests__/clawhub.test.ts +54 -24
- package/src/__tests__/cli-command-risk-guard.test.ts +14 -0
- package/src/__tests__/config-schema.test.ts +6 -1
- package/src/__tests__/config-set-platform-guard.test.ts +302 -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 +13 -6
- package/src/__tests__/conversation-agent-loop.test.ts +13 -51
- 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 +6 -1
- 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 +653 -832
- package/src/__tests__/conversation-runtime-workspace.test.ts +1 -93
- package/src/__tests__/conversation-starter-routes.test.ts +20 -11
- package/src/__tests__/conversation-store.test.ts +2 -6
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +17 -4
- package/src/__tests__/conversation-usage.test.ts +2 -6
- package/src/__tests__/conversation-wipe.test.ts +13 -414
- package/src/__tests__/conversation-workspace-cache-state.test.ts +6 -12
- package/src/__tests__/conversation-workspace-injection.test.ts +25 -26
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +1 -1
- package/src/__tests__/copy-composer-tc-templates.test.ts +335 -0
- 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 +2 -0
- package/src/__tests__/date-context.test.ts +76 -210
- package/src/__tests__/db-schedule-syntax-migration.test.ts +16 -1
- package/src/__tests__/file-list-tool.test.ts +219 -0
- package/src/__tests__/first-greeting.test.ts +1 -1
- 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 +192 -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 +180 -3
- package/src/__tests__/identity-routes.test.ts +328 -0
- package/src/__tests__/inbound-invite-redemption.test.ts +2 -6
- package/src/__tests__/injection-block.test.ts +178 -0
- package/src/__tests__/install-meta.test.ts +506 -0
- package/src/__tests__/install-skill-routing.test.ts +293 -0
- 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 +17 -28
- package/src/__tests__/list-messages-attachments.test.ts +2 -6
- package/src/__tests__/list-messages-tool-merge.test.ts +300 -0
- package/src/__tests__/llm-context-normalization.test.ts +18 -18
- package/src/__tests__/llm-context-route-provider.test.ts +103 -6
- package/src/__tests__/llm-request-log-turn-query.test.ts +164 -6
- package/src/__tests__/llm-usage-store.test.ts +2 -6
- package/src/__tests__/log-export-workspace.test.ts +74 -111
- package/src/__tests__/managed-store.test.ts +38 -11
- package/src/__tests__/mcp-abort-signal.test.ts +5 -0
- package/src/__tests__/mcp-client-auth.test.ts +5 -0
- package/src/__tests__/memory-jobs-worker-backoff.test.ts +2 -8
- package/src/__tests__/memory-recall-log-store.test.ts +134 -6
- package/src/__tests__/memory-upsert-concurrency.test.ts +4 -112
- package/src/__tests__/migration-export-streaming.test.ts +304 -0
- package/src/__tests__/migration-import-commit-http.test.ts +11 -10
- package/src/__tests__/mock-fetch.ts +87 -0
- package/src/__tests__/non-member-access-request.test.ts +2 -6
- package/src/__tests__/notification-decision-recipient-context.test.ts +282 -0
- package/src/__tests__/notification-guardian-path.test.ts +2 -6
- package/src/__tests__/oauth-cli.test.ts +364 -2
- package/src/__tests__/oauth2-gateway-transport.test.ts +18 -3
- package/src/__tests__/onboarding-template-contract.test.ts +62 -14
- 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 +498 -3
- package/src/__tests__/outlook-trash.test.ts +77 -0
- package/src/__tests__/outlook-unsubscribe.test.ts +250 -0
- package/src/__tests__/parser.test.ts +32 -0
- package/src/__tests__/permission-checker-host-gate.test.ts +452 -0
- package/src/__tests__/permission-controls-v2-flag.test.ts +55 -0
- package/src/__tests__/permission-mode-sse.test.ts +418 -0
- package/src/__tests__/permission-mode-store.test.ts +277 -0
- package/src/__tests__/permission-mode.test.ts +101 -0
- package/src/__tests__/platform-bash-auto-approve.test.ts +359 -0
- package/src/__tests__/platform-callback-registration.test.ts +4 -4
- package/src/__tests__/playbook-execution.test.ts +76 -80
- package/src/__tests__/playbook-tools.test.ts +5 -7
- package/src/__tests__/profiler-routes.test.ts +502 -0
- package/src/__tests__/profiler-run-store.test.ts +441 -0
- package/src/__tests__/provider-error-scenarios.test.ts +21 -0
- package/src/__tests__/proxy-approval-callback.test.ts +4 -75
- package/src/__tests__/rebuild-index-graph-nodes.test.ts +273 -0
- package/src/__tests__/registry.test.ts +3 -3
- package/src/__tests__/require-fresh-approval.test.ts +64 -2
- 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-host-parity.test.ts +5 -4
- 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__/scheduler-reuse-conversation.test.ts +368 -0
- package/src/__tests__/scoped-approval-grants.test.ts +2 -6
- package/src/__tests__/scoped-grant-security-matrix.test.ts +2 -6
- package/src/__tests__/scrub-corrupted-image-attachments.test.ts +278 -0
- package/src/__tests__/search-skills-unified.test.ts +422 -0
- package/src/__tests__/secret-onetime-send.test.ts +2 -0
- package/src/__tests__/send-endpoint-busy.test.ts +44 -9
- package/src/__tests__/sequence-store.test.ts +2 -6
- package/src/__tests__/server-history-render.test.ts +2 -6
- package/src/__tests__/set-permission-mode.test.ts +274 -0
- 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 +23 -11
- package/src/__tests__/skill-memory.test.ts +2 -741
- package/src/__tests__/skills-uninstall.test.ts +2 -2
- package/src/__tests__/skills.test.ts +1 -1
- package/src/__tests__/slack-inbound-verification.test.ts +2 -6
- package/src/__tests__/strip-memory-injections.test.ts +187 -0
- package/src/__tests__/subagent-detail.test.ts +84 -0
- package/src/__tests__/subagent-disposal.test.ts +308 -0
- package/src/__tests__/subagent-manager-notify.test.ts +19 -10
- package/src/__tests__/subagent-notify-parent.test.ts +390 -0
- package/src/__tests__/subagent-role-registry.test.ts +108 -0
- package/src/__tests__/subagent-tool-filtering.test.ts +71 -0
- package/src/__tests__/subagent-tools.test.ts +464 -4
- package/src/__tests__/system-prompt-ask-mode.test.ts +139 -0
- package/src/__tests__/task-compiler.test.ts +2 -6
- package/src/__tests__/task-management-tools.test.ts +2 -6
- package/src/__tests__/task-memory-cleanup.test.ts +185 -241
- package/src/__tests__/task-runner.test.ts +2 -6
- package/src/__tests__/task-scheduler.test.ts +2 -6
- package/src/__tests__/terminal-tools.test.ts +17 -27
- package/src/__tests__/test-preload.ts +7 -0
- package/src/__tests__/tool-approval-handler.test.ts +2 -6
- package/src/__tests__/tool-executor.test.ts +4 -26
- package/src/__tests__/tool-grant-request-escalation.test.ts +2 -6
- package/src/__tests__/tool-side-effects-slack-dm.test.ts +277 -0
- package/src/__tests__/top-level-renderer.test.ts +10 -13
- package/src/__tests__/trust-store.test.ts +1 -1
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +2 -6
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +118 -8
- package/src/__tests__/trusted-contact-multichannel.test.ts +2 -6
- package/src/__tests__/trusted-contact-verification.test.ts +2 -6
- package/src/__tests__/turn-boundary-resolution.test.ts +2 -6
- package/src/__tests__/usage-cache-backfill-migration.test.ts +1 -6
- package/src/__tests__/usage-routes.test.ts +2 -6
- package/src/__tests__/verification-control-plane-policy.test.ts +0 -2
- package/src/__tests__/voice-invite-redemption.test.ts +2 -6
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +2 -6
- package/src/__tests__/voice-session-bridge.test.ts +2 -6
- 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 +2 -6
- package/src/__tests__/workspace-migration-013-repair-conversation-disk-view.test.ts +2 -6
- package/src/__tests__/workspace-migration-026-backfill-install-meta.test.ts +558 -0
- package/src/__tests__/workspace-migration-028-recover-conversations-from-disk-view.test.ts +387 -0
- package/src/__tests__/workspace-policy.test.ts +1 -1
- package/src/agent/attachments.ts +7 -2
- package/src/agent/image-optimize.ts +165 -0
- package/src/agent/loop.ts +7 -15
- package/src/approvals/guardian-request-resolvers.ts +24 -0
- package/src/avatar/traits-png-sync.ts +3 -3
- package/src/bundler/app-compiler.ts +179 -2
- package/src/bundler/package-resolver.ts +3 -5
- package/src/cli/__tests__/notifications.test.ts +1 -2
- package/src/cli/__tests__/run-assistant-command.ts +29 -0
- package/src/cli/commands/__tests__/email-download.test.ts +245 -0
- package/src/cli/commands/__tests__/email-list.test.ts +192 -0
- package/src/cli/commands/__tests__/email-register.test.ts +186 -0
- package/src/cli/commands/__tests__/email-send.test.ts +291 -0
- package/src/cli/commands/__tests__/email-status.test.ts +181 -0
- package/src/cli/commands/__tests__/email-unregister.test.ts +139 -0
- package/src/cli/commands/__tests__/routes.test.ts +562 -0
- package/src/cli/commands/avatar.ts +3 -3
- package/src/cli/commands/config.ts +26 -13
- package/src/cli/commands/conversations.ts +1 -8
- package/src/cli/commands/doctor.ts +2 -2
- package/src/cli/commands/email.ts +584 -835
- package/src/cli/commands/memory.ts +37 -84
- package/src/cli/commands/notifications.ts +7 -2
- 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__/status.test.ts +2 -2
- package/src/cli/commands/oauth/connect.ts +25 -11
- package/src/cli/commands/oauth/mode.ts +7 -0
- package/src/cli/commands/oauth/shared.ts +39 -3
- package/src/cli/commands/platform/__tests__/connect.test.ts +1 -1
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +1 -1
- package/src/cli/commands/platform/__tests__/status.test.ts +5 -5
- package/src/cli/commands/platform/index.ts +16 -16
- package/src/cli/commands/routes.ts +396 -0
- package/src/cli/commands/skills.ts +218 -36
- package/src/cli/commands/trust.ts +2 -2
- package/src/cli/lib/daemon-credential-client.ts +2 -3
- package/src/cli/program.ts +2 -0
- package/src/cli.ts +1 -120
- package/src/config/bundled-skills/acp/TOOLS.json +1 -1
- package/src/config/bundled-skills/app-builder/SKILL.md +4 -1
- 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 +4 -12
- package/src/config/bundled-skills/google-calendar/SKILL.md +1 -9
- package/src/config/bundled-skills/messaging/SKILL.md +17 -18
- 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/schedule/SKILL.md +22 -2
- package/src/config/bundled-skills/schedule/TOOLS.json +8 -0
- package/src/config/bundled-skills/settings/tools/avatar-get.ts +3 -13
- package/src/config/bundled-skills/settings/tools/avatar-remove.ts +2 -4
- package/src/config/bundled-skills/settings/tools/avatar-update.ts +5 -2
- package/src/config/bundled-skills/slack/SKILL.md +3 -7
- package/src/config/bundled-skills/subagent/SKILL.md +43 -3
- package/src/config/bundled-skills/subagent/TOOLS.json +29 -4
- package/src/config/bundled-tool-registry.ts +56 -4
- package/src/config/env-registry.ts +78 -8
- package/src/config/feature-flag-registry.json +38 -125
- package/src/config/schema.ts +8 -0
- package/src/config/schemas/filing.ts +51 -0
- package/src/config/schemas/heartbeat.ts +15 -12
- package/src/config/schemas/memory-lifecycle.ts +12 -0
- package/src/config/schemas/platform.ts +8 -0
- package/src/config/schemas/security.ts +14 -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 +6 -2
- package/src/credential-execution/process-manager.ts +3 -1
- package/src/daemon/app-source-watcher.ts +93 -0
- package/src/daemon/config-watcher.ts +79 -1
- package/src/daemon/context-overflow-reducer.ts +46 -2
- package/src/daemon/conversation-agent-loop-handlers.ts +143 -82
- package/src/daemon/conversation-agent-loop.ts +236 -108
- package/src/daemon/conversation-error.ts +31 -8
- package/src/daemon/conversation-history.ts +4 -19
- package/src/daemon/conversation-lifecycle.ts +36 -9
- package/src/daemon/conversation-media-retry.ts +85 -7
- package/src/daemon/conversation-notifiers.ts +4 -1
- package/src/daemon/conversation-process.ts +13 -7
- package/src/daemon/conversation-runtime-assembly.ts +305 -306
- package/src/daemon/conversation-tool-setup.ts +44 -14
- package/src/daemon/conversation-workspace.ts +1 -2
- package/src/daemon/conversation.ts +59 -2
- package/src/daemon/daemon-control.ts +8 -2
- package/src/daemon/date-context.ts +26 -53
- package/src/daemon/first-greeting.ts +1 -1
- package/src/daemon/handlers/conversations.ts +4 -7
- package/src/daemon/handlers/shared.test.ts +143 -0
- package/src/daemon/handlers/shared.ts +85 -17
- package/src/daemon/handlers/skills.ts +416 -209
- package/src/daemon/lifecycle.ts +212 -131
- package/src/daemon/main.ts +5 -1
- package/src/daemon/message-types/conversations.ts +29 -7
- package/src/daemon/message-types/messages.ts +12 -2
- package/src/daemon/message-types/schedules.ts +1 -0
- package/src/daemon/message-types/settings.ts +6 -0
- package/src/daemon/message-types/skills.ts +97 -36
- package/src/daemon/profiler-run-store.ts +557 -0
- package/src/daemon/providers-setup.ts +5 -0
- package/src/daemon/server.ts +100 -11
- package/src/daemon/shutdown-handlers.ts +5 -0
- package/src/daemon/tool-side-effects.ts +50 -8
- package/src/export/transcript-formatter.ts +148 -0
- package/src/filing/filing-service.ts +228 -0
- package/src/heartbeat/heartbeat-service.ts +97 -7
- 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/mcp/client.ts +6 -0
- package/src/mcp/mcp-oauth-provider.ts +149 -27
- package/src/memory/admin.ts +42 -75
- package/src/memory/app-store.ts +69 -0
- package/src/memory/conversation-bootstrap.ts +3 -1
- package/src/memory/conversation-crud.ts +211 -288
- package/src/memory/conversation-group-migration.ts +157 -0
- package/src/memory/conversation-queries.ts +61 -13
- package/src/memory/conversation-title-service.ts +1 -0
- package/src/memory/db-init.ts +194 -361
- 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 +521 -0
- package/src/memory/graph/capability-seed.ts +449 -0
- package/src/memory/graph/consolidation.ts +725 -0
- package/src/memory/graph/conversation-graph-memory.ts +659 -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 +74 -0
- package/src/memory/graph/extraction.test.ts +936 -0
- package/src/memory/graph/extraction.ts +1297 -0
- package/src/memory/graph/graph-memory-state-store.ts +37 -0
- package/src/memory/graph/graph-search.ts +280 -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 +469 -0
- package/src/memory/graph/inspect.ts +543 -0
- package/src/memory/graph/narrative.ts +267 -0
- package/src/memory/graph/pattern-scan.ts +269 -0
- package/src/memory/graph/retriever.ts +1111 -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 +1098 -0
- package/src/memory/graph/store.ts +838 -0
- package/src/memory/graph/tool-handlers.ts +301 -0
- package/src/memory/graph/tools.ts +97 -0
- package/src/memory/graph/triggers.test.ts +487 -0
- package/src/memory/graph/triggers.ts +223 -0
- package/src/memory/graph/types.ts +295 -0
- package/src/memory/group-crud.ts +191 -0
- package/src/memory/indexer.ts +37 -19
- package/src/memory/job-handlers/cleanup.ts +32 -42
- package/src/memory/job-handlers/conversation-starters.ts +91 -53
- 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 +21 -31
- package/src/memory/jobs-worker.ts +180 -129
- package/src/memory/llm-request-log-store.ts +96 -12
- package/src/memory/memory-recall-log-store.ts +49 -5
- package/src/memory/message-content.ts +1 -0
- package/src/memory/migrations/202-memory-graph-tables.ts +130 -0
- package/src/memory/migrations/203-drop-memory-items-tables.ts +55 -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/206-memory-graph-node-edits.ts +19 -0
- package/src/memory/migrations/206-scrub-corrupted-image-attachments.ts +131 -0
- package/src/memory/migrations/207-conversation-graph-memory-state.ts +20 -0
- package/src/memory/migrations/208-conversations-last-message-at.ts +35 -0
- package/src/memory/migrations/209-strip-thinking-from-consolidated.ts +85 -0
- package/src/memory/migrations/210-schedule-reuse-conversation.ts +13 -0
- package/src/memory/migrations/211-memory-recall-logs-query-context.ts +21 -0
- package/src/memory/migrations/212-llm-request-logs-created-at-index.ts +19 -0
- package/src/memory/migrations/index.ts +12 -0
- package/src/memory/migrations/registry.ts +16 -0
- package/src/memory/qdrant-client.ts +44 -17
- package/src/memory/schema/conversations.ts +14 -0
- package/src/memory/schema/index.ts +1 -0
- package/src/memory/schema/infrastructure.ts +8 -1
- package/src/memory/schema/memory-core.ts +0 -51
- package/src/memory/schema/memory-graph.ts +154 -0
- package/src/memory/search/semantic.ts +47 -91
- package/src/memory/task-memory-cleanup.ts +58 -61
- package/src/messaging/providers/outlook/adapter.ts +8 -1
- package/src/messaging/providers/outlook/client.ts +299 -0
- package/src/messaging/providers/outlook/types.ts +118 -0
- package/src/notifications/adapters/macos.ts +1 -0
- package/src/notifications/copy-composer.ts +95 -0
- package/src/notifications/decision-engine.ts +35 -0
- package/src/notifications/signal.ts +16 -0
- package/src/oauth/seed-providers.ts +2 -1
- package/src/permissions/checker.ts +36 -4
- package/src/permissions/defaults.ts +4 -4
- package/src/permissions/permission-mode-store.ts +180 -0
- package/src/permissions/permission-mode.ts +31 -0
- package/src/permissions/workspace-policy.ts +10 -1
- package/src/playbooks/playbook-compiler.ts +19 -18
- package/src/playbooks/types.ts +4 -3
- package/src/prompts/system-prompt.ts +62 -36
- package/src/prompts/templates/BOOTSTRAP-REFERENCE.md +100 -0
- package/src/prompts/templates/BOOTSTRAP.md +70 -165
- package/src/prompts/templates/HEARTBEAT.md +3 -1
- package/src/prompts/templates/SOUL.md +25 -4
- package/src/prompts/templates/UPDATES.md +8 -0
- package/src/providers/anthropic/client.ts +136 -220
- 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/route-policy.ts +30 -0
- package/src/runtime/guardian-reply-router.ts +5 -1
- package/src/runtime/http-server.ts +55 -5
- package/src/runtime/http-types.ts +12 -1
- package/src/runtime/middleware/auth.ts +20 -0
- package/src/runtime/migrations/vbundle-builder.ts +389 -3
- package/src/runtime/migrations/vbundle-importer.ts +8 -6
- package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +378 -0
- package/src/runtime/routes/app-management-routes.ts +1 -11
- package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +26 -0
- package/src/runtime/routes/archive-utils.ts +29 -0
- package/src/runtime/routes/attachment-routes.test.ts +106 -0
- package/src/runtime/routes/attachment-routes.ts +106 -16
- package/src/runtime/routes/avatar-routes.ts +2 -9
- package/src/runtime/routes/brain-graph-routes.ts +21 -22
- package/src/runtime/routes/btw-routes.ts +22 -1
- package/src/runtime/routes/conversation-analysis-routes.ts +173 -0
- package/src/runtime/routes/conversation-management-routes.ts +3 -14
- package/src/runtime/routes/conversation-query-routes.ts +49 -3
- package/src/runtime/routes/conversation-routes.ts +264 -44
- 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/heartbeat-routes.ts +4 -10
- package/src/runtime/routes/identity-routes.ts +53 -18
- package/src/runtime/routes/inbound-message-handler.ts +19 -0
- 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/llm-context-normalization.ts +14 -10
- package/src/runtime/routes/log-export-routes.ts +23 -275
- package/src/runtime/routes/memory-item-routes.test.ts +170 -247
- package/src/runtime/routes/memory-item-routes.ts +341 -388
- package/src/runtime/routes/migration-routes.ts +18 -7
- package/src/runtime/routes/profiler-routes.ts +350 -0
- package/src/runtime/routes/schedule-routes.ts +28 -11
- package/src/runtime/routes/settings-routes.ts +95 -8
- package/src/runtime/routes/skills-routes.ts +103 -37
- package/src/runtime/routes/subagents-routes.ts +28 -7
- package/src/runtime/routes/user-route-dispatcher.ts +223 -0
- package/src/runtime/routes/user-routes.ts +41 -0
- package/src/runtime/routes/work-items-routes.test.ts +2 -6
- package/src/runtime/routes/workspace-routes.ts +0 -1
- package/src/schedule/schedule-store.ts +30 -0
- package/src/schedule/scheduler.ts +52 -18
- package/src/security/oauth2.ts +1 -1
- 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 +25 -16
- package/src/skills/clawhub.ts +134 -154
- package/src/skills/install-meta.ts +208 -0
- package/src/skills/managed-store.ts +29 -18
- package/src/skills/skill-memory.ts +12 -229
- package/src/skills/skillssh-registry.ts +19 -17
- package/src/subagent/index.ts +13 -3
- package/src/subagent/manager.ts +308 -29
- package/src/subagent/types.ts +68 -0
- package/src/tasks/task-runner.ts +7 -5
- package/src/telemetry/usage-telemetry-reporter.test.ts +3 -5
- package/src/tools/apps/executors.ts +29 -4
- package/src/tools/browser/runtime-check.ts +3 -1
- package/src/tools/filesystem/list.ts +93 -0
- package/src/tools/memory/register.ts +63 -46
- package/src/tools/permission-checker.ts +85 -1
- package/src/tools/registry.ts +4 -0
- package/src/tools/schedule/create.ts +3 -0
- package/src/tools/schedule/list.ts +1 -0
- package/src/tools/schedule/update.ts +6 -0
- package/src/tools/shared/filesystem/errors.ts +5 -0
- package/src/tools/shared/filesystem/file-ops-service.ts +90 -2
- package/src/tools/shared/filesystem/image-read.ts +22 -85
- package/src/tools/shared/filesystem/types.ts +17 -0
- package/src/tools/shared/shell-output.ts +31 -2
- package/src/tools/subagent/abort.ts +12 -2
- package/src/tools/subagent/message.ts +9 -2
- package/src/tools/subagent/notify-parent.ts +79 -0
- package/src/tools/subagent/read.ts +29 -8
- package/src/tools/subagent/resolve.ts +21 -0
- package/src/tools/subagent/spawn.ts +2 -0
- package/src/tools/subagent/status.ts +11 -1
- package/src/tools/system/avatar-generator.ts +3 -3
- package/src/tools/system/register.ts +23 -0
- package/src/tools/system/set-permission-mode.ts +103 -0
- package/src/tools/terminal/parser.ts +30 -5
- package/src/tools/terminal/safe-env.ts +17 -1
- package/src/tools/tool-manifest.ts +9 -3
- package/src/tools/types.ts +2 -0
- package/src/util/browser.ts +25 -10
- package/src/util/bun-runtime.ts +172 -0
- package/src/util/logger.ts +1 -1
- package/src/util/platform.ts +50 -17
- package/src/watcher/providers/outlook-calendar.ts +343 -0
- package/src/watcher/providers/outlook.ts +198 -0
- package/src/workspace/migrations/023-move-config-files-to-workspace.ts +2 -2
- package/src/workspace/migrations/024-move-runtime-files-to-workspace.ts +2 -2
- 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/028-recover-conversations-from-disk-view.ts +270 -0
- package/src/workspace/migrations/029-seed-pkb.ts +84 -0
- package/src/workspace/migrations/registry.ts +10 -0
- package/src/workspace/top-level-renderer.ts +5 -9
- package/src/__tests__/cli-memory.test.ts +0 -372
- package/src/__tests__/clipboard.test.ts +0 -88
- 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/cli/cli-memory.ts +0 -176
- 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 -753
- package/src/memory/job-handlers/extraction.ts +0 -40
- package/src/memory/job-handlers/journal-carry-forward.test.ts +0 -355
- 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 -1592
- package/src/memory/retriever.ts +0 -1331
- package/src/memory/search/formatting.test.ts +0 -140
- package/src/memory/search/formatting.ts +0 -262
- package/src/memory/search/mmr.ts +0 -139
- 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 -154
- package/src/tools/memory/definitions.ts +0 -69
- package/src/tools/memory/handlers.test.ts +0 -562
- package/src/tools/memory/handlers.ts +0 -434
- package/src/util/clipboard.ts +0 -34
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
|
|
4
|
+
import { getConfig } from "../config/loader.js";
|
|
5
|
+
import type { Speed } from "../config/schemas/inference.js";
|
|
6
|
+
import { bootstrapConversation } from "../memory/conversation-bootstrap.js";
|
|
7
|
+
import { getLogger } from "../util/logger.js";
|
|
8
|
+
import { getWorkspaceDir } from "../util/platform.js";
|
|
9
|
+
import { stripCommentLines } from "../util/strip-comment-lines.js";
|
|
10
|
+
|
|
11
|
+
const log = getLogger("filing-service");
|
|
12
|
+
|
|
13
|
+
const FILING_TIMEOUT_MS = 15 * 60 * 1000; // 15 minutes
|
|
14
|
+
|
|
15
|
+
const FILING_PROMPT_TEMPLATE = `You are running a periodic knowledge base filing job. This is a background maintenance task.
|
|
16
|
+
|
|
17
|
+
## Part 1: File the buffer
|
|
18
|
+
|
|
19
|
+
Read \`pkb/buffer.md\`. For each item in the buffer:
|
|
20
|
+
1. Determine which topic file it belongs in. Check \`pkb/INDEX.md\` to see what topic files exist.
|
|
21
|
+
2. Read the target topic file, then append or integrate the new fact.
|
|
22
|
+
3. If the fact is important enough to always be in context, add it to \`pkb/essentials.md\` instead.
|
|
23
|
+
4. If the fact is a commitment, follow-up, or active project, add it to \`pkb/threads.md\`.
|
|
24
|
+
5. If no existing topic file fits, create a new one and update \`pkb/INDEX.md\`.
|
|
25
|
+
|
|
26
|
+
After all items are filed, clear the processed items from \`pkb/buffer.md\` (leave the file empty, don't delete it).
|
|
27
|
+
|
|
28
|
+
## Part 2: Nest
|
|
29
|
+
|
|
30
|
+
Pick 1-2 topic files from your knowledge base and review them:
|
|
31
|
+
- Is the information still accurate and up to date?
|
|
32
|
+
- Are there duplicates that should be consolidated?
|
|
33
|
+
- Is anything important enough to promote to \`pkb/essentials.md\`?
|
|
34
|
+
- Is anything in \`pkb/essentials.md\` that's no longer essential? Demote it to a topic file.
|
|
35
|
+
- Are any threads in \`pkb/threads.md\` completed or stale? Remove them.
|
|
36
|
+
- Is any file getting too long? Consider splitting it.
|
|
37
|
+
- Should any topic file be restructured for clarity?
|
|
38
|
+
|
|
39
|
+
Make improvements as you see fit. This is your knowledge base — keep it sharp.`;
|
|
40
|
+
|
|
41
|
+
export interface FilingDeps {
|
|
42
|
+
processMessage: (
|
|
43
|
+
conversationId: string,
|
|
44
|
+
content: string,
|
|
45
|
+
options?: { speed?: Speed },
|
|
46
|
+
) => Promise<{ messageId: string }>;
|
|
47
|
+
onConversationCreated?: (info: {
|
|
48
|
+
conversationId: string;
|
|
49
|
+
title: string;
|
|
50
|
+
}) => void;
|
|
51
|
+
getCurrentHour?: () => number;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export class FilingService {
|
|
55
|
+
private readonly deps: FilingDeps;
|
|
56
|
+
private timer: ReturnType<typeof setInterval> | null = null;
|
|
57
|
+
private activeRun: Promise<void> | null = null;
|
|
58
|
+
private _lastRunAt: number | null = null;
|
|
59
|
+
private _nextRunAt: number | null = null;
|
|
60
|
+
|
|
61
|
+
constructor(deps: FilingDeps) {
|
|
62
|
+
this.deps = deps;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
get lastRunAt(): number | null {
|
|
66
|
+
return this._lastRunAt;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
get nextRunAt(): number | null {
|
|
70
|
+
return this._nextRunAt;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
start(): void {
|
|
74
|
+
const config = getConfig().filing;
|
|
75
|
+
if (!config.enabled) {
|
|
76
|
+
log.info("Filing service disabled by config");
|
|
77
|
+
this._nextRunAt = null;
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
if (this.timer) return;
|
|
81
|
+
|
|
82
|
+
log.info({ intervalMs: config.intervalMs }, "Filing service started");
|
|
83
|
+
this.scheduleNextRun(config.intervalMs);
|
|
84
|
+
this.timer = setInterval(() => {
|
|
85
|
+
this.runOnce().catch((err) => {
|
|
86
|
+
log.error({ err }, "Filing runOnce failed");
|
|
87
|
+
});
|
|
88
|
+
}, config.intervalMs);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
reconfigure(): void {
|
|
92
|
+
if (this.timer) {
|
|
93
|
+
clearInterval(this.timer);
|
|
94
|
+
this.timer = null;
|
|
95
|
+
}
|
|
96
|
+
this._nextRunAt = null;
|
|
97
|
+
this.start();
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
async stop(): Promise<void> {
|
|
101
|
+
if (this.timer) {
|
|
102
|
+
clearInterval(this.timer);
|
|
103
|
+
this.timer = null;
|
|
104
|
+
}
|
|
105
|
+
this._nextRunAt = null;
|
|
106
|
+
if (this.activeRun) {
|
|
107
|
+
let timerId: ReturnType<typeof setTimeout>;
|
|
108
|
+
const timeout = new Promise<void>((resolve) => {
|
|
109
|
+
timerId = setTimeout(resolve, 5_000);
|
|
110
|
+
});
|
|
111
|
+
await Promise.race([this.activeRun, timeout]);
|
|
112
|
+
clearTimeout(timerId!);
|
|
113
|
+
}
|
|
114
|
+
log.info("Filing service stopped");
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
async runOnce({ force = false }: { force?: boolean } = {}): Promise<boolean> {
|
|
118
|
+
const config = getConfig().filing;
|
|
119
|
+
if (!force && !config.enabled) return false;
|
|
120
|
+
|
|
121
|
+
if (
|
|
122
|
+
!force &&
|
|
123
|
+
config.activeHoursStart != null &&
|
|
124
|
+
config.activeHoursEnd != null
|
|
125
|
+
) {
|
|
126
|
+
const hour = this.deps.getCurrentHour?.() ?? new Date().getHours();
|
|
127
|
+
if (
|
|
128
|
+
!isWithinActiveHours(
|
|
129
|
+
hour,
|
|
130
|
+
config.activeHoursStart,
|
|
131
|
+
config.activeHoursEnd,
|
|
132
|
+
)
|
|
133
|
+
) {
|
|
134
|
+
log.debug("Outside active hours, skipping filing");
|
|
135
|
+
this.scheduleNextRun(config.intervalMs);
|
|
136
|
+
return false;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (this.activeRun) {
|
|
141
|
+
log.debug("Previous filing run still active, skipping");
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Skip if buffer is empty — no work to do
|
|
146
|
+
if (!force && !this.hasBufferContent()) {
|
|
147
|
+
log.debug("Buffer is empty, skipping filing");
|
|
148
|
+
this.scheduleNextRun(config.intervalMs);
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const run = this.executeRun();
|
|
153
|
+
this.activeRun = run;
|
|
154
|
+
try {
|
|
155
|
+
await Promise.race([
|
|
156
|
+
run,
|
|
157
|
+
new Promise<never>((_, reject) =>
|
|
158
|
+
setTimeout(
|
|
159
|
+
() => reject(new Error("Filing execution timed out")),
|
|
160
|
+
FILING_TIMEOUT_MS,
|
|
161
|
+
),
|
|
162
|
+
),
|
|
163
|
+
]);
|
|
164
|
+
} finally {
|
|
165
|
+
this.activeRun = null;
|
|
166
|
+
this._lastRunAt = Date.now();
|
|
167
|
+
this.scheduleNextRun(getConfig().filing.intervalMs);
|
|
168
|
+
}
|
|
169
|
+
return true;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
private scheduleNextRun(intervalMs: number): void {
|
|
173
|
+
this._nextRunAt = Date.now() + intervalMs;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
private hasBufferContent(): boolean {
|
|
177
|
+
const bufferPath = join(getWorkspaceDir(), "pkb", "buffer.md");
|
|
178
|
+
if (!existsSync(bufferPath)) return false;
|
|
179
|
+
try {
|
|
180
|
+
const content = stripCommentLines(
|
|
181
|
+
readFileSync(bufferPath, "utf-8"),
|
|
182
|
+
).trim();
|
|
183
|
+
return content.length > 0;
|
|
184
|
+
} catch {
|
|
185
|
+
return false;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
private async executeRun(): Promise<void> {
|
|
190
|
+
log.info("Running filing job");
|
|
191
|
+
|
|
192
|
+
try {
|
|
193
|
+
const config = getConfig().filing;
|
|
194
|
+
|
|
195
|
+
const conversation = bootstrapConversation({
|
|
196
|
+
conversationType: "background",
|
|
197
|
+
source: "filing",
|
|
198
|
+
groupId: "system:background",
|
|
199
|
+
origin: "filing",
|
|
200
|
+
systemHint: "Filing",
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
this.deps.onConversationCreated?.({
|
|
204
|
+
conversationId: conversation.id,
|
|
205
|
+
title: "Filing",
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
await this.deps.processMessage(conversation.id, FILING_PROMPT_TEMPLATE, {
|
|
209
|
+
speed: config.speed,
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
log.info({ conversationId: conversation.id }, "Filing job completed");
|
|
213
|
+
} catch (err) {
|
|
214
|
+
log.error({ err }, "Filing job failed");
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
function isWithinActiveHours(
|
|
220
|
+
hour: number,
|
|
221
|
+
start: number,
|
|
222
|
+
end: number,
|
|
223
|
+
): boolean {
|
|
224
|
+
if (start <= end) {
|
|
225
|
+
return hour >= start && hour < end;
|
|
226
|
+
}
|
|
227
|
+
return hour >= start || hour < end;
|
|
228
|
+
}
|
|
@@ -1,18 +1,69 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
|
|
1
4
|
import { getConfig } from "../config/loader.js";
|
|
2
5
|
import type { Speed } from "../config/schemas/inference.js";
|
|
3
6
|
import type { HeartbeatAlert } from "../daemon/message-protocol.js";
|
|
4
7
|
import { bootstrapConversation } from "../memory/conversation-bootstrap.js";
|
|
8
|
+
import { isTemplateContent } from "../prompts/system-prompt.js";
|
|
5
9
|
import { readTextFileSync } from "../util/fs.js";
|
|
6
10
|
import { getLogger } from "../util/logger.js";
|
|
7
|
-
import { getWorkspacePromptPath } from "../util/platform.js";
|
|
11
|
+
import { getWorkspaceDir, getWorkspacePromptPath } from "../util/platform.js";
|
|
8
12
|
import { stripCommentLines } from "../util/strip-comment-lines.js";
|
|
9
13
|
|
|
10
14
|
const log = getLogger("heartbeat-check");
|
|
11
15
|
|
|
12
16
|
const DEFAULT_CHECKLIST = `- Check in with yourself. Read NOW.md. Is it still accurate? Update it if anything has changed.
|
|
13
17
|
- Think about your user. Is there anything from recent conversations you should follow up on? Anything you noticed that you should bring up?
|
|
18
|
+
- Have a thought. Think about something your user would find interesting or worth talking about. A follow-up, a connection you made, something you came across. Give them a reason to open a conversation.
|
|
14
19
|
- Check if there's anything on the horizon — events, deadlines, things they mentioned wanting to do.
|
|
15
|
-
- If you have a thought worth sharing, send it. A follow-up, a useful find, a check-in. Not every beat, but when it feels right
|
|
20
|
+
- If you have a thought worth sharing, send it. A follow-up, a useful find, a check-in. Not every beat, but when it feels right.
|
|
21
|
+
- If something has happened since your last journal entry, write one. Even a few sentences. The journal is how future-you stays connected.`;
|
|
22
|
+
|
|
23
|
+
const REENGAGEMENT_COOLDOWN_MS = 18 * 60 * 60 * 1000; // 18 hours
|
|
24
|
+
const HEARTBEAT_TIMEOUT_MS = 30 * 60 * 1000; // 30 minutes
|
|
25
|
+
|
|
26
|
+
/** @internal Exported for testing. */
|
|
27
|
+
export function isShallowProfile(): boolean {
|
|
28
|
+
try {
|
|
29
|
+
const identityPath = getWorkspacePromptPath("IDENTITY.md");
|
|
30
|
+
const userPath = getWorkspacePromptPath("USER.md");
|
|
31
|
+
const rawIdentity = readTextFileSync(identityPath);
|
|
32
|
+
const rawUser = readTextFileSync(userPath);
|
|
33
|
+
const identity = rawIdentity != null ? stripCommentLines(rawIdentity) : null;
|
|
34
|
+
const user = rawUser != null ? stripCommentLines(rawUser) : null;
|
|
35
|
+
return (
|
|
36
|
+
isTemplateContent(identity, "IDENTITY.md") &&
|
|
37
|
+
isTemplateContent(user, "USER.md")
|
|
38
|
+
);
|
|
39
|
+
} catch {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function getReengagementTimestampPath(): string {
|
|
45
|
+
return join(getWorkspaceDir(), ".reengagement-ts");
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function isReengagementCooldownElapsed(): boolean {
|
|
49
|
+
const tsPath = getReengagementTimestampPath();
|
|
50
|
+
if (!existsSync(tsPath)) return true;
|
|
51
|
+
try {
|
|
52
|
+
const lastTs = parseInt(readFileSync(tsPath, "utf-8").trim(), 10);
|
|
53
|
+
if (isNaN(lastTs)) return true;
|
|
54
|
+
return Date.now() - lastTs >= REENGAGEMENT_COOLDOWN_MS;
|
|
55
|
+
} catch {
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function recordReengagementTimestamp(): void {
|
|
61
|
+
try {
|
|
62
|
+
writeFileSync(getReengagementTimestampPath(), Date.now().toString());
|
|
63
|
+
} catch {
|
|
64
|
+
// Best-effort; don't block the heartbeat.
|
|
65
|
+
}
|
|
66
|
+
}
|
|
16
67
|
|
|
17
68
|
export interface HeartbeatDeps {
|
|
18
69
|
processMessage: (
|
|
@@ -141,6 +192,7 @@ export class HeartbeatService {
|
|
|
141
192
|
},
|
|
142
193
|
"Outside active hours, skipping",
|
|
143
194
|
);
|
|
195
|
+
this.scheduleNextRun(config.intervalMs);
|
|
144
196
|
return false;
|
|
145
197
|
}
|
|
146
198
|
}
|
|
@@ -153,10 +205,34 @@ export class HeartbeatService {
|
|
|
153
205
|
|
|
154
206
|
const run = this.executeRun();
|
|
155
207
|
this.activeRun = run;
|
|
208
|
+
// Clear activeRun once executeRun finishes. On timeout, runOnce releases
|
|
209
|
+
// activeRun separately (see catch block below) so future runs aren't
|
|
210
|
+
// permanently blocked. The .finally() handler still serves as the
|
|
211
|
+
// normal-completion cleanup path and uses an identity guard to avoid
|
|
212
|
+
// clearing a different run's activeRun.
|
|
213
|
+
run.finally(() => {
|
|
214
|
+
if (this.activeRun === run) {
|
|
215
|
+
this.activeRun = null;
|
|
216
|
+
}
|
|
217
|
+
}).catch(() => {}); // Suppress unhandled rejection if executeRun rejects
|
|
218
|
+
|
|
219
|
+
let timerId: ReturnType<typeof setTimeout> | undefined;
|
|
156
220
|
try {
|
|
157
|
-
|
|
158
|
-
|
|
221
|
+
const timeout = new Promise<never>((_, reject) => {
|
|
222
|
+
timerId = setTimeout(
|
|
223
|
+
() => reject(new Error("Heartbeat execution timed out")),
|
|
224
|
+
HEARTBEAT_TIMEOUT_MS,
|
|
225
|
+
);
|
|
226
|
+
});
|
|
227
|
+
timeout.catch(() => {}); // Prevent unhandled rejection if run resolves first
|
|
228
|
+
await Promise.race([run, timeout]);
|
|
229
|
+
} catch (err) {
|
|
230
|
+
log.warn({ err }, "Heartbeat run timed out");
|
|
231
|
+
// Release activeRun so the overlap guard doesn't permanently block
|
|
232
|
+
// future heartbeat runs when executeRun hangs past the timeout.
|
|
159
233
|
this.activeRun = null;
|
|
234
|
+
} finally {
|
|
235
|
+
clearTimeout(timerId);
|
|
160
236
|
this._lastRunAt = Date.now();
|
|
161
237
|
this.scheduleNextRun(getConfig().heartbeat.intervalMs);
|
|
162
238
|
}
|
|
@@ -173,11 +249,12 @@ export class HeartbeatService {
|
|
|
173
249
|
try {
|
|
174
250
|
const config = getConfig().heartbeat;
|
|
175
251
|
const checklist = this.readChecklist();
|
|
176
|
-
const prompt = this.buildPrompt(checklist);
|
|
252
|
+
const { prompt, includedReengagement } = this.buildPrompt(checklist);
|
|
177
253
|
|
|
178
254
|
const conversation = bootstrapConversation({
|
|
179
255
|
conversationType: "background",
|
|
180
256
|
source: "heartbeat",
|
|
257
|
+
groupId: "system:background",
|
|
181
258
|
origin: "heartbeat",
|
|
182
259
|
systemHint: "Heartbeat",
|
|
183
260
|
});
|
|
@@ -190,6 +267,11 @@ export class HeartbeatService {
|
|
|
190
267
|
await this.deps.processMessage(conversation.id, prompt, {
|
|
191
268
|
speed: config.speed,
|
|
192
269
|
});
|
|
270
|
+
|
|
271
|
+
if (includedReengagement) {
|
|
272
|
+
recordReengagementTimestamp();
|
|
273
|
+
}
|
|
274
|
+
|
|
193
275
|
log.info({ conversationId: conversation.id }, "Heartbeat completed");
|
|
194
276
|
} catch (err) {
|
|
195
277
|
log.error({ err }, "Heartbeat failed");
|
|
@@ -213,8 +295,8 @@ export class HeartbeatService {
|
|
|
213
295
|
}
|
|
214
296
|
|
|
215
297
|
/** @internal Exposed for testing. */
|
|
216
|
-
buildPrompt(checklist: string): string {
|
|
217
|
-
|
|
298
|
+
buildPrompt(checklist: string): { prompt: string; includedReengagement: boolean } {
|
|
299
|
+
let prompt = `You are running a periodic heartbeat check. Review the following checklist and take any necessary actions.
|
|
218
300
|
|
|
219
301
|
<heartbeat-checklist>
|
|
220
302
|
${checklist}
|
|
@@ -225,6 +307,14 @@ After completing your review, end your response with one of:
|
|
|
225
307
|
- HEARTBEAT_OK — if everything looks good, no action needed
|
|
226
308
|
- HEARTBEAT_ALERT — if you found issues that need attention (describe them before this marker)
|
|
227
309
|
</heartbeat-disposition>`;
|
|
310
|
+
|
|
311
|
+
let includedReengagement = false;
|
|
312
|
+
if (isShallowProfile() && isReengagementCooldownElapsed()) {
|
|
313
|
+
includedReengagement = true;
|
|
314
|
+
prompt += `\n\n<relationship-depth>\nYou don't know much about this person yet — their profile is still sparse. If the moment feels right during this beat, gently invite them to share something about themselves. Not an interrogation — something natural like "I realized I don't actually know much about what you do. Fill me in sometime?" Only do this occasionally, not every beat. If they engage, save what you learn.\n</relationship-depth>`;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
return { prompt, includedReengagement };
|
|
228
318
|
}
|
|
229
319
|
}
|
|
230
320
|
|
package/src/hooks/cli.ts
CHANGED
|
@@ -20,7 +20,7 @@ export function registerHooksCommand(program: Command): void {
|
|
|
20
20
|
Hooks are user-installed scripts that run in response to assistant lifecycle
|
|
21
21
|
events (e.g. tool invocations, message sends). Each hook is a directory
|
|
22
22
|
containing a hook.json manifest and a script file. Hooks are stored in
|
|
23
|
-
|
|
23
|
+
$VELLUM_WORKSPACE_DIR/hooks/ and must be explicitly enabled after installation.
|
|
24
24
|
|
|
25
25
|
Examples:
|
|
26
26
|
$ assistant hooks list
|
|
@@ -136,7 +136,7 @@ Arguments:
|
|
|
136
136
|
The manifest must have name, script, description, version, and at
|
|
137
137
|
least one valid event.
|
|
138
138
|
|
|
139
|
-
Copies the hook directory into
|
|
139
|
+
Copies the hook directory into $VELLUM_WORKSPACE_DIR/hooks/<name>/ and registers it as
|
|
140
140
|
disabled by default. Run 'assistant hooks enable <name>' to activate.
|
|
141
141
|
|
|
142
142
|
Examples:
|
package/src/hooks/runner.ts
CHANGED
|
@@ -1,42 +1,19 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
2
|
import { homedir } from "node:os";
|
|
3
|
-
import {
|
|
3
|
+
import { extname, join } from "node:path";
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { ensureBun } from "../util/bun-runtime.js";
|
|
6
6
|
import { getWorkspaceDir } from "../util/platform.js";
|
|
7
7
|
import { getHookSettings } from "./config.js";
|
|
8
8
|
import type { DiscoveredHook, HookEventData } from "./types.js";
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
* daemon is a `bun build --compile` binary, `process.execPath` points to the
|
|
14
|
-
* compiled binary itself -- spawning it with `['run', script]` would re-launch
|
|
15
|
-
* the daemon. In that case we locate bun via PATH or at `~/.bun/bin/bun`.
|
|
16
|
-
*/
|
|
17
|
-
function resolveBunPath(): string {
|
|
18
|
-
const execBasename = basename(process.execPath);
|
|
19
|
-
if (execBasename === "bun" || execBasename === "bun.exe") {
|
|
20
|
-
return process.execPath;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
// Compiled-binary mode -- find a standalone bun runtime.
|
|
24
|
-
const found = Bun.which("bun");
|
|
25
|
-
if (found) return found;
|
|
26
|
-
|
|
27
|
-
const fallback = join(homedir(), ".bun", "bin", "bun");
|
|
28
|
-
if (pathExists(fallback)) return fallback;
|
|
29
|
-
|
|
30
|
-
throw new Error(
|
|
31
|
-
"Cannot find a bun runtime to execute .ts hooks. " +
|
|
32
|
-
"Install bun (https://bun.sh) or ensure it is on your PATH.",
|
|
33
|
-
);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function getSpawnArgs(scriptPath: string): { command: string; args: string[] } {
|
|
10
|
+
async function getSpawnArgs(
|
|
11
|
+
scriptPath: string,
|
|
12
|
+
): Promise<{ command: string; args: string[] }> {
|
|
37
13
|
const ext = extname(scriptPath);
|
|
38
14
|
if (ext === ".ts") {
|
|
39
|
-
|
|
15
|
+
const bunPath = await ensureBun();
|
|
16
|
+
return { command: bunPath, args: ["run", scriptPath] };
|
|
40
17
|
}
|
|
41
18
|
return { command: scriptPath, args: [] };
|
|
42
19
|
}
|
|
@@ -54,15 +31,15 @@ export async function runHookScript(
|
|
|
54
31
|
): Promise<HookRunResult> {
|
|
55
32
|
const timeoutMs = options?.timeoutMs ?? 5000;
|
|
56
33
|
|
|
34
|
+
let spawnResult: { command: string; args: string[] };
|
|
35
|
+
try {
|
|
36
|
+
spawnResult = await getSpawnArgs(hook.scriptPath);
|
|
37
|
+
} catch (err) {
|
|
38
|
+
return { exitCode: null, stdout: "", stderr: (err as Error).message };
|
|
39
|
+
}
|
|
40
|
+
const { command, args } = spawnResult;
|
|
41
|
+
|
|
57
42
|
return new Promise<HookRunResult>((resolve) => {
|
|
58
|
-
let spawnResult: { command: string; args: string[] };
|
|
59
|
-
try {
|
|
60
|
-
spawnResult = getSpawnArgs(hook.scriptPath);
|
|
61
|
-
} catch (err) {
|
|
62
|
-
resolve({ exitCode: null, stdout: "", stderr: (err as Error).message });
|
|
63
|
-
return;
|
|
64
|
-
}
|
|
65
|
-
const { command, args } = spawnResult;
|
|
66
43
|
const child = spawn(command, args, {
|
|
67
44
|
cwd: hook.dir,
|
|
68
45
|
env: {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Platform callback route registration for
|
|
2
|
+
* Platform callback route registration for platform-managed deployments.
|
|
3
3
|
*
|
|
4
|
-
* When the assistant daemon runs
|
|
4
|
+
* When the assistant daemon runs as a platform-managed instance (IS_PLATFORM=true)
|
|
5
5
|
* with a configured VELLUM_PLATFORM_URL and PLATFORM_ASSISTANT_ID, external
|
|
6
6
|
* service callbacks (Twilio webhooks, OAuth redirects, Telegram webhooks, etc.)
|
|
7
7
|
* must route through the platform's gateway proxy instead of hitting the
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*
|
|
10
10
|
* This module registers callback routes with the platform's internal
|
|
11
11
|
* gateway endpoint so the platform knows how to forward inbound provider
|
|
12
|
-
* webhooks to the correct
|
|
12
|
+
* webhooks to the correct platform-managed assistant instance.
|
|
13
13
|
*
|
|
14
14
|
* The platform endpoint is:
|
|
15
15
|
* POST {VELLUM_PLATFORM_URL}/v1/internal/gateway/callback-routes/register/
|
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
getPlatformBaseUrl,
|
|
24
24
|
getPlatformInternalApiKey,
|
|
25
25
|
} from "../config/env.js";
|
|
26
|
-
import {
|
|
26
|
+
import { getIsPlatform } from "../config/env-registry.js";
|
|
27
27
|
import { credentialKey } from "../security/credential-key.js";
|
|
28
28
|
import { getSecureKeyAsync } from "../security/secure-keys.js";
|
|
29
29
|
import { getLogger } from "../util/logger.js";
|
|
@@ -31,7 +31,7 @@ import { getLogger } from "../util/logger.js";
|
|
|
31
31
|
const log = getLogger("platform-callback-registration");
|
|
32
32
|
|
|
33
33
|
export interface PlatformCallbackRegistrationContext {
|
|
34
|
-
|
|
34
|
+
isPlatform: boolean;
|
|
35
35
|
platformBaseUrl: string;
|
|
36
36
|
assistantId: string;
|
|
37
37
|
hasInternalApiKey: boolean;
|
|
@@ -42,21 +42,21 @@ export interface PlatformCallbackRegistrationContext {
|
|
|
42
42
|
|
|
43
43
|
/**
|
|
44
44
|
* Whether the daemon should register callback routes with the platform.
|
|
45
|
-
* True when
|
|
45
|
+
* True when IS_PLATFORM, VELLUM_PLATFORM_URL, and PLATFORM_ASSISTANT_ID
|
|
46
46
|
* are all set. Intentionally does **not** require the managed proxy API key
|
|
47
47
|
* so that callback-only flows (OAuth transport, Telegram/Twilio callback
|
|
48
48
|
* registration) work during partial bootstrap before the key is injected.
|
|
49
49
|
*/
|
|
50
50
|
export function shouldUsePlatformCallbacks(): boolean {
|
|
51
51
|
return (
|
|
52
|
-
|
|
52
|
+
getIsPlatform() &&
|
|
53
53
|
!!getPlatformBaseUrl() &&
|
|
54
54
|
!!getPlatformAssistantId()
|
|
55
55
|
);
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
export async function resolvePlatformCallbackRegistrationContext(): Promise<PlatformCallbackRegistrationContext> {
|
|
59
|
-
const
|
|
59
|
+
const platform = getIsPlatform();
|
|
60
60
|
const [storedBaseUrlRaw, storedAssistantIdRaw, storedAssistantApiKeyRaw] =
|
|
61
61
|
await Promise.all([
|
|
62
62
|
getSecureKeyAsync(credentialKey("vellum", "platform_base_url")),
|
|
@@ -80,14 +80,14 @@ export async function resolvePlatformCallbackRegistrationContext(): Promise<Plat
|
|
|
80
80
|
: null;
|
|
81
81
|
|
|
82
82
|
return {
|
|
83
|
-
|
|
83
|
+
isPlatform: platform,
|
|
84
84
|
platformBaseUrl,
|
|
85
85
|
assistantId,
|
|
86
86
|
hasInternalApiKey: internalApiKey.length > 0,
|
|
87
87
|
hasAssistantApiKey: assistantApiKey.length > 0,
|
|
88
88
|
authHeader,
|
|
89
89
|
enabled:
|
|
90
|
-
|
|
90
|
+
platform &&
|
|
91
91
|
platformBaseUrl.length > 0 &&
|
|
92
92
|
assistantId.length > 0 &&
|
|
93
93
|
authHeader !== null,
|
|
@@ -119,7 +119,7 @@ export async function registerCallbackRoute(
|
|
|
119
119
|
const context = await resolvePlatformCallbackRegistrationContext();
|
|
120
120
|
if (!context.enabled || !context.authHeader) {
|
|
121
121
|
throw new Error(
|
|
122
|
-
"Platform callbacks not available — missing
|
|
122
|
+
"Platform callbacks not available — missing platform registration context",
|
|
123
123
|
);
|
|
124
124
|
}
|
|
125
125
|
|
|
@@ -166,7 +166,7 @@ export async function registerCallbackRoute(
|
|
|
166
166
|
}
|
|
167
167
|
|
|
168
168
|
/**
|
|
169
|
-
* Resolve a callback URL, registering with the platform when
|
|
169
|
+
* Resolve a callback URL, registering with the platform when platform-managed.
|
|
170
170
|
*
|
|
171
171
|
* When platform callbacks are enabled, registers the route and returns the
|
|
172
172
|
* platform's stable callback URL (optionally with query parameters appended).
|
|
@@ -176,7 +176,7 @@ export async function registerCallbackRoute(
|
|
|
176
176
|
* string) rather than an eagerly-evaluated string. This is critical because
|
|
177
177
|
* the direct URL builders (e.g. `getTwilioVoiceWebhookUrl`) call
|
|
178
178
|
* `getPublicBaseUrl()` which throws when no public ingress URL is configured.
|
|
179
|
-
* In
|
|
179
|
+
* In platform-managed environments that rely solely on platform callbacks, the
|
|
180
180
|
* direct URL is never needed — deferring evaluation avoids the throw.
|
|
181
181
|
*
|
|
182
182
|
* @param directUrl - Lazy supplier for the direct callback URL.
|
|
@@ -204,7 +204,7 @@ export async function resolveCallbackUrl(
|
|
|
204
204
|
}
|
|
205
205
|
return url;
|
|
206
206
|
} catch (err) {
|
|
207
|
-
// In managed
|
|
207
|
+
// In platform-managed mode there is no local-ingress fallback and
|
|
208
208
|
// ngrok is not applicable. Surface a clear error so callers (and the
|
|
209
209
|
// user) understand this is a platform-side issue, not a tunnel problem.
|
|
210
210
|
const detail = err instanceof Error ? err.message : String(err);
|
package/src/mcp/client.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js"
|
|
|
5
5
|
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
6
6
|
|
|
7
7
|
import type { McpTransport } from "../config/schemas/mcp.js";
|
|
8
|
+
import { shouldUsePlatformCallbacks } from "../inbound/platform-callback-registration.js";
|
|
8
9
|
import { getSecureKeyAsync } from "../security/secure-keys.js";
|
|
9
10
|
import { getLogger } from "../util/logger.js";
|
|
10
11
|
import { McpOAuthProvider } from "./mcp-oauth-provider.js";
|
|
@@ -63,9 +64,14 @@ export class McpClient {
|
|
|
63
64
|
`mcp:${this.serverId}:tokens`,
|
|
64
65
|
);
|
|
65
66
|
if (cachedTokens) {
|
|
67
|
+
const callbackTransport = shouldUsePlatformCallbacks()
|
|
68
|
+
? "gateway"
|
|
69
|
+
: "loopback";
|
|
66
70
|
this.oauthProvider = new McpOAuthProvider(
|
|
67
71
|
this.serverId,
|
|
68
72
|
transportConfig.url,
|
|
73
|
+
/* interactive */ false,
|
|
74
|
+
callbackTransport,
|
|
69
75
|
);
|
|
70
76
|
}
|
|
71
77
|
}
|