@vellumai/assistant 0.7.2 → 0.7.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +16 -1
- package/docs/architecture/memory.md +5 -2
- package/node_modules/@vellumai/gateway-client/src/ipc-client.ts +13 -4
- 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 +449 -22
- package/package.json +1 -1
- package/src/__tests__/app-control-flow.test.ts +21 -11
- 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 +62 -1
- package/src/__tests__/background-workers-disk-pressure.test.ts +268 -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__/config-loader-backfill.test.ts +379 -0
- 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 +3 -7
- package/src/__tests__/context-search-memory-v2-source.test.ts +0 -2
- package/src/__tests__/context-search-pkb-source.test.ts +0 -1
- package/src/__tests__/context-search-workspace-source.test.ts +0 -1
- package/src/__tests__/conversation-abort-tool-results.test.ts +6 -0
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +223 -0
- package/src/__tests__/conversation-agent-loop.test.ts +454 -5
- package/src/__tests__/conversation-error.test.ts +150 -3
- package/src/__tests__/conversation-process-callsite.test.ts +43 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +6 -0
- package/src/__tests__/conversation-runtime-assembly.test.ts +65 -0
- package/src/__tests__/conversation-slash-unknown.test.ts +6 -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-app-control.test.ts +15 -4
- package/src/__tests__/conversation-surfaces-data-persist.test.ts +404 -0
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +2 -5
- package/src/__tests__/conversation-workspace-injection.test.ts +6 -0
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +6 -0
- 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 +3 -4
- 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 +18 -6
- package/src/__tests__/injector-disk-pressure.test.ts +224 -0
- 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__/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 +15 -4
- 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__/suggestion-routes.test.ts +46 -0
- package/src/__tests__/twilio-validation.test.ts +2 -2
- 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-safe-storage-limits-release.test.ts +90 -0
- package/src/approvals/guardian-decision-primitive.ts +13 -0
- package/src/approvals/guardian-request-resolvers.ts +16 -17
- package/src/backup/snapshot-lock.ts +2 -27
- package/src/bundler/compiler-tools.ts +3 -2
- package/src/calls/call-conversation-messages.ts +46 -10
- 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 +7 -6
- package/src/cli/commands/oauth/__tests__/connect.test.ts +437 -1
- package/src/cli/commands/oauth/connect.ts +127 -1
- 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/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 +27 -3
- package/src/config/loader.ts +127 -8
- 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 +75 -11
- 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-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 +6 -0
- package/src/daemon/conversation-agent-loop.ts +170 -33
- package/src/daemon/conversation-error.ts +87 -15
- package/src/daemon/conversation-lifecycle.ts +1 -3
- 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 +195 -15
- package/src/daemon/conversation-tool-setup.ts +57 -14
- package/src/daemon/conversation.ts +17 -22
- 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 +0 -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 +46 -21
- package/src/daemon/host-cu-proxy.ts +49 -3
- package/src/daemon/host-file-proxy.ts +43 -7
- package/src/daemon/host-transfer-proxy.ts +95 -4
- package/src/daemon/lifecycle.ts +79 -28
- 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 +14 -4
- 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 +3 -0
- package/src/daemon/profiler-run-store.ts +5 -5
- package/src/daemon/tool-setup-types.ts +2 -2
- package/src/documents/document-store.ts +85 -0
- package/src/filing/filing-service.ts +30 -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 +56 -2
- package/src/ipc/gateway-client.ts +37 -3
- 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 +52 -22
- 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 +5 -4
- package/src/memory/context-search/sources/memory.ts +0 -1
- 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 +32 -21
- package/src/memory/graph/conversation-graph-memory.ts +42 -54
- package/src/memory/graph/extraction.ts +1 -3
- package/src/memory/graph/graph-search.test.ts +10 -67
- package/src/memory/graph/graph-search.ts +1 -20
- package/src/memory/graph/retriever.test.ts +6 -0
- package/src/memory/graph/retriever.ts +6 -10
- package/src/memory/indexer.ts +54 -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-store.ts +48 -0
- package/src/memory/jobs-worker.ts +81 -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 +6 -0
- package/src/memory/qdrant-client.ts +0 -13
- package/src/memory/rerank-local.ts +374 -0
- package/src/memory/search/semantic.ts +6 -67
- package/src/memory/trace-event-store.ts +1 -17
- package/src/memory/v2/__tests__/activation.test.ts +311 -250
- package/src/memory/v2/__tests__/consolidation-job.test.ts +40 -8
- package/src/memory/v2/__tests__/injection.test.ts +157 -167
- package/src/memory/v2/__tests__/prompts-consolidation.test.ts +61 -2
- package/src/memory/v2/__tests__/qdrant.test.ts +16 -0
- package/src/memory/v2/__tests__/reranker.test.ts +338 -0
- package/src/memory/v2/__tests__/sim.test.ts +5 -199
- package/src/memory/v2/__tests__/skill-store.test.ts +71 -65
- package/src/memory/v2/__tests__/static-context.test.ts +76 -1
- package/src/memory/v2/activation.ts +149 -156
- package/src/memory/v2/consolidation-job.ts +62 -12
- package/src/memory/v2/injection.ts +47 -60
- package/src/memory/v2/prompts/consolidation.ts +36 -1
- package/src/memory/v2/qdrant.ts +99 -0
- package/src/memory/v2/reranker.ts +177 -0
- package/src/memory/v2/sim.ts +10 -84
- 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 +22 -0
- package/src/memory/v2/types.ts +10 -10
- package/src/notifications/copy-composer.ts +13 -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/plugins/defaults/injectors.ts +35 -2
- 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 +867 -0
- package/src/proactive-artifact/job.ts +352 -0
- package/src/proactive-artifact/message-copy.ts +41 -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/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 +14 -1
- package/src/runtime/auth/same-actor.ts +216 -0
- package/src/runtime/channel-retry-sweep.ts +65 -1
- package/src/runtime/guardian-reply-router.ts +10 -0
- package/src/runtime/local-actor-identity.ts +52 -11
- package/src/runtime/pending-interactions.ts +8 -0
- 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/client-routes.ts +20 -2
- package/src/runtime/routes/contact-routes.ts +0 -25
- package/src/runtime/routes/conversation-routes.ts +35 -26
- package/src/runtime/routes/debug-bash-routes.ts +163 -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/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/inbound-stages/guardian-reply-intercept.ts +3 -0
- package/src/runtime/routes/index.ts +6 -0
- package/src/runtime/routes/memory-item-routes.test.ts +41 -15
- package/src/runtime/routes/memory-v2-routes.ts +33 -0
- 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/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/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 +12 -9
- package/src/tools/memory/register.ts +1 -2
- package/src/tools/provider-tool-name.ts +28 -0
- package/src/tools/registry.ts +30 -9
- package/src/tools/terminal/shell.ts +9 -1
- package/src/tools/tool-approval-handler.ts +31 -6
- package/src/tools/types.ts +24 -2
- 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 +72 -0
- package/src/workspace/migrations/068-release-notes-local-timezone.ts +65 -0
- package/src/workspace/migrations/registry.ts +8 -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
|
@@ -14,12 +14,16 @@ let mockResolvePlatformCallbackRegistrationContext: () => Promise<
|
|
|
14
14
|
isPlatform: false,
|
|
15
15
|
platformBaseUrl: "",
|
|
16
16
|
assistantId: "",
|
|
17
|
-
hasInternalApiKey: false,
|
|
18
17
|
hasAssistantApiKey: false,
|
|
19
18
|
authHeader: null,
|
|
20
19
|
enabled: false,
|
|
21
20
|
});
|
|
22
21
|
|
|
22
|
+
let mockIpcGetVelayStatus: () => Promise<{
|
|
23
|
+
connected: boolean;
|
|
24
|
+
publicUrl: string | null;
|
|
25
|
+
} | null> = async () => null;
|
|
26
|
+
|
|
23
27
|
// ---------------------------------------------------------------------------
|
|
24
28
|
// Mocks
|
|
25
29
|
// ---------------------------------------------------------------------------
|
|
@@ -47,6 +51,13 @@ mock.module("../../../../security/secure-keys.js", () => ({
|
|
|
47
51
|
onCesClientChanged: () => ({ unsubscribe: () => {} }),
|
|
48
52
|
setCesReconnect: () => {},
|
|
49
53
|
getActiveBackendName: () => "file",
|
|
54
|
+
getActiveBackendInfoAsync: async () => ({
|
|
55
|
+
backend: "encrypted-store",
|
|
56
|
+
storePath: "/tmp/keys.enc",
|
|
57
|
+
storeKeyPath: "/tmp/store.key",
|
|
58
|
+
storeExists: false,
|
|
59
|
+
storeKeyExists: false,
|
|
60
|
+
}),
|
|
50
61
|
_resetBackend: () => {},
|
|
51
62
|
}));
|
|
52
63
|
|
|
@@ -100,6 +111,15 @@ mock.module("../../../../config/loader.js", () => ({
|
|
|
100
111
|
mergeDefaultWorkspaceConfig: () => {},
|
|
101
112
|
}));
|
|
102
113
|
|
|
114
|
+
mock.module("../../../../ipc/gateway-client.js", () => ({
|
|
115
|
+
ipcGetVelayStatus: () => mockIpcGetVelayStatus(),
|
|
116
|
+
ipcCall: async () => undefined,
|
|
117
|
+
ipcCallPersistent: async () => undefined,
|
|
118
|
+
resetPersistentClient: () => {},
|
|
119
|
+
ipcGetFeatureFlags: async () => ({}),
|
|
120
|
+
ipcClassifyRisk: async () => undefined,
|
|
121
|
+
}));
|
|
122
|
+
|
|
103
123
|
// ---------------------------------------------------------------------------
|
|
104
124
|
// Import module under test (after mocks are registered)
|
|
105
125
|
// ---------------------------------------------------------------------------
|
|
@@ -158,11 +178,11 @@ describe("assistant platform status", () => {
|
|
|
158
178
|
isPlatform: false,
|
|
159
179
|
platformBaseUrl: "",
|
|
160
180
|
assistantId: "",
|
|
161
|
-
hasInternalApiKey: false,
|
|
162
181
|
hasAssistantApiKey: false,
|
|
163
182
|
authHeader: null,
|
|
164
183
|
enabled: false,
|
|
165
184
|
});
|
|
185
|
+
mockIpcGetVelayStatus = async () => null;
|
|
166
186
|
process.exitCode = 0;
|
|
167
187
|
});
|
|
168
188
|
|
|
@@ -179,9 +199,8 @@ describe("assistant platform status", () => {
|
|
|
179
199
|
isPlatform: true,
|
|
180
200
|
platformBaseUrl: "https://platform.vellum.ai",
|
|
181
201
|
assistantId: "asst-abc-123",
|
|
182
|
-
hasInternalApiKey: true,
|
|
183
202
|
hasAssistantApiKey: true,
|
|
184
|
-
authHeader: "
|
|
203
|
+
authHeader: "Api-Key assistant-key",
|
|
185
204
|
enabled: true,
|
|
186
205
|
});
|
|
187
206
|
|
|
@@ -209,12 +228,91 @@ describe("assistant platform status", () => {
|
|
|
209
228
|
expect(parsed.isPlatform).toBe(true);
|
|
210
229
|
expect(parsed.baseUrl).toBe("https://platform.vellum.ai");
|
|
211
230
|
expect(parsed.assistantId).toBe("asst-abc-123");
|
|
212
|
-
expect(parsed.hasInternalApiKey).toBe(true);
|
|
213
231
|
expect(parsed.hasAssistantApiKey).toBe(true);
|
|
214
232
|
expect(parsed.hasWebhookSecret).toBe(true);
|
|
215
233
|
expect(parsed.available).toBe(true);
|
|
216
234
|
expect(parsed.organizationId).toBe("org-456");
|
|
217
235
|
expect(parsed.userId).toBe("user-789");
|
|
236
|
+
// velayTunnel is null when gateway is unreachable
|
|
237
|
+
expect(parsed.velayTunnel).toBeNull();
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
test("velayTunnel connected with publicUrl is returned when gateway is live", async () => {
|
|
241
|
+
/**
|
|
242
|
+
* When the gateway is running and the Velay tunnel is connected, the
|
|
243
|
+
* status command includes velayTunnel.connected=true and the public URL.
|
|
244
|
+
*/
|
|
245
|
+
|
|
246
|
+
// GIVEN a connected Velay tunnel reported by the gateway IPC
|
|
247
|
+
mockIpcGetVelayStatus = async () => ({
|
|
248
|
+
connected: true,
|
|
249
|
+
publicUrl: "https://abc123.vellum.ai",
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
// WHEN the status command is run with --json
|
|
253
|
+
const { exitCode, stdout } = await runCommand([
|
|
254
|
+
"platform",
|
|
255
|
+
"status",
|
|
256
|
+
"--json",
|
|
257
|
+
]);
|
|
258
|
+
|
|
259
|
+
// THEN the command succeeds
|
|
260
|
+
expect(exitCode).toBe(0);
|
|
261
|
+
|
|
262
|
+
// AND velayTunnel reflects the live connection
|
|
263
|
+
const parsed = JSON.parse(stdout);
|
|
264
|
+
expect(parsed.velayTunnel).toEqual({
|
|
265
|
+
connected: true,
|
|
266
|
+
publicUrl: "https://abc123.vellum.ai",
|
|
267
|
+
});
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
test("velayTunnel disconnected when gateway reports no active connection", async () => {
|
|
271
|
+
/**
|
|
272
|
+
* When the gateway is running but Velay is not connected (e.g.
|
|
273
|
+
* reconnecting after disconnect), velayTunnel.connected is false.
|
|
274
|
+
*/
|
|
275
|
+
|
|
276
|
+
// GIVEN a disconnected Velay tunnel
|
|
277
|
+
mockIpcGetVelayStatus = async () => ({
|
|
278
|
+
connected: false,
|
|
279
|
+
publicUrl: null,
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
// WHEN the status command is run with --json
|
|
283
|
+
const { exitCode, stdout } = await runCommand([
|
|
284
|
+
"platform",
|
|
285
|
+
"status",
|
|
286
|
+
"--json",
|
|
287
|
+
]);
|
|
288
|
+
|
|
289
|
+
expect(exitCode).toBe(0);
|
|
290
|
+
const parsed = JSON.parse(stdout);
|
|
291
|
+
expect(parsed.velayTunnel).toEqual({ connected: false, publicUrl: null });
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
test("velayTunnel is null when gateway IPC is unreachable", async () => {
|
|
295
|
+
/**
|
|
296
|
+
* When the gateway IPC socket is not available (assistant not running),
|
|
297
|
+
* velayTunnel is null rather than causing the status command to fail.
|
|
298
|
+
*/
|
|
299
|
+
|
|
300
|
+
// GIVEN the gateway IPC throws
|
|
301
|
+
mockIpcGetVelayStatus = async () => {
|
|
302
|
+
throw new Error("ENOENT");
|
|
303
|
+
};
|
|
304
|
+
|
|
305
|
+
// WHEN the status command is run with --json
|
|
306
|
+
const { exitCode, stdout } = await runCommand([
|
|
307
|
+
"platform",
|
|
308
|
+
"status",
|
|
309
|
+
"--json",
|
|
310
|
+
]);
|
|
311
|
+
|
|
312
|
+
// THEN the command still succeeds (graceful fallback)
|
|
313
|
+
expect(exitCode).toBe(0);
|
|
314
|
+
const parsed = JSON.parse(stdout);
|
|
315
|
+
expect(parsed.velayTunnel).toBeNull();
|
|
218
316
|
});
|
|
219
317
|
|
|
220
318
|
test("plain text mode does not emit JSON to stdout", async () => {
|
|
@@ -229,7 +327,6 @@ describe("assistant platform status", () => {
|
|
|
229
327
|
isPlatform: false,
|
|
230
328
|
platformBaseUrl: "",
|
|
231
329
|
assistantId: "",
|
|
232
|
-
hasInternalApiKey: false,
|
|
233
330
|
hasAssistantApiKey: false,
|
|
234
331
|
authHeader: null,
|
|
235
332
|
enabled: false,
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
registerCallbackRoute,
|
|
5
5
|
resolvePlatformCallbackRegistrationContext,
|
|
6
6
|
} from "../../../inbound/platform-callback-registration.js";
|
|
7
|
+
import { ipcGetVelayStatus } from "../../../ipc/gateway-client.js";
|
|
7
8
|
import { credentialKey } from "../../../security/credential-key.js";
|
|
8
9
|
import { getSecureKeyAsync } from "../../../security/secure-keys.js";
|
|
9
10
|
import { log } from "../../logger.js";
|
|
@@ -62,14 +63,14 @@ Fields:
|
|
|
62
63
|
isPlatform Whether IS_PLATFORM is set (boolean)
|
|
63
64
|
baseUrl VELLUM_PLATFORM_URL — the platform gateway base URL
|
|
64
65
|
assistantId This assistant's platform UUID
|
|
65
|
-
hasInternalApiKey Whether PLATFORM_INTERNAL_API_KEY is set (boolean,
|
|
66
|
-
value not disclosed)
|
|
67
66
|
hasAssistantApiKey Whether a stored assistant API key is available
|
|
68
67
|
hasWebhookSecret Whether a stored webhook secret is available (needed
|
|
69
68
|
for email and other inbound webhook channels)
|
|
70
69
|
available Whether callback registration prerequisites are satisfied
|
|
71
70
|
organizationId The platform organization ID (from stored credentials)
|
|
72
71
|
userId The platform user ID (from stored credentials)
|
|
72
|
+
velayTunnel Live Velay tunnel status from the gateway IPC socket
|
|
73
|
+
(null when the gateway is not running)
|
|
73
74
|
|
|
74
75
|
Examples:
|
|
75
76
|
$ assistant platform status
|
|
@@ -77,7 +78,10 @@ Examples:
|
|
|
77
78
|
)
|
|
78
79
|
.action(async (_opts: Record<string, unknown>, cmd: Command) => {
|
|
79
80
|
try {
|
|
80
|
-
const context = await
|
|
81
|
+
const [context, velayTunnel] = await Promise.all([
|
|
82
|
+
resolvePlatformCallbackRegistrationContext(),
|
|
83
|
+
ipcGetVelayStatus().catch(() => null),
|
|
84
|
+
]);
|
|
81
85
|
|
|
82
86
|
const organizationId =
|
|
83
87
|
(
|
|
@@ -106,12 +110,12 @@ Examples:
|
|
|
106
110
|
isPlatform: context.isPlatform,
|
|
107
111
|
baseUrl: context.platformBaseUrl,
|
|
108
112
|
assistantId: context.assistantId,
|
|
109
|
-
hasInternalApiKey: context.hasInternalApiKey,
|
|
110
113
|
hasAssistantApiKey: context.hasAssistantApiKey,
|
|
111
114
|
hasWebhookSecret,
|
|
112
115
|
available: context.enabled,
|
|
113
116
|
organizationId: organizationId || null,
|
|
114
117
|
userId: userId || null,
|
|
118
|
+
velayTunnel,
|
|
115
119
|
};
|
|
116
120
|
|
|
117
121
|
if (shouldOutputJson(cmd)) {
|
|
@@ -120,9 +124,6 @@ Examples:
|
|
|
120
124
|
log.info(`Platform: ${result.isPlatform}`);
|
|
121
125
|
log.info(`Base URL: ${result.baseUrl || "(not set)"}`);
|
|
122
126
|
log.info(`Assistant ID: ${result.assistantId || "(not set)"}`);
|
|
123
|
-
log.info(
|
|
124
|
-
`Internal API key: ${result.hasInternalApiKey ? "set" : "not set"}`,
|
|
125
|
-
);
|
|
126
127
|
log.info(
|
|
127
128
|
`Assistant API key: ${result.hasAssistantApiKey ? "set" : "not set"}`,
|
|
128
129
|
);
|
|
@@ -134,6 +135,14 @@ Examples:
|
|
|
134
135
|
);
|
|
135
136
|
log.info(`Organization ID: ${organizationId || "(not set)"}`);
|
|
136
137
|
log.info(`User ID: ${userId || "(not set)"}`);
|
|
138
|
+
if (result.velayTunnel !== null) {
|
|
139
|
+
const tunnelState = result.velayTunnel.connected
|
|
140
|
+
? `connected${result.velayTunnel.publicUrl ? ` (${result.velayTunnel.publicUrl})` : ""}`
|
|
141
|
+
: "disconnected";
|
|
142
|
+
log.info(`Velay tunnel: ${tunnelState}`);
|
|
143
|
+
} else {
|
|
144
|
+
log.info(`Velay tunnel: (gateway not running)`);
|
|
145
|
+
}
|
|
137
146
|
}
|
|
138
147
|
} catch (err) {
|
|
139
148
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { Command } from "commander";
|
|
2
|
+
|
|
3
|
+
import { cliIpcCall } from "../../ipc/cli-client.js";
|
|
4
|
+
import { getWorkspaceDirDisplay } from "../../util/platform.js";
|
|
5
|
+
import { log } from "../logger.js";
|
|
6
|
+
|
|
7
|
+
interface HealthResponse {
|
|
8
|
+
version: string;
|
|
9
|
+
memory: { currentMb: number; maxMb: number };
|
|
10
|
+
disk: { freeMb: number; totalMb: number } | null;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function fmtMb(mb: number): string {
|
|
14
|
+
if (mb >= 1024) return `${(mb / 1024).toFixed(1)} GB`;
|
|
15
|
+
return `${Math.round(mb)} MB`;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function registerStatusCommand(program: Command): void {
|
|
19
|
+
program
|
|
20
|
+
.command("status")
|
|
21
|
+
.description("Show assistant version, workspace, and runtime health")
|
|
22
|
+
.action(async () => {
|
|
23
|
+
const result = await cliIpcCall<HealthResponse>("health");
|
|
24
|
+
|
|
25
|
+
if (!result.ok || !result.result) {
|
|
26
|
+
log.error(
|
|
27
|
+
result.error ??
|
|
28
|
+
"Assistant not running — could not connect to IPC socket.",
|
|
29
|
+
);
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const h = result.result;
|
|
34
|
+
const workspace = getWorkspaceDirDisplay();
|
|
35
|
+
|
|
36
|
+
const rows: [string, string][] = [
|
|
37
|
+
["Version", h.version],
|
|
38
|
+
["Workspace", workspace],
|
|
39
|
+
["", ""],
|
|
40
|
+
["Memory", `${fmtMb(h.memory.currentMb)} / ${fmtMb(h.memory.maxMb)}`],
|
|
41
|
+
...(h.disk
|
|
42
|
+
? ([["Disk", `${fmtMb(h.disk.freeMb)} free`]] as [string, string][])
|
|
43
|
+
: []),
|
|
44
|
+
];
|
|
45
|
+
|
|
46
|
+
const labelWidth = Math.max(
|
|
47
|
+
...rows.filter(([l]) => l).map(([l]) => l.length),
|
|
48
|
+
);
|
|
49
|
+
for (const [label, value] of rows) {
|
|
50
|
+
if (!label) {
|
|
51
|
+
log.info("");
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
log.info(`${label.padEnd(labelWidth)} ${value}`);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
}
|
package/src/cli/program.ts
CHANGED
|
@@ -41,6 +41,7 @@ import { registerPlatformCommand } from "./commands/platform/index.js";
|
|
|
41
41
|
import { registerRoutesCommand } from "./commands/routes.js";
|
|
42
42
|
import { registerSequenceCommand } from "./commands/sequence.js";
|
|
43
43
|
import { registerSkillsCommand } from "./commands/skills.js";
|
|
44
|
+
import { registerStatusCommand } from "./commands/status.js";
|
|
44
45
|
import { registerSttCommand } from "./commands/stt.js";
|
|
45
46
|
import { registerTaskCommand } from "./commands/task.js";
|
|
46
47
|
import { registerTrustCommand } from "./commands/trust.js";
|
|
@@ -56,7 +57,7 @@ import { log } from "./logger.js";
|
|
|
56
57
|
* the gateway so flag-gated commands are registered correctly.
|
|
57
58
|
*/
|
|
58
59
|
export async function buildCliProgram(): Promise<Command> {
|
|
59
|
-
await initFeatureFlagOverrides();
|
|
60
|
+
await initFeatureFlagOverrides({ retryBackoffsMs: [], callTimeoutMs: 200 });
|
|
60
61
|
const program = new Command();
|
|
61
62
|
|
|
62
63
|
program
|
|
@@ -110,6 +111,7 @@ Examples:
|
|
|
110
111
|
registerPlatformCommand(program);
|
|
111
112
|
registerRoutesCommand(program);
|
|
112
113
|
registerSequenceCommand(program);
|
|
114
|
+
registerStatusCommand(program);
|
|
113
115
|
registerSkillsCommand(program);
|
|
114
116
|
registerSttCommand(program);
|
|
115
117
|
registerTaskCommand(program);
|
|
@@ -126,7 +128,7 @@ Examples:
|
|
|
126
128
|
// remain available even without a workspace.
|
|
127
129
|
// Workspace-independent commands are exempt:
|
|
128
130
|
// completions — pure shell-script generation, no workspace files needed
|
|
129
|
-
const workspaceExemptCommands = new Set(["completions"]);
|
|
131
|
+
const workspaceExemptCommands = new Set(["completions", "status"]);
|
|
130
132
|
program.hook("preAction", (_thisCommand, actionCommand) => {
|
|
131
133
|
if (workspaceExemptCommands.has(actionCommand.name())) {
|
|
132
134
|
return;
|
|
@@ -135,9 +135,11 @@ let cachedOverridesFromGateway = false;
|
|
|
135
135
|
* timeout, parse error). No auth needed — the IPC socket is
|
|
136
136
|
* access-controlled by file-system permissions on the shared volume.
|
|
137
137
|
*/
|
|
138
|
-
async function fetchOverridesFromGateway(
|
|
138
|
+
async function fetchOverridesFromGateway(
|
|
139
|
+
timeoutMs?: number,
|
|
140
|
+
): Promise<Record<string, boolean>> {
|
|
139
141
|
try {
|
|
140
|
-
return await ipcGetFeatureFlags();
|
|
142
|
+
return await ipcGetFeatureFlags(timeoutMs);
|
|
141
143
|
} catch {
|
|
142
144
|
return {};
|
|
143
145
|
}
|
|
@@ -182,10 +184,18 @@ const DEFAULT_INIT_RETRY_BACKOFFS_MS: readonly number[] = [
|
|
|
182
184
|
*/
|
|
183
185
|
export async function initFeatureFlagOverrides(options?: {
|
|
184
186
|
retryBackoffsMs?: readonly number[];
|
|
187
|
+
/**
|
|
188
|
+
* Timeout (ms) for each IPC call to the gateway. When omitted the
|
|
189
|
+
* transport defaults apply (3 s connect + 5 s call). CLI callers should
|
|
190
|
+
* pass a small value (e.g. 200) so a slow/absent gateway fails fast
|
|
191
|
+
* instead of blocking startup.
|
|
192
|
+
*/
|
|
193
|
+
callTimeoutMs?: number;
|
|
185
194
|
}): Promise<void> {
|
|
186
195
|
if (cachedOverridesFromGateway) return;
|
|
187
196
|
|
|
188
197
|
const backoffs = options?.retryBackoffsMs ?? DEFAULT_INIT_RETRY_BACKOFFS_MS;
|
|
198
|
+
const callTimeoutMs = options?.callTimeoutMs;
|
|
189
199
|
|
|
190
200
|
// First attempt has no preceding delay; subsequent attempts wait per the
|
|
191
201
|
// backoff schedule. An empty result is treated as a transient miss
|
|
@@ -201,7 +211,7 @@ export async function initFeatureFlagOverrides(options?: {
|
|
|
201
211
|
if (cachedOverridesFromGateway) return;
|
|
202
212
|
}
|
|
203
213
|
|
|
204
|
-
const gatewayOverrides = await fetchOverridesFromGateway();
|
|
214
|
+
const gatewayOverrides = await fetchOverridesFromGateway(callTimeoutMs);
|
|
205
215
|
if (Object.keys(gatewayOverrides).length > 0) {
|
|
206
216
|
cachedOverrides = gatewayOverrides;
|
|
207
217
|
cachedOverridesFromGateway = true;
|
|
@@ -67,7 +67,8 @@ function upsertMemoryItem(opts: {
|
|
|
67
67
|
created: now,
|
|
68
68
|
lastAccessed: now,
|
|
69
69
|
lastConsolidated: now,
|
|
70
|
-
emotionalCharge:
|
|
70
|
+
emotionalCharge:
|
|
71
|
+
'{"valence":0,"intensity":0.1,"decayCurve":"linear","decayRate":0.05,"originalIntensity":0.1}',
|
|
71
72
|
fidelity: "vivid",
|
|
72
73
|
confidence: 0.8,
|
|
73
74
|
significance: clampUnitInterval(opts.importance),
|
|
@@ -87,7 +88,7 @@ function upsertMemoryItem(opts: {
|
|
|
87
88
|
|
|
88
89
|
export async function run(
|
|
89
90
|
input: Record<string, unknown>,
|
|
90
|
-
|
|
91
|
+
_context: ToolContext,
|
|
91
92
|
): Promise<ToolExecutionResult> {
|
|
92
93
|
const platform = input.platform as string | undefined;
|
|
93
94
|
const maxMessages = Math.min(
|
|
@@ -119,7 +120,7 @@ export async function run(
|
|
|
119
120
|
return err("No style patterns were extracted. Try with more messages.");
|
|
120
121
|
}
|
|
121
122
|
|
|
122
|
-
const scopeId =
|
|
123
|
+
const scopeId = "default";
|
|
123
124
|
let savedCount = 0;
|
|
124
125
|
|
|
125
126
|
for (const pattern of result.stylePatterns) {
|
|
@@ -10,18 +10,24 @@ Run `assistant config set calls.enabled true`.
|
|
|
10
10
|
|
|
11
11
|
## "No public base URL configured"
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
First check whether this is a managed/platform assistant:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
assistant platform status --json
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
If it reports an available platform assistant, do not install or start ngrok for Twilio. The gateway should use Velay, and `velayTunnel.connected` should become `true` after registration. If this is a local/self-hosted assistant without Velay, run the **public-ingress** skill to set up ngrok or another custom tunnel and configure `ingress.publicBaseUrl`.
|
|
14
20
|
|
|
15
21
|
## Call fails immediately after initiating
|
|
16
22
|
|
|
17
23
|
- Check that the phone number is in E.164 format
|
|
18
24
|
- Verify Twilio credentials are correct (wrong auth token causes API errors)
|
|
19
25
|
- On trial accounts, ensure the destination number is verified
|
|
20
|
-
- Check that the configured tunnel is still running. For ngrok, use `curl -s http://127.0.0.1:4040/api/tunnels`. For Velay, confirm
|
|
26
|
+
- Check that the configured tunnel is still running. For ngrok, use `curl -s http://127.0.0.1:4040/api/tunnels`. For Velay, run `assistant platform status --json` and confirm `velayTunnel.connected` is `true`, or check gateway logs for `Velay tunnel registered`.
|
|
21
27
|
|
|
22
28
|
## Call connects but no audio / one-way audio
|
|
23
29
|
|
|
24
|
-
- The ConversationRelay WebSocket may not be connecting. If you are using ngrok or a custom tunnel, check that `ingress.publicBaseUrl` is correct and the tunnel is active. If you are using Velay, check
|
|
30
|
+
- The ConversationRelay WebSocket may not be connecting. If you are using ngrok or a custom tunnel, check that `ingress.publicBaseUrl` is correct and the tunnel is active. If you are using Velay, check `assistant platform status --json`; a 503 from `https://velay.../<assistant-id>/...` usually means the assistant tunnel is not connected or the gateway did not complete the WebSocket open, not that ngrok is required.
|
|
25
31
|
- Verify the assistant is running
|
|
26
32
|
|
|
27
33
|
## "Number not eligible for caller identity"
|
|
@@ -50,20 +56,20 @@ assistant config set ingress.publicBaseUrl "<new-url>"
|
|
|
50
56
|
|
|
51
57
|
Or re-run the public-ingress skill to auto-detect and save the new URL.
|
|
52
58
|
|
|
53
|
-
|
|
59
|
+
Do not rotate ngrok to work around a managed Velay WebSocket failure. Fix the Velay tunnel state instead, or restart the assistant/gateway so it re-registers.
|
|
54
60
|
|
|
55
61
|
## Velay tunnel is not registering
|
|
56
62
|
|
|
57
|
-
- Confirm vembda passes `VELAY_BASE_URL
|
|
63
|
+
- Confirm vembda passes the environment-appropriate `VELAY_BASE_URL` to the gateway container.
|
|
58
64
|
- Re-hatch or restart the assistant after changing the environment.
|
|
59
65
|
- Check gateway logs for `Velay tunnel connected` followed by `Velay tunnel registered`.
|
|
60
|
-
- If `VELAY_BASE_URL` is not set, the gateway does not start the Velay client. Use ngrok or another custom tunnel in `ingress.publicBaseUrl`.
|
|
66
|
+
- If `VELAY_BASE_URL` is not set on a local/self-hosted assistant, the gateway does not start the Velay client. Use ngrok or another custom tunnel in `ingress.publicBaseUrl`.
|
|
61
67
|
|
|
62
68
|
## Local Twilio Velay smoke tests
|
|
63
69
|
|
|
64
70
|
- HTTP bridge: request `${VELAY_PUBLIC_BASE_URL}/<assistant-id>/healthz` and `${VELAY_PUBLIC_BASE_URL}/<assistant-id>/schema`. When testing a JSON webhook route under active development, POST a small JSON body through the same Velay public URL and confirm the gateway receives it.
|
|
65
71
|
- Synthetic WebSocket: connect a local WebSocket client to `${VELAY_PUBLIC_BASE_URL}/<assistant-id>/webhooks/twilio/relay?callSessionId=session-123&token=<edge-token>` and confirm the upgrade reaches the gateway.
|
|
66
|
-
- Real Twilio call:
|
|
72
|
+
- Real Twilio call: wait for the gateway to register with Velay, then place a call and confirm Twilio fetches `/webhooks/twilio/voice` and opens the relay or media-stream WebSocket through the Velay URL.
|
|
67
73
|
|
|
68
74
|
## Call drops after 30 seconds of silence
|
|
69
75
|
|
|
@@ -18,7 +18,7 @@ const VALID_AUTONOMY_LEVELS = new Set<string>(["auto", "draft", "notify"]);
|
|
|
18
18
|
|
|
19
19
|
export async function executePlaybookCreate(
|
|
20
20
|
input: Record<string, unknown>,
|
|
21
|
-
|
|
21
|
+
_context: ToolContext,
|
|
22
22
|
): Promise<ToolExecutionResult> {
|
|
23
23
|
const trigger = input.trigger as string;
|
|
24
24
|
const action = input.action as string;
|
|
@@ -58,7 +58,7 @@ export async function executePlaybookCreate(
|
|
|
58
58
|
const sanitizedTrigger = trigger.replace(/[\r\n]+/g, " ");
|
|
59
59
|
const subject = `Playbook: ${sanitizedTrigger}`.slice(0, 80);
|
|
60
60
|
const content = `${subject}\n${statement}`;
|
|
61
|
-
const scopeId =
|
|
61
|
+
const scopeId = "default";
|
|
62
62
|
|
|
63
63
|
try {
|
|
64
64
|
const db = getDb();
|
|
@@ -7,7 +7,7 @@ import type {
|
|
|
7
7
|
|
|
8
8
|
export async function executePlaybookDelete(
|
|
9
9
|
input: Record<string, unknown>,
|
|
10
|
-
|
|
10
|
+
_context: ToolContext,
|
|
11
11
|
): Promise<ToolExecutionResult> {
|
|
12
12
|
const playbookId = input.playbook_id as string;
|
|
13
13
|
if (!playbookId || typeof playbookId !== "string") {
|
|
@@ -17,7 +17,7 @@ export async function executePlaybookDelete(
|
|
|
17
17
|
};
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
const scopeId =
|
|
20
|
+
const scopeId = "default";
|
|
21
21
|
|
|
22
22
|
try {
|
|
23
23
|
const existing = getNode(playbookId);
|
|
@@ -10,9 +10,9 @@ import type {
|
|
|
10
10
|
|
|
11
11
|
export async function executePlaybookList(
|
|
12
12
|
input: Record<string, unknown>,
|
|
13
|
-
|
|
13
|
+
_context: ToolContext,
|
|
14
14
|
): Promise<ToolExecutionResult> {
|
|
15
|
-
const scopeId =
|
|
15
|
+
const scopeId = "default";
|
|
16
16
|
const channelFilter =
|
|
17
17
|
typeof input.channel === "string" ? input.channel : null;
|
|
18
18
|
const categoryFilter =
|
|
@@ -18,7 +18,7 @@ const VALID_AUTONOMY_LEVELS = new Set<string>(["auto", "draft", "notify"]);
|
|
|
18
18
|
|
|
19
19
|
export async function executePlaybookUpdate(
|
|
20
20
|
input: Record<string, unknown>,
|
|
21
|
-
|
|
21
|
+
_context: ToolContext,
|
|
22
22
|
): Promise<ToolExecutionResult> {
|
|
23
23
|
const playbookId = input.playbook_id as string;
|
|
24
24
|
if (!playbookId || typeof playbookId !== "string") {
|
|
@@ -28,7 +28,7 @@ export async function executePlaybookUpdate(
|
|
|
28
28
|
};
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
const scopeId =
|
|
31
|
+
const scopeId = "default";
|
|
32
32
|
|
|
33
33
|
try {
|
|
34
34
|
const existing = getNode(playbookId);
|
package/src/config/env.ts
CHANGED
|
@@ -253,14 +253,6 @@ export function getPlatformUserId(): string {
|
|
|
253
253
|
return str("PLATFORM_USER_ID") ?? _platformUserIdOverride ?? "";
|
|
254
254
|
}
|
|
255
255
|
|
|
256
|
-
/**
|
|
257
|
-
* PLATFORM_INTERNAL_API_KEY — static internal gateway key for authenticating
|
|
258
|
-
* with the platform's internal gateway callback route registration endpoint.
|
|
259
|
-
*/
|
|
260
|
-
export function getPlatformInternalApiKey(): string {
|
|
261
|
-
return str("PLATFORM_INTERNAL_API_KEY") ?? "";
|
|
262
|
-
}
|
|
263
|
-
|
|
264
256
|
// ── Startup validation ──────────────────────────────────────────────────────
|
|
265
257
|
|
|
266
258
|
/**
|
|
@@ -241,13 +241,21 @@
|
|
|
241
241
|
"description": "Expose the developer-only Compaction Playground tab in macOS Settings and enable the /playground/* HTTP endpoints for exercising compaction conditions. Dev-only; default off.",
|
|
242
242
|
"defaultEnabled": false
|
|
243
243
|
},
|
|
244
|
+
{
|
|
245
|
+
"id": "safe-storage-limits",
|
|
246
|
+
"scope": "assistant",
|
|
247
|
+
"key": "safe-storage-limits",
|
|
248
|
+
"label": "Safe Storage Limits",
|
|
249
|
+
"description": "Enable disk pressure protection flows that block background work and remote actors while storage is critically low.",
|
|
250
|
+
"defaultEnabled": false
|
|
251
|
+
},
|
|
244
252
|
{
|
|
245
253
|
"id": "memory-v2-enabled",
|
|
246
254
|
"scope": "assistant",
|
|
247
255
|
"key": "memory-v2-enabled",
|
|
248
256
|
"label": "Memory v2 (concept-page activation model)",
|
|
249
|
-
"description": "Enables the v2 memory subsystem: prose concept pages with bidirectional edges, activation-based retrieval, and hourly LLM-driven consolidation. v1 graph
|
|
250
|
-
"defaultEnabled":
|
|
257
|
+
"description": "Enables the v2 memory subsystem: prose concept pages with bidirectional edges, activation-based retrieval, and hourly LLM-driven consolidation. When on, v1 graph extraction/maintenance and PKB filing are suppressed; flipping the flag back off re-engages the full v1 pipeline.",
|
|
258
|
+
"defaultEnabled": true
|
|
251
259
|
},
|
|
252
260
|
{
|
|
253
261
|
"id": "account-deletion",
|
|
@@ -255,7 +263,7 @@
|
|
|
255
263
|
"key": "account-deletion",
|
|
256
264
|
"label": "Account Deletion",
|
|
257
265
|
"description": "Surfaces the user-initiated account deletion flow in client settings.",
|
|
258
|
-
"defaultEnabled":
|
|
266
|
+
"defaultEnabled": true
|
|
259
267
|
},
|
|
260
268
|
{
|
|
261
269
|
"id": "app-control",
|
|
@@ -272,6 +280,22 @@
|
|
|
272
280
|
"label": "Analyze Conversation",
|
|
273
281
|
"description": "Show the 'Analyze' / 'Analyze conversation' option in conversation context menus and the conversation title actions dropdown.",
|
|
274
282
|
"defaultEnabled": false
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
"id": "pro-plan-adjust",
|
|
286
|
+
"scope": "assistant",
|
|
287
|
+
"key": "pro-plan-adjust",
|
|
288
|
+
"label": "Pro Plan Adjust",
|
|
289
|
+
"description": "Show the rich Plan card (current plan, features, Manage/Upgrade CTA) at the top of the macOS Settings → Billing tab. The 'Configure Auto Top Ups' CTA is gated separately on `auto-credit-topup`.",
|
|
290
|
+
"defaultEnabled": false
|
|
291
|
+
},
|
|
292
|
+
{
|
|
293
|
+
"id": "auto-credit-topup",
|
|
294
|
+
"scope": "assistant",
|
|
295
|
+
"key": "auto-credit-topup",
|
|
296
|
+
"label": "Auto Credit Top-Up",
|
|
297
|
+
"description": "Show the 'Configure Auto Top Ups' CTA in the macOS Settings → Billing tab. Mirrors the platform web flag of the same name that gates the auto-reload card and /v1/organizations/billing/auto-top-up/ API.",
|
|
298
|
+
"defaultEnabled": false
|
|
275
299
|
}
|
|
276
300
|
]
|
|
277
301
|
}
|