@deepstrike/wasm 0.2.52 → 0.2.60
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 +15 -14
- package/dist/agent-ir.d.ts +81 -0
- package/dist/agent-ir.js +115 -0
- package/dist/agent.d.ts +140 -0
- package/dist/agent.js +34 -0
- package/dist/governance.d.ts +0 -25
- package/dist/governance.js +1 -53
- package/dist/index.d.ts +23 -8
- package/dist/index.js +11 -4
- package/dist/memory/durable.d.ts +13 -0
- package/dist/memory/durable.js +42 -0
- package/dist/memory/in-memory-store.d.ts +8 -6
- package/dist/memory/in-memory-store.js +8 -2
- package/dist/memory/index.d.ts +18 -2
- package/dist/providers/anthropic.d.ts +9 -0
- package/dist/providers/anthropic.js +12 -33
- package/dist/providers/content-policy.d.ts +16 -0
- package/dist/providers/content-policy.js +39 -0
- package/dist/providers/openai.d.ts +36 -17
- package/dist/providers/openai.js +86 -46
- package/dist/providers/provider-error.d.ts +22 -0
- package/dist/providers/provider-error.js +90 -0
- package/dist/providers/request-plan.d.ts +87 -0
- package/dist/providers/request-plan.js +153 -0
- package/dist/providers/stop-reason.d.ts +5 -0
- package/dist/providers/stop-reason.js +24 -0
- package/dist/runtime/canonical-kernel-step.d.ts +2 -5
- package/dist/runtime/canonical-kernel-step.js +40 -58
- package/dist/runtime/context-policy.d.ts +10 -12
- package/dist/runtime/context-policy.js +6 -8
- package/dist/runtime/durable-content.d.ts +44 -0
- package/dist/runtime/durable-content.js +119 -0
- package/dist/runtime/execution-plane.d.ts +2 -2
- package/dist/runtime/execution-plane.js +2 -2
- package/dist/runtime/kernel-event-log.js +0 -1
- package/dist/runtime/kernel-step.d.ts +1 -2
- package/dist/runtime/kernel-step.js +1 -1
- package/dist/runtime/provider-replay.d.ts +1 -1
- package/dist/runtime/provider-replay.js +12 -20
- package/dist/runtime/runner.d.ts +22 -18
- package/dist/runtime/runner.js +115 -55
- package/dist/runtime/session-log.d.ts +8 -1
- package/dist/runtime/session-repair.d.ts +1 -1
- package/dist/runtime/session-repair.js +1 -1
- package/dist/runtime/sha256.d.ts +2 -0
- package/dist/runtime/sha256.js +38 -0
- package/dist/runtime/sub-agent-orchestrator.d.ts +1 -1
- package/dist/runtime/sub-agent-orchestrator.js +3 -3
- package/dist/runtime/types/agent.d.ts +17 -7
- package/dist/runtime/types/agent.js +30 -4
- package/dist/runtime/workflow-control-flow.d.ts +0 -4
- package/dist/runtime/workflow-control-flow.js +0 -16
- package/dist/types.d.ts +58 -5
- package/package.json +2 -2
package/dist/runtime/runner.js
CHANGED
|
@@ -5,6 +5,7 @@ import { getKernel } from "./kernel.js";
|
|
|
5
5
|
import { CanonicalRunnerRuntime, canonicalKernelAction, canonicalKernelApply, canonicalKernelMaybeAction, canonicalStartAgent, canonicalStartWorkflow, sha256 as canonicalSha256, } from "./canonical-kernel-step.js";
|
|
6
6
|
import { peekProviderReplay, seedProviderReplayFromEvents } from "./provider-replay.js";
|
|
7
7
|
import { sanitizeReplayText } from "./replay-sanitize.js";
|
|
8
|
+
import { decodeDurableContent, decodeDurableToolResult, durableBlocksToToolOutput, toolOutputBlocksToDurable } from "./durable-content.js";
|
|
8
9
|
import { formatToolError } from "../tools/errors.js";
|
|
9
10
|
import { buildLlmCompletedEvent, buildRunTerminalEvent, buildWorkflowNodeCompletedEvent, buildWorkflowNodesSubmittedEvent, } from "./session-repair.js";
|
|
10
11
|
import { messageToKernelMessage, skillMetadataToKernel, taskUpdateToKernel, toolResultToKernel, toolSchemaToKernel, } from "./kernel-step.js";
|
|
@@ -12,24 +13,30 @@ import { agentRunSpecToKernel, MILESTONE_UNVERIFIED_REASON, milestoneCheckFail,
|
|
|
12
13
|
import { defaultSubAgentOrchestrator } from "./sub-agent-orchestrator.js";
|
|
13
14
|
import { extractJsonValue, schemaInstruction, schemaRetryInstruction, validateAgainstSchema, } from "./output-schema.js";
|
|
14
15
|
import { resolveReducer } from "./reducers.js";
|
|
15
|
-
import { loopInstruction, classifyInstruction, judgeGoal, dependencyOutputsNote,
|
|
16
|
+
import { loopInstruction, classifyInstruction, judgeGoal, dependencyOutputsNote, extractClassifyBranch, extractJudgeWinner, } from "./workflow-control-flow.js";
|
|
16
17
|
import { kernelObservationToSessionEvent } from "./kernel-event-log.js";
|
|
17
18
|
import { assertNativeProfile } from "./os-profile.js";
|
|
19
|
+
import { classifyProviderError, providerErrorEventFields } from "../providers/provider-error.js";
|
|
18
20
|
import { PayloadStore } from "./payload-store.js";
|
|
19
|
-
import {
|
|
21
|
+
import { contextPolicy, normalizeContextPolicy, } from "./context-policy.js";
|
|
22
|
+
import { createProviderRequestPlanForProvider, estimateProviderPromptTokens, measurementForPlan, recordPromptMeasurement, } from "../providers/request-plan.js";
|
|
20
23
|
export function schedulerPolicyToKernel(policy) {
|
|
21
24
|
const allowed = new Set([
|
|
22
|
-
"
|
|
25
|
+
"criticalPathWeight", "fanoutWeight", "ageWeight", "tokenCostWeight",
|
|
26
|
+
"deadlineWeight", "processPriorityWeight", "resourcePressureWeight", "budgetPressureWeight",
|
|
23
27
|
]);
|
|
24
28
|
const unknown = Object.keys(policy).filter(key => !allowed.has(key));
|
|
25
29
|
if (unknown.length > 0)
|
|
26
30
|
throw new TypeError(`unknown scheduler policy field(s): ${unknown.join(", ")}`);
|
|
27
31
|
return {
|
|
28
|
-
version: policy.version,
|
|
29
32
|
critical_path_weight: policy.criticalPathWeight,
|
|
30
33
|
fanout_weight: policy.fanoutWeight,
|
|
31
34
|
age_weight: policy.ageWeight,
|
|
32
35
|
token_cost_weight: policy.tokenCostWeight,
|
|
36
|
+
...(policy.deadlineWeight !== undefined ? { deadline_weight: policy.deadlineWeight } : {}),
|
|
37
|
+
...(policy.processPriorityWeight !== undefined ? { process_priority_weight: policy.processPriorityWeight } : {}),
|
|
38
|
+
...(policy.resourcePressureWeight !== undefined ? { resource_pressure_weight: policy.resourcePressureWeight } : {}),
|
|
39
|
+
...(policy.budgetPressureWeight !== undefined ? { budget_pressure_weight: policy.budgetPressureWeight } : {}),
|
|
33
40
|
};
|
|
34
41
|
}
|
|
35
42
|
function kernelReliabilityToKernel(policy) {
|
|
@@ -292,10 +299,10 @@ export class RuntimeRunner {
|
|
|
292
299
|
yield* this.execute(sessionId, start.run_id, start.goal, start.criteria, extensions, events, true, start.attachments);
|
|
293
300
|
}
|
|
294
301
|
async writeMemory(memory, sessionId) {
|
|
295
|
-
if (!this.opts.
|
|
302
|
+
if (!this.opts.memoryStore || !this.opts.agentId)
|
|
296
303
|
return;
|
|
297
304
|
try {
|
|
298
|
-
await this.opts.
|
|
305
|
+
await this.opts.memoryStore.put(this.opts.agentId, memory);
|
|
299
306
|
}
|
|
300
307
|
catch (cause) {
|
|
301
308
|
throw new Error(formatToolError(cause));
|
|
@@ -419,6 +426,7 @@ export class RuntimeRunner {
|
|
|
419
426
|
output: `permission denied: ${denyReason}`,
|
|
420
427
|
is_error: true,
|
|
421
428
|
error_kind: "governance_denied",
|
|
429
|
+
content: { blocks: [{ type: "text", text: `permission denied: ${denyReason}` }] },
|
|
422
430
|
}],
|
|
423
431
|
});
|
|
424
432
|
}
|
|
@@ -436,6 +444,12 @@ export class RuntimeRunner {
|
|
|
436
444
|
const ext = { ...this.opts.extensions, ...(extensions ?? {}) };
|
|
437
445
|
const providerState = this.opts.provider.createRunState?.();
|
|
438
446
|
let nextCompressedArchiveStart = nextArchivedSeqStart(priorEvents);
|
|
447
|
+
const recordedMeasurements = new Map();
|
|
448
|
+
for (const entry of priorEvents ?? []) {
|
|
449
|
+
if (entry.event.kind === "prompt_measured") {
|
|
450
|
+
recordedMeasurements.set(entry.event.measurement.requestFingerprint, entry.event.measurement);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
439
453
|
const providerPolicy = this.opts.provider.runtimePolicy?.() ?? {};
|
|
440
454
|
const effectiveMaxTurns = this.opts.maxTurns ?? providerPolicy.maxTurns ?? 25;
|
|
441
455
|
const effectiveTimeoutMs = this.opts.timeoutMs ?? providerPolicy.timeoutMs;
|
|
@@ -494,7 +508,7 @@ export class RuntimeRunner {
|
|
|
494
508
|
tool_ids: this.opts.stableCoreToolIds,
|
|
495
509
|
});
|
|
496
510
|
}
|
|
497
|
-
if (this.opts.
|
|
511
|
+
if (this.opts.memoryStore && this.opts.agentId) {
|
|
498
512
|
await this.commitKernelApply(runtime, this.pendingObservations, { kind: "set_memory_enabled", enabled: true });
|
|
499
513
|
}
|
|
500
514
|
if (this.opts.knowledgeSource) {
|
|
@@ -542,7 +556,7 @@ export class RuntimeRunner {
|
|
|
542
556
|
const output = toolResultByCallId.get(tc.id);
|
|
543
557
|
if (output && !this.knowledgePushedSkills.has(name)) {
|
|
544
558
|
this.knowledgePushedSkills.add(name);
|
|
545
|
-
// K1: keyed — the kernel-side
|
|
559
|
+
// K1: keyed — the kernel-side put is the authoritative dedup across wake replays.
|
|
546
560
|
this.pushKnowledge({ role: "system", content: output }, undefined, { key: `skill:${name}` });
|
|
547
561
|
}
|
|
548
562
|
}
|
|
@@ -565,15 +579,14 @@ export class RuntimeRunner {
|
|
|
565
579
|
const startTask = { goal, criteria };
|
|
566
580
|
let startRunSpec;
|
|
567
581
|
// P0-A: lower an explicit `runSpec`, the `allowedToolIds` ceiling, and/or the `baselineToolIds`
|
|
568
|
-
// pre-activation surface to the kernel run spec
|
|
569
|
-
//
|
|
582
|
+
// pre-activation surface to the kernel run spec. Every run has a run spec; an omitted baseline
|
|
583
|
+
// is the canonical minimal surface.
|
|
570
584
|
const allowedToolIds = this.opts.allowedToolIds;
|
|
571
585
|
const hasProfile = allowedToolIds !== undefined && allowedToolIds.length > 0;
|
|
572
586
|
// NOT the `length > 0` idiom above: `baselineToolIds: []` is the legitimate minimal surface
|
|
573
587
|
// (meta + stable-core only), so mere presence triggers the lowering.
|
|
574
|
-
const baselineToolIds = this.opts.baselineToolIds;
|
|
575
|
-
|
|
576
|
-
if (this.opts.runSpec || hasProfile || hasBaseline) {
|
|
588
|
+
const baselineToolIds = this.opts.baselineToolIds ?? this.opts.runSpec?.exposureBaseline ?? [];
|
|
589
|
+
{
|
|
577
590
|
const baseSpec = this.opts.runSpec ?? {
|
|
578
591
|
identity: { agentId: this.opts.agentId ?? "root", sessionId, isSubAgent: false },
|
|
579
592
|
role: "custom",
|
|
@@ -582,8 +595,7 @@ export class RuntimeRunner {
|
|
|
582
595
|
let spec = hasProfile
|
|
583
596
|
? { ...baseSpec, capabilityFilter: { ...baseSpec.capabilityFilter, allowedIds: allowedToolIds } }
|
|
584
597
|
: baseSpec;
|
|
585
|
-
|
|
586
|
-
spec = { ...spec, exposureBaseline: baselineToolIds };
|
|
598
|
+
spec = { ...spec, exposureBaseline: baselineToolIds };
|
|
587
599
|
startRunSpec = agentRunSpecToKernel(spec);
|
|
588
600
|
}
|
|
589
601
|
if (!resumeMidRun)
|
|
@@ -651,6 +663,43 @@ export class RuntimeRunner {
|
|
|
651
663
|
let turnCacheCreationTokens = 0;
|
|
652
664
|
let turnCacheReadBySlot;
|
|
653
665
|
let turnStopReason;
|
|
666
|
+
const providerPlan = createProviderRequestPlanForProvider(this.opts.provider, context, tools, ext);
|
|
667
|
+
let promptMeasurement = measurementForPlan(providerPlan, recordedMeasurements.get(providerPlan.fingerprint));
|
|
668
|
+
if (!promptMeasurement && !context.budgetOverflow) {
|
|
669
|
+
try {
|
|
670
|
+
const counted = this.opts.provider.countTokens
|
|
671
|
+
? await withTimeout(this.opts.provider.countTokens(context, tools, Object.keys(ext).length ? ext : undefined), 5_000)
|
|
672
|
+
: undefined;
|
|
673
|
+
promptMeasurement = recordPromptMeasurement(providerPlan, counted ?? {
|
|
674
|
+
inputTokens: estimateProviderPromptTokens(context, tools),
|
|
675
|
+
source: { kind: "heuristic" },
|
|
676
|
+
confidence: "low_confidence",
|
|
677
|
+
});
|
|
678
|
+
}
|
|
679
|
+
catch {
|
|
680
|
+
promptMeasurement = recordPromptMeasurement(providerPlan, {
|
|
681
|
+
inputTokens: estimateProviderPromptTokens(context, tools),
|
|
682
|
+
source: { kind: "heuristic" },
|
|
683
|
+
confidence: "low_confidence",
|
|
684
|
+
});
|
|
685
|
+
}
|
|
686
|
+
recordedMeasurements.set(providerPlan.fingerprint, promptMeasurement);
|
|
687
|
+
await this.opts.sessionLog.append(sessionId, { kind: "prompt_measured", turn: runtime.turn(), measurement: promptMeasurement });
|
|
688
|
+
}
|
|
689
|
+
const reservedPromptTokens = (this.opts.promptBudget?.promptOverheadTokens ?? 0)
|
|
690
|
+
+ (this.opts.promptBudget?.outputReserveTokens ?? 0)
|
|
691
|
+
+ (this.opts.promptBudget?.safetyMarginTokens ?? 0);
|
|
692
|
+
const measuredOverflow = promptMeasurement
|
|
693
|
+
&& promptMeasurement.source.kind !== "heuristic"
|
|
694
|
+
&& promptMeasurement.inputTokens + reservedPromptTokens > this.opts.maxTokens;
|
|
695
|
+
if (context.budgetOverflow || measuredOverflow) {
|
|
696
|
+
action = await this.commitKernelAction(runtime, this.pendingObservations, {
|
|
697
|
+
kind: "provider_error", effect_id: providerEffectId,
|
|
698
|
+
message: "provider-visible prompt exceeds the configured context budget",
|
|
699
|
+
error_kind: "context_overflow", retryable: false,
|
|
700
|
+
});
|
|
701
|
+
continue;
|
|
702
|
+
}
|
|
654
703
|
const abortSignal = this.abortController?.signal;
|
|
655
704
|
try {
|
|
656
705
|
for await (const evt of this.opts.provider.stream(context, tools, Object.keys(ext).length ? ext : undefined, providerState, abortSignal)) {
|
|
@@ -690,6 +739,8 @@ export class RuntimeRunner {
|
|
|
690
739
|
this.cancellationReason ??= "user";
|
|
691
740
|
}
|
|
692
741
|
else {
|
|
742
|
+
const descriptor = this.opts.provider.descriptor?.();
|
|
743
|
+
const providerError = classifyProviderError(descriptor?.provider ?? "unknown", err);
|
|
693
744
|
// Reactive recovery is now a kernel decision. Forward the raw provider error and
|
|
694
745
|
// dispatch whatever the kernel returns: `call_provider` to retry with a freshly
|
|
695
746
|
// compacted context, or `done` to terminate with an honest `ContextOverflow`. The
|
|
@@ -698,7 +749,8 @@ export class RuntimeRunner {
|
|
|
698
749
|
action = await this.commitKernelAction(runtime, this.pendingObservations, {
|
|
699
750
|
kind: "provider_error",
|
|
700
751
|
effect_id: providerEffectId,
|
|
701
|
-
message:
|
|
752
|
+
message: providerError.message,
|
|
753
|
+
...providerErrorEventFields(providerError),
|
|
702
754
|
});
|
|
703
755
|
// Withholding (query.ts parity): surface the raw provider error only when the kernel
|
|
704
756
|
// could NOT recover (it returned a terminal). On a recovered retry (`call_provider`)
|
|
@@ -706,7 +758,7 @@ export class RuntimeRunner {
|
|
|
706
758
|
// compaction archive via the loop-top appendObservations, and a terminal `done` exits
|
|
707
759
|
// through `isTerminal()`.
|
|
708
760
|
if (action.kind === "done") {
|
|
709
|
-
yield { type: "error", message:
|
|
761
|
+
yield { type: "error", message: providerError.message };
|
|
710
762
|
}
|
|
711
763
|
continue;
|
|
712
764
|
}
|
|
@@ -784,9 +836,9 @@ export class RuntimeRunner {
|
|
|
784
836
|
else if (action.kind === "persist_memory") {
|
|
785
837
|
let error;
|
|
786
838
|
try {
|
|
787
|
-
if (!this.opts.
|
|
788
|
-
throw new Error("WASM memory persistence requires
|
|
789
|
-
await this.opts.
|
|
839
|
+
if (!this.opts.memoryStore || !this.opts.agentId)
|
|
840
|
+
throw new Error("WASM memory persistence requires memoryStore and agentId");
|
|
841
|
+
await this.opts.memoryStore.put(this.opts.agentId, action.memory);
|
|
790
842
|
}
|
|
791
843
|
catch (cause) {
|
|
792
844
|
error = formatToolError(cause);
|
|
@@ -801,9 +853,9 @@ export class RuntimeRunner {
|
|
|
801
853
|
let hits = [];
|
|
802
854
|
let error;
|
|
803
855
|
try {
|
|
804
|
-
if (!this.opts.
|
|
805
|
-
throw new Error("WASM memory queries require
|
|
806
|
-
hits = await this.opts.
|
|
856
|
+
if (!this.opts.memoryStore || !this.opts.agentId)
|
|
857
|
+
throw new Error("WASM memory queries require memoryStore and agentId");
|
|
858
|
+
hits = await this.opts.memoryStore.search(this.opts.agentId, {
|
|
807
859
|
...action.query, top_k: action.requestedK,
|
|
808
860
|
});
|
|
809
861
|
}
|
|
@@ -820,7 +872,7 @@ export class RuntimeRunner {
|
|
|
820
872
|
// M3/M4: mirror the kernel's journaled recall lifecycle + surface promotion suggestions.
|
|
821
873
|
for (const obs of this.pendingObservations.slice(obsStart)) {
|
|
822
874
|
if (obs.kind === "memory_recalled" && obs.recalls?.length && this.opts.agentId) {
|
|
823
|
-
await this.opts.
|
|
875
|
+
await this.opts.memoryStore?.recordRecall?.(this.opts.agentId, obs.recalls);
|
|
824
876
|
}
|
|
825
877
|
if (obs.kind === "promotion_suggested" && obs.record_id) {
|
|
826
878
|
this.opts.onPromotionSuggested?.({ recordId: obs.record_id, recallCount: obs.recall_count ?? 0 });
|
|
@@ -888,7 +940,7 @@ export class RuntimeRunner {
|
|
|
888
940
|
agentId: this.opts.agentId,
|
|
889
941
|
memoryScope: this.opts.memoryScope,
|
|
890
942
|
skillContentMap: this.opts.skillContentMap,
|
|
891
|
-
|
|
943
|
+
memoryStore: this.opts.memoryStore,
|
|
892
944
|
knowledgeSource: this.opts.knowledgeSource,
|
|
893
945
|
onToolSuspend: this.opts.onToolSuspend,
|
|
894
946
|
onPermissionRequest: this.opts.onPermissionRequest,
|
|
@@ -1029,6 +1081,7 @@ export class RuntimeRunner {
|
|
|
1029
1081
|
output: r.output,
|
|
1030
1082
|
is_error: r.isError,
|
|
1031
1083
|
token_count: r.tokenCount,
|
|
1084
|
+
content: { blocks: toolOutputBlocksToDurable(r.contentParts?.length ? r.contentParts : [{ type: "text", text: r.output }]) },
|
|
1032
1085
|
})),
|
|
1033
1086
|
});
|
|
1034
1087
|
// Canonical provider-result reduction activates a successfully resolved `skill` call. The
|
|
@@ -1050,10 +1103,10 @@ export class RuntimeRunner {
|
|
|
1050
1103
|
if (!name)
|
|
1051
1104
|
continue;
|
|
1052
1105
|
// With a lease configured, skip the Set optimization: an expired-then-reloaded skill
|
|
1053
|
-
// must re-pin — only the kernel knows the lease state; its
|
|
1106
|
+
// must re-pin — only the kernel knows the lease state; its put dedupes anyway.
|
|
1054
1107
|
if (this.opts.skillLeaseTurns !== undefined || !this.knowledgePushedSkills.has(name)) {
|
|
1055
1108
|
this.knowledgePushedSkills.add(name);
|
|
1056
|
-
// K1: keyed `skill:<name>` — the kernel-side
|
|
1109
|
+
// K1: keyed `skill:<name>` — the kernel-side put dedupes across runner instances.
|
|
1057
1110
|
this.pushKnowledge({ role: "system", content: res.output }, undefined, { key: `skill:${name}` });
|
|
1058
1111
|
}
|
|
1059
1112
|
}
|
|
@@ -1071,7 +1124,6 @@ export class RuntimeRunner {
|
|
|
1071
1124
|
this.lastEntropySample = {
|
|
1072
1125
|
turn: obs.turn ?? 0,
|
|
1073
1126
|
score: obs.score ?? 0,
|
|
1074
|
-
scoreVersion: obs.score_version ?? 0,
|
|
1075
1127
|
rho: obs.rho ?? 0,
|
|
1076
1128
|
repeatPressure: obs.repeat_pressure ?? 0,
|
|
1077
1129
|
failureRate: obs.failure_rate ?? 0,
|
|
@@ -1201,7 +1253,7 @@ export class RuntimeRunner {
|
|
|
1201
1253
|
turnsUsed,
|
|
1202
1254
|
totalTokens,
|
|
1203
1255
|
}));
|
|
1204
|
-
if (this.opts.
|
|
1256
|
+
if (this.opts.memoryStore && this.opts.agentId) {
|
|
1205
1257
|
const newMsgs = runtime.drainNewMessages().map(m => ({
|
|
1206
1258
|
role: m.role,
|
|
1207
1259
|
content: m.content,
|
|
@@ -1218,9 +1270,9 @@ export class RuntimeRunner {
|
|
|
1218
1270
|
createdAtMs: sessionStart,
|
|
1219
1271
|
updatedAtMs: Date.now(),
|
|
1220
1272
|
};
|
|
1221
|
-
await this.opts.
|
|
1273
|
+
await this.opts.memoryStore.saveSession(completedSession);
|
|
1222
1274
|
if (this.opts.memoryScope) {
|
|
1223
|
-
const extracted = await extractSessionMemories(this.opts.
|
|
1275
|
+
const extracted = await extractSessionMemories(this.opts.memoryProvider ?? this.opts.provider, completedSession, this.opts.memoryScope, this.opts.memorySystemPrompt);
|
|
1224
1276
|
for (const memory of extracted)
|
|
1225
1277
|
await this.writeMemory(memory, sessionId);
|
|
1226
1278
|
}
|
|
@@ -1291,20 +1343,15 @@ export class RuntimeRunner {
|
|
|
1291
1343
|
const winnerId = winner === "right" ? node.judge_match.right : node.judge_match.left;
|
|
1292
1344
|
return withSignal(result, { tournamentWinner: winnerId });
|
|
1293
1345
|
}
|
|
1294
|
-
//
|
|
1346
|
+
// loop-control loop iteration: run the increment under the armed pacing trap (workflowNodeToSpec set
|
|
1295
1347
|
// `loopRound`, and the iteration resumes the loop's stable session — transcript-as-carry).
|
|
1296
|
-
//
|
|
1297
|
-
//
|
|
1298
|
-
// when no pace decision arrives (stub orchestrators, harness children), where no signal still
|
|
1299
|
-
// means "run to max_iters" (v1).
|
|
1348
|
+
// The kernel-adjudicated `pace` verb is the only continuation signal. Ending without a pace
|
|
1349
|
+
// decision completes the loop.
|
|
1300
1350
|
if (node.loop_max_iters != null) {
|
|
1301
1351
|
const iteration = Number(/-i(\d+)$/.exec(node.agent_id)?.[1] ?? "0");
|
|
1302
1352
|
const result = await orchestrator.run(mkCtx(`${baseSpec.goal}\n\n${loopInstruction(node.loop_max_iters, iteration)}`));
|
|
1303
1353
|
const pace = result.result.paceDecision;
|
|
1304
|
-
|
|
1305
|
-
return withSignal(result, { loopContinue: pace.action !== "stop" });
|
|
1306
|
-
const cont = extractLoopContinue(textOf(result));
|
|
1307
|
-
return cont === undefined ? result : withSignal(result, { loopContinue: cont });
|
|
1354
|
+
return withSignal(result, { loopContinue: pace?.action === "continue" });
|
|
1308
1355
|
}
|
|
1309
1356
|
// A#2 classify: run the classifier, then extract the chosen branch label (kernel prunes the rest).
|
|
1310
1357
|
if (node.classify_labels && node.classify_labels.length) {
|
|
@@ -1384,10 +1431,9 @@ export class RuntimeRunner {
|
|
|
1384
1431
|
const { kind: _govKind, ...governance } = governancePolicyToKernelEvent(governancePolicy);
|
|
1385
1432
|
const config = { governance };
|
|
1386
1433
|
if (this.opts.contextPolicy) {
|
|
1387
|
-
config.context_policy =
|
|
1434
|
+
config.context_policy = normalizeContextPolicy(contextPolicy(this.opts.contextPolicy));
|
|
1388
1435
|
}
|
|
1389
1436
|
config.signal_policy = {
|
|
1390
|
-
version: 1,
|
|
1391
1437
|
queue_max: signalPolicy.queueMax,
|
|
1392
1438
|
...(signalPolicy.ttlMs !== undefined ? { ttl_ms: signalPolicy.ttlMs } : {}),
|
|
1393
1439
|
...(signalPolicy.deadlineEscalation !== undefined
|
|
@@ -1429,11 +1475,6 @@ export class RuntimeRunner {
|
|
|
1429
1475
|
if (this.opts.criteriaGate !== undefined) {
|
|
1430
1476
|
config.criteria_gate = this.opts.criteriaGate;
|
|
1431
1477
|
}
|
|
1432
|
-
// P1: fail-closed dispatch selector (absent ⇒ kernel default "exposed"). "registered" is the
|
|
1433
|
-
// escape hatch back to permissive dispatch; the kernel rejects any other value.
|
|
1434
|
-
if (this.opts.toolDispatchGate !== undefined) {
|
|
1435
|
-
config.tool_dispatch_gate = this.opts.toolDispatchGate;
|
|
1436
|
-
}
|
|
1437
1478
|
// K2: knowledge budget ratio (absent ⇒ kernel default 0.25; 0 disables).
|
|
1438
1479
|
if (this.opts.knowledgeBudgetRatio !== undefined) {
|
|
1439
1480
|
config.knowledge_budget_ratio = this.opts.knowledgeBudgetRatio;
|
|
@@ -1744,7 +1785,7 @@ export class RuntimeRunner {
|
|
|
1744
1785
|
* re-fired after each sprint renewal (renewal drops the old history INCLUDING earlier memory
|
|
1745
1786
|
* hits). Errs-open throughout. */
|
|
1746
1787
|
async prefetchMemoryIntoHistory(runtime, phase) {
|
|
1747
|
-
if (!this.opts.
|
|
1788
|
+
if (!this.opts.memoryStore || !this.opts.agentId || !this.opts.memoryScope)
|
|
1748
1789
|
return;
|
|
1749
1790
|
// P10: recall is default-on (CC session-start recall) — with no hook configured,
|
|
1750
1791
|
// the goal itself is the query. preQueryMemory stays as the targeting override.
|
|
@@ -1756,7 +1797,7 @@ export class RuntimeRunner {
|
|
|
1756
1797
|
for (const q of queries ?? []) {
|
|
1757
1798
|
if (!q.query.trim())
|
|
1758
1799
|
continue;
|
|
1759
|
-
const hits = await this.opts.
|
|
1800
|
+
const hits = await this.opts.memoryStore.search(this.opts.agentId, q);
|
|
1760
1801
|
for (const hit of hits) {
|
|
1761
1802
|
lines.push(`[memory record_id=${hit.record.record_id} trust=${hit.record.provenance.trust} score=${hit.score.toFixed(3)}] ${hit.record.content}`);
|
|
1762
1803
|
}
|
|
@@ -1771,12 +1812,12 @@ export class RuntimeRunner {
|
|
|
1771
1812
|
catch { /* errs-open */ }
|
|
1772
1813
|
}
|
|
1773
1814
|
async archiveSemanticPageOut(archived, action) {
|
|
1774
|
-
if (!this.opts.
|
|
1815
|
+
if (!this.opts.memoryStore || !this.opts.agentId || !this.opts.memoryScope)
|
|
1775
1816
|
return;
|
|
1776
1817
|
try {
|
|
1777
|
-
const summary = this.opts.
|
|
1778
|
-
? await this.opts.
|
|
1779
|
-
: await summarizeForLongTermMemory(this.opts.
|
|
1818
|
+
const summary = this.opts.memorySummarizer
|
|
1819
|
+
? await this.opts.memorySummarizer.summarize(archived, { action })
|
|
1820
|
+
: await summarizeForLongTermMemory(this.opts.memoryProvider ?? this.opts.provider, archived, this.opts.memorySystemPrompt);
|
|
1780
1821
|
const now = Date.now();
|
|
1781
1822
|
const name = `page-out-${now}`;
|
|
1782
1823
|
await this.writeMemory({
|
|
@@ -1823,7 +1864,7 @@ function compressionAction(action) {
|
|
|
1823
1864
|
}
|
|
1824
1865
|
return undefined;
|
|
1825
1866
|
}
|
|
1826
|
-
async function replayMessages(events, maxBytes, archiveStore) {
|
|
1867
|
+
export async function replayMessages(events, maxBytes, archiveStore) {
|
|
1827
1868
|
// Build upgraded-summary index: compressed_seq -> upgraded summary
|
|
1828
1869
|
const upgradedSummaries = new Map();
|
|
1829
1870
|
for (const { event: e } of events) {
|
|
@@ -1893,10 +1934,16 @@ async function replayMessages(events, maxBytes, archiveStore) {
|
|
|
1893
1934
|
}
|
|
1894
1935
|
else if (e.kind === "tool_completed") {
|
|
1895
1936
|
for (const r of e.results) {
|
|
1937
|
+
const durable = decodeDurableToolResult({
|
|
1938
|
+
call_id: r.call_id,
|
|
1939
|
+
is_error: r.is_error ?? false,
|
|
1940
|
+
blocks: decodeDurableContent(r.content).blocks,
|
|
1941
|
+
});
|
|
1896
1942
|
messages.push({
|
|
1897
1943
|
role: "tool",
|
|
1898
|
-
content:
|
|
1944
|
+
content: "",
|
|
1899
1945
|
toolCalls: [],
|
|
1946
|
+
contentParts: [{ type: "tool_result", callId: durable.call_id, output: sanitizeReplayText(r.output, maxBytes), isError: durable.is_error, ...(durable.blocks.length ? { contentParts: durableBlocksToToolOutput(durable.blocks) } : {}) }],
|
|
1900
1947
|
tokenCount: r.token_count,
|
|
1901
1948
|
});
|
|
1902
1949
|
}
|
|
@@ -1926,6 +1973,19 @@ export async function collectText(stream) {
|
|
|
1926
1973
|
}
|
|
1927
1974
|
return text;
|
|
1928
1975
|
}
|
|
1976
|
+
async function withTimeout(promise, timeoutMs) {
|
|
1977
|
+
let timer;
|
|
1978
|
+
try {
|
|
1979
|
+
return await Promise.race([
|
|
1980
|
+
promise,
|
|
1981
|
+
new Promise((_, reject) => { timer = setTimeout(() => reject(new Error("provider token measurement timed out")), timeoutMs); }),
|
|
1982
|
+
]);
|
|
1983
|
+
}
|
|
1984
|
+
finally {
|
|
1985
|
+
if (timer !== undefined)
|
|
1986
|
+
clearTimeout(timer);
|
|
1987
|
+
}
|
|
1988
|
+
}
|
|
1929
1989
|
/** Parse `update_plan` meta-tool args into a task update (snake_case aliases accepted, mirroring
|
|
1930
1990
|
* the node/python runners). Malformed payload → an empty update (a no-op `update_task`). */
|
|
1931
1991
|
function parseUpdatePlanArgs(argsStr) {
|
|
@@ -2,6 +2,7 @@ import type { ProviderReplay, ToolCall, ToolErrorKind } from "../types.js";
|
|
|
2
2
|
import type { MemoryRecall, MemoryScope } from "../memory/index.js";
|
|
3
3
|
import type { KernelPrimitive } from "./kernel-event-log.js";
|
|
4
4
|
import type { KernelJournal } from "./kernel-journal.js";
|
|
5
|
+
import type { RecordedPromptMeasurement } from "../providers/request-plan.js";
|
|
5
6
|
export type RollbackReason = {
|
|
6
7
|
kind: "fatal_tool_error";
|
|
7
8
|
tool_name: string;
|
|
@@ -36,6 +37,10 @@ export type SessionEvent = {
|
|
|
36
37
|
token_count?: number;
|
|
37
38
|
tool_calls: ToolCall[];
|
|
38
39
|
provider_replay?: ProviderReplay;
|
|
40
|
+
} | {
|
|
41
|
+
kind: "prompt_measured";
|
|
42
|
+
turn: number;
|
|
43
|
+
measurement: RecordedPromptMeasurement;
|
|
39
44
|
} | {
|
|
40
45
|
kind: "tool_requested";
|
|
41
46
|
turn: number;
|
|
@@ -50,6 +55,9 @@ export type SessionEvent = {
|
|
|
50
55
|
is_fatal?: boolean;
|
|
51
56
|
error_kind?: ToolErrorKind;
|
|
52
57
|
token_count?: number;
|
|
58
|
+
content: {
|
|
59
|
+
blocks: Record<string, unknown>[];
|
|
60
|
+
};
|
|
53
61
|
}>;
|
|
54
62
|
} | {
|
|
55
63
|
kind: "tool_argument_repaired";
|
|
@@ -177,7 +185,6 @@ export type SessionEvent = {
|
|
|
177
185
|
kind: "entropy_sample";
|
|
178
186
|
turn: number;
|
|
179
187
|
score: number;
|
|
180
|
-
score_version: number;
|
|
181
188
|
rho: number;
|
|
182
189
|
repeat_pressure: number;
|
|
183
190
|
failure_rate: number;
|
|
@@ -6,7 +6,7 @@ export { REPLAY_CONTENT_MAX_BYTES as RECOVERY_CONTENT_MAX_BYTES } from "./replay
|
|
|
6
6
|
* Normalize a persisted llm_completed event for recovery. Content is sanitized
|
|
7
7
|
* and token_count backfilled, but the stored `provider_replay` envelope is
|
|
8
8
|
* passed through verbatim — this layer is provider-neutral and never
|
|
9
|
-
* synthesizes protocol-specific replay shapes.
|
|
9
|
+
* synthesizes protocol-specific replay shapes. Canonical replay seeding is the
|
|
10
10
|
* responsibility of the target provider's `seedProviderReplay`.
|
|
11
11
|
*/
|
|
12
12
|
export declare function normalizeLlmCompleted(event: Extract<SessionEvent, {
|
|
@@ -7,7 +7,7 @@ function estimateTokenCount(text) {
|
|
|
7
7
|
* Normalize a persisted llm_completed event for recovery. Content is sanitized
|
|
8
8
|
* and token_count backfilled, but the stored `provider_replay` envelope is
|
|
9
9
|
* passed through verbatim — this layer is provider-neutral and never
|
|
10
|
-
* synthesizes protocol-specific replay shapes.
|
|
10
|
+
* synthesizes protocol-specific replay shapes. Canonical replay seeding is the
|
|
11
11
|
* responsibility of the target provider's `seedProviderReplay`.
|
|
12
12
|
*/
|
|
13
13
|
export function normalizeLlmCompleted(event, maxBytes) {
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/** Small synchronous SHA-256 for Worker/browser hosts (no node:crypto). */
|
|
2
|
+
export function sha256Hex(value) {
|
|
3
|
+
const input = new TextEncoder().encode(value);
|
|
4
|
+
const bitLength = input.length * 8;
|
|
5
|
+
const length = ((input.length + 9 + 63) >> 6) << 6;
|
|
6
|
+
const data = new Uint8Array(length);
|
|
7
|
+
data.set(input);
|
|
8
|
+
data[input.length] = 0x80;
|
|
9
|
+
new DataView(data.buffer).setUint32(length - 4, bitLength >>> 0, false);
|
|
10
|
+
const h = new Uint32Array([0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19]);
|
|
11
|
+
const k = [0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2];
|
|
12
|
+
const ror = (x, n) => (x >>> n) | (x << (32 - n));
|
|
13
|
+
for (let offset = 0; offset < data.length; offset += 64) {
|
|
14
|
+
const w = new Uint32Array(64);
|
|
15
|
+
const view = new DataView(data.buffer, offset, 64);
|
|
16
|
+
for (let i = 0; i < 16; i++)
|
|
17
|
+
w[i] = view.getUint32(i * 4, false);
|
|
18
|
+
for (let i = 16; i < 64; i++) {
|
|
19
|
+
w[i] = (w[i - 16] + (ror(w[i - 15], 7) ^ ror(w[i - 15], 18) ^ (w[i - 15] >>> 3)) + w[i - 7] + (ror(w[i - 2], 17) ^ ror(w[i - 2], 19) ^ (w[i - 2] >>> 10))) >>> 0;
|
|
20
|
+
}
|
|
21
|
+
let [a, b, c, d, e, f, g, hh] = h;
|
|
22
|
+
for (let i = 0; i < 64; i++) {
|
|
23
|
+
const t1 = (hh + (ror(e, 6) ^ ror(e, 11) ^ ror(e, 25)) + ((e & f) ^ ((~e) & g)) + k[i] + w[i]) >>> 0;
|
|
24
|
+
const t2 = ((ror(a, 2) ^ ror(a, 13) ^ ror(a, 22)) + ((a & b) ^ (a & c) ^ (b & c))) >>> 0;
|
|
25
|
+
hh = g;
|
|
26
|
+
g = f;
|
|
27
|
+
f = e;
|
|
28
|
+
e = (d + t1) >>> 0;
|
|
29
|
+
d = c;
|
|
30
|
+
c = b;
|
|
31
|
+
b = a;
|
|
32
|
+
a = (t1 + t2) >>> 0;
|
|
33
|
+
}
|
|
34
|
+
for (let i = 0; i < 8; i++)
|
|
35
|
+
h[i] = (h[i] + [a, b, c, d, e, f, g, hh][i]) >>> 0;
|
|
36
|
+
}
|
|
37
|
+
return `sha256:${Array.from(h, word => word.toString(16).padStart(8, "0")).join("")}`;
|
|
38
|
+
}
|
|
@@ -7,7 +7,7 @@ export interface SubAgentRunContext {
|
|
|
7
7
|
spec: AgentRunSpec;
|
|
8
8
|
manifest: AgentProcessChangedObservation;
|
|
9
9
|
sessionLog: SessionLog;
|
|
10
|
-
/**
|
|
10
|
+
/** workflow-node: set when this child is a workflow node — propagated so a nested `start_workflow`
|
|
11
11
|
* FLATTENS to the parent kernel rather than auto-pivoting into its own bootstrap. */
|
|
12
12
|
isWorkflowNode?: boolean;
|
|
13
13
|
/** W-N1 tool exposure. The kernel omits an EMPTY `permitted_capability_ids` on the wire, so a
|
|
@@ -39,7 +39,7 @@ function deriveMetaTools(permitted, opts) {
|
|
|
39
39
|
const metaTools = new Set();
|
|
40
40
|
if (permitted.has("skill") && opts.skillContentMap?.size)
|
|
41
41
|
metaTools.add("skill");
|
|
42
|
-
if (permitted.has("memory") && opts.
|
|
42
|
+
if (permitted.has("memory") && opts.memoryStore)
|
|
43
43
|
metaTools.add("memory");
|
|
44
44
|
if (permitted.has("knowledge") && opts.knowledgeSource)
|
|
45
45
|
metaTools.add("knowledge");
|
|
@@ -53,7 +53,7 @@ function availableMetaTools(opts) {
|
|
|
53
53
|
const metaTools = new Set();
|
|
54
54
|
if (opts.skillContentMap?.size)
|
|
55
55
|
metaTools.add("skill");
|
|
56
|
-
if (opts.
|
|
56
|
+
if (opts.memoryStore)
|
|
57
57
|
metaTools.add("memory");
|
|
58
58
|
if (opts.knowledgeSource)
|
|
59
59
|
metaTools.add("knowledge");
|
|
@@ -116,7 +116,7 @@ export class SubAgentOrchestrator {
|
|
|
116
116
|
systemPrompt,
|
|
117
117
|
sessionLog: ctx.sessionLog,
|
|
118
118
|
skillContentMap: metaTools.has("skill") ? ctx.parentOpts.skillContentMap : undefined,
|
|
119
|
-
|
|
119
|
+
memoryStore: metaTools.has("memory") ? ctx.parentOpts.memoryStore : undefined,
|
|
120
120
|
knowledgeSource: metaTools.has("knowledge") ? ctx.parentOpts.knowledgeSource : undefined,
|
|
121
121
|
enablePlanTool: metaTools.has("update_plan") ? ctx.parentOpts.enablePlanTool : undefined,
|
|
122
122
|
// The child runs under ITS OWN spec, never the parent's: the spread above would otherwise
|
|
@@ -45,7 +45,7 @@ export interface AgentRunSpec {
|
|
|
45
45
|
* The ceiling bounds what this run may EVER expose; the baseline selects which of those are
|
|
46
46
|
* advertised before any skill activates, so `exposed = meta ∪ ((baseline ∪ stableCore ∪
|
|
47
47
|
* ⋃ activeSkills.allowed_tools) ∩ ceiling)`. That makes narrow→wide progressive disclosure
|
|
48
|
-
* expressible. Absent
|
|
48
|
+
* expressible. Absent and `[]` both mean the minimal
|
|
49
49
|
* surface (meta-tools + stable-core only). Entries outside the ceiling silently intersect away.
|
|
50
50
|
* Lowered from `RuntimeOptions.baselineToolIds`. */
|
|
51
51
|
exposureBaseline?: string[];
|
|
@@ -84,7 +84,7 @@ export interface LoopResult {
|
|
|
84
84
|
finalMessage?: Message;
|
|
85
85
|
turnsUsed: number;
|
|
86
86
|
totalTokensUsed: number;
|
|
87
|
-
/**
|
|
87
|
+
/** loop-control loop stop signal: a loop iteration sets `false` to end the loop before `max_iters`.
|
|
88
88
|
* `undefined` (every non-loop result) ⇒ no opinion → run to the cap. Sent only when set. */
|
|
89
89
|
loopContinue?: boolean;
|
|
90
90
|
/** A#2 classify routing: a classifier node reports the chosen branch label here; the kernel runs
|
|
@@ -94,7 +94,7 @@ export interface LoopResult {
|
|
|
94
94
|
tournamentWinner?: string;
|
|
95
95
|
/** ③ loop-agent pacing: the kernel-adjudicated after-round decision, surfaced by the orchestrator
|
|
96
96
|
* from the child's done event. For a loop-node iteration this is the PRIMARY continuation
|
|
97
|
-
* vocabulary (stop → loopContinue=false)
|
|
97
|
+
* vocabulary (stop → loopContinue=false).
|
|
98
98
|
* SDK-internal — stripped by `subAgentResultToKernel`. */
|
|
99
99
|
paceDecision?: import("../kernel-step.js").PaceDecision;
|
|
100
100
|
}
|
|
@@ -149,6 +149,14 @@ export type WorkflowTaskSpec = {
|
|
|
149
149
|
export type NodeTrust = "trusted" | "quarantined";
|
|
150
150
|
export type WorkflowDependencyPolicy = "all_success" | "accept_partial" | "all_terminal" | "optional";
|
|
151
151
|
export type WorkflowNodeStatus = "completed" | "completed_partial" | "failed" | "skipped_upstream_failed";
|
|
152
|
+
/** Host-observed, deterministic scheduling inputs for one workflow node. They never originate
|
|
153
|
+
* from model-authored workflow tools. */
|
|
154
|
+
export interface SchedulingFactors {
|
|
155
|
+
deadlineUrgency?: number;
|
|
156
|
+
processPriority?: number;
|
|
157
|
+
resourcePressure?: number;
|
|
158
|
+
budgetPressure?: number;
|
|
159
|
+
}
|
|
152
160
|
export declare function workflowNodeStatusFromTermination(termination: TerminationReason | string): WorkflowNodeStatus;
|
|
153
161
|
export interface WorkflowNodeSpec {
|
|
154
162
|
task: WorkflowTaskSpec;
|
|
@@ -163,7 +171,7 @@ export interface WorkflowNodeSpec {
|
|
|
163
171
|
/** G2: make this a deterministic reduce node — runs no LLM; the runner routes it to the registered
|
|
164
172
|
* reducer of this name over its `dependsOn` nodes' outputs. */
|
|
165
173
|
reducer?: string;
|
|
166
|
-
/**
|
|
174
|
+
/** loop-control: make this a *loop* node — re-run its agent up to `maxIters` times. An iteration may end
|
|
167
175
|
* the loop early by reporting `loopContinue: false` (the runner solicits this from the agent). */
|
|
168
176
|
loop?: {
|
|
169
177
|
maxIters: number;
|
|
@@ -187,6 +195,8 @@ export interface WorkflowNodeSpec {
|
|
|
187
195
|
maxTurns?: number;
|
|
188
196
|
/** O3: cap this node's child run at `maxWallMs` wall-clock milliseconds. */
|
|
189
197
|
maxWallMs?: number;
|
|
198
|
+
/** Host-only scheduling facts used with the configured deterministic scheduler policy. */
|
|
199
|
+
schedulingFactors?: SchedulingFactors;
|
|
190
200
|
/** Indices of nodes this node depends on. */
|
|
191
201
|
dependsOn?: number[];
|
|
192
202
|
/** How dependency terminal states gate this node. Defaults to `all_success`. */
|
|
@@ -251,7 +261,7 @@ export interface WorkflowSpawnInfo {
|
|
|
251
261
|
left: string;
|
|
252
262
|
right: string;
|
|
253
263
|
};
|
|
254
|
-
/**
|
|
264
|
+
/** loop-control: present only for a *loop* iteration spawn — the loop's `max_iters`. Marks the spawn as a
|
|
255
265
|
* loop iteration so the runner solicits + reports a `loopContinue` stop signal. */
|
|
256
266
|
loop_max_iters?: number;
|
|
257
267
|
/** A#2: present only for a *classify* spawn — the branch labels the classifier must choose among.
|
|
@@ -286,9 +296,9 @@ export declare function workflowBudgetNote(budget: WorkflowBudget | undefined):
|
|
|
286
296
|
export declare function workflowNodeSpecToKernel(n: WorkflowNodeSpec): Record<string, unknown>;
|
|
287
297
|
export declare function workflowSpecToKernel(spec: WorkflowSpec): Record<string, unknown>;
|
|
288
298
|
export declare const submitWorkflowNodesTool: ToolSchema;
|
|
289
|
-
/**
|
|
299
|
+
/** workflow authoring: the tool an agent calls to author a sub-workflow — a cohesive DAG of nodes
|
|
290
300
|
* composed onto the running workflow. Lowers to the same append path as `submit_workflow_nodes`
|
|
291
|
-
* (a `WorkflowSpec` is a node batch).
|
|
301
|
+
* (a `WorkflowSpec` is a node batch). Top-level bootstrap uses (the `LoadWorkflow` syscall). */
|
|
292
302
|
export declare const startWorkflowTool: ToolSchema;
|
|
293
303
|
/** Build a sub-agent run spec for a kernel-generated workflow node. */
|
|
294
304
|
export declare function workflowNodeToSpec(node: WorkflowSpawnInfo, parentSessionId: string): AgentRunSpec;
|