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 @@
|
|
|
1
|
+
{"version":3,"file":"budget.js","sourceRoot":"","sources":["../../../../src/core/fusion/budget.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from 'node:crypto';\nimport {\n TOKEN_BUDGET_AFFINE_F_TOKENS,\n TOKEN_BUDGET_CALIBRATION_VERSION,\n TOKEN_BUDGET_FAMILY_CALIBRATIONS,\n TOKEN_BUDGET_LARGE_PROMPT_MIN_BYTES,\n TOKEN_BUDGET_RATE_SCALE,\n estimateInputTokens,\n knownTextSegment,\n maxKnownTextBytesForTokens,\n resolveTokenBudgetFamily,\n unknownOutputContractSegment,\n allowedInputTokens,\n isUsableContextWindow,\n} from '../context/token-budget.js';\nimport {\n buildBlindEvaluationInput,\n buildCandidatePrompt,\n buildEvaluationPrompt,\n buildEvaluationRepairPrompt,\n buildMergeInput,\n buildMergePrompt,\n type AnonymousFusionCandidate,\n} from './prompts.js';\nimport { FUSION_REASON_WORKFLOW, type FusionWorkflowProfile } from './workflows.js';\nimport {\n FUSION_CANDIDATE_MAX_OUTPUT_BYTES,\n FUSION_DIAGNOSTICS_MAX_BYTES,\n FUSION_EVALUATION_MAX_OUTPUT_BYTES,\n FUSION_MERGE_MAX_OUTPUT_BYTES,\n} from './output-contract.js';\nexport {\n FUSION_CANDIDATE_MAX_OUTPUT_BYTES,\n FUSION_DIAGNOSTICS_MAX_BYTES,\n FUSION_EVALUATION_MAX_OUTPUT_BYTES,\n FUSION_MERGE_MAX_OUTPUT_BYTES,\n assertChildOutputWithinContract,\n fusionOutputContractBytes,\n} from './output-contract.js';\nimport {\n FUSION_BUDGET_PLAN_SCHEMA_VERSION,\n FUSION_CALIBRATION_VIOLATION_SCHEMA_VERSION,\n FUSION_EVALUATION_SCHEMA_VERSION,\n FusionError,\n type FusionBudgetBlocker,\n type FusionBudgetCheckKind,\n type FusionBudgetComponentBreakdown,\n type FusionBudgetCounterfactuals,\n type FusionBudgetEmptyRequestVerdict,\n type FusionBudgetErrorDetail,\n type FusionBudgetPlanV1,\n type FusionBudgetPolicyDescriptor,\n type FusionBudgetRouteTableEntry,\n type FusionBudgetStage,\n type FusionBudgetStageComposition,\n type FusionBudgetWarning,\n type FusionCalibrationViolation,\n type FusionCanonicalInputV3,\n type FusionCapability,\n type FusionEvaluationV1,\n type FusionRouteCapacity,\n type FusionStage,\n type FusionStageBudgetPlanEntry,\n type FusionChildRunResult,\n type ResolvedFusionModel,\n type ResolvedFusionModels,\n} from './types.js';\n\nexport const FUSION_CALIBRATED_BYTES_PER_TOKEN = TOKEN_BUDGET_FAMILY_CALIBRATIONS;\n\nconst FUSION_OUTPUT_RESERVE_RATE_X100 = 200;\nexport const FUSION_UTILIZATION_WARNING_THRESHOLD_BASIS_POINTS = 8000;\nconst BASIS_POINTS_DENOMINATOR = 10_000;\n\nfunction ceilDiv(numerator: number, denominator: number): number {\n if (!Number.isSafeInteger(numerator) || numerator < 0) {\n throw new TypeError('ceilDiv numerator must be a non-negative safe integer');\n }\n if (!Number.isSafeInteger(denominator) || denominator <= 0) {\n throw new TypeError('ceilDiv denominator must be a positive safe integer');\n }\n if (numerator === 0) return 0;\n return Math.floor((numerator - 1) / denominator) + 1;\n}\n\nexport const FUSION_RESERVED_OUTPUT_TOKENS = ceilDiv(\n FUSION_MERGE_MAX_OUTPUT_BYTES * TOKEN_BUDGET_RATE_SCALE,\n FUSION_OUTPUT_RESERVE_RATE_X100,\n);\nexport const FUSION_FRAMING_RESERVE_TOKENS = 0;\nexport const FUSION_SAFETY_RESERVE_TOKENS = 4_096;\nexport const FUSION_MIN_CANONICAL_INPUT_TOKENS = 8_192;\nexport const FUSION_MIN_CONTEXT_WINDOW_TOKENS =\n FUSION_MIN_CANONICAL_INPUT_TOKENS +\n FUSION_RESERVED_OUTPUT_TOKENS +\n FUSION_FRAMING_RESERVE_TOKENS +\n FUSION_SAFETY_RESERVE_TOKENS;\n\nexport const FUSION_BUDGET_POLICY: FusionBudgetPolicyDescriptor = {\n id: 'fusion-budget-policy-v4',\n route_output_reserve_strategy: 'max_fusion_contract_or_model_max',\n calibration_version: TOKEN_BUDGET_CALIBRATION_VERSION,\n calibration_table: FUSION_CALIBRATED_BYTES_PER_TOKEN,\n reserved_output_tokens: FUSION_RESERVED_OUTPUT_TOKENS,\n framing_reserve_tokens: FUSION_FRAMING_RESERVE_TOKENS,\n safety_reserve_tokens: FUSION_SAFETY_RESERVE_TOKENS,\n candidate_output_contract_bytes: FUSION_CANDIDATE_MAX_OUTPUT_BYTES,\n evaluation_output_contract_bytes: FUSION_EVALUATION_MAX_OUTPUT_BYTES,\n merge_output_contract_bytes: FUSION_MERGE_MAX_OUTPUT_BYTES,\n diagnostics_contract_bytes: FUSION_DIAGNOSTICS_MAX_BYTES,\n utilization_warning_threshold_basis_points: FUSION_UTILIZATION_WARNING_THRESHOLD_BASIS_POINTS,\n};\n\nconst REASON_EMPTY_REMEDIATION: readonly string[] = Object.freeze([\n 'Start a fresh Pi conversation, or run fusion_reason earlier in the session.',\n \"Raise the route's context window with a larger-context subscription model via /fusion-models.\",\n 'Restate only the required prior findings in the fusion_reason prompt.',\n]);\n\nconst REASON_REQUEST_REMEDIATION: readonly string[] = Object.freeze([\n 'Provide a shorter fusion_reason prompt.',\n 'Start a fresh Pi conversation, or run fusion_reason earlier in the session.',\n \"Raise the route's context window with a larger-context subscription model via /fusion-models.\",\n]);\n\nconst INVESTIGATE_EMPTY_REMEDIATION: readonly string[] = Object.freeze([\n 'Split the repository investigation into smaller independently complete path or subsystem scopes.',\n \"Raise the route's context window with a larger-context subscription model via /fusion-models.\",\n]);\nconst INVESTIGATE_REQUEST_REMEDIATION: readonly string[] = Object.freeze([\n 'Narrow the fusion_investigate objective, repository scope, or required evidence.',\n \"Raise the route's context window with a larger-context subscription model via /fusion-models.\",\n]);\nconst RESEARCH_EMPTY_REMEDIATION: readonly string[] = Object.freeze([\n 'Split the research into smaller independently complete source sets.',\n \"Raise the route's context window with a larger-context subscription model via /fusion-models.\",\n]);\nconst RESEARCH_REQUEST_REMEDIATION: readonly string[] = Object.freeze([\n 'Narrow the fusion_research question or split large declared-source sets across independent runs.',\n \"Raise the route's context window with a larger-context subscription model via /fusion-models.\",\n]);\nconst VALIDATE_EMPTY_REMEDIATION: readonly string[] = Object.freeze([\n 'Split validation into smaller independently complete change or acceptance-criterion scopes.',\n \"Raise the route's context window with a larger-context subscription model via /fusion-models.\",\n]);\nconst VALIDATE_REQUEST_REMEDIATION: readonly string[] = Object.freeze([\n 'Narrow the fusion_validate scope, acceptance criteria, or supplied verification evidence.',\n \"Raise the route's context window with a larger-context subscription model via /fusion-models.\",\n]);\n\nfunction cleanRemediation(\n profile: FusionWorkflowProfile,\n requestDeterminesFeasibility: boolean,\n): readonly string[] {\n if (profile.id === 'investigate') {\n return requestDeterminesFeasibility\n ? INVESTIGATE_REQUEST_REMEDIATION\n : INVESTIGATE_EMPTY_REMEDIATION;\n }\n if (profile.id === 'research') {\n return requestDeterminesFeasibility ? RESEARCH_REQUEST_REMEDIATION : RESEARCH_EMPTY_REMEDIATION;\n }\n if (profile.id === 'validate') {\n return requestDeterminesFeasibility ? VALIDATE_REQUEST_REMEDIATION : VALIDATE_EMPTY_REMEDIATION;\n }\n return requestDeterminesFeasibility ? REASON_REQUEST_REMEDIATION : REASON_EMPTY_REMEDIATION;\n}\n\nconst RESERVATION_REMEDIATION: readonly string[] = Object.freeze([\n 'Route the blocking stage to a model with larger byte capacity.',\n 'Keep producer output contracts intact; do not shrink or truncate child answers.',\n 'Inspect budget-plan.json for the advisory reservation component before retrying.',\n]);\n\nconst DENSE_REMEDIATION: readonly string[] = Object.freeze([\n 'Remove or externalize low-whitespace dense ASCII payloads (base64, minified code, PEM/hex blocks), then retry.',\n 'The prompt is preserved; no content was clipped to fit.',\n]);\n\nconst MULTIBYTE_REMEDIATION: readonly string[] = Object.freeze([\n 'This rejection is dominated by multibyte UTF-8 content; use a larger-context route or split the non-Latin/CJK-heavy task.',\n 'The budget plan includes the stricter multibyte advisory ceiling separately from the fatal estimate.',\n 'The prompt is preserved; no content was clipped to fit.',\n]);\n\nconst EMPTY_CANDIDATES: readonly [\n AnonymousFusionCandidate,\n AnonymousFusionCandidate,\n AnonymousFusionCandidate,\n] = Object.freeze([\n Object.freeze({ candidate_id: 'A', response: '' }),\n Object.freeze({ candidate_id: 'B', response: '' }),\n Object.freeze({ candidate_id: 'C', response: '' }),\n]);\n\nconst EMPTY_EVALUATION: FusionEvaluationV1 = Object.freeze({\n schema_version: FUSION_EVALUATION_SCHEMA_VERSION,\n candidate_assessments: Object.freeze([\n Object.freeze({\n candidate_id: 'A',\n summary: '',\n strengths: Object.freeze([]),\n limitations: Object.freeze([]),\n useful_contributions: Object.freeze([]),\n risks: Object.freeze([]),\n }),\n Object.freeze({\n candidate_id: 'B',\n summary: '',\n strengths: Object.freeze([]),\n limitations: Object.freeze([]),\n useful_contributions: Object.freeze([]),\n risks: Object.freeze([]),\n }),\n Object.freeze({\n candidate_id: 'C',\n summary: '',\n strengths: Object.freeze([]),\n limitations: Object.freeze([]),\n useful_contributions: Object.freeze([]),\n risks: Object.freeze([]),\n }),\n ]) as readonly [\n FusionEvaluationV1['candidate_assessments'][0],\n FusionEvaluationV1['candidate_assessments'][1],\n FusionEvaluationV1['candidate_assessments'][2],\n ],\n agreements: Object.freeze([]),\n conflicts: Object.freeze([]),\n synthesis_plan: Object.freeze({\n must_include: Object.freeze([]),\n must_resolve: Object.freeze([]),\n must_avoid: Object.freeze([]),\n }),\n});\n\ninterface StageForecastDraft {\n budget_stage: FusionBudgetStage;\n slot?: 1 | 2 | 3;\n route: FusionRouteCapacity;\n conditional: boolean;\n system_prompt: string;\n empty_user_prompt: string;\n upstream_output_contract_bytes: number;\n}\n\nexport function fusionTokenUpperBound(utf8Bytes: number): number {\n return estimateInputTokens({\n family: 'unknown',\n scope: 'conservative',\n segments: [{ kind: 'known_text', bytes: utf8Bytes, multibyteBytes: 0, denseBytes: 0 }],\n }).tokens;\n}\n\nfunction utf8Bytes(value: string): number {\n return Buffer.byteLength(value, 'utf8');\n}\n\nfunction sha256Hex(value: string): string {\n return createHash('sha256').update(value, 'utf8').digest('hex');\n}\n\nfunction requirePositiveContextWindow(model: ResolvedFusionModel, role: string): number {\n const value = model.contextWindow;\n if (!isUsableContextWindow(value)) {\n throw new FusionError(\n `fusion ${role} route ${model.qualifiedId} has no usable context window capacity`,\n { code: 'model_capacity_unknown', childCreated: false },\n );\n }\n return value;\n}\n\nfunction formatRateX100(value: number): string {\n const whole = Math.floor(value / TOKEN_BUDGET_RATE_SCALE);\n const frac = String(value % TOKEN_BUDGET_RATE_SCALE).padStart(2, '0');\n return `${String(whole)}.${frac}`;\n}\n\nfunction routeCapacity(\n model: ResolvedFusionModel,\n role: FusionRouteCapacity['role'],\n): FusionRouteCapacity {\n const contextWindow = requirePositiveContextWindow(model, role);\n const reservedOutputTokens = Math.max(FUSION_RESERVED_OUTPUT_TOKENS, model.maxOutputTokens);\n const allowed = allowedInputTokens(contextWindow, {\n reservedOutputTokens,\n framingReserveTokens: FUSION_FRAMING_RESERVE_TOKENS,\n safetyReserveTokens: FUSION_SAFETY_RESERVE_TOKENS,\n });\n if (allowed < FUSION_MIN_CANONICAL_INPUT_TOKENS) {\n const minimumContextWindow =\n reservedOutputTokens +\n FUSION_FRAMING_RESERVE_TOKENS +\n FUSION_SAFETY_RESERVE_TOKENS +\n FUSION_MIN_CANONICAL_INPUT_TOKENS;\n throw new FusionError(\n `fusion ${role} route ${model.qualifiedId} has a ${String(contextWindow)}-token context window, but Fusion requires at least ${String(minimumContextWindow)} tokens: ${String(reservedOutputTokens)} reserved for the route's configured maximum output + ${String(FUSION_FRAMING_RESERVE_TOKENS)} framing + ${String(FUSION_SAFETY_RESERVE_TOKENS)} safety + ${String(FUSION_MIN_CANONICAL_INPUT_TOKENS)} usable input. Choose a larger-context or lower-max-output subscription model for this slot with /fusion-models.`,\n { code: 'model_capacity_unknown', childCreated: false },\n );\n }\n const family = resolveTokenBudgetFamily({ provider: model.provider, model: model.model });\n const rateSource = estimateInputTokens({\n family: family.family,\n calibrationBacked: family.backed,\n familyResolution: family.resolution,\n allowedInputTokens: allowed,\n scope: 'fusion',\n segments: [\n {\n kind: 'known_text',\n bytes: TOKEN_BUDGET_LARGE_PROMPT_MIN_BYTES,\n multibyteBytes: 0,\n denseBytes: 0,\n asciiWhitespaceBytes: TOKEN_BUDGET_LARGE_PROMPT_MIN_BYTES,\n },\n ],\n }).rateSource;\n return {\n role,\n provider: model.provider,\n model: model.model,\n qualified_id: model.qualifiedId,\n context_window_tokens: contextWindow,\n reserved_output_tokens: reservedOutputTokens,\n framing_reserve_tokens: FUSION_FRAMING_RESERVE_TOKENS,\n safety_reserve_tokens: FUSION_SAFETY_RESERVE_TOKENS,\n allowed_input_tokens: allowed,\n family: family.family,\n rate_source: rateSource,\n byte_capacity_utf8_bytes: Math.floor(\n (allowed * rateSource.effective_rate_bytes_per_token_x100) / TOKEN_BUDGET_RATE_SCALE,\n ),\n };\n}\n\nexport function fusionRouteCapacities(models: ResolvedFusionModels): readonly FusionRouteCapacity[] {\n return [\n routeCapacity(models.candidates[0], 'candidate-1'),\n routeCapacity(models.candidates[1], 'candidate-2'),\n routeCapacity(models.candidates[2], 'candidate-3'),\n routeCapacity(models.evaluator, 'evaluator'),\n routeCapacity(models.merger, 'merger'),\n ];\n}\n\nexport function fusionLimitingRoute(\n routes: readonly FusionRouteCapacity[],\n): FusionRouteCapacity {\n let limiting: FusionRouteCapacity | undefined;\n for (const route of routes) {\n if (\n limiting === undefined ||\n route.byte_capacity_utf8_bytes < limiting.byte_capacity_utf8_bytes ||\n (route.byte_capacity_utf8_bytes === limiting.byte_capacity_utf8_bytes &&\n route.role.localeCompare(limiting.role) < 0)\n ) {\n limiting = route;\n }\n }\n if (limiting === undefined) {\n throw new FusionError('fusion budget planning received no configured routes', {\n code: 'model_capacity_unknown',\n childCreated: false,\n });\n }\n return limiting;\n}\n\nfunction routeByRole(\n routes: readonly FusionRouteCapacity[],\n role: FusionRouteCapacity['role'],\n): FusionRouteCapacity {\n const route = routes.find((item) => item.role === role);\n if (route === undefined) {\n throw new FusionError(`fusion budget route ${role} is missing`, {\n code: 'model_capacity_unknown',\n childCreated: false,\n });\n }\n return route;\n}\n\nfunction candidateRole(slot: 1 | 2 | 3): FusionRouteCapacity['role'] {\n if (slot === 1) return 'candidate-1';\n if (slot === 2) return 'candidate-2';\n return 'candidate-3';\n}\n\nfunction estimateRouteInput(\n route: FusionRouteCapacity,\n segments: Parameters<typeof estimateInputTokens>[0]['segments'],\n) {\n return estimateInputTokens({\n family: route.family,\n calibrationBacked: route.rate_source.backed,\n familyResolution: route.rate_source.model_resolution,\n allowedInputTokens: route.allowed_input_tokens,\n scope: 'fusion',\n segments,\n });\n}\n\nfunction utilizationBasisPoints(tokens: number, allowed: number): number {\n return ceilDiv(tokens * BASIS_POINTS_DENOMINATOR, allowed);\n}\n\nfunction forecastEntry(draft: StageForecastDraft): FusionStageBudgetPlanEntry {\n const inputSegments = [knownTextSegment(draft.system_prompt), knownTextSegment(draft.empty_user_prompt)];\n const inputBytes = inputSegments.reduce((sum, segment) => sum + segment.bytes, 0);\n const inputOnly = estimateRouteInput(draft.route, inputSegments);\n const reservationSegments =\n draft.upstream_output_contract_bytes === 0\n ? inputSegments\n : [...inputSegments, unknownOutputContractSegment(draft.upstream_output_contract_bytes)];\n const reservation = estimateRouteInput(draft.route, reservationSegments);\n const forecastUtf8Bytes = inputBytes + draft.upstream_output_contract_bytes;\n const entry: FusionStageBudgetPlanEntry = {\n budget_stage: draft.budget_stage,\n route: draft.route,\n conditional: draft.conditional,\n check_kind: 'input_only_preflight',\n input_utf8_bytes: inputBytes,\n upstream_output_contract_bytes: draft.upstream_output_contract_bytes,\n forecast_utf8_bytes: forecastUtf8Bytes,\n input_only_input_tokens_upper_bound: inputOnly.tokens,\n forecast_input_tokens_upper_bound: reservation.tokens,\n allowed_input_tokens: draft.route.allowed_input_tokens,\n input_only_signed_headroom_tokens: draft.route.allowed_input_tokens - inputOnly.tokens,\n signed_headroom_tokens: draft.route.allowed_input_tokens - reservation.tokens,\n input_only_utilization_basis_points: utilizationBasisPoints(\n inputOnly.tokens,\n draft.route.allowed_input_tokens,\n ),\n utilization_basis_points: utilizationBasisPoints(\n reservation.tokens,\n draft.route.allowed_input_tokens,\n ),\n input_only_estimate: inputOnly,\n reservation_estimate: reservation,\n fits: inputOnly.tokens <= draft.route.allowed_input_tokens,\n reservation_fits: reservation.tokens <= draft.route.allowed_input_tokens,\n };\n if (draft.slot !== undefined) entry.slot = draft.slot;\n return entry;\n}\n\nfunction maxKnownTextBytes(route: FusionRouteCapacity): number {\n return maxKnownTextBytesForTokens({\n family: route.family,\n calibrationBacked: route.rate_source.backed,\n familyResolution: route.rate_source.model_resolution,\n allowedInputTokens: route.allowed_input_tokens,\n scope: 'fusion',\n });\n}\n\nfunction blockerFromEntry(entry: FusionStageBudgetPlanEntry): FusionBudgetBlocker {\n return {\n ...entry,\n overage_tokens: Math.max(0, entry.input_only_input_tokens_upper_bound - entry.allowed_input_tokens),\n bytes_over: Math.max(0, entry.input_utf8_bytes - maxKnownTextBytes(entry.route)),\n };\n}\n\nfunction blockerOrder(blocker: FusionBudgetBlocker): number {\n if (blocker.budget_stage === 'candidate') return blocker.slot ?? 1;\n if (blocker.budget_stage === 'evaluation') return 4;\n if (blocker.budget_stage === 'merge') return 5;\n return 6;\n}\n\nfunction selectBlockers(entries: readonly FusionStageBudgetPlanEntry[]): readonly FusionBudgetBlocker[] {\n return entries.filter((entry) => !entry.fits).map(blockerFromEntry).sort((left, right) => {\n const byOrder = blockerOrder(left) - blockerOrder(right);\n if (byOrder !== 0) return byOrder;\n return left.route.role.localeCompare(right.route.role);\n });\n}\n\nfunction selectPrimaryBlocker(\n blockers: readonly FusionBudgetBlocker[],\n): FusionBudgetBlocker | undefined {\n const mandatory = blockers.find((blocker) => !blocker.conditional);\n return mandatory ?? blockers[0];\n}\n\nfunction replaceRequestText(input: FusionCanonicalInputV3, text: string): FusionCanonicalInputV3 {\n return {\n ...input,\n request: {\n ...input.request,\n text,\n sha256: sha256Hex(text),\n },\n };\n}\n\nfunction visibleTextBytes(input: FusionCanonicalInputV3): number {\n const projection = input.context?.kind === 'session_projection'\n ? input.context.conversation_projection\n : 'conversation_projection' in input\n ? input.conversation_projection\n : undefined;\n if (projection === undefined) return 0;\n let total = 0;\n for (const entry of projection.entries) {\n if (entry[0] === 't') total += utf8Bytes(JSON.stringify(entry[4]));\n }\n return total;\n}\n\nfunction omissionReceiptBytes(input: FusionCanonicalInputV3): number {\n const projection = input.context?.kind === 'session_projection'\n ? input.context.conversation_projection\n : 'conversation_projection' in input\n ? input.conversation_projection\n : undefined;\n if (projection === undefined) return 0;\n let total = 0;\n for (const entry of projection.entries) {\n if (entry[0] === 'o') total += utf8Bytes(JSON.stringify(entry));\n }\n return total;\n}\n\nfunction warningFromEntry(entry: FusionStageBudgetPlanEntry): FusionBudgetWarning | undefined {\n if (!entry.fits) return undefined;\n if (!entry.reservation_fits) {\n return {\n ...entry,\n warning_kind: 'worst_case_reservation',\n threshold_basis_points: FUSION_UTILIZATION_WARNING_THRESHOLD_BASIS_POINTS,\n };\n }\n if (entry.utilization_basis_points >= FUSION_UTILIZATION_WARNING_THRESHOLD_BASIS_POINTS) {\n return {\n ...entry,\n warning_kind: 'input_utilization',\n threshold_basis_points: FUSION_UTILIZATION_WARNING_THRESHOLD_BASIS_POINTS,\n };\n }\n return undefined;\n}\n\nfunction warningsFor(entries: readonly FusionStageBudgetPlanEntry[]): readonly FusionBudgetWarning[] {\n return entries.flatMap((entry) => {\n const warning = warningFromEntry(entry);\n return warning === undefined ? [] : [warning];\n });\n}\n\nfunction entryLabel(entry: FusionStageBudgetPlanEntry): string {\n const slot = entry.slot === undefined ? '' : `-${String(entry.slot)}`;\n const conditional = entry.conditional ? ' (conditional)' : '';\n return `${entry.budget_stage}${slot}${conditional}`;\n}\n\nfunction blockingChildLabel(entry: FusionStageBudgetPlanEntry): string {\n if (entry.budget_stage === 'candidate') return `candidate-${String(entry.slot ?? 1)}`;\n if (entry.budget_stage === 'evaluation_repair') return 'evaluator-repair';\n if (entry.budget_stage === 'evaluation') return 'evaluator';\n return 'merger';\n}\n\nfunction formatTable(entries: readonly FusionStageBudgetPlanEntry[]): string {\n const lines = entries.map(\n (entry) =>\n `${entryLabel(entry)} | route=${entry.route.qualified_id} | input=${String(entry.input_only_input_tokens_upper_bound)} | reserved=${String(entry.forecast_input_tokens_upper_bound)} | allowed=${String(entry.allowed_input_tokens)} | input_headroom=${String(entry.input_only_signed_headroom_tokens)} | reservation_headroom=${String(entry.signed_headroom_tokens)} | ${entry.fits ? 'input-fits' : 'input-over'} | ${entry.reservation_fits ? 'reservation-fits' : 'reservation-warn'}`,\n );\n return lines.join('\\n');\n}\n\nfunction formatComposition(composition: FusionBudgetStageComposition): string {\n return [\n `visible text ${String(composition.visible_text_bytes)} B`,\n `omission receipts ${String(composition.omission_receipt_bytes)} B`,\n `projection metadata ${String(composition.projection_metadata_bytes)} B`,\n `request ${String(composition.request_bytes)} B`,\n `static stage framing ${String(composition.static_stage_framing_bytes)} B`,\n `upstream output contracts ${String(composition.upstream_output_contract_bytes)} B`,\n ].join('; ');\n}\n\nfunction dominantRemediation(\n verdict: FusionBudgetEmptyRequestVerdict,\n composition: FusionBudgetStageComposition | undefined,\n dominantByteClass: string,\n profile: FusionWorkflowProfile,\n): readonly string[] {\n if (dominantByteClass === 'dense_ascii') return DENSE_REMEDIATION;\n if (dominantByteClass === 'multibyte') return MULTIBYTE_REMEDIATION;\n if (composition === undefined) return remediationFor(verdict, profile);\n const entries = [\n { name: 'visible', bytes: composition.visible_text_bytes },\n { name: 'request', bytes: composition.request_bytes },\n { name: 'reservation', bytes: composition.upstream_output_contract_bytes },\n ].sort((left, right) => right.bytes - left.bytes);\n const dominant = entries[0];\n if (dominant?.name === 'reservation') return RESERVATION_REMEDIATION;\n if (dominant?.name === 'request' && !verdict.still_fails_with_empty_request) {\n return profile.contextKind === 'clean_task'\n ? cleanRemediation(profile, true)\n : REASON_REQUEST_REMEDIATION;\n }\n if (profile.contextKind === 'clean_task') return cleanRemediation(profile, false);\n return REASON_EMPTY_REMEDIATION;\n}\n\nfunction remediationFor(\n verdict: FusionBudgetEmptyRequestVerdict,\n profile: FusionWorkflowProfile,\n): readonly string[] {\n if (profile.contextKind === 'clean_task') {\n return cleanRemediation(profile, !verdict.still_fails_with_empty_request);\n }\n return verdict.still_fails_with_empty_request\n ? REASON_EMPTY_REMEDIATION\n : REASON_REQUEST_REMEDIATION;\n}\n\nfunction formatEmptyRequestVerdict(verdict: FusionBudgetEmptyRequestVerdict): string {\n if (verdict.still_fails_with_empty_request) {\n return `Empty-request counterfactual: still fails with ${String(verdict.blockers_with_empty_request.length)} blocking stage(s), so shortening the request cannot make this workflow fit.`;\n }\n if (verdict.minimum_request_byte_reduction === 0) {\n return 'Empty-request counterfactual: fits; no request reduction is required by the current plan.';\n }\n return `Empty-request counterfactual: fits, so request size determines feasibility; reduce the request by at least ${String(verdict.minimum_request_byte_reduction)} UTF-8 bytes, leaving at most ${String(verdict.maximum_safe_request_utf8_bytes)} UTF-8 bytes.`;\n}\n\nfunction stageFromBudgetStage(stage: FusionBudgetStage): FusionStage {\n if (stage === 'merge') return 'merge';\n if (stage === 'candidate') return 'candidate';\n return 'evaluation';\n}\n\nfunction routeTable(routes: readonly FusionRouteCapacity[]): readonly FusionBudgetRouteTableEntry[] {\n return [...routes]\n .sort((left, right) => {\n const byCapacity = left.byte_capacity_utf8_bytes - right.byte_capacity_utf8_bytes;\n if (byCapacity !== 0) return byCapacity;\n return left.role.localeCompare(right.role);\n })\n .map((route) => ({\n role: route.role,\n qualified_id: route.qualified_id,\n allowed_input_tokens: route.allowed_input_tokens,\n family: route.family,\n effective_rate_bytes_per_token_x100: route.rate_source.effective_rate_bytes_per_token_x100,\n byte_capacity_utf8_bytes: route.byte_capacity_utf8_bytes,\n backed: route.rate_source.backed,\n }));\n}\n\nfunction segmentTokensForBytes(route: FusionRouteCapacity, bytes: number): number {\n if (bytes <= 0) return 0;\n const estimate = estimateRouteInput(route, [\n { kind: 'known_text', bytes, multibyteBytes: 0, denseBytes: 0 },\n ]);\n const segment = estimate.perSegment[0];\n return segment === undefined ? 0 : segment.tokens;\n}\n\nfunction contractTokens(bytes: number): number {\n return bytes;\n}\n\nfunction componentBreakdown(\n composition: FusionBudgetStageComposition | undefined,\n route: FusionRouteCapacity,\n): FusionBudgetComponentBreakdown {\n const empty = {\n visible_text_bytes: 0,\n omission_receipt_bytes: 0,\n projection_metadata_bytes: 0,\n request_bytes: 0,\n static_stage_framing_bytes: 0,\n upstream_output_contract_bytes: 0,\n } satisfies FusionBudgetStageComposition;\n const item = composition ?? empty;\n return {\n visible_text: {\n bytes: item.visible_text_bytes,\n tokens: segmentTokensForBytes(route, item.visible_text_bytes),\n },\n omission_receipts: {\n bytes: item.omission_receipt_bytes,\n tokens: segmentTokensForBytes(route, item.omission_receipt_bytes),\n },\n projection_metadata: {\n bytes: item.projection_metadata_bytes,\n tokens: segmentTokensForBytes(route, item.projection_metadata_bytes),\n },\n request: {\n bytes: item.request_bytes,\n tokens: segmentTokensForBytes(route, item.request_bytes),\n },\n static_stage_framing: {\n bytes: item.static_stage_framing_bytes,\n tokens: segmentTokensForBytes(route, item.static_stage_framing_bytes),\n },\n upstream_output_contracts: {\n bytes: item.upstream_output_contract_bytes,\n tokens: contractTokens(item.upstream_output_contract_bytes),\n },\n };\n}\n\nfunction medianCounterfactual(primary: FusionBudgetBlocker): FusionBudgetCounterfactuals['at_median_rate'] {\n if (!primary.route.rate_source.backed) {\n return { forecast_input_tokens_upper_bound: null, signed_headroom_tokens: null, fits: null };\n }\n const median = primary.route.rate_source.provenance.median_bpt_x1000;\n if (median === null) return { forecast_input_tokens_upper_bound: null, signed_headroom_tokens: null, fits: null };\n const variableTokens = ceilDiv(primary.input_utf8_bytes * 1000, median);\n const tokens = variableTokens + TOKEN_BUDGET_AFFINE_F_TOKENS;\n return {\n forecast_input_tokens_upper_bound: tokens,\n signed_headroom_tokens: primary.allowed_input_tokens - tokens,\n fits: tokens <= primary.allowed_input_tokens,\n };\n}\n\nfunction inputCounterfactuals(\n primary: FusionBudgetBlocker,\n plan: FusionBudgetPlanV1,\n): FusionBudgetCounterfactuals {\n return {\n empty_request: plan.empty_request,\n without_reservation: {\n forecast_input_tokens_upper_bound: primary.input_only_input_tokens_upper_bound,\n signed_headroom_tokens: primary.input_only_signed_headroom_tokens,\n fits: primary.fits,\n },\n at_median_rate: medianCounterfactual(primary),\n };\n}\n\nfunction budgetErrorCode(\n checkKind: FusionBudgetCheckKind,\n): 'prompt_budget_exceeded_forecast' | 'prompt_budget_exceeded_measured' {\n return checkKind === 'rendered_prompt'\n ? 'prompt_budget_exceeded_measured'\n : 'prompt_budget_exceeded_forecast';\n}\n\nexport class FusionBudget {\n readonly routes: readonly FusionRouteCapacity[];\n readonly limiting: FusionRouteCapacity;\n private readonly contextPolicyId: string;\n private readonly candidateCapability: FusionCapability;\n private readonly profile: FusionWorkflowProfile;\n\n constructor(\n models: ResolvedFusionModels,\n contextPolicyId: string,\n candidateCapability: FusionCapability = FUSION_REASON_WORKFLOW.candidateCapability,\n profile: FusionWorkflowProfile = FUSION_REASON_WORKFLOW,\n ) {\n this.routes = fusionRouteCapacities(models);\n this.limiting = fusionLimitingRoute(this.routes);\n this.contextPolicyId = contextPolicyId;\n this.candidateCapability = candidateCapability;\n this.profile = profile;\n }\n\n get allowedInputTokens(): number {\n return this.limiting.allowed_input_tokens;\n }\n\n get resultRateSources() {\n return this.routes.map((route) => route.rate_source);\n }\n\n get unknownProviderWarnings(): readonly string[] {\n return this.routes.flatMap((route) => {\n const warning = route.rate_source.warning;\n return route.rate_source.backed || warning === null\n ? []\n : [`${route.qualified_id}: ${warning}`];\n });\n }\n\n private routeForStage(stage: FusionBudgetStage, slot?: 1 | 2 | 3): FusionRouteCapacity {\n if (stage === 'candidate') return routeByRole(this.routes, candidateRole(slot ?? 1));\n if (stage === 'merge') return routeByRole(this.routes, 'merger');\n return routeByRole(this.routes, 'evaluator');\n }\n\n private drafts(input: FusionCanonicalInputV3): readonly StageForecastDraft[] {\n const candidateSystemPrompt = this.profile.candidateSystemPrompt(this.candidateCapability);\n const candidatePrompt = buildCandidatePrompt(input);\n const blindInput = buildBlindEvaluationInput(input, EMPTY_CANDIDATES);\n const evaluationPrompt = buildEvaluationPrompt(blindInput);\n const repairPrompt = buildEvaluationRepairPrompt({\n schema_version: 'pi-background-tasks.fusion-evaluation-repair-input.v1',\n original_blind_input: blindInput,\n invalid_output: '',\n validation_errors: [],\n });\n const mergePrompt = buildMergePrompt(buildMergeInput(input, EMPTY_CANDIDATES, EMPTY_EVALUATION));\n return [\n {\n budget_stage: 'candidate',\n slot: 1,\n route: this.routeForStage('candidate', 1),\n conditional: false,\n system_prompt: candidateSystemPrompt,\n empty_user_prompt: candidatePrompt,\n upstream_output_contract_bytes: 0,\n },\n {\n budget_stage: 'candidate',\n slot: 2,\n route: this.routeForStage('candidate', 2),\n conditional: false,\n system_prompt: candidateSystemPrompt,\n empty_user_prompt: candidatePrompt,\n upstream_output_contract_bytes: 0,\n },\n {\n budget_stage: 'candidate',\n slot: 3,\n route: this.routeForStage('candidate', 3),\n conditional: false,\n system_prompt: candidateSystemPrompt,\n empty_user_prompt: candidatePrompt,\n upstream_output_contract_bytes: 0,\n },\n {\n budget_stage: 'evaluation',\n route: this.routeForStage('evaluation'),\n conditional: false,\n system_prompt: this.profile.evaluatorSystemPrompt,\n empty_user_prompt: evaluationPrompt,\n upstream_output_contract_bytes: 3 * FUSION_CANDIDATE_MAX_OUTPUT_BYTES,\n },\n {\n budget_stage: 'merge',\n route: this.routeForStage('merge'),\n conditional: false,\n system_prompt: this.profile.mergerSystemPrompt,\n empty_user_prompt: mergePrompt,\n upstream_output_contract_bytes:\n 3 * FUSION_CANDIDATE_MAX_OUTPUT_BYTES + FUSION_EVALUATION_MAX_OUTPUT_BYTES,\n },\n {\n budget_stage: 'evaluation_repair',\n route: this.routeForStage('evaluation_repair'),\n conditional: true,\n system_prompt: this.profile.evaluationRepairSystemPrompt,\n empty_user_prompt: repairPrompt,\n upstream_output_contract_bytes:\n 3 * FUSION_CANDIDATE_MAX_OUTPUT_BYTES +\n FUSION_EVALUATION_MAX_OUTPUT_BYTES +\n FUSION_DIAGNOSTICS_MAX_BYTES,\n },\n ];\n }\n\n private entries(input: FusionCanonicalInputV3): readonly FusionStageBudgetPlanEntry[] {\n return this.drafts(input).map(forecastEntry);\n }\n\n private composition(\n input: FusionCanonicalInputV3,\n blocker: FusionBudgetBlocker,\n ): FusionBudgetStageComposition {\n const canonicalBytes = utf8Bytes(buildCandidatePrompt(input));\n const emptyRequestCanonicalBytes = utf8Bytes(buildCandidatePrompt(replaceRequestText(input, '')));\n const requestBytes = canonicalBytes - emptyRequestCanonicalBytes;\n const visible = visibleTextBytes(input);\n const omissions = omissionReceiptBytes(input);\n const projectionMetadata = canonicalBytes - requestBytes - visible - omissions;\n const draft = this.drafts(input).find(\n (item) => item.budget_stage === blocker.budget_stage && item.slot === blocker.slot,\n );\n if (draft === undefined) {\n throw new FusionError('primary budget blocker disappeared during composition', {\n code: 'orchestration_failed',\n childCreated: false,\n });\n }\n return {\n visible_text_bytes: visible,\n omission_receipt_bytes: omissions,\n projection_metadata_bytes: projectionMetadata,\n request_bytes: requestBytes,\n static_stage_framing_bytes:\n utf8Bytes(draft.system_prompt) + utf8Bytes(draft.empty_user_prompt) - canonicalBytes,\n upstream_output_contract_bytes: draft.upstream_output_contract_bytes,\n };\n }\n\n private emptyRequestVerdict(\n input: FusionCanonicalInputV3,\n entries: readonly FusionStageBudgetPlanEntry[],\n ): FusionBudgetEmptyRequestVerdict {\n const emptyEntries = this.entries(replaceRequestText(input, ''));\n const emptyBlockers = selectBlockers(emptyEntries);\n let reduction = 0;\n for (const entry of entries) {\n reduction = Math.max(reduction, entry.input_utf8_bytes - maxKnownTextBytes(entry.route));\n }\n reduction = Math.max(0, reduction);\n const requestBytes = utf8Bytes(input.request.text);\n return {\n request_utf8_bytes: requestBytes,\n still_fails_with_empty_request: emptyBlockers.length > 0,\n shortening_request_can_help: emptyBlockers.length === 0,\n minimum_request_byte_reduction: reduction,\n maximum_safe_request_utf8_bytes: Math.max(0, requestBytes - reduction),\n blockers_with_empty_request: emptyBlockers,\n };\n }\n\n private failure(\n primary: FusionBudgetBlocker,\n plan: FusionBudgetPlanV1,\n artifactDir: string,\n measurementKind: FusionBudgetErrorDetail['measurement_kind'],\n checkKind: FusionBudgetCheckKind,\n ): FusionError {\n const composition = plan.primary_blocker_composition;\n const dominantByteClass = primary.input_only_estimate.rateSource.dominant_byte_class;\n const remediation = dominantRemediation(\n plan.empty_request,\n composition,\n dominantByteClass,\n this.profile,\n );\n const tokensOver = primary.input_only_input_tokens_upper_bound - primary.allowed_input_tokens;\n const budget: FusionBudgetErrorDetail = {\n budget_stage: primary.budget_stage,\n measurement_kind: measurementKind,\n check_kind: checkKind,\n measured_utf8_bytes: primary.input_utf8_bytes,\n measured_input_tokens_upper_bound: primary.input_only_input_tokens_upper_bound,\n allowed_input_tokens: primary.allowed_input_tokens,\n limiting_model: {\n provider: primary.route.provider,\n model: primary.route.model,\n qualified_id: primary.route.qualified_id,\n context_window_tokens: primary.route.context_window_tokens,\n },\n rate_source: primary.input_only_estimate.rateSource,\n backed: primary.input_only_estimate.rateSource.backed,\n dominant_byte_class: dominantByteClass,\n component_breakdown: componentBreakdown(composition, primary.route),\n byte_class_breakdown: primary.input_only_estimate.byte_class_breakdown,\n dense_regions: [],\n bytes_over: primary.bytes_over,\n tokens_over: Math.max(0, tokensOver),\n required_allowed_tokens: primary.input_only_input_tokens_upper_bound,\n route_table: routeTable(this.routes),\n counterfactuals: inputCounterfactuals(primary, plan),\n stage_upstream_actuals: [],\n policy_id: FUSION_BUDGET_POLICY.id,\n calibration_version: TOKEN_BUDGET_CALIBRATION_VERSION,\n context_policy_id: this.contextPolicyId,\n remediation,\n blockers: plan.blockers,\n artifact_dir: artifactDir,\n };\n if (primary.slot !== undefined) budget.slot = primary.slot;\n const compositionText = composition === undefined ? 'unavailable' : formatComposition(composition);\n const additional = plan.blockers\n .filter((blocker) => blocker !== primary)\n .map((blocker) => `${entryLabel(blocker)} route=${blocker.route.qualified_id}`)\n .join('; ');\n const rateText = `${primary.route.family} ${formatRateX100(primary.input_only_estimate.rateSource.effective_rate_bytes_per_token_x100)} B/tok + ${String(primary.input_only_estimate.rateSource.affine_f_tokens)} tokens (${primary.input_only_estimate.rateSource.source}, backed=${String(primary.input_only_estimate.rateSource.backed)}, dominant=${dominantByteClass})`;\n const sourceWarning = primary.input_only_estimate.rateSource.warning;\n const routeWarning = sourceWarning === null ? '' : ` Rate warning: ${sourceWarning}.`;\n const checkText =\n checkKind === 'input_only_preflight'\n ? 'input-only preflight forecast'\n : 'exact rendered prompt measurement';\n const dominantText =\n dominantByteClass === 'multibyte'\n ? ' Dominant byte class is multibyte UTF-8; the fatal gate uses the conservative multibyte rate and the plan separately records the provable 1.00 B/tok advisory ceiling.'\n : dominantByteClass === 'dense_ascii'\n ? ' Dominant byte class is dense ASCII/low-whitespace content; the whitespace gate is a heuristic token-density proxy, not a bound.'\n : ` Dominant byte class is ${dominantByteClass}.`;\n const message =\n `Fusion prompt budget exceeded by ${checkText} before ${blockingChildLabel(primary)} child creation. Primary blocking stage: ${entryLabel(primary)} on route ${primary.route.qualified_id}. ` +\n `Forecast ${String(primary.input_utf8_bytes)} UTF-8 bytes (<= ${String(primary.input_only_input_tokens_upper_bound)} input tokens) against ${String(primary.allowed_input_tokens)} allowed input tokens, over by ${String(Math.max(0, tokensOver))} tokens. ` +\n `Estimator: ${rateText}.${routeWarning}${dominantText} ` +\n `The ${blockingChildLabel(primary)} child was not created. Nothing was clipped, dropped, or substituted. Artifact directory: ${artifactDir}.\\n` +\n `Per-stage forecast table:\\n${formatTable(plan.stages)}\\n` +\n `Primary blocker byte composition: ${compositionText}.\\n` +\n `Additional blockers: ${additional.length === 0 ? 'none' : additional}.\\n` +\n `${formatEmptyRequestVerdict(plan.empty_request)}\\n` +\n `Route byte-capacity order: ${routeTable(this.routes).map((route) => `${route.qualified_id}=${String(route.byte_capacity_utf8_bytes)}B`).join(', ')}.\\n` +\n `Remediation: ${remediation.join(' ')}`;\n const details = {\n code: budgetErrorCode(checkKind),\n childCreated: false,\n budget,\n stage: stageFromBudgetStage(primary.budget_stage),\n };\n if (primary.slot !== undefined) return new FusionError(message, { ...details, slot: primary.slot });\n return new FusionError(message, details);\n }\n\n private planMetadata(input?: FusionCanonicalInputV3): Pick<FusionBudgetPlanV1, 'workflow' | 'context' | 'fixed_candidate_policy' | 'tool_policy'> {\n return {\n workflow: this.profile.id,\n context: {\n kind: this.profile.contextKind,\n policy_id: input?.context?.policy_id ?? this.contextPolicyId,\n },\n fixed_candidate_policy: {\n capability: this.candidateCapability,\n tools: this.profile.candidateTools,\n },\n tool_policy: {\n candidate_tools: this.profile.candidateTools,\n evaluation_tools: [] as readonly [],\n merge_tools: [] as readonly [],\n },\n };\n }\n\n plan(input: FusionCanonicalInputV3): FusionBudgetPlanV1 {\n const stages = this.entries(input);\n const blockers = selectBlockers(stages);\n const primary = selectPrimaryBlocker(blockers);\n const emptyRequest = this.emptyRequestVerdict(input, stages);\n const base: FusionBudgetPlanV1 = {\n schema_version: FUSION_BUDGET_PLAN_SCHEMA_VERSION,\n ...this.planMetadata(input),\n policy: FUSION_BUDGET_POLICY,\n routes: this.routes,\n stages,\n blockers,\n empty_request: emptyRequest,\n warnings: warningsFor(stages),\n };\n if (primary === undefined) return base;\n return {\n ...base,\n primary_blocker: primary,\n primary_blocker_composition: this.composition(input, primary),\n };\n }\n\n assertPlanFits(plan: FusionBudgetPlanV1, artifactDir: string): void {\n if (plan.primary_blocker !== undefined) {\n throw this.failure(\n plan.primary_blocker,\n plan,\n artifactDir,\n 'stage_forecast',\n 'input_only_preflight',\n );\n }\n }\n\n assertStagePrompt(\n stage: FusionBudgetStage,\n systemPrompt: string,\n userPrompt: string,\n slot?: 1 | 2 | 3,\n ): void {\n const route = this.routeForStage(stage, slot);\n const inputSegments = [knownTextSegment(systemPrompt), knownTextSegment(userPrompt)];\n const inputBytes = inputSegments.reduce((sum, segment) => sum + segment.bytes, 0);\n const estimate = estimateRouteInput(route, inputSegments);\n if (estimate.tokens <= route.allowed_input_tokens) return;\n const entry: FusionStageBudgetPlanEntry = {\n budget_stage: stage,\n route,\n conditional: stage === 'evaluation_repair',\n check_kind: 'input_only_preflight',\n input_utf8_bytes: inputBytes,\n upstream_output_contract_bytes: 0,\n forecast_utf8_bytes: inputBytes,\n input_only_input_tokens_upper_bound: estimate.tokens,\n forecast_input_tokens_upper_bound: estimate.tokens,\n allowed_input_tokens: route.allowed_input_tokens,\n input_only_signed_headroom_tokens: route.allowed_input_tokens - estimate.tokens,\n signed_headroom_tokens: route.allowed_input_tokens - estimate.tokens,\n input_only_utilization_basis_points: utilizationBasisPoints(estimate.tokens, route.allowed_input_tokens),\n utilization_basis_points: utilizationBasisPoints(estimate.tokens, route.allowed_input_tokens),\n input_only_estimate: estimate,\n reservation_estimate: estimate,\n fits: false,\n reservation_fits: false,\n };\n if (slot !== undefined) entry.slot = slot;\n const blocker = blockerFromEntry(entry);\n const plan: FusionBudgetPlanV1 = {\n schema_version: FUSION_BUDGET_PLAN_SCHEMA_VERSION,\n ...this.planMetadata(),\n policy: FUSION_BUDGET_POLICY,\n routes: this.routes,\n stages: [entry],\n blockers: [blocker],\n primary_blocker: blocker,\n empty_request: {\n request_utf8_bytes: 0,\n still_fails_with_empty_request: true,\n shortening_request_can_help: false,\n minimum_request_byte_reduction: blocker.bytes_over,\n maximum_safe_request_utf8_bytes: 0,\n blockers_with_empty_request: [blocker],\n },\n warnings: [],\n };\n throw this.failure(blocker, plan, 'stage prompt re-measurement', 'rendered_prompt', 'rendered_prompt');\n }\n\n calibrationViolationForCompletedChild(\n stage: FusionStage,\n systemPrompt: string,\n userPrompt: string,\n result: FusionChildRunResult,\n slot?: 1 | 2 | 3,\n ): FusionCalibrationViolation | undefined {\n const route = this.routeForStage(stage, slot);\n const inputSegments = [knownTextSegment(systemPrompt), knownTextSegment(userPrompt)];\n const promptUtf8Bytes = inputSegments.reduce((sum, segment) => sum + segment.bytes, 0);\n const estimate = estimateRouteInput(route, inputSegments);\n // The forecast is a one-request admission estimate. Compare it only with\n // the first provider request, never with aggregate agent-loop/cache usage.\n // Custom child runners predating this observation field remain compatible,\n // but cannot produce a calibration verdict without like-for-like evidence.\n const observedUsage = result.firstRequestUsage;\n if (observedUsage === undefined) return undefined;\n const billedInput = observedUsage.input + observedUsage.cacheRead + observedUsage.cacheWrite;\n if (billedInput <= estimate.tokens) return undefined;\n const violation: FusionCalibrationViolation = {\n schema_version: FUSION_CALIBRATION_VIOLATION_SCHEMA_VERSION,\n stage,\n attempt: result.attempt,\n route: {\n provider: result.provider,\n model: result.model,\n qualified_id: result.qualifiedId,\n },\n family: route.family,\n rate_source: estimate.rateSource,\n prompt_utf8_bytes: promptUtf8Bytes,\n prompt_sha256: sha256Hex(`${systemPrompt}\\u0000${userPrompt}`),\n observation_scope: 'first_provider_request',\n provider_request_count: result.providerRequestCount ?? 1,\n forecast_input_tokens: estimate.tokens,\n billed_input_tokens: billedInput,\n billed_input_breakdown: {\n input: observedUsage.input,\n cache_read: observedUsage.cacheRead,\n cache_write: observedUsage.cacheWrite,\n },\n under_forecast_tokens: billedInput - estimate.tokens,\n byte_class_breakdown: estimate.byte_class_breakdown,\n dominant_byte_class: estimate.rateSource.dominant_byte_class,\n };\n if (slot !== undefined) violation.slot = slot;\n return violation;\n }\n}\n"]}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { FUSION_CANDIDATE_MAX_OUTPUT_BYTES, fusionJsonRenderedTextBytes, } from './output-contract.js';
|
|
3
|
+
export const FUSION_CHILD_RESULT_SCHEMA_VERSION = 'pi-background-tasks.fusion-child-result.v4';
|
|
4
|
+
export const FUSION_CHILD_RESULT_PREFIX = '\u001ePI_FUSION_CHILD_RESULT ';
|
|
5
|
+
export const FUSION_CHILD_SETTLEMENT_SCHEMA_VERSION = 'pi-background-tasks.fusion-child-settlement.v3';
|
|
6
|
+
export const FUSION_CHILD_SETTLEMENT_PREFIX = '\u001ePI_FUSION_CHILD_SETTLEMENT ';
|
|
7
|
+
export const FUSION_TOOL_CALL_LOG_PATH_ENV = 'PI_FUSION_TOOL_CALL_LOG_PATH';
|
|
8
|
+
export const FUSION_CANDIDATE_OUTPUT_RECOVERY_PATH_ENV = 'PI_FUSION_CANDIDATE_OUTPUT_RECOVERY_PATH';
|
|
9
|
+
export const FUSION_RESEARCH_ENABLED_ENV = 'PI_FUSION_RESEARCH_ENABLED';
|
|
10
|
+
export const FUSION_SOURCE_POLICY_PATH_ENV = 'PI_FUSION_SOURCE_POLICY_PATH';
|
|
11
|
+
export const FUSION_SOURCE_POLICY_SHA256_ENV = 'PI_FUSION_SOURCE_POLICY_SHA256';
|
|
12
|
+
export const FUSION_TOOL_CALL_SEAL_SCHEMA_VERSION = 'pi-background-tasks.fusion-tool-call-seal.v1';
|
|
13
|
+
export const FUSION_TOOL_CALL_SEAL_SUFFIX = '.seal.json';
|
|
14
|
+
export const FUSION_RUNTIME_GUARD_SCHEMA_VERSION = 'pi-background-tasks.fusion-runtime-guard.v2';
|
|
15
|
+
export const FUSION_RUNTIME_GUARD_PREFIX = '\u001ePI_FUSION_RUNTIME_GUARD ';
|
|
16
|
+
export const FUSION_CHILD_MAX_PROVIDER_REQUESTS = 550;
|
|
17
|
+
export const FUSION_CHILD_MAX_TOOL_CALLS = 600;
|
|
18
|
+
/**
|
|
19
|
+
* Aggregate ceiling on tool-result bytes a single candidate child may accumulate.
|
|
20
|
+
*
|
|
21
|
+
* The byte ceiling complements the tool/request count limits and pre-spawn stage
|
|
22
|
+
* budgets. It remains an independent bound on total tool material across the child run.
|
|
23
|
+
*/
|
|
24
|
+
export const FUSION_CHILD_MAX_TOTAL_TOOL_RESULT_BYTES = 32 * 1024 * 1024;
|
|
25
|
+
function protocolSha256(value) {
|
|
26
|
+
return createHash('sha256').update(value).digest('hex');
|
|
27
|
+
}
|
|
28
|
+
export function serializeFusionChildResultRecords(records) {
|
|
29
|
+
return Buffer.from(records.length === 0 ? '' : `${records.map((record) => JSON.stringify(record)).join('\n')}\n`, 'utf8');
|
|
30
|
+
}
|
|
31
|
+
function hasZeroUsage(record) {
|
|
32
|
+
const usage = record.usage;
|
|
33
|
+
return (usage.input === 0 &&
|
|
34
|
+
usage.output === 0 &&
|
|
35
|
+
usage.cacheRead === 0 &&
|
|
36
|
+
usage.cacheWrite === 0 &&
|
|
37
|
+
usage.totalTokens === 0 &&
|
|
38
|
+
usage.cost.input === 0 &&
|
|
39
|
+
usage.cost.output === 0 &&
|
|
40
|
+
usage.cost.cacheRead === 0 &&
|
|
41
|
+
usage.cost.cacheWrite === 0 &&
|
|
42
|
+
usage.cost.total === 0);
|
|
43
|
+
}
|
|
44
|
+
export function isRecoverableFusionChildErrorRecord(record) {
|
|
45
|
+
return (record.stop_reason === 'error' &&
|
|
46
|
+
record.text_blocks.length === 0 &&
|
|
47
|
+
record.text_sha256 === protocolSha256(Buffer.alloc(0)) &&
|
|
48
|
+
hasZeroUsage(record) &&
|
|
49
|
+
record.output_contract.recovery_role === 'none');
|
|
50
|
+
}
|
|
51
|
+
function isOversizedOriginal(record) {
|
|
52
|
+
const output = record.output_contract;
|
|
53
|
+
return (output.recovery_role === 'oversized_original' &&
|
|
54
|
+
output.candidate_limit_bytes === FUSION_CANDIDATE_MAX_OUTPUT_BYTES &&
|
|
55
|
+
output.json_rendered_bytes > FUSION_CANDIDATE_MAX_OUTPUT_BYTES &&
|
|
56
|
+
record.stop_reason === 'stop');
|
|
57
|
+
}
|
|
58
|
+
function outputRecoveryProtocolInvalid(records) {
|
|
59
|
+
const originals = records.flatMap((record, ordinal) => record.output_contract.recovery_role === 'oversized_original' ? [ordinal] : []);
|
|
60
|
+
const replacements = records.flatMap((record, ordinal) => record.output_contract.recovery_role === 'replacement' ? [ordinal] : []);
|
|
61
|
+
for (const record of records) {
|
|
62
|
+
const output = record.output_contract;
|
|
63
|
+
if (output.candidate_limit_bytes !== null &&
|
|
64
|
+
output.candidate_limit_bytes !== FUSION_CANDIDATE_MAX_OUTPUT_BYTES) {
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
if (output.recovery_role !== 'none' && output.candidate_limit_bytes === null)
|
|
68
|
+
return true;
|
|
69
|
+
if (output.recovery_role === 'oversized_original' && !isOversizedOriginal(record))
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
if (originals.length === 0 && replacements.length === 0)
|
|
73
|
+
return false;
|
|
74
|
+
if (originals.length !== 1 || replacements.length !== 1)
|
|
75
|
+
return true;
|
|
76
|
+
const original = originals[0];
|
|
77
|
+
const replacement = replacements[0];
|
|
78
|
+
return (original === undefined ||
|
|
79
|
+
replacement === undefined ||
|
|
80
|
+
original !== records.length - 2 ||
|
|
81
|
+
replacement !== records.length - 1);
|
|
82
|
+
}
|
|
83
|
+
function finalCandidateOutputExceedsContract(records) {
|
|
84
|
+
const final = records.at(-1);
|
|
85
|
+
if (final === undefined)
|
|
86
|
+
return false;
|
|
87
|
+
const output = final.output_contract;
|
|
88
|
+
return (output.candidate_limit_bytes === FUSION_CANDIDATE_MAX_OUTPUT_BYTES &&
|
|
89
|
+
output.json_rendered_bytes > FUSION_CANDIDATE_MAX_OUTPUT_BYTES);
|
|
90
|
+
}
|
|
91
|
+
export function buildFusionChildSettlement(records, runtimeGuardFailed = false, cacheObservationFailed = false, outputRecoveryFailed = false) {
|
|
92
|
+
const finalRecordIndex = records.length === 0 ? null : records.length - 1;
|
|
93
|
+
const final = records.at(-1);
|
|
94
|
+
const recoveredErrorOrdinals = records.flatMap((record, ordinal) => ordinal < records.length - 1 && isRecoverableFusionChildErrorRecord(record) ? [ordinal] : []);
|
|
95
|
+
const recoveredOutputCapOrdinals = records.flatMap((record, ordinal) => ordinal < records.length - 1 && isOversizedOriginal(record) ? [ordinal] : []);
|
|
96
|
+
const invalidRecovery = outputRecoveryProtocolInvalid(records);
|
|
97
|
+
const invalidNonFinal = records.some((record, ordinal) => ordinal < records.length - 1 &&
|
|
98
|
+
record.stop_reason !== 'toolUse' &&
|
|
99
|
+
!isRecoverableFusionChildErrorRecord(record) &&
|
|
100
|
+
!isOversizedOriginal(record));
|
|
101
|
+
let failureReason = null;
|
|
102
|
+
if (runtimeGuardFailed)
|
|
103
|
+
failureReason = 'runtime_guard';
|
|
104
|
+
else if (cacheObservationFailed)
|
|
105
|
+
failureReason = 'cache_observation';
|
|
106
|
+
else if (final === undefined)
|
|
107
|
+
failureReason = 'no_records';
|
|
108
|
+
else if (final.stop_reason !== 'stop')
|
|
109
|
+
failureReason = 'final_not_stop';
|
|
110
|
+
else if (outputRecoveryFailed ||
|
|
111
|
+
invalidRecovery ||
|
|
112
|
+
finalCandidateOutputExceedsContract(records)) {
|
|
113
|
+
failureReason = 'output_recovery';
|
|
114
|
+
}
|
|
115
|
+
else if (invalidNonFinal)
|
|
116
|
+
failureReason = 'invalid_non_final';
|
|
117
|
+
return {
|
|
118
|
+
schema_version: FUSION_CHILD_SETTLEMENT_SCHEMA_VERSION,
|
|
119
|
+
status: failureReason === null ? 'complete' : 'failed',
|
|
120
|
+
record_count: records.length,
|
|
121
|
+
records_sha256: protocolSha256(serializeFusionChildResultRecords(records)),
|
|
122
|
+
final_record_index: finalRecordIndex,
|
|
123
|
+
final_text_sha256: final?.text_sha256 ?? null,
|
|
124
|
+
recovered_error_ordinals: recoveredErrorOrdinals,
|
|
125
|
+
recovered_output_cap_ordinals: recoveredOutputCapOrdinals,
|
|
126
|
+
failure_reason: failureReason,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
export function buildFusionChildResultMetadata(message, cacheObservation, outputContract = { candidateLimitBytes: null, recoveryRole: 'none' }) {
|
|
130
|
+
if (outputContract.candidateLimitBytes !== null &&
|
|
131
|
+
outputContract.candidateLimitBytes !== FUSION_CANDIDATE_MAX_OUTPUT_BYTES) {
|
|
132
|
+
throw new Error('fusion child candidate output limit does not match the shared contract');
|
|
133
|
+
}
|
|
134
|
+
if (outputContract.recoveryRole !== 'none' && outputContract.candidateLimitBytes === null) {
|
|
135
|
+
throw new Error('fusion child output recovery role requires the candidate output contract');
|
|
136
|
+
}
|
|
137
|
+
const textBlocks = message.content.flatMap((part) => part.type === 'text' && typeof part.text === 'string' ? [part.text] : []);
|
|
138
|
+
const text = textBlocks.join('');
|
|
139
|
+
const usage = {
|
|
140
|
+
input: message.usage.input,
|
|
141
|
+
output: message.usage.output,
|
|
142
|
+
cacheRead: message.usage.cacheRead,
|
|
143
|
+
cacheWrite: message.usage.cacheWrite,
|
|
144
|
+
...(message.usage.cacheWrite1h === undefined
|
|
145
|
+
? {}
|
|
146
|
+
: { cacheWrite1h: message.usage.cacheWrite1h }),
|
|
147
|
+
...(message.usage.reasoning === undefined ? {} : { reasoning: message.usage.reasoning }),
|
|
148
|
+
totalTokens: message.usage.totalTokens,
|
|
149
|
+
cost: {
|
|
150
|
+
input: message.usage.cost.input,
|
|
151
|
+
output: message.usage.cost.output,
|
|
152
|
+
cacheRead: message.usage.cost.cacheRead,
|
|
153
|
+
cacheWrite: message.usage.cost.cacheWrite,
|
|
154
|
+
total: message.usage.cost.total,
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
return {
|
|
158
|
+
schema_version: FUSION_CHILD_RESULT_SCHEMA_VERSION,
|
|
159
|
+
provider: message.provider,
|
|
160
|
+
model: message.model,
|
|
161
|
+
stop_reason: message.stopReason,
|
|
162
|
+
text_blocks: textBlocks.map((blockText) => ({
|
|
163
|
+
utf8_bytes: Buffer.byteLength(blockText, 'utf8'),
|
|
164
|
+
sha256: protocolSha256(blockText),
|
|
165
|
+
})),
|
|
166
|
+
text_sha256: protocolSha256(text),
|
|
167
|
+
usage,
|
|
168
|
+
cache_observation: cacheObservation,
|
|
169
|
+
output_contract: {
|
|
170
|
+
json_rendered_bytes: fusionJsonRenderedTextBytes(text),
|
|
171
|
+
candidate_limit_bytes: outputContract.candidateLimitBytes,
|
|
172
|
+
recovery_role: outputContract.recoveryRole,
|
|
173
|
+
},
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=child-protocol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"child-protocol.js","sourceRoot":"","sources":["../../../../src/core/fusion/child-protocol.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from 'node:crypto';\nimport type { Usage } from '@earendil-works/pi-ai';\nimport type { FusionClaudeCacheObservation } from './claude-cache.js';\nimport {\n FUSION_CANDIDATE_MAX_OUTPUT_BYTES,\n fusionJsonRenderedTextBytes,\n} from './output-contract.js';\n\nexport const FUSION_CHILD_RESULT_SCHEMA_VERSION =\n 'pi-background-tasks.fusion-child-result.v4' as const;\nexport const FUSION_CHILD_RESULT_PREFIX = '\\u001ePI_FUSION_CHILD_RESULT ';\nexport const FUSION_CHILD_SETTLEMENT_SCHEMA_VERSION =\n 'pi-background-tasks.fusion-child-settlement.v3' as const;\nexport const FUSION_CHILD_SETTLEMENT_PREFIX = '\\u001ePI_FUSION_CHILD_SETTLEMENT ';\nexport const FUSION_TOOL_CALL_LOG_PATH_ENV = 'PI_FUSION_TOOL_CALL_LOG_PATH';\nexport const FUSION_CANDIDATE_OUTPUT_RECOVERY_PATH_ENV = 'PI_FUSION_CANDIDATE_OUTPUT_RECOVERY_PATH';\nexport const FUSION_RESEARCH_ENABLED_ENV = 'PI_FUSION_RESEARCH_ENABLED';\nexport const FUSION_SOURCE_POLICY_PATH_ENV = 'PI_FUSION_SOURCE_POLICY_PATH';\nexport const FUSION_SOURCE_POLICY_SHA256_ENV = 'PI_FUSION_SOURCE_POLICY_SHA256';\nexport const FUSION_TOOL_CALL_SEAL_SCHEMA_VERSION =\n 'pi-background-tasks.fusion-tool-call-seal.v1' as const;\nexport const FUSION_TOOL_CALL_SEAL_SUFFIX = '.seal.json';\nexport const FUSION_RUNTIME_GUARD_SCHEMA_VERSION =\n 'pi-background-tasks.fusion-runtime-guard.v2' as const;\nexport const FUSION_RUNTIME_GUARD_PREFIX = '\\u001ePI_FUSION_RUNTIME_GUARD ';\nexport const FUSION_CHILD_MAX_PROVIDER_REQUESTS = 550;\nexport const FUSION_CHILD_MAX_TOOL_CALLS = 600;\n\n/**\n * Aggregate ceiling on tool-result bytes a single candidate child may accumulate.\n *\n * The byte ceiling complements the tool/request count limits and pre-spawn stage\n * budgets. It remains an independent bound on total tool material across the child run.\n */\nexport const FUSION_CHILD_MAX_TOTAL_TOOL_RESULT_BYTES = 32 * 1024 * 1024;\n\nexport type FusionRuntimeGuardCode =\n | 'provider_request_limit'\n | 'provider_payload_invalid'\n | 'claude_cache_policy'\n | 'tool_call_limit';\n\nexport interface FusionRuntimeGuardRecord {\n schema_version: typeof FUSION_RUNTIME_GUARD_SCHEMA_VERSION;\n code: FusionRuntimeGuardCode;\n provider: string;\n model: string;\n request_ordinal: number;\n tool_call_count: number;\n payload_bytes: number;\n payload_sha256: string;\n message: string;\n}\n\nexport interface FusionChildTextBlockMetadata {\n utf8_bytes: number;\n sha256: string;\n}\n\nexport type FusionChildResultUsageMetadata = Usage;\n\nexport type FusionChildOutputRecoveryRole = 'none' | 'oversized_original' | 'replacement';\n\nexport interface FusionChildOutputContractMetadata {\n json_rendered_bytes: number;\n candidate_limit_bytes: number | null;\n recovery_role: FusionChildOutputRecoveryRole;\n}\n\nexport interface FusionChildResultMetadata {\n schema_version: typeof FUSION_CHILD_RESULT_SCHEMA_VERSION;\n provider: string;\n model: string;\n stop_reason: string;\n text_blocks: FusionChildTextBlockMetadata[];\n text_sha256: string;\n usage: FusionChildResultUsageMetadata;\n cache_observation: FusionClaudeCacheObservation;\n output_contract: FusionChildOutputContractMetadata;\n}\n\nexport type FusionChildSettlementFailureReason =\n | 'no_records'\n | 'final_not_stop'\n | 'invalid_non_final'\n | 'runtime_guard'\n | 'cache_observation'\n | 'output_recovery';\n\nexport interface FusionChildSettlementRecord {\n schema_version: typeof FUSION_CHILD_SETTLEMENT_SCHEMA_VERSION;\n status: 'complete' | 'failed';\n record_count: number;\n records_sha256: string;\n final_record_index: number | null;\n final_text_sha256: string | null;\n recovered_error_ordinals: number[];\n recovered_output_cap_ordinals: number[];\n failure_reason: FusionChildSettlementFailureReason | null;\n}\n\nfunction protocolSha256(value: string | Buffer): string {\n return createHash('sha256').update(value).digest('hex');\n}\n\nexport function serializeFusionChildResultRecords(\n records: readonly FusionChildResultMetadata[],\n): Buffer {\n return Buffer.from(\n records.length === 0 ? '' : `${records.map((record) => JSON.stringify(record)).join('\\n')}\\n`,\n 'utf8',\n );\n}\n\nfunction hasZeroUsage(record: FusionChildResultMetadata): boolean {\n const usage = record.usage;\n return (\n usage.input === 0 &&\n usage.output === 0 &&\n usage.cacheRead === 0 &&\n usage.cacheWrite === 0 &&\n usage.totalTokens === 0 &&\n usage.cost.input === 0 &&\n usage.cost.output === 0 &&\n usage.cost.cacheRead === 0 &&\n usage.cost.cacheWrite === 0 &&\n usage.cost.total === 0\n );\n}\n\nexport function isRecoverableFusionChildErrorRecord(record: FusionChildResultMetadata): boolean {\n return (\n record.stop_reason === 'error' &&\n record.text_blocks.length === 0 &&\n record.text_sha256 === protocolSha256(Buffer.alloc(0)) &&\n hasZeroUsage(record) &&\n record.output_contract.recovery_role === 'none'\n );\n}\n\nfunction isOversizedOriginal(record: FusionChildResultMetadata): boolean {\n const output = record.output_contract;\n return (\n output.recovery_role === 'oversized_original' &&\n output.candidate_limit_bytes === FUSION_CANDIDATE_MAX_OUTPUT_BYTES &&\n output.json_rendered_bytes > FUSION_CANDIDATE_MAX_OUTPUT_BYTES &&\n record.stop_reason === 'stop'\n );\n}\n\nfunction outputRecoveryProtocolInvalid(records: readonly FusionChildResultMetadata[]): boolean {\n const originals = records.flatMap((record, ordinal) =>\n record.output_contract.recovery_role === 'oversized_original' ? [ordinal] : [],\n );\n const replacements = records.flatMap((record, ordinal) =>\n record.output_contract.recovery_role === 'replacement' ? [ordinal] : [],\n );\n for (const record of records) {\n const output = record.output_contract;\n if (\n output.candidate_limit_bytes !== null &&\n output.candidate_limit_bytes !== FUSION_CANDIDATE_MAX_OUTPUT_BYTES\n ) {\n return true;\n }\n if (output.recovery_role !== 'none' && output.candidate_limit_bytes === null) return true;\n if (output.recovery_role === 'oversized_original' && !isOversizedOriginal(record)) return true;\n }\n if (originals.length === 0 && replacements.length === 0) return false;\n if (originals.length !== 1 || replacements.length !== 1) return true;\n const original = originals[0];\n const replacement = replacements[0];\n return (\n original === undefined ||\n replacement === undefined ||\n original !== records.length - 2 ||\n replacement !== records.length - 1\n );\n}\n\nfunction finalCandidateOutputExceedsContract(\n records: readonly FusionChildResultMetadata[],\n): boolean {\n const final = records.at(-1);\n if (final === undefined) return false;\n const output = final.output_contract;\n return (\n output.candidate_limit_bytes === FUSION_CANDIDATE_MAX_OUTPUT_BYTES &&\n output.json_rendered_bytes > FUSION_CANDIDATE_MAX_OUTPUT_BYTES\n );\n}\n\nexport function buildFusionChildSettlement(\n records: readonly FusionChildResultMetadata[],\n runtimeGuardFailed = false,\n cacheObservationFailed = false,\n outputRecoveryFailed = false,\n): FusionChildSettlementRecord {\n const finalRecordIndex = records.length === 0 ? null : records.length - 1;\n const final = records.at(-1);\n const recoveredErrorOrdinals = records.flatMap((record, ordinal) =>\n ordinal < records.length - 1 && isRecoverableFusionChildErrorRecord(record) ? [ordinal] : [],\n );\n const recoveredOutputCapOrdinals = records.flatMap((record, ordinal) =>\n ordinal < records.length - 1 && isOversizedOriginal(record) ? [ordinal] : [],\n );\n const invalidRecovery = outputRecoveryProtocolInvalid(records);\n const invalidNonFinal = records.some(\n (record, ordinal) =>\n ordinal < records.length - 1 &&\n record.stop_reason !== 'toolUse' &&\n !isRecoverableFusionChildErrorRecord(record) &&\n !isOversizedOriginal(record),\n );\n let failureReason: FusionChildSettlementFailureReason | null = null;\n if (runtimeGuardFailed) failureReason = 'runtime_guard';\n else if (cacheObservationFailed) failureReason = 'cache_observation';\n else if (final === undefined) failureReason = 'no_records';\n else if (final.stop_reason !== 'stop') failureReason = 'final_not_stop';\n else if (\n outputRecoveryFailed ||\n invalidRecovery ||\n finalCandidateOutputExceedsContract(records)\n ) {\n failureReason = 'output_recovery';\n } else if (invalidNonFinal) failureReason = 'invalid_non_final';\n return {\n schema_version: FUSION_CHILD_SETTLEMENT_SCHEMA_VERSION,\n status: failureReason === null ? 'complete' : 'failed',\n record_count: records.length,\n records_sha256: protocolSha256(serializeFusionChildResultRecords(records)),\n final_record_index: finalRecordIndex,\n final_text_sha256: final?.text_sha256 ?? null,\n recovered_error_ordinals: recoveredErrorOrdinals,\n recovered_output_cap_ordinals: recoveredOutputCapOrdinals,\n failure_reason: failureReason,\n };\n}\n\nexport function buildFusionChildResultMetadata(\n message: {\n provider: string;\n model: string;\n stopReason: string;\n content: ReadonlyArray<{ type: string; text?: string }>;\n usage: Usage;\n },\n cacheObservation: FusionClaudeCacheObservation,\n outputContract: {\n candidateLimitBytes: number | null;\n recoveryRole: FusionChildOutputRecoveryRole;\n } = { candidateLimitBytes: null, recoveryRole: 'none' },\n): FusionChildResultMetadata {\n if (\n outputContract.candidateLimitBytes !== null &&\n outputContract.candidateLimitBytes !== FUSION_CANDIDATE_MAX_OUTPUT_BYTES\n ) {\n throw new Error('fusion child candidate output limit does not match the shared contract');\n }\n if (outputContract.recoveryRole !== 'none' && outputContract.candidateLimitBytes === null) {\n throw new Error('fusion child output recovery role requires the candidate output contract');\n }\n const textBlocks = message.content.flatMap((part) =>\n part.type === 'text' && typeof part.text === 'string' ? [part.text] : [],\n );\n const text = textBlocks.join('');\n const usage: FusionChildResultUsageMetadata = {\n input: message.usage.input,\n output: message.usage.output,\n cacheRead: message.usage.cacheRead,\n cacheWrite: message.usage.cacheWrite,\n ...(message.usage.cacheWrite1h === undefined\n ? {}\n : { cacheWrite1h: message.usage.cacheWrite1h }),\n ...(message.usage.reasoning === undefined ? {} : { reasoning: message.usage.reasoning }),\n totalTokens: message.usage.totalTokens,\n cost: {\n input: message.usage.cost.input,\n output: message.usage.cost.output,\n cacheRead: message.usage.cost.cacheRead,\n cacheWrite: message.usage.cost.cacheWrite,\n total: message.usage.cost.total,\n },\n };\n return {\n schema_version: FUSION_CHILD_RESULT_SCHEMA_VERSION,\n provider: message.provider,\n model: message.model,\n stop_reason: message.stopReason,\n text_blocks: textBlocks.map((blockText) => ({\n utf8_bytes: Buffer.byteLength(blockText, 'utf8'),\n sha256: protocolSha256(blockText),\n })),\n text_sha256: protocolSha256(text),\n usage,\n cache_observation: cacheObservation,\n output_contract: {\n json_rendered_bytes: fusionJsonRenderedTextBytes(text),\n candidate_limit_bytes: outputContract.candidateLimitBytes,\n recovery_role: outputContract.recoveryRole,\n },\n };\n}\n"]}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
export const FUSION_CLAUDE_CACHE_OBSERVATION_SCHEMA_VERSION = 'pi-background-tasks.fusion-claude-cache-observation.v1';
|
|
2
|
+
export const FUSION_CLAUDE_CACHE_RETENTION_ENV = 'PI_CACHE_RETENTION';
|
|
3
|
+
export const FUSION_CLAUDE_CACHE_DEFAULT_RETENTION = 'long';
|
|
4
|
+
export const FUSION_CLAUDE_CACHE_BREAKPOINT_LIMIT = 4;
|
|
5
|
+
export const FUSION_CLAUDE_PROMPT_CACHING_SCOPE_BETA = 'prompt-caching-scope-2026-01-05';
|
|
6
|
+
function isRecord(value) {
|
|
7
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
8
|
+
}
|
|
9
|
+
function unknownArray(value) {
|
|
10
|
+
return Array.isArray(value) ? value : undefined;
|
|
11
|
+
}
|
|
12
|
+
function requireRequestOrdinal(value) {
|
|
13
|
+
if (!Number.isSafeInteger(value) || value <= 0) {
|
|
14
|
+
throw new Error('Fusion Claude cache request ordinal must be a positive safe integer');
|
|
15
|
+
}
|
|
16
|
+
return value;
|
|
17
|
+
}
|
|
18
|
+
function parseRetention(value) {
|
|
19
|
+
if (value === 'none' || value === 'short' || value === 'long')
|
|
20
|
+
return value;
|
|
21
|
+
throw new Error(`${FUSION_CLAUDE_CACHE_RETENTION_ENV} must be one of none, short, or long; got ${JSON.stringify(value)}`);
|
|
22
|
+
}
|
|
23
|
+
export function resolveFusionClaudeCachePolicy(env = process.env) {
|
|
24
|
+
const configured = env[FUSION_CLAUDE_CACHE_RETENTION_ENV];
|
|
25
|
+
if (configured === undefined) {
|
|
26
|
+
return { retention: FUSION_CLAUDE_CACHE_DEFAULT_RETENTION, source: 'default' };
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
retention: parseRetention(configured),
|
|
30
|
+
source: FUSION_CLAUDE_CACHE_RETENTION_ENV,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
export function applyFusionClaudePromptCachingScopeHeader(headers) {
|
|
34
|
+
const matchingKey = Object.keys(headers).find((key) => key.toLowerCase() === 'anthropic-beta');
|
|
35
|
+
const existing = matchingKey === undefined ? undefined : headers[matchingKey];
|
|
36
|
+
const values = typeof existing === 'string'
|
|
37
|
+
? existing
|
|
38
|
+
.split(',')
|
|
39
|
+
.map((value) => value.trim())
|
|
40
|
+
.filter((value) => value.length > 0)
|
|
41
|
+
: [];
|
|
42
|
+
if (!values.includes(FUSION_CLAUDE_PROMPT_CACHING_SCOPE_BETA)) {
|
|
43
|
+
values.push(FUSION_CLAUDE_PROMPT_CACHING_SCOPE_BETA);
|
|
44
|
+
}
|
|
45
|
+
const targetKey = matchingKey ?? 'anthropic-beta';
|
|
46
|
+
headers[targetKey] = values.join(',');
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
function validateCacheControl(value) {
|
|
50
|
+
if (!isRecord(value)) {
|
|
51
|
+
throw new Error('Fusion Claude cache_control must be an object');
|
|
52
|
+
}
|
|
53
|
+
if (value['type'] !== 'ephemeral') {
|
|
54
|
+
throw new Error('Fusion Claude cache_control.type must be "ephemeral"');
|
|
55
|
+
}
|
|
56
|
+
const ttl = value['ttl'];
|
|
57
|
+
if (ttl !== undefined && ttl !== '1h' && ttl !== '5m') {
|
|
58
|
+
throw new Error('Fusion Claude cache_control.ttl must be "1h" or "5m" when present');
|
|
59
|
+
}
|
|
60
|
+
return value;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Normalize only cache breakpoints already selected by Pi's Anthropic adapter.
|
|
64
|
+
*
|
|
65
|
+
* Not creating new breakpoints is deliberate: an empty marker set may represent
|
|
66
|
+
* Pi's explicit cacheRetention="none" compaction request or a model compatibility
|
|
67
|
+
* restriction. The package may strengthen or disable native markers, but it must
|
|
68
|
+
* not override an upstream call-level opt-out that is no longer visible in the
|
|
69
|
+
* final provider payload.
|
|
70
|
+
*/
|
|
71
|
+
export function normalizeFusionClaudeCachePayload(input) {
|
|
72
|
+
if (!isRecord(input.payload)) {
|
|
73
|
+
throw new Error('Fusion Claude provider payload must be an object');
|
|
74
|
+
}
|
|
75
|
+
const requestOrdinal = requireRequestOrdinal(input.requestOrdinal);
|
|
76
|
+
const policy = resolveFusionClaudeCachePolicy(input.env ?? process.env);
|
|
77
|
+
const normalizedRetention = policy.retention === 'long' && input.supportsLongCacheRetention === false
|
|
78
|
+
? 'short'
|
|
79
|
+
: policy.retention;
|
|
80
|
+
let incomingBreakpoints = 0;
|
|
81
|
+
let outputBreakpoints = 0;
|
|
82
|
+
const normalizeBlock = (value) => {
|
|
83
|
+
if (!isRecord(value) || !Object.hasOwn(value, 'cache_control'))
|
|
84
|
+
return value;
|
|
85
|
+
const existing = value['cache_control'];
|
|
86
|
+
if (existing === undefined) {
|
|
87
|
+
const next = { ...value };
|
|
88
|
+
Reflect.deleteProperty(next, 'cache_control');
|
|
89
|
+
return next;
|
|
90
|
+
}
|
|
91
|
+
incomingBreakpoints += 1;
|
|
92
|
+
if (incomingBreakpoints > FUSION_CLAUDE_CACHE_BREAKPOINT_LIMIT) {
|
|
93
|
+
throw new Error(`Fusion Claude payload has ${String(incomingBreakpoints)} cache_control breakpoints; Anthropic supports at most ${String(FUSION_CLAUDE_CACHE_BREAKPOINT_LIMIT)}`);
|
|
94
|
+
}
|
|
95
|
+
const control = validateCacheControl(existing);
|
|
96
|
+
const next = { ...value };
|
|
97
|
+
if (normalizedRetention === 'none') {
|
|
98
|
+
Reflect.deleteProperty(next, 'cache_control');
|
|
99
|
+
return next;
|
|
100
|
+
}
|
|
101
|
+
const normalizedControl = { ...control, type: 'ephemeral' };
|
|
102
|
+
Reflect.deleteProperty(normalizedControl, 'ttl');
|
|
103
|
+
if (normalizedRetention === 'long')
|
|
104
|
+
Object.assign(normalizedControl, { ttl: '1h' });
|
|
105
|
+
next['cache_control'] = normalizedControl;
|
|
106
|
+
outputBreakpoints += 1;
|
|
107
|
+
return next;
|
|
108
|
+
};
|
|
109
|
+
const system = unknownArray(input.payload['system']);
|
|
110
|
+
const tools = unknownArray(input.payload['tools']);
|
|
111
|
+
const messages = unknownArray(input.payload['messages']);
|
|
112
|
+
const payload = {
|
|
113
|
+
...input.payload,
|
|
114
|
+
...(system === undefined ? {} : { system: system.map(normalizeBlock) }),
|
|
115
|
+
...(tools === undefined ? {} : { tools: tools.map(normalizeBlock) }),
|
|
116
|
+
...(messages === undefined
|
|
117
|
+
? {}
|
|
118
|
+
: {
|
|
119
|
+
messages: messages.map((message) => {
|
|
120
|
+
if (!isRecord(message))
|
|
121
|
+
return message;
|
|
122
|
+
const content = unknownArray(message['content']);
|
|
123
|
+
return content === undefined
|
|
124
|
+
? message
|
|
125
|
+
: { ...message, content: content.map(normalizeBlock) };
|
|
126
|
+
}),
|
|
127
|
+
}),
|
|
128
|
+
};
|
|
129
|
+
if (outputBreakpoints > FUSION_CLAUDE_CACHE_BREAKPOINT_LIMIT) {
|
|
130
|
+
throw new Error(`Fusion Claude payload produced ${String(outputBreakpoints)} cache_control breakpoints; Anthropic supports at most ${String(FUSION_CLAUDE_CACHE_BREAKPOINT_LIMIT)}`);
|
|
131
|
+
}
|
|
132
|
+
return {
|
|
133
|
+
payload,
|
|
134
|
+
observation: {
|
|
135
|
+
schema_version: FUSION_CLAUDE_CACHE_OBSERVATION_SCHEMA_VERSION,
|
|
136
|
+
applicability: 'anthropic',
|
|
137
|
+
source: policy.source,
|
|
138
|
+
requested_retention: policy.retention,
|
|
139
|
+
effective_retention: outputBreakpoints === 0 ? 'none' : normalizedRetention,
|
|
140
|
+
breakpoint_count: outputBreakpoints,
|
|
141
|
+
request_ordinal: requestOrdinal,
|
|
142
|
+
},
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
export function nonAnthropicFusionCacheObservation(requestOrdinal) {
|
|
146
|
+
return {
|
|
147
|
+
schema_version: FUSION_CLAUDE_CACHE_OBSERVATION_SCHEMA_VERSION,
|
|
148
|
+
applicability: 'not_applicable',
|
|
149
|
+
source: 'not_applicable',
|
|
150
|
+
requested_retention: null,
|
|
151
|
+
effective_retention: null,
|
|
152
|
+
breakpoint_count: 0,
|
|
153
|
+
request_ordinal: requireRequestOrdinal(requestOrdinal),
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
//# sourceMappingURL=claude-cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-cache.js","sourceRoot":"","sources":["../../../../src/core/fusion/claude-cache.ts"],"names":[],"mappings":"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","sourcesContent":["import type { JsonObject } from '../common.js';\n\nexport const FUSION_CLAUDE_CACHE_OBSERVATION_SCHEMA_VERSION =\n 'pi-background-tasks.fusion-claude-cache-observation.v1' as const;\nexport const FUSION_CLAUDE_CACHE_RETENTION_ENV = 'PI_CACHE_RETENTION';\nexport const FUSION_CLAUDE_CACHE_DEFAULT_RETENTION = 'long' as const;\nexport const FUSION_CLAUDE_CACHE_BREAKPOINT_LIMIT = 4;\nexport const FUSION_CLAUDE_PROMPT_CACHING_SCOPE_BETA = 'prompt-caching-scope-2026-01-05' as const;\n\nexport type FusionClaudeCacheRetention = 'none' | 'short' | 'long';\nexport type FusionClaudeCachePolicySource =\n | 'default'\n | typeof FUSION_CLAUDE_CACHE_RETENTION_ENV\n | 'not_applicable';\n\nexport interface FusionClaudeCacheObservation {\n schema_version: typeof FUSION_CLAUDE_CACHE_OBSERVATION_SCHEMA_VERSION;\n applicability: 'anthropic' | 'not_applicable';\n source: FusionClaudeCachePolicySource;\n requested_retention: FusionClaudeCacheRetention | null;\n effective_retention: FusionClaudeCacheRetention | null;\n breakpoint_count: number;\n request_ordinal: number;\n}\n\nexport interface FusionClaudeCacheNormalization {\n payload: JsonObject;\n observation: FusionClaudeCacheObservation;\n}\n\nfunction isRecord(value: unknown): value is JsonObject {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction unknownArray(value: unknown): unknown[] | undefined {\n return Array.isArray(value) ? (value as unknown[]) : undefined;\n}\n\nfunction requireRequestOrdinal(value: number): number {\n if (!Number.isSafeInteger(value) || value <= 0) {\n throw new Error('Fusion Claude cache request ordinal must be a positive safe integer');\n }\n return value;\n}\n\nfunction parseRetention(value: string): FusionClaudeCacheRetention {\n if (value === 'none' || value === 'short' || value === 'long') return value;\n throw new Error(\n `${FUSION_CLAUDE_CACHE_RETENTION_ENV} must be one of none, short, or long; got ${JSON.stringify(value)}`,\n );\n}\n\nexport function resolveFusionClaudeCachePolicy(env: Readonly<NodeJS.ProcessEnv> = process.env): {\n retention: FusionClaudeCacheRetention;\n source: FusionClaudeCachePolicySource;\n} {\n const configured = env[FUSION_CLAUDE_CACHE_RETENTION_ENV];\n if (configured === undefined) {\n return { retention: FUSION_CLAUDE_CACHE_DEFAULT_RETENTION, source: 'default' };\n }\n return {\n retention: parseRetention(configured),\n source: FUSION_CLAUDE_CACHE_RETENTION_ENV,\n };\n}\n\nexport function applyFusionClaudePromptCachingScopeHeader(\n headers: Record<string, string | null>,\n): boolean {\n const matchingKey = Object.keys(headers).find((key) => key.toLowerCase() === 'anthropic-beta');\n const existing = matchingKey === undefined ? undefined : headers[matchingKey];\n const values =\n typeof existing === 'string'\n ? existing\n .split(',')\n .map((value) => value.trim())\n .filter((value) => value.length > 0)\n : [];\n if (!values.includes(FUSION_CLAUDE_PROMPT_CACHING_SCOPE_BETA)) {\n values.push(FUSION_CLAUDE_PROMPT_CACHING_SCOPE_BETA);\n }\n const targetKey = matchingKey ?? 'anthropic-beta';\n headers[targetKey] = values.join(',');\n return true;\n}\n\nfunction validateCacheControl(value: unknown): JsonObject {\n if (!isRecord(value)) {\n throw new Error('Fusion Claude cache_control must be an object');\n }\n if (value['type'] !== 'ephemeral') {\n throw new Error('Fusion Claude cache_control.type must be \"ephemeral\"');\n }\n const ttl = value['ttl'];\n if (ttl !== undefined && ttl !== '1h' && ttl !== '5m') {\n throw new Error('Fusion Claude cache_control.ttl must be \"1h\" or \"5m\" when present');\n }\n return value;\n}\n\n/**\n * Normalize only cache breakpoints already selected by Pi's Anthropic adapter.\n *\n * Not creating new breakpoints is deliberate: an empty marker set may represent\n * Pi's explicit cacheRetention=\"none\" compaction request or a model compatibility\n * restriction. The package may strengthen or disable native markers, but it must\n * not override an upstream call-level opt-out that is no longer visible in the\n * final provider payload.\n */\nexport function normalizeFusionClaudeCachePayload(input: {\n payload: unknown;\n requestOrdinal: number;\n env?: Readonly<NodeJS.ProcessEnv>;\n supportsLongCacheRetention?: boolean | undefined;\n}): FusionClaudeCacheNormalization {\n if (!isRecord(input.payload)) {\n throw new Error('Fusion Claude provider payload must be an object');\n }\n const requestOrdinal = requireRequestOrdinal(input.requestOrdinal);\n const policy = resolveFusionClaudeCachePolicy(input.env ?? process.env);\n const normalizedRetention: FusionClaudeCacheRetention =\n policy.retention === 'long' && input.supportsLongCacheRetention === false\n ? 'short'\n : policy.retention;\n let incomingBreakpoints = 0;\n let outputBreakpoints = 0;\n\n const normalizeBlock = (value: unknown): unknown => {\n if (!isRecord(value) || !Object.hasOwn(value, 'cache_control')) return value;\n const existing = value['cache_control'];\n if (existing === undefined) {\n const next = { ...value };\n Reflect.deleteProperty(next, 'cache_control');\n return next;\n }\n incomingBreakpoints += 1;\n if (incomingBreakpoints > FUSION_CLAUDE_CACHE_BREAKPOINT_LIMIT) {\n throw new Error(\n `Fusion Claude payload has ${String(incomingBreakpoints)} cache_control breakpoints; Anthropic supports at most ${String(FUSION_CLAUDE_CACHE_BREAKPOINT_LIMIT)}`,\n );\n }\n const control = validateCacheControl(existing);\n const next = { ...value };\n if (normalizedRetention === 'none') {\n Reflect.deleteProperty(next, 'cache_control');\n return next;\n }\n const normalizedControl = { ...control, type: 'ephemeral' };\n Reflect.deleteProperty(normalizedControl, 'ttl');\n if (normalizedRetention === 'long') Object.assign(normalizedControl, { ttl: '1h' });\n next['cache_control'] = normalizedControl;\n outputBreakpoints += 1;\n return next;\n };\n\n const system = unknownArray(input.payload['system']);\n const tools = unknownArray(input.payload['tools']);\n const messages = unknownArray(input.payload['messages']);\n const payload = {\n ...input.payload,\n ...(system === undefined ? {} : { system: system.map(normalizeBlock) }),\n ...(tools === undefined ? {} : { tools: tools.map(normalizeBlock) }),\n ...(messages === undefined\n ? {}\n : {\n messages: messages.map((message) => {\n if (!isRecord(message)) return message;\n const content = unknownArray(message['content']);\n return content === undefined\n ? message\n : { ...message, content: content.map(normalizeBlock) };\n }),\n }),\n };\n if (outputBreakpoints > FUSION_CLAUDE_CACHE_BREAKPOINT_LIMIT) {\n throw new Error(\n `Fusion Claude payload produced ${String(outputBreakpoints)} cache_control breakpoints; Anthropic supports at most ${String(FUSION_CLAUDE_CACHE_BREAKPOINT_LIMIT)}`,\n );\n }\n\n return {\n payload,\n observation: {\n schema_version: FUSION_CLAUDE_CACHE_OBSERVATION_SCHEMA_VERSION,\n applicability: 'anthropic',\n source: policy.source,\n requested_retention: policy.retention,\n effective_retention: outputBreakpoints === 0 ? 'none' : normalizedRetention,\n breakpoint_count: outputBreakpoints,\n request_ordinal: requestOrdinal,\n },\n };\n}\n\nexport function nonAnthropicFusionCacheObservation(\n requestOrdinal: number,\n): FusionClaudeCacheObservation {\n return {\n schema_version: FUSION_CLAUDE_CACHE_OBSERVATION_SCHEMA_VERSION,\n applicability: 'not_applicable',\n source: 'not_applicable',\n requested_retention: null,\n effective_retention: null,\n breakpoint_count: 0,\n request_ordinal: requireRequestOrdinal(requestOrdinal),\n };\n}\n"]}
|