@pi-unipi/background-tasks 2.16.1 → 2.18.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.
Files changed (46) hide show
  1. package/README.md +21 -27
  2. package/package.json +3 -4
  3. package/src/cards.ts +76 -0
  4. package/src/child-process.ts +1 -1
  5. package/src/config.ts +0 -42
  6. package/src/context-visible-conversation-v2.ts +1 -1
  7. package/src/delegate/artifacts.ts +1 -1
  8. package/src/delegate/launch.ts +17 -30
  9. package/src/delegate/result-package.ts +1 -1
  10. package/src/delegate/runner.ts +1 -20
  11. package/src/delegate/seed.ts +1 -1
  12. package/src/delegate-extension.ts +16 -168
  13. package/src/index.ts +53 -25
  14. package/src/json-utils.ts +56 -0
  15. package/src/package-assets.ts +51 -0
  16. package/src/registry.ts +8 -459
  17. package/src/task-manager.ts +13 -2
  18. package/src/tools.ts +4 -189
  19. package/src/types.ts +17 -70
  20. package/extensions/anthropic-attribution.ts +0 -1
  21. package/extensions/fusion-child.ts +0 -1
  22. package/src/anthropic-attribution-path.ts +0 -21
  23. package/src/anthropic-attribution.ts +0 -1983
  24. package/src/attested-pi-run.ts +0 -612
  25. package/src/fixtures/fusion-golden-bytes.json +0 -310
  26. package/src/fixtures/fusion-validate-golden-bytes.json +0 -282
  27. package/src/fusion/artifacts.ts +0 -967
  28. package/src/fusion/budget.ts +0 -1162
  29. package/src/fusion/child-protocol.ts +0 -305
  30. package/src/fusion/claude-cache.ts +0 -207
  31. package/src/fusion/clean-context.ts +0 -91
  32. package/src/fusion/config.ts +0 -449
  33. package/src/fusion/context.ts +0 -265
  34. package/src/fusion/evaluation.ts +0 -800
  35. package/src/fusion/orchestrator.ts +0 -1288
  36. package/src/fusion/output-contract.ts +0 -34
  37. package/src/fusion/pi-child.ts +0 -2373
  38. package/src/fusion/prompts.ts +0 -345
  39. package/src/fusion/result-package.ts +0 -959
  40. package/src/fusion/source-policy.ts +0 -257
  41. package/src/fusion/types.ts +0 -1139
  42. package/src/fusion/web-fetch.ts +0 -1060
  43. package/src/fusion/workflows.ts +0 -184
  44. package/src/fusion-child-extension.ts +0 -1052
  45. package/src/fusion-extension.ts +0 -1293
  46. package/src/ui/fusion-model-selector.ts +0 -322
@@ -1,265 +0,0 @@
1
- import { createHash } from 'node:crypto';
2
- import { canonicalJson } from '../attested-pi-run.js';
3
- import {
4
- projectVisibleConversationV2,
5
- type OmittedRunCounts,
6
- type ProjectedConversationV2,
7
- type ProjectionEntry,
8
- } from '../context-visible-conversation-v2.js';
9
- import {
10
- snapshotParentConversation,
11
- type ParentContextSource,
12
- type ParentSnapshotOptions,
13
- type ReadonlyParentSessionManager,
14
- } from '../context-parent-snapshot.js';
15
- import type { Message } from '@earendil-works/pi-ai';
16
- import { FUSION_REASON_TOOL_NAME } from './workflows.js';
17
- import {
18
- FUSION_BRANCH_FILTER_ID,
19
- FUSION_COMMAND_CONTEXT_POLICY_ID,
20
- FUSION_CONTEXT_LEDGER_SCHEMA_VERSION,
21
- FUSION_CONTEXT_TRANSFORM_ID,
22
- FUSION_INPUT_SCHEMA_VERSION,
23
- FUSION_TOOL_CONTEXT_POLICY_ID,
24
- FusionError,
25
- type FusionBranchFilterDescriptor,
26
- type FusionCanonicalRequestV3,
27
- type FusionSessionProjectionCanonicalInputV5,
28
- type FusionWorkflowId,
29
- type FusionContextOmissionLedgerV2,
30
- type FusionContextPolicyDescriptor,
31
- type FusionConversationProjectionV3,
32
- type FusionProjectionEntry,
33
- type FusionProjectionOmissionCounts,
34
- type FusionRequestAuthority,
35
- type FusionSource,
36
- } from './types.js';
37
-
38
- /**
39
- * Re-exported from the workflow registry, which owns every workflow's tool name.
40
- * Kept here so existing importers of this module keep working unchanged.
41
- */
42
- export {
43
- FUSION_BRAINSTORM_TOOL_NAME,
44
- FUSION_REASON_TOOL_NAME,
45
- FUSION_INVESTIGATE_TOOL_NAME,
46
- FUSION_RESEARCH_TOOL_NAME,
47
- FUSION_VALIDATE_TOOL_NAME,
48
- } from './workflows.js';
49
-
50
- /** Retained for source compatibility; Fusion's session access is the shared adapter. */
51
- export type FusionReadonlySessionManager = ReadonlyParentSessionManager;
52
- export type FusionContextSource = ParentContextSource;
53
-
54
- export interface BuildFusionCanonicalInputOptions {
55
- source: FusionSource;
56
- request: string;
57
- toolCallId?: string;
58
- toolName?: string;
59
- workflow?: FusionWorkflowId;
60
- }
61
-
62
- export interface BuiltFusionCanonicalInput {
63
- input: FusionSessionProjectionCanonicalInputV5;
64
- serialized: string;
65
- ledger: FusionContextOmissionLedgerV2;
66
- transcriptLeafId: string | null;
67
- }
68
-
69
- export function normalizeFusionCommandRequest(args: string): string {
70
- return args.trim();
71
- }
72
-
73
- function sha256Text(value: string): string {
74
- return createHash('sha256').update(Buffer.from(value, 'utf8')).digest('hex');
75
- }
76
-
77
- function contextPolicyId(source: FusionSource): string {
78
- return source === 'tool' ? FUSION_TOOL_CONTEXT_POLICY_ID : FUSION_COMMAND_CONTEXT_POLICY_ID;
79
- }
80
-
81
- function requestAuthority(source: FusionSource): FusionRequestAuthority {
82
- return source === 'tool' ? 'explicit_text' : 'directive_over_projected_conversation';
83
- }
84
-
85
- function policyDescriptor(source: FusionSource): FusionContextPolicyDescriptor {
86
- return {
87
- id: contextPolicyId(source),
88
- transform: FUSION_CONTEXT_TRANSFORM_ID,
89
- version: 2,
90
- receipt_format: 'omitted_activity.v2',
91
- user_text: 'verbatim',
92
- assistant_text: 'verbatim',
93
- assistant_thinking: 'ledger_only',
94
- tool_call_arguments: 'ledger_only',
95
- tool_results: 'ledger_only',
96
- tool_payload_preview_bytes: 0,
97
- images: 'marker_or_ledger_only',
98
- unknown_block_behavior: 'error',
99
- };
100
- }
101
-
102
- function compactOmissionCounts(counts: OmittedRunCounts): FusionProjectionOmissionCounts {
103
- return [
104
- counts.assistant_thinking ?? 0,
105
- counts.tool_calls ?? 0,
106
- counts.tool_result_texts ?? 0,
107
- ];
108
- }
109
-
110
- function expandOmissionCounts(counts: FusionProjectionOmissionCounts): OmittedRunCounts {
111
- const out: OmittedRunCounts = {};
112
- const [assistantThinking, toolCalls, toolResults] = counts;
113
- if (assistantThinking > 0) out.assistant_thinking = assistantThinking;
114
- if (toolCalls > 0) out.tool_calls = toolCalls;
115
- if (toolResults > 0) out.tool_result_texts = toolResults;
116
- return out;
117
- }
118
-
119
- export function compactFusionProjectionEntry(entry: ProjectionEntry): FusionProjectionEntry {
120
- if (entry.kind === 'text') {
121
- return [
122
- 't',
123
- entry.role === 'user' ? 'u' : 'a',
124
- entry.source_ordinal,
125
- entry.block_ordinal,
126
- entry.text,
127
- ];
128
- }
129
- return ['o', [entry.at[0], entry.at[1]], entry.bytes, compactOmissionCounts(entry.counts)];
130
- }
131
-
132
- export function expandFusionProjectionEntry(entry: FusionProjectionEntry): ProjectionEntry {
133
- if (entry[0] === 't') {
134
- return {
135
- kind: 'text',
136
- source_ordinal: entry[2],
137
- block_ordinal: entry[3],
138
- role: entry[1] === 'u' ? 'user' : 'assistant',
139
- text: entry[4],
140
- };
141
- }
142
- return {
143
- kind: 'omitted_activity',
144
- at: [entry[1][0], entry[1][1]],
145
- bytes: entry[2],
146
- counts: expandOmissionCounts(entry[3]),
147
- };
148
- }
149
-
150
- function compactFusionProjectionEntries(
151
- entries: readonly ProjectionEntry[],
152
- ): readonly FusionProjectionEntry[] {
153
- return entries.map(compactFusionProjectionEntry);
154
- }
155
-
156
- function compactOmissionReceiptBytes(entries: readonly FusionProjectionEntry[]): number {
157
- let total = 0;
158
- for (const entry of entries) {
159
- if (entry[0] === 'o') total += Buffer.byteLength(canonicalJson(entry), 'utf8');
160
- }
161
- return total;
162
- }
163
-
164
- /**
165
- * Seal the shared transform output into Fusion's versioned envelopes.
166
- *
167
- * Fusion v4 compacts only the child-facing projection entries. Ledger rows are
168
- * carried through unchanged, so the ledger root commits to exactly the same
169
- * omitted payload records before and after tuple encoding. Golden tests pin the
170
- * new canonical-input bytes and the unchanged ledger bytes.
171
- */
172
- function sealFusionProjection(
173
- projected: ProjectedConversationV2,
174
- source: FusionSource,
175
- branchFilter: FusionBranchFilterDescriptor,
176
- ): { projection: FusionConversationProjectionV3; ledger: FusionContextOmissionLedgerV2 } {
177
- const entries = compactFusionProjectionEntries(projected.entries);
178
- return {
179
- projection: {
180
- policy: policyDescriptor(source),
181
- branch_filter: branchFilter,
182
- entries,
183
- accounting: {
184
- ...projected.accounting,
185
- omission_receipt_utf8_bytes: compactOmissionReceiptBytes(entries),
186
- },
187
- },
188
- ledger: {
189
- schema_version: FUSION_CONTEXT_LEDGER_SCHEMA_VERSION,
190
- policy_id: contextPolicyId(source),
191
- transform: FUSION_CONTEXT_TRANSFORM_ID,
192
- entries: projected.ledger.entries,
193
- projection_map: projected.ledger.projection_map,
194
- root_sha256: projected.ledger.root_sha256,
195
- },
196
- };
197
- }
198
-
199
- /** Preserved public entry point; delegates to the shared frozen transform. */
200
- export function projectFusionConversation(
201
- messages: readonly Message[],
202
- source: FusionSource,
203
- branchFilter: FusionBranchFilterDescriptor,
204
- ): { projection: FusionConversationProjectionV3; ledger: FusionContextOmissionLedgerV2 } {
205
- return sealFusionProjection(projectVisibleConversationV2(messages), source, branchFilter);
206
- }
207
-
208
- export function buildFusionCanonicalInput(
209
- ctx: FusionContextSource,
210
- options: BuildFusionCanonicalInputOptions,
211
- ): BuiltFusionCanonicalInput {
212
- if (options.request.trim().length === 0) {
213
- throw new FusionError('fusion request must not be blank', {
214
- code: 'context_capture_failed',
215
- childCreated: false,
216
- });
217
- }
218
- const workflow = options.workflow ?? 'reason';
219
- if (workflow !== 'reason') {
220
- throw new FusionError('parent session projection is available only to the reason workflow', {
221
- code: 'context_capture_failed',
222
- childCreated: false,
223
- });
224
- }
225
- const toolName = options.toolName ?? FUSION_REASON_TOOL_NAME;
226
- const snapshotOptions: ParentSnapshotOptions = {
227
- toolName,
228
- excludeActiveToolCallLeaf: options.source === 'tool',
229
- };
230
- if (options.toolCallId !== undefined) snapshotOptions.toolCallId = options.toolCallId;
231
- const snapshot = snapshotParentConversation(ctx, snapshotOptions);
232
- const branchFilter: FusionBranchFilterDescriptor = {
233
- id: FUSION_BRANCH_FILTER_ID,
234
- tool_name: toolName,
235
- tool_call_id: options.source === 'tool' ? (options.toolCallId ?? null) : null,
236
- active_tool_call_leaf_excluded: snapshot.activeToolCallLeafExcluded,
237
- };
238
- const projected = projectFusionConversation(snapshot.messages, options.source, branchFilter);
239
- const request: FusionCanonicalRequestV3 = {
240
- source: options.source,
241
- authority: requestAuthority(options.source),
242
- text: options.request,
243
- sha256: sha256Text(options.request),
244
- };
245
- const input: FusionSessionProjectionCanonicalInputV5 = {
246
- schema_version: FUSION_INPUT_SCHEMA_VERSION,
247
- workflow: 'reason',
248
- cwd: ctx.cwd,
249
- request,
250
- system_prompt: ctx.getSystemPrompt(),
251
- conversation_projection: projected.projection,
252
- context: {
253
- kind: 'session_projection',
254
- policy_id: 'fusion-session-projection-v1',
255
- system_prompt: ctx.getSystemPrompt(),
256
- conversation_projection: projected.projection,
257
- },
258
- };
259
- return {
260
- input,
261
- serialized: canonicalJson(input),
262
- ledger: projected.ledger,
263
- transcriptLeafId: snapshot.leafId,
264
- };
265
- }