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.
- package/out/providers/acp/AcpSession.d.ts +188 -0
- package/out/providers/acp/AcpSession.js +683 -0
- package/out/providers/acp/AcpSession.js.map +1 -0
- package/out/providers/grok/GrokAcpSession.d.ts +11 -112
- package/out/providers/grok/GrokAcpSession.js +40 -493
- package/out/providers/grok/GrokAcpSession.js.map +1 -1
- package/out/providers/grok/authClassify.d.ts +36 -0
- package/out/providers/grok/authClassify.js +44 -1
- package/out/providers/grok/authClassify.js.map +1 -1
- package/out/providers/grok/tui.js +94 -3
- package/out/providers/grok/tui.js.map +1 -1
- package/out/providers/opencode/acp.d.ts +40 -0
- package/out/providers/opencode/acp.js +382 -0
- package/out/providers/opencode/acp.js.map +1 -0
- package/out/providers/opencode/sdk.d.ts +9 -8
- package/out/providers/opencode/sdk.js +30 -5
- package/out/providers/opencode/sdk.js.map +1 -1
- package/out/rateLimit.js +8 -0
- package/out/rateLimit.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { AcpLaunchSpec } from '../acp/AcpSession';
|
|
2
|
+
/** opencode's ACP launch spec. NB the model is NOT a CLI arg — `opencode acp`
|
|
3
|
+
* rejects `-m` (and the global `-m … acp` form exits 1). The model is injected
|
|
4
|
+
* via a merged OPENCODE_CONFIG file instead (see _writeAcpConfig). */
|
|
5
|
+
export declare const OPENCODE_ACP_SPEC: AcpLaunchSpec;
|
|
6
|
+
/** Cached probe: is `opencode acp` a real subcommand? (opencode prints its help
|
|
7
|
+
* to STDERR, so we merge 2>&1 and look for the ACP banner.) */
|
|
8
|
+
export declare function opencodeAcpSupported(): boolean;
|
|
9
|
+
/** Test-only: force the ACP enablement decision. */
|
|
10
|
+
export declare function __setOpencodeAcpEnabledForTest(v: boolean | null): void;
|
|
11
|
+
/**
|
|
12
|
+
* Whether opencode should run over native ACP instead of the createOpencode
|
|
13
|
+
* server. Gated by AUTODEV_OPENCODE_ACP (false/0/off/no forces the server path)
|
|
14
|
+
* AND `opencode acp` being available. Default ON when available.
|
|
15
|
+
*/
|
|
16
|
+
export declare function opencodeAcpEnabled(env?: NodeJS.ProcessEnv): boolean;
|
|
17
|
+
/** True while an opencode ACP turn (incl. steered continuations) is running. */
|
|
18
|
+
export declare function isOpencodeAcpBusy(root: string): boolean;
|
|
19
|
+
/** Current tool activity label for the root (undefined = idle). */
|
|
20
|
+
export declare function getOpencodeAcpActivity(root: string): string | undefined;
|
|
21
|
+
/** Latest opencode ACP session id (for resume-on-restart / session save). */
|
|
22
|
+
export declare function getOpencodeAcpLatestSessionId(root: string): string | undefined;
|
|
23
|
+
/** Is an opencode ACP session currently held for this root? */
|
|
24
|
+
export declare function hasOpencodeAcpSession(root: string): boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Run ONE turn through the persistent opencode ACP session. Mirrors the SDK
|
|
27
|
+
* path's stdout/exit contract. On ACP startup failure, calls `onAcpUnavailable`
|
|
28
|
+
* (the createOpencode-server fallback) and does NOT write the exit file itself.
|
|
29
|
+
*/
|
|
30
|
+
export declare function sendOpencodeAcpPrompt(root: string, promptFilePath: string, resumeSessionId: string | undefined, stdoutFile: string, exitFile: string, log: (msg: string) => void, model: string | undefined, showOutput: (() => void) | undefined, onAcpUnavailable: () => void): void;
|
|
31
|
+
/** Steer the live opencode ACP process mid-turn (a queued session/prompt). */
|
|
32
|
+
export declare function steerOpencodeAcp(root: string, text: string, log: (msg: string) => void): boolean;
|
|
33
|
+
/** Best-effort /compact on the live opencode ACP session (quiet, no Stop hook). */
|
|
34
|
+
export declare function compactOpencodeAcp(root: string, log: (msg: string) => void): Promise<void>;
|
|
35
|
+
/** Force-clear busy + evict the ACP session for a root. */
|
|
36
|
+
export declare function forceIdleOpencodeAcp(root: string): void;
|
|
37
|
+
/** Close + evict the opencode ACP session for a root (preserves session id). */
|
|
38
|
+
export declare function closeOpencodeAcp(root: string, log: (msg: string) => void): void;
|
|
39
|
+
/** Close all opencode ACP sessions — extension deactivate. */
|
|
40
|
+
export declare function closeAllOpencodeAcp(): void;
|
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ---------------------------------------------------------------------------
|
|
3
|
+
// opencode ACP — native `opencode acp` driven through the shared AcpSession.
|
|
4
|
+
//
|
|
5
|
+
// opencode ships FIRST-PARTY ACP (`opencode acp`, verified live on opencode
|
|
6
|
+
// 1.14.22): the same line-delimited JSON-RPC 2.0 protocol grok speaks, so we
|
|
7
|
+
// reuse the exact AcpSession client. One long-lived `opencode acp` process per
|
|
8
|
+
// workspace root, fed each turn, kept alive; resume only at (re)start via
|
|
9
|
+
// session/load (never minting a new session per turn — the opencode-session-
|
|
10
|
+
// explosion guard).
|
|
11
|
+
//
|
|
12
|
+
// This layer is the opencode BINDING of AcpSession:
|
|
13
|
+
// - the launch spec: `opencode [-m MODEL] acp` (global -m BEFORE the acp
|
|
14
|
+
// subcommand; the acp subcommand itself rejects -m). The MODEL comes from the
|
|
15
|
+
// agent's settings (settings.opencodeModel) — a real, usable model. NB the
|
|
16
|
+
// free `opencode/*` zen models return empty over raw ACP ("only usable from
|
|
17
|
+
// within OpenCode"), so an empty clean turn is surfaced as a clear log.
|
|
18
|
+
// - host hooks that emit the SAME canonical hook events (provider
|
|
19
|
+
// 'opencode-sdk') + live narration + secret redaction the SDK path emits, so
|
|
20
|
+
// pixel-office sees an identical event stream whether opencode runs via ACP
|
|
21
|
+
// or the createOpencode server.
|
|
22
|
+
// - gate `AUTODEV_OPENCODE_ACP` (default ON when `opencode acp` is available)
|
|
23
|
+
// with the createOpencode-server path as automatic fallback (wired in sdk.ts).
|
|
24
|
+
// ---------------------------------------------------------------------------
|
|
25
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
26
|
+
if (k2 === undefined) k2 = k;
|
|
27
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
28
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
29
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
30
|
+
}
|
|
31
|
+
Object.defineProperty(o, k2, desc);
|
|
32
|
+
}) : (function(o, m, k, k2) {
|
|
33
|
+
if (k2 === undefined) k2 = k;
|
|
34
|
+
o[k2] = m[k];
|
|
35
|
+
}));
|
|
36
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
37
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
38
|
+
}) : function(o, v) {
|
|
39
|
+
o["default"] = v;
|
|
40
|
+
});
|
|
41
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
42
|
+
var ownKeys = function(o) {
|
|
43
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
44
|
+
var ar = [];
|
|
45
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
46
|
+
return ar;
|
|
47
|
+
};
|
|
48
|
+
return ownKeys(o);
|
|
49
|
+
};
|
|
50
|
+
return function (mod) {
|
|
51
|
+
if (mod && mod.__esModule) return mod;
|
|
52
|
+
var result = {};
|
|
53
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
54
|
+
__setModuleDefault(result, mod);
|
|
55
|
+
return result;
|
|
56
|
+
};
|
|
57
|
+
})();
|
|
58
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
59
|
+
exports.OPENCODE_ACP_SPEC = void 0;
|
|
60
|
+
exports.opencodeAcpSupported = opencodeAcpSupported;
|
|
61
|
+
exports.__setOpencodeAcpEnabledForTest = __setOpencodeAcpEnabledForTest;
|
|
62
|
+
exports.opencodeAcpEnabled = opencodeAcpEnabled;
|
|
63
|
+
exports.isOpencodeAcpBusy = isOpencodeAcpBusy;
|
|
64
|
+
exports.getOpencodeAcpActivity = getOpencodeAcpActivity;
|
|
65
|
+
exports.getOpencodeAcpLatestSessionId = getOpencodeAcpLatestSessionId;
|
|
66
|
+
exports.hasOpencodeAcpSession = hasOpencodeAcpSession;
|
|
67
|
+
exports.sendOpencodeAcpPrompt = sendOpencodeAcpPrompt;
|
|
68
|
+
exports.steerOpencodeAcp = steerOpencodeAcp;
|
|
69
|
+
exports.compactOpencodeAcp = compactOpencodeAcp;
|
|
70
|
+
exports.forceIdleOpencodeAcp = forceIdleOpencodeAcp;
|
|
71
|
+
exports.closeOpencodeAcp = closeOpencodeAcp;
|
|
72
|
+
exports.closeAllOpencodeAcp = closeAllOpencodeAcp;
|
|
73
|
+
const fs = __importStar(require("fs"));
|
|
74
|
+
const path = __importStar(require("path"));
|
|
75
|
+
const child_process = __importStar(require("child_process"));
|
|
76
|
+
const AcpSession_1 = require("../acp/AcpSession");
|
|
77
|
+
const ProviderNormalizer_1 = require("../base/ProviderNormalizer");
|
|
78
|
+
const redactSecrets_1 = require("../../core/redactSecrets");
|
|
79
|
+
const OPENCODE_BIN = 'opencode';
|
|
80
|
+
/** opencode's ACP launch spec. NB the model is NOT a CLI arg — `opencode acp`
|
|
81
|
+
* rejects `-m` (and the global `-m … acp` form exits 1). The model is injected
|
|
82
|
+
* via a merged OPENCODE_CONFIG file instead (see _writeAcpConfig). */
|
|
83
|
+
exports.OPENCODE_ACP_SPEC = {
|
|
84
|
+
buildArgs(_model, extraArgs) {
|
|
85
|
+
return [...extraArgs, 'acp'];
|
|
86
|
+
},
|
|
87
|
+
decodeUpdate: AcpSession_1.decodeAcpUpdateStandard,
|
|
88
|
+
narrationTitle: 'opencode',
|
|
89
|
+
narrateReasoning: false, // keep opencode's agent_thought_chunk out of the feed
|
|
90
|
+
};
|
|
91
|
+
/**
|
|
92
|
+
* Write a MERGED opencode config to `<root>/.autodev/opencode-acp.json` and return
|
|
93
|
+
* its path — the workspace `opencode.json` (which carries autodev's office/operate
|
|
94
|
+
* MCP) with the agent's model layered in (and permission:allow ensured). Pointed
|
|
95
|
+
* at via OPENCODE_CONFIG so `opencode acp` runs the right model WITHOUT the CLI
|
|
96
|
+
* -m flag and WITHOUT mutating the workspace file. Returns undefined on failure
|
|
97
|
+
* (the session then just runs with opencode's own resolved config/model).
|
|
98
|
+
*/
|
|
99
|
+
function _writeAcpConfig(root, model) {
|
|
100
|
+
try {
|
|
101
|
+
let cfg = {};
|
|
102
|
+
const wsFile = path.join(root, 'opencode.json');
|
|
103
|
+
if (fs.existsSync(wsFile)) {
|
|
104
|
+
try {
|
|
105
|
+
cfg = JSON.parse(fs.readFileSync(wsFile, 'utf8'));
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
cfg = {};
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
if (!cfg['$schema']) {
|
|
112
|
+
cfg['$schema'] = 'https://opencode.ai/config.json';
|
|
113
|
+
}
|
|
114
|
+
if (model) {
|
|
115
|
+
cfg['model'] = model;
|
|
116
|
+
}
|
|
117
|
+
if (!cfg['permission']) {
|
|
118
|
+
cfg['permission'] = { '*': 'allow' };
|
|
119
|
+
} // empty client caps → opencode does its own I/O
|
|
120
|
+
const dir = path.join(root, '.autodev');
|
|
121
|
+
if (!fs.existsSync(dir)) {
|
|
122
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
123
|
+
}
|
|
124
|
+
const out = path.join(dir, 'opencode-acp.json');
|
|
125
|
+
fs.writeFileSync(out, JSON.stringify(cfg, null, 2), 'utf8');
|
|
126
|
+
return out;
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
return undefined;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
// --- persistent state (one AcpSession per root) ---------------------------
|
|
133
|
+
const _acpSessions = new Map();
|
|
134
|
+
/** Roots with an opencode ACP turn dispatched (busy synchronously from dispatch
|
|
135
|
+
* through full drain — covers the window before AcpSession.runTurn sets busy). */
|
|
136
|
+
const _acpBusyRoots = new Set();
|
|
137
|
+
const _latestSessionIds = new Map();
|
|
138
|
+
// --- availability gate ----------------------------------------------------
|
|
139
|
+
let _opencodeAcpSupported = null;
|
|
140
|
+
/** Cached probe: is `opencode acp` a real subcommand? (opencode prints its help
|
|
141
|
+
* to STDERR, so we merge 2>&1 and look for the ACP banner.) */
|
|
142
|
+
function opencodeAcpSupported() {
|
|
143
|
+
if (_opencodeAcpSupported !== null) {
|
|
144
|
+
return _opencodeAcpSupported;
|
|
145
|
+
}
|
|
146
|
+
try {
|
|
147
|
+
const out = child_process.execSync(`${OPENCODE_BIN} acp --help 2>&1`, { encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'], timeout: 10000 });
|
|
148
|
+
_opencodeAcpSupported = /Agent Client Protocol|\bACP\b/i.test(out);
|
|
149
|
+
}
|
|
150
|
+
catch {
|
|
151
|
+
_opencodeAcpSupported = false;
|
|
152
|
+
}
|
|
153
|
+
return _opencodeAcpSupported;
|
|
154
|
+
}
|
|
155
|
+
let _opencodeAcpTestOverride = null;
|
|
156
|
+
/** Test-only: force the ACP enablement decision. */
|
|
157
|
+
function __setOpencodeAcpEnabledForTest(v) { _opencodeAcpTestOverride = v; }
|
|
158
|
+
/**
|
|
159
|
+
* Whether opencode should run over native ACP instead of the createOpencode
|
|
160
|
+
* server. Gated by AUTODEV_OPENCODE_ACP (false/0/off/no forces the server path)
|
|
161
|
+
* AND `opencode acp` being available. Default ON when available.
|
|
162
|
+
*/
|
|
163
|
+
function opencodeAcpEnabled(env = process.env) {
|
|
164
|
+
if (_opencodeAcpTestOverride !== null) {
|
|
165
|
+
return _opencodeAcpTestOverride;
|
|
166
|
+
}
|
|
167
|
+
const raw = String(env['AUTODEV_OPENCODE_ACP'] ?? '').toLowerCase();
|
|
168
|
+
if (raw === 'false' || raw === '0' || raw === 'off' || raw === 'no') {
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
return opencodeAcpSupported();
|
|
172
|
+
}
|
|
173
|
+
// --- canonical hook emission (parity with grok ACP + the opencode-sdk sink) --
|
|
174
|
+
function _emitOpencodeHook(root, hookEventName, extra = {}) {
|
|
175
|
+
try {
|
|
176
|
+
const dir = path.join(root, '.autodev');
|
|
177
|
+
if (!fs.existsSync(dir)) {
|
|
178
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
179
|
+
}
|
|
180
|
+
const ev = { hook_event_name: hookEventName, event_type: (0, ProviderNormalizer_1.eventTypeFor)(hookEventName), provider: 'opencode-sdk', cwd: root, timestamp: new Date().toISOString(), ...extra };
|
|
181
|
+
fs.appendFileSync(path.join(dir, 'hooks-events.jsonl'), JSON.stringify(ev) + '\n', 'utf8');
|
|
182
|
+
}
|
|
183
|
+
catch { /* non-critical */ }
|
|
184
|
+
}
|
|
185
|
+
/** Get (or lazily create) the persistent opencode ACP session for a root. */
|
|
186
|
+
function _getOrCreate(root, model, log, resumeSessionId) {
|
|
187
|
+
let sess = _acpSessions.get(root);
|
|
188
|
+
if (sess) {
|
|
189
|
+
return sess;
|
|
190
|
+
}
|
|
191
|
+
const seedId = resumeSessionId || _latestSessionIds.get(root) || undefined;
|
|
192
|
+
const hooks = {
|
|
193
|
+
emitHook: (name, e) => {
|
|
194
|
+
if (name === 'Notification' && typeof e['message'] === 'string') {
|
|
195
|
+
const msg = (0, redactSecrets_1.redactSecrets)(String(e['message'])).slice(0, 1200);
|
|
196
|
+
if (!msg.trim()) {
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
_emitOpencodeHook(root, 'Notification', { ...e, message: msg });
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
_emitOpencodeHook(root, name, (0, redactSecrets_1.redactDeep)(e));
|
|
203
|
+
}
|
|
204
|
+
},
|
|
205
|
+
log,
|
|
206
|
+
};
|
|
207
|
+
const cfgPath = _writeAcpConfig(root, model);
|
|
208
|
+
const extraEnv = cfgPath ? { OPENCODE_CONFIG: cfgPath } : {};
|
|
209
|
+
sess = new AcpSession_1.AcpSession({ root, model, bin: OPENCODE_BIN, hooks, spec: exports.OPENCODE_ACP_SPEC, initialSessionId: seedId, extraEnv });
|
|
210
|
+
_acpSessions.set(root, sess);
|
|
211
|
+
return sess;
|
|
212
|
+
}
|
|
213
|
+
/** True while an opencode ACP turn (incl. steered continuations) is running. */
|
|
214
|
+
function isOpencodeAcpBusy(root) {
|
|
215
|
+
if (_acpBusyRoots.has(root)) {
|
|
216
|
+
return true;
|
|
217
|
+
}
|
|
218
|
+
const s = _acpSessions.get(root);
|
|
219
|
+
return !!s && s.isBusy();
|
|
220
|
+
}
|
|
221
|
+
/** Current tool activity label for the root (undefined = idle). */
|
|
222
|
+
function getOpencodeAcpActivity(root) {
|
|
223
|
+
return _acpSessions.get(root)?.activity;
|
|
224
|
+
}
|
|
225
|
+
/** Latest opencode ACP session id (for resume-on-restart / session save). */
|
|
226
|
+
function getOpencodeAcpLatestSessionId(root) {
|
|
227
|
+
return _acpSessions.get(root)?.sessionId ?? _latestSessionIds.get(root);
|
|
228
|
+
}
|
|
229
|
+
/** Is an opencode ACP session currently held for this root? */
|
|
230
|
+
function hasOpencodeAcpSession(root) {
|
|
231
|
+
return _acpSessions.has(root);
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Run ONE turn through the persistent opencode ACP session. Mirrors the SDK
|
|
235
|
+
* path's stdout/exit contract. On ACP startup failure, calls `onAcpUnavailable`
|
|
236
|
+
* (the createOpencode-server fallback) and does NOT write the exit file itself.
|
|
237
|
+
*/
|
|
238
|
+
function sendOpencodeAcpPrompt(root, promptFilePath, resumeSessionId, stdoutFile, exitFile, log, model, showOutput, onAcpUnavailable) {
|
|
239
|
+
try {
|
|
240
|
+
fs.writeFileSync(stdoutFile, '', 'utf8');
|
|
241
|
+
}
|
|
242
|
+
catch { /* ignore */ }
|
|
243
|
+
try {
|
|
244
|
+
fs.writeFileSync(exitFile, '', 'utf8');
|
|
245
|
+
}
|
|
246
|
+
catch { /* ignore */ }
|
|
247
|
+
let promptText = '';
|
|
248
|
+
try {
|
|
249
|
+
promptText = fs.readFileSync(promptFilePath, 'utf8');
|
|
250
|
+
}
|
|
251
|
+
catch (err) {
|
|
252
|
+
try {
|
|
253
|
+
fs.appendFileSync(stdoutFile, `\n[OpenCode ACP: cannot read prompt file: ${err?.message ?? err}]\n`, 'utf8');
|
|
254
|
+
}
|
|
255
|
+
catch { /* ignore */ }
|
|
256
|
+
try {
|
|
257
|
+
fs.writeFileSync(exitFile, '1\n', 'utf8');
|
|
258
|
+
}
|
|
259
|
+
catch { /* ignore */ }
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
const sess = _getOrCreate(root, model, log, resumeSessionId);
|
|
263
|
+
_acpBusyRoots.add(root); // synchronous busy (before runTurn flips its own flag)
|
|
264
|
+
if (showOutput) {
|
|
265
|
+
try {
|
|
266
|
+
showOutput();
|
|
267
|
+
}
|
|
268
|
+
catch { /* ignore */ }
|
|
269
|
+
}
|
|
270
|
+
const sink = (text) => { try {
|
|
271
|
+
fs.appendFileSync(stdoutFile, text, 'utf8');
|
|
272
|
+
}
|
|
273
|
+
catch { /* ignore */ } };
|
|
274
|
+
void (async () => {
|
|
275
|
+
try {
|
|
276
|
+
await sess.ensureReady();
|
|
277
|
+
}
|
|
278
|
+
catch (err) {
|
|
279
|
+
log(`OpenCode ACP: startup failed (${err?.message ?? err}); stderr="${sess.stderrSnapshot.slice(0, 200)}" — falling back to createOpencode server`);
|
|
280
|
+
try {
|
|
281
|
+
sess.close();
|
|
282
|
+
}
|
|
283
|
+
catch { /* ignore */ }
|
|
284
|
+
_acpSessions.delete(root);
|
|
285
|
+
_acpBusyRoots.delete(root); // hand the busy flag over to the server path
|
|
286
|
+
onAcpUnavailable();
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
if (sess.sessionId) {
|
|
290
|
+
_latestSessionIds.set(root, sess.sessionId);
|
|
291
|
+
}
|
|
292
|
+
let res;
|
|
293
|
+
try {
|
|
294
|
+
res = await sess.runTurn(promptText, sink);
|
|
295
|
+
}
|
|
296
|
+
catch (err) {
|
|
297
|
+
res = { clean: false, stopReason: 'exception', error: err?.message ?? String(err) };
|
|
298
|
+
}
|
|
299
|
+
if (res.emptyOutput) {
|
|
300
|
+
log(`OpenCode ACP: turn produced NO output (stopReason=${res.stopReason}). The model "${model ?? '(default)'}" may be an unusable free zen model or misconfigured — set a real model (e.g. ollama-cloud/gpt-oss:20b or a configured provider) in the agent settings.`);
|
|
301
|
+
try {
|
|
302
|
+
fs.appendFileSync(stdoutFile, `\n[OpenCode ACP: empty turn — check the configured model "${model ?? '(default)'}"]\n`, 'utf8');
|
|
303
|
+
}
|
|
304
|
+
catch { /* ignore */ }
|
|
305
|
+
}
|
|
306
|
+
if (!res.clean && res.error) {
|
|
307
|
+
try {
|
|
308
|
+
fs.appendFileSync(stdoutFile, `\n[OpenCode ACP: turn ended ${res.stopReason} — ${res.error}]\n`, 'utf8');
|
|
309
|
+
}
|
|
310
|
+
catch { /* ignore */ }
|
|
311
|
+
}
|
|
312
|
+
try {
|
|
313
|
+
fs.writeFileSync(exitFile, `${res.clean ? 0 : 1}\n`, 'utf8');
|
|
314
|
+
}
|
|
315
|
+
catch { /* ignore */ }
|
|
316
|
+
_acpBusyRoots.delete(root);
|
|
317
|
+
})();
|
|
318
|
+
}
|
|
319
|
+
/** Steer the live opencode ACP process mid-turn (a queued session/prompt). */
|
|
320
|
+
function steerOpencodeAcp(root, text, log) {
|
|
321
|
+
const sess = _acpSessions.get(root);
|
|
322
|
+
if (!sess || !sess.isAlive()) {
|
|
323
|
+
return false;
|
|
324
|
+
}
|
|
325
|
+
const ok = sess.steer(text);
|
|
326
|
+
if (ok) {
|
|
327
|
+
log(`OpenCode ACP: steered live process (${text.length} chars) — queued to the running session`);
|
|
328
|
+
}
|
|
329
|
+
return ok;
|
|
330
|
+
}
|
|
331
|
+
/** Best-effort /compact on the live opencode ACP session (quiet, no Stop hook). */
|
|
332
|
+
async function compactOpencodeAcp(root, log) {
|
|
333
|
+
const sess = _acpSessions.get(root);
|
|
334
|
+
if (!sess) {
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
log('OpenCode ACP: requesting /compact');
|
|
338
|
+
await sess.sendQuiet('/compact');
|
|
339
|
+
}
|
|
340
|
+
/** Force-clear busy + evict the ACP session for a root. */
|
|
341
|
+
function forceIdleOpencodeAcp(root) {
|
|
342
|
+
_acpBusyRoots.delete(root);
|
|
343
|
+
const sess = _acpSessions.get(root);
|
|
344
|
+
if (sess) {
|
|
345
|
+
if (sess.pid) {
|
|
346
|
+
try {
|
|
347
|
+
child_process.spawn('kill', ['-9', String(sess.pid)]);
|
|
348
|
+
}
|
|
349
|
+
catch { /* ignore */ }
|
|
350
|
+
}
|
|
351
|
+
try {
|
|
352
|
+
sess.close();
|
|
353
|
+
}
|
|
354
|
+
catch { /* ignore */ }
|
|
355
|
+
_acpSessions.delete(root);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
/** Close + evict the opencode ACP session for a root (preserves session id). */
|
|
359
|
+
function closeOpencodeAcp(root, log) {
|
|
360
|
+
const sess = _acpSessions.get(root);
|
|
361
|
+
if (sess) {
|
|
362
|
+
log('OpenCode ACP: closing persistent session');
|
|
363
|
+
try {
|
|
364
|
+
sess.close();
|
|
365
|
+
}
|
|
366
|
+
catch { /* ignore */ }
|
|
367
|
+
_acpSessions.delete(root);
|
|
368
|
+
}
|
|
369
|
+
_acpBusyRoots.delete(root);
|
|
370
|
+
}
|
|
371
|
+
/** Close all opencode ACP sessions — extension deactivate. */
|
|
372
|
+
function closeAllOpencodeAcp() {
|
|
373
|
+
for (const [, sess] of _acpSessions) {
|
|
374
|
+
try {
|
|
375
|
+
sess.close();
|
|
376
|
+
}
|
|
377
|
+
catch { /* ignore */ }
|
|
378
|
+
}
|
|
379
|
+
_acpSessions.clear();
|
|
380
|
+
_acpBusyRoots.clear();
|
|
381
|
+
}
|
|
382
|
+
//# sourceMappingURL=acp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"acp.js","sourceRoot":"","sources":["../../../src/providers/opencode/acp.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** True while an opencode
|
|
1
|
+
/** True while an opencode turn is running (ACP session OR createOpencode server). */
|
|
2
2
|
export declare function isOpencodeSdkBusy(root: string): boolean;
|
|
3
3
|
/** Current tool activity label for the given root (undefined = idle). */
|
|
4
4
|
export declare function getOpencodeSdkActivity(root: string): string | undefined;
|
|
@@ -17,13 +17,14 @@ export declare function opencodeSdkTransportAvailable(): boolean;
|
|
|
17
17
|
/** Test-only: force the persistence decision regardless of env/transport. */
|
|
18
18
|
export declare function __setOpencodeCliPersistentForTest(v: boolean | null): void;
|
|
19
19
|
export declare function opencodeCliPersistentEnabled(env?: NodeJS.ProcessEnv): boolean;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
20
|
+
/**
|
|
21
|
+
* Router: prefer native `opencode acp` (persistent AcpSession) when enabled;
|
|
22
|
+
* otherwise use the createOpencode in-process server. On ACP startup failure the
|
|
23
|
+
* ACP layer transparently falls back to the server path (onAcpUnavailable), so
|
|
24
|
+
* nothing regresses. Both paths are "SDK-like" to the task loop (persistent,
|
|
25
|
+
* turn-end via isOpencodeSdkBusy) so no loop change is needed.
|
|
26
|
+
*/
|
|
27
|
+
export declare function sendOpencodeSdkPrompt(root: string, promptFilePath: string, resumeSessionId: string | undefined, stdoutFile: string, exitFile: string, log: (msg: string) => void, model?: string, showOutput?: () => void): void;
|
|
27
28
|
export declare function runOpencodeSdkCompact(root: string, log: (msg: string) => void): Promise<void>;
|
|
28
29
|
export declare function closeOpencodeSdkClient(root: string, log: (msg: string) => void): void;
|
|
29
30
|
/**
|
|
@@ -62,6 +62,7 @@ const net = __importStar(require("net"));
|
|
|
62
62
|
const url_1 = require("url");
|
|
63
63
|
const hookEventNormalizer_1 = require("../../hookEventNormalizer");
|
|
64
64
|
const liveNarration_1 = require("../../core/liveNarration");
|
|
65
|
+
const acp_1 = require("./acp");
|
|
65
66
|
const _state = new Map();
|
|
66
67
|
const _latestSessionIds = new Map();
|
|
67
68
|
/** Latest log function per root — updated every dispatch so the background logger always writes to the active channel. */
|
|
@@ -70,16 +71,16 @@ const _loggers = new Map();
|
|
|
70
71
|
const _activity = new Map();
|
|
71
72
|
/** Roots that currently have an opencode-sdk turn actively running. */
|
|
72
73
|
const _busyRoots = new Set();
|
|
73
|
-
/** True while an opencode
|
|
74
|
+
/** True while an opencode turn is running (ACP session OR createOpencode server). */
|
|
74
75
|
function isOpencodeSdkBusy(root) {
|
|
75
|
-
return _busyRoots.has(root);
|
|
76
|
+
return _busyRoots.has(root) || (0, acp_1.isOpencodeAcpBusy)(root);
|
|
76
77
|
}
|
|
77
78
|
/** Current tool activity label for the given root (undefined = idle). */
|
|
78
79
|
function getOpencodeSdkActivity(root) {
|
|
79
|
-
return _activity.get(root);
|
|
80
|
+
return (0, acp_1.getOpencodeAcpActivity)(root) ?? _activity.get(root);
|
|
80
81
|
}
|
|
81
82
|
function getOpencodeSdkLatestSessionId(root) {
|
|
82
|
-
return _latestSessionIds.get(root) ?? _state.get(root)?.sessionId;
|
|
83
|
+
return (0, acp_1.getOpencodeAcpLatestSessionId)(root) ?? _latestSessionIds.get(root) ?? _state.get(root)?.sessionId;
|
|
83
84
|
}
|
|
84
85
|
/**
|
|
85
86
|
* Steer the live OpenCode SDK session MID-TURN. Unlike opencode-cli / grok /
|
|
@@ -91,6 +92,10 @@ function getOpencodeSdkLatestSessionId(root) {
|
|
|
91
92
|
* the durable TODO queue (at-least-once delivery preserved).
|
|
92
93
|
*/
|
|
93
94
|
async function steerOpencodeSdk(root, text, log) {
|
|
95
|
+
// Native-ACP path: a queued session/prompt to the live opencode acp process.
|
|
96
|
+
if ((0, acp_1.hasOpencodeAcpSession)(root)) {
|
|
97
|
+
return (0, acp_1.steerOpencodeAcp)(root, text, log);
|
|
98
|
+
}
|
|
94
99
|
const st = _state.get(root);
|
|
95
100
|
if (!st || !_busyRoots.has(root)) {
|
|
96
101
|
return false;
|
|
@@ -449,7 +454,21 @@ function _evictClient(root) {
|
|
|
449
454
|
// persistent SDK session, streams output to stdoutFile + log(), writes the
|
|
450
455
|
// exit code to exitFile once session.idle fires.
|
|
451
456
|
// ---------------------------------------------------------------------------
|
|
452
|
-
|
|
457
|
+
/**
|
|
458
|
+
* Router: prefer native `opencode acp` (persistent AcpSession) when enabled;
|
|
459
|
+
* otherwise use the createOpencode in-process server. On ACP startup failure the
|
|
460
|
+
* ACP layer transparently falls back to the server path (onAcpUnavailable), so
|
|
461
|
+
* nothing regresses. Both paths are "SDK-like" to the task loop (persistent,
|
|
462
|
+
* turn-end via isOpencodeSdkBusy) so no loop change is needed.
|
|
463
|
+
*/
|
|
464
|
+
function sendOpencodeSdkPrompt(root, promptFilePath, resumeSessionId, stdoutFile, exitFile, log, model, showOutput) {
|
|
465
|
+
if ((0, acp_1.opencodeAcpEnabled)()) {
|
|
466
|
+
(0, acp_1.sendOpencodeAcpPrompt)(root, promptFilePath, resumeSessionId, stdoutFile, exitFile, log, model, showOutput, () => _sendOpencodeSdkServerPrompt(root, promptFilePath, resumeSessionId, stdoutFile, exitFile, log, model, showOutput));
|
|
467
|
+
return;
|
|
468
|
+
}
|
|
469
|
+
_sendOpencodeSdkServerPrompt(root, promptFilePath, resumeSessionId, stdoutFile, exitFile, log, model, showOutput);
|
|
470
|
+
}
|
|
471
|
+
function _sendOpencodeSdkServerPrompt(root,
|
|
453
472
|
/** Absolute path to the combined agent-profile + message file. */
|
|
454
473
|
promptFilePath, resumeSessionId, stdoutFile, exitFile, log,
|
|
455
474
|
/** Optional model string "providerID/modelID" */
|
|
@@ -598,6 +617,9 @@ showOutput) {
|
|
|
598
617
|
// Compact (summarise) the active session to free context window space.
|
|
599
618
|
// ---------------------------------------------------------------------------
|
|
600
619
|
function runOpencodeSdkCompact(root, log) {
|
|
620
|
+
if ((0, acp_1.hasOpencodeAcpSession)(root)) {
|
|
621
|
+
return (0, acp_1.compactOpencodeAcp)(root, log);
|
|
622
|
+
}
|
|
601
623
|
return new Promise((resolve) => {
|
|
602
624
|
const s = _state.get(root);
|
|
603
625
|
if (!s) {
|
|
@@ -616,6 +638,7 @@ function runOpencodeSdkCompact(root, log) {
|
|
|
616
638
|
// Shutdown — cleanly close the server when the task loop stops.
|
|
617
639
|
// ---------------------------------------------------------------------------
|
|
618
640
|
function closeOpencodeSdkClient(root, log) {
|
|
641
|
+
(0, acp_1.closeOpencodeAcp)(root, log);
|
|
619
642
|
const s = _state.get(root);
|
|
620
643
|
if (s) {
|
|
621
644
|
log('OpenCode SDK: closing persistent session + server');
|
|
@@ -639,10 +662,12 @@ function closeOpencodeSdkClient(root, log) {
|
|
|
639
662
|
function forceIdleOpencodeSdk(root) {
|
|
640
663
|
_busyRoots.delete(root);
|
|
641
664
|
_activity.delete(root);
|
|
665
|
+
(0, acp_1.forceIdleOpencodeAcp)(root);
|
|
642
666
|
_evictClient(root);
|
|
643
667
|
}
|
|
644
668
|
/** Close all open SDK servers — called on extension deactivate to avoid orphaned processes. */
|
|
645
669
|
function closeAllOpencodeSdkClients() {
|
|
670
|
+
(0, acp_1.closeAllOpencodeAcp)();
|
|
646
671
|
for (const [root, s] of _state) {
|
|
647
672
|
try {
|
|
648
673
|
s.server.close();
|