@vellumai/assistant 0.7.2 → 0.8.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 +45 -29
- package/Dockerfile +1 -0
- package/__tests__/permissions/gateway-threshold-reader.test.ts +236 -9
- package/bun.lock +3 -0
- package/docs/architecture/memory.md +5 -2
- package/knip.json +1 -0
- package/node_modules/@vellumai/gateway-client/src/ipc-client.ts +13 -4
- package/node_modules/@vellumai/ipc-server-utils/bun.lock +24 -0
- package/node_modules/@vellumai/ipc-server-utils/package.json +18 -0
- package/node_modules/@vellumai/ipc-server-utils/src/index.ts +6 -0
- package/node_modules/@vellumai/ipc-server-utils/src/socket-watchdog.test.ts +430 -0
- package/node_modules/@vellumai/ipc-server-utils/src/socket-watchdog.ts +221 -0
- package/node_modules/@vellumai/ipc-server-utils/tsconfig.json +20 -0
- package/node_modules/@vellumai/skill-host-contracts/src/assistant-event.ts +0 -9
- package/node_modules/@vellumai/slack-text/src/index.test.ts +18 -35
- package/node_modules/@vellumai/slack-text/src/index.ts +2 -48
- package/openapi.yaml +470 -25
- package/package.json +3 -1
- package/src/__tests__/annotate-risk-options.test.ts +291 -0
- package/src/__tests__/app-control-flow.test.ts +21 -11
- package/src/__tests__/approval-cascade.test.ts +8 -16
- package/src/__tests__/approval-routes-http.test.ts +6 -0
- package/src/__tests__/assistant-event-hub.test.ts +48 -0
- package/src/__tests__/assistant-event.test.ts +0 -10
- package/src/__tests__/assistant-events-sse-hardening.test.ts +2 -7
- package/src/__tests__/assistant-feature-flags-integration.test.ts +18 -0
- package/src/__tests__/auto-analysis-end-to-end.test.ts +48 -0
- package/src/__tests__/background-workers-disk-pressure.test.ts +268 -0
- package/src/__tests__/call-constants.test.ts +10 -1
- package/src/__tests__/call-controller.test.ts +127 -0
- package/src/__tests__/call-conversation-messages.test.ts +8 -2
- package/src/__tests__/channel-inbound-disk-pressure.test.ts +537 -0
- package/src/__tests__/channel-readiness-service.test.ts +4 -2
- package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +58 -28
- package/src/__tests__/config-loader-backfill.test.ts +379 -0
- package/src/__tests__/config-loader-platform-defaults.test.ts +284 -1
- package/src/__tests__/config-schema.test.ts +1 -0
- package/src/__tests__/config-watcher-cleanup-throttle.test.ts +18 -9
- package/src/__tests__/config-watcher.test.ts +140 -69
- package/src/__tests__/context-search-agent-runner.test.ts +61 -3
- package/src/__tests__/context-search-conversations-source.test.ts +0 -24
- package/src/__tests__/context-search-fanout.test.ts +0 -1
- package/src/__tests__/context-search-memory-source.test.ts +6 -33
- package/src/__tests__/context-search-memory-v2-source.test.ts +0 -2
- package/src/__tests__/context-search-pkb-source.test.ts +12 -7
- package/src/__tests__/context-search-workspace-source.test.ts +0 -1
- package/src/__tests__/conversation-abort-tool-results.test.ts +1 -0
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +223 -0
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +1 -1
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -1
- package/src/__tests__/conversation-agent-loop.test.ts +457 -8
- package/src/__tests__/conversation-confirmation-signals.test.ts +5 -13
- package/src/__tests__/conversation-error.test.ts +150 -3
- package/src/__tests__/conversation-init.benchmark.test.ts +1 -1
- package/src/__tests__/conversation-process-callsite.test.ts +38 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +1 -0
- package/src/__tests__/conversation-runtime-assembly.test.ts +74 -0
- package/src/__tests__/conversation-slash-unknown.test.ts +1 -0
- package/src/__tests__/conversation-speed-override.test.ts +0 -3
- package/src/__tests__/conversation-store.test.ts +0 -18
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +170 -9
- package/src/__tests__/conversation-surfaces-app-control.test.ts +15 -4
- package/src/__tests__/conversation-surfaces-data-persist.test.ts +476 -0
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +61 -5
- package/src/__tests__/conversation-workspace-injection.test.ts +1 -1
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +1 -1
- package/src/__tests__/credentials-cli.test.ts +7 -0
- package/src/__tests__/cu-unified-flow.test.ts +176 -10
- package/src/__tests__/date-context.test.ts +164 -2
- package/src/__tests__/disk-pressure-guard.test.ts +262 -0
- package/src/__tests__/disk-pressure-lifecycle.test.ts +168 -0
- package/src/__tests__/disk-pressure-policy.test.ts +241 -0
- package/src/__tests__/disk-pressure-routes.test.ts +379 -0
- package/src/__tests__/disk-pressure-tools.test.ts +277 -0
- package/src/__tests__/disk-usage.test.ts +150 -0
- package/src/__tests__/events-client-registration.test.ts +52 -0
- package/src/__tests__/events-dev-bypass-actor.test.ts +162 -0
- package/src/__tests__/file-write-tool.test.ts +4 -10
- package/src/__tests__/filing-service.test.ts +2 -20
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +10 -26
- package/src/__tests__/heartbeat-disk-pressure.test.ts +183 -0
- package/src/__tests__/heartbeat-service.test.ts +260 -11
- package/src/__tests__/host-app-control-proxy.test.ts +195 -25
- package/src/__tests__/host-bash-proxy.test.ts +227 -34
- package/src/__tests__/host-bash-routes.test.ts +178 -13
- package/src/__tests__/host-cu-proxy.test.ts +210 -3
- package/src/__tests__/host-cu-routes-targeted.test.ts +141 -12
- package/src/__tests__/host-file-proxy-targeted.test.ts +48 -9
- package/src/__tests__/host-file-proxy.test.ts +268 -6
- package/src/__tests__/host-file-routes-targeted.test.ts +175 -17
- package/src/__tests__/host-transfer-proxy-targeted.test.ts +408 -59
- package/src/__tests__/host-transfer-routes-targeted.test.ts +232 -17
- package/src/__tests__/http-user-message-parity.test.ts +107 -1
- package/src/__tests__/injector-chain.test.ts +36 -16
- package/src/__tests__/injector-disk-pressure.test.ts +224 -0
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +10 -7
- package/src/__tests__/lifecycle-memory-v2-seed.test.ts +154 -67
- package/src/__tests__/managed-profile-guard.test.ts +18 -0
- package/src/__tests__/mcp-abort-signal.test.ts +130 -0
- package/src/__tests__/memory-admin-recall.test.ts +3 -11
- package/src/__tests__/memory-retrieval-pipeline.test.ts +22 -1
- package/src/__tests__/normalize-onboarding.test.ts +180 -0
- package/src/__tests__/notification-decision-fallback.test.ts +91 -0
- package/src/__tests__/notification-decision-strategy.test.ts +22 -0
- package/src/__tests__/oauth-cli.test.ts +121 -0
- package/src/__tests__/oauth-connect-routes.test.ts +316 -0
- package/src/__tests__/oauth-provider-seed-logos.test.ts +24 -2
- package/src/__tests__/onboarding-persona-write.test.ts +308 -0
- package/src/__tests__/openai-provider.test.ts +45 -8
- package/src/__tests__/persist-onboarding-artifacts.test.ts +44 -64
- package/src/__tests__/platform-callback-registration.test.ts +21 -4
- package/src/__tests__/platform.test.ts +2 -1
- package/src/__tests__/playbook-execution.test.ts +0 -43
- package/src/__tests__/plugin-tool-contribution.test.ts +47 -0
- package/src/__tests__/prechat-onboarding-contract.test.ts +214 -27
- package/src/__tests__/provider-tool-name.test.ts +23 -0
- package/src/__tests__/relay-server.test.ts +60 -5
- package/src/__tests__/runtime-events-sse.test.ts +4 -8
- package/src/__tests__/scheduler-disk-pressure.test.ts +148 -0
- package/src/__tests__/secret-ingress-http.test.ts +0 -1
- package/src/__tests__/secret-prompt-log-hygiene.test.ts +7 -5
- package/src/__tests__/secret-prompter-channel-fallback.test.ts +7 -5
- package/src/__tests__/secret-response-routing.test.ts +7 -5
- package/src/__tests__/server-history-render.test.ts +82 -0
- package/src/__tests__/skill-include-graph.test.ts +31 -0
- package/src/__tests__/skill-load-tool.test.ts +44 -16
- package/src/__tests__/skills.test.ts +39 -0
- package/src/__tests__/suggestion-routes.test.ts +46 -0
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +0 -42
- package/src/__tests__/tool-executor.test.ts +155 -0
- package/src/__tests__/twilio-validation.test.ts +2 -2
- package/src/__tests__/voice-session-bridge.test.ts +3 -0
- package/src/__tests__/workspace-migration-065-bump-stale-heartbeat-interval.test.ts +122 -0
- package/src/__tests__/workspace-migration-066-seed-heartbeat-callsite-cost-default.test.ts +285 -0
- package/src/__tests__/workspace-migration-068-release-notes-local-timezone.test.ts +90 -0
- package/src/__tests__/workspace-migration-069-seed-onboarding-threads.test.ts +120 -0
- package/src/__tests__/workspace-migration-071-remove-safe-storage-release-note.test.ts +206 -0
- package/src/__tests__/workspace-migration-safe-storage-limits-release.test.ts +78 -0
- package/src/agent/loop.ts +11 -0
- package/src/approvals/guardian-request-resolvers.ts +3 -32
- package/src/backup/snapshot-lock.ts +2 -27
- package/src/bundler/compiler-tools.ts +3 -2
- package/src/calls/call-constants.ts +5 -8
- package/src/calls/call-controller.ts +130 -67
- package/src/calls/call-conversation-messages.ts +46 -10
- package/src/calls/relay-server.ts +7 -1
- package/src/calls/voice-session-bridge.ts +1 -1
- package/src/cli/commands/__tests__/webhooks.test.ts +0 -4
- package/src/cli/commands/bash.ts +35 -108
- package/src/cli/commands/contacts.ts +64 -25
- package/src/cli/commands/credentials.ts +56 -0
- package/src/cli/commands/memory-v2.ts +11 -10
- package/src/cli/commands/oauth/__tests__/connect.test.ts +401 -219
- package/src/cli/commands/oauth/connect.ts +124 -40
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +0 -3
- package/src/cli/commands/platform/__tests__/connect.test.ts +7 -1
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +7 -1
- package/src/cli/commands/platform/__tests__/status.test.ts +103 -6
- package/src/cli/commands/platform/index.ts +16 -7
- package/src/cli/commands/status.ts +57 -0
- package/src/cli/program.ts +4 -2
- package/src/config/assistant-feature-flags.ts +13 -3
- package/src/config/bundled-skills/app-builder/SKILL.md +1 -3
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +4 -3
- package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +13 -7
- package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +2 -2
- package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +2 -2
- package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +2 -2
- package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +2 -2
- package/src/config/env.ts +0 -8
- package/src/config/feature-flag-registry.json +13 -5
- package/src/config/loader.ts +199 -27
- package/src/config/schemas/__tests__/memory-v2.test.ts +10 -5
- package/src/config/schemas/call-site-catalog.ts +14 -0
- package/src/config/schemas/channels.ts +0 -5
- package/src/config/schemas/heartbeat.ts +1 -1
- package/src/config/schemas/llm.ts +2 -0
- package/src/config/schemas/memory-lifecycle.ts +13 -0
- package/src/config/schemas/memory-v2.ts +76 -12
- package/src/config/schemas/platform.ts +43 -3
- package/src/config/schemas/services.ts +28 -0
- package/src/config/seed-inference-profiles.ts +230 -33
- package/src/contacts/contact-store.ts +0 -25
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +32 -0
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +86 -25
- package/src/daemon/assistant-attachments.ts +4 -4
- package/src/daemon/config-watcher.ts +85 -57
- package/src/daemon/conversation-agent-loop-handlers.ts +38 -0
- package/src/daemon/conversation-agent-loop.ts +183 -43
- package/src/daemon/conversation-error.ts +87 -15
- package/src/daemon/conversation-lifecycle.ts +22 -10
- package/src/daemon/conversation-process.ts +8 -0
- package/src/daemon/conversation-runtime-assembly.ts +26 -0
- package/src/daemon/conversation-store.ts +2 -2
- package/src/daemon/conversation-surfaces.ts +211 -29
- package/src/daemon/conversation-tool-setup.ts +66 -19
- package/src/daemon/conversation.ts +18 -23
- package/src/daemon/date-context.ts +71 -22
- package/src/daemon/disk-pressure-background-gate.ts +73 -0
- package/src/daemon/disk-pressure-guard.ts +343 -0
- package/src/daemon/disk-pressure-policy.ts +163 -0
- package/src/daemon/handlers/shared.ts +26 -1
- package/src/daemon/handlers/skills.ts +3 -4
- package/src/daemon/host-app-control-proxy.ts +137 -41
- package/src/daemon/host-bash-proxy.ts +47 -22
- package/src/daemon/host-browser-proxy.ts +1 -1
- package/src/daemon/host-cu-proxy.ts +50 -4
- package/src/daemon/host-file-proxy.ts +44 -8
- package/src/daemon/host-transfer-proxy.ts +97 -6
- package/src/daemon/lifecycle.ts +167 -101
- package/src/daemon/meet-host-supervisor.ts +4 -4
- package/src/daemon/meet-manifest-loader.ts +0 -1
- package/src/daemon/memory-v2-startup.ts +66 -15
- package/src/daemon/message-protocol.ts +3 -0
- package/src/daemon/message-types/conversations.ts +4 -0
- package/src/daemon/message-types/disk-pressure.ts +9 -0
- package/src/daemon/message-types/messages.ts +22 -1
- package/src/daemon/profiler-run-store.ts +5 -5
- package/src/daemon/tool-setup-types.ts +2 -2
- package/src/documents/document-store.ts +119 -0
- package/src/filing/filing-service.ts +29 -5
- package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +9 -16
- package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +36 -0
- package/src/heartbeat/heartbeat-run-store.ts +13 -0
- package/src/heartbeat/heartbeat-service.ts +205 -31
- package/src/home/feed-scheduler.ts +18 -0
- package/src/inbound/platform-callback-registration.ts +8 -15
- package/src/ipc/__tests__/clients-list-ipc.test.ts +169 -0
- package/src/ipc/assistant-server.ts +149 -38
- package/src/ipc/gateway-client.ts +37 -3
- package/src/ipc/skill-server.ts +99 -42
- package/src/live-voice/live-voice-archive.ts +4 -4
- package/src/live-voice/protocol.ts +5 -7
- package/src/media/image-service.ts +1 -7
- package/src/memory/__tests__/fixtures/memory-v2-activation-fixtures.ts +21 -13
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +34 -51
- package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +0 -6
- package/src/memory/__tests__/memory-v2-concept-frequency.test.ts +272 -0
- package/src/memory/admin.ts +5 -9
- package/src/memory/context-search/agent-runner.ts +19 -2
- package/src/memory/context-search/sources/conversations.ts +2 -11
- package/src/memory/context-search/sources/memory-v2.ts +1 -16
- package/src/memory/context-search/sources/memory.ts +2 -3
- package/src/memory/context-search/sources/pkb.ts +2 -3
- package/src/memory/context-search/types.ts +0 -1
- package/src/memory/conversation-crud.ts +4 -12
- package/src/memory/db-init.ts +2 -0
- package/src/memory/embedding-runtime-manager.ts +119 -5
- package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +136 -82
- package/src/memory/graph/__tests__/handle-remember-v2.test.ts +11 -26
- package/src/memory/graph/conversation-graph-memory.ts +72 -61
- package/src/memory/graph/extraction.ts +1 -3
- package/src/memory/graph/graph-search.test.ts +11 -67
- package/src/memory/graph/graph-search.ts +4 -24
- package/src/memory/graph/retriever.test.ts +12 -1
- package/src/memory/graph/retriever.ts +10 -15
- package/src/memory/graph/tool-handlers.ts +3 -4
- package/src/memory/graph/tools.ts +4 -4
- package/src/memory/indexer.ts +53 -45
- package/src/memory/job-handlers/backfill.ts +2 -11
- package/src/memory/job-handlers/cleanup.ts +43 -0
- package/src/memory/job-handlers/embedding.ts +6 -8
- package/src/memory/job-handlers/summarization.ts +2 -7
- package/src/memory/jobs/__tests__/embed-concept-page.test.ts +116 -0
- package/src/memory/jobs/embed-concept-page.ts +223 -87
- package/src/memory/jobs-store.ts +48 -0
- package/src/memory/jobs-worker.ts +85 -43
- package/src/memory/memory-v2-activation-log-store.ts +32 -14
- package/src/memory/memory-v2-concept-frequency.ts +169 -0
- package/src/memory/migrations/239-trace-events-created-at-index.ts +18 -0
- package/src/memory/migrations/index.ts +1 -0
- package/src/memory/pkb/pkb-search.test.ts +7 -0
- package/src/memory/pkb/pkb-search.ts +4 -5
- package/src/memory/qdrant-client.ts +3 -13
- package/src/memory/rerank-local.ts +374 -0
- package/src/memory/search/semantic.ts +10 -72
- package/src/memory/trace-event-store.ts +1 -17
- package/src/memory/v2/__tests__/activation.test.ts +346 -255
- package/src/memory/v2/__tests__/consolidation-job.test.ts +61 -40
- package/src/memory/v2/__tests__/injection.test.ts +297 -190
- package/src/memory/v2/__tests__/prompts-consolidation.test.ts +61 -2
- package/src/memory/v2/__tests__/qdrant.test.ts +326 -9
- package/src/memory/v2/__tests__/reranker.test.ts +338 -0
- package/src/memory/v2/__tests__/sim.test.ts +113 -196
- package/src/memory/v2/__tests__/skill-store.test.ts +71 -65
- package/src/memory/v2/__tests__/static-context.test.ts +77 -14
- package/src/memory/v2/__tests__/sweep-job.test.ts +19 -33
- package/src/memory/v2/activation.ts +149 -156
- package/src/memory/v2/consolidation-job.ts +69 -20
- package/src/memory/v2/injection.ts +75 -68
- package/src/memory/v2/page-store.ts +39 -0
- package/src/memory/v2/prompts/consolidation.ts +41 -1
- package/src/memory/v2/qdrant.ts +306 -46
- package/src/memory/v2/reranker.ts +177 -0
- package/src/memory/v2/sim.ts +77 -110
- package/src/memory/v2/skill-content.ts +4 -3
- package/src/memory/v2/skill-store.ts +82 -59
- package/src/memory/v2/static-context.ts +26 -8
- package/src/memory/v2/sweep-job.ts +5 -6
- package/src/memory/v2/types.ts +17 -10
- package/src/notifications/copy-composer.ts +47 -0
- package/src/notifications/decision-engine.ts +46 -0
- package/src/notifications/signal.ts +4 -0
- package/src/oauth/AGENTS.md +3 -1
- package/src/oauth/__tests__/oauth-connect-state.test.ts +137 -0
- package/src/oauth/connect-orchestrator.ts +2 -0
- package/src/oauth/connection-resolver.test.ts +66 -1
- package/src/oauth/connection-resolver.ts +55 -1
- package/src/oauth/oauth-connect-state.ts +77 -0
- package/src/oauth/seed-providers.ts +58 -1
- package/src/permissions/gateway-threshold-reader.ts +116 -8
- package/src/permissions/prompter.ts +86 -96
- package/src/permissions/secret-prompter.ts +31 -31
- package/src/plugins/defaults/injectors.ts +36 -4
- package/src/plugins/defaults/memory-retrieval.ts +5 -6
- package/src/plugins/types.ts +7 -0
- package/src/proactive-artifact/aux-message-injector.ts +74 -0
- package/src/proactive-artifact/decision.test.ts +226 -0
- package/src/proactive-artifact/decision.ts +165 -0
- package/src/proactive-artifact/index.ts +7 -0
- package/src/proactive-artifact/job.test.ts +914 -0
- package/src/proactive-artifact/job.ts +366 -0
- package/src/proactive-artifact/message-copy.ts +58 -0
- package/src/proactive-artifact/trigger-state.test.ts +277 -0
- package/src/proactive-artifact/trigger-state.ts +119 -0
- package/src/prompts/normalize-onboarding.ts +80 -0
- package/src/prompts/persona-resolver.ts +101 -9
- package/src/prompts/system-prompt.ts +21 -7
- package/src/prompts/templates/BOOTSTRAP.md +13 -5
- package/src/prompts/templates/SOUL.md +13 -28
- package/src/providers/__tests__/retry-callsite.test.ts +222 -1
- package/src/providers/model-intents.ts +7 -0
- package/src/providers/openrouter/client.ts +8 -0
- package/src/providers/retry.ts +50 -0
- package/src/providers/types.ts +1 -0
- package/src/runtime/__tests__/agent-wake.test.ts +456 -3
- package/src/runtime/agent-wake.ts +238 -100
- package/src/runtime/assistant-event-hub.ts +36 -6
- package/src/runtime/assistant-event.ts +0 -1
- package/src/runtime/auth/__tests__/route-policy.test.ts +64 -0
- package/src/runtime/auth/route-policy.ts +15 -1
- package/src/runtime/auth/same-actor.ts +216 -0
- package/src/runtime/channel-approvals.ts +3 -2
- package/src/runtime/channel-retry-sweep.ts +65 -1
- package/src/runtime/local-actor-identity.ts +52 -11
- package/src/runtime/pending-interactions.ts +27 -15
- package/src/runtime/routes/__tests__/client-routes.test.ts +155 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +0 -5
- package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +147 -0
- package/src/runtime/routes/approval-routes.ts +7 -3
- package/src/runtime/routes/client-routes.ts +20 -2
- package/src/runtime/routes/consolidation-routes.ts +8 -9
- package/src/runtime/routes/contact-routes.ts +0 -25
- package/src/runtime/routes/conversation-query-routes.ts +44 -1
- package/src/runtime/routes/conversation-routes.ts +35 -26
- package/src/runtime/routes/debug-bash-routes.ts +165 -0
- package/src/runtime/routes/disk-pressure-routes.ts +121 -0
- package/src/runtime/routes/document-pdf-renderer.ts +6 -2
- package/src/runtime/routes/documents-routes.ts +2 -75
- package/src/runtime/routes/events-routes.ts +41 -9
- package/src/runtime/routes/filing-routes.ts +2 -3
- package/src/runtime/routes/host-bash-routes.ts +23 -3
- package/src/runtime/routes/host-cu-routes.ts +33 -6
- package/src/runtime/routes/host-file-routes.ts +32 -6
- package/src/runtime/routes/host-transfer-routes.ts +79 -16
- package/src/runtime/routes/identity-routes.ts +7 -138
- package/src/runtime/routes/inbound-message-handler.ts +77 -12
- package/src/runtime/routes/index.ts +6 -0
- package/src/runtime/routes/memory-item-routes.test.ts +37 -17
- package/src/runtime/routes/memory-item-routes.ts +5 -6
- package/src/runtime/routes/memory-v2-routes.ts +136 -17
- package/src/runtime/routes/oauth-connect-routes.ts +153 -0
- package/src/runtime/verification-outbound-actions.ts +4 -4
- package/src/schedule/run-script.ts +37 -5
- package/src/schedule/scheduler.ts +20 -1
- package/src/security/encrypted-store.ts +2 -0
- package/src/security/secure-keys.ts +55 -0
- package/src/skills/include-graph.ts +35 -13
- package/src/skills/remote-skill-policy.ts +4 -10
- package/src/subagent/index.ts +1 -7
- package/src/subagent/manager.ts +1 -15
- package/src/tasks/task-runner.ts +0 -1
- package/src/tasks/task-store.ts +0 -3
- package/src/tools/background-tool-registry.ts +17 -3
- package/src/tools/document/document-tool.ts +20 -0
- package/src/tools/executor.ts +18 -2
- package/src/tools/host-filesystem/edit.test.ts +151 -0
- package/src/tools/host-filesystem/edit.ts +43 -1
- package/src/tools/host-filesystem/read.test.ts +129 -0
- package/src/tools/host-filesystem/read.ts +43 -1
- package/src/tools/host-filesystem/transfer.test.ts +127 -2
- package/src/tools/host-filesystem/transfer.ts +56 -11
- package/src/tools/host-filesystem/write.test.ts +134 -0
- package/src/tools/host-filesystem/write.ts +43 -1
- package/src/tools/host-terminal/host-shell.ts +13 -6
- package/src/tools/mcp/mcp-tool-factory.ts +2 -1
- package/src/tools/memory/register.test.ts +14 -9
- package/src/tools/memory/register.ts +1 -2
- package/src/tools/permission-checker.ts +15 -0
- package/src/tools/provider-tool-name.ts +28 -0
- package/src/tools/registry.ts +30 -9
- package/src/tools/skills/load.ts +24 -20
- package/src/tools/terminal/shell.ts +9 -1
- package/src/tools/tool-approval-handler.ts +31 -6
- package/src/tools/tool-name-aliases.ts +19 -0
- package/src/tools/types.ts +43 -3
- package/src/tts/provider-catalog.ts +3 -5
- package/src/util/disk-usage.ts +138 -0
- package/src/util/platform.ts +21 -11
- package/src/util/process-liveness.ts +26 -0
- package/src/workspace/heartbeat-service.ts +19 -0
- package/src/workspace/migrations/065-bump-stale-heartbeat-interval.ts +60 -0
- package/src/workspace/migrations/066-seed-heartbeat-callsite-cost-default.ts +146 -0
- package/src/workspace/migrations/067-release-notes-safe-storage-limits.ts +14 -0
- package/src/workspace/migrations/068-release-notes-local-timezone.ts +65 -0
- package/src/workspace/migrations/069-seed-onboarding-threads.ts +28 -0
- package/src/workspace/migrations/070-memory-v2-summary-schema-rebuild.ts +31 -0
- package/src/workspace/migrations/071-remove-safe-storage-release-note.ts +111 -0
- package/src/workspace/migrations/registry.ts +14 -0
- package/src/__tests__/conversation-tool-setup-memory-scope.test.ts +0 -167
- package/src/memory/v2/__tests__/skill-qdrant.test.ts +0 -657
- package/src/memory/v2/skill-qdrant.ts +0 -404
- package/src/signals/bash.ts +0 -198
|
@@ -28,13 +28,21 @@
|
|
|
28
28
|
* back to a shorter deterministic path so CLI commands can still connect.
|
|
29
29
|
*/
|
|
30
30
|
|
|
31
|
-
import { existsSync,
|
|
31
|
+
import { existsSync, unlinkSync } from "node:fs";
|
|
32
32
|
import { createServer, type Server, type Socket } from "node:net";
|
|
33
|
-
import { dirname } from "node:path";
|
|
34
33
|
|
|
34
|
+
import {
|
|
35
|
+
ensureSocketDir,
|
|
36
|
+
SocketWatchdog,
|
|
37
|
+
} from "@vellumai/ipc-server-utils";
|
|
38
|
+
|
|
39
|
+
import { findLocalGuardianPrincipalId } from "../runtime/local-actor-identity.js";
|
|
35
40
|
import { RouteError } from "../runtime/routes/errors.js";
|
|
36
41
|
import { ROUTES } from "../runtime/routes/index.js";
|
|
37
|
-
import type {
|
|
42
|
+
import type {
|
|
43
|
+
RouteDefinition,
|
|
44
|
+
RouteHandlerArgs,
|
|
45
|
+
} from "../runtime/routes/types.js";
|
|
38
46
|
import { getLogger } from "../util/logger.js";
|
|
39
47
|
import {
|
|
40
48
|
type IpcEnvelope,
|
|
@@ -126,13 +134,29 @@ function isIpcBinaryResponse(value: unknown): value is IpcBinaryResponse {
|
|
|
126
134
|
// Server
|
|
127
135
|
// ---------------------------------------------------------------------------
|
|
128
136
|
|
|
137
|
+
/** Optional configuration for {@link AssistantIpcServer}. */
|
|
138
|
+
export interface AssistantIpcServerOptions {
|
|
139
|
+
/**
|
|
140
|
+
* How often the socket-file watchdog stats the listening socket path.
|
|
141
|
+
* Set to `0` to disable. Defaults to {@link SocketWatchdog}'s 5000ms.
|
|
142
|
+
*/
|
|
143
|
+
watchdogIntervalMs?: number;
|
|
144
|
+
}
|
|
145
|
+
|
|
129
146
|
export class AssistantIpcServer {
|
|
130
147
|
private server: Server | null = null;
|
|
131
148
|
private clients = new Set<Socket>();
|
|
132
149
|
private methods = new Map<string, RouteDefinition["handler"]>();
|
|
133
150
|
private socketPath: string;
|
|
151
|
+
private watchdog: SocketWatchdog;
|
|
152
|
+
/**
|
|
153
|
+
* Servers whose listener path has been replaced by a re-bind. Kept around
|
|
154
|
+
* so already-connected sockets continue to work; closed gracefully once
|
|
155
|
+
* their accept loops drain.
|
|
156
|
+
*/
|
|
157
|
+
private legacyServers = new Set<Server>();
|
|
134
158
|
|
|
135
|
-
constructor() {
|
|
159
|
+
constructor(options?: AssistantIpcServerOptions) {
|
|
136
160
|
const resolution = resolveIpcSocketPath("assistant");
|
|
137
161
|
this.socketPath = resolution.path;
|
|
138
162
|
log.info(
|
|
@@ -150,62 +174,55 @@ export class AssistantIpcServer {
|
|
|
150
174
|
this.methods.set("db_proxy", (params) =>
|
|
151
175
|
handleDbProxy(params as unknown as DbProxyParams),
|
|
152
176
|
);
|
|
177
|
+
|
|
178
|
+
this.watchdog = new SocketWatchdog({
|
|
179
|
+
socketPath: this.socketPath,
|
|
180
|
+
intervalMs: options?.watchdogIntervalMs,
|
|
181
|
+
getServer: () => this.server,
|
|
182
|
+
createServer: () => this.createListeningServer(),
|
|
183
|
+
onRebind: (newServer, oldServer) => {
|
|
184
|
+
this.server = newServer;
|
|
185
|
+
this.legacyServers.add(oldServer);
|
|
186
|
+
oldServer.close(() => {
|
|
187
|
+
this.legacyServers.delete(oldServer);
|
|
188
|
+
});
|
|
189
|
+
},
|
|
190
|
+
log,
|
|
191
|
+
});
|
|
153
192
|
}
|
|
154
193
|
|
|
155
194
|
/** Start listening on the Unix domain socket. */
|
|
156
195
|
async start(): Promise<void> {
|
|
157
196
|
// Ensure the parent directory exists before listening.
|
|
158
|
-
|
|
159
|
-
if (!existsSync(socketDir)) {
|
|
160
|
-
mkdirSync(socketDir, { recursive: true, mode: 0o700 });
|
|
161
|
-
}
|
|
197
|
+
ensureSocketDir(this.socketPath);
|
|
162
198
|
|
|
163
199
|
// Probe before unlink so a second daemon can't silently orphan an active
|
|
164
200
|
// listener (Unix lets you unlink a still-bound socket file). See
|
|
165
201
|
// `ensureSocketPathFree` for the behavior matrix.
|
|
166
202
|
await ensureSocketPathFree(this.socketPath);
|
|
167
203
|
|
|
168
|
-
this.server =
|
|
169
|
-
this.clients.add(socket);
|
|
170
|
-
log.debug("IPC client connected");
|
|
171
|
-
|
|
172
|
-
const reader = new IpcFrameReader(
|
|
173
|
-
(envelope, binary) =>
|
|
174
|
-
this.handleEnvelope(socket, reader, envelope, binary),
|
|
175
|
-
(err) => log.warn({ err }, "IPC frame read error"),
|
|
176
|
-
);
|
|
177
|
-
|
|
178
|
-
socket.on("data", (chunk) => {
|
|
179
|
-
reader.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
socket.on("close", () => {
|
|
183
|
-
this.clients.delete(socket);
|
|
184
|
-
log.debug("IPC client disconnected");
|
|
185
|
-
});
|
|
186
|
-
|
|
187
|
-
socket.on("error", (err) => {
|
|
188
|
-
log.warn({ err }, "IPC client socket error");
|
|
189
|
-
this.clients.delete(socket);
|
|
190
|
-
});
|
|
191
|
-
});
|
|
192
|
-
|
|
193
|
-
this.server.on("error", (err) => {
|
|
194
|
-
log.error({ err }, "Assistant IPC server error");
|
|
195
|
-
});
|
|
196
|
-
|
|
204
|
+
this.server = this.createListeningServer();
|
|
197
205
|
this.server.listen(this.socketPath, () => {
|
|
198
206
|
log.info({ path: this.socketPath }, "Assistant IPC server listening");
|
|
199
207
|
});
|
|
208
|
+
|
|
209
|
+
this.watchdog.start();
|
|
200
210
|
}
|
|
201
211
|
|
|
202
212
|
/** Stop the server and disconnect all clients. */
|
|
203
213
|
stop(): void {
|
|
214
|
+
this.watchdog.stop();
|
|
215
|
+
|
|
204
216
|
for (const client of this.clients) {
|
|
205
217
|
if (!client.destroyed) client.destroy();
|
|
206
218
|
}
|
|
207
219
|
this.clients.clear();
|
|
208
220
|
|
|
221
|
+
for (const legacy of this.legacyServers) {
|
|
222
|
+
legacy.close();
|
|
223
|
+
}
|
|
224
|
+
this.legacyServers.clear();
|
|
225
|
+
|
|
209
226
|
if (this.server) {
|
|
210
227
|
this.server.close();
|
|
211
228
|
this.server = null;
|
|
@@ -225,8 +242,52 @@ export class AssistantIpcServer {
|
|
|
225
242
|
return this.socketPath;
|
|
226
243
|
}
|
|
227
244
|
|
|
245
|
+
/**
|
|
246
|
+
* Re-bind the listening socket if its path entry is missing on disk.
|
|
247
|
+
*
|
|
248
|
+
* Public for tests so the watchdog can be exercised deterministically
|
|
249
|
+
* without waiting for the interval. Returns `true` when a re-bind was
|
|
250
|
+
* performed, `false` otherwise.
|
|
251
|
+
*/
|
|
252
|
+
async rebindIfMissing(): Promise<boolean> {
|
|
253
|
+
return this.watchdog.rebindIfMissing();
|
|
254
|
+
}
|
|
255
|
+
|
|
228
256
|
// ── Internal ──────────────────────────────────────────────────────────
|
|
229
257
|
|
|
258
|
+
private createListeningServer(): Server {
|
|
259
|
+
const server = createServer((socket) => {
|
|
260
|
+
this.clients.add(socket);
|
|
261
|
+
log.debug("IPC client connected");
|
|
262
|
+
|
|
263
|
+
const reader = new IpcFrameReader(
|
|
264
|
+
(envelope, binary) =>
|
|
265
|
+
this.handleEnvelope(socket, reader, envelope, binary),
|
|
266
|
+
(err) => log.warn({ err }, "IPC frame read error"),
|
|
267
|
+
);
|
|
268
|
+
|
|
269
|
+
socket.on("data", (chunk) => {
|
|
270
|
+
reader.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
socket.on("close", () => {
|
|
274
|
+
this.clients.delete(socket);
|
|
275
|
+
log.debug("IPC client disconnected");
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
socket.on("error", (err) => {
|
|
279
|
+
log.warn({ err }, "IPC client socket error");
|
|
280
|
+
this.clients.delete(socket);
|
|
281
|
+
});
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
server.on("error", (err) => {
|
|
285
|
+
log.error({ err }, "Assistant IPC server error");
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
return server;
|
|
289
|
+
}
|
|
290
|
+
|
|
230
291
|
private handleEnvelope(
|
|
231
292
|
socket: Socket,
|
|
232
293
|
reader: IpcFrameReader,
|
|
@@ -256,7 +317,8 @@ export class AssistantIpcServer {
|
|
|
256
317
|
void binary;
|
|
257
318
|
|
|
258
319
|
try {
|
|
259
|
-
const
|
|
320
|
+
const handlerArgs = injectLocalActorHeader(req.params);
|
|
321
|
+
const result = handler(handlerArgs);
|
|
260
322
|
|
|
261
323
|
if (result instanceof Promise) {
|
|
262
324
|
result
|
|
@@ -454,3 +516,52 @@ export class AssistantIpcServer {
|
|
|
454
516
|
// ---------------------------------------------------------------------------
|
|
455
517
|
// Helpers
|
|
456
518
|
// ---------------------------------------------------------------------------
|
|
519
|
+
|
|
520
|
+
/**
|
|
521
|
+
* Inject a synthetic `x-vellum-actor-principal-id` header from the local
|
|
522
|
+
* guardian principal when the caller hasn't already provided one.
|
|
523
|
+
*
|
|
524
|
+
* Local IPC is intra-process and owned by the same user as the daemon, so
|
|
525
|
+
* routes that consume `headers["x-vellum-actor-principal-id"]` (e.g. the
|
|
526
|
+
* same-user filter on `GET /v1/clients`) need an actor identity to function
|
|
527
|
+
* over IPC. The HTTP adapter does this from the verified `AuthContext`
|
|
528
|
+
* (`http-adapter.ts`); this helper mirrors that convention for IPC.
|
|
529
|
+
*
|
|
530
|
+
* Existing headers from the caller (e.g. the gateway's IPC runtime proxy,
|
|
531
|
+
* which forwards real `x-vellum-*` headers from the authenticated HTTP
|
|
532
|
+
* request) are preserved — we only fill in the gap for direct CLI/local
|
|
533
|
+
* IPC callers.
|
|
534
|
+
*/
|
|
535
|
+
function injectLocalActorHeader(
|
|
536
|
+
params: Record<string, unknown> | undefined,
|
|
537
|
+
): RouteHandlerArgs {
|
|
538
|
+
const args = (params ?? {}) as RouteHandlerArgs;
|
|
539
|
+
const existingHeaders = args.headers;
|
|
540
|
+
if (existingHeaders?.["x-vellum-actor-principal-id"]) {
|
|
541
|
+
return args;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
// Defensive: the guardian lookup queries the contacts table, which may
|
|
545
|
+
// not yet exist on a very early boot path or in test fixtures that don't
|
|
546
|
+
// initialize the DB. A failure here must not block IPC dispatch — routes
|
|
547
|
+
// that require the header will fail-closed on their own.
|
|
548
|
+
let localActor: string | undefined;
|
|
549
|
+
try {
|
|
550
|
+
localActor = findLocalGuardianPrincipalId();
|
|
551
|
+
} catch (err) {
|
|
552
|
+
log.debug(
|
|
553
|
+
{ err },
|
|
554
|
+
"failed to resolve local actor principal for IPC header injection",
|
|
555
|
+
);
|
|
556
|
+
return args;
|
|
557
|
+
}
|
|
558
|
+
if (!localActor) return args;
|
|
559
|
+
|
|
560
|
+
return {
|
|
561
|
+
...args,
|
|
562
|
+
headers: {
|
|
563
|
+
...existingHeaders,
|
|
564
|
+
"x-vellum-actor-principal-id": localActor,
|
|
565
|
+
},
|
|
566
|
+
};
|
|
567
|
+
}
|
|
@@ -38,9 +38,10 @@ const log = getLogger("gateway-ipc-client");
|
|
|
38
38
|
export async function ipcCall(
|
|
39
39
|
method: string,
|
|
40
40
|
params?: Record<string, unknown>,
|
|
41
|
+
timeoutMs?: number,
|
|
41
42
|
): Promise<unknown> {
|
|
42
43
|
const socketPath = getGatewaySocketPath();
|
|
43
|
-
return packageIpcCall(socketPath, method, params, log);
|
|
44
|
+
return packageIpcCall(socketPath, method, params, log, timeoutMs);
|
|
44
45
|
}
|
|
45
46
|
|
|
46
47
|
// ---------------------------------------------------------------------------
|
|
@@ -90,9 +91,15 @@ export function resetPersistentClient(): void {
|
|
|
90
91
|
/**
|
|
91
92
|
* Fetch all merged feature flags from the gateway via IPC.
|
|
92
93
|
* Returns an empty record on any failure.
|
|
94
|
+
*
|
|
95
|
+
* @param timeoutMs - Optional timeout override forwarded to the IPC
|
|
96
|
+
* transport. Pass a small value (e.g. 200) for CLI startup paths where
|
|
97
|
+
* a slow/absent gateway should fail fast.
|
|
93
98
|
*/
|
|
94
|
-
export async function ipcGetFeatureFlags(
|
|
95
|
-
|
|
99
|
+
export async function ipcGetFeatureFlags(
|
|
100
|
+
timeoutMs?: number,
|
|
101
|
+
): Promise<Record<string, boolean>> {
|
|
102
|
+
const result = await ipcCall("get_feature_flags", undefined, timeoutMs);
|
|
96
103
|
if (result && typeof result === "object" && !Array.isArray(result)) {
|
|
97
104
|
const filtered: Record<string, boolean> = {};
|
|
98
105
|
for (const [k, v] of Object.entries(result as Record<string, unknown>)) {
|
|
@@ -103,6 +110,33 @@ export async function ipcGetFeatureFlags(): Promise<Record<string, boolean>> {
|
|
|
103
110
|
return {};
|
|
104
111
|
}
|
|
105
112
|
|
|
113
|
+
// ---------------------------------------------------------------------------
|
|
114
|
+
// Velay tunnel status
|
|
115
|
+
// ---------------------------------------------------------------------------
|
|
116
|
+
|
|
117
|
+
export interface VelayTunnelStatus {
|
|
118
|
+
connected: boolean;
|
|
119
|
+
publicUrl: string | null;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Fetch the current Velay tunnel status from the gateway via IPC.
|
|
124
|
+
* Returns `null` when the gateway is unreachable or returns an unexpected
|
|
125
|
+
* response — callers should treat `null` as "gateway not running".
|
|
126
|
+
*/
|
|
127
|
+
export async function ipcGetVelayStatus(): Promise<VelayTunnelStatus | null> {
|
|
128
|
+
const result = await ipcCall("get_velay_status");
|
|
129
|
+
if (!result || typeof result !== "object" || Array.isArray(result)) {
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
const obj = result as Record<string, unknown>;
|
|
133
|
+
if (typeof obj.connected !== "boolean") return null;
|
|
134
|
+
return {
|
|
135
|
+
connected: obj.connected,
|
|
136
|
+
publicUrl: typeof obj.publicUrl === "string" ? obj.publicUrl : null,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
|
|
106
140
|
/**
|
|
107
141
|
* Classify risk for a tool invocation via the gateway's persistent IPC
|
|
108
142
|
* connection.
|
package/src/ipc/skill-server.ts
CHANGED
|
@@ -37,9 +37,13 @@
|
|
|
37
37
|
* back to a shorter deterministic path via the shared socket-path resolver.
|
|
38
38
|
*/
|
|
39
39
|
|
|
40
|
-
import { existsSync,
|
|
40
|
+
import { existsSync, unlinkSync } from "node:fs";
|
|
41
41
|
import { createServer, type Server, type Socket } from "node:net";
|
|
42
|
-
|
|
42
|
+
|
|
43
|
+
import {
|
|
44
|
+
ensureSocketDir,
|
|
45
|
+
SocketWatchdog,
|
|
46
|
+
} from "@vellumai/ipc-server-utils";
|
|
43
47
|
|
|
44
48
|
import {
|
|
45
49
|
type SkillRouteHandle,
|
|
@@ -233,6 +237,15 @@ class SkillIpcConnectionState implements SkillIpcConnection {
|
|
|
233
237
|
// Server
|
|
234
238
|
// ---------------------------------------------------------------------------
|
|
235
239
|
|
|
240
|
+
/** Optional configuration for {@link SkillIpcServer}. */
|
|
241
|
+
export interface SkillIpcServerOptions {
|
|
242
|
+
/**
|
|
243
|
+
* How often the socket-file watchdog stats the listening socket path.
|
|
244
|
+
* Set to `0` to disable. Defaults to {@link SocketWatchdog}'s 5000ms.
|
|
245
|
+
*/
|
|
246
|
+
watchdogIntervalMs?: number;
|
|
247
|
+
}
|
|
248
|
+
|
|
236
249
|
export class SkillIpcServer {
|
|
237
250
|
private server: Server | null = null;
|
|
238
251
|
private clients = new Set<Socket>();
|
|
@@ -252,8 +265,15 @@ export class SkillIpcServer {
|
|
|
252
265
|
private connections = new WeakMap<Socket, SkillIpcConnectionState>();
|
|
253
266
|
private nextConnectionId = 1;
|
|
254
267
|
private socketPath: string;
|
|
268
|
+
private watchdog: SocketWatchdog;
|
|
269
|
+
/**
|
|
270
|
+
* Servers whose listener path has been replaced by a re-bind. Kept around
|
|
271
|
+
* so already-connected sockets continue to work; closed gracefully once
|
|
272
|
+
* their accept loops drain.
|
|
273
|
+
*/
|
|
274
|
+
private legacyServers = new Set<Server>();
|
|
255
275
|
|
|
256
|
-
constructor() {
|
|
276
|
+
constructor(options?: SkillIpcServerOptions) {
|
|
257
277
|
const resolution = resolveSkillIpcSocketPath();
|
|
258
278
|
this.socketPath = resolution.path;
|
|
259
279
|
log.info(
|
|
@@ -266,6 +286,21 @@ export class SkillIpcServer {
|
|
|
266
286
|
for (const route of skillIpcStreamingRoutes) {
|
|
267
287
|
this.streamingMethods.set(route.method, route.handler);
|
|
268
288
|
}
|
|
289
|
+
|
|
290
|
+
this.watchdog = new SocketWatchdog({
|
|
291
|
+
socketPath: this.socketPath,
|
|
292
|
+
intervalMs: options?.watchdogIntervalMs,
|
|
293
|
+
getServer: () => this.server,
|
|
294
|
+
createServer: () => this.createListeningServer(),
|
|
295
|
+
onRebind: (newServer, oldServer) => {
|
|
296
|
+
this.server = newServer;
|
|
297
|
+
this.legacyServers.add(oldServer);
|
|
298
|
+
oldServer.close(() => {
|
|
299
|
+
this.legacyServers.delete(oldServer);
|
|
300
|
+
});
|
|
301
|
+
},
|
|
302
|
+
log,
|
|
303
|
+
});
|
|
269
304
|
}
|
|
270
305
|
|
|
271
306
|
/** Register an additional method handler after construction. */
|
|
@@ -349,17 +384,71 @@ export class SkillIpcServer {
|
|
|
349
384
|
/** Start listening on the Unix domain socket. */
|
|
350
385
|
async start(): Promise<void> {
|
|
351
386
|
// Ensure the parent directory exists before listening.
|
|
352
|
-
|
|
353
|
-
if (!existsSync(socketDir)) {
|
|
354
|
-
mkdirSync(socketDir, { recursive: true, mode: 0o700 });
|
|
355
|
-
}
|
|
387
|
+
ensureSocketDir(this.socketPath);
|
|
356
388
|
|
|
357
389
|
// Probe before unlink so a second daemon can't silently orphan an active
|
|
358
390
|
// listener (Unix lets you unlink a still-bound socket file). See
|
|
359
391
|
// `ensureSocketPathFree` for the behavior matrix.
|
|
360
392
|
await ensureSocketPathFree(this.socketPath);
|
|
361
393
|
|
|
362
|
-
this.server =
|
|
394
|
+
this.server = this.createListeningServer();
|
|
395
|
+
this.server.listen(this.socketPath, () => {
|
|
396
|
+
log.info({ path: this.socketPath }, "Skill IPC server listening");
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
this.watchdog.start();
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
/** Stop the server and disconnect all clients. */
|
|
403
|
+
stop(): void {
|
|
404
|
+
this.watchdog.stop();
|
|
405
|
+
|
|
406
|
+
for (const client of this.clients) {
|
|
407
|
+
this.teardownSubscriptions(client);
|
|
408
|
+
this.teardownConnection(client);
|
|
409
|
+
if (!client.destroyed) client.destroy();
|
|
410
|
+
}
|
|
411
|
+
this.clients.clear();
|
|
412
|
+
|
|
413
|
+
for (const legacy of this.legacyServers) {
|
|
414
|
+
legacy.close();
|
|
415
|
+
}
|
|
416
|
+
this.legacyServers.clear();
|
|
417
|
+
|
|
418
|
+
if (this.server) {
|
|
419
|
+
this.server.close();
|
|
420
|
+
this.server = null;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
if (existsSync(this.socketPath)) {
|
|
424
|
+
try {
|
|
425
|
+
unlinkSync(this.socketPath);
|
|
426
|
+
} catch {
|
|
427
|
+
// Ignore
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
/** Get the socket path (for diagnostics). */
|
|
433
|
+
getSocketPath(): string {
|
|
434
|
+
return this.socketPath;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
/**
|
|
438
|
+
* Re-bind the listening socket if its path entry is missing on disk.
|
|
439
|
+
*
|
|
440
|
+
* Public for tests so the watchdog can be exercised deterministically
|
|
441
|
+
* without waiting for the interval. Returns `true` when a re-bind was
|
|
442
|
+
* performed, `false` otherwise.
|
|
443
|
+
*/
|
|
444
|
+
async rebindIfMissing(): Promise<boolean> {
|
|
445
|
+
return this.watchdog.rebindIfMissing();
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
// ── Internal ──────────────────────────────────────────────────────────
|
|
449
|
+
|
|
450
|
+
private createListeningServer(): Server {
|
|
451
|
+
const server = createServer((socket) => {
|
|
363
452
|
this.clients.add(socket);
|
|
364
453
|
const connection = new SkillIpcConnectionState(
|
|
365
454
|
`skill-ipc-${this.nextConnectionId++}`,
|
|
@@ -406,45 +495,13 @@ export class SkillIpcServer {
|
|
|
406
495
|
});
|
|
407
496
|
});
|
|
408
497
|
|
|
409
|
-
|
|
498
|
+
server.on("error", (err) => {
|
|
410
499
|
log.error({ err }, "Skill IPC server error");
|
|
411
500
|
});
|
|
412
501
|
|
|
413
|
-
|
|
414
|
-
log.info({ path: this.socketPath }, "Skill IPC server listening");
|
|
415
|
-
});
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
/** Stop the server and disconnect all clients. */
|
|
419
|
-
stop(): void {
|
|
420
|
-
for (const client of this.clients) {
|
|
421
|
-
this.teardownSubscriptions(client);
|
|
422
|
-
this.teardownConnection(client);
|
|
423
|
-
if (!client.destroyed) client.destroy();
|
|
424
|
-
}
|
|
425
|
-
this.clients.clear();
|
|
426
|
-
|
|
427
|
-
if (this.server) {
|
|
428
|
-
this.server.close();
|
|
429
|
-
this.server = null;
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
if (existsSync(this.socketPath)) {
|
|
433
|
-
try {
|
|
434
|
-
unlinkSync(this.socketPath);
|
|
435
|
-
} catch {
|
|
436
|
-
// Ignore
|
|
437
|
-
}
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
/** Get the socket path (for diagnostics). */
|
|
442
|
-
getSocketPath(): string {
|
|
443
|
-
return this.socketPath;
|
|
502
|
+
return server;
|
|
444
503
|
}
|
|
445
504
|
|
|
446
|
-
// ── Internal ──────────────────────────────────────────────────────────
|
|
447
|
-
|
|
448
505
|
private handleMessage(socket: Socket, line: string): void {
|
|
449
506
|
let frame: IpcRequest & { result?: unknown; error?: string };
|
|
450
507
|
try {
|
|
@@ -17,7 +17,7 @@ const LIVE_VOICE_AUDIO_SOURCE = "live-voice";
|
|
|
17
17
|
|
|
18
18
|
export type LiveVoiceAudioArchiveRole = "user" | "assistant";
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
type LiveVoiceAudioSource =
|
|
21
21
|
| {
|
|
22
22
|
type: "base64";
|
|
23
23
|
dataBase64: string;
|
|
@@ -28,7 +28,7 @@ export type LiveVoiceAudioSource =
|
|
|
28
28
|
sizeBytes?: number;
|
|
29
29
|
};
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
interface ArchiveLiveVoiceAudioInput {
|
|
32
32
|
messageId: string;
|
|
33
33
|
sessionId: string;
|
|
34
34
|
turnId: string;
|
|
@@ -55,7 +55,7 @@ export interface LiveVoiceAudioArtifactMetadata {
|
|
|
55
55
|
archivedAt: number;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
type LiveVoiceAudioArchiveWarningCode =
|
|
59
59
|
| "archive_failed"
|
|
60
60
|
| "attachment_not_found"
|
|
61
61
|
| "invalid_audio_source"
|
|
@@ -591,7 +591,7 @@ type LinkLiveVoiceRolelessAudioInput = Omit<
|
|
|
591
591
|
messageId?: string | null;
|
|
592
592
|
};
|
|
593
593
|
|
|
594
|
-
|
|
594
|
+
interface LinkLiveVoiceAudioArtifactInput {
|
|
595
595
|
messageId?: string | null;
|
|
596
596
|
artifact: LiveVoiceAudioArtifactMetadata;
|
|
597
597
|
position?: number;
|
|
@@ -6,8 +6,7 @@ const LIVE_VOICE_CLIENT_FRAME_TYPES = [
|
|
|
6
6
|
"end",
|
|
7
7
|
] as const;
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
(typeof LIVE_VOICE_CLIENT_FRAME_TYPES)[number];
|
|
9
|
+
type LiveVoiceClientFrameType = (typeof LIVE_VOICE_CLIENT_FRAME_TYPES)[number];
|
|
11
10
|
|
|
12
11
|
const _LIVE_VOICE_SERVER_FRAME_TYPES = [
|
|
13
12
|
"ready",
|
|
@@ -23,8 +22,7 @@ const _LIVE_VOICE_SERVER_FRAME_TYPES = [
|
|
|
23
22
|
"error",
|
|
24
23
|
] as const;
|
|
25
24
|
|
|
26
|
-
|
|
27
|
-
(typeof _LIVE_VOICE_SERVER_FRAME_TYPES)[number];
|
|
25
|
+
type LiveVoiceServerFrameType = (typeof _LIVE_VOICE_SERVER_FRAME_TYPES)[number];
|
|
28
26
|
|
|
29
27
|
export const LiveVoiceProtocolErrorCode = {
|
|
30
28
|
InvalidJson: "invalid_json",
|
|
@@ -45,7 +43,7 @@ export interface LiveVoiceProtocolError {
|
|
|
45
43
|
readonly frameType?: string;
|
|
46
44
|
}
|
|
47
45
|
|
|
48
|
-
|
|
46
|
+
type LiveVoiceParseResult<T> =
|
|
49
47
|
| { ok: true; frame: T }
|
|
50
48
|
| { ok: false; error: LiveVoiceProtocolError };
|
|
51
49
|
|
|
@@ -85,12 +83,12 @@ export type LiveVoiceClientFrame =
|
|
|
85
83
|
| LiveVoiceClientInterruptFrame
|
|
86
84
|
| LiveVoiceClientEndFrame;
|
|
87
85
|
|
|
88
|
-
|
|
86
|
+
interface LiveVoiceBinaryAudioFrame {
|
|
89
87
|
readonly type: "binary_audio";
|
|
90
88
|
readonly data: Uint8Array;
|
|
91
89
|
}
|
|
92
90
|
|
|
93
|
-
|
|
91
|
+
interface LiveVoiceServerFrameBase {
|
|
94
92
|
readonly type: LiveVoiceServerFrameType;
|
|
95
93
|
readonly seq: number;
|
|
96
94
|
}
|
|
@@ -76,10 +76,4 @@ export function providerForModel(
|
|
|
76
76
|
return fallback;
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
export type {
|
|
80
|
-
GeneratedImage,
|
|
81
|
-
ImageGenCredentials,
|
|
82
|
-
ImageGenerationRequest,
|
|
83
|
-
ImageGenerationResult,
|
|
84
|
-
ImageGenProvider,
|
|
85
|
-
} from "./types.js";
|
|
79
|
+
export type { ImageGenCredentials } from "./types.js";
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
MemoryV2ConceptRowRecord,
|
|
3
3
|
MemoryV2ConfigSnapshot,
|
|
4
|
-
MemoryV2SkillRowRecord,
|
|
5
4
|
} from "../../memory-v2-activation-log-store.js";
|
|
6
5
|
|
|
7
6
|
export const sampleConcepts: MemoryV2ConceptRowRecord[] = [
|
|
@@ -13,10 +12,28 @@ export const sampleConcepts: MemoryV2ConceptRowRecord[] = [
|
|
|
13
12
|
simUser: 0.6,
|
|
14
13
|
simAssistant: 0.4,
|
|
15
14
|
simNow: 0.3,
|
|
15
|
+
simUserRerankBoost: 0,
|
|
16
|
+
simAssistantRerankBoost: 0,
|
|
17
|
+
inRerankPool: false,
|
|
16
18
|
spreadContribution: 0.2,
|
|
17
19
|
source: "both",
|
|
18
20
|
status: "injected",
|
|
19
21
|
},
|
|
22
|
+
{
|
|
23
|
+
slug: "skills/skill-1",
|
|
24
|
+
finalActivation: 0.8,
|
|
25
|
+
ownActivation: 0.8,
|
|
26
|
+
priorActivation: 0,
|
|
27
|
+
simUser: 0.5,
|
|
28
|
+
simAssistant: 0.4,
|
|
29
|
+
simNow: 0.3,
|
|
30
|
+
simUserRerankBoost: 0,
|
|
31
|
+
simAssistantRerankBoost: 0,
|
|
32
|
+
inRerankPool: false,
|
|
33
|
+
spreadContribution: 0,
|
|
34
|
+
source: "ann_top50",
|
|
35
|
+
status: "injected",
|
|
36
|
+
},
|
|
20
37
|
{
|
|
21
38
|
slug: "concept-b",
|
|
22
39
|
finalActivation: 0.4,
|
|
@@ -25,23 +42,15 @@ export const sampleConcepts: MemoryV2ConceptRowRecord[] = [
|
|
|
25
42
|
simUser: 0.2,
|
|
26
43
|
simAssistant: 0.1,
|
|
27
44
|
simNow: 0.05,
|
|
45
|
+
simUserRerankBoost: 0,
|
|
46
|
+
simAssistantRerankBoost: 0,
|
|
47
|
+
inRerankPool: false,
|
|
28
48
|
spreadContribution: 0.0,
|
|
29
49
|
source: "ann_top50",
|
|
30
50
|
status: "not_injected",
|
|
31
51
|
},
|
|
32
52
|
];
|
|
33
53
|
|
|
34
|
-
export const sampleSkills: MemoryV2SkillRowRecord[] = [
|
|
35
|
-
{
|
|
36
|
-
id: "skill-1",
|
|
37
|
-
activation: 0.8,
|
|
38
|
-
simUser: 0.5,
|
|
39
|
-
simAssistant: 0.4,
|
|
40
|
-
simNow: 0.3,
|
|
41
|
-
status: "injected",
|
|
42
|
-
},
|
|
43
|
-
];
|
|
44
|
-
|
|
45
54
|
export const sampleConfig: MemoryV2ConfigSnapshot = {
|
|
46
55
|
d: 0.85,
|
|
47
56
|
c_user: 1.0,
|
|
@@ -50,6 +59,5 @@ export const sampleConfig: MemoryV2ConfigSnapshot = {
|
|
|
50
59
|
k: 5,
|
|
51
60
|
hops: 2,
|
|
52
61
|
top_k: 10,
|
|
53
|
-
top_k_skills: 3,
|
|
54
62
|
epsilon: 0.001,
|
|
55
63
|
};
|