@vellumai/assistant 0.8.6 → 0.8.7-dev.202606052118.34cd356
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +4 -4
- package/Dockerfile +21 -4
- package/bun.lock +13 -4
- package/docker-entrypoint.sh +12 -8
- package/docker-init-apt-root.sh +3 -1
- package/docker-kata-apt-env.sh +3 -1
- package/docker-kata-runtime-family.sh +12 -0
- package/docs/architecture/memory.md +1 -1
- package/docs/plugins.md +110 -83
- package/examples/plugins/echo/README.md +13 -12
- package/examples/plugins/echo/register.ts +0 -54
- package/knip.json +1 -0
- package/node_modules/@vellumai/environments/bun.lock +24 -0
- package/node_modules/@vellumai/environments/package.json +18 -0
- package/node_modules/@vellumai/environments/src/__tests__/package-boundary.test.ts +95 -0
- package/node_modules/@vellumai/environments/src/index.ts +11 -0
- package/node_modules/@vellumai/environments/src/seeds.ts +73 -0
- package/node_modules/@vellumai/environments/src/types.ts +70 -0
- package/node_modules/@vellumai/environments/tsconfig.json +20 -0
- package/node_modules/@vellumai/skill-host-contracts/src/assistant-event.ts +11 -0
- package/node_modules/@vellumai/skill-host-contracts/src/client.ts +3 -4
- package/node_modules/@vellumai/skill-host-contracts/src/server-message.ts +3 -3
- package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +13 -8
- package/openapi.yaml +6964 -539
- package/package.json +8 -4
- package/scripts/generate-openapi.ts +88 -54
- package/src/__tests__/agent-loop-callsite-precedence.test.ts +42 -80
- package/src/__tests__/agent-loop-exit-reason.test.ts +188 -45
- package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +141 -0
- package/src/__tests__/agent-loop-override-profile.test.ts +19 -32
- package/src/__tests__/agent-loop-provider-error-recording.test.ts +7 -5
- package/src/__tests__/agent-loop-thinking.test.ts +17 -12
- package/src/__tests__/agent-loop.test.ts +238 -422
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +6 -2
- package/src/__tests__/agent-wake-override-profile.test.ts +22 -40
- package/src/__tests__/annotate-activity-metadata.test.ts +262 -0
- package/src/__tests__/annotate-risk-options.test.ts +2 -3
- package/src/__tests__/anthropic-provider.test.ts +296 -57
- package/src/__tests__/app-builder-skill-instructions.test.ts +22 -0
- package/src/__tests__/app-control-flow.test.ts +6 -1
- package/src/__tests__/app-dir-path-guard.test.ts +1 -0
- package/src/__tests__/approval-cascade.test.ts +4 -11
- package/src/__tests__/approval-routes-http.test.ts +8 -3
- package/src/__tests__/assistant-event-hub.test.ts +25 -0
- package/src/__tests__/assistant-event.test.ts +15 -0
- package/src/__tests__/assistant-events-sse-shed.test.ts +8 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +2 -2
- package/src/__tests__/assistant-stream-state.test.ts +645 -0
- package/src/__tests__/auth-fallback-events-store.test.ts +116 -0
- package/src/__tests__/avatar-e2e.test.ts +7 -37
- package/src/__tests__/avatar-generator.test.ts +12 -42
- package/src/__tests__/avatar-identity-sync.test.ts +28 -3
- package/src/__tests__/background-shell-bash.test.ts +3 -7
- package/src/__tests__/background-workers-disk-pressure.test.ts +6 -0
- package/src/__tests__/btw-routes.test.ts +69 -15
- package/src/__tests__/build-persisted-content.test.ts +184 -0
- package/src/__tests__/call-pointer-messages.test.ts +5 -3
- package/src/__tests__/call-site-routing-provider.test.ts +22 -40
- package/src/__tests__/catalog-files.test.ts +1 -0
- package/src/__tests__/channel-approval-routes.test.ts +49 -21
- package/src/__tests__/channel-approvals.test.ts +4 -2
- package/src/__tests__/channel-invite-transport.test.ts +1 -5
- package/src/__tests__/channel-readiness-routes.test.ts +0 -4
- package/src/__tests__/channel-readiness-slack-remote.test.ts +2 -7
- package/src/__tests__/channel-retry-sweep.test.ts +71 -79
- package/src/__tests__/clawhub-files.test.ts +1 -0
- package/src/__tests__/compaction-circuit.test.ts +258 -0
- package/src/__tests__/compaction-direct.test.ts +132 -0
- package/src/__tests__/compaction-events.test.ts +5 -17
- package/src/__tests__/compaction-trail-store.test.ts +1 -79
- package/src/__tests__/compaction.benchmark.test.ts +0 -30
- package/src/__tests__/compactor-image-manifest-trust.test.ts +112 -0
- package/src/__tests__/computer-use-tools.test.ts +2 -2
- package/src/__tests__/config-watcher.test.ts +28 -0
- package/src/__tests__/context-search-agent-runner.test.ts +6 -3
- package/src/__tests__/context-token-estimator.test.ts +34 -0
- package/src/__tests__/context-window-manager-compact-retry.test.ts +291 -0
- package/src/__tests__/conversation-abort-tool-results.test.ts +70 -25
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +9 -7
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +22 -34
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +476 -963
- package/src/__tests__/conversation-agent-loop.test.ts +823 -1321
- package/src/__tests__/conversation-analysis-routes.test.ts +7 -3
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +1 -1
- package/src/__tests__/conversation-clean-command.test.ts +5 -2
- package/src/__tests__/conversation-clear-safety.test.ts +20 -10
- package/src/__tests__/conversation-confirmation-signals.test.ts +15 -45
- package/src/__tests__/conversation-disk-view-integration.test.ts +2 -2
- package/src/__tests__/conversation-disk-view.test.ts +10 -17
- package/src/__tests__/conversation-fork-crud.test.ts +86 -172
- package/src/__tests__/conversation-fork-route.test.ts +16 -14
- package/src/__tests__/conversation-history-web-search.test.ts +11 -1
- package/src/__tests__/conversation-init.benchmark.test.ts +6 -6
- package/src/__tests__/conversation-lifecycle.test.ts +3 -2
- package/src/__tests__/conversation-load-history-repair.test.ts +3 -2
- package/src/__tests__/conversation-load-history-stripped.test.ts +1 -1
- package/src/__tests__/conversation-message-sync-tags.test.ts +3 -4
- package/src/__tests__/conversation-pairing.test.ts +10 -7
- package/src/__tests__/conversation-pre-run-repair.test.ts +1 -1
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +10 -0
- package/src/__tests__/conversation-process-callsite.test.ts +27 -30
- package/src/__tests__/conversation-provider-retry-repair.test.ts +80 -51
- package/src/__tests__/conversation-queue.test.ts +272 -164
- package/src/__tests__/conversation-routes-disk-view.test.ts +6 -2
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +2 -2
- package/src/__tests__/conversation-routes-slash-commands.test.ts +8 -7
- package/src/__tests__/conversation-runtime-assembly.test.ts +317 -313
- package/src/__tests__/conversation-runtime-workspace.test.ts +114 -36
- package/src/__tests__/conversation-slash-commands.test.ts +8 -42
- package/src/__tests__/conversation-slash-queue.test.ts +42 -31
- package/src/__tests__/conversation-slash-unknown.test.ts +13 -15
- package/src/__tests__/conversation-speed-override.test.ts +8 -22
- package/src/__tests__/conversation-starter-routes.test.ts +14 -6
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +90 -15
- package/src/__tests__/conversation-surfaces-app-control.test.ts +32 -4
- package/src/__tests__/conversation-surfaces-state-update.test.ts +5 -2
- package/src/__tests__/conversation-surfaces-table-action.test.ts +6 -15
- package/src/__tests__/conversation-sync-tags.test.ts +27 -15
- package/src/__tests__/conversation-title-service.test.ts +135 -2
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +23 -11
- package/src/__tests__/conversation-unread-route.test.ts +14 -2
- package/src/__tests__/conversation-usage.test.ts +0 -2
- package/src/__tests__/conversation-wipe.test.ts +1 -1
- package/src/__tests__/conversation-workspace-cache-state.test.ts +20 -17
- package/src/__tests__/conversation-workspace-injection.test.ts +114 -23
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +34 -13
- package/src/__tests__/conversations-import-system-filter.test.ts +101 -0
- package/src/__tests__/credential-execution-tools.test.ts +1 -2
- package/src/__tests__/credential-security-invariants.test.ts +0 -1
- package/src/__tests__/cross-provider-web-search.test.ts +220 -3
- package/src/__tests__/cu-unified-flow.test.ts +26 -1
- package/src/__tests__/db-acp-history.test.ts +101 -0
- package/src/__tests__/db-schedule-syntax-migration.test.ts +16 -0
- package/src/__tests__/disk-pressure-guard.test.ts +66 -0
- package/src/__tests__/disk-pressure-routes.test.ts +9 -2
- package/src/__tests__/dm-persistence.test.ts +12 -3
- package/src/__tests__/dynamic-page-surface.test.ts +99 -0
- package/src/__tests__/edit-propagation.test.ts +1 -2
- package/src/__tests__/empty-response-hook.test.ts +304 -0
- package/src/__tests__/feature-flag-test-helpers.ts +2 -2
- package/src/__tests__/file-write-tool.test.ts +63 -0
- package/src/__tests__/filing-service.test.ts +2 -2
- package/src/__tests__/first-greeting.test.ts +55 -14
- package/src/__tests__/gemini-image-service.test.ts +13 -0
- package/src/__tests__/gemini-inline-media.test.ts +78 -0
- package/src/__tests__/gemini-provider.test.ts +351 -28
- package/src/__tests__/guardian-grant-minting.test.ts +1 -1
- package/src/__tests__/guardian-routing-invariants.test.ts +2 -4
- package/src/__tests__/guardian-routing-state.test.ts +60 -71
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +10 -8
- package/src/__tests__/heartbeat-disk-pressure.test.ts +2 -0
- package/src/__tests__/heartbeat-service.test.ts +3 -1
- package/src/__tests__/helpers/mock-provider.ts +110 -0
- package/src/__tests__/helpers/native-web-search-harness.ts +129 -0
- package/src/__tests__/history-repair-hook.test.ts +162 -0
- package/src/__tests__/history-repair-observability.test.ts +1 -1
- package/src/__tests__/history-repair.test.ts +2 -1
- package/src/__tests__/host-app-control-proxy.test.ts +2 -0
- package/src/__tests__/host-app-control-routes.test.ts +1 -1
- package/src/__tests__/host-cu-proxy.test.ts +2 -0
- package/src/__tests__/host-cu-routes-targeted.test.ts +3 -3
- package/src/__tests__/host-file-edit-tool.test.ts +4 -2
- package/src/__tests__/host-file-proxy.test.ts +31 -0
- package/src/__tests__/host-file-read-tool.test.ts +4 -2
- package/src/__tests__/host-file-write-tool.test.ts +9 -3
- package/src/__tests__/host-proxy-preactivation.test.ts +53 -14
- package/src/__tests__/host-shell-tool.test.ts +9 -4
- package/src/__tests__/http-user-message-parity.test.ts +2 -2
- package/src/__tests__/identity-intro-cache.test.ts +47 -114
- package/src/__tests__/identity-routes.test.ts +248 -7
- package/src/__tests__/inbound-slack-persistence.test.ts +12 -3
- package/src/__tests__/injector-background-turn.test.ts +3 -9
- package/src/__tests__/injector-chain.test.ts +139 -275
- package/src/__tests__/injector-disk-pressure.test.ts +75 -41
- package/src/__tests__/injector-document-comments.test.ts +3 -3
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +30 -22
- package/src/__tests__/injector-v3-suppression.test.ts +214 -0
- package/src/__tests__/internal-telemetry-routes.test.ts +109 -0
- package/src/__tests__/list-messages-attachments.test.ts +7 -8
- package/src/__tests__/list-messages-hidden-metadata.test.ts +55 -15
- package/src/__tests__/list-messages-page-latest.test.ts +60 -1
- package/src/__tests__/list-messages-tool-merge.test.ts +56 -6
- package/src/__tests__/llm-request-log-turn-query.test.ts +42 -86
- package/src/__tests__/llm-resolver.test.ts +23 -47
- package/src/__tests__/llm-usage-store.test.ts +268 -1
- package/src/__tests__/log-export-routes.test.ts +59 -0
- package/src/__tests__/managed-skill-lifecycle.test.ts +1 -8
- package/src/__tests__/mcp-auth-routes.test.ts +15 -10
- package/src/__tests__/mcp-health-check.test.ts +18 -13
- package/src/__tests__/memory-retrieval-hook.test.ts +297 -0
- package/src/__tests__/memory-v2-static-injector.test.ts +103 -35
- package/src/__tests__/messaging-send-tool.test.ts +8 -4
- package/src/__tests__/migration-export-http.test.ts +12 -12
- package/src/__tests__/migration-import-commit-http.test.ts +8 -8
- package/src/__tests__/migration-import-preflight-http.test.ts +7 -7
- package/src/__tests__/migration-validate-http.test.ts +3 -3
- package/src/__tests__/native-web-search.test.ts +205 -20
- package/src/__tests__/notification-decision-identity.test.ts +9 -18
- package/src/__tests__/notification-decision-recipient-context.test.ts +3 -6
- package/src/__tests__/oauth-commands-routes.test.ts +1 -1
- package/src/__tests__/onboarding-template-contract.test.ts +12 -0
- package/src/__tests__/openai-image-service.test.ts +17 -0
- package/src/__tests__/openai-provider.test.ts +97 -71
- package/src/__tests__/openai-responses-provider.test.ts +21 -77
- package/src/__tests__/outbound-slack-persistence.test.ts +2 -1
- package/src/__tests__/{overflow-reduce-pipeline.test.ts → overflow-reduction-loop.test.ts} +64 -286
- package/src/__tests__/parallel-tool.benchmark.test.ts +24 -36
- package/src/__tests__/persist-unsendable-image.test.ts +215 -0
- package/src/__tests__/persistence-secret-redaction.test.ts +3 -1
- package/src/__tests__/pipeline-runner.test.ts +31 -43
- package/src/__tests__/pkb-autoinject.test.ts +2 -5
- package/src/__tests__/plugin-bootstrap.test.ts +62 -51
- package/src/__tests__/plugin-registry.test.ts +0 -27
- package/src/__tests__/plugin-route-contribution.test.ts +6 -16
- package/src/__tests__/plugin-skill-contribution.test.ts +7 -17
- package/src/__tests__/plugin-tool-contribution.test.ts +10 -26
- package/src/__tests__/plugin-types.test.ts +8 -173
- package/src/__tests__/prechat-onboarding-contract.test.ts +23 -0
- package/src/__tests__/process-message-background-slack.test.ts +17 -16
- package/src/__tests__/process-message-display-content.test.ts +36 -44
- package/src/__tests__/provider-commit-message-generator.test.ts +19 -14
- package/src/__tests__/provider-error-scenarios.test.ts +7 -6
- package/src/__tests__/provider-platform-proxy-integration.test.ts +3 -8
- package/src/__tests__/provider-send-message-override-profile.test.ts +9 -25
- package/src/__tests__/provider-streaming.benchmark.test.ts +12 -22
- package/src/__tests__/provider-usage-tracking.test.ts +0 -6
- package/src/__tests__/ratelimit.test.ts +9 -4
- package/src/__tests__/reaction-persistence.test.ts +1 -1
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +5 -1
- package/src/__tests__/relay-server.test.ts +20 -13
- package/src/__tests__/resolve-trust-class.test.ts +4 -4
- package/src/__tests__/retry-openrouter-only-normalization.test.ts +5 -8
- package/src/__tests__/retry-thinking-tool-choice.test.ts +10 -13
- package/src/__tests__/retry-verbosity-normalization.test.ts +5 -8
- package/src/__tests__/runtime-events-sse-reconnect.test.ts +390 -0
- package/src/__tests__/schedule-routes.test.ts +683 -12
- package/src/__tests__/schedule-store.test.ts +108 -0
- package/src/__tests__/schedule-tools.test.ts +160 -0
- package/src/__tests__/secret-ingress-http.test.ts +2 -2
- package/src/__tests__/secret-prompt-log-hygiene.test.ts +11 -7
- package/src/__tests__/secret-prompter-channel-fallback.test.ts +11 -9
- package/src/__tests__/secret-response-routing.test.ts +13 -11
- package/src/__tests__/send-endpoint-busy.test.ts +6 -2
- package/src/__tests__/server-history-render.test.ts +314 -1
- package/src/__tests__/shell-observability.test.ts +249 -0
- package/src/__tests__/skill-feature-flags-integration.test.ts +44 -11
- package/src/__tests__/skill-feature-flags.test.ts +6 -6
- package/src/__tests__/skill-load-feature-flag.test.ts +10 -10
- package/src/__tests__/skills-files-catalog-fallback.test.ts +10 -0
- package/src/__tests__/skillssh-files.test.ts +1 -0
- package/src/__tests__/starter-task-flow.test.ts +6 -6
- package/src/__tests__/strip-memory-injections.test.ts +102 -14
- package/src/__tests__/subagent-call-site-routing.test.ts +3 -3
- package/src/__tests__/subagent-fork-notifications.test.ts +1 -3
- package/src/__tests__/subagent-fork-spawn.test.ts +1 -1
- package/src/__tests__/subagent-manager-notify.test.ts +1 -3
- package/src/__tests__/subagent-notify-parent.test.ts +1 -3
- package/src/__tests__/subagent-spawn-tool-fork.test.ts +1 -1
- package/src/__tests__/suggestion-routes.test.ts +3 -3
- package/src/__tests__/sync-message-contract.test.ts +19 -16
- package/src/__tests__/system-prompt.test.ts +74 -0
- package/src/__tests__/task-scheduler.test.ts +162 -1
- package/src/__tests__/terminal-tools.test.ts +9 -25
- package/src/__tests__/thread-backfill.test.ts +4 -9
- package/src/__tests__/title-generate-hook.test.ts +319 -0
- package/src/__tests__/tool-error-hook.test.ts +278 -0
- package/src/__tests__/tool-preview-lifecycle.test.ts +481 -16
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +1 -0
- package/src/__tests__/tool-result-truncate-hook.test.ts +127 -0
- package/src/__tests__/tool-result-truncation.test.ts +1 -1
- package/src/__tests__/tools-audio-read.test.ts +113 -0
- package/src/__tests__/turn-boundary-resolution.test.ts +44 -84
- package/src/__tests__/turn-events-store.test.ts +11 -7
- package/src/__tests__/ui-choice-copy-surfaces.test.ts +254 -0
- package/src/__tests__/ui-work-result-surface.test.ts +159 -0
- package/src/__tests__/usage-routes.test.ts +285 -1
- package/src/__tests__/user-plugin-loader.test.ts +2 -2
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +8 -6
- package/src/__tests__/voice-session-bridge.test.ts +19 -10
- package/src/__tests__/web-search-backend-failure.test.ts +166 -0
- package/src/acp/__tests__/agent-process.test.ts +161 -0
- package/src/acp/__tests__/client-handler.test.ts +40 -0
- package/src/acp/__tests__/helpers/acp-history-db.ts +82 -0
- package/src/acp/__tests__/helpers/exec-file-stub.ts +101 -0
- package/src/acp/__tests__/prepare-agent-env.test.ts +143 -31
- package/src/acp/__tests__/session-manager-persistence.test.ts +95 -28
- package/src/acp/__tests__/session-manager-resume.test.ts +695 -0
- package/src/acp/agent-process.ts +61 -1
- package/src/acp/auto-install.test.ts +125 -0
- package/src/acp/auto-install.ts +174 -0
- package/src/acp/client-handler.ts +31 -0
- package/src/acp/feature-gate.test.ts +48 -0
- package/src/acp/feature-gate.ts +34 -0
- package/src/acp/prepare-agent-env.ts +52 -11
- package/src/acp/resolve-agent.test.ts +147 -6
- package/src/acp/resolve-agent.ts +81 -7
- package/src/acp/resume-hint.ts +22 -0
- package/src/acp/session-manager.ts +487 -71
- package/src/agent/compaction-circuit.ts +98 -0
- package/src/agent/loop.ts +651 -450
- package/src/api/README.md +19 -17
- package/src/api/constants/tool-execution.ts +21 -0
- package/src/api/events/assistant-activity-state.ts +75 -0
- package/src/api/events/assistant-outbound-attachment.ts +25 -27
- package/src/api/events/assistant-text-delta.ts +6 -8
- package/src/api/events/assistant-thinking-delta.ts +33 -0
- package/src/api/events/assistant-turn-start.ts +5 -7
- package/src/api/events/avatar-updated.ts +24 -0
- package/src/api/events/compaction-circuit-closed.ts +26 -0
- package/src/api/events/compaction-circuit-open.ts +28 -0
- package/src/api/events/confirmation-request.ts +114 -0
- package/src/api/events/contact-request.ts +33 -0
- package/src/api/events/conversation-error.ts +77 -0
- package/src/api/events/conversation-list-invalidated.ts +38 -0
- package/src/api/events/conversation-title-updated.ts +24 -0
- package/src/api/events/disk-pressure-status-changed.ts +61 -0
- package/src/api/events/document-comment-created.ts +24 -28
- package/src/api/events/document-comment-deleted.ts +6 -8
- package/src/api/events/document-comment-reopened.ts +6 -8
- package/src/api/events/document-comment-resolved.ts +8 -10
- package/src/api/events/document-editor-update.ts +27 -0
- package/src/api/events/error.ts +32 -0
- package/src/api/events/generation-cancelled.ts +4 -6
- package/src/api/events/generation-handoff.ts +13 -15
- package/src/api/events/home-feed-updated.ts +26 -0
- package/src/api/events/identity-changed.ts +32 -0
- package/src/api/events/interaction-resolved.ts +50 -0
- package/src/api/events/message-complete.ts +10 -12
- package/src/api/events/message-dequeued.ts +21 -0
- package/src/api/events/message-queued-deleted.ts +23 -0
- package/src/api/events/message-queued.ts +22 -0
- package/src/api/events/message-request-complete.ts +29 -0
- package/src/api/events/navigate-settings.ts +20 -0
- package/src/api/events/notification-intent.ts +33 -0
- package/src/api/events/open-url.ts +6 -8
- package/src/api/events/question-request.ts +67 -0
- package/src/api/events/relationship-state-updated.ts +4 -6
- package/src/api/events/secret-request.ts +42 -0
- package/src/api/events/subagent-event.ts +79 -0
- package/src/api/events/subagent-spawned.ts +40 -0
- package/src/api/events/subagent-status-changed.ts +65 -0
- package/src/api/events/sync-changed.ts +29 -0
- package/src/api/events/tool-output-chunk.ts +45 -0
- package/src/api/events/tool-result.ts +129 -0
- package/src/api/events/tool-use-preview-start.ts +32 -0
- package/src/api/events/tool-use-start.ts +8 -10
- package/src/api/events/trace-event.ts +69 -0
- package/src/api/events/turn-profile-auto-routed.ts +28 -0
- package/src/api/events/ui-surface-complete.ts +30 -0
- package/src/api/events/ui-surface-dismiss.ts +22 -0
- package/src/api/events/ui-surface-show.ts +67 -0
- package/src/api/events/ui-surface-update.ts +26 -0
- package/src/api/events/usage-update.ts +34 -0
- package/src/api/events/user-message-echo.ts +35 -0
- package/src/api/index.ts +389 -0
- package/src/api/requests/dictation.ts +45 -0
- package/src/api/responses/conversation-message.ts +374 -0
- package/src/api/responses/disk-pressure-status.ts +26 -0
- package/src/api/responses/home.ts +217 -0
- package/src/api/responses/llm-context-response.ts +2 -0
- package/src/api/responses/memory-v3-selection-log.ts +50 -0
- package/src/api/responses/subagent-detail.ts +48 -0
- package/src/approvals/guardian-decision-primitive.ts +7 -15
- package/src/approvals/guardian-request-resolvers.ts +7 -10
- package/src/avatar/__tests__/avatar-manifest.test.ts +236 -0
- package/src/avatar/__tests__/avatar-store.test.ts +198 -0
- package/src/avatar/avatar-manifest.ts +195 -0
- package/src/avatar/avatar-store.ts +113 -0
- package/src/avatar/traits-png-sync.ts +8 -2
- package/src/background-wake/next-wake.test.ts +31 -1
- package/src/background-wake/next-wake.ts +5 -1
- package/src/calls/call-conversation-messages.ts +6 -4
- package/src/calls/guardian-action-sweep.ts +6 -4
- package/src/calls/relay-server.ts +12 -8
- package/src/calls/voice-session-bridge.ts +13 -27
- package/src/cli/commands/__tests__/memory-v3.test.ts +245 -0
- package/src/cli/commands/__tests__/notifications.test.ts +58 -14
- package/src/cli/commands/avatar.ts +17 -11
- package/src/cli/commands/conversations.ts +15 -1
- package/src/cli/commands/db/__tests__/repair.test.ts +540 -0
- package/src/cli/commands/db/__tests__/status.test.ts +253 -0
- package/src/cli/commands/db/format.ts +48 -0
- package/src/cli/commands/db/index.ts +29 -0
- package/src/cli/commands/db/repair-step-conversation-backfill.ts +345 -0
- package/src/cli/commands/db/repair-step-integrity.ts +146 -0
- package/src/cli/commands/db/repair-steps.ts +164 -0
- package/src/cli/commands/db/repair.ts +141 -0
- package/src/cli/commands/db/status.ts +366 -0
- package/src/cli/commands/memory-v3.ts +159 -445
- package/src/cli/commands/notifications.ts +112 -60
- package/src/cli/lib/cli-colors.ts +24 -6
- package/src/cli/program.ts +4 -5
- package/src/config/__tests__/feature-flag-registry-guard.test.ts +4 -4
- package/src/config/acp-defaults.test.ts +10 -0
- package/src/config/acp-defaults.ts +6 -0
- package/src/config/assistant-feature-flags.ts +24 -13
- package/src/config/bundled-skills/acp/SKILL.md +64 -30
- package/src/config/bundled-skills/acp/TOOLS.json +4 -4
- package/src/config/bundled-skills/app-builder/SKILL.md +224 -387
- package/src/config/bundled-skills/app-builder/TOOLS.json +29 -0
- package/src/config/bundled-skills/app-builder/references/DESIGN_SYSTEM.md +48 -0
- package/src/config/bundled-skills/app-builder/references/RESPONSIVE.md +57 -0
- package/src/config/bundled-skills/app-builder/references/SLIDES.md +38 -0
- package/src/config/bundled-skills/app-builder/references/examples/README.md +17 -0
- package/src/config/bundled-skills/app-builder/references/examples/expense-tracker.md +515 -0
- package/src/config/bundled-skills/app-builder/references/examples/focus-timer.md +342 -0
- package/src/config/bundled-skills/app-builder/references/examples/habit-tracker.md +490 -0
- package/src/config/bundled-skills/app-builder/tools/app-list.ts +62 -0
- package/src/config/bundled-skills/document-editor/SKILL.md +28 -23
- package/src/config/bundled-skills/document-editor/TOOLS.json +1 -1
- package/src/config/bundled-skills/media-processing/services/reduce.ts +6 -9
- package/src/config/bundled-skills/messaging/SKILL.md +0 -7
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +7 -2
- package/src/config/bundled-skills/schedule/SKILL.md +1 -1
- package/src/config/bundled-skills/schedule/TOOLS.json +8 -0
- package/src/config/bundled-tool-registry.ts +2 -0
- package/src/config/call-site-defaults.ts +2 -7
- package/src/config/feature-flag-cache.ts +3 -3
- package/src/config/feature-flag-registry.json +68 -12
- package/src/config/schemas/__tests__/memory-v2.test.ts +2 -226
- package/src/config/schemas/__tests__/memory-v3.test.ts +25 -0
- package/src/config/schemas/call-site-catalog.ts +8 -15
- package/src/config/schemas/heartbeat.ts +9 -0
- package/src/config/schemas/llm.ts +3 -3
- package/src/config/schemas/memory-lifecycle.ts +24 -0
- package/src/config/schemas/memory-v2.ts +8 -253
- package/src/config/schemas/memory-v3.ts +47 -0
- package/src/config/schemas/memory.ts +6 -1
- package/src/config/schemas/platform.ts +8 -0
- package/src/config/schemas/timeouts.ts +3 -1
- package/src/config/seed-inference-profiles.ts +2 -2
- package/src/config/skills.ts +13 -0
- package/src/context/compactor.ts +55 -32
- package/src/context/strip-injections.ts +128 -0
- package/src/context/token-estimator.ts +42 -0
- package/src/context/tool-result-truncation.ts +1 -66
- package/src/context/window-manager.ts +141 -26
- package/src/credential-execution/executable-discovery.ts +16 -0
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +6 -0
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +2 -2
- package/src/daemon/__tests__/inference-profile-notification.test.ts +153 -0
- package/src/daemon/__tests__/native-web-search-metadata.test.ts +10 -8
- package/src/daemon/__tests__/web-search-status-text.test.ts +10 -6
- package/src/daemon/approval-generators.ts +4 -4
- package/src/daemon/assistant-attachments.ts +1 -1
- package/src/daemon/config-watcher.ts +7 -1
- package/src/daemon/context-overflow-reducer.ts +0 -1
- package/src/daemon/conversation-agent-loop-handlers.ts +793 -215
- package/src/daemon/conversation-agent-loop.ts +487 -1478
- package/src/daemon/conversation-error.ts +7 -7
- package/src/daemon/conversation-history.ts +27 -10
- package/src/daemon/conversation-launch.ts +4 -8
- package/src/daemon/conversation-lifecycle.ts +13 -42
- package/src/daemon/conversation-messaging.ts +8 -9
- package/src/daemon/conversation-notifiers.ts +7 -5
- package/src/daemon/conversation-process.ts +109 -93
- package/src/daemon/conversation-registry.ts +159 -0
- package/src/daemon/conversation-runtime-assembly.ts +209 -382
- package/src/daemon/conversation-slash.ts +6 -25
- package/src/daemon/conversation-store.ts +15 -95
- package/src/daemon/conversation-surfaces.ts +277 -73
- package/src/daemon/conversation-tool-setup.ts +5 -29
- package/src/daemon/conversation-workspace.ts +17 -0
- package/src/daemon/conversation.ts +123 -146
- package/src/daemon/daemon-skill-host.ts +2 -6
- package/src/daemon/disk-pressure-guard.ts +35 -29
- package/src/daemon/external-plugins-bootstrap.ts +53 -32
- package/src/daemon/first-greeting.ts +26 -4
- package/src/daemon/guardian-action-generators.ts +2 -2
- package/src/daemon/handlers/config-a2a.ts +51 -36
- package/src/daemon/handlers/config-slack-channel.ts +20 -14
- package/src/daemon/handlers/config-telegram.ts +16 -2
- package/src/daemon/handlers/conversations.ts +9 -23
- package/src/daemon/handlers/shared.ts +158 -82
- package/src/daemon/handlers/skills.ts +53 -20
- package/src/daemon/host-app-control-proxy.ts +54 -1
- package/src/daemon/host-cu-proxy.ts +46 -22
- package/src/daemon/host-file-proxy.ts +25 -1
- package/src/daemon/host-proxy-preactivation.ts +25 -6
- package/src/daemon/lifecycle.ts +53 -55
- package/src/daemon/message-protocol.ts +2 -3
- package/src/daemon/message-provenance.ts +49 -0
- package/src/daemon/message-types/apps.ts +1 -29
- package/src/daemon/message-types/contacts.ts +3 -20
- package/src/daemon/message-types/conversations.ts +13 -111
- package/src/daemon/message-types/documents.ts +3 -9
- package/src/daemon/message-types/home.ts +4 -17
- package/src/daemon/message-types/integrations.ts +2 -6
- package/src/daemon/message-types/messages.ts +37 -400
- package/src/daemon/message-types/notifications.ts +2 -32
- package/src/daemon/message-types/settings.ts +3 -8
- package/src/daemon/message-types/skills.ts +4 -0
- package/src/daemon/message-types/surfaces.ts +138 -3
- package/src/daemon/message-types/sync.ts +12 -25
- package/src/daemon/message-types/workspace.ts +3 -11
- package/src/daemon/now-scratchpad.ts +21 -0
- package/src/daemon/orphan-reaper.test.ts +210 -0
- package/src/daemon/orphan-reaper.ts +240 -0
- package/src/daemon/overflow-reduction-loop.ts +230 -0
- package/src/daemon/persist-unsendable-image.ts +117 -0
- package/src/daemon/process-message.ts +50 -49
- package/src/daemon/server.ts +14 -0
- package/src/daemon/tool-side-effects.ts +10 -7
- package/src/daemon/trace-emitter.ts +6 -4
- package/src/daemon/trust-context.ts +32 -0
- package/src/daemon/wake-target-adapter.ts +14 -2
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +6 -1
- package/src/heartbeat/heartbeat-run-store.ts +54 -1
- package/src/heartbeat/heartbeat-service.ts +42 -0
- package/src/home/feed-types.ts +36 -221
- package/src/home/home-greeting-cache.ts +24 -1
- package/src/ipc/__tests__/browser-ipc.test.ts +1 -1
- package/src/ipc/__tests__/email-ipc.test.ts +0 -9
- package/src/ipc/__tests__/ui-request-route.test.ts +3 -3
- package/src/ipc/gateway-client.test.ts +2 -2
- package/src/ipc/gateway-client.ts +3 -3
- package/src/ipc/routes/__tests__/route-adapter.test.ts +244 -0
- package/src/ipc/routes/route-adapter.ts +45 -6
- package/src/ipc/skill-routes/__tests__/memory.test.ts +33 -9
- package/src/ipc/skill-routes/__tests__/providers.test.ts +10 -10
- package/src/ipc/skill-routes/__tests__/registries.test.ts +28 -18
- package/src/ipc/skill-routes/memory.ts +29 -14
- package/src/ipc/skill-routes/providers.ts +5 -6
- package/src/ipc/skill-routes/registries.ts +13 -61
- package/src/live-voice/__tests__/live-voice-archive.test.ts +24 -11
- package/src/media/gemini-image-service.ts +15 -0
- package/src/media/openai-image-service.ts +14 -0
- package/src/media/types.ts +34 -0
- package/src/memory/__tests__/conversation-queries.test.ts +192 -8
- package/src/memory/__tests__/db-maintenance.test.ts +128 -0
- package/src/memory/__tests__/jobs-store-job-classes.test.ts +5 -4
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +56 -0
- package/src/memory/__tests__/memory-retrospective-job.test.ts +10 -6
- package/src/memory/__tests__/memory-v3-selections-migration.test.ts +103 -0
- package/src/memory/auth-fallback-events-store.ts +94 -0
- package/src/memory/context-search/agent-runner.ts +2 -4
- package/src/memory/conversation-crud.ts +39 -8
- package/src/memory/conversation-queries.ts +78 -22
- package/src/memory/conversation-starter-checkpoints.ts +1 -0
- package/src/memory/conversation-title-service.ts +65 -41
- package/src/memory/db-init.ts +14 -0
- package/src/memory/db-maintenance.ts +18 -2
- package/src/memory/graph/__tests__/conversation-graph-memory-registry.test.ts +119 -0
- package/src/memory/graph/consolidation.ts +8 -11
- package/src/memory/graph/conversation-graph-memory.ts +106 -8
- package/src/memory/graph/extraction.ts +6 -9
- package/src/memory/graph/narrative.ts +2 -2
- package/src/memory/graph/pattern-scan.ts +2 -2
- package/src/memory/graph/retriever.ts +20 -26
- package/src/memory/graph/tools.ts +4 -4
- package/src/memory/job-handlers/conversation-starters.ts +45 -34
- package/src/memory/job-handlers/summarization.ts +1 -2
- package/src/memory/jobs-store.ts +36 -1
- package/src/memory/jobs-worker.ts +82 -43
- package/src/memory/llm-request-log-source-clickhouse.ts +5 -31
- package/src/memory/llm-request-log-source-local.ts +0 -11
- package/src/memory/llm-request-log-source.ts +9 -25
- package/src/memory/llm-request-log-store.ts +0 -41
- package/src/memory/llm-usage-store.ts +234 -50
- package/src/memory/memory-marker.ts +17 -0
- package/src/memory/memory-retrospective-job.ts +6 -2
- package/src/memory/memory-v2-activation-log-store.ts +1 -83
- package/src/memory/migrations/222-strip-placeholder-sentinels-from-messages.ts +6 -5
- package/src/memory/migrations/267-llm-usage-events-add-assistant-version.ts +46 -0
- package/src/memory/migrations/268-add-memory-v3-selections.ts +28 -0
- package/src/memory/migrations/269-schedule-script-timeout.ts +11 -0
- package/src/memory/migrations/270-messages-role-created-at-index.ts +18 -0
- package/src/memory/migrations/270-schedule-source-conversation.ts +13 -0
- package/src/memory/migrations/271-create-auth-fallback-events.ts +21 -0
- package/src/memory/migrations/272-acp-session-history-cwd.ts +36 -0
- package/src/memory/migrations/__tests__/267-llm-usage-events-add-assistant-version.test.ts +117 -0
- package/src/memory/migrations/index.ts +7 -0
- package/src/memory/pkb/autoinject.ts +61 -0
- package/src/memory/pkb/context.ts +50 -0
- package/src/memory/pkb/types.ts +14 -0
- package/src/memory/schedule-attribution-sql.ts +104 -0
- package/src/memory/schema/acp.ts +4 -0
- package/src/memory/schema/infrastructure.ts +27 -0
- package/src/memory/usage-grouped-buckets.ts +6 -1
- package/src/memory/v2/__tests__/consolidation-job.test.ts +125 -1
- package/src/memory/v2/__tests__/migration.test.ts +11 -3
- package/src/memory/v2/__tests__/page-index.test.ts +37 -1
- package/src/memory/v2/__tests__/router.test.ts +14 -4
- package/src/memory/v2/__tests__/sweep-job.test.ts +6 -5
- package/src/memory/v2/backfill-jobs.ts +6 -0
- package/src/memory/v2/consolidation-job.ts +99 -10
- package/src/memory/v2/migration.ts +5 -3
- package/src/memory/v2/page-index.ts +11 -0
- package/src/memory/v2/router.ts +8 -11
- package/src/memory/v2/sweep-job.ts +8 -11
- package/src/memory/v2/types.ts +1 -0
- package/src/messaging/providers/slack/render-transcript.test.ts +1 -1
- package/src/messaging/providers/slack/render-transcript.ts +2 -2
- package/src/messaging/style-analyzer.ts +8 -11
- package/src/notifications/conversation-pairing.ts +8 -13
- package/src/notifications/decision-engine.ts +16 -16
- package/src/notifications/home-feed-side-effect.ts +12 -1
- package/src/notifications/preference-extractor.ts +11 -14
- package/src/permissions/prompter.ts +46 -36
- package/src/permissions/question-prompter.test.ts +35 -26
- package/src/permissions/question-prompter.ts +6 -10
- package/src/plugin-api/constants.ts +4 -0
- package/src/plugin-api/index.ts +10 -1
- package/src/plugin-api/types.ts +176 -4
- package/src/plugins/defaults/compaction/compact.ts +59 -0
- package/src/plugins/defaults/compaction/package.json +15 -0
- package/src/plugins/defaults/compaction/register.ts +24 -0
- package/src/plugins/defaults/empty-response/hooks/stop.ts +126 -0
- package/src/plugins/defaults/empty-response/package.json +15 -0
- package/src/plugins/defaults/empty-response/register.ts +23 -0
- package/src/plugins/defaults/history-repair/hooks/user-prompt-submit.ts +35 -0
- package/src/plugins/defaults/history-repair/package.json +15 -0
- package/src/plugins/defaults/history-repair/register.ts +24 -0
- package/src/{daemon/history-repair.ts → plugins/defaults/history-repair/terminal.ts} +48 -35
- package/src/plugins/defaults/index.ts +22 -49
- package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +95 -0
- package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit-temp.ts +216 -0
- package/src/plugins/defaults/memory-retrieval/injector-chain.ts +35 -0
- package/src/plugins/defaults/{injectors.ts → memory-retrieval/injectors.ts} +295 -112
- package/src/plugins/defaults/memory-v3-shadow/__tests__/assign.test.ts +242 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/capabilities.test.ts +118 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/core.test.ts +39 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/fixtures/eval-turns.json +36 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/fixtures/live-turns.json +37 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/health.test.ts +219 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/live-integration.test.ts +330 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/maintain-job.test.ts +288 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/needle.test.ts +107 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/orchestrate.test.ts +436 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/provider-blocks.test.ts +13 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/reconcile.test.ts +274 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/render-injection.test.ts +61 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/router.test.ts +332 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/selection-log-store.test.ts +179 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/selector.test.ts +470 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +432 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/snapshot.test.ts +168 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/tree.test.ts +192 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/types.test.ts +54 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/working-set-eviction.test.ts +106 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/working-set-skeleton.test.ts +44 -0
- package/src/plugins/defaults/memory-v3-shadow/assign.ts +268 -0
- package/src/plugins/defaults/memory-v3-shadow/capabilities.ts +124 -0
- package/src/plugins/defaults/memory-v3-shadow/core.ts +26 -0
- package/src/plugins/defaults/memory-v3-shadow/data/README.md +84 -0
- package/src/plugins/defaults/memory-v3-shadow/data/assignments.json +5 -0
- package/src/plugins/defaults/memory-v3-shadow/data/core.json +1 -0
- package/src/plugins/defaults/memory-v3-shadow/data/leaves/domain-a/topic-x.md +9 -0
- package/src/plugins/defaults/memory-v3-shadow/data/leaves/domain-a/topic-y.md +9 -0
- package/src/plugins/defaults/memory-v3-shadow/data/leaves/domain-b/topic-z.md +9 -0
- package/src/plugins/defaults/memory-v3-shadow/health.ts +0 -0
- package/src/plugins/defaults/memory-v3-shadow/hooks/post-compact.ts +14 -0
- package/src/plugins/defaults/memory-v3-shadow/hooks/user-prompt-submit.ts +19 -0
- package/src/plugins/defaults/memory-v3-shadow/injector.ts +75 -0
- package/src/plugins/defaults/memory-v3-shadow/llm-retry.ts +32 -0
- package/src/plugins/defaults/memory-v3-shadow/maintain-job.ts +314 -0
- package/src/plugins/defaults/memory-v3-shadow/needle.ts +115 -0
- package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +126 -0
- package/src/plugins/defaults/memory-v3-shadow/package.json +15 -0
- package/src/plugins/defaults/memory-v3-shadow/page-content.ts +34 -0
- package/src/plugins/defaults/memory-v3-shadow/provider-blocks.ts +26 -0
- package/src/plugins/defaults/memory-v3-shadow/reconcile.ts +523 -0
- package/src/plugins/defaults/memory-v3-shadow/register.ts +26 -0
- package/src/plugins/defaults/memory-v3-shadow/render-injection.ts +32 -0
- package/src/plugins/defaults/memory-v3-shadow/router.ts +190 -0
- package/src/plugins/defaults/memory-v3-shadow/selection-log-store.ts +84 -0
- package/src/plugins/defaults/memory-v3-shadow/selector.ts +226 -0
- package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +349 -0
- package/src/plugins/defaults/memory-v3-shadow/snapshot.ts +209 -0
- package/src/plugins/defaults/memory-v3-shadow/tree.ts +174 -0
- package/src/plugins/defaults/memory-v3-shadow/types.ts +59 -0
- package/src/plugins/defaults/memory-v3-shadow/working-set.ts +88 -0
- package/src/plugins/defaults/title-generate/hooks/stop.ts +75 -0
- package/src/plugins/defaults/title-generate/hooks/user-prompt-submit.ts +35 -0
- package/src/plugins/defaults/title-generate/package.json +15 -0
- package/src/plugins/defaults/title-generate/register.ts +35 -0
- package/src/plugins/defaults/tool-error/hooks/post-tool-use.ts +118 -0
- package/src/plugins/defaults/tool-error/package.json +15 -0
- package/src/plugins/defaults/tool-error/register.ts +23 -0
- package/src/plugins/defaults/tool-result-truncate/hooks/post-tool-use.ts +32 -0
- package/src/plugins/defaults/tool-result-truncate/package.json +15 -0
- package/src/plugins/defaults/tool-result-truncate/register.ts +24 -0
- package/src/plugins/defaults/tool-result-truncate/terminal.ts +132 -0
- package/src/plugins/external-plugin-loader.ts +2 -2
- package/src/plugins/pipeline.ts +8 -35
- package/src/plugins/registry.ts +8 -25
- package/src/plugins/types.ts +62 -721
- package/src/plugins/user-loader.ts +4 -3
- package/src/proactive-artifact/aux-message-injector.ts +4 -5
- package/src/proactive-artifact/job.test.ts +28 -21
- package/src/proactive-artifact/job.ts +3 -1
- package/src/prompts/__tests__/system-prompt.test.ts +42 -0
- package/src/prompts/sections.ts +20 -7
- package/src/prompts/templates/BOOTSTRAP-ACTIVATION-RAIL.md +64 -0
- package/src/prompts/templates/BOOTSTRAP-CONTENT-AUTOMATION.md +2 -2
- package/src/prompts/templates/BOOTSTRAP.md +7 -3
- package/src/prompts/templates/system-sections.ts +21 -0
- package/src/providers/__tests__/retry-callsite.test.ts +25 -25
- package/src/providers/__tests__/satellite-connection-routing.test.ts +7 -21
- package/src/providers/anthropic/client.ts +61 -34
- package/src/providers/call-site-routing.ts +1 -9
- package/src/providers/gemini/client.ts +152 -34
- package/src/providers/gemini/inline-media.ts +74 -0
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +112 -2
- package/src/providers/openai/chat-completions-provider.ts +45 -4
- package/src/providers/openai/responses-provider.ts +1 -4
- package/src/providers/openrouter/client.ts +2 -6
- package/src/providers/placeholder-sentinels.ts +35 -0
- package/src/providers/provider-send-message.ts +6 -6
- package/src/providers/ratelimit.ts +1 -9
- package/src/providers/retry.ts +0 -5
- package/src/providers/types.ts +11 -2
- package/src/providers/usage-tracking.ts +1 -9
- package/src/runtime/__tests__/agent-wake.test.ts +141 -32
- package/src/runtime/__tests__/background-job-runner.test.ts +1 -3
- package/src/runtime/__tests__/interactive-ui.test.ts +1 -1
- package/src/runtime/agent-wake.ts +95 -23
- package/src/runtime/assistant-event-hub.ts +38 -8
- package/src/runtime/assistant-stream-state.ts +368 -0
- package/src/runtime/auth/__tests__/guard-tests.test.ts +75 -109
- package/src/runtime/auth/__tests__/route-policy.test.ts +153 -170
- package/src/runtime/auth/route-policy.ts +42 -1079
- package/src/runtime/background-job-runner.ts +1 -4
- package/src/runtime/btw-sidechain.ts +3 -1
- package/src/runtime/channel-approvals.ts +4 -15
- package/src/runtime/channel-invite-transport.ts +5 -6
- package/src/runtime/channel-readiness-service.ts +2 -5
- package/src/runtime/channel-retry-sweep.ts +12 -16
- package/src/runtime/http-router.ts +35 -43
- package/src/runtime/http-types.ts +23 -71
- package/src/runtime/interactive-ui.ts +1 -1
- package/src/runtime/invite-instruction-generator.ts +3 -3
- package/src/runtime/pending-interactions.ts +3 -2
- package/src/runtime/routes/__tests__/acp-routes.test.ts +253 -55
- package/src/runtime/routes/__tests__/avatar-state-routes.test.ts +565 -0
- package/src/runtime/routes/__tests__/consolidation-routes.test.ts +265 -2
- package/src/runtime/routes/__tests__/content-source-routes.test.ts +4 -4
- package/src/runtime/routes/__tests__/conversation-compaction-routes.test.ts +62 -32
- package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +237 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +31 -1
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +13 -22
- package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +6 -2
- package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +7 -2
- package/src/runtime/routes/__tests__/sanity-routes.test.ts +6 -6
- package/src/runtime/routes/__tests__/stt-routes.test.ts +3 -3
- package/src/runtime/routes/__tests__/suggest-trust-rule-routes.test.ts +5 -2
- package/src/runtime/routes/__tests__/surface-action-routes.test.ts +5 -4
- package/src/runtime/routes/__tests__/surface-content-routes.test.ts +4 -1
- package/src/runtime/routes/__tests__/tts-routes.test.ts +9 -5
- package/src/runtime/routes/acp-routes.test.ts +186 -100
- package/src/runtime/routes/acp-routes.ts +110 -35
- package/src/runtime/routes/app-management-routes.ts +93 -131
- package/src/runtime/routes/app-routes.ts +38 -20
- package/src/runtime/routes/approval-routes.ts +17 -5
- package/src/runtime/routes/attachment-routes.ts +51 -16
- package/src/runtime/routes/audio-routes.ts +1 -0
- package/src/runtime/routes/audit-routes.ts +5 -0
- package/src/runtime/routes/auth-routes.ts +5 -0
- package/src/runtime/routes/avatar-routes.ts +264 -59
- package/src/runtime/routes/background-tool-routes.ts +9 -0
- package/src/runtime/routes/background-wake-routes.ts +13 -3
- package/src/runtime/routes/backup-routes.ts +45 -0
- package/src/runtime/routes/bookmark-routes.ts +13 -0
- package/src/runtime/routes/brain-graph-routes.ts +9 -0
- package/src/runtime/routes/browser-routes.ts +6 -1
- package/src/runtime/routes/browser-tabs-routes.ts +11 -10
- package/src/runtime/routes/btw-routes.ts +34 -24
- package/src/runtime/routes/cache-routes.ts +13 -0
- package/src/runtime/routes/call-routes.ts +21 -10
- package/src/runtime/routes/channel-availability-routes.ts +5 -1
- package/src/runtime/routes/channel-readiness-routes.ts +37 -4
- package/src/runtime/routes/channel-route-definitions.ts +21 -0
- package/src/runtime/routes/channel-verification-routes.ts +21 -0
- package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +9 -2
- package/src/runtime/routes/client-routes.ts +9 -0
- package/src/runtime/routes/consolidation-routes.ts +133 -25
- package/src/runtime/routes/contact-prompt-routes.ts +9 -0
- package/src/runtime/routes/contact-routes.ts +90 -23
- package/src/runtime/routes/content-source-routes.ts +5 -1
- package/src/runtime/routes/conversation-analysis-routes.ts +5 -1
- package/src/runtime/routes/conversation-attention-routes.ts +5 -0
- package/src/runtime/routes/conversation-cli-routes.ts +54 -7
- package/src/runtime/routes/conversation-compaction-routes.ts +54 -25
- package/src/runtime/routes/conversation-list-routes.ts +81 -12
- package/src/runtime/routes/conversation-management-routes.ts +57 -14
- package/src/runtime/routes/conversation-query-routes.ts +90 -41
- package/src/runtime/routes/conversation-routes.ts +446 -204
- package/src/runtime/routes/conversation-starter-routes.ts +35 -20
- package/src/runtime/routes/conversations-import-routes.ts +30 -8
- package/src/runtime/routes/credential-prompt-routes.ts +5 -0
- package/src/runtime/routes/credential-routes.ts +25 -6
- package/src/runtime/routes/debug-bash-routes.ts +5 -0
- package/src/runtime/routes/debug-routes.ts +11 -2
- package/src/runtime/routes/defer-routes.ts +13 -0
- package/src/runtime/routes/diagnostics-routes.ts +37 -46
- package/src/runtime/routes/disk-pressure-routes.ts +17 -31
- package/src/runtime/routes/document-comments-routes.ts +46 -27
- package/src/runtime/routes/documents-routes.ts +25 -10
- package/src/runtime/routes/domain-routes.ts +98 -51
- package/src/runtime/routes/email-routes.ts +33 -0
- package/src/runtime/routes/epoch-millis-range.ts +34 -0
- package/src/runtime/routes/events-routes.ts +107 -8
- package/src/runtime/routes/filing-routes.ts +9 -4
- package/src/runtime/routes/gateway-log-routes.ts +31 -4
- package/src/runtime/routes/global-search-routes.ts +53 -50
- package/src/runtime/routes/group-routes.ts +21 -5
- package/src/runtime/routes/guardian-action-routes.ts +9 -0
- package/src/runtime/routes/guardian-approval-interception.ts +0 -31
- package/src/runtime/routes/heartbeat-routes.ts +57 -21
- package/src/runtime/routes/home-feed-routes.ts +23 -19
- package/src/runtime/routes/home-state-routes.ts +8 -40
- package/src/runtime/routes/host-app-control-routes.ts +6 -1
- package/src/runtime/routes/host-bash-routes.ts +5 -0
- package/src/runtime/routes/host-browser-routes.ts +13 -0
- package/src/runtime/routes/host-cu-routes.ts +6 -1
- package/src/runtime/routes/host-file-routes.ts +26 -6
- package/src/runtime/routes/host-transfer-routes.ts +13 -2
- package/src/runtime/routes/http-adapter.ts +1 -2
- package/src/runtime/routes/identity-intro-cache.ts +28 -40
- package/src/runtime/routes/identity-routes.ts +236 -20
- package/src/runtime/routes/image-generation-routes.ts +45 -2
- package/src/runtime/routes/inbound-message-handler.ts +16 -12
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +0 -12
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +15 -19
- package/src/runtime/routes/index.ts +2 -0
- package/src/runtime/routes/inference-profile-session-routes.ts +13 -3
- package/src/runtime/routes/inference-provider-connection-routes.ts +21 -5
- package/src/runtime/routes/inference-send-routes.ts +11 -11
- package/src/runtime/routes/integrations/a2a.ts +32 -7
- package/src/runtime/routes/integrations/slack/__tests__/channel.test.ts +16 -0
- package/src/runtime/routes/integrations/slack/channel.ts +23 -3
- package/src/runtime/routes/integrations/slack/share.ts +36 -8
- package/src/runtime/routes/integrations/telegram.ts +34 -9
- package/src/runtime/routes/integrations/twilio.ts +77 -7
- package/src/runtime/routes/integrations/vercel.ts +3 -3
- package/src/runtime/routes/internal-oauth-routes.ts +5 -0
- package/src/runtime/routes/internal-telemetry-routes.ts +88 -0
- package/src/runtime/routes/internal-twilio-routes.ts +13 -0
- package/src/runtime/routes/llm-call-sites-routes.ts +39 -4
- package/src/runtime/routes/log-export-routes.ts +36 -10
- package/src/runtime/routes/mcp-auth-routes.ts +25 -0
- package/src/runtime/routes/memory-item-routes.ts +21 -10
- package/src/runtime/routes/memory-v2-routes.ts +105 -44
- package/src/runtime/routes/memory-v3-routes.ts +306 -408
- package/src/runtime/routes/migration-rollback-routes.ts +5 -1
- package/src/runtime/routes/migration-routes.ts +29 -0
- package/src/runtime/routes/notification-routes.ts +17 -1
- package/src/runtime/routes/oauth-apps.ts +99 -23
- package/src/runtime/routes/oauth-commands-routes.ts +37 -14
- package/src/runtime/routes/oauth-connect-routes.ts +9 -0
- package/src/runtime/routes/oauth-lifecycle-routes.ts +5 -1
- package/src/runtime/routes/oauth-providers.ts +79 -15
- package/src/runtime/routes/platform-routes.ts +102 -5
- package/src/runtime/routes/playground/__tests__/force-compact.test.ts +9 -6
- package/src/runtime/routes/playground/__tests__/inject-failures.test.ts +37 -16
- package/src/runtime/routes/playground/__tests__/reset-circuit.test.ts +7 -3
- package/src/runtime/routes/playground/__tests__/state.test.ts +10 -3
- package/src/runtime/routes/playground/force-compact.ts +2 -2
- package/src/runtime/routes/playground/helpers.ts +1 -2
- package/src/runtime/routes/playground/inject-failures.ts +13 -8
- package/src/runtime/routes/playground/reset-circuit.ts +14 -9
- package/src/runtime/routes/playground/seed-conversation.ts +1 -1
- package/src/runtime/routes/playground/seeded-conversations.ts +3 -3
- package/src/runtime/routes/playground/state.ts +4 -3
- package/src/runtime/routes/plugins-routes.ts +22 -19
- package/src/runtime/routes/profiler-routes.ts +17 -4
- package/src/runtime/routes/ps-routes.ts +5 -0
- package/src/runtime/routes/publish-routes.ts +13 -3
- package/src/runtime/routes/question-routes.ts +5 -0
- package/src/runtime/routes/recording-routes.ts +25 -12
- package/src/runtime/routes/rename-conversation-routes.ts +10 -0
- package/src/runtime/routes/sanity-routes.ts +9 -2
- package/src/runtime/routes/schedule-routes.ts +288 -88
- package/src/runtime/routes/secret-routes.ts +31 -6
- package/src/runtime/routes/sequence-routes.ts +33 -0
- package/src/runtime/routes/settings-routes.ts +65 -19
- package/src/runtime/routes/skills-routes.ts +166 -73
- package/src/runtime/routes/slack-channel-routes.ts +5 -0
- package/src/runtime/routes/stt-routes.ts +13 -6
- package/src/runtime/routes/subagents-routes.ts +24 -18
- package/src/runtime/routes/suggest-trust-rule-routes.ts +7 -2
- package/src/runtime/routes/surface-action-routes.ts +9 -0
- package/src/runtime/routes/surface-content-routes.ts +10 -2
- package/src/runtime/routes/surface-conversation-resolver.ts +4 -3
- package/src/runtime/routes/task-routes.ts +37 -0
- package/src/runtime/routes/telemetry-routes.ts +9 -0
- package/src/runtime/routes/tool-call-confirmation-enrichment.test.ts +161 -0
- package/src/runtime/routes/tool-call-confirmation-enrichment.ts +107 -0
- package/src/runtime/routes/trace-event-routes.ts +42 -1
- package/src/runtime/routes/trust-rules-routes.ts +31 -2
- package/src/runtime/routes/tts-routes.ts +48 -6
- package/src/runtime/routes/types.ts +83 -16
- package/src/runtime/routes/ui-request-routes.ts +5 -0
- package/src/runtime/routes/upgrade-broadcast-routes.ts +5 -0
- package/src/runtime/routes/usage-routes.ts +118 -42
- package/src/runtime/routes/user-routes-cli.ts +9 -0
- package/src/runtime/routes/user-routes.ts +5 -1
- package/src/runtime/routes/wake-conversation-routes.ts +5 -0
- package/src/runtime/routes/watcher-routes.ts +21 -0
- package/src/runtime/routes/webhook-routes.ts +50 -2
- package/src/runtime/routes/wipe-conversation-routes.ts +5 -0
- package/src/runtime/routes/work-items-routes.ts +49 -23
- package/src/runtime/routes/workspace-commit-routes.ts +5 -0
- package/src/runtime/routes/workspace-routes.test.ts +42 -0
- package/src/runtime/routes/workspace-routes.ts +124 -9
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +8 -4
- package/src/runtime/services/analyze-conversation.ts +5 -8
- package/src/runtime/services/conversation-serializer.ts +24 -2
- package/src/runtime/sync/resource-sync-events.ts +16 -2
- package/src/runtime/sync/sync-publisher.ts +2 -2
- package/src/schedule/run-script.ts +28 -3
- package/src/schedule/schedule-store.ts +28 -1
- package/src/schedule/schedule-usage-store.ts +83 -0
- package/src/schedule/scheduler.ts +15 -6
- package/src/signals/cancel.ts +2 -4
- package/src/signals/user-message.ts +5 -8
- package/src/skills/catalog-files.ts +4 -1
- package/src/skills/catalog-install.ts +3 -0
- package/src/skills/categories-cache.ts +118 -0
- package/src/skills/clawhub-files.ts +1 -0
- package/src/skills/skillssh-files.ts +1 -0
- package/src/subagent/manager.ts +20 -11
- package/src/telemetry/types.ts +55 -1
- package/src/telemetry/usage-telemetry-reporter.test.ts +250 -4
- package/src/telemetry/usage-telemetry-reporter.ts +88 -2
- package/src/tools/acp/context.ts +20 -0
- package/src/tools/acp/list-agents.test.ts +7 -1
- package/src/tools/acp/spawn.test.ts +198 -93
- package/src/tools/acp/spawn.ts +32 -70
- package/src/tools/acp/steer.test.ts +105 -8
- package/src/tools/acp/steer.ts +48 -17
- package/src/tools/apps/definitions.ts +8 -4
- package/src/tools/apps/executors.ts +13 -8
- package/src/tools/ask-question/ask-question-tool.test.ts +120 -105
- package/src/tools/ask-question/ask-question-tool.ts +85 -90
- package/src/tools/computer-use/definitions.ts +28 -24
- package/src/tools/credential-execution/make-authenticated-request.ts +56 -51
- package/src/tools/credential-execution/manage-secure-command-tool.ts +2 -2
- package/src/tools/credential-execution/run-authenticated-command.ts +82 -77
- package/src/tools/credentials/vault.ts +112 -111
- package/src/tools/execution-target.ts +1 -1
- package/src/tools/execution-timeout.ts +3 -4
- package/src/tools/executor.ts +1 -53
- package/src/tools/filesystem/edit.ts +45 -42
- package/src/tools/filesystem/list.ts +33 -30
- package/src/tools/filesystem/read.ts +54 -35
- package/src/tools/filesystem/write.ts +69 -32
- package/src/tools/host-filesystem/edit.ts +44 -42
- package/src/tools/host-filesystem/read.ts +49 -35
- package/src/tools/host-filesystem/transfer.ts +121 -108
- package/src/tools/host-filesystem/write.ts +33 -31
- package/src/tools/host-terminal/host-shell.ts +50 -48
- package/src/tools/memory/register.ts +23 -24
- package/src/tools/network/__tests__/web-search-metadata.test.ts +7 -1
- package/src/tools/network/__tests__/web-search.test.ts +11 -3
- package/src/tools/network/web-fetch.ts +49 -46
- package/src/tools/network/web-search-error.test.ts +248 -0
- package/src/tools/network/web-search-error.ts +267 -0
- package/src/tools/network/web-search.ts +223 -61
- package/src/tools/registry.ts +39 -16
- package/src/tools/schedule/create.ts +13 -0
- package/src/tools/schedule/update.ts +16 -0
- package/src/tools/shared/filesystem/audio-read.ts +122 -0
- package/src/tools/shared/filesystem/image-read.ts +1 -1
- package/src/tools/skills/execute.ts +34 -31
- package/src/tools/skills/load.ts +29 -23
- package/src/tools/subagent/notify-parent.ts +35 -32
- package/src/tools/subagent/spawn.ts +2 -4
- package/src/tools/system/avatar-generator.ts +13 -22
- package/src/tools/system/request-permission.ts +30 -27
- package/src/tools/terminal/safe-env.ts +10 -1
- package/src/tools/terminal/shell.ts +190 -61
- package/src/tools/tool-defaults.ts +20 -9
- package/src/tools/tool-manifest.ts +4 -4
- package/src/tools/types.ts +74 -23
- package/src/tools/ui-surface/definitions.ts +99 -10
- package/src/tts/__tests__/provider-catalog-consistency.test.ts +85 -1
- package/src/tts/provider-catalog.ts +76 -1
- package/src/usage/types.ts +10 -0
- package/src/util/errors.ts +2 -2
- package/src/util/map-limit.ts +27 -0
- package/src/util/mutex.ts +47 -0
- package/src/util/platform.ts +15 -12
- package/src/work-items/work-item-runner.ts +7 -2
- package/src/workspace/git-service.ts +1 -42
- package/src/workspace/migrations/028-recover-conversations-from-disk-view.ts +7 -20
- package/src/workspace/migrations/092-backfill-v3-leaves.ts +169 -0
- package/src/workspace/migrations/093-backfill-leaf-ids.ts +144 -0
- package/src/workspace/migrations/094-seed-avatar-manifest.ts +155 -0
- package/src/workspace/migrations/095-bump-heartbeat-interval-30m-to-60m.ts +51 -0
- package/src/workspace/migrations/096-reduce-quality-profile-effort.ts +72 -0
- package/src/workspace/migrations/097-enable-adaptive-thinking-managed-profiles.ts +117 -0
- package/src/workspace/migrations/__tests__/094-seed-avatar-manifest.test.ts +136 -0
- package/src/workspace/migrations/__tests__/backfill-leaf-ids.test.ts +175 -0
- package/src/workspace/migrations/__tests__/backfill-v3-leaves.test.ts +124 -0
- package/src/workspace/migrations/registry.ts +12 -0
- package/src/workspace/provider-commit-message-generator.ts +15 -17
- package/tsconfig.json +4 -1
- package/src/__tests__/bootstrap-turn-cleanup.test.ts +0 -44
- package/src/__tests__/circuit-breaker-pipeline.test.ts +0 -405
- package/src/__tests__/compaction-pipeline.test.ts +0 -210
- package/src/__tests__/compaction-timeout-recovery.test.ts +0 -262
- package/src/__tests__/empty-response-pipeline.test.ts +0 -301
- package/src/__tests__/history-repair-pipeline.test.ts +0 -396
- package/src/__tests__/llm-call-pipeline.test.ts +0 -281
- package/src/__tests__/memory-retrieval-pipeline.test.ts +0 -418
- package/src/__tests__/persistence-pipeline.test.ts +0 -514
- package/src/__tests__/title-generate-pipeline.test.ts +0 -211
- package/src/__tests__/token-estimate-pipeline.test.ts +0 -481
- package/src/__tests__/tool-error-pipeline.test.ts +0 -241
- package/src/__tests__/tool-execute-pipeline.test.ts +0 -417
- package/src/__tests__/tool-result-truncate-pipeline.test.ts +0 -344
- package/src/cli/commands/__tests__/memory-v3-render.test.ts +0 -340
- package/src/cli/commands/memory-v3-render.ts +0 -491
- package/src/daemon/bootstrap-turn-cleanup.ts +0 -45
- package/src/daemon/message-types/disk-pressure.ts +0 -9
- package/src/email/feature-gate.ts +0 -23
- package/src/gallery/default-gallery.ts +0 -1359
- package/src/gallery/gallery-manifest.ts +0 -28
- package/src/memory/v3/__tests__/coactivation-store.test.ts +0 -422
- package/src/memory/v3/__tests__/consolidation-job.test.ts +0 -466
- package/src/memory/v3/__tests__/coretrieval-seed.test.ts +0 -270
- package/src/memory/v3/__tests__/edge-learning-job.test.ts +0 -324
- package/src/memory/v3/__tests__/edges.test.ts +0 -706
- package/src/memory/v3/__tests__/filter.test.ts +0 -560
- package/src/memory/v3/__tests__/gate.test.ts +0 -637
- package/src/memory/v3/__tests__/index-composition.test.ts +0 -291
- package/src/memory/v3/__tests__/loop.test.ts +0 -775
- package/src/memory/v3/__tests__/retriever.test.ts +0 -226
- package/src/memory/v3/__tests__/scouts.test.ts +0 -489
- package/src/memory/v3/__tests__/shadow-diff.test.ts +0 -225
- package/src/memory/v3/__tests__/shadow-middleware.test.ts +0 -398
- package/src/memory/v3/__tests__/system-prompts.test.ts +0 -154
- package/src/memory/v3/__tests__/traversal.test.ts +0 -508
- package/src/memory/v3/__tests__/tree-index.test.ts +0 -280
- package/src/memory/v3/__tests__/tree-store.test.ts +0 -529
- package/src/memory/v3/__tests__/tree-walk.test.ts +0 -784
- package/src/memory/v3/__tests__/validate.test.ts +0 -277
- package/src/memory/v3/auto-edges.ts +0 -223
- package/src/memory/v3/coactivation-store.ts +0 -124
- package/src/memory/v3/consolidation-job.ts +0 -323
- package/src/memory/v3/coretrieval-seed.ts +0 -240
- package/src/memory/v3/edge-learning-job.ts +0 -160
- package/src/memory/v3/edges.ts +0 -286
- package/src/memory/v3/filter.ts +0 -286
- package/src/memory/v3/gate.ts +0 -349
- package/src/memory/v3/index-composition.ts +0 -126
- package/src/memory/v3/llm-capture.ts +0 -46
- package/src/memory/v3/loop.ts +0 -430
- package/src/memory/v3/maintenance.ts +0 -144
- package/src/memory/v3/prompt-context.ts +0 -33
- package/src/memory/v3/prompts/consolidation.ts +0 -458
- package/src/memory/v3/prompts/system-prompts.ts +0 -196
- package/src/memory/v3/retriever.ts +0 -33
- package/src/memory/v3/scouts.ts +0 -431
- package/src/memory/v3/shadow-diff.ts +0 -287
- package/src/memory/v3/shadow-middleware.ts +0 -347
- package/src/memory/v3/traversal.ts +0 -211
- package/src/memory/v3/tree-index.ts +0 -237
- package/src/memory/v3/tree-store.ts +0 -394
- package/src/memory/v3/tree-walk.ts +0 -356
- package/src/memory/v3/types.ts +0 -65
- package/src/memory/v3/validate.ts +0 -323
- package/src/plugins/defaults/circuit-breaker.ts +0 -141
- package/src/plugins/defaults/compaction.ts +0 -141
- package/src/plugins/defaults/empty-response.ts +0 -124
- package/src/plugins/defaults/history-repair.ts +0 -83
- package/src/plugins/defaults/llm-call.ts +0 -77
- package/src/plugins/defaults/memory-retrieval.ts +0 -219
- package/src/plugins/defaults/overflow-reduce.ts +0 -185
- package/src/plugins/defaults/persistence.ts +0 -146
- package/src/plugins/defaults/title-generate.ts +0 -90
- package/src/plugins/defaults/token-estimate.ts +0 -101
- package/src/plugins/defaults/tool-error.ts +0 -119
- package/src/plugins/defaults/tool-execute.ts +0 -87
- package/src/plugins/defaults/tool-result-truncate.ts +0 -84
- package/src/runtime/routes/__tests__/memory-v3-simulate-params.test.ts +0 -35
- package/src/skills/category-inference.ts +0 -111
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { mkdirSync, rmSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test";
|
|
2
4
|
|
|
3
5
|
// This test exercises v1 PKB injection. `config.memory.v2.enabled` (default
|
|
4
6
|
// `true`) makes the PKB injector go silent — force it off here so the v1
|
|
@@ -33,6 +35,10 @@ mock.module("../memory/pkb/pkb-search.js", () => ({
|
|
|
33
35
|
},
|
|
34
36
|
}));
|
|
35
37
|
|
|
38
|
+
import {
|
|
39
|
+
clearConversations,
|
|
40
|
+
setConversation,
|
|
41
|
+
} from "../daemon/conversation-registry.js";
|
|
36
42
|
import type {
|
|
37
43
|
ChannelCapabilities,
|
|
38
44
|
SlackTranscriptInputRow,
|
|
@@ -44,7 +50,6 @@ import {
|
|
|
44
50
|
assembleSlackChronologicalMessages,
|
|
45
51
|
buildSubagentStatusBlock,
|
|
46
52
|
buildUnifiedTurnContextBlock,
|
|
47
|
-
findLastInjectedNowContent,
|
|
48
53
|
getSlackCompactionWatermarkForPrefix,
|
|
49
54
|
injectChannelCapabilityContext,
|
|
50
55
|
injectChannelCommandContext,
|
|
@@ -58,31 +63,102 @@ import {
|
|
|
58
63
|
stripInjectionsForCompaction,
|
|
59
64
|
stripNowScratchpad,
|
|
60
65
|
} from "../daemon/conversation-runtime-assembly.js";
|
|
66
|
+
import type { SurfaceData, SurfaceType } from "../daemon/message-protocol.js";
|
|
61
67
|
import { buildPkbReminder } from "../daemon/pkb-reminder-builder.js";
|
|
62
68
|
import type { MessageRow } from "../memory/conversation-crud.js";
|
|
69
|
+
import { ConversationGraphMemory } from "../memory/graph/conversation-graph-memory.js";
|
|
70
|
+
import { getPkbRoot } from "../memory/pkb/types.js";
|
|
63
71
|
import {
|
|
64
72
|
type SlackMessageMetadata,
|
|
65
73
|
writeSlackMetadata,
|
|
66
74
|
} from "../messaging/providers/slack/message-metadata.js";
|
|
67
75
|
import { parentAlias } from "../messaging/providers/slack/render-transcript.js";
|
|
68
|
-
import { defaultInjectorsPlugin } from "../plugins/defaults/injectors.js";
|
|
69
|
-
import {
|
|
70
|
-
registerPlugin,
|
|
71
|
-
resetPluginRegistryForTests,
|
|
72
|
-
} from "../plugins/registry.js";
|
|
73
76
|
import type { Message } from "../providers/types.js";
|
|
74
77
|
import { wrapUntrustedContent } from "../security/untrusted-content.js";
|
|
75
78
|
import type { SubagentState } from "../subagent/types.js";
|
|
79
|
+
import { getWorkspacePromptPath } from "../util/platform.js";
|
|
80
|
+
|
|
81
|
+
// The pkb-reminder injector derives PKB-active state from the workspace itself
|
|
82
|
+
// — `readPkbContext()` returning content behind the personal-memory trust gate
|
|
83
|
+
// — rather than from a threaded flag. Tests that need the reminder to fire seed
|
|
84
|
+
// a default auto-injected PKB file under the workspace pkb root; tests that
|
|
85
|
+
// need it suppressed leave the pkb dir empty.
|
|
86
|
+
function seedPkbContent(): void {
|
|
87
|
+
const root = getPkbRoot();
|
|
88
|
+
mkdirSync(root, { recursive: true });
|
|
89
|
+
writeFileSync(join(root, "INDEX.md"), "workspace knowledge index", "utf-8");
|
|
90
|
+
}
|
|
76
91
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
//
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
92
|
+
function clearPkbContent(): void {
|
|
93
|
+
rmSync(getPkbRoot(), { recursive: true, force: true });
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// The now-md injector derives NOW.md state from the workspace itself —
|
|
97
|
+
// `readNowScratchpad()` returning content behind the personal-memory trust gate
|
|
98
|
+
// and the `scratchpadInjection` config toggle — rather than from a threaded
|
|
99
|
+
// option. Seed the file so the injector fires; clear it so suites that assert
|
|
100
|
+
// NOW.md is absent stay unaffected.
|
|
101
|
+
function seedNowScratchpad(content: string): void {
|
|
102
|
+
const nowPath = getWorkspacePromptPath("NOW.md");
|
|
103
|
+
mkdirSync(dirname(nowPath), { recursive: true });
|
|
104
|
+
writeFileSync(nowPath, content, "utf-8");
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function clearNowScratchpad(): void {
|
|
108
|
+
rmSync(getWorkspacePromptPath("NOW.md"), { force: true });
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// The workspace-context injector sources its block off the live `Conversation`
|
|
112
|
+
// looked up by `conversationId`. Register a fake instance carrying both a
|
|
113
|
+
// non-dirty workspace context (non-null content, not dirty) so
|
|
114
|
+
// `resolveWorkspaceTopLevelContext` returns it verbatim without rescanning the
|
|
115
|
+
// filesystem, and an active dynamic-page surface, so `applyRuntimeInjections`
|
|
116
|
+
// resolves the `<workspace>` and `<active_workspace>` blocks from it;
|
|
117
|
+
// `clearConversations()` between tests keeps suites that assert the blocks are
|
|
118
|
+
// absent unaffected.
|
|
119
|
+
function seedActiveSurfaceConversation(
|
|
120
|
+
conversationId: string,
|
|
121
|
+
workspaceText: string,
|
|
122
|
+
surfaceId: string,
|
|
123
|
+
data: SurfaceData,
|
|
124
|
+
channelCapabilities?: ChannelCapabilities,
|
|
125
|
+
): void {
|
|
126
|
+
setConversation(conversationId, {
|
|
127
|
+
conversationId,
|
|
128
|
+
workingDir: "/sandbox",
|
|
129
|
+
workspaceTopLevelContext: workspaceText,
|
|
130
|
+
workspaceTopLevelDirty: false,
|
|
131
|
+
currentActiveSurfaceId: surfaceId,
|
|
132
|
+
surfaceState: new Map<
|
|
133
|
+
string,
|
|
134
|
+
{ surfaceType: SurfaceType; data: SurfaceData }
|
|
135
|
+
>([[surfaceId, { surfaceType: "dynamic_page", data }]]),
|
|
136
|
+
channelCapabilities: channelCapabilities ?? undefined,
|
|
137
|
+
} as never);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function clearWorkspaceContext(): void {
|
|
141
|
+
clearConversations();
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// The `<channel_capabilities>` branch and the Slack gates source the channel
|
|
145
|
+
// capabilities off the live `Conversation` looked up by `conversationId`.
|
|
146
|
+
// Register a fake fallback instance carrying the given capabilities (and a
|
|
147
|
+
// non-dirty empty workspace + empty surface so the other live-sourced branches
|
|
148
|
+
// stay inert) so `applyRuntimeInjections` resolves them; `clearConversations()`
|
|
149
|
+
// between tests keeps suites asserting absence unaffected.
|
|
150
|
+
function seedChannelCapabilitiesConversation(
|
|
151
|
+
caps: ChannelCapabilities | null,
|
|
152
|
+
): void {
|
|
153
|
+
setConversation("runtime-assembly-fallback", {
|
|
154
|
+
conversationId: "runtime-assembly-fallback",
|
|
155
|
+
workingDir: "/sandbox",
|
|
156
|
+
workspaceTopLevelContext: "",
|
|
157
|
+
workspaceTopLevelDirty: false,
|
|
158
|
+
surfaceState: new Map(),
|
|
159
|
+
channelCapabilities: caps ?? undefined,
|
|
160
|
+
} as never);
|
|
161
|
+
}
|
|
86
162
|
|
|
87
163
|
// ---------------------------------------------------------------------------
|
|
88
164
|
// resolveChannelCapabilities
|
|
@@ -556,6 +632,8 @@ describe("stripChannelCapabilityContext", () => {
|
|
|
556
632
|
// ---------------------------------------------------------------------------
|
|
557
633
|
|
|
558
634
|
describe("applyRuntimeInjections with channelCapabilities", () => {
|
|
635
|
+
afterEach(clearConversations);
|
|
636
|
+
|
|
559
637
|
const baseMessages: Message[] = [
|
|
560
638
|
{
|
|
561
639
|
role: "user",
|
|
@@ -571,9 +649,8 @@ describe("applyRuntimeInjections with channelCapabilities", () => {
|
|
|
571
649
|
supportsVoiceInput: false,
|
|
572
650
|
};
|
|
573
651
|
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
});
|
|
652
|
+
seedChannelCapabilitiesConversation(caps);
|
|
653
|
+
const { messages: result } = await applyRuntimeInjections(baseMessages, {});
|
|
577
654
|
|
|
578
655
|
expect(result.length).toBe(1);
|
|
579
656
|
expect(result[0].content.length).toBe(2);
|
|
@@ -584,9 +661,8 @@ describe("applyRuntimeInjections with channelCapabilities", () => {
|
|
|
584
661
|
});
|
|
585
662
|
|
|
586
663
|
test("does not inject when channelCapabilities is null", async () => {
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
});
|
|
664
|
+
seedChannelCapabilitiesConversation(null);
|
|
665
|
+
const { messages: result } = await applyRuntimeInjections(baseMessages, {});
|
|
590
666
|
|
|
591
667
|
expect(result.length).toBe(1);
|
|
592
668
|
expect(result[0].content.length).toBe(1);
|
|
@@ -607,9 +683,8 @@ describe("applyRuntimeInjections with channelCapabilities", () => {
|
|
|
607
683
|
supportsVoiceInput: false,
|
|
608
684
|
};
|
|
609
685
|
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
});
|
|
686
|
+
seedChannelCapabilitiesConversation(caps);
|
|
687
|
+
const { messages: result } = await applyRuntimeInjections(baseMessages, {});
|
|
613
688
|
|
|
614
689
|
expect(result.length).toBe(1);
|
|
615
690
|
// channelCapabilities prepends
|
|
@@ -736,24 +811,52 @@ describe("applyRuntimeInjections — injection mode", () => {
|
|
|
736
811
|
},
|
|
737
812
|
];
|
|
738
813
|
|
|
814
|
+
const channelCapabilities: ChannelCapabilities = {
|
|
815
|
+
channel: "telegram",
|
|
816
|
+
dashboardCapable: false,
|
|
817
|
+
supportsDynamicUi: false,
|
|
818
|
+
supportsVoiceInput: false,
|
|
819
|
+
};
|
|
820
|
+
|
|
739
821
|
const fullOptions = {
|
|
740
|
-
workspaceTopLevelContext: "<workspace>\nRoot: /sandbox\n</workspace>",
|
|
741
822
|
channelCommandContext: { type: "start" } as const,
|
|
742
|
-
activeSurface: { surfaceId: "sf_1", html: "<div>test</div>" },
|
|
743
|
-
channelCapabilities: {
|
|
744
|
-
channel: "telegram",
|
|
745
|
-
dashboardCapable: false,
|
|
746
|
-
supportsDynamicUi: false,
|
|
747
|
-
supportsVoiceInput: false,
|
|
748
|
-
} as ChannelCapabilities,
|
|
749
823
|
unifiedTurnContext:
|
|
750
824
|
"<turn_context>\ncurrent_time: 2026-03-04 (Tuesday) 12:00:00 +00:00 (UTC)\ninterface: telegram\n</turn_context>",
|
|
751
|
-
nowScratchpad: "Current focus: shipping PR 3",
|
|
752
|
-
pkbContext: "essentials content here",
|
|
753
|
-
pkbActive: true,
|
|
754
825
|
isNonInteractive: true,
|
|
826
|
+
// Guardian trust so the personal-memory gate admits the actor regardless
|
|
827
|
+
// of the telegram channel capabilities under test, letting the reminder
|
|
828
|
+
// gate hinge purely on PKB content presence.
|
|
829
|
+
turnContext: {
|
|
830
|
+
requestId: "injection-mode-req",
|
|
831
|
+
conversationId: "injection-mode-conv",
|
|
832
|
+
turnIndex: 0,
|
|
833
|
+
trust: {
|
|
834
|
+
sourceChannel: "vellum" as const,
|
|
835
|
+
trustClass: "guardian" as const,
|
|
836
|
+
},
|
|
837
|
+
},
|
|
755
838
|
};
|
|
756
839
|
|
|
840
|
+
// The reminder fires only when the workspace has PKB content, and the now-md
|
|
841
|
+
// injector only when NOW.md has content; seed both so the full-mode cases
|
|
842
|
+
// exercise the active branch.
|
|
843
|
+
beforeEach(() => {
|
|
844
|
+
seedPkbContent();
|
|
845
|
+
seedNowScratchpad("Current focus: shipping PR 3");
|
|
846
|
+
seedActiveSurfaceConversation(
|
|
847
|
+
"injection-mode-conv",
|
|
848
|
+
"<workspace>\nRoot: /sandbox\n</workspace>",
|
|
849
|
+
"sf_1",
|
|
850
|
+
{ html: "<div>test</div>" },
|
|
851
|
+
channelCapabilities,
|
|
852
|
+
);
|
|
853
|
+
});
|
|
854
|
+
afterEach(() => {
|
|
855
|
+
clearPkbContent();
|
|
856
|
+
clearNowScratchpad();
|
|
857
|
+
clearWorkspaceContext();
|
|
858
|
+
});
|
|
859
|
+
|
|
757
860
|
test("full mode (default) includes all injections", async () => {
|
|
758
861
|
const { messages: result } = await applyRuntimeInjections(
|
|
759
862
|
baseMessages,
|
|
@@ -860,12 +963,10 @@ describe("applyRuntimeInjections — injection mode", () => {
|
|
|
860
963
|
});
|
|
861
964
|
});
|
|
862
965
|
|
|
863
|
-
// The
|
|
864
|
-
//
|
|
865
|
-
//
|
|
866
|
-
//
|
|
867
|
-
// nowScratchpad` and the injection-mode tests) cover that behaviour
|
|
868
|
-
// end-to-end.
|
|
966
|
+
// The now-md default injector emits the `<NOW.md>` block as an
|
|
967
|
+
// `after-memory-prefix` placement during `applyRuntimeInjections`. The suites
|
|
968
|
+
// below (`applyRuntimeInjections with nowScratchpad` and the injection-mode
|
|
969
|
+
// tests) cover that behaviour end-to-end.
|
|
869
970
|
|
|
870
971
|
// ---------------------------------------------------------------------------
|
|
871
972
|
// stripNowScratchpad
|
|
@@ -1013,7 +1114,7 @@ describe("stripInjectionsForCompaction preserves persistent blocks", () => {
|
|
|
1013
1114
|
).toContain("<turn_context>");
|
|
1014
1115
|
});
|
|
1015
1116
|
|
|
1016
|
-
test("<workspace> blocks
|
|
1117
|
+
test("<workspace> blocks ARE stripped so the injector re-sources them post-compaction", () => {
|
|
1017
1118
|
const messages: Message[] = [
|
|
1018
1119
|
{
|
|
1019
1120
|
role: "user",
|
|
@@ -1029,10 +1130,10 @@ describe("stripInjectionsForCompaction preserves persistent blocks", () => {
|
|
|
1029
1130
|
|
|
1030
1131
|
const result = stripInjectionsForCompaction(messages);
|
|
1031
1132
|
expect(result.length).toBe(1);
|
|
1032
|
-
expect(result[0].content.length).toBe(
|
|
1033
|
-
expect(
|
|
1034
|
-
|
|
1035
|
-
)
|
|
1133
|
+
expect(result[0].content.length).toBe(1);
|
|
1134
|
+
expect((result[0].content[0] as { type: "text"; text: string }).text).toBe(
|
|
1135
|
+
"Hello",
|
|
1136
|
+
);
|
|
1036
1137
|
});
|
|
1037
1138
|
|
|
1038
1139
|
test("legacy <workspace_top_level> blocks ARE stripped for backward compat", () => {
|
|
@@ -1192,10 +1293,14 @@ describe("applyRuntimeInjections with nowScratchpad", () => {
|
|
|
1192
1293
|
},
|
|
1193
1294
|
];
|
|
1194
1295
|
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1296
|
+
// The now-md injector sources NOW.md from the workspace itself rather than
|
|
1297
|
+
// from a threaded option, so seed the file to drive injection and clear it so
|
|
1298
|
+
// the absent-content cases see no block.
|
|
1299
|
+
afterEach(clearNowScratchpad);
|
|
1300
|
+
|
|
1301
|
+
test("injects NOW.md block when the file has content", async () => {
|
|
1302
|
+
seedNowScratchpad("Current focus: fix the bug");
|
|
1303
|
+
const { messages: result } = await applyRuntimeInjections(baseMessages, {});
|
|
1199
1304
|
|
|
1200
1305
|
expect(result.length).toBe(1);
|
|
1201
1306
|
expect(result[0].content.length).toBe(2);
|
|
@@ -1206,9 +1311,8 @@ describe("applyRuntimeInjections with nowScratchpad", () => {
|
|
|
1206
1311
|
});
|
|
1207
1312
|
|
|
1208
1313
|
test("scratchpad appears before user's original text content", async () => {
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
});
|
|
1314
|
+
seedNowScratchpad("scratchpad notes");
|
|
1315
|
+
const { messages: result } = await applyRuntimeInjections(baseMessages, {});
|
|
1212
1316
|
|
|
1213
1317
|
// Scratchpad comes first (before user content)
|
|
1214
1318
|
expect(
|
|
@@ -1220,16 +1324,7 @@ describe("applyRuntimeInjections with nowScratchpad", () => {
|
|
|
1220
1324
|
);
|
|
1221
1325
|
});
|
|
1222
1326
|
|
|
1223
|
-
test("does not inject when
|
|
1224
|
-
const { messages: result } = await applyRuntimeInjections(baseMessages, {
|
|
1225
|
-
nowScratchpad: null,
|
|
1226
|
-
});
|
|
1227
|
-
|
|
1228
|
-
expect(result.length).toBe(1);
|
|
1229
|
-
expect(result[0].content.length).toBe(1);
|
|
1230
|
-
});
|
|
1231
|
-
|
|
1232
|
-
test("does not inject when nowScratchpad is omitted", async () => {
|
|
1327
|
+
test("does not inject when the NOW.md file is absent", async () => {
|
|
1233
1328
|
const { messages: result } = await applyRuntimeInjections(baseMessages, {});
|
|
1234
1329
|
|
|
1235
1330
|
expect(result.length).toBe(1);
|
|
@@ -1237,8 +1332,8 @@ describe("applyRuntimeInjections with nowScratchpad", () => {
|
|
|
1237
1332
|
});
|
|
1238
1333
|
|
|
1239
1334
|
test("skipped in minimal mode", async () => {
|
|
1335
|
+
seedNowScratchpad("Current focus: fix the bug");
|
|
1240
1336
|
const { messages: result } = await applyRuntimeInjections(baseMessages, {
|
|
1241
|
-
nowScratchpad: "Current focus: fix the bug",
|
|
1242
1337
|
mode: "minimal",
|
|
1243
1338
|
});
|
|
1244
1339
|
|
|
@@ -1782,85 +1877,6 @@ describe("applyRuntimeInjections blocks.unifiedTurnContext", () => {
|
|
|
1782
1877
|
});
|
|
1783
1878
|
});
|
|
1784
1879
|
|
|
1785
|
-
// ---------------------------------------------------------------------------
|
|
1786
|
-
// findLastInjectedNowContent
|
|
1787
|
-
// ---------------------------------------------------------------------------
|
|
1788
|
-
|
|
1789
|
-
describe("findLastInjectedNowContent", () => {
|
|
1790
|
-
test("extracts NOW.md content from the last user message", () => {
|
|
1791
|
-
const messages: Message[] = [
|
|
1792
|
-
{
|
|
1793
|
-
role: "user",
|
|
1794
|
-
content: [
|
|
1795
|
-
{
|
|
1796
|
-
type: "text",
|
|
1797
|
-
text: "<NOW.md Always keep this up to date>\nCurrent focus: fix the bug\n</NOW.md>",
|
|
1798
|
-
},
|
|
1799
|
-
{ type: "text", text: "Hello" },
|
|
1800
|
-
],
|
|
1801
|
-
},
|
|
1802
|
-
];
|
|
1803
|
-
|
|
1804
|
-
expect(findLastInjectedNowContent(messages)).toBe(
|
|
1805
|
-
"Current focus: fix the bug",
|
|
1806
|
-
);
|
|
1807
|
-
});
|
|
1808
|
-
|
|
1809
|
-
test("returns null when no NOW.md injection exists", () => {
|
|
1810
|
-
const messages: Message[] = [
|
|
1811
|
-
{
|
|
1812
|
-
role: "user",
|
|
1813
|
-
content: [{ type: "text", text: "Hello" }],
|
|
1814
|
-
},
|
|
1815
|
-
];
|
|
1816
|
-
|
|
1817
|
-
expect(findLastInjectedNowContent(messages)).toBeNull();
|
|
1818
|
-
});
|
|
1819
|
-
|
|
1820
|
-
test("returns the most recent injection when multiple exist", () => {
|
|
1821
|
-
const messages: Message[] = [
|
|
1822
|
-
{
|
|
1823
|
-
role: "user",
|
|
1824
|
-
content: [
|
|
1825
|
-
{
|
|
1826
|
-
type: "text",
|
|
1827
|
-
text: "<NOW.md Always keep this up to date>\nOld focus\n</NOW.md>",
|
|
1828
|
-
},
|
|
1829
|
-
],
|
|
1830
|
-
},
|
|
1831
|
-
{ role: "assistant", content: [{ type: "text", text: "OK" }] },
|
|
1832
|
-
{
|
|
1833
|
-
role: "user",
|
|
1834
|
-
content: [
|
|
1835
|
-
{
|
|
1836
|
-
type: "text",
|
|
1837
|
-
text: "<NOW.md Always keep this up to date>\nNew focus\n</NOW.md>",
|
|
1838
|
-
},
|
|
1839
|
-
],
|
|
1840
|
-
},
|
|
1841
|
-
];
|
|
1842
|
-
|
|
1843
|
-
expect(findLastInjectedNowContent(messages)).toBe("New focus");
|
|
1844
|
-
});
|
|
1845
|
-
|
|
1846
|
-
test("skips assistant messages", () => {
|
|
1847
|
-
const messages: Message[] = [
|
|
1848
|
-
{
|
|
1849
|
-
role: "user",
|
|
1850
|
-
content: [
|
|
1851
|
-
{
|
|
1852
|
-
type: "text",
|
|
1853
|
-
text: "<NOW.md Always keep this up to date>\nUser focus\n</NOW.md>",
|
|
1854
|
-
},
|
|
1855
|
-
],
|
|
1856
|
-
},
|
|
1857
|
-
{ role: "assistant", content: [{ type: "text", text: "response" }] },
|
|
1858
|
-
];
|
|
1859
|
-
|
|
1860
|
-
expect(findLastInjectedNowContent(messages)).toBe("User focus");
|
|
1861
|
-
});
|
|
1862
|
-
});
|
|
1863
|
-
|
|
1864
1880
|
// ---------------------------------------------------------------------------
|
|
1865
1881
|
// Subagent status injection
|
|
1866
1882
|
// ---------------------------------------------------------------------------
|
|
@@ -2032,21 +2048,33 @@ describe("applyRuntimeInjections — PKB relevance hints", () => {
|
|
|
2032
2048
|
|
|
2033
2049
|
const FLAT_REMINDER = buildPkbReminder([]);
|
|
2034
2050
|
|
|
2035
|
-
//
|
|
2036
|
-
//
|
|
2037
|
-
//
|
|
2038
|
-
const
|
|
2039
|
-
|
|
2051
|
+
// The pkb-reminder injector sources the PKB root itself via `getPkbRoot()`,
|
|
2052
|
+
// so the in-context file paths these tests build must resolve against the
|
|
2053
|
+
// same per-test workspace the injector sees.
|
|
2054
|
+
const pkbRoot = getPkbRoot();
|
|
2055
|
+
|
|
2056
|
+
// The pkb-reminder injector reads the dense/sparse PKB query pair off the
|
|
2057
|
+
// conversation's live graph handle (the memory-retrieval hook records it
|
|
2058
|
+
// there during retrieval), not from the injection options. Register a handle
|
|
2059
|
+
// for the fallback conversation id `applyRuntimeInjections` synthesizes and
|
|
2060
|
+
// seed it with a query vector so the hint-search branch runs.
|
|
2061
|
+
let graphHandle: ConversationGraphMemory;
|
|
2062
|
+
beforeEach(() => {
|
|
2063
|
+
graphHandle = new ConversationGraphMemory("runtime-assembly-fallback");
|
|
2064
|
+
graphHandle.recordPkbQueryVectors([0.1, 0.2, 0.3], undefined);
|
|
2065
|
+
});
|
|
2066
|
+
afterEach(() => {
|
|
2067
|
+
graphHandle.dispose();
|
|
2068
|
+
});
|
|
2069
|
+
|
|
2070
|
+
// PKB content makes `readPkbContext()` non-null so the (vellum/guardian-
|
|
2071
|
+
// equivalent) fallback trust gate admits the reminder; cleared after each
|
|
2072
|
+
// test to avoid leaking into suites that assert the reminder is absent.
|
|
2073
|
+
beforeEach(seedPkbContent);
|
|
2074
|
+
afterEach(clearPkbContent);
|
|
2040
2075
|
|
|
2041
2076
|
function makePkbOptions(overrides: Record<string, unknown> = {}) {
|
|
2042
2077
|
return {
|
|
2043
|
-
pkbActive: true,
|
|
2044
|
-
pkbQueryVector: [0.1, 0.2, 0.3],
|
|
2045
|
-
pkbScopeId: "scope-1",
|
|
2046
|
-
pkbConversation: { messages: baseMessages },
|
|
2047
|
-
pkbRoot,
|
|
2048
|
-
pkbWorkingDir,
|
|
2049
|
-
pkbAutoInjectList: [],
|
|
2050
2078
|
...overrides,
|
|
2051
2079
|
};
|
|
2052
2080
|
}
|
|
@@ -2082,10 +2110,11 @@ describe("applyRuntimeInjections — PKB relevance hints", () => {
|
|
|
2082
2110
|
test("default auto-injected files (from PKB_DEFAULT_FILES) are filtered out of hints", async () => {
|
|
2083
2111
|
// Regression test: when `_autoinject.md` is missing, `readPkbContext`
|
|
2084
2112
|
// falls back to PKB_DEFAULT_FILES — so those files ARE in the prompt.
|
|
2085
|
-
// The
|
|
2086
|
-
//
|
|
2087
|
-
//
|
|
2088
|
-
//
|
|
2113
|
+
// The injector sources the same fallback via `getPkbAutoInjectList`, so
|
|
2114
|
+
// it must know about them too, otherwise the reminder would redundantly
|
|
2115
|
+
// recommend e.g. `essentials.md` even though its contents are already
|
|
2116
|
+
// injected. The per-test workspace has no `_autoinject.md`, so the
|
|
2117
|
+
// injector resolves PKB_DEFAULT_FILES here.
|
|
2089
2118
|
pkbSearchResults = [
|
|
2090
2119
|
{ path: "essentials.md", denseScore: 0.95 },
|
|
2091
2120
|
{ path: "topics/alpha.md", denseScore: 0.9 },
|
|
@@ -2094,16 +2123,7 @@ describe("applyRuntimeInjections — PKB relevance hints", () => {
|
|
|
2094
2123
|
|
|
2095
2124
|
const { messages: result } = await applyRuntimeInjections(
|
|
2096
2125
|
baseMessages,
|
|
2097
|
-
makePkbOptions(
|
|
2098
|
-
// Simulate the fallback the agent-loop now threads through:
|
|
2099
|
-
// `_autoinject.md` is missing, so defaults are injected.
|
|
2100
|
-
pkbAutoInjectList: [
|
|
2101
|
-
"INDEX.md",
|
|
2102
|
-
"essentials.md",
|
|
2103
|
-
"threads.md",
|
|
2104
|
-
"buffer.md",
|
|
2105
|
-
],
|
|
2106
|
-
}),
|
|
2126
|
+
makePkbOptions(),
|
|
2107
2127
|
);
|
|
2108
2128
|
const texts = extractTexts(result);
|
|
2109
2129
|
const reminder = texts.find((t) => t.startsWith("<system_reminder>"));
|
|
@@ -2143,27 +2163,26 @@ describe("applyRuntimeInjections — PKB relevance hints", () => {
|
|
|
2143
2163
|
];
|
|
2144
2164
|
pkbSearchThrows = null;
|
|
2145
2165
|
|
|
2146
|
-
//
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
};
|
|
2166
|
+
// Working messages where topics/beta.md was already read via file_read on
|
|
2167
|
+
// an earlier turn, followed by the current user prompt as the tail.
|
|
2168
|
+
const conversationWithRead: Message[] = [
|
|
2169
|
+
{
|
|
2170
|
+
role: "assistant",
|
|
2171
|
+
content: [
|
|
2172
|
+
{
|
|
2173
|
+
type: "tool_use",
|
|
2174
|
+
id: "tu_1",
|
|
2175
|
+
name: "file_read",
|
|
2176
|
+
input: { path: `${pkbRoot}/topics/beta.md` },
|
|
2177
|
+
},
|
|
2178
|
+
],
|
|
2179
|
+
},
|
|
2180
|
+
...baseMessages,
|
|
2181
|
+
];
|
|
2163
2182
|
|
|
2164
2183
|
const { messages: result } = await applyRuntimeInjections(
|
|
2165
|
-
|
|
2166
|
-
makePkbOptions(
|
|
2184
|
+
conversationWithRead,
|
|
2185
|
+
makePkbOptions(),
|
|
2167
2186
|
);
|
|
2168
2187
|
const texts = extractTexts(result);
|
|
2169
2188
|
const reminder = texts.find((t) => t.startsWith("<system_reminder>"));
|
|
@@ -2201,10 +2220,13 @@ describe("applyRuntimeInjections — PKB relevance hints", () => {
|
|
|
2201
2220
|
|
|
2202
2221
|
test("missing query vector → flat fallback, search is not attempted", async () => {
|
|
2203
2222
|
pkbSearchThrows = new Error("should not be called");
|
|
2223
|
+
// No dense vector was recorded on the graph handle this turn, so the
|
|
2224
|
+
// injector must skip the hint search entirely.
|
|
2225
|
+
graphHandle.recordPkbQueryVectors(undefined, undefined);
|
|
2204
2226
|
|
|
2205
2227
|
const { messages: result } = await applyRuntimeInjections(
|
|
2206
2228
|
baseMessages,
|
|
2207
|
-
makePkbOptions(
|
|
2229
|
+
makePkbOptions(),
|
|
2208
2230
|
);
|
|
2209
2231
|
const texts = extractTexts(result);
|
|
2210
2232
|
const reminder = texts.find((t) => t.startsWith("<system_reminder>"));
|
|
@@ -2318,37 +2340,28 @@ describe("applyRuntimeInjections — PKB relevance hints", () => {
|
|
|
2318
2340
|
];
|
|
2319
2341
|
pkbSearchThrows = null;
|
|
2320
2342
|
|
|
2321
|
-
// Pre-compaction
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
};
|
|
2343
|
+
// Pre-compaction working messages: beta was already read on an earlier
|
|
2344
|
+
// turn, followed by the current user prompt as the tail.
|
|
2345
|
+
const preCompactionMessages: Message[] = [
|
|
2346
|
+
{
|
|
2347
|
+
role: "assistant",
|
|
2348
|
+
content: [
|
|
2349
|
+
{
|
|
2350
|
+
type: "tool_use",
|
|
2351
|
+
id: "tu_pre",
|
|
2352
|
+
name: "file_read",
|
|
2353
|
+
input: { path: `${pkbRoot}/topics/beta.md` },
|
|
2354
|
+
},
|
|
2355
|
+
],
|
|
2356
|
+
},
|
|
2357
|
+
...baseMessages,
|
|
2358
|
+
];
|
|
2338
2359
|
|
|
2339
2360
|
// 1. Initial injection sees the pre-compaction state — beta should be
|
|
2340
2361
|
// filtered out.
|
|
2341
2362
|
const { messages: initialResult } = await applyRuntimeInjections(
|
|
2342
|
-
|
|
2343
|
-
{
|
|
2344
|
-
pkbActive: true,
|
|
2345
|
-
pkbQueryVector: [0.1, 0.2],
|
|
2346
|
-
pkbScopeId: "scope-1",
|
|
2347
|
-
pkbConversation: preCompactionConversation,
|
|
2348
|
-
pkbRoot,
|
|
2349
|
-
pkbWorkingDir,
|
|
2350
|
-
pkbAutoInjectList: [],
|
|
2351
|
-
},
|
|
2363
|
+
preCompactionMessages,
|
|
2364
|
+
{},
|
|
2352
2365
|
);
|
|
2353
2366
|
// Unwrap the injected reminder from the last user message.
|
|
2354
2367
|
const initialTexts = extractTexts(initialResult);
|
|
@@ -2360,41 +2373,29 @@ describe("applyRuntimeInjections — PKB relevance hints", () => {
|
|
|
2360
2373
|
expect(initialReminder).toBeDefined();
|
|
2361
2374
|
expect(initialReminder).not.toContain("- topics/beta.md");
|
|
2362
2375
|
|
|
2363
|
-
// 2.
|
|
2364
|
-
//
|
|
2365
|
-
//
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
},
|
|
2381
|
-
],
|
|
2382
|
-
};
|
|
2383
|
-
const postCompactionMessages = stripInjectionsForCompaction(initialResult);
|
|
2376
|
+
// 2. After compaction the working messages reflect the post-compaction
|
|
2377
|
+
// state: beta's tool_use was serialized into summary text and dropped,
|
|
2378
|
+
// so the only live file_read is the newly-read gamma.
|
|
2379
|
+
const postCompactionMessages: Message[] = [
|
|
2380
|
+
{
|
|
2381
|
+
role: "assistant",
|
|
2382
|
+
content: [
|
|
2383
|
+
{
|
|
2384
|
+
type: "tool_use",
|
|
2385
|
+
id: "tu_post",
|
|
2386
|
+
name: "file_read",
|
|
2387
|
+
input: { path: `${pkbRoot}/topics/gamma.md` },
|
|
2388
|
+
},
|
|
2389
|
+
],
|
|
2390
|
+
},
|
|
2391
|
+
...baseMessages,
|
|
2392
|
+
];
|
|
2384
2393
|
|
|
2385
|
-
// 3. Re-inject
|
|
2394
|
+
// 3. Re-inject over the post-compaction messages — gamma (now in context)
|
|
2386
2395
|
// should be filtered, and beta (no longer "in context") should appear.
|
|
2387
2396
|
const { messages: rebuiltResult } = await applyRuntimeInjections(
|
|
2388
2397
|
postCompactionMessages,
|
|
2389
|
-
{
|
|
2390
|
-
pkbActive: true,
|
|
2391
|
-
pkbQueryVector: [0.1, 0.2],
|
|
2392
|
-
pkbScopeId: "scope-1",
|
|
2393
|
-
pkbConversation: postCompactionConversation,
|
|
2394
|
-
pkbRoot,
|
|
2395
|
-
pkbWorkingDir,
|
|
2396
|
-
pkbAutoInjectList: [],
|
|
2397
|
-
},
|
|
2398
|
+
{},
|
|
2398
2399
|
);
|
|
2399
2400
|
const rebuiltTexts = extractTexts(rebuiltResult);
|
|
2400
2401
|
const rebuiltReminder = rebuiltTexts.find(
|
|
@@ -2414,6 +2415,8 @@ describe("applyRuntimeInjections — PKB relevance hints", () => {
|
|
|
2414
2415
|
// ---------------------------------------------------------------------------
|
|
2415
2416
|
|
|
2416
2417
|
describe("Slack channel chronological rendering — multi-thread", () => {
|
|
2418
|
+
afterEach(clearConversations);
|
|
2419
|
+
|
|
2417
2420
|
// Slack ts values are seconds-since-epoch with microsecond precision.
|
|
2418
2421
|
// Pick a few stable anchors so thread aliases (sha-derived) stay
|
|
2419
2422
|
// predictable across the scenarios.
|
|
@@ -2499,8 +2502,8 @@ describe("Slack channel chronological rendering — multi-thread", () => {
|
|
|
2499
2502
|
role: "user",
|
|
2500
2503
|
content: [{ type: "text", text: "current turn" }],
|
|
2501
2504
|
};
|
|
2505
|
+
seedChannelCapabilitiesConversation(slackChannelCaps);
|
|
2502
2506
|
const { messages } = await applyRuntimeInjections([lastUserMessage], {
|
|
2503
|
-
channelCapabilities: slackChannelCaps,
|
|
2504
2507
|
slackChronologicalMessages,
|
|
2505
2508
|
});
|
|
2506
2509
|
return messages;
|
|
@@ -2788,15 +2791,15 @@ describe("Slack channel chronological rendering — multi-thread", () => {
|
|
|
2788
2791
|
role: "user",
|
|
2789
2792
|
content: [{ type: "text", text: "vellum question" }],
|
|
2790
2793
|
};
|
|
2794
|
+
seedChannelCapabilitiesConversation({
|
|
2795
|
+
channel: "vellum",
|
|
2796
|
+
dashboardCapable: true,
|
|
2797
|
+
supportsDynamicUi: true,
|
|
2798
|
+
supportsVoiceInput: true,
|
|
2799
|
+
});
|
|
2791
2800
|
const { messages: result } = await applyRuntimeInjections(
|
|
2792
2801
|
[lastUserMessage],
|
|
2793
2802
|
{
|
|
2794
|
-
channelCapabilities: {
|
|
2795
|
-
channel: "vellum",
|
|
2796
|
-
dashboardCapable: true,
|
|
2797
|
-
supportsDynamicUi: true,
|
|
2798
|
-
supportsVoiceInput: true,
|
|
2799
|
-
},
|
|
2800
2803
|
// Even if we accidentally pass a chronological transcript, the
|
|
2801
2804
|
// branch must be a no-op for non-slack channels.
|
|
2802
2805
|
slackChronologicalMessages: [
|
|
@@ -2826,16 +2829,16 @@ describe("Slack channel chronological rendering — multi-thread", () => {
|
|
|
2826
2829
|
role: "user",
|
|
2827
2830
|
content: [{ type: "text", text: "DM question" }],
|
|
2828
2831
|
};
|
|
2832
|
+
seedChannelCapabilitiesConversation({
|
|
2833
|
+
channel: "slack",
|
|
2834
|
+
dashboardCapable: false,
|
|
2835
|
+
supportsDynamicUi: false,
|
|
2836
|
+
supportsVoiceInput: false,
|
|
2837
|
+
chatType: "im",
|
|
2838
|
+
});
|
|
2829
2839
|
const { messages: result } = await applyRuntimeInjections(
|
|
2830
2840
|
[lastUserMessage],
|
|
2831
2841
|
{
|
|
2832
|
-
channelCapabilities: {
|
|
2833
|
-
channel: "slack",
|
|
2834
|
-
dashboardCapable: false,
|
|
2835
|
-
supportsDynamicUi: false,
|
|
2836
|
-
supportsVoiceInput: false,
|
|
2837
|
-
chatType: "im",
|
|
2838
|
-
},
|
|
2839
2842
|
slackChronologicalMessages: [
|
|
2840
2843
|
{
|
|
2841
2844
|
role: "user",
|
|
@@ -2894,10 +2897,10 @@ describe("Slack channel chronological rendering — multi-thread", () => {
|
|
|
2894
2897
|
],
|
|
2895
2898
|
},
|
|
2896
2899
|
];
|
|
2900
|
+
seedChannelCapabilitiesConversation(slackCaps);
|
|
2897
2901
|
const { messages: result } = await applyRuntimeInjections(
|
|
2898
2902
|
runMessagesWithMemory,
|
|
2899
2903
|
{
|
|
2900
|
-
channelCapabilities: slackCaps,
|
|
2901
2904
|
slackChronologicalMessages: [
|
|
2902
2905
|
{
|
|
2903
2906
|
role: "user",
|
|
@@ -2958,10 +2961,10 @@ describe("Slack channel chronological rendering — multi-thread", () => {
|
|
|
2958
2961
|
],
|
|
2959
2962
|
},
|
|
2960
2963
|
];
|
|
2964
|
+
seedChannelCapabilitiesConversation(slackCaps);
|
|
2961
2965
|
const { messages: result } = await applyRuntimeInjections(
|
|
2962
2966
|
runMessagesWithMemory,
|
|
2963
2967
|
{
|
|
2964
|
-
channelCapabilities: slackCaps,
|
|
2965
2968
|
slackChronologicalMessages: [
|
|
2966
2969
|
{
|
|
2967
2970
|
role: "user",
|
|
@@ -2997,10 +3000,10 @@ describe("Slack channel chronological rendering — multi-thread", () => {
|
|
|
2997
3000
|
supportsVoiceInput: false,
|
|
2998
3001
|
chatType: "im",
|
|
2999
3002
|
};
|
|
3003
|
+
seedChannelCapabilitiesConversation(slackCaps);
|
|
3000
3004
|
const { messages: result } = await applyRuntimeInjections(
|
|
3001
3005
|
[{ role: "user", content: [{ type: "text", text: "inbound" }] }],
|
|
3002
3006
|
{
|
|
3003
|
-
channelCapabilities: slackCaps,
|
|
3004
3007
|
slackChronologicalMessages: [
|
|
3005
3008
|
{
|
|
3006
3009
|
role: "user",
|
|
@@ -3041,10 +3044,10 @@ describe("Slack channel chronological rendering — multi-thread", () => {
|
|
|
3041
3044
|
{ loader: () => rows, trustClass: "guardian" },
|
|
3042
3045
|
);
|
|
3043
3046
|
|
|
3047
|
+
seedChannelCapabilitiesConversation(slackChannelCaps);
|
|
3044
3048
|
const { messages: result } = await applyRuntimeInjections(
|
|
3045
3049
|
[{ role: "user", content: [{ type: "text", text: "current turn" }] }],
|
|
3046
3050
|
{
|
|
3047
|
-
channelCapabilities: slackChannelCaps,
|
|
3048
3051
|
slackChronologicalMessages,
|
|
3049
3052
|
transportHints: ["thread context: ..."],
|
|
3050
3053
|
},
|
|
@@ -3071,10 +3074,10 @@ describe("Slack channel chronological rendering — multi-thread", () => {
|
|
|
3071
3074
|
chatType: "im",
|
|
3072
3075
|
};
|
|
3073
3076
|
|
|
3077
|
+
seedChannelCapabilitiesConversation(slackDmCaps);
|
|
3074
3078
|
const { messages: result } = await applyRuntimeInjections(
|
|
3075
3079
|
[{ role: "user", content: [{ type: "text", text: "hi DM" }] }],
|
|
3076
3080
|
{
|
|
3077
|
-
channelCapabilities: slackDmCaps,
|
|
3078
3081
|
transportHints: ["dm context: ..."],
|
|
3079
3082
|
},
|
|
3080
3083
|
);
|
|
@@ -3090,16 +3093,16 @@ describe("Slack channel chronological rendering — multi-thread", () => {
|
|
|
3090
3093
|
|
|
3091
3094
|
// ── transport_hints kept for non-slack channels ───────────────────────
|
|
3092
3095
|
test("non-slack conversations still receive <transport_hints>", async () => {
|
|
3096
|
+
seedChannelCapabilitiesConversation({
|
|
3097
|
+
channel: "telegram",
|
|
3098
|
+
dashboardCapable: false,
|
|
3099
|
+
supportsDynamicUi: false,
|
|
3100
|
+
supportsVoiceInput: false,
|
|
3101
|
+
chatType: "private",
|
|
3102
|
+
});
|
|
3093
3103
|
const { messages: result } = await applyRuntimeInjections(
|
|
3094
3104
|
[{ role: "user", content: [{ type: "text", text: "hi" }] }],
|
|
3095
3105
|
{
|
|
3096
|
-
channelCapabilities: {
|
|
3097
|
-
channel: "telegram",
|
|
3098
|
-
dashboardCapable: false,
|
|
3099
|
-
supportsDynamicUi: false,
|
|
3100
|
-
supportsVoiceInput: false,
|
|
3101
|
-
chatType: "private",
|
|
3102
|
-
},
|
|
3103
3106
|
transportHints: ["please answer concisely"],
|
|
3104
3107
|
},
|
|
3105
3108
|
);
|
|
@@ -3426,8 +3429,8 @@ describe("Slack channel chronological rendering — multi-thread", () => {
|
|
|
3426
3429
|
role: "user",
|
|
3427
3430
|
content: [{ type: "text", text: "current turn" }],
|
|
3428
3431
|
};
|
|
3432
|
+
seedChannelCapabilitiesConversation(slackChannelCaps);
|
|
3429
3433
|
const { messages } = await applyRuntimeInjections([lastUserMessage], {
|
|
3430
|
-
channelCapabilities: slackChannelCaps,
|
|
3431
3434
|
slackChronologicalMessages,
|
|
3432
3435
|
slackActiveThreadFocusBlock: focusBlock,
|
|
3433
3436
|
});
|
|
@@ -3696,8 +3699,8 @@ describe("Slack channel chronological rendering — multi-thread", () => {
|
|
|
3696
3699
|
chatType: "channel",
|
|
3697
3700
|
};
|
|
3698
3701
|
const newFocus = "<active_thread>\nnewly built\n</active_thread>";
|
|
3702
|
+
seedChannelCapabilitiesConversation(slackChannelCaps);
|
|
3699
3703
|
const { messages: reInjected } = await applyRuntimeInjections(stripped, {
|
|
3700
|
-
channelCapabilities: slackChannelCaps,
|
|
3701
3704
|
slackActiveThreadFocusBlock: newFocus,
|
|
3702
3705
|
});
|
|
3703
3706
|
const reInjectedTexts = reInjected
|
|
@@ -3717,15 +3720,15 @@ describe("Slack channel chronological rendering — multi-thread", () => {
|
|
|
3717
3720
|
// Defensive: the focus injection is gated on `slackChannel` (i.e.
|
|
3718
3721
|
// `isSlackChannelConversation`). Even if a caller mistakenly forwards
|
|
3719
3722
|
// a focus block on a non-Slack channel, it must NOT be appended.
|
|
3723
|
+
seedChannelCapabilitiesConversation({
|
|
3724
|
+
channel: "vellum",
|
|
3725
|
+
dashboardCapable: true,
|
|
3726
|
+
supportsDynamicUi: true,
|
|
3727
|
+
supportsVoiceInput: true,
|
|
3728
|
+
});
|
|
3720
3729
|
const { messages: result } = await applyRuntimeInjections(
|
|
3721
3730
|
[{ role: "user", content: [{ type: "text", text: "vellum question" }] }],
|
|
3722
3731
|
{
|
|
3723
|
-
channelCapabilities: {
|
|
3724
|
-
channel: "vellum",
|
|
3725
|
-
dashboardCapable: true,
|
|
3726
|
-
supportsDynamicUi: true,
|
|
3727
|
-
supportsVoiceInput: true,
|
|
3728
|
-
},
|
|
3729
3732
|
slackActiveThreadFocusBlock: "<active_thread>\nbogus\n</active_thread>",
|
|
3730
3733
|
},
|
|
3731
3734
|
);
|
|
@@ -3742,16 +3745,16 @@ describe("Slack channel chronological rendering — multi-thread", () => {
|
|
|
3742
3745
|
// Same as above but for Slack DMs (chatType === "im"). The focus
|
|
3743
3746
|
// injection is keyed on `isSlackChannelConversation` which excludes
|
|
3744
3747
|
// DMs, so the block must not appear.
|
|
3748
|
+
seedChannelCapabilitiesConversation({
|
|
3749
|
+
channel: "slack",
|
|
3750
|
+
dashboardCapable: false,
|
|
3751
|
+
supportsDynamicUi: false,
|
|
3752
|
+
supportsVoiceInput: false,
|
|
3753
|
+
chatType: "im",
|
|
3754
|
+
});
|
|
3745
3755
|
const { messages: result } = await applyRuntimeInjections(
|
|
3746
3756
|
[{ role: "user", content: [{ type: "text", text: "DM question" }] }],
|
|
3747
3757
|
{
|
|
3748
|
-
channelCapabilities: {
|
|
3749
|
-
channel: "slack",
|
|
3750
|
-
dashboardCapable: false,
|
|
3751
|
-
supportsDynamicUi: false,
|
|
3752
|
-
supportsVoiceInput: false,
|
|
3753
|
-
chatType: "im",
|
|
3754
|
-
},
|
|
3755
3758
|
slackActiveThreadFocusBlock: "<active_thread>\nbogus\n</active_thread>",
|
|
3756
3759
|
},
|
|
3757
3760
|
);
|
|
@@ -3990,11 +3993,11 @@ describe("assembleSlackActiveThreadFocusBlock", () => {
|
|
|
3990
3993
|
expect(result!).not.toContain("Sibling top-level");
|
|
3991
3994
|
});
|
|
3992
3995
|
|
|
3993
|
-
test("preserves
|
|
3996
|
+
test("preserves user attribution while leaving assistant text unchanged", () => {
|
|
3994
3997
|
// The `<active_thread>` block is rendered as newline-joined plain text,
|
|
3995
|
-
// discarding `Message.role`.
|
|
3996
|
-
//
|
|
3997
|
-
//
|
|
3998
|
+
// discarding `Message.role`. User rows keep explicit Slack attribution,
|
|
3999
|
+
// while assistant rows remain raw to avoid teaching the model a synthetic
|
|
4000
|
+
// reply prefix.
|
|
3998
4001
|
const rows: SlackTranscriptInputRow[] = [
|
|
3999
4002
|
buildRow(
|
|
4000
4003
|
"user",
|
|
@@ -4021,17 +4024,16 @@ describe("assembleSlackActiveThreadFocusBlock", () => {
|
|
|
4021
4024
|
const result = assembleSlackActiveThreadFocusBlock(rows, SLACK_CAPS);
|
|
4022
4025
|
expect(result).not.toBeNull();
|
|
4023
4026
|
expect(result!).toContain("@alice");
|
|
4024
|
-
expect(result!).toContain("
|
|
4027
|
+
expect(result!).toContain("Assistant reply");
|
|
4028
|
+
expect(result!).not.toContain("@assistant: Assistant reply");
|
|
4025
4029
|
expect(result!).toContain("@user");
|
|
4026
4030
|
});
|
|
4027
4031
|
|
|
4028
4032
|
test("assistant reactions are not double-attributed (`@assistant: [... @assistant reacted ...]`)", () => {
|
|
4029
4033
|
// `renderReaction` bakes `@assistant` into the reaction tag line
|
|
4030
4034
|
// (`[11/14/23 14:28 @assistant reacted 👍 to Mxxxxxx]`). The
|
|
4031
|
-
//
|
|
4032
|
-
//
|
|
4033
|
-
// produces `@assistant: [... @assistant reacted ...]` — two
|
|
4034
|
-
// attributions for one event.
|
|
4035
|
+
// flattened block should preserve that renderer-owned attribution without
|
|
4036
|
+
// adding any extra assistant-message prefix.
|
|
4035
4037
|
const rows: SlackTranscriptInputRow[] = [
|
|
4036
4038
|
buildRow(
|
|
4037
4039
|
"user",
|
|
@@ -4039,7 +4041,7 @@ describe("assembleSlackActiveThreadFocusBlock", () => {
|
|
|
4039
4041
|
1_000,
|
|
4040
4042
|
buildMeta({ channelTs: PARENT_TS, displayName: "@alice" }),
|
|
4041
4043
|
),
|
|
4042
|
-
// Assistant reply in the thread —
|
|
4044
|
+
// Assistant reply in the thread — stays unchanged.
|
|
4043
4045
|
buildRow(
|
|
4044
4046
|
"assistant",
|
|
4045
4047
|
"Assistant reply",
|
|
@@ -4081,12 +4083,13 @@ describe("assembleSlackActiveThreadFocusBlock", () => {
|
|
|
4081
4083
|
expect(result).not.toBeNull();
|
|
4082
4084
|
// Double-attribution anti-pattern must NOT appear anywhere.
|
|
4083
4085
|
expect(result!).not.toContain("@assistant: [");
|
|
4084
|
-
//
|
|
4086
|
+
// Reaction attribution remains, and the assistant reply stays raw.
|
|
4085
4087
|
expect(result!).toContain("@assistant reacted 👍");
|
|
4086
|
-
expect(result!).toContain("
|
|
4088
|
+
expect(result!).toContain("Assistant reply");
|
|
4089
|
+
expect(result!).not.toContain("@assistant: Assistant reply");
|
|
4087
4090
|
});
|
|
4088
4091
|
|
|
4089
|
-
test("timezone-aware assistant rows
|
|
4092
|
+
test("timezone-aware assistant rows stay unchanged in active-thread focus block", () => {
|
|
4090
4093
|
const rows: SlackTranscriptInputRow[] = [
|
|
4091
4094
|
buildRow(
|
|
4092
4095
|
"user",
|
|
@@ -4127,15 +4130,12 @@ describe("assembleSlackActiveThreadFocusBlock", () => {
|
|
|
4127
4130
|
|
|
4128
4131
|
const result = assembleSlackActiveThreadFocusBlock(rows, SLACK_CAPS);
|
|
4129
4132
|
expect(result).not.toBeNull();
|
|
4130
|
-
expect(result!).toContain(
|
|
4131
|
-
|
|
4132
|
-
);
|
|
4133
|
-
expect(result!).not.toContain(
|
|
4134
|
-
"@assistant: [nov 14 2023 3:13 PM MT assistant]",
|
|
4135
|
-
);
|
|
4133
|
+
expect(result!).toContain("\nAssistant reply\n");
|
|
4134
|
+
expect(result!).not.toContain("[nov 14 2023 3:13 PM MT assistant]");
|
|
4135
|
+
expect(result!).not.toContain("@assistant: Assistant reply");
|
|
4136
4136
|
});
|
|
4137
4137
|
|
|
4138
|
-
test("assistant content that only looks like a compact tag
|
|
4138
|
+
test("assistant content that only looks like a compact tag stays unchanged", () => {
|
|
4139
4139
|
const compactLookingContent =
|
|
4140
4140
|
"[nov 14 2023 3:13 PM MT assistant] Assistant reply";
|
|
4141
4141
|
const rows: SlackTranscriptInputRow[] = [
|
|
@@ -4168,7 +4168,8 @@ describe("assembleSlackActiveThreadFocusBlock", () => {
|
|
|
4168
4168
|
|
|
4169
4169
|
const result = assembleSlackActiveThreadFocusBlock(rows, SLACK_CAPS);
|
|
4170
4170
|
expect(result).not.toBeNull();
|
|
4171
|
-
expect(result!).toContain(
|
|
4171
|
+
expect(result!).toContain(`\n${compactLookingContent}\n`);
|
|
4172
|
+
expect(result!).not.toContain(`@assistant: ${compactLookingContent}`);
|
|
4172
4173
|
});
|
|
4173
4174
|
|
|
4174
4175
|
test("assistant reaction overflow trailer is not double-attributed", () => {
|
|
@@ -5102,11 +5103,15 @@ describe("applyRuntimeInjections blocks.pkbSystemReminder", () => {
|
|
|
5102
5103
|
},
|
|
5103
5104
|
];
|
|
5104
5105
|
|
|
5106
|
+
// The reminder gate hinges on PKB content presence; clear it after each test
|
|
5107
|
+
// so the "PKB inactive" case starts from an empty workspace pkb dir.
|
|
5108
|
+
afterEach(clearPkbContent);
|
|
5109
|
+
|
|
5105
5110
|
test("captures exact reminder bytes when full mode and PKB active", async () => {
|
|
5111
|
+
seedPkbContent();
|
|
5106
5112
|
pkbSearchResults = [];
|
|
5107
5113
|
pkbSearchThrows = null;
|
|
5108
5114
|
const { blocks } = await applyRuntimeInjections(baseMessages, {
|
|
5109
|
-
pkbActive: true,
|
|
5110
5115
|
mode: "full",
|
|
5111
5116
|
});
|
|
5112
5117
|
|
|
@@ -5115,8 +5120,8 @@ describe("applyRuntimeInjections blocks.pkbSystemReminder", () => {
|
|
|
5115
5120
|
});
|
|
5116
5121
|
|
|
5117
5122
|
test("not captured in minimal mode", async () => {
|
|
5123
|
+
seedPkbContent();
|
|
5118
5124
|
const { blocks } = await applyRuntimeInjections(baseMessages, {
|
|
5119
|
-
pkbActive: true,
|
|
5120
5125
|
mode: "minimal",
|
|
5121
5126
|
});
|
|
5122
5127
|
|
|
@@ -5125,7 +5130,6 @@ describe("applyRuntimeInjections blocks.pkbSystemReminder", () => {
|
|
|
5125
5130
|
|
|
5126
5131
|
test("not captured when PKB inactive", async () => {
|
|
5127
5132
|
const { blocks } = await applyRuntimeInjections(baseMessages, {
|
|
5128
|
-
pkbActive: false,
|
|
5129
5133
|
mode: "full",
|
|
5130
5134
|
});
|
|
5131
5135
|
|