@inflexa-ai/harness 0.44.0 → 0.45.1
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/agents/conversation-agent.d.ts +10 -0
- package/dist/agents/conversation-agent.js +19 -1
- package/dist/agents/sandbox/shared.d.ts +23 -2
- package/dist/agents/sandbox/shared.js +51 -18
- package/dist/agents/sandbox/translational-safety-agent.js +26 -0
- package/dist/agents/sandbox/types.d.ts +24 -1
- package/dist/agents/sandbox-catalog.d.ts +14 -0
- package/dist/agents/sandbox-catalog.js +19 -0
- package/dist/app/approve-plan.d.ts +51 -0
- package/dist/app/approve-plan.js +84 -0
- package/dist/app/chat-turn.js +6 -3
- package/dist/app/data-profile-view.d.ts +1 -1
- package/dist/app/run-activity.js +4 -6
- package/dist/config/environment-stores.d.ts +4 -2
- package/dist/contracts/chat-events.d.ts +14 -2
- package/dist/contracts/chat-events.js +1 -1
- package/dist/contracts/chat-frame.d.ts +7 -0
- package/dist/contracts/chat-frame.js +24 -6
- package/dist/contracts/chat-parts.d.ts +73 -2
- package/dist/contracts/chat-parts.js +3 -1
- package/dist/contracts/index.d.ts +4 -2
- package/dist/contracts/index.js +1 -0
- package/dist/contracts/part-registry.js +3 -0
- package/dist/contracts/schemas/chat-events.d.ts +38 -0
- package/dist/contracts/schemas/chat-events.js +8 -0
- package/dist/contracts/schemas/chat-parts.d.ts +239 -15
- package/dist/contracts/schemas/chat-parts.js +80 -12
- package/dist/contracts/schemas/index.d.ts +2 -2
- package/dist/contracts/schemas/index.js +2 -2
- package/dist/contracts/subagent-activity.d.ts +12 -0
- package/dist/contracts/subagent-activity.js +76 -0
- package/dist/execution/artifact-metadata.js +1 -3
- package/dist/execution/dbos-workflow-purger.d.ts +2 -0
- package/dist/execution/dbos-workflow-purger.js +21 -14
- package/dist/execution/run-canceler.d.ts +33 -11
- package/dist/execution/run-canceler.js +130 -28
- package/dist/execution/run-end-record.d.ts +30 -0
- package/dist/execution/run-end-record.js +27 -0
- package/dist/execution/run-event-parts.d.ts +6 -5
- package/dist/execution/run-event-parts.js +6 -5
- package/dist/execution/run-event-stream.d.ts +18 -6
- package/dist/execution/run-event-stream.js +67 -17
- package/dist/execution/run-synthesis.d.ts +21 -0
- package/dist/execution/run-synthesis.js +77 -3
- package/dist/index.d.ts +28 -10
- package/dist/index.js +26 -2
- package/dist/lib/hooks.d.ts +1 -1
- package/dist/lib/metrics.d.ts +2 -2
- package/dist/loop/call-guard.d.ts +50 -0
- package/dist/loop/call-guard.js +90 -0
- package/dist/loop/compaction.d.ts +5 -0
- package/dist/loop/compaction.js +17 -0
- package/dist/loop/run-agent.d.ts +9 -0
- package/dist/loop/run-agent.js +16 -1
- package/dist/loop/run-to-terminal.js +4 -1
- package/dist/loop/types.d.ts +8 -0
- package/dist/memory/card-builders.d.ts +11 -0
- package/dist/memory/card-builders.js +35 -21
- package/dist/memory/conversation-display-recorder.d.ts +2 -2
- package/dist/memory/conversation-display-recorder.js +38 -4
- package/dist/memory/conversation-display-storage.d.ts +9 -2
- package/dist/memory/conversation-display-storage.js +18 -3
- package/dist/memory/thread-history.d.ts +42 -8
- package/dist/memory/thread-history.js +164 -45
- package/dist/memory/thread-store.d.ts +13 -0
- package/dist/memory/thread-store.js +15 -1
- package/dist/prompts/briefing.d.ts +57 -3
- package/dist/prompts/briefing.js +129 -2
- package/dist/prompts/conversation.d.ts +1 -1
- package/dist/prompts/conversation.js +3 -1
- package/dist/prompts/planner.js +13 -2
- package/dist/provenance/seam.d.ts +39 -20
- package/dist/provenance/seam.js +7 -5
- package/dist/providers/ai-sdk.js +93 -11
- package/dist/providers/types.d.ts +6 -0
- package/dist/reference-data/catalog.js +141 -2
- package/dist/report-model/authoring-grammar.d.ts +26 -26
- package/dist/report-model/pin-snapshot.d.ts +1 -1
- package/dist/report-model/pin-snapshot.js +2 -50
- package/dist/runtime/assemble.d.ts +8 -1
- package/dist/runtime/assemble.js +11 -0
- package/dist/runtime/boot.d.ts +3 -0
- package/dist/runtime/boot.js +10 -1
- package/dist/sandbox/image-packages.d.ts +26 -4
- package/dist/sandbox/image-packages.js +18 -4
- package/dist/sandbox/sandbox-step-translate.d.ts +23 -0
- package/dist/sandbox/sandbox-step-translate.js +24 -0
- package/dist/schemas/artifact-manifest.d.ts +1 -1
- package/dist/schemas/artifact-manifest.js +11 -9
- package/dist/schemas/data-profile-schemas.d.ts +12 -12
- package/dist/schemas/plan-schemas.d.ts +75 -21
- package/dist/schemas/plan-schemas.js +1 -1
- package/dist/schemas/run-synthesis.d.ts +2 -2
- package/dist/schemas/workflow-state.d.ts +113 -0
- package/dist/schemas/workflow-state.js +54 -0
- package/dist/state/analyses-metrics.d.ts +79 -7
- package/dist/state/analyses-metrics.js +141 -6
- package/dist/state/artifacts.d.ts +66 -3
- package/dist/state/artifacts.js +85 -7
- package/dist/state/data-profile.d.ts +4 -2
- package/dist/state/data-profile.js +7 -5
- package/dist/state/index.d.ts +9 -8
- package/dist/state/index.js +5 -5
- package/dist/state/migrations/20261012120000_index_the_runs_by_start.d.ts +8 -0
- package/dist/state/migrations/20261012120000_index_the_runs_by_start.js +12 -0
- package/dist/state/migrations/20261013120000_index_the_ended_runs_and_the_recent_threads.d.ts +8 -0
- package/dist/state/migrations/20261013120000_index_the_ended_runs_and_the_recent_threads.js +13 -0
- package/dist/state/migrations/20261013180000_narrow_the_active_run_index.d.ts +8 -0
- package/dist/state/migrations/20261013180000_narrow_the_active_run_index.js +13 -0
- package/dist/state/migrations/20261014120000_index_the_plans_by_parent_and_the_runs_by_plan.d.ts +8 -0
- package/dist/state/migrations/20261014120000_index_the_plans_by_parent_and_the_runs_by_plan.js +13 -0
- package/dist/state/migrations/index.js +8 -0
- package/dist/state/plans.d.ts +21 -0
- package/dist/state/plans.js +25 -0
- package/dist/state/runs.d.ts +79 -14
- package/dist/state/runs.js +150 -33
- package/dist/state/schema.d.ts +2 -0
- package/dist/state/step-executions.d.ts +9 -0
- package/dist/state/step-executions.js +22 -0
- package/dist/tasks/data-profile-activity.d.ts +7 -1
- package/dist/tasks/data-profile-activity.js +18 -9
- package/dist/tasks/data-profile.d.ts +15 -1
- package/dist/tasks/data-profile.js +16 -11
- package/dist/tools/ad-hoc-router.d.ts +2 -0
- package/dist/tools/ad-hoc-router.js +18 -2
- package/dist/tools/approval/gateway.js +28 -5
- package/dist/tools/capability-data.d.ts +36 -0
- package/dist/tools/capability-data.js +73 -0
- package/dist/tools/display/show-user.d.ts +1 -1
- package/dist/tools/execute-analysis.d.ts +80 -1
- package/dist/tools/execute-analysis.js +352 -110
- package/dist/tools/knowledge/check.d.ts +60 -0
- package/dist/tools/knowledge/check.js +92 -0
- package/dist/tools/knowledge/client.d.ts +382 -0
- package/dist/tools/knowledge/client.js +302 -0
- package/dist/tools/knowledge/environment.d.ts +78 -0
- package/dist/tools/knowledge/environment.js +105 -0
- package/dist/tools/knowledge/index.d.ts +49 -0
- package/dist/tools/knowledge/index.js +70 -0
- package/dist/tools/knowledge/local-slots.d.ts +62 -0
- package/dist/tools/knowledge/local-slots.js +177 -0
- package/dist/tools/knowledge/pin.d.ts +14 -0
- package/dist/tools/knowledge/pin.js +17 -0
- package/dist/tools/knowledge/recommend.d.ts +92 -0
- package/dist/tools/knowledge/recommend.js +98 -0
- package/dist/tools/knowledge/situation.d.ts +143 -0
- package/dist/tools/knowledge/situation.js +164 -0
- package/dist/tools/knowledge/skeleton.d.ts +69 -0
- package/dist/tools/knowledge/skeleton.js +202 -0
- package/dist/tools/knowledge/template.d.ts +137 -0
- package/dist/tools/knowledge/template.js +267 -0
- package/dist/tools/research/generate-plan.d.ts +23 -0
- package/dist/tools/research/generate-plan.js +203 -12
- package/dist/tools/research/guarded-address.d.ts +20 -0
- package/dist/tools/research/guarded-address.js +148 -0
- package/dist/tools/research/inspect-data-profile.d.ts +1 -1
- package/dist/tools/research/inspect-run.d.ts +1 -1
- package/dist/tools/research/inspect-run.js +7 -7
- package/dist/tools/research/searxng-engine.d.ts +40 -0
- package/dist/tools/research/searxng-engine.js +120 -0
- package/dist/tools/research/web-fetch.d.ts +124 -0
- package/dist/tools/research/web-fetch.js +627 -0
- package/dist/tools/research/web-search.d.ts +75 -0
- package/dist/tools/research/web-search.js +112 -0
- package/dist/tools/sandbox/list-available-packages.d.ts +7 -4
- package/dist/tools/sandbox/list-available-packages.js +12 -4
- package/dist/tools/sandbox/list-available-refs.d.ts +21 -0
- package/dist/tools/sandbox/list-available-refs.js +60 -3
- package/dist/tools/sandbox/report-blocker.js +5 -1
- package/dist/tools/terminal-text.d.ts +11 -0
- package/dist/tools/terminal-text.js +19 -0
- package/dist/tools/workspace/decision-record.d.ts +81 -0
- package/dist/tools/workspace/decision-record.js +117 -0
- package/dist/tools/workspace/edit-file.d.ts +3 -1
- package/dist/tools/workspace/edit-file.js +20 -2
- package/dist/tools/workspace/execute-command.d.ts +17 -0
- package/dist/tools/workspace/execute-command.js +28 -1
- package/dist/tools/workspace/index.d.ts +1 -0
- package/dist/tools/workspace/index.js +1 -0
- package/dist/tools/workspace/mutator.d.ts +1 -1
- package/dist/workflows/execute-analysis.d.ts +62 -21
- package/dist/workflows/execute-analysis.js +307 -79
- package/dist/workflows/plan/graph.d.ts +16 -0
- package/dist/workflows/plan/graph.js +36 -0
- package/dist/workflows/sandbox-step.d.ts +12 -0
- package/dist/workflows/sandbox-step.js +14 -12
- package/package.json +5 -1
|
@@ -17,6 +17,7 @@ import { ok } from "neverthrow";
|
|
|
17
17
|
import { z } from "zod";
|
|
18
18
|
import { defineTool, withToolCallRecord } from "../define-tool.js";
|
|
19
19
|
import { unwrapOrThrow } from "../../lib/result.js";
|
|
20
|
+
import { noteScriptChange, scriptSha256 } from "./decision-record.js";
|
|
20
21
|
const EditFileInputSchema = z.object({
|
|
21
22
|
path: z
|
|
22
23
|
.string()
|
|
@@ -172,6 +173,19 @@ export function createEditFileTool(deps) {
|
|
|
172
173
|
});
|
|
173
174
|
if (write.status !== "ok")
|
|
174
175
|
return ok(write);
|
|
176
|
+
// A rendered script carries a decision record. The edit is a change the curator did not vet, and the
|
|
177
|
+
// record keeps it with the digest after the change, thus an empty `unvetted_edits` stays a fact.
|
|
178
|
+
const noted = await noteScriptChange({
|
|
179
|
+
filesystem: deps.workspaceFilesystem,
|
|
180
|
+
mutator: deps.mutator,
|
|
181
|
+
session: ctx.session,
|
|
182
|
+
...(deps.workingDir !== undefined ? { workingDir: deps.workingDir } : {}),
|
|
183
|
+
invocationId: ctx.invocationId,
|
|
184
|
+
toolName: "edit_file",
|
|
185
|
+
scriptPath: path,
|
|
186
|
+
note: `edit_file: ${replaced.replacements} replacement(s)`,
|
|
187
|
+
sha256: scriptSha256(replaced.content),
|
|
188
|
+
});
|
|
175
189
|
const lines = replaced.lines;
|
|
176
190
|
return ok(withToolCallRecord({
|
|
177
191
|
status: "ok",
|
|
@@ -179,8 +193,12 @@ export function createEditFileTool(deps) {
|
|
|
179
193
|
replacements: replaced.replacements,
|
|
180
194
|
bytesWritten: write.bytesWritten,
|
|
181
195
|
...(lines === undefined ? {} : { lines }),
|
|
182
|
-
|
|
196
|
+
...(noted.status === "noted" ? { decision_record_noted: true } : {}),
|
|
197
|
+
}, noted.status === "noted" ? [write.record, noted.write] : [write.record]));
|
|
198
|
+
},
|
|
199
|
+
foldCallRecord: (records) => {
|
|
200
|
+
for (const record of records)
|
|
201
|
+
deps.mutator.recordWrite(record);
|
|
183
202
|
},
|
|
184
|
-
foldCallRecord: (record) => deps.mutator.recordWrite(record),
|
|
185
203
|
});
|
|
186
204
|
}
|
|
@@ -18,12 +18,20 @@
|
|
|
18
18
|
* `sandbox-provenance-tracking`), and artifact registration reconciles them.
|
|
19
19
|
* The frame of each exec rides the call record, and the fold feeds it to the
|
|
20
20
|
* lineage collector of the step.
|
|
21
|
+
*
|
|
22
|
+
* A script the command names that carries a decision record is compared
|
|
23
|
+
* with the digest the record expects before it runs. A difference is a
|
|
24
|
+
* change that no file tool recorded, and the record gets it with the digest
|
|
25
|
+
* of the bytes that run, thus the record connects the cited decision to the
|
|
26
|
+
* code that ran.
|
|
21
27
|
*/
|
|
22
28
|
import { type WithToolCallRecord } from "../define-tool.js";
|
|
23
29
|
import type { SandboxClient } from "../../sandbox/client.js";
|
|
24
30
|
import type { ProvenanceFrame, SandboxRef } from "../../sandbox/types.js";
|
|
25
31
|
import type { ProvenanceCollector } from "../../provenance/collector.js";
|
|
32
|
+
import type { WorkspaceMutator, WriteRecord } from "./mutator.js";
|
|
26
33
|
import { type BoundedExecResult } from "./result-bounds.js";
|
|
34
|
+
import type { WorkspaceFilesystem } from "../../workspace/filesystem.js";
|
|
27
35
|
import type { Logger } from "../../lib/logger.js";
|
|
28
36
|
/** What one exec leaves for the lineage collector of the step. */
|
|
29
37
|
interface ExecCallRecord {
|
|
@@ -31,6 +39,8 @@ interface ExecCallRecord {
|
|
|
31
39
|
readonly exitCode: number | null;
|
|
32
40
|
readonly durationMs: number | null;
|
|
33
41
|
readonly provenance?: ProvenanceFrame;
|
|
42
|
+
/** The decision-record writes of the script check before the exec, for the mutator. */
|
|
43
|
+
readonly recordWrites?: readonly WriteRecord[];
|
|
34
44
|
}
|
|
35
45
|
type ExecuteCommandResult = {
|
|
36
46
|
readonly status: "ok";
|
|
@@ -58,6 +68,13 @@ export interface ExecuteCommandDeps {
|
|
|
58
68
|
readonly lineageCollector?: ProvenanceCollector;
|
|
59
69
|
/** Analysis resource mount root (`/{resourceId}`) — strips frame paths to relative. */
|
|
60
70
|
readonly mountRoot?: string;
|
|
71
|
+
/**
|
|
72
|
+
* The workspace filesystem and the mutator of the step, for the record check of a
|
|
73
|
+
* script the command runs. Both absent (a read-only agent), no record is
|
|
74
|
+
* read or written.
|
|
75
|
+
*/
|
|
76
|
+
readonly workspaceFilesystem?: WorkspaceFilesystem;
|
|
77
|
+
readonly mutator?: WorkspaceMutator;
|
|
61
78
|
}
|
|
62
79
|
export declare function createExecuteCommandTool(deps: ExecuteCommandDeps): import("../define-tool.js").Tool<{
|
|
63
80
|
command: string[];
|
|
@@ -18,12 +18,19 @@
|
|
|
18
18
|
* `sandbox-provenance-tracking`), and artifact registration reconciles them.
|
|
19
19
|
* The frame of each exec rides the call record, and the fold feeds it to the
|
|
20
20
|
* lineage collector of the step.
|
|
21
|
+
*
|
|
22
|
+
* A script the command names that carries a decision record is compared
|
|
23
|
+
* with the digest the record expects before it runs. A difference is a
|
|
24
|
+
* change that no file tool recorded, and the record gets it with the digest
|
|
25
|
+
* of the bytes that run, thus the record connects the cited decision to the
|
|
26
|
+
* code that ran.
|
|
21
27
|
*/
|
|
22
28
|
import { posix as posixPath } from "node:path";
|
|
23
29
|
import { ok } from "neverthrow";
|
|
24
30
|
import { z } from "zod";
|
|
25
31
|
import { defineTool, withToolCallRecord } from "../define-tool.js";
|
|
26
32
|
import { feedExecFrame } from "../../provenance/exec-frame.js";
|
|
33
|
+
import { reconcileScriptRecord } from "./decision-record.js";
|
|
27
34
|
import { EXEC_STREAM_BYTE_CAP, boundExecResult } from "./result-bounds.js";
|
|
28
35
|
import { runSandboxExec } from "./run-exec.js";
|
|
29
36
|
import { createNoopLogger } from "../../lib/console-logger.js";
|
|
@@ -86,6 +93,23 @@ export function createExecuteCommandTool(deps) {
|
|
|
86
93
|
describeCall: ({ command }) => scriptToken(command) ?? command.join(" "),
|
|
87
94
|
execute: async ({ command, cwd, env, timeoutSeconds }, ctx) => {
|
|
88
95
|
const effectiveCwd = cwd === undefined ? defaultCwd : cwd.startsWith("/") ? cwd : posixPath.join(defaultCwd, cwd);
|
|
96
|
+
// Each script the argv names, as the sandbox resolves it. A relative token resolves against the cwd of the
|
|
97
|
+
// command, which is a `/{analysisId}/...` path, thus the workspace filesystem resolves it the same way.
|
|
98
|
+
const recordWrites = [];
|
|
99
|
+
if (deps.workspaceFilesystem && deps.mutator) {
|
|
100
|
+
for (const token of command.filter((arg) => SCRIPT_EXTENSIONS.test(arg))) {
|
|
101
|
+
const noted = await reconcileScriptRecord({
|
|
102
|
+
filesystem: deps.workspaceFilesystem,
|
|
103
|
+
mutator: deps.mutator,
|
|
104
|
+
session: ctx.session,
|
|
105
|
+
invocationId: ctx.invocationId,
|
|
106
|
+
toolName: "execute_command",
|
|
107
|
+
scriptPath: token.startsWith("/") ? token : posixPath.join(effectiveCwd, token),
|
|
108
|
+
});
|
|
109
|
+
if (noted.status === "noted")
|
|
110
|
+
recordWrites.push(noted.write);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
89
113
|
const result = await runSandboxExec({
|
|
90
114
|
sandboxClient,
|
|
91
115
|
sandbox,
|
|
@@ -97,18 +121,21 @@ export function createExecuteCommandTool(deps) {
|
|
|
97
121
|
emit: ctx.emit,
|
|
98
122
|
});
|
|
99
123
|
const bounded = { status: "ok", ...boundExecResult(result) };
|
|
100
|
-
if (!lineageCollector || !mountRoot)
|
|
124
|
+
if ((!lineageCollector || !mountRoot) && recordWrites.length === 0)
|
|
101
125
|
return ok(bounded);
|
|
102
126
|
const record = {
|
|
103
127
|
command,
|
|
104
128
|
exitCode: result.exitCode,
|
|
105
129
|
durationMs: result.durationMs,
|
|
106
130
|
...(result.provenance ? { provenance: result.provenance } : {}),
|
|
131
|
+
...(recordWrites.length > 0 ? { recordWrites } : {}),
|
|
107
132
|
};
|
|
108
133
|
return ok(withToolCallRecord(bounded, record));
|
|
109
134
|
},
|
|
110
135
|
// Best-effort: a collector failure must never fail the exec.
|
|
111
136
|
foldCallRecord: (record) => {
|
|
137
|
+
for (const write of record.recordWrites ?? [])
|
|
138
|
+
deps.mutator?.recordWrite(write);
|
|
112
139
|
if (!lineageCollector || !mountRoot)
|
|
113
140
|
return;
|
|
114
141
|
try {
|
|
@@ -21,5 +21,6 @@ export * from "./mutator.js";
|
|
|
21
21
|
export * from "./execute-command.js";
|
|
22
22
|
export * from "./write-file.js";
|
|
23
23
|
export * from "./edit-file.js";
|
|
24
|
+
export * from "./decision-record.js";
|
|
24
25
|
export { EXEC_STREAM_BYTE_CAP, boundExecResult } from "./result-bounds.js";
|
|
25
26
|
export type { BoundedExecResult } from "./result-bounds.js";
|
|
@@ -80,7 +80,7 @@ export type WriteOutcome = {
|
|
|
80
80
|
* (`inflexa:tool` in the signed document) — the seam records the write without
|
|
81
81
|
* inspecting its caller.
|
|
82
82
|
*/
|
|
83
|
-
export type MutateToolName = "write_file" | "edit_file";
|
|
83
|
+
export type MutateToolName = "write_file" | "edit_file" | "knowledge_template" | "execute_command";
|
|
84
84
|
export interface WorkspaceMutatorDeps {
|
|
85
85
|
/** Absolute host root of this analysis's workspace tree — used by the resolver. */
|
|
86
86
|
readonly workspaceRoot: string;
|
|
@@ -50,20 +50,25 @@
|
|
|
50
50
|
* the run before any step starts
|
|
51
51
|
* - a `suspend` error of a synthesis model request suspends the run in
|
|
52
52
|
* place of the synthesis failure
|
|
53
|
-
* - the analysis
|
|
54
|
-
* `collectAndComplete`. The
|
|
53
|
+
* - the run row and the analysis flip to `suspended_insufficient_funds` in
|
|
54
|
+
* `collectAndComplete`. The run status is terminal and does not block a
|
|
55
|
+
* new run of the plan. The paused parent lands in `CANCELLED`, a
|
|
55
56
|
* durably reschedulable state; re-driving it is a future enhancement,
|
|
56
57
|
* not yet wired here. The reason of the host rides to the run row, the
|
|
57
58
|
* charge close, the metric, and the terminal part, unread.
|
|
58
59
|
* 5. `synthesizeFindings` (single sequential block, no sandbox)
|
|
59
60
|
* 6. `collectAndComplete` (terminal — runs on ALL paths)
|
|
60
61
|
* - determine final status from completed/cancelled/failed counts
|
|
61
|
-
* - update `cortex_runs.status` + `error
|
|
62
|
-
* the
|
|
63
|
-
*
|
|
64
|
-
* died before
|
|
65
|
-
*
|
|
66
|
-
*
|
|
62
|
+
* - update `cortex_runs.status` + `error`. When the write changes the row,
|
|
63
|
+
* the same step emits `run_completed` before the commit, records the run
|
|
64
|
+
* outcome metric plus the outcome of every settled step whose child never
|
|
65
|
+
* wrote its own terminal row (a cancelled child, or one that died before
|
|
66
|
+
* `failStep`), closes the running charge with the matching outcome, and
|
|
67
|
+
* revokes the run authorization through the injected `runAuthorizer`
|
|
68
|
+
* - the write retries with backoff on a failed transaction. When the write is
|
|
69
|
+
* refused, or fails on each attempt, close and revoke in their own steps, then
|
|
70
|
+
* emit `run_completed`. After a failed write the row stays `running`, so the
|
|
71
|
+
* body records its run end as a workflow event for the run canceler
|
|
67
72
|
* - emit terminal stream part
|
|
68
73
|
* - WRITES NOTHING to the conversation thread (results are pull-only
|
|
69
74
|
* via `inspectRun`)
|
|
@@ -81,6 +86,8 @@ import type { WorkingMemoryStore } from "../memory/working-memory.js";
|
|
|
81
86
|
import type { AnalysisStep } from "../schemas/workflow-state.js";
|
|
82
87
|
import type { ChatProvider, EmbeddingProvider } from "../providers/types.js";
|
|
83
88
|
import type { BioToolKeys } from "../tools/bio/keys.js";
|
|
89
|
+
import type { KnowledgeClient } from "../tools/knowledge/client.js";
|
|
90
|
+
import type { TemplateBinding } from "../tools/knowledge/template.js";
|
|
84
91
|
import type { ProvenanceSeam } from "../provenance/seam.js";
|
|
85
92
|
import type { ToolOutputStore } from "../loop/tool-output.js";
|
|
86
93
|
import type { RunCharge } from "../billing/run-charge.js";
|
|
@@ -160,7 +167,7 @@ export interface ExecuteAnalysisInput {
|
|
|
160
167
|
* path returns — the caller joined an in-flight run, no new workflow was
|
|
161
168
|
* started. Every other variant is a terminal status the parent reached.
|
|
162
169
|
*/
|
|
163
|
-
export type ExecuteAnalysisFinalStatus = "running" | "completed" | "partial" | "failed" | "canceled";
|
|
170
|
+
export type ExecuteAnalysisFinalStatus = "running" | "completed" | "partial" | "failed" | "canceled" | "suspended_insufficient_funds";
|
|
164
171
|
export interface ExecuteAnalysisResult {
|
|
165
172
|
readonly runId: string;
|
|
166
173
|
readonly workflowId: string;
|
|
@@ -255,16 +262,27 @@ export interface ExecuteAnalysisDeps {
|
|
|
255
262
|
* carries the goal and the constraints as they are at the dispatch of that step.
|
|
256
263
|
*/
|
|
257
264
|
readonly workingMemory: WorkingMemoryStore;
|
|
265
|
+
/**
|
|
266
|
+
* The knowledge client of the composition, when the embedder binds one.
|
|
267
|
+
* The seed composition reads the contract of the template a grounded step
|
|
268
|
+
* renders through it, and binds the plan settings to that contract.
|
|
269
|
+
* Absent, the seed says the contract was not retrieved, and the step agent
|
|
270
|
+
* learns the slots from the render answers alone.
|
|
271
|
+
*/
|
|
272
|
+
readonly knowledge?: KnowledgeClient;
|
|
258
273
|
/**
|
|
259
274
|
* The provenance seam of the composition. The body reads its run emit member,
|
|
260
275
|
* and it reads no other member.
|
|
261
276
|
*
|
|
262
|
-
*
|
|
263
|
-
* in `DBOS.runStep`) so that body re-execution on DBOS recovery
|
|
264
|
-
* a cached step would suppress the recovery re-emission
|
|
265
|
-
*
|
|
266
|
-
*
|
|
267
|
-
*
|
|
277
|
+
* `run_started` and `step_completed` are emitted directly in the workflow body
|
|
278
|
+
* (NOT wrapped in `DBOS.runStep`) so that body re-execution on DBOS recovery
|
|
279
|
+
* re-fires them — a cached step would suppress the recovery re-emission.
|
|
280
|
+
* `run_completed` is emitted by the won `persist-final-status` step, or by the
|
|
281
|
+
* body after that step when the step did not emit in this execution (a refused
|
|
282
|
+
* or failed write, or a won step served from the DBOS cache), so a recovery
|
|
283
|
+
* replay still fires it. Idempotency is the consumer's job, achieved via the
|
|
284
|
+
* deterministic identifiers the events carry, not via step caching. Every call
|
|
285
|
+
* site is guarded so a throwing observer never fails the run.
|
|
268
286
|
*
|
|
269
287
|
* Events arrive with the run's `RunSession` from durable workflow input — a
|
|
270
288
|
* persisting realization needs its credential, scope, and identity.
|
|
@@ -306,6 +324,7 @@ export declare function buildChildInput(args: {
|
|
|
306
324
|
runId: string;
|
|
307
325
|
workflowId: string;
|
|
308
326
|
prompt: string;
|
|
327
|
+
templateBinding?: TemplateBinding;
|
|
309
328
|
}): Omit<SandboxStepInput, "runSession">;
|
|
310
329
|
/**
|
|
311
330
|
* Compose one step's seed — the user-content message its agent opens on.
|
|
@@ -316,17 +335,26 @@ export declare function buildChildInput(args: {
|
|
|
316
335
|
* rendered any earlier (at plan submission, say) cannot mention them, and the
|
|
317
336
|
* agent is left to rediscover its own upstream.
|
|
318
337
|
*
|
|
319
|
-
*
|
|
320
|
-
*
|
|
321
|
-
*
|
|
322
|
-
*
|
|
338
|
+
* The template contract of a grounded step is read with the package, and the
|
|
339
|
+
* plan settings are bound to it: the seed describes the binding, and the child
|
|
340
|
+
* input carries it, from one checkpoint. The child fetches nothing.
|
|
341
|
+
*
|
|
342
|
+
* REPLAY: the caller wraps this in a `DBOS.runStep`, so the composed seed is
|
|
343
|
+
* checkpointed and a replay returns it verbatim — the DB, the disk, and the
|
|
344
|
+
* knowledge service are not read again and cannot drift the seed under a
|
|
345
|
+
* recovered run. Never call it unwrapped from the workflow body.
|
|
323
346
|
*/
|
|
324
347
|
export declare function composeStepSeed(args: {
|
|
325
348
|
input: ExecuteAnalysisInput;
|
|
326
349
|
stepId: string;
|
|
327
350
|
runId: string;
|
|
328
351
|
deps: ExecuteAnalysisDeps;
|
|
329
|
-
}): Promise<
|
|
352
|
+
}): Promise<StepSeed>;
|
|
353
|
+
/** What `gatherStepPackage` gives: the data of the seed, and the binding of the plan settings when one holds. */
|
|
354
|
+
export interface StepPackage {
|
|
355
|
+
readonly briefing: StepBriefing;
|
|
356
|
+
readonly templateBinding?: TemplateBinding;
|
|
357
|
+
}
|
|
330
358
|
/**
|
|
331
359
|
* Do every read of one step's package and give the data its seed is rendered
|
|
332
360
|
* from. All reads live here, so `composeStepBriefing` stays a pure renderer.
|
|
@@ -339,6 +367,9 @@ export declare function composeStepSeed(args: {
|
|
|
339
367
|
* so an edit during a run reaches each later step, and two steps of one run
|
|
340
368
|
* can carry different copies.
|
|
341
369
|
*
|
|
370
|
+
* The contract of the template a grounded step renders is read here too, from
|
|
371
|
+
* the knowledge client, and the plan settings are bound to it.
|
|
372
|
+
*
|
|
342
373
|
* A read failure throws (house rules): a swallowed error would be frozen into
|
|
343
374
|
* the checkpointed seed and served to every replay of this step.
|
|
344
375
|
*/
|
|
@@ -347,7 +378,17 @@ export declare function gatherStepPackage(args: {
|
|
|
347
378
|
stepId: string;
|
|
348
379
|
runId: string;
|
|
349
380
|
deps: ExecuteAnalysisDeps;
|
|
350
|
-
}): Promise<
|
|
381
|
+
}): Promise<StepPackage>;
|
|
382
|
+
/**
|
|
383
|
+
* What `composeStepSeed` checkpoints: the seed, and the binding of the plan
|
|
384
|
+
* settings to the template of the step when the contract was retrieved and
|
|
385
|
+
* its served version is the version the plan names. JSON-serialisable, as a
|
|
386
|
+
* durable step result must be.
|
|
387
|
+
*/
|
|
388
|
+
export interface StepSeed {
|
|
389
|
+
readonly prompt: string;
|
|
390
|
+
readonly templateBinding?: TemplateBinding;
|
|
391
|
+
}
|
|
351
392
|
/**
|
|
352
393
|
* Project a classified synthesis outcome onto the run-phase `synthesis` ledger
|
|
353
394
|
* row's terminal update (see the run-synthesis-outcome spec). The blocker keeps
|