lark-remote 0.1.6 → 0.1.8
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 +51 -1
- package/README.en.md +9 -1
- package/README.md +14 -2
- package/dist/bridge/approval-coordinator.d.ts +71 -34
- package/dist/bridge/approval-coordinator.js +225 -41
- package/dist/bridge/inbound-media.d.ts +62 -0
- package/dist/bridge/inbound-media.js +282 -0
- package/dist/bridge/index.d.ts +97 -13
- package/dist/bridge/index.js +227 -87
- package/dist/bridge/queue-manager.d.ts +2 -1
- package/dist/bridge/queue-manager.js +1 -0
- package/dist/card/approval-render.js +294 -36
- package/dist/card/bash-card-session.d.ts +2 -24
- package/dist/card/bash-card-session.js +6 -73
- package/dist/card/bash-renderer.js +2 -3
- package/dist/card/card-budget.js +29 -75
- package/dist/card/card-session.d.ts +48 -0
- package/dist/card/card-session.js +86 -0
- package/dist/card/card-shared.d.ts +7 -16
- package/dist/card/card-shared.js +7 -30
- package/dist/card/run-card-session.d.ts +2 -55
- package/dist/card/run-card-session.js +6 -104
- package/dist/card/run-renderer.d.ts +7 -0
- package/dist/card/run-renderer.js +116 -238
- package/dist/card/run-state.d.ts +13 -0
- package/dist/card/run-state.js +25 -16
- package/dist/card/text-truncate.d.ts +13 -12
- package/dist/card/text-truncate.js +13 -63
- package/dist/common/fs.d.ts +8 -0
- package/dist/common/fs.js +17 -0
- package/dist/common/guards.d.ts +0 -20
- package/dist/common/guards.js +0 -43
- package/dist/common/sleep.d.ts +2 -0
- package/dist/common/sleep.js +5 -0
- package/dist/common/truncate.d.ts +39 -0
- package/dist/common/truncate.js +92 -0
- package/dist/config/codex-config.d.ts +1 -1
- package/dist/config/codex-config.js +1 -1
- package/dist/config/index.d.ts +112 -24
- package/dist/config/index.js +139 -37
- package/dist/connector/index.d.ts +69 -2
- package/dist/connector/index.js +107 -1
- package/dist/index.js +150 -118
- package/dist/instance-lock.js +4 -12
- package/dist/order/alias-resolve.d.ts +13 -0
- package/dist/order/alias-resolve.js +22 -0
- package/dist/order/alias-store.d.ts +38 -0
- package/dist/order/alias-store.js +106 -0
- package/dist/persistence/atomic-write.d.ts +8 -2
- package/dist/persistence/atomic-write.js +23 -7
- package/dist/restart.js +2 -1
- package/dist/router/card-action-payload.d.ts +30 -0
- package/dist/router/card-action-payload.js +39 -0
- package/dist/router/card-helpers.d.ts +63 -0
- package/dist/router/card-helpers.js +146 -0
- package/dist/router/config/claude.js +30 -1
- package/dist/router/config/codex.js +29 -50
- package/dist/router/config/common/model-patch.d.ts +22 -0
- package/dist/router/config/common/model-patch.js +26 -0
- package/dist/router/config/common/render.js +5 -4
- package/dist/router/config/dsh.d.ts +51 -0
- package/dist/router/config/dsh.js +179 -0
- package/dist/router/config/index.d.ts +12 -0
- package/dist/router/config/index.js +28 -1
- package/dist/router/config/kimi.d.ts +4 -1
- package/dist/router/config/kimi.js +27 -0
- package/dist/router/config/opencode.js +18 -5
- package/dist/router/config/pi.js +4 -5
- package/dist/router/config/types.d.ts +17 -2
- package/dist/router/index.d.ts +76 -22
- package/dist/router/index.js +479 -548
- package/dist/router/utils.d.ts +2 -0
- package/dist/router/utils.js +16 -2
- package/dist/runner/agent-choices-common.d.ts +16 -0
- package/dist/runner/agent-choices-common.js +34 -0
- package/dist/runner/claude/runner.d.ts +47 -10
- package/dist/runner/claude/runner.js +117 -46
- package/dist/runner/claude/session.d.ts +166 -0
- package/dist/runner/claude/session.js +768 -0
- package/dist/runner/codex/app-server/protocol-types.d.ts +66 -39
- package/dist/runner/codex/app-server/protocol-types.js +2 -13
- package/dist/runner/codex/app-server/runner.d.ts +52 -59
- package/dist/runner/codex/app-server/runner.js +216 -338
- package/dist/runner/codex/app-server/translator.d.ts +8 -21
- package/dist/runner/codex/app-server/translator.js +45 -18
- package/dist/runner/codex/index.d.ts +0 -2
- package/dist/runner/codex/index.js +0 -2
- package/dist/runner/common/acp/protocol-helpers.d.ts +14 -0
- package/dist/runner/common/acp/protocol-helpers.js +21 -0
- package/dist/runner/common/acp/protocol-types.d.ts +271 -0
- package/dist/runner/common/acp/protocol-types.js +77 -0
- package/dist/runner/common/connection-based-runner.d.ts +111 -0
- package/dist/runner/common/connection-based-runner.js +261 -0
- package/dist/runner/{codex/app-server → common/jsonrpc}/client.d.ts +14 -7
- package/dist/runner/{codex/app-server → common/jsonrpc}/client.js +27 -18
- package/dist/runner/common/jsonrpc/connection-manager.d.ts +125 -0
- package/dist/runner/{codex/app-server → common/jsonrpc}/connection-manager.js +63 -28
- package/dist/runner/{codex/app-server → common/jsonrpc}/transport.d.ts +5 -4
- package/dist/runner/{codex/app-server → common/jsonrpc}/transport.js +18 -19
- package/dist/runner/common/jsonrpc/types.d.ts +32 -0
- package/dist/runner/common/jsonrpc/types.js +9 -0
- package/dist/runner/common/process-stopper.d.ts +2 -1
- package/dist/runner/common/process-stopper.js +1 -0
- package/dist/runner/common/runner-utils.d.ts +6 -13
- package/dist/runner/common/runner-utils.js +6 -47
- package/dist/runner/common/spawning-runner.d.ts +24 -70
- package/dist/runner/common/spawning-runner.js +98 -152
- package/dist/runner/dsh/client.d.ts +95 -0
- package/dist/runner/dsh/client.js +418 -0
- package/dist/runner/dsh/fake-dsh-server.d.ts +60 -0
- package/dist/runner/dsh/fake-dsh-server.js +156 -0
- package/dist/runner/dsh/index.d.ts +3 -0
- package/dist/runner/dsh/index.js +4 -0
- package/dist/runner/dsh/runner.d.ts +57 -0
- package/dist/runner/dsh/runner.js +191 -0
- package/dist/runner/dsh/translator.d.ts +28 -0
- package/dist/runner/dsh/translator.js +98 -0
- package/dist/runner/dsh/types.d.ts +155 -0
- package/dist/runner/dsh/types.js +14 -0
- package/dist/runner/index.d.ts +5 -4
- package/dist/runner/index.js +5 -4
- package/dist/runner/kimi/acp/runner.d.ts +106 -0
- package/dist/runner/kimi/acp/runner.js +516 -0
- package/dist/runner/kimi/acp/translator.d.ts +138 -0
- package/dist/runner/kimi/acp/translator.js +441 -0
- package/dist/runner/kimi/index.d.ts +1 -1
- package/dist/runner/kimi/index.js +1 -1
- package/dist/runner/opencode/acp/index.d.ts +1 -0
- package/dist/runner/opencode/acp/index.js +2 -0
- package/dist/runner/opencode/acp/runner.d.ts +121 -0
- package/dist/runner/opencode/acp/runner.js +429 -0
- package/dist/runner/opencode/acp/translator.d.ts +119 -0
- package/dist/runner/opencode/acp/translator.js +345 -0
- package/dist/runner/opencode/index.d.ts +1 -1
- package/dist/runner/opencode/index.js +1 -1
- package/dist/runner/pi/index.d.ts +1 -1
- package/dist/runner/pi/index.js +1 -1
- package/dist/runner/pi/rpc/client.d.ts +52 -0
- package/dist/runner/pi/rpc/client.js +114 -0
- package/dist/runner/pi/rpc/index.d.ts +4 -0
- package/dist/runner/pi/rpc/index.js +4 -0
- package/dist/runner/pi/rpc/protocol-types.d.ts +127 -0
- package/dist/runner/pi/rpc/protocol-types.js +21 -0
- package/dist/runner/pi/rpc/runner.d.ts +74 -0
- package/dist/runner/pi/rpc/runner.js +190 -0
- package/dist/runner/pi/rpc/translator.d.ts +55 -0
- package/dist/runner/pi/rpc/translator.js +258 -0
- package/dist/runner/probe.js +6 -1
- package/dist/runner/question-common.d.ts +26 -0
- package/dist/runner/question-common.js +42 -0
- package/dist/runner/registry.d.ts +7 -8
- package/dist/runner/registry.js +3 -4
- package/dist/runner/resolve-agent-choices.js +18 -59
- package/dist/runner/sync-agent-choices.js +16 -67
- package/dist/runner/types.d.ts +97 -14
- package/dist/session/claude/session-index.js +2 -3
- package/dist/session/claude/session-reader.js +3 -6
- package/dist/session/claude/sessions.js +43 -28
- package/dist/session/codex/rollout-reader.d.ts +2 -2
- package/dist/session/codex/rollout-reader.js +14 -17
- package/dist/session/codex/sessions.d.ts +1 -1
- package/dist/session/codex/sessions.js +2 -2
- package/dist/session/common/content-blocks.d.ts +7 -0
- package/dist/session/common/content-blocks.js +13 -9
- package/dist/session/common/jsonl.d.ts +8 -25
- package/dist/session/common/jsonl.js +126 -261
- package/dist/session/common/pagination.d.ts +28 -0
- package/dist/session/common/pagination.js +33 -0
- package/dist/session/dsh/index.d.ts +1 -0
- package/dist/session/dsh/index.js +2 -0
- package/dist/session/dsh/sessions.d.ts +39 -0
- package/dist/session/dsh/sessions.js +237 -0
- package/dist/session/index.d.ts +1 -0
- package/dist/session/index.js +1 -0
- package/dist/session/kimi/sessions.d.ts +34 -1
- package/dist/session/kimi/sessions.js +208 -98
- package/dist/session/opencode/sessions.d.ts +17 -3
- package/dist/session/opencode/sessions.js +29 -29
- package/dist/session/pi/sessions.d.ts +5 -1
- package/dist/session/pi/sessions.js +12 -16
- package/dist/session/session-store.d.ts +11 -1
- package/dist/session/session-store.js +75 -178
- package/dist/update/index.d.ts +2 -2
- package/dist/update/index.js +2 -2
- package/dist/update/install.d.ts +20 -2
- package/dist/update/install.js +51 -7
- package/dist/workspace/index.d.ts +4 -0
- package/dist/workspace/index.js +8 -1
- package/package.json +2 -1
- package/dist/runner/codex/app-server/connection-manager.d.ts +0 -56
- package/dist/runner/codex/argv.d.ts +0 -33
- package/dist/runner/codex/argv.js +0 -40
- package/dist/runner/codex/factory.d.ts +0 -29
- package/dist/runner/codex/factory.js +0 -39
- package/dist/runner/codex/jsonl.d.ts +0 -37
- package/dist/runner/codex/jsonl.js +0 -221
- package/dist/runner/codex/runner.d.ts +0 -66
- package/dist/runner/codex/runner.js +0 -129
- package/dist/runner/common/exec-translator.d.ts +0 -73
- package/dist/runner/common/exec-translator.js +0 -105
- package/dist/runner/kimi/jsonl.d.ts +0 -28
- package/dist/runner/kimi/jsonl.js +0 -143
- package/dist/runner/kimi/runner.d.ts +0 -49
- package/dist/runner/kimi/runner.js +0 -105
- package/dist/runner/opencode/argv.d.ts +0 -32
- package/dist/runner/opencode/argv.js +0 -35
- package/dist/runner/opencode/jsonl.d.ts +0 -68
- package/dist/runner/opencode/jsonl.js +0 -295
- package/dist/runner/opencode/runner.d.ts +0 -61
- package/dist/runner/opencode/runner.js +0 -93
- package/dist/runner/pi/jsonl.d.ts +0 -128
- package/dist/runner/pi/jsonl.js +0 -249
- package/dist/runner/pi/runner.d.ts +0 -36
- package/dist/runner/pi/runner.js +0 -76
- package/dist/session/common/catch-up.d.ts +0 -12
- package/dist/session/common/catch-up.js +0 -31
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pi RPC protocol types.
|
|
3
|
+
*
|
|
4
|
+
* pi's `--mode rpc` is a headless JSON-lines protocol over stdio (NOT JSON-RPC):
|
|
5
|
+
* - client → stdin: commands `{ type, id, ... }`
|
|
6
|
+
* - server → stdout: responses `{ id, type:"response", command, success, data|error }`
|
|
7
|
+
* and events (session lifecycle / message / compaction) as bare
|
|
8
|
+
* JSON objects (no envelope).
|
|
9
|
+
*
|
|
10
|
+
* Turn semantics (verified live against pi 0.84.1, 2026-08-18):
|
|
11
|
+
* - `prompt` returns an ack (`success:true`) immediately; the turn then streams
|
|
12
|
+
* events and completes with an `agent_settled` event.
|
|
13
|
+
* - `compact` runs synchronously and returns its response at completion; it also
|
|
14
|
+
* streams `compaction_start` / `compaction_end` events.
|
|
15
|
+
* - `abort` cancels the current operation.
|
|
16
|
+
* - `get_state` returns the bound session id (`data.sessionId`) — pi binds the
|
|
17
|
+
* session at spawn via `--session-id`, so this is how a new session's id is
|
|
18
|
+
* discovered.
|
|
19
|
+
*/
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=protocol-types.js.map
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PiRpcRunner: workspace-lifetime runner driving pi in `--mode rpc`
|
|
3
|
+
* (JSON-lines protocol over stdio).
|
|
4
|
+
*
|
|
5
|
+
* Flow per run: acquire persistent connection → resolve session id (via
|
|
6
|
+
* `get_state`, or the spawn-bound `--session-id`) → synthetic init → send
|
|
7
|
+
* `prompt` (fire-and-ack) → consume pi events until `agent_settled` → result.
|
|
8
|
+
*
|
|
9
|
+
* Compact flow: acquire → `compact` command → consume `compaction_*` events →
|
|
10
|
+
* result from the compact response (completion signal).
|
|
11
|
+
*
|
|
12
|
+
* Structurally aligned with KimiAcpRunner / OpencodeAcpRunner via the shared
|
|
13
|
+
* ConnectionBasedRunner base (notification queue, forceFinish/stopRequested,
|
|
14
|
+
* turn idle watchdog, connection-lost retry). Differences:
|
|
15
|
+
* - pi binds the session at spawn via `--session-id` (no RPC resume-by-id);
|
|
16
|
+
* the PiRpcConnectionManager respawns when the requested session changes.
|
|
17
|
+
* - pi,极简风格,没有 Ask User question。
|
|
18
|
+
* - `prompt` ack ≠ turn completion; the turn ends on `agent_settled`.
|
|
19
|
+
*/
|
|
20
|
+
import type { AgentSessionReader, AgentEvent, AgentStatusInfo, SpawnOptions } from '../../types.js';
|
|
21
|
+
import { ConnectionBasedRunner } from '../../common/connection-based-runner.js';
|
|
22
|
+
import { PiRpcClient } from './client.js';
|
|
23
|
+
import { type PiRpcTranslatorEvent } from './translator.js';
|
|
24
|
+
export interface PiRpcRunnerOptions {
|
|
25
|
+
/** LLM provider, e.g. 'Volcano'. */
|
|
26
|
+
provider?: string;
|
|
27
|
+
/** Model id or alias, e.g. 'glm-5.2'. */
|
|
28
|
+
model?: string;
|
|
29
|
+
/** Thinking level: off/minimal/low/medium/high/xhigh/max. */
|
|
30
|
+
thinking?: string;
|
|
31
|
+
/** Tool allowlist. */
|
|
32
|
+
tools?: string[];
|
|
33
|
+
workspace: string;
|
|
34
|
+
sessionReader: AgentSessionReader;
|
|
35
|
+
/** Path to the pi binary. Defaults to `pi`. */
|
|
36
|
+
binary?: string;
|
|
37
|
+
/** Environment variables to pass to the pi process. */
|
|
38
|
+
env?: Record<string, string | undefined>;
|
|
39
|
+
requestTimeoutMs?: number;
|
|
40
|
+
idleTtlMs?: number;
|
|
41
|
+
turnIdleTimeoutMs?: number;
|
|
42
|
+
}
|
|
43
|
+
export declare class PiRpcRunner extends ConnectionBasedRunner<PiRpcClient, PiRpcTranslatorEvent> {
|
|
44
|
+
private readonly manager;
|
|
45
|
+
private currentTranslator;
|
|
46
|
+
private activeSessionId;
|
|
47
|
+
private promptSettled;
|
|
48
|
+
private readonly defaultModel;
|
|
49
|
+
private readonly provider;
|
|
50
|
+
private readonly thinking;
|
|
51
|
+
constructor(opts: PiRpcRunnerOptions);
|
|
52
|
+
protected get logTag(): string;
|
|
53
|
+
protected get turnTimeoutErrorMessage(): string;
|
|
54
|
+
protected get turnInterruptedErrorMessage(): string;
|
|
55
|
+
protected currentSessionId(): string | null;
|
|
56
|
+
protected shouldDeferStop(): boolean;
|
|
57
|
+
protected cancelCurrentTurn(): Promise<void>;
|
|
58
|
+
protected clearTurnState(): void;
|
|
59
|
+
protected releaseConnection(cwd: string): Promise<void>;
|
|
60
|
+
protected notifyIdle(cwd: string): void;
|
|
61
|
+
protected disposeConnections(): Promise<void>;
|
|
62
|
+
getStatusInfo(): AgentStatusInfo;
|
|
63
|
+
/**
|
|
64
|
+
* Normal turn: acquire → resolve session id → prompt (fire-and-ack) → the
|
|
65
|
+
* `agent_settled` event produces the result.
|
|
66
|
+
*/
|
|
67
|
+
protected setupTurn(message: string, opts: SpawnOptions): Promise<void>;
|
|
68
|
+
/**
|
|
69
|
+
* Compact the current session. The `compact` command returns a response at
|
|
70
|
+
* completion (the completion signal); `compaction_*` events stream meanwhile.
|
|
71
|
+
*/
|
|
72
|
+
runCompact(_message: string, opts: SpawnOptions): AsyncGenerator<AgentEvent>;
|
|
73
|
+
private handleEvent;
|
|
74
|
+
}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PiRpcRunner: workspace-lifetime runner driving pi in `--mode rpc`
|
|
3
|
+
* (JSON-lines protocol over stdio).
|
|
4
|
+
*
|
|
5
|
+
* Flow per run: acquire persistent connection → resolve session id (via
|
|
6
|
+
* `get_state`, or the spawn-bound `--session-id`) → synthetic init → send
|
|
7
|
+
* `prompt` (fire-and-ack) → consume pi events until `agent_settled` → result.
|
|
8
|
+
*
|
|
9
|
+
* Compact flow: acquire → `compact` command → consume `compaction_*` events →
|
|
10
|
+
* result from the compact response (completion signal).
|
|
11
|
+
*
|
|
12
|
+
* Structurally aligned with KimiAcpRunner / OpencodeAcpRunner via the shared
|
|
13
|
+
* ConnectionBasedRunner base (notification queue, forceFinish/stopRequested,
|
|
14
|
+
* turn idle watchdog, connection-lost retry). Differences:
|
|
15
|
+
* - pi binds the session at spawn via `--session-id` (no RPC resume-by-id);
|
|
16
|
+
* the PiRpcConnectionManager respawns when the requested session changes.
|
|
17
|
+
* - pi,极简风格,没有 Ask User question。
|
|
18
|
+
* - `prompt` ack ≠ turn completion; the turn ends on `agent_settled`.
|
|
19
|
+
*/
|
|
20
|
+
import { ConnectionBasedRunner } from '../../common/connection-based-runner.js';
|
|
21
|
+
import { ConnectionManager } from '../../common/jsonrpc/connection-manager.js';
|
|
22
|
+
import { getLogger } from '../../../logger/index.js';
|
|
23
|
+
import { PiRpcClient } from './client.js';
|
|
24
|
+
import { PiRpcTranslator } from './translator.js';
|
|
25
|
+
export class PiRpcRunner extends ConnectionBasedRunner {
|
|
26
|
+
manager;
|
|
27
|
+
currentTranslator = null;
|
|
28
|
+
activeSessionId = null;
|
|
29
|
+
promptSettled = false;
|
|
30
|
+
defaultModel;
|
|
31
|
+
provider;
|
|
32
|
+
thinking;
|
|
33
|
+
constructor(opts) {
|
|
34
|
+
super({
|
|
35
|
+
kind: 'pi',
|
|
36
|
+
sessionReader: opts.sessionReader,
|
|
37
|
+
turnIdleTimeoutMs: opts.turnIdleTimeoutMs,
|
|
38
|
+
});
|
|
39
|
+
this.defaultModel = opts.model ?? 'glm-5.2';
|
|
40
|
+
this.provider = opts.provider ?? 'Volcano';
|
|
41
|
+
this.thinking = opts.thinking ?? 'medium';
|
|
42
|
+
const tools = (opts.tools ?? ['read', 'bash', 'edit', 'write', 'grep', 'find', 'ls']).join(',');
|
|
43
|
+
this.manager = new ConnectionManager({
|
|
44
|
+
binary: opts.binary ?? 'pi',
|
|
45
|
+
buildArgs: (req) => buildPiArgs(this.provider, this.defaultModel, this.thinking, tools, req.sessionId),
|
|
46
|
+
clientFactory: ({ transport, baseOnClose, requestTimeoutMs }) => new PiRpcClient(transport, baseOnClose, requestTimeoutMs),
|
|
47
|
+
shouldReuse: ({ client, req, boundSessionId }) => req.sessionId !== undefined &&
|
|
48
|
+
boundSessionId === req.sessionId &&
|
|
49
|
+
client.ready &&
|
|
50
|
+
client.healthy,
|
|
51
|
+
env: opts.env,
|
|
52
|
+
requestTimeoutMs: opts.requestTimeoutMs,
|
|
53
|
+
idleTtlMs: opts.idleTtlMs,
|
|
54
|
+
logTag: 'pi-rpc-connection-manager',
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
get logTag() {
|
|
58
|
+
return 'pi-rpc-runner';
|
|
59
|
+
}
|
|
60
|
+
get turnTimeoutErrorMessage() {
|
|
61
|
+
return 'Pi RPC turn timed out';
|
|
62
|
+
}
|
|
63
|
+
get turnInterruptedErrorMessage() {
|
|
64
|
+
return 'Pi RPC turn interrupted';
|
|
65
|
+
}
|
|
66
|
+
currentSessionId() {
|
|
67
|
+
return this.activeSessionId;
|
|
68
|
+
}
|
|
69
|
+
shouldDeferStop() {
|
|
70
|
+
return !this.promptSettled;
|
|
71
|
+
}
|
|
72
|
+
async cancelCurrentTurn() {
|
|
73
|
+
if (!this.currentClient || !this.activeSessionId)
|
|
74
|
+
return;
|
|
75
|
+
try {
|
|
76
|
+
this.currentClient.notify({ type: 'abort' });
|
|
77
|
+
}
|
|
78
|
+
catch (err) {
|
|
79
|
+
getLogger().warn(`[${this.logTag}] abort failed: ${err.message}`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
clearTurnState() {
|
|
83
|
+
this.currentTranslator = null;
|
|
84
|
+
this.promptSettled = false;
|
|
85
|
+
this.activeSessionId = null;
|
|
86
|
+
}
|
|
87
|
+
async releaseConnection(cwd) {
|
|
88
|
+
await this.manager.release(cwd);
|
|
89
|
+
}
|
|
90
|
+
notifyIdle(cwd) {
|
|
91
|
+
this.manager.notifyIdle(cwd);
|
|
92
|
+
}
|
|
93
|
+
async disposeConnections() {
|
|
94
|
+
await this.manager.disposeAll();
|
|
95
|
+
}
|
|
96
|
+
getStatusInfo() {
|
|
97
|
+
return {
|
|
98
|
+
kind: 'pi',
|
|
99
|
+
model: this.defaultModel,
|
|
100
|
+
provider: this.provider,
|
|
101
|
+
reasoning: this.thinking,
|
|
102
|
+
extras: { mode: 'rpc' },
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Normal turn: acquire → resolve session id → prompt (fire-and-ack) → the
|
|
107
|
+
* `agent_settled` event produces the result.
|
|
108
|
+
*/
|
|
109
|
+
async setupTurn(message, opts) {
|
|
110
|
+
const client = await this.manager.acquire(opts.cwd, { sessionId: opts.sessionId });
|
|
111
|
+
this.manager.notifyActivity(opts.cwd);
|
|
112
|
+
this.currentClient = client;
|
|
113
|
+
client.setHooks({
|
|
114
|
+
onEvent: (evt) => this.handleEvent(evt),
|
|
115
|
+
onClose: () => this.failTurn('Pi RPC connection closed'),
|
|
116
|
+
});
|
|
117
|
+
let sessionId = opts.sessionId;
|
|
118
|
+
if (!sessionId) {
|
|
119
|
+
const state = await client.request({ type: 'get_state' });
|
|
120
|
+
if (state.success && state.data) {
|
|
121
|
+
sessionId = state.data.sessionId;
|
|
122
|
+
}
|
|
123
|
+
if (!sessionId)
|
|
124
|
+
throw new Error('pi RPC did not report a session id');
|
|
125
|
+
// Bind the discovered id so a following run resumes the SAME session on
|
|
126
|
+
// this live connection instead of respawning it.
|
|
127
|
+
this.manager.bindSession(opts.cwd, sessionId);
|
|
128
|
+
}
|
|
129
|
+
this.activeSessionId = sessionId;
|
|
130
|
+
const translator = new PiRpcTranslator();
|
|
131
|
+
translator.setSessionId(sessionId);
|
|
132
|
+
this.currentTranslator = translator;
|
|
133
|
+
const turnId = `turn-${Date.now()}`;
|
|
134
|
+
this.currentTurnId = turnId;
|
|
135
|
+
this.pushEvents([translator.produceTurnStarted(sessionId, turnId)]);
|
|
136
|
+
this.promptSettled = false;
|
|
137
|
+
await client.request({ type: 'prompt', message });
|
|
138
|
+
this.promptSettled = true;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Compact the current session. The `compact` command returns a response at
|
|
142
|
+
* completion (the completion signal); `compaction_*` events stream meanwhile.
|
|
143
|
+
*/
|
|
144
|
+
async *runCompact(_message, opts) {
|
|
145
|
+
yield* this.executeTurn(opts, async () => {
|
|
146
|
+
if (!opts.sessionId) {
|
|
147
|
+
throw new Error('compact requires a sessionId');
|
|
148
|
+
}
|
|
149
|
+
const client = await this.manager.acquire(opts.cwd, { sessionId: opts.sessionId });
|
|
150
|
+
this.manager.notifyActivity(opts.cwd);
|
|
151
|
+
this.currentClient = client;
|
|
152
|
+
client.setHooks({
|
|
153
|
+
onEvent: (evt) => this.handleEvent(evt),
|
|
154
|
+
onClose: () => this.failTurn('Pi RPC connection closed'),
|
|
155
|
+
});
|
|
156
|
+
this.activeSessionId = opts.sessionId;
|
|
157
|
+
const translator = new PiRpcTranslator();
|
|
158
|
+
translator.setSessionId(opts.sessionId);
|
|
159
|
+
translator.setOperationKind('compact');
|
|
160
|
+
this.currentTranslator = translator;
|
|
161
|
+
const turnId = `compact-${Date.now()}`;
|
|
162
|
+
this.currentTurnId = turnId;
|
|
163
|
+
this.pushEvents([translator.produceTurnStarted(opts.sessionId, turnId)]);
|
|
164
|
+
this.promptSettled = false;
|
|
165
|
+
const response = await client.request({ type: 'compact' });
|
|
166
|
+
this.promptSettled = true;
|
|
167
|
+
// Guard: a stop may have already ended this turn (deferred-stop during
|
|
168
|
+
// compaction) — don't push a stale result into a (possibly reused) queue.
|
|
169
|
+
if (this.stopRequested || !this._isRunning)
|
|
170
|
+
return;
|
|
171
|
+
this.pushEvents([translator.produceCompactResult(opts.sessionId, response)]);
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
handleEvent(evt) {
|
|
175
|
+
this.pushEvents(this.currentTranslator?.handleEvent(evt) ?? []);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
/** Build pi `--mode rpc` spawn args. `sessionId` is bound at spawn (pi has no
|
|
179
|
+
* RPC resume-by-id command); omitting it spawns a brand-new session. */
|
|
180
|
+
function buildPiArgs(provider, model, thinking, tools, sessionId) {
|
|
181
|
+
const args = ['--mode', 'rpc', '--provider', provider, '--model', model];
|
|
182
|
+
if (thinking && thinking !== 'off')
|
|
183
|
+
args.push('--thinking', thinking);
|
|
184
|
+
if (tools)
|
|
185
|
+
args.push('--tools', tools);
|
|
186
|
+
if (sessionId)
|
|
187
|
+
args.push('--session-id', sessionId);
|
|
188
|
+
return args;
|
|
189
|
+
}
|
|
190
|
+
//# sourceMappingURL=runner.js.map
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PiRpcTranslator: maps pi RPC events into AgentEvents for the PiRpcRunner.
|
|
3
|
+
*
|
|
4
|
+
* Content mapping accumulates pi's incremental message_start/update/end events
|
|
5
|
+
* into assistant/user events with text/thinking/tool content, and drives the
|
|
6
|
+
* turn lifecycle differently:
|
|
7
|
+
* - `prompt` is fire-and-ack, so the runner produces a `result` on the
|
|
8
|
+
* `agent_settled` event (turn completion), not on a prompt response.
|
|
9
|
+
* - `compact` returns a response at completion; the runner produces the
|
|
10
|
+
* `result` from that response.
|
|
11
|
+
* - `agent_settled` is ignored for compaction turns (no double result).
|
|
12
|
+
*/
|
|
13
|
+
import type { AgentEvent, ResultEvent } from '../../types.js';
|
|
14
|
+
import { type PiRpcEvent, type PiRpcResponse } from './protocol-types.js';
|
|
15
|
+
export interface PiRpcTurnStartedEvent {
|
|
16
|
+
type: 'turn_started';
|
|
17
|
+
threadId: string;
|
|
18
|
+
turnId: string;
|
|
19
|
+
operationKind: 'turn' | 'compaction';
|
|
20
|
+
timestamp?: string;
|
|
21
|
+
}
|
|
22
|
+
export type PiRpcTranslatorEvent = AgentEvent | PiRpcTurnStartedEvent;
|
|
23
|
+
export declare class PiRpcTranslator {
|
|
24
|
+
private content;
|
|
25
|
+
private currentContentIndex;
|
|
26
|
+
private sessionId;
|
|
27
|
+
private operationKind;
|
|
28
|
+
private currentTurnId;
|
|
29
|
+
private accInput;
|
|
30
|
+
private accOutput;
|
|
31
|
+
private accCacheRead;
|
|
32
|
+
private accCacheCreation;
|
|
33
|
+
private lastTotalTokens;
|
|
34
|
+
private hasUsage;
|
|
35
|
+
/** Provider failure (stopReason="error") on the final assistant message. */
|
|
36
|
+
private lastAssistantStopReason;
|
|
37
|
+
private lastAssistantErrorMessage;
|
|
38
|
+
getSessionId(): string;
|
|
39
|
+
setSessionId(id: string): void;
|
|
40
|
+
setOperationKind(kind: 'turn' | 'compact'): void;
|
|
41
|
+
getUsage(): ResultEvent['usage'] | undefined;
|
|
42
|
+
/** Translate an incoming pi RPC event into AgentEvents to push. */
|
|
43
|
+
handleEvent(evt: PiRpcEvent): PiRpcTranslatorEvent[];
|
|
44
|
+
/** Self-produced turn_started (no wire equivalent). */
|
|
45
|
+
produceTurnStarted(sessionId: string, turnId: string): PiRpcTurnStartedEvent;
|
|
46
|
+
/** Result for a completed normal turn (agent_settled). */
|
|
47
|
+
produceResultFromSettled(): AgentEvent;
|
|
48
|
+
/** Result from a compact command response (completion signal for compaction). */
|
|
49
|
+
produceCompactResult(sessionId: string, response: PiRpcResponse): AgentEvent;
|
|
50
|
+
/** Error result (for setup/request failures). */
|
|
51
|
+
produceErrorResult(sessionId: string, errorMessage: string): AgentEvent;
|
|
52
|
+
private handleMessageEnd;
|
|
53
|
+
private addUsage;
|
|
54
|
+
private applyUpdate;
|
|
55
|
+
}
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PiRpcTranslator: maps pi RPC events into AgentEvents for the PiRpcRunner.
|
|
3
|
+
*
|
|
4
|
+
* Content mapping accumulates pi's incremental message_start/update/end events
|
|
5
|
+
* into assistant/user events with text/thinking/tool content, and drives the
|
|
6
|
+
* turn lifecycle differently:
|
|
7
|
+
* - `prompt` is fire-and-ack, so the runner produces a `result` on the
|
|
8
|
+
* `agent_settled` event (turn completion), not on a prompt response.
|
|
9
|
+
* - `compact` returns a response at completion; the runner produces the
|
|
10
|
+
* `result` from that response.
|
|
11
|
+
* - `agent_settled` is ignored for compaction turns (no double result).
|
|
12
|
+
*/
|
|
13
|
+
export class PiRpcTranslator {
|
|
14
|
+
content = [];
|
|
15
|
+
currentContentIndex = -1;
|
|
16
|
+
sessionId = '';
|
|
17
|
+
operationKind = 'turn';
|
|
18
|
+
currentTurnId = '';
|
|
19
|
+
// ccusage-aligned usage accumulation (per-message, summed across the turn).
|
|
20
|
+
accInput = 0;
|
|
21
|
+
accOutput = 0;
|
|
22
|
+
accCacheRead = 0;
|
|
23
|
+
accCacheCreation = 0;
|
|
24
|
+
lastTotalTokens;
|
|
25
|
+
hasUsage = false;
|
|
26
|
+
/** Provider failure (stopReason="error") on the final assistant message. */
|
|
27
|
+
lastAssistantStopReason;
|
|
28
|
+
lastAssistantErrorMessage;
|
|
29
|
+
getSessionId() {
|
|
30
|
+
return this.sessionId;
|
|
31
|
+
}
|
|
32
|
+
setSessionId(id) {
|
|
33
|
+
this.sessionId = id;
|
|
34
|
+
}
|
|
35
|
+
setOperationKind(kind) {
|
|
36
|
+
this.operationKind = kind;
|
|
37
|
+
}
|
|
38
|
+
getUsage() {
|
|
39
|
+
if (!this.hasUsage &&
|
|
40
|
+
this.accInput === 0 &&
|
|
41
|
+
this.accOutput === 0 &&
|
|
42
|
+
this.accCacheRead === 0 &&
|
|
43
|
+
this.accCacheCreation === 0 &&
|
|
44
|
+
this.lastTotalTokens === undefined) {
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
return {
|
|
48
|
+
input_tokens: this.accInput,
|
|
49
|
+
output_tokens: this.accOutput,
|
|
50
|
+
cache_read_tokens: this.accCacheRead,
|
|
51
|
+
cache_creation_tokens: this.accCacheCreation,
|
|
52
|
+
...(this.lastTotalTokens != null ? { total_tokens: this.lastTotalTokens } : {}),
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/** Translate an incoming pi RPC event into AgentEvents to push. */
|
|
56
|
+
handleEvent(evt) {
|
|
57
|
+
switch (evt.type) {
|
|
58
|
+
case 'session': {
|
|
59
|
+
const s = evt;
|
|
60
|
+
this.sessionId = s.id;
|
|
61
|
+
return [
|
|
62
|
+
{
|
|
63
|
+
type: 'system',
|
|
64
|
+
subtype: 'init',
|
|
65
|
+
session_id: s.id,
|
|
66
|
+
cwd: s.cwd,
|
|
67
|
+
model: s.model ?? '',
|
|
68
|
+
timestamp: new Date().toISOString(),
|
|
69
|
+
},
|
|
70
|
+
];
|
|
71
|
+
}
|
|
72
|
+
case 'message_start': {
|
|
73
|
+
const m = evt.message;
|
|
74
|
+
if (m.role === 'assistant') {
|
|
75
|
+
this.content = [];
|
|
76
|
+
this.currentContentIndex = -1;
|
|
77
|
+
}
|
|
78
|
+
return [];
|
|
79
|
+
}
|
|
80
|
+
case 'message_update': {
|
|
81
|
+
this.applyUpdate(evt.assistantMessageEvent);
|
|
82
|
+
return [];
|
|
83
|
+
}
|
|
84
|
+
case 'message_end': {
|
|
85
|
+
return this.handleMessageEnd(evt);
|
|
86
|
+
}
|
|
87
|
+
case 'agent_settled': {
|
|
88
|
+
// Normal-turn completion signal. Compaction turns finish via the
|
|
89
|
+
// compact response, not agent_settled.
|
|
90
|
+
if (this.operationKind === 'turn') {
|
|
91
|
+
return [this.produceResultFromSettled()];
|
|
92
|
+
}
|
|
93
|
+
return [];
|
|
94
|
+
}
|
|
95
|
+
default:
|
|
96
|
+
// turn_start/turn_end, agent_start/agent_end, compaction_start/end,
|
|
97
|
+
// tool_execution_*, and unknown types are ignored.
|
|
98
|
+
return [];
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/** Self-produced turn_started (no wire equivalent). */
|
|
102
|
+
produceTurnStarted(sessionId, turnId) {
|
|
103
|
+
this.sessionId = sessionId;
|
|
104
|
+
this.currentTurnId = turnId;
|
|
105
|
+
return {
|
|
106
|
+
type: 'turn_started',
|
|
107
|
+
threadId: sessionId,
|
|
108
|
+
turnId,
|
|
109
|
+
operationKind: this.operationKind === 'compact' ? 'compaction' : 'turn',
|
|
110
|
+
timestamp: new Date().toISOString(),
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
/** Result for a completed normal turn (agent_settled). */
|
|
114
|
+
produceResultFromSettled() {
|
|
115
|
+
const usage = this.getUsage();
|
|
116
|
+
return {
|
|
117
|
+
type: 'result',
|
|
118
|
+
subtype: this.lastAssistantStopReason === 'error' ? 'error' : 'success',
|
|
119
|
+
session_id: this.sessionId,
|
|
120
|
+
...(this.lastAssistantStopReason === 'error'
|
|
121
|
+
? { errorMessage: this.lastAssistantErrorMessage?.trim() || 'pi reported an error' }
|
|
122
|
+
: {}),
|
|
123
|
+
...(usage ? { usage } : {}),
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
/** Result from a compact command response (completion signal for compaction). */
|
|
127
|
+
produceCompactResult(sessionId, response) {
|
|
128
|
+
if (response.success) {
|
|
129
|
+
return {
|
|
130
|
+
type: 'result',
|
|
131
|
+
subtype: 'success',
|
|
132
|
+
session_id: sessionId,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
return {
|
|
136
|
+
type: 'result',
|
|
137
|
+
subtype: 'error',
|
|
138
|
+
session_id: sessionId,
|
|
139
|
+
errorMessage: response.error,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
/** Error result (for setup/request failures). */
|
|
143
|
+
produceErrorResult(sessionId, errorMessage) {
|
|
144
|
+
return {
|
|
145
|
+
type: 'result',
|
|
146
|
+
subtype: 'error',
|
|
147
|
+
session_id: sessionId,
|
|
148
|
+
errorMessage,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
// =========================================================================
|
|
152
|
+
// Internal
|
|
153
|
+
// =========================================================================
|
|
154
|
+
handleMessageEnd(evt) {
|
|
155
|
+
const m = evt.message;
|
|
156
|
+
if (m.role === 'assistant') {
|
|
157
|
+
this.lastAssistantStopReason = m.stopReason;
|
|
158
|
+
this.lastAssistantErrorMessage = m.stopReason === 'error' ? m.errorMessage : undefined;
|
|
159
|
+
if (m.usage)
|
|
160
|
+
this.addUsage(m.usage);
|
|
161
|
+
const event = {
|
|
162
|
+
type: 'assistant',
|
|
163
|
+
message: { content: this.content },
|
|
164
|
+
timestamp: new Date().toISOString(),
|
|
165
|
+
};
|
|
166
|
+
this.content = [];
|
|
167
|
+
this.currentContentIndex = -1;
|
|
168
|
+
return [event];
|
|
169
|
+
}
|
|
170
|
+
if (m.role === 'toolResult') {
|
|
171
|
+
return [
|
|
172
|
+
{
|
|
173
|
+
type: 'user',
|
|
174
|
+
message: {
|
|
175
|
+
content: [
|
|
176
|
+
{
|
|
177
|
+
type: 'tool_result',
|
|
178
|
+
tool_use_id: m.toolCallId ?? '',
|
|
179
|
+
content: m.content ?? '',
|
|
180
|
+
is_error: m.isError ?? false,
|
|
181
|
+
},
|
|
182
|
+
],
|
|
183
|
+
},
|
|
184
|
+
timestamp: new Date().toISOString(),
|
|
185
|
+
},
|
|
186
|
+
];
|
|
187
|
+
}
|
|
188
|
+
return [];
|
|
189
|
+
}
|
|
190
|
+
addUsage(u) {
|
|
191
|
+
this.hasUsage = true;
|
|
192
|
+
this.accInput += u.input ?? 0;
|
|
193
|
+
this.accOutput += u.output ?? 0;
|
|
194
|
+
this.accCacheRead += u.cacheRead ?? 0;
|
|
195
|
+
this.accCacheCreation += u.cacheWrite ?? 0;
|
|
196
|
+
if (u.totalTokens != null)
|
|
197
|
+
this.lastTotalTokens = u.totalTokens;
|
|
198
|
+
}
|
|
199
|
+
applyUpdate(evt) {
|
|
200
|
+
switch (evt.type) {
|
|
201
|
+
case 'text_start':
|
|
202
|
+
this.content.push({ type: 'text', text: '' });
|
|
203
|
+
this.currentContentIndex++;
|
|
204
|
+
break;
|
|
205
|
+
case 'text_delta':
|
|
206
|
+
if (this.currentContentIndex >= 0 &&
|
|
207
|
+
this.content[this.currentContentIndex]?.type === 'text') {
|
|
208
|
+
this.content[this.currentContentIndex].text += evt.delta ?? '';
|
|
209
|
+
}
|
|
210
|
+
break;
|
|
211
|
+
case 'text_end':
|
|
212
|
+
if (this.currentContentIndex >= 0 &&
|
|
213
|
+
this.content[this.currentContentIndex]?.type === 'text' &&
|
|
214
|
+
evt.content) {
|
|
215
|
+
this.content[this.currentContentIndex].text = evt.content;
|
|
216
|
+
}
|
|
217
|
+
break;
|
|
218
|
+
case 'thinking_start':
|
|
219
|
+
this.content.push({ type: 'thinking', thinking: '' });
|
|
220
|
+
this.currentContentIndex++;
|
|
221
|
+
break;
|
|
222
|
+
case 'thinking_delta':
|
|
223
|
+
if (this.currentContentIndex >= 0 &&
|
|
224
|
+
this.content[this.currentContentIndex]?.type === 'thinking') {
|
|
225
|
+
this.content[this.currentContentIndex].thinking +=
|
|
226
|
+
evt.delta ?? '';
|
|
227
|
+
}
|
|
228
|
+
break;
|
|
229
|
+
case 'thinking_end':
|
|
230
|
+
if (this.currentContentIndex >= 0 &&
|
|
231
|
+
this.content[this.currentContentIndex]?.type === 'thinking' &&
|
|
232
|
+
evt.content) {
|
|
233
|
+
this.content[this.currentContentIndex].thinking = evt.content;
|
|
234
|
+
}
|
|
235
|
+
break;
|
|
236
|
+
case 'toolcall_start':
|
|
237
|
+
this.content.push({ type: 'tool_use', id: '', name: '', input: {} });
|
|
238
|
+
this.currentContentIndex++;
|
|
239
|
+
break;
|
|
240
|
+
case 'toolcall_end':
|
|
241
|
+
if (this.currentContentIndex >= 0 &&
|
|
242
|
+
this.content[this.currentContentIndex]?.type === 'tool_use' &&
|
|
243
|
+
evt.toolCall) {
|
|
244
|
+
this.content[this.currentContentIndex] = {
|
|
245
|
+
type: 'tool_use',
|
|
246
|
+
id: evt.toolCall.id,
|
|
247
|
+
name: evt.toolCall.name,
|
|
248
|
+
input: evt.toolCall.arguments,
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
break;
|
|
252
|
+
default:
|
|
253
|
+
// toolcall_delta: pi provides complete arguments at toolcall_end, ignore.
|
|
254
|
+
break;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
//# sourceMappingURL=translator.js.map
|
package/dist/runner/probe.js
CHANGED
|
@@ -28,6 +28,9 @@ const BINARY_MAP = {
|
|
|
28
28
|
opencode: 'opencode',
|
|
29
29
|
pi: 'pi',
|
|
30
30
|
kimi: 'kimi',
|
|
31
|
+
// DSH is an HTTP-only agent (no CLI). `which ''` fails → reported unavailable,
|
|
32
|
+
// which is semantically correct for the /config availability display.
|
|
33
|
+
dsh: '',
|
|
31
34
|
};
|
|
32
35
|
const CACHE_TTL_MS = 5 * 60_000;
|
|
33
36
|
/** Module-level cache, survives across calls within the process. */
|
|
@@ -65,7 +68,9 @@ export async function probeAgentAvailability(kind) {
|
|
|
65
68
|
* on resource-constrained devices.
|
|
66
69
|
*/
|
|
67
70
|
export async function probeAllAgents() {
|
|
68
|
-
|
|
71
|
+
// Skip agents with no CLI binary (DSH is HTTP-only, binary === ''): the
|
|
72
|
+
// probe / availability display only covers spawn-able agents.
|
|
73
|
+
const kinds = Object.keys(BINARY_MAP).filter((k) => BINARY_MAP[k] !== '');
|
|
69
74
|
const entries = await Promise.all(kinds.map(async (k) => [k, await probeAgentAvailability(k)]));
|
|
70
75
|
return new Map(entries);
|
|
71
76
|
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AskUserQuestion 公共工厂与映射(agent 无关)。
|
|
3
|
+
*
|
|
4
|
+
* 接入约定(types.ts UserQuestion 注释的落点):
|
|
5
|
+
* - 各 runner 用 makeQuestionApprovalEvent 构造标准 question 审批事件,
|
|
6
|
+
* 避免四处手拼事件形状(claude/codex/kimi/pi 共用);
|
|
7
|
+
* - 用户答案经 ApprovalCoordinator 以 {问题文本: 值} 回传 runner 后,
|
|
8
|
+
* 用 mapAnswersByIndex 按问题顺序展开,再做协议级编码
|
|
9
|
+
* (Codex 问题 id、Kimi q{i}、Pi 单题取值)。
|
|
10
|
+
*/
|
|
11
|
+
import type { ApprovalRequestedEvent, UserQuestion } from './types.js';
|
|
12
|
+
export interface QuestionEventOptions {
|
|
13
|
+
/** Per-request 审批超时覆盖(Codex autoResolutionMs)。 */
|
|
14
|
+
timeoutMs?: number;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* 构造标准 question approval_requested 事件。
|
|
18
|
+
* availableDecisions 恒为空数组:提问只能作答或跳过(decline/cancel 是
|
|
19
|
+
* coordinator 的通用安全兜底),不允许 accept/decline 按钮混入提问卡。
|
|
20
|
+
*/
|
|
21
|
+
export declare function makeQuestionApprovalEvent(requestId: number | string, questions: UserQuestion[], threadId: string, opts?: QuestionEventOptions): ApprovalRequestedEvent;
|
|
22
|
+
/**
|
|
23
|
+
* 按问题顺序把 coordinator 回传的 {问题文本: 值} 展开成索引对齐数组。
|
|
24
|
+
* 未作答的问题对应 undefined,由各 runner 决定协议编码(跳过/空 answers)。
|
|
25
|
+
*/
|
|
26
|
+
export declare function mapAnswersByIndex(questions: UserQuestion[], answers: Record<string, string | string[]>): Array<string | string[] | undefined>;
|