@mycadet/assistant 0.12.9 → 0.12.10
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/Dockerfile +0 -8
- package/eslint-rules/__tests__/cli-no-daemon-internals.test.ts +1 -1
- package/openapi.yaml +62 -910
- package/package.json +3 -7
- package/scripts/build-test-fixtures.ts +1 -1
- package/scripts/generate-openapi.ts +22 -6
- package/scripts/postinstall.ts +4 -10
- package/scripts/run-tests.ts +0 -21
- package/src/__tests__/adaptive-thinking-repair.test.ts +19 -57
- package/src/__tests__/agent-loop.test.ts +0 -76
- package/src/__tests__/anthropic-provider.test.ts +6 -6
- package/src/__tests__/assert-not-live-db.ts +1 -1
- package/src/__tests__/assistant-id-boundary-guard.test.ts +3 -3
- package/src/__tests__/attachments-store-heic-normalize.test.ts +1 -1
- package/src/__tests__/attachments-store.test.ts +1 -1
- package/src/__tests__/audit-log-rotation.test.ts +1 -1
- package/src/__tests__/btw-routes.test.ts +1 -1
- package/src/__tests__/byok-default-profile-ensure.test.ts +21 -27
- package/src/__tests__/call-conversation-messages.test.ts +0 -5
- package/src/__tests__/call-recovery.test.ts +2 -7
- package/src/__tests__/call-routes-http.test.ts +0 -12
- package/src/__tests__/call-store.test.ts +2 -7
- package/src/__tests__/catalog-files.test.ts +7 -5
- package/src/__tests__/checker.test.ts +1 -1
- package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +4 -4
- package/src/__tests__/cloud-client-verify-credential.test.ts +0 -4
- package/src/__tests__/cloud-credential-catalog-cli.test.ts +14 -14
- package/src/__tests__/cloud-profile-guard.test.ts +48 -401
- package/src/__tests__/compaction-events.test.ts +2 -2
- package/src/__tests__/config-loader-backfill.test.ts +74 -163
- package/src/__tests__/config-loader-cloud-defaults.test.ts +11 -11
- package/src/__tests__/config-loader-corrupt.test.ts +10 -10
- package/src/__tests__/config-loader-quarantine-notice.test.ts +7 -7
- package/src/__tests__/config-loader-validation-reset-notice.test.ts +11 -11
- package/src/__tests__/config-schema.test.ts +26 -27
- package/src/__tests__/config-set-route.test.ts +2 -6
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +28 -300
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +39 -246
- package/src/__tests__/conversation-agent-loop.test.ts +2 -58
- package/src/__tests__/conversation-clear-safety.test.ts +0 -30
- package/src/__tests__/conversation-inference-profile-route.test.ts +1 -1
- package/src/__tests__/conversation-queue.test.ts +1 -1
- package/src/__tests__/conversation-runtime-assembly.test.ts +1 -1
- package/src/__tests__/conversation-skill-tools.test.ts +4 -444
- package/src/__tests__/conversation-slash-commands.test.ts +1 -1
- package/src/__tests__/conversation-store.test.ts +1 -84
- package/src/__tests__/conversation-surface-state.test.ts +0 -16
- package/src/__tests__/credential-health-service.test.ts +14 -1
- package/src/__tests__/credential-record-retire.test.ts +1 -1
- package/src/__tests__/credential-record-write-through.test.ts +1 -1
- package/src/__tests__/credential-security-invariants.test.ts +0 -145
- package/src/__tests__/custom-profile-ensure.test.ts +1 -1
- package/src/__tests__/default-profile-catalog-fallback.test.ts +5 -15
- package/src/__tests__/deterministic-verification-control-plane.test.ts +0 -2
- package/src/__tests__/dictation-profile-store.test.ts +6 -6
- package/src/__tests__/disk-usage.test.ts +28 -164
- package/src/__tests__/docker-signing-key-bootstrap.test.ts +1 -1
- package/src/__tests__/embedding-cloud-proxy-selection.test.ts +1 -1
- package/src/__tests__/emit-event-signal.test.ts +1 -1
- package/src/__tests__/gateway-client-cloud-outbound.test.ts +3 -3
- package/src/__tests__/gateway-only-enforcement.test.ts +1 -1
- package/src/__tests__/guardian-dispatch.test.ts +0 -13
- package/src/__tests__/helpers/seed-app.ts +1 -1
- package/src/__tests__/host-cu-routes-targeted.test.ts +1 -1
- package/src/__tests__/host-shell-tool.test.ts +1 -1
- package/src/__tests__/identity-routes.test.ts +1 -1
- package/src/__tests__/inference-profile-session-handler.test.ts +1 -1
- package/src/__tests__/inference-profile-session-ipc.test.ts +1 -1
- package/src/__tests__/injector-chain.test.ts +1 -1
- package/src/__tests__/injector-config-quarantine-notice.test.ts +1 -1
- package/src/__tests__/injector-config-validation-reset-notice.test.ts +1 -1
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +1 -1
- package/src/__tests__/{platform.test.ts → layout.test.ts} +1 -1
- package/src/__tests__/list-all-apps.test.ts +1 -1
- package/src/__tests__/live-workspace-guard.test.ts +2 -2
- package/src/__tests__/llm-resolver-override-or-default.test.ts +5 -6
- package/src/__tests__/llm-resolver.test.ts +7 -7
- package/src/__tests__/llm-schema-fallback-profile.test.ts +9 -10
- package/src/__tests__/llm-usage-store.test.ts +0 -495
- package/src/__tests__/log-export-routes.test.ts +1 -1
- package/src/__tests__/mcp-config-secret-boundary.test.ts +12 -53
- package/src/__tests__/mcp-list-plugin-servers.test.ts +1 -1
- package/src/__tests__/memory-config-file-parity.test.ts +1 -1
- package/src/__tests__/memory-v2-static-injector.test.ts +1 -1
- package/src/__tests__/messages-read-boundary-guard.test.ts +0 -2
- package/src/__tests__/notification-guardian-path.test.ts +0 -7
- package/src/__tests__/onboarding-persona-write.test.ts +1 -1
- package/src/__tests__/openai-provider.test.ts +8 -8
- package/src/__tests__/path-policy.test.ts +1 -1
- package/src/__tests__/persona-resolver.test.ts +1 -1
- package/src/__tests__/plugin-app-serve-routes.test.ts +1 -1
- package/src/__tests__/plugin-effective-enabled-set.test.ts +1 -1
- package/src/__tests__/plugin-import-boundary-guard.test.ts +4 -6
- package/src/__tests__/plugin-import-boundary-reverse-guard.test.ts +0 -3
- package/src/__tests__/provider-cloud-proxy-integration.test.ts +1 -5
- package/src/__tests__/provider-connections-backfill.test.ts +10 -10
- package/src/__tests__/prune-old-conversations-job.test.ts +6 -31
- package/src/__tests__/resolve-app.test.ts +1 -1
- package/src/__tests__/run-due-schedules.test.ts +1 -1
- package/src/__tests__/scaffold-managed-skill-tool.test.ts +0 -53
- package/src/__tests__/schedule-routes.test.ts +1 -1
- package/src/__tests__/schedule-store.test.ts +1 -1
- package/src/__tests__/secret-routes-cloud-proxy.test.ts +1 -1
- package/src/__tests__/skill-load-plugin-scope.test.ts +1 -1
- package/src/__tests__/surface-completion-compaction-boundary.test.ts +1 -1
- package/src/__tests__/tool-approval-handler.test.ts +1 -1
- package/src/__tests__/tool-audit.test.ts +5 -235
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +54 -114
- package/src/__tests__/tools-get-route.test.ts +1 -1
- package/src/__tests__/turn-outcome-read.test.ts +1 -1
- package/src/__tests__/twilio-routes.test.ts +0 -1
- package/src/__tests__/usage-attribution.test.ts +0 -31
- package/src/__tests__/verification-control-plane-policy.test.ts +3 -10
- package/src/__tests__/visible-app-context.test.ts +1 -1
- package/src/__tests__/voice-ingress-preflight.test.ts +1 -1
- package/src/__tests__/workspace-git-service.test.ts +1 -1
- package/src/__tests__/workspace-greetings.test.ts +1 -1
- package/src/acp/__tests__/helpers/acp-config-stub.ts +1 -1
- package/src/activation/progress-store.ts +1 -1
- package/src/activation/turn-hooks.ts +1 -1
- package/src/agent/loop.ts +0 -51
- package/src/apps/app-store.ts +1 -1
- package/src/avatar/__tests__/avatar-store.test.ts +2 -172
- package/src/avatar/accent-backfill.ts +1 -1
- package/src/avatar/avatar-manifest.ts +1 -1
- package/src/avatar/avatar-store.ts +10 -69
- package/src/avatar/ensure-raster.ts +1 -1
- package/src/avatar/identity-avatar.ts +1 -1
- package/src/avatar/sync-avatar.ts +1 -1
- package/src/avatar/traits-png-sync.ts +1 -1
- package/src/bundler/compiler-tools.ts +1 -1
- package/src/bundler/package-resolver.ts +1 -1
- package/src/calls/__tests__/call-controller.test.ts +25 -27
- package/src/calls/active-call-lease.ts +1 -1
- package/src/calls/call-controller.ts +3 -3
- package/src/calls/call-domain.ts +4 -8
- package/src/calls/call-store.ts +2 -76
- package/src/calls/resolve-call-tts-provider.ts +3 -3
- package/src/calls/twilio-config.ts +3 -3
- package/src/calls/twilio-rest.ts +2 -2
- package/src/calls/voice-ingress-preflight.ts +2 -2
- package/src/cli/bundled-modules.ts +0 -2
- package/src/cli/commands/__tests__/apps.test.ts +1 -1
- package/src/cli/commands/__tests__/plugins.test.ts +9 -66
- package/src/cli/commands/__tests__/ps.test.ts +67 -0
- package/src/cli/commands/auth.help.ts +2 -2
- package/src/cli/commands/avatar.ts +1 -1
- package/src/cli/commands/changelog.ts +1 -1
- package/src/cli/commands/cloud/__tests__/subscription.test.ts +2 -2
- package/src/cli/commands/cloud/index.help.ts +1 -1
- package/src/cli/commands/cloud/index.ts +2 -2
- package/src/cli/commands/db/refresh.ts +1 -1
- package/src/cli/commands/db/repair-step-conversation-backfill.ts +1 -1
- package/src/cli/commands/db/repair.ts +1 -1
- package/src/cli/commands/db/status.ts +1 -1
- package/src/cli/commands/inference-profiles.ts +1 -12
- package/src/cli/commands/memory/__tests__/memory-v3.test.ts +1 -116
- package/src/cli/commands/memory/index.help.ts +1 -43
- package/src/cli/commands/memory/memory-v3.ts +0 -64
- package/src/cli/commands/plugins.ts +54 -205
- package/src/cli/commands/ps.ts +5 -2
- package/src/cli/commands/status.ts +1 -1
- package/src/cli/index.help.ts +0 -2
- package/src/cli/lib/__tests__/inspect-plugin.test.ts +36 -66
- package/src/cli/lib/__tests__/install-from-cloud.test.ts +1 -1
- package/src/cli/lib/__tests__/install-from-github.test.ts +41 -117
- package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +2 -185
- package/src/cli/lib/__tests__/plugin-catalog-resolve.test.ts +36 -66
- package/src/cli/lib/__tests__/plugin-catalog-visibility.test.ts +4 -6
- package/src/cli/lib/__tests__/plugin-details.test.ts +113 -96
- package/src/cli/lib/__tests__/search-plugins.test.ts +9 -16
- package/src/cli/lib/__tests__/uninstall-plugin.test.ts +1 -1
- package/src/cli/lib/__tests__/upgrade-plugin.test.ts +38 -15
- package/src/cli/lib/diff-plugin.ts +1 -1
- package/src/cli/lib/inspect-plugin.ts +13 -97
- package/src/cli/lib/install-from-cloud.ts +1 -1
- package/src/cli/lib/install-from-github.ts +75 -154
- package/src/cli/lib/install-plugin-dependencies.ts +1 -1
- package/src/cli/lib/list-installed-plugins.ts +1 -1
- package/src/cli/lib/open-browser.ts +1 -1
- package/src/cli/lib/plugin-catalog-cache.ts +8 -51
- package/src/cli/lib/plugin-catalog-resolve.ts +3 -22
- package/src/cli/lib/plugin-details.ts +5 -27
- package/src/cli/lib/plugin-marketplace.ts +18 -266
- package/src/cli/lib/search-plugins.ts +23 -43
- package/src/cli/lib/toggle-plugin.ts +1 -1
- package/src/cli/lib/uninstall-plugin.ts +1 -1
- package/src/cli/lib/upgrade-plugin.ts +3 -49
- package/src/cli/program.ts +1 -3
- package/src/cli.ts +1 -1
- package/src/cloud/client.ts +0 -6
- package/src/cloud/consent-cache.test.ts +22 -201
- package/src/cloud/consent-cache.ts +16 -111
- package/src/cloud/sync-identity.ts +1 -1
- package/src/config/__tests__/chat-settings.test.ts +1 -1
- package/src/config/__tests__/cloud-identity.test.ts +15 -2
- package/src/config/__tests__/default-plugin-skill-discovery.test.ts +1 -1
- package/src/config/__tests__/default-profile-catalog.test.ts +12 -51
- package/src/config/__tests__/deployment-context-defaults.test.ts +13 -13
- package/src/config/__tests__/loader-callsite-strip-fallback.test.ts +4 -4
- package/src/config/__tests__/loader-last-known-good.test.ts +9 -9
- package/src/config/__tests__/loader-sparse-array-cleanup.test.ts +7 -7
- package/src/config/__tests__/plugin-resident-skill-discovery.test.ts +1 -1
- package/src/config/__tests__/profile-materialization.test.ts +2 -4
- package/src/config/__tests__/sync-gated-profiles.test.ts +1 -106
- package/src/config/acp-agent-write.ts +1 -1
- package/src/config/bundled-skills/settings/tools/open-system-settings.test.ts +1 -1
- package/src/config/bundled-skills/settings/tools/open-system-settings.ts +1 -1
- package/src/config/call-site-defaults.ts +0 -6
- package/src/config/cloud-identity.ts +12 -5
- package/src/config/composer-preferences.ts +1 -1
- package/src/config/default-profile-catalog.ts +8 -75
- package/src/config/default-profile-names.ts +2 -25
- package/src/config/env-registry.ts +1 -14
- package/src/config/env.ts +8 -6
- package/src/config/llm-resolver.ts +1 -2
- package/src/config/loader.ts +13 -17
- package/src/config/profile-materialization.ts +1 -1
- package/src/config/schema.ts +1 -7
- package/src/config/schemas/call-site-catalog.ts +0 -7
- package/src/config/schemas/llm.ts +22 -27
- package/src/config/seed-inference-profiles.ts +16 -17
- package/src/config/skills.ts +2 -2
- package/src/config/sync-gated-profiles.ts +6 -24
- package/src/credential-health/credential-health-service.ts +10 -3
- package/src/daemon/approval-generators.ts +3 -3
- package/src/daemon/config-watcher.ts +2 -2
- package/src/daemon/conversation-agent-loop-handlers.ts +0 -18
- package/src/daemon/conversation-agent-loop.ts +6 -97
- package/src/daemon/conversation-process.ts +1 -1
- package/src/daemon/conversation-skill-tools.ts +4 -72
- package/src/daemon/conversation-store.ts +1 -1
- package/src/daemon/conversation-surface-state.ts +0 -33
- package/src/daemon/conversation-surfaces.ts +1 -86
- package/src/daemon/conversation-tool-setup.test.ts +1 -1
- package/src/daemon/conversation-tool-setup.ts +0 -23
- package/src/daemon/conversation.ts +3 -5
- package/src/daemon/daemon-control.ts +3 -3
- package/src/daemon/dictation-profile-store.ts +3 -3
- package/src/daemon/event-loop-watchdog.test.ts +2 -198
- package/src/daemon/event-loop-watchdog.ts +0 -185
- package/src/daemon/external-plugins-bootstrap.ts +1 -1
- package/src/daemon/first-greeting.ts +1 -1
- package/src/daemon/handlers/skills.ts +1 -1
- package/src/daemon/host-app-control-proxy.ts +1 -1
- package/src/daemon/host-cu-proxy.ts +2 -2
- package/src/daemon/identity-helpers.ts +1 -1
- package/src/daemon/lifecycle.ts +11 -15
- package/src/daemon/main.ts +1 -1
- package/src/daemon/now-scratchpad.ts +1 -1
- package/src/daemon/process-message.ts +4 -4
- package/src/daemon/profiler-run-store.ts +2 -2
- package/src/daemon/providers-setup.ts +2 -2
- package/src/daemon/shutdown-handlers.ts +0 -10
- package/src/daemon/sqlite-corruption-watchdog.test.ts +2 -142
- package/src/daemon/sqlite-corruption-watchdog.ts +17 -81
- package/src/daemon/tool-side-effects.ts +1 -1
- package/src/desktop/desktop-session-manager.ts +1 -1
- package/src/desktop/desktop-wallpaper-renderer.ts +1 -1
- package/src/heartbeat/heartbeat-service.ts +1 -1
- package/src/home/feed-writer.ts +1 -1
- package/src/home/home-greeting-cache.ts +1 -1
- package/src/home/relationship-state-writer.ts +2 -2
- package/src/hooks/__tests__/hook-live-reload.test.ts +1 -1
- package/src/hooks/hook-loader.ts +2 -2
- package/src/inbound/__tests__/oauth-callback-url.test.ts +2 -2
- package/src/inbound/oauth-callback-url.ts +3 -3
- package/src/ipc/__tests__/attachment-ipc.test.ts +1 -1
- package/src/ipc/socket-path.ts +1 -1
- package/src/live-voice/__tests__/live-voice-archive.test.ts +1 -1
- package/src/live-voice/__tests__/live-voice-vad.test.ts +1 -1
- package/src/live-voice/live-voice-session.ts +3 -66
- package/src/mcp/__tests__/effective-config.test.ts +1 -1
- package/src/mcp/__tests__/mcp-oauth-client-registration.test.ts +2 -2
- package/src/mcp/__tests__/mcp-oauth-provider.test.ts +2 -3
- package/src/mcp/__tests__/reload-signal-emission.test.ts +1 -1
- package/src/mcp/__tests__/reload-signal.test.ts +1 -1
- package/src/mcp/__tests__/workspace-mcp-config.test.ts +19 -21
- package/src/mcp/reload-signal.ts +1 -1
- package/src/mcp/workspace-mcp-config.ts +1 -23
- package/src/messaging/draft-store.ts +1 -1
- package/src/monitoring/__tests__/active-conversations.test.ts +1 -1
- package/src/monitoring/__tests__/page-cache.test.ts +1 -1
- package/src/monitoring/__tests__/stall-capture.test.ts +1 -1
- package/src/monitoring/__tests__/workspace-git-heartbeat.test.ts +1 -1
- package/src/monitoring/active-conversations.ts +1 -1
- package/src/monitoring/control.ts +1 -1
- package/src/monitoring/daemon-boot-time.ts +1 -1
- package/src/monitoring/daemon-heartbeat.ts +1 -1
- package/src/monitoring/page-cache.ts +1 -1
- package/src/monitoring/plugin-auto-update.ts +1 -7
- package/src/monitoring/plugin-source-watch.ts +1 -1
- package/src/monitoring/recovery/db.ts +1 -1
- package/src/monitoring/recovery/inflight-content.ts +1 -1
- package/src/monitoring/resource-sampler.ts +3 -14
- package/src/monitoring/stall-capture.ts +1 -1
- package/src/monitoring/worker.ts +9 -76
- package/src/monitoring/workspace-git-heartbeat.ts +1 -1
- package/src/oauth/connect-orchestrator.ts +4 -4
- package/src/permissions/checker.ts +1 -1
- package/src/permissions/workspace-policy.ts +1 -1
- package/src/persistence/__tests__/main-db-readonly-probe.ts +27 -52
- package/src/persistence/__tests__/message-content-file.test.ts +1 -1
- package/src/persistence/__tests__/slow-sync-log.test.ts +0 -2
- package/src/persistence/attachments-store.ts +1 -1
- package/src/persistence/conversation-crud.ts +1 -38
- package/src/persistence/conversation-directories.ts +1 -1
- package/src/persistence/conversation-types.ts +0 -8
- package/src/persistence/db-async-query.ts +1 -1
- package/src/persistence/db-connection.ts +11 -1
- package/src/persistence/db-init.ts +1 -1
- package/src/persistence/db-maintenance.ts +1 -1
- package/src/persistence/embeddings/__tests__/embedding-local-lifecycle.test.ts +1 -1
- package/src/persistence/embeddings/embedding-local.ts +4 -4
- package/src/persistence/embeddings/embedding-runtime-manager.ts +1 -1
- package/src/persistence/embeddings/qdrant-client.ts +1 -1
- package/src/persistence/embeddings/qdrant-manager.ts +1 -1
- package/src/persistence/job-handlers/__tests__/message-lexical-backfill.test.ts +1 -1
- package/src/persistence/job-handlers/__tests__/message-lexical-enqueue.test.ts +1 -1
- package/src/persistence/job-handlers/cleanup.ts +8 -17
- package/src/persistence/llm-usage-store.ts +2 -229
- package/src/persistence/message-content-file.ts +1 -1
- package/src/persistence/migrations/209-strip-thinking-from-consolidated.ts +1 -1
- package/src/persistence/migrations/222-strip-placeholder-sentinels-from-messages.ts +1 -1
- package/src/persistence/migrations/296-rewrite-balanced-economy-profile-pins.test.ts +1 -1
- package/src/persistence/migrations/306-rewrite-frontier-profile-pins.test.ts +1 -1
- package/src/persistence/migrations/329-move-onboarding-events-to-telemetry-db.test.ts +13 -0
- package/src/persistence/migrations/330-move-auth-fallback-events-to-telemetry-db.test.ts +13 -0
- package/src/persistence/migrations/331-move-lifecycle-events-to-telemetry-db.test.ts +13 -0
- package/src/persistence/migrations/332-move-skill-loaded-events-to-telemetry-db.test.ts +13 -0
- package/src/persistence/migrations/333-create-telemetry-events-table.test.ts +7 -4
- package/src/persistence/migrations/334-backfill-telemetry-events-outbox.test.ts +13 -0
- package/src/persistence/migrations/387-drop-telemetry-tables.ts +51 -0
- package/src/persistence/migrations/__tests__/327-create-flush-checkpoints.test.ts +9 -1
- package/src/persistence/migrations/__tests__/387-drop-telemetry-tables.test.ts +79 -0
- package/src/persistence/migrations/helpers/relocation.ts +1 -1
- package/src/persistence/migrations/run-migrations.ts +1 -1
- package/src/persistence/migrations/validate-migration-state.ts +1 -1
- package/src/persistence/raw-query.ts +1 -29
- package/src/persistence/slow-sync-log.ts +0 -23
- package/src/persistence/steps.ts +2 -0
- package/src/{telemetry → persistence}/tool-audit.ts +6 -121
- package/src/plugin-api/index.ts +1 -1
- package/src/plugin-api/plugin-name-env.ts +1 -1
- package/src/plugins/__tests__/installed-plugin-dirs.test.ts +1 -1
- package/src/plugins/collect-source-versions.ts +1 -1
- package/src/plugins/defaults/channel/package.json +1 -1
- package/src/plugins/defaults/cloud-hosted/package.json +1 -1
- package/src/plugins/defaults/compaction/package.json +1 -1
- package/src/plugins/defaults/documents/package.json +1 -1
- package/src/plugins/defaults/empty-response/package.json +1 -1
- package/src/plugins/defaults/exploration-drift/package.json +1 -1
- package/src/plugins/defaults/image-fallback/package.json +1 -1
- package/src/plugins/defaults/image-recovery/package.json +1 -1
- package/src/plugins/defaults/max-tokens-continue/package.json +1 -1
- package/src/plugins/defaults/memory/__tests__/db-async-query.test.ts +1 -1
- package/src/plugins/defaults/memory/__tests__/db-maintenance.test.ts +1 -1
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +0 -82
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-skill-card.test.ts +0 -41
- package/src/plugins/defaults/memory/__tests__/memory-tier-boundary-guard.test.ts +0 -2
- package/src/plugins/defaults/memory/memory-retrospective-job.ts +3 -52
- package/src/plugins/defaults/memory/memory-retrospective-skill-card.ts +0 -18
- package/src/plugins/defaults/memory/package.json +1 -1
- package/src/plugins/defaults/memory/paths.ts +4 -4
- package/src/plugins/defaults/memory/src/__tests__/memory-worker-routes.test.ts +1 -1
- package/src/plugins/defaults/memory/src/memory-v2-routes.ts +5 -5
- package/src/plugins/defaults/memory/src/memory-v3-routes.ts +0 -207
- package/src/plugins/defaults/memory/src/memory-worker-routes.ts +1 -1
- package/src/plugins/defaults/memory/startup.ts +1 -22
- package/src/plugins/defaults/memory/v3/__tests__/orchestrate.test.ts +2 -253
- package/src/plugins/defaults/memory/v3/orchestrate.ts +5 -129
- package/src/plugins/defaults/memory/worker-control.ts +1 -1
- package/src/plugins/defaults/memory/worker.ts +2 -2
- package/src/plugins/defaults/session/package.json +1 -1
- package/src/plugins/defaults/surface-completion-nudge/package.json +1 -1
- package/src/plugins/defaults/task-progress/package.json +1 -1
- package/src/plugins/defaults/task-progress-nudge/package.json +1 -1
- package/src/plugins/defaults/title-generate/package.json +1 -1
- package/src/plugins/defaults/tool-error/package.json +1 -1
- package/src/plugins/defaults/tool-result-truncate/package.json +1 -1
- package/src/plugins/defaults/turn-context/package.json +1 -1
- package/src/plugins/defaults/workspace/injectors.ts +1 -1
- package/src/plugins/defaults/workspace/package.json +1 -1
- package/src/plugins/disabled-state.ts +1 -1
- package/src/plugins/ensure-plugin-api-shim.ts +1 -1
- package/src/plugins/ensure-shared-dep-links.ts +1 -1
- package/src/plugins/installed-plugin-dirs.ts +1 -1
- package/src/plugins/mcp-servers.ts +7 -9
- package/src/plugins/mtime-cache.ts +2 -2
- package/src/plugins/source-versions.ts +1 -1
- package/src/prompts/bootstrap-cleanup.ts +1 -1
- package/src/prompts/persona-resolver.ts +1 -1
- package/src/prompts/sections.ts +2 -2
- package/src/prompts/system-prompt.ts +10 -42
- package/src/prompts/templates/BOOTSTRAP-ACTIVATION-RAIL.md +0 -37
- package/src/providers/__tests__/cadet-connection-routing.test.ts +2 -2
- package/src/providers/cadet/client.ts +1 -1
- package/src/providers/inference/__tests__/base-url-route-validation.test.ts +1 -1
- package/src/providers/inference/adapter-factory.ts +1 -1
- package/src/providers/inference/backfill.ts +3 -10
- package/src/providers/inference/profile-probe.ts +1 -1
- package/src/providers/retry.ts +0 -2
- package/src/providers/types.ts +0 -7
- package/src/providers/usage-tracking.ts +1 -1
- package/src/routes/__tests__/route-host.test.ts +1 -1
- package/src/routes/control.ts +1 -1
- package/src/routes/route-host-client.ts +1 -1
- package/src/routes/worker.ts +2 -2
- package/src/runtime/agent-wake.ts +1 -1
- package/src/runtime/assistant-stream-state.ts +1 -1
- package/src/runtime/auth/token-service.ts +1 -1
- package/src/runtime/background-job-runner.ts +1 -1
- package/src/runtime/middleware/twilio-validation.ts +2 -2
- package/src/runtime/routes/__tests__/app-pin-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/apps-refresh-route.test.ts +1 -1
- package/src/runtime/routes/__tests__/avatar-state-routes.test.ts +3 -33
- package/src/runtime/routes/__tests__/cloud-credits-routes.test.ts +5 -4
- package/src/runtime/routes/__tests__/cloud-invoice-routes.test.ts +4 -3
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +59 -287
- package/src/runtime/routes/__tests__/default-plugin-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/deprecated-route-context.test.ts +15 -62
- package/src/runtime/routes/__tests__/inference-profiles-routes.test.ts +105 -12
- package/src/runtime/routes/__tests__/ingress-status-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/monitoring-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +47 -211
- package/src/runtime/routes/__tests__/route-host-worker-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/schedule-routes-disarm-reason.test.ts +1 -1
- package/src/runtime/routes/__tests__/schedule-worker-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/user-route-dispatcher-host.test.ts +1 -1
- package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +1 -1
- package/src/runtime/routes/__tests__/user-routes-cli.test.ts +1 -1
- package/src/runtime/routes/__tests__/user-routes-notices.test.ts +1 -1
- package/src/runtime/routes/__tests__/user-routes-request.test.ts +1 -1
- package/src/runtime/routes/app-management-routes.ts +1 -1
- package/src/runtime/routes/attachment-routes.ts +1 -1
- package/src/runtime/routes/audit-routes.ts +1 -1
- package/src/runtime/routes/avatar-routes.ts +3 -10
- package/src/runtime/routes/cloud-routes.ts +3 -3
- package/src/runtime/routes/content-source-routes.ts +1 -1
- package/src/runtime/routes/conversation-query-routes.ts +60 -621
- package/src/runtime/routes/conversation-routes.ts +1 -38
- package/src/runtime/routes/debug-routes.ts +1 -1
- package/src/runtime/routes/deprecated-route-context.ts +5 -61
- package/src/runtime/routes/heartbeat-routes.ts +1 -1
- package/src/runtime/routes/identity-routes.ts +1 -1
- package/src/runtime/routes/index.ts +0 -6
- package/src/runtime/routes/inference-profile-session-handler.ts +3 -3
- package/src/runtime/routes/inference-profiles-routes.ts +48 -21
- package/src/runtime/routes/inference-provider-connection-routes.ts +0 -1
- package/src/runtime/routes/llm-call-sites-routes.ts +3 -3
- package/src/runtime/routes/log-export/__tests__/installed-inventory.test.ts +1 -1
- package/src/runtime/routes/log-export/__tests__/workspace-allowlist-error-contract.test.ts +1 -1
- package/src/runtime/routes/log-export/__tests__/workspace-allowlist.test.ts +1 -1
- package/src/runtime/routes/log-export/workspace-allowlist.ts +1 -1
- package/src/runtime/routes/log-export-routes.ts +17 -15
- package/src/runtime/routes/migration-rollback-routes.ts +1 -1
- package/src/runtime/routes/migration-routes.ts +2 -3
- package/src/runtime/routes/monitoring-routes.ts +2 -2
- package/src/runtime/routes/oauth-providers.ts +5 -5
- package/src/runtime/routes/plugins-routes.ts +38 -163
- package/src/runtime/routes/profiler-routes.ts +1 -1
- package/src/runtime/routes/route-host-worker-routes.ts +1 -1
- package/src/runtime/routes/sanity-routes.ts +1 -1
- package/src/runtime/routes/schedule-routes.ts +1 -1
- package/src/runtime/routes/schedule-worker-routes.ts +1 -1
- package/src/runtime/routes/settings-routes.ts +1 -1
- package/src/runtime/routes/sounds-config-routes.ts +1 -1
- package/src/runtime/routes/surface-conversation-resolver.ts +1 -7
- package/src/runtime/routes/user-route-dispatcher.ts +1 -3
- package/src/runtime/routes/user-route-import.ts +1 -1
- package/src/runtime/routes/user-route-resolution.ts +1 -1
- package/src/runtime/routes/user-routes-cli.ts +1 -1
- package/src/runtime/routes/workspace-commit-routes.ts +1 -1
- package/src/runtime/routes/workspace-greetings.ts +1 -1
- package/src/runtime/routes/workspace-routes.ts +1 -1
- package/src/runtime/routes/workspace-utils.ts +1 -1
- package/src/runtime/sync/resource-sync-events.ts +1 -1
- package/src/schedule/__tests__/plugin-schedule-declarations.test.ts +1 -1
- package/src/schedule/__tests__/plugin-schedule-reconciler.test.ts +1 -1
- package/src/schedule/plugin-schedule-availability.ts +1 -1
- package/src/schedule/plugin-schedule-declarations.ts +1 -1
- package/src/schedule/run-script.ts +1 -1
- package/src/schedule/scheduler.ts +1 -11
- package/src/schedule/worker-control.ts +1 -1
- package/src/schedule/worker.ts +3 -3
- package/src/security/oauth2.ts +2 -2
- package/src/security/secret-allowlist.ts +1 -1
- package/src/signals/cancel.ts +1 -1
- package/src/signals/conversation-undo.ts +1 -1
- package/src/signals/emit-event.ts +1 -1
- package/src/signals/event-stream.ts +1 -1
- package/src/signals/user-message.ts +1 -1
- package/src/skills/catalog-install.ts +2 -1
- package/src/skills/clawhub.ts +1 -1
- package/src/skills/cloud-store.ts +1 -1
- package/src/skills/path-classifier.ts +1 -1
- package/src/skills/skill-history.ts +1 -1
- package/src/skills/skillssh-registry.ts +1 -1
- package/src/skills/uninstall.ts +1 -1
- package/src/skills/workspace-skill-md-signature.ts +1 -1
- package/src/subagent/manager.ts +1 -1
- package/src/theme/workspace-theme.ts +1 -1
- package/src/tools/browser/auth-cache.ts +1 -1
- package/src/tools/browser/browser-manager.ts +1 -1
- package/src/tools/browser/runtime-check.ts +1 -1
- package/src/tools/executor.ts +4 -4
- package/src/tools/filesystem/write.ts +1 -1
- package/src/tools/permission-checker.ts +2 -51
- package/src/tools/run-standalone.ts +1 -1
- package/src/tools/skills/format-input-schema.ts +1 -1
- package/src/tools/skills/load.ts +1 -1
- package/src/tools/skills/scaffold-cloud.ts +0 -32
- package/src/tools/terminal/safe-env.ts +1 -2
- package/src/tools/terminal/sanitized-bash.ts +1 -1
- package/src/tools/terminal/shell.ts +1 -1
- package/src/tools/tool-approval-handler.ts +4 -1
- package/src/tools/workflows/manage-workflows.ts +2 -2
- package/src/tools/workflows/run-workflow.test.ts +1 -1
- package/src/tools/workspace-tools/loader.ts +1 -1
- package/src/tts/synthesis-stream.ts +2 -2
- package/src/usage/attribution.ts +1 -11
- package/src/util/browser.ts +1 -1
- package/src/util/bun-runtime.ts +2 -1
- package/src/util/device-id.ts +1 -1
- package/src/util/disk-usage.ts +4 -139
- package/src/util/layout.ts +3 -3
- package/src/util/logger.ts +1 -1
- package/src/util/logs-db-path.ts +1 -1
- package/src/util/memory-db-path.ts +1 -1
- package/src/util/{platform.ts → os.ts} +5 -30
- package/src/util/process-tree.ts +19 -0
- package/src/util/sqlite3-runtime.ts +1 -1
- package/src/util/telemetry-db-path.ts +1 -1
- package/src/watcher/__tests__/engine.test.ts +0 -23
- package/src/watcher/engine.ts +0 -7
- package/src/windows-compiled-cli.ts +0 -4
- package/src/windows-compiled-worker-entry.ts +0 -6
- package/src/workflows/leaf-runner.test.ts +1 -1
- package/src/workflows/leaf-runner.ts +1 -1
- package/src/workflows/library.ts +1 -1
- package/src/workspace/adaptive-thinking-repair.ts +5 -24
- package/src/workspace/byok-default-profile-ensure.ts +24 -26
- package/src/workspace/custom-profile-ensure.ts +2 -2
- package/src/workspace/git-service.ts +1 -1
- package/src/workspace/hatched-date.ts +1 -1
- package/src/workspace/migrations/038-unify-llm-callsite-configs.ts +2 -2
- package/src/workspace/migrations/040-seed-latency-callsite-defaults.ts +1 -1
- package/src/workspace/migrations/050-seed-main-agent-opus-callsite.ts +1 -1
- package/src/workspace/migrations/077-seed-memory-router-callsite.ts +1 -1
- package/src/workspace/migrations/registry.ts +0 -4
- package/src/workspace/turn-commit.ts +1 -1
- package/docs/activation-funnel-telemetry.md +0 -324
- package/scripts/bundled-plugin-packages.ts +0 -154
- package/scripts/generate-bundled-plugin-packages.ts +0 -29
- package/src/__tests__/activation-early-marking.test.ts +0 -114
- package/src/__tests__/auth-fallback-events-store.test.ts +0 -99
- package/src/__tests__/config-get-vision-flag.test.ts +0 -139
- package/src/__tests__/conversation-surfaces-activation-emit.test.ts +0 -400
- package/src/__tests__/internal-telemetry-routes.test.ts +0 -213
- package/src/__tests__/telemetry-routes.test.ts +0 -182
- package/src/__tests__/turn-events-store.test.ts +0 -376
- package/src/__tests__/ui-channel-variants.test.ts +0 -53
- package/src/avatar/__tests__/avatar-changed-telemetry.test.ts +0 -217
- package/src/avatar/avatar-changed-telemetry.ts +0 -128
- package/src/calls/__tests__/call-funnel-telemetry.test.ts +0 -204
- package/src/cli/commands/telemetry.help.ts +0 -27
- package/src/cli/commands/telemetry.ts +0 -83
- package/src/cli/lib/__tests__/local-plugin-upgrade.test.ts +0 -251
- package/src/cli/lib/__tests__/plugin-catalog-local.test.ts +0 -113
- package/src/cli/lib/__tests__/plugin-marketplace.test.ts +0 -384
- package/src/cli/lib/__tests__/plugin-pin-history.test.ts +0 -164
- package/src/cli/lib/__tests__/plugins-install-offline.test.ts +0 -228
- package/src/cli/lib/bundled-marketplace.json +0 -1575
- package/src/cli/lib/bundled-plugin-packages.json +0 -827
- package/src/cli/lib/bundled-plugin-packages.ts +0 -87
- package/src/cli/lib/plugin-catalog-local.ts +0 -94
- package/src/cli/lib/plugin-pin-history.ts +0 -276
- package/src/cloud/feature-gate.ts +0 -8
- package/src/config/__tests__/cloud-rehydration.test.ts +0 -180
- package/src/config/cloud-rehydration.ts +0 -35
- package/src/daemon/__tests__/auto-profile-router.test.ts +0 -380
- package/src/daemon/auto-profile-router.ts +0 -428
- package/src/live-voice/__tests__/live-voice-session-telemetry.test.ts +0 -391
- package/src/monitoring/__tests__/db-integrity-sample.test.ts +0 -113
- package/src/monitoring/__tests__/oom-kill-reporter.test.ts +0 -374
- package/src/monitoring/db-integrity-check.ts +0 -163
- package/src/monitoring/db-integrity-sample.ts +0 -176
- package/src/monitoring/oom-kill-reporter.ts +0 -469
- package/src/onboarding/__tests__/onboarding-events-store.test.ts +0 -158
- package/src/onboarding/onboarding-events-store.ts +0 -296
- package/src/persistence/__tests__/raw-query-telemetry.test.ts +0 -76
- package/src/persistence/lifecycle-events-store.test.ts +0 -134
- package/src/persistence/lifecycle-events-store.ts +0 -110
- package/src/plugins/defaults/memory/__tests__/activation-session-store.test.ts +0 -76
- package/src/plugins/defaults/memory/activation-session-store.ts +0 -50
- package/src/plugins/defaults/memory/src/__tests__/memory-v3-gate-stats.test.ts +0 -281
- package/src/runtime/routes/auto-profile-routes.ts +0 -83
- package/src/runtime/routes/internal-telemetry-routes.ts +0 -142
- package/src/runtime/routes/telemetry-routes.ts +0 -274
- package/src/security/auth-fallback-events-store.ts +0 -57
- package/src/telemetry/__tests__/activation-funnel.test.ts +0 -95
- package/src/telemetry/__tests__/config-setting-events-store.test.ts +0 -63
- package/src/telemetry/__tests__/config-setting-snapshot.test.ts +0 -143
- package/src/telemetry/__tests__/flush-checkpoints.test.ts +0 -56
- package/src/telemetry/__tests__/live-voice-funnel.test.ts +0 -174
- package/src/telemetry/__tests__/outbox-test-harness.ts +0 -85
- package/src/telemetry/__tests__/phone-call-funnel.test.ts +0 -72
- package/src/telemetry/__tests__/telemetry-event-fixtures.ts +0 -282
- package/src/telemetry/__tests__/watchdog-events-store.test.ts +0 -71
- package/src/telemetry/activation-funnel.ts +0 -172
- package/src/telemetry/config-setting-events-store.ts +0 -40
- package/src/telemetry/config-setting-snapshot.ts +0 -170
- package/src/telemetry/flush-checkpoints.ts +0 -70
- package/src/telemetry/live-voice-funnel.ts +0 -185
- package/src/telemetry/memory-corpus-size.test.ts +0 -120
- package/src/telemetry/memory-corpus-size.ts +0 -184
- package/src/telemetry/memory-tier-reporter.test.ts +0 -195
- package/src/telemetry/memory-tier-reporter.ts +0 -130
- package/src/telemetry/phone-call-funnel.ts +0 -144
- package/src/telemetry/skill-loaded-events-store.test.ts +0 -93
- package/src/telemetry/skill-loaded-events-store.ts +0 -39
- package/src/telemetry/telemetry-event-sources.test.ts +0 -223
- package/src/telemetry/telemetry-event-sources.ts +0 -597
- package/src/telemetry/telemetry-events-outbox.test.ts +0 -375
- package/src/telemetry/telemetry-events-outbox.ts +0 -237
- package/src/telemetry/telemetry-main-db.ts +0 -48
- package/src/telemetry/telemetry-wire-source.json +0 -4
- package/src/telemetry/telemetry-wire-validation.test.ts +0 -157
- package/src/telemetry/telemetry-wire-validation.ts +0 -162
- package/src/telemetry/telemetry-wire.generated.ts +0 -483
- package/src/telemetry/tool-executed-events-store.test.ts +0 -210
- package/src/telemetry/tool-executed-events-store.ts +0 -102
- package/src/telemetry/trace-collection-policy.test.ts +0 -28
- package/src/telemetry/trace-collection-policy.ts +0 -30
- package/src/telemetry/turn-events-store.ts +0 -216
- package/src/telemetry/turn-trace-store.test.ts +0 -884
- package/src/telemetry/turn-trace-store.ts +0 -399
- package/src/telemetry/types.test.ts +0 -38
- package/src/telemetry/types.ts +0 -780
- package/src/telemetry/usage-telemetry-reporter.test.ts +0 -3445
- package/src/telemetry/usage-telemetry-reporter.ts +0 -566
- package/src/telemetry/watchdog-direct-emit.test.ts +0 -112
- package/src/telemetry/watchdog-direct-emit.ts +0 -104
- package/src/telemetry/watchdog-events-store.ts +0 -31
- package/src/tools/ui-surface/channel-variants.ts +0 -52
- package/src/watcher/__tests__/telemetry.test.ts +0 -178
- package/src/watcher/telemetry.ts +0 -93
- package/src/workspace/migrations/097-enable-adaptive-thinking-managed-profiles.ts +0 -165
- package/src/workspace/migrations/104-recheck-adaptive-thinking-model-implied-anthropic.ts +0 -151
- /package/src/{telemetry → persistence}/tool-usage-store.ts +0 -0
- /package/src/{telemetry → persistence}/turn-outcome.ts +0 -0
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
import { readdirSync, readFileSync, statSync } from "node:fs";
|
|
2
|
-
import { join } from "node:path";
|
|
3
|
-
|
|
4
|
-
import { getWorkspaceDir } from "../util/platform.js";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Coarse on-disk size of the assistant's memory corpus, in the snake_case
|
|
8
|
-
* shape the `memory_tier` watchdog `detail` bag carries to the cloud.
|
|
9
|
-
*
|
|
10
|
-
* Both corpora are measured on every tier rather than branching on the tier
|
|
11
|
-
* itself: an assistant part-way through a v1 -> v2 -> v3 migration has content
|
|
12
|
-
* in both trees, and a `memory.enabled: false` assistant still has whatever it
|
|
13
|
-
* accumulated before being switched off. Reporting both unconditionally keeps
|
|
14
|
-
* the numbers legible across a migration instead of blinking to zero the
|
|
15
|
-
* moment a tier flips.
|
|
16
|
-
*
|
|
17
|
-
* KNOWN GAP: this measures on-disk Markdown only. It does NOT count
|
|
18
|
-
* `memory_graph_nodes`, which is a real part of a v1 assistant's learned state
|
|
19
|
-
* — `v2/migration.ts` gathers graph nodes alongside PKB Markdown when it
|
|
20
|
-
* migrates v1 — so a v1 assistant rich in graph nodes but holding only the
|
|
21
|
-
* seeded PKB files reads as near-empty here. Counting them means opening the
|
|
22
|
-
* memory SQLite DB from the resource-monitor process, which this probe
|
|
23
|
-
* deliberately does not do. Treat `pkb_files` as a lower bound on v1 corpus
|
|
24
|
-
* size and confirm v1 assistants directly before sizing a migration off it.
|
|
25
|
-
*/
|
|
26
|
-
export interface MemoryCorpusSize {
|
|
27
|
-
/** `.md` files under `memory/concepts/` — the v2/v3 concept-page count. */
|
|
28
|
-
concept_pages: number;
|
|
29
|
-
/** Total bytes of those concept pages. */
|
|
30
|
-
concept_bytes: number;
|
|
31
|
-
/** `.md` files under `pkb/` — the v1 personal-knowledge-base corpus. */
|
|
32
|
-
pkb_files: number;
|
|
33
|
-
/** Total bytes of those PKB files. */
|
|
34
|
-
pkb_bytes: number;
|
|
35
|
-
/**
|
|
36
|
-
* Non-empty lines in `memory/buffer.md` — remembered facts still waiting on
|
|
37
|
-
* consolidation. Matches `countBufferLines` in the substrate's
|
|
38
|
-
* consolidation job: for a well-formed buffer, one non-empty line is one
|
|
39
|
-
* entry.
|
|
40
|
-
*/
|
|
41
|
-
buffer_lines: number;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Ceiling on directory entries examined per tree. The largest corpus observed
|
|
46
|
-
* in the fleet is in the low hundreds of pages, so this never binds in
|
|
47
|
-
* practice; it exists so a pathological workspace cannot turn a telemetry
|
|
48
|
-
* probe into a long walk.
|
|
49
|
-
*
|
|
50
|
-
* It counts every dirent seen — directories and non-Markdown files included —
|
|
51
|
-
* not just the Markdown matches. A cap on matches alone would not bound the
|
|
52
|
-
* walk at all: a tree of a million empty directories contains zero Markdown
|
|
53
|
-
* files and would still be traversed in full by this synchronous probe.
|
|
54
|
-
*
|
|
55
|
-
* A tree that hits the cap returns what it counted so far, making the result
|
|
56
|
-
* a floor rather than an error.
|
|
57
|
-
*/
|
|
58
|
-
const MAX_ENTRIES_PER_TREE = 20_000;
|
|
59
|
-
|
|
60
|
-
interface TreeSize {
|
|
61
|
-
files: number;
|
|
62
|
-
bytes: number;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const EMPTY_TREE: TreeSize = { files: 0, bytes: 0 };
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Recursively total the `.md` files under `dir`.
|
|
69
|
-
*
|
|
70
|
-
* Deliberately synchronous, and deliberately not routed through the memory
|
|
71
|
-
* plugin's `listPages` / `getPageIndex`. This runs in the resource-monitor
|
|
72
|
-
* process, where the plugin's page-index cache is cold — going through it
|
|
73
|
-
* would read and parse every concept page on each six-hour cycle, and would
|
|
74
|
-
* add an import out of `telemetry/` into the plugin tree that the plugin
|
|
75
|
-
* import-boundary guard exists to prevent. A bare readdir + stat is the whole
|
|
76
|
-
* job here.
|
|
77
|
-
*
|
|
78
|
-
* `withFileTypes` dirents carry lstat semantics, so a symlinked directory
|
|
79
|
-
* reports as a symlink rather than a directory and is skipped — the walk
|
|
80
|
-
* cannot follow a link into a cycle, and needs no visited-inode bookkeeping.
|
|
81
|
-
*
|
|
82
|
-
* `maxEntries` is a parameter only so the ceiling is testable without
|
|
83
|
-
* materializing twenty thousand files; production callers take the default.
|
|
84
|
-
*/
|
|
85
|
-
export function measureMarkdownTree(
|
|
86
|
-
dir: string,
|
|
87
|
-
maxEntries: number = MAX_ENTRIES_PER_TREE,
|
|
88
|
-
): TreeSize {
|
|
89
|
-
let files = 0;
|
|
90
|
-
let bytes = 0;
|
|
91
|
-
let visited = 0;
|
|
92
|
-
const pending: string[] = [dir];
|
|
93
|
-
|
|
94
|
-
while (pending.length > 0) {
|
|
95
|
-
const current = pending.pop();
|
|
96
|
-
if (current === undefined) {
|
|
97
|
-
break;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
let entries;
|
|
101
|
-
try {
|
|
102
|
-
entries = readdirSync(current, { withFileTypes: true });
|
|
103
|
-
} catch {
|
|
104
|
-
// A missing or unreadable subtree contributes nothing. The common case
|
|
105
|
-
// is ENOENT: the tier that owns this tree was never active here.
|
|
106
|
-
continue;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
for (const entry of entries) {
|
|
110
|
-
visited += 1;
|
|
111
|
-
if (visited > maxEntries) {
|
|
112
|
-
return { files, bytes };
|
|
113
|
-
}
|
|
114
|
-
if (entry.isDirectory()) {
|
|
115
|
-
pending.push(join(current, entry.name));
|
|
116
|
-
continue;
|
|
117
|
-
}
|
|
118
|
-
if (!entry.isFile() || !entry.name.endsWith(".md")) {
|
|
119
|
-
continue;
|
|
120
|
-
}
|
|
121
|
-
files += 1;
|
|
122
|
-
try {
|
|
123
|
-
bytes += statSync(join(current, entry.name)).size;
|
|
124
|
-
} catch {
|
|
125
|
-
// Counted in `files` but contributes no bytes — a file that vanished
|
|
126
|
-
// between the readdir and the stat is a race, not a failure.
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
return { files, bytes };
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/** Non-empty-line count of the file at `path`; 0 when it is absent or empty. */
|
|
135
|
-
function countNonEmptyLines(path: string): number {
|
|
136
|
-
let content: string;
|
|
137
|
-
try {
|
|
138
|
-
content = readFileSync(path, "utf8");
|
|
139
|
-
} catch {
|
|
140
|
-
return 0;
|
|
141
|
-
}
|
|
142
|
-
if (content.length === 0) {
|
|
143
|
-
return 0;
|
|
144
|
-
}
|
|
145
|
-
return content.split("\n").filter((line) => line.trim().length > 0).length;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Measure the on-disk memory corpus for this assistant.
|
|
150
|
-
*
|
|
151
|
-
* Never throws: every probe degrades to zero independently, so a corpus that
|
|
152
|
-
* is partly unreadable still reports the part that is.
|
|
153
|
-
*/
|
|
154
|
-
export function measureMemoryCorpusSize(): MemoryCorpusSize {
|
|
155
|
-
const workspaceDir = getWorkspaceDir();
|
|
156
|
-
|
|
157
|
-
let concepts: TreeSize = EMPTY_TREE;
|
|
158
|
-
let pkb: TreeSize = EMPTY_TREE;
|
|
159
|
-
let bufferLines = 0;
|
|
160
|
-
|
|
161
|
-
try {
|
|
162
|
-
concepts = measureMarkdownTree(join(workspaceDir, "memory", "concepts"));
|
|
163
|
-
} catch {
|
|
164
|
-
concepts = EMPTY_TREE;
|
|
165
|
-
}
|
|
166
|
-
try {
|
|
167
|
-
pkb = measureMarkdownTree(join(workspaceDir, "pkb"));
|
|
168
|
-
} catch {
|
|
169
|
-
pkb = EMPTY_TREE;
|
|
170
|
-
}
|
|
171
|
-
try {
|
|
172
|
-
bufferLines = countNonEmptyLines(join(workspaceDir, "memory", "buffer.md"));
|
|
173
|
-
} catch {
|
|
174
|
-
bufferLines = 0;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
return {
|
|
178
|
-
concept_pages: concepts.files,
|
|
179
|
-
concept_bytes: concepts.bytes,
|
|
180
|
-
pkb_files: pkb.files,
|
|
181
|
-
pkb_bytes: pkb.bytes,
|
|
182
|
-
buffer_lines: bufferLines,
|
|
183
|
-
};
|
|
184
|
-
}
|
|
@@ -1,195 +0,0 @@
|
|
|
1
|
-
import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test";
|
|
2
|
-
|
|
3
|
-
import type { ConsentState } from "../cloud/consent-cache.js";
|
|
4
|
-
import { memoryTier } from "../config/memory-tier.js";
|
|
5
|
-
import type { AssistantConfig } from "../config/schema.js";
|
|
6
|
-
import type { MemoryCorpusSize } from "./memory-corpus-size.js";
|
|
7
|
-
import type { WatchdogEventRecord } from "./watchdog-events-store.js";
|
|
8
|
-
|
|
9
|
-
// Mutable stubs flipped per test. bun's `mock.module` patches retroactively
|
|
10
|
-
// (live bindings), so the reporter's imports resolve to these regardless of
|
|
11
|
-
// import order (mirrors `outbox-test-harness.ts`). Kept off the outbox/DB path
|
|
12
|
-
// on purpose: mocking `recordWatchdogEvent` lets these assert emission without
|
|
13
|
-
// standing up the telemetry DB.
|
|
14
|
-
let consent: ConsentState = true;
|
|
15
|
-
let currentConfig: AssistantConfig = {} as AssistantConfig;
|
|
16
|
-
let recorded: WatchdogEventRecord[] = [];
|
|
17
|
-
|
|
18
|
-
// Stubbed so the assertions below stay exact-match: the real probe walks the
|
|
19
|
-
// live workspace, whose contents differ per machine. `measureMemoryCorpusSize`
|
|
20
|
-
// has its own tests against a temp tree.
|
|
21
|
-
const ZERO_CORPUS: MemoryCorpusSize = {
|
|
22
|
-
concept_pages: 0,
|
|
23
|
-
concept_bytes: 0,
|
|
24
|
-
pkb_files: 0,
|
|
25
|
-
pkb_bytes: 0,
|
|
26
|
-
buffer_lines: 0,
|
|
27
|
-
};
|
|
28
|
-
let corpus: MemoryCorpusSize = ZERO_CORPUS;
|
|
29
|
-
let corpusError: Error | null = null;
|
|
30
|
-
|
|
31
|
-
mock.module("./memory-corpus-size.js", () => ({
|
|
32
|
-
measureMemoryCorpusSize: () => {
|
|
33
|
-
if (corpusError) {
|
|
34
|
-
throw corpusError;
|
|
35
|
-
}
|
|
36
|
-
return corpus;
|
|
37
|
-
},
|
|
38
|
-
}));
|
|
39
|
-
mock.module("../cloud/consent-cache.js", () => ({
|
|
40
|
-
getRawShareAnalytics: () => consent,
|
|
41
|
-
}));
|
|
42
|
-
mock.module("../config/loader.js", () => ({
|
|
43
|
-
getConfigReadOnly: () => currentConfig,
|
|
44
|
-
}));
|
|
45
|
-
mock.module("./watchdog-events-store.js", () => ({
|
|
46
|
-
recordWatchdogEvent: (record: WatchdogEventRecord) => {
|
|
47
|
-
recorded.push(record);
|
|
48
|
-
},
|
|
49
|
-
}));
|
|
50
|
-
|
|
51
|
-
import {
|
|
52
|
-
recordMemoryTierOnce,
|
|
53
|
-
startMemoryTierReporter,
|
|
54
|
-
stopMemoryTierReporter,
|
|
55
|
-
} from "./memory-tier-reporter.js";
|
|
56
|
-
|
|
57
|
-
function makeConfig(
|
|
58
|
-
enabled: boolean,
|
|
59
|
-
v2Enabled: boolean,
|
|
60
|
-
v3Live = false,
|
|
61
|
-
): AssistantConfig {
|
|
62
|
-
return {
|
|
63
|
-
memory: {
|
|
64
|
-
enabled,
|
|
65
|
-
v2: { enabled: v2Enabled },
|
|
66
|
-
v3: { live: v3Live },
|
|
67
|
-
},
|
|
68
|
-
} as AssistantConfig;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
describe("memory-tier-reporter", () => {
|
|
72
|
-
beforeEach(() => {
|
|
73
|
-
consent = true;
|
|
74
|
-
currentConfig = {} as AssistantConfig;
|
|
75
|
-
recorded = [];
|
|
76
|
-
corpus = ZERO_CORPUS;
|
|
77
|
-
corpusError = null;
|
|
78
|
-
// Clear any interval/boot-retry timer a prior test's start left behind.
|
|
79
|
-
stopMemoryTierReporter();
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
afterEach(() => {
|
|
83
|
-
stopMemoryTierReporter();
|
|
84
|
-
delete process.env.CADET_DEV;
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
test("emits a memory_tier watchdog carrying the current tier", () => {
|
|
88
|
-
const config = makeConfig(true, true); // memory on, v2 enabled → "v2"
|
|
89
|
-
currentConfig = config;
|
|
90
|
-
|
|
91
|
-
recordMemoryTierOnce();
|
|
92
|
-
|
|
93
|
-
expect(recorded).toHaveLength(1);
|
|
94
|
-
expect(recorded[0]).toEqual({
|
|
95
|
-
checkName: "memory_tier",
|
|
96
|
-
detail: { tier: memoryTier(config), ...ZERO_CORPUS },
|
|
97
|
-
});
|
|
98
|
-
expect(recorded[0]?.detail?.tier).toBe("v2");
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
test("reflects a different tier for a different config (v3 live)", () => {
|
|
102
|
-
currentConfig = makeConfig(true, true, true); // v3 live wins over v2
|
|
103
|
-
recordMemoryTierOnce();
|
|
104
|
-
|
|
105
|
-
expect(recorded[0]?.detail).toEqual({ tier: "v3", ...ZERO_CORPUS });
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
test("carries the measured corpus size alongside the tier", () => {
|
|
109
|
-
currentConfig = makeConfig(true, true, true);
|
|
110
|
-
corpus = {
|
|
111
|
-
concept_pages: 42,
|
|
112
|
-
concept_bytes: 133_700,
|
|
113
|
-
pkb_files: 3,
|
|
114
|
-
pkb_bytes: 900,
|
|
115
|
-
buffer_lines: 7,
|
|
116
|
-
};
|
|
117
|
-
|
|
118
|
-
recordMemoryTierOnce();
|
|
119
|
-
|
|
120
|
-
expect(recorded[0]?.detail).toEqual({ tier: "v3", ...corpus });
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
test("a failed corpus probe still emits the tier heartbeat", () => {
|
|
124
|
-
// The fleet-mix dashboards read `detail.tier`; a sizing failure must
|
|
125
|
-
// degrade the payload, never drop the event and gap the series.
|
|
126
|
-
currentConfig = makeConfig(true, true, true);
|
|
127
|
-
corpusError = new Error("workspace unreadable");
|
|
128
|
-
|
|
129
|
-
recordMemoryTierOnce();
|
|
130
|
-
|
|
131
|
-
expect(recorded).toHaveLength(1);
|
|
132
|
-
expect(recorded[0]?.detail).toEqual({ tier: "v3" });
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
test("emits every invocation — no memo", () => {
|
|
136
|
-
currentConfig = makeConfig(true, false); // "v1"
|
|
137
|
-
recordMemoryTierOnce();
|
|
138
|
-
recordMemoryTierOnce();
|
|
139
|
-
recordMemoryTierOnce();
|
|
140
|
-
|
|
141
|
-
expect(recorded).toHaveLength(3);
|
|
142
|
-
for (const event of recorded) {
|
|
143
|
-
expect(event).toEqual({
|
|
144
|
-
checkName: "memory_tier",
|
|
145
|
-
detail: { tier: "v1", ...ZERO_CORPUS },
|
|
146
|
-
});
|
|
147
|
-
}
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
test("unknown consent emits nothing", () => {
|
|
151
|
-
consent = "unknown";
|
|
152
|
-
currentConfig = makeConfig(true, true);
|
|
153
|
-
|
|
154
|
-
recordMemoryTierOnce();
|
|
155
|
-
|
|
156
|
-
expect(recorded).toHaveLength(0);
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
test("a confirmed opt-out still calls through (recordWatchdogEvent no-ops)", () => {
|
|
160
|
-
// The reporter only skips the UNKNOWN state; the `false` opt-out is
|
|
161
|
-
// honored one layer down in `recordWatchdogEvent`. Here that layer is the
|
|
162
|
-
// stub, so the call is observed — the drop is the real store's concern.
|
|
163
|
-
consent = false;
|
|
164
|
-
currentConfig = makeConfig(true, true);
|
|
165
|
-
|
|
166
|
-
recordMemoryTierOnce();
|
|
167
|
-
|
|
168
|
-
expect(recorded).toHaveLength(1);
|
|
169
|
-
});
|
|
170
|
-
|
|
171
|
-
test("a confirmed opt-out skips the corpus probe entirely", () => {
|
|
172
|
-
// The event is dropped one layer down, so walking the workspace for it
|
|
173
|
-
// would be pure cost on an assistant that asked us not to collect. The
|
|
174
|
-
// throwing stub asserts the probe is never reached.
|
|
175
|
-
consent = false;
|
|
176
|
-
currentConfig = makeConfig(true, true);
|
|
177
|
-
corpusError = new Error("probe must not run");
|
|
178
|
-
|
|
179
|
-
recordMemoryTierOnce();
|
|
180
|
-
|
|
181
|
-
expect(recorded).toHaveLength(1);
|
|
182
|
-
expect(recorded[0]?.detail).toEqual({ tier: "v2" });
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
test("startMemoryTierReporter is a no-op under CADET_DEV=1", () => {
|
|
186
|
-
process.env.CADET_DEV = "1";
|
|
187
|
-
consent = true; // consent known → a non-dev start would emit immediately
|
|
188
|
-
currentConfig = makeConfig(true, true);
|
|
189
|
-
|
|
190
|
-
startMemoryTierReporter();
|
|
191
|
-
|
|
192
|
-
// No boot emit and no interval scheduled.
|
|
193
|
-
expect(recorded).toHaveLength(0);
|
|
194
|
-
});
|
|
195
|
-
});
|
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
import { getRawShareAnalytics } from "../cloud/consent-cache.js";
|
|
2
|
-
import { getConfigReadOnly } from "../config/loader.js";
|
|
3
|
-
import { memoryTier } from "../config/memory-tier.js";
|
|
4
|
-
import { getLogger } from "../util/logger.js";
|
|
5
|
-
import { measureMemoryCorpusSize } from "./memory-corpus-size.js";
|
|
6
|
-
import { recordWatchdogEvent } from "./watchdog-events-store.js";
|
|
7
|
-
|
|
8
|
-
const log = getLogger("memory-tier-reporter");
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* How often each assistant re-asserts its coarse memory tier as a
|
|
12
|
-
* `memory_tier` watchdog event. Unlike the config-setting snapshot this emits
|
|
13
|
-
* UNCONDITIONALLY every cycle (no memo): the cloud-side query wants a
|
|
14
|
-
* periodic per-assistant heartbeat of the current tier, so a gap in the series
|
|
15
|
-
* is meaningful (assistant offline) rather than "value unchanged". Six-hourly
|
|
16
|
-
* keeps the volume trivial while giving a same-day read on the fleet's tier
|
|
17
|
-
* mix, and every boot re-asserts the tier regardless.
|
|
18
|
-
*/
|
|
19
|
-
const MEMORY_TIER_INTERVAL_MS = 6 * 60 * 60 * 1000;
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Watchdog `check_name` carrying the coarse memory tier in `detail.tier`,
|
|
23
|
-
* alongside the on-disk corpus size (see {@link measureMemoryCorpusSize}).
|
|
24
|
-
*
|
|
25
|
-
* The check name and the `detail.tier` bucket strings are frozen — platform
|
|
26
|
-
* dashboards group on them. The rest of `detail` is an open bag, so the
|
|
27
|
-
* corpus-size keys are additive and need no wire, serializer, or dbt change.
|
|
28
|
-
*/
|
|
29
|
-
const MEMORY_TIER_CHECK_NAME = "memory_tier";
|
|
30
|
-
|
|
31
|
-
// The boot-time emit races the first consent refresh (fire-and-forget in the
|
|
32
|
-
// monitor's startup), so consent is usually still "unknown" on the first call
|
|
33
|
-
// and the emit is skipped. Retry on a short timer until consent resolves
|
|
34
|
-
// rather than waiting a full six-hour interval for the per-boot assertion.
|
|
35
|
-
const BOOT_RETRY_INTERVAL_MS = 60_000;
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Emit one `memory_tier` watchdog event for this assistant's current tier.
|
|
39
|
-
*
|
|
40
|
-
* Consent-gated like the config-setting snapshot but with NO memo: every
|
|
41
|
-
* invocation emits, so the cloud sees a periodic heartbeat of the current
|
|
42
|
-
* tier rather than only edges. An UNKNOWN consent state skips entirely
|
|
43
|
-
* (consent resolves asynchronously after boot; the boot-retry loop re-invokes
|
|
44
|
-
* once it lands) — deferring loses nothing since the tier is re-derivable
|
|
45
|
-
* state. A confirmed opt-out is honored inside `recordWatchdogEvent`, which
|
|
46
|
-
* no-ops on a `false` share_analytics, so the call still goes through and the
|
|
47
|
-
* record layer drops it. Never throws: a storage failure is logged and
|
|
48
|
-
* retried on the next cycle.
|
|
49
|
-
*
|
|
50
|
-
* The event also carries the on-disk corpus size. That probe is best-effort
|
|
51
|
-
* and isolated: if it fails the event still goes out with the tier alone,
|
|
52
|
-
* because the tier heartbeat is what the fleet-mix dashboards depend on and a
|
|
53
|
-
* sizing failure must not create a gap in that series. It is also skipped
|
|
54
|
-
* outright on a confirmed opt-out — the event is dropped one layer down, so
|
|
55
|
-
* walking the workspace for it would be pure cost on the assistants that
|
|
56
|
-
* asked us not to collect.
|
|
57
|
-
*/
|
|
58
|
-
export function recordMemoryTierOnce(): void {
|
|
59
|
-
const consent = getRawShareAnalytics();
|
|
60
|
-
if (consent === "unknown") {
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
try {
|
|
64
|
-
// `getConfigReadOnly()` re-reads config.json on change (capturing live
|
|
65
|
-
// edits) and never writes to disk — safe for the monitor process.
|
|
66
|
-
const tier = memoryTier(getConfigReadOnly());
|
|
67
|
-
|
|
68
|
-
let corpus: Record<string, number> = {};
|
|
69
|
-
if (consent !== false) {
|
|
70
|
-
try {
|
|
71
|
-
corpus = { ...measureMemoryCorpusSize() };
|
|
72
|
-
} catch (err) {
|
|
73
|
-
log.warn({ err }, "memory corpus sizing failed (emitting tier only)");
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
recordWatchdogEvent({
|
|
78
|
-
checkName: MEMORY_TIER_CHECK_NAME,
|
|
79
|
-
detail: { tier, ...corpus },
|
|
80
|
-
});
|
|
81
|
-
} catch (err) {
|
|
82
|
-
log.warn({ err }, "memory_tier watchdog emit failed (non-fatal)");
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
let tierTimer: ReturnType<typeof setInterval> | null = null;
|
|
87
|
-
let bootRetryTimer: ReturnType<typeof setTimeout> | null = null;
|
|
88
|
-
|
|
89
|
-
function recordBootTierOnceConsentKnown(): void {
|
|
90
|
-
if (getRawShareAnalytics() === "unknown") {
|
|
91
|
-
bootRetryTimer = setTimeout(
|
|
92
|
-
recordBootTierOnceConsentKnown,
|
|
93
|
-
BOOT_RETRY_INTERVAL_MS,
|
|
94
|
-
);
|
|
95
|
-
bootRetryTimer.unref?.();
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
bootRetryTimer = null;
|
|
99
|
-
recordMemoryTierOnce();
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Start the memory-tier reporter in the resource monitor process: emit the
|
|
104
|
-
* current tier once at boot (once consent resolves), then every six hours,
|
|
105
|
-
* UNCONDITIONALLY. No-op in dev mode (CADET_DEV=1) and idempotent if already
|
|
106
|
-
* started. Runs alongside {@link import("./config-setting-snapshot.js").startConfigSnapshotReporter}
|
|
107
|
-
* in the monitor worker.
|
|
108
|
-
*/
|
|
109
|
-
export function startMemoryTierReporter(): void {
|
|
110
|
-
if (process.env.CADET_DEV === "1") {
|
|
111
|
-
return;
|
|
112
|
-
}
|
|
113
|
-
if (tierTimer) {
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
116
|
-
recordBootTierOnceConsentKnown();
|
|
117
|
-
tierTimer = setInterval(recordMemoryTierOnce, MEMORY_TIER_INTERVAL_MS);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/** Stop the memory-tier reporter loop. Idempotent. */
|
|
121
|
-
export function stopMemoryTierReporter(): void {
|
|
122
|
-
if (tierTimer) {
|
|
123
|
-
clearInterval(tierTimer);
|
|
124
|
-
tierTimer = null;
|
|
125
|
-
}
|
|
126
|
-
if (bootRetryTimer) {
|
|
127
|
-
clearTimeout(bootRetryTimer);
|
|
128
|
-
bootRetryTimer = null;
|
|
129
|
-
}
|
|
130
|
-
}
|
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Phone-call telemetry vocabulary: the single source of truth for the step
|
|
3
|
-
* names, funnel version, and dimension values the call store's emitter uses.
|
|
4
|
-
*
|
|
5
|
-
* The phone half of the live-voice funnel, and deliberately its mirror image:
|
|
6
|
-
* same onboarding substrate (`type: "onboarding"`), same open-string
|
|
7
|
-
* `step_name` / `funnel_version`, same reason for both. See
|
|
8
|
-
* `live-voice-funnel.ts` for the full argument; the short version is that the
|
|
9
|
-
* backend stores those two as open strings, so a new funnel needs no platform
|
|
10
|
-
* serializer and no wire-contract change.
|
|
11
|
-
*
|
|
12
|
-
* **Duration is not a field**, for the same reason it is not one on live
|
|
13
|
-
* voice: the onboarding event shape has no numeric slot. The two events below
|
|
14
|
-
* are keyed by the call session id in `session_id` and the warehouse subtracts
|
|
15
|
-
* their `recorded_at` stamps.
|
|
16
|
-
*
|
|
17
|
-
* **Turn count is not a field either.** Phone turns already carry the call
|
|
18
|
-
* session id in their `client` bag (`voiceTelemetry` at the bridge call site),
|
|
19
|
-
* so a turn count is a count of those rows.
|
|
20
|
-
*
|
|
21
|
-
* A call that starts and never ends is **censored, not infinite**: a daemon
|
|
22
|
-
* crash between the two writes emits no end event, so duration math must drop
|
|
23
|
-
* unmatched `started` rows rather than treat the call as still running.
|
|
24
|
-
*/
|
|
25
|
-
|
|
26
|
-
import type { CallMode, CallStatus } from "../calls/types.js";
|
|
27
|
-
|
|
28
|
-
/** Funnel version stamped on every phone-call event. */
|
|
29
|
-
export const PHONE_CALL_FUNNEL_VERSION = "phone_call_v1_2026_09";
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Phone-call funnel steps. `stepName` is the wire value; `stepIndex` is the
|
|
33
|
-
* ordinal position.
|
|
34
|
-
*
|
|
35
|
-
* `callStarted` fires when the call session row is created, before the
|
|
36
|
-
* provider has dialled: a call that never connects is exactly the one worth
|
|
37
|
-
* counting, so the start event precedes no-answer, busy, provider failure and
|
|
38
|
-
* the inbound credential preflight (an inbound session exists before that
|
|
39
|
-
* preflight runs and records against it).
|
|
40
|
-
*
|
|
41
|
-
* It does **not** cover an outbound attempt rejected before a session exists:
|
|
42
|
-
* `startCall`, `startVerificationCall` and `startInviteCall` all return on a
|
|
43
|
-
* failed `preflightVoiceIngress()` without creating a row, and this funnel is
|
|
44
|
-
* keyed by the session id it would have had. Counting those needs a key that
|
|
45
|
-
* does not depend on a session row, which is its own piece of work.
|
|
46
|
-
*/
|
|
47
|
-
export const PHONE_CALL_STEPS = {
|
|
48
|
-
callStarted: { stepName: "phone_call_started", stepIndex: 0 },
|
|
49
|
-
callEnded: { stepName: "phone_call_ended", stepIndex: 1 },
|
|
50
|
-
} as const;
|
|
51
|
-
|
|
52
|
-
export type PhoneCallStepName =
|
|
53
|
-
(typeof PHONE_CALL_STEPS)[keyof typeof PHONE_CALL_STEPS]["stepName"];
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Which way the call was placed. Inbound is someone dialling the assistant's
|
|
57
|
-
* number; outbound is the assistant dialling out on a task.
|
|
58
|
-
*/
|
|
59
|
-
export type PhoneCallDirection = "inbound" | "outbound";
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* How a call ended, stamped as `outcome`.
|
|
63
|
-
*
|
|
64
|
-
* `failed` means the call died on an error: no answer, a provider or
|
|
65
|
-
* credential failure, a dropped media stream. A call the caller or the
|
|
66
|
-
* assistant hung up, including one cancelled before it connected, is
|
|
67
|
-
* `completed`: it ran its course and the close reason on `screen` says how.
|
|
68
|
-
*/
|
|
69
|
-
export type PhoneCallOutcome = "completed" | "failed";
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* How far a call that produced NO caller turn actually got.
|
|
73
|
-
*
|
|
74
|
-
* The phone analogue of the live-voice silence taxonomy, and the closest thing
|
|
75
|
-
* call telemetry has to a "the phone path didn't work" rate. A bare
|
|
76
|
-
* started/ended pair cannot separate a call that never connected from one that
|
|
77
|
-
* connected to silence, and those have completely different fixes.
|
|
78
|
-
*
|
|
79
|
-
* - `no_connect` the call never reached `in_progress`: it failed, was
|
|
80
|
-
* cancelled, or was never answered, so nobody could have
|
|
81
|
-
* spoken.
|
|
82
|
-
* - `no_turn` the call connected and then no caller utterance was ever
|
|
83
|
-
* transcribed: a silent line, a failed STT leg, or a caller who
|
|
84
|
-
* hung up on the disclosure.
|
|
85
|
-
*/
|
|
86
|
-
export type PhoneCallSilenceReason = "no_connect" | "no_turn";
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* Classify a call that produced no caller turn. Call only when the call really
|
|
90
|
-
* produced none: the second branch asserts silence, so a call that did take a
|
|
91
|
-
* turn would be mislabelled by it.
|
|
92
|
-
*/
|
|
93
|
-
export function phoneCallSilenceReason(signals: {
|
|
94
|
-
connected: boolean;
|
|
95
|
-
}): PhoneCallSilenceReason {
|
|
96
|
-
return signals.connected ? "no_turn" : "no_connect";
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* The mode an ordinary call carries. Only the verification and invite flows
|
|
101
|
-
* write a mode on the session row, so a null there is not a missing dimension
|
|
102
|
-
* but the ordinary conversation every other path creates.
|
|
103
|
-
*/
|
|
104
|
-
const PHONE_CALL_DEFAULT_MODE: CallMode = "normal";
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* The `screen` dimension for a started call: which way it was placed and what
|
|
108
|
-
* kind of call it is, as `started_<direction>:<mode>`.
|
|
109
|
-
*
|
|
110
|
-
* The mode separates the three things a phone call can be (a normal
|
|
111
|
-
* conversation, a callee verification, an invite redemption) because they have
|
|
112
|
-
* completely different shapes and success criteria, and a funnel that mixed
|
|
113
|
-
* them would report the verification flow's brevity as a conversation problem.
|
|
114
|
-
*/
|
|
115
|
-
export function phoneCallStartScreen(
|
|
116
|
-
direction: PhoneCallDirection,
|
|
117
|
-
mode?: CallMode | null,
|
|
118
|
-
): string {
|
|
119
|
-
return `started_${direction}:${mode ?? PHONE_CALL_DEFAULT_MODE}`;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* The `screen` dimension for an ended call: the terminal status it reached,
|
|
124
|
-
* plus a detail half carrying the silence classification when the call took no
|
|
125
|
-
* caller turn at all.
|
|
126
|
-
*
|
|
127
|
-
* The status is the daemon's own `CallStatus` verbatim rather than a mapping,
|
|
128
|
-
* so a rename surfaces here as a compile error instead of a silently-empty
|
|
129
|
-
* dashboard facet.
|
|
130
|
-
*
|
|
131
|
-
* The silence value carries a `silent_` prefix to match the live-voice stamp,
|
|
132
|
-
* which shares its detail slot with failure codes and renders in an admin
|
|
133
|
-
* column labelled "failure code". Reading the two funnels side by side is
|
|
134
|
-
* worth more than a shorter string here.
|
|
135
|
-
*/
|
|
136
|
-
export function phoneCallEndScreen(
|
|
137
|
-
status: CallStatus,
|
|
138
|
-
silenceReason?: PhoneCallSilenceReason | null,
|
|
139
|
-
): string {
|
|
140
|
-
if (silenceReason) {
|
|
141
|
-
return `ended_${status}:silent_${silenceReason}`;
|
|
142
|
-
}
|
|
143
|
-
return `ended_${status}`;
|
|
144
|
-
}
|