@excitedjs/agent-runtime-claude-code 0.2.0-alpha.g0ddd418597ca
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/LICENSE +21 -0
- package/README.md +32 -0
- package/dist/args.d.ts +71 -0
- package/dist/args.d.ts.map +1 -0
- package/dist/args.js +87 -0
- package/dist/args.js.map +1 -0
- package/dist/config.d.ts +71 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +86 -0
- package/dist/config.js.map +1 -0
- package/dist/diagnostic.d.ts +12 -0
- package/dist/diagnostic.d.ts.map +1 -0
- package/dist/diagnostic.js +25 -0
- package/dist/diagnostic.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/completion-body.d.ts +38 -0
- package/dist/internal/completion-body.d.ts.map +1 -0
- package/dist/internal/completion-body.js +62 -0
- package/dist/internal/completion-body.js.map +1 -0
- package/dist/internal/config-validate.d.ts +23 -0
- package/dist/internal/config-validate.d.ts.map +1 -0
- package/dist/internal/config-validate.js +122 -0
- package/dist/internal/config-validate.js.map +1 -0
- package/dist/internal/os.d.ts +30 -0
- package/dist/internal/os.d.ts.map +1 -0
- package/dist/internal/os.js +81 -0
- package/dist/internal/os.js.map +1 -0
- package/dist/internal/turn-render.d.ts +22 -0
- package/dist/internal/turn-render.d.ts.map +1 -0
- package/dist/internal/turn-render.js +40 -0
- package/dist/internal/turn-render.js.map +1 -0
- package/dist/mcp-config.d.ts +19 -0
- package/dist/mcp-config.d.ts.map +1 -0
- package/dist/mcp-config.js +22 -0
- package/dist/mcp-config.js.map +1 -0
- package/dist/provider-ref.d.ts +8 -0
- package/dist/provider-ref.d.ts.map +1 -0
- package/dist/provider-ref.js +8 -0
- package/dist/provider-ref.js.map +1 -0
- package/dist/provider.d.ts +60 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +110 -0
- package/dist/provider.js.map +1 -0
- package/dist/rpc.d.ts +45 -0
- package/dist/rpc.d.ts.map +1 -0
- package/dist/rpc.js +212 -0
- package/dist/rpc.js.map +1 -0
- package/dist/runtime.d.ts +174 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +464 -0
- package/dist/runtime.js.map +1 -0
- package/dist/stream.d.ts +96 -0
- package/dist/stream.d.ts.map +1 -0
- package/dist/stream.js +289 -0
- package/dist/stream.js.map +1 -0
- package/dist/supervisor.d.ts +17 -0
- package/dist/supervisor.d.ts.map +1 -0
- package/dist/supervisor.js +170 -0
- package/dist/supervisor.js.map +1 -0
- package/dist/types.d.ts +133 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +7 -0
- package/dist/types.js.map +1 -0
- package/package.json +53 -0
package/dist/rpc.js
ADDED
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Code stream-json turn RPC.
|
|
3
|
+
*
|
|
4
|
+
* The supervisor owns the child process. This class owns one in-flight turn,
|
|
5
|
+
* stdout line demux, turn aggregation, and defensive control-request replies.
|
|
6
|
+
*/
|
|
7
|
+
import { randomUUID } from 'node:crypto';
|
|
8
|
+
import { buildCanUseToolAllow, buildControlAck, buildRemoteControlEnable, buildUserMessage, LineBuffer, parseLine, TurnAggregator, } from './stream.js';
|
|
9
|
+
export class ClaudeCodeStreamRpc {
|
|
10
|
+
stdin;
|
|
11
|
+
options;
|
|
12
|
+
lineBuf = new LineBuffer();
|
|
13
|
+
pending = null;
|
|
14
|
+
remoteControlRequestId = null;
|
|
15
|
+
constructor(stdin, options) {
|
|
16
|
+
this.stdin = stdin;
|
|
17
|
+
this.options = options;
|
|
18
|
+
}
|
|
19
|
+
async submitTurn(prompt, options = {}) {
|
|
20
|
+
if (!this.stdin.writable) {
|
|
21
|
+
return Promise.reject(new Error('claude resident child is not running'));
|
|
22
|
+
}
|
|
23
|
+
if (this.pending !== null) {
|
|
24
|
+
return Promise.reject(new Error('claude resident session is already mid-turn'));
|
|
25
|
+
}
|
|
26
|
+
return new Promise((resolve, reject) => {
|
|
27
|
+
const pending = {
|
|
28
|
+
resolve,
|
|
29
|
+
reject,
|
|
30
|
+
aggregator: new TurnAggregator(),
|
|
31
|
+
timer: null,
|
|
32
|
+
settleImmediate: null,
|
|
33
|
+
steered: false,
|
|
34
|
+
deferredOutcome: null,
|
|
35
|
+
};
|
|
36
|
+
this.pending = pending;
|
|
37
|
+
// Arm the idle deadline (reset on every inbound stream line in `onLine`).
|
|
38
|
+
this.armIdleTimer(pending);
|
|
39
|
+
this.stdin.write(`${buildUserMessage(prompt, options)}\n`, (err) => {
|
|
40
|
+
if (err != null && this.pending === pending) {
|
|
41
|
+
this.settlePending()?.reject(err instanceof Error ? err : new Error(String(err)));
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
async steerTurn(prompt, options = {}) {
|
|
47
|
+
if (!this.stdin.writable) {
|
|
48
|
+
return Promise.reject(new Error('claude resident child is not running'));
|
|
49
|
+
}
|
|
50
|
+
if (this.pending === null) {
|
|
51
|
+
return Promise.reject(new Error('claude resident session has no active turn'));
|
|
52
|
+
}
|
|
53
|
+
const pending = this.pending;
|
|
54
|
+
pending.steered = true;
|
|
55
|
+
return new Promise((resolve, reject) => {
|
|
56
|
+
this.stdin.write(`${buildUserMessage(prompt, { priority: 'now', ...options })}\n`, (err) => {
|
|
57
|
+
if (err != null) {
|
|
58
|
+
reject(err instanceof Error ? err : new Error(String(err)));
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
resolve();
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
onStdoutChunk(chunk) {
|
|
66
|
+
for (const line of this.lineBuf.push(chunk))
|
|
67
|
+
this.onLine(parseLine(line));
|
|
68
|
+
}
|
|
69
|
+
failPending(err) {
|
|
70
|
+
this.settlePending()?.reject(err);
|
|
71
|
+
}
|
|
72
|
+
enableRemoteControl() {
|
|
73
|
+
if (!this.stdin.writable)
|
|
74
|
+
return;
|
|
75
|
+
this.remoteControlRequestId = randomUUID();
|
|
76
|
+
this.stdin.write(`${buildRemoteControlEnable(this.remoteControlRequestId)}\n`);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Detach the in-flight turn: clear its deadline timer and null `pending`,
|
|
80
|
+
* returning it so the caller can resolve or reject it exactly once.
|
|
81
|
+
*/
|
|
82
|
+
settlePending() {
|
|
83
|
+
const pending = this.pending;
|
|
84
|
+
if (pending === null)
|
|
85
|
+
return null;
|
|
86
|
+
if (pending.timer !== null)
|
|
87
|
+
clearTimeout(pending.timer);
|
|
88
|
+
if (pending.settleImmediate !== null)
|
|
89
|
+
clearImmediate(pending.settleImmediate);
|
|
90
|
+
this.pending = null;
|
|
91
|
+
return pending;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* (Re)arm the per-turn idle deadline. `turnTimeoutMs` is a *max-idle* window,
|
|
95
|
+
* not a total-turn cap: any inbound stream line for this turn pushes it out
|
|
96
|
+
* (see `onLine`). A genuinely wedged child (no stream activity for the whole
|
|
97
|
+
* window) is still reaped — preserving the #120 anti-hang intent — but a long
|
|
98
|
+
* but continuously-streaming turn never trips the deadline (#156).
|
|
99
|
+
*/
|
|
100
|
+
armIdleTimer(pending) {
|
|
101
|
+
if (pending.timer !== null)
|
|
102
|
+
clearTimeout(pending.timer);
|
|
103
|
+
pending.timer = setTimeout(() => {
|
|
104
|
+
if (this.pending !== pending)
|
|
105
|
+
return;
|
|
106
|
+
this.pending = null;
|
|
107
|
+
this.options.log?.('error', `claude turn stalled: no stream activity for ${this.options.turnTimeoutMs}ms; reaping resident child`);
|
|
108
|
+
pending.reject(new Error(`claude resident turn stalled: no stream activity for ${this.options.turnTimeoutMs}ms`));
|
|
109
|
+
this.options.reapOnTimeout();
|
|
110
|
+
}, this.options.turnTimeoutMs);
|
|
111
|
+
}
|
|
112
|
+
onLine(line) {
|
|
113
|
+
// Idle-timeout reset: any inbound stream line for the pending turn is
|
|
114
|
+
// activity, so push the deadline out. The terminal `result` clears the
|
|
115
|
+
// timer via `settlePending` below.
|
|
116
|
+
if (this.pending !== null)
|
|
117
|
+
this.armIdleTimer(this.pending);
|
|
118
|
+
switch (line.kind) {
|
|
119
|
+
case 'init':
|
|
120
|
+
case 'assistant':
|
|
121
|
+
this.pending?.aggregator.accept(line);
|
|
122
|
+
break;
|
|
123
|
+
case 'result': {
|
|
124
|
+
if (this.pending === null)
|
|
125
|
+
break;
|
|
126
|
+
this.pending.aggregator.accept(line);
|
|
127
|
+
const outcome = this.pending.aggregator.outcome();
|
|
128
|
+
if (this.pending.steered) {
|
|
129
|
+
this.deferSteeredResult(this.pending, outcome);
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
const pending = this.settlePending();
|
|
133
|
+
if (pending === null)
|
|
134
|
+
break;
|
|
135
|
+
if (outcome !== null)
|
|
136
|
+
pending.resolve(outcome);
|
|
137
|
+
else
|
|
138
|
+
pending.reject(new Error('claude turn ended without a result'));
|
|
139
|
+
break;
|
|
140
|
+
}
|
|
141
|
+
case 'control_request':
|
|
142
|
+
this.onControlRequest(line.requestId, line.subtype, line.request);
|
|
143
|
+
break;
|
|
144
|
+
case 'control_response':
|
|
145
|
+
this.onControlResponse(line.requestId, line.ok, line.response, line.error);
|
|
146
|
+
break;
|
|
147
|
+
case 'parse_error':
|
|
148
|
+
this.options.log?.('warn', `claude stream-json parse error: ${line.raw}`);
|
|
149
|
+
break;
|
|
150
|
+
default:
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
deferSteeredResult(pending, outcome) {
|
|
155
|
+
pending.deferredOutcome = outcome;
|
|
156
|
+
if (pending.settleImmediate !== null)
|
|
157
|
+
return;
|
|
158
|
+
// A stream-json `priority` steer can cause Claude Code to close the
|
|
159
|
+
// interrupted run and immediately drain the queued steer in the same stdout
|
|
160
|
+
// flush. Resolve on the next tick so those follow-up lines are still folded
|
|
161
|
+
// into this one Dreamux logical turn instead of becoming a silent late result.
|
|
162
|
+
pending.settleImmediate = setImmediate(() => {
|
|
163
|
+
if (this.pending !== pending)
|
|
164
|
+
return;
|
|
165
|
+
const finalOutcome = pending.deferredOutcome;
|
|
166
|
+
const settled = this.settlePending();
|
|
167
|
+
if (settled === null)
|
|
168
|
+
return;
|
|
169
|
+
if (finalOutcome !== null)
|
|
170
|
+
settled.resolve(finalOutcome);
|
|
171
|
+
else
|
|
172
|
+
settled.reject(new Error('claude turn ended without a result'));
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
onControlRequest(requestId, subtype, request) {
|
|
176
|
+
if (requestId === null || !this.stdin.writable)
|
|
177
|
+
return;
|
|
178
|
+
// Unattended posture: answer permission callbacks so a turn never wedges
|
|
179
|
+
// waiting on a human.
|
|
180
|
+
let reply;
|
|
181
|
+
if (subtype === 'can_use_tool') {
|
|
182
|
+
const rawInput = request['input'];
|
|
183
|
+
const input = typeof rawInput === 'object' &&
|
|
184
|
+
rawInput !== null &&
|
|
185
|
+
!Array.isArray(rawInput)
|
|
186
|
+
? rawInput
|
|
187
|
+
: {};
|
|
188
|
+
reply = buildCanUseToolAllow(requestId, input);
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
reply = buildControlAck(requestId);
|
|
192
|
+
}
|
|
193
|
+
this.stdin.write(`${reply}\n`);
|
|
194
|
+
}
|
|
195
|
+
onControlResponse(requestId, ok, response, error) {
|
|
196
|
+
if (requestId === null || requestId !== this.remoteControlRequestId)
|
|
197
|
+
return;
|
|
198
|
+
this.remoteControlRequestId = null;
|
|
199
|
+
if (ok && response !== null) {
|
|
200
|
+
const url = response['session_url'] ?? response['connect_url'];
|
|
201
|
+
if (typeof url === 'string') {
|
|
202
|
+
this.options.onRemoteControlUrl?.(url);
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
this.options.log?.('warn', 'claude remote control enable succeeded without a URL');
|
|
206
|
+
}
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
this.options.log?.('warn', `claude remote control enable failed${error !== null ? `: ${error}` : ''}`);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
//# sourceMappingURL=rpc.js.map
|
package/dist/rpc.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rpc.js","sourceRoot":"","sources":["../src/rpc.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `builtin:claude-code` AgentRuntime (issue #110 PR6, resident stream-json
|
|
3
|
+
* transport since issue #120; extracted into `@excitedjs/agent-runtime-claude-code`
|
|
4
|
+
* in issue #209).
|
|
5
|
+
*
|
|
6
|
+
* A real second agent runtime that proves the AgentRuntimeProvider abstraction
|
|
7
|
+
* is not "Codex renamed". Like Codex it runs a **resident child process**
|
|
8
|
+
* supervised for the runtime's lifetime — but it differs in every
|
|
9
|
+
* runtime-specific dimension:
|
|
10
|
+
*
|
|
11
|
+
* - **Stream-json over stdio, not an app-server WebSocket.** The resident child
|
|
12
|
+
* is `claude --print --input-format stream-json --output-format stream-json`
|
|
13
|
+
* (see `./args.ts`); turns are NDJSON `user` lines on stdin and
|
|
14
|
+
* `init`/`assistant`/`result` envelopes on stdout (see `./stream.ts`). There
|
|
15
|
+
* is no `initialize` handshake — the child emits `init` lazily with the first
|
|
16
|
+
* turn — so readiness is "child spawned", not "handshake completed".
|
|
17
|
+
* - **MCP injection is a JSON config document** (`--mcp-config <file>`), not
|
|
18
|
+
* Codex's `-c mcp_servers.*` TOML CLI flags.
|
|
19
|
+
* - **Runtime-owned config** is `DispatcherClaudeCodeConfig` (bin / model /
|
|
20
|
+
* permission_mode / remote_control / extra_args / extra_env), distinct from
|
|
21
|
+
* the Codex config.
|
|
22
|
+
* - **Completion delivery** is a plain user turn (no fake task-notification),
|
|
23
|
+
* not the Codex inbox-then-trigger path.
|
|
24
|
+
*
|
|
25
|
+
* Process spawning goes through an injectable {@link ClaudeCodeSessionFactory}
|
|
26
|
+
* seam (mirroring Codex's process-factory seam), so the lifecycle contract is
|
|
27
|
+
* fully unit-testable with a fake session. A live `claude` binary is exercised
|
|
28
|
+
* only by the opt-in live test.
|
|
29
|
+
*
|
|
30
|
+
* Failure contract (unchanged by #120): a turn failure (spawn error, child
|
|
31
|
+
* exit, error `result`) is never swallowed. For inbound/restart turns it drives
|
|
32
|
+
* the runtime to `degraded` with a persisted `last_error` (observable via
|
|
33
|
+
* status/doctor). For `completionInput` it surfaces as a `failed`
|
|
34
|
+
* result the caller can act on (PR8 delivery retry). `channelInput` still
|
|
35
|
+
* returns after accept (submit != completion) so the channel can ack promptly.
|
|
36
|
+
*
|
|
37
|
+
* Restart: an unexpected child exit marks the runtime `degraded`; the next turn
|
|
38
|
+
* re-spawns the resident child with `--resume <session_id>`, restoring the
|
|
39
|
+
* conversation. There is no background backoff timer — re-spawn is lazy and
|
|
40
|
+
* bound to the (serialized) turn queue, so it stays deterministic.
|
|
41
|
+
*
|
|
42
|
+
* Per-turn idle deadline: a turn whose still-alive child goes silent — never
|
|
43
|
+
* emitting another stream line (a stall, or a wait on input the runtime cannot
|
|
44
|
+
* satisfy) — would otherwise pend forever and wedge the serial queue, and behind
|
|
45
|
+
* it TeamMate completion delivery, which awaits this runtime. `turn_timeout_ms`
|
|
46
|
+
* is a *max-idle* window (issue #156): it is reset on every inbound stream line,
|
|
47
|
+
* so a long but continuously-streaming turn (e.g. a deep audit running many
|
|
48
|
+
* tool calls for far longer than the window) is never reaped, while a child that
|
|
49
|
+
* emits nothing for the whole window still is — turning an infinite hang into a
|
|
50
|
+
* normal degraded + `last_error` (inbound) or `failed` delivery result.
|
|
51
|
+
*
|
|
52
|
+
* Reference: the resident stream-json protocol model and process-supervision
|
|
53
|
+
* shape are adapted from the Claudemux `next` implementation; the AgentRuntime /
|
|
54
|
+
* Channel / DispatcherService boundaries (provider seam, runtime-owned MCP
|
|
55
|
+
* injection, degraded/last_error status, TeamMate delivery result contract) are
|
|
56
|
+
* Dreamux's own, per `.agents/decisions/agent-runtime-provider.md`.
|
|
57
|
+
*/
|
|
58
|
+
import type { DispatcherClaudeCodeConfig } from './config.js';
|
|
59
|
+
import { type ClaudeCodeSessionFactory } from './supervisor.js';
|
|
60
|
+
import type { AgentRuntimeCapabilities, AgentRuntime, AgentRuntimeIdentity, AgentRuntimeLastResult, AgentRuntimeMcpServer, AgentRuntimePathContext, AgentRuntimeResumeInput, AgentRuntimeSkillSource, AgentRuntimeStateCallbacks, AgentRuntimeStatus, AgentRuntimeSystemInput, AgentRuntimeTurnResult, CompletionEnvelope, DreamuxLogger, InboundDeliveryHooks, InboundTurnInput, TeamMateCompletionDeliveryResult, TurnSettledSignal } from '@excitedjs/dreamux-types';
|
|
61
|
+
/**
|
|
62
|
+
* Everything the Claude Code runtime needs, assembled by the provider from the
|
|
63
|
+
* neutral create context plus host-supplied hooks. The host contracts the
|
|
64
|
+
* package must not reconstruct — the per-dispatcher path context, the durable
|
|
65
|
+
* state sink, and the base process env (`PATH` seeded with the host package
|
|
66
|
+
* bins) — arrive here; nothing references a Dreamux host module.
|
|
67
|
+
*/
|
|
68
|
+
export interface ClaudeCodeRuntimeDeps {
|
|
69
|
+
/** Provider-parsed Claude Code runtime config. */
|
|
70
|
+
config: DispatcherClaudeCodeConfig;
|
|
71
|
+
/** Working directory the resident `claude` child runs in. */
|
|
72
|
+
cwd: string;
|
|
73
|
+
/** Neutral state sink for status/thread transitions. */
|
|
74
|
+
state: AgentRuntimeStateCallbacks;
|
|
75
|
+
/** Neutral path context: the runtime derives its mcp-config / log subpaths here. */
|
|
76
|
+
paths: AgentRuntimePathContext;
|
|
77
|
+
/** MCP server descriptors translated into the `--mcp-config` JSON document. */
|
|
78
|
+
mcpServers: readonly AgentRuntimeMcpServer[];
|
|
79
|
+
/** Resident-session factory (tests inject a fake). */
|
|
80
|
+
sessionFactory: ClaudeCodeSessionFactory;
|
|
81
|
+
/** Host-level bin resolver (default: identity on the config bin). */
|
|
82
|
+
resolveBinPath: (bin: string) => string;
|
|
83
|
+
/**
|
|
84
|
+
* The host's neutral env-injection entries from the create context, merged
|
|
85
|
+
* into the resident child env before this provider's own `extra_env`.
|
|
86
|
+
* Empty/omitted means inject nothing (the common case).
|
|
87
|
+
*/
|
|
88
|
+
injectEnv?: Record<string, string>;
|
|
89
|
+
/**
|
|
90
|
+
* Launcher-supplied role/system-prompt content, applied as an APPEND via
|
|
91
|
+
* `--append-system-prompt`. Omitted for launches that supply none (teammates).
|
|
92
|
+
*/
|
|
93
|
+
systemPromptContent?: string;
|
|
94
|
+
/**
|
|
95
|
+
* Role-gated skill sources core selected (issue #209 slice 6). The
|
|
96
|
+
* add-dir-compatible ones become `--add-dir` flags on every (re)spawn.
|
|
97
|
+
*/
|
|
98
|
+
skillSources?: readonly AgentRuntimeSkillSource[];
|
|
99
|
+
/** Fired each time a delivered turn reaches a terminal state. */
|
|
100
|
+
onTurnSettled?: (settled: TurnSettledSignal) => void;
|
|
101
|
+
/** Structured logger; falls back to a minimal `console.error` sink. */
|
|
102
|
+
logger?: DreamuxLogger;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* The Claude Code agent runtime for one dispatcher. A single resident
|
|
106
|
+
* stream-json child serves every turn. Turns run serially (one at a time) and
|
|
107
|
+
* `channelInput` returns after the message is accepted — not after the turn
|
|
108
|
+
* completes — matching the Codex runtime's submit-then-serialize contract.
|
|
109
|
+
*/
|
|
110
|
+
export declare class ClaudeCodeRuntime implements AgentRuntime {
|
|
111
|
+
private readonly deps;
|
|
112
|
+
readonly providerRef = "builtin:claude-code";
|
|
113
|
+
private readonly dispatcherId;
|
|
114
|
+
private readonly config;
|
|
115
|
+
private readonly bin;
|
|
116
|
+
private readonly cwd;
|
|
117
|
+
private readonly mcpConfigPath;
|
|
118
|
+
private readonly mcpConfigDoc;
|
|
119
|
+
private readonly stderrLogPath;
|
|
120
|
+
private readonly completionSpillDir;
|
|
121
|
+
private readonly logger;
|
|
122
|
+
private status;
|
|
123
|
+
private threadId;
|
|
124
|
+
private resumed;
|
|
125
|
+
private stopped;
|
|
126
|
+
private readonly seen;
|
|
127
|
+
private queue;
|
|
128
|
+
private readonly runtimeInstanceId;
|
|
129
|
+
private turnCounter;
|
|
130
|
+
private session;
|
|
131
|
+
private lastResult;
|
|
132
|
+
private activeChannelTurn;
|
|
133
|
+
constructor(identity: AgentRuntimeIdentity, deps: ClaudeCodeRuntimeDeps);
|
|
134
|
+
getStatus(): AgentRuntimeStatus;
|
|
135
|
+
getCapabilities(): AgentRuntimeCapabilities;
|
|
136
|
+
getThreadId(): string | null;
|
|
137
|
+
wasThreadResumed(): boolean;
|
|
138
|
+
getLast(): Promise<AgentRuntimeLastResult | null>;
|
|
139
|
+
getContext(): Promise<null>;
|
|
140
|
+
resume(input?: AgentRuntimeResumeInput): Promise<void>;
|
|
141
|
+
start(): Promise<void>;
|
|
142
|
+
stop(): Promise<void>;
|
|
143
|
+
systemInput(notice: AgentRuntimeSystemInput): Promise<AgentRuntimeTurnResult>;
|
|
144
|
+
channelInput(input: InboundTurnInput, hooks?: InboundDeliveryHooks): Promise<AgentRuntimeTurnResult>;
|
|
145
|
+
completionInput(completion: CompletionEnvelope): Promise<TeamMateCompletionDeliveryResult>;
|
|
146
|
+
/**
|
|
147
|
+
* Chain a turn onto the serial queue. Returns a promise that resolves when
|
|
148
|
+
* this turn completes and rejects when it fails, so awaiting callers (delivery)
|
|
149
|
+
* see the real outcome. The queue itself continues regardless of outcome so a
|
|
150
|
+
* failed turn does not wedge later turns.
|
|
151
|
+
*/
|
|
152
|
+
private runTurnOnQueue;
|
|
153
|
+
private runChannelTurnOnQueue;
|
|
154
|
+
private runChannelTurn;
|
|
155
|
+
private steerChannelTurn;
|
|
156
|
+
private markTurnSucceeded;
|
|
157
|
+
private markTurnFailed;
|
|
158
|
+
/**
|
|
159
|
+
* Ensure a live resident session exists, spawning (or re-spawning after an
|
|
160
|
+
* unexpected exit) as needed. Re-spawn resumes the persisted session id so the
|
|
161
|
+
* conversation survives a crash.
|
|
162
|
+
*/
|
|
163
|
+
private ensureSession;
|
|
164
|
+
/** React to an unexpected resident-child exit: degrade and drop the session. */
|
|
165
|
+
private onSessionExit;
|
|
166
|
+
private runTurn;
|
|
167
|
+
private runTurnWithSession;
|
|
168
|
+
private applyTurnOutcome;
|
|
169
|
+
private nextTurnId;
|
|
170
|
+
private buildProcessEnv;
|
|
171
|
+
private setStatus;
|
|
172
|
+
private log;
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"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"}
|