@earendil-works/pi-durable 1.4.0 → 1.5.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/CHANGELOG.md +204 -0
- package/README.md +195 -85
- package/dist/codemode/codemode.d.ts +6 -5
- package/dist/codemode/codemode.d.ts.map +1 -1
- package/dist/codemode/codemode.js +10 -49
- package/dist/codemode/codemode.js.map +1 -1
- package/dist/codemode/models.d.ts +2 -1
- package/dist/codemode/models.d.ts.map +1 -1
- package/dist/codemode/models.js +4 -4
- package/dist/codemode/models.js.map +1 -1
- package/dist/documents.d.ts +1 -1
- package/dist/documents.d.ts.map +1 -1
- package/dist/documents.js +1 -1
- package/dist/documents.js.map +1 -1
- package/dist/entries.d.ts +1 -1
- package/dist/entries.d.ts.map +1 -1
- package/dist/entries.js.map +1 -1
- package/dist/env/index.d.ts +13 -11
- package/dist/env/index.d.ts.map +1 -1
- package/dist/env/index.js.map +1 -1
- package/dist/env/node-watch.d.ts +4 -4
- package/dist/env/node-watch.d.ts.map +1 -1
- package/dist/env/node-watch.js +18 -16
- package/dist/env/node-watch.js.map +1 -1
- package/dist/env/node.d.ts +3 -3
- package/dist/env/node.d.ts.map +1 -1
- package/dist/env/node.js +1 -1
- package/dist/env/node.js.map +1 -1
- package/dist/errors.d.ts +18 -2
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +26 -3
- package/dist/errors.js.map +1 -1
- package/dist/harness/agent.d.ts.map +1 -1
- package/dist/harness/agent.js +37 -3
- package/dist/harness/agent.js.map +1 -1
- package/dist/harness/compaction.d.ts +8 -3
- package/dist/harness/compaction.d.ts.map +1 -1
- package/dist/harness/compaction.js +40 -11
- package/dist/harness/compaction.js.map +1 -1
- package/dist/harness/context.d.ts +24 -8
- package/dist/harness/context.d.ts.map +1 -1
- package/dist/harness/context.js +71 -25
- package/dist/harness/context.js.map +1 -1
- package/dist/harness/define.d.ts +8 -4
- package/dist/harness/define.d.ts.map +1 -1
- package/dist/harness/define.js +4 -0
- package/dist/harness/define.js.map +1 -1
- package/dist/harness/generation.d.ts +39 -6
- package/dist/harness/generation.d.ts.map +1 -1
- package/dist/harness/generation.js +451 -100
- package/dist/harness/generation.js.map +1 -1
- package/dist/harness/harness.d.ts +3 -1
- package/dist/harness/harness.d.ts.map +1 -1
- package/dist/harness/harness.js +87 -62
- package/dist/harness/harness.js.map +1 -1
- package/dist/harness/inbox.d.ts +7 -2
- package/dist/harness/inbox.d.ts.map +1 -1
- package/dist/harness/inbox.js +5 -2
- package/dist/harness/inbox.js.map +1 -1
- package/dist/harness/json.d.ts +21 -5
- package/dist/harness/json.d.ts.map +1 -1
- package/dist/harness/json.js +23 -5
- package/dist/harness/json.js.map +1 -1
- package/dist/harness/live.d.ts +124 -17
- package/dist/harness/live.d.ts.map +1 -1
- package/dist/harness/live.js +93 -12
- package/dist/harness/live.js.map +1 -1
- package/dist/harness/partial-changes.d.ts +54 -0
- package/dist/harness/partial-changes.d.ts.map +1 -0
- package/dist/harness/partial-changes.js +163 -0
- package/dist/harness/partial-changes.js.map +1 -0
- package/dist/harness/prompt.d.ts +1 -1
- package/dist/harness/prompt.d.ts.map +1 -1
- package/dist/harness/prompt.js.map +1 -1
- package/dist/harness/provider.d.ts +1 -1
- package/dist/harness/provider.d.ts.map +1 -1
- package/dist/harness/provider.js.map +1 -1
- package/dist/harness/registry-reader.d.ts +11 -0
- package/dist/harness/registry-reader.d.ts.map +1 -0
- package/dist/harness/registry-reader.js +25 -0
- package/dist/harness/registry-reader.js.map +1 -0
- package/dist/harness/scheduler.d.ts +48 -20
- package/dist/harness/scheduler.d.ts.map +1 -1
- package/dist/harness/scheduler.js +1006 -380
- package/dist/harness/scheduler.js.map +1 -1
- package/dist/harness/submissions.d.ts +18 -11
- package/dist/harness/submissions.d.ts.map +1 -1
- package/dist/harness/submissions.js +63 -26
- package/dist/harness/submissions.js.map +1 -1
- package/dist/harness/task-graph.d.ts +14 -9
- package/dist/harness/task-graph.d.ts.map +1 -1
- package/dist/harness/task-graph.js +38 -28
- package/dist/harness/task-graph.js.map +1 -1
- package/dist/harness/telemetry.d.ts +11 -11
- package/dist/harness/telemetry.d.ts.map +1 -1
- package/dist/harness/telemetry.js +7 -7
- package/dist/harness/telemetry.js.map +1 -1
- package/dist/harness/tool.d.ts +3 -1
- package/dist/harness/tool.d.ts.map +1 -1
- package/dist/harness/tool.js +172 -56
- package/dist/harness/tool.js.map +1 -1
- package/dist/harness/transcript.d.ts +72 -0
- package/dist/harness/transcript.d.ts.map +1 -0
- package/dist/harness/transcript.js +264 -0
- package/dist/harness/transcript.js.map +1 -0
- package/dist/harness/types.d.ts +237 -61
- package/dist/harness/types.d.ts.map +1 -1
- package/dist/harness/types.js.map +1 -1
- package/dist/harness/usage.d.ts +2 -1
- package/dist/harness/usage.d.ts.map +1 -1
- package/dist/harness/usage.js +1 -1
- package/dist/harness/usage.js.map +1 -1
- package/dist/harness/util.d.ts +4 -2
- package/dist/harness/util.d.ts.map +1 -1
- package/dist/harness/util.js +9 -0
- package/dist/harness/util.js.map +1 -1
- package/dist/harness/view.d.ts +44 -22
- package/dist/harness/view.d.ts.map +1 -1
- package/dist/harness/view.js +130 -71
- package/dist/harness/view.js.map +1 -1
- package/dist/index.d.ts +9 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/search.d.ts +19 -3
- package/dist/search.d.ts.map +1 -1
- package/dist/search.js +107 -44
- package/dist/search.js.map +1 -1
- package/dist/session/cached-storage.d.ts +72 -0
- package/dist/session/cached-storage.d.ts.map +1 -0
- package/dist/session/cached-storage.js +269 -0
- package/dist/session/cached-storage.js.map +1 -0
- package/dist/session/conversation-tails.d.ts +33 -0
- package/dist/session/conversation-tails.d.ts.map +1 -0
- package/dist/session/conversation-tails.js +101 -0
- package/dist/session/conversation-tails.js.map +1 -0
- package/dist/session/forks.d.ts +1 -1
- package/dist/session/forks.d.ts.map +1 -1
- package/dist/session/forks.js.map +1 -1
- package/dist/session/keys.d.ts +69 -0
- package/dist/session/keys.d.ts.map +1 -0
- package/dist/session/keys.js +161 -0
- package/dist/session/keys.js.map +1 -0
- package/dist/session/session.d.ts +169 -26
- package/dist/session/session.d.ts.map +1 -1
- package/dist/session/session.js +1029 -171
- package/dist/session/session.js.map +1 -1
- package/dist/session/transaction.d.ts +84 -5
- package/dist/session/transaction.d.ts.map +1 -1
- package/dist/session/transaction.js +227 -40
- package/dist/session/transaction.js.map +1 -1
- package/dist/session/writer.d.ts +74 -0
- package/dist/session/writer.d.ts.map +1 -0
- package/dist/session/writer.js +294 -0
- package/dist/session/writer.js.map +1 -0
- package/dist/storage/indexeddb.d.ts +12 -3
- package/dist/storage/indexeddb.d.ts.map +1 -1
- package/dist/storage/indexeddb.js +91 -41
- package/dist/storage/indexeddb.js.map +1 -1
- package/dist/storage/jsonl/index.d.ts +1 -1
- package/dist/storage/jsonl/index.d.ts.map +1 -1
- package/dist/storage/jsonl/index.js +1 -1
- package/dist/storage/jsonl/index.js.map +1 -1
- package/dist/storage/jsonl/node.d.ts +3 -3
- package/dist/storage/jsonl/node.d.ts.map +1 -1
- package/dist/storage/jsonl/node.js +2 -2
- package/dist/storage/jsonl/node.js.map +1 -1
- package/dist/storage/jsonl/storage.d.ts +46 -5
- package/dist/storage/jsonl/storage.d.ts.map +1 -1
- package/dist/storage/jsonl/storage.js +158 -43
- package/dist/storage/jsonl/storage.js.map +1 -1
- package/dist/storage/memory.d.ts +9 -3
- package/dist/storage/memory.d.ts.map +1 -1
- package/dist/storage/memory.js +28 -2
- package/dist/storage/memory.js.map +1 -1
- package/dist/storage/sqlite/commit.d.ts +52 -0
- package/dist/storage/sqlite/commit.d.ts.map +1 -0
- package/dist/storage/sqlite/commit.js +371 -0
- package/dist/storage/sqlite/commit.js.map +1 -0
- package/dist/storage/sqlite/rows.d.ts +33 -0
- package/dist/storage/sqlite/rows.d.ts.map +1 -0
- package/dist/storage/sqlite/rows.js +53 -0
- package/dist/storage/sqlite/rows.js.map +1 -0
- package/dist/storage/sqlite/statements.d.ts +13 -0
- package/dist/storage/sqlite/statements.d.ts.map +1 -0
- package/dist/storage/sqlite/statements.js +88 -0
- package/dist/storage/sqlite/statements.js.map +1 -0
- package/dist/storage/sqlite/storage.d.ts +23 -10
- package/dist/storage/sqlite/storage.d.ts.map +1 -1
- package/dist/storage/sqlite/storage.js +120 -261
- package/dist/storage/sqlite/storage.js.map +1 -1
- package/dist/storage/store/commit.d.ts +33 -0
- package/dist/storage/store/commit.d.ts.map +1 -0
- package/dist/storage/store/commit.js +286 -0
- package/dist/storage/store/commit.js.map +1 -0
- package/dist/storage/store/documents.d.ts +43 -0
- package/dist/storage/store/documents.d.ts.map +1 -0
- package/dist/storage/store/documents.js +102 -0
- package/dist/storage/store/documents.js.map +1 -0
- package/dist/storage/store/index.d.ts +2 -0
- package/dist/storage/store/index.d.ts.map +1 -0
- package/dist/storage/store/index.js +2 -0
- package/dist/storage/store/index.js.map +1 -0
- package/dist/storage/store/queries.d.ts +49 -0
- package/dist/storage/store/queries.d.ts.map +1 -0
- package/dist/storage/store/queries.js +93 -0
- package/dist/storage/store/queries.js.map +1 -0
- package/dist/storage/store/storage.d.ts +60 -0
- package/dist/storage/store/storage.d.ts.map +1 -0
- package/dist/storage/store/storage.js +438 -0
- package/dist/storage/store/storage.js.map +1 -0
- package/dist/storage/store/tables.d.ts +54 -0
- package/dist/storage/store/tables.d.ts.map +1 -0
- package/dist/storage/store/tables.js +108 -0
- package/dist/storage/store/tables.js.map +1 -0
- package/dist/testing/commit-writes.d.ts +5 -0
- package/dist/testing/commit-writes.d.ts.map +1 -0
- package/dist/testing/commit-writes.js +12 -0
- package/dist/testing/commit-writes.js.map +1 -0
- package/dist/testing/env-conformance.js +7 -7
- package/dist/testing/env-conformance.js.map +1 -1
- package/dist/testing/index.d.ts +1 -0
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +1 -0
- package/dist/testing/index.js.map +1 -1
- package/dist/testing/storage-benchmark.d.ts.map +1 -1
- package/dist/testing/storage-benchmark.js +18 -17
- package/dist/testing/storage-benchmark.js.map +1 -1
- package/dist/testing/storage-conformance.d.ts.map +1 -1
- package/dist/testing/storage-conformance.js +354 -69
- package/dist/testing/storage-conformance.js.map +1 -1
- package/dist/tool-search/tool-search.d.ts +8 -14
- package/dist/tool-search/tool-search.d.ts.map +1 -1
- package/dist/tool-search/tool-search.js +25 -13
- package/dist/tool-search/tool-search.js.map +1 -1
- package/dist/tools/bash.d.ts +13 -13
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/bash.js +16 -15
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/edit.d.ts +7 -7
- package/dist/tools/edit.d.ts.map +1 -1
- package/dist/tools/edit.js +9 -9
- package/dist/tools/edit.js.map +1 -1
- package/dist/tools/file-mutation-queue.d.ts +1 -1
- package/dist/tools/file-mutation-queue.d.ts.map +1 -1
- package/dist/tools/file-mutation-queue.js.map +1 -1
- package/dist/tools/index.d.ts +32 -32
- package/dist/tools/path-utils.d.ts +1 -1
- package/dist/tools/path-utils.d.ts.map +1 -1
- package/dist/tools/path-utils.js.map +1 -1
- package/dist/tools/read.d.ts +6 -6
- package/dist/tools/read.d.ts.map +1 -1
- package/dist/tools/read.js +19 -8
- package/dist/tools/read.js.map +1 -1
- package/dist/tools/write.d.ts +4 -4
- package/dist/tools/write.d.ts.map +1 -1
- package/dist/tools/write.js +5 -5
- package/dist/tools/write.js.map +1 -1
- package/dist/types.d.ts +228 -78
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +19 -12
- package/dist/harness/events.d.ts +0 -186
- package/dist/harness/events.d.ts.map +0 -1
- package/dist/harness/events.js +0 -373
- package/dist/harness/events.js.map +0 -1
- package/dist/session/observation.d.ts +0 -42
- package/dist/session/observation.d.ts.map +0 -1
- package/dist/session/observation.js +0 -281
- package/dist/session/observation.js.map +0 -1
package/dist/harness/types.d.ts
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
1
|
+
import type { Context } from "@earendil-works/chord/context";
|
|
2
|
+
import type { JsonValue } from "@earendil-works/chord/json";
|
|
3
|
+
import type { WatchHandle } from "@earendil-works/chord/watch";
|
|
4
|
+
import type { Api, AssistantMessage, CacheRetention, ClientIdentity, Message, Model, Models, ModelThinkingLevel, ThinkingBudgets, Tool, ToolCall, ToolResultMessage, Transport, Usage, UserMessage } from "@earendil-works/pi-ai";
|
|
5
|
+
import type { Static } from "@earendil-works/pi-schema";
|
|
3
6
|
import type { TelemetryContext } from "@earendil-works/pi-telemetry";
|
|
4
7
|
import type { ExecutionEnv, ShellOutputSkip, ShellOutputWindow } from "../env/index.ts";
|
|
5
|
-
import type { ConversationId, ConversationOwnership, ConversationRecord, Cursor, DocumentObserver, DocumentReader, EntryDraft, EntryId, EntryQuery, EntryRecord, JsonObject, Page,
|
|
8
|
+
import type { CommitOptions, ConversationId, ConversationOwnership, ConversationRecord, Cursor, DocumentObserver, DocumentReader, Entry, EntryDraft, EntryId, EntryQuery, EntryRecord, JsonObject, Observation, Observer, Page, Report, Session, SetTimer, SubmissionId, SubmissionRecord, Task, TaskId, TaskOptions, TaskRecord, TaskState, Tx, TypedEntry } from "../types.ts";
|
|
6
9
|
import type { TaskGraph, TaskGraphWatch } from "./task-graph.ts";
|
|
7
10
|
import type { UsageState } from "./usage.ts";
|
|
8
|
-
import type { ConversationView } from "./view.ts";
|
|
11
|
+
import type { ConversationView, ConversationWindow } from "./view.ts";
|
|
9
12
|
/** Provider and model ID resolved through pi-ai `Models`. */
|
|
10
13
|
export type ModelRef = {
|
|
11
14
|
readonly provider: string;
|
|
@@ -20,13 +23,23 @@ export type InputEntry = {
|
|
|
20
23
|
readonly kind: string;
|
|
21
24
|
readonly data?: JsonValue;
|
|
22
25
|
};
|
|
23
|
-
/**
|
|
26
|
+
/**
|
|
27
|
+
* Host submission: user input that may start a run, a passive entry write, or a continue: a run without a new user
|
|
28
|
+
* message, for an idle conversation whose context the model still owes an answer (it ends in a user message or tool
|
|
29
|
+
* results, for example after a run that ended without an answer).
|
|
30
|
+
*/
|
|
24
31
|
export type SubmissionDraft = {
|
|
25
32
|
readonly requestId?: string;
|
|
26
33
|
} & ({
|
|
27
34
|
readonly type: "input";
|
|
28
35
|
readonly content: UserInput;
|
|
29
36
|
readonly whenBusy?: "steer" | "followUp" | "reject";
|
|
37
|
+
/**
|
|
38
|
+
* `reject`: an idle conversation (no run) rejects the input with `ConversationIdle` and writes nothing, so the input
|
|
39
|
+
* never starts a run of its own. With `whenBusy: "steer"` it steers the current run or is refused; a run that
|
|
40
|
+
* answered and waits for its `afterRun` tasks is still busy, and such an input queues and starts the next run.
|
|
41
|
+
*/
|
|
42
|
+
readonly whenIdle?: "reject";
|
|
30
43
|
/** Place the input as this entry; default `pi.user` without data. The kind must not start with `pi.`. */
|
|
31
44
|
readonly entry?: InputEntry;
|
|
32
45
|
} | {
|
|
@@ -34,6 +47,20 @@ export type SubmissionDraft = {
|
|
|
34
47
|
readonly entry: EntryDraft;
|
|
35
48
|
readonly content?: never;
|
|
36
49
|
readonly whenBusy?: never;
|
|
50
|
+
readonly whenIdle?: never;
|
|
51
|
+
} | {
|
|
52
|
+
/**
|
|
53
|
+
* Start a run on the context as it is, without a user message. Only when idle: a busy conversation rejects it with
|
|
54
|
+
* `ConversationBusy`, and it never queues. Items kept in `pi.inbox` are placed first and join the run. A context
|
|
55
|
+
* with nothing to answer (empty, or ending in an answer, also a text answer cut off at its output limit) ends the
|
|
56
|
+
* run without a request, `unanswered` with `nothing_to_answer`. A cut-off answer with tool calls is continued:
|
|
57
|
+
* its calls never ran, and the context ends in their error results (`missing_result`).
|
|
58
|
+
*/
|
|
59
|
+
readonly type: "continue";
|
|
60
|
+
readonly content?: never;
|
|
61
|
+
readonly entry?: never;
|
|
62
|
+
readonly whenBusy?: never;
|
|
63
|
+
readonly whenIdle?: never;
|
|
37
64
|
});
|
|
38
65
|
export type InputSubmissionDraft = Extract<SubmissionDraft, {
|
|
39
66
|
readonly type: "input";
|
|
@@ -77,12 +104,16 @@ export type ConversationAbortOptions = {
|
|
|
77
104
|
/** Hook handler map declared by a task definition. */
|
|
78
105
|
export type HooksOf<K> = K extends Task<infer _I, infer _S, infer _R, infer H> ? H : never;
|
|
79
106
|
/**
|
|
80
|
-
* Invocation-bound conversation operations for tasks and tools. Rejects after the invocation ends
|
|
81
|
-
*
|
|
107
|
+
* Invocation-bound conversation operations for tasks and tools. Rejects after the invocation ends. `submit` takes any
|
|
108
|
+
* submission, in both forms of `Conversation.submit()`: a subagent's conversation is an ordinary one, so a tool may also
|
|
109
|
+
* continue it, and a task may admit a submission in the same commit as its own writes (`runtime.commit()`); entries
|
|
110
|
+
* the admission appends there carry the task's `byTaskId`. The transaction form also rejects once the invocation is
|
|
111
|
+
* aborted.
|
|
82
112
|
*/
|
|
83
113
|
export interface ConversationHandle {
|
|
84
114
|
readonly id: ConversationId;
|
|
85
|
-
submit(submission:
|
|
115
|
+
submit(submission: SubmissionDraft, context: Context): Promise<Submission>;
|
|
116
|
+
submit(tx: Tx, submission: SubmissionDraft): Promise<SubmissionId>;
|
|
86
117
|
/** `Conversation.abort()`: withdraw queued inputs, abort the ordinary ownership scope, and wait until it is idle. */
|
|
87
118
|
abort(context: Context, options?: ConversationAbortOptions): Promise<void>;
|
|
88
119
|
/** Resolve when the conversation's ordinary ownership scope has no live non-background task. */
|
|
@@ -93,6 +124,10 @@ export type ToolControl = {
|
|
|
93
124
|
readonly addTools?: readonly string[];
|
|
94
125
|
/** End the run without another model request when every result of the round sets it to `true`; `false` is a no-op. */
|
|
95
126
|
readonly terminate?: boolean;
|
|
127
|
+
/**
|
|
128
|
+
* Start a new context with this text as its user message, as `reset(handoff)` writes, and continue the run there.
|
|
129
|
+
* The last handoff in call order wins.
|
|
130
|
+
*/
|
|
96
131
|
readonly handoff?: string;
|
|
97
132
|
};
|
|
98
133
|
/** Remark about a call for the model and the UI, such as truncation or a spill path; never part of the tool's data. */
|
|
@@ -189,7 +224,8 @@ export interface ToolExecutionApi<TDetails extends JsonValue = JsonValue> extend
|
|
|
189
224
|
diagnostic(diagnostic: ToolDiagnostic): void;
|
|
190
225
|
/** Replace running details; the last value becomes the result details when the result omits `details`. */
|
|
191
226
|
details(value: TDetails, context: Context): Promise<void>;
|
|
192
|
-
commit
|
|
227
|
+
/** A commit of this call's task; `options` may defer storing it (`CommitPersistence`). */
|
|
228
|
+
commit<T>(change: (tx: Tx) => T | Promise<T>, context: Context, options?: CommitOptions): Promise<T>;
|
|
193
229
|
memo<T extends JsonValue>(name: string, context: Context): Promise<T | undefined>;
|
|
194
230
|
memo<T extends JsonValue>(name: string, candidate: T, context: Context): Promise<T>;
|
|
195
231
|
/**
|
|
@@ -235,11 +271,18 @@ export interface ToolExecutionApi<TDetails extends JsonValue = JsonValue> extend
|
|
|
235
271
|
readonly progress?: boolean;
|
|
236
272
|
}): Promise<NestedToolExecutionResult>;
|
|
237
273
|
}
|
|
274
|
+
/**
|
|
275
|
+
* The arguments type of a tool with parameter schema `TParameters`: pi-schema's `Static<TParameters>` (the builders'
|
|
276
|
+
* type, TypeBox's for the common TypeBox kinds, else `unknown`), and `any` for `ToolRegistration<any>`.
|
|
277
|
+
*/
|
|
278
|
+
export type ToolArgs<TParameters> = IsAny<TParameters> extends true ? any : Static<TParameters>;
|
|
279
|
+
type IsAny<T> = boolean extends (T extends never ? true : false) ? true : false;
|
|
238
280
|
/**
|
|
239
281
|
* Executable tool registered in a registry. Only pi-ai `Tool` fields enter the transcript. `args` are typed by
|
|
240
|
-
* `parameters
|
|
282
|
+
* `parameters` (any JSON Schema object; see {@link ToolArgs}), which the Harness validates them against before
|
|
283
|
+
* `execute()`; `defineTool()` infers both generics.
|
|
241
284
|
*/
|
|
242
|
-
export type ToolRegistration<TParameters extends
|
|
285
|
+
export type ToolRegistration<TParameters extends object = object, TDetails extends JsonValue = JsonValue> = Tool<TParameters> & {
|
|
243
286
|
/** Whether an interrupted execution may rerun on recovery. Default `unsafe`. */
|
|
244
287
|
readonly replay?: "safe" | "unsafe";
|
|
245
288
|
/** Default: the settings' `toolExecution`. One sequential call makes its whole round sequential. */
|
|
@@ -249,12 +292,12 @@ export type ToolRegistration<TParameters extends TSchema = TSchema, TDetails ext
|
|
|
249
292
|
* pure and must not mutate `args`: it runs again when a call is retried before its intent is recorded. Its result is
|
|
250
293
|
* still validated against `parameters`.
|
|
251
294
|
*/
|
|
252
|
-
prepareArguments?(args: unknown):
|
|
295
|
+
prepareArguments?(args: unknown): ToolArgs<TParameters>;
|
|
253
296
|
/**
|
|
254
297
|
* Schema of `structuredOutput`, which programs that call the tool receive. Omitted: they receive the result's bounded
|
|
255
298
|
* output, success or error, as `NestedToolExecutionResult.structuredOutput` describes.
|
|
256
299
|
*/
|
|
257
|
-
readonly structuredOutputSchema?:
|
|
300
|
+
readonly structuredOutputSchema?: object;
|
|
258
301
|
/**
|
|
259
302
|
* Who may call the tool: the model, other tools through `executeTool()`, or both (default). A code mode tool is
|
|
260
303
|
* `["model"]`, so scripts cannot start scripts; tools behind code mode, such as MCP tools, can be `["tools"]`, so the
|
|
@@ -271,7 +314,7 @@ export type ToolRegistration<TParameters extends TSchema = TSchema, TDetails ext
|
|
|
271
314
|
readonly maxLines?: number;
|
|
272
315
|
readonly retain?: "head" | "tail";
|
|
273
316
|
};
|
|
274
|
-
execute(args:
|
|
317
|
+
execute(args: ToolArgs<TParameters>, api: ToolExecutionApi<TDetails>, context: Context): Promise<ToolExecutionResult<TDetails>>;
|
|
275
318
|
};
|
|
276
319
|
/** Input to system prompt section rendering for one request preparation. */
|
|
277
320
|
export type PromptInput<Tool extends ToolRegistration = ToolRegistration> = {
|
|
@@ -377,6 +420,17 @@ export type AgentState = {
|
|
|
377
420
|
instructions?: string;
|
|
378
421
|
/** Directory within the environment's file system, passed to `HarnessOptions.env`. */
|
|
379
422
|
cwd?: string;
|
|
423
|
+
/**
|
|
424
|
+
* Tool rounds one run takes at most (`pi.live.run.turns`): the round that reaches it runs its tools, then the run ends
|
|
425
|
+
* `unanswered` with `turn_limit`. An integer, `1` or more; unset, no limit. Task-owned children and forks inherit it.
|
|
426
|
+
*/
|
|
427
|
+
maxTurns?: number;
|
|
428
|
+
/**
|
|
429
|
+
* This conversation's compaction settings over the harness's, field by field: its `modelOverrides` entry, then the
|
|
430
|
+
* harness's, then its own fields, then the harness-wide policy. Its `enabled: false` also beats the harness's model
|
|
431
|
+
* override. Task-owned children and forks inherit it.
|
|
432
|
+
*/
|
|
433
|
+
compaction?: CompactionSettings;
|
|
380
434
|
};
|
|
381
435
|
/** A change to `pi.agent`: a given field replaces the stored one, `null` clears it, `undefined` changes nothing. */
|
|
382
436
|
export type AgentChange = {
|
|
@@ -396,6 +450,10 @@ export type AgentChange = {
|
|
|
396
450
|
} | null;
|
|
397
451
|
readonly instructions?: string | null;
|
|
398
452
|
readonly cwd?: string | null;
|
|
453
|
+
/** `configure()` throws a `RangeError` unless it is an integer `1` or more (or `null`). */
|
|
454
|
+
readonly maxTurns?: number | null;
|
|
455
|
+
/** Replaces the stored settings as a whole; `configure()` throws a `RangeError` unless every token count is an integer `0` or more. */
|
|
456
|
+
readonly compaction?: CompactionSettings | null;
|
|
399
457
|
};
|
|
400
458
|
/** A conversation's agent resolved against a registry snapshot and the settings. */
|
|
401
459
|
export type Agent<Tool extends ToolRegistration = ToolRegistration> = {
|
|
@@ -412,6 +470,13 @@ export type Agent<Tool extends ToolRegistration = ToolRegistration> = {
|
|
|
412
470
|
readonly sections: readonly PromptSection<Tool>[];
|
|
413
471
|
readonly instructions?: string;
|
|
414
472
|
readonly cwd?: string;
|
|
473
|
+
/**
|
|
474
|
+
* Tool rounds one run takes at most (`pi.live.run.turns`): the round that reaches it runs its tools, then the run ends
|
|
475
|
+
* `unanswered` with `turn_limit`. An integer, `1` or more; unset, no limit. Task-owned children and forks inherit it.
|
|
476
|
+
*/
|
|
477
|
+
readonly maxTurns?: number;
|
|
478
|
+
/** This conversation's compaction settings over the harness's (`AgentState.compaction`). */
|
|
479
|
+
readonly compaction?: CompactionSettings;
|
|
415
480
|
};
|
|
416
481
|
/**
|
|
417
482
|
* Runs inside the creating commit, after the creation hook and the `agent` change. The conversation creation is already
|
|
@@ -428,6 +493,10 @@ export type ConversationCreateOptions = {
|
|
|
428
493
|
export type ConversationStreamOptions = {
|
|
429
494
|
transport?: Transport;
|
|
430
495
|
timeoutMs?: number;
|
|
496
|
+
/** WebSocket connection/open handshake timeout; stream idleness uses `timeoutMs`. */
|
|
497
|
+
websocketConnectTimeoutMs?: number;
|
|
498
|
+
/** Custom token budgets for thinking levels on token-based providers. */
|
|
499
|
+
thinkingBudgets?: ThinkingBudgets;
|
|
431
500
|
/** Provider/SDK retries inside one request attempt. */
|
|
432
501
|
maxRetries?: number;
|
|
433
502
|
maxRetryDelayMs?: number;
|
|
@@ -457,21 +526,29 @@ export type CompactionPolicy = {
|
|
|
457
526
|
backgroundTokens: number;
|
|
458
527
|
};
|
|
459
528
|
/**
|
|
460
|
-
*
|
|
461
|
-
*
|
|
529
|
+
* Compaction settings of the harness (`HarnessSettings.compaction`) or of one conversation (`AgentState.compaction`).
|
|
530
|
+
* `modelOverrides` is keyed by exact `"provider/modelId"`; each field it sets replaces the general one for that model,
|
|
531
|
+
* so small- and large-window models can share a harness.
|
|
462
532
|
*/
|
|
463
533
|
export type CompactionSettings = Partial<CompactionPolicy> & {
|
|
464
534
|
readonly modelOverrides?: Readonly<Record<string, Partial<CompactionPolicy>>>;
|
|
465
535
|
};
|
|
466
536
|
/**
|
|
467
|
-
* How often running progress is committed
|
|
468
|
-
*
|
|
537
|
+
* How often running progress is committed, and how long it may wait in memory before it is stored. Progress commits are
|
|
538
|
+
* deferred (`CommitPersistence`): watches see each at once, and Storage gets them together, at the run's next phase
|
|
539
|
+
* boundary or after `persistWithinMs`. A host can commit less often, so live answers and tool output appear in larger steps.
|
|
469
540
|
*/
|
|
470
541
|
export type ProgressPolicy = {
|
|
471
542
|
/** Minimum pause between commits of the answer being generated. */
|
|
472
543
|
partialIntervalMs: number;
|
|
473
544
|
/** Minimum pause between commits of running tool output; large commits also pause in proportion to their size. */
|
|
474
545
|
outputIntervalMs: number;
|
|
546
|
+
/**
|
|
547
|
+
* How long these commits, and other deferred commits without their own `withinMs`, may stay in memory before they are
|
|
548
|
+
* stored (`CommitPersistence`); a crash loses at most about this much of an answer or of tool output. Default 1,000;
|
|
549
|
+
* `Infinity` stores them only at the next commit that reads or writes their document and at close.
|
|
550
|
+
*/
|
|
551
|
+
persistWithinMs: number;
|
|
475
552
|
};
|
|
476
553
|
/** Why a compaction runs: `compact()`, a threshold in generation preparation, or a context overflow. */
|
|
477
554
|
export type CompactionReason = "manual" | "threshold" | "overflow";
|
|
@@ -500,25 +577,32 @@ export type HarnessSettings = {
|
|
|
500
577
|
*/
|
|
501
578
|
readonly contextRetentionMs?: number;
|
|
502
579
|
/**
|
|
503
|
-
* How long a loaded document that no watch
|
|
580
|
+
* How long a loaded document that no watch observes stays in memory after its last read or write;
|
|
504
581
|
* the next access loads it from Storage. Observed documents always stay. Default ten minutes; `0` drops one right
|
|
505
582
|
* after use; `Infinity` keeps them. Anything else that is not a number of milliseconds means the default.
|
|
506
583
|
*/
|
|
507
584
|
readonly documentRetentionMs?: number;
|
|
508
585
|
/**
|
|
509
|
-
* What a run that fails (`model_error`, `no_model`
|
|
510
|
-
* queued until the next input or queued write, `continue` starts the
|
|
511
|
-
* `withdraw` settles them `unanswered` with reason `run_failed`. Default
|
|
586
|
+
* What a run that fails (`model_error`, `no_model`, `interrupted`, `restart_limit`, `nothing_to_answer`,
|
|
587
|
+
* `turn_limit`) does with the inputs queued behind it: `keep` leaves them queued until the next input or queued write, `continue` starts the
|
|
588
|
+
* next run with them, as an answer would, and `withdraw` settles them `unanswered` with reason `run_failed`. Default
|
|
589
|
+
* `keep`.
|
|
512
590
|
*/
|
|
513
591
|
readonly afterFailedRun?: AfterFailedRun;
|
|
514
592
|
/**
|
|
515
593
|
* How many times in a row a task may be cut off by a crash, eviction, or reset (a close does not count) without
|
|
516
|
-
* changing its state before it
|
|
517
|
-
*
|
|
594
|
+
* changing its state before it ends instead of running again: a tool call with an error result, a compaction failed
|
|
595
|
+
* into `pi.live.compactionFailure`, a run with `pi.live.runFailure` reason `restart_limit`, any other task `faulted`
|
|
596
|
+
* with detail `{ reason: "restart_limit" }`. A generation's request or poll the host died during is a failed attempt
|
|
597
|
+
* under `retry` first; the limit bounds it only when charging that attempt keeps being cut off. Default 5;
|
|
598
|
+
* `Infinity` never ends a task for it.
|
|
518
599
|
*/
|
|
519
600
|
readonly restartLimit?: number;
|
|
520
601
|
};
|
|
521
|
-
/**
|
|
602
|
+
/**
|
|
603
|
+
* What a failed run does with the inputs queued behind it (`HarnessSettings.afterFailedRun`): a run that ends with
|
|
604
|
+
* `model_error`, `no_model`, `interrupted`, `restart_limit`, `nothing_to_answer`, or `turn_limit`.
|
|
605
|
+
*/
|
|
522
606
|
export type AfterFailedRun = "keep" | "continue" | "withdraw";
|
|
523
607
|
/** Resolved settings: every field over its built-in default, object fields merged. */
|
|
524
608
|
export type Settings = {
|
|
@@ -587,18 +671,27 @@ export type HarnessOptions<Tool extends ToolRegistration = ToolRegistration> = {
|
|
|
587
671
|
* Wakes the process for sleeping tasks instead of a `setTimer` timer. Without it, while scheduling runs, a timer that
|
|
588
672
|
* keeps the process alive resumes sleeping tasks when they are due. With it, the Harness arms no timer for them: it
|
|
589
673
|
* calls `onWake` after open and whenever `Harness.wake()` changes, and the host arms its own wakeup, such as a
|
|
590
|
-
* Durable Object alarm, and calls `resume()` when it fires. Called
|
|
591
|
-
* changed the value, so a host arms a recovery wakeup before calls that can start
|
|
592
|
-
* `resume()`, and must not block. A throw is reported, and the value is offered again
|
|
674
|
+
* Durable Object alarm, and calls `resume()` when it fires. Called in a microtask the Session line never waits for,
|
|
675
|
+
* after the commit that changed the value was adopted, so a host arms a recovery wakeup before calls that can start
|
|
676
|
+
* work. It may call `wake()` and `resume()`, and must not block. A throw is reported, and the value is offered again
|
|
677
|
+
* at the next change.
|
|
593
678
|
*/
|
|
594
679
|
readonly onWake?: (wake: Wake) => void;
|
|
595
680
|
/**
|
|
596
681
|
* Receives failures that do not fail the calling operation, such as a throwing hook or listener, a task that faulted,
|
|
597
|
-
* and the error that fails the Session, once
|
|
598
|
-
* (`
|
|
599
|
-
* Its own throw or rejection is dropped.
|
|
682
|
+
* and the error that fails the Session, once: one `Report`, the `error` and what happened (`kind` and the fields of
|
|
683
|
+
* its `ReportInfo`). A host can tell a failed Session (`storage_failed`, often a platform reset) from a faulted task
|
|
684
|
+
* (`task_faulted`). Its own throw or rejection is dropped.
|
|
600
685
|
*/
|
|
601
|
-
readonly onReport?: (
|
|
686
|
+
readonly onReport?: (report: Report) => void;
|
|
687
|
+
/**
|
|
688
|
+
* Open for reading only, as a viewer of a session that another process drives, for example a synced copy on a device
|
|
689
|
+
* that only shows it. Open recovers nothing: a `running` task stays as committed. Every commit with writes rejects
|
|
690
|
+
* with `ReadOnlySession` before it reaches Storage, and so does `resume()` and every call that enables scheduling;
|
|
691
|
+
* the Harness stays usable for reads and watches. `wake()` is always inactive, and `onWake` is never called. Reopen
|
|
692
|
+
* without it to write.
|
|
693
|
+
*/
|
|
694
|
+
readonly readOnly?: boolean;
|
|
602
695
|
};
|
|
603
696
|
/**
|
|
604
697
|
* When a Session next needs a running process (`Harness.wake()`). `active`: some task can run now or is running, or a
|
|
@@ -619,7 +712,7 @@ export type TaskInspection = {
|
|
|
619
712
|
}
|
|
620
713
|
/** The next scheduling pass reserves it; `migrates` when its definition is newer and has `migrate`. */
|
|
621
714
|
| {
|
|
622
|
-
readonly kind: "
|
|
715
|
+
readonly kind: "pending";
|
|
623
716
|
readonly migrates: boolean;
|
|
624
717
|
}
|
|
625
718
|
/**
|
|
@@ -639,13 +732,10 @@ export type TaskInspection = {
|
|
|
639
732
|
| {
|
|
640
733
|
readonly kind: "completing";
|
|
641
734
|
}
|
|
642
|
-
/**
|
|
643
|
-
* Cannot run here: no registered definition can take it (aborting it settles it as `orphaned`), or it is parked by
|
|
644
|
-
* the restart limit (`retryTask()` runs it again).
|
|
645
|
-
*/
|
|
735
|
+
/** Cannot run here: no registered definition can take it (aborting it settles it as `orphaned`). */
|
|
646
736
|
| {
|
|
647
737
|
readonly kind: "blocked";
|
|
648
|
-
readonly reason: "missing_task" | "task_too_old" | "migration_failed"
|
|
738
|
+
readonly reason: "missing_task" | "task_too_old" | "migration_failed";
|
|
649
739
|
readonly error?: unknown;
|
|
650
740
|
};
|
|
651
741
|
};
|
|
@@ -675,12 +765,25 @@ export interface Conversation {
|
|
|
675
765
|
/** `configure()` in its own commit. */
|
|
676
766
|
configure(change: AgentChange, context: Context): Promise<void>;
|
|
677
767
|
/**
|
|
678
|
-
* Durably admit user input
|
|
679
|
-
* writes that affect model context in `pi.inbox`; `whenBusy: "reject"` rejects input with
|
|
680
|
-
* and writes nothing.
|
|
681
|
-
*
|
|
768
|
+
* Durably admit user input, a passive entry write, or a continue. A busy conversation, or one with queued items,
|
|
769
|
+
* queues input and writes that affect model context in `pi.inbox`; `whenBusy: "reject"` rejects input with
|
|
770
|
+
* `ConversationBusy` instead and writes nothing. An idle conversation rejects `whenIdle: "reject"` input with
|
|
771
|
+
* `ConversationIdle` and writes nothing. A write of only `kind` and `data` (no `model`, `head`, or `edits`)
|
|
772
|
+
* is appended at once, even mid-run, as it changes nothing the model sees. A continue starts a run on the context as
|
|
773
|
+
* it is, after placing queued items; a busy conversation rejects it with `ConversationBusy`, as it never queues.
|
|
682
774
|
*/
|
|
683
775
|
submit(submission: SubmissionDraft, context: Context): Promise<Submission>;
|
|
776
|
+
/**
|
|
777
|
+
* Admit a submission inside the caller's commit `tx` (`Harness.commit()`, `Conversation.commit()`, a task's
|
|
778
|
+
* `runtime.commit()`), with the same rules, and return its ID: the admission is stored with that commit, or not at all
|
|
779
|
+
* when the callback throws later or the commit fails. Call it before the commit's first table write (`appendEntry()`,
|
|
780
|
+
* `createTask()`, `createSubmission()`, another admission): otherwise it throws `ReadAfterWrite`, on every path.
|
|
781
|
+
* Documents may be read and written before and after it. A rejection (`ConversationBusy`, `ConversationIdle`) throws
|
|
782
|
+
* before any write, so the callback may catch it. Do not call `Submission` or other Harness reads inside the callback:
|
|
783
|
+
* they wait for the commit holding the line. Its `pi.durable.submit` span covers the admission only, so its `result`
|
|
784
|
+
* is provisional. Throws for a transaction of another Session.
|
|
785
|
+
*/
|
|
786
|
+
submit(tx: Tx, submission: SubmissionDraft): Promise<SubmissionId>;
|
|
684
787
|
/**
|
|
685
788
|
* Admit a write of a `pi.reset` entry that starts a new context, carrying `handoff` as a user message when given.
|
|
686
789
|
* Resolves after admission; while busy, it is placed at the next boundary.
|
|
@@ -691,8 +794,8 @@ export interface Conversation {
|
|
|
691
794
|
* summary through a write submission: at once when idle, otherwise at the next boundary (spec §8.7).
|
|
692
795
|
*/
|
|
693
796
|
compact(instructions: string | undefined, context: Context): Promise<TaskId<CompactionResult>>;
|
|
694
|
-
/** Session commit whose `tx.createTask()` defaults to this conversation. */
|
|
695
|
-
commit<T>(change: (tx: Tx) => T | Promise<T>, context: Context): Promise<T>;
|
|
797
|
+
/** Session commit whose `tx.createTask()` defaults to this conversation; `options` as for `Session.commit()`. */
|
|
798
|
+
commit<T>(change: (tx: Tx) => T | Promise<T>, context: Context, options?: CommitOptions): Promise<T>;
|
|
696
799
|
/**
|
|
697
800
|
* Committed raw active transcript and model context. With `at`, the context as of that visible entry: the same view
|
|
698
801
|
* `fork(at)` would start with, without creating a conversation.
|
|
@@ -713,18 +816,21 @@ export interface Conversation {
|
|
|
713
816
|
* owned, transitively, by its non-background tasks.
|
|
714
817
|
*/
|
|
715
818
|
waitForIdle(context: Context): Promise<void>;
|
|
716
|
-
/**
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
819
|
+
/**
|
|
820
|
+
* The structural view (spec §9.3) as a serialized watch; commits made while its listener runs arrive folded. Its
|
|
821
|
+
* `entries` are a window over the transcript, as `window` says: the newest 50 by default, then appends, dropping the
|
|
822
|
+
* oldest past 100. Built on the same mount as `Harness.observeConversation()`.
|
|
823
|
+
*/
|
|
824
|
+
watch(context: Context, window?: ConversationWindow): Promise<ConversationWatch>;
|
|
720
825
|
}
|
|
721
826
|
export type ConversationWatch = WatchHandle<ConversationView>;
|
|
722
827
|
/** Durable agent harness over one Session. */
|
|
723
828
|
export interface Harness extends Session {
|
|
724
829
|
/**
|
|
725
|
-
* Enable task scheduling. Idempotent; throws after close
|
|
726
|
-
* `Conversation.submit()`, `Conversation.compact()`, `Conversation.abort()`,
|
|
727
|
-
* `Harness.waitForIdle()`, and `Conversation.waitForIdle()`. Read-only viewers
|
|
830
|
+
* Enable task scheduling. Idempotent; throws after close, and `ReadOnlySession` on a read-only Harness. Calls that
|
|
831
|
+
* ask for progress enable it too: `Conversation.submit()`, `Conversation.compact()`, `Conversation.abort()`,
|
|
832
|
+
* `Submission.wait()`, `waitForTask()`, `Harness.waitForIdle()`, and `Conversation.waitForIdle()`. Read-only viewers
|
|
833
|
+
* never do.
|
|
728
834
|
*/
|
|
729
835
|
resume(): void;
|
|
730
836
|
/**
|
|
@@ -753,23 +859,35 @@ export interface Harness extends Session {
|
|
|
753
859
|
* definition cannot take it settles as `orphaned` instead.
|
|
754
860
|
*/
|
|
755
861
|
abortTask(id: TaskId, context: Context): Promise<"marked" | "terminal">;
|
|
756
|
-
/**
|
|
757
|
-
* Run a task parked by `settings.restartLimit` again: clears its restart count and enables scheduling. Does nothing
|
|
758
|
-
* for a task that is not parked; rejects for an unknown one.
|
|
759
|
-
*/
|
|
760
|
-
retryTask(id: TaskId, context: Context): Promise<void>;
|
|
761
862
|
/** Resolve with the terminal receipt; cancelling `context` cancels only this wait. */
|
|
762
863
|
waitForTask<R>(id: TaskId<R>, context: Context): Promise<SettledTask<R>>;
|
|
763
864
|
/** Resolve when the ordinary ownership scope of every ownerless conversation has no live non-background task. */
|
|
764
865
|
waitForIdle(context: Context): Promise<void>;
|
|
765
866
|
/** Session total: every conversation's `pi.usage` summed. */
|
|
766
867
|
usage(context: Context): Promise<UsageState>;
|
|
767
|
-
/**
|
|
768
|
-
|
|
769
|
-
|
|
868
|
+
/**
|
|
869
|
+
* Every live task with its owner edge, status, and owned conversations (spec §9.4), as a serialized watch; commits
|
|
870
|
+
* made while its listener runs arrive folded.
|
|
871
|
+
*/
|
|
770
872
|
watchTaskGraph(context: Context): Promise<TaskGraphWatch>;
|
|
873
|
+
/**
|
|
874
|
+
* Attach a synchronous `Observer` to a conversation's structural view (spec §9.3), atomically on the Session line,
|
|
875
|
+
* for adapters: `advance` gets each next revision with its operations as memory adopts the commit, inside Storage's
|
|
876
|
+
* `adopt` for a stored one and before it is stored for a deferred one, so it only records it. `window` as for
|
|
877
|
+
* `Conversation.watch()`; each observer has its own. `context` governs only the attachment.
|
|
878
|
+
*/
|
|
879
|
+
observeConversation(id: ConversationId, observer: Observer<ConversationView>, context: Context, window?: ConversationWindow): Promise<Observation<ConversationView>>;
|
|
880
|
+
/**
|
|
881
|
+
* Attach a synchronous `Observer` to the task graph (spec §9.4), as `observeConversation()` does to a view. A
|
|
882
|
+
* `blocked` reason that changes without a commit (a registry change, a failed migration) advances it on the Session
|
|
883
|
+
* line outside any commit and `adopt`, with the background context.
|
|
884
|
+
*/
|
|
885
|
+
observeTaskGraph(observer: Observer<TaskGraph>, context: Context): Promise<Observation<TaskGraph>>;
|
|
771
886
|
}
|
|
772
|
-
/**
|
|
887
|
+
/**
|
|
888
|
+
* What a hook may use: committed reads and the asking task's memos, which hooks and the task share. Hooks run off the
|
|
889
|
+
* Session line, so reads see what is committed when they run; a hook rerun after a crash may see more.
|
|
890
|
+
*/
|
|
773
891
|
export interface HookApi extends DocumentReader {
|
|
774
892
|
readonly taskId: TaskId;
|
|
775
893
|
readonly conversationId: ConversationId;
|
|
@@ -777,6 +895,12 @@ export interface HookApi extends DocumentReader {
|
|
|
777
895
|
readonly models: Models;
|
|
778
896
|
memo<T extends JsonValue>(name: string, context: Context): Promise<T | undefined>;
|
|
779
897
|
memo<T extends JsonValue>(name: string, candidate: T, context: Context): Promise<T>;
|
|
898
|
+
/** Committed entry visible from the task's conversation, as `TaskRuntime.entry()`. */
|
|
899
|
+
entry(id: EntryId, context: Context): Promise<EntryRecord | undefined>;
|
|
900
|
+
/** Undefined when the entry is absent, not visible, or has another kind. */
|
|
901
|
+
entry<D extends JsonValue>(token: Entry<D>, id: EntryId, context: Context): Promise<TypedEntry<D> | undefined>;
|
|
902
|
+
/** Committed raw history of the task's conversation, as `TaskRuntime.entries()`. */
|
|
903
|
+
entries(query: Omit<EntryQuery, "conversationId">, limit: number, cursor: Cursor | undefined, context: Context): Promise<Page<EntryRecord, Cursor>>;
|
|
780
904
|
}
|
|
781
905
|
export type HookResult<T> = T | undefined | Promise<T | undefined>;
|
|
782
906
|
/** Hooks of the built-in generation task. */
|
|
@@ -787,6 +911,17 @@ export interface GenerationHooks {
|
|
|
787
911
|
}, api: HookApi, context: Context): HookResult<{
|
|
788
912
|
readonly messages: readonly Message[];
|
|
789
913
|
}>;
|
|
914
|
+
/**
|
|
915
|
+
* After pi-ai builds the provider request body, before it is sent; the result replaces the body for that request only.
|
|
916
|
+
* Runs again whenever pi-ai rebuilds the body, such as a retry within one attempt. The body is in the provider API's
|
|
917
|
+
* own format (`request.model.api`), so a hook checks the API before changing it.
|
|
918
|
+
*/
|
|
919
|
+
beforeProviderRequest(request: {
|
|
920
|
+
readonly model: Model<Api>;
|
|
921
|
+
readonly payload: unknown;
|
|
922
|
+
}, api: HookApi, context: Context): HookResult<{
|
|
923
|
+
readonly payload: unknown;
|
|
924
|
+
}>;
|
|
790
925
|
/** Every terminal provider message, before classification. */
|
|
791
926
|
afterResponse(message: AssistantMessage, api: HookApi, context: Context): void | Promise<void>;
|
|
792
927
|
/** A final answer; the first `continue` appends a user message and continues the run. */
|
|
@@ -795,7 +930,36 @@ export interface GenerationHooks {
|
|
|
795
930
|
}>;
|
|
796
931
|
/** After every tool of the round is terminal; `results` are the round's result entries in call order. */
|
|
797
932
|
afterTools(assistant: EntryId, results: readonly EntryId[], api: HookApi, context: Context): void | Promise<void>;
|
|
933
|
+
/**
|
|
934
|
+
* After a run answered, its answer committed and its inputs settled `done`: a final answer, or a `terminate` round;
|
|
935
|
+
* not when an `onYield` continuation is taken, and never after a failure or an abort. The requested tasks of every
|
|
936
|
+
* hook are created together as children of the generation, which keeps the run, and the conversation busy, until
|
|
937
|
+
* they are terminal; then queued items are placed and the run ends (spec §8.3). A crash before they are created asks
|
|
938
|
+
* again; once created, never again for this run.
|
|
939
|
+
*/
|
|
940
|
+
afterRun(run: RunSummary, api: HookApi, context: Context): HookResult<{
|
|
941
|
+
readonly tasks: readonly RunEndTask[];
|
|
942
|
+
}>;
|
|
798
943
|
}
|
|
944
|
+
/** How a run ended, for `afterRun` hooks. Read the run's history with `api.entries({ minEntryId: first, maxEntryId: last })`. */
|
|
945
|
+
export type RunSummary = {
|
|
946
|
+
/** A final answer, or a tool round whose every call asked to `terminate`. */
|
|
947
|
+
readonly reason: "answer" | "terminate";
|
|
948
|
+
/**
|
|
949
|
+
* The run's first entry (`LiveRun.first`): the first one the boundary that started it placed, for a continue the failed
|
|
950
|
+
* run's it continues, otherwise its first tool-calling answer; the answer itself for a run that has none of these.
|
|
951
|
+
*/
|
|
952
|
+
readonly first: EntryId;
|
|
953
|
+
/** The answer, or the terminating round's tool-calling answer, whose results follow it. */
|
|
954
|
+
readonly answer: EntryId;
|
|
955
|
+
/** The run's last entry: the answer; for a `terminate` round its newest result, or the reset of its handoff. */
|
|
956
|
+
readonly last: EntryId;
|
|
957
|
+
};
|
|
958
|
+
/** A task an `afterRun` hook asks for, built by `runEndTask()`. */
|
|
959
|
+
export type RunEndTask = {
|
|
960
|
+
readonly task: AnyTask;
|
|
961
|
+
readonly input: JsonValue;
|
|
962
|
+
};
|
|
799
963
|
/** A call as tool hooks see it; `parent` is set for a nested call, one a running tool made through `executeTool()`. */
|
|
800
964
|
export type ToolHookCall = ToolCall & {
|
|
801
965
|
readonly parent?: {
|
|
@@ -810,7 +974,18 @@ export interface ToolHooks {
|
|
|
810
974
|
readonly arguments?: JsonObject;
|
|
811
975
|
readonly block?: string;
|
|
812
976
|
}>;
|
|
813
|
-
/**
|
|
977
|
+
/**
|
|
978
|
+
* Before the result is committed; replaces the result. Runs on every result the tool task writes: an executed
|
|
979
|
+
* call's, and the error results the Harness writes itself, told apart by their diagnostic code: a tool that does not
|
|
980
|
+
* resolve (`tool_unavailable`), invalid arguments (`invalid_arguments`, with `call.arguments` as the model sent
|
|
981
|
+
* them), a block (`blocked`), and, rebuilt from the call's partial output, an interruption (`interrupted`), the
|
|
982
|
+
* restart limit (`restart_limit`), and an abort (`aborted`, `abandoned`). Once the task was cut off more than
|
|
983
|
+
* `settings.restartLimit` times the hooks no longer run, since they may be what cuts it off, nor in the last attempt
|
|
984
|
+
* the scheduler gives an abort handler (restarts at the limit minus one). A result's `structuredOutput` is dropped
|
|
985
|
+
* when the Harness wrote it (a nested call a hook turns into a success gets the bounded output as a schema-less tool's
|
|
986
|
+
* does), and its `control` applies only to a call that completes (not to an interrupted, cut-off, or aborted one).
|
|
987
|
+
* An abort's hooks run inside the abort handler, which cannot be aborted: a slow hook delays `Conversation.abort()`.
|
|
988
|
+
*/
|
|
814
989
|
afterTool(call: ToolHookCall, result: ToolExecutionResult, api: HookApi, context: Context): HookResult<ToolExecutionResult>;
|
|
815
990
|
}
|
|
816
991
|
/** Hooks of the built-in compaction task. */
|
|
@@ -832,4 +1007,5 @@ export interface CompactionHooks {
|
|
|
832
1007
|
readonly summary: string;
|
|
833
1008
|
}>;
|
|
834
1009
|
}
|
|
1010
|
+
export {};
|
|
835
1011
|
//# sourceMappingURL=types.d.ts.map
|