opencode-tbot 0.1.25 → 0.1.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ja.md +5 -0
- package/README.md +9 -0
- package/README.zh-CN.md +5 -0
- package/dist/assets/{plugin-config-CCeFjxSf.js → plugin-config-DNeV2Ckw.js} +20 -1
- package/dist/assets/plugin-config-DNeV2Ckw.js.map +1 -0
- package/dist/cli.js +1 -1
- package/dist/index.js +1 -1
- package/dist/plugin.js +330 -129
- package/dist/plugin.js.map +1 -1
- package/package.json +1 -1
- package/dist/assets/plugin-config-CCeFjxSf.js.map +0 -1
package/dist/plugin.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as loadAppConfig, i as preparePluginConfiguration, o as OPENCODE_TBOT_VERSION } from "./assets/plugin-config-
|
|
1
|
+
import { c as loadAppConfig, i as preparePluginConfiguration, o as OPENCODE_TBOT_VERSION } from "./assets/plugin-config-DNeV2Ckw.js";
|
|
2
2
|
import { mkdir, readFile, rename, stat, writeFile } from "node:fs/promises";
|
|
3
3
|
import { dirname, isAbsolute, join } from "node:path";
|
|
4
4
|
import { parse, printParseErrorCode } from "jsonc-parser";
|
|
@@ -227,11 +227,13 @@ var PROMPT_MESSAGE_POLL_INITIAL_DELAYS_MS = [
|
|
|
227
227
|
1e3
|
|
228
228
|
];
|
|
229
229
|
var PROMPT_MESSAGE_POLL_INTERVAL_MS = 2e3;
|
|
230
|
-
var PROMPT_POLL_REQUEST_TIMEOUT_MS = 15e3;
|
|
231
|
-
var PROMPT_SEND_TIMEOUT_MS = 3e4;
|
|
232
|
-
var PROMPT_MESSAGE_POLL_TIMEOUT_MS = 6e4;
|
|
233
230
|
var PROMPT_MESSAGE_POLL_LIMIT = 20;
|
|
234
231
|
var PROMPT_LOG_SERVICE = "opencode-tbot";
|
|
232
|
+
var DEFAULT_OPENCODE_PROMPT_TIMEOUT_POLICY = {
|
|
233
|
+
pollRequestTimeoutMs: 15e3,
|
|
234
|
+
recoveryInactivityTimeoutMs: 12e4,
|
|
235
|
+
waitTimeoutMs: 18e5
|
|
236
|
+
};
|
|
235
237
|
var STRUCTURED_REPLY_SCHEMA = {
|
|
236
238
|
type: "json_schema",
|
|
237
239
|
retryCount: 2,
|
|
@@ -253,20 +255,39 @@ var StructuredReplySchema = z.object({ body_md: z.string() });
|
|
|
253
255
|
var OpenCodeClient = class {
|
|
254
256
|
client;
|
|
255
257
|
fetchFn;
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
sendMs: PROMPT_SEND_TIMEOUT_MS,
|
|
259
|
-
totalPollMs: PROMPT_MESSAGE_POLL_TIMEOUT_MS
|
|
260
|
-
};
|
|
258
|
+
sdkFlavor;
|
|
259
|
+
promptTimeoutPolicy;
|
|
261
260
|
modelCache = {
|
|
262
261
|
expiresAt: 0,
|
|
263
262
|
promise: null,
|
|
264
263
|
value: null
|
|
265
264
|
};
|
|
266
|
-
constructor(options, client, fetchFn = fetch) {
|
|
265
|
+
constructor(options, client, fetchFn = fetch, promptTimeoutPolicy = {}) {
|
|
267
266
|
if (!options && !client) throw new Error("OpenCodeClient requires either base URL options or an injected SDK client.");
|
|
268
267
|
this.client = client ?? createOpencodeClient(buildOpenCodeSdkConfig(options));
|
|
269
268
|
this.fetchFn = fetchFn;
|
|
269
|
+
this.sdkFlavor = detectSdkFlavor(this.client);
|
|
270
|
+
this.promptTimeoutPolicy = resolvePromptTimeoutPolicy(promptTimeoutPolicy);
|
|
271
|
+
}
|
|
272
|
+
configurePromptTimeoutPolicy(promptTimeoutPolicy) {
|
|
273
|
+
this.promptTimeoutPolicy = resolvePromptTimeoutPolicy({
|
|
274
|
+
...this.promptTimeoutPolicy,
|
|
275
|
+
...promptTimeoutPolicy
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
async callScopedSdkMethod(scope, method, input) {
|
|
279
|
+
const target = this.client[scope];
|
|
280
|
+
const handler = target?.[method];
|
|
281
|
+
if (typeof handler !== "function") throw new Error(`OpenCode SDK client does not expose a compatible ${scope}.${method} method.`);
|
|
282
|
+
if (this.sdkFlavor === "legacy") return unwrapSdkData(await handler.call(target, {
|
|
283
|
+
...SDK_OPTIONS,
|
|
284
|
+
...input.signal ? { signal: input.signal } : {},
|
|
285
|
+
...input.legacyOptions ?? {}
|
|
286
|
+
}));
|
|
287
|
+
return unwrapSdkData(await handler.call(target, input.v2Parameters, {
|
|
288
|
+
...SDK_OPTIONS,
|
|
289
|
+
...input.signal ? { signal: input.signal } : {}
|
|
290
|
+
}));
|
|
270
291
|
}
|
|
271
292
|
async getHealth() {
|
|
272
293
|
const rawClient = getRawSdkClient(this.client);
|
|
@@ -277,62 +298,70 @@ var OpenCodeClient = class {
|
|
|
277
298
|
return this.requestRaw("get", { url: "/global/health" });
|
|
278
299
|
}
|
|
279
300
|
async abortSession(sessionId) {
|
|
280
|
-
if (hasRawSdkMethod(this.client, "post")) return this.requestRaw("post",
|
|
281
|
-
|
|
282
|
-
path: {
|
|
301
|
+
if (hasRawSdkMethod(this.client, "post")) return this.requestRaw("post", buildRawSessionRequest(this.sdkFlavor, sessionId, "/abort"));
|
|
302
|
+
return this.callScopedSdkMethod("session", "abort", {
|
|
303
|
+
legacyOptions: { path: { id: sessionId } },
|
|
304
|
+
v2Parameters: { sessionID: sessionId }
|
|
283
305
|
});
|
|
284
|
-
return unwrapSdkData(await this.client.session.abort({ sessionID: sessionId }, SDK_OPTIONS));
|
|
285
306
|
}
|
|
286
307
|
async deleteSession(sessionId) {
|
|
287
|
-
if (hasRawSdkMethod(this.client, "delete")) return this.requestRaw("delete",
|
|
288
|
-
|
|
289
|
-
path: {
|
|
308
|
+
if (hasRawSdkMethod(this.client, "delete")) return this.requestRaw("delete", buildRawSessionRequest(this.sdkFlavor, sessionId));
|
|
309
|
+
return this.callScopedSdkMethod("session", "delete", {
|
|
310
|
+
legacyOptions: { path: { id: sessionId } },
|
|
311
|
+
v2Parameters: { sessionID: sessionId }
|
|
290
312
|
});
|
|
291
|
-
return unwrapSdkData(await this.client.session.delete({ sessionID: sessionId }, SDK_OPTIONS));
|
|
292
313
|
}
|
|
293
314
|
async forkSession(sessionId, messageId) {
|
|
294
|
-
if (hasRawSdkMethod(this.client, "post")) return this.requestRaw("post", {
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
315
|
+
if (hasRawSdkMethod(this.client, "post")) return this.requestRaw("post", buildRawSessionRequest(this.sdkFlavor, sessionId, "/fork", messageId?.trim() ? { body: { messageID: messageId.trim() } } : {}));
|
|
316
|
+
return this.callScopedSdkMethod("session", "fork", {
|
|
317
|
+
legacyOptions: {
|
|
318
|
+
path: { id: sessionId },
|
|
319
|
+
...messageId?.trim() ? { body: { messageID: messageId.trim() } } : {}
|
|
320
|
+
},
|
|
321
|
+
v2Parameters: {
|
|
322
|
+
sessionID: sessionId,
|
|
323
|
+
...messageId?.trim() ? { messageID: messageId.trim() } : {}
|
|
324
|
+
}
|
|
298
325
|
});
|
|
299
|
-
return unwrapSdkData(await this.client.session.fork({
|
|
300
|
-
sessionID: sessionId,
|
|
301
|
-
...messageId?.trim() ? { messageID: messageId.trim() } : {}
|
|
302
|
-
}, SDK_OPTIONS));
|
|
303
326
|
}
|
|
304
327
|
async getPath() {
|
|
305
328
|
if (hasRawSdkMethod(this.client, "get")) return this.requestRaw("get", { url: "/path" });
|
|
306
|
-
return
|
|
329
|
+
return this.callScopedSdkMethod("path", "get", {});
|
|
307
330
|
}
|
|
308
331
|
async listLspStatuses(directory) {
|
|
309
332
|
if (hasRawSdkMethod(this.client, "get")) return this.requestRaw("get", {
|
|
310
333
|
url: "/lsp",
|
|
311
334
|
...directory ? { query: { directory } } : {}
|
|
312
335
|
});
|
|
313
|
-
return
|
|
336
|
+
return this.callScopedSdkMethod("lsp", "status", {
|
|
337
|
+
legacyOptions: directory ? { query: { directory } } : void 0,
|
|
338
|
+
v2Parameters: directory ? { directory } : void 0
|
|
339
|
+
});
|
|
314
340
|
}
|
|
315
341
|
async listMcpStatuses(directory) {
|
|
316
342
|
if (hasRawSdkMethod(this.client, "get")) return this.requestRaw("get", {
|
|
317
343
|
url: "/mcp",
|
|
318
344
|
...directory ? { query: { directory } } : {}
|
|
319
345
|
});
|
|
320
|
-
return
|
|
346
|
+
return this.callScopedSdkMethod("mcp", "status", {
|
|
347
|
+
legacyOptions: directory ? { query: { directory } } : void 0,
|
|
348
|
+
v2Parameters: directory ? { directory } : void 0
|
|
349
|
+
});
|
|
321
350
|
}
|
|
322
351
|
async getSessionStatuses() {
|
|
323
352
|
return this.loadSessionStatuses();
|
|
324
353
|
}
|
|
325
354
|
async listProjects() {
|
|
326
355
|
if (hasRawSdkMethod(this.client, "get")) return this.requestRaw("get", { url: "/project" });
|
|
327
|
-
return
|
|
356
|
+
return this.callScopedSdkMethod("project", "list", {});
|
|
328
357
|
}
|
|
329
358
|
async listSessions() {
|
|
330
359
|
if (hasRawSdkMethod(this.client, "get")) return this.requestRaw("get", { url: "/session" });
|
|
331
|
-
return
|
|
360
|
+
return this.callScopedSdkMethod("session", "list", {});
|
|
332
361
|
}
|
|
333
362
|
async getCurrentProject() {
|
|
334
363
|
if (hasRawSdkMethod(this.client, "get")) return this.requestRaw("get", { url: "/project/current" });
|
|
335
|
-
return
|
|
364
|
+
return this.callScopedSdkMethod("project", "current", {});
|
|
336
365
|
}
|
|
337
366
|
async createSessionForDirectory(directory, title) {
|
|
338
367
|
if (hasRawSdkMethod(this.client, "post")) return this.requestRaw("post", {
|
|
@@ -340,34 +369,57 @@ var OpenCodeClient = class {
|
|
|
340
369
|
query: { directory },
|
|
341
370
|
...title ? { body: { title } } : {}
|
|
342
371
|
});
|
|
343
|
-
return
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
372
|
+
return this.callScopedSdkMethod("session", "create", {
|
|
373
|
+
legacyOptions: {
|
|
374
|
+
query: { directory },
|
|
375
|
+
...title ? { body: { title } } : {}
|
|
376
|
+
},
|
|
377
|
+
v2Parameters: title ? {
|
|
378
|
+
directory,
|
|
379
|
+
title
|
|
380
|
+
} : { directory }
|
|
381
|
+
});
|
|
347
382
|
}
|
|
348
383
|
async renameSession(sessionId, title) {
|
|
349
|
-
if (hasRawSdkMethod(this.client, "patch")) return this.requestRaw("patch", {
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
384
|
+
if (hasRawSdkMethod(this.client, "patch")) return this.requestRaw("patch", buildRawSessionRequest(this.sdkFlavor, sessionId, "", { body: { title } }));
|
|
385
|
+
return this.callScopedSdkMethod("session", "update", {
|
|
386
|
+
legacyOptions: {
|
|
387
|
+
path: { id: sessionId },
|
|
388
|
+
body: { title }
|
|
389
|
+
},
|
|
390
|
+
v2Parameters: {
|
|
391
|
+
sessionID: sessionId,
|
|
392
|
+
title
|
|
393
|
+
}
|
|
353
394
|
});
|
|
354
|
-
return unwrapSdkData(await this.client.session.update({
|
|
355
|
-
sessionID: sessionId,
|
|
356
|
-
title
|
|
357
|
-
}, SDK_OPTIONS));
|
|
358
395
|
}
|
|
359
396
|
async listAgents() {
|
|
360
397
|
if (hasRawSdkMethod(this.client, "get")) return this.requestRaw("get", { url: "/agent" });
|
|
361
|
-
return
|
|
398
|
+
return this.callScopedSdkMethod("app", "agents", {});
|
|
362
399
|
}
|
|
363
400
|
async listPendingPermissions(directory) {
|
|
364
|
-
if (hasRawSdkMethod(this.client, "get")) return this.requestRaw("get", {
|
|
401
|
+
if (this.sdkFlavor === "v2" && hasRawSdkMethod(this.client, "get")) return this.requestRaw("get", {
|
|
365
402
|
url: "/permission",
|
|
366
403
|
...directory ? { query: { directory } } : {}
|
|
367
404
|
});
|
|
368
|
-
return
|
|
405
|
+
return this.callScopedSdkMethod("permission", "list", {
|
|
406
|
+
legacyOptions: directory ? { query: { directory } } : void 0,
|
|
407
|
+
v2Parameters: directory ? { directory } : void 0
|
|
408
|
+
});
|
|
369
409
|
}
|
|
370
|
-
async replyToPermission(requestId, reply, message) {
|
|
410
|
+
async replyToPermission(requestId, reply, message, sessionId) {
|
|
411
|
+
if (this.sdkFlavor === "legacy" && sessionId) {
|
|
412
|
+
if (hasRawSdkMethod(this.client, "post")) return this.requestRaw("post", buildRawLegacyPermissionReplyRequest(sessionId, requestId, reply));
|
|
413
|
+
const legacyClient = this.client;
|
|
414
|
+
if (typeof legacyClient.postSessionIdPermissionsPermissionId === "function") return unwrapSdkData(await legacyClient.postSessionIdPermissionsPermissionId({
|
|
415
|
+
...SDK_OPTIONS,
|
|
416
|
+
body: { response: reply },
|
|
417
|
+
path: {
|
|
418
|
+
id: sessionId,
|
|
419
|
+
permissionID: requestId
|
|
420
|
+
}
|
|
421
|
+
}));
|
|
422
|
+
}
|
|
371
423
|
if (hasRawSdkMethod(this.client, "post")) return this.requestRaw("post", {
|
|
372
424
|
url: "/permission/{requestID}/reply",
|
|
373
425
|
path: { requestID: requestId },
|
|
@@ -376,11 +428,20 @@ var OpenCodeClient = class {
|
|
|
376
428
|
...message?.trim() ? { message: message.trim() } : {}
|
|
377
429
|
}
|
|
378
430
|
});
|
|
379
|
-
return
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
431
|
+
return this.callScopedSdkMethod("permission", "reply", {
|
|
432
|
+
legacyOptions: sessionId ? {
|
|
433
|
+
body: { response: reply },
|
|
434
|
+
path: {
|
|
435
|
+
id: sessionId,
|
|
436
|
+
permissionID: requestId
|
|
437
|
+
}
|
|
438
|
+
} : void 0,
|
|
439
|
+
v2Parameters: {
|
|
440
|
+
requestID: requestId,
|
|
441
|
+
reply,
|
|
442
|
+
...message?.trim() ? { message: message.trim() } : {}
|
|
443
|
+
}
|
|
444
|
+
});
|
|
384
445
|
}
|
|
385
446
|
async listModels() {
|
|
386
447
|
const now = Date.now();
|
|
@@ -416,7 +477,7 @@ var OpenCodeClient = class {
|
|
|
416
477
|
}
|
|
417
478
|
async resolvePromptResponse(input, data, knownMessageIds, startedAt) {
|
|
418
479
|
const structured = input.structured ?? false;
|
|
419
|
-
if (data &&
|
|
480
|
+
if (data && shouldReturnPromptResponseImmediately(data, structured)) return data;
|
|
420
481
|
const messageId = data ? extractMessageId(data.info) : null;
|
|
421
482
|
const candidateOptions = {
|
|
422
483
|
initialMessageId: messageId,
|
|
@@ -426,14 +487,18 @@ var OpenCodeClient = class {
|
|
|
426
487
|
structured
|
|
427
488
|
};
|
|
428
489
|
let bestCandidate = selectPromptResponseCandidate(data ? [data] : [], candidateOptions);
|
|
429
|
-
|
|
490
|
+
let lastProgressAt = Date.now();
|
|
491
|
+
const deadlineAt = startedAt + this.promptTimeoutPolicy.waitTimeoutMs;
|
|
430
492
|
let idleStatusSeen = false;
|
|
431
493
|
let attempt = 0;
|
|
432
494
|
while (true) {
|
|
495
|
+
const remainingWaitMs = deadlineAt - Date.now();
|
|
496
|
+
const remainingInactivityMs = this.promptTimeoutPolicy.recoveryInactivityTimeoutMs - (Date.now() - lastProgressAt);
|
|
497
|
+
if (remainingWaitMs <= 0 || remainingInactivityMs <= 0) break;
|
|
433
498
|
const delayMs = getPromptMessagePollDelayMs(attempt);
|
|
434
499
|
attempt += 1;
|
|
435
500
|
if (delayMs > 0) {
|
|
436
|
-
const remainingMs =
|
|
501
|
+
const remainingMs = Math.min(remainingWaitMs, remainingInactivityMs);
|
|
437
502
|
if (remainingMs <= 0) break;
|
|
438
503
|
await delay(Math.min(delayMs, remainingMs));
|
|
439
504
|
}
|
|
@@ -441,37 +506,59 @@ var OpenCodeClient = class {
|
|
|
441
506
|
const next = await this.fetchPromptMessage(input.sessionId, messageId);
|
|
442
507
|
if (next) {
|
|
443
508
|
const nextCandidate = selectPromptResponseCandidate([bestCandidate, next], candidateOptions);
|
|
444
|
-
if (nextCandidate)
|
|
445
|
-
|
|
509
|
+
if (nextCandidate) {
|
|
510
|
+
if (didPromptResponseAdvance(bestCandidate, nextCandidate, structured)) {
|
|
511
|
+
lastProgressAt = Date.now();
|
|
512
|
+
idleStatusSeen = false;
|
|
513
|
+
}
|
|
514
|
+
bestCandidate = nextCandidate;
|
|
515
|
+
}
|
|
516
|
+
if (bestCandidate && shouldReturnPromptResponseImmediately(bestCandidate, structured)) return bestCandidate;
|
|
446
517
|
}
|
|
447
518
|
}
|
|
448
519
|
const latest = await this.findLatestPromptResponse(input.sessionId, candidateOptions, "poll-messages");
|
|
449
520
|
if (latest) {
|
|
450
521
|
const nextCandidate = selectPromptResponseCandidate([bestCandidate, latest], candidateOptions);
|
|
451
|
-
if (nextCandidate)
|
|
452
|
-
|
|
522
|
+
if (nextCandidate) {
|
|
523
|
+
if (didPromptResponseAdvance(bestCandidate, nextCandidate, structured)) {
|
|
524
|
+
lastProgressAt = Date.now();
|
|
525
|
+
idleStatusSeen = false;
|
|
526
|
+
}
|
|
527
|
+
bestCandidate = nextCandidate;
|
|
528
|
+
}
|
|
529
|
+
if (bestCandidate && shouldReturnPromptResponseImmediately(bestCandidate, structured)) return bestCandidate;
|
|
453
530
|
}
|
|
454
|
-
|
|
531
|
+
const status = await this.fetchPromptSessionStatus(input.sessionId);
|
|
532
|
+
if (status?.type === "busy" || status?.type === "retry") {
|
|
533
|
+
lastProgressAt = Date.now();
|
|
534
|
+
idleStatusSeen = false;
|
|
535
|
+
} else if (status?.type === "idle") {
|
|
455
536
|
if (idleStatusSeen) break;
|
|
456
537
|
idleStatusSeen = true;
|
|
457
538
|
}
|
|
539
|
+
if (bestCandidate && isCompletedEmptyPromptResponse(bestCandidate, structured) && status?.type !== "busy" && status?.type !== "retry") break;
|
|
458
540
|
if (Date.now() >= deadlineAt) break;
|
|
459
541
|
}
|
|
460
542
|
const latest = await this.findLatestPromptResponse(input.sessionId, candidateOptions, "final-scan");
|
|
461
543
|
const resolved = selectPromptResponseCandidate([bestCandidate, latest], candidateOptions);
|
|
462
544
|
if (!resolved || shouldPollPromptMessage(resolved, structured)) {
|
|
545
|
+
const timeoutReason = Date.now() >= deadlineAt ? "max-wait" : "recovery-inactivity";
|
|
546
|
+
const timeoutMs = timeoutReason === "max-wait" ? this.promptTimeoutPolicy.waitTimeoutMs : this.promptTimeoutPolicy.recoveryInactivityTimeoutMs;
|
|
463
547
|
const error = createOpenCodePromptTimeoutError({
|
|
464
548
|
sessionId: input.sessionId,
|
|
465
549
|
stage: "final-scan",
|
|
466
|
-
timeoutMs
|
|
550
|
+
timeoutMs,
|
|
467
551
|
messageId: messageId ?? void 0
|
|
468
552
|
});
|
|
469
|
-
this.
|
|
553
|
+
this.logPromptRequest("warn", {
|
|
554
|
+
lastProgressAt,
|
|
555
|
+
messageId: messageId ?? void 0,
|
|
556
|
+
sdkFlavor: this.sdkFlavor,
|
|
470
557
|
sessionId: input.sessionId,
|
|
471
558
|
stage: "final-scan",
|
|
472
|
-
timeoutMs
|
|
473
|
-
|
|
474
|
-
});
|
|
559
|
+
timeoutMs,
|
|
560
|
+
timeoutReason
|
|
561
|
+
}, "OpenCode prompt recovery timed out");
|
|
475
562
|
throw error;
|
|
476
563
|
}
|
|
477
564
|
return resolved;
|
|
@@ -481,31 +568,28 @@ var OpenCodeClient = class {
|
|
|
481
568
|
return await this.runPromptRequestWithTimeout({
|
|
482
569
|
sessionId,
|
|
483
570
|
stage: "poll-message",
|
|
484
|
-
timeoutMs: this.
|
|
571
|
+
timeoutMs: this.promptTimeoutPolicy.pollRequestTimeoutMs,
|
|
485
572
|
messageId
|
|
486
573
|
}, async (signal) => {
|
|
487
|
-
if (hasRawSdkMethod(this.client, "get")) return normalizePromptResponse(await this.requestRaw("get", {
|
|
488
|
-
|
|
489
|
-
|
|
574
|
+
if (hasRawSdkMethod(this.client, "get")) return normalizePromptResponse(await this.requestRaw("get", buildRawSessionMessageRequest(this.sdkFlavor, sessionId, messageId, { signal })));
|
|
575
|
+
if (typeof this.client.session.message !== "function") return null;
|
|
576
|
+
return normalizePromptResponse(await this.callScopedSdkMethod("session", "message", {
|
|
577
|
+
legacyOptions: { path: {
|
|
578
|
+
id: sessionId,
|
|
579
|
+
messageID: messageId
|
|
580
|
+
} },
|
|
581
|
+
signal,
|
|
582
|
+
v2Parameters: {
|
|
490
583
|
sessionID: sessionId,
|
|
491
584
|
messageID: messageId
|
|
492
|
-
}
|
|
493
|
-
signal
|
|
585
|
+
}
|
|
494
586
|
}));
|
|
495
|
-
if (typeof this.client.session.message !== "function") return null;
|
|
496
|
-
return normalizePromptResponse(unwrapSdkData(await this.client.session.message({
|
|
497
|
-
sessionID: sessionId,
|
|
498
|
-
messageID: messageId
|
|
499
|
-
}, {
|
|
500
|
-
...SDK_OPTIONS,
|
|
501
|
-
signal
|
|
502
|
-
})));
|
|
503
587
|
});
|
|
504
588
|
} catch (error) {
|
|
505
589
|
this.logPromptRequestFailure(error, {
|
|
506
590
|
sessionId,
|
|
507
591
|
stage: "poll-message",
|
|
508
|
-
timeoutMs: this.
|
|
592
|
+
timeoutMs: this.promptTimeoutPolicy.pollRequestTimeoutMs,
|
|
509
593
|
messageId
|
|
510
594
|
});
|
|
511
595
|
return null;
|
|
@@ -521,28 +605,30 @@ var OpenCodeClient = class {
|
|
|
521
605
|
return await this.runPromptRequestWithTimeout({
|
|
522
606
|
sessionId,
|
|
523
607
|
stage,
|
|
524
|
-
timeoutMs: this.
|
|
608
|
+
timeoutMs: this.promptTimeoutPolicy.pollRequestTimeoutMs
|
|
525
609
|
}, async (signal) => {
|
|
526
|
-
if (hasRawSdkMethod(this.client, "get")) return normalizePromptResponses(await this.requestRaw("get", {
|
|
527
|
-
url: "/session/{sessionID}/message",
|
|
528
|
-
path: { sessionID: sessionId },
|
|
610
|
+
if (hasRawSdkMethod(this.client, "get")) return normalizePromptResponses(await this.requestRaw("get", buildRawSessionRequest(this.sdkFlavor, sessionId, "/message", {
|
|
529
611
|
query: { limit: PROMPT_MESSAGE_POLL_LIMIT },
|
|
530
612
|
signal
|
|
531
|
-
}));
|
|
532
|
-
if (typeof this.client.session.messages !== "function") return null;
|
|
533
|
-
return normalizePromptResponses(unwrapSdkData(await this.client.session.messages({
|
|
534
|
-
sessionID: sessionId,
|
|
535
|
-
limit: PROMPT_MESSAGE_POLL_LIMIT
|
|
536
|
-
}, {
|
|
537
|
-
...SDK_OPTIONS,
|
|
538
|
-
signal
|
|
539
613
|
})));
|
|
614
|
+
if (typeof this.client.session.messages !== "function") return null;
|
|
615
|
+
return normalizePromptResponses(await this.callScopedSdkMethod("session", "messages", {
|
|
616
|
+
legacyOptions: {
|
|
617
|
+
path: { id: sessionId },
|
|
618
|
+
query: { limit: PROMPT_MESSAGE_POLL_LIMIT }
|
|
619
|
+
},
|
|
620
|
+
signal,
|
|
621
|
+
v2Parameters: {
|
|
622
|
+
sessionID: sessionId,
|
|
623
|
+
limit: PROMPT_MESSAGE_POLL_LIMIT
|
|
624
|
+
}
|
|
625
|
+
}));
|
|
540
626
|
});
|
|
541
627
|
} catch (error) {
|
|
542
628
|
this.logPromptRequestFailure(error, {
|
|
543
629
|
sessionId,
|
|
544
630
|
stage,
|
|
545
|
-
timeoutMs: this.
|
|
631
|
+
timeoutMs: this.promptTimeoutPolicy.pollRequestTimeoutMs
|
|
546
632
|
});
|
|
547
633
|
return null;
|
|
548
634
|
}
|
|
@@ -552,13 +638,13 @@ var OpenCodeClient = class {
|
|
|
552
638
|
return (await this.runPromptRequestWithTimeout({
|
|
553
639
|
sessionId,
|
|
554
640
|
stage: "poll-status",
|
|
555
|
-
timeoutMs: this.
|
|
641
|
+
timeoutMs: this.promptTimeoutPolicy.pollRequestTimeoutMs
|
|
556
642
|
}, async (signal) => this.loadSessionStatuses(signal)))[sessionId] ?? null;
|
|
557
643
|
} catch (error) {
|
|
558
644
|
this.logPromptRequestFailure(error, {
|
|
559
645
|
sessionId,
|
|
560
646
|
stage: "poll-status",
|
|
561
|
-
timeoutMs: this.
|
|
647
|
+
timeoutMs: this.promptTimeoutPolicy.pollRequestTimeoutMs
|
|
562
648
|
});
|
|
563
649
|
return null;
|
|
564
650
|
}
|
|
@@ -581,11 +667,11 @@ var OpenCodeClient = class {
|
|
|
581
667
|
}
|
|
582
668
|
async loadConfig() {
|
|
583
669
|
if (hasRawSdkMethod(this.client, "get")) return this.requestRaw("get", { url: "/config" });
|
|
584
|
-
return
|
|
670
|
+
return this.callScopedSdkMethod("config", "get", {});
|
|
585
671
|
}
|
|
586
672
|
async loadProviderCatalog() {
|
|
587
673
|
if (hasRawSdkMethod(this.client, "get")) return this.requestRaw("get", { url: "/config/providers" });
|
|
588
|
-
return
|
|
674
|
+
return this.callScopedSdkMethod("config", "providers", {});
|
|
589
675
|
}
|
|
590
676
|
async sendPromptRequest(input, parts) {
|
|
591
677
|
const requestBody = {
|
|
@@ -600,43 +686,52 @@ var OpenCodeClient = class {
|
|
|
600
686
|
...requestBody
|
|
601
687
|
};
|
|
602
688
|
try {
|
|
689
|
+
if (hasRawSdkMethod(this.client, "post")) return await this.runPromptRequestWithTimeout({
|
|
690
|
+
sessionId: input.sessionId,
|
|
691
|
+
stage: "send-prompt",
|
|
692
|
+
timeoutMs: this.promptTimeoutPolicy.waitTimeoutMs
|
|
693
|
+
}, async (signal) => normalizePromptResponse(await this.requestRaw("post", buildRawSessionRequest(this.sdkFlavor, input.sessionId, "/message", {
|
|
694
|
+
body: requestBody,
|
|
695
|
+
signal
|
|
696
|
+
}))));
|
|
697
|
+
if (typeof this.client.session?.prompt === "function") return await this.runPromptRequestWithTimeout({
|
|
698
|
+
sessionId: input.sessionId,
|
|
699
|
+
stage: "send-prompt",
|
|
700
|
+
timeoutMs: this.promptTimeoutPolicy.waitTimeoutMs
|
|
701
|
+
}, async (signal) => normalizePromptResponse(await this.callScopedSdkMethod("session", "prompt", {
|
|
702
|
+
legacyOptions: {
|
|
703
|
+
body: requestBody,
|
|
704
|
+
path: { id: input.sessionId }
|
|
705
|
+
},
|
|
706
|
+
signal,
|
|
707
|
+
v2Parameters: requestParameters
|
|
708
|
+
})));
|
|
603
709
|
if (typeof this.client.session?.promptAsync === "function") {
|
|
604
710
|
await this.runPromptRequestWithTimeout({
|
|
605
711
|
sessionId: input.sessionId,
|
|
606
712
|
stage: "send-prompt",
|
|
607
|
-
timeoutMs: this.
|
|
713
|
+
timeoutMs: this.promptTimeoutPolicy.waitTimeoutMs
|
|
608
714
|
}, async (signal) => {
|
|
609
|
-
await this.
|
|
610
|
-
|
|
611
|
-
|
|
715
|
+
await this.callScopedSdkMethod("session", "promptAsync", {
|
|
716
|
+
legacyOptions: {
|
|
717
|
+
body: requestBody,
|
|
718
|
+
path: { id: input.sessionId }
|
|
719
|
+
},
|
|
720
|
+
signal,
|
|
721
|
+
v2Parameters: requestParameters
|
|
612
722
|
});
|
|
613
723
|
});
|
|
614
724
|
return null;
|
|
615
725
|
}
|
|
616
|
-
return await this.runPromptRequestWithTimeout({
|
|
617
|
-
sessionId: input.sessionId,
|
|
618
|
-
stage: "send-prompt",
|
|
619
|
-
timeoutMs: this.promptRequestTimeouts.sendMs
|
|
620
|
-
}, async (signal) => {
|
|
621
|
-
if (hasRawSdkMethod(this.client, "post")) return normalizePromptResponse(await this.requestRaw("post", {
|
|
622
|
-
url: "/session/{sessionID}/message",
|
|
623
|
-
path: { sessionID: input.sessionId },
|
|
624
|
-
body: requestBody,
|
|
625
|
-
signal
|
|
626
|
-
}));
|
|
627
|
-
return normalizePromptResponse(unwrapSdkData(await this.client.session.prompt(requestParameters, {
|
|
628
|
-
...SDK_OPTIONS,
|
|
629
|
-
signal
|
|
630
|
-
})));
|
|
631
|
-
});
|
|
632
726
|
} catch (error) {
|
|
633
727
|
this.logPromptRequestFailure(error, {
|
|
634
728
|
sessionId: input.sessionId,
|
|
635
729
|
stage: "send-prompt",
|
|
636
|
-
timeoutMs: this.
|
|
730
|
+
timeoutMs: this.promptTimeoutPolicy.waitTimeoutMs
|
|
637
731
|
});
|
|
638
732
|
throw error;
|
|
639
733
|
}
|
|
734
|
+
throw new Error("OpenCode SDK client does not expose a compatible prompt endpoint.");
|
|
640
735
|
}
|
|
641
736
|
async requestRaw(method, options) {
|
|
642
737
|
const handler = getRawSdkClient(this.client)?.[method];
|
|
@@ -651,10 +746,7 @@ var OpenCodeClient = class {
|
|
|
651
746
|
url: "/session/status",
|
|
652
747
|
...signal ? { signal } : {}
|
|
653
748
|
});
|
|
654
|
-
return
|
|
655
|
-
...SDK_OPTIONS,
|
|
656
|
-
...signal ? { signal } : {}
|
|
657
|
-
}));
|
|
749
|
+
return this.callScopedSdkMethod("session", "status", { signal });
|
|
658
750
|
}
|
|
659
751
|
async runPromptRequestWithTimeout(input, operation) {
|
|
660
752
|
const startedAt = Date.now();
|
|
@@ -681,8 +773,10 @@ var OpenCodeClient = class {
|
|
|
681
773
|
logPromptRequestFailure(error, input) {
|
|
682
774
|
if (error instanceof OpenCodePromptTimeoutError) {
|
|
683
775
|
this.logPromptRequest("warn", {
|
|
776
|
+
endpointKind: resolvePromptEndpointKind(error.data.stage),
|
|
684
777
|
elapsedMs: error.data.elapsedMs,
|
|
685
778
|
messageId: error.data.messageId,
|
|
779
|
+
sdkFlavor: this.sdkFlavor,
|
|
686
780
|
sessionId: error.data.sessionId,
|
|
687
781
|
stage: error.data.stage,
|
|
688
782
|
timeoutMs: error.data.timeoutMs
|
|
@@ -690,8 +784,10 @@ var OpenCodeClient = class {
|
|
|
690
784
|
return;
|
|
691
785
|
}
|
|
692
786
|
this.logPromptRequest("warn", {
|
|
787
|
+
endpointKind: resolvePromptEndpointKind(input.stage),
|
|
693
788
|
error,
|
|
694
789
|
messageId: input.messageId ?? void 0,
|
|
790
|
+
sdkFlavor: this.sdkFlavor,
|
|
695
791
|
sessionId: input.sessionId,
|
|
696
792
|
stage: input.stage,
|
|
697
793
|
timeoutMs: input.timeoutMs
|
|
@@ -708,8 +804,8 @@ var OpenCodeClient = class {
|
|
|
708
804
|
}).catch(() => void 0);
|
|
709
805
|
}
|
|
710
806
|
};
|
|
711
|
-
function createOpenCodeClientFromSdkClient(client, fetchFn = fetch) {
|
|
712
|
-
return new OpenCodeClient(void 0, client, fetchFn);
|
|
807
|
+
function createOpenCodeClientFromSdkClient(client, fetchFn = fetch, promptTimeoutPolicy = {}) {
|
|
808
|
+
return new OpenCodeClient(void 0, client, fetchFn, promptTimeoutPolicy);
|
|
713
809
|
}
|
|
714
810
|
function buildSelectableModels(config, providers, providerAvailability = /* @__PURE__ */ new Map()) {
|
|
715
811
|
const configuredProviders = config.provider ?? {};
|
|
@@ -816,7 +912,14 @@ function shouldPollPromptMessage(data, structured) {
|
|
|
816
912
|
const bodyMd = structured ? extractStructuredMarkdown(extractStructuredPayload(assistantInfo)) : null;
|
|
817
913
|
const hasText = extractTextFromParts(Array.isArray(data.parts) ? data.parts : []).length > 0;
|
|
818
914
|
const hasAssistantError = !!assistantInfo?.error;
|
|
819
|
-
|
|
915
|
+
const isCompleted = isAssistantMessageCompleted(assistantInfo);
|
|
916
|
+
return !hasText && !bodyMd && !hasAssistantError && !isCompleted;
|
|
917
|
+
}
|
|
918
|
+
function shouldReturnPromptResponseImmediately(data, structured) {
|
|
919
|
+
return !shouldPollPromptMessage(data, structured) && !isCompletedEmptyPromptResponse(data, structured);
|
|
920
|
+
}
|
|
921
|
+
function isPromptResponseUsable(data, structured) {
|
|
922
|
+
return !shouldPollPromptMessage(data, structured) && !isCompletedEmptyPromptResponse(data, structured);
|
|
820
923
|
}
|
|
821
924
|
function normalizePromptResponse(response) {
|
|
822
925
|
return {
|
|
@@ -878,6 +981,9 @@ function extractMessageId(message) {
|
|
|
878
981
|
function delay(ms) {
|
|
879
982
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
880
983
|
}
|
|
984
|
+
function didPromptResponseAdvance(previous, next, structured) {
|
|
985
|
+
return getPromptResponseProgressSignature(previous, structured) !== getPromptResponseProgressSignature(next, structured);
|
|
986
|
+
}
|
|
881
987
|
function createOpenCodePromptTimeoutError(input) {
|
|
882
988
|
return new OpenCodePromptTimeoutError({
|
|
883
989
|
...input,
|
|
@@ -885,6 +991,16 @@ function createOpenCodePromptTimeoutError(input) {
|
|
|
885
991
|
message: input.message ?? "The OpenCode host did not finish this request in time."
|
|
886
992
|
});
|
|
887
993
|
}
|
|
994
|
+
function resolvePromptEndpointKind(stage) {
|
|
995
|
+
switch (stage) {
|
|
996
|
+
case "capture-known-messages":
|
|
997
|
+
case "poll-messages":
|
|
998
|
+
case "final-scan": return "messages";
|
|
999
|
+
case "poll-message": return "message";
|
|
1000
|
+
case "poll-status": return "status";
|
|
1001
|
+
default: return "prompt";
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
888
1004
|
function getPromptMessagePollDelayMs(attempt) {
|
|
889
1005
|
return PROMPT_MESSAGE_POLL_INITIAL_DELAYS_MS[attempt] ?? PROMPT_MESSAGE_POLL_INTERVAL_MS;
|
|
890
1006
|
}
|
|
@@ -940,6 +1056,47 @@ function unwrapSdkData(response) {
|
|
|
940
1056
|
if (response && typeof response === "object" && "data" in response) return response.data;
|
|
941
1057
|
return response;
|
|
942
1058
|
}
|
|
1059
|
+
function resolvePromptTimeoutPolicy(input) {
|
|
1060
|
+
return {
|
|
1061
|
+
pollRequestTimeoutMs: input.pollRequestTimeoutMs ?? DEFAULT_OPENCODE_PROMPT_TIMEOUT_POLICY.pollRequestTimeoutMs,
|
|
1062
|
+
recoveryInactivityTimeoutMs: input.recoveryInactivityTimeoutMs ?? DEFAULT_OPENCODE_PROMPT_TIMEOUT_POLICY.recoveryInactivityTimeoutMs,
|
|
1063
|
+
waitTimeoutMs: input.waitTimeoutMs ?? DEFAULT_OPENCODE_PROMPT_TIMEOUT_POLICY.waitTimeoutMs
|
|
1064
|
+
};
|
|
1065
|
+
}
|
|
1066
|
+
function detectSdkFlavor(client) {
|
|
1067
|
+
if (typeof client.global?.health === "function" || "permission" in client) return "v2";
|
|
1068
|
+
return clientExposesTwoArgumentSdkMethod(client) ? "v2" : "legacy";
|
|
1069
|
+
}
|
|
1070
|
+
function buildRawSessionRequest(sdkFlavor, sessionId, suffix = "", extra = {}) {
|
|
1071
|
+
return {
|
|
1072
|
+
url: sdkFlavor === "legacy" ? `/session/{id}${suffix}` : `/session/{sessionID}${suffix}`,
|
|
1073
|
+
path: sdkFlavor === "legacy" ? { id: sessionId } : { sessionID: sessionId },
|
|
1074
|
+
...extra
|
|
1075
|
+
};
|
|
1076
|
+
}
|
|
1077
|
+
function buildRawSessionMessageRequest(sdkFlavor, sessionId, messageId, extra = {}) {
|
|
1078
|
+
return {
|
|
1079
|
+
url: sdkFlavor === "legacy" ? "/session/{id}/message/{messageID}" : "/session/{sessionID}/message/{messageID}",
|
|
1080
|
+
path: sdkFlavor === "legacy" ? {
|
|
1081
|
+
id: sessionId,
|
|
1082
|
+
messageID: messageId
|
|
1083
|
+
} : {
|
|
1084
|
+
sessionID: sessionId,
|
|
1085
|
+
messageID: messageId
|
|
1086
|
+
},
|
|
1087
|
+
...extra
|
|
1088
|
+
};
|
|
1089
|
+
}
|
|
1090
|
+
function buildRawLegacyPermissionReplyRequest(sessionId, requestId, reply) {
|
|
1091
|
+
return {
|
|
1092
|
+
body: { response: reply },
|
|
1093
|
+
path: {
|
|
1094
|
+
id: sessionId,
|
|
1095
|
+
permissionID: requestId
|
|
1096
|
+
},
|
|
1097
|
+
url: "/session/{id}/permissions/{permissionID}"
|
|
1098
|
+
};
|
|
1099
|
+
}
|
|
943
1100
|
function getRawSdkClient(client) {
|
|
944
1101
|
return client.client ?? client._client ?? null;
|
|
945
1102
|
}
|
|
@@ -954,6 +1111,32 @@ function normalizeAssistantError(value) {
|
|
|
954
1111
|
...isPlainRecord(value.data) ? { data: value.data } : {}
|
|
955
1112
|
};
|
|
956
1113
|
}
|
|
1114
|
+
function isAssistantMessageCompleted(message) {
|
|
1115
|
+
return !!message?.error || typeof message?.time?.completed === "number" || typeof message?.finish === "string" && message.finish.trim().length > 0;
|
|
1116
|
+
}
|
|
1117
|
+
function isCompletedEmptyPromptResponse(data, structured) {
|
|
1118
|
+
const assistantInfo = toAssistantMessage(data.info);
|
|
1119
|
+
const bodyMd = structured ? extractStructuredMarkdown(extractStructuredPayload(assistantInfo)) : null;
|
|
1120
|
+
const hasText = extractTextFromParts(Array.isArray(data.parts) ? data.parts : []).length > 0;
|
|
1121
|
+
return isAssistantMessageCompleted(assistantInfo) && !assistantInfo?.error && !hasText && !bodyMd;
|
|
1122
|
+
}
|
|
1123
|
+
function clientExposesTwoArgumentSdkMethod(client) {
|
|
1124
|
+
return [
|
|
1125
|
+
"app",
|
|
1126
|
+
"config",
|
|
1127
|
+
"global",
|
|
1128
|
+
"lsp",
|
|
1129
|
+
"mcp",
|
|
1130
|
+
"path",
|
|
1131
|
+
"permission",
|
|
1132
|
+
"project",
|
|
1133
|
+
"session"
|
|
1134
|
+
].some((scope) => {
|
|
1135
|
+
const target = client[scope];
|
|
1136
|
+
if (!target || typeof target !== "object") return false;
|
|
1137
|
+
return Object.values(target).some((value) => typeof value === "function" && value.length >= 2);
|
|
1138
|
+
});
|
|
1139
|
+
}
|
|
957
1140
|
function extractStructuredPayload(message) {
|
|
958
1141
|
if (!isPlainRecord(message)) return null;
|
|
959
1142
|
if ("structured" in message && message.structured !== void 0) return message.structured;
|
|
@@ -978,7 +1161,7 @@ function getPromptResponseCandidateRank(message, options) {
|
|
|
978
1161
|
createdAt,
|
|
979
1162
|
isInitial: !!id && id === options.initialMessageId,
|
|
980
1163
|
isNewSinceRequestStart: isPromptResponseNewSinceRequestStart(id, createdAt, options.knownMessageIds, options.requestStartedAt),
|
|
981
|
-
isUsable:
|
|
1164
|
+
isUsable: isPromptResponseUsable(message, options.structured),
|
|
982
1165
|
sharesParent: !!assistant?.parentID && assistant.parentID === options.initialParentId
|
|
983
1166
|
};
|
|
984
1167
|
}
|
|
@@ -988,6 +1171,20 @@ function resolvePromptCandidateStartTime(startedAt, initialMessage) {
|
|
|
988
1171
|
if (initialCreatedAt === null) return startedAt;
|
|
989
1172
|
return areComparablePromptTimestamps(startedAt, initialCreatedAt) ? startedAt : initialCreatedAt;
|
|
990
1173
|
}
|
|
1174
|
+
function getPromptResponseProgressSignature(response, structured) {
|
|
1175
|
+
if (!response) return "null";
|
|
1176
|
+
const assistant = toAssistantMessage(response.info);
|
|
1177
|
+
const responseParts = Array.isArray(response.parts) ? response.parts : [];
|
|
1178
|
+
return JSON.stringify({
|
|
1179
|
+
assistantError: assistant?.error?.name ?? null,
|
|
1180
|
+
bodyMd: structured ? extractStructuredMarkdown(extractStructuredPayload(assistant)) : null,
|
|
1181
|
+
completedAt: assistant?.time?.completed ?? null,
|
|
1182
|
+
finish: assistant?.finish ?? null,
|
|
1183
|
+
id: assistant?.id ?? null,
|
|
1184
|
+
partCount: responseParts.length,
|
|
1185
|
+
text: extractTextFromParts(responseParts)
|
|
1186
|
+
});
|
|
1187
|
+
}
|
|
991
1188
|
function isPromptResponseNewSinceRequestStart(messageId, createdAt, knownMessageIds, requestStartedAt) {
|
|
992
1189
|
if (!messageId || knownMessageIds.has(messageId)) return false;
|
|
993
1190
|
if (requestStartedAt === null) return true;
|
|
@@ -2025,7 +2222,11 @@ function resolveExtension(mimeType) {
|
|
|
2025
2222
|
//#region src/app/container.ts
|
|
2026
2223
|
function createAppContainer(config, client) {
|
|
2027
2224
|
const logger = createOpenCodeAppLogger(client, { level: config.logLevel });
|
|
2028
|
-
return createContainer(config, createOpenCodeClientFromSdkClient(client
|
|
2225
|
+
return createContainer(config, createOpenCodeClientFromSdkClient(client, fetch, {
|
|
2226
|
+
waitTimeoutMs: config.promptWaitTimeoutMs,
|
|
2227
|
+
pollRequestTimeoutMs: config.promptPollRequestTimeoutMs,
|
|
2228
|
+
recoveryInactivityTimeoutMs: config.promptRecoveryInactivityTimeoutMs
|
|
2229
|
+
}), logger);
|
|
2029
2230
|
}
|
|
2030
2231
|
function createContainer(config, opencodeClient, logger) {
|
|
2031
2232
|
const stateStore = new JsonStateStore({
|
|
@@ -4478,8 +4679,8 @@ async function handlePermissionApprovalCallback(ctx, dependencies) {
|
|
|
4478
4679
|
const parsed = parsePermissionApprovalCallbackData(data);
|
|
4479
4680
|
if (!parsed) return;
|
|
4480
4681
|
try {
|
|
4481
|
-
await dependencies.opencodeClient.replyToPermission(parsed.requestId, parsed.reply);
|
|
4482
4682
|
const approval = (await dependencies.permissionApprovalRepo.listByRequestId(parsed.requestId)).find((item) => item.chatId === ctx.chat?.id);
|
|
4683
|
+
await dependencies.opencodeClient.replyToPermission(parsed.requestId, parsed.reply, void 0, approval?.sessionId);
|
|
4483
4684
|
if (approval) await dependencies.permissionApprovalRepo.set({
|
|
4484
4685
|
...approval,
|
|
4485
4686
|
status: parsed.reply,
|