@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,182 +0,0 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, test } from "bun:test";
|
|
2
|
-
|
|
3
|
-
import { ACTOR_PRINCIPALS } from "../runtime/auth/route-policy.js";
|
|
4
|
-
import { RouteError } from "../runtime/routes/errors.js";
|
|
5
|
-
import { ROUTES } from "../runtime/routes/telemetry-routes.js";
|
|
6
|
-
import type { RouteHandlerArgs } from "../runtime/routes/types.js";
|
|
7
|
-
import {
|
|
8
|
-
pendingOutboxPayloads,
|
|
9
|
-
resetOutboxTable,
|
|
10
|
-
setShareAnalytics,
|
|
11
|
-
setShareDiagnostics,
|
|
12
|
-
} from "../telemetry/__tests__/outbox-test-harness.js";
|
|
13
|
-
import type { OnboardingResearchTelemetryEvent } from "../telemetry/types.js";
|
|
14
|
-
|
|
15
|
-
function pendingPayloads(): OnboardingResearchTelemetryEvent[] {
|
|
16
|
-
return pendingOutboxPayloads<OnboardingResearchTelemetryEvent>(
|
|
17
|
-
"onboarding_research",
|
|
18
|
-
);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const route = ROUTES.find((r) => r.operationId === "telemetry_ingest");
|
|
22
|
-
|
|
23
|
-
function call(body: unknown) {
|
|
24
|
-
if (!route) {
|
|
25
|
-
throw new Error("route not found");
|
|
26
|
-
}
|
|
27
|
-
return route.handler({ body } as RouteHandlerArgs);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/** Well-formed onboarding_research `fields` (base fields stamped by the daemon). */
|
|
31
|
-
const VALID_FIELDS = {
|
|
32
|
-
conversation_id: "conv-xyz",
|
|
33
|
-
status: "done",
|
|
34
|
-
self_reported_occupation: "engineer",
|
|
35
|
-
claims: [{ claim: "Senior engineer", confidence: "confident", sources: [] }],
|
|
36
|
-
claim_count: 1,
|
|
37
|
-
claims_confident: 1,
|
|
38
|
-
claims_maybe: 0,
|
|
39
|
-
claims_guessing: 0,
|
|
40
|
-
suggestions: [
|
|
41
|
-
{ suggestion: "I'll find 3 papers", prompt: "Find me 3 papers" },
|
|
42
|
-
],
|
|
43
|
-
suggestion_count: 1,
|
|
44
|
-
plugins: ["marketing-expert"],
|
|
45
|
-
installed_plugins: ["marketing-expert", "web-research"],
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
const VALID_BODY = {
|
|
49
|
-
type: "onboarding_research",
|
|
50
|
-
fields: VALID_FIELDS,
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
describe("telemetry-routes: ingest", () => {
|
|
54
|
-
beforeEach(() => {
|
|
55
|
-
setShareAnalytics(true);
|
|
56
|
-
setShareDiagnostics(true);
|
|
57
|
-
resetOutboxTable();
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
test("route policy matches the other client-facing telemetry routes", () => {
|
|
61
|
-
expect(route).toBeDefined();
|
|
62
|
-
expect(route?.endpoint).toBe("telemetry/ingest");
|
|
63
|
-
expect(route?.method).toBe("POST");
|
|
64
|
-
expect(route?.policy?.allowedPrincipalTypes).toEqual(ACTOR_PRINCIPALS);
|
|
65
|
-
expect(route?.policy?.requiredScopes).toEqual(["settings.write"]);
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
test("valid body is persisted to the outbox as a wire event", () => {
|
|
69
|
-
const result = call(VALID_BODY);
|
|
70
|
-
expect(result).toEqual({ id: expect.any(String) });
|
|
71
|
-
|
|
72
|
-
const payloads = pendingPayloads();
|
|
73
|
-
expect(payloads.length).toBe(1);
|
|
74
|
-
expect(payloads[0]).toMatchObject({
|
|
75
|
-
type: "onboarding_research",
|
|
76
|
-
conversation_id: "conv-xyz",
|
|
77
|
-
status: "done",
|
|
78
|
-
claim_count: 1,
|
|
79
|
-
claims_confident: 1,
|
|
80
|
-
suggestion_count: 1,
|
|
81
|
-
plugins: ["marketing-expert"],
|
|
82
|
-
installed_plugins: ["marketing-expert", "web-research"],
|
|
83
|
-
});
|
|
84
|
-
// Base fields are stamped by the daemon, not the client.
|
|
85
|
-
expect(payloads[0]?.daemon_event_id).toEqual(expect.any(String));
|
|
86
|
-
expect(payloads[0]?.recorded_at).toEqual(expect.any(Number));
|
|
87
|
-
expect(payloads[0]?.assistant_version).toEqual(expect.any(String));
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
test("stamps a fresh daemon_event_id by default", () => {
|
|
91
|
-
call(VALID_BODY);
|
|
92
|
-
// No override → the collapse key falls back to the row id (a uuid), not the
|
|
93
|
-
// conversation-scoped key.
|
|
94
|
-
expect(pendingPayloads()[0]?.daemon_event_id).not.toBe(
|
|
95
|
-
"onboarding_research:conv-xyz",
|
|
96
|
-
);
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
test("honors a client-supplied daemon_event_id collapse key", () => {
|
|
100
|
-
call({ ...VALID_BODY, daemon_event_id: "onboarding_research:conv-xyz" });
|
|
101
|
-
expect(pendingPayloads()[0]?.daemon_event_id).toBe(
|
|
102
|
-
"onboarding_research:conv-xyz",
|
|
103
|
-
);
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
test("returns skipped and persists nothing under the analytics opt-out", () => {
|
|
107
|
-
setShareAnalytics(false);
|
|
108
|
-
expect(call(VALID_BODY)).toEqual({ skipped: true });
|
|
109
|
-
expect(pendingPayloads().length).toBe(0);
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
test("persists regardless of the diagnostics opt-out (rides analytics only)", () => {
|
|
113
|
-
setShareDiagnostics(false, "2000-01-01");
|
|
114
|
-
expect(call(VALID_BODY)).toEqual({ id: expect.any(String) });
|
|
115
|
-
expect(pendingPayloads().length).toBe(1);
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
test("rejects a non-outbox (watermark) or unknown type", () => {
|
|
119
|
-
// `turn` is a real wire type but watermark-flushed, not outbox-backed, so it
|
|
120
|
-
// has no ingest variant and a client can't inject it.
|
|
121
|
-
expect(() => call({ type: "turn", fields: {} })).toThrow(RouteError);
|
|
122
|
-
// An unknown type is rejected the same way.
|
|
123
|
-
expect(() => call({ type: "not_a_type", fields: {} })).toThrow(RouteError);
|
|
124
|
-
expect(pendingPayloads().length).toBe(0);
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
test("accepts any outbox-backed type, e.g. config_setting", () => {
|
|
128
|
-
const result = call({
|
|
129
|
-
type: "config_setting",
|
|
130
|
-
fields: { config_key: "voice.provider", config_value: "elevenlabs" },
|
|
131
|
-
});
|
|
132
|
-
expect(result).toEqual({ id: expect.any(String) });
|
|
133
|
-
|
|
134
|
-
const payloads = pendingOutboxPayloads<{ config_key: string }>(
|
|
135
|
-
"config_setting",
|
|
136
|
-
);
|
|
137
|
-
expect(payloads.length).toBe(1);
|
|
138
|
-
expect(payloads[0]).toMatchObject({
|
|
139
|
-
type: "config_setting",
|
|
140
|
-
config_key: "voice.provider",
|
|
141
|
-
config_value: "elevenlabs",
|
|
142
|
-
});
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
test("rejects malformed fields (missing or mistyped) without persisting", () => {
|
|
146
|
-
// Missing the required derived counts.
|
|
147
|
-
const {
|
|
148
|
-
claim_count: _c,
|
|
149
|
-
suggestion_count: _s,
|
|
150
|
-
...missingCounts
|
|
151
|
-
} = VALID_FIELDS;
|
|
152
|
-
expect(() =>
|
|
153
|
-
call({ type: "onboarding_research", fields: missingCounts }),
|
|
154
|
-
).toThrow(RouteError);
|
|
155
|
-
|
|
156
|
-
// Wrong type for a numeric field.
|
|
157
|
-
expect(() =>
|
|
158
|
-
call({
|
|
159
|
-
type: "onboarding_research",
|
|
160
|
-
fields: { ...VALID_FIELDS, claim_count: "one" },
|
|
161
|
-
}),
|
|
162
|
-
).toThrow(RouteError);
|
|
163
|
-
|
|
164
|
-
expect(pendingPayloads().length).toBe(0);
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
test("rejects a structurally invalid request body", () => {
|
|
168
|
-
expect(() => call({ type: "onboarding_research" })).toThrow(RouteError);
|
|
169
|
-
expect(() => call({ fields: VALID_FIELDS })).toThrow(RouteError);
|
|
170
|
-
expect(pendingPayloads().length).toBe(0);
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
test("strips unknown fields keys (typed schema, not a passthrough record)", () => {
|
|
174
|
-
call({
|
|
175
|
-
type: "onboarding_research",
|
|
176
|
-
fields: { ...VALID_FIELDS, bogus_extra: "nope" },
|
|
177
|
-
});
|
|
178
|
-
const payloads = pendingPayloads();
|
|
179
|
-
expect(payloads.length).toBe(1);
|
|
180
|
-
expect(payloads[0]).not.toHaveProperty("bogus_extra");
|
|
181
|
-
});
|
|
182
|
-
});
|
|
@@ -1,376 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for queryUnreportedTurnEvents.
|
|
3
|
-
*
|
|
4
|
-
* Verifies that the JOIN to `conversations` correctly attaches the parent
|
|
5
|
-
* conversation's `conversationType` to each returned turn, so analytics
|
|
6
|
-
* downstream (DAU) can filter out background/scheduled prompts.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import { beforeEach, describe, expect, test } from "bun:test";
|
|
10
|
-
|
|
11
|
-
import {
|
|
12
|
-
addMessage,
|
|
13
|
-
createConversation,
|
|
14
|
-
} from "../persistence/conversation-crud.js";
|
|
15
|
-
import { getDb } from "../persistence/db-connection.js";
|
|
16
|
-
import { initializeDb } from "../persistence/db-init.js";
|
|
17
|
-
import { messages } from "../persistence/schema/index.js";
|
|
18
|
-
import { queryUnreportedTurnEvents } from "../telemetry/turn-events-store.js";
|
|
19
|
-
import { stampTurnOutcome } from "../telemetry/turn-outcome.js";
|
|
20
|
-
|
|
21
|
-
await initializeDb();
|
|
22
|
-
|
|
23
|
-
function purge(): void {
|
|
24
|
-
const db = getDb();
|
|
25
|
-
// Wipe messages then conversations to keep tests independent. FK cascade
|
|
26
|
-
// also removes any dependent rows.
|
|
27
|
-
db.run("DELETE FROM messages");
|
|
28
|
-
db.run("DELETE FROM conversations");
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
beforeEach(() => {
|
|
32
|
-
purge();
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Insert a user message at a specific epoch-millis timestamp so we can
|
|
37
|
-
* assert ordering and the watermark cursor.
|
|
38
|
-
*/
|
|
39
|
-
async function insertUserMessageAt(
|
|
40
|
-
conversationId: string,
|
|
41
|
-
content: string,
|
|
42
|
-
createdAt: number,
|
|
43
|
-
): Promise<string> {
|
|
44
|
-
const message = await addMessage(conversationId, "user", content);
|
|
45
|
-
// addMessage stamps createdAt to monotonic now(); rewrite for
|
|
46
|
-
// deterministic ordering in the test.
|
|
47
|
-
const db = getDb();
|
|
48
|
-
db.run(
|
|
49
|
-
`UPDATE messages SET created_at = ${createdAt} WHERE id = '${message.id}'`,
|
|
50
|
-
);
|
|
51
|
-
return message.id;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
describe("queryUnreportedTurnEvents", () => {
|
|
55
|
-
test("attaches conversationId, conversationType, and turnIndex for a standard conversation", async () => {
|
|
56
|
-
const conv = createConversation({ conversationType: "standard" });
|
|
57
|
-
await insertUserMessageAt(conv.id, "hello", 1000);
|
|
58
|
-
|
|
59
|
-
const events = queryUnreportedTurnEvents(0, undefined, 100);
|
|
60
|
-
expect(events.length).toBe(1);
|
|
61
|
-
expect(events[0].conversationId).toBe(conv.id);
|
|
62
|
-
expect(events[0].conversationType).toBe("standard");
|
|
63
|
-
// The single user message in this conversation is turn 1.
|
|
64
|
-
expect(events[0].turnIndex).toBe(1);
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
test("attaches conversationType for background and scheduled conversations", async () => {
|
|
68
|
-
const bg = createConversation({ conversationType: "background" });
|
|
69
|
-
const sched = createConversation({ conversationType: "scheduled" });
|
|
70
|
-
const std = createConversation({ conversationType: "standard" });
|
|
71
|
-
|
|
72
|
-
const bgMsg = await insertUserMessageAt(bg.id, "bg prompt", 1000);
|
|
73
|
-
const schedMsg = await insertUserMessageAt(sched.id, "sched prompt", 2000);
|
|
74
|
-
const stdMsg = await insertUserMessageAt(std.id, "user typed this", 3000);
|
|
75
|
-
|
|
76
|
-
const events = queryUnreportedTurnEvents(0, undefined, 100);
|
|
77
|
-
const byId = Object.fromEntries(events.map((e) => [e.id, e]));
|
|
78
|
-
|
|
79
|
-
expect(byId[bgMsg].conversationType).toBe("background");
|
|
80
|
-
expect(byId[schedMsg].conversationType).toBe("scheduled");
|
|
81
|
-
expect(byId[stdMsg].conversationType).toBe("standard");
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
test("excludes tool_result and web_search_tool_result content patterns", async () => {
|
|
85
|
-
const conv = createConversation({ conversationType: "standard" });
|
|
86
|
-
|
|
87
|
-
// Real user turn
|
|
88
|
-
const realId = await insertUserMessageAt(conv.id, "real user text", 1000);
|
|
89
|
-
|
|
90
|
-
// Synthetic "user" rows that wrap tool results: these should be filtered
|
|
91
|
-
const db = getDb();
|
|
92
|
-
db.insert(messages)
|
|
93
|
-
.values({
|
|
94
|
-
id: "tool-result-id",
|
|
95
|
-
conversationId: conv.id,
|
|
96
|
-
role: "user",
|
|
97
|
-
content: JSON.stringify([
|
|
98
|
-
{ type: "tool_result", tool_use_id: "x", content: "" },
|
|
99
|
-
]),
|
|
100
|
-
createdAt: 2000,
|
|
101
|
-
})
|
|
102
|
-
.run();
|
|
103
|
-
db.insert(messages)
|
|
104
|
-
.values({
|
|
105
|
-
id: "web-search-tool-result-id",
|
|
106
|
-
conversationId: conv.id,
|
|
107
|
-
role: "user",
|
|
108
|
-
content: JSON.stringify([
|
|
109
|
-
{ type: "web_search_tool_result", tool_use_id: "y", content: "" },
|
|
110
|
-
]),
|
|
111
|
-
createdAt: 3000,
|
|
112
|
-
})
|
|
113
|
-
.run();
|
|
114
|
-
|
|
115
|
-
const events = queryUnreportedTurnEvents(0, undefined, 100);
|
|
116
|
-
expect(events.length).toBe(1);
|
|
117
|
-
expect(events[0].id).toBe(realId);
|
|
118
|
-
expect(events[0].conversationType).toBe("standard");
|
|
119
|
-
// Tool-result rows must NOT increment the turn index: this is the
|
|
120
|
-
// only real user turn in the conversation, so its index is 1 even
|
|
121
|
-
// though two synthetic role="user" rows exist with later timestamps.
|
|
122
|
-
expect(events[0].turnIndex).toBe(1);
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
test("turnIndex counts real user turns in (createdAt, id) order within a conversation", async () => {
|
|
126
|
-
const conv = createConversation({ conversationType: "standard" });
|
|
127
|
-
const m1 = await insertUserMessageAt(conv.id, "first", 1000);
|
|
128
|
-
const m2 = await insertUserMessageAt(conv.id, "second", 2000);
|
|
129
|
-
const m3 = await insertUserMessageAt(conv.id, "third", 3000);
|
|
130
|
-
|
|
131
|
-
const events = queryUnreportedTurnEvents(0, undefined, 100);
|
|
132
|
-
const byId = Object.fromEntries(events.map((e) => [e.id, e]));
|
|
133
|
-
expect(byId[m1].turnIndex).toBe(1);
|
|
134
|
-
expect(byId[m2].turnIndex).toBe(2);
|
|
135
|
-
expect(byId[m3].turnIndex).toBe(3);
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
test("turnIndex resets across conversations", async () => {
|
|
139
|
-
const a = createConversation({ conversationType: "standard" });
|
|
140
|
-
const b = createConversation({ conversationType: "standard" });
|
|
141
|
-
const a1 = await insertUserMessageAt(a.id, "a first", 1000);
|
|
142
|
-
const b1 = await insertUserMessageAt(b.id, "b first", 1500);
|
|
143
|
-
const a2 = await insertUserMessageAt(a.id, "a second", 2000);
|
|
144
|
-
|
|
145
|
-
const events = queryUnreportedTurnEvents(0, undefined, 100);
|
|
146
|
-
const byId = Object.fromEntries(events.map((e) => [e.id, e]));
|
|
147
|
-
// Conversation A: 1, 2. Conversation B: 1 (independent of A).
|
|
148
|
-
expect(byId[a1].turnIndex).toBe(1);
|
|
149
|
-
expect(byId[a2].turnIndex).toBe(2);
|
|
150
|
-
expect(byId[b1].turnIndex).toBe(1);
|
|
151
|
-
// And the conversation_id labels them correctly.
|
|
152
|
-
expect(byId[a1].conversationId).toBe(a.id);
|
|
153
|
-
expect(byId[b1].conversationId).toBe(b.id);
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
test("turnIndex skips tool_result rows even when they're interleaved", async () => {
|
|
157
|
-
const conv = createConversation({ conversationType: "standard" });
|
|
158
|
-
const real1 = await insertUserMessageAt(conv.id, "first real", 1000);
|
|
159
|
-
|
|
160
|
-
// Inject a tool_result row between the two real turns. The
|
|
161
|
-
// correlated subquery must use the same content filter as the
|
|
162
|
-
// outer query, otherwise turn_index would jump by 2 instead of 1.
|
|
163
|
-
const db = getDb();
|
|
164
|
-
db.insert(messages)
|
|
165
|
-
.values({
|
|
166
|
-
id: "interleaved-tool-result",
|
|
167
|
-
conversationId: conv.id,
|
|
168
|
-
role: "user",
|
|
169
|
-
content: JSON.stringify([
|
|
170
|
-
{ type: "tool_result", tool_use_id: "x", content: "" },
|
|
171
|
-
]),
|
|
172
|
-
createdAt: 1500,
|
|
173
|
-
})
|
|
174
|
-
.run();
|
|
175
|
-
|
|
176
|
-
const real2 = await insertUserMessageAt(conv.id, "second real", 2000);
|
|
177
|
-
|
|
178
|
-
const events = queryUnreportedTurnEvents(0, undefined, 100);
|
|
179
|
-
const byId = Object.fromEntries(events.map((e) => [e.id, e]));
|
|
180
|
-
expect(events.length).toBe(2);
|
|
181
|
-
expect(byId[real1].turnIndex).toBe(1);
|
|
182
|
-
expect(byId[real2].turnIndex).toBe(2);
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
test("respects the cursor and returns events in (createdAt, id) order", async () => {
|
|
186
|
-
const conv = createConversation({ conversationType: "standard" });
|
|
187
|
-
const m1 = await insertUserMessageAt(conv.id, "first", 1000);
|
|
188
|
-
const m2 = await insertUserMessageAt(conv.id, "second", 2000);
|
|
189
|
-
const m3 = await insertUserMessageAt(conv.id, "third", 3000);
|
|
190
|
-
|
|
191
|
-
// Cursor at (1500, undefined) should skip m1 and return m2, m3 in order.
|
|
192
|
-
const after = queryUnreportedTurnEvents(1500, undefined, 100);
|
|
193
|
-
expect(after.map((e) => e.id)).toEqual([m2, m3]);
|
|
194
|
-
|
|
195
|
-
// Sanity: pulling from the start returns all three with correct types.
|
|
196
|
-
const all = queryUnreportedTurnEvents(0, undefined, 100);
|
|
197
|
-
expect(all.map((e) => e.id)).toEqual([m1, m2, m3]);
|
|
198
|
-
for (const e of all) {
|
|
199
|
-
expect(e.conversationType).toBe("standard");
|
|
200
|
-
}
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
test("extracts interfaceId, channelId, and clientMetadata from messages.metadata", async () => {
|
|
204
|
-
// Three user messages with different metadata shapes to cover the
|
|
205
|
-
// realistic spectrum of attribution carried on messages.metadata:
|
|
206
|
-
// - Full interactive: macOS surface, cadet channel, with a client
|
|
207
|
-
// block stamped by the (forthcoming) HTTP header middleware.
|
|
208
|
-
// - Channel inbound: Slack surface, no client headers (channel
|
|
209
|
-
// inbound paths don't carry browser context).
|
|
210
|
-
// - Legacy: a message persisted before metadata threading existed.
|
|
211
|
-
const conv = createConversation({ conversationType: "standard" });
|
|
212
|
-
|
|
213
|
-
const macOsMsg = await addMessage(conv.id, "user", "hi from desktop", {
|
|
214
|
-
metadata: {
|
|
215
|
-
userMessageInterface: "macos",
|
|
216
|
-
userMessageChannel: "cadet",
|
|
217
|
-
client: {
|
|
218
|
-
os: "darwin",
|
|
219
|
-
interface_version: "0.8.2",
|
|
220
|
-
},
|
|
221
|
-
},
|
|
222
|
-
});
|
|
223
|
-
const slackMsg = await addMessage(conv.id, "user", "hi from slack", {
|
|
224
|
-
metadata: {
|
|
225
|
-
userMessageInterface: "slack",
|
|
226
|
-
userMessageChannel: "slack",
|
|
227
|
-
},
|
|
228
|
-
});
|
|
229
|
-
const legacyMsg = await addMessage(conv.id, "user", "hi from the past");
|
|
230
|
-
|
|
231
|
-
const events = queryUnreportedTurnEvents(0, undefined, 100);
|
|
232
|
-
const byId = Object.fromEntries(events.map((e) => [e.id, e]));
|
|
233
|
-
|
|
234
|
-
expect(byId[macOsMsg.id]).toBeDefined();
|
|
235
|
-
expect(byId[macOsMsg.id].interfaceId).toBe("macos");
|
|
236
|
-
expect(byId[macOsMsg.id].channelId).toBe("cadet");
|
|
237
|
-
// clientMetadata is returned as raw JSON text -- the reporter parses it.
|
|
238
|
-
// We verify it round-trips back to the input object.
|
|
239
|
-
expect(byId[macOsMsg.id].clientMetadata).not.toBeNull();
|
|
240
|
-
expect(
|
|
241
|
-
JSON.parse(byId[macOsMsg.id].clientMetadata as string),
|
|
242
|
-
).toMatchObject({
|
|
243
|
-
os: "darwin",
|
|
244
|
-
interface_version: "0.8.2",
|
|
245
|
-
});
|
|
246
|
-
|
|
247
|
-
expect(byId[slackMsg.id].interfaceId).toBe("slack");
|
|
248
|
-
expect(byId[slackMsg.id].channelId).toBe("slack");
|
|
249
|
-
expect(byId[slackMsg.id].clientMetadata).toBeNull();
|
|
250
|
-
|
|
251
|
-
// Legacy rows (no metadata threading) return null for all three
|
|
252
|
-
// attribution fields -- downstream analytics treats these as
|
|
253
|
-
// "unknown" without breaking the batch.
|
|
254
|
-
expect(byId[legacyMsg.id].interfaceId).toBeNull();
|
|
255
|
-
expect(byId[legacyMsg.id].channelId).toBeNull();
|
|
256
|
-
expect(byId[legacyMsg.id].clientMetadata).toBeNull();
|
|
257
|
-
});
|
|
258
|
-
|
|
259
|
-
test("projects turn-outcome stamps from messages.metadata", async () => {
|
|
260
|
-
const conv = createConversation({ conversationType: "standard" });
|
|
261
|
-
const head = await addMessage(conv.id, "user", "first of a burst", {
|
|
262
|
-
metadata: { userMessageInterface: "web", userMessageChannel: "cadet" },
|
|
263
|
-
});
|
|
264
|
-
const final = await addMessage(conv.id, "user", "second of a burst");
|
|
265
|
-
const failed = await addMessage(conv.id, "user", "doomed turn");
|
|
266
|
-
const cancelled = await addMessage(conv.id, "user", "stopped turn");
|
|
267
|
-
const normal = await addMessage(conv.id, "user", "replied turn");
|
|
268
|
-
|
|
269
|
-
stampTurnOutcome(head.id, "batched", { batchedInto: final.id });
|
|
270
|
-
stampTurnOutcome(failed.id, "failed", {
|
|
271
|
-
failureCode: "PROVIDER_RATE_LIMIT",
|
|
272
|
-
});
|
|
273
|
-
stampTurnOutcome(cancelled.id, "cancelled");
|
|
274
|
-
|
|
275
|
-
const events = queryUnreportedTurnEvents(0, undefined, 100);
|
|
276
|
-
const byId = Object.fromEntries(events.map((e) => [e.id, e]));
|
|
277
|
-
|
|
278
|
-
expect(byId[head.id].outcome).toBe("batched");
|
|
279
|
-
expect(byId[head.id].batchedInto).toBe(final.id);
|
|
280
|
-
expect(byId[head.id].failureCode).toBeNull();
|
|
281
|
-
// The stamp shallow-merges into existing metadata: attribution keys
|
|
282
|
-
// written at persist time survive.
|
|
283
|
-
expect(byId[head.id].interfaceId).toBe("web");
|
|
284
|
-
expect(byId[head.id].channelId).toBe("cadet");
|
|
285
|
-
|
|
286
|
-
expect(byId[failed.id].outcome).toBe("failed");
|
|
287
|
-
expect(byId[failed.id].failureCode).toBe("PROVIDER_RATE_LIMIT");
|
|
288
|
-
expect(byId[failed.id].batchedInto).toBeNull();
|
|
289
|
-
|
|
290
|
-
expect(byId[cancelled.id].outcome).toBe("cancelled");
|
|
291
|
-
expect(byId[cancelled.id].batchedInto).toBeNull();
|
|
292
|
-
expect(byId[cancelled.id].failureCode).toBeNull();
|
|
293
|
-
|
|
294
|
-
// Unstamped turns (normal replies, pre-stamping rows) project null for
|
|
295
|
-
// all three outcome fields.
|
|
296
|
-
expect(byId[normal.id].outcome).toBeNull();
|
|
297
|
-
expect(byId[normal.id].batchedInto).toBeNull();
|
|
298
|
-
expect(byId[normal.id].failureCode).toBeNull();
|
|
299
|
-
|
|
300
|
-
// The batch-final turn itself carries no stamp.
|
|
301
|
-
expect(byId[final.id].outcome).toBeNull();
|
|
302
|
-
});
|
|
303
|
-
|
|
304
|
-
test("projects the scripted flag, keeping false distinct from unknown", async () => {
|
|
305
|
-
const conv = createConversation({ conversationType: "standard" });
|
|
306
|
-
const scripted = await addMessage(conv.id, "user", "auto-sent kickoff", {
|
|
307
|
-
metadata: { scripted: true },
|
|
308
|
-
});
|
|
309
|
-
const typed = await addMessage(conv.id, "user", "a real message", {
|
|
310
|
-
metadata: { scripted: false },
|
|
311
|
-
});
|
|
312
|
-
const legacy = await addMessage(conv.id, "user", "row predating the flag");
|
|
313
|
-
|
|
314
|
-
const events = queryUnreportedTurnEvents(0, undefined, 100);
|
|
315
|
-
const byId = Object.fromEntries(events.map((e) => [e.id, e]));
|
|
316
|
-
|
|
317
|
-
// sqlite's json_extract yields 1/0 for JSON booleans, so these must come
|
|
318
|
-
// back as real booleans. A raw 1 would be rejected by the cloud's
|
|
319
|
-
// BooleanField and the event silently dropped at ingest.
|
|
320
|
-
expect(byId[scripted.id].scripted).toBe(true);
|
|
321
|
-
expect(byId[typed.id].scripted).toBe(false);
|
|
322
|
-
|
|
323
|
-
// The three-state contract: a row persisted before the flag existed is
|
|
324
|
-
// UNKNOWN, not "the user typed it". Collapsing this to false is exactly
|
|
325
|
-
// the bug the flag exists to fix, so assert null rather than falsy.
|
|
326
|
-
expect(byId[legacy.id].scripted).toBeNull();
|
|
327
|
-
expect(byId[legacy.id].scripted).not.toBe(false);
|
|
328
|
-
});
|
|
329
|
-
|
|
330
|
-
test("stampTurnOutcome never throws, even for a nonexistent message id", () => {
|
|
331
|
-
expect(() => stampTurnOutcome("no-such-message", "failed")).not.toThrow();
|
|
332
|
-
});
|
|
333
|
-
});
|
|
334
|
-
|
|
335
|
-
describe("unfinalized rows and turn accounting", () => {
|
|
336
|
-
test("an in-flight grouped tool-result row is not a real user turn", async () => {
|
|
337
|
-
const conv = createConversation({ conversationType: "standard" });
|
|
338
|
-
const first = await insertUserMessageAt(conv.id, "real question", 1000);
|
|
339
|
-
// The grouped tool-result row: user-role, reserved unfinalized while
|
|
340
|
-
// tool output streams, content a { ref } that does not contain the
|
|
341
|
-
// tool_result text the content exclusions match. Without the finalized
|
|
342
|
-
// predicate it counts as a phantom user turn until the fold.
|
|
343
|
-
const inflight = await insertUserMessageAt(
|
|
344
|
-
conv.id,
|
|
345
|
-
JSON.stringify({ ref: "conversations/conv/inflight/x.jsonl" }),
|
|
346
|
-
2000,
|
|
347
|
-
);
|
|
348
|
-
getDb().run(`UPDATE messages SET finalized = 0 WHERE id = '${inflight}'`);
|
|
349
|
-
const second = await insertUserMessageAt(conv.id, "second question", 3000);
|
|
350
|
-
|
|
351
|
-
const events = queryUnreportedTurnEvents(0, undefined, 100);
|
|
352
|
-
const ids = events
|
|
353
|
-
.filter((e) => e.conversationId === conv.id)
|
|
354
|
-
.map((e) => e.id);
|
|
355
|
-
|
|
356
|
-
expect(ids).toEqual([first, second]);
|
|
357
|
-
const byId = Object.fromEntries(events.map((e) => [e.id, e]));
|
|
358
|
-
expect(byId[first].turnIndex).toBe(1);
|
|
359
|
-
expect(byId[second].turnIndex).toBe(2);
|
|
360
|
-
});
|
|
361
|
-
|
|
362
|
-
test("a persisted empty-display user row still counts as a turn", async () => {
|
|
363
|
-
const conv = createConversation({ conversationType: "standard" });
|
|
364
|
-
const real = await insertUserMessageAt(conv.id, "real question", 1000);
|
|
365
|
-
// A hidden send persists its user row with [] content (displayContent "")
|
|
366
|
-
// and still runs a turn, so [] rows must stay in turn accounting.
|
|
367
|
-
const hidden = await insertUserMessageAt(conv.id, "[]", 2000);
|
|
368
|
-
|
|
369
|
-
const events = queryUnreportedTurnEvents(0, undefined, 100);
|
|
370
|
-
const ids = events
|
|
371
|
-
.filter((e) => e.conversationId === conv.id)
|
|
372
|
-
.map((e) => e.id);
|
|
373
|
-
|
|
374
|
-
expect(ids).toEqual([real, hidden]);
|
|
375
|
-
});
|
|
376
|
-
});
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from "bun:test";
|
|
2
|
-
|
|
3
|
-
import type { ToolDefinition } from "../providers/types.js";
|
|
4
|
-
import { ACTIVATION_MOMENT_PARAMS } from "../telemetry/activation-funnel.js";
|
|
5
|
-
import { injectActivationMomentParam } from "../tools/ui-surface/channel-variants.js";
|
|
6
|
-
import {
|
|
7
|
-
uiDismissTool,
|
|
8
|
-
uiShowTool,
|
|
9
|
-
uiUpdateTool,
|
|
10
|
-
} from "../tools/ui-surface/definitions.js";
|
|
11
|
-
|
|
12
|
-
const defs: ToolDefinition[] = [
|
|
13
|
-
uiShowTool,
|
|
14
|
-
uiUpdateTool,
|
|
15
|
-
uiDismissTool,
|
|
16
|
-
{
|
|
17
|
-
name: "bash",
|
|
18
|
-
description: "run a command",
|
|
19
|
-
input_schema: { type: "object" },
|
|
20
|
-
},
|
|
21
|
-
];
|
|
22
|
-
|
|
23
|
-
describe("injectActivationMomentParam", () => {
|
|
24
|
-
function properties(def: ToolDefinition): Record<string, unknown> {
|
|
25
|
-
return (def.input_schema as { properties: Record<string, unknown> })
|
|
26
|
-
.properties;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
test("the standard ui_show schema does not carry activation_moment", () => {
|
|
30
|
-
expect(properties(uiShowTool).activation_moment).toBeUndefined();
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
test("adds the optional param to ui_show only, leaving required unchanged", () => {
|
|
34
|
-
const projected = injectActivationMomentParam(defs);
|
|
35
|
-
const uiShow = projected.find((d) => d.name === "ui_show")!;
|
|
36
|
-
|
|
37
|
-
const param = properties(uiShow).activation_moment as { enum: string[] };
|
|
38
|
-
expect(param).toBeDefined();
|
|
39
|
-
expect(param.enum).toEqual([...ACTIVATION_MOMENT_PARAMS]);
|
|
40
|
-
expect((uiShow.input_schema as { required: string[] }).required).toEqual([
|
|
41
|
-
"surface_type",
|
|
42
|
-
"data",
|
|
43
|
-
]);
|
|
44
|
-
expect(projected.find((d) => d.name === "ui_update")).toBe(uiUpdateTool);
|
|
45
|
-
expect(projected.find((d) => d.name === "bash")).toBe(defs[3]);
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
test("injection never mutates the shared definition", () => {
|
|
49
|
-
const before = JSON.stringify(uiShowTool.input_schema);
|
|
50
|
-
injectActivationMomentParam(defs);
|
|
51
|
-
expect(JSON.stringify(uiShowTool.input_schema)).toBe(before);
|
|
52
|
-
});
|
|
53
|
-
});
|