@vellumai/assistant 0.8.7-dev.202606052232.2ddc989 → 0.8.8
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 +2 -2
- package/docs/plugins.md +832 -0
- package/examples/plugins/echo/README.md +60 -61
- package/examples/plugins/echo/package.json +2 -1
- package/examples/plugins/echo/register.ts +143 -0
- package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +6 -7
- package/openapi.yaml +5 -15
- package/package.json +2 -2
- package/src/__tests__/agent-loop-exit-reason.test.ts +56 -3
- package/src/__tests__/anthropic-provider.test.ts +1 -1
- package/src/__tests__/app-control-flow.test.ts +1 -1
- package/src/__tests__/app-dir-path-guard.test.ts +0 -1
- package/src/__tests__/approval-routes-http.test.ts +1 -4
- package/src/__tests__/channel-approval-routes.test.ts +1 -1
- package/src/__tests__/channel-approvals.test.ts +1 -1
- package/src/__tests__/circuit-breaker-pipeline.test.ts +405 -0
- package/src/__tests__/compaction-pipeline.test.ts +210 -0
- package/src/__tests__/compaction-timeout-recovery.test.ts +251 -0
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +3 -0
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +3 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +7 -3
- package/src/__tests__/conversation-agent-loop.test.ts +39 -42
- package/src/__tests__/conversation-clean-command.test.ts +2 -5
- package/src/__tests__/conversation-provider-retry-repair.test.ts +5 -4
- package/src/__tests__/conversation-runtime-assembly.test.ts +71 -140
- package/src/__tests__/conversation-runtime-workspace.test.ts +27 -108
- package/src/__tests__/conversation-starter-routes.test.ts +6 -14
- package/src/__tests__/conversation-workspace-cache-state.test.ts +16 -17
- package/src/__tests__/conversation-workspace-injection.test.ts +1 -61
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +6 -7
- package/src/__tests__/db-acp-history.test.ts +0 -101
- package/src/__tests__/dynamic-page-surface.test.ts +0 -31
- package/src/__tests__/file-write-tool.test.ts +0 -63
- package/src/__tests__/gateway-only-guard.test.ts +2 -12
- package/src/__tests__/guardian-grant-minting.test.ts +1 -1
- package/src/__tests__/guardian-routing-invariants.test.ts +4 -2
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +1 -1
- package/src/__tests__/heartbeat-disk-pressure.test.ts +0 -1
- package/src/__tests__/heartbeat-service.test.ts +0 -1
- package/src/__tests__/host-app-control-routes.test.ts +1 -1
- package/src/__tests__/host-cu-routes-targeted.test.ts +3 -3
- package/src/__tests__/injector-background-turn.test.ts +1 -1
- package/src/__tests__/injector-chain.test.ts +6 -34
- package/src/__tests__/injector-disk-pressure.test.ts +34 -77
- package/src/__tests__/injector-document-comments.test.ts +1 -1
- package/src/__tests__/list-messages-hidden-metadata.test.ts +0 -38
- package/src/__tests__/memory-v2-static-injector.test.ts +1 -1
- package/src/__tests__/{overflow-reduction-loop.test.ts → overflow-reduce-pipeline.test.ts} +284 -64
- package/src/__tests__/pipeline-runner.test.ts +554 -0
- package/src/__tests__/plugin-api-shim.test.ts +6 -3
- package/src/__tests__/plugin-bootstrap.test.ts +23 -12
- package/src/__tests__/plugin-registry.test.ts +49 -3
- package/src/__tests__/plugin-types.test.ts +70 -0
- package/src/__tests__/reaction-persistence.test.ts +1 -1
- package/src/__tests__/send-endpoint-busy.test.ts +1 -4
- package/src/__tests__/skill-feature-flags-integration.test.ts +0 -33
- package/src/__tests__/subagent-call-site-routing.test.ts +1 -1
- package/src/__tests__/subagent-fork-notifications.test.ts +3 -1
- package/src/__tests__/subagent-fork-spawn.test.ts +1 -1
- package/src/__tests__/subagent-manager-notify.test.ts +3 -1
- package/src/__tests__/subagent-notify-parent.test.ts +3 -1
- package/src/__tests__/subagent-spawn-tool-fork.test.ts +1 -1
- package/src/__tests__/user-plugin-loader.test.ts +286 -54
- package/src/acp/__tests__/client-handler.test.ts +0 -40
- package/src/acp/__tests__/prepare-agent-env.test.ts +0 -137
- package/src/acp/__tests__/session-manager-persistence.test.ts +28 -95
- package/src/acp/agent-process.ts +1 -61
- package/src/acp/client-handler.ts +0 -31
- package/src/acp/prepare-agent-env.ts +29 -83
- package/src/acp/resolve-agent.test.ts +7 -320
- package/src/acp/resolve-agent.ts +18 -182
- package/src/acp/session-manager.ts +73 -495
- package/src/acp/types.ts +0 -8
- package/src/agent/compaction-circuit.ts +102 -60
- package/src/agent/loop.ts +59 -32
- package/src/api/responses/conversation-message.ts +1 -7
- package/src/approvals/guardian-request-resolvers.ts +1 -1
- package/src/background-wake/next-wake.ts +0 -1
- package/src/config/__tests__/feature-flag-registry-guard.test.ts +2 -2
- package/src/config/acp-defaults.test.ts +0 -10
- package/src/config/acp-defaults.ts +0 -6
- package/src/config/bundled-skills/acp/SKILL.md +31 -83
- package/src/config/bundled-skills/acp/TOOLS.json +4 -4
- package/src/config/bundled-skills/app-builder/SKILL.md +381 -224
- package/src/config/bundled-skills/app-builder/TOOLS.json +0 -29
- package/src/config/bundled-skills/document-editor/SKILL.md +23 -28
- package/src/config/bundled-skills/document-editor/TOOLS.json +1 -1
- package/src/config/bundled-tool-registry.ts +0 -2
- package/src/config/feature-flag-registry.json +5 -14
- package/src/config/schemas/heartbeat.ts +0 -9
- package/src/context/strip-injections.ts +2 -8
- package/src/context/window-manager.ts +1 -2
- package/src/daemon/conversation-agent-loop-handlers.ts +11 -0
- package/src/daemon/conversation-agent-loop.ts +279 -62
- package/src/daemon/conversation-runtime-assembly.ts +69 -106
- package/src/daemon/conversation-store.ts +90 -9
- package/src/daemon/conversation-workspace.ts +0 -17
- package/src/daemon/conversation.ts +6 -0
- package/src/daemon/external-plugins-bootstrap.ts +11 -11
- package/src/daemon/handlers/conversations.ts +1 -3
- package/src/daemon/handlers/skills.ts +1 -4
- package/src/daemon/lifecycle.ts +0 -21
- package/src/daemon/server.ts +0 -2
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +0 -3
- package/src/heartbeat/heartbeat-run-store.ts +1 -23
- package/src/heartbeat/heartbeat-service.ts +0 -26
- package/src/ipc/__tests__/browser-ipc.test.ts +1 -1
- package/src/ipc/__tests__/ui-request-route.test.ts +3 -3
- package/src/ipc/skill-routes/__tests__/memory.test.ts +0 -15
- package/src/ipc/skill-routes/memory.ts +2 -4
- package/src/memory/conversation-starter-checkpoints.ts +0 -1
- package/src/memory/db-init.ts +0 -2
- package/src/memory/job-handlers/conversation-starters.ts +2 -13
- package/src/memory/jobs-worker.ts +1 -1
- package/src/memory/migrations/index.ts +0 -1
- package/src/memory/schema/acp.ts +0 -4
- package/src/memory/v2/__tests__/consolidation-job.test.ts +3 -3
- package/src/memory/v2/consolidation-job.ts +4 -13
- package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/assign.test.ts +4 -4
- package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/live-integration.test.ts +4 -4
- package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/maintain-job.test.ts +5 -5
- package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/orchestrate.test.ts +3 -3
- package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/reconcile.test.ts +2 -2
- package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/render-injection.test.ts +1 -1
- package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/router.test.ts +3 -3
- package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/selection-log-store.test.ts +8 -8
- package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/selector.test.ts +3 -3
- package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/shadow-plugin.test.ts +12 -12
- package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/assign.ts +5 -5
- package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/capabilities.ts +2 -2
- package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/maintain-job.ts +8 -8
- package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/page-content.ts +2 -2
- package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/provider-blocks.ts +1 -1
- package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/reconcile.ts +3 -3
- package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/render-injection.ts +1 -1
- package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/router.ts +3 -3
- package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/selection-log-store.ts +4 -4
- package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/selector.ts +4 -4
- package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/shadow-plugin.ts +90 -28
- package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/tree.ts +1 -1
- package/src/plugin-api/index.ts +5 -0
- package/src/plugins/defaults/circuit-breaker/middlewares/circuitBreaker.ts +93 -0
- package/src/plugins/defaults/{memory-v3-shadow → circuit-breaker}/package.json +2 -2
- package/src/plugins/defaults/circuit-breaker/register.ts +39 -0
- package/src/plugins/defaults/compaction/middlewares/compaction.ts +25 -0
- package/src/plugins/defaults/compaction/package.json +1 -1
- package/src/plugins/defaults/compaction/register.ts +19 -8
- package/src/plugins/defaults/compaction/terminal.ts +73 -0
- package/src/plugins/defaults/index.ts +5 -3
- package/src/plugins/defaults/{memory-retrieval/injectors.ts → injectors/register.ts} +7 -45
- package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +7 -11
- package/src/plugins/defaults/memory-retrieval/injector-chain.ts +2 -2
- package/src/plugins/defaults/overflow-reduce/middlewares/overflowReduce.ts +126 -0
- package/src/plugins/defaults/overflow-reduce/package.json +15 -0
- package/src/plugins/defaults/overflow-reduce/register.ts +42 -0
- package/src/plugins/external-api.ts +2 -2
- package/src/plugins/pipeline.ts +293 -6
- package/src/plugins/registry.ts +37 -9
- package/src/plugins/types.ts +336 -32
- package/src/plugins/user-loader.ts +127 -30
- package/src/proactive-artifact/aux-message-injector.ts +1 -1
- package/src/proactive-artifact/job.test.ts +1 -1
- package/src/prompts/__tests__/system-prompt.test.ts +0 -6
- package/src/prompts/templates/BOOTSTRAP-ACTIVATION-RAIL.md +2 -4
- package/src/runtime/__tests__/agent-wake.test.ts +5 -5
- package/src/runtime/__tests__/interactive-ui.test.ts +1 -1
- package/src/runtime/agent-wake.ts +3 -0
- package/src/runtime/assistant-event-hub.ts +1 -1
- package/src/runtime/channel-approvals.ts +1 -1
- package/src/runtime/interactive-ui.ts +1 -1
- package/src/runtime/routes/__tests__/acp-routes.test.ts +55 -283
- package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/surface-action-routes.test.ts +4 -5
- package/src/runtime/routes/__tests__/surface-content-routes.test.ts +1 -4
- package/src/runtime/routes/acp-routes.test.ts +25 -89
- package/src/runtime/routes/acp-routes.ts +29 -81
- package/src/runtime/routes/approval-routes.ts +1 -1
- package/src/runtime/routes/browser-routes.ts +1 -1
- package/src/runtime/routes/browser-tabs-routes.ts +10 -6
- package/src/runtime/routes/conversation-cli-routes.ts +1 -1
- package/src/runtime/routes/conversation-list-routes.ts +1 -1
- package/src/runtime/routes/conversation-query-routes.ts +1 -1
- package/src/runtime/routes/conversation-routes.ts +2 -15
- package/src/runtime/routes/conversation-starter-routes.ts +7 -13
- package/src/runtime/routes/conversations-import-routes.ts +7 -24
- package/src/runtime/routes/host-app-control-routes.ts +1 -1
- package/src/runtime/routes/host-cu-routes.ts +1 -1
- package/src/runtime/routes/identity-routes.ts +3 -18
- package/src/runtime/routes/inbound-message-handler.ts +1 -1
- package/src/runtime/routes/memory-v3-routes.ts +6 -16
- package/src/runtime/routes/playground/helpers.ts +1 -1
- package/src/runtime/routes/surface-conversation-resolver.ts +3 -4
- package/src/runtime/routes/work-items-routes.ts +4 -2
- package/src/runtime/services/conversation-serializer.ts +1 -1
- package/src/signals/cancel.ts +4 -2
- package/src/subagent/manager.ts +5 -17
- package/src/tools/acp/list-agents.test.ts +1 -7
- package/src/tools/acp/spawn.test.ts +55 -158
- package/src/tools/acp/spawn.ts +72 -47
- package/src/tools/acp/steer.test.ts +8 -105
- package/src/tools/acp/steer.ts +17 -48
- package/src/tools/apps/executors.ts +8 -13
- package/src/tools/filesystem/write.ts +0 -34
- package/src/tools/subagent/spawn.ts +4 -2
- package/src/tools/ui-surface/definitions.ts +4 -25
- package/src/workspace/migrations/051-seed-conversation-summarization-callsite.ts +5 -4
- package/src/workspace/migrations/097-enable-adaptive-thinking-managed-profiles.ts +45 -69
- package/examples/plugins/echo/hooks/post-tool-use.ts +0 -18
- package/examples/plugins/echo/hooks/stop.ts +0 -16
- package/examples/plugins/echo/hooks/user-prompt-submit.ts +0 -18
- package/examples/plugins/echo/src/emit.ts +0 -19
- package/src/__tests__/compaction-circuit.test.ts +0 -258
- package/src/__tests__/compaction-direct.test.ts +0 -132
- package/src/__tests__/conversations-import-system-filter.test.ts +0 -101
- package/src/acp/__tests__/agent-process.test.ts +0 -161
- package/src/acp/__tests__/helpers/acp-history-db.ts +0 -82
- package/src/acp/__tests__/helpers/exec-file-stub.ts +0 -101
- package/src/acp/__tests__/session-manager-resume.test.ts +0 -736
- package/src/acp/auto-install.test.ts +0 -196
- package/src/acp/auto-install.ts +0 -177
- package/src/acp/feature-gate.test.ts +0 -48
- package/src/acp/feature-gate.ts +0 -34
- package/src/acp/resume-hint.ts +0 -25
- package/src/config/bundled-skills/app-builder/references/DESIGN_SYSTEM.md +0 -48
- package/src/config/bundled-skills/app-builder/references/RESPONSIVE.md +0 -57
- package/src/config/bundled-skills/app-builder/references/SLIDES.md +0 -38
- package/src/config/bundled-skills/app-builder/tools/app-list.ts +0 -62
- package/src/daemon/conversation-registry.ts +0 -159
- package/src/daemon/overflow-reduction-loop.ts +0 -230
- package/src/memory/migrations/272-acp-session-history-cwd.ts +0 -36
- package/src/plugins/defaults/compaction/compact.ts +0 -59
- package/src/plugins/defaults/memory-v3-shadow/hooks/post-compact.ts +0 -14
- package/src/plugins/defaults/memory-v3-shadow/hooks/user-prompt-submit.ts +0 -19
- package/src/plugins/defaults/memory-v3-shadow/injector.ts +0 -75
- package/src/plugins/defaults/memory-v3-shadow/register.ts +0 -26
- package/src/tools/acp/context.ts +0 -20
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/capabilities.test.ts +0 -0
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/core.test.ts +0 -0
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/fixtures/eval-turns.json +0 -0
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/fixtures/live-turns.json +0 -0
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/health.test.ts +0 -0
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/needle.test.ts +0 -0
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/provider-blocks.test.ts +0 -0
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/snapshot.test.ts +0 -0
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/tree.test.ts +0 -0
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/types.test.ts +0 -0
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/working-set-eviction.test.ts +0 -0
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/working-set-skeleton.test.ts +0 -0
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/core.ts +0 -0
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/data/README.md +0 -0
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/data/assignments.json +0 -0
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/data/core.json +0 -0
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/data/leaves/domain-a/topic-x.md +0 -0
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/data/leaves/domain-a/topic-y.md +0 -0
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/data/leaves/domain-b/topic-z.md +0 -0
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/health.ts +0 -0
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/llm-retry.ts +0 -0
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/needle.ts +0 -0
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/orchestrate.ts +0 -0
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/snapshot.ts +0 -0
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/types.ts +0 -0
- /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/working-set.ts +0 -0
|
@@ -41,28 +41,20 @@ mock.module("../config/loader.js", () => ({
|
|
|
41
41
|
const { applyRuntimeInjections, composeInjectorChain } =
|
|
42
42
|
await import("../daemon/conversation-runtime-assembly.js");
|
|
43
43
|
const { DEFAULT_INJECTOR_ORDER, defaultInjectors } =
|
|
44
|
-
await import("../plugins/defaults/
|
|
44
|
+
await import("../plugins/defaults/injectors/register.js");
|
|
45
45
|
const { getInjectorChain } =
|
|
46
46
|
await import("../plugins/defaults/memory-retrieval/injector-chain.js");
|
|
47
|
-
import {
|
|
48
|
-
clearConversations,
|
|
49
|
-
setConversation,
|
|
50
|
-
} from "../daemon/conversation-registry.js";
|
|
51
47
|
import { buildPkbReminder } from "../daemon/pkb-reminder-builder.js";
|
|
52
48
|
import { getPkbRoot } from "../memory/pkb/types.js";
|
|
53
49
|
import type { TurnContext } from "../plugins/types.js";
|
|
54
50
|
import type { Message } from "../providers/types.js";
|
|
55
51
|
import { getWorkspacePromptPath } from "../util/platform.js";
|
|
56
52
|
|
|
57
|
-
// `makeTurnContext` and the workspace registry seed share this id so the
|
|
58
|
-
// `workspace-context` injector resolves the seeded block for the turn.
|
|
59
|
-
const TEST_CONVERSATION_ID = "conv-test-1";
|
|
60
|
-
|
|
61
53
|
/** A fake TurnContext sufficient for driving `composeInjectorChain`. */
|
|
62
54
|
function makeTurnContext(): TurnContext {
|
|
63
55
|
return {
|
|
64
56
|
requestId: "req-test-1",
|
|
65
|
-
conversationId:
|
|
57
|
+
conversationId: "conv-test-1",
|
|
66
58
|
turnIndex: 0,
|
|
67
59
|
trust: {
|
|
68
60
|
sourceChannel: "vellum",
|
|
@@ -102,25 +94,10 @@ function clearNowScratchpad(): void {
|
|
|
102
94
|
rmSync(getWorkspacePromptPath("NOW.md"), { force: true });
|
|
103
95
|
}
|
|
104
96
|
|
|
105
|
-
// The workspace-context injector sources its block off the live `Conversation`
|
|
106
|
-
// looked up by `conversationId`. Seed a fake instance carrying a non-dirty
|
|
107
|
-
// workspace cache under the id `makeTurnContext()` uses so the injector emits
|
|
108
|
-
// the block; `clearConversations()` between tests keeps suites that assert the
|
|
109
|
-
// workspace block is absent unaffected.
|
|
110
|
-
function seedWorkspaceContext(text: string): void {
|
|
111
|
-
setConversation(TEST_CONVERSATION_ID, {
|
|
112
|
-
conversationId: TEST_CONVERSATION_ID,
|
|
113
|
-
workingDir: "/sandbox",
|
|
114
|
-
workspaceTopLevelContext: text,
|
|
115
|
-
workspaceTopLevelDirty: false,
|
|
116
|
-
} as never);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
97
|
describe("injector chain", () => {
|
|
120
98
|
beforeEach(() => {
|
|
121
99
|
clearPkbContent();
|
|
122
100
|
clearNowScratchpad();
|
|
123
|
-
clearConversations();
|
|
124
101
|
});
|
|
125
102
|
|
|
126
103
|
test("defaultInjectors lists the defaults in the documented order", () => {
|
|
@@ -276,9 +253,9 @@ describe("injector chain", () => {
|
|
|
276
253
|
const subagentBlock =
|
|
277
254
|
'<active_subagents>\n- [running] "worker" (sub-1) | elapsed: 5s\n</active_subagents>';
|
|
278
255
|
|
|
279
|
-
seedWorkspaceContext(workspaceText);
|
|
280
256
|
const result = await applyRuntimeInjections(runMessages, {
|
|
281
257
|
turnContext: makeTurnContext(),
|
|
258
|
+
workspaceTopLevelContext: workspaceText,
|
|
282
259
|
unifiedTurnContext: unifiedTurn,
|
|
283
260
|
subagentStatusBlock: subagentBlock,
|
|
284
261
|
});
|
|
@@ -350,11 +327,8 @@ describe("injector chain", () => {
|
|
|
350
327
|
},
|
|
351
328
|
];
|
|
352
329
|
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
workingDir: "/sandbox",
|
|
356
|
-
workspaceTopLevelContext: "",
|
|
357
|
-
workspaceTopLevelDirty: false,
|
|
330
|
+
const result = await applyRuntimeInjections(originalRun, {
|
|
331
|
+
turnContext: makeTurnContext(),
|
|
358
332
|
channelCapabilities: {
|
|
359
333
|
channel: "slack",
|
|
360
334
|
dashboardCapable: false,
|
|
@@ -362,9 +336,6 @@ describe("injector chain", () => {
|
|
|
362
336
|
supportsVoiceInput: false,
|
|
363
337
|
chatType: "channel",
|
|
364
338
|
},
|
|
365
|
-
} as never);
|
|
366
|
-
const result = await applyRuntimeInjections(originalRun, {
|
|
367
|
-
turnContext: makeTurnContext(),
|
|
368
339
|
slackChronologicalMessages: slackTranscript,
|
|
369
340
|
});
|
|
370
341
|
|
|
@@ -402,6 +373,7 @@ describe("injector chain", () => {
|
|
|
402
373
|
{
|
|
403
374
|
turnContext: makeTurnContext(),
|
|
404
375
|
mode: "minimal",
|
|
376
|
+
workspaceTopLevelContext: "<workspace>...</workspace>",
|
|
405
377
|
unifiedTurnContext: "<turn_context>...</turn_context>",
|
|
406
378
|
subagentStatusBlock: "<active_subagents>...</active_subagents>",
|
|
407
379
|
},
|
|
@@ -1,10 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
clearConversations,
|
|
5
|
-
setConversation,
|
|
6
|
-
} from "../daemon/conversation-registry.js";
|
|
7
|
-
import type { ChannelCapabilities } from "../daemon/conversation-runtime-assembly.js";
|
|
8
3
|
import {
|
|
9
4
|
applyRuntimeInjections,
|
|
10
5
|
stripInjectionsForCompaction,
|
|
@@ -13,14 +8,10 @@ import {
|
|
|
13
8
|
DEFAULT_INJECTOR_ORDER,
|
|
14
9
|
defaultInjectors,
|
|
15
10
|
DISK_PRESSURE_WARNING_PROMPT,
|
|
16
|
-
} from "../plugins/defaults/
|
|
11
|
+
} from "../plugins/defaults/injectors/register.js";
|
|
17
12
|
import type { Injector, TurnContext } from "../plugins/types.js";
|
|
18
13
|
import type { Message } from "../providers/types.js";
|
|
19
14
|
|
|
20
|
-
// `makeContext` and the workspace registry seed share this id so the
|
|
21
|
-
// `workspace-context` injector resolves the seeded block for the turn.
|
|
22
|
-
const TEST_CONVERSATION_ID = "conv-test";
|
|
23
|
-
|
|
24
15
|
function findInjector(name: string): Injector {
|
|
25
16
|
const injector = defaultInjectors.find(
|
|
26
17
|
(candidate) => candidate.name === name,
|
|
@@ -34,7 +25,7 @@ function findInjector(name: string): Injector {
|
|
|
34
25
|
function makeContext(overrides: Partial<TurnContext> = {}): TurnContext {
|
|
35
26
|
return {
|
|
36
27
|
requestId: "req-test",
|
|
37
|
-
conversationId:
|
|
28
|
+
conversationId: "conv-test",
|
|
38
29
|
turnIndex: 0,
|
|
39
30
|
trust: { sourceChannel: "vellum", trustClass: "guardian" },
|
|
40
31
|
...overrides,
|
|
@@ -52,58 +43,15 @@ function tailTexts(messages: Message[]): string[] {
|
|
|
52
43
|
}
|
|
53
44
|
|
|
54
45
|
const diskPressureInjector = findInjector("disk-pressure-warning");
|
|
55
|
-
|
|
56
|
-
// The disk-pressure-warning and workspace-context injectors both read their
|
|
57
|
-
// per-conversation state off the live `Conversation` looked up by
|
|
58
|
-
// `conversationId`. Seed a single fake instance under the id `makeContext()`
|
|
59
|
-
// uses, carrying the disk-pressure flag and the workspace top-level cache, so a
|
|
60
|
-
// turn can exercise both; the seed helpers mutate and re-register the same
|
|
61
|
-
// instance. An empty (non-dirty) workspace cache resolves to no block, so
|
|
62
|
-
// disk-pressure-only tests don't trigger a directory scan.
|
|
63
|
-
let liveConversation: {
|
|
64
|
-
conversationId: string;
|
|
65
|
-
workingDir: string;
|
|
66
|
-
workspaceTopLevelContext: string | null;
|
|
67
|
-
workspaceTopLevelDirty: boolean;
|
|
68
|
-
diskPressureCleanupModeActive: boolean;
|
|
69
|
-
channelCapabilities?: ChannelCapabilities;
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
function resetLiveConversation(): void {
|
|
73
|
-
liveConversation = {
|
|
74
|
-
conversationId: TEST_CONVERSATION_ID,
|
|
75
|
-
workingDir: "/workspace",
|
|
76
|
-
workspaceTopLevelContext: "",
|
|
77
|
-
workspaceTopLevelDirty: false,
|
|
78
|
-
diskPressureCleanupModeActive: false,
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
function seedChannelCapabilities(caps: ChannelCapabilities): void {
|
|
83
|
-
liveConversation.channelCapabilities = caps;
|
|
84
|
-
setConversation(TEST_CONVERSATION_ID, liveConversation as never);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
function seedDiskPressure(cleanupModeActive: boolean): void {
|
|
88
|
-
liveConversation.diskPressureCleanupModeActive = cleanupModeActive;
|
|
89
|
-
setConversation(TEST_CONVERSATION_ID, liveConversation as never);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
function seedWorkspaceContext(text: string): void {
|
|
93
|
-
liveConversation.workspaceTopLevelContext = text;
|
|
94
|
-
liveConversation.workspaceTopLevelDirty = false;
|
|
95
|
-
setConversation(TEST_CONVERSATION_ID, liveConversation as never);
|
|
96
|
-
}
|
|
46
|
+
const cleanupContext = { cleanupModeActive: true };
|
|
97
47
|
|
|
98
48
|
describe("disk-pressure-warning injector", () => {
|
|
99
|
-
beforeEach(() => {
|
|
100
|
-
clearConversations();
|
|
101
|
-
resetLiveConversation();
|
|
102
|
-
});
|
|
103
|
-
|
|
104
49
|
test("emits the exact cleanup prompt during disk pressure cleanup mode", async () => {
|
|
105
|
-
|
|
106
|
-
|
|
50
|
+
const block = await diskPressureInjector.produce(
|
|
51
|
+
makeContext({
|
|
52
|
+
injectionInputs: { diskPressureContext: cleanupContext },
|
|
53
|
+
}),
|
|
54
|
+
);
|
|
107
55
|
|
|
108
56
|
expect(block).toEqual({
|
|
109
57
|
id: "disk-pressure-warning",
|
|
@@ -124,14 +72,21 @@ Do not work on unrelated tasks until enough space is freed to clear the lock or
|
|
|
124
72
|
</disk_pressure_warning>`);
|
|
125
73
|
});
|
|
126
74
|
|
|
127
|
-
test("omits the prompt when
|
|
75
|
+
test("omits the prompt when cleanup context is null or inactive", async () => {
|
|
128
76
|
await expect(
|
|
129
|
-
diskPressureInjector.produce(
|
|
77
|
+
diskPressureInjector.produce(
|
|
78
|
+
makeContext({ injectionInputs: { diskPressureContext: null } }),
|
|
79
|
+
),
|
|
130
80
|
).resolves.toBeNull();
|
|
131
81
|
|
|
132
|
-
seedDiskPressure(false);
|
|
133
82
|
await expect(
|
|
134
|
-
diskPressureInjector.produce(
|
|
83
|
+
diskPressureInjector.produce(
|
|
84
|
+
makeContext({
|
|
85
|
+
injectionInputs: {
|
|
86
|
+
diskPressureContext: { cleanupModeActive: false },
|
|
87
|
+
},
|
|
88
|
+
}),
|
|
89
|
+
),
|
|
135
90
|
).resolves.toBeNull();
|
|
136
91
|
});
|
|
137
92
|
|
|
@@ -142,10 +97,10 @@ Do not work on unrelated tasks until enough space is freed to clear the lock or
|
|
|
142
97
|
const workspace = "<workspace>\nRoot: /workspace\n</workspace>";
|
|
143
98
|
const turnContext = "<turn_context>\ninterface: macos\n</turn_context>";
|
|
144
99
|
|
|
145
|
-
seedWorkspaceContext(workspace);
|
|
146
|
-
seedDiskPressure(true);
|
|
147
100
|
const result = await applyRuntimeInjections(runMessages, {
|
|
148
101
|
turnContext: makeContext(),
|
|
102
|
+
diskPressureContext: cleanupContext,
|
|
103
|
+
workspaceTopLevelContext: workspace,
|
|
149
104
|
unifiedTurnContext: turnContext,
|
|
150
105
|
});
|
|
151
106
|
|
|
@@ -163,12 +118,13 @@ Do not work on unrelated tasks until enough space is freed to clear the lock or
|
|
|
163
118
|
});
|
|
164
119
|
|
|
165
120
|
test("survives minimal mode as safety-critical context", async () => {
|
|
166
|
-
seedDiskPressure(true);
|
|
167
121
|
const result = await applyRuntimeInjections(
|
|
168
122
|
[{ role: "user", content: [{ type: "text", text: "status" }] }],
|
|
169
123
|
{
|
|
170
124
|
turnContext: makeContext(),
|
|
171
125
|
mode: "minimal",
|
|
126
|
+
diskPressureContext: cleanupContext,
|
|
127
|
+
workspaceTopLevelContext: "<workspace>...</workspace>",
|
|
172
128
|
unifiedTurnContext: "<turn_context>...</turn_context>",
|
|
173
129
|
},
|
|
174
130
|
);
|
|
@@ -198,16 +154,16 @@ Do not work on unrelated tasks until enough space is freed to clear the lock or
|
|
|
198
154
|
},
|
|
199
155
|
];
|
|
200
156
|
|
|
201
|
-
seedDiskPressure(true);
|
|
202
|
-
seedChannelCapabilities({
|
|
203
|
-
channel: "slack",
|
|
204
|
-
dashboardCapable: false,
|
|
205
|
-
supportsDynamicUi: false,
|
|
206
|
-
supportsVoiceInput: false,
|
|
207
|
-
chatType: "channel",
|
|
208
|
-
});
|
|
209
157
|
const result = await applyRuntimeInjections(originalRun, {
|
|
210
158
|
turnContext: makeContext(),
|
|
159
|
+
diskPressureContext: cleanupContext,
|
|
160
|
+
channelCapabilities: {
|
|
161
|
+
channel: "slack",
|
|
162
|
+
dashboardCapable: false,
|
|
163
|
+
supportsDynamicUi: false,
|
|
164
|
+
supportsVoiceInput: false,
|
|
165
|
+
chatType: "channel",
|
|
166
|
+
},
|
|
211
167
|
slackChronologicalMessages: slackTranscript,
|
|
212
168
|
});
|
|
213
169
|
|
|
@@ -225,15 +181,16 @@ Do not work on unrelated tasks until enough space is freed to clear the lock or
|
|
|
225
181
|
{ role: "user", content: [{ type: "text", text: "find large files" }] },
|
|
226
182
|
];
|
|
227
183
|
|
|
228
|
-
seedDiskPressure(true);
|
|
229
184
|
const first = await applyRuntimeInjections(runMessages, {
|
|
230
185
|
turnContext: makeContext(),
|
|
186
|
+
diskPressureContext: cleanupContext,
|
|
231
187
|
});
|
|
232
188
|
const stripped = stripInjectionsForCompaction(first.messages);
|
|
233
189
|
expect(tailTexts(stripped)).toEqual(["find large files"]);
|
|
234
190
|
|
|
235
191
|
const second = await applyRuntimeInjections(stripped, {
|
|
236
192
|
turnContext: makeContext(),
|
|
193
|
+
diskPressureContext: cleanupContext,
|
|
237
194
|
});
|
|
238
195
|
expect(
|
|
239
196
|
tailTexts(second.messages).filter(
|
|
@@ -9,7 +9,7 @@ mock.module("../documents/document-comments-store.js", () => ({
|
|
|
9
9
|
}));
|
|
10
10
|
|
|
11
11
|
const { DEFAULT_INJECTOR_ORDER, defaultInjectors } =
|
|
12
|
-
await import("../plugins/defaults/
|
|
12
|
+
await import("../plugins/defaults/injectors/register.js");
|
|
13
13
|
import type { Injector, TurnContext } from "../plugins/types.js";
|
|
14
14
|
|
|
15
15
|
function findInjector(name: string): Injector {
|
|
@@ -96,44 +96,6 @@ describe("handleListMessages metadata.hidden filtering", () => {
|
|
|
96
96
|
expect(llmRows[1].metadata).toContain('"hidden":true');
|
|
97
97
|
});
|
|
98
98
|
|
|
99
|
-
test("UI serializer omits system rows but LLM-side getMessages includes them", async () => {
|
|
100
|
-
// GIVEN a conversation with a system row sandwiched between two
|
|
101
|
-
// renderable turns (e.g. a skill-authored context message)
|
|
102
|
-
const conv = createConversation();
|
|
103
|
-
await addMessage(
|
|
104
|
-
conv.id,
|
|
105
|
-
"user",
|
|
106
|
-
JSON.stringify([{ type: "text", text: "first visible" }]),
|
|
107
|
-
);
|
|
108
|
-
await addMessage(
|
|
109
|
-
conv.id,
|
|
110
|
-
"system",
|
|
111
|
-
JSON.stringify([{ type: "text", text: "system scaffolding" }]),
|
|
112
|
-
);
|
|
113
|
-
await addMessage(
|
|
114
|
-
conv.id,
|
|
115
|
-
"assistant",
|
|
116
|
-
JSON.stringify([{ type: "text", text: "second visible" }]),
|
|
117
|
-
);
|
|
118
|
-
|
|
119
|
-
// WHEN the UI history list is serialized
|
|
120
|
-
const response = handleListMessages({
|
|
121
|
-
queryParams: { conversationId: conv.id },
|
|
122
|
-
});
|
|
123
|
-
const body = response as { messages: MessagePayload[] };
|
|
124
|
-
|
|
125
|
-
// THEN only the user/assistant turns are returned, never the system row
|
|
126
|
-
expect(body.messages.map((m) => m.role)).toEqual(["user", "assistant"]);
|
|
127
|
-
expect(
|
|
128
|
-
body.messages.some((m) => plainText(m).includes("system scaffolding")),
|
|
129
|
-
).toBe(false);
|
|
130
|
-
|
|
131
|
-
// AND the LLM-side loader still includes the system row for agent context
|
|
132
|
-
const llmRows = getMessages(conv.id);
|
|
133
|
-
expect(llmRows).toHaveLength(3);
|
|
134
|
-
expect(llmRows[1].role).toBe("system");
|
|
135
|
-
});
|
|
136
|
-
|
|
137
99
|
test("messages without metadata or with hidden=false are returned", async () => {
|
|
138
100
|
const conv = createConversation();
|
|
139
101
|
await addMessage(
|
|
@@ -35,7 +35,7 @@ mock.module("../config/loader.js", () => ({
|
|
|
35
35
|
}));
|
|
36
36
|
|
|
37
37
|
const { defaultInjectors } =
|
|
38
|
-
await import("../plugins/defaults/
|
|
38
|
+
await import("../plugins/defaults/injectors/register.js");
|
|
39
39
|
import type { Injector, TurnContext } from "../plugins/types.js";
|
|
40
40
|
import type { Message } from "../providers/types.js";
|
|
41
41
|
import { getWorkspacePromptPath } from "../util/platform.js";
|