@kontourai/flow-agents 3.8.0 → 3.10.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/.github/workflows/ci.yml +8 -0
- package/CHANGELOG.md +24 -0
- package/README.md +1 -1
- package/build/src/builder-flow-runtime.js +16 -10
- package/build/src/cli/assignment-provider.js +4 -18
- package/build/src/cli/continuation-adapter.d.ts +26 -0
- package/build/src/cli/continuation-adapter.js +243 -0
- package/build/src/cli/validate-workflow-artifacts.js +21 -1
- package/build/src/cli/workflow-sidecar.js +15 -20
- package/build/src/cli/workflow.js +99 -6
- package/build/src/continuation-driver.d.ts +116 -0
- package/build/src/continuation-driver.js +527 -0
- package/build/src/index.d.ts +2 -0
- package/build/src/index.js +1 -0
- package/build/src/tools/build-universal-bundles.js +52 -25
- package/build/src/tools/validate-source-tree.js +5 -2
- package/context/scripts/hooks/lib/continuation-turn-authority.js +386 -0
- package/context/scripts/hooks/stop-goal-fit.js +244 -73
- package/context/scripts/hooks/workflow-steering.js +24 -15
- package/context/scripts/telemetry/lib/pricing.sh +18 -6
- package/context/scripts/telemetry/lib/transport.sh +139 -37
- package/context/scripts/telemetry/lib/usage.sh +282 -32
- package/context/scripts/telemetry/lib/usage_model_guard.sh +42 -0
- package/context/scripts/telemetry/telemetry.sh +76 -1
- package/docs/coordination-guide.md +21 -5
- package/docs/fixture-ownership.md +2 -1
- package/docs/public-workflow-cli.md +98 -0
- package/docs/spec/runtime-hook-surface.md +8 -4
- package/docs/workflow-usage-guide.md +7 -0
- package/evals/acceptance/prove-capture-teeth-declared.sh +13 -0
- package/evals/acceptance/prove-capture-teeth.sh +13 -0
- package/evals/ci/run-baseline.sh +2 -0
- package/evals/fixtures/codex-legacy-agents/5273878130bdafc8a024a650bb5b66c9b003f1f859b5dc6e5b588cbf4ab23228.md +25 -0
- package/evals/fixtures/telemetry/usage-transcript-adversarial.jsonl +2 -0
- package/evals/fixtures/telemetry/usage-transcript-malformed-sandwich.jsonl +3 -0
- package/evals/fixtures/telemetry/usage-transcript-negative-tokens.jsonl +1 -0
- package/evals/fixtures/telemetry/usage-transcript-oversized-prefix.jsonl +201 -0
- package/evals/fixtures/telemetry/usage-transcript-oversized-tokens.jsonl +1 -0
- package/evals/fixtures/telemetry/usage-transcript-prefixed-secret-lower.jsonl +1 -0
- package/evals/fixtures/telemetry/usage-transcript-prefixed-secret-upper.jsonl +1 -0
- package/evals/fixtures/telemetry/usage-transcript-secret-model-jwt.jsonl +1 -0
- package/evals/fixtures/telemetry/usage-transcript-secret-model.jsonl +1 -0
- package/evals/fixtures/telemetry/usage-transcript-torn-trailing.jsonl +2 -0
- package/evals/integration/test_actor_identity.sh +63 -0
- package/evals/integration/test_assignment_provider_local_file.sh +34 -0
- package/evals/integration/test_builder_entry_enforcement.sh +5 -1
- package/evals/integration/test_bundle_install.sh +106 -17
- package/evals/integration/test_bundle_lifecycle.sh +17 -3
- package/evals/integration/test_captured_fail_reconciliation.sh +11 -0
- package/evals/integration/test_ci_actor_identity.sh +2 -2
- package/evals/integration/test_command_log_concurrency.sh +11 -0
- package/evals/integration/test_command_log_fork_classification.sh +11 -0
- package/evals/integration/test_command_log_integrity.sh +11 -0
- package/evals/integration/test_current_json_per_actor.sh +416 -21
- package/evals/integration/test_enforcer_expects_driven.sh +11 -0
- package/evals/integration/test_ensure_session_ownership_guard.sh +39 -0
- package/evals/integration/test_evidence_capture_hook.sh +25 -6
- package/evals/integration/test_fixture_retirement_audit.sh +2 -2
- package/evals/integration/test_flowdef_union_floor_regression.sh +11 -0
- package/evals/integration/test_gate_bypass_chain.sh +11 -0
- package/evals/integration/test_gate_lockdown.sh +10 -0
- package/evals/integration/test_goal_fit_ghost_session.sh +11 -0
- package/evals/integration/test_goal_fit_hook.sh +257 -9
- package/evals/integration/test_goal_fit_rederive.sh +11 -0
- package/evals/integration/test_install_merge.sh +141 -3
- package/evals/integration/test_liveness_conflict_injection.sh +39 -3
- package/evals/integration/test_liveness_heartbeat.sh +46 -9
- package/evals/integration/test_phase_map_and_gate_claim.sh +10 -1
- package/evals/integration/test_public_workflow_cli.sh +6 -6
- package/evals/integration/test_session_resume_roundtrip.sh +30 -0
- package/evals/integration/test_stop_hook_release.sh +111 -11
- package/evals/integration/test_telemetry_tool_usage.sh +394 -0
- package/evals/integration/test_verify_hold.sh +64 -1
- package/evals/integration/test_workflow_sidecar_writer.sh +10 -1
- package/evals/integration/test_workflow_steering_hook.sh +20 -4
- package/evals/run.sh +2 -0
- package/evals/static/test_universal_bundles.sh +123 -0
- package/package.json +4 -4
- package/packaging/README.md +21 -0
- package/packaging/codex-legacy-agents-fingerprints.json +33 -0
- package/scripts/README.md +2 -1
- package/scripts/audit-codex-legacy-agents.js +43 -0
- package/scripts/classify-codex-legacy-agents.js +71 -0
- package/scripts/hooks/evidence-capture.js +18 -6
- package/scripts/hooks/lib/actor-identity.js +62 -29
- package/scripts/hooks/lib/continuation-turn-authority.js +386 -0
- package/scripts/hooks/lib/current-pointer.js +114 -12
- package/scripts/hooks/lib/liveness-heartbeat.js +15 -12
- package/scripts/hooks/stop-goal-fit.js +244 -73
- package/scripts/hooks/workflow-steering.js +24 -15
- package/scripts/install-codex-home.sh +8 -7
- package/scripts/telemetry/lib/pricing.sh +18 -6
- package/scripts/telemetry/lib/transport.sh +71 -0
- package/scripts/telemetry/lib/usage.sh +282 -32
- package/scripts/telemetry/lib/usage_model_guard.sh +42 -0
- package/scripts/telemetry/telemetry.sh +76 -1
- package/src/builder-flow-runtime.ts +9 -3
- package/src/cli/assignment-provider.ts +5 -26
- package/src/cli/builder-flow-runtime.test.mjs +215 -2
- package/src/cli/continuation-adapter.ts +265 -0
- package/src/cli/continuation-driver.test.mjs +1303 -0
- package/src/cli/public-api.test.mjs +1 -0
- package/src/cli/validate-workflow-artifacts.ts +19 -1
- package/src/cli/workflow-sidecar.ts +18 -23
- package/src/cli/workflow.ts +113 -6
- package/src/continuation-driver.ts +638 -0
- package/src/index.ts +24 -0
- package/src/tools/build-universal-bundles.ts +61 -25
- package/src/tools/validate-source-tree.ts +5 -2
|
@@ -6,6 +6,7 @@ import { isDeepStrictEqual } from "node:util";
|
|
|
6
6
|
import { fileURLToPath } from "node:url";
|
|
7
7
|
import { validateDefinition } from "@kontourai/flow";
|
|
8
8
|
import { loadBuilderFlowRun } from "../builder-flow-run-adapter.js";
|
|
9
|
+
import { driveBuilderFlowSession, withContinuationDriverLock } from "../continuation-driver.js";
|
|
9
10
|
import { inspectBuilderFlowSession, recoverBuilderFlowSession, syncBuilderFlowSession } from "../builder-flow-runtime.js";
|
|
10
11
|
import { flowAgentsPackageRoot, flowAgentsPackageVersion } from "../lib/package-version.js";
|
|
11
12
|
import { pinnedFlowAgentsCommand } from "../lib/pinned-cli-command.js";
|
|
@@ -14,12 +15,13 @@ import { flagBool, flagList, flagString, parseArgs } from "../lib/args.js";
|
|
|
14
15
|
import { main as builderRun } from "./builder-run.js";
|
|
15
16
|
import { currentWorkflowSessionDir, isMeaningfulTestCommand, mainFromPublicWorkflow, WORKFLOW_WRITER_CONTRACT_VERSION } from "./workflow-sidecar.js";
|
|
16
17
|
import { resolveCurrentAssignmentActor, withSubjectLock } from "./assignment-provider.js";
|
|
18
|
+
import { assertLoadedContinuationAdapterIntegrity, executeLoadedContinuationAdapter, loadContinuationAdapterCommand, waitForContinuationBarrier } from "./continuation-adapter.js";
|
|
17
19
|
export const WORKFLOW_CONTRACT_VERSION = "1.0";
|
|
18
20
|
const PACKAGE_ROOT = flowAgentsPackageRoot();
|
|
19
21
|
const REQUIRE = createRequire(import.meta.url);
|
|
20
22
|
const PACKAGE_METADATA = readJsonFile(path.join(PACKAGE_ROOT, "package.json"), "Flow Agents package metadata");
|
|
21
23
|
const CLI_VERSION = flowAgentsPackageVersion();
|
|
22
|
-
const PUBLIC_VERBS = ["start", "status", "evidence", "critique", "pause", "resume", "release", "cancel", "archive", "doctor"];
|
|
24
|
+
const PUBLIC_VERBS = ["start", "status", "evidence", "critique", "drive", "pause", "resume", "release", "cancel", "archive", "doctor"];
|
|
23
25
|
function usage() {
|
|
24
26
|
console.log(`Usage: flow-agents workflow <verb> [options]
|
|
25
27
|
|
|
@@ -28,6 +30,7 @@ Public workflow verbs:
|
|
|
28
30
|
status Show the current canonical run and projected next action.
|
|
29
31
|
evidence Record evidence for the current Flow gate and synchronize it.
|
|
30
32
|
critique Record review critique directly into the current trust bundle.
|
|
33
|
+
drive Continue the canonical run through an explicit runtime adapter.
|
|
31
34
|
pause Pause the current run as its assignment actor.
|
|
32
35
|
resume Resume the current paused run as its assignment actor.
|
|
33
36
|
release Release the current assignment without canceling the run.
|
|
@@ -60,11 +63,69 @@ export async function main(argv) {
|
|
|
60
63
|
return evidence(sessionDir, argv.slice(1), flagBool(parsed.flags, "json"));
|
|
61
64
|
if (verb === "critique")
|
|
62
65
|
return critique(sessionDir, argv.slice(1), flagBool(parsed.flags, "json"));
|
|
66
|
+
if (verb === "drive")
|
|
67
|
+
return drive(sessionDir, argv.slice(1), flagBool(parsed.flags, "json"));
|
|
63
68
|
const forwarded = stripPublicFlags(argv.slice(1), new Set(["artifact-root", "session-dir", "json"]));
|
|
64
69
|
if (verb === "release" && !flagString(parsed.flags, "reason"))
|
|
65
70
|
throw new Error("workflow release requires --reason <text>");
|
|
66
71
|
return builderRun([verb === "release" ? "release-assignment" : verb, "--session-dir", sessionDir, ...forwarded]);
|
|
67
72
|
}
|
|
73
|
+
async function drive(sessionDir, argv, json) {
|
|
74
|
+
const parsed = parseArgs(argv);
|
|
75
|
+
assertOnlyFlags(parsed.flags, new Set(["artifact-root", "session-dir", "json", "adapter-command-file", "max-turns", "turn-timeout-ms", "barrier-wait-ms", "barrier-poll-ms"]), "workflow drive");
|
|
76
|
+
const adapterCommandFile = flagString(parsed.flags, "adapter-command-file");
|
|
77
|
+
if (!adapterCommandFile)
|
|
78
|
+
throw new Error("workflow drive requires --adapter-command-file <path>");
|
|
79
|
+
const maxTurns = integerFlag(parsed.flags, "max-turns", 4, 1, 100);
|
|
80
|
+
const turnTimeoutMs = integerFlag(parsed.flags, "turn-timeout-ms", 900_000, 1, 86_400_000);
|
|
81
|
+
const barrierWaitMs = integerFlag(parsed.flags, "barrier-wait-ms", 300_000, 0, 86_400_000);
|
|
82
|
+
const barrierPollMs = integerFlag(parsed.flags, "barrier-poll-ms", 1_000, 1, 60_000);
|
|
83
|
+
const { slug, projectRoot } = readBoundSession(sessionDir);
|
|
84
|
+
assertOrdinaryMatchingAssignmentActor(sessionDir, slug);
|
|
85
|
+
const adapterCommand = loadContinuationAdapterCommand(adapterCommandFile);
|
|
86
|
+
const result = await withContinuationDriverLock(sessionDir, async (lock) => {
|
|
87
|
+
assertOrdinaryMatchingAssignmentActor(sessionDir, slug);
|
|
88
|
+
return driveBuilderFlowSession({
|
|
89
|
+
sessionDir,
|
|
90
|
+
maxTurns,
|
|
91
|
+
adapterCommandIdentity: adapterCommand.identity,
|
|
92
|
+
authorizeTurn: async () => { assertOrdinaryMatchingAssignmentActor(sessionDir, slug); },
|
|
93
|
+
issueTurnAuthority: async (request) => {
|
|
94
|
+
const currentAssignment = assertOrdinaryMatchingAssignmentActor(sessionDir, slug);
|
|
95
|
+
assertLoadedContinuationAdapterIntegrity(adapterCommand);
|
|
96
|
+
const authority = loadContinuationTurnAuthority();
|
|
97
|
+
return authority.issueActiveTurnAuthority({
|
|
98
|
+
sessionDir,
|
|
99
|
+
runId: request.run_id,
|
|
100
|
+
definitionId: request.definition_id,
|
|
101
|
+
currentStep: request.current_step,
|
|
102
|
+
iteration: request.iteration,
|
|
103
|
+
maxTurns: request.max_turns,
|
|
104
|
+
adapterCommandIdentity: adapterCommand.identity,
|
|
105
|
+
assignmentActor: currentAssignment.actorKey,
|
|
106
|
+
assignmentActorStruct: currentAssignment.actor,
|
|
107
|
+
lock,
|
|
108
|
+
timeoutMs: turnTimeoutMs,
|
|
109
|
+
});
|
|
110
|
+
},
|
|
111
|
+
execute: async (request, context) => executeLoadedContinuationAdapter(adapterCommand, request, {
|
|
112
|
+
cwd: projectRoot,
|
|
113
|
+
timeoutMs: turnTimeoutMs,
|
|
114
|
+
continuationTurnSecret: context?.continuationTurnSecret,
|
|
115
|
+
continuationRunId: context?.continuationRunId,
|
|
116
|
+
}),
|
|
117
|
+
waitForBarrier: async (barrier) => waitForContinuationBarrier(barrier, { maxWaitMs: barrierWaitMs, pollMs: barrierPollMs }),
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
if (json)
|
|
121
|
+
console.log(JSON.stringify(result));
|
|
122
|
+
else
|
|
123
|
+
console.log(`Continuation driver ${result.outcome} after ${result.turns_started} turn(s); canonical Flow is ${result.snapshot.status} at ${result.snapshot.current_step}.`);
|
|
124
|
+
return 0;
|
|
125
|
+
}
|
|
126
|
+
function loadContinuationTurnAuthority() {
|
|
127
|
+
return REQUIRE(path.resolve(PACKAGE_ROOT, "scripts", "hooks", "lib", "continuation-turn-authority.js"));
|
|
128
|
+
}
|
|
68
129
|
async function start(argv) {
|
|
69
130
|
const parsed = parseArgs(argv);
|
|
70
131
|
assertOnlyFlags(parsed.flags, new Set(["flow", "work-item", "task-slug", "artifact-root", "source-request", "summary", "title", "criterion", "assignment-provider", "effective-state-json"]), "workflow start");
|
|
@@ -518,14 +579,35 @@ function readAssignment(sessionDir, slug) {
|
|
|
518
579
|
return readJsonFile(file, "workflow assignment");
|
|
519
580
|
}
|
|
520
581
|
function assertMatchingAssignmentActor(sessionDir, slug) {
|
|
521
|
-
const assignment =
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
582
|
+
const { assignment, caller, matches } = assignmentActorContext(sessionDir, slug);
|
|
583
|
+
if (matches)
|
|
584
|
+
return caller;
|
|
585
|
+
const authority = loadContinuationTurnAuthority().validateSignedActiveTurnAssignmentAuthority({
|
|
586
|
+
sessionDir,
|
|
587
|
+
runId: process.env.FLOW_AGENTS_CONTINUATION_RUN_ID,
|
|
588
|
+
turnSecret: process.env.FLOW_AGENTS_CONTINUATION_TURN_SECRET,
|
|
589
|
+
});
|
|
590
|
+
if (authority.valid && authority.record
|
|
591
|
+
&& assignment.actor_key === authority.record.assignment_actor
|
|
592
|
+
&& isDeepStrictEqual(normalizeAssignmentActor(assignment.actor), normalizeAssignmentActor(authority.record.assignment_actor_struct))) {
|
|
593
|
+
return { actorKey: authority.record.assignment_actor, actor: normalizeAssignmentActor(authority.record.assignment_actor_struct) };
|
|
526
594
|
}
|
|
595
|
+
throw new Error("workflow mutation requires the session's active, matching assignment actor");
|
|
596
|
+
}
|
|
597
|
+
function assertOrdinaryMatchingAssignmentActor(sessionDir, slug) {
|
|
598
|
+
const { caller, matches } = assignmentActorContext(sessionDir, slug);
|
|
599
|
+
if (!matches)
|
|
600
|
+
throw new Error("workflow mutation requires the session's active, matching assignment actor");
|
|
527
601
|
return caller;
|
|
528
602
|
}
|
|
603
|
+
function assignmentActorContext(sessionDir, slug) {
|
|
604
|
+
const assignment = readActiveAssignment(sessionDir, slug);
|
|
605
|
+
const caller = resolveCurrentAssignmentActor();
|
|
606
|
+
return { assignment, caller, matches: assignment.actor_key === caller.actorKey && isDeepStrictEqual(normalizeAssignmentActor(assignment.actor), normalizeAssignmentActor(caller.actor)) };
|
|
607
|
+
}
|
|
608
|
+
function normalizeAssignmentActor(value) {
|
|
609
|
+
return value && typeof value === "object" ? { ...value, human: value.human ?? null } : null;
|
|
610
|
+
}
|
|
529
611
|
function readActiveAssignment(sessionDir, slug) {
|
|
530
612
|
const assignment = readAssignment(sessionDir, slug);
|
|
531
613
|
if (assignment.status !== "claimed" || assignment.artifact_dir !== slug || typeof assignment.actor_key !== "string" || !assignment.actor_key || !assignment.actor || typeof assignment.actor !== "object" || Array.isArray(assignment.actor)) {
|
|
@@ -610,6 +692,17 @@ function assertOnlyFlags(flags, allowed, command) {
|
|
|
610
692
|
if (unsupported)
|
|
611
693
|
throw new Error(`${command} does not support --${unsupported}`);
|
|
612
694
|
}
|
|
695
|
+
function integerFlag(flags, name, fallback, min, max) {
|
|
696
|
+
const raw = flagString(flags, name);
|
|
697
|
+
if (raw === undefined)
|
|
698
|
+
return fallback;
|
|
699
|
+
if (!/^(0|[1-9][0-9]*)$/.test(raw))
|
|
700
|
+
throw new Error(`workflow drive --${name} must be an integer from ${min} through ${max}`);
|
|
701
|
+
const value = Number(raw);
|
|
702
|
+
if (!Number.isSafeInteger(value) || value < min || value > max)
|
|
703
|
+
throw new Error(`workflow drive --${name} must be an integer from ${min} through ${max}`);
|
|
704
|
+
return value;
|
|
705
|
+
}
|
|
613
706
|
function isWithin(candidate, root) {
|
|
614
707
|
const relative = path.relative(root, candidate);
|
|
615
708
|
return relative === "" || (!relative.startsWith(`..${path.sep}`) && relative !== ".." && !path.isAbsolute(relative));
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
export type ContinuationBarrier = {
|
|
2
|
+
kind: "pid";
|
|
3
|
+
pid: number;
|
|
4
|
+
} | {
|
|
5
|
+
kind: "deadline";
|
|
6
|
+
at: string;
|
|
7
|
+
};
|
|
8
|
+
export type ContinuationSnapshot = {
|
|
9
|
+
run_id: string;
|
|
10
|
+
definition_id: string;
|
|
11
|
+
status: string;
|
|
12
|
+
disposition: "continue" | "waiting" | "done" | "failed";
|
|
13
|
+
current_step: string;
|
|
14
|
+
next_action: Record<string, unknown> | null;
|
|
15
|
+
};
|
|
16
|
+
export type ContinuationTurnRequest = {
|
|
17
|
+
schema_version: "1.0";
|
|
18
|
+
run_id: string;
|
|
19
|
+
definition_id: string;
|
|
20
|
+
current_step: string;
|
|
21
|
+
iteration: number;
|
|
22
|
+
max_turns: number;
|
|
23
|
+
next_action: Record<string, unknown> | null;
|
|
24
|
+
};
|
|
25
|
+
export type ContinuationTurnResult = {
|
|
26
|
+
status: "completed";
|
|
27
|
+
summary?: string;
|
|
28
|
+
} | {
|
|
29
|
+
status: "wait";
|
|
30
|
+
barrier: ContinuationBarrier;
|
|
31
|
+
summary?: string;
|
|
32
|
+
};
|
|
33
|
+
export declare class ContinuationAdapterTimeoutError extends Error {
|
|
34
|
+
readonly code = "CONTINUATION_ADAPTER_TIMEOUT";
|
|
35
|
+
constructor(timeoutMs: number);
|
|
36
|
+
}
|
|
37
|
+
export type ContinuationDriverState = {
|
|
38
|
+
schema_version: "1.0";
|
|
39
|
+
run_id: string;
|
|
40
|
+
definition_id: string;
|
|
41
|
+
max_turns: number;
|
|
42
|
+
adapter_command_identity: string | null;
|
|
43
|
+
status: "active" | "waiting" | "done" | "failed" | "budget_exhausted";
|
|
44
|
+
turns_started: number;
|
|
45
|
+
active_turn_step?: string | null;
|
|
46
|
+
active_turn_public_key_digest?: string | null;
|
|
47
|
+
pending_barrier: ContinuationBarrier | null;
|
|
48
|
+
updated_at: string;
|
|
49
|
+
};
|
|
50
|
+
export type ContinuationDriverEvent = {
|
|
51
|
+
schema_version: "1.0";
|
|
52
|
+
type: "started" | "turn_started" | "turn_completed" | "gate_not_advanced" | "turn_failed" | "authority_cleanup_failed" | "parked" | "resumed" | "done" | "budget_exhausted";
|
|
53
|
+
run_id: string;
|
|
54
|
+
definition_id: string;
|
|
55
|
+
current_step: string;
|
|
56
|
+
turns_started: number;
|
|
57
|
+
at: string;
|
|
58
|
+
barrier?: ContinuationBarrier;
|
|
59
|
+
summary?: string;
|
|
60
|
+
failure_kind?: "adapter_error" | "timeout";
|
|
61
|
+
};
|
|
62
|
+
export interface ContinuationStateStore {
|
|
63
|
+
load(): ContinuationDriverState | null;
|
|
64
|
+
save(state: ContinuationDriverState): void;
|
|
65
|
+
append(event: ContinuationDriverEvent): void;
|
|
66
|
+
}
|
|
67
|
+
export interface ContinuationRuntimePort {
|
|
68
|
+
inspect(): Promise<ContinuationSnapshot>;
|
|
69
|
+
synchronize(): Promise<ContinuationSnapshot>;
|
|
70
|
+
execute(request: ContinuationTurnRequest, context?: ContinuationTurnContext): Promise<ContinuationTurnResult>;
|
|
71
|
+
}
|
|
72
|
+
export type ContinuationTurnContext = {
|
|
73
|
+
continuationTurnSecret?: string;
|
|
74
|
+
continuationRunId?: string;
|
|
75
|
+
};
|
|
76
|
+
export type ContinuationDriverLockLease = {
|
|
77
|
+
pid: number;
|
|
78
|
+
token: string;
|
|
79
|
+
created_at: string;
|
|
80
|
+
};
|
|
81
|
+
export type ContinuationTurnAuthority = {
|
|
82
|
+
runId: string;
|
|
83
|
+
turnSecret: string;
|
|
84
|
+
publicKeyDigest: string;
|
|
85
|
+
cleanup(): boolean;
|
|
86
|
+
};
|
|
87
|
+
export type ContinuationDriverOutcome = {
|
|
88
|
+
outcome: "done" | "waiting" | "failed" | "budget_exhausted";
|
|
89
|
+
turns_started: number;
|
|
90
|
+
snapshot: ContinuationSnapshot;
|
|
91
|
+
barrier?: ContinuationBarrier;
|
|
92
|
+
};
|
|
93
|
+
export interface RunContinuationDriverInput {
|
|
94
|
+
maxTurns: number;
|
|
95
|
+
adapterCommandIdentity?: string;
|
|
96
|
+
runtime: ContinuationRuntimePort;
|
|
97
|
+
store: ContinuationStateStore;
|
|
98
|
+
waitForBarrier?: (barrier: ContinuationBarrier) => Promise<"ready" | "pending">;
|
|
99
|
+
authorizeTurn?: () => Promise<void>;
|
|
100
|
+
issueTurnAuthority?: (request: ContinuationTurnRequest) => Promise<ContinuationTurnAuthority>;
|
|
101
|
+
now?: () => Date;
|
|
102
|
+
}
|
|
103
|
+
export interface DriveBuilderFlowSessionInput {
|
|
104
|
+
sessionDir: string;
|
|
105
|
+
maxTurns: number;
|
|
106
|
+
adapterCommandIdentity?: string;
|
|
107
|
+
execute: ContinuationRuntimePort["execute"];
|
|
108
|
+
waitForBarrier?: RunContinuationDriverInput["waitForBarrier"];
|
|
109
|
+
authorizeTurn?: RunContinuationDriverInput["authorizeTurn"];
|
|
110
|
+
issueTurnAuthority?: RunContinuationDriverInput["issueTurnAuthority"];
|
|
111
|
+
now?: () => Date;
|
|
112
|
+
}
|
|
113
|
+
export declare function runContinuationDriver(input: RunContinuationDriverInput): Promise<ContinuationDriverOutcome>;
|
|
114
|
+
export declare function driveBuilderFlowSession(input: DriveBuilderFlowSessionInput): Promise<ContinuationDriverOutcome>;
|
|
115
|
+
export declare function withContinuationDriverLock<T>(sessionDirInput: string, body: (lease: ContinuationDriverLockLease) => Promise<T>): Promise<T>;
|
|
116
|
+
export declare function createFileContinuationStore(sessionDirInput: string): ContinuationStateStore;
|