pi-background-tasks 2.3.0 → 2.4.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/README.md +2 -1
- package/TESTING.md +8 -4
- package/TEST_PLAN.md +3 -3
- package/docs/INDEX.md +1 -1
- package/docs/concepts/context-projection-and-budgeting.md +4 -2
- package/docs/manifest.json +5 -6
- package/docs/operations/troubleshooting.md +3 -1
- package/docs/reference/runtime-contracts.md +18 -18
- package/docs/subsystems/delegation.md +22 -13
- package/docs/subsystems/docs-freshness-gate.md +3 -3
- package/docs/tools/bg_delegate.md +12 -7
- package/docs/tools/bg_result.md +2 -2
- package/package.json +1 -1
- package/src/core/context/token-budget.ts +16 -3
- package/src/core/delegate/artifacts.ts +14 -12
- package/src/core/delegate/budget.ts +78 -33
- package/src/core/delegate/launch.ts +4 -2
- package/src/core/delegate/result-package.ts +16 -0
- package/src/core/delegate/runner.ts +21 -2
- package/src/core/delegate/types.ts +12 -1
- package/src/delegate-child-extension.ts +368 -69
- package/src/delegate-extension.ts +5 -2
|
@@ -4,7 +4,6 @@ import {
|
|
|
4
4
|
TOKEN_BUDGET_RATE_SCALE,
|
|
5
5
|
estimateInputTokens,
|
|
6
6
|
knownTextSegment,
|
|
7
|
-
maxKnownTextBytesForTokens,
|
|
8
7
|
resolveTokenBudgetFamily,
|
|
9
8
|
utf8ByteClassBreakdown,
|
|
10
9
|
allowedInputTokens,
|
|
@@ -28,11 +27,15 @@ import {
|
|
|
28
27
|
* A delegate child is a multi-turn, tool-using agent, so its budget has two
|
|
29
28
|
* distinct phases rather than Fusion's single-shot stage forecast:
|
|
30
29
|
*
|
|
31
|
-
* 1. Launch admission checks the frozen seed, framing, and child system prompt
|
|
32
|
-
*
|
|
30
|
+
* 1. Launch admission checks the frozen seed, framing, and child system prompt
|
|
31
|
+
* with the same backed family calibration used by Fusion for large prompts.
|
|
32
|
+
* 2. A separate provable 1 B/token forecast sizes the transcript-growth runway
|
|
33
|
+
* used for explicit tool-result spilling.
|
|
34
|
+
* 3. Runtime measurements are advisory. Package-owned growth is controlled
|
|
35
|
+
* before transcript entry; Pi and the provider own live context handling.
|
|
33
36
|
*
|
|
34
|
-
* Nothing here
|
|
35
|
-
* fit
|
|
37
|
+
* Nothing here clips, substitutes, or silently reduces content. Tool bytes that
|
|
38
|
+
* do not fit the retained-growth runway are preserved as hashed spill artifacts.
|
|
36
39
|
*/
|
|
37
40
|
|
|
38
41
|
/** Output tokens reserved so the child can always finish an answer. */
|
|
@@ -54,10 +57,14 @@ export const DELEGATE_DEFAULT_TIMEOUT_SECONDS = 1200;
|
|
|
54
57
|
export const DELEGATE_MAX_TOOL_RESULT_BYTES = 64 * 1024;
|
|
55
58
|
export const DELEGATE_MAX_TOTAL_TOOL_OUTPUT_BYTES = 64 * 1024 * 1024;
|
|
56
59
|
export const DELEGATE_MAX_ANSWER_BYTES = 4 * 1024 * 1024;
|
|
60
|
+
/** Input runway held back for a final no-tool answer after investigation. */
|
|
61
|
+
export const DELEGATE_FINALIZATION_INPUT_RESERVE_TOKENS = 32 * 1024;
|
|
62
|
+
/** Remaining retained-growth runway at which the child disables tools. */
|
|
63
|
+
export const DELEGATE_FINALIZATION_TRIGGER_TOKENS = 8 * 1024;
|
|
57
64
|
/** Answers at or under this serialize inline; larger ones degrade explicitly. */
|
|
58
65
|
export const DELEGATE_INLINE_ANSWER_BYTES = 48 * 1024;
|
|
59
66
|
|
|
60
|
-
export const DELEGATE_BUDGET_POLICY_ID = 'delegate-budget-policy-
|
|
67
|
+
export const DELEGATE_BUDGET_POLICY_ID = 'delegate-budget-policy-v3';
|
|
61
68
|
|
|
62
69
|
export interface DelegateBudgetPolicyDescriptor {
|
|
63
70
|
id: typeof DELEGATE_BUDGET_POLICY_ID;
|
|
@@ -68,7 +75,11 @@ export interface DelegateBudgetPolicyDescriptor {
|
|
|
68
75
|
safety_reserve_tokens: number;
|
|
69
76
|
min_usable_input_tokens: number;
|
|
70
77
|
inline_answer_bytes: number;
|
|
71
|
-
|
|
78
|
+
finalization_input_reserve_tokens: number;
|
|
79
|
+
finalization_trigger_tokens: number;
|
|
80
|
+
launch_estimator_scope: 'calibrated_large_prompt';
|
|
81
|
+
retained_growth_estimator_scope: 'provable_1_byte_per_token';
|
|
82
|
+
live_provider_context_owner: 'pi_and_provider';
|
|
72
83
|
}
|
|
73
84
|
|
|
74
85
|
export const DELEGATE_BUDGET_POLICY: DelegateBudgetPolicyDescriptor = {
|
|
@@ -80,7 +91,11 @@ export const DELEGATE_BUDGET_POLICY: DelegateBudgetPolicyDescriptor = {
|
|
|
80
91
|
safety_reserve_tokens: DELEGATE_SAFETY_RESERVE_TOKENS,
|
|
81
92
|
min_usable_input_tokens: DELEGATE_MIN_USABLE_INPUT_TOKENS,
|
|
82
93
|
inline_answer_bytes: DELEGATE_INLINE_ANSWER_BYTES,
|
|
83
|
-
|
|
94
|
+
finalization_input_reserve_tokens: DELEGATE_FINALIZATION_INPUT_RESERVE_TOKENS,
|
|
95
|
+
finalization_trigger_tokens: DELEGATE_FINALIZATION_TRIGGER_TOKENS,
|
|
96
|
+
launch_estimator_scope: 'calibrated_large_prompt',
|
|
97
|
+
retained_growth_estimator_scope: 'provable_1_byte_per_token',
|
|
98
|
+
live_provider_context_owner: 'pi_and_provider',
|
|
84
99
|
};
|
|
85
100
|
|
|
86
101
|
export interface DelegateAdmissionPlanV1 {
|
|
@@ -97,17 +112,22 @@ export interface DelegateAdmissionPlanV1 {
|
|
|
97
112
|
rate_source: TokenBudgetRateSource;
|
|
98
113
|
byte_capacity_utf8_bytes: number;
|
|
99
114
|
};
|
|
100
|
-
|
|
101
|
-
|
|
115
|
+
child_prompt_utf8_bytes: number;
|
|
116
|
+
child_prompt_multibyte_utf8_bytes: number;
|
|
102
117
|
system_prompt_utf8_bytes: number;
|
|
103
118
|
system_prompt_multibyte_utf8_bytes: number;
|
|
104
119
|
launch_utf8_bytes: number;
|
|
105
120
|
launch_input_tokens_upper_bound: number;
|
|
121
|
+
conservative_launch_input_tokens: number;
|
|
122
|
+
conservative_launch_fits: boolean;
|
|
106
123
|
signed_headroom_tokens: number;
|
|
107
124
|
utilization_basis_points: number;
|
|
125
|
+
retained_growth_budget_tokens: number;
|
|
126
|
+
finalization_input_reserve_tokens: number;
|
|
108
127
|
byte_class_breakdown: TokenBudgetByteClassBreakdown;
|
|
109
128
|
dominant_byte_class: EstimateInputTokensResult['rateSource']['dominant_byte_class'];
|
|
110
129
|
estimate: EstimateInputTokensResult;
|
|
130
|
+
conservative_estimate: EstimateInputTokensResult;
|
|
111
131
|
fits: boolean;
|
|
112
132
|
limits: DelegateLimits;
|
|
113
133
|
}
|
|
@@ -167,7 +187,7 @@ export function delegateAllowedInputTokens(route: DelegatePinnedRoute): number {
|
|
|
167
187
|
|
|
168
188
|
export interface DelegateAdmissionInput {
|
|
169
189
|
route: DelegatePinnedRoute;
|
|
170
|
-
|
|
190
|
+
childPrompt: string;
|
|
171
191
|
childSystemPrompt: string;
|
|
172
192
|
limits: DelegateLimits;
|
|
173
193
|
}
|
|
@@ -176,20 +196,39 @@ export interface DelegateAdmissionInput {
|
|
|
176
196
|
export function planDelegateAdmission(input: DelegateAdmissionInput): DelegateAdmissionPlanV1 {
|
|
177
197
|
const allowed = delegateAllowedInputTokens(input.route);
|
|
178
198
|
const family = routeFamily(input.route);
|
|
179
|
-
const
|
|
199
|
+
const childPrompt = utf8ByteClassBreakdown(input.childPrompt);
|
|
180
200
|
const system = utf8ByteClassBreakdown(input.childSystemPrompt);
|
|
201
|
+
const segments = [knownTextSegment(input.childPrompt), knownTextSegment(input.childSystemPrompt)];
|
|
181
202
|
const estimate = estimateInputTokens({
|
|
182
203
|
family: family.family,
|
|
183
204
|
calibrationBacked: family.backed,
|
|
184
205
|
familyResolution: family.resolution,
|
|
185
206
|
allowedInputTokens: allowed,
|
|
186
|
-
scope: '
|
|
187
|
-
segments
|
|
207
|
+
scope: 'delegate_launch',
|
|
208
|
+
segments,
|
|
188
209
|
});
|
|
210
|
+
const conservativeEstimate = estimateInputTokens({
|
|
211
|
+
family: family.family,
|
|
212
|
+
calibrationBacked: family.backed,
|
|
213
|
+
familyResolution: family.resolution,
|
|
214
|
+
allowedInputTokens: allowed,
|
|
215
|
+
scope: 'conservative',
|
|
216
|
+
segments,
|
|
217
|
+
});
|
|
218
|
+
// `conservativeEstimate.tokens` intentionally uses the shared estimator's
|
|
219
|
+
// calibrated multibyte diagnostic rate. The counter-forecast published as
|
|
220
|
+
// "provable" must instead use that estimator's explicit 1 B/token ceiling
|
|
221
|
+
// for multibyte bytes as well as normal/dense bytes.
|
|
222
|
+
const provableConservativeLaunchTokens =
|
|
223
|
+
conservativeEstimate.advisory.input_tokens_if_multibyte_used_provable_ceiling;
|
|
189
224
|
const byteCapacity = Math.floor(
|
|
190
225
|
(allowed * estimate.rateSource.effective_rate_bytes_per_token_x100) / TOKEN_BUDGET_RATE_SCALE,
|
|
191
226
|
);
|
|
192
|
-
const launchBytes =
|
|
227
|
+
const launchBytes = childPrompt.bytes + system.bytes;
|
|
228
|
+
const retainedGrowthBudget = Math.max(
|
|
229
|
+
0,
|
|
230
|
+
allowed - estimate.tokens - DELEGATE_FINALIZATION_INPUT_RESERVE_TOKENS,
|
|
231
|
+
);
|
|
193
232
|
return {
|
|
194
233
|
schema_version: DELEGATE_BUDGET_PLAN_SCHEMA_VERSION,
|
|
195
234
|
policy: DELEGATE_BUDGET_POLICY,
|
|
@@ -204,17 +243,22 @@ export function planDelegateAdmission(input: DelegateAdmissionInput): DelegateAd
|
|
|
204
243
|
rate_source: estimate.rateSource,
|
|
205
244
|
byte_capacity_utf8_bytes: byteCapacity,
|
|
206
245
|
},
|
|
207
|
-
|
|
208
|
-
|
|
246
|
+
child_prompt_utf8_bytes: childPrompt.bytes,
|
|
247
|
+
child_prompt_multibyte_utf8_bytes: childPrompt.multibyteBytes,
|
|
209
248
|
system_prompt_utf8_bytes: system.bytes,
|
|
210
249
|
system_prompt_multibyte_utf8_bytes: system.multibyteBytes,
|
|
211
250
|
launch_utf8_bytes: launchBytes,
|
|
212
251
|
launch_input_tokens_upper_bound: estimate.tokens,
|
|
252
|
+
conservative_launch_input_tokens: provableConservativeLaunchTokens,
|
|
253
|
+
conservative_launch_fits: provableConservativeLaunchTokens <= allowed,
|
|
213
254
|
signed_headroom_tokens: allowed - estimate.tokens,
|
|
214
255
|
utilization_basis_points: utilizationBasisPoints(estimate.tokens, allowed),
|
|
256
|
+
retained_growth_budget_tokens: retainedGrowthBudget,
|
|
257
|
+
finalization_input_reserve_tokens: DELEGATE_FINALIZATION_INPUT_RESERVE_TOKENS,
|
|
215
258
|
byte_class_breakdown: estimate.byte_class_breakdown,
|
|
216
259
|
dominant_byte_class: estimate.rateSource.dominant_byte_class,
|
|
217
260
|
estimate,
|
|
261
|
+
conservative_estimate: conservativeEstimate,
|
|
218
262
|
fits: estimate.tokens <= allowed,
|
|
219
263
|
limits: input.limits,
|
|
220
264
|
};
|
|
@@ -226,17 +270,15 @@ function rateWarningText(rateSource: TokenBudgetRateSource, qualifiedId: string)
|
|
|
226
270
|
}
|
|
227
271
|
|
|
228
272
|
function requiredByteReduction(plan: DelegateAdmissionPlanV1): number {
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
}),
|
|
239
|
-
);
|
|
273
|
+
const variableTokens =
|
|
274
|
+
plan.route.allowed_input_tokens - plan.route.rate_source.affine_f_tokens;
|
|
275
|
+
const maximumBytes = variableTokens <= 0
|
|
276
|
+
? 0
|
|
277
|
+
: Math.floor(
|
|
278
|
+
(variableTokens * plan.route.rate_source.effective_rate_bytes_per_token_x100) /
|
|
279
|
+
TOKEN_BUDGET_RATE_SCALE,
|
|
280
|
+
);
|
|
281
|
+
return Math.max(0, plan.launch_utf8_bytes - maximumBytes);
|
|
240
282
|
}
|
|
241
283
|
|
|
242
284
|
/**
|
|
@@ -249,7 +291,7 @@ export function assertDelegateAdmission(plan: DelegateAdmissionPlanV1): void {
|
|
|
249
291
|
if (plan.fits) return;
|
|
250
292
|
const overage = plan.launch_input_tokens_upper_bound - plan.route.allowed_input_tokens;
|
|
251
293
|
throw new DelegateError(
|
|
252
|
-
`bg_delegate
|
|
294
|
+
`bg_delegate child prompt does not fit the pinned route before launch. Route ${plan.route.qualified_id} allows ${String(plan.route.allowed_input_tokens)} input tokens; the exact child prompt plus child system prompt measure ${String(plan.launch_utf8_bytes)} UTF-8 bytes (<= ${String(plan.launch_input_tokens_upper_bound)} input tokens), over by ${String(overage)} tokens. Estimator family ${plan.route.family}, source ${plan.route.rate_source.source}, backed=${String(plan.route.rate_source.backed)}, dominant_byte_class=${plan.dominant_byte_class}, rate ${String(plan.route.rate_source.effective_rate_bytes_per_token_x100)}/100 B/tok + ${String(plan.route.rate_source.affine_f_tokens)} tokens.${rateWarningText(plan.route.rate_source, plan.route.qualified_id)} Required reduction is at least ${String(requiredByteReduction(plan))} UTF-8 bytes. No child process, child session, or artifact was created. Nothing was clipped, dropped, or substituted.`,
|
|
253
295
|
{
|
|
254
296
|
code: 'seed_budget_exceeded',
|
|
255
297
|
childCreated: false,
|
|
@@ -291,10 +333,13 @@ export interface DelegateGovernorVerdict {
|
|
|
291
333
|
}
|
|
292
334
|
|
|
293
335
|
/**
|
|
294
|
-
*
|
|
336
|
+
* Advisory runtime measurement for one prospective model call.
|
|
295
337
|
*
|
|
296
|
-
*
|
|
297
|
-
*
|
|
338
|
+
* This deliberately uses the calibrated large-prompt policy and never decides
|
|
339
|
+
* whether transport may occur. Fusion's BUG-185 proved that a package-local
|
|
340
|
+
* estimator must not reject a live provider payload by subtracting hypothetical
|
|
341
|
+
* output. The delegate child uses this result for evidence and graceful
|
|
342
|
+
* finalization while proactive spilling controls package-owned growth.
|
|
298
343
|
*/
|
|
299
344
|
export function evaluateDelegateRuntimeBudget(
|
|
300
345
|
measurement: DelegateRuntimeMeasurement,
|
|
@@ -307,7 +352,7 @@ export function evaluateDelegateRuntimeBudget(
|
|
|
307
352
|
calibrationBacked: family.backed,
|
|
308
353
|
familyResolution: family.resolution,
|
|
309
354
|
allowedInputTokens: allowedTokens,
|
|
310
|
-
scope: '
|
|
355
|
+
scope: 'delegate_launch',
|
|
311
356
|
segments: [
|
|
312
357
|
{
|
|
313
358
|
kind: 'known_text',
|
|
@@ -380,7 +380,9 @@ export function buildDelegateChildSystemPrompt(seedPathHint: string): string {
|
|
|
380
380
|
'',
|
|
381
381
|
'You are inspect-only. You can read, search, and list files. You cannot run shell commands, edit or write files, reach the network, or start further delegates. Do not claim to have done so.',
|
|
382
382
|
'',
|
|
383
|
-
'If a tool result is replaced by a spill receipt, the complete
|
|
383
|
+
'If a tool result is replaced by a spill receipt, the complete encoded content is on disk and nothing was truncated. Use delegate_read_artifact with an exact offset and length when you genuinely need lossless base64 bytes, then interpret them using the receipt content_format.',
|
|
384
|
+
'',
|
|
385
|
+
'The child controls retained context by spilling tool results before they consume protected final-answer runway. A spill is not a failure. If a finalization-runway notice appears, all investigation tools are finished: stop investigating and answer immediately from the evidence already gathered.',
|
|
384
386
|
'',
|
|
385
387
|
'Finish with a single, direct, self-contained answer to the directive. Your final assistant message is the answer that will be returned to the parent.',
|
|
386
388
|
].join('\n');
|
|
@@ -468,7 +470,7 @@ export function preflightDelegateLaunch(input: DelegatePreflightInput): Delegate
|
|
|
468
470
|
route: input.route,
|
|
469
471
|
// The seed reaches the child inside its prompt, so the admission forecast
|
|
470
472
|
// must measure the prompt that is actually sent, not the seed alone.
|
|
471
|
-
|
|
473
|
+
childPrompt,
|
|
472
474
|
childSystemPrompt,
|
|
473
475
|
limits,
|
|
474
476
|
});
|
|
@@ -247,6 +247,21 @@ function parseAttestations(
|
|
|
247
247
|
});
|
|
248
248
|
}
|
|
249
249
|
|
|
250
|
+
function parseSpillContentFormat(
|
|
251
|
+
value: unknown,
|
|
252
|
+
taskId: string,
|
|
253
|
+
): DelegateSpillReceipt['content_format'] {
|
|
254
|
+
if (value === undefined) return undefined;
|
|
255
|
+
if (
|
|
256
|
+
value !== 'single_text_utf8' &&
|
|
257
|
+
value !== 'tool_result_content_json_v1' &&
|
|
258
|
+
value !== 'opaque_bytes'
|
|
259
|
+
) {
|
|
260
|
+
fail('delegate spill receipt content_format is invalid', 'child_result_invalid', taskId);
|
|
261
|
+
}
|
|
262
|
+
return value;
|
|
263
|
+
}
|
|
264
|
+
|
|
250
265
|
function parseSpillReceipts(value: unknown, taskId: string): readonly DelegateSpillReceipt[] {
|
|
251
266
|
if (!Array.isArray(value))
|
|
252
267
|
fail('delegate result package spilled_artifacts must be an array', 'child_result_invalid', taskId);
|
|
@@ -264,6 +279,7 @@ function parseSpillReceipts(value: unknown, taskId: string): readonly DelegateSp
|
|
|
264
279
|
source_call_index: requireInteger(entry, 'source_call_index', taskId),
|
|
265
280
|
byte_length: requireInteger(entry, 'byte_length', taskId),
|
|
266
281
|
sha256: requireSha256(entry, 'sha256', taskId),
|
|
282
|
+
content_format: parseSpillContentFormat(entry['content_format'], taskId),
|
|
267
283
|
};
|
|
268
284
|
});
|
|
269
285
|
}
|
|
@@ -160,6 +160,7 @@ export async function prepareDelegateLaunch(
|
|
|
160
160
|
budget: {
|
|
161
161
|
family: preflight.plan.route.family,
|
|
162
162
|
rate_source: preflight.plan.route.rate_source,
|
|
163
|
+
conservative_rate_source: preflight.plan.conservative_estimate.rateSource,
|
|
163
164
|
},
|
|
164
165
|
extensionMode: input.extensionMode,
|
|
165
166
|
autoDeliver: input.autoDeliver,
|
|
@@ -200,6 +201,9 @@ export interface EvaluateDelegateTerminalInput {
|
|
|
200
201
|
/** Terminal status observed by the background task registry. */
|
|
201
202
|
taskStatus: 'completed' | 'failed' | 'killed';
|
|
202
203
|
taskError: string | undefined;
|
|
204
|
+
/** Real merged child output owned by the background-task registry. */
|
|
205
|
+
taskOutputPath?: string | undefined;
|
|
206
|
+
taskOutputAbsPath?: string | undefined;
|
|
203
207
|
}
|
|
204
208
|
|
|
205
209
|
/**
|
|
@@ -251,6 +255,21 @@ async function adjudicateDelegateTerminal(
|
|
|
251
255
|
recorded?.message ??
|
|
252
256
|
input.taskError ??
|
|
253
257
|
'the delegate child exited without committing a result package';
|
|
258
|
+
const preserved = ['seed.json', 'budget-plan.json', 'child-terminal.json', 'runtime-budget.json']
|
|
259
|
+
.filter((name) => existsSync(join(input.artifactDirAbs, name)));
|
|
260
|
+
if (
|
|
261
|
+
input.taskOutputPath !== undefined &&
|
|
262
|
+
input.taskOutputAbsPath !== undefined &&
|
|
263
|
+
existsSync(input.taskOutputAbsPath)
|
|
264
|
+
) {
|
|
265
|
+
preserved.push(input.taskOutputPath);
|
|
266
|
+
}
|
|
267
|
+
const diagnosticTargets = preserved.filter(
|
|
268
|
+
(name) => name === 'child-terminal.json' || name === 'runtime-budget.json' || name === input.taskOutputPath,
|
|
269
|
+
);
|
|
270
|
+
const diagnostic = diagnosticTargets.length === 0
|
|
271
|
+
? 'No child terminal record or merged task output exists; inspect the preserved launch artifacts listed above.'
|
|
272
|
+
: `Inspect the preserved diagnostic evidence: ${diagnosticTargets.join(', ')}.`;
|
|
254
273
|
const error = new DelegateError(
|
|
255
274
|
`bg_delegate produced no committed answer: ${detail}`,
|
|
256
275
|
{
|
|
@@ -258,9 +277,9 @@ async function adjudicateDelegateTerminal(
|
|
|
258
277
|
childCreated: true,
|
|
259
278
|
taskId: input.taskId,
|
|
260
279
|
artifactDir: input.artifactDirAbs,
|
|
261
|
-
preserved
|
|
280
|
+
preserved,
|
|
262
281
|
remediation: [
|
|
263
|
-
|
|
282
|
+
diagnostic,
|
|
264
283
|
'No partial answer is returned; nothing was truncated to look like success.',
|
|
265
284
|
],
|
|
266
285
|
},
|
|
@@ -18,7 +18,7 @@ export const DELEGATE_RESULT_PACKAGE_SCHEMA_VERSION =
|
|
|
18
18
|
'pi-background-tasks.delegate-result.v1' as const;
|
|
19
19
|
export const DELEGATE_RECEIPT_SCHEMA_VERSION = 'pi-background-tasks.delegate-receipt.v1' as const;
|
|
20
20
|
export const DELEGATE_BUDGET_PLAN_SCHEMA_VERSION =
|
|
21
|
-
'pi-background-tasks.delegate-budget-plan.
|
|
21
|
+
'pi-background-tasks.delegate-budget-plan.v3' as const;
|
|
22
22
|
export const DELEGATE_MANIFEST_SCHEMA_VERSION = 'pi-background-tasks.delegate-manifest.v2' as const;
|
|
23
23
|
|
|
24
24
|
/**
|
|
@@ -64,6 +64,7 @@ export interface DelegatePinnedRoute extends DelegateRoute {
|
|
|
64
64
|
export interface DelegateBudgetRouteSource {
|
|
65
65
|
family: TokenBudgetFamily;
|
|
66
66
|
rate_source: TokenBudgetRateSource;
|
|
67
|
+
conservative_rate_source?: TokenBudgetRateSource | undefined;
|
|
67
68
|
}
|
|
68
69
|
|
|
69
70
|
export interface DelegateContextPolicyDescriptor {
|
|
@@ -192,6 +193,11 @@ export interface DelegateResultPackageV1 {
|
|
|
192
193
|
spilled_artifacts: readonly DelegateSpillReceipt[];
|
|
193
194
|
}
|
|
194
195
|
|
|
196
|
+
export type DelegateSpillContentFormat =
|
|
197
|
+
| 'single_text_utf8'
|
|
198
|
+
| 'tool_result_content_json_v1'
|
|
199
|
+
| 'opaque_bytes';
|
|
200
|
+
|
|
195
201
|
export interface DelegateSpillReceipt {
|
|
196
202
|
schema_version: typeof DELEGATE_RECEIPT_SCHEMA_VERSION;
|
|
197
203
|
artifact: string;
|
|
@@ -201,6 +207,11 @@ export interface DelegateSpillReceipt {
|
|
|
201
207
|
source_call_index: number;
|
|
202
208
|
byte_length: number;
|
|
203
209
|
sha256: string;
|
|
210
|
+
/**
|
|
211
|
+
* Encoding of the hashed artifact bytes. Optional only for compatibility
|
|
212
|
+
* with v1 receipts written before content formats were recorded.
|
|
213
|
+
*/
|
|
214
|
+
content_format?: DelegateSpillContentFormat | undefined;
|
|
204
215
|
}
|
|
205
216
|
|
|
206
217
|
export const DELEGATE_ERROR_CODES = [
|