@vellumai/assistant 0.6.0 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +4 -0
- package/ARCHITECTURE.md +68 -15
- package/Dockerfile +2 -2
- package/bun.lock +6 -2
- package/docker-entrypoint.sh +32 -1
- package/docs/architecture/integrations.md +1 -1
- package/docs/architecture/memory.md +21 -24
- package/openapi.yaml +538 -3
- package/package.json +5 -1
- package/src/__tests__/anthropic-provider.test.ts +160 -95
- package/src/__tests__/app-dir-path-guard.test.ts +1 -0
- package/src/__tests__/app-executors.test.ts +47 -1
- package/src/__tests__/app-source-watcher.test.ts +159 -0
- package/src/__tests__/checker.test.ts +38 -6
- package/src/__tests__/config-schema.test.ts +5 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +4 -6
- package/src/__tests__/conversation-agent-loop.test.ts +4 -51
- package/src/__tests__/conversation-history-web-search.test.ts +1 -1
- package/src/__tests__/conversation-runtime-assembly.test.ts +653 -832
- package/src/__tests__/conversation-runtime-workspace.test.ts +1 -93
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +17 -4
- package/src/__tests__/conversation-wipe.test.ts +2 -6
- package/src/__tests__/conversation-workspace-cache-state.test.ts +6 -12
- package/src/__tests__/conversation-workspace-injection.test.ts +25 -26
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +1 -1
- package/src/__tests__/copy-composer-tc-templates.test.ts +335 -0
- package/src/__tests__/date-context.test.ts +76 -210
- package/src/__tests__/db-schedule-syntax-migration.test.ts +16 -1
- package/src/__tests__/file-list-tool.test.ts +219 -0
- package/src/__tests__/first-greeting.test.ts +1 -1
- package/src/__tests__/heartbeat-service.test.ts +180 -3
- package/src/__tests__/identity-routes.test.ts +328 -0
- package/src/__tests__/injection-block.test.ts +24 -0
- package/src/__tests__/install-skill-routing.test.ts +7 -6
- package/src/__tests__/jobs-store-qdrant-breaker.test.ts +15 -14
- package/src/__tests__/list-messages-tool-merge.test.ts +300 -0
- package/src/__tests__/llm-context-normalization.test.ts +18 -18
- package/src/__tests__/llm-context-route-provider.test.ts +101 -0
- package/src/__tests__/llm-request-log-turn-query.test.ts +162 -0
- package/src/__tests__/log-export-workspace.test.ts +72 -105
- package/src/__tests__/mcp-abort-signal.test.ts +5 -0
- package/src/__tests__/mcp-client-auth.test.ts +5 -0
- package/src/__tests__/memory-recall-log-store.test.ts +132 -0
- package/src/__tests__/migration-export-streaming.test.ts +304 -0
- package/src/__tests__/migration-import-commit-http.test.ts +11 -10
- package/src/__tests__/mock-fetch.ts +87 -0
- package/src/__tests__/notification-decision-recipient-context.test.ts +282 -0
- package/src/__tests__/onboarding-template-contract.test.ts +62 -14
- package/src/__tests__/parser.test.ts +32 -0
- package/src/__tests__/permission-checker-host-gate.test.ts +452 -0
- package/src/__tests__/permission-controls-v2-flag.test.ts +55 -0
- package/src/__tests__/permission-mode-sse.test.ts +418 -0
- package/src/__tests__/permission-mode-store.test.ts +277 -0
- package/src/__tests__/permission-mode.test.ts +101 -0
- package/src/__tests__/platform-bash-auto-approve.test.ts +359 -0
- package/src/__tests__/profiler-routes.test.ts +502 -0
- package/src/__tests__/profiler-run-store.test.ts +441 -0
- package/src/__tests__/proxy-approval-callback.test.ts +4 -75
- package/src/__tests__/registry.test.ts +1 -1
- package/src/__tests__/sandbox-host-parity.test.ts +5 -4
- package/src/__tests__/scheduler-reuse-conversation.test.ts +368 -0
- package/src/__tests__/scrub-corrupted-image-attachments.test.ts +278 -0
- package/src/__tests__/search-skills-unified.test.ts +4 -3
- package/src/__tests__/send-endpoint-busy.test.ts +42 -3
- package/src/__tests__/set-permission-mode.test.ts +274 -0
- package/src/__tests__/skill-load-feature-flag.test.ts +12 -0
- package/src/__tests__/skill-memory.test.ts +2 -783
- package/src/__tests__/strip-memory-injections.test.ts +187 -0
- package/src/__tests__/subagent-detail.test.ts +84 -0
- package/src/__tests__/subagent-disposal.test.ts +308 -0
- package/src/__tests__/subagent-manager-notify.test.ts +19 -10
- package/src/__tests__/subagent-notify-parent.test.ts +390 -0
- package/src/__tests__/subagent-role-registry.test.ts +108 -0
- package/src/__tests__/subagent-tool-filtering.test.ts +71 -0
- package/src/__tests__/subagent-tools.test.ts +464 -4
- package/src/__tests__/system-prompt-ask-mode.test.ts +139 -0
- package/src/__tests__/task-memory-cleanup.test.ts +12 -12
- package/src/__tests__/terminal-tools.test.ts +17 -27
- package/src/__tests__/test-preload.ts +4 -0
- package/src/__tests__/tool-executor.test.ts +4 -26
- package/src/__tests__/tool-side-effects-slack-dm.test.ts +1 -0
- package/src/__tests__/top-level-renderer.test.ts +10 -13
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +116 -2
- package/src/__tests__/workspace-migration-028-recover-conversations-from-disk-view.test.ts +387 -0
- package/src/agent/loop.ts +6 -0
- package/src/approvals/guardian-request-resolvers.ts +24 -0
- package/src/avatar/traits-png-sync.ts +3 -3
- package/src/cli/__tests__/run-assistant-command.ts +29 -0
- package/src/cli/commands/__tests__/email-download.test.ts +245 -0
- package/src/cli/commands/__tests__/email-list.test.ts +192 -0
- package/src/cli/commands/__tests__/email-register.test.ts +186 -0
- package/src/cli/commands/__tests__/email-send.test.ts +291 -0
- package/src/cli/commands/__tests__/email-status.test.ts +181 -0
- package/src/cli/commands/__tests__/email-unregister.test.ts +139 -0
- package/src/cli/commands/__tests__/routes.test.ts +562 -0
- package/src/cli/commands/conversations.ts +1 -8
- package/src/cli/commands/email.ts +584 -835
- package/src/cli/commands/memory.ts +1 -34
- package/src/cli/commands/notifications.ts +7 -2
- package/src/cli/commands/oauth/connect.ts +14 -5
- package/src/cli/commands/routes.ts +396 -0
- package/src/cli/commands/skills.ts +130 -20
- package/src/cli/program.ts +2 -0
- package/src/cli.ts +1 -120
- package/src/config/bundled-skills/app-builder/SKILL.md +4 -1
- package/src/config/bundled-skills/gmail/SKILL.md +2 -2
- package/src/config/bundled-skills/messaging/SKILL.md +7 -0
- package/src/config/bundled-skills/schedule/SKILL.md +22 -2
- package/src/config/bundled-skills/schedule/TOOLS.json +8 -0
- package/src/config/bundled-skills/settings/tools/avatar-get.ts +3 -13
- package/src/config/bundled-skills/settings/tools/avatar-remove.ts +2 -4
- package/src/config/bundled-skills/settings/tools/avatar-update.ts +5 -2
- package/src/config/bundled-skills/slack/SKILL.md +2 -0
- package/src/config/bundled-skills/subagent/SKILL.md +43 -3
- package/src/config/bundled-skills/subagent/TOOLS.json +29 -4
- package/src/config/env-registry.ts +63 -0
- package/src/config/feature-flag-registry.json +17 -1
- package/src/config/schema.ts +8 -0
- package/src/config/schemas/filing.ts +51 -0
- package/src/config/schemas/heartbeat.ts +15 -12
- package/src/config/schemas/memory-lifecycle.ts +12 -0
- package/src/config/schemas/security.ts +14 -0
- package/src/daemon/app-source-watcher.ts +93 -0
- package/src/daemon/config-watcher.ts +79 -1
- package/src/daemon/conversation-agent-loop-handlers.ts +20 -0
- package/src/daemon/conversation-agent-loop.ts +158 -65
- package/src/daemon/conversation-history.ts +4 -19
- package/src/daemon/conversation-lifecycle.ts +8 -14
- package/src/daemon/conversation-process.ts +13 -7
- package/src/daemon/conversation-runtime-assembly.ts +300 -306
- package/src/daemon/conversation-tool-setup.ts +44 -14
- package/src/daemon/conversation-workspace.ts +1 -2
- package/src/daemon/conversation.ts +18 -0
- package/src/daemon/date-context.ts +26 -53
- package/src/daemon/first-greeting.ts +1 -1
- package/src/daemon/handlers/conversations.ts +4 -7
- package/src/daemon/handlers/shared.test.ts +143 -0
- package/src/daemon/handlers/shared.ts +63 -5
- package/src/daemon/handlers/skills.ts +11 -18
- package/src/daemon/lifecycle.ts +199 -157
- package/src/daemon/message-types/conversations.ts +25 -6
- package/src/daemon/message-types/messages.ts +9 -1
- package/src/daemon/message-types/schedules.ts +1 -0
- package/src/daemon/message-types/settings.ts +6 -0
- package/src/daemon/profiler-run-store.ts +557 -0
- package/src/daemon/server.ts +89 -9
- package/src/daemon/shutdown-handlers.ts +5 -0
- package/src/daemon/tool-side-effects.ts +23 -3
- package/src/export/transcript-formatter.ts +148 -0
- package/src/filing/filing-service.ts +228 -0
- package/src/heartbeat/heartbeat-service.ts +96 -7
- package/src/mcp/client.ts +6 -0
- package/src/mcp/mcp-oauth-provider.ts +149 -27
- package/src/memory/admin.ts +33 -32
- package/src/memory/app-store.ts +69 -0
- package/src/memory/conversation-bootstrap.ts +1 -1
- package/src/memory/conversation-crud.ts +136 -107
- package/src/memory/conversation-group-migration.ts +1 -1
- package/src/memory/conversation-queries.ts +58 -12
- package/src/memory/conversation-title-service.ts +1 -0
- package/src/memory/db-init.ts +182 -376
- package/src/memory/graph/bootstrap.ts +75 -66
- package/src/memory/graph/capability-seed.ts +167 -15
- package/src/memory/graph/consolidation.ts +38 -4
- package/src/memory/graph/conversation-graph-memory.ts +133 -104
- package/src/memory/graph/extraction-job.ts +9 -4
- package/src/memory/graph/extraction.ts +66 -23
- package/src/memory/graph/graph-memory-state-store.ts +37 -0
- package/src/memory/graph/graph-search.ts +29 -15
- package/src/memory/graph/injection.ts +38 -8
- package/src/memory/graph/inspect.ts +12 -3
- package/src/memory/graph/retriever.ts +365 -262
- package/src/memory/graph/store.test.ts +48 -0
- package/src/memory/graph/store.ts +150 -11
- package/src/memory/graph/tool-handlers.ts +84 -209
- package/src/memory/graph/tools.ts +8 -52
- package/src/memory/graph/types.ts +24 -0
- package/src/memory/job-handlers/cleanup.ts +44 -1
- package/src/memory/jobs-store.ts +70 -60
- package/src/memory/jobs-worker.ts +44 -28
- package/src/memory/llm-request-log-store.ts +96 -12
- package/src/memory/memory-recall-log-store.ts +49 -5
- package/src/memory/migrations/203-drop-memory-items-tables.ts +33 -1
- package/src/memory/migrations/206-memory-graph-node-edits.ts +19 -0
- package/src/memory/migrations/206-scrub-corrupted-image-attachments.ts +131 -0
- package/src/memory/migrations/207-conversation-graph-memory-state.ts +20 -0
- package/src/memory/migrations/208-conversations-last-message-at.ts +35 -0
- package/src/memory/migrations/209-strip-thinking-from-consolidated.ts +85 -0
- package/src/memory/migrations/210-schedule-reuse-conversation.ts +13 -0
- package/src/memory/migrations/211-memory-recall-logs-query-context.ts +21 -0
- package/src/memory/migrations/212-llm-request-logs-created-at-index.ts +19 -0
- package/src/memory/migrations/index.ts +8 -0
- package/src/memory/migrations/registry.ts +8 -0
- package/src/memory/schema/conversations.ts +14 -0
- package/src/memory/schema/infrastructure.ts +8 -1
- package/src/memory/schema/memory-core.ts +0 -51
- package/src/memory/schema/memory-graph.ts +15 -0
- package/src/memory/task-memory-cleanup.ts +30 -11
- package/src/notifications/copy-composer.ts +86 -0
- package/src/notifications/decision-engine.ts +35 -0
- package/src/permissions/checker.ts +12 -1
- package/src/permissions/permission-mode-store.ts +180 -0
- package/src/permissions/permission-mode.ts +31 -0
- package/src/permissions/workspace-policy.ts +9 -0
- package/src/prompts/system-prompt.ts +59 -7
- package/src/prompts/templates/BOOTSTRAP-REFERENCE.md +100 -0
- package/src/prompts/templates/BOOTSTRAP.md +70 -165
- package/src/prompts/templates/HEARTBEAT.md +3 -1
- package/src/prompts/templates/SOUL.md +25 -4
- package/src/prompts/templates/UPDATES.md +8 -0
- package/src/providers/anthropic/client.ts +107 -219
- package/src/runtime/auth/route-policy.ts +23 -0
- package/src/runtime/http-server.ts +32 -2
- package/src/runtime/http-types.ts +12 -1
- package/src/runtime/migrations/vbundle-builder.ts +389 -3
- package/src/runtime/migrations/vbundle-importer.ts +8 -6
- package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +378 -0
- package/src/runtime/routes/app-management-routes.ts +1 -11
- package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +26 -0
- package/src/runtime/routes/archive-utils.ts +29 -0
- package/src/runtime/routes/avatar-routes.ts +2 -9
- package/src/runtime/routes/btw-routes.ts +14 -1
- package/src/runtime/routes/conversation-analysis-routes.ts +173 -0
- package/src/runtime/routes/conversation-management-routes.ts +1 -14
- package/src/runtime/routes/conversation-query-routes.ts +49 -3
- package/src/runtime/routes/conversation-routes.ts +264 -44
- package/src/runtime/routes/heartbeat-routes.ts +4 -10
- package/src/runtime/routes/identity-routes.ts +53 -18
- package/src/runtime/routes/llm-context-normalization.ts +14 -10
- package/src/runtime/routes/log-export-routes.ts +23 -275
- package/src/runtime/routes/memory-item-routes.test.ts +168 -233
- package/src/runtime/routes/migration-routes.ts +18 -7
- package/src/runtime/routes/profiler-routes.ts +350 -0
- package/src/runtime/routes/schedule-routes.ts +27 -12
- package/src/runtime/routes/settings-routes.ts +95 -8
- package/src/runtime/routes/subagents-routes.ts +28 -7
- package/src/runtime/routes/user-route-dispatcher.ts +223 -0
- package/src/runtime/routes/user-routes.ts +41 -0
- package/src/runtime/routes/workspace-routes.ts +0 -1
- package/src/schedule/schedule-store.ts +30 -0
- package/src/schedule/scheduler.ts +45 -18
- package/src/skills/catalog-install.ts +10 -2
- package/src/skills/managed-store.ts +2 -2
- package/src/skills/skill-memory.ts +1 -293
- package/src/subagent/index.ts +13 -3
- package/src/subagent/manager.ts +308 -29
- package/src/subagent/types.ts +68 -0
- package/src/tasks/task-runner.ts +4 -4
- package/src/tools/apps/executors.ts +29 -4
- package/src/tools/filesystem/list.ts +93 -0
- package/src/tools/permission-checker.ts +78 -0
- package/src/tools/registry.ts +4 -0
- package/src/tools/schedule/create.ts +3 -0
- package/src/tools/schedule/list.ts +1 -0
- package/src/tools/schedule/update.ts +6 -0
- package/src/tools/shared/filesystem/errors.ts +5 -0
- package/src/tools/shared/filesystem/file-ops-service.ts +90 -2
- package/src/tools/shared/filesystem/types.ts +17 -0
- package/src/tools/shared/shell-output.ts +31 -2
- package/src/tools/subagent/abort.ts +12 -2
- package/src/tools/subagent/message.ts +9 -2
- package/src/tools/subagent/notify-parent.ts +79 -0
- package/src/tools/subagent/read.ts +29 -8
- package/src/tools/subagent/resolve.ts +21 -0
- package/src/tools/subagent/spawn.ts +2 -0
- package/src/tools/subagent/status.ts +11 -1
- package/src/tools/system/avatar-generator.ts +3 -3
- package/src/tools/system/register.ts +23 -0
- package/src/tools/system/set-permission-mode.ts +103 -0
- package/src/tools/terminal/parser.ts +30 -5
- package/src/tools/terminal/safe-env.ts +16 -1
- package/src/tools/tool-manifest.ts +6 -0
- package/src/tools/types.ts +2 -0
- package/src/util/logger.ts +1 -1
- package/src/util/platform.ts +50 -17
- package/src/workspace/migrations/023-move-config-files-to-workspace.ts +2 -2
- package/src/workspace/migrations/024-move-runtime-files-to-workspace.ts +2 -2
- package/src/workspace/migrations/028-recover-conversations-from-disk-view.ts +270 -0
- package/src/workspace/migrations/029-seed-pkb.ts +84 -0
- package/src/workspace/migrations/registry.ts +4 -0
- package/src/workspace/top-level-renderer.ts +5 -9
- package/src/__tests__/cli-memory.test.ts +0 -377
- package/src/__tests__/clipboard.test.ts +0 -88
- package/src/cli/cli-memory.ts +0 -179
- package/src/util/clipboard.ts +0 -34
package/src/daemon/lifecycle.ts
CHANGED
|
@@ -5,7 +5,6 @@ import { reconcileCallsOnStartup } from "../calls/call-recovery.js";
|
|
|
5
5
|
import { setRelayBroadcast } from "../calls/relay-server.js";
|
|
6
6
|
import { TwilioConversationRelayProvider } from "../calls/twilio-provider.js";
|
|
7
7
|
import { setVoiceBridgeDeps } from "../calls/voice-session-bridge.js";
|
|
8
|
-
import { seedCliCommandMemories } from "../cli/cli-memory.js";
|
|
9
8
|
import {
|
|
10
9
|
getPlatformAssistantId,
|
|
11
10
|
getQdrantHttpPortEnv,
|
|
@@ -32,6 +31,7 @@ import {
|
|
|
32
31
|
awaitCesClientWithTimeout,
|
|
33
32
|
DEFAULT_CES_STARTUP_TIMEOUT_MS,
|
|
34
33
|
} from "../credential-execution/startup-timeout.js";
|
|
34
|
+
import { FilingService } from "../filing/filing-service.js";
|
|
35
35
|
import { HeartbeatService } from "../heartbeat/heartbeat-service.js";
|
|
36
36
|
import { getHookManager } from "../hooks/manager.js";
|
|
37
37
|
import { installTemplates } from "../hooks/templates.js";
|
|
@@ -82,10 +82,6 @@ import {
|
|
|
82
82
|
setCesClient,
|
|
83
83
|
setCesReconnect,
|
|
84
84
|
} from "../security/secure-keys.js";
|
|
85
|
-
import {
|
|
86
|
-
seedCatalogSkillMemories,
|
|
87
|
-
seedUninstalledCatalogSkillMemories,
|
|
88
|
-
} from "../skills/skill-memory.js";
|
|
89
85
|
import { UsageTelemetryReporter } from "../telemetry/usage-telemetry-reporter.js";
|
|
90
86
|
import { getDeviceId } from "../util/device-id.js";
|
|
91
87
|
import { getLogger, initLogger } from "../util/logger.js";
|
|
@@ -127,6 +123,7 @@ import {
|
|
|
127
123
|
} from "./handlers/conversations.js";
|
|
128
124
|
import { installAssistantSymlink } from "./install-symlink.js";
|
|
129
125
|
import type { ServerMessage } from "./message-protocol.js";
|
|
126
|
+
import { runProfilerSweep } from "./profiler-run-store.js";
|
|
130
127
|
import {
|
|
131
128
|
initializeProvidersAndTools,
|
|
132
129
|
registerMessagingProviders,
|
|
@@ -282,151 +279,191 @@ export async function runDaemon(): Promise<void> {
|
|
|
282
279
|
// workspace migrations (e.g. 009-backfill-conversation-disk-view)
|
|
283
280
|
// depend on DB migrations having run (e.g. the inline-attachment-to-disk
|
|
284
281
|
// backfill that populates attachment filePaths).
|
|
285
|
-
initializeDb();
|
|
286
|
-
// Seed well-known OAuth provider configurations (insert-if-not-exists)
|
|
287
|
-
seedOAuthProviders();
|
|
288
|
-
log.info("Daemon startup: DB initialized");
|
|
289
|
-
|
|
290
|
-
await runWorkspaceMigrations(getWorkspaceDir(), WORKSPACE_MIGRATIONS);
|
|
291
|
-
log.info("Daemon startup: workspace migrations complete");
|
|
292
|
-
|
|
293
|
-
// Backfill oauth_connection rows for manual-token providers (Telegram,
|
|
294
|
-
// Slack channel) that already have stored credentials from before the
|
|
295
|
-
// oauth_connection migration. Safe to call on every startup.
|
|
296
282
|
//
|
|
297
|
-
//
|
|
298
|
-
//
|
|
299
|
-
//
|
|
283
|
+
// If DB initialization fails (e.g. a migration error), the daemon
|
|
284
|
+
// continues in a degraded state — DB-dependent features won't work but
|
|
285
|
+
// the HTTP server and config-based subsystems still start so the process
|
|
286
|
+
// remains reachable for health checks and diagnostics.
|
|
287
|
+
let dbReady = false;
|
|
300
288
|
try {
|
|
301
|
-
|
|
289
|
+
initializeDb();
|
|
290
|
+
dbReady = true;
|
|
291
|
+
log.info("Daemon startup: DB initialized");
|
|
302
292
|
} catch (err) {
|
|
303
|
-
log.
|
|
293
|
+
log.error(
|
|
304
294
|
{ err },
|
|
305
|
-
"
|
|
295
|
+
"DB initialization failed — continuing startup in degraded mode",
|
|
306
296
|
);
|
|
307
297
|
}
|
|
308
298
|
|
|
309
|
-
//
|
|
310
|
-
//
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
"
|
|
317
|
-
|
|
299
|
+
// Seed well-known OAuth provider configurations (insert-if-not-exists).
|
|
300
|
+
// Runs in its own try/catch so a seeding error doesn't force degraded mode
|
|
301
|
+
// when the DB itself initialized successfully.
|
|
302
|
+
if (dbReady) {
|
|
303
|
+
try {
|
|
304
|
+
seedOAuthProviders();
|
|
305
|
+
} catch (err) {
|
|
306
|
+
log.warn({ err }, "OAuth provider seeding failed — continuing startup");
|
|
307
|
+
}
|
|
318
308
|
}
|
|
319
309
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
setSentryDeviceId(getDeviceId());
|
|
310
|
+
if (dbReady) {
|
|
311
|
+
await runWorkspaceMigrations(getWorkspaceDir(), WORKSPACE_MIGRATIONS);
|
|
312
|
+
log.info("Daemon startup: workspace migrations complete");
|
|
324
313
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
314
|
+
// Profiler retention sweep — prune completed profiler runs to stay
|
|
315
|
+
// within configured byte-count, run-count, and free-space budgets.
|
|
316
|
+
// Runs on every startup and is safe to call from explicit cleanup routes.
|
|
317
|
+
try {
|
|
318
|
+
const sweepResult = runProfilerSweep();
|
|
319
|
+
if (sweepResult.prunedCount > 0 || sweepResult.activeRunOverBudget) {
|
|
320
|
+
log.info(
|
|
321
|
+
{
|
|
322
|
+
prunedCount: sweepResult.prunedCount,
|
|
323
|
+
freedBytes: sweepResult.freedBytes,
|
|
324
|
+
activeRunOverBudget: sweepResult.activeRunOverBudget,
|
|
325
|
+
remainingRuns: sweepResult.remainingRuns,
|
|
326
|
+
},
|
|
327
|
+
"Profiler retention sweep completed on startup",
|
|
328
|
+
);
|
|
329
|
+
}
|
|
330
|
+
} catch (err) {
|
|
331
|
+
log.warn(
|
|
332
|
+
{ err },
|
|
333
|
+
"Profiler retention sweep failed — continuing startup",
|
|
334
|
+
);
|
|
340
335
|
}
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
336
|
+
|
|
337
|
+
// Backfill oauth_connection rows for manual-token providers (Telegram,
|
|
338
|
+
// Slack channel) that already have stored credentials from before the
|
|
339
|
+
// oauth_connection migration. Safe to call on every startup.
|
|
340
|
+
//
|
|
341
|
+
// Must run AFTER workspace migrations.
|
|
342
|
+
// Otherwise syncManualTokenConnection sees no stored credentials and
|
|
343
|
+
// incorrectly removes existing connection rows.
|
|
344
|
+
try {
|
|
345
|
+
await backfillManualTokenConnections();
|
|
346
|
+
} catch (err) {
|
|
347
|
+
log.warn(
|
|
348
|
+
{ err },
|
|
349
|
+
"Manual-token connection backfill failed — continuing startup",
|
|
350
|
+
);
|
|
346
351
|
}
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
+
|
|
353
|
+
// Backfill injection templates on Slack bot token credentials so the
|
|
354
|
+
// credential proxy can inject Authorization headers. Safe on every startup.
|
|
355
|
+
try {
|
|
356
|
+
backfillSlackInjectionTemplates();
|
|
357
|
+
} catch (err) {
|
|
358
|
+
log.warn(
|
|
359
|
+
{ err },
|
|
360
|
+
"Slack injection template backfill failed — continuing startup",
|
|
361
|
+
);
|
|
352
362
|
}
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
)
|
|
363
|
+
|
|
364
|
+
// Now that workspace migrations have run (including 003-seed-device-id
|
|
365
|
+
// which may copy the legacy installationId into device.json), it is safe
|
|
366
|
+
// to read the device ID and set the Sentry tag.
|
|
367
|
+
setSentryDeviceId(getDeviceId());
|
|
368
|
+
|
|
369
|
+
// Purge private (temporary) conversations from the previous daemon run.
|
|
370
|
+
// These are ephemeral by design and should not survive daemon restarts.
|
|
371
|
+
const { count: purgedCount, deletedMemory } = purgePrivateConversations();
|
|
372
|
+
if (purgedCount > 0) {
|
|
358
373
|
log.info(
|
|
359
|
-
{
|
|
360
|
-
|
|
361
|
-
orphanedItems: deletedMemory.orphanedItemIds.length,
|
|
362
|
-
deletedSummaries: deletedMemory.deletedSummaryIds.length,
|
|
363
|
-
},
|
|
364
|
-
"Enqueued Qdrant vector cleanup jobs for purged private conversations",
|
|
374
|
+
{ purgedCount },
|
|
375
|
+
`Purged ${purgedCount} private conversation(s) from previous daemon run`,
|
|
365
376
|
);
|
|
377
|
+
// Qdrant may not be ready at startup, so enqueue vector cleanup jobs
|
|
378
|
+
// rather than attempting direct deletion.
|
|
379
|
+
for (const segId of deletedMemory.segmentIds) {
|
|
380
|
+
enqueueMemoryJob("delete_qdrant_vectors", {
|
|
381
|
+
targetType: "segment",
|
|
382
|
+
targetId: segId,
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
for (const summaryId of deletedMemory.deletedSummaryIds) {
|
|
386
|
+
enqueueMemoryJob("delete_qdrant_vectors", {
|
|
387
|
+
targetType: "summary",
|
|
388
|
+
targetId: summaryId,
|
|
389
|
+
});
|
|
390
|
+
}
|
|
391
|
+
if (
|
|
392
|
+
deletedMemory.segmentIds.length > 0 ||
|
|
393
|
+
deletedMemory.deletedSummaryIds.length > 0
|
|
394
|
+
) {
|
|
395
|
+
log.info(
|
|
396
|
+
{
|
|
397
|
+
segments: deletedMemory.segmentIds.length,
|
|
398
|
+
deletedSummaries: deletedMemory.deletedSummaryIds.length,
|
|
399
|
+
},
|
|
400
|
+
"Enqueued Qdrant vector cleanup jobs for purged private conversations",
|
|
401
|
+
);
|
|
402
|
+
}
|
|
366
403
|
}
|
|
367
|
-
}
|
|
368
404
|
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
405
|
+
// Expire stale pending canonical guardian requests left over from before
|
|
406
|
+
// this process started. Two categories are cleaned up:
|
|
407
|
+
//
|
|
408
|
+
// 1. Interaction-bound kinds (tool_approval, pending_question) — their
|
|
409
|
+
// in-memory pending-interaction session references are gone, so they
|
|
410
|
+
// can never be completed.
|
|
411
|
+
// 2. Any pending request whose expiresAt has already passed — persistent
|
|
412
|
+
// kinds (access_request, tool_grant_request) that expired while the
|
|
413
|
+
// daemon was stopped are transitioned so dedup logic doesn't return
|
|
414
|
+
// stale rows.
|
|
415
|
+
const expiredCount = expireAllPendingCanonicalRequests();
|
|
416
|
+
if (expiredCount > 0) {
|
|
417
|
+
log.info(
|
|
418
|
+
{ event: "startup_expired_stale_requests", expiredCount },
|
|
419
|
+
`Expired ${expiredCount} stale canonical request(s) from previous process`,
|
|
420
|
+
);
|
|
421
|
+
}
|
|
386
422
|
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
423
|
+
// Ensure a vellum guardian binding exists so the identity system works
|
|
424
|
+
// without requiring a manual bootstrap step.
|
|
425
|
+
try {
|
|
426
|
+
ensureVellumGuardianBinding(DAEMON_INTERNAL_ASSISTANT_ID);
|
|
427
|
+
} catch (err) {
|
|
428
|
+
log.warn(
|
|
429
|
+
{ err },
|
|
430
|
+
"Vellum guardian binding backfill failed — continuing startup",
|
|
431
|
+
);
|
|
432
|
+
}
|
|
397
433
|
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
434
|
+
try {
|
|
435
|
+
syncUpdateBulletinOnStartup();
|
|
436
|
+
} catch (err) {
|
|
437
|
+
log.warn({ err }, "Bulletin sync failed — continuing startup");
|
|
438
|
+
}
|
|
403
439
|
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
440
|
+
// Recover orphaned work items that were left in 'running' state when the
|
|
441
|
+
// daemon previously crashed or was killed mid-task.
|
|
442
|
+
const orphanedRunning = listWorkItems({ status: "running" });
|
|
443
|
+
if (orphanedRunning.length > 0) {
|
|
444
|
+
for (const item of orphanedRunning) {
|
|
445
|
+
updateWorkItem(item.id, {
|
|
446
|
+
status: "failed",
|
|
447
|
+
lastRunStatus: "interrupted",
|
|
448
|
+
});
|
|
449
|
+
log.info(
|
|
450
|
+
{ workItemId: item.id, title: item.title },
|
|
451
|
+
"Recovered orphaned running work item → failed (interrupted)",
|
|
452
|
+
);
|
|
453
|
+
}
|
|
413
454
|
log.info(
|
|
414
|
-
{
|
|
415
|
-
"Recovered orphaned running work
|
|
455
|
+
{ count: orphanedRunning.length },
|
|
456
|
+
"Recovered orphaned running work items",
|
|
416
457
|
);
|
|
417
458
|
}
|
|
418
|
-
log.info(
|
|
419
|
-
{ count: orphanedRunning.length },
|
|
420
|
-
"Recovered orphaned running work items",
|
|
421
|
-
);
|
|
422
|
-
}
|
|
423
459
|
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
460
|
+
try {
|
|
461
|
+
const twilioProvider = new TwilioConversationRelayProvider();
|
|
462
|
+
await reconcileCallsOnStartup(twilioProvider, log);
|
|
463
|
+
} catch (err) {
|
|
464
|
+
log.warn({ err }, "Call recovery failed — continuing startup");
|
|
465
|
+
}
|
|
466
|
+
} // end if (dbReady)
|
|
430
467
|
|
|
431
468
|
// Merge CLI-provided default config (from VELLUM_DEFAULT_WORKSPACE_CONFIG_PATH)
|
|
432
469
|
// into the workspace config file before the first loadConfig() call so
|
|
@@ -645,35 +682,21 @@ export async function runDaemon(): Promise<void> {
|
|
|
645
682
|
log.info("Daemon startup: starting memory worker");
|
|
646
683
|
bgRefs.memoryWorker = startMemoryJobsWorker();
|
|
647
684
|
|
|
648
|
-
// Seed capability memories for all enabled skills so the memory
|
|
649
|
-
// pipeline can surface relevant skills via semantic search.
|
|
650
|
-
try {
|
|
651
|
-
seedCatalogSkillMemories();
|
|
652
|
-
} catch (err) {
|
|
653
|
-
log.warn({ err }, "Catalog skill memory seeding failed — continuing");
|
|
654
|
-
}
|
|
655
|
-
|
|
656
|
-
// Seed memories for catalog skills not yet installed so they're
|
|
657
|
-
// discoverable via memory injection and can be auto-installed.
|
|
658
|
-
void seedUninstalledCatalogSkillMemories().catch((err) =>
|
|
659
|
-
log.warn(
|
|
660
|
-
{ err },
|
|
661
|
-
"Uninstalled catalog skill memory seeding failed — continuing",
|
|
662
|
-
),
|
|
663
|
-
);
|
|
664
|
-
|
|
665
|
-
try {
|
|
666
|
-
seedCliCommandMemories();
|
|
667
|
-
} catch (err) {
|
|
668
|
-
log.warn({ err }, "CLI command memory seeding failed — continuing");
|
|
669
|
-
}
|
|
670
|
-
|
|
671
685
|
// Seed capability graph nodes (new memory graph system)
|
|
672
686
|
try {
|
|
673
|
-
const {
|
|
674
|
-
|
|
687
|
+
const {
|
|
688
|
+
seedSkillGraphNodes,
|
|
689
|
+
seedCliGraphNodes,
|
|
690
|
+
seedUninstalledCatalogSkillMemories,
|
|
691
|
+
} = await import("../memory/graph/capability-seed.js");
|
|
675
692
|
seedSkillGraphNodes();
|
|
676
693
|
seedCliGraphNodes();
|
|
694
|
+
void seedUninstalledCatalogSkillMemories().catch((err) =>
|
|
695
|
+
log.warn(
|
|
696
|
+
{ err },
|
|
697
|
+
"Uninstalled catalog skill memory seeding failed — continuing",
|
|
698
|
+
),
|
|
699
|
+
);
|
|
677
700
|
} catch (err) {
|
|
678
701
|
log.warn({ err }, "Graph capability seeding failed — continuing");
|
|
679
702
|
}
|
|
@@ -682,10 +705,8 @@ export async function runDaemon(): Promise<void> {
|
|
|
682
705
|
// segments exist, enqueue a one-time graph_bootstrap job to populate the
|
|
683
706
|
// graph from conversation history and journal files.
|
|
684
707
|
try {
|
|
685
|
-
const {
|
|
686
|
-
|
|
687
|
-
cleanupStaleItemVectors,
|
|
688
|
-
} = await import("../memory/graph/bootstrap.js");
|
|
708
|
+
const { maybeEnqueueGraphBootstrap, cleanupStaleItemVectors } =
|
|
709
|
+
await import("../memory/graph/bootstrap.js");
|
|
689
710
|
maybeEnqueueGraphBootstrap();
|
|
690
711
|
// Fire-and-forget: clean up orphaned Qdrant vectors from dropped memory_items table
|
|
691
712
|
void cleanupStaleItemVectors().catch((err) =>
|
|
@@ -849,8 +870,8 @@ export async function runDaemon(): Promise<void> {
|
|
|
849
870
|
guardianFollowUpConversationGenerator:
|
|
850
871
|
createGuardianFollowUpConversationGenerator(),
|
|
851
872
|
sendMessageDeps: {
|
|
852
|
-
getOrCreateConversation: (conversationId) =>
|
|
853
|
-
server.getConversationForMessages(conversationId),
|
|
873
|
+
getOrCreateConversation: (conversationId, options) =>
|
|
874
|
+
server.getConversationForMessages(conversationId, options),
|
|
854
875
|
assistantEventHub,
|
|
855
876
|
resolveAttachments: (attachmentIds) => {
|
|
856
877
|
const resolved = attachmentsStore.getAttachmentsByIds(attachmentIds, {
|
|
@@ -1226,6 +1247,26 @@ export async function runDaemon(): Promise<void> {
|
|
|
1226
1247
|
"Heartbeat service configured",
|
|
1227
1248
|
);
|
|
1228
1249
|
|
|
1250
|
+
const filingConfig = config.filing;
|
|
1251
|
+
const filing = new FilingService({
|
|
1252
|
+
processMessage: (conversationId, content, options) =>
|
|
1253
|
+
server.processMessage(conversationId, content, undefined, {
|
|
1254
|
+
trustContext: {
|
|
1255
|
+
sourceChannel: "vellum",
|
|
1256
|
+
trustClass: "guardian",
|
|
1257
|
+
},
|
|
1258
|
+
...options,
|
|
1259
|
+
}),
|
|
1260
|
+
});
|
|
1261
|
+
filing.start();
|
|
1262
|
+
log.info(
|
|
1263
|
+
{
|
|
1264
|
+
enabled: filingConfig.enabled,
|
|
1265
|
+
intervalMs: filingConfig.intervalMs,
|
|
1266
|
+
},
|
|
1267
|
+
"Filing service configured",
|
|
1268
|
+
);
|
|
1269
|
+
|
|
1229
1270
|
// Retrieve the MCP manager if MCP servers were configured.
|
|
1230
1271
|
// The manager is a singleton created during initializeProvidersAndTools().
|
|
1231
1272
|
const mcpManager =
|
|
@@ -1237,6 +1278,7 @@ export async function runDaemon(): Promise<void> {
|
|
|
1237
1278
|
server,
|
|
1238
1279
|
workspaceHeartbeat,
|
|
1239
1280
|
heartbeat,
|
|
1281
|
+
filing,
|
|
1240
1282
|
hookManager,
|
|
1241
1283
|
runtimeHttp,
|
|
1242
1284
|
scheduler,
|
|
@@ -14,12 +14,10 @@ export interface ConversationListRequest {
|
|
|
14
14
|
limit?: number;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
/**
|
|
18
|
-
|
|
17
|
+
/** Shared fields for all transport metadata variants. */
|
|
18
|
+
interface BaseTransportMetadata {
|
|
19
19
|
/** Logical channel identifier (e.g. "desktop", "telegram", "mobile"). */
|
|
20
20
|
channelId: ChannelId;
|
|
21
|
-
/** Interface identifier for this transport (e.g. "macos", "ios", "cli"). */
|
|
22
|
-
interfaceId?: InterfaceId;
|
|
23
21
|
/** Optional natural-language hints for channel-specific UX behavior. */
|
|
24
22
|
hints?: string[];
|
|
25
23
|
/** Optional concise UX brief for this channel. */
|
|
@@ -28,6 +26,27 @@ export interface ConversationTransportMetadata {
|
|
|
28
26
|
chatType?: string;
|
|
29
27
|
}
|
|
30
28
|
|
|
29
|
+
/** Transport metadata for macOS desktop clients, including host environment fields. */
|
|
30
|
+
export interface MacosTransportMetadata extends BaseTransportMetadata {
|
|
31
|
+
/** Interface identifier for macOS transport. */
|
|
32
|
+
interfaceId: "macos";
|
|
33
|
+
/** Home directory of the host macOS user. */
|
|
34
|
+
hostHomeDir?: string;
|
|
35
|
+
/** Username of the host macOS user. */
|
|
36
|
+
hostUsername?: string;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** Transport metadata for non-macOS transports. */
|
|
40
|
+
export interface NonMacosTransportMetadata extends BaseTransportMetadata {
|
|
41
|
+
/** Interface identifier for this transport (e.g. "ios", "cli"). */
|
|
42
|
+
interfaceId?: Exclude<InterfaceId, "macos">;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** Lightweight conversation transport metadata for channel identity and natural-language guidance. */
|
|
46
|
+
export type ConversationTransportMetadata =
|
|
47
|
+
| MacosTransportMetadata
|
|
48
|
+
| NonMacosTransportMetadata;
|
|
49
|
+
|
|
31
50
|
export interface ConversationCreateRequest {
|
|
32
51
|
type: "conversation_create";
|
|
33
52
|
title?: string;
|
|
@@ -310,11 +329,11 @@ export interface HistoryResponse {
|
|
|
310
329
|
contentOrder?: string[];
|
|
311
330
|
/** UI surfaces (widgets) embedded in the message. */
|
|
312
331
|
surfaces?: HistoryResponseSurface[];
|
|
313
|
-
/** Present when this message is a subagent lifecycle notification (completed/failed/aborted). */
|
|
332
|
+
/** Present when this message is a subagent lifecycle notification (running/completed/failed/aborted). */
|
|
314
333
|
subagentNotification?: {
|
|
315
334
|
subagentId: string;
|
|
316
335
|
label: string;
|
|
317
|
-
status: "completed" | "failed" | "aborted";
|
|
336
|
+
status: "running" | "completed" | "failed" | "aborted";
|
|
318
337
|
error?: string;
|
|
319
338
|
conversationId?: string;
|
|
320
339
|
};
|
|
@@ -308,6 +308,13 @@ export interface AssistantActivityState {
|
|
|
308
308
|
statusText?: string;
|
|
309
309
|
}
|
|
310
310
|
|
|
311
|
+
/** Broadcast to clients when the two-axis permission mode changes. */
|
|
312
|
+
export interface PermissionModeUpdate {
|
|
313
|
+
type: "permission_mode_update";
|
|
314
|
+
askBeforeActing: boolean;
|
|
315
|
+
hostAccess: boolean;
|
|
316
|
+
}
|
|
317
|
+
|
|
311
318
|
export type TraceEventKind =
|
|
312
319
|
| "request_received"
|
|
313
320
|
| "request_queued"
|
|
@@ -369,4 +376,5 @@ export type _MessagesServerMessages =
|
|
|
369
376
|
| SuggestionResponse
|
|
370
377
|
| TraceEvent
|
|
371
378
|
| ConfirmationStateChanged
|
|
372
|
-
| AssistantActivityState
|
|
379
|
+
| AssistantActivityState
|
|
380
|
+
| PermissionModeUpdate;
|
|
@@ -34,6 +34,11 @@ export interface AvatarUpdated {
|
|
|
34
34
|
avatarPath: string;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
/** Sent by the daemon when sounds config or sound files change on disk. */
|
|
38
|
+
export interface SoundsConfigUpdated {
|
|
39
|
+
type: "sounds_config_updated";
|
|
40
|
+
}
|
|
41
|
+
|
|
37
42
|
/** Response to a generate_avatar request indicating success or failure. */
|
|
38
43
|
export interface GenerateAvatarResponse {
|
|
39
44
|
type: "generate_avatar_response";
|
|
@@ -51,4 +56,5 @@ export type _SettingsClientMessages =
|
|
|
51
56
|
export type _SettingsServerMessages =
|
|
52
57
|
| ClientSettingsUpdate
|
|
53
58
|
| AvatarUpdated
|
|
59
|
+
| SoundsConfigUpdated
|
|
54
60
|
| GenerateAvatarResponse;
|