@hassangameryt/freeflow 0.7.1 → 0.7.3
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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/.cursor-plugin/plugin.json +1 -1
- package/README.md +153 -128
- package/capabilities/cognitive-routing/SKILL.md +126 -274
- package/command-surface.json +7 -1
- package/gemini-extension.json +1 -1
- package/package.json +4 -4
- package/pi-extension/dist/cognitive-routing-v2/budget.js +42 -0
- package/pi-extension/dist/cognitive-routing-v2/config.js +136 -0
- package/pi-extension/dist/cognitive-routing-v2/projection.js +330 -0
- package/pi-extension/dist/cognitive-routing-v2/render.js +252 -0
- package/pi-extension/dist/cognitive-routing-v2/runtime.js +2181 -0
- package/pi-extension/dist/cognitive-routing-v2/schemas.js +173 -0
- package/pi-extension/dist/cognitive-routing-v2/state.js +828 -0
- package/pi-extension/dist/cognitive-routing-v2/tools.js +60 -0
- package/pi-extension/dist/cognitive-routing-v2/types.js +48 -0
- package/pi-extension/dist/context-virtualization/runtime.js +29 -7
- package/pi-extension/dist/freeflow-context/tool.js +12 -6
- package/pi-extension/dist/index.js +302 -626
- package/pi-extension/dist/provider-support/astra/adapter.js +110 -0
- package/pi-extension/dist/provider-support/astra/history.js +125 -0
- package/pi-extension/dist/provider-support/astra/index.js +11 -0
- package/pi-extension/dist/provider-support/astra/session-state.js +114 -0
- package/pi-extension/dist/provider-support/index.js +4 -0
- package/pi-extension/dist/runtime/request-history.js +216 -0
- package/pi-extension/dist/runtime/runtime-context.js +85 -16
- package/pi-extension/dist/session-sources/events.js +217 -0
- package/pi-extension/dist/session-sources/provenance.js +32 -0
- package/pi-extension/dist/session-sources/read-only-session.js +148 -0
- package/pi-extension/dist/session-sources/sources.js +277 -0
- package/pi-extension/dist/settings/settings-ui.js +274 -147
- package/pi-extension/src/cognitive-routing-v2/budget.ts +42 -0
- package/pi-extension/src/cognitive-routing-v2/config.ts +173 -0
- package/pi-extension/src/cognitive-routing-v2/projection.ts +375 -0
- package/pi-extension/src/cognitive-routing-v2/render.ts +277 -0
- package/pi-extension/src/cognitive-routing-v2/runtime.ts +2241 -0
- package/pi-extension/src/cognitive-routing-v2/schemas.ts +180 -0
- package/pi-extension/src/cognitive-routing-v2/state.ts +839 -0
- package/pi-extension/src/cognitive-routing-v2/tools.ts +62 -0
- package/pi-extension/src/cognitive-routing-v2/types.ts +254 -0
- package/pi-extension/src/context-virtualization/runtime.ts +30 -8
- package/pi-extension/src/freeflow-context/tool.ts +12 -6
- package/pi-extension/src/index.ts +308 -675
- package/pi-extension/src/provider-support/astra/adapter.ts +108 -0
- package/pi-extension/src/provider-support/astra/history.ts +145 -0
- package/pi-extension/src/provider-support/astra/index.ts +12 -0
- package/pi-extension/src/provider-support/astra/session-state.ts +113 -0
- package/pi-extension/src/provider-support/index.ts +5 -0
- package/pi-extension/src/runtime/request-history.ts +243 -0
- package/pi-extension/src/runtime/runtime-context.ts +100 -17
- package/pi-extension/src/session-sources/events.ts +230 -0
- package/pi-extension/src/session-sources/provenance.ts +39 -0
- package/pi-extension/src/session-sources/read-only-session.ts +170 -0
- package/pi-extension/src/session-sources/sources.ts +334 -0
- package/pi-extension/src/settings/settings-ui.ts +311 -158
- package/pi-extension/tests/cache-reuse/history.test.js +117 -0
- package/pi-extension/tests/cache-reuse/native.test.js +91 -0
- package/pi-extension/tests/cache-reuse/settings.test.js +211 -0
- package/pi-extension/tests/cognitive-routing-v2/communication.test.js +577 -0
- package/pi-extension/tests/cognitive-routing-v2/compaction-input.test.js +183 -0
- package/pi-extension/tests/cognitive-routing-v2/delegation.test.js +557 -0
- package/pi-extension/tests/cognitive-routing-v2/native.test.js +474 -0
- package/pi-extension/tests/cognitive-routing-v2/performance.test.js +87 -0
- package/pi-extension/tests/cognitive-routing-v2/persistence.test.js +300 -0
- package/pi-extension/tests/cognitive-routing-v2/projection.test.js +241 -0
- package/pi-extension/tests/cognitive-routing-v2/recovery.test.js +1034 -0
- package/pi-extension/tests/cognitive-routing-v2/render.test.js +244 -0
- package/pi-extension/tests/cognitive-routing-v2/runtime.test.js +423 -0
- package/pi-extension/tests/cognitive-routing-v2/stabilization.test.js +521 -0
- package/pi-extension/tests/cognitive-routing-v2/state.test.js +586 -0
- package/pi-extension/tests/context-virtualization/extension.test.js +33 -7
- package/pi-extension/tests/context-virtualization/runtime.test.js +17 -3
- package/pi-extension/tests/fixtures/routing-native.js +191 -0
- package/pi-extension/tests/integration/mode-free-core.test.js +6 -4
- package/pi-extension/tests/integration/pi-extension.test.js +655 -59
- package/pi-extension/tests/integration/prompt-architecture.test.js +127 -30
- package/pi-extension/tests/integration/unaffected-regressions.test.js +78 -11
- package/pi-extension/tests/provider-support/astra-boundaries.test.js +75 -0
- package/pi-extension/tests/provider-support/astra.test.js +306 -0
- package/pi-extension/tests/provider-support/cli.test.js +92 -0
- package/pi-extension/tests/provider-support/native.test.js +183 -0
- package/plugin.json +1 -1
- package/runtime/prompts/cognitive-routing.md +4 -5
- package/runtime/prompts/core.md +51 -45
- package/runtime/prompts/interaction-contract.md +5 -5
- package/skills/action-selection/SKILL.md +57 -97
- package/skills/design-for-depth/SKILL.md +58 -193
- package/skills/design-for-depth/references/implementation-decisions.md +76 -0
- package/skills/diagnose-failure/SKILL.md +64 -196
- package/skills/discuss/SKILL.md +64 -123
- package/skills/discuss/references/discussion-continuity.md +7 -3
- package/skills/execute-work/SKILL.md +69 -88
- package/skills/execute-work/references/execute-work-edges.md +9 -3
- package/skills/handoff/SKILL.md +44 -54
- package/skills/handoff/references/handoff-templates.md +15 -6
- package/skills/review-artifact/SKILL.md +80 -127
- package/skills/review-artifact/references/independent-artifact-reviewer-contract.md +1 -1
- package/skills/review-work/SKILL.md +65 -115
- package/skills/review-work/references/independent-work-reviewer-contract.md +1 -1
- package/skills/simplify-code/SKILL.md +47 -100
- package/skills/track-work/SKILL.md +128 -119
- package/skills/track-work/references/working-record-format.md +14 -2
- package/skills/verify-work/SKILL.md +58 -62
- package/skills/verify-work/references/integration-evidence.md +4 -2
- package/skills/verify-work/references/test-design.md +89 -0
- package/skills/workflow/SKILL.md +73 -119
- package/skills/write-plan/SKILL.md +46 -77
- package/skills/write-plan/references/plan-shapes.md +5 -5
- package/skills/write-spec/SKILL.md +51 -63
- package/skills/write-spec/references/artifact-standards.md +2 -2
- package/skills/write-spec/references/decision-records.md +3 -2
- package/skills/write-spec/references/spec-shapes.md +15 -0
- package/pi-extension/dist/cognitive-routing/commands.js +0 -96
- package/pi-extension/dist/cognitive-routing/config.js +0 -232
- package/pi-extension/dist/cognitive-routing/controller.js +0 -1292
- package/pi-extension/dist/cognitive-routing/history.js +0 -451
- package/pi-extension/dist/cognitive-routing/host.js +0 -188
- package/pi-extension/dist/cognitive-routing/pi-routing-session.js +0 -414
- package/pi-extension/dist/cognitive-routing/pi-session-control.js +0 -320
- package/pi-extension/dist/cognitive-routing/runtime.js +0 -43
- package/pi-extension/dist/cognitive-routing/tool.js +0 -212
- package/pi-extension/dist/cognitive-routing/types.js +0 -6
- package/pi-extension/src/cognitive-routing/commands.ts +0 -129
- package/pi-extension/src/cognitive-routing/config.ts +0 -303
- package/pi-extension/src/cognitive-routing/controller.ts +0 -1628
- package/pi-extension/src/cognitive-routing/history.ts +0 -650
- package/pi-extension/src/cognitive-routing/host.ts +0 -266
- package/pi-extension/src/cognitive-routing/pi-routing-session.ts +0 -538
- package/pi-extension/src/cognitive-routing/pi-session-control.ts +0 -444
- package/pi-extension/src/cognitive-routing/runtime.ts +0 -57
- package/pi-extension/src/cognitive-routing/tool.ts +0 -273
- package/pi-extension/src/cognitive-routing/types.ts +0 -89
- package/pi-extension/tests/cognitive-routing/commands.test.js +0 -134
- package/pi-extension/tests/cognitive-routing/controller.test.js +0 -1128
- package/pi-extension/tests/cognitive-routing/extension-lifecycle.test.js +0 -1142
- package/pi-extension/tests/cognitive-routing/history.test.js +0 -274
- package/pi-extension/tests/cognitive-routing/host-identity.test.js +0 -63
- package/pi-extension/tests/cognitive-routing/pi-normal-lifecycle.test.js +0 -434
- package/pi-extension/tests/cognitive-routing/pi-session-control.test.js +0 -174
- package/pi-extension/tests/cognitive-routing/pi-session-history.test.js +0 -91
- package/pi-extension/tests/cognitive-routing/profile-resolution.test.js +0 -279
- package/pi-extension/tests/cognitive-routing/tool.test.js +0 -230
- package/skills/tdd/SKILL.md +0 -143
- package/skills/tdd/references/test-design.md +0 -96
- /package/pi-extension/tests/{cognitive-routing/host-fixture.js → fixtures/pi-host.js} +0 -0
|
@@ -1,434 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert/strict";
|
|
2
|
-
import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
|
|
3
|
-
import { tmpdir } from "node:os";
|
|
4
|
-
import { join } from "node:path";
|
|
5
|
-
import test from "node:test";
|
|
6
|
-
import freeflowExtension from "../../dist/index.js";
|
|
7
|
-
|
|
8
|
-
const profiles = {
|
|
9
|
-
standard: { provider: "faux", model: "standard", thinkingLevel: "high" },
|
|
10
|
-
reasoning: { provider: "faux", model: "reasoning", thinkingLevel: "max" },
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
function createNormalPiHost({
|
|
14
|
-
failInactivePersistence = false,
|
|
15
|
-
failTargetThinking = false,
|
|
16
|
-
emitNativeEvents = false,
|
|
17
|
-
} = {}) {
|
|
18
|
-
let currentModel = {
|
|
19
|
-
provider: "faux",
|
|
20
|
-
id: "return",
|
|
21
|
-
reasoning: true,
|
|
22
|
-
thinkingLevelMap: { xhigh: "xhigh", max: "max" },
|
|
23
|
-
};
|
|
24
|
-
let currentThinkingLevel = "medium";
|
|
25
|
-
let activeToolNames;
|
|
26
|
-
const entries = [];
|
|
27
|
-
const tools = [];
|
|
28
|
-
const commands = [];
|
|
29
|
-
const shortcuts = [];
|
|
30
|
-
const handlers = new Map();
|
|
31
|
-
const calls = [];
|
|
32
|
-
const statuses = [];
|
|
33
|
-
const models = new Map([
|
|
34
|
-
["faux/return", currentModel],
|
|
35
|
-
["faux/standard", { provider: "faux", id: "standard", reasoning: true, thinkingLevelMap: { max: "max" } }],
|
|
36
|
-
["faux/reasoning", { provider: "faux", id: "reasoning", reasoning: true, thinkingLevelMap: { max: "max" } }],
|
|
37
|
-
]);
|
|
38
|
-
|
|
39
|
-
const appendNativeEntry = (entry) => entries.push({ type: entry.type, ...entry });
|
|
40
|
-
const pi = {
|
|
41
|
-
registerTool(tool) {
|
|
42
|
-
tools.push(tool);
|
|
43
|
-
},
|
|
44
|
-
registerCommand(name, definition) {
|
|
45
|
-
commands.push({ name, definition });
|
|
46
|
-
},
|
|
47
|
-
registerShortcut(shortcut, definition) {
|
|
48
|
-
shortcuts.push({ shortcut, definition });
|
|
49
|
-
},
|
|
50
|
-
on(event, handler) {
|
|
51
|
-
handlers.set(event, handler);
|
|
52
|
-
},
|
|
53
|
-
appendEntry(customType, data) {
|
|
54
|
-
if (failInactivePersistence && customType === "freeflow-cognitive-routing-inactive") {
|
|
55
|
-
throw new Error("simulated inactive persistence failure");
|
|
56
|
-
}
|
|
57
|
-
entries.push({ type: "custom", customType, data });
|
|
58
|
-
},
|
|
59
|
-
async setModel(model) {
|
|
60
|
-
calls.push(["setModel", model.provider, model.id]);
|
|
61
|
-
const previousModel = currentModel;
|
|
62
|
-
currentModel = model;
|
|
63
|
-
appendNativeEntry({ type: "model_change", provider: model.provider, modelId: model.id });
|
|
64
|
-
if (emitNativeEvents) {
|
|
65
|
-
await handlers.get("model_select")?.({ type: "model_select", model, previousModel, source: "set" }, ctx);
|
|
66
|
-
}
|
|
67
|
-
return true;
|
|
68
|
-
},
|
|
69
|
-
setThinkingLevel(level) {
|
|
70
|
-
calls.push(["setThinkingLevel", level]);
|
|
71
|
-
if (failTargetThinking && level === "max") throw new Error("simulated target thinking failure");
|
|
72
|
-
currentThinkingLevel = level;
|
|
73
|
-
appendNativeEntry({ type: "thinking_level_change", thinkingLevel: level });
|
|
74
|
-
},
|
|
75
|
-
getAllTools() {
|
|
76
|
-
return tools.map((tool) => ({ name: tool.name }));
|
|
77
|
-
},
|
|
78
|
-
getActiveTools() {
|
|
79
|
-
return activeToolNames ?? tools.map((tool) => tool.name);
|
|
80
|
-
},
|
|
81
|
-
setActiveTools(names) {
|
|
82
|
-
activeToolNames = [...names];
|
|
83
|
-
},
|
|
84
|
-
sendUserMessage() {},
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
const ctx = {
|
|
88
|
-
cwd: undefined,
|
|
89
|
-
mode: "print",
|
|
90
|
-
hasUI: false,
|
|
91
|
-
get model() {
|
|
92
|
-
return currentModel;
|
|
93
|
-
},
|
|
94
|
-
get thinkingLevel() {
|
|
95
|
-
return currentThinkingLevel;
|
|
96
|
-
},
|
|
97
|
-
modelRegistry: {
|
|
98
|
-
find(provider, modelId) {
|
|
99
|
-
return models.get(`${provider}/${modelId}`);
|
|
100
|
-
},
|
|
101
|
-
async getApiKeyAndHeaders() {
|
|
102
|
-
return { ok: true };
|
|
103
|
-
},
|
|
104
|
-
},
|
|
105
|
-
modelStateProvenance: {},
|
|
106
|
-
isIdle: () => true,
|
|
107
|
-
sessionManager: {
|
|
108
|
-
getEntries: () => entries,
|
|
109
|
-
getBranch: () => entries,
|
|
110
|
-
buildContextEntries: () => entries,
|
|
111
|
-
getLeafId: () => entries.at(-1)?.id ?? null,
|
|
112
|
-
},
|
|
113
|
-
ui: {
|
|
114
|
-
notify() {},
|
|
115
|
-
setStatus(_key, value) {
|
|
116
|
-
statuses.push(value);
|
|
117
|
-
},
|
|
118
|
-
},
|
|
119
|
-
};
|
|
120
|
-
|
|
121
|
-
return { pi, ctx, entries, tools, commands, shortcuts, handlers, calls, statuses, models };
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
async function configure(cwd) {
|
|
125
|
-
await mkdir(join(cwd, ".freeflow"));
|
|
126
|
-
await writeFile(
|
|
127
|
-
join(cwd, ".freeflow", "config.json"),
|
|
128
|
-
JSON.stringify({ cognitiveRouting: { enabled: true, profiles } }),
|
|
129
|
-
"utf8",
|
|
130
|
-
);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
async function start(host) {
|
|
134
|
-
freeflowExtension(host.pi);
|
|
135
|
-
await host.handlers.get("session_start")({ type: "session_start", reason: "startup" }, host.ctx);
|
|
136
|
-
return host.handlers.get("before_agent_start")({ systemPrompt: "base prompt" }, host.ctx);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
function switchTool(host) {
|
|
140
|
-
return host.tools.find((tool) => tool.name === "freeflow_switch_profile");
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
function runtimeMessages(host) {
|
|
144
|
-
return host.entries.filter((entry) => entry.customType === "freeflow-cognitive-routing-model-state");
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
test("normal Pi activates and switches Cognitive Routing through official APIs", async () => {
|
|
148
|
-
const cwd = await mkdtemp(join(tmpdir(), "freeflow-pi-normal-lifecycle-"));
|
|
149
|
-
const host = createNormalPiHost();
|
|
150
|
-
host.ctx.cwd = cwd;
|
|
151
|
-
try {
|
|
152
|
-
await configure(cwd);
|
|
153
|
-
const before = await start(host);
|
|
154
|
-
|
|
155
|
-
assert.match(before.systemPrompt, /## Cognitive Routing Cue/);
|
|
156
|
-
assert.equal(host.ctx.model.id, "reasoning");
|
|
157
|
-
assert.equal(host.ctx.thinkingLevel, "max");
|
|
158
|
-
assert.ok(host.pi.getActiveTools().includes("freeflow_switch_profile"));
|
|
159
|
-
|
|
160
|
-
const tool = switchTool(host);
|
|
161
|
-
assert.ok(tool);
|
|
162
|
-
assert.equal(tool.executionMode, "sequential");
|
|
163
|
-
const result = await tool.execute(
|
|
164
|
-
"normal-pi-switch",
|
|
165
|
-
{ target: "standard", reason: "Use Standard for bounded execution." },
|
|
166
|
-
undefined,
|
|
167
|
-
undefined,
|
|
168
|
-
host.ctx,
|
|
169
|
-
);
|
|
170
|
-
|
|
171
|
-
assert.deepEqual(result.details.result, {
|
|
172
|
-
status: "active",
|
|
173
|
-
changed: true,
|
|
174
|
-
from: "reasoning",
|
|
175
|
-
to: "standard",
|
|
176
|
-
profile: "standard",
|
|
177
|
-
});
|
|
178
|
-
assert.equal(host.ctx.model.id, "standard");
|
|
179
|
-
assert.equal(host.ctx.thinkingLevel, "high");
|
|
180
|
-
assert.equal(runtimeMessages(host).at(-1).data.status, "applied");
|
|
181
|
-
} finally {
|
|
182
|
-
await rm(cwd, { recursive: true, force: true });
|
|
183
|
-
}
|
|
184
|
-
});
|
|
185
|
-
|
|
186
|
-
test("normal Pi ignores model events emitted by Freeflow-owned transitions", async () => {
|
|
187
|
-
const cwd = await mkdtemp(join(tmpdir(), "freeflow-pi-normal-internal-events-"));
|
|
188
|
-
const host = createNormalPiHost({ emitNativeEvents: true });
|
|
189
|
-
host.ctx.cwd = cwd;
|
|
190
|
-
try {
|
|
191
|
-
await configure(cwd);
|
|
192
|
-
const before = await start(host);
|
|
193
|
-
|
|
194
|
-
assert.equal(
|
|
195
|
-
host.entries.some((entry) => entry.customType === "freeflow-cognitive-routing-inactive"),
|
|
196
|
-
false,
|
|
197
|
-
);
|
|
198
|
-
assert.match(before.systemPrompt, /## Cognitive Routing Cue/);
|
|
199
|
-
assert.equal(host.ctx.model.id, "reasoning");
|
|
200
|
-
assert.equal(host.ctx.thinkingLevel, "max");
|
|
201
|
-
} finally {
|
|
202
|
-
await rm(cwd, { recursive: true, force: true });
|
|
203
|
-
}
|
|
204
|
-
});
|
|
205
|
-
|
|
206
|
-
test("normal Pi no-op profile switches preserve one runtime-state message", async () => {
|
|
207
|
-
const cwd = await mkdtemp(join(tmpdir(), "freeflow-pi-normal-no-op-"));
|
|
208
|
-
const host = createNormalPiHost();
|
|
209
|
-
host.ctx.cwd = cwd;
|
|
210
|
-
try {
|
|
211
|
-
await configure(cwd);
|
|
212
|
-
await start(host);
|
|
213
|
-
const contextHandler = host.handlers.get("context");
|
|
214
|
-
const first = await contextHandler({ messages: [] }, host.ctx);
|
|
215
|
-
const tool = switchTool(host);
|
|
216
|
-
const result = await tool.execute(
|
|
217
|
-
"normal-pi-no-op",
|
|
218
|
-
{ target: "reasoning", reason: "Remain on the current profile." },
|
|
219
|
-
undefined,
|
|
220
|
-
undefined,
|
|
221
|
-
host.ctx,
|
|
222
|
-
);
|
|
223
|
-
assert.equal(result.details.result.changed, false);
|
|
224
|
-
|
|
225
|
-
await host.handlers.get("tool_result")({ type: "tool_result", toolName: "freeflow_switch_profile" }, host.ctx);
|
|
226
|
-
assert.equal(await contextHandler({ messages: first.messages }, host.ctx), undefined);
|
|
227
|
-
assert.equal(first.messages.filter((message) => message.customType === "freeflow-runtime-state").length, 1);
|
|
228
|
-
} finally {
|
|
229
|
-
await rm(cwd, { recursive: true, force: true });
|
|
230
|
-
}
|
|
231
|
-
});
|
|
232
|
-
|
|
233
|
-
test("normal Pi supports manual and automatic profile shortcuts", async () => {
|
|
234
|
-
const cwd = await mkdtemp(join(tmpdir(), "freeflow-pi-normal-shortcuts-"));
|
|
235
|
-
const host = createNormalPiHost();
|
|
236
|
-
host.ctx.cwd = cwd;
|
|
237
|
-
try {
|
|
238
|
-
await configure(cwd);
|
|
239
|
-
await start(host);
|
|
240
|
-
const manual = host.shortcuts.find(({ shortcut }) => shortcut === "ctrl+shift+r");
|
|
241
|
-
const automatic = host.shortcuts.find(({ shortcut }) => shortcut === "ctrl+shift+a");
|
|
242
|
-
assert.ok(manual);
|
|
243
|
-
assert.ok(automatic);
|
|
244
|
-
|
|
245
|
-
await manual.definition.handler(host.ctx);
|
|
246
|
-
assert.equal(host.ctx.model.id, "standard");
|
|
247
|
-
assert.match(host.statuses.at(-1), /standard · manual hold/);
|
|
248
|
-
|
|
249
|
-
await automatic.definition.handler(host.ctx);
|
|
250
|
-
assert.equal(host.ctx.model.id, "reasoning");
|
|
251
|
-
assert.equal(host.ctx.thinkingLevel, "max");
|
|
252
|
-
assert.match(host.statuses.at(-1), /reasoning · automatic/);
|
|
253
|
-
} finally {
|
|
254
|
-
await rm(cwd, { recursive: true, force: true });
|
|
255
|
-
}
|
|
256
|
-
});
|
|
257
|
-
|
|
258
|
-
test("normal Pi disables routing after a native model override and can reactivate explicitly", async () => {
|
|
259
|
-
const cwd = await mkdtemp(join(tmpdir(), "freeflow-pi-normal-native-override-"));
|
|
260
|
-
const host = createNormalPiHost();
|
|
261
|
-
host.ctx.cwd = cwd;
|
|
262
|
-
try {
|
|
263
|
-
await configure(cwd);
|
|
264
|
-
await start(host);
|
|
265
|
-
const previousModel = host.ctx.model;
|
|
266
|
-
const selectedModel = host.models.get("faux/standard");
|
|
267
|
-
await host.pi.setModel(selectedModel);
|
|
268
|
-
host.pi.setThinkingLevel("high");
|
|
269
|
-
await host.handlers.get("model_select")(
|
|
270
|
-
{ type: "model_select", model: selectedModel, previousModel, source: "set" },
|
|
271
|
-
host.ctx,
|
|
272
|
-
);
|
|
273
|
-
|
|
274
|
-
assert.equal(host.pi.getActiveTools().includes("freeflow_switch_profile"), false);
|
|
275
|
-
assert.ok(host.entries.some((entry) => entry.customType === "freeflow-cognitive-routing-inactive"));
|
|
276
|
-
assert.match(host.statuses.at(-1), /cognitive/);
|
|
277
|
-
|
|
278
|
-
const automatic = host.shortcuts.find(({ shortcut }) => shortcut === "ctrl+shift+a");
|
|
279
|
-
await automatic.definition.handler(host.ctx);
|
|
280
|
-
assert.equal(host.ctx.model.id, "standard");
|
|
281
|
-
assert.equal(host.ctx.thinkingLevel, "high");
|
|
282
|
-
assert.equal(host.pi.getActiveTools().includes("freeflow_switch_profile"), true);
|
|
283
|
-
} finally {
|
|
284
|
-
await rm(cwd, { recursive: true, force: true });
|
|
285
|
-
}
|
|
286
|
-
});
|
|
287
|
-
|
|
288
|
-
test("normal Pi honors explicit startup selection and supports explicit reactivation", async () => {
|
|
289
|
-
const cwd = await mkdtemp(join(tmpdir(), "freeflow-pi-normal-startup-override-"));
|
|
290
|
-
const originalArgv = process.argv;
|
|
291
|
-
const host = createNormalPiHost();
|
|
292
|
-
host.ctx.cwd = cwd;
|
|
293
|
-
try {
|
|
294
|
-
await configure(cwd);
|
|
295
|
-
process.argv = [originalArgv[0], originalArgv[1], "--model", "faux/return"];
|
|
296
|
-
freeflowExtension(host.pi);
|
|
297
|
-
await host.handlers.get("session_start")({ type: "session_start", reason: "startup" }, host.ctx);
|
|
298
|
-
const before = await host.handlers.get("before_agent_start")({ systemPrompt: "base prompt" }, host.ctx);
|
|
299
|
-
|
|
300
|
-
assert.equal(host.ctx.model.id, "return");
|
|
301
|
-
assert.equal(host.ctx.thinkingLevel, "medium");
|
|
302
|
-
assert.ok(host.entries.some((entry) => entry.customType === "freeflow-cognitive-routing-inactive"));
|
|
303
|
-
assert.equal(host.pi.getActiveTools().includes("freeflow_switch_profile"), false);
|
|
304
|
-
assert.doesNotMatch(before.systemPrompt, /## Cognitive Routing Cue/);
|
|
305
|
-
|
|
306
|
-
const command = host.commands.find(({ name }) => name === "freeflow");
|
|
307
|
-
await command.definition.handler("profile standard", host.ctx);
|
|
308
|
-
assert.equal(host.ctx.model.id, "standard");
|
|
309
|
-
assert.equal(host.ctx.thinkingLevel, "high");
|
|
310
|
-
} finally {
|
|
311
|
-
process.argv = originalArgv;
|
|
312
|
-
await rm(cwd, { recursive: true, force: true });
|
|
313
|
-
}
|
|
314
|
-
});
|
|
315
|
-
|
|
316
|
-
test("normal Pi uses documented startup arguments instead of host provenance", async () => {
|
|
317
|
-
const cwd = await mkdtemp(join(tmpdir(), "freeflow-pi-normal-provenance-"));
|
|
318
|
-
const originalArgv = process.argv;
|
|
319
|
-
const host = createNormalPiHost();
|
|
320
|
-
host.ctx.cwd = cwd;
|
|
321
|
-
host.ctx.modelStateProvenance = { explicitModel: true, explicitThinking: true };
|
|
322
|
-
try {
|
|
323
|
-
await configure(cwd);
|
|
324
|
-
process.argv = [originalArgv[0], originalArgv[1]];
|
|
325
|
-
const before = await start(host);
|
|
326
|
-
|
|
327
|
-
assert.equal(host.ctx.model.id, "reasoning");
|
|
328
|
-
assert.equal(host.ctx.thinkingLevel, "max");
|
|
329
|
-
assert.match(before.systemPrompt, /## Cognitive Routing Cue/);
|
|
330
|
-
} finally {
|
|
331
|
-
process.argv = originalArgv;
|
|
332
|
-
await rm(cwd, { recursive: true, force: true });
|
|
333
|
-
}
|
|
334
|
-
});
|
|
335
|
-
|
|
336
|
-
test("normal Pi disables routing after a native thinking-level override", async () => {
|
|
337
|
-
const cwd = await mkdtemp(join(tmpdir(), "freeflow-pi-normal-native-thinking-"));
|
|
338
|
-
const host = createNormalPiHost();
|
|
339
|
-
host.ctx.cwd = cwd;
|
|
340
|
-
try {
|
|
341
|
-
await configure(cwd);
|
|
342
|
-
await start(host);
|
|
343
|
-
const previousLevel = host.ctx.thinkingLevel;
|
|
344
|
-
host.pi.setThinkingLevel("low");
|
|
345
|
-
await host.handlers.get("thinking_level_select")(
|
|
346
|
-
{ type: "thinking_level_select", level: "low", previousLevel },
|
|
347
|
-
host.ctx,
|
|
348
|
-
);
|
|
349
|
-
|
|
350
|
-
assert.equal(host.ctx.model.id, "reasoning");
|
|
351
|
-
assert.equal(host.ctx.thinkingLevel, "low");
|
|
352
|
-
assert.equal(host.pi.getActiveTools().includes("freeflow_switch_profile"), false);
|
|
353
|
-
assert.ok(host.entries.some((entry) => entry.customType === "freeflow-cognitive-routing-inactive"));
|
|
354
|
-
} finally {
|
|
355
|
-
await rm(cwd, { recursive: true, force: true });
|
|
356
|
-
}
|
|
357
|
-
});
|
|
358
|
-
|
|
359
|
-
test("normal Pi fails closed when native inactivity cannot be persisted", async () => {
|
|
360
|
-
const cwd = await mkdtemp(join(tmpdir(), "freeflow-pi-normal-inactive-persistence-"));
|
|
361
|
-
const host = createNormalPiHost({ failInactivePersistence: true });
|
|
362
|
-
host.ctx.cwd = cwd;
|
|
363
|
-
try {
|
|
364
|
-
await configure(cwd);
|
|
365
|
-
await start(host);
|
|
366
|
-
const previousModel = host.ctx.model;
|
|
367
|
-
const selectedModel = host.models.get("faux/standard");
|
|
368
|
-
await host.pi.setModel(selectedModel);
|
|
369
|
-
host.pi.setThinkingLevel("high");
|
|
370
|
-
await host.handlers.get("model_select")(
|
|
371
|
-
{ type: "model_select", model: selectedModel, previousModel, source: "set" },
|
|
372
|
-
host.ctx,
|
|
373
|
-
);
|
|
374
|
-
|
|
375
|
-
assert.equal(host.pi.getActiveTools().includes("freeflow_switch_profile"), false);
|
|
376
|
-
assert.equal(
|
|
377
|
-
host.entries.some((entry) => entry.customType === "freeflow-cognitive-routing-inactive"),
|
|
378
|
-
false,
|
|
379
|
-
);
|
|
380
|
-
assert.match(host.statuses.at(-1), /cognitive blocked/);
|
|
381
|
-
} finally {
|
|
382
|
-
await rm(cwd, { recursive: true, force: true });
|
|
383
|
-
}
|
|
384
|
-
});
|
|
385
|
-
|
|
386
|
-
test("normal Pi reload restores the active semantic profile", async () => {
|
|
387
|
-
const cwd = await mkdtemp(join(tmpdir(), "freeflow-pi-normal-reload-"));
|
|
388
|
-
const host = createNormalPiHost();
|
|
389
|
-
host.ctx.cwd = cwd;
|
|
390
|
-
try {
|
|
391
|
-
await configure(cwd);
|
|
392
|
-
await start(host);
|
|
393
|
-
const tool = switchTool(host);
|
|
394
|
-
await tool.execute(
|
|
395
|
-
"normal-pi-reload-switch",
|
|
396
|
-
{ target: "standard", reason: "Use Standard for bounded execution." },
|
|
397
|
-
undefined,
|
|
398
|
-
undefined,
|
|
399
|
-
host.ctx,
|
|
400
|
-
);
|
|
401
|
-
await host.handlers.get("session_shutdown")({ type: "session_shutdown", reason: "reload" }, host.ctx);
|
|
402
|
-
assert.equal(host.ctx.model.id, "return");
|
|
403
|
-
assert.equal(host.ctx.thinkingLevel, "medium");
|
|
404
|
-
|
|
405
|
-
freeflowExtension(host.pi);
|
|
406
|
-
await host.handlers.get("session_start")({ type: "session_start", reason: "reload" }, host.ctx);
|
|
407
|
-
await host.handlers.get("before_agent_start")({ systemPrompt: "base prompt" }, host.ctx);
|
|
408
|
-
assert.equal(host.ctx.model.id, "standard");
|
|
409
|
-
assert.equal(host.ctx.thinkingLevel, "high");
|
|
410
|
-
} finally {
|
|
411
|
-
await rm(cwd, { recursive: true, force: true });
|
|
412
|
-
}
|
|
413
|
-
});
|
|
414
|
-
|
|
415
|
-
test("normal Pi preserves Cognitive Routing skill and runtime surface without Conversation routing", async () => {
|
|
416
|
-
const cwd = await mkdtemp(join(tmpdir(), "freeflow-pi-normal-surface-"));
|
|
417
|
-
const host = createNormalPiHost();
|
|
418
|
-
host.ctx.cwd = cwd;
|
|
419
|
-
try {
|
|
420
|
-
await configure(cwd);
|
|
421
|
-
const before = await start(host);
|
|
422
|
-
assert.match(before.systemPrompt, /## Cognitive Routing Cue/);
|
|
423
|
-
assert.doesNotMatch(before.systemPrompt, /Conversation(?: Route| profile| selects)/);
|
|
424
|
-
const resources = await host.handlers.get("resources_discover")({}, host.ctx);
|
|
425
|
-
const routingSkillPath = resources.skillPaths.find((path) => path.endsWith("cognitive-routing/SKILL.md"));
|
|
426
|
-
assert.ok(routingSkillPath);
|
|
427
|
-
const state = await host.handlers.get("context")({ messages: [] }, host.ctx);
|
|
428
|
-
assert.match(state.messages.at(-1).content, /Control: `automatic`/);
|
|
429
|
-
assert.match(state.messages.at(-1).content, /Profile: `reasoning`/);
|
|
430
|
-
assert.doesNotMatch(state.messages.at(-1).content, /Conversation:/);
|
|
431
|
-
} finally {
|
|
432
|
-
await rm(cwd, { recursive: true, force: true });
|
|
433
|
-
}
|
|
434
|
-
});
|
|
@@ -1,174 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert/strict";
|
|
2
|
-
import test from "node:test";
|
|
3
|
-
import {
|
|
4
|
-
createPiSessionModelStateControl,
|
|
5
|
-
PI_SESSION_MODEL_STATE_ENTRY,
|
|
6
|
-
} from "../../dist/cognitive-routing/pi-session-control.js";
|
|
7
|
-
|
|
8
|
-
const fromPair = {
|
|
9
|
-
provider: "faux",
|
|
10
|
-
modelId: "standard",
|
|
11
|
-
thinkingLevel: "medium",
|
|
12
|
-
};
|
|
13
|
-
const targetPair = {
|
|
14
|
-
provider: "faux",
|
|
15
|
-
modelId: "reasoning",
|
|
16
|
-
thinkingLevel: "high",
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
function createHost({ failTargetThinking = false, failRollbackModel = false, failCommitPersistence = false } = {}) {
|
|
20
|
-
let currentModel = { provider: fromPair.provider, id: fromPair.modelId };
|
|
21
|
-
let currentThinkingLevel = fromPair.thinkingLevel;
|
|
22
|
-
const entries = [];
|
|
23
|
-
const calls = [];
|
|
24
|
-
const models = new Map([
|
|
25
|
-
["faux/standard", currentModel],
|
|
26
|
-
["faux/reasoning", { provider: targetPair.provider, id: targetPair.modelId }],
|
|
27
|
-
]);
|
|
28
|
-
|
|
29
|
-
const pi = {
|
|
30
|
-
async setModel(model) {
|
|
31
|
-
calls.push(["setModel", model.provider, model.id]);
|
|
32
|
-
if (failRollbackModel && model.id === fromPair.modelId) return false;
|
|
33
|
-
currentModel = model;
|
|
34
|
-
return true;
|
|
35
|
-
},
|
|
36
|
-
setThinkingLevel(level) {
|
|
37
|
-
calls.push(["setThinkingLevel", level]);
|
|
38
|
-
currentThinkingLevel = level;
|
|
39
|
-
if (failTargetThinking && level === targetPair.thinkingLevel) {
|
|
40
|
-
throw new Error("simulated target thinking failure");
|
|
41
|
-
}
|
|
42
|
-
},
|
|
43
|
-
appendEntry(customType, data) {
|
|
44
|
-
calls.push(["appendEntry", customType, data]);
|
|
45
|
-
if (failCommitPersistence && data?.phase === "committed") {
|
|
46
|
-
throw new Error("simulated commit persistence failure");
|
|
47
|
-
}
|
|
48
|
-
entries.push({ type: "custom", customType, data });
|
|
49
|
-
},
|
|
50
|
-
};
|
|
51
|
-
const ctx = {
|
|
52
|
-
get model() {
|
|
53
|
-
return currentModel;
|
|
54
|
-
},
|
|
55
|
-
get thinkingLevel() {
|
|
56
|
-
return currentThinkingLevel;
|
|
57
|
-
},
|
|
58
|
-
modelRegistry: {
|
|
59
|
-
find(provider, modelId) {
|
|
60
|
-
return models.get(`${provider}/${modelId}`);
|
|
61
|
-
},
|
|
62
|
-
},
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
return { pi, ctx, entries, calls };
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
test("applies and commits a complete Pi session model-state transition", async () => {
|
|
69
|
-
const host = createHost();
|
|
70
|
-
const control = createPiSessionModelStateControl(host);
|
|
71
|
-
const acquisition = await control.acquireModelStateControl({ label: "Cognitive Routing" });
|
|
72
|
-
|
|
73
|
-
assert.equal(acquisition.status, "acquired");
|
|
74
|
-
const result = await acquisition.lease.setState({ ...targetPair, correlationId: "correlation-1" });
|
|
75
|
-
|
|
76
|
-
assert.deepEqual(result, { status: "applied" });
|
|
77
|
-
assert.deepEqual(
|
|
78
|
-
host.calls.map(([name]) => name),
|
|
79
|
-
["appendEntry", "setModel", "setThinkingLevel", "appendEntry"],
|
|
80
|
-
);
|
|
81
|
-
assert.deepEqual(host.entries, [
|
|
82
|
-
{
|
|
83
|
-
type: "custom",
|
|
84
|
-
customType: PI_SESSION_MODEL_STATE_ENTRY,
|
|
85
|
-
data: {
|
|
86
|
-
version: 1,
|
|
87
|
-
phase: "prepared",
|
|
88
|
-
status: "prepared",
|
|
89
|
-
correlationId: "correlation-1",
|
|
90
|
-
fromPair,
|
|
91
|
-
target: targetPair,
|
|
92
|
-
origin: { source: "pi", operation: "session-model-state-control" },
|
|
93
|
-
},
|
|
94
|
-
},
|
|
95
|
-
{
|
|
96
|
-
type: "custom",
|
|
97
|
-
customType: PI_SESSION_MODEL_STATE_ENTRY,
|
|
98
|
-
data: {
|
|
99
|
-
version: 1,
|
|
100
|
-
phase: "committed",
|
|
101
|
-
status: "applied",
|
|
102
|
-
correlationId: "correlation-1",
|
|
103
|
-
fromPair,
|
|
104
|
-
target: targetPair,
|
|
105
|
-
origin: { source: "pi", operation: "session-model-state-control" },
|
|
106
|
-
},
|
|
107
|
-
},
|
|
108
|
-
]);
|
|
109
|
-
assert.deepEqual(
|
|
110
|
-
{ provider: host.ctx.model.provider, modelId: host.ctx.model.id, thinkingLevel: host.ctx.thinkingLevel },
|
|
111
|
-
targetPair,
|
|
112
|
-
);
|
|
113
|
-
|
|
114
|
-
await acquisition.lease.release();
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
test("rolls back a partially applied target and records an aborted transition", async () => {
|
|
118
|
-
const host = createHost({ failTargetThinking: true });
|
|
119
|
-
const control = createPiSessionModelStateControl(host);
|
|
120
|
-
const acquisition = await control.acquireModelStateControl({ label: "Cognitive Routing" });
|
|
121
|
-
|
|
122
|
-
assert.equal(acquisition.status, "acquired");
|
|
123
|
-
const result = await acquisition.lease.setState({ ...targetPair, correlationId: "correlation-rollback" });
|
|
124
|
-
|
|
125
|
-
assert.deepEqual(result, { status: "rejected" });
|
|
126
|
-
assert.deepEqual(
|
|
127
|
-
host.calls.map(([name]) => name),
|
|
128
|
-
["appendEntry", "setModel", "setThinkingLevel", "setModel", "setThinkingLevel", "appendEntry"],
|
|
129
|
-
);
|
|
130
|
-
assert.deepEqual(
|
|
131
|
-
{ provider: host.ctx.model.provider, modelId: host.ctx.model.id, thinkingLevel: host.ctx.thinkingLevel },
|
|
132
|
-
fromPair,
|
|
133
|
-
);
|
|
134
|
-
assert.equal(host.entries.at(-1).data.failure, "thinking-level-change-failed");
|
|
135
|
-
|
|
136
|
-
await acquisition.lease.release();
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
test("fails closed when rollback cannot restore the captured pair", async () => {
|
|
140
|
-
const host = createHost({ failTargetThinking: true, failRollbackModel: true });
|
|
141
|
-
const control = createPiSessionModelStateControl(host);
|
|
142
|
-
const acquisition = await control.acquireModelStateControl({ label: "Cognitive Routing" });
|
|
143
|
-
|
|
144
|
-
assert.equal(acquisition.status, "acquired");
|
|
145
|
-
const result = await acquisition.lease.setState({ ...targetPair, correlationId: "correlation-rollback-failed" });
|
|
146
|
-
|
|
147
|
-
assert.deepEqual(result, { status: "rejected" });
|
|
148
|
-
assert.deepEqual(
|
|
149
|
-
{ provider: host.ctx.model.provider, modelId: host.ctx.model.id, thinkingLevel: host.ctx.thinkingLevel },
|
|
150
|
-
targetPair,
|
|
151
|
-
);
|
|
152
|
-
assert.equal(host.entries.at(-1).data.status, "rollback-failed");
|
|
153
|
-
assert.equal(host.entries.at(-1).data.failure, "rollback-failed");
|
|
154
|
-
|
|
155
|
-
await acquisition.lease.release();
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
test("restores the baseline when committed-marker persistence fails", async () => {
|
|
159
|
-
const host = createHost({ failCommitPersistence: true });
|
|
160
|
-
const control = createPiSessionModelStateControl(host);
|
|
161
|
-
const acquisition = await control.acquireModelStateControl({ label: "Cognitive Routing" });
|
|
162
|
-
|
|
163
|
-
assert.equal(acquisition.status, "acquired");
|
|
164
|
-
const result = await acquisition.lease.setState({ ...targetPair, correlationId: "correlation-commit-failed" });
|
|
165
|
-
|
|
166
|
-
assert.deepEqual(result, { status: "rejected" });
|
|
167
|
-
assert.deepEqual(
|
|
168
|
-
{ provider: host.ctx.model.provider, modelId: host.ctx.model.id, thinkingLevel: host.ctx.thinkingLevel },
|
|
169
|
-
fromPair,
|
|
170
|
-
);
|
|
171
|
-
assert.equal(host.entries.at(-1).data.failure, "commit-persistence-failed");
|
|
172
|
-
|
|
173
|
-
await acquisition.lease.release();
|
|
174
|
-
});
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert/strict";
|
|
2
|
-
import test from "node:test";
|
|
3
|
-
import { projectCognitiveRoutingHistory } from "../../dist/cognitive-routing/history.js";
|
|
4
|
-
import { PI_SESSION_MODEL_STATE_ENTRY } from "../../dist/cognitive-routing/pi-session-control.js";
|
|
5
|
-
|
|
6
|
-
const standard = { provider: "faux", modelId: "standard", thinkingLevel: "high" };
|
|
7
|
-
const reasoning = { provider: "faux", modelId: "reasoning", thinkingLevel: "max" };
|
|
8
|
-
|
|
9
|
-
const intent = {
|
|
10
|
-
version: 2,
|
|
11
|
-
phase: "prepared",
|
|
12
|
-
kind: "profile",
|
|
13
|
-
control: "automatic",
|
|
14
|
-
source: "agent",
|
|
15
|
-
mechanism: "agent-tool",
|
|
16
|
-
decisionCorrelationId: "correlation-1",
|
|
17
|
-
fromPair: standard,
|
|
18
|
-
fromProfile: "standard",
|
|
19
|
-
epoch: "epoch-1",
|
|
20
|
-
correlationId: "correlation-1",
|
|
21
|
-
profile: "reasoning",
|
|
22
|
-
target: reasoning,
|
|
23
|
-
returnTarget: { provider: "faux", modelId: "return", thinkingLevel: "medium" },
|
|
24
|
-
reason: "Need deeper analysis.",
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
test("projects a committed Pi session marker as the completed transition", () => {
|
|
28
|
-
const entries = [
|
|
29
|
-
{ id: "root", type: "message", parentId: null, timestamp: "2026-08-25T12:00:00.000Z" },
|
|
30
|
-
{
|
|
31
|
-
id: "intent-1",
|
|
32
|
-
type: "custom",
|
|
33
|
-
parentId: "root",
|
|
34
|
-
timestamp: "2026-08-25T12:00:01.000Z",
|
|
35
|
-
customType: "freeflow-cognitive-routing-intent",
|
|
36
|
-
data: intent,
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
id: "commit-1",
|
|
40
|
-
type: "custom",
|
|
41
|
-
parentId: "intent-1",
|
|
42
|
-
timestamp: "2026-08-25T12:00:02.000Z",
|
|
43
|
-
customType: PI_SESSION_MODEL_STATE_ENTRY,
|
|
44
|
-
data: {
|
|
45
|
-
version: 1,
|
|
46
|
-
phase: "committed",
|
|
47
|
-
status: "applied",
|
|
48
|
-
correlationId: "correlation-1",
|
|
49
|
-
fromPair: standard,
|
|
50
|
-
target: reasoning,
|
|
51
|
-
origin: { source: "pi", operation: "session-model-state-control" },
|
|
52
|
-
},
|
|
53
|
-
},
|
|
54
|
-
];
|
|
55
|
-
|
|
56
|
-
const result = projectCognitiveRoutingHistory(entries, {
|
|
57
|
-
branchEntries: entries,
|
|
58
|
-
current: { control: "automatic", profile: "reasoning" },
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
assert.deepEqual(result.events, [
|
|
62
|
-
{
|
|
63
|
-
id: "intent:intent-1",
|
|
64
|
-
timestamp: "2026-08-25T12:00:02.000Z",
|
|
65
|
-
jsonlPosition: 2,
|
|
66
|
-
entryId: "commit-1",
|
|
67
|
-
parentId: "intent-1",
|
|
68
|
-
branchAnchor: "commit-1",
|
|
69
|
-
classification: "semantic-switch",
|
|
70
|
-
decisionSource: "agent",
|
|
71
|
-
mechanism: "agent-tool",
|
|
72
|
-
outcome: "completed",
|
|
73
|
-
changed: true,
|
|
74
|
-
integrity: "valid",
|
|
75
|
-
from: "standard",
|
|
76
|
-
to: "reasoning",
|
|
77
|
-
control: "automatic",
|
|
78
|
-
reason: "Need deeper analysis.",
|
|
79
|
-
epoch: "epoch-1",
|
|
80
|
-
correlationId: "correlation-1",
|
|
81
|
-
decisionCorrelationId: "correlation-1",
|
|
82
|
-
hostOrigin: { source: "pi", operation: "session-model-state-control" },
|
|
83
|
-
},
|
|
84
|
-
]);
|
|
85
|
-
assert.deepEqual(result.summary, {
|
|
86
|
-
latestSemanticEventId: "intent:intent-1",
|
|
87
|
-
latestCompletedEventId: "intent:intent-1",
|
|
88
|
-
unresolvedCount: 0,
|
|
89
|
-
anomalyCount: 0,
|
|
90
|
-
});
|
|
91
|
-
});
|