@parcha/agentrun-pi 0.1.0-beta.2 → 0.1.0-beta.21
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 +123 -32
- package/dist/cli.js +15 -4
- package/dist/demo-cli.d.ts +2 -0
- package/dist/demo-cli.js +25 -0
- package/dist/demo.js +1 -0
- package/dist/durable/decision-recovery.d.ts +23 -0
- package/dist/durable/decision-recovery.js +57 -0
- package/dist/durable/decisions.d.ts +113 -0
- package/dist/durable/decisions.js +71 -0
- package/dist/durable/index.d.ts +20 -0
- package/dist/durable/index.js +14 -0
- package/dist/durable/node-runner.d.ts +106 -0
- package/dist/durable/node-runner.js +253 -0
- package/dist/durable/node.d.ts +88 -0
- package/dist/durable/node.js +98 -0
- package/dist/durable/pi-versions.d.ts +34 -0
- package/dist/durable/pi-versions.js +66 -0
- package/dist/durable/readers.d.ts +28 -0
- package/dist/durable/readers.js +103 -0
- package/dist/durable/receipts.d.ts +54 -0
- package/dist/durable/receipts.js +92 -0
- package/dist/durable/record-file.d.ts +10 -0
- package/dist/durable/record-file.js +56 -0
- package/dist/durable/record-tool.d.ts +76 -0
- package/dist/durable/record-tool.js +123 -0
- package/dist/durable/record.d.ts +157 -0
- package/dist/durable/record.js +402 -0
- package/dist/durable/recording.d.ts +90 -0
- package/dist/durable/recording.js +292 -0
- package/dist/durable/store.d.ts +23 -0
- package/dist/durable/store.js +242 -0
- package/dist/durable/task.d.ts +133 -0
- package/dist/durable/task.js +411 -0
- package/dist/durable/workflow-tool.d.ts +32 -0
- package/dist/durable/workflow-tool.js +188 -0
- package/dist/extension-service.js +63 -22
- package/dist/extension.d.ts +2 -0
- package/dist/extension.js +463 -80
- package/dist/host-addendum.d.ts +4 -0
- package/dist/host-addendum.js +20 -0
- package/dist/host-session.js +5 -2
- package/dist/index.d.ts +1 -2
- package/dist/index.js +1 -2
- package/dist/pi-host.d.ts +7 -0
- package/dist/pi-host.js +22 -0
- package/dist/presentation.js +2 -2
- package/dist/run-error.d.ts +6 -0
- package/dist/run-error.js +13 -0
- package/dist/runner.d.ts +1 -6
- package/dist/runner.js +7 -13
- package/dist/signin/index.d.ts +9 -0
- package/dist/signin/index.js +7 -0
- package/dist/signin/limit.d.ts +10 -0
- package/dist/signin/limit.js +23 -0
- package/dist/signin/resolve.d.ts +47 -0
- package/dist/signin/resolve.js +163 -0
- package/dist/signin/signin.d.ts +44 -0
- package/dist/signin/signin.js +126 -0
- package/dist/signin/spec.d.ts +116 -0
- package/dist/signin/spec.js +181 -0
- package/dist/signin/store.d.ts +40 -0
- package/dist/signin/store.js +206 -0
- package/dist/skills/author/SKILL.md +138 -0
- package/{skills → dist/skills}/author/references/jev-decisions.md +27 -14
- package/dist/skills/author/references/language.md +134 -0
- package/dist/skills/author/references/sdk-authoring.md +11 -0
- package/{skills → dist/skills}/author/references/workflow-format.md +7 -15
- package/dist/sop.d.ts +12 -0
- package/dist/sop.js +29 -0
- package/dist/thinking.d.ts +3 -0
- package/dist/thinking.js +7 -0
- package/dist/tool-context.d.ts +21 -0
- package/dist/tool-context.js +13 -0
- package/dist/triage-demo.d.ts +62 -0
- package/dist/triage-demo.js +153 -0
- package/dist/types.d.ts +7 -0
- package/dist/workflow-inspector.d.ts +47 -0
- package/dist/workflow-inspector.js +235 -0
- package/dist/workflow-session.d.ts +23 -0
- package/dist/workflow-session.js +168 -0
- package/dist/workflow-store.d.ts +36 -0
- package/dist/workflow-store.js +255 -0
- package/dist/workflow-tool.d.ts +81 -0
- package/dist/workflow-tool.js +94 -0
- package/dist/workflow-view.d.ts +64 -0
- package/dist/workflow-view.js +273 -0
- package/dist/workflows.d.ts +1 -0
- package/dist/workflows.js +3 -0
- package/package.json +57 -11
- package/dist/admission.d.ts +0 -6
- package/dist/admission.js +0 -51
- package/dist/author.d.ts +0 -21
- package/dist/author.js +0 -72
- package/dist/benchmark-contract.d.ts +0 -88
- package/dist/benchmark-contract.js +0 -50
- package/dist/benchmark-freeze.d.ts +0 -9
- package/dist/benchmark-freeze.js +0 -9
- package/dist/benchmark.d.ts +0 -127
- package/dist/benchmark.js +0 -260
- package/dist/comparison.d.ts +0 -69
- package/dist/comparison.js +0 -229
- package/dist/skill-bundle.d.ts +0 -5
- package/dist/skill-bundle.js +0 -15
- package/skills/author/SKILL.md +0 -102
- package/skills/author/references/sdk-authoring.md +0 -16
- /package/{skills → dist/skills}/author/examples/evidence-gate.input.json +0 -0
- /package/{skills → dist/skills}/author/examples/evidence-gate.json +0 -0
- /package/{skills → dist/skills}/author/examples/read-file.input.json +0 -0
- /package/{skills → dist/skills}/author/examples/read-file.json +0 -0
- /package/{skills → dist/skills}/author/examples/read-source-decision.input.json +0 -0
- /package/{skills → dist/skills}/author/examples/read-source-decision.json +0 -0
- /package/{skills → dist/skills}/author/examples/release-note.txt +0 -0
- /package/{skills → dist/skills}/author/examples/review-release-notes.input.json +0 -0
- /package/{skills → dist/skills}/author/examples/review-release-notes.json +0 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { defineDoc, defineTool, GenerationTask, hook, } from "@earendil-works/pi-durable";
|
|
2
|
+
import { DELIVERY_ATTEMPTS, deliver, deliveryTerminates, deliveryText, fileSubmission, mixedFileSubmission, nudgeText, repairRecord, VIOLATIONS_SHOWN, } from "./record.js";
|
|
3
|
+
import { toolResult } from "./pi-versions.js";
|
|
4
|
+
/** The record a conversation delivered, or null while it has not, and the delivery attempts it has spent. */
|
|
5
|
+
export const RecordDoc = defineDoc({
|
|
6
|
+
kind: "agentrun.record", version: 1, scope: "conversation", history: "latest", fork: "initial", initial: () => ({ record: null, attempts: 0 }),
|
|
7
|
+
});
|
|
8
|
+
/** The gate's own state beside the record: whether the second reading's round was spent, and what it still
|
|
9
|
+
* disagreed with in the delivered record. */
|
|
10
|
+
export const GateDoc = defineDoc({
|
|
11
|
+
kind: "agentrun.gate", version: 1, scope: "conversation", history: "latest", fork: "initial", initial: () => ({ bounced: false, disagreements: [] }),
|
|
12
|
+
});
|
|
13
|
+
/** Where `prepareArguments` carries a call's arguments to `execute`. A record's own fields are never read as it. */
|
|
14
|
+
const RAW = "_raw";
|
|
15
|
+
/** The core's store on a conversation's two documents, written through a tool call's commits. */
|
|
16
|
+
export function recordStore(api, context) {
|
|
17
|
+
const id = api.conversationId;
|
|
18
|
+
return {
|
|
19
|
+
read: async () => ({
|
|
20
|
+
record: (await api.snapshot(RecordDoc, id, context)) ?? { record: null, attempts: 0 },
|
|
21
|
+
gate: (await api.snapshot(GateDoc, id, context)) ?? { bounced: false, disagreements: [] },
|
|
22
|
+
}),
|
|
23
|
+
reject: () => api.commit(async (tx) => { const state = await tx.doc(RecordDoc, id); state.attempts += 1; return state.attempts; }, context),
|
|
24
|
+
bounce: () => api.commit(async (tx) => {
|
|
25
|
+
(await tx.doc(GateDoc, id)).bounced = true;
|
|
26
|
+
const state = await tx.doc(RecordDoc, id);
|
|
27
|
+
state.attempts += 1;
|
|
28
|
+
return state.attempts;
|
|
29
|
+
}, context),
|
|
30
|
+
accept: (record, disagreements) => api.commit(async (tx) => {
|
|
31
|
+
const state = await tx.doc(RecordDoc, id);
|
|
32
|
+
state.record = record;
|
|
33
|
+
state.attempts += 1;
|
|
34
|
+
if (disagreements.length)
|
|
35
|
+
(await tx.doc(GateDoc, id)).disagreements = disagreements;
|
|
36
|
+
}, context),
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/** The record a conversation delivered, or undefined while it has not, with what its second reading still disagreed with. */
|
|
40
|
+
export async function deliveredRecord(reader, conversationId, context) {
|
|
41
|
+
const state = await reader.snapshot(RecordDoc, conversationId, context);
|
|
42
|
+
if (state?.record == null)
|
|
43
|
+
return undefined;
|
|
44
|
+
return { record: state.record, disagreements: [...((await reader.snapshot(GateDoc, conversationId, context))?.disagreements ?? [])] };
|
|
45
|
+
}
|
|
46
|
+
/** The `submit` tool as a model is shown it for one record: what it delivers, and the record's top-level fields with
|
|
47
|
+
* their plain types and descriptions, none required, since a partial record is an attempt the core counts. A record
|
|
48
|
+
* that may be delivered as a workspace file is offered the envelope under `fileKey`. */
|
|
49
|
+
export function submitDefinition(record) {
|
|
50
|
+
const { schema, label, fileKey } = record;
|
|
51
|
+
const declared = schema.properties && typeof schema.properties === "object" ? schema.properties : {};
|
|
52
|
+
return {
|
|
53
|
+
description: fileKey
|
|
54
|
+
? `Deliver ${label}. Submit it inline, or for a large record write JSON in the workspace and pass {"${fileKey}":"relative/path.json"}. It ends the run. These parameters are the output schema: submit validates the record against it and returns the violations to fix, up to ${VIOLATIONS_SHOWN} per call, so there is no schema file to find and no need to validate the record yourself first.`
|
|
55
|
+
: `Deliver ${label}. Submit it inline as the tool arguments. It ends the run. These parameters are the output schema: submit validates the record against it and returns the violations to fix, up to ${VIOLATIONS_SHOWN} per call.`,
|
|
56
|
+
parameters: { type: "object", additionalProperties: true, properties: {
|
|
57
|
+
...Object.fromEntries(Object.entries(declared).filter(([key]) => key !== RAW).map(([key, property]) => [key, { ...(typeof property?.type === "string" ? { type: property.type } : {}), ...(typeof property?.description === "string" ? { description: property.description } : {}) }])),
|
|
58
|
+
...(fileKey ? { [fileKey]: { type: "string", description: "Workspace-relative path to the complete JSON record" } } : {})
|
|
59
|
+
} },
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
/** A call's arguments as the core decides them: a file submission as it is, an inline record repaired as a transport
|
|
63
|
+
* spelling. The reserved file key beside inline fields is the transport's, never the record's. */
|
|
64
|
+
function carried(args, schema, fileKey) {
|
|
65
|
+
if (fileKey && (fileSubmission(args, fileKey) !== null || mixedFileSubmission(args, schema, fileKey)))
|
|
66
|
+
return args;
|
|
67
|
+
const inline = fileKey && args && typeof args === "object" && !Array.isArray(args) ? (({ [fileKey]: _reserved, ...rest }) => rest)(args) : args;
|
|
68
|
+
return repairRecord(inline, schema);
|
|
69
|
+
}
|
|
70
|
+
/** The `submit` tool. */
|
|
71
|
+
export function recordTool(options) {
|
|
72
|
+
const { record } = options;
|
|
73
|
+
const shown = record ? submitDefinition(record) : { description: "Deliver the record. It ends the run.", parameters: { type: "object", additionalProperties: true } };
|
|
74
|
+
const answer = (delivery, maxAttempts) => toolResult([{ type: "text", text: deliveryText(delivery, maxAttempts, options.say) }], {
|
|
75
|
+
...(delivery.status === "rejected" || delivery.status === "bounced" ? { isError: true } : {}),
|
|
76
|
+
...(deliveryTerminates(delivery) ? { control: { terminate: true } } : {}),
|
|
77
|
+
});
|
|
78
|
+
return defineTool({
|
|
79
|
+
name: "submit",
|
|
80
|
+
description: shown.description,
|
|
81
|
+
parameters: shown.parameters,
|
|
82
|
+
// Every call's arguments are carried to `execute`; one record's are repaired here, before the Harness validates.
|
|
83
|
+
prepareArguments: (args) => ({ [RAW]: record ? carried(args, record.schema, record.fileKey) : args }),
|
|
84
|
+
replay: "safe",
|
|
85
|
+
executionMode: "sequential",
|
|
86
|
+
execute: async (args, api, context) => {
|
|
87
|
+
try {
|
|
88
|
+
const contract = await options.contract(api, context);
|
|
89
|
+
const raw = args[RAW];
|
|
90
|
+
const delivery = await deliver({ ...contract, ...(options.fatal ? { fatal: options.fatal } : {}) }, recordStore(api, context), record ? raw : carried(raw, contract.schema, contract.file?.key));
|
|
91
|
+
await options.onDelivery?.(delivery, api.conversationId);
|
|
92
|
+
return answer(delivery, contract.maxAttempts ?? DELIVERY_ATTEMPTS);
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
if (!options.fatal?.(error))
|
|
96
|
+
throw error;
|
|
97
|
+
options.onFatal?.(error, api.conversationId);
|
|
98
|
+
return toolResult([{ type: "text", text: options.fatalText ?? "The run cannot record this submission; the run stops." }], { isError: true, control: { terminate: true } });
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
/** The nudge: a yield with the record still owed continues the run with a reminder, each nudge one delivery attempt;
|
|
104
|
+
* past the attempts the run ends. The nudge that spends the last attempt still continues, so the model is asked once
|
|
105
|
+
* more after it. */
|
|
106
|
+
export function recordNudge(options) {
|
|
107
|
+
return hook(GenerationTask, {
|
|
108
|
+
onYield: async (_answer, api, context) => {
|
|
109
|
+
const state = await api.snapshot(RecordDoc, api.conversationId, context);
|
|
110
|
+
if (state?.record != null)
|
|
111
|
+
return undefined;
|
|
112
|
+
const label = await options.label(api, context);
|
|
113
|
+
if (label === undefined || (state?.attempts ?? 0) >= (options.maxAttempts ?? DELIVERY_ATTEMPTS))
|
|
114
|
+
return undefined;
|
|
115
|
+
await options.spend(api.conversationId, context);
|
|
116
|
+
return { continue: nudgeText(label) };
|
|
117
|
+
},
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
/** One nudge's delivery attempt, as a commit on the conversation's record. */
|
|
121
|
+
export const spendNudge = async (tx, conversationId) => {
|
|
122
|
+
(await tx.doc(RecordDoc, conversationId)).attempts += 1;
|
|
123
|
+
};
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/** The record a node delivered, or null while it has not, and the delivery attempts it has spent. */
|
|
2
|
+
export type RecordState = {
|
|
3
|
+
record: unknown;
|
|
4
|
+
attempts: number;
|
|
5
|
+
};
|
|
6
|
+
/** What the second reading disagrees with in a record: its question, the kind of reading, the verdict and why. */
|
|
7
|
+
export type Disagreement = {
|
|
8
|
+
id: string;
|
|
9
|
+
kind: string;
|
|
10
|
+
verdict: string;
|
|
11
|
+
reasons: string[];
|
|
12
|
+
};
|
|
13
|
+
/** Whether the second reading's round was spent, and what it still disagreed with in the delivered record. */
|
|
14
|
+
export type GateState = {
|
|
15
|
+
bounced: boolean;
|
|
16
|
+
disagreements: Disagreement[];
|
|
17
|
+
};
|
|
18
|
+
/** Delivery attempts a node gets: rejections, the second reading's one bounce and nudges, each once. */
|
|
19
|
+
export declare const DELIVERY_ATTEMPTS = 6;
|
|
20
|
+
/** The most schema violations one rejected delivery lists; the submit tool's description tells the model the number. */
|
|
21
|
+
export declare const VIOLATIONS_SHOWN = 8;
|
|
22
|
+
/** One reviewer's reading of a structurally valid record. `no_verdict` is a reviewer that could not answer. */
|
|
23
|
+
export type Reading = "disagrees" | "agrees" | "no_verdict";
|
|
24
|
+
/** The second reading on one structurally valid submission: it sends the record back only while its round
|
|
25
|
+
* is unspent and a reviewer disagrees. A reviewer with no verdict never sends a record back. */
|
|
26
|
+
export declare function gate(bounced: boolean, readings: readonly Reading[]): "accept" | "bounce";
|
|
27
|
+
/** What a node is answered with. Only `delivered` is a delivery; each of the others spends one attempt. */
|
|
28
|
+
export type DeliveryEvent = "rejected" | "bounce" | "nudge" | "delivered";
|
|
29
|
+
/** A node's delivery, as far as the attempts count it. */
|
|
30
|
+
export type DeliveryCount = {
|
|
31
|
+
attempts: number;
|
|
32
|
+
delivered: boolean;
|
|
33
|
+
};
|
|
34
|
+
/** Whether a node's delivery has ended: it delivered, or its attempts are spent. */
|
|
35
|
+
export declare const deliveryEnded: (max: number, state: DeliveryCount) => boolean;
|
|
36
|
+
/** One answer applied to the count. An ended delivery takes no further answer; every other answer counts once. */
|
|
37
|
+
export declare function spend(max: number, state: DeliveryCount, event: DeliveryEvent): DeliveryCount;
|
|
38
|
+
/** What makes a schema one no `submit` call can satisfy: a call's arguments are an object, so the schema must be a
|
|
39
|
+
* JSON Schema object whose root type, when it names one, admits an object. A node runner refuses such a schema
|
|
40
|
+
* before any conversation exists. */
|
|
41
|
+
export declare function lintRecordRoot(schema: unknown): string[];
|
|
42
|
+
/** What an author should fix in a record schema, for a host or a validator to report: the root findings above, and
|
|
43
|
+
* a schema that declares its fields and requires one that is not among them, which the tool's shown fields never
|
|
44
|
+
* name. A record of the second kind can still be delivered (the tool's parameters are open, and the delivery
|
|
45
|
+
* contract that ends the node's task carries the schema with its `required`), so a runner does not refuse it. A
|
|
46
|
+
* schema that declares no `properties` is not held to it. */
|
|
47
|
+
export declare function lintRecordSchema(schema: unknown): string[];
|
|
48
|
+
/** Where the schema expects an object or an array and the submitted value is a string that parses to one, the
|
|
49
|
+
* parsed value; where it expects a number, an integer, a boolean or null and admits no string, the scalar a
|
|
50
|
+
* string spells. Some model families serialise nested tool arguments as strings: the content is valid and
|
|
51
|
+
* every submit fails on its spelling. A string that parses to a container the field also admits is read as that
|
|
52
|
+
* container; only against a scalar does a field that admits a string keep the string. */
|
|
53
|
+
export declare function parseStringifiedContainers(value: unknown, schema: Record<string, unknown> | undefined, depth?: number, rootDefinitions?: Record<string, unknown>): unknown;
|
|
54
|
+
/** The path of every string that spells "no value" in a field whose schema admits JSON null. */
|
|
55
|
+
export declare function nullSpellings(value: unknown, schema: unknown, root?: unknown, at?: string): string[];
|
|
56
|
+
/** The record with every such string replaced by JSON null, in place. A repair the record as a whole refuses
|
|
57
|
+
* (it satisfied its schema before and does not after) is undone in full, so a spelling stays only where null
|
|
58
|
+
* is inadmissible; `undo: false` leaves that judgement to a caller that repairs more of the record and judges the
|
|
59
|
+
* whole. `""` is a value and stays. */
|
|
60
|
+
export declare function healNullSpellings<T>(record: T, schema: Record<string, unknown>, options?: {
|
|
61
|
+
undo?: boolean;
|
|
62
|
+
}): T;
|
|
63
|
+
/** A record's transport spellings repaired against its schema, without touching `args`. */
|
|
64
|
+
export declare function repairRecord(args: unknown, schema: Record<string, unknown>): unknown;
|
|
65
|
+
/** The file a submission names and nothing else: `{ <key>: "relative/path.json" }`. */
|
|
66
|
+
export declare function fileSubmission(args: unknown, key: string): string | null;
|
|
67
|
+
/** A submission with fields beside the file key. Fields that form a whole record on their own are that record;
|
|
68
|
+
* otherwise the file holds the record, and each field beside it may only restate the file's value. A schema
|
|
69
|
+
* that declares the file key as its own field keeps it inline. */
|
|
70
|
+
export declare function mixedFileSubmission(args: unknown, schema: Record<string, unknown> | undefined, key: string): {
|
|
71
|
+
file: string;
|
|
72
|
+
extras: Record<string, unknown>;
|
|
73
|
+
} | null;
|
|
74
|
+
/** The fields beside the file key that the file's record does not hold with the same value. */
|
|
75
|
+
export declare function extrasNotInRecord(record: unknown, extras: Record<string, unknown>): string[];
|
|
76
|
+
/** One host check's refusal of a candidate: the problems the model must fix, and the reason they are grouped under. */
|
|
77
|
+
export type Refusal = {
|
|
78
|
+
problems: string[];
|
|
79
|
+
reason?: string;
|
|
80
|
+
};
|
|
81
|
+
/** A second reader of a structurally valid record. It returns what it disagrees with (nothing when it agrees or
|
|
82
|
+
* has no verdict). `round` says whether a disagreement still sends the record back. A reviewer that throws
|
|
83
|
+
* decides nothing, unless the contract's `fatal` claims the error. */
|
|
84
|
+
export type Reviewer = (candidate: unknown, context: {
|
|
85
|
+
round: boolean;
|
|
86
|
+
}) => Disagreement[] | Promise<Disagreement[]>;
|
|
87
|
+
export type RecordContract = {
|
|
88
|
+
/** The node's record schema, the `submit` tool's contract. */
|
|
89
|
+
schema: Record<string, unknown>;
|
|
90
|
+
/** Delivery attempts the node gets (default `DELIVERY_ATTEMPTS`). */
|
|
91
|
+
maxAttempts?: number;
|
|
92
|
+
/** A record may be delivered as a workspace file named under `key`; `read` returns the file's parsed JSON or
|
|
93
|
+
* throws (an error whose `code` is `ENOENT` for a file that is not there). Absent, a record is inline only. */
|
|
94
|
+
file?: {
|
|
95
|
+
key: string;
|
|
96
|
+
read(path: string): Promise<unknown>;
|
|
97
|
+
};
|
|
98
|
+
/** Contracts the host owns, held before the schema: each problem is said with the core's own findings. */
|
|
99
|
+
contracts?: (candidate: unknown) => string[] | Promise<string[]>;
|
|
100
|
+
/** Checks held after the schema, in order; the first refusal is the rejection. One that throws refuses with
|
|
101
|
+
* what it threw. */
|
|
102
|
+
checks?: ReadonlyArray<(candidate: unknown) => Refusal | null | Promise<Refusal | null>>;
|
|
103
|
+
/** The second reading, in order. */
|
|
104
|
+
reviewers?: readonly Reviewer[];
|
|
105
|
+
/** Whether a reviewer's error is the caller's own failure, to be thrown and not absorbed. */
|
|
106
|
+
fatal?: (error: unknown) => boolean;
|
|
107
|
+
};
|
|
108
|
+
/** The two states behind a node's delivery. Each write is one atomic change; `reject` and `bounce` return the
|
|
109
|
+
* attempts spent after it. The bounce spends the round before the model is told, so a crash cannot grant it twice. */
|
|
110
|
+
export type RecordStore = {
|
|
111
|
+
read(): Promise<{
|
|
112
|
+
record: RecordState;
|
|
113
|
+
gate: GateState;
|
|
114
|
+
}>;
|
|
115
|
+
reject(): Promise<number>;
|
|
116
|
+
bounce(): Promise<number>;
|
|
117
|
+
accept(record: unknown, disagreements: Disagreement[]): Promise<void>;
|
|
118
|
+
};
|
|
119
|
+
/** What one submission came to. `spent` says the delivery attempts are gone and the node's run ends here. */
|
|
120
|
+
export type Delivery = {
|
|
121
|
+
status: "already";
|
|
122
|
+
} | {
|
|
123
|
+
status: "rejected";
|
|
124
|
+
attempts: number;
|
|
125
|
+
spent: boolean;
|
|
126
|
+
reason: string;
|
|
127
|
+
problems: string[];
|
|
128
|
+
} | {
|
|
129
|
+
status: "bounced";
|
|
130
|
+
attempts: number;
|
|
131
|
+
spent: boolean;
|
|
132
|
+
disagreements: Disagreement[];
|
|
133
|
+
} | {
|
|
134
|
+
status: "accepted";
|
|
135
|
+
record: unknown;
|
|
136
|
+
disagreements: Disagreement[];
|
|
137
|
+
};
|
|
138
|
+
/** Decide one `submit` call. `args` are the call's arguments as the model sent them, or as `repairRecord`
|
|
139
|
+
* already repaired them. */
|
|
140
|
+
export declare function deliver(contract: RecordContract, store: RecordStore, args: unknown): Promise<Delivery>;
|
|
141
|
+
/** The `submit` tool's answer to the model for one delivery. */
|
|
142
|
+
export declare function deliveryText(delivery: Delivery, maxAttempts?: number, say?: (disagreement: Disagreement) => string): string;
|
|
143
|
+
/** One disagreement as the model reads it. */
|
|
144
|
+
export declare const disagreementText: (d: Disagreement) => string;
|
|
145
|
+
/** Whether a delivery ends the node's run: a record was delivered, or the attempts are spent. */
|
|
146
|
+
export declare const deliveryTerminates: (delivery: Delivery) => boolean;
|
|
147
|
+
/** The delivery contract a node's task ends with: the label, the file envelope when one is offered, the
|
|
148
|
+
* authoritative schema and the host's own delivery instructions. The model sees the exact schema only here. */
|
|
149
|
+
export declare function submitFooter(record: {
|
|
150
|
+
label: string;
|
|
151
|
+
schema: Record<string, unknown>;
|
|
152
|
+
fileKey?: string;
|
|
153
|
+
instructions?: string;
|
|
154
|
+
reviewed?: boolean;
|
|
155
|
+
}): string;
|
|
156
|
+
/** What a yield without a record is answered with, when the delivery has an attempt left for it. */
|
|
157
|
+
export declare const nudgeText: (label: string) => string;
|