@parcha/agentrun-pi 0.1.0-beta.17 → 0.1.0-beta.19
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 +7 -7
- package/dist/durable/node-runner.d.ts +8 -2
- package/dist/durable/node-runner.js +15 -5
- package/dist/host-session.js +2 -1
- package/dist/runner.js +2 -1
- package/dist/skills/author/SKILL.md +2 -0
- package/dist/skills/author/references/language.md +3 -3
- package/dist/thinking.d.ts +3 -0
- package/dist/thinking.js +7 -0
- package/dist/types.d.ts +4 -0
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# agent.run() + Pi
|
|
2
2
|
|
|
3
|
-
Describe a task in Pi, inspect the workflow, run it with your current model, and save its definition for new input. Requires Node 22.19+ and Pi 1.2.0.
|
|
3
|
+
Describe a task in Pi, inspect the workflow, run it with your current model, and save its definition for new input. Requires Node 22.19+ and Pi 1.0.4 to below 1.4 (CI tests 1.0.4, 1.1.0, 1.2.0 and 1.3.0).
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
7
|
-
If you do not have Pi, install the
|
|
7
|
+
If you do not have Pi, install it first; 1.3.0 is the newest version CI tests:
|
|
8
8
|
|
|
9
9
|
```sh
|
|
10
|
-
npm install -g @earendil-works/pi-coding-agent@1.
|
|
10
|
+
npm install -g @earendil-works/pi-coding-agent@1.3.0
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
Then, in your project:
|
|
@@ -37,7 +37,7 @@ npx @parcha/agentrun-pi@beta demo
|
|
|
37
37
|
|
|
38
38
|
It prints each sub-question with its answer, then `Status: complete`, the answer and the scripted call counts, and exits 0. `npx @parcha/agentrun-pi@beta demo empty` runs the missing-evidence path and prints `Status: escalated`.
|
|
39
39
|
|
|
40
|
-
The demo shows the workflow graph, progress, and a completed result with call counts. It uses scripted responses over fictional sources. It makes no model calls and does not test model quality. Run `/agentrun status` to check the loaded skill and Pi host version.
|
|
40
|
+
The demo shows the workflow graph, progress, and a completed result with call counts. It uses scripted responses over fictional sources. It makes no model calls and does not test model quality. Run `/agentrun status` to check the loaded skill and Pi host version. Status names the supported range, 1.0.4 to below 1.4, and flags a host outside it without blocking it. Missing Pi or Jev access does not prevent the scripted demo. To repeat it, run `/agentrun run` or `/agentrun demo`. A scripted demo stays scripted on rerun, including its missing-evidence path. Use `/agentrun demo live` to switch to real Pi and Jev calls. Workflows authored by Pi use real adapters.
|
|
41
41
|
|
|
42
42
|
For an offline Pi startup, use `pi --offline`. Without that flag, Pi may download optional command-line tools on first launch. This is separate from the scripted demo, which makes no network calls.
|
|
43
43
|
|
|
@@ -213,7 +213,7 @@ const result = await runWorkflow(workflow, input, {
|
|
|
213
213
|
});
|
|
214
214
|
```
|
|
215
215
|
|
|
216
|
-
`ctx` supplies the active model and public model registry. Tools are explicitly supplied and receive the original context; outer hooks are not copied. The captured active model remains fixed for the run.
|
|
216
|
+
`ctx` supplies the active model and public model registry. Tools are explicitly supplied and receive the original context; outer hooks are not copied. The captured active model remains fixed for the run. A node thinks at its own `thinking` level; a node that names none thinks at medium, not at the host session's level, unless the runner's own `thinkingLevel` option sets another. Thinking is never off: a level of `off` runs at medium. The runner bounds turns, submissions, and time, and refuses an absent model instead of selecting a fallback. These limits do not impose token or spending caps.
|
|
217
217
|
|
|
218
218
|
For a standalone application, `createPiRunner(options)` accepts a configured SDK `ModelRuntime` and its selected `model`. Supply `tools` explicitly. It loads no ambient filesystem tools, workspace instructions, extensions, prompt templates, or skills. `createPiHostSessionFactory(ctx)` exposes the same native child session transport for integrations that own their own runner. Factories are unnecessary for ordinary extension use.
|
|
219
219
|
|
|
@@ -248,7 +248,7 @@ The standalone CLI remains available as `node packages/pi/dist/cli.js --help` fr
|
|
|
248
248
|
|
|
249
249
|
## Sign in, pick a model, check keys
|
|
250
250
|
|
|
251
|
-
`@parcha/agentrun-pi/signin` is what a demo, or your own app, runs before its first model call. It is the only entry of this package that loads `@earendil-works/pi-ai`, an optional peer: install it beside the package (`npm install @earendil-works/pi-ai
|
|
251
|
+
`@parcha/agentrun-pi/signin` is what a demo, or your own app, runs before its first model call. It is the only entry of this package that loads `@earendil-works/pi-ai`, an optional peer: install it beside the package (`npm install @earendil-works/pi-ai`) to use this entry. No other entry imports it.
|
|
252
252
|
|
|
253
253
|
```js
|
|
254
254
|
import { builtinModels } from '@earendil-works/pi-ai/providers/all';
|
|
@@ -290,7 +290,7 @@ These commands create a separate `agentrun-pi-project` beside the checkout. You
|
|
|
290
290
|
|
|
291
291
|
Pi is optional for `@parcha/agentrun-dsl`. This package depends on the DSL and the Jev adapter only. The Pi packages it uses (`@earendil-works/pi-coding-agent`, `@earendil-works/pi-agent-core`, `@earendil-works/pi-tui`, and `@earendil-works/pi-ai` for the sign-in entry only) and `typebox` are optional peer dependencies at `*`, as Pi's package guidance requires, so an installed copy never shadows the host's. The release inventory records the locked versions.
|
|
292
292
|
|
|
293
|
-
When loaded as an extension, Pi resolves its core packages and TypeBox through the host loader, and `pi install` adds nothing else. A standalone application or the `agentrun-pi` CLI has no host: install the peers yourself (`npm install @earendil-works/pi-coding-agent
|
|
293
|
+
When loaded as an extension, Pi resolves its core packages and TypeBox through the host loader, and `pi install` adds nothing else. A standalone application or the `agentrun-pi` CLI has no host: install the peers yourself (`npm install @earendil-works/pi-coding-agent @earendil-works/pi-agent-core @earendil-works/pi-tui typebox`). This release supports Pi 1.0.4 to below 1.4, and CI tests 1.0.4, 1.1.0, 1.2.0 and 1.3.0; peer ranges at `*` do not make an older or newer host compatible. The sign-in entry needs pi-ai 1.1.0 or later: pi-ai 1.0.x ignores the app name and would put pi's name on ChatGPT's sign-in page, so `signIn` refuses it with `SignInError` (`APP_NAME_IGNORED`) before the page is shown. The offline loader regression checks competing local dependencies, a native file read, and the scripted workflow. Pi's [package guidance](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/docs/packages.md#dependencies) is the rule this follows.
|
|
294
294
|
|
|
295
295
|
The durable entry (`@parcha/agentrun-pi/durable`) takes pi-durable and chord as optional peers from 1.0.4 to below 1.4; CI runs it on 1.0.4, 1.1.0, 1.2.0 and 1.3.0. A run that pi-durable 1.1 left (killed, paused, or with a tool call in flight) continues on 1.2. The move does not go back. A run that pi 1.2 left with a tool call in flight cannot be continued by pi 1.1: 1.1 waits on the newer task, and the only thing it writes is that task's mark from running back to pending, as pi does for any task a dead process left running. Continue such a run on 1.2, and do not downgrade pi under a live run. A host can call `refuseNewerTasks(harness, context)` from the durable entry after opening its Harness. On pi before 1.2, it then fails such a store with `NewerTaskError` (code `PI_TASK_NEWER`, naming the task's kind and version) instead of waiting.
|
|
296
296
|
|
|
@@ -33,7 +33,9 @@ export type NodeRecord = Pick<RecordContract, "contracts" | "checks"> & {
|
|
|
33
33
|
};
|
|
34
34
|
export type NodeHost = {
|
|
35
35
|
/** The agent a node's conversation runs with: its model, thinking level, working directory and the host's own
|
|
36
|
-
* extensions and tools. The runner adds its extension and `submit` where the host did not place them.
|
|
36
|
+
* extensions and tools. The runner adds its extension and `submit` where the host did not place them. The node's
|
|
37
|
+
* own thinking level outranks the host's; when neither names one, the node thinks at medium (never at the level its
|
|
38
|
+
* conversation would copy from its owner's, and never off). */
|
|
37
39
|
agent(node: NodeRequest): AgentChange | Promise<AgentChange>;
|
|
38
40
|
/** Duty text for a node's system prompt, after the interpreter's. `offered` names the tools the agent lists. */
|
|
39
41
|
stance?(node: NodeRequest, offered: {
|
|
@@ -74,10 +76,14 @@ export declare class NodeFailure extends Error {
|
|
|
74
76
|
detail?: JsonValue;
|
|
75
77
|
} | undefined;
|
|
76
78
|
readonly code = "NODE_NOT_DELIVERED";
|
|
79
|
+
/** The item a map that collects its items' failures ends on this (`isItemFailure`): the node's delivery attempts are
|
|
80
|
+
* spent, or its model will not answer (`model_error`, as a provider's content filter). Never an abort, a stale or
|
|
81
|
+
* faulted run, a missing model, or a schema no record can satisfy. */
|
|
82
|
+
readonly itemFailure: boolean;
|
|
77
83
|
constructor(message: string, node: string, final: boolean, executionPath?: string | undefined, unanswered?: {
|
|
78
84
|
reason: string;
|
|
79
85
|
detail?: JsonValue;
|
|
80
|
-
} | undefined);
|
|
86
|
+
} | undefined, itemFailure?: boolean);
|
|
81
87
|
}
|
|
82
88
|
/** The node runner over a host. Install `extension` in the registry before the Harness opens; `on` binds the runner
|
|
83
89
|
* to where its conversations live (`taskScope`, `hostScope`). */
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
import { randomUUID } from "node:crypto";
|
|
13
13
|
import { configure, defineDoc, defineExtension, GenerationTask, hook, section, } from "@earendil-works/pi-durable";
|
|
14
14
|
import { canonicalSha256, runStopOf } from "@parcha/agentrun-dsl/recovery";
|
|
15
|
+
import { nodeThinking } from "../thinking.js";
|
|
15
16
|
import { closeNodeAttempt, runNodeAttempt } from "./node.js";
|
|
16
17
|
import { DELIVERY_ATTEMPTS, lintRecordRoot, submitFooter } from "./record.js";
|
|
17
18
|
import { workspaceRecordFile } from "./record-file.js";
|
|
@@ -29,13 +30,18 @@ export class NodeFailure extends Error {
|
|
|
29
30
|
executionPath;
|
|
30
31
|
unanswered;
|
|
31
32
|
code = "NODE_NOT_DELIVERED";
|
|
32
|
-
|
|
33
|
+
/** The item a map that collects its items' failures ends on this (`isItemFailure`): the node's delivery attempts are
|
|
34
|
+
* spent, or its model will not answer (`model_error`, as a provider's content filter). Never an abort, a stale or
|
|
35
|
+
* faulted run, a missing model, or a schema no record can satisfy. */
|
|
36
|
+
itemFailure;
|
|
37
|
+
constructor(message, node, final, executionPath, unanswered, itemFailure = false) {
|
|
33
38
|
super(message);
|
|
34
39
|
this.node = node;
|
|
35
40
|
this.final = final;
|
|
36
41
|
this.executionPath = executionPath;
|
|
37
42
|
this.unanswered = unanswered;
|
|
38
43
|
this.name = "NodeFailure";
|
|
44
|
+
this.itemFailure = final && itemFailure;
|
|
39
45
|
}
|
|
40
46
|
}
|
|
41
47
|
/** `work` under a run's stop: its result, or the stop's reason as soon as the stop lands, and at once when it already
|
|
@@ -123,6 +129,9 @@ export function nodeRunner(host, options = {}) {
|
|
|
123
129
|
sections: [section("task", async (input, context) => (await input.read.snapshot(NodeDoc, input.conversationId, context))?.system || undefined, { tag: false })],
|
|
124
130
|
hooks: [hook(GenerationTask, { beforeRequest: present }), nudge],
|
|
125
131
|
});
|
|
132
|
+
/** The host's agent at the node's thinking level. A level left unset would follow the conversation's creation: a
|
|
133
|
+
* task's node copies its owner's level, and a node no task owns starts off. */
|
|
134
|
+
const leveled = (agent, node) => ({ ...agent, thinkingLevel: nodeThinking(node.thinking, agent.thinkingLevel) });
|
|
126
135
|
/** The host's agent with the runner's extension first and `submit` last, unless the host placed them. */
|
|
127
136
|
const withNodes = (agent) => ({
|
|
128
137
|
...agent,
|
|
@@ -145,13 +154,13 @@ export function nodeRunner(host, options = {}) {
|
|
|
145
154
|
const { review, signal, step, ...asked } = params;
|
|
146
155
|
// An attempt the driver admitted is found again by its session; any other call is a conversation of its own.
|
|
147
156
|
const node = { ...asked, sessionId: step?.sessionId ?? `unjournaled:${randomUUID()}`, attempt: step?.attempt ?? 0, earlierSessionIds: step?.earlierSessionIds ?? [] };
|
|
148
|
-
const fail = (message, final, unanswered) => new NodeFailure(message, node.label, final, node.executionPath, unanswered);
|
|
157
|
+
const fail = (message, final, unanswered, itemFailure = false) => new NodeFailure(message, node.label, final, node.executionPath, unanswered, itemFailure);
|
|
149
158
|
// Only a schema no submit call can satisfy is refused here: any other is the node's contract as its author wrote it.
|
|
150
159
|
const lint = lintRecordRoot(node.schema);
|
|
151
160
|
if (lint.length)
|
|
152
161
|
throw fail(`${node.kind} node "${node.label}" cannot deliver a record of its schema: ${lint.join("; ")}`, true);
|
|
153
162
|
// The host's own answers are awaited under the stop too: one that lands meanwhile opens no conversation.
|
|
154
|
-
const { agent, record } = await underStop(signal, async () => ({ agent: await host.agent(node), record: await host.record?.(node) ?? {} }));
|
|
163
|
+
const { agent, record } = await underStop(signal, async () => ({ agent: leveled(await host.agent(node), node), record: await host.record?.(node) ?? {} }));
|
|
155
164
|
const label = record.label ?? `the ${node.label} record`;
|
|
156
165
|
const offered = (listed(agent.tools) ? agent.tools : listed(agent.extensions) ? agent.extensions.flatMap((selected) => selected.tools ?? []) : [])
|
|
157
166
|
.map((offer) => offer.name).filter((name) => name !== "submit");
|
|
@@ -215,10 +224,11 @@ export function nodeRunner(host, options = {}) {
|
|
|
215
224
|
return outcome.delivered.record;
|
|
216
225
|
if (outcome.settled?.status === "unanswered") {
|
|
217
226
|
const { reason, detail } = outcome.settled;
|
|
218
|
-
|
|
227
|
+
// Only the model's own refusal to answer is the item's: an abort, a stale or faulted run and a missing model are the run's.
|
|
228
|
+
throw fail(`${node.label}: the model did not answer (${reason})`, true, { reason, ...(detail !== undefined ? { detail } : {}) }, reason === "model_error");
|
|
219
229
|
}
|
|
220
230
|
const spent = ((await scope.snapshot(RecordDoc, outcome.conversationId, base))?.attempts ?? 0) >= maxAttempts;
|
|
221
|
-
throw fail(`${node.label} did not submit (${spent ? "its delivery attempts are spent" : "it ended its run without a record"})`, spent);
|
|
231
|
+
throw fail(`${node.label} did not submit (${spent ? "its delivery attempts are spent" : "it ended its run without a record"})`, spent, undefined, spent);
|
|
222
232
|
}
|
|
223
233
|
catch (error) {
|
|
224
234
|
if (!signal?.aborted)
|
package/dist/host-session.js
CHANGED
|
@@ -74,9 +74,10 @@ export function createPiHostSessionFactory(context) {
|
|
|
74
74
|
}
|
|
75
75
|
export function createPiHostRunner(context, options = {}) {
|
|
76
76
|
const model = selectedModel(context);
|
|
77
|
+
// The host session's thinking level is not a node's: a node that names none thinks at medium, unless the caller
|
|
78
|
+
// passes its own `thinkingLevel`.
|
|
77
79
|
return createPiRunner({
|
|
78
80
|
...options, model, cwd: options.cwd ?? context.cwd,
|
|
79
|
-
thinkingLevel: options.thinkingLevel ?? context.thinkingLevel,
|
|
80
81
|
sessionFactory: createPiHostSessionFactory(context),
|
|
81
82
|
});
|
|
82
83
|
}
|
package/dist/runner.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Compile } from "typebox/compile";
|
|
2
2
|
import { createAgentSession, DefaultResourceLoader, SessionManager, SettingsManager, ModelRuntime, } from "@earendil-works/pi-coding-agent";
|
|
3
3
|
import { PiRunError } from "./run-error.js";
|
|
4
|
+
import { nodeThinking } from "./thinking.js";
|
|
4
5
|
export { PiRunError } from "./run-error.js";
|
|
5
6
|
function positive(value, name) {
|
|
6
7
|
if (!Number.isSafeInteger(value) || value < 1)
|
|
@@ -159,7 +160,7 @@ export function createPiRunner(options) {
|
|
|
159
160
|
const sessionManager = SessionManager.inMemory(cwd);
|
|
160
161
|
const prepared = {
|
|
161
162
|
cwd, model: options.model, modelRuntime: options.modelRuntime,
|
|
162
|
-
thinkingLevel: request.thinking
|
|
163
|
+
thinkingLevel: nodeThinking(request.thinking, options.thinkingLevel), maxTurns: maxTurns ?? undefined, resourceLoader, settingsManager,
|
|
163
164
|
sessionManager,
|
|
164
165
|
tools: [...requested, "submit"],
|
|
165
166
|
customTools: [...(options.tools ?? []).filter(tool => requested.includes(tool.name)).map(tool => ({
|
|
@@ -58,6 +58,8 @@ A mandatory category with no valid `unknown` value needs a missing-facts path wh
|
|
|
58
58
|
}
|
|
59
59
|
```
|
|
60
60
|
|
|
61
|
+
A dry run gives a boolean whose schema leaves it open (no `const` or `enum`) the value `false`, so an `escalate` on such a boolean being `false`, like this one, always fires there: the dry run reports `not_run` and names the escalation in `skipped`. The steps after it are not exercised, and that is not a defect to repair.
|
|
62
|
+
|
|
61
63
|
For Jev nodes, use the bundled [decision design guide](references/jev-decisions.md), also returned by `describe` under `authoring.jev`. No separate TypeSafe skill installation or live documentation access is required to author this DSL. Give each decision the actual material it must judge: a researcher's summary is a claim, not an independent source. Let code perform exact operations and agents do open-ended research; use Jev for focused semantic decisions with complete context.
|
|
62
64
|
|
|
63
65
|
## Minimal typed example
|
|
@@ -25,7 +25,7 @@ This is the complete set. Each kind accepts exactly these fields; any other fiel
|
|
|
25
25
|
- `extract`: `label`, `state`, `instructions`, `sopSection`, `out`, `as`, `requires`, `tools`, `effort`, `thinking`, `verify`, `tier`
|
|
26
26
|
- `report`: `label`, `state`, `instructions`, `sopSection`, `requires`, `tools`, `effort`, `thinking`
|
|
27
27
|
- `artifact`: `label`, `state`, `type`, `path`, `instructions`, `sopSection`, `requires`, `tools`, `effort`, `thinking`
|
|
28
|
-
- `map`: `label`, `itemsPath`, `body`, `as`, `resultPath`, `maxConcurrency`
|
|
28
|
+
- `map`: `label`, `itemsPath`, `body`, `as`, `resultPath`, `maxConcurrency`, `onItemFailure`, `failedAs`
|
|
29
29
|
- `parallel`: `label`, `branches`
|
|
30
30
|
- `loop`: `label`, `body`, `until`, `maxIters`, `expect_iters`
|
|
31
31
|
- `escalate`: `label`, `when`, `kind`, `stage`, `summary`
|
|
@@ -51,7 +51,7 @@ Their fields:
|
|
|
51
51
|
- `out` names the schema the submission must satisfy; the value lands at `as`.
|
|
52
52
|
- `requires` lists state paths that must hold evidence before the node runs, each produced upstream: missing values, null, blank strings, empty arrays and empty objects stop the run; `false` and `0` pass.
|
|
53
53
|
- `tools` names tools the host offers. `[]` means no tools; omitting `tools` offers every tool the host allows. Never name a tool the host did not offer.
|
|
54
|
-
- `effort` is minimal|low|medium|high; `thinking` is low|medium|high (never off); `tier` is fast|default|strong. They are requests to the host: resource ceilings are the host's.
|
|
54
|
+
- `effort` is minimal|low|medium|high; `thinking` is low|medium|high (never off); `tier` is fast|default|strong. They are requests to the host: resource ceilings are the host's. A node that names no `thinking` thinks at medium, unless its host sets another level.
|
|
55
55
|
- An `agent` node may carry `budget_usd`, the most it asks to spend in dollars (above 0), which the host caps by what it has left, and `context`, fresh|fork: `fresh` (the default) sees only its instructions and state; `fork` asks the host to start it from the caller's transcript, which a host refuses where it has none.
|
|
56
56
|
- `sopSection` names one heading of the host's SOP, or a list of them, as the exact text after "## ". The node receives those sections verbatim.
|
|
57
57
|
- `verify` reviews a submission before it is accepted: {"out": a question schema with at least one boolean question, "state"?, "maxDrives"?: an integer >= 1 (default 2, no maximum), "override"?: {"below": a number in (0, 1), default 0.3}}. A boolean question named after a submission field doubts that field when its yes-probability is below `override.below`; any other boolean question is a requirement met at 0.5. A rejected submission returns to the same session with the reasons.
|
|
@@ -76,7 +76,7 @@ Typed questions answered by the host's judge in one request each: no tools, no s
|
|
|
76
76
|
### Control nodes
|
|
77
77
|
|
|
78
78
|
- `chain`: non-empty `steps`, run in order.
|
|
79
|
-
- `map`: `itemsPath` (an upstream list), `body` and `as`. The body sees `item` and `item_index`; `maxConcurrency` is a positive integer (default 4); `resultPath` selects one path from each completed item's state. Without `resultPath`, and with no `as` in the body, each item's result is its whole state, the mapped list included: set `resultPath` (or an `as` in the body) for a large map; the validator warns.
|
|
79
|
+
- `map`: `itemsPath` (an upstream list), `body` and `as`. The body sees `item` and `item_index`; `maxConcurrency` is a positive integer (default 4); `resultPath` selects one path from each completed item's state. Without `resultPath`, and with no `as` in the body, each item's result is its whole state, the mapped list included: set `resultPath` (or an `as` in the body) for a large map; the validator warns. `onItemFailure` is `stop` (default: the first failing item stops the map and the run) or `collect`. With `collect`, an item whose node fails (a call that failed after its retries, an agent that delivered no record, output that does not match its schema, a failed check) ends as {item_index, label, code, message} in the list at `failedAs`, the other items finish, and `as` stays aligned with the items: `as[i]` is item i's result, or `null` when item i failed. Filter the nulls explicitly if only successes are wanted. Gate on `failedAs` with `escalate` or a code node; never let failures pass silently. A crash, a cancel, an `escalate` inside the item or an effect whose outcome is unknown is never collected.
|
|
80
80
|
- `parallel`: at least two `branches`, each starting from the state before the parallel node. Branches write disjoint keys and never read a sibling's writes.
|
|
81
81
|
- `loop`: `body`, `until` (a predicate) and an integer `maxIters` of at least 1 (no maximum), optionally an integer `expect_iters` of at least 1 (priced passes). At the bound the state passes through with `until` unmet; follow the loop with an escalate or gate on that condition.
|
|
82
82
|
- `escalate`: `when` (a predicate), and non-empty `kind`, `stage` and `summary`. When the predicate holds the run stops without output and returns the escalation with its interpolated summary.
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
/** A workflow node's thinking level: the first level given, the node's own before its host's, else medium. Thinking is
|
|
2
|
+
* never off: a level of `off` is medium too. */
|
|
3
|
+
export declare function nodeThinking<Level extends string>(...given: readonly (Level | null | undefined)[]): Exclude<Level, "off"> | "medium";
|
package/dist/thinking.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Kept apart from runner.ts so the durable node runner reads it without a pi coding agent installed.
|
|
2
|
+
/** A workflow node's thinking level: the first level given, the node's own before its host's, else medium. Thinking is
|
|
3
|
+
* never off: a level of `off` is medium too. */
|
|
4
|
+
export function nodeThinking(...given) {
|
|
5
|
+
const level = given.find((named) => named !== undefined && named !== null);
|
|
6
|
+
return level === undefined || level === "off" ? "medium" : level;
|
|
7
|
+
}
|
package/dist/types.d.ts
CHANGED
|
@@ -88,6 +88,8 @@ export type PiSessionFactory = (options: PiSessionOptions) => Promise<{
|
|
|
88
88
|
}>;
|
|
89
89
|
export interface PiRunnerCommonOptions {
|
|
90
90
|
model: PiModel;
|
|
91
|
+
/** The level a node that names none thinks at (default `medium`). A node's own level outranks it, and `off` is
|
|
92
|
+
* `medium`: thinking is never off. */
|
|
91
93
|
thinkingLevel?: PiThinkingLevel;
|
|
92
94
|
cwd?: string;
|
|
93
95
|
tools?: PiToolDefinition[];
|
|
@@ -117,6 +119,8 @@ export interface PiHostContext {
|
|
|
117
119
|
result(): Promise<unknown>;
|
|
118
120
|
};
|
|
119
121
|
};
|
|
122
|
+
/** The host session's thinking level. A node does not inherit it: a node that names no level thinks at medium,
|
|
123
|
+
* unless the runner's own `thinkingLevel` option says otherwise. */
|
|
120
124
|
thinkingLevel?: PiThinkingLevel;
|
|
121
125
|
}
|
|
122
126
|
export type PiHostRunnerOptions = Omit<PiRunnerCommonOptions, "model">;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@parcha/agentrun-pi",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.19",
|
|
4
4
|
"description": "Pi extension for building, running and evaluating AgentRun workflows",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -50,12 +50,12 @@
|
|
|
50
50
|
"@earendil-works/pi-coding-agent": "1.1.0",
|
|
51
51
|
"@earendil-works/pi-durable": "1.1.0",
|
|
52
52
|
"@earendil-works/pi-tui": "1.1.0",
|
|
53
|
-
"@parcha/pi-durable-disk": "0.1.0-beta.
|
|
53
|
+
"@parcha/pi-durable-disk": "0.1.0-beta.19",
|
|
54
54
|
"typebox": "1.3.7"
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
|
-
"@parcha/agentrun-dsl": "0.1.0-beta.
|
|
58
|
-
"@parcha/agentrun-jev": "0.1.0-beta.
|
|
57
|
+
"@parcha/agentrun-dsl": "0.1.0-beta.19",
|
|
58
|
+
"@parcha/agentrun-jev": "0.1.0-beta.19"
|
|
59
59
|
},
|
|
60
60
|
"peerDependencies": {
|
|
61
61
|
"@earendil-works/pi-agent-core": "*",
|