pi-background-tasks 2.5.0 → 2.6.0
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/BACKGROUND-TASKS-INSTRUCTIONS.md +1 -1
- package/README.md +70 -25
- package/TESTING.md +42 -2
- package/TEST_PLAN.md +7 -4
- package/dist/extensions/anthropic-attribution-child.js +4 -0
- package/dist/extensions/anthropic-attribution-child.js.map +1 -0
- package/dist/extensions/anthropic-attribution.js +107 -0
- package/dist/extensions/anthropic-attribution.js.map +1 -0
- package/dist/extensions/background-tasks.js +2 -0
- package/dist/extensions/background-tasks.js.map +1 -0
- package/dist/extensions/delegate-child.js +2 -0
- package/dist/extensions/delegate-child.js.map +1 -0
- package/dist/extensions/fusion-child.js +2 -0
- package/dist/extensions/fusion-child.js.map +1 -0
- package/dist/package.json +5 -0
- package/dist/src/core/anthropic-attribution-path.js +24 -0
- package/dist/src/core/anthropic-attribution-path.js.map +1 -0
- package/dist/src/core/anthropic-attribution.js +2247 -0
- package/dist/src/core/anthropic-attribution.js.map +1 -0
- package/dist/src/core/attested-pi-contract.js +5 -0
- package/dist/src/core/attested-pi-contract.js.map +1 -0
- package/dist/src/core/attested-pi-run.js +749 -0
- package/dist/src/core/attested-pi-run.js.map +1 -0
- package/dist/src/core/canonical-json.js +19 -0
- package/dist/src/core/canonical-json.js.map +1 -0
- package/dist/src/core/common.js +787 -0
- package/dist/src/core/common.js.map +1 -0
- package/dist/src/core/config.js +78 -0
- package/dist/src/core/config.js.map +1 -0
- package/dist/src/core/context/parent-snapshot.js +75 -0
- package/dist/src/core/context/parent-snapshot.js.map +1 -0
- package/dist/src/core/context/token-budget.js +631 -0
- package/dist/src/core/context/token-budget.js.map +1 -0
- package/dist/src/core/context/visible-conversation-v2.js +390 -0
- package/dist/src/core/context/visible-conversation-v2.js.map +1 -0
- package/dist/src/core/delegate/artifacts.js +357 -0
- package/dist/src/core/delegate/artifacts.js.map +1 -0
- package/dist/src/core/delegate/budget.js +266 -0
- package/dist/src/core/delegate/budget.js.map +1 -0
- package/dist/src/core/delegate/facade-contract.js +7 -0
- package/dist/src/core/delegate/facade-contract.js.map +1 -0
- package/dist/src/core/delegate/hook-contract-evidence.json +18 -0
- package/dist/src/core/delegate/hook-contract.js +124 -0
- package/dist/src/core/delegate/hook-contract.js.map +1 -0
- package/dist/src/core/delegate/launch.js +366 -0
- package/dist/src/core/delegate/launch.js.map +1 -0
- package/dist/src/core/delegate/result-package.js +293 -0
- package/dist/src/core/delegate/result-package.js.map +1 -0
- package/dist/src/core/delegate/runner.js +398 -0
- package/dist/src/core/delegate/runner.js.map +1 -0
- package/dist/src/core/delegate/seed.js +334 -0
- package/dist/src/core/delegate/seed.js.map +1 -0
- package/dist/src/core/delegate/types.js +103 -0
- package/dist/src/core/delegate/types.js.map +1 -0
- package/dist/src/core/durable-fs.js +372 -0
- package/dist/src/core/durable-fs.js.map +1 -0
- package/dist/src/core/extension-api.js +382 -0
- package/dist/src/core/extension-api.js.map +1 -0
- package/dist/src/core/fusion/artifacts.js +654 -0
- package/dist/src/core/fusion/artifacts.js.map +1 -0
- package/dist/src/core/fusion/budget.js +949 -0
- package/dist/src/core/fusion/budget.js.map +1 -0
- package/dist/src/core/fusion/child-protocol.js +176 -0
- package/dist/src/core/fusion/child-protocol.js.map +1 -0
- package/dist/src/core/fusion/claude-cache.js +156 -0
- package/dist/src/core/fusion/claude-cache.js.map +1 -0
- package/dist/src/core/fusion/clean-context.js +64 -0
- package/dist/src/core/fusion/clean-context.js.map +1 -0
- package/dist/src/core/fusion/config.js +349 -0
- package/dist/src/core/fusion/config.js.map +1 -0
- package/dist/src/core/fusion/context.js +184 -0
- package/dist/src/core/fusion/context.js.map +1 -0
- package/dist/src/core/fusion/evaluation.js +696 -0
- package/dist/src/core/fusion/evaluation.js.map +1 -0
- package/dist/src/core/fusion/facade-contract.js +3 -0
- package/dist/src/core/fusion/facade-contract.js.map +1 -0
- package/dist/src/core/fusion/orchestrator.js +867 -0
- package/dist/src/core/fusion/orchestrator.js.map +1 -0
- package/dist/src/core/fusion/output-contract.js +27 -0
- package/dist/src/core/fusion/output-contract.js.map +1 -0
- package/dist/src/core/fusion/pi-child.js +1741 -0
- package/dist/src/core/fusion/pi-child.js.map +1 -0
- package/dist/src/core/fusion/prompts.js +260 -0
- package/dist/src/core/fusion/prompts.js.map +1 -0
- package/dist/src/core/fusion/result-package.js +857 -0
- package/dist/src/core/fusion/result-package.js.map +1 -0
- package/dist/src/core/fusion/source-policy.js +259 -0
- package/dist/src/core/fusion/source-policy.js.map +1 -0
- package/dist/src/core/fusion/types.js +207 -0
- package/dist/src/core/fusion/types.js.map +1 -0
- package/dist/src/core/fusion/web-fetch.js +777 -0
- package/dist/src/core/fusion/web-fetch.js.map +1 -0
- package/dist/src/core/fusion/workflows.js +126 -0
- package/dist/src/core/fusion/workflows.js.map +1 -0
- package/dist/src/core/lazy-module.js +181 -0
- package/dist/src/core/lazy-module.js.map +1 -0
- package/dist/src/core/pi-launch.js +431 -0
- package/dist/src/core/pi-launch.js.map +1 -0
- package/dist/src/core/registry.js +3331 -0
- package/dist/src/core/registry.js.map +1 -0
- package/dist/src/core/reload-shell-owner.js +1396 -0
- package/dist/src/core/reload-shell-owner.js.map +1 -0
- package/dist/src/core/shell-policy.js +80 -0
- package/dist/src/core/shell-policy.js.map +1 -0
- package/dist/src/core/task-durable.js +51 -0
- package/dist/src/core/task-durable.js.map +1 -0
- package/dist/src/core/update-check.js +92 -0
- package/dist/src/core/update-check.js.map +1 -0
- package/dist/src/core/windows-taskkill.js +185 -0
- package/dist/src/core/windows-taskkill.js.map +1 -0
- package/dist/src/delegate-child-extension.js +776 -0
- package/dist/src/delegate-child-extension.js.map +1 -0
- package/dist/src/delegate-extension.js +746 -0
- package/dist/src/delegate-extension.js.map +1 -0
- package/dist/src/extension.js +953 -0
- package/dist/src/extension.js.map +1 -0
- package/dist/src/fusion-child-extension.js +760 -0
- package/dist/src/fusion-child-extension.js.map +1 -0
- package/dist/src/fusion-extension.js +1030 -0
- package/dist/src/fusion-extension.js.map +1 -0
- package/dist/src/ui/background-tasks-manager.js +689 -0
- package/dist/src/ui/background-tasks-manager.js.map +1 -0
- package/dist/src/ui/fusion-model-selector.js +277 -0
- package/dist/src/ui/fusion-model-selector.js.map +1 -0
- package/docs/INDEX.md +35 -33
- package/docs/api/eventbus-v1.md +21 -5
- package/docs/choose-a-workflow.md +2 -0
- package/docs/commands/bg-clear.md +3 -3
- package/docs/commands/bg-update.md +3 -3
- package/docs/commands/bg.md +18 -6
- package/docs/commands/claude-cache.md +4 -4
- package/docs/commands/fusion-models.md +49 -4
- package/docs/commands/fusion.md +3 -3
- package/docs/commands/jobs.md +3 -3
- package/docs/commands/kill.md +3 -3
- package/docs/commands/logs.md +3 -3
- package/docs/commands/task-manager.md +5 -5
- package/docs/concepts/completion-delivery.md +6 -2
- package/docs/getting-started.md +7 -1
- package/docs/manifest.json +228 -42
- package/docs/operations/configuration.md +58 -5
- package/docs/operations/releasing.md +4 -2
- package/docs/operations/testing.md +22 -0
- package/docs/operations/troubleshooting.md +6 -2
- package/docs/read-before-edit.md +44 -31
- package/docs/reference/runtime-contracts.md +87 -51
- package/docs/reference/shortcuts-and-dock.md +28 -14
- package/docs/subsystems/anthropic-attribution.md +23 -11
- package/docs/subsystems/attested-pi-runs.md +12 -7
- package/docs/subsystems/background-task-runtime.md +53 -11
- package/docs/subsystems/child-launch-durability-and-safety.md +28 -9
- package/docs/subsystems/delegation.md +16 -3
- package/docs/subsystems/docs-freshness-gate.md +14 -7
- package/docs/subsystems/fusion.md +36 -11
- package/docs/subsystems/host-ui-and-telemetry.md +22 -9
- package/docs/tools/bg_delegate.md +3 -1
- package/docs/tools/bg_kill.md +3 -1
- package/docs/tools/bg_logs.md +3 -1
- package/docs/tools/bg_result.md +5 -3
- package/docs/tools/bg_run.md +31 -5
- package/docs/tools/bg_run_pi_attested.md +3 -1
- package/docs/tools/bg_status.md +3 -1
- package/docs/tools/fusion_investigate.md +3 -1
- package/docs/tools/fusion_reason.md +3 -1
- package/docs/tools/fusion_research.md +3 -1
- package/docs/tools/fusion_validate.md +3 -1
- package/extensions/anthropic-attribution-child.ts +3 -0
- package/extensions/anthropic-attribution.ts +166 -1
- package/package.json +12 -10
- package/src/core/anthropic-attribution-path.ts +5 -4
- package/src/core/anthropic-attribution.ts +293 -113
- package/src/core/attested-pi-contract.ts +4 -0
- package/src/core/attested-pi-run.ts +468 -81
- package/src/core/canonical-json.ts +21 -0
- package/src/core/common.ts +450 -40
- package/src/core/config.ts +121 -0
- package/src/core/context/visible-conversation-v2.ts +3 -6
- package/src/core/delegate/artifacts.ts +13 -9
- package/src/core/delegate/budget.ts +13 -6
- package/src/core/delegate/facade-contract.ts +6 -0
- package/src/core/delegate/result-package.ts +32 -14
- package/src/core/delegate/runner.ts +129 -58
- package/src/core/delegate/seed.ts +5 -7
- package/src/core/durable-fs.ts +178 -30
- package/src/core/extension-api.ts +36 -8
- package/src/core/fusion/artifacts.ts +17 -16
- package/src/core/fusion/clean-context.ts +8 -5
- package/src/core/fusion/config.ts +2 -1
- package/src/core/fusion/context.ts +2 -6
- package/src/core/fusion/facade-contract.ts +2 -0
- package/src/core/fusion/orchestrator.ts +3 -3
- package/src/core/fusion/prompts.ts +1 -1
- package/src/core/fusion/result-package.ts +259 -72
- package/src/core/fusion/source-policy.ts +43 -17
- package/src/core/lazy-module.ts +215 -0
- package/src/core/pi-launch.ts +390 -65
- package/src/core/registry.ts +2010 -381
- package/src/core/reload-shell-owner.ts +1662 -0
- package/src/core/shell-policy.ts +134 -0
- package/src/core/task-durable.ts +67 -0
- package/src/delegate-extension.ts +404 -144
- package/src/extension.ts +387 -114
- package/src/fusion-extension.ts +202 -96
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { canonicalJson } from '../canonical-json.js';
|
|
3
|
+
import { projectVisibleConversationV2, } from '../context/visible-conversation-v2.js';
|
|
4
|
+
import { snapshotParentConversation, } from '../context/parent-snapshot.js';
|
|
5
|
+
import { FUSION_REASON_TOOL_NAME } from './workflows.js';
|
|
6
|
+
import { FUSION_BRANCH_FILTER_ID, FUSION_COMMAND_CONTEXT_POLICY_ID, FUSION_CONTEXT_LEDGER_SCHEMA_VERSION, FUSION_CONTEXT_TRANSFORM_ID, FUSION_INPUT_SCHEMA_VERSION, FUSION_TOOL_CONTEXT_POLICY_ID, FusionError, } from './types.js';
|
|
7
|
+
/**
|
|
8
|
+
* Re-exported from the workflow registry, which owns every workflow's tool name.
|
|
9
|
+
* Kept here so existing importers of this module keep working unchanged.
|
|
10
|
+
*/
|
|
11
|
+
export { FUSION_BRAINSTORM_TOOL_NAME, FUSION_REASON_TOOL_NAME, FUSION_INVESTIGATE_TOOL_NAME, FUSION_RESEARCH_TOOL_NAME, FUSION_VALIDATE_TOOL_NAME, } from './workflows.js';
|
|
12
|
+
export function normalizeFusionCommandRequest(args) {
|
|
13
|
+
return args.trim();
|
|
14
|
+
}
|
|
15
|
+
function sha256Text(value) {
|
|
16
|
+
return createHash('sha256').update(Buffer.from(value, 'utf8')).digest('hex');
|
|
17
|
+
}
|
|
18
|
+
function contextPolicyId(source) {
|
|
19
|
+
return source === 'tool' ? FUSION_TOOL_CONTEXT_POLICY_ID : FUSION_COMMAND_CONTEXT_POLICY_ID;
|
|
20
|
+
}
|
|
21
|
+
function requestAuthority(source) {
|
|
22
|
+
return source === 'tool' ? 'explicit_text' : 'directive_over_projected_conversation';
|
|
23
|
+
}
|
|
24
|
+
function policyDescriptor(source) {
|
|
25
|
+
return {
|
|
26
|
+
id: contextPolicyId(source),
|
|
27
|
+
transform: FUSION_CONTEXT_TRANSFORM_ID,
|
|
28
|
+
version: 2,
|
|
29
|
+
receipt_format: 'omitted_activity.v2',
|
|
30
|
+
user_text: 'verbatim',
|
|
31
|
+
assistant_text: 'verbatim',
|
|
32
|
+
assistant_thinking: 'ledger_only',
|
|
33
|
+
tool_call_arguments: 'ledger_only',
|
|
34
|
+
tool_results: 'ledger_only',
|
|
35
|
+
tool_payload_preview_bytes: 0,
|
|
36
|
+
images: 'marker_or_ledger_only',
|
|
37
|
+
unknown_block_behavior: 'error',
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
function compactOmissionCounts(counts) {
|
|
41
|
+
return [counts.assistant_thinking ?? 0, counts.tool_calls ?? 0, counts.tool_result_texts ?? 0];
|
|
42
|
+
}
|
|
43
|
+
function expandOmissionCounts(counts) {
|
|
44
|
+
const out = {};
|
|
45
|
+
const [assistantThinking, toolCalls, toolResults] = counts;
|
|
46
|
+
if (assistantThinking > 0)
|
|
47
|
+
out.assistant_thinking = assistantThinking;
|
|
48
|
+
if (toolCalls > 0)
|
|
49
|
+
out.tool_calls = toolCalls;
|
|
50
|
+
if (toolResults > 0)
|
|
51
|
+
out.tool_result_texts = toolResults;
|
|
52
|
+
return out;
|
|
53
|
+
}
|
|
54
|
+
export function compactFusionProjectionEntry(entry) {
|
|
55
|
+
if (entry.kind === 'text') {
|
|
56
|
+
return [
|
|
57
|
+
't',
|
|
58
|
+
entry.role === 'user' ? 'u' : 'a',
|
|
59
|
+
entry.source_ordinal,
|
|
60
|
+
entry.block_ordinal,
|
|
61
|
+
entry.text,
|
|
62
|
+
];
|
|
63
|
+
}
|
|
64
|
+
return ['o', [entry.at[0], entry.at[1]], entry.bytes, compactOmissionCounts(entry.counts)];
|
|
65
|
+
}
|
|
66
|
+
export function expandFusionProjectionEntry(entry) {
|
|
67
|
+
if (entry[0] === 't') {
|
|
68
|
+
return {
|
|
69
|
+
kind: 'text',
|
|
70
|
+
source_ordinal: entry[2],
|
|
71
|
+
block_ordinal: entry[3],
|
|
72
|
+
role: entry[1] === 'u' ? 'user' : 'assistant',
|
|
73
|
+
text: entry[4],
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
return {
|
|
77
|
+
kind: 'omitted_activity',
|
|
78
|
+
at: [entry[1][0], entry[1][1]],
|
|
79
|
+
bytes: entry[2],
|
|
80
|
+
counts: expandOmissionCounts(entry[3]),
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
function compactFusionProjectionEntries(entries) {
|
|
84
|
+
return entries.map(compactFusionProjectionEntry);
|
|
85
|
+
}
|
|
86
|
+
function compactOmissionReceiptBytes(entries) {
|
|
87
|
+
let total = 0;
|
|
88
|
+
for (const entry of entries) {
|
|
89
|
+
if (entry[0] === 'o')
|
|
90
|
+
total += Buffer.byteLength(canonicalJson(entry), 'utf8');
|
|
91
|
+
}
|
|
92
|
+
return total;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Seal the shared transform output into Fusion's versioned envelopes.
|
|
96
|
+
*
|
|
97
|
+
* Fusion v4 compacts only the child-facing projection entries. Ledger rows are
|
|
98
|
+
* carried through unchanged, so the ledger root commits to exactly the same
|
|
99
|
+
* omitted payload records before and after tuple encoding. Golden tests pin the
|
|
100
|
+
* new canonical-input bytes and the unchanged ledger bytes.
|
|
101
|
+
*/
|
|
102
|
+
function sealFusionProjection(projected, source, branchFilter) {
|
|
103
|
+
const entries = compactFusionProjectionEntries(projected.entries);
|
|
104
|
+
return {
|
|
105
|
+
projection: {
|
|
106
|
+
policy: policyDescriptor(source),
|
|
107
|
+
branch_filter: branchFilter,
|
|
108
|
+
entries,
|
|
109
|
+
accounting: {
|
|
110
|
+
...projected.accounting,
|
|
111
|
+
omission_receipt_utf8_bytes: compactOmissionReceiptBytes(entries),
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
ledger: {
|
|
115
|
+
schema_version: FUSION_CONTEXT_LEDGER_SCHEMA_VERSION,
|
|
116
|
+
policy_id: contextPolicyId(source),
|
|
117
|
+
transform: FUSION_CONTEXT_TRANSFORM_ID,
|
|
118
|
+
entries: projected.ledger.entries,
|
|
119
|
+
projection_map: projected.ledger.projection_map,
|
|
120
|
+
root_sha256: projected.ledger.root_sha256,
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
/** Preserved public entry point; delegates to the shared frozen transform. */
|
|
125
|
+
export function projectFusionConversation(messages, source, branchFilter) {
|
|
126
|
+
return sealFusionProjection(projectVisibleConversationV2(messages), source, branchFilter);
|
|
127
|
+
}
|
|
128
|
+
export function buildFusionCanonicalInput(ctx, options) {
|
|
129
|
+
if (options.request.trim().length === 0) {
|
|
130
|
+
throw new FusionError('fusion request must not be blank', {
|
|
131
|
+
code: 'context_capture_failed',
|
|
132
|
+
childCreated: false,
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
const workflow = options.workflow ?? 'reason';
|
|
136
|
+
if (workflow !== 'reason') {
|
|
137
|
+
throw new FusionError('parent session projection is available only to the reason workflow', {
|
|
138
|
+
code: 'context_capture_failed',
|
|
139
|
+
childCreated: false,
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
const toolName = options.toolName ?? FUSION_REASON_TOOL_NAME;
|
|
143
|
+
const snapshotOptions = {
|
|
144
|
+
toolName,
|
|
145
|
+
excludeActiveToolCallLeaf: options.source === 'tool',
|
|
146
|
+
};
|
|
147
|
+
if (options.toolCallId !== undefined)
|
|
148
|
+
snapshotOptions.toolCallId = options.toolCallId;
|
|
149
|
+
const snapshot = snapshotParentConversation(ctx, snapshotOptions);
|
|
150
|
+
const branchFilter = {
|
|
151
|
+
id: FUSION_BRANCH_FILTER_ID,
|
|
152
|
+
tool_name: toolName,
|
|
153
|
+
tool_call_id: options.source === 'tool' ? (options.toolCallId ?? null) : null,
|
|
154
|
+
active_tool_call_leaf_excluded: snapshot.activeToolCallLeafExcluded,
|
|
155
|
+
};
|
|
156
|
+
const projected = projectFusionConversation(snapshot.messages, options.source, branchFilter);
|
|
157
|
+
const request = {
|
|
158
|
+
source: options.source,
|
|
159
|
+
authority: requestAuthority(options.source),
|
|
160
|
+
text: options.request,
|
|
161
|
+
sha256: sha256Text(options.request),
|
|
162
|
+
};
|
|
163
|
+
const input = {
|
|
164
|
+
schema_version: FUSION_INPUT_SCHEMA_VERSION,
|
|
165
|
+
workflow: 'reason',
|
|
166
|
+
cwd: ctx.cwd,
|
|
167
|
+
request,
|
|
168
|
+
system_prompt: ctx.getSystemPrompt(),
|
|
169
|
+
conversation_projection: projected.projection,
|
|
170
|
+
context: {
|
|
171
|
+
kind: 'session_projection',
|
|
172
|
+
policy_id: 'fusion-session-projection-v1',
|
|
173
|
+
system_prompt: ctx.getSystemPrompt(),
|
|
174
|
+
conversation_projection: projected.projection,
|
|
175
|
+
},
|
|
176
|
+
};
|
|
177
|
+
return {
|
|
178
|
+
input,
|
|
179
|
+
serialized: canonicalJson(input),
|
|
180
|
+
ledger: projected.ledger,
|
|
181
|
+
transcriptLeafId: snapshot.leafId,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../../../src/core/fusion/context.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from 'node:crypto';\nimport { canonicalJson } from '../canonical-json.js';\nimport {\n projectVisibleConversationV2,\n type OmittedRunCounts,\n type ProjectedConversationV2,\n type ProjectionEntry,\n} from '../context/visible-conversation-v2.js';\nimport {\n snapshotParentConversation,\n type ParentContextSource,\n type ParentSnapshotOptions,\n type ReadonlyParentSessionManager,\n} from '../context/parent-snapshot.js';\nimport type { Message } from '@earendil-works/pi-ai';\nimport { FUSION_REASON_TOOL_NAME } from './workflows.js';\nimport {\n FUSION_BRANCH_FILTER_ID,\n FUSION_COMMAND_CONTEXT_POLICY_ID,\n FUSION_CONTEXT_LEDGER_SCHEMA_VERSION,\n FUSION_CONTEXT_TRANSFORM_ID,\n FUSION_INPUT_SCHEMA_VERSION,\n FUSION_TOOL_CONTEXT_POLICY_ID,\n FusionError,\n type FusionBranchFilterDescriptor,\n type FusionCanonicalRequestV3,\n type FusionSessionProjectionCanonicalInputV5,\n type FusionWorkflowId,\n type FusionContextOmissionLedgerV2,\n type FusionContextPolicyDescriptor,\n type FusionConversationProjectionV3,\n type FusionProjectionEntry,\n type FusionProjectionOmissionCounts,\n type FusionRequestAuthority,\n type FusionSource,\n} from './types.js';\n\n/**\n * Re-exported from the workflow registry, which owns every workflow's tool name.\n * Kept here so existing importers of this module keep working unchanged.\n */\nexport {\n FUSION_BRAINSTORM_TOOL_NAME,\n FUSION_REASON_TOOL_NAME,\n FUSION_INVESTIGATE_TOOL_NAME,\n FUSION_RESEARCH_TOOL_NAME,\n FUSION_VALIDATE_TOOL_NAME,\n} from './workflows.js';\n\n/** Retained for source compatibility; Fusion's session access is the shared adapter. */\nexport type FusionReadonlySessionManager = ReadonlyParentSessionManager;\nexport type FusionContextSource = ParentContextSource;\n\nexport interface BuildFusionCanonicalInputOptions {\n source: FusionSource;\n request: string;\n toolCallId?: string;\n toolName?: string;\n workflow?: FusionWorkflowId;\n}\n\nexport interface BuiltFusionCanonicalInput {\n input: FusionSessionProjectionCanonicalInputV5;\n serialized: string;\n ledger: FusionContextOmissionLedgerV2;\n transcriptLeafId: string | null;\n}\n\nexport function normalizeFusionCommandRequest(args: string): string {\n return args.trim();\n}\n\nfunction sha256Text(value: string): string {\n return createHash('sha256').update(Buffer.from(value, 'utf8')).digest('hex');\n}\n\nfunction contextPolicyId(source: FusionSource): string {\n return source === 'tool' ? FUSION_TOOL_CONTEXT_POLICY_ID : FUSION_COMMAND_CONTEXT_POLICY_ID;\n}\n\nfunction requestAuthority(source: FusionSource): FusionRequestAuthority {\n return source === 'tool' ? 'explicit_text' : 'directive_over_projected_conversation';\n}\n\nfunction policyDescriptor(source: FusionSource): FusionContextPolicyDescriptor {\n return {\n id: contextPolicyId(source),\n transform: FUSION_CONTEXT_TRANSFORM_ID,\n version: 2,\n receipt_format: 'omitted_activity.v2',\n user_text: 'verbatim',\n assistant_text: 'verbatim',\n assistant_thinking: 'ledger_only',\n tool_call_arguments: 'ledger_only',\n tool_results: 'ledger_only',\n tool_payload_preview_bytes: 0,\n images: 'marker_or_ledger_only',\n unknown_block_behavior: 'error',\n };\n}\n\nfunction compactOmissionCounts(counts: OmittedRunCounts): FusionProjectionOmissionCounts {\n return [counts.assistant_thinking ?? 0, counts.tool_calls ?? 0, counts.tool_result_texts ?? 0];\n}\n\nfunction expandOmissionCounts(counts: FusionProjectionOmissionCounts): OmittedRunCounts {\n const out: OmittedRunCounts = {};\n const [assistantThinking, toolCalls, toolResults] = counts;\n if (assistantThinking > 0) out.assistant_thinking = assistantThinking;\n if (toolCalls > 0) out.tool_calls = toolCalls;\n if (toolResults > 0) out.tool_result_texts = toolResults;\n return out;\n}\n\nexport function compactFusionProjectionEntry(entry: ProjectionEntry): FusionProjectionEntry {\n if (entry.kind === 'text') {\n return [\n 't',\n entry.role === 'user' ? 'u' : 'a',\n entry.source_ordinal,\n entry.block_ordinal,\n entry.text,\n ];\n }\n return ['o', [entry.at[0], entry.at[1]], entry.bytes, compactOmissionCounts(entry.counts)];\n}\n\nexport function expandFusionProjectionEntry(entry: FusionProjectionEntry): ProjectionEntry {\n if (entry[0] === 't') {\n return {\n kind: 'text',\n source_ordinal: entry[2],\n block_ordinal: entry[3],\n role: entry[1] === 'u' ? 'user' : 'assistant',\n text: entry[4],\n };\n }\n return {\n kind: 'omitted_activity',\n at: [entry[1][0], entry[1][1]],\n bytes: entry[2],\n counts: expandOmissionCounts(entry[3]),\n };\n}\n\nfunction compactFusionProjectionEntries(\n entries: readonly ProjectionEntry[],\n): readonly FusionProjectionEntry[] {\n return entries.map(compactFusionProjectionEntry);\n}\n\nfunction compactOmissionReceiptBytes(entries: readonly FusionProjectionEntry[]): number {\n let total = 0;\n for (const entry of entries) {\n if (entry[0] === 'o') total += Buffer.byteLength(canonicalJson(entry), 'utf8');\n }\n return total;\n}\n\n/**\n * Seal the shared transform output into Fusion's versioned envelopes.\n *\n * Fusion v4 compacts only the child-facing projection entries. Ledger rows are\n * carried through unchanged, so the ledger root commits to exactly the same\n * omitted payload records before and after tuple encoding. Golden tests pin the\n * new canonical-input bytes and the unchanged ledger bytes.\n */\nfunction sealFusionProjection(\n projected: ProjectedConversationV2,\n source: FusionSource,\n branchFilter: FusionBranchFilterDescriptor,\n): { projection: FusionConversationProjectionV3; ledger: FusionContextOmissionLedgerV2 } {\n const entries = compactFusionProjectionEntries(projected.entries);\n return {\n projection: {\n policy: policyDescriptor(source),\n branch_filter: branchFilter,\n entries,\n accounting: {\n ...projected.accounting,\n omission_receipt_utf8_bytes: compactOmissionReceiptBytes(entries),\n },\n },\n ledger: {\n schema_version: FUSION_CONTEXT_LEDGER_SCHEMA_VERSION,\n policy_id: contextPolicyId(source),\n transform: FUSION_CONTEXT_TRANSFORM_ID,\n entries: projected.ledger.entries,\n projection_map: projected.ledger.projection_map,\n root_sha256: projected.ledger.root_sha256,\n },\n };\n}\n\n/** Preserved public entry point; delegates to the shared frozen transform. */\nexport function projectFusionConversation(\n messages: readonly Message[],\n source: FusionSource,\n branchFilter: FusionBranchFilterDescriptor,\n): { projection: FusionConversationProjectionV3; ledger: FusionContextOmissionLedgerV2 } {\n return sealFusionProjection(projectVisibleConversationV2(messages), source, branchFilter);\n}\n\nexport function buildFusionCanonicalInput(\n ctx: FusionContextSource,\n options: BuildFusionCanonicalInputOptions,\n): BuiltFusionCanonicalInput {\n if (options.request.trim().length === 0) {\n throw new FusionError('fusion request must not be blank', {\n code: 'context_capture_failed',\n childCreated: false,\n });\n }\n const workflow = options.workflow ?? 'reason';\n if (workflow !== 'reason') {\n throw new FusionError('parent session projection is available only to the reason workflow', {\n code: 'context_capture_failed',\n childCreated: false,\n });\n }\n const toolName = options.toolName ?? FUSION_REASON_TOOL_NAME;\n const snapshotOptions: ParentSnapshotOptions = {\n toolName,\n excludeActiveToolCallLeaf: options.source === 'tool',\n };\n if (options.toolCallId !== undefined) snapshotOptions.toolCallId = options.toolCallId;\n const snapshot = snapshotParentConversation(ctx, snapshotOptions);\n const branchFilter: FusionBranchFilterDescriptor = {\n id: FUSION_BRANCH_FILTER_ID,\n tool_name: toolName,\n tool_call_id: options.source === 'tool' ? (options.toolCallId ?? null) : null,\n active_tool_call_leaf_excluded: snapshot.activeToolCallLeafExcluded,\n };\n const projected = projectFusionConversation(snapshot.messages, options.source, branchFilter);\n const request: FusionCanonicalRequestV3 = {\n source: options.source,\n authority: requestAuthority(options.source),\n text: options.request,\n sha256: sha256Text(options.request),\n };\n const input: FusionSessionProjectionCanonicalInputV5 = {\n schema_version: FUSION_INPUT_SCHEMA_VERSION,\n workflow: 'reason',\n cwd: ctx.cwd,\n request,\n system_prompt: ctx.getSystemPrompt(),\n conversation_projection: projected.projection,\n context: {\n kind: 'session_projection',\n policy_id: 'fusion-session-projection-v1',\n system_prompt: ctx.getSystemPrompt(),\n conversation_projection: projected.projection,\n },\n };\n return {\n input,\n serialized: canonicalJson(input),\n ledger: projected.ledger,\n transcriptLeafId: snapshot.leafId,\n };\n}\n"]}
|