@vellumai/assistant 0.8.10 → 0.8.11-staging.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bun.lock +62 -1
- package/docs/workspace-tools.md +196 -0
- package/examples/plugins/echo/README.md +3 -3
- package/knip.json +1 -0
- package/openapi.yaml +460 -128
- package/package.json +2 -1
- package/scripts/build-plugin-api.ts +299 -0
- package/src/__tests__/agent-loop-callsite-precedence.test.ts +7 -0
- package/src/__tests__/agent-loop-compaction-events.test.ts +197 -0
- package/src/__tests__/agent-loop-exit-reason.test.ts +93 -96
- package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +2 -0
- package/src/__tests__/agent-loop-output-hooks.test.ts +274 -1
- package/src/__tests__/agent-loop-override-profile.test.ts +3 -0
- package/src/__tests__/agent-loop-provider-error-recording.test.ts +4 -0
- package/src/__tests__/agent-loop-thinking.test.ts +4 -0
- package/src/__tests__/agent-loop.test.ts +578 -5
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +0 -1
- package/src/__tests__/approval-cascade.test.ts +1 -0
- package/src/__tests__/background-workers-disk-pressure.test.ts +0 -2
- package/src/__tests__/btw-routes.test.ts +0 -1
- package/src/__tests__/build-persisted-content.test.ts +75 -1
- package/src/__tests__/catalog-install-normalize.test.ts +141 -0
- package/src/__tests__/ces-startup-timeout.test.ts +60 -0
- package/src/__tests__/compaction-events.test.ts +1 -0
- package/src/__tests__/config-managed-gemini-defaults.test.ts +2 -46
- package/src/__tests__/context-overflow-reducer.test.ts +264 -124
- package/src/__tests__/context-window-manager-overflow-rung.test.ts +351 -0
- package/src/__tests__/conversation-abort-tool-results.test.ts +1 -1
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +13 -5
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +284 -455
- package/src/__tests__/conversation-agent-loop.test.ts +131 -551
- package/src/__tests__/conversation-app-control-instantiation.test.ts +13 -0
- package/src/__tests__/conversation-confirmation-signals.test.ts +1 -0
- package/src/__tests__/conversation-fork-crud.test.ts +259 -0
- package/src/__tests__/conversation-history-web-search.test.ts +1 -1
- package/src/__tests__/conversation-lifecycle.test.ts +257 -1
- package/src/__tests__/conversation-process-callsite.test.ts +1 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +38 -377
- package/src/__tests__/conversation-queue.test.ts +1 -39
- package/src/__tests__/conversation-runtime-assembly.test.ts +119 -8
- package/src/__tests__/conversation-skill-tools.test.ts +491 -5
- package/src/__tests__/conversation-slash-queue.test.ts +1 -1
- package/src/__tests__/conversation-slash-unknown.test.ts +1 -0
- package/src/__tests__/conversation-speed-override.test.ts +1 -0
- package/src/__tests__/conversation-store.test.ts +74 -0
- package/src/__tests__/conversation-surfaces-app-control.test.ts +4 -1
- package/src/__tests__/conversation-tool-setup-attribution.test.ts +323 -0
- package/src/__tests__/conversation-tool-setup-tools-disabled.test.ts +34 -0
- package/src/__tests__/conversation-workspace-cache-state.test.ts +1 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +1 -1
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +1 -0
- package/src/__tests__/corrected-target.test.ts +93 -0
- package/src/__tests__/credential-execution-feature-gates.test.ts +3 -5
- package/src/__tests__/credential-execution-tools.test.ts +23 -11
- package/src/__tests__/credential-security-invariants.test.ts +6 -1
- package/src/__tests__/db-schedule-syntax-migration.test.ts +80 -0
- package/src/__tests__/device-id.test.ts +70 -1
- package/src/__tests__/embedding-managed-proxy-selection.test.ts +6 -40
- package/src/__tests__/empty-response-hook.test.ts +242 -66
- package/src/__tests__/external-plugin-loader.test.ts +0 -31
- package/src/__tests__/get-skill-detail-audit.test.ts +43 -1
- package/src/__tests__/guardian-routing-invariants.test.ts +91 -0
- package/src/__tests__/history-repair-hook.test.ts +228 -3
- package/src/__tests__/host-app-control-proxy.test.ts +45 -0
- package/src/__tests__/host-browser-proxy.test.ts +254 -9
- package/src/__tests__/identity-routes.test.ts +1 -0
- package/src/__tests__/image-recovery-hook.test.ts +387 -0
- package/src/__tests__/injector-chain.test.ts +5 -4
- package/src/__tests__/injector-v3-suppression.test.ts +373 -47
- package/src/__tests__/intent-routing.test.ts +7 -0
- package/src/__tests__/memory-retrieval-hook.test.ts +117 -15
- package/src/__tests__/notification-decision-strategy.test.ts +3 -3
- package/src/__tests__/oauth-store.test.ts +0 -85
- package/src/__tests__/{context-overflow-policy.test.ts → overflow-policy.test.ts} +1 -1
- package/src/__tests__/parallel-tool.benchmark.test.ts +4 -0
- package/src/__tests__/persist-unsendable-image-downscale.test.ts +29 -9
- package/src/__tests__/persist-unsendable-image.test.ts +4 -4
- package/src/__tests__/persistence-secret-redaction.test.ts +78 -0
- package/src/__tests__/plugin-bootstrap.test.ts +82 -73
- package/src/__tests__/plugin-tool-contribution.test.ts +7 -4
- package/src/__tests__/plugin-types.test.ts +0 -8
- package/src/__tests__/provider-catalog-visibility.test.ts +1 -9
- package/src/__tests__/prune-old-conversations-job.test.ts +99 -0
- package/src/__tests__/registry.test.ts +240 -1
- package/src/__tests__/require-fresh-approval.test.ts +3 -0
- package/src/__tests__/schedule-routes.test.ts +116 -1
- package/src/__tests__/schedule-store.test.ts +28 -0
- package/src/__tests__/schedule-tools.test.ts +94 -1
- package/src/__tests__/server-history-render.test.ts +39 -0
- package/src/__tests__/skill-projection-feature-flag.test.ts +13 -0
- package/src/__tests__/skill-projection.benchmark.test.ts +25 -7
- package/src/__tests__/skills.test.ts +202 -0
- package/src/__tests__/slim-skill-category.test.ts +195 -0
- package/src/__tests__/strip-memory-injections.test.ts +33 -39
- package/src/__tests__/test-support/tool-invocation-seed.ts +79 -0
- package/src/__tests__/title-generate-hook.test.ts +9 -7
- package/src/__tests__/tool-audit-listener.test.ts +264 -1
- package/src/__tests__/tool-error-hook.test.ts +4 -3
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +1 -0
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +273 -0
- package/src/__tests__/tool-result-truncate-hook.test.ts +1 -0
- package/src/__tests__/tool-start-timestamp.test.ts +218 -0
- package/src/__tests__/tools-get-route.test.ts +202 -0
- package/src/__tests__/workspace-tool-loader.test.ts +319 -0
- package/src/__tests__/workspace-tools-watcher-flag.test.ts +70 -0
- package/src/agent/loop.ts +569 -319
- package/src/api/events/tool-result.ts +9 -0
- package/src/api/events/tool-use-start.ts +7 -0
- package/src/api/index.ts +10 -0
- package/src/api/responses/conversation-message.ts +135 -27
- package/src/api/responses/memory-v3-selection-log.ts +4 -4
- package/src/approvals/guardian-request-resolvers.ts +26 -0
- package/src/browser-session/backends/host-bridge.ts +29 -0
- package/src/browser-session/index.ts +1 -0
- package/src/browser-session/types.ts +5 -1
- package/src/cli/commands/__tests__/schedules.test.ts +62 -4
- package/src/cli/commands/__tests__/skills.test.ts +53 -0
- package/src/cli/commands/channel-verification-sessions.ts +6 -6
- package/src/cli/commands/inference-providers.ts +0 -8
- package/src/cli/commands/plugins.ts +2 -2
- package/src/cli/commands/schedules.ts +27 -4
- package/src/cli/commands/skills.ts +187 -146
- package/src/cli/commands/tools.ts +106 -0
- package/src/cli/lib/__tests__/install-from-github.test.ts +256 -328
- package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +6 -2
- package/src/cli/lib/__tests__/plugin-details.test.ts +10 -16
- package/src/cli/lib/__tests__/plugin-marketplace.test.ts +2 -2
- package/src/cli/lib/__tests__/search-plugins.test.ts +145 -240
- package/src/cli/lib/install-from-github.ts +187 -117
- package/src/cli/lib/plugin-catalog-cache.ts +9 -9
- package/src/cli/lib/plugin-details.ts +38 -68
- package/src/cli/lib/plugin-marketplace.ts +42 -14
- package/src/cli/lib/search-plugins.ts +29 -129
- package/src/cli/program.ts +2 -0
- package/src/config/bundled-skills/acp/SKILL.md +1 -0
- package/src/config/bundled-skills/app-builder/SKILL.md +1 -0
- package/src/config/bundled-skills/app-control/SKILL.md +1 -0
- package/src/config/bundled-skills/computer-use/SKILL.md +1 -0
- package/src/config/bundled-skills/contacts/SKILL.md +1 -0
- package/src/config/bundled-skills/document-editor/SKILL.md +1 -0
- package/src/config/bundled-skills/followups/SKILL.md +1 -0
- package/src/config/bundled-skills/image-studio/SKILL.md +1 -0
- package/src/config/bundled-skills/media-processing/SKILL.md +1 -0
- package/src/config/bundled-skills/messaging/SKILL.md +1 -0
- package/src/config/bundled-skills/phone-calls/SKILL.md +1 -0
- package/src/config/bundled-skills/playbooks/SKILL.md +1 -0
- package/src/config/bundled-skills/schedule/SKILL.md +1 -0
- package/src/config/bundled-skills/schedule/TOOLS.json +11 -3
- package/src/config/bundled-skills/sequences/SKILL.md +1 -0
- package/src/config/bundled-skills/settings/SKILL.md +1 -0
- package/src/config/bundled-skills/skill-management/SKILL.md +101 -1
- package/src/config/bundled-skills/subagent/SKILL.md +1 -0
- package/src/config/bundled-skills/transcribe/SKILL.md +1 -0
- package/src/config/env-registry.ts +23 -0
- package/src/config/feature-flag-registry.json +17 -81
- package/src/config/loader.ts +5 -22
- package/src/config/schema.ts +2 -0
- package/src/config/schemas/__tests__/compaction-logs.test.ts +56 -0
- package/src/config/schemas/__tests__/memory-v2.test.ts +0 -1
- package/src/config/schemas/__tests__/memory-v3.test.ts +61 -1
- package/src/config/schemas/compaction-logs.ts +79 -0
- package/src/config/schemas/memory-v2.ts +0 -8
- package/src/config/schemas/memory-v3.ts +104 -33
- package/src/config/seed-inference-profiles.ts +1 -1
- package/src/config/skills.ts +117 -47
- package/src/context/compactor.ts +11 -0
- package/src/context/strip-injections.ts +38 -4
- package/src/credential-execution/feature-gates.ts +0 -21
- package/src/credential-execution/startup-timeout.ts +32 -4
- package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +18 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +140 -91
- package/src/daemon/conversation-agent-loop.ts +123 -658
- package/src/daemon/conversation-error.ts +6 -33
- package/src/daemon/conversation-lifecycle.ts +1 -1
- package/src/daemon/conversation-runtime-assembly.ts +183 -22
- package/src/daemon/conversation-skill-tools.ts +137 -8
- package/src/daemon/conversation-slash.ts +0 -14
- package/src/daemon/conversation-store.ts +2 -19
- package/src/daemon/conversation-tool-setup.ts +87 -1
- package/src/daemon/conversation.ts +119 -50
- package/src/daemon/external-plugins-bootstrap.ts +36 -95
- package/src/daemon/handlers/config-channels.ts +11 -2
- package/src/daemon/handlers/shared.ts +9 -1
- package/src/daemon/handlers/skills.ts +10 -4
- package/src/daemon/host-app-control-proxy.ts +72 -57
- package/src/daemon/host-browser-proxy.ts +117 -22
- package/src/daemon/lifecycle.ts +34 -5
- package/src/daemon/message-protocol.ts +0 -7
- package/src/daemon/message-types/schedules.ts +1 -0
- package/src/daemon/message-types/skills.ts +17 -0
- package/src/daemon/providers-setup.ts +3 -0
- package/src/daemon/server.ts +3 -3
- package/src/daemon/tool-setup-types.ts +9 -3
- package/src/daemon/trust-context.ts +23 -0
- package/src/daemon/workspace-tools-watcher.ts +324 -0
- package/src/events/tool-audit-listener.ts +78 -16
- package/src/events/tool-metrics-listener.ts +2 -5
- package/src/memory/__tests__/compaction-log-writer-clickhouse.test.ts +227 -0
- package/src/memory/__tests__/conversation-queries.test.ts +176 -0
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +20 -32
- package/src/memory/compaction-log-writer-clickhouse.ts +418 -0
- package/src/memory/conversation-crud.ts +134 -3
- package/src/memory/conversation-queries.ts +64 -7
- package/src/memory/db-init.ts +14 -0
- package/src/memory/embedding-backend.test.ts +130 -1
- package/src/memory/embedding-backend.ts +79 -106
- package/src/memory/embedding-gemini.ts +5 -0
- package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +12 -0
- package/src/memory/graph/__tests__/handle-remember-v2.test.ts +19 -0
- package/src/memory/graph/conversation-graph-memory.ts +36 -25
- package/src/memory/graph/tool-handlers.ts +3 -0
- package/src/memory/job-handlers/cleanup.ts +3 -1
- package/src/memory/jobs-store.ts +0 -28
- package/src/memory/jobs-worker.ts +10 -22
- package/src/memory/memory-marker.ts +29 -0
- package/src/memory/memory-retrospective-startup-cleanup.ts +1 -1
- package/src/memory/migrations/268-add-memory-v3-selections.ts +6 -0
- package/src/memory/migrations/270-schedule-description.ts +36 -0
- package/src/memory/migrations/275-tool-invocations-add-skill-id.test.ts +81 -0
- package/src/memory/migrations/275-tool-invocations-add-skill-id.ts +20 -0
- package/src/memory/migrations/276-tool-invocations-created-at-id-index.test.ts +68 -0
- package/src/memory/migrations/276-tool-invocations-created-at-id-index.ts +20 -0
- package/src/memory/migrations/277-add-memory-v3-ever-injected.ts +29 -0
- package/src/memory/migrations/278-tool-invocations-telemetry-columns.test.ts +96 -0
- package/src/memory/migrations/278-tool-invocations-telemetry-columns.ts +39 -0
- package/src/memory/migrations/279-create-skill-loaded-events.test.ts +84 -0
- package/src/memory/migrations/279-create-skill-loaded-events.ts +26 -0
- package/src/memory/migrations/280-conversations-surfaced-at.test.ts +88 -0
- package/src/memory/migrations/280-conversations-surfaced-at.ts +24 -0
- package/src/memory/migrations/index.ts +10 -0
- package/src/memory/migrations/registry.ts +8 -0
- package/src/memory/schema/conversations.ts +16 -0
- package/src/memory/schema/infrastructure.ts +26 -0
- package/src/memory/skill-loaded-events-store.test.ts +160 -0
- package/src/memory/skill-loaded-events-store.ts +95 -0
- package/src/memory/tool-executed-events-store.test.ts +219 -0
- package/src/memory/tool-executed-events-store.ts +102 -0
- package/src/memory/tool-usage-store.ts +15 -3
- package/src/memory/v2/__tests__/consolidation-job.test.ts +117 -12
- package/src/memory/v2/__tests__/consolidation-prompt-flag-gating-guard.test.ts +189 -0
- package/src/memory/v2/__tests__/injected-block-slugs.test.ts +90 -0
- package/src/memory/v2/__tests__/page-store.test.ts +33 -0
- package/src/memory/v2/__tests__/prompts-consolidation.test.ts +88 -15
- package/src/memory/v2/activation-store.ts +50 -1
- package/src/memory/v2/consolidation-job.ts +113 -29
- package/src/memory/v2/injected-block-slugs.ts +79 -0
- package/src/memory/v2/injection.ts +6 -1
- package/src/memory/v2/prompts/consolidation.ts +414 -13
- package/src/memory/v2/router.ts +2 -28
- package/src/memory/v2/static-context.ts +1 -1
- package/src/memory/v2/types.ts +16 -0
- package/src/notifications/__tests__/copy-composer.test.ts +244 -0
- package/src/notifications/access-request-copy.ts +298 -0
- package/src/notifications/adapters/slack.ts +3 -3
- package/src/notifications/adapters/telegram.ts +2 -1
- package/src/notifications/copy-composer.ts +49 -267
- package/src/notifications/decision-engine.ts +16 -35
- package/src/notifications/home-feed-side-effect.ts +1 -6
- package/src/oauth/oauth-store.ts +0 -9
- package/src/permissions/checker.test.ts +83 -1
- package/src/permissions/checker.ts +25 -2
- package/src/permissions/gateway-threshold-reader.test.ts +182 -0
- package/src/permissions/gateway-threshold-reader.ts +80 -0
- package/src/platform/client.ts +1 -3
- package/src/platform/feature-gate.ts +3 -12
- package/src/plugin-api/constants.ts +4 -2
- package/src/plugin-api/index.ts +63 -11
- package/src/plugin-api/types.ts +236 -71
- package/src/plugins/defaults/compaction/compact.ts +66 -2
- package/src/plugins/defaults/compaction/context-overflow-reducer.ts +240 -32
- package/src/plugins/defaults/compaction/corrected-target.ts +53 -0
- package/src/{daemon/context-overflow-policy.ts → plugins/defaults/compaction/overflow-policy.ts} +1 -1
- package/src/plugins/defaults/compaction/window-manager.ts +303 -1
- package/src/plugins/defaults/empty-response/hooks/post-model-call.ts +173 -0
- package/src/plugins/defaults/empty-response/hooks/stop.ts +11 -115
- package/src/plugins/defaults/empty-response/nudge-state-store.ts +46 -0
- package/src/plugins/defaults/history-repair/hooks/post-model-call.ts +50 -0
- package/src/plugins/defaults/history-repair/hooks/stop.ts +22 -0
- package/src/plugins/defaults/history-repair/repair-state-store.ts +51 -0
- package/src/plugins/defaults/history-repair/terminal.ts +39 -2
- package/src/plugins/defaults/image-recovery/detect.ts +25 -0
- package/src/plugins/defaults/image-recovery/hooks/post-model-call.ts +73 -0
- package/src/plugins/defaults/image-recovery/hooks/stop.ts +22 -0
- package/src/plugins/defaults/image-recovery/image-recovery-state-store.ts +48 -0
- package/src/plugins/defaults/image-recovery/package.json +14 -0
- package/src/{daemon/persist-unsendable-image.ts → plugins/defaults/image-recovery/recover.ts} +67 -14
- package/src/plugins/defaults/index.ts +71 -5
- package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +76 -112
- package/src/plugins/defaults/memory-retrieval/hooks/{user-prompt-submit-temp.ts → user-prompt-submit.ts} +83 -74
- package/src/plugins/defaults/memory-retrieval/injector-chain.ts +14 -8
- package/src/plugins/defaults/memory-retrieval/injectors.ts +2 -18
- package/src/plugins/defaults/memory-retrieval/package.json +14 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/carry-integration.test.ts +1157 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/injection.test.ts +683 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/live-integration.test.ts +161 -140
- package/src/plugins/defaults/memory-v3-shadow/__tests__/maintain-job.test.ts +160 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/orchestrate.test.ts +335 -316
- package/src/plugins/defaults/memory-v3-shadow/__tests__/pool-select.test.ts +145 -53
- package/src/plugins/defaults/memory-v3-shadow/__tests__/render-injection.test.ts +38 -1
- package/src/plugins/defaults/memory-v3-shadow/__tests__/selection-log-store.test.ts +18 -8
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-integration.test.ts +112 -71
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +192 -51
- package/src/plugins/defaults/memory-v3-shadow/__tests__/types.test.ts +4 -16
- package/src/plugins/defaults/memory-v3-shadow/card.test.ts +173 -0
- package/src/plugins/defaults/memory-v3-shadow/card.ts +116 -0
- package/src/plugins/defaults/memory-v3-shadow/core-set.test.ts +104 -0
- package/src/plugins/defaults/memory-v3-shadow/core-set.ts +59 -0
- package/src/plugins/defaults/memory-v3-shadow/ever-injected-store.test.ts +305 -0
- package/src/plugins/defaults/memory-v3-shadow/ever-injected-store.ts +278 -0
- package/src/plugins/defaults/memory-v3-shadow/hot-set.test.ts +138 -0
- package/src/plugins/defaults/memory-v3-shadow/hot-set.ts +85 -0
- package/src/plugins/defaults/memory-v3-shadow/injector.ts +331 -24
- package/src/plugins/defaults/memory-v3-shadow/maintain-job.ts +119 -13
- package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +169 -114
- package/src/plugins/defaults/memory-v3-shadow/page-content.ts +47 -16
- package/src/plugins/defaults/memory-v3-shadow/pool-select.ts +144 -66
- package/src/plugins/defaults/memory-v3-shadow/prune.test.ts +758 -0
- package/src/plugins/defaults/memory-v3-shadow/prune.ts +471 -0
- package/src/plugins/defaults/memory-v3-shadow/render-injection.ts +68 -16
- package/src/plugins/defaults/memory-v3-shadow/selection-log-store.ts +19 -12
- package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +96 -43
- package/src/plugins/defaults/memory-v3-shadow/types.ts +34 -17
- package/src/plugins/defaults/title-generate/hooks/stop.ts +9 -11
- package/src/plugins/pipeline.ts +8 -5
- package/src/plugins/types.ts +5 -51
- package/src/providers/cache-control.ts +26 -0
- package/src/providers/inference/__tests__/base-url-route-validation.test.ts +1 -2
- package/src/providers/model-catalog.ts +13 -1
- package/src/providers/openai/__tests__/tool-choice-mapping.test.ts +147 -0
- package/src/providers/openai/chat-completions-provider.ts +46 -0
- package/src/providers/openai/responses-provider.ts +45 -0
- package/src/providers/registry.ts +0 -8
- package/src/runtime/__tests__/agent-wake.test.ts +0 -1
- package/src/runtime/agent-wake.ts +13 -0
- package/src/runtime/routes/__tests__/acp-routes.test.ts +151 -0
- package/src/runtime/routes/__tests__/consolidation-routes.test.ts +12 -50
- package/src/runtime/routes/__tests__/conversation-surface-routes.test.ts +322 -0
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +0 -62
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +31 -11
- package/src/runtime/routes/acp-routes.test.ts +106 -0
- package/src/runtime/routes/acp-routes.ts +248 -2
- package/src/runtime/routes/browser-tabs-routes.ts +1 -1
- package/src/runtime/routes/channel-verification-routes.ts +14 -5
- package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +0 -14
- package/src/runtime/routes/consolidation-routes.ts +6 -82
- package/src/runtime/routes/conversation-list-routes.ts +6 -0
- package/src/runtime/routes/conversation-management-routes.ts +71 -0
- package/src/runtime/routes/identity-routes.ts +8 -0
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +33 -34
- package/src/runtime/routes/inference-provider-connection-routes.ts +0 -45
- package/src/runtime/routes/plugins-routes.ts +34 -45
- package/src/runtime/routes/schedule-routes.ts +43 -5
- package/src/runtime/routes/settings-routes.ts +140 -15
- package/src/runtime/routes/skills-routes.ts +18 -6
- package/src/runtime/services/__tests__/conversation-serializer.test.ts +140 -0
- package/src/runtime/services/conversation-serializer.ts +38 -1
- package/src/runtime/verification-outbound-actions.ts +147 -2
- package/src/runtime/verification-templates.ts +29 -3
- package/src/schedule/schedule-store.ts +19 -0
- package/src/skills/catalog-install.ts +77 -13
- package/src/tasks/task-scheduler.ts +1 -0
- package/src/telemetry/types.ts +66 -1
- package/src/telemetry/usage-telemetry-reporter.test.ts +542 -13
- package/src/telemetry/usage-telemetry-reporter.ts +213 -20
- package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +49 -2
- package/src/tools/browser/__tests__/browser-status.test.ts +29 -5
- package/src/tools/browser/browser-execution.ts +27 -9
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +380 -4
- package/src/tools/browser/cdp-client/__tests__/host-bridge-cdp-client.test.ts +107 -0
- package/src/tools/browser/cdp-client/__tests__/types.test.ts +6 -1
- package/src/tools/browser/cdp-client/factory.ts +217 -17
- package/src/tools/browser/cdp-client/host-bridge-cdp-client.ts +67 -0
- package/src/tools/browser/cdp-client/types.ts +22 -2
- package/src/tools/credential-execution/make-authenticated-request.ts +2 -1
- package/src/tools/credential-execution/manage-secure-command-tool.ts +169 -164
- package/src/tools/credential-execution/run-authenticated-command.ts +2 -1
- package/src/tools/executor.ts +39 -7
- package/src/tools/registry.ts +387 -5
- package/src/tools/schedule/create.ts +16 -0
- package/src/tools/schedule/list.ts +12 -4
- package/src/tools/schedule/update.ts +12 -0
- package/src/tools/skills/load.ts +11 -6
- package/src/tools/terminal/safe-env.ts +2 -0
- package/src/tools/types.ts +65 -9
- package/src/tools/workspace-tools/loader.ts +673 -0
- package/src/usage/attribution.ts +28 -0
- package/src/util/device-id.ts +17 -3
- package/src/util/platform.ts +16 -0
- package/tsconfig.plugin-api.json +13 -0
- package/src/__tests__/plugin-external-api.test.ts +0 -68
- package/src/__tests__/plugin-skill-contribution.test.ts +0 -355
- package/src/daemon/message-types/browser.ts +0 -10
- package/src/notifications/__tests__/emit-signal-home-feed.test.ts +0 -187
- package/src/plugins/defaults/memory-v3-shadow/__tests__/fixtures/eval-turns.json +0 -36
- package/src/plugins/defaults/memory-v3-shadow/__tests__/fixtures/live-turns.json +0 -37
- package/src/plugins/defaults/memory-v3-shadow/__tests__/working-set-eviction.test.ts +0 -106
- package/src/plugins/defaults/memory-v3-shadow/__tests__/working-set-skeleton.test.ts +0 -44
- package/src/plugins/defaults/memory-v3-shadow/working-set.ts +0 -91
- package/src/plugins/external-api.ts +0 -114
- package/src/plugins/plugin-skill-contributions.ts +0 -292
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for the default `image-recovery` plugin's hooks.
|
|
3
|
+
*
|
|
4
|
+
* `post-model-call` (error-recovery):
|
|
5
|
+
* - On a provider rejection carrying an image-too-large error, the hook
|
|
6
|
+
* downscales the oversized image blocks in the working history (a text note
|
|
7
|
+
* when resize is a no-op on this host), persists the same downgrade durably,
|
|
8
|
+
* marks the per-conversation bound, and asks the loop to continue.
|
|
9
|
+
* - Bounded to one pass per turn via that bound: a second consecutive image
|
|
10
|
+
* rejection is left to surface (the bound is cleared by the `stop` hook, not
|
|
11
|
+
* here).
|
|
12
|
+
* - Ignores non-image errors, tool-bearing turns, and finalized (non-error)
|
|
13
|
+
* replies — none of which it ever touches the bound for.
|
|
14
|
+
*
|
|
15
|
+
* `stop` (terminal cleanup):
|
|
16
|
+
* - Clears the recovery bound unconditionally on the definitive terminal stop,
|
|
17
|
+
* so the next turn always recovers afresh no matter how the turn ended.
|
|
18
|
+
*
|
|
19
|
+
* Uses the real SQLite DB wired up via `test-preload.ts` (per-file temp
|
|
20
|
+
* workspace) so the durable-persist leg exercises the same path production does.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
import { beforeEach, describe, expect, test } from "bun:test";
|
|
24
|
+
|
|
25
|
+
import {
|
|
26
|
+
addMessage,
|
|
27
|
+
createConversation,
|
|
28
|
+
getMessages,
|
|
29
|
+
} from "../memory/conversation-crud.js";
|
|
30
|
+
import { getDb } from "../memory/db-connection.js";
|
|
31
|
+
import { initializeDb } from "../memory/db-init.js";
|
|
32
|
+
import { HOOKS } from "../plugin-api/constants.js";
|
|
33
|
+
import type {
|
|
34
|
+
PluginLogger,
|
|
35
|
+
PostModelCallContext,
|
|
36
|
+
StopContext,
|
|
37
|
+
} from "../plugin-api/types.js";
|
|
38
|
+
import postModelCall from "../plugins/defaults/image-recovery/hooks/post-model-call.js";
|
|
39
|
+
import stop from "../plugins/defaults/image-recovery/hooks/stop.js";
|
|
40
|
+
import {
|
|
41
|
+
clearImageRecoveryAttempted,
|
|
42
|
+
isImageRecoveryAttempted,
|
|
43
|
+
markImageRecoveryAttempted,
|
|
44
|
+
resetImageRecoveryStoreForTests,
|
|
45
|
+
} from "../plugins/defaults/image-recovery/image-recovery-state-store.js";
|
|
46
|
+
import { defaultImageRecoveryPlugin } from "../plugins/defaults/index.js";
|
|
47
|
+
import { runHook } from "../plugins/pipeline.js";
|
|
48
|
+
import {
|
|
49
|
+
registerPlugin,
|
|
50
|
+
resetPluginRegistryForTests,
|
|
51
|
+
} from "../plugins/registry.js";
|
|
52
|
+
import type { ContentBlock, Message } from "../providers/types.js";
|
|
53
|
+
|
|
54
|
+
initializeDb();
|
|
55
|
+
|
|
56
|
+
/** Provider rejection text matched by `isImageDimensionsTooLargeError`. */
|
|
57
|
+
const IMAGE_ERROR_MESSAGE =
|
|
58
|
+
"At least one of the image dimensions exceed max allowed size: 8000 pixels";
|
|
59
|
+
|
|
60
|
+
const PROVIDER_MAX_IMAGE_DIMENSION = 8000;
|
|
61
|
+
|
|
62
|
+
const noopLogger: PluginLogger = {
|
|
63
|
+
info: () => {},
|
|
64
|
+
warn: () => {},
|
|
65
|
+
error: () => {},
|
|
66
|
+
debug: () => {},
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
function resetTables(): void {
|
|
70
|
+
const db = getDb();
|
|
71
|
+
db.run("DELETE FROM message_attachments");
|
|
72
|
+
db.run("DELETE FROM attachments");
|
|
73
|
+
db.run("DELETE FROM memory_segments");
|
|
74
|
+
db.run("DELETE FROM memory_embeddings");
|
|
75
|
+
db.run("DELETE FROM messages");
|
|
76
|
+
db.run("DELETE FROM conversations");
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Build a minimal PNG whose IHDR declares the given dimensions. Only the 8-byte
|
|
81
|
+
* signature and width/height fields (read by `parseImageDimensions`) need to be
|
|
82
|
+
* correct — enough for the recovery path to classify the image as over the
|
|
83
|
+
* provider pixel cap. Depending on whether this host can re-encode the image,
|
|
84
|
+
* recovery either downscales it or replaces it with the unsendable note; the
|
|
85
|
+
* tests assert the rejected payload is gone rather than which of those landed.
|
|
86
|
+
*/
|
|
87
|
+
function makePngBase64(width: number, height: number): string {
|
|
88
|
+
return Buffer.from(
|
|
89
|
+
Uint8Array.from([
|
|
90
|
+
0x89,
|
|
91
|
+
0x50,
|
|
92
|
+
0x4e,
|
|
93
|
+
0x47,
|
|
94
|
+
0x0d,
|
|
95
|
+
0x0a,
|
|
96
|
+
0x1a,
|
|
97
|
+
0x0a, // PNG signature
|
|
98
|
+
0x00,
|
|
99
|
+
0x00,
|
|
100
|
+
0x00,
|
|
101
|
+
0x0d, // IHDR length (13)
|
|
102
|
+
0x49,
|
|
103
|
+
0x48,
|
|
104
|
+
0x44,
|
|
105
|
+
0x52, // "IHDR"
|
|
106
|
+
(width >>> 24) & 0xff,
|
|
107
|
+
(width >>> 16) & 0xff,
|
|
108
|
+
(width >>> 8) & 0xff,
|
|
109
|
+
width & 0xff,
|
|
110
|
+
(height >>> 24) & 0xff,
|
|
111
|
+
(height >>> 16) & 0xff,
|
|
112
|
+
(height >>> 8) & 0xff,
|
|
113
|
+
height & 0xff,
|
|
114
|
+
0x08,
|
|
115
|
+
0x06,
|
|
116
|
+
0x00,
|
|
117
|
+
0x00,
|
|
118
|
+
0x00, // bit depth / color type / etc.
|
|
119
|
+
]),
|
|
120
|
+
).toString("base64");
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function imageBlock(data: string): ContentBlock {
|
|
124
|
+
return {
|
|
125
|
+
type: "image",
|
|
126
|
+
source: { type: "base64", media_type: "image/png", data },
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/** A base64 PNG whose declared dimensions exceed the provider pixel cap. */
|
|
131
|
+
const OVERSIZED_IMAGE_DATA = makePngBase64(
|
|
132
|
+
PROVIDER_MAX_IMAGE_DIMENSION + 1000,
|
|
133
|
+
6000,
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
/** A user turn carrying an image past the provider pixel cap. */
|
|
137
|
+
function oversizedImageHistory(): Message[] {
|
|
138
|
+
return [
|
|
139
|
+
{
|
|
140
|
+
role: "user",
|
|
141
|
+
content: [
|
|
142
|
+
{ type: "text", text: "look at this" },
|
|
143
|
+
imageBlock(OVERSIZED_IMAGE_DATA),
|
|
144
|
+
],
|
|
145
|
+
},
|
|
146
|
+
];
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function makeStopCtx(overrides: Partial<StopContext> = {}): StopContext {
|
|
150
|
+
return {
|
|
151
|
+
conversationId: "conv-stop",
|
|
152
|
+
messages: [],
|
|
153
|
+
exitReason: "no_tool_calls",
|
|
154
|
+
logger: noopLogger,
|
|
155
|
+
...overrides,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function makePostModelCallCtx(
|
|
160
|
+
overrides: Partial<PostModelCallContext> = {},
|
|
161
|
+
): PostModelCallContext {
|
|
162
|
+
return {
|
|
163
|
+
conversationId: "conv-pmc",
|
|
164
|
+
callSite: "mainAgent",
|
|
165
|
+
content: [],
|
|
166
|
+
messages: [],
|
|
167
|
+
stopReason: null,
|
|
168
|
+
decision: "stop",
|
|
169
|
+
logger: noopLogger,
|
|
170
|
+
...overrides,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
describe("image-recovery post-model-call hook — direct", () => {
|
|
175
|
+
beforeEach(() => {
|
|
176
|
+
resetImageRecoveryStoreForTests();
|
|
177
|
+
resetTables();
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
test("recoverable image error → recovers oversized image and continues", async () => {
|
|
181
|
+
// GIVEN a provider rejection carrying an image-too-large error over a
|
|
182
|
+
// history with an oversized image block.
|
|
183
|
+
const messages = oversizedImageHistory();
|
|
184
|
+
const ctx = makePostModelCallCtx({
|
|
185
|
+
messages,
|
|
186
|
+
error: new Error(IMAGE_ERROR_MESSAGE),
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
// WHEN the hook runs.
|
|
190
|
+
await postModelCall(ctx);
|
|
191
|
+
|
|
192
|
+
// THEN it asks the loop to retry, marks the bound, and the oversized image
|
|
193
|
+
// is recovered — downscaled to a smaller image or collapsed to the
|
|
194
|
+
// unsendable note, depending on whether this host can resize — so the
|
|
195
|
+
// rejected payload is gone from the working history either way.
|
|
196
|
+
expect(ctx.decision).toBe("continue");
|
|
197
|
+
expect(isImageRecoveryAttempted(ctx.conversationId)).toBe(true);
|
|
198
|
+
expect(JSON.stringify(ctx.messages)).not.toContain(OVERSIZED_IMAGE_DATA);
|
|
199
|
+
// The accompanying text block is preserved — only the image is rewritten.
|
|
200
|
+
expect(ctx.messages[0].content).toContainEqual({
|
|
201
|
+
type: "text",
|
|
202
|
+
text: "look at this",
|
|
203
|
+
});
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
test("durably persists the downgrade so the image cannot resurface", async () => {
|
|
207
|
+
// GIVEN a conversation whose stored history holds an oversized image.
|
|
208
|
+
const conv = createConversation();
|
|
209
|
+
await addMessage(
|
|
210
|
+
conv.id,
|
|
211
|
+
"user",
|
|
212
|
+
JSON.stringify([
|
|
213
|
+
{ type: "text", text: "look at this" },
|
|
214
|
+
imageBlock(OVERSIZED_IMAGE_DATA),
|
|
215
|
+
]),
|
|
216
|
+
{ skipIndexing: true },
|
|
217
|
+
);
|
|
218
|
+
const ctx = makePostModelCallCtx({
|
|
219
|
+
conversationId: conv.id,
|
|
220
|
+
messages: oversizedImageHistory(),
|
|
221
|
+
error: new Error(IMAGE_ERROR_MESSAGE),
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
// WHEN the hook recovers the rejection.
|
|
225
|
+
await postModelCall(ctx);
|
|
226
|
+
|
|
227
|
+
// THEN the stored row no longer holds the oversized payload — it was
|
|
228
|
+
// rewritten (downscaled or replaced with the unsendable note) so a later
|
|
229
|
+
// turn cannot rehydrate the rejected upload from the DB.
|
|
230
|
+
expect(getMessages(conv.id)[0].content).not.toContain(OVERSIZED_IMAGE_DATA);
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
test("second consecutive image rejection is left to surface", async () => {
|
|
234
|
+
// GIVEN a turn whose first image rejection already triggered a recovery.
|
|
235
|
+
const conversationId = "conv-bounded";
|
|
236
|
+
markImageRecoveryAttempted(conversationId);
|
|
237
|
+
const messages = oversizedImageHistory();
|
|
238
|
+
const ctx = makePostModelCallCtx({
|
|
239
|
+
conversationId,
|
|
240
|
+
messages,
|
|
241
|
+
error: new Error(IMAGE_ERROR_MESSAGE),
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
// WHEN a second image rejection reaches the hook.
|
|
245
|
+
await postModelCall(ctx);
|
|
246
|
+
|
|
247
|
+
// THEN it does not recover again — the error surfaces.
|
|
248
|
+
expect(ctx.decision).toBe("stop");
|
|
249
|
+
expect(ctx.messages).toEqual(messages);
|
|
250
|
+
|
|
251
|
+
// AND the bound stays marked — the hook never clears it; the `stop` hook
|
|
252
|
+
// clears it at the turn boundary.
|
|
253
|
+
expect(isImageRecoveryAttempted(conversationId)).toBe(true);
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
test("a mid-turn tool-bearing turn is a no-op", async () => {
|
|
257
|
+
// GIVEN this turn already recovered an image rejection (bound marked), then
|
|
258
|
+
// the model returns a tool-bearing turn that the loop continues mid-run.
|
|
259
|
+
const conversationId = "conv-tool-turn";
|
|
260
|
+
markImageRecoveryAttempted(conversationId);
|
|
261
|
+
const ctx = makePostModelCallCtx({
|
|
262
|
+
conversationId,
|
|
263
|
+
content: [{ type: "tool_use", id: "tu_1", name: "do", input: {} }],
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
// WHEN the hook runs on that tool-bearing turn.
|
|
267
|
+
await postModelCall(ctx);
|
|
268
|
+
|
|
269
|
+
// THEN it leaves the bound alone — there is no provider rejection to act on.
|
|
270
|
+
expect(isImageRecoveryAttempted(conversationId)).toBe(true);
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
test("a non-image error while continuing is a no-op", async () => {
|
|
274
|
+
// GIVEN this turn already recovered an image rejection (bound marked), then
|
|
275
|
+
// an earlier hook (e.g. history-repair on an ordering rejection) recovered a
|
|
276
|
+
// different error and set the decision to continue.
|
|
277
|
+
const conversationId = "conv-cross-hook";
|
|
278
|
+
markImageRecoveryAttempted(conversationId);
|
|
279
|
+
const ctx = makePostModelCallCtx({
|
|
280
|
+
conversationId,
|
|
281
|
+
decision: "continue",
|
|
282
|
+
error: new Error("messages: roles must alternate"),
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
// WHEN the image-recovery hook runs after that earlier hook.
|
|
286
|
+
await postModelCall(ctx);
|
|
287
|
+
|
|
288
|
+
// THEN it leaves the in-flight continue and the bound alone — it only acts
|
|
289
|
+
// on an image-too-large rejection.
|
|
290
|
+
expect(ctx.decision).toBe("continue");
|
|
291
|
+
expect(isImageRecoveryAttempted(conversationId)).toBe(true);
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
test("non-image error is left untouched", async () => {
|
|
295
|
+
// GIVEN a provider rejection that is not an image-size violation.
|
|
296
|
+
const messages = oversizedImageHistory();
|
|
297
|
+
const ctx = makePostModelCallCtx({
|
|
298
|
+
messages,
|
|
299
|
+
error: new Error("rate limit exceeded"),
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
// WHEN the hook runs.
|
|
303
|
+
await postModelCall(ctx);
|
|
304
|
+
|
|
305
|
+
// THEN it defers — the decision and history are unchanged.
|
|
306
|
+
expect(ctx.decision).toBe("stop");
|
|
307
|
+
expect(ctx.messages).toEqual(messages);
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
test("finalized (non-error) reply is ignored", async () => {
|
|
311
|
+
// GIVEN a finalized reply — the model returned content, no error.
|
|
312
|
+
const messages = oversizedImageHistory();
|
|
313
|
+
const ctx = makePostModelCallCtx({
|
|
314
|
+
messages,
|
|
315
|
+
content: [{ type: "text", text: "done" }],
|
|
316
|
+
stopReason: "end_turn",
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
// WHEN the hook runs.
|
|
320
|
+
await postModelCall(ctx);
|
|
321
|
+
|
|
322
|
+
// THEN the model response is left untouched — recovery only applies to
|
|
323
|
+
// image rejections.
|
|
324
|
+
expect(ctx.decision).toBe("stop");
|
|
325
|
+
expect(ctx.messages).toEqual(messages);
|
|
326
|
+
});
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
// ─── stop hook (terminal cleanup) ────────────────────────────────────────────
|
|
330
|
+
|
|
331
|
+
describe("image-recovery stop hook — direct", () => {
|
|
332
|
+
beforeEach(() => {
|
|
333
|
+
resetImageRecoveryStoreForTests();
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
test("a terminal stop clears the recovery bound", async () => {
|
|
337
|
+
// GIVEN a turn marked a recovery-retry.
|
|
338
|
+
const conversationId = "conv-backstop";
|
|
339
|
+
markImageRecoveryAttempted(conversationId);
|
|
340
|
+
|
|
341
|
+
// WHEN the terminal stop hook runs.
|
|
342
|
+
await stop(makeStopCtx({ conversationId }));
|
|
343
|
+
|
|
344
|
+
// THEN the bound is cleared so the next turn recovers afresh.
|
|
345
|
+
expect(isImageRecoveryAttempted(conversationId)).toBe(false);
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
test("clears the bound regardless of how the turn ended", async () => {
|
|
349
|
+
// GIVEN a turn marked a recovery-retry that ends on an abort rather than a
|
|
350
|
+
// finalized reply.
|
|
351
|
+
const conversationId = "conv-abort";
|
|
352
|
+
markImageRecoveryAttempted(conversationId);
|
|
353
|
+
|
|
354
|
+
// WHEN the terminal stop hook runs for that exit.
|
|
355
|
+
await stop(makeStopCtx({ conversationId, exitReason: "aborted_pre_call" }));
|
|
356
|
+
|
|
357
|
+
// THEN the bound is still cleared — `stop` is the definitive terminal, so
|
|
358
|
+
// the next turn always recovers afresh.
|
|
359
|
+
expect(isImageRecoveryAttempted(conversationId)).toBe(false);
|
|
360
|
+
});
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
describe("image-recovery post-model-call hook — via runHook", () => {
|
|
364
|
+
beforeEach(() => {
|
|
365
|
+
resetPluginRegistryForTests();
|
|
366
|
+
resetImageRecoveryStoreForTests();
|
|
367
|
+
resetTables();
|
|
368
|
+
clearImageRecoveryAttempted("conv-pmc");
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
test("registering the default plugin recovers an image rejection", async () => {
|
|
372
|
+
// GIVEN the default image-recovery plugin is registered.
|
|
373
|
+
registerPlugin(defaultImageRecoveryPlugin);
|
|
374
|
+
const messages = oversizedImageHistory();
|
|
375
|
+
|
|
376
|
+
// WHEN the post-model-call chain runs on an image-too-large rejection.
|
|
377
|
+
const result = await runHook<PostModelCallContext>(
|
|
378
|
+
HOOKS.POST_MODEL_CALL,
|
|
379
|
+
makePostModelCallCtx({ messages, error: new Error(IMAGE_ERROR_MESSAGE) }),
|
|
380
|
+
);
|
|
381
|
+
|
|
382
|
+
// THEN the working history is recovered (the rejected payload is gone) and
|
|
383
|
+
// the loop is asked to retry.
|
|
384
|
+
expect(result.decision).toBe("continue");
|
|
385
|
+
expect(JSON.stringify(result.messages)).not.toContain(OVERSIZED_IMAGE_DATA);
|
|
386
|
+
});
|
|
387
|
+
});
|
|
@@ -342,16 +342,17 @@ describe("injector chain", () => {
|
|
|
342
342
|
expect(byName.get("thread-focus")).toBe(DEFAULT_INJECTOR_ORDER.threadFocus);
|
|
343
343
|
});
|
|
344
344
|
|
|
345
|
-
test("the injector chain sorts the defaults plus memory-v3 by ascending order", () => {
|
|
346
|
-
// The assembled chain merges the defaults with the memory-v3
|
|
347
|
-
// sorts by `order`, so
|
|
345
|
+
test("the injector chain sorts the defaults plus the memory-v3 injectors by ascending order", () => {
|
|
346
|
+
// The assembled chain merges the defaults with the two memory-v3
|
|
347
|
+
// injectors and sorts by `order`, so the cards injector (order 1000) and
|
|
348
|
+
// the spotlight injector (order 1001) sit last, in that order.
|
|
348
349
|
const chain = getInjectorChain();
|
|
349
350
|
const orders = chain.map((i) => i.order);
|
|
350
351
|
expect(orders).toEqual([...orders].sort((a, b) => a - b));
|
|
351
|
-
expect(chain[chain.length - 1]?.name).toBe("memory-v3-shadow");
|
|
352
352
|
expect(chain.map((i) => i.name)).toEqual([
|
|
353
353
|
...defaultInjectors.map((i) => i.name),
|
|
354
354
|
"memory-v3-shadow",
|
|
355
|
+
"memory-v3-spotlight",
|
|
355
356
|
]);
|
|
356
357
|
});
|
|
357
358
|
|