@inflexa-ai/harness 0.7.1 → 0.8.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/dist/contracts/chat-parts.d.ts +4 -2
- package/dist/contracts/schemas/chat-parts.d.ts +8 -0
- package/dist/contracts/schemas/chat-parts.js +1 -1
- package/dist/provenance/collector.d.ts +39 -2
- package/dist/provenance/collector.js +62 -33
- package/dist/provenance/exec-frame.d.ts +14 -2
- package/dist/provenance/exec-frame.js +27 -4
- package/dist/providers/ai-sdk.d.ts +23 -0
- package/dist/providers/ai-sdk.js +254 -34
- package/dist/providers/anthropic.d.ts +2 -0
- package/dist/providers/anthropic.js +1 -0
- package/dist/reference-data/catalog.js +680 -1
- package/dist/tools/workspace/execute-command.js +1 -0
- package/dist/workflows/execute-analysis.d.ts +10 -5
- package/dist/workflows/execute-analysis.js +102 -36
- package/dist/workflows/sandbox-step.d.ts +25 -0
- package/dist/workflows/sandbox-step.js +20 -9
- package/package.json +3 -1
|
@@ -30,11 +30,16 @@
|
|
|
30
30
|
* completion
|
|
31
31
|
* - await child results via `getResult` (these are themselves cached
|
|
32
32
|
* in DBOS, so parent recovery does NOT re-run completed children)
|
|
33
|
-
* 3.
|
|
34
|
-
* -
|
|
35
|
-
*
|
|
36
|
-
* `
|
|
37
|
-
*
|
|
33
|
+
* 3. Failure isolation
|
|
34
|
+
* - a child settling `failed`/`blocked` (or throwing for a non-budget
|
|
35
|
+
* cause) dooms only its transitive dependents: they can never become
|
|
36
|
+
* dependency-satisfied, are marked `skipped` on the dag-state part, and
|
|
37
|
+
* are never dispatched. In-flight siblings and independent ready steps
|
|
38
|
+
* continue; the loop drains and the run finalises (typically `partial`).
|
|
39
|
+
* - the halt cascade (cancel in-flight via
|
|
40
|
+
* `Promise.allSettled(handles.map(h => DBOS.cancelWorkflow(h.workflowID)))`,
|
|
41
|
+
* stop scheduling) survives only for the budget paths: a
|
|
42
|
+
* `budget_exceeded` settlement and the `neverFits` plan-validation guard.
|
|
38
43
|
* 4. Pause cascade (402)
|
|
39
44
|
* - on a child cancelling itself with `budget_exceeded`: cancel siblings
|
|
40
45
|
* then self-cancel the parent to `CANCELLED` (NOT `ERROR` — ERROR
|
|
@@ -30,11 +30,16 @@
|
|
|
30
30
|
* completion
|
|
31
31
|
* - await child results via `getResult` (these are themselves cached
|
|
32
32
|
* in DBOS, so parent recovery does NOT re-run completed children)
|
|
33
|
-
* 3.
|
|
34
|
-
* -
|
|
35
|
-
*
|
|
36
|
-
* `
|
|
37
|
-
*
|
|
33
|
+
* 3. Failure isolation
|
|
34
|
+
* - a child settling `failed`/`blocked` (or throwing for a non-budget
|
|
35
|
+
* cause) dooms only its transitive dependents: they can never become
|
|
36
|
+
* dependency-satisfied, are marked `skipped` on the dag-state part, and
|
|
37
|
+
* are never dispatched. In-flight siblings and independent ready steps
|
|
38
|
+
* continue; the loop drains and the run finalises (typically `partial`).
|
|
39
|
+
* - the halt cascade (cancel in-flight via
|
|
40
|
+
* `Promise.allSettled(handles.map(h => DBOS.cancelWorkflow(h.workflowID)))`,
|
|
41
|
+
* stop scheduling) survives only for the budget paths: a
|
|
42
|
+
* `budget_exceeded` settlement and the `neverFits` plan-validation guard.
|
|
38
43
|
* 4. Pause cascade (402)
|
|
39
44
|
* - on a child cancelling itself with `budget_exceeded`: cancel siblings
|
|
40
45
|
* then self-cancel the parent to `CANCELLED` (NOT `ERROR` — ERROR
|
|
@@ -105,11 +110,23 @@ export function buildChildInput(args) {
|
|
|
105
110
|
if (!resources) {
|
|
106
111
|
throw new Error(`executeAnalysis: step "${stepId}" missing from resourcesByStepId — every step must declare resources`);
|
|
107
112
|
}
|
|
113
|
+
const planStep = input.planStepById[stepId];
|
|
114
|
+
if (!planStep) {
|
|
115
|
+
throw new Error(`executeAnalysis: step "${stepId}" missing from planStepById — every step must carry its plan data`);
|
|
116
|
+
}
|
|
108
117
|
return {
|
|
109
118
|
analysisId: input.analysisId,
|
|
110
119
|
runId,
|
|
111
120
|
stepId,
|
|
112
121
|
agentId: input.agentByStepId[stepId] ?? "scientific-executor",
|
|
122
|
+
// Carried into the child because lineage classification admits a same-run
|
|
123
|
+
// sibling edge only when the sibling was declared here — the scheduler's
|
|
124
|
+
// ordering guarantee attaches to this list and nothing else. Read from the
|
|
125
|
+
// keyed plan snapshot rather than scanning `steps`, and thrown for rather
|
|
126
|
+
// than defaulted: an empty list is indistinguishable from a step that
|
|
127
|
+
// genuinely declared nothing, and it silently deletes every same-run edge
|
|
128
|
+
// the step was entitled to.
|
|
129
|
+
dependsOn: planStep.depends_on,
|
|
113
130
|
level,
|
|
114
131
|
prompt,
|
|
115
132
|
parentWorkflowId: workflowId,
|
|
@@ -319,7 +336,7 @@ export async function runExecuteAnalysisBody(input, deps) {
|
|
|
319
336
|
stepCount: input.steps.length,
|
|
320
337
|
atMs: startedAtMs,
|
|
321
338
|
});
|
|
322
|
-
// (2-4) Scheduler loop +
|
|
339
|
+
// (2-4) Scheduler loop + failure isolation + pause cascade.
|
|
323
340
|
const final = await runSchedulerLoop({
|
|
324
341
|
input,
|
|
325
342
|
runId,
|
|
@@ -434,7 +451,7 @@ async function runSchedulerLoop(args) {
|
|
|
434
451
|
const canceled = new Set();
|
|
435
452
|
const inFlight = new Map();
|
|
436
453
|
const budgetExceededChildIds = new Set();
|
|
437
|
-
// Child workflow ids the parent itself cancelled (
|
|
454
|
+
// Child workflow ids the parent itself cancelled (budget / neverFits halt cascade). Their `getResult`
|
|
438
455
|
// rejects with a DBOS cancellation error and lands in the settlement error branch — but the step was
|
|
439
456
|
// CANCELED by us, not failed on its own merits. Keyed here (deterministic: `cancelInFlight` runs the
|
|
440
457
|
// same way on a replay) so that branch records it as canceled everywhere, matching how a child that
|
|
@@ -444,7 +461,40 @@ async function runSchedulerLoop(args) {
|
|
|
444
461
|
for (const step of input.steps) {
|
|
445
462
|
stepRuntime.set(step.id, { status: "pending" });
|
|
446
463
|
}
|
|
447
|
-
|
|
464
|
+
// Reverse adjacency over the static plan — who depends on whom.
|
|
465
|
+
const dependentsByStepId = new Map();
|
|
466
|
+
for (const step of input.steps) {
|
|
467
|
+
for (const dep of step.depends_on) {
|
|
468
|
+
const list = dependentsByStepId.get(dep);
|
|
469
|
+
if (list)
|
|
470
|
+
list.push(step.id);
|
|
471
|
+
else
|
|
472
|
+
dependentsByStepId.set(dep, [step.id]);
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
/**
|
|
476
|
+
* Mark every transitive dependent of a failed/blocked step `skipped` in the
|
|
477
|
+
* dag snapshot: a failed step never enters `completed`, so its dependents
|
|
478
|
+
* can never become dependency-satisfied and will never be dispatched.
|
|
479
|
+
* Stream-only — ledger rows stay `pending` until the terminal sweep flips
|
|
480
|
+
* them to `skipped`. Dependents of an unfinished step are necessarily
|
|
481
|
+
* `pending` (never queued/running); an already-`skipped` one is not
|
|
482
|
+
* re-walked.
|
|
483
|
+
*/
|
|
484
|
+
const markDependentsSkipped = (failedStepId) => {
|
|
485
|
+
const stack = [...(dependentsByStepId.get(failedStepId) ?? [])];
|
|
486
|
+
while (stack.length > 0) {
|
|
487
|
+
const id = stack.pop();
|
|
488
|
+
if (stepRuntime.get(id).status === "pending") {
|
|
489
|
+
stepRuntime.set(id, { status: "skipped" });
|
|
490
|
+
stack.push(...(dependentsByStepId.get(id) ?? []));
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
};
|
|
494
|
+
// Halts scheduling entirely — reserved for the budget paths (a
|
|
495
|
+
// `budget_exceeded` settlement, the `neverFits` guard). An ordinary step
|
|
496
|
+
// failure does NOT set it: it dooms only that step's transitive dependents.
|
|
497
|
+
let halted = false;
|
|
448
498
|
let budgetExceeded = false;
|
|
449
499
|
let failureReason = null;
|
|
450
500
|
const stepIndexById = new Map(input.steps.map((s, i) => [s.id, i]));
|
|
@@ -473,20 +523,28 @@ async function runSchedulerLoop(args) {
|
|
|
473
523
|
};
|
|
474
524
|
const dbosParentId = DBOS.workflowID ?? workflowId;
|
|
475
525
|
const dispatchReady = async () => {
|
|
476
|
-
if (
|
|
526
|
+
if (halted)
|
|
477
527
|
return;
|
|
478
528
|
const inFlightStepIds = new Set([...inFlight.values()].map((h) => h.stepId));
|
|
529
|
+
// A settled-but-not-completed step (failed / blocked / canceled) is not
|
|
530
|
+
// in `completed` and not in flight, so `scheduleReady` would offer it
|
|
531
|
+
// again — filter it out of the candidate list. This also stops its
|
|
532
|
+
// declared resources from weighing against the budget: settled steps
|
|
533
|
+
// hold no capacity.
|
|
534
|
+
const candidates = input.steps.filter((s) => !failed.has(s.id) && !canceled.has(s.id));
|
|
479
535
|
let admit;
|
|
480
536
|
let queuedChanged = false;
|
|
481
537
|
if (input.budget) {
|
|
482
|
-
const scheduled = scheduleReady(
|
|
538
|
+
const scheduled = scheduleReady(candidates, completed, inFlightStepIds, {
|
|
483
539
|
budget: input.budget,
|
|
484
540
|
resourcesByStepId: input.resourcesByStepId,
|
|
485
541
|
});
|
|
486
542
|
if (scheduled.neverFits.length > 0) {
|
|
487
543
|
// An over-budget step can never be admitted — plan-time validation
|
|
488
544
|
// makes this unreachable for new plans; stored plans fail loudly
|
|
489
|
-
// instead of waiting forever.
|
|
545
|
+
// instead of waiting forever. The stored plan is invalid against
|
|
546
|
+
// this machine, so the run halts outright — unlike an ordinary
|
|
547
|
+
// step failure, which dooms only its dependents.
|
|
490
548
|
for (const stepId of scheduled.neverFits) {
|
|
491
549
|
const r = input.resourcesByStepId[stepId];
|
|
492
550
|
const declared = r ? `${r.cpu} CPU / ${r.memoryGb} GB` : "undeclared";
|
|
@@ -496,7 +554,7 @@ async function runSchedulerLoop(args) {
|
|
|
496
554
|
error: `step resources (${declared}) exceed the machine budget (${input.budget.cpu} CPU / ${input.budget.memoryGb} GB)`,
|
|
497
555
|
});
|
|
498
556
|
}
|
|
499
|
-
|
|
557
|
+
halted = true;
|
|
500
558
|
failureReason = `step "${scheduled.neverFits[0]}" exceeds the machine resource budget`;
|
|
501
559
|
await cancelInFlight(inFlight, "fail_fast", canceledByParent);
|
|
502
560
|
await emitDagSnapshot();
|
|
@@ -511,7 +569,7 @@ async function runSchedulerLoop(args) {
|
|
|
511
569
|
admit = scheduled.admit;
|
|
512
570
|
}
|
|
513
571
|
else {
|
|
514
|
-
admit = scheduleReady(
|
|
572
|
+
admit = scheduleReady(candidates, completed, inFlightStepIds);
|
|
515
573
|
}
|
|
516
574
|
if (admit.length === 0) {
|
|
517
575
|
if (queuedChanged)
|
|
@@ -590,7 +648,7 @@ async function runSchedulerLoop(args) {
|
|
|
590
648
|
const isBudgetCancel = childWasBudgetExceeded || r.error === "budget_exceeded";
|
|
591
649
|
if (isBudgetCancel && !budgetExceeded) {
|
|
592
650
|
budgetExceeded = true;
|
|
593
|
-
|
|
651
|
+
halted = true;
|
|
594
652
|
failureReason = "budget_exceeded";
|
|
595
653
|
await cancelInFlight(inFlight, "budget_exceeded", canceledByParent);
|
|
596
654
|
}
|
|
@@ -604,31 +662,31 @@ async function runSchedulerLoop(args) {
|
|
|
604
662
|
await emitDagSnapshot();
|
|
605
663
|
}
|
|
606
664
|
else {
|
|
607
|
-
// failed or blocked — a blocker (see the harness-sandbox-agents spec)
|
|
608
|
-
// failure: the step declared it cannot
|
|
609
|
-
//
|
|
665
|
+
// failed or blocked — a blocker (see the harness-sandbox-agents spec)
|
|
666
|
+
// is treated exactly like a failure: the step declared it cannot
|
|
667
|
+
// deliver, so only its transitive dependents can never run. In-flight
|
|
668
|
+
// siblings and independent ready steps continue; the dispatch round
|
|
669
|
+
// below also lets a budget-held step claim the freed capacity.
|
|
610
670
|
failed.add(settled.stepId);
|
|
611
|
-
|
|
612
|
-
failFast = true;
|
|
613
|
-
failureReason = r.error ?? (r.status === "blocked" ? "step_blocked" : "step_failed");
|
|
614
|
-
await cancelInFlight(inFlight, "fail_fast", canceledByParent);
|
|
615
|
-
}
|
|
671
|
+
failureReason ??= r.error ?? (r.status === "blocked" ? "step_blocked" : "step_failed");
|
|
616
672
|
stepRuntime.set(settled.stepId, {
|
|
617
673
|
status: "failed",
|
|
618
674
|
durationMs: r.durationMs ?? undefined,
|
|
619
675
|
error: r.error ?? (r.status === "blocked" ? "step_blocked" : "step_failed"),
|
|
620
676
|
});
|
|
677
|
+
markDependentsSkipped(settled.stepId);
|
|
621
678
|
stepStatus = "failed";
|
|
622
679
|
stepDurationMs = r.durationMs ?? undefined;
|
|
623
680
|
await emitDagSnapshot();
|
|
681
|
+
await dispatchReady();
|
|
624
682
|
}
|
|
625
683
|
}
|
|
626
684
|
else if (canceledByParent.has(settled.childId)) {
|
|
627
|
-
// The child threw because the PARENT cancelled it (
|
|
628
|
-
// it failed on its own — its `getResult` rejects with a DBOS cancellation error.
|
|
629
|
-
// canceled, mirroring the graceful `{status:"canceled"}` branch above so the
|
|
630
|
-
// the terminal result, and the `step_completed` provenance all agree. No
|
|
631
|
-
// cascade here: the run is already
|
|
685
|
+
// The child threw because the PARENT cancelled it (budget / neverFits halt cascade), not
|
|
686
|
+
// because it failed on its own — its `getResult` rejects with a DBOS cancellation error.
|
|
687
|
+
// Record it as canceled, mirroring the graceful `{status:"canceled"}` branch above so the
|
|
688
|
+
// `canceled` set, the terminal result, and the `step_completed` provenance all agree. No
|
|
689
|
+
// halt / cancel cascade here: the run is already halted (that is why this child was cancelled).
|
|
632
690
|
canceled.add(settled.stepId);
|
|
633
691
|
stepRuntime.set(settled.stepId, {
|
|
634
692
|
// `stepRuntime` (the DAG snapshot) has no canceled tier; the graceful-cancel branch above
|
|
@@ -641,18 +699,24 @@ async function runSchedulerLoop(args) {
|
|
|
641
699
|
await emitDagSnapshot();
|
|
642
700
|
}
|
|
643
701
|
else {
|
|
702
|
+
// The child threw on its own (not a parent-driven cancel). A
|
|
703
|
+
// budget_exceeded throw still halts the run — the pause cascade is a
|
|
704
|
+
// money decision, not a DAG one. Any other throw is treated exactly
|
|
705
|
+
// like a step failure: dependents doomed, siblings continue.
|
|
644
706
|
failed.add(settled.stepId);
|
|
645
|
-
const
|
|
646
|
-
if (
|
|
647
|
-
budgetExceeded
|
|
648
|
-
|
|
649
|
-
|
|
707
|
+
const isBudgetThrow = childWasBudgetExceeded || isBudgetExceeded(settled.err);
|
|
708
|
+
if (isBudgetThrow) {
|
|
709
|
+
if (!budgetExceeded) {
|
|
710
|
+
budgetExceeded = true;
|
|
711
|
+
halted = true;
|
|
712
|
+
failureReason = "budget_exceeded";
|
|
713
|
+
}
|
|
714
|
+
await cancelInFlight(inFlight, "budget_exceeded", canceledByParent);
|
|
650
715
|
}
|
|
651
|
-
else
|
|
652
|
-
|
|
653
|
-
|
|
716
|
+
else {
|
|
717
|
+
failureReason ??= settled.err instanceof Error ? settled.err.message : String(settled.err);
|
|
718
|
+
markDependentsSkipped(settled.stepId);
|
|
654
719
|
}
|
|
655
|
-
await cancelInFlight(inFlight, cause, canceledByParent);
|
|
656
720
|
stepRuntime.set(settled.stepId, {
|
|
657
721
|
status: "failed",
|
|
658
722
|
error: settled.err instanceof Error ? settled.err.message : String(settled.err),
|
|
@@ -661,6 +725,8 @@ async function runSchedulerLoop(args) {
|
|
|
661
725
|
// A child that settled by throwing carries no durable duration.
|
|
662
726
|
stepDurationMs = undefined;
|
|
663
727
|
await emitDagSnapshot();
|
|
728
|
+
if (!isBudgetThrow)
|
|
729
|
+
await dispatchReady();
|
|
664
730
|
}
|
|
665
731
|
// One `step_completed` provenance emission per settled child — this
|
|
666
732
|
// settlement loop is the only site that observes every executed step.
|
|
@@ -51,6 +51,18 @@ export interface SandboxStepInput {
|
|
|
51
51
|
readonly runId: string;
|
|
52
52
|
readonly stepId: string;
|
|
53
53
|
readonly agentId: string;
|
|
54
|
+
/**
|
|
55
|
+
* Step ids this step declared as dependencies. Load-bearing for lineage:
|
|
56
|
+
* classification admits a same-run sibling edge only on declaration, so a
|
|
57
|
+
* collector seeded without this refuses every same-run read — legitimate
|
|
58
|
+
* declared dependencies included.
|
|
59
|
+
*
|
|
60
|
+
* Optional because this is durable DBOS workflow input: a workflow started
|
|
61
|
+
* under an input shape predating the field recovers without it. Absence
|
|
62
|
+
* reads as an empty declaration list, which under-captures sibling edges
|
|
63
|
+
* rather than admitting unstable ones.
|
|
64
|
+
*/
|
|
65
|
+
readonly dependsOn?: readonly string[];
|
|
54
66
|
/** Topological level — persisted on `cortex_step_executions.wave`. */
|
|
55
67
|
readonly level: number;
|
|
56
68
|
/** User-content prompt the agent receives as its initial message. */
|
|
@@ -240,6 +252,19 @@ export interface PostStepContext {
|
|
|
240
252
|
/** Same step-scoped collector the agent loop fed each exec frame into. */
|
|
241
253
|
readonly lineageCollector: ProvenanceCollector;
|
|
242
254
|
}
|
|
255
|
+
/**
|
|
256
|
+
* Build the step's lineage collector from its durable input. The agent loop
|
|
257
|
+
* feeds each exec's provenance frame into it; post-step registration reads the
|
|
258
|
+
* resulting input/script edges. Reconstructed deterministically on replay — the
|
|
259
|
+
* frames it consumes are cached recv outputs and the command strings are cached
|
|
260
|
+
* LLM tool-use (see the harness-thread-store and harness-durable-runtime specs).
|
|
261
|
+
*
|
|
262
|
+
* Split out of the body, and taking only the fields it reads, so the seeding is
|
|
263
|
+
* exercisable without a live workflow: `dependsOn` is what makes a same-run edge
|
|
264
|
+
* admissible at all, so a collector built without it silently erases every
|
|
265
|
+
* legitimate declared-dependency edge while leaving each layer's own tests green.
|
|
266
|
+
*/
|
|
267
|
+
export declare function createLineageCollector(input: Pick<SandboxStepInput, "stepId" | "runId" | "dependsOn">): ProvenanceCollector;
|
|
243
268
|
/**
|
|
244
269
|
* Register the sandbox-step child workflow with DBOS. Returns the
|
|
245
270
|
* registered callable so callers can dispatch via `DBOS.startWorkflow`.
|
|
@@ -82,6 +82,25 @@ function stepPartId(kind, runId, stepId) {
|
|
|
82
82
|
function userFacingStepFailure(errorClass) {
|
|
83
83
|
return errorClass === "lineage_attestation" ? "Step results could not be finalized." : "Step failed during execution.";
|
|
84
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* Build the step's lineage collector from its durable input. The agent loop
|
|
87
|
+
* feeds each exec's provenance frame into it; post-step registration reads the
|
|
88
|
+
* resulting input/script edges. Reconstructed deterministically on replay — the
|
|
89
|
+
* frames it consumes are cached recv outputs and the command strings are cached
|
|
90
|
+
* LLM tool-use (see the harness-thread-store and harness-durable-runtime specs).
|
|
91
|
+
*
|
|
92
|
+
* Split out of the body, and taking only the fields it reads, so the seeding is
|
|
93
|
+
* exercisable without a live workflow: `dependsOn` is what makes a same-run edge
|
|
94
|
+
* admissible at all, so a collector built without it silently erases every
|
|
95
|
+
* legitimate declared-dependency edge while leaving each layer's own tests green.
|
|
96
|
+
*/
|
|
97
|
+
export function createLineageCollector(input) {
|
|
98
|
+
return new ProvenanceCollector({
|
|
99
|
+
stepId: input.stepId,
|
|
100
|
+
runId: input.runId,
|
|
101
|
+
dependsOn: [...(input.dependsOn ?? [])],
|
|
102
|
+
});
|
|
103
|
+
}
|
|
85
104
|
// ── The child workflow body ───────────────────────────────────────────
|
|
86
105
|
/**
|
|
87
106
|
* Register the sandbox-step child workflow with DBOS. Returns the
|
|
@@ -132,15 +151,7 @@ async function runSandboxStepBody(input, deps) {
|
|
|
132
151
|
// `session.provenance.agentId`, and billing tags ride the same provenance.
|
|
133
152
|
const session = forSubAgent(input.runSession, input.agentId);
|
|
134
153
|
const writePrefix = deps.resolveWritePrefix(input);
|
|
135
|
-
|
|
136
|
-
// provenance frame into it; post-step registration reads the resulting
|
|
137
|
-
// input/script edges. Reconstructed deterministically on replay — the
|
|
138
|
-
// frames it consumes are cached recv outputs and the command strings are
|
|
139
|
-
// cached LLM tool-use (see the harness-thread-store and harness-durable-runtime specs).
|
|
140
|
-
const lineageCollector = new ProvenanceCollector({
|
|
141
|
-
stepId: input.stepId,
|
|
142
|
-
runId: input.runId,
|
|
143
|
-
});
|
|
154
|
+
const lineageCollector = createLineageCollector(input);
|
|
144
155
|
// (2a) sandbox.mint — checkpoint the machine's identity (name + HMAC secret)
|
|
145
156
|
// BEFORE it is spawned (see the harness-sandbox-exec spec). Durable-before-create is what makes (2b)
|
|
146
157
|
// idempotent: a crash between spawn and the spawn checkpoint re-runs (2b)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inflexa-ai/harness",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Host-agnostic bioinformatics agent harness \u2014 hand-rolled agent loop, DBOS-durable workflows, sandboxed compute.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -40,12 +40,14 @@
|
|
|
40
40
|
"prepare": "tsc -p tsconfig.json",
|
|
41
41
|
"prepublishOnly": "bun run build && bun run smoke",
|
|
42
42
|
"smoke": "node scripts/smoke.mjs",
|
|
43
|
+
"test:full": "bash scripts/test-full.sh",
|
|
43
44
|
"typecheck": "tsc --noEmit"
|
|
44
45
|
},
|
|
45
46
|
"dependencies": {
|
|
46
47
|
"@ai-sdk/anthropic": "^4.0.15",
|
|
47
48
|
"@ai-sdk/openai-compatible": "^3.0.10",
|
|
48
49
|
"@ai-sdk/provider": "^4.0.3",
|
|
50
|
+
"@ai-sdk/provider-utils": "5.0.10",
|
|
49
51
|
"@anthropic-ai/sdk": "^0.107.0",
|
|
50
52
|
"@dbos-inc/dbos-sdk": "^4.23.6",
|
|
51
53
|
"@kubernetes/client-node": "^1.4.0",
|