autodev-cli 1.4.189 → 1.4.191

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.
@@ -0,0 +1,188 @@
1
+ /** Callbacks the host injects so hook emission + redaction stay in one place. */
2
+ export interface AcpHostHooks {
3
+ /** Emit ONE hook event (host adds redaction + provider tagging). */
4
+ emitHook(name: string, extra: Record<string, unknown>): void;
5
+ /** Human log line. */
6
+ log(msg: string): void;
7
+ }
8
+ export interface AcpTurnResult {
9
+ clean: boolean;
10
+ stopReason: string;
11
+ error?: string;
12
+ /** True when the turn ended clean but produced NO assistant text / tool calls
13
+ * (e.g. an unusable model). Lets the host surface a clear log instead of
14
+ * silently spinning. */
15
+ emptyOutput?: boolean;
16
+ }
17
+ /** A decoded session/update notification (pure; unit-tested). */
18
+ export type AcpUpdate = {
19
+ kind: 'assistant';
20
+ text: string;
21
+ } | {
22
+ kind: 'reasoning';
23
+ text: string;
24
+ } | {
25
+ kind: 'tool_call';
26
+ id: string;
27
+ name: string;
28
+ input: unknown;
29
+ } | {
30
+ kind: 'tool_result';
31
+ id: string;
32
+ outputText: string;
33
+ status: string;
34
+ } | {
35
+ kind: 'other';
36
+ };
37
+ /** Provider-specific launch + decode configuration. */
38
+ export interface AcpLaunchSpec {
39
+ /** Build the argv (after the binary) for `spawn`. */
40
+ buildArgs(model: string | undefined, extraArgs: string[]): string[];
41
+ /** Decode a raw JSON-RPC session/update into an AcpUpdate. Defaults to the
42
+ * standard-ACP decoder (`decodeAcpUpdateStandard`). */
43
+ decodeUpdate?: (msg: unknown) => AcpUpdate;
44
+ /** Title attached to narration (Notification) hooks. */
45
+ narrationTitle: string;
46
+ /** Forward agent_thought_chunk as narration too (default false). */
47
+ narrateReasoning?: boolean;
48
+ }
49
+ /**
50
+ * STANDARD-ACP decoder (opencode, and the generic default). Handles the ACP-spec
51
+ * session/update shapes:
52
+ * agent_message_chunk {content:{type:'text',text}} -> assistant
53
+ * agent_thought_chunk {content:{type:'text',text}} -> reasoning
54
+ * tool_call {toolCallId,title,rawInput} -> tool_call (name=title)
55
+ * tool_call_update {toolCallId,status,content|rawOutput} -> tool_result
56
+ * Anything else (available_commands_update, usage_update, plan, …) -> other. PURE.
57
+ */
58
+ export declare function decodeAcpUpdateStandard(msg: unknown): AcpUpdate;
59
+ /** Best-effort flatten of a tool_call_update's output into a short string. PURE. */
60
+ export declare function extractToolOutput(u: Record<string, unknown>): string;
61
+ /**
62
+ * Classify a session/prompt RESULT into clean-vs-error for the exit file. PURE.
63
+ * - end_turn / max_tokens / max_turn_requests → clean (exit 0)
64
+ * - cancelled → clean (an intentional interrupt, not a failure)
65
+ * - a JSON-RPC error, or any other stopReason → error (exit 1)
66
+ */
67
+ export declare function classifyAcpResult(result: {
68
+ result?: {
69
+ stopReason?: string;
70
+ };
71
+ error?: {
72
+ message?: string;
73
+ };
74
+ }): AcpTurnResult;
75
+ /**
76
+ * One persistent ACP process for a workspace root. Not a singleton — the host
77
+ * keeps a Map<root, AcpSession> and reuses it. Provider behaviour is injected via
78
+ * the `spec`.
79
+ */
80
+ export declare class AcpSession {
81
+ protected readonly root: string;
82
+ protected readonly model: string | undefined;
83
+ protected readonly bin: string;
84
+ protected readonly hooks: AcpHostHooks;
85
+ protected readonly extraArgs: string[];
86
+ protected readonly spec: AcpLaunchSpec;
87
+ /** Extra env vars merged into the child's environment (e.g. OPENCODE_CONFIG). */
88
+ protected readonly extraEnv: Record<string, string>;
89
+ private readonly _decode;
90
+ private child;
91
+ private buf;
92
+ private nextId;
93
+ private readonly pending;
94
+ private _sessionId;
95
+ private _wantSessionId;
96
+ private _ready;
97
+ private _busy;
98
+ private _startCount;
99
+ private earlyStderr;
100
+ /** True WHILE session/load is replaying prior history — every session/update
101
+ * during the replay is dropped (emits ZERO hooks) so a (re)start never
102
+ * re-spams historical narration + tool_calls to the office feed (Layer A.1). */
103
+ private _loading;
104
+ /** The active PRIMARY turn's stdout sink (assistant text). Null between turns. */
105
+ private _sink;
106
+ /** Tool-call names by id, so a tool_result can carry the originating name. */
107
+ private readonly _toolNames;
108
+ /** Accumulates assistant chunks so Notification hooks are line-granular. */
109
+ private _narrationBuf;
110
+ /** The current tool activity label (set on tool_call, cleared on result). */
111
+ private _activity;
112
+ /** Did the active turn produce ANY assistant text or tool call? (empty-turn guard) */
113
+ private _turnHadOutput;
114
+ /** ALL outstanding session/prompt promises — the primary turn AND any steered
115
+ * (queued) continuation prompts. The turn is not "done" until this drains, so
116
+ * the loop keeps the agent WORKING through steers instead of going idle while
117
+ * the agent runs an untracked queued turn (Bug A). */
118
+ private readonly _inflight;
119
+ constructor(opts: {
120
+ root: string;
121
+ model?: string;
122
+ bin: string;
123
+ hooks: AcpHostHooks;
124
+ spec: AcpLaunchSpec;
125
+ initialSessionId?: string;
126
+ extraArgs?: string[];
127
+ extraEnv?: Record<string, string>;
128
+ });
129
+ /** Per-turn watchdog budget (ms). Env: AUTODEV_ACP_MAX_RUN_MS, else GROK_MAX_RUN_MS
130
+ * (parity with the headless path), else 20 minutes. A 0/negative value disables. */
131
+ static maxRunMs(): number;
132
+ get pid(): number | undefined;
133
+ get sessionId(): string | undefined;
134
+ get activity(): string | undefined;
135
+ /** Busy while the primary turn is running OR any steered/queued prompt is still
136
+ * in-flight — so the loop never treats the agent as idle mid-queue (Bug A). */
137
+ isBusy(): boolean;
138
+ isAlive(): boolean;
139
+ /** Spawn + initialize + session/new|load, once. Respawns transparently if dead. */
140
+ ensureReady(): Promise<void>;
141
+ private _startup;
142
+ private _spawnChild;
143
+ private _onExit;
144
+ private _onStdout;
145
+ private _handle;
146
+ private _onUpdate;
147
+ /**
148
+ * Bug B invariant: every forwarded tool-START must get a matching tool-END. On
149
+ * turn end / cancel / teardown, FLUSH any tool_call ids still open (never got a
150
+ * terminal tool_call_update) as ended, so pixel-office (which pairs start→end)
151
+ * never shows a tool stuck "running" after the agent is idle.
152
+ */
153
+ private _flushOpenTools;
154
+ /** Emit completed narration lines as Notification hooks. `final` flushes the
155
+ * trailing partial line (turn end). Keeps the office feed line-granular. */
156
+ private _flushNarration;
157
+ /**
158
+ * Run ONE primary turn: send the prompt and await turn end. Streams assistant
159
+ * text to `sink`. Emits Stop/StopFailure + SessionEnd. The process stays alive.
160
+ */
161
+ runTurn(promptText: string, sink: (text: string) => void): Promise<AcpTurnResult>;
162
+ /**
163
+ * Deliver a mid-run STEER: send an additional session/prompt the agent QUEUES
164
+ * (FIFO) and runs next — without exiting. The prompt is TRACKED in `_inflight`
165
+ * so the in-progress runTurn drains it before finishing (Bug A) — the steered
166
+ * turn's session/update hooks are forwarded like a normal turn and the loop
167
+ * stays WORKING until it completes. Returns true if handed to the live agent.
168
+ */
169
+ steer(text: string): boolean;
170
+ /** Send a tracked session/prompt (primary or steer) and register it in
171
+ * `_inflight` until it resolves. */
172
+ private _promptRequest;
173
+ /** Wait until every in-flight/queued prompt has resolved. */
174
+ private _drainInflight;
175
+ /**
176
+ * Send a QUIET prompt (e.g. `/compact`) and await it WITHOUT emitting the
177
+ * Stop/SessionEnd turn-boundary hooks — used for maintenance commands so they
178
+ * don't register as a task turn. Best-effort.
179
+ */
180
+ sendQuiet(text: string): Promise<void>;
181
+ /** Cancel the running turn (process stays alive). */
182
+ cancel(): void;
183
+ /** Kill the persistent process. Preserves the known session id for a later load. */
184
+ close(): void;
185
+ private _request;
186
+ private _send;
187
+ get stderrSnapshot(): string;
188
+ }