@liy/agent-runner 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -2
- package/dist/bin/agent-runner.d.ts +8 -0
- package/dist/bin/agent-runner.js +110 -52
- package/dist/bin/agent-runner.js.map +2 -2
- package/dist/harness-drivers/pi-rpc.d.ts +110 -0
- package/dist/harness-drivers/shared.d.ts +4 -3
- package/dist/index.d.ts +1 -0
- package/dist/index.js +98 -50
- package/dist/index.js.map +2 -2
- package/package.json +7 -3
package/README.md
CHANGED
|
@@ -191,8 +191,10 @@ pi --mode rpc --provider deepseek --model deepseek-v4-flash --thinking high --no
|
|
|
191
191
|
```
|
|
192
192
|
|
|
193
193
|
The driver writes one Pi RPC `prompt` command to stdin, parses Pi stdout as
|
|
194
|
-
byte-buffered JSONL, forwards Pi
|
|
195
|
-
|
|
194
|
+
byte-buffered JSONL, forwards native Pi records as `pi.event` or
|
|
195
|
+
`pi.extension_ui_request`, routes malformed stdout/stderr as
|
|
196
|
+
`harness.stdout`/`harness.stderr`, and cancels with Pi `abort`, then
|
|
197
|
+
`SIGTERM`, then `SIGKILL` after five seconds.
|
|
196
198
|
|
|
197
199
|
Direct DeepSeek token example:
|
|
198
200
|
|
|
@@ -32,3 +32,11 @@ export declare function shouldPrintHelp(argv: string[]): boolean;
|
|
|
32
32
|
* @returns Help text.
|
|
33
33
|
*/
|
|
34
34
|
export declare function formatHelp(): string;
|
|
35
|
+
/**
|
|
36
|
+
* Check whether this module is executing as the Node entrypoint.
|
|
37
|
+
*
|
|
38
|
+
* @param moduleUrl - Current module URL.
|
|
39
|
+
* @param argvPath - Process entrypoint path, defaulting to `process.argv[1]`.
|
|
40
|
+
* @returns Whether the module should run the CLI.
|
|
41
|
+
*/
|
|
42
|
+
export declare function isEntrypoint(moduleUrl: string, argvPath?: string | undefined): boolean;
|
package/dist/bin/agent-runner.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { createRequire as ___liy_agent_runnerCreateRequire } from "node:module";var require = ___liy_agent_runnerCreateRequire(import.meta.url);
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __export = (target, all) => {
|
|
4
5
|
for (var name in all)
|
|
@@ -6,6 +7,7 @@ var __export = (target, all) => {
|
|
|
6
7
|
};
|
|
7
8
|
|
|
8
9
|
// src/bin/agent-runner.ts
|
|
10
|
+
import { realpathSync } from "node:fs";
|
|
9
11
|
import { resolve } from "node:path";
|
|
10
12
|
import { fileURLToPath } from "node:url";
|
|
11
13
|
|
|
@@ -15334,25 +15336,17 @@ function forwardJsonlByteStream(stream, onLine) {
|
|
|
15334
15336
|
});
|
|
15335
15337
|
});
|
|
15336
15338
|
}
|
|
15337
|
-
function forwardHarnessLine(channel, line, streamName, sanitizer
|
|
15339
|
+
function forwardHarnessLine(channel, taskId, harness, line, streamName, sanitizer) {
|
|
15338
15340
|
const trimmed = sanitizer.redactText(line.trim());
|
|
15339
15341
|
if (!trimmed) {
|
|
15340
15342
|
return;
|
|
15341
15343
|
}
|
|
15342
|
-
|
|
15343
|
-
|
|
15344
|
-
|
|
15345
|
-
|
|
15346
|
-
|
|
15347
|
-
|
|
15348
|
-
}));
|
|
15349
|
-
} catch {
|
|
15350
|
-
channel.send(createExecuteTaskRpcNotification("task.log", {
|
|
15351
|
-
...driver ? { driver } : {},
|
|
15352
|
-
stream: streamName,
|
|
15353
|
-
message: trimmed
|
|
15354
|
-
}));
|
|
15355
|
-
}
|
|
15344
|
+
channel.send(createExecuteTaskRpcNotification(`harness.${streamName}`, {
|
|
15345
|
+
taskId,
|
|
15346
|
+
harness,
|
|
15347
|
+
stream: streamName,
|
|
15348
|
+
message: trimmed
|
|
15349
|
+
}));
|
|
15356
15350
|
}
|
|
15357
15351
|
function waitForChildClose(child) {
|
|
15358
15352
|
return new Promise((resolve2, reject) => {
|
|
@@ -15432,10 +15426,10 @@ function startCodexJsonlHarness(input, spawnProcess) {
|
|
|
15432
15426
|
let cleanupTermination = () => void 0;
|
|
15433
15427
|
child.stdin.end(input.prompt);
|
|
15434
15428
|
const stdoutDone = forwardHarnessLines(child.stdout, (line) => {
|
|
15435
|
-
forwardHarnessLine(input.channel, line, "stdout", sanitizer);
|
|
15429
|
+
forwardHarnessLine(input.channel, input.spec.taskId, "codex-jsonl", line, "stdout", sanitizer);
|
|
15436
15430
|
});
|
|
15437
15431
|
const stderrDone = forwardHarnessLines(child.stderr, (line) => {
|
|
15438
|
-
forwardHarnessLine(input.channel, line, "stderr", sanitizer);
|
|
15432
|
+
forwardHarnessLine(input.channel, input.spec.taskId, "codex-jsonl", line, "stderr", sanitizer);
|
|
15439
15433
|
});
|
|
15440
15434
|
const result = waitForChildClose(child).then(async (closeResult) => {
|
|
15441
15435
|
cleanupTermination();
|
|
@@ -15585,11 +15579,11 @@ function startPiRpcHarness(input, spawnProcess) {
|
|
|
15585
15579
|
cleanupTermination();
|
|
15586
15580
|
await Promise.all([stdoutDone, stderrDone]);
|
|
15587
15581
|
if (!agentEndReached && terminal.exitCode !== 0) {
|
|
15588
|
-
|
|
15589
|
-
|
|
15590
|
-
|
|
15591
|
-
|
|
15592
|
-
|
|
15582
|
+
forwardPiHarnessStreamLine(
|
|
15583
|
+
input,
|
|
15584
|
+
"stderr",
|
|
15585
|
+
`pi-rpc process closed before agent_end with ${formatHarnessExit(terminal)}`
|
|
15586
|
+
);
|
|
15593
15587
|
}
|
|
15594
15588
|
return terminal;
|
|
15595
15589
|
})();
|
|
@@ -15611,37 +15605,57 @@ function handlePiRpcStdoutLine(input) {
|
|
|
15611
15605
|
try {
|
|
15612
15606
|
parsed = JSON.parse(trimmed);
|
|
15613
15607
|
} catch {
|
|
15614
|
-
input.input
|
|
15615
|
-
driver: "pi-rpc",
|
|
15616
|
-
stream: "stdout",
|
|
15617
|
-
message: input.sanitizer.redactText(trimmed)
|
|
15618
|
-
}));
|
|
15608
|
+
forwardPiHarnessStreamLine(input.input, "stdout", input.sanitizer.redactText(trimmed));
|
|
15619
15609
|
return;
|
|
15620
15610
|
}
|
|
15621
|
-
|
|
15622
|
-
|
|
15623
|
-
|
|
15624
|
-
|
|
15625
|
-
}));
|
|
15626
|
-
if (parsed.type === "response" && parsed.command === "prompt" && parsed.success === false) {
|
|
15627
|
-
input.onPromptRejected(new Error(`Pi RPC prompt was rejected: ${formatPiRpcError(parsed, input.sanitizer.redactText)}`));
|
|
15611
|
+
if (isPiRpcResponse(parsed)) {
|
|
15612
|
+
if (parsed.command === "prompt" && parsed.success === false) {
|
|
15613
|
+
input.onPromptRejected(new Error(`Pi RPC prompt was rejected: ${formatPiRpcError(parsed, input.sanitizer.redactText)}`));
|
|
15614
|
+
}
|
|
15628
15615
|
return;
|
|
15629
15616
|
}
|
|
15617
|
+
if (isPiExtensionUiRequest(parsed)) {
|
|
15618
|
+
forwardPiExtensionUiRequest(input.input, input.sanitizer.redactJson(parsed));
|
|
15619
|
+
return;
|
|
15620
|
+
}
|
|
15621
|
+
forwardPiEvent(input.input, input.sanitizer.redactJson(parsed));
|
|
15630
15622
|
if (parsed.type === "agent_end") {
|
|
15631
15623
|
input.onAgentEnd();
|
|
15632
15624
|
}
|
|
15633
15625
|
}
|
|
15634
|
-
function
|
|
15635
|
-
|
|
15626
|
+
function forwardPiEvent(input, event) {
|
|
15627
|
+
input.channel.send(createExecuteTaskRpcNotification("pi.event", {
|
|
15628
|
+
taskId: input.spec.taskId,
|
|
15629
|
+
event
|
|
15630
|
+
}));
|
|
15631
|
+
}
|
|
15632
|
+
function forwardPiExtensionUiRequest(input, request) {
|
|
15633
|
+
input.channel.send(createExecuteTaskRpcNotification("pi.extension_ui_request", {
|
|
15634
|
+
taskId: input.spec.taskId,
|
|
15635
|
+
request
|
|
15636
|
+
}));
|
|
15637
|
+
}
|
|
15638
|
+
function isPiRpcResponse(parsed) {
|
|
15639
|
+
return parsed.type === "response" && typeof parsed.command === "string";
|
|
15640
|
+
}
|
|
15641
|
+
function isPiExtensionUiRequest(parsed) {
|
|
15642
|
+
return parsed.type === "extension_ui_request" && typeof parsed.id === "string";
|
|
15643
|
+
}
|
|
15644
|
+
function forwardPiHarnessStreamLine(input, stream, message) {
|
|
15645
|
+
const trimmed = message.trim();
|
|
15636
15646
|
if (!trimmed) {
|
|
15637
15647
|
return;
|
|
15638
15648
|
}
|
|
15639
|
-
input.channel.send(createExecuteTaskRpcNotification(
|
|
15640
|
-
|
|
15641
|
-
|
|
15649
|
+
input.channel.send(createExecuteTaskRpcNotification(`harness.${stream}`, {
|
|
15650
|
+
taskId: input.spec.taskId,
|
|
15651
|
+
harness: "pi-rpc",
|
|
15652
|
+
stream,
|
|
15642
15653
|
message: trimmed
|
|
15643
15654
|
}));
|
|
15644
15655
|
}
|
|
15656
|
+
function forwardPiStderrLine(input, line, sanitizer) {
|
|
15657
|
+
forwardPiHarnessStreamLine(input, "stderr", sanitizer.redactText(line));
|
|
15658
|
+
}
|
|
15645
15659
|
function writePiRpcCommand(child, command) {
|
|
15646
15660
|
child.stdin.write(`${JSON.stringify(command)}
|
|
15647
15661
|
`);
|
|
@@ -15768,30 +15782,40 @@ async function runTaskAgentRunner(spec, options = {}) {
|
|
|
15768
15782
|
const harness = resolveAgentRunnerHarness(config2, spec.agentRunner);
|
|
15769
15783
|
const channel = await openControlChannel(spec.rpcUrl);
|
|
15770
15784
|
try {
|
|
15771
|
-
channel
|
|
15785
|
+
sendTaskStatus(channel, {
|
|
15772
15786
|
taskId: spec.taskId,
|
|
15773
|
-
|
|
15774
|
-
})
|
|
15787
|
+
status: "running"
|
|
15788
|
+
});
|
|
15775
15789
|
const completion = await runHarnessAndReadCompletion({
|
|
15776
15790
|
spec,
|
|
15777
15791
|
harness,
|
|
15778
15792
|
channel,
|
|
15779
15793
|
...options.env ? { env: options.env } : {}
|
|
15780
15794
|
});
|
|
15781
|
-
channel
|
|
15795
|
+
sendTaskStatus(channel, {
|
|
15782
15796
|
taskId: spec.taskId,
|
|
15783
15797
|
...completion
|
|
15784
|
-
})
|
|
15798
|
+
});
|
|
15785
15799
|
return completion;
|
|
15800
|
+
} catch (error48) {
|
|
15801
|
+
const completion = createFailedCompletion(error48);
|
|
15802
|
+
await writeTaskCompletion({
|
|
15803
|
+
paths,
|
|
15804
|
+
completion
|
|
15805
|
+
}).catch(() => void 0);
|
|
15806
|
+
try {
|
|
15807
|
+
sendTaskStatus(channel, {
|
|
15808
|
+
taskId: spec.taskId,
|
|
15809
|
+
...completion
|
|
15810
|
+
});
|
|
15811
|
+
} catch {
|
|
15812
|
+
}
|
|
15813
|
+
throw error48;
|
|
15786
15814
|
} finally {
|
|
15787
15815
|
channel.close();
|
|
15788
15816
|
}
|
|
15789
15817
|
} catch (error48) {
|
|
15790
|
-
const completion =
|
|
15791
|
-
status: "failed",
|
|
15792
|
-
summary: error48 instanceof Error ? error48.message : String(error48),
|
|
15793
|
-
artifactIds: []
|
|
15794
|
-
};
|
|
15818
|
+
const completion = createFailedCompletion(error48);
|
|
15795
15819
|
await writeTaskCompletion({
|
|
15796
15820
|
paths,
|
|
15797
15821
|
completion
|
|
@@ -15799,6 +15823,16 @@ async function runTaskAgentRunner(spec, options = {}) {
|
|
|
15799
15823
|
throw error48;
|
|
15800
15824
|
}
|
|
15801
15825
|
}
|
|
15826
|
+
function sendTaskStatus(channel, params) {
|
|
15827
|
+
channel.send(createExecuteTaskRpcNotification("task.status", params));
|
|
15828
|
+
}
|
|
15829
|
+
function createFailedCompletion(error48) {
|
|
15830
|
+
return {
|
|
15831
|
+
status: "failed",
|
|
15832
|
+
summary: error48 instanceof Error ? error48.message : String(error48),
|
|
15833
|
+
artifactIds: []
|
|
15834
|
+
};
|
|
15835
|
+
}
|
|
15802
15836
|
function createHarnessEnvironment(input) {
|
|
15803
15837
|
const baseEnv = input.env ?? process.env;
|
|
15804
15838
|
const harnessEnv = {};
|
|
@@ -15906,7 +15940,14 @@ async function runHarnessAndReadCompletion(input) {
|
|
|
15906
15940
|
});
|
|
15907
15941
|
return completion2;
|
|
15908
15942
|
}
|
|
15909
|
-
const completion = await readTaskCompletion(paths)
|
|
15943
|
+
const completion = await readTaskCompletion(paths).catch(async (error48) => {
|
|
15944
|
+
const fallback = createMissingCompletionFailure(error48);
|
|
15945
|
+
await writeTaskCompletion({
|
|
15946
|
+
paths,
|
|
15947
|
+
completion: fallback
|
|
15948
|
+
});
|
|
15949
|
+
return fallback;
|
|
15950
|
+
});
|
|
15910
15951
|
await validateTaskArtifactFiles({
|
|
15911
15952
|
paths,
|
|
15912
15953
|
completion
|
|
@@ -15916,6 +15957,14 @@ async function runHarnessAndReadCompletion(input) {
|
|
|
15916
15957
|
}
|
|
15917
15958
|
return completion;
|
|
15918
15959
|
}
|
|
15960
|
+
function createMissingCompletionFailure(error48) {
|
|
15961
|
+
const detail = error48 instanceof Error ? error48.message : String(error48);
|
|
15962
|
+
return {
|
|
15963
|
+
status: "failed",
|
|
15964
|
+
summary: `harness ended without writing state/completion.json: ${detail}`,
|
|
15965
|
+
artifactIds: []
|
|
15966
|
+
};
|
|
15967
|
+
}
|
|
15919
15968
|
function validateRunnerSpec(spec) {
|
|
15920
15969
|
if ("harness" in spec) {
|
|
15921
15970
|
throw new Error("task spec harness is no longer supported; use task spec agentRunner");
|
|
@@ -16063,11 +16112,20 @@ if (isEntrypoint(import.meta.url)) {
|
|
|
16063
16112
|
process.exitCode = 1;
|
|
16064
16113
|
});
|
|
16065
16114
|
}
|
|
16066
|
-
function isEntrypoint(moduleUrl) {
|
|
16067
|
-
return
|
|
16115
|
+
function isEntrypoint(moduleUrl, argvPath = process.argv[1]) {
|
|
16116
|
+
return argvPath ? realpathEntrypointPath(fileURLToPath(moduleUrl)) === realpathEntrypointPath(argvPath) : false;
|
|
16117
|
+
}
|
|
16118
|
+
function realpathEntrypointPath(path) {
|
|
16119
|
+
const resolved = resolve(path);
|
|
16120
|
+
try {
|
|
16121
|
+
return realpathSync.native(resolved);
|
|
16122
|
+
} catch {
|
|
16123
|
+
return resolved;
|
|
16124
|
+
}
|
|
16068
16125
|
}
|
|
16069
16126
|
export {
|
|
16070
16127
|
formatHelp,
|
|
16128
|
+
isEntrypoint,
|
|
16071
16129
|
main,
|
|
16072
16130
|
readConfigPathArg,
|
|
16073
16131
|
readTaskSpecArg,
|