pi-background-tasks 2.1.2 → 2.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/TESTING.md +1 -1
- package/TEST_PLAN.md +4 -4
- package/docs/INDEX.md +2 -2
- package/docs/manifest.json +4 -4
- package/docs/operations/configuration.md +4 -1
- package/docs/operations/troubleshooting.md +3 -2
- package/docs/reference/runtime-contracts.md +53 -52
- package/docs/subsystems/docs-freshness-gate.md +2 -2
- package/docs/subsystems/fusion.md +9 -4
- package/docs/tools/bg_delegate.md +1 -1
- package/docs/tools/bg_result.md +8 -1
- package/package.json +1 -1
- package/src/core/fusion/artifacts.ts +265 -3
- package/src/core/fusion/child-protocol.ts +3 -12
- package/src/core/fusion/orchestrator.ts +47 -57
- package/src/core/fusion/pi-child.ts +9 -78
- package/src/core/fusion/result-package.ts +550 -3
- package/src/core/fusion/types.ts +89 -1
- package/src/delegate-extension.ts +66 -5
- package/src/fusion-child-extension.ts +12 -126
package/src/core/fusion/types.ts
CHANGED
|
@@ -30,6 +30,8 @@ export const FUSION_CALIBRATION_VIOLATION_SCHEMA_VERSION =
|
|
|
30
30
|
export const FUSION_VALIDATE_CANDIDATE_CONTRACT_EVENT_SCHEMA_VERSION =
|
|
31
31
|
'pi-background-tasks.fusion-validation-candidate-contract-event.v1';
|
|
32
32
|
export const FUSION_TOOL_CALL_LOG_SCHEMA_VERSION = 'pi-background-tasks.fusion-tool-call.v1';
|
|
33
|
+
export const FUSION_FAILURE_SUMMARY_SCHEMA_VERSION =
|
|
34
|
+
'pi-background-tasks.fusion-failure-summary.v1';
|
|
33
35
|
|
|
34
36
|
/**
|
|
35
37
|
* Conversation-projection transform shared by every Fusion entry point.
|
|
@@ -640,7 +642,8 @@ export type FusionErrorCode =
|
|
|
640
642
|
| 'child_stdin_failed'
|
|
641
643
|
| 'child_event_invalid'
|
|
642
644
|
| 'child_exit_failed'
|
|
643
|
-
| '
|
|
645
|
+
| 'child_runtime_limit_exceeded'
|
|
646
|
+
| 'child_runtime_payload_invalid'
|
|
644
647
|
| 'child_cache_policy_invalid'
|
|
645
648
|
| 'child_timeout'
|
|
646
649
|
| 'child_output_cap'
|
|
@@ -876,6 +879,91 @@ export interface FusionArtifactRef {
|
|
|
876
879
|
sha256: string;
|
|
877
880
|
}
|
|
878
881
|
|
|
882
|
+
export type FusionFailureArtifactClassification =
|
|
883
|
+
| 'complete_stage_output'
|
|
884
|
+
| 'partial_stage_output'
|
|
885
|
+
| 'oversized_original'
|
|
886
|
+
| 'empty_rejected_output'
|
|
887
|
+
| 'evidence_only';
|
|
888
|
+
|
|
889
|
+
export interface FusionFailureEvidenceArtifact {
|
|
890
|
+
name: string;
|
|
891
|
+
classification: FusionFailureArtifactClassification;
|
|
892
|
+
ref: FusionArtifactRef;
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
export interface FusionFailureAttemptMetadata {
|
|
896
|
+
stage: FusionStage;
|
|
897
|
+
slot?: 1 | 2 | 3 | undefined;
|
|
898
|
+
attempt: number;
|
|
899
|
+
status: 'completed' | 'failed' | 'cancelled';
|
|
900
|
+
child_created: boolean;
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
export interface FusionFailureList<T> {
|
|
904
|
+
listed: readonly T[];
|
|
905
|
+
omitted_count: number;
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
export interface FusionFailureMessageMetadata {
|
|
909
|
+
byte_length: number;
|
|
910
|
+
sha256: string;
|
|
911
|
+
inline_message?: string | undefined;
|
|
912
|
+
omission_reason?: 'exceeds_inline_message_bytes_cap' | 'result_view_byte_budget' | undefined;
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
export interface FusionFailureSummaryV1 {
|
|
916
|
+
schema_version: typeof FUSION_FAILURE_SUMMARY_SCHEMA_VERSION;
|
|
917
|
+
run_id: string;
|
|
918
|
+
workflow: FusionWorkflowId;
|
|
919
|
+
source: FusionSource;
|
|
920
|
+
terminal_state: Exclude<FusionTerminalState, 'completed'>;
|
|
921
|
+
created_at: string;
|
|
922
|
+
answer: { present: false; reason: 'run_did_not_commit' };
|
|
923
|
+
failure: {
|
|
924
|
+
code: FusionErrorCode | null;
|
|
925
|
+
stage?: FusionStage | undefined;
|
|
926
|
+
slot?: 1 | 2 | 3 | undefined;
|
|
927
|
+
attempt?: number | undefined;
|
|
928
|
+
child_created: boolean;
|
|
929
|
+
message: FusionFailureMessageMetadata;
|
|
930
|
+
};
|
|
931
|
+
progress: FusionRunProgress;
|
|
932
|
+
usage_so_far: FusionUsage;
|
|
933
|
+
attempts: FusionFailureList<FusionFailureAttemptMetadata>;
|
|
934
|
+
evidence_artifacts: FusionFailureList<FusionFailureEvidenceArtifact>;
|
|
935
|
+
remediation_ids: readonly (
|
|
936
|
+
| 'inspect_manifest_bound_evidence'
|
|
937
|
+
| 'inspect_terminal_error'
|
|
938
|
+
| 'split_or_reduce_work'
|
|
939
|
+
| 'retry_same_route_after_operator_review'
|
|
940
|
+
)[];
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
export interface FusionFailureViewFailure {
|
|
944
|
+
code?: FusionErrorCode | null | undefined;
|
|
945
|
+
stage?: FusionStage | undefined;
|
|
946
|
+
slot?: 1 | 2 | 3 | undefined;
|
|
947
|
+
attempt?: number | undefined;
|
|
948
|
+
child_created?: boolean | undefined;
|
|
949
|
+
message: FusionFailureMessageMetadata;
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
export interface FusionFailureResultView {
|
|
953
|
+
schema_version: typeof FUSION_FAILURE_SUMMARY_SCHEMA_VERSION;
|
|
954
|
+
summary_status: 'verified' | 'legacy_manifest_only' | 'unavailable' | 'integrity_failed';
|
|
955
|
+
terminal_state: Exclude<FusionTerminalState, 'completed'>;
|
|
956
|
+
answer: { present: false; reason: 'run_did_not_commit' };
|
|
957
|
+
failure?: FusionFailureViewFailure | undefined;
|
|
958
|
+
progress?: FusionRunProgress | undefined;
|
|
959
|
+
usage_so_far?: FusionUsage | undefined;
|
|
960
|
+
attempts?: FusionFailureList<FusionFailureAttemptMetadata> | undefined;
|
|
961
|
+
evidence_artifacts?: FusionFailureList<FusionFailureEvidenceArtifact> | undefined;
|
|
962
|
+
remediation_ids?: FusionFailureSummaryV1['remediation_ids'] | undefined;
|
|
963
|
+
failure_summary_ref?: FusionArtifactRef | undefined;
|
|
964
|
+
summary_unavailable_reason?: 'no_durable_summary' | 'manifest_untrusted' | 'summary_integrity_failed' | undefined;
|
|
965
|
+
}
|
|
966
|
+
|
|
879
967
|
export interface FusionArtifactManifest {
|
|
880
968
|
schema_version: typeof FUSION_MANIFEST_SCHEMA_VERSION;
|
|
881
969
|
run_id: string;
|
|
@@ -11,8 +11,13 @@ import { Type, type Static } from 'typebox';
|
|
|
11
11
|
import type { BgTask, BgTaskSnapshot, StartDelegateTaskOptions } from './core/common.js';
|
|
12
12
|
import { truncateChars } from './core/common.js';
|
|
13
13
|
import { sha256Buffer } from './core/attested-pi-run.js';
|
|
14
|
-
import { readFusionCommittedResult } from './core/fusion/result-package.js';
|
|
15
|
-
import {
|
|
14
|
+
import { readFusionCommittedResult, readFusionFailureResult } from './core/fusion/result-package.js';
|
|
15
|
+
import {
|
|
16
|
+
cloneFusionUsage,
|
|
17
|
+
type FusionFailureResultView,
|
|
18
|
+
type FusionUsage,
|
|
19
|
+
type FusionWorkflowId,
|
|
20
|
+
} from './core/fusion/types.js';
|
|
16
21
|
import {
|
|
17
22
|
DELEGATE_AUTO_DELIVER_MODES,
|
|
18
23
|
DELEGATE_CAPABILITIES,
|
|
@@ -161,6 +166,16 @@ export interface FusionBackgroundResultDetails {
|
|
|
161
166
|
answer_bytes?: number | undefined;
|
|
162
167
|
answer_sha256?: string | undefined;
|
|
163
168
|
usage_delivered?: boolean | undefined;
|
|
169
|
+
answer?: { present: false; reason: 'run_did_not_commit' } | undefined;
|
|
170
|
+
summary_status?: FusionFailureResultView['summary_status'] | undefined;
|
|
171
|
+
failure_summary_ref?: FusionFailureResultView['failure_summary_ref'] | undefined;
|
|
172
|
+
failure?: FusionFailureResultView['failure'] | undefined;
|
|
173
|
+
progress?: FusionFailureResultView['progress'] | undefined;
|
|
174
|
+
usage_so_far?: FusionFailureResultView['usage_so_far'] | undefined;
|
|
175
|
+
attempts?: FusionFailureResultView['attempts'] | undefined;
|
|
176
|
+
evidence_artifacts?: FusionFailureResultView['evidence_artifacts'] | undefined;
|
|
177
|
+
remediation_ids?: FusionFailureResultView['remediation_ids'] | undefined;
|
|
178
|
+
summary_unavailable_reason?: FusionFailureResultView['summary_unavailable_reason'] | undefined;
|
|
164
179
|
}
|
|
165
180
|
|
|
166
181
|
export type BackgroundResultDetails = DelegateResultDetails | FusionBackgroundResultDetails;
|
|
@@ -508,9 +523,48 @@ export function registerDelegateExtension(
|
|
|
508
523
|
};
|
|
509
524
|
}
|
|
510
525
|
if (task.status !== 'completed' || fusion.outcome?.status !== 'committed') {
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
526
|
+
const terminal = await readFusionFailureResult({
|
|
527
|
+
artifactDirAbs: fusion.artifactDirAbs,
|
|
528
|
+
artifactDir: fusion.artifactDir,
|
|
529
|
+
runId: fusion.runId,
|
|
530
|
+
workflow: fusion.workflow,
|
|
531
|
+
});
|
|
532
|
+
const state =
|
|
533
|
+
fusion.outcome?.status === 'cancelled' || task.status === 'killed'
|
|
534
|
+
? 'cancelled'
|
|
535
|
+
: 'failed';
|
|
536
|
+
const details: FusionBackgroundResultDetails = {
|
|
537
|
+
schema_version: 'pi-background-tasks.fusion-result-view.v1',
|
|
538
|
+
task_id: task.id,
|
|
539
|
+
state,
|
|
540
|
+
delivery: 'none',
|
|
541
|
+
workflow: fusion.workflow,
|
|
542
|
+
artifact_dir: fusion.artifactDir,
|
|
543
|
+
answer: terminal.answer,
|
|
544
|
+
summary_status: terminal.summary_status,
|
|
545
|
+
...(terminal.failure_summary_ref === undefined
|
|
546
|
+
? {}
|
|
547
|
+
: { failure_summary_ref: terminal.failure_summary_ref }),
|
|
548
|
+
...(terminal.failure === undefined ? {} : { failure: terminal.failure }),
|
|
549
|
+
...(terminal.progress === undefined ? {} : { progress: terminal.progress }),
|
|
550
|
+
...(terminal.usage_so_far === undefined ? {} : { usage_so_far: terminal.usage_so_far }),
|
|
551
|
+
...(terminal.attempts === undefined ? {} : { attempts: terminal.attempts }),
|
|
552
|
+
...(terminal.evidence_artifacts === undefined
|
|
553
|
+
? {}
|
|
554
|
+
: { evidence_artifacts: terminal.evidence_artifacts }),
|
|
555
|
+
...(terminal.remediation_ids === undefined
|
|
556
|
+
? {}
|
|
557
|
+
: { remediation_ids: terminal.remediation_ids }),
|
|
558
|
+
...(terminal.summary_unavailable_reason === undefined
|
|
559
|
+
? {}
|
|
560
|
+
: { summary_unavailable_reason: terminal.summary_unavailable_reason }),
|
|
561
|
+
};
|
|
562
|
+
return {
|
|
563
|
+
content: textContent(
|
|
564
|
+
`Fusion ${task.id} ${state}; no answer was committed. Terminal evidence status: ${terminal.summary_status}. Delivery is none; use only the manifest-bound artifact references in details.`,
|
|
565
|
+
),
|
|
566
|
+
details,
|
|
567
|
+
};
|
|
514
568
|
}
|
|
515
569
|
const verified = await readFusionCommittedResult({
|
|
516
570
|
artifactDirAbs: fusion.artifactDirAbs,
|
|
@@ -673,6 +727,13 @@ export function registerDelegateExtension(
|
|
|
673
727
|
0,
|
|
674
728
|
0,
|
|
675
729
|
);
|
|
730
|
+
if (fusion && (details.state === 'failed' || details.state === 'cancelled')) {
|
|
731
|
+
return new Text(
|
|
732
|
+
theme.fg('warning', `${details.state} fusion; no committed answer · ${details.summary_status ?? 'unavailable'}`),
|
|
733
|
+
0,
|
|
734
|
+
0,
|
|
735
|
+
);
|
|
736
|
+
}
|
|
676
737
|
return new Text(
|
|
677
738
|
`${theme.fg('success', fusion ? '✓ fusion answer' : '✓ delegate answer')} ${theme.fg('dim', `${String(details.answer_bytes ?? 0)}B · ${details.delivery}`)}`,
|
|
678
739
|
0,
|
|
@@ -12,11 +12,6 @@ import { dirname, isAbsolute } from 'node:path';
|
|
|
12
12
|
import { parseJsonText } from './core/common.js';
|
|
13
13
|
import type { ExtensionAPI } from '@earendil-works/pi-coding-agent';
|
|
14
14
|
import { Type, type Static } from 'typebox';
|
|
15
|
-
import {
|
|
16
|
-
estimateInputTokens,
|
|
17
|
-
knownJsonSegment,
|
|
18
|
-
resolveTokenBudgetFamily,
|
|
19
|
-
} from './core/context/token-budget.js';
|
|
20
15
|
import {
|
|
21
16
|
FUSION_TOOL_CALL_LOG_SCHEMA_VERSION,
|
|
22
17
|
FUSION_WEB_FETCH_TOOL_NAME,
|
|
@@ -42,9 +37,7 @@ import {
|
|
|
42
37
|
FUSION_CHILD_MAX_PROVIDER_REQUESTS,
|
|
43
38
|
FUSION_CHILD_MAX_TOOL_CALLS,
|
|
44
39
|
FUSION_CHILD_MAX_TOTAL_TOOL_RESULT_BYTES,
|
|
45
|
-
FUSION_CHILD_MIN_OUTPUT_RESERVE_TOKENS,
|
|
46
40
|
FUSION_CHILD_RESULT_PREFIX,
|
|
47
|
-
FUSION_CHILD_SAFETY_RESERVE_TOKENS,
|
|
48
41
|
FUSION_CHILD_SETTLEMENT_PREFIX,
|
|
49
42
|
FUSION_RESEARCH_ENABLED_ENV,
|
|
50
43
|
FUSION_RUNTIME_GUARD_PREFIX,
|
|
@@ -88,10 +81,8 @@ export {
|
|
|
88
81
|
FUSION_CHILD_MAX_PROVIDER_REQUESTS,
|
|
89
82
|
FUSION_CHILD_MAX_TOOL_CALLS,
|
|
90
83
|
FUSION_CHILD_MAX_TOTAL_TOOL_RESULT_BYTES,
|
|
91
|
-
FUSION_CHILD_MIN_OUTPUT_RESERVE_TOKENS,
|
|
92
84
|
FUSION_CHILD_RESULT_PREFIX,
|
|
93
85
|
FUSION_CHILD_RESULT_SCHEMA_VERSION,
|
|
94
|
-
FUSION_CHILD_SAFETY_RESERVE_TOKENS,
|
|
95
86
|
FUSION_CHILD_SETTLEMENT_PREFIX,
|
|
96
87
|
FUSION_CHILD_SETTLEMENT_SCHEMA_VERSION,
|
|
97
88
|
FUSION_RESEARCH_ENABLED_ENV,
|
|
@@ -370,8 +361,6 @@ export interface FusionRuntimeRequestEvaluationInput {
|
|
|
370
361
|
payload: unknown;
|
|
371
362
|
provider: string | undefined;
|
|
372
363
|
model: string | undefined;
|
|
373
|
-
contextWindowTokens: number | undefined;
|
|
374
|
-
maxOutputTokens: number | undefined;
|
|
375
364
|
requestOrdinal: number;
|
|
376
365
|
toolCallCount: number;
|
|
377
366
|
}
|
|
@@ -384,23 +373,6 @@ function invalidFusionRuntimeRequest(
|
|
|
384
373
|
'provider_payload_invalid' | 'claude_cache_policy'
|
|
385
374
|
> = 'provider_payload_invalid',
|
|
386
375
|
): FusionRuntimeGuardRecord {
|
|
387
|
-
const contextWindowTokens =
|
|
388
|
-
input.contextWindowTokens !== undefined &&
|
|
389
|
-
Number.isSafeInteger(input.contextWindowTokens) &&
|
|
390
|
-
input.contextWindowTokens > 0
|
|
391
|
-
? input.contextWindowTokens
|
|
392
|
-
: 0;
|
|
393
|
-
const modelOutputTokens =
|
|
394
|
-
input.maxOutputTokens !== undefined &&
|
|
395
|
-
Number.isSafeInteger(input.maxOutputTokens) &&
|
|
396
|
-
input.maxOutputTokens > 0
|
|
397
|
-
? input.maxOutputTokens
|
|
398
|
-
: 0;
|
|
399
|
-
const reservedOutputTokens = Math.max(FUSION_CHILD_MIN_OUTPUT_RESERVE_TOKENS, modelOutputTokens);
|
|
400
|
-
const allowedInputTokens = Math.max(
|
|
401
|
-
0,
|
|
402
|
-
contextWindowTokens - reservedOutputTokens - FUSION_CHILD_SAFETY_RESERVE_TOKENS,
|
|
403
|
-
);
|
|
404
376
|
const emptyPayload = Buffer.alloc(0);
|
|
405
377
|
return {
|
|
406
378
|
schema_version: FUSION_RUNTIME_GUARD_SCHEMA_VERSION,
|
|
@@ -411,11 +383,6 @@ function invalidFusionRuntimeRequest(
|
|
|
411
383
|
tool_call_count: input.toolCallCount,
|
|
412
384
|
payload_bytes: 0,
|
|
413
385
|
payload_sha256: sha256(emptyPayload),
|
|
414
|
-
estimated_input_tokens: 0,
|
|
415
|
-
context_window_tokens: contextWindowTokens,
|
|
416
|
-
reserved_output_tokens: reservedOutputTokens,
|
|
417
|
-
safety_reserve_tokens: FUSION_CHILD_SAFETY_RESERVE_TOKENS,
|
|
418
|
-
allowed_input_tokens: allowedInputTokens,
|
|
419
386
|
message: `fusion child could not validate provider request ${String(input.requestOrdinal)}: ${detail}`,
|
|
420
387
|
};
|
|
421
388
|
}
|
|
@@ -455,84 +422,31 @@ export function prepareFusionRuntimeRequest(
|
|
|
455
422
|
export function evaluateFusionRuntimeRequest(
|
|
456
423
|
input: FusionRuntimeRequestEvaluationInput,
|
|
457
424
|
): FusionRuntimeGuardRecord | undefined {
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
let payloadBytes = Buffer.alloc(0);
|
|
461
|
-
let estimatedInputTokens = 0;
|
|
462
|
-
let allowedInputTokens = 0;
|
|
463
|
-
const provider = input.provider ?? 'unknown';
|
|
464
|
-
const model = input.model ?? 'unknown';
|
|
465
|
-
const contextWindowTokens = input.contextWindowTokens ?? 0;
|
|
466
|
-
const reservedOutputTokens = Math.max(
|
|
467
|
-
FUSION_CHILD_MIN_OUTPUT_RESERVE_TOKENS,
|
|
468
|
-
input.maxOutputTokens ?? 0,
|
|
469
|
-
);
|
|
470
|
-
try {
|
|
471
|
-
if (input.provider === undefined || input.model === undefined) {
|
|
472
|
-
throw new Error('active model is unavailable');
|
|
473
|
-
}
|
|
474
|
-
if (!Number.isSafeInteger(contextWindowTokens) || contextWindowTokens <= 0) {
|
|
475
|
-
throw new Error('active model context window is unavailable');
|
|
476
|
-
}
|
|
477
|
-
if (
|
|
478
|
-
input.maxOutputTokens === undefined ||
|
|
479
|
-
!Number.isSafeInteger(input.maxOutputTokens) ||
|
|
480
|
-
input.maxOutputTokens <= 0
|
|
481
|
-
) {
|
|
482
|
-
throw new Error('active model maximum output tokens are unavailable');
|
|
483
|
-
}
|
|
484
|
-
allowedInputTokens =
|
|
485
|
-
contextWindowTokens - reservedOutputTokens - FUSION_CHILD_SAFETY_RESERVE_TOKENS;
|
|
486
|
-
if (allowedInputTokens <= 0) {
|
|
487
|
-
throw new Error('active model has no safe provider input capacity');
|
|
488
|
-
}
|
|
489
|
-
const payloadText = JSON.stringify(input.payload);
|
|
490
|
-
if (payloadText === undefined) throw new Error('provider payload serialized to undefined');
|
|
491
|
-
payloadBytes = Buffer.from(payloadText, 'utf8');
|
|
492
|
-
const family = resolveTokenBudgetFamily({ provider, model });
|
|
493
|
-
estimatedInputTokens = estimateInputTokens({
|
|
494
|
-
family: family.family,
|
|
495
|
-
calibrationBacked: family.backed,
|
|
496
|
-
familyResolution: family.resolution,
|
|
497
|
-
allowedInputTokens,
|
|
498
|
-
scope: 'fusion',
|
|
499
|
-
segments: [knownJsonSegment(payloadText)],
|
|
500
|
-
}).tokens;
|
|
501
|
-
if (input.requestOrdinal > FUSION_CHILD_MAX_PROVIDER_REQUESTS) {
|
|
502
|
-
code = 'provider_request_limit';
|
|
503
|
-
message = `fusion child reached provider request ${String(input.requestOrdinal)}, exceeding the ${String(FUSION_CHILD_MAX_PROVIDER_REQUESTS)}-request execution limit`;
|
|
504
|
-
} else if (estimatedInputTokens > allowedInputTokens) {
|
|
505
|
-
code = 'provider_request_budget';
|
|
506
|
-
message = `fusion child blocked provider request ${String(input.requestOrdinal)} before transport: exact final payload is ${String(payloadBytes.length)} UTF-8 bytes (estimated <= ${String(estimatedInputTokens)} input tokens), exceeding ${String(allowedInputTokens)} allowed input tokens after reserving ${String(reservedOutputTokens)} model output + ${String(FUSION_CHILD_SAFETY_RESERVE_TOKENS)} safety from the ${String(contextWindowTokens)}-token context window`;
|
|
507
|
-
}
|
|
508
|
-
} catch (error) {
|
|
509
|
-
code = 'provider_payload_invalid';
|
|
510
|
-
message = `fusion child could not validate provider request ${String(input.requestOrdinal)}: ${error instanceof Error ? error.message : String(error)}`;
|
|
425
|
+
if (input.provider === undefined || input.model === undefined) {
|
|
426
|
+
return invalidFusionRuntimeRequest(input, 'active model is unavailable');
|
|
511
427
|
}
|
|
512
|
-
if (
|
|
428
|
+
if (input.requestOrdinal <= FUSION_CHILD_MAX_PROVIDER_REQUESTS) return undefined;
|
|
429
|
+
const serialized: unknown = JSON.stringify(input.payload);
|
|
430
|
+
if (typeof serialized !== 'string') {
|
|
431
|
+
return invalidFusionRuntimeRequest(input, 'provider payload serialized to a non-string value');
|
|
432
|
+
}
|
|
433
|
+
const payloadBytes = Buffer.from(serialized, 'utf8');
|
|
513
434
|
return {
|
|
514
435
|
schema_version: FUSION_RUNTIME_GUARD_SCHEMA_VERSION,
|
|
515
|
-
code,
|
|
516
|
-
provider,
|
|
517
|
-
model,
|
|
436
|
+
code: 'provider_request_limit',
|
|
437
|
+
provider: input.provider,
|
|
438
|
+
model: input.model,
|
|
518
439
|
request_ordinal: input.requestOrdinal,
|
|
519
440
|
tool_call_count: input.toolCallCount,
|
|
520
441
|
payload_bytes: payloadBytes.length,
|
|
521
442
|
payload_sha256: sha256(payloadBytes),
|
|
522
|
-
|
|
523
|
-
context_window_tokens: contextWindowTokens,
|
|
524
|
-
reserved_output_tokens: reservedOutputTokens,
|
|
525
|
-
safety_reserve_tokens: FUSION_CHILD_SAFETY_RESERVE_TOKENS,
|
|
526
|
-
allowed_input_tokens: allowedInputTokens,
|
|
527
|
-
message,
|
|
443
|
+
message: `fusion child reached provider request ${String(input.requestOrdinal)}, exceeding the ${String(FUSION_CHILD_MAX_PROVIDER_REQUESTS)}-request execution limit`,
|
|
528
444
|
};
|
|
529
445
|
}
|
|
530
446
|
|
|
531
447
|
export interface FusionRuntimeToolLimitEvaluationInput {
|
|
532
448
|
provider: string | undefined;
|
|
533
449
|
model: string | undefined;
|
|
534
|
-
contextWindowTokens: number | undefined;
|
|
535
|
-
maxOutputTokens: number | undefined;
|
|
536
450
|
requestOrdinal: number;
|
|
537
451
|
toolCallCount: number;
|
|
538
452
|
}
|
|
@@ -541,23 +455,6 @@ export function evaluateFusionRuntimeToolLimit(
|
|
|
541
455
|
input: FusionRuntimeToolLimitEvaluationInput,
|
|
542
456
|
): FusionRuntimeGuardRecord | undefined {
|
|
543
457
|
if (input.toolCallCount <= FUSION_CHILD_MAX_TOOL_CALLS) return undefined;
|
|
544
|
-
const contextWindowTokens =
|
|
545
|
-
input.contextWindowTokens !== undefined &&
|
|
546
|
-
Number.isSafeInteger(input.contextWindowTokens) &&
|
|
547
|
-
input.contextWindowTokens > 0
|
|
548
|
-
? input.contextWindowTokens
|
|
549
|
-
: 0;
|
|
550
|
-
const modelOutputTokens =
|
|
551
|
-
input.maxOutputTokens !== undefined &&
|
|
552
|
-
Number.isSafeInteger(input.maxOutputTokens) &&
|
|
553
|
-
input.maxOutputTokens > 0
|
|
554
|
-
? input.maxOutputTokens
|
|
555
|
-
: 0;
|
|
556
|
-
const reservedOutputTokens = Math.max(FUSION_CHILD_MIN_OUTPUT_RESERVE_TOKENS, modelOutputTokens);
|
|
557
|
-
const allowedInputTokens = Math.max(
|
|
558
|
-
0,
|
|
559
|
-
contextWindowTokens - reservedOutputTokens - FUSION_CHILD_SAFETY_RESERVE_TOKENS,
|
|
560
|
-
);
|
|
561
458
|
const emptyPayload = Buffer.alloc(0);
|
|
562
459
|
return {
|
|
563
460
|
schema_version: FUSION_RUNTIME_GUARD_SCHEMA_VERSION,
|
|
@@ -568,11 +465,6 @@ export function evaluateFusionRuntimeToolLimit(
|
|
|
568
465
|
tool_call_count: input.toolCallCount,
|
|
569
466
|
payload_bytes: 0,
|
|
570
467
|
payload_sha256: sha256(emptyPayload),
|
|
571
|
-
estimated_input_tokens: 0,
|
|
572
|
-
context_window_tokens: contextWindowTokens,
|
|
573
|
-
reserved_output_tokens: reservedOutputTokens,
|
|
574
|
-
safety_reserve_tokens: FUSION_CHILD_SAFETY_RESERVE_TOKENS,
|
|
575
|
-
allowed_input_tokens: allowedInputTokens,
|
|
576
468
|
message: `fusion child reached tool call ${String(input.toolCallCount)}, exceeding the ${String(FUSION_CHILD_MAX_TOOL_CALLS)}-call execution limit`,
|
|
577
469
|
};
|
|
578
470
|
}
|
|
@@ -773,8 +665,6 @@ export default function fusionChildExtension(pi: ExtensionAPI): void {
|
|
|
773
665
|
payload: event.payload,
|
|
774
666
|
provider: model?.provider,
|
|
775
667
|
model: model?.id,
|
|
776
|
-
contextWindowTokens: model?.contextWindow,
|
|
777
|
-
maxOutputTokens: model?.maxTokens,
|
|
778
668
|
requestOrdinal: providerRequestCount,
|
|
779
669
|
toolCallCount,
|
|
780
670
|
},
|
|
@@ -793,8 +683,6 @@ export default function fusionChildExtension(pi: ExtensionAPI): void {
|
|
|
793
683
|
payload: cacheNormalizedPayload,
|
|
794
684
|
provider: model?.provider,
|
|
795
685
|
model: model?.id,
|
|
796
|
-
contextWindowTokens: model?.contextWindow,
|
|
797
|
-
maxOutputTokens: model?.maxTokens,
|
|
798
686
|
requestOrdinal: providerRequestCount,
|
|
799
687
|
toolCallCount,
|
|
800
688
|
});
|
|
@@ -888,8 +776,6 @@ export default function fusionChildExtension(pi: ExtensionAPI): void {
|
|
|
888
776
|
const guard = evaluateFusionRuntimeToolLimit({
|
|
889
777
|
provider: model?.provider,
|
|
890
778
|
model: model?.id,
|
|
891
|
-
contextWindowTokens: model?.contextWindow,
|
|
892
|
-
maxOutputTokens: model?.maxTokens,
|
|
893
779
|
requestOrdinal: providerRequestCount,
|
|
894
780
|
toolCallCount,
|
|
895
781
|
});
|