oh-my-opencode 3.12.1 → 3.12.2
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/dist/cli/index.js +69 -26
- package/dist/config/schema/background-task.d.ts +1 -2
- package/dist/config/schema/oh-my-opencode-config.d.ts +1 -2
- package/dist/features/background-agent/constants.d.ts +1 -2
- package/dist/features/background-agent/loop-detector.d.ts +1 -4
- package/dist/features/background-agent/manager.d.ts +1 -0
- package/dist/features/background-agent/session-status-classifier.d.ts +2 -0
- package/dist/features/background-agent/types.d.ts +4 -4
- package/dist/index.js +264 -202
- package/dist/oh-my-opencode.schema.json +1 -6
- package/package.json +12 -12
package/dist/index.js
CHANGED
|
@@ -55,20 +55,43 @@ __export(exports_logger, {
|
|
|
55
55
|
import * as fs from "fs";
|
|
56
56
|
import * as os from "os";
|
|
57
57
|
import * as path from "path";
|
|
58
|
+
function flush() {
|
|
59
|
+
if (buffer.length === 0)
|
|
60
|
+
return;
|
|
61
|
+
const data = buffer.join("");
|
|
62
|
+
buffer = [];
|
|
63
|
+
try {
|
|
64
|
+
fs.appendFileSync(logFile, data);
|
|
65
|
+
} catch {}
|
|
66
|
+
}
|
|
67
|
+
function scheduleFlush() {
|
|
68
|
+
if (flushTimer)
|
|
69
|
+
return;
|
|
70
|
+
flushTimer = setTimeout(() => {
|
|
71
|
+
flushTimer = null;
|
|
72
|
+
flush();
|
|
73
|
+
}, FLUSH_INTERVAL_MS);
|
|
74
|
+
}
|
|
58
75
|
function log(message, data) {
|
|
59
76
|
try {
|
|
60
77
|
const timestamp2 = new Date().toISOString();
|
|
61
78
|
const logEntry = `[${timestamp2}] ${message} ${data ? JSON.stringify(data) : ""}
|
|
62
79
|
`;
|
|
63
|
-
|
|
80
|
+
buffer.push(logEntry);
|
|
81
|
+
if (buffer.length >= BUFFER_SIZE_LIMIT) {
|
|
82
|
+
flush();
|
|
83
|
+
} else {
|
|
84
|
+
scheduleFlush();
|
|
85
|
+
}
|
|
64
86
|
} catch {}
|
|
65
87
|
}
|
|
66
88
|
function getLogFilePath() {
|
|
67
89
|
return logFile;
|
|
68
90
|
}
|
|
69
|
-
var logFile;
|
|
91
|
+
var logFile, buffer, flushTimer = null, FLUSH_INTERVAL_MS = 500, BUFFER_SIZE_LIMIT = 50;
|
|
70
92
|
var init_logger = __esm(() => {
|
|
71
93
|
logFile = path.join(os.tmpdir(), "oh-my-opencode.log");
|
|
94
|
+
buffer = [];
|
|
72
95
|
});
|
|
73
96
|
|
|
74
97
|
// src/shared/truncate-description.ts
|
|
@@ -2454,18 +2477,18 @@ var require_sharedArrayCancellation = __commonJS((exports) => {
|
|
|
2454
2477
|
if (request.id === null) {
|
|
2455
2478
|
return;
|
|
2456
2479
|
}
|
|
2457
|
-
const
|
|
2458
|
-
const data = new Int32Array(
|
|
2480
|
+
const buffer2 = new SharedArrayBuffer(4);
|
|
2481
|
+
const data = new Int32Array(buffer2, 0, 1);
|
|
2459
2482
|
data[0] = CancellationState.Continue;
|
|
2460
|
-
this.buffers.set(request.id,
|
|
2461
|
-
request.$cancellationData =
|
|
2483
|
+
this.buffers.set(request.id, buffer2);
|
|
2484
|
+
request.$cancellationData = buffer2;
|
|
2462
2485
|
}
|
|
2463
2486
|
async sendCancellation(_conn, id) {
|
|
2464
|
-
const
|
|
2465
|
-
if (
|
|
2487
|
+
const buffer2 = this.buffers.get(id);
|
|
2488
|
+
if (buffer2 === undefined) {
|
|
2466
2489
|
return;
|
|
2467
2490
|
}
|
|
2468
|
-
const data = new Int32Array(
|
|
2491
|
+
const data = new Int32Array(buffer2, 0, 1);
|
|
2469
2492
|
Atomics.store(data, 0, CancellationState.Cancelled);
|
|
2470
2493
|
}
|
|
2471
2494
|
cleanup(id) {
|
|
@@ -2478,8 +2501,8 @@ var require_sharedArrayCancellation = __commonJS((exports) => {
|
|
|
2478
2501
|
exports.SharedArraySenderStrategy = SharedArraySenderStrategy;
|
|
2479
2502
|
|
|
2480
2503
|
class SharedArrayBufferCancellationToken {
|
|
2481
|
-
constructor(
|
|
2482
|
-
this.data = new Int32Array(
|
|
2504
|
+
constructor(buffer2) {
|
|
2505
|
+
this.data = new Int32Array(buffer2, 0, 1);
|
|
2483
2506
|
}
|
|
2484
2507
|
get isCancellationRequested() {
|
|
2485
2508
|
return Atomics.load(this.data, 0) === CancellationState.Cancelled;
|
|
@@ -2490,8 +2513,8 @@ var require_sharedArrayCancellation = __commonJS((exports) => {
|
|
|
2490
2513
|
}
|
|
2491
2514
|
|
|
2492
2515
|
class SharedArrayBufferCancellationTokenSource {
|
|
2493
|
-
constructor(
|
|
2494
|
-
this.token = new SharedArrayBufferCancellationToken(
|
|
2516
|
+
constructor(buffer2) {
|
|
2517
|
+
this.token = new SharedArrayBufferCancellationToken(buffer2);
|
|
2495
2518
|
}
|
|
2496
2519
|
cancel() {}
|
|
2497
2520
|
dispose() {}
|
|
@@ -2502,11 +2525,11 @@ var require_sharedArrayCancellation = __commonJS((exports) => {
|
|
|
2502
2525
|
this.kind = "request";
|
|
2503
2526
|
}
|
|
2504
2527
|
createCancellationTokenSource(request) {
|
|
2505
|
-
const
|
|
2506
|
-
if (
|
|
2528
|
+
const buffer2 = request.$cancellationData;
|
|
2529
|
+
if (buffer2 === undefined) {
|
|
2507
2530
|
return new cancellation_1.CancellationTokenSource;
|
|
2508
2531
|
}
|
|
2509
|
-
return new SharedArrayBufferCancellationTokenSource(
|
|
2532
|
+
return new SharedArrayBufferCancellationTokenSource(buffer2);
|
|
2510
2533
|
}
|
|
2511
2534
|
}
|
|
2512
2535
|
exports.SharedArrayReceiverStrategy = SharedArrayReceiverStrategy;
|
|
@@ -2840,18 +2863,18 @@ var require_messageWriter = __commonJS((exports) => {
|
|
|
2840
2863
|
}
|
|
2841
2864
|
async write(msg) {
|
|
2842
2865
|
return this.writeSemaphore.lock(async () => {
|
|
2843
|
-
const payload = this.options.contentTypeEncoder.encode(msg, this.options).then((
|
|
2866
|
+
const payload = this.options.contentTypeEncoder.encode(msg, this.options).then((buffer2) => {
|
|
2844
2867
|
if (this.options.contentEncoder !== undefined) {
|
|
2845
|
-
return this.options.contentEncoder.encode(
|
|
2868
|
+
return this.options.contentEncoder.encode(buffer2);
|
|
2846
2869
|
} else {
|
|
2847
|
-
return
|
|
2870
|
+
return buffer2;
|
|
2848
2871
|
}
|
|
2849
2872
|
});
|
|
2850
|
-
return payload.then((
|
|
2873
|
+
return payload.then((buffer2) => {
|
|
2851
2874
|
const headers = [];
|
|
2852
|
-
headers.push(ContentLength,
|
|
2875
|
+
headers.push(ContentLength, buffer2.byteLength.toString(), CRLF);
|
|
2853
2876
|
headers.push(CRLF);
|
|
2854
|
-
return this.doWrite(msg, headers,
|
|
2877
|
+
return this.doWrite(msg, headers, buffer2);
|
|
2855
2878
|
}, (error48) => {
|
|
2856
2879
|
this.fireError(error48);
|
|
2857
2880
|
throw error48;
|
|
@@ -2953,9 +2976,9 @@ var require_messageBuffer = __commonJS((exports) => {
|
|
|
2953
2976
|
if (state3 !== 4) {
|
|
2954
2977
|
return;
|
|
2955
2978
|
}
|
|
2956
|
-
const
|
|
2979
|
+
const buffer2 = this._read(chunkBytesRead + offset);
|
|
2957
2980
|
const result = new Map;
|
|
2958
|
-
const headers = this.toString(
|
|
2981
|
+
const headers = this.toString(buffer2, "ascii").split(CRLF);
|
|
2959
2982
|
if (headers.length < 2) {
|
|
2960
2983
|
return result;
|
|
2961
2984
|
}
|
|
@@ -4379,11 +4402,11 @@ var require_ril = __commonJS((exports) => {
|
|
|
4379
4402
|
return new util_1.TextDecoder(encoding).decode(value);
|
|
4380
4403
|
}
|
|
4381
4404
|
}
|
|
4382
|
-
asNative(
|
|
4405
|
+
asNative(buffer2, length) {
|
|
4383
4406
|
if (length === undefined) {
|
|
4384
|
-
return
|
|
4407
|
+
return buffer2 instanceof Buffer ? buffer2 : Buffer.from(buffer2);
|
|
4385
4408
|
} else {
|
|
4386
|
-
return
|
|
4409
|
+
return buffer2 instanceof Buffer ? buffer2.slice(0, length) : Buffer.from(buffer2, 0, length);
|
|
4387
4410
|
}
|
|
4388
4411
|
}
|
|
4389
4412
|
allocNative(length) {
|
|
@@ -4467,12 +4490,12 @@ var require_ril = __commonJS((exports) => {
|
|
|
4467
4490
|
}),
|
|
4468
4491
|
decoder: Object.freeze({
|
|
4469
4492
|
name: "application/json",
|
|
4470
|
-
decode: (
|
|
4493
|
+
decode: (buffer2, options) => {
|
|
4471
4494
|
try {
|
|
4472
|
-
if (
|
|
4473
|
-
return Promise.resolve(JSON.parse(
|
|
4495
|
+
if (buffer2 instanceof Buffer) {
|
|
4496
|
+
return Promise.resolve(JSON.parse(buffer2.toString(options.charset)));
|
|
4474
4497
|
} else {
|
|
4475
|
-
return Promise.resolve(JSON.parse(new util_1.TextDecoder(options.charset).decode(
|
|
4498
|
+
return Promise.resolve(JSON.parse(new util_1.TextDecoder(options.charset).decode(buffer2)));
|
|
4476
4499
|
}
|
|
4477
4500
|
} catch (err) {
|
|
4478
4501
|
return Promise.reject(err);
|
|
@@ -8405,20 +8428,20 @@ var require_utils2 = __commonJS((exports, module) => {
|
|
|
8405
8428
|
return acc;
|
|
8406
8429
|
}
|
|
8407
8430
|
var nonSimpleDomain = RegExp.prototype.test.bind(/[^!"$&'()*+,\-.;=_`a-z{}~]/u);
|
|
8408
|
-
function consumeIsZone(
|
|
8409
|
-
|
|
8431
|
+
function consumeIsZone(buffer2) {
|
|
8432
|
+
buffer2.length = 0;
|
|
8410
8433
|
return true;
|
|
8411
8434
|
}
|
|
8412
|
-
function consumeHextets(
|
|
8413
|
-
if (
|
|
8414
|
-
const hex5 = stringArrayToHexStripped(
|
|
8435
|
+
function consumeHextets(buffer2, address, output) {
|
|
8436
|
+
if (buffer2.length) {
|
|
8437
|
+
const hex5 = stringArrayToHexStripped(buffer2);
|
|
8415
8438
|
if (hex5 !== "") {
|
|
8416
8439
|
address.push(hex5);
|
|
8417
8440
|
} else {
|
|
8418
8441
|
output.error = true;
|
|
8419
8442
|
return false;
|
|
8420
8443
|
}
|
|
8421
|
-
|
|
8444
|
+
buffer2.length = 0;
|
|
8422
8445
|
}
|
|
8423
8446
|
return true;
|
|
8424
8447
|
}
|
|
@@ -8426,7 +8449,7 @@ var require_utils2 = __commonJS((exports, module) => {
|
|
|
8426
8449
|
let tokenCount = 0;
|
|
8427
8450
|
const output = { error: false, address: "", zone: "" };
|
|
8428
8451
|
const address = [];
|
|
8429
|
-
const
|
|
8452
|
+
const buffer2 = [];
|
|
8430
8453
|
let endipv6Encountered = false;
|
|
8431
8454
|
let endIpv6 = false;
|
|
8432
8455
|
let consume = consumeHextets;
|
|
@@ -8439,7 +8462,7 @@ var require_utils2 = __commonJS((exports, module) => {
|
|
|
8439
8462
|
if (endipv6Encountered === true) {
|
|
8440
8463
|
endIpv6 = true;
|
|
8441
8464
|
}
|
|
8442
|
-
if (!consume(
|
|
8465
|
+
if (!consume(buffer2, address, output)) {
|
|
8443
8466
|
break;
|
|
8444
8467
|
}
|
|
8445
8468
|
if (++tokenCount > 7) {
|
|
@@ -8452,22 +8475,22 @@ var require_utils2 = __commonJS((exports, module) => {
|
|
|
8452
8475
|
address.push(":");
|
|
8453
8476
|
continue;
|
|
8454
8477
|
} else if (cursor === "%") {
|
|
8455
|
-
if (!consume(
|
|
8478
|
+
if (!consume(buffer2, address, output)) {
|
|
8456
8479
|
break;
|
|
8457
8480
|
}
|
|
8458
8481
|
consume = consumeIsZone;
|
|
8459
8482
|
} else {
|
|
8460
|
-
|
|
8483
|
+
buffer2.push(cursor);
|
|
8461
8484
|
continue;
|
|
8462
8485
|
}
|
|
8463
8486
|
}
|
|
8464
|
-
if (
|
|
8487
|
+
if (buffer2.length) {
|
|
8465
8488
|
if (consume === consumeIsZone) {
|
|
8466
|
-
output.zone =
|
|
8489
|
+
output.zone = buffer2.join("");
|
|
8467
8490
|
} else if (endIpv6) {
|
|
8468
|
-
address.push(
|
|
8491
|
+
address.push(buffer2.join(""));
|
|
8469
8492
|
} else {
|
|
8470
|
-
address.push(stringArrayToHexStripped(
|
|
8493
|
+
address.push(stringArrayToHexStripped(buffer2));
|
|
8471
8494
|
}
|
|
8472
8495
|
}
|
|
8473
8496
|
output.address = address.join("");
|
|
@@ -12160,14 +12183,14 @@ var require_readShebang = __commonJS((exports, module) => {
|
|
|
12160
12183
|
var shebangCommand = require_shebang_command();
|
|
12161
12184
|
function readShebang(command) {
|
|
12162
12185
|
const size = 150;
|
|
12163
|
-
const
|
|
12186
|
+
const buffer2 = Buffer.alloc(size);
|
|
12164
12187
|
let fd;
|
|
12165
12188
|
try {
|
|
12166
12189
|
fd = fs19.openSync(command, "r");
|
|
12167
|
-
fs19.readSync(fd,
|
|
12190
|
+
fs19.readSync(fd, buffer2, 0, size, 0);
|
|
12168
12191
|
fs19.closeSync(fd);
|
|
12169
12192
|
} catch (e) {}
|
|
12170
|
-
return shebangCommand(
|
|
12193
|
+
return shebangCommand(buffer2.toString());
|
|
12171
12194
|
}
|
|
12172
12195
|
module.exports = readShebang;
|
|
12173
12196
|
});
|
|
@@ -15246,7 +15269,7 @@ async function resolveFileReferencesInText(text, cwd = process.cwd(), depth = 0,
|
|
|
15246
15269
|
}
|
|
15247
15270
|
let resolved = text;
|
|
15248
15271
|
for (const [pattern, replacement] of replacements.entries()) {
|
|
15249
|
-
resolved = resolved.
|
|
15272
|
+
resolved = resolved.replaceAll(pattern, replacement);
|
|
15250
15273
|
}
|
|
15251
15274
|
if (findFileReferences(resolved).length > 0 && depth + 1 < maxDepth) {
|
|
15252
15275
|
return resolveFileReferencesInText(resolved, cwd, depth + 1, maxDepth);
|
|
@@ -15345,6 +15368,7 @@ function transformToolName(toolName) {
|
|
|
15345
15368
|
function escapeRegexExceptAsterisk(str2) {
|
|
15346
15369
|
return str2.replace(/[.+?^${}()|[\]\\]/g, "\\$&");
|
|
15347
15370
|
}
|
|
15371
|
+
var regexCache = new Map;
|
|
15348
15372
|
function matchesToolMatcher(toolName, matcher) {
|
|
15349
15373
|
if (!matcher) {
|
|
15350
15374
|
return true;
|
|
@@ -15352,8 +15376,12 @@ function matchesToolMatcher(toolName, matcher) {
|
|
|
15352
15376
|
const patterns = matcher.split("|").map((p) => p.trim());
|
|
15353
15377
|
return patterns.some((p) => {
|
|
15354
15378
|
if (p.includes("*")) {
|
|
15355
|
-
|
|
15356
|
-
|
|
15379
|
+
let regex = regexCache.get(p);
|
|
15380
|
+
if (!regex) {
|
|
15381
|
+
const escaped = escapeRegexExceptAsterisk(p);
|
|
15382
|
+
regex = new RegExp(`^${escaped.replace(/\*/g, ".*")}$`, "i");
|
|
15383
|
+
regexCache.set(p, regex);
|
|
15384
|
+
}
|
|
15357
15385
|
return regex.test(toolName);
|
|
15358
15386
|
}
|
|
15359
15387
|
return p.toLowerCase() === toolName.toLowerCase();
|
|
@@ -17588,6 +17616,8 @@ function createConnectedProvidersCacheStore(getCacheDir2 = getOmoOpenCodeCacheDi
|
|
|
17588
17616
|
function getCacheFilePath(filename) {
|
|
17589
17617
|
return join9(getCacheDir2(), filename);
|
|
17590
17618
|
}
|
|
17619
|
+
let memConnected;
|
|
17620
|
+
let memProviderModels;
|
|
17591
17621
|
function ensureCacheDir2() {
|
|
17592
17622
|
const cacheDir = getCacheDir2();
|
|
17593
17623
|
if (!existsSync8(cacheDir)) {
|
|
@@ -17595,18 +17625,23 @@ function createConnectedProvidersCacheStore(getCacheDir2 = getOmoOpenCodeCacheDi
|
|
|
17595
17625
|
}
|
|
17596
17626
|
}
|
|
17597
17627
|
function readConnectedProvidersCache() {
|
|
17628
|
+
if (memConnected !== undefined)
|
|
17629
|
+
return memConnected;
|
|
17598
17630
|
const cacheFile = getCacheFilePath(CONNECTED_PROVIDERS_CACHE_FILE);
|
|
17599
17631
|
if (!existsSync8(cacheFile)) {
|
|
17600
17632
|
log("[connected-providers-cache] Cache file not found", { cacheFile });
|
|
17633
|
+
memConnected = null;
|
|
17601
17634
|
return null;
|
|
17602
17635
|
}
|
|
17603
17636
|
try {
|
|
17604
17637
|
const content = readFileSync4(cacheFile, "utf-8");
|
|
17605
17638
|
const data = JSON.parse(content);
|
|
17606
17639
|
log("[connected-providers-cache] Read cache", { count: data.connected.length, updatedAt: data.updatedAt });
|
|
17640
|
+
memConnected = data.connected;
|
|
17607
17641
|
return data.connected;
|
|
17608
17642
|
} catch (err) {
|
|
17609
17643
|
log("[connected-providers-cache] Error reading cache", { error: String(err) });
|
|
17644
|
+
memConnected = null;
|
|
17610
17645
|
return null;
|
|
17611
17646
|
}
|
|
17612
17647
|
}
|
|
@@ -17623,15 +17658,19 @@ function createConnectedProvidersCacheStore(getCacheDir2 = getOmoOpenCodeCacheDi
|
|
|
17623
17658
|
};
|
|
17624
17659
|
try {
|
|
17625
17660
|
writeFileSync2(cacheFile, JSON.stringify(data, null, 2));
|
|
17661
|
+
memConnected = connected;
|
|
17626
17662
|
log("[connected-providers-cache] Cache written", { count: connected.length });
|
|
17627
17663
|
} catch (err) {
|
|
17628
17664
|
log("[connected-providers-cache] Error writing cache", { error: String(err) });
|
|
17629
17665
|
}
|
|
17630
17666
|
}
|
|
17631
17667
|
function readProviderModelsCache() {
|
|
17668
|
+
if (memProviderModels !== undefined)
|
|
17669
|
+
return memProviderModels;
|
|
17632
17670
|
const cacheFile = getCacheFilePath(PROVIDER_MODELS_CACHE_FILE);
|
|
17633
17671
|
if (!existsSync8(cacheFile)) {
|
|
17634
17672
|
log("[connected-providers-cache] Provider-models cache file not found", { cacheFile });
|
|
17673
|
+
memProviderModels = null;
|
|
17635
17674
|
return null;
|
|
17636
17675
|
}
|
|
17637
17676
|
try {
|
|
@@ -17641,9 +17680,11 @@ function createConnectedProvidersCacheStore(getCacheDir2 = getOmoOpenCodeCacheDi
|
|
|
17641
17680
|
providerCount: Object.keys(data.models).length,
|
|
17642
17681
|
updatedAt: data.updatedAt
|
|
17643
17682
|
});
|
|
17683
|
+
memProviderModels = data;
|
|
17644
17684
|
return data;
|
|
17645
17685
|
} catch (err) {
|
|
17646
17686
|
log("[connected-providers-cache] Error reading provider-models cache", { error: String(err) });
|
|
17687
|
+
memProviderModels = null;
|
|
17647
17688
|
return null;
|
|
17648
17689
|
}
|
|
17649
17690
|
}
|
|
@@ -17660,6 +17701,7 @@ function createConnectedProvidersCacheStore(getCacheDir2 = getOmoOpenCodeCacheDi
|
|
|
17660
17701
|
};
|
|
17661
17702
|
try {
|
|
17662
17703
|
writeFileSync2(cacheFile, JSON.stringify(cacheData, null, 2));
|
|
17704
|
+
memProviderModels = cacheData;
|
|
17663
17705
|
log("[connected-providers-cache] Provider-models cache written", {
|
|
17664
17706
|
providerCount: Object.keys(data.models).length
|
|
17665
17707
|
});
|
|
@@ -20394,15 +20436,18 @@ async function handleSessionIdle(args) {
|
|
|
20394
20436
|
shouldSkipContinuation
|
|
20395
20437
|
} = args;
|
|
20396
20438
|
log(`[${HOOK_NAME}] session.idle`, { sessionID });
|
|
20439
|
+
console.error(`[TODO-DIAG] session.idle fired for ${sessionID}`);
|
|
20397
20440
|
const state2 = sessionStateStore.getState(sessionID);
|
|
20398
20441
|
if (state2.isRecovering) {
|
|
20399
20442
|
log(`[${HOOK_NAME}] Skipped: in recovery`, { sessionID });
|
|
20443
|
+
console.error(`[TODO-DIAG] BLOCKED: isRecovering=true`);
|
|
20400
20444
|
return;
|
|
20401
20445
|
}
|
|
20402
20446
|
if (state2.abortDetectedAt) {
|
|
20403
20447
|
const timeSinceAbort = Date.now() - state2.abortDetectedAt;
|
|
20404
20448
|
if (timeSinceAbort < ABORT_WINDOW_MS) {
|
|
20405
20449
|
log(`[${HOOK_NAME}] Skipped: abort detected via event ${timeSinceAbort}ms ago`, { sessionID });
|
|
20450
|
+
console.error(`[TODO-DIAG] BLOCKED: abort detected ${timeSinceAbort}ms ago`);
|
|
20406
20451
|
state2.abortDetectedAt = undefined;
|
|
20407
20452
|
return;
|
|
20408
20453
|
}
|
|
@@ -20411,6 +20456,7 @@ async function handleSessionIdle(args) {
|
|
|
20411
20456
|
const hasRunningBgTasks = backgroundManager ? backgroundManager.getTasksByParentSession(sessionID).some((task) => task.status === "running") : false;
|
|
20412
20457
|
if (hasRunningBgTasks) {
|
|
20413
20458
|
log(`[${HOOK_NAME}] Skipped: background tasks running`, { sessionID });
|
|
20459
|
+
console.error(`[TODO-DIAG] BLOCKED: background tasks running`, backgroundManager?.getTasksByParentSession(sessionID).filter((t) => t.status === "running").map((t) => t.id));
|
|
20414
20460
|
return;
|
|
20415
20461
|
}
|
|
20416
20462
|
try {
|
|
@@ -20421,10 +20467,12 @@ async function handleSessionIdle(args) {
|
|
|
20421
20467
|
const messages = normalizeSDKResponse(messagesResp, []);
|
|
20422
20468
|
if (isLastAssistantMessageAborted(messages)) {
|
|
20423
20469
|
log(`[${HOOK_NAME}] Skipped: last assistant message was aborted (API fallback)`, { sessionID });
|
|
20470
|
+
console.error(`[TODO-DIAG] BLOCKED: last assistant message aborted`);
|
|
20424
20471
|
return;
|
|
20425
20472
|
}
|
|
20426
20473
|
if (hasUnansweredQuestion(messages)) {
|
|
20427
20474
|
log(`[${HOOK_NAME}] Skipped: pending question awaiting user response`, { sessionID });
|
|
20475
|
+
console.error(`[TODO-DIAG] BLOCKED: hasUnansweredQuestion=true`);
|
|
20428
20476
|
return;
|
|
20429
20477
|
}
|
|
20430
20478
|
} catch (error) {
|
|
@@ -20436,21 +20484,27 @@ async function handleSessionIdle(args) {
|
|
|
20436
20484
|
todos = normalizeSDKResponse(response, [], { preferResponseOnMissingData: true });
|
|
20437
20485
|
} catch (error) {
|
|
20438
20486
|
log(`[${HOOK_NAME}] Todo fetch failed`, { sessionID, error: String(error) });
|
|
20487
|
+
console.error(`[TODO-DIAG] BLOCKED: todo fetch failed`, String(error));
|
|
20439
20488
|
return;
|
|
20440
20489
|
}
|
|
20441
20490
|
if (!todos || todos.length === 0) {
|
|
20491
|
+
sessionStateStore.resetContinuationProgress(sessionID);
|
|
20442
20492
|
sessionStateStore.resetContinuationProgress(sessionID);
|
|
20443
20493
|
log(`[${HOOK_NAME}] No todos`, { sessionID });
|
|
20494
|
+
console.error(`[TODO-DIAG] BLOCKED: no todos`);
|
|
20444
20495
|
return;
|
|
20445
20496
|
}
|
|
20446
20497
|
const incompleteCount = getIncompleteCount(todos);
|
|
20447
20498
|
if (incompleteCount === 0) {
|
|
20499
|
+
sessionStateStore.resetContinuationProgress(sessionID);
|
|
20448
20500
|
sessionStateStore.resetContinuationProgress(sessionID);
|
|
20449
20501
|
log(`[${HOOK_NAME}] All todos complete`, { sessionID, total: todos.length });
|
|
20502
|
+
console.error(`[TODO-DIAG] BLOCKED: all todos complete (${todos.length})`);
|
|
20450
20503
|
return;
|
|
20451
20504
|
}
|
|
20452
20505
|
if (state2.inFlight) {
|
|
20453
20506
|
log(`[${HOOK_NAME}] Skipped: injection in flight`, { sessionID });
|
|
20507
|
+
console.error(`[TODO-DIAG] BLOCKED: inFlight=true`);
|
|
20454
20508
|
return;
|
|
20455
20509
|
}
|
|
20456
20510
|
if (state2.consecutiveFailures >= MAX_CONSECUTIVE_FAILURES && state2.lastInjectedAt && Date.now() - state2.lastInjectedAt >= FAILURE_RESET_WINDOW_MS) {
|
|
@@ -20458,20 +20512,14 @@ async function handleSessionIdle(args) {
|
|
|
20458
20512
|
log(`[${HOOK_NAME}] Reset consecutive failures after recovery window`, { sessionID, failureResetWindowMs: FAILURE_RESET_WINDOW_MS });
|
|
20459
20513
|
}
|
|
20460
20514
|
if (state2.consecutiveFailures >= MAX_CONSECUTIVE_FAILURES) {
|
|
20461
|
-
log(`[${HOOK_NAME}] Skipped: max consecutive failures reached`, {
|
|
20462
|
-
|
|
20463
|
-
consecutiveFailures: state2.consecutiveFailures,
|
|
20464
|
-
maxConsecutiveFailures: MAX_CONSECUTIVE_FAILURES
|
|
20465
|
-
});
|
|
20515
|
+
log(`[${HOOK_NAME}] Skipped: max consecutive failures reached`, { sessionID, consecutiveFailures: state2.consecutiveFailures });
|
|
20516
|
+
console.error(`[TODO-DIAG] BLOCKED: consecutiveFailures=${state2.consecutiveFailures} >= ${MAX_CONSECUTIVE_FAILURES}`);
|
|
20466
20517
|
return;
|
|
20467
20518
|
}
|
|
20468
20519
|
const effectiveCooldown = CONTINUATION_COOLDOWN_MS * Math.pow(2, Math.min(state2.consecutiveFailures, 5));
|
|
20469
20520
|
if (state2.lastInjectedAt && Date.now() - state2.lastInjectedAt < effectiveCooldown) {
|
|
20470
|
-
log(`[${HOOK_NAME}] Skipped: cooldown active`, {
|
|
20471
|
-
|
|
20472
|
-
effectiveCooldown,
|
|
20473
|
-
consecutiveFailures: state2.consecutiveFailures
|
|
20474
|
-
});
|
|
20521
|
+
log(`[${HOOK_NAME}] Skipped: cooldown active`, { sessionID, effectiveCooldown, consecutiveFailures: state2.consecutiveFailures });
|
|
20522
|
+
console.error(`[TODO-DIAG] BLOCKED: cooldown active (${effectiveCooldown}ms, failures=${state2.consecutiveFailures})`);
|
|
20475
20523
|
return;
|
|
20476
20524
|
}
|
|
20477
20525
|
let resolvedInfo;
|
|
@@ -20492,10 +20540,12 @@ async function handleSessionIdle(args) {
|
|
|
20492
20540
|
const resolvedAgentName = resolvedInfo?.agent;
|
|
20493
20541
|
if (resolvedAgentName && skipAgents.some((s) => getAgentConfigKey(s) === getAgentConfigKey(resolvedAgentName))) {
|
|
20494
20542
|
log(`[${HOOK_NAME}] Skipped: agent in skipAgents list`, { sessionID, agent: resolvedAgentName });
|
|
20543
|
+
console.error(`[TODO-DIAG] BLOCKED: agent '${resolvedAgentName}' in skipAgents`);
|
|
20495
20544
|
return;
|
|
20496
20545
|
}
|
|
20497
20546
|
if ((compactionGuardActive || encounteredCompaction) && !resolvedInfo?.agent) {
|
|
20498
20547
|
log(`[${HOOK_NAME}] Skipped: compaction occurred but no agent info resolved`, { sessionID });
|
|
20548
|
+
console.error(`[TODO-DIAG] BLOCKED: compaction guard + no agent`);
|
|
20499
20549
|
return;
|
|
20500
20550
|
}
|
|
20501
20551
|
if (state2.recentCompactionAt && resolvedInfo?.agent) {
|
|
@@ -20503,16 +20553,20 @@ async function handleSessionIdle(args) {
|
|
|
20503
20553
|
}
|
|
20504
20554
|
if (isContinuationStopped?.(sessionID)) {
|
|
20505
20555
|
log(`[${HOOK_NAME}] Skipped: continuation stopped for session`, { sessionID });
|
|
20556
|
+
console.error(`[TODO-DIAG] BLOCKED: isContinuationStopped=true`);
|
|
20506
20557
|
return;
|
|
20507
20558
|
}
|
|
20508
20559
|
if (shouldSkipContinuation?.(sessionID)) {
|
|
20509
20560
|
log(`[${HOOK_NAME}] Skipped: another continuation hook already injected`, { sessionID });
|
|
20561
|
+
console.error(`[TODO-DIAG] BLOCKED: shouldSkipContinuation=true (gptPermissionContinuation recently injected)`);
|
|
20510
20562
|
return;
|
|
20511
20563
|
}
|
|
20512
20564
|
const progressUpdate = sessionStateStore.trackContinuationProgress(sessionID, incompleteCount, todos);
|
|
20513
20565
|
if (shouldStopForStagnation({ sessionID, incompleteCount, progressUpdate })) {
|
|
20566
|
+
console.error(`[TODO-DIAG] BLOCKED: stagnation detected (count=${progressUpdate.stagnationCount})`);
|
|
20514
20567
|
return;
|
|
20515
20568
|
}
|
|
20569
|
+
console.error(`[TODO-DIAG] PASSED all gates! Starting countdown (${incompleteCount}/${todos.length} incomplete)`);
|
|
20516
20570
|
startCountdown({
|
|
20517
20571
|
ctx,
|
|
20518
20572
|
sessionID,
|
|
@@ -20603,6 +20657,9 @@ function createTodoContinuationHandler(args) {
|
|
|
20603
20657
|
} = args;
|
|
20604
20658
|
return async ({ event }) => {
|
|
20605
20659
|
const props = event.properties;
|
|
20660
|
+
if (event.type === "session.idle") {
|
|
20661
|
+
console.error(`[TODO-DIAG] handler received session.idle event`, { sessionID: props?.sessionID });
|
|
20662
|
+
}
|
|
20606
20663
|
if (event.type === "session.error") {
|
|
20607
20664
|
const sessionID = props?.sessionID;
|
|
20608
20665
|
if (!sessionID)
|
|
@@ -36324,6 +36381,15 @@ function takePendingCall(callID) {
|
|
|
36324
36381
|
import * as fs6 from "fs";
|
|
36325
36382
|
import { tmpdir as tmpdir4 } from "os";
|
|
36326
36383
|
import { join as join30 } from "path";
|
|
36384
|
+
var ApplyPatchMetadataSchema = zod_default.object({
|
|
36385
|
+
files: zod_default.array(zod_default.object({
|
|
36386
|
+
filePath: zod_default.string(),
|
|
36387
|
+
movePath: zod_default.string().optional(),
|
|
36388
|
+
before: zod_default.string(),
|
|
36389
|
+
after: zod_default.string(),
|
|
36390
|
+
type: zod_default.string().optional()
|
|
36391
|
+
}))
|
|
36392
|
+
});
|
|
36327
36393
|
var DEBUG3 = process.env.COMMENT_CHECKER_DEBUG === "1";
|
|
36328
36394
|
var DEBUG_FILE3 = join30(tmpdir4(), "comment-checker-debug.log");
|
|
36329
36395
|
function debugLog3(...args) {
|
|
@@ -36384,15 +36450,6 @@ function createCommentCheckerHooks(config2) {
|
|
|
36384
36450
|
debugLog3("skipping due to tool failure in output");
|
|
36385
36451
|
return;
|
|
36386
36452
|
}
|
|
36387
|
-
const ApplyPatchMetadataSchema = zod_default.object({
|
|
36388
|
-
files: zod_default.array(zod_default.object({
|
|
36389
|
-
filePath: zod_default.string(),
|
|
36390
|
-
movePath: zod_default.string().optional(),
|
|
36391
|
-
before: zod_default.string(),
|
|
36392
|
-
after: zod_default.string(),
|
|
36393
|
-
type: zod_default.string().optional()
|
|
36394
|
-
}))
|
|
36395
|
-
});
|
|
36396
36453
|
if (toolLower === "apply_patch") {
|
|
36397
36454
|
const parsed = ApplyPatchMetadataSchema.safeParse(output.metadata);
|
|
36398
36455
|
if (!parsed.success) {
|
|
@@ -36863,7 +36920,7 @@ function isTokenLimitError(text) {
|
|
|
36863
36920
|
return false;
|
|
36864
36921
|
}
|
|
36865
36922
|
const lower = text.toLowerCase();
|
|
36866
|
-
return TOKEN_LIMIT_KEYWORDS.some((kw) => lower.includes(kw
|
|
36923
|
+
return TOKEN_LIMIT_KEYWORDS.some((kw) => lower.includes(kw));
|
|
36867
36924
|
}
|
|
36868
36925
|
function parseAnthropicTokenLimitError(err) {
|
|
36869
36926
|
try {
|
|
@@ -38281,7 +38338,6 @@ function createAnthropicContextWindowLimitRecoveryHook(ctx, options) {
|
|
|
38281
38338
|
};
|
|
38282
38339
|
}
|
|
38283
38340
|
// src/hooks/think-mode/detector.ts
|
|
38284
|
-
var ENGLISH_PATTERNS = [/\bultrathink\b/i, /\bthink\b/i];
|
|
38285
38341
|
var MULTILINGUAL_KEYWORDS = [
|
|
38286
38342
|
"\uC0DD\uAC01",
|
|
38287
38343
|
"\uAC80\uD1A0",
|
|
@@ -38367,8 +38423,7 @@ var MULTILINGUAL_KEYWORDS = [
|
|
|
38367
38423
|
"fikir",
|
|
38368
38424
|
"berfikir"
|
|
38369
38425
|
];
|
|
38370
|
-
var
|
|
38371
|
-
var THINK_PATTERNS = [...ENGLISH_PATTERNS, ...MULTILINGUAL_PATTERNS];
|
|
38426
|
+
var COMBINED_THINK_PATTERN = new RegExp(`\\b(?:ultrathink|think)\\b|${MULTILINGUAL_KEYWORDS.join("|")}`, "i");
|
|
38372
38427
|
var CODE_BLOCK_PATTERN = /```[\s\S]*?```/g;
|
|
38373
38428
|
var INLINE_CODE_PATTERN = /`[^`]+`/g;
|
|
38374
38429
|
function removeCodeBlocks(text) {
|
|
@@ -38376,7 +38431,7 @@ function removeCodeBlocks(text) {
|
|
|
38376
38431
|
}
|
|
38377
38432
|
function detectThinkKeyword(text) {
|
|
38378
38433
|
const textWithoutCode = removeCodeBlocks(text);
|
|
38379
|
-
return
|
|
38434
|
+
return COMBINED_THINK_PATTERN.test(textWithoutCode);
|
|
38380
38435
|
}
|
|
38381
38436
|
function extractPromptText(parts) {
|
|
38382
38437
|
return parts.filter((p) => p.type === "text").map((p) => p.text || "").join("");
|
|
@@ -39033,16 +39088,16 @@ async function loadPluginExtendedConfig() {
|
|
|
39033
39088
|
}
|
|
39034
39089
|
return merged;
|
|
39035
39090
|
}
|
|
39036
|
-
var
|
|
39091
|
+
var regexCache2 = new Map;
|
|
39037
39092
|
function getRegex(pattern) {
|
|
39038
|
-
let regex =
|
|
39093
|
+
let regex = regexCache2.get(pattern);
|
|
39039
39094
|
if (!regex) {
|
|
39040
39095
|
try {
|
|
39041
39096
|
regex = new RegExp(pattern);
|
|
39042
|
-
|
|
39097
|
+
regexCache2.set(pattern, regex);
|
|
39043
39098
|
} catch {
|
|
39044
39099
|
regex = new RegExp(pattern.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"));
|
|
39045
|
-
|
|
39100
|
+
regexCache2.set(pattern, regex);
|
|
39046
39101
|
}
|
|
39047
39102
|
}
|
|
39048
39103
|
return regex;
|
|
@@ -39908,8 +39963,6 @@ function createToolExecuteAfterHandler(ctx, config2) {
|
|
|
39908
39963
|
if (!output) {
|
|
39909
39964
|
return;
|
|
39910
39965
|
}
|
|
39911
|
-
const claudeConfig = await loadClaudeHooksConfig();
|
|
39912
|
-
const extendedConfig = await loadPluginExtendedConfig();
|
|
39913
39966
|
const cachedInput = getToolInput(input.sessionID, input.tool, input.callID) || {};
|
|
39914
39967
|
appendTranscriptEntry(input.sessionID, {
|
|
39915
39968
|
type: "tool_result",
|
|
@@ -39921,6 +39974,8 @@ function createToolExecuteAfterHandler(ctx, config2) {
|
|
|
39921
39974
|
if (isHookDisabled(config2, "PostToolUse")) {
|
|
39922
39975
|
return;
|
|
39923
39976
|
}
|
|
39977
|
+
const claudeConfig = await loadClaudeHooksConfig();
|
|
39978
|
+
const extendedConfig = await loadPluginExtendedConfig();
|
|
39924
39979
|
const postClient = {
|
|
39925
39980
|
session: {
|
|
39926
39981
|
messages: (opts) => ctx.client.session.messages(opts)
|
|
@@ -40101,8 +40156,6 @@ function createToolExecuteBeforeHandler(ctx, config2) {
|
|
|
40101
40156
|
output.args.todos = parsed;
|
|
40102
40157
|
log("todowrite: parsed todos string to array", { sessionID: input.sessionID });
|
|
40103
40158
|
}
|
|
40104
|
-
const claudeConfig = await loadClaudeHooksConfig();
|
|
40105
|
-
const extendedConfig = await loadPluginExtendedConfig();
|
|
40106
40159
|
appendTranscriptEntry(input.sessionID, {
|
|
40107
40160
|
type: "tool_use",
|
|
40108
40161
|
timestamp: new Date().toISOString(),
|
|
@@ -40113,6 +40166,8 @@ function createToolExecuteBeforeHandler(ctx, config2) {
|
|
|
40113
40166
|
if (isHookDisabled(config2, "PreToolUse")) {
|
|
40114
40167
|
return;
|
|
40115
40168
|
}
|
|
40169
|
+
const claudeConfig = await loadClaudeHooksConfig();
|
|
40170
|
+
const extendedConfig = await loadPluginExtendedConfig();
|
|
40116
40171
|
const preCtx = {
|
|
40117
40172
|
sessionId: input.sessionID,
|
|
40118
40173
|
toolName: input.tool,
|
|
@@ -47544,8 +47599,7 @@ var BabysittingConfigSchema = exports_external.object({
|
|
|
47544
47599
|
var CircuitBreakerConfigSchema = exports_external.object({
|
|
47545
47600
|
enabled: exports_external.boolean().optional(),
|
|
47546
47601
|
maxToolCalls: exports_external.number().int().min(10).optional(),
|
|
47547
|
-
|
|
47548
|
-
repetitionThresholdPercent: exports_external.number().gt(0).max(100).optional()
|
|
47602
|
+
consecutiveThreshold: exports_external.number().int().min(5).optional()
|
|
47549
47603
|
});
|
|
47550
47604
|
var BackgroundTaskConfigSchema = exports_external.object({
|
|
47551
47605
|
defaultConcurrency: exports_external.number().min(1).optional(),
|
|
@@ -49640,9 +49694,6 @@ function skillToCommandInfo(skill) {
|
|
|
49640
49694
|
lazyContentLoader: skill.lazyContent
|
|
49641
49695
|
};
|
|
49642
49696
|
}
|
|
49643
|
-
function filterDiscoveredCommandsByScope(commands3, scope) {
|
|
49644
|
-
return commands3.filter((command) => command.scope === scope);
|
|
49645
|
-
}
|
|
49646
49697
|
async function discoverAllCommands(options) {
|
|
49647
49698
|
const discoveredCommands = discoverCommandsSync(process.cwd(), {
|
|
49648
49699
|
pluginsEnabled: options?.pluginsEnabled,
|
|
@@ -49650,14 +49701,17 @@ async function discoverAllCommands(options) {
|
|
|
49650
49701
|
});
|
|
49651
49702
|
const skills2 = options?.skills ?? await discoverAllSkills();
|
|
49652
49703
|
const skillCommands = skills2.map(skillToCommandInfo);
|
|
49704
|
+
const scopeOrder = ["project", "user", "opencode-project", "opencode", "builtin", "plugin"];
|
|
49705
|
+
const grouped = new Map;
|
|
49706
|
+
for (const cmd of discoveredCommands) {
|
|
49707
|
+
const list = grouped.get(cmd.scope) ?? [];
|
|
49708
|
+
list.push(cmd);
|
|
49709
|
+
grouped.set(cmd.scope, list);
|
|
49710
|
+
}
|
|
49711
|
+
const orderedCommands = scopeOrder.flatMap((scope) => grouped.get(scope) ?? []);
|
|
49653
49712
|
return [
|
|
49654
49713
|
...skillCommands,
|
|
49655
|
-
...
|
|
49656
|
-
...filterDiscoveredCommandsByScope(discoveredCommands, "user"),
|
|
49657
|
-
...filterDiscoveredCommandsByScope(discoveredCommands, "opencode-project"),
|
|
49658
|
-
...filterDiscoveredCommandsByScope(discoveredCommands, "opencode"),
|
|
49659
|
-
...filterDiscoveredCommandsByScope(discoveredCommands, "builtin"),
|
|
49660
|
-
...filterDiscoveredCommandsByScope(discoveredCommands, "plugin")
|
|
49714
|
+
...orderedCommands
|
|
49661
49715
|
];
|
|
49662
49716
|
}
|
|
49663
49717
|
async function findCommand2(commandName, options) {
|
|
@@ -53418,6 +53472,7 @@ function getErrorMessage2(error48) {
|
|
|
53418
53472
|
return "";
|
|
53419
53473
|
}
|
|
53420
53474
|
}
|
|
53475
|
+
var DEFAULT_RETRY_PATTERN = new RegExp(`\\b(${DEFAULT_CONFIG2.retry_on_errors.join("|")})\\b`);
|
|
53421
53476
|
function extractStatusCode(error48, retryOnErrors) {
|
|
53422
53477
|
if (!error48)
|
|
53423
53478
|
return;
|
|
@@ -53432,8 +53487,7 @@ function extractStatusCode(error48, retryOnErrors) {
|
|
|
53432
53487
|
if (statusCode !== undefined) {
|
|
53433
53488
|
return statusCode;
|
|
53434
53489
|
}
|
|
53435
|
-
const
|
|
53436
|
-
const pattern = new RegExp(`\\b(${codes.join("|")})\\b`);
|
|
53490
|
+
const pattern = retryOnErrors ? new RegExp(`\\b(${retryOnErrors.join("|")})\\b`) : DEFAULT_RETRY_PATTERN;
|
|
53437
53491
|
const message = getErrorMessage2(error48);
|
|
53438
53492
|
const statusMatch = message.match(pattern);
|
|
53439
53493
|
if (statusMatch) {
|
|
@@ -54714,97 +54768,97 @@ function toImageDimensions(width, height) {
|
|
|
54714
54768
|
}
|
|
54715
54769
|
return { width, height };
|
|
54716
54770
|
}
|
|
54717
|
-
function parsePngDimensions(
|
|
54718
|
-
if (
|
|
54771
|
+
function parsePngDimensions(buffer2) {
|
|
54772
|
+
if (buffer2.length < 24) {
|
|
54719
54773
|
return null;
|
|
54720
54774
|
}
|
|
54721
|
-
const isPngSignature =
|
|
54722
|
-
if (!isPngSignature ||
|
|
54775
|
+
const isPngSignature = buffer2[0] === 137 && buffer2[1] === 80 && buffer2[2] === 78 && buffer2[3] === 71 && buffer2[4] === 13 && buffer2[5] === 10 && buffer2[6] === 26 && buffer2[7] === 10;
|
|
54776
|
+
if (!isPngSignature || buffer2.toString("ascii", 12, 16) !== "IHDR") {
|
|
54723
54777
|
return null;
|
|
54724
54778
|
}
|
|
54725
|
-
const width =
|
|
54726
|
-
const height =
|
|
54779
|
+
const width = buffer2.readUInt32BE(16);
|
|
54780
|
+
const height = buffer2.readUInt32BE(20);
|
|
54727
54781
|
return toImageDimensions(width, height);
|
|
54728
54782
|
}
|
|
54729
|
-
function parseGifDimensions(
|
|
54730
|
-
if (
|
|
54783
|
+
function parseGifDimensions(buffer2) {
|
|
54784
|
+
if (buffer2.length < 10) {
|
|
54731
54785
|
return null;
|
|
54732
54786
|
}
|
|
54733
|
-
if (
|
|
54787
|
+
if (buffer2.toString("ascii", 0, 4) !== "GIF8") {
|
|
54734
54788
|
return null;
|
|
54735
54789
|
}
|
|
54736
|
-
const width =
|
|
54737
|
-
const height =
|
|
54790
|
+
const width = buffer2.readUInt16LE(6);
|
|
54791
|
+
const height = buffer2.readUInt16LE(8);
|
|
54738
54792
|
return toImageDimensions(width, height);
|
|
54739
54793
|
}
|
|
54740
|
-
function parseJpegDimensions(
|
|
54741
|
-
if (
|
|
54794
|
+
function parseJpegDimensions(buffer2) {
|
|
54795
|
+
if (buffer2.length < 4 || buffer2[0] !== 255 || buffer2[1] !== 216) {
|
|
54742
54796
|
return null;
|
|
54743
54797
|
}
|
|
54744
54798
|
let offset = 2;
|
|
54745
|
-
while (offset <
|
|
54746
|
-
if (
|
|
54799
|
+
while (offset < buffer2.length) {
|
|
54800
|
+
if (buffer2[offset] !== 255) {
|
|
54747
54801
|
offset += 1;
|
|
54748
54802
|
continue;
|
|
54749
54803
|
}
|
|
54750
|
-
while (offset <
|
|
54804
|
+
while (offset < buffer2.length && buffer2[offset] === 255) {
|
|
54751
54805
|
offset += 1;
|
|
54752
54806
|
}
|
|
54753
|
-
if (offset >=
|
|
54807
|
+
if (offset >= buffer2.length) {
|
|
54754
54808
|
return null;
|
|
54755
54809
|
}
|
|
54756
|
-
const marker =
|
|
54810
|
+
const marker = buffer2[offset];
|
|
54757
54811
|
offset += 1;
|
|
54758
54812
|
if (marker === 217 || marker === 218) {
|
|
54759
54813
|
break;
|
|
54760
54814
|
}
|
|
54761
|
-
if (offset + 1 >=
|
|
54815
|
+
if (offset + 1 >= buffer2.length) {
|
|
54762
54816
|
return null;
|
|
54763
54817
|
}
|
|
54764
|
-
const segmentLength =
|
|
54818
|
+
const segmentLength = buffer2.readUInt16BE(offset);
|
|
54765
54819
|
if (segmentLength < 2) {
|
|
54766
54820
|
return null;
|
|
54767
54821
|
}
|
|
54768
|
-
if ((marker === 192 || marker === 194) && offset + 7 <
|
|
54769
|
-
const height =
|
|
54770
|
-
const width =
|
|
54822
|
+
if ((marker === 192 || marker === 194) && offset + 7 < buffer2.length) {
|
|
54823
|
+
const height = buffer2.readUInt16BE(offset + 3);
|
|
54824
|
+
const width = buffer2.readUInt16BE(offset + 5);
|
|
54771
54825
|
return toImageDimensions(width, height);
|
|
54772
54826
|
}
|
|
54773
54827
|
offset += segmentLength;
|
|
54774
54828
|
}
|
|
54775
54829
|
return null;
|
|
54776
54830
|
}
|
|
54777
|
-
function readUInt24LE(
|
|
54778
|
-
return
|
|
54831
|
+
function readUInt24LE(buffer2, offset) {
|
|
54832
|
+
return buffer2[offset] | buffer2[offset + 1] << 8 | buffer2[offset + 2] << 16;
|
|
54779
54833
|
}
|
|
54780
|
-
function parseWebpDimensions(
|
|
54781
|
-
if (
|
|
54834
|
+
function parseWebpDimensions(buffer2) {
|
|
54835
|
+
if (buffer2.length < 16) {
|
|
54782
54836
|
return null;
|
|
54783
54837
|
}
|
|
54784
|
-
if (
|
|
54838
|
+
if (buffer2.toString("ascii", 0, 4) !== "RIFF" || buffer2.toString("ascii", 8, 12) !== "WEBP") {
|
|
54785
54839
|
return null;
|
|
54786
54840
|
}
|
|
54787
|
-
const chunkType =
|
|
54841
|
+
const chunkType = buffer2.toString("ascii", 12, 16);
|
|
54788
54842
|
if (chunkType === "VP8 ") {
|
|
54789
|
-
if (
|
|
54843
|
+
if (buffer2[23] !== 157 || buffer2[24] !== 1 || buffer2[25] !== 42) {
|
|
54790
54844
|
return null;
|
|
54791
54845
|
}
|
|
54792
|
-
const width =
|
|
54793
|
-
const height =
|
|
54846
|
+
const width = buffer2.readUInt16LE(26) & 16383;
|
|
54847
|
+
const height = buffer2.readUInt16LE(28) & 16383;
|
|
54794
54848
|
return toImageDimensions(width, height);
|
|
54795
54849
|
}
|
|
54796
54850
|
if (chunkType === "VP8L") {
|
|
54797
|
-
if (
|
|
54851
|
+
if (buffer2.length < 25 || buffer2[20] !== 47) {
|
|
54798
54852
|
return null;
|
|
54799
54853
|
}
|
|
54800
|
-
const bits =
|
|
54854
|
+
const bits = buffer2.readUInt32LE(21);
|
|
54801
54855
|
const width = (bits & 16383) + 1;
|
|
54802
54856
|
const height = (bits >>> 14 & 16383) + 1;
|
|
54803
54857
|
return toImageDimensions(width, height);
|
|
54804
54858
|
}
|
|
54805
54859
|
if (chunkType === "VP8X") {
|
|
54806
|
-
const width = readUInt24LE(
|
|
54807
|
-
const height = readUInt24LE(
|
|
54860
|
+
const width = readUInt24LE(buffer2, 24) + 1;
|
|
54861
|
+
const height = readUInt24LE(buffer2, 27) + 1;
|
|
54808
54862
|
return toImageDimensions(width, height);
|
|
54809
54863
|
}
|
|
54810
54864
|
return null;
|
|
@@ -54819,22 +54873,22 @@ function parseImageDimensions(base64DataUrl, mimeType) {
|
|
|
54819
54873
|
return null;
|
|
54820
54874
|
}
|
|
54821
54875
|
const headerBase64 = rawBase64.length > HEADER_BASE64_CHARS ? rawBase64.slice(0, HEADER_BASE64_CHARS) : rawBase64;
|
|
54822
|
-
const
|
|
54823
|
-
if (
|
|
54876
|
+
const buffer2 = Buffer.from(headerBase64, "base64");
|
|
54877
|
+
if (buffer2.length === 0) {
|
|
54824
54878
|
return null;
|
|
54825
54879
|
}
|
|
54826
54880
|
const normalizedMime = mimeType.toLowerCase();
|
|
54827
54881
|
if (normalizedMime === "image/png") {
|
|
54828
|
-
return parsePngDimensions(
|
|
54882
|
+
return parsePngDimensions(buffer2);
|
|
54829
54883
|
}
|
|
54830
54884
|
if (normalizedMime === "image/gif") {
|
|
54831
|
-
return parseGifDimensions(
|
|
54885
|
+
return parseGifDimensions(buffer2);
|
|
54832
54886
|
}
|
|
54833
54887
|
if (normalizedMime === "image/jpeg" || normalizedMime === "image/jpg") {
|
|
54834
|
-
return parseJpegDimensions(
|
|
54888
|
+
return parseJpegDimensions(buffer2);
|
|
54835
54889
|
}
|
|
54836
54890
|
if (normalizedMime === "image/webp") {
|
|
54837
|
-
return parseWebpDimensions(
|
|
54891
|
+
return parseWebpDimensions(buffer2);
|
|
54838
54892
|
}
|
|
54839
54893
|
return null;
|
|
54840
54894
|
} catch {
|
|
@@ -73268,8 +73322,8 @@ function convertBase64ImageToJpeg(base64Data, mimeType) {
|
|
|
73268
73322
|
const tempFiles = [inputPath];
|
|
73269
73323
|
try {
|
|
73270
73324
|
const cleanBase64 = base64Data.replace(/^data:[^;]+;base64,/, "");
|
|
73271
|
-
const
|
|
73272
|
-
writeFileSync19(inputPath,
|
|
73325
|
+
const buffer2 = Buffer.from(cleanBase64, "base64");
|
|
73326
|
+
writeFileSync19(inputPath, buffer2);
|
|
73273
73327
|
log(`[image-converter] Converting Base64 ${mimeType} to JPEG`);
|
|
73274
73328
|
const outputPath = convertImageToJpeg(inputPath, mimeType);
|
|
73275
73329
|
tempFiles.push(outputPath);
|
|
@@ -75738,10 +75792,11 @@ Returns summary format: id, subject, status, owner, blockedBy (not full descript
|
|
|
75738
75792
|
allTasks.push(task);
|
|
75739
75793
|
}
|
|
75740
75794
|
}
|
|
75795
|
+
const taskMap = new Map(allTasks.map((t) => [t.id, t]));
|
|
75741
75796
|
const activeTasks = allTasks.filter((task) => task.status !== "completed" && task.status !== "deleted");
|
|
75742
75797
|
const summaries = activeTasks.map((task) => {
|
|
75743
75798
|
const unresolvedBlockers = task.blockedBy.filter((blockerId) => {
|
|
75744
|
-
const blockerTask =
|
|
75799
|
+
const blockerTask = taskMap.get(blockerId);
|
|
75745
75800
|
return !blockerTask || blockerTask.status !== "completed";
|
|
75746
75801
|
});
|
|
75747
75802
|
return {
|
|
@@ -76430,6 +76485,15 @@ function applyPrepend(lines, text) {
|
|
|
76430
76485
|
}
|
|
76431
76486
|
|
|
76432
76487
|
// src/tools/hashline-edit/edit-operations.ts
|
|
76488
|
+
function arraysEqual(a, b) {
|
|
76489
|
+
if (a.length !== b.length)
|
|
76490
|
+
return false;
|
|
76491
|
+
for (let i2 = 0;i2 < a.length; i2++) {
|
|
76492
|
+
if (a[i2] !== b[i2])
|
|
76493
|
+
return false;
|
|
76494
|
+
}
|
|
76495
|
+
return true;
|
|
76496
|
+
}
|
|
76433
76497
|
function applyHashlineEditsWithReport(content, edits) {
|
|
76434
76498
|
if (edits.length === 0) {
|
|
76435
76499
|
return {
|
|
@@ -76459,9 +76523,7 @@ function applyHashlineEditsWithReport(content, edits) {
|
|
|
76459
76523
|
switch (edit.op) {
|
|
76460
76524
|
case "replace": {
|
|
76461
76525
|
const next = edit.end ? applyReplaceLines(lines, edit.pos, edit.end, edit.lines, { skipValidation: true }) : applySetLine(lines, edit.pos, edit.lines, { skipValidation: true });
|
|
76462
|
-
if (next
|
|
76463
|
-
`) === lines.join(`
|
|
76464
|
-
`)) {
|
|
76526
|
+
if (arraysEqual(next, lines)) {
|
|
76465
76527
|
noopEdits += 1;
|
|
76466
76528
|
break;
|
|
76467
76529
|
}
|
|
@@ -76470,9 +76532,7 @@ function applyHashlineEditsWithReport(content, edits) {
|
|
|
76470
76532
|
}
|
|
76471
76533
|
case "append": {
|
|
76472
76534
|
const next = edit.pos ? applyInsertAfter(lines, edit.pos, edit.lines, { skipValidation: true }) : applyAppend(lines, edit.lines);
|
|
76473
|
-
if (next
|
|
76474
|
-
`) === lines.join(`
|
|
76475
|
-
`)) {
|
|
76535
|
+
if (arraysEqual(next, lines)) {
|
|
76476
76536
|
noopEdits += 1;
|
|
76477
76537
|
break;
|
|
76478
76538
|
}
|
|
@@ -76481,9 +76541,7 @@ function applyHashlineEditsWithReport(content, edits) {
|
|
|
76481
76541
|
}
|
|
76482
76542
|
case "prepend": {
|
|
76483
76543
|
const next = edit.pos ? applyInsertBefore(lines, edit.pos, edit.lines, { skipValidation: true }) : applyPrepend(lines, edit.lines);
|
|
76484
|
-
if (next
|
|
76485
|
-
`) === lines.join(`
|
|
76486
|
-
`)) {
|
|
76544
|
+
if (arraysEqual(next, lines)) {
|
|
76487
76545
|
noopEdits += 1;
|
|
76488
76546
|
break;
|
|
76489
76547
|
}
|
|
@@ -78048,8 +78106,7 @@ var MIN_STABILITY_TIME_MS2 = 10 * 1000;
|
|
|
78048
78106
|
var DEFAULT_STALE_TIMEOUT_MS = 1200000;
|
|
78049
78107
|
var DEFAULT_MESSAGE_STALENESS_TIMEOUT_MS = 1800000;
|
|
78050
78108
|
var DEFAULT_MAX_TOOL_CALLS = 200;
|
|
78051
|
-
var
|
|
78052
|
-
var DEFAULT_CIRCUIT_BREAKER_REPETITION_THRESHOLD_PERCENT = 80;
|
|
78109
|
+
var DEFAULT_CIRCUIT_BREAKER_CONSECUTIVE_THRESHOLD = 20;
|
|
78053
78110
|
var DEFAULT_CIRCUIT_BREAKER_ENABLED = true;
|
|
78054
78111
|
var MIN_RUNTIME_BEFORE_STALE_MS = 30000;
|
|
78055
78112
|
var MIN_IDLE_TIME_MS = 5000;
|
|
@@ -78471,6 +78528,22 @@ function removeTaskToastTracking(taskId) {
|
|
|
78471
78528
|
}
|
|
78472
78529
|
}
|
|
78473
78530
|
|
|
78531
|
+
// src/features/background-agent/session-status-classifier.ts
|
|
78532
|
+
var ACTIVE_SESSION_STATUSES = new Set(["busy", "retry", "running"]);
|
|
78533
|
+
var KNOWN_TERMINAL_STATUSES = new Set(["idle", "interrupted"]);
|
|
78534
|
+
function isActiveSessionStatus(type2) {
|
|
78535
|
+
if (ACTIVE_SESSION_STATUSES.has(type2)) {
|
|
78536
|
+
return true;
|
|
78537
|
+
}
|
|
78538
|
+
if (!KNOWN_TERMINAL_STATUSES.has(type2)) {
|
|
78539
|
+
log("[background-agent] Unknown session status type encountered:", type2);
|
|
78540
|
+
}
|
|
78541
|
+
return false;
|
|
78542
|
+
}
|
|
78543
|
+
function isTerminalSessionStatus(type2) {
|
|
78544
|
+
return KNOWN_TERMINAL_STATUSES.has(type2) && type2 !== "idle";
|
|
78545
|
+
}
|
|
78546
|
+
|
|
78474
78547
|
// src/features/background-agent/task-poller.ts
|
|
78475
78548
|
var TERMINAL_TASK_STATUSES = new Set([
|
|
78476
78549
|
"completed",
|
|
@@ -78549,7 +78622,7 @@ async function checkAndInterruptStaleTasks(args) {
|
|
|
78549
78622
|
if (!startedAt || !sessionID)
|
|
78550
78623
|
continue;
|
|
78551
78624
|
const sessionStatus = sessionStatuses?.[sessionID]?.type;
|
|
78552
|
-
const sessionIsRunning = sessionStatus !== undefined && sessionStatus
|
|
78625
|
+
const sessionIsRunning = sessionStatus !== undefined && isActiveSessionStatus(sessionStatus);
|
|
78553
78626
|
const runtime = now - startedAt.getTime();
|
|
78554
78627
|
if (!task.progress?.lastUpdate) {
|
|
78555
78628
|
if (sessionIsRunning)
|
|
@@ -78607,18 +78680,22 @@ function resolveCircuitBreakerSettings(config4) {
|
|
|
78607
78680
|
return {
|
|
78608
78681
|
enabled: config4?.circuitBreaker?.enabled ?? DEFAULT_CIRCUIT_BREAKER_ENABLED,
|
|
78609
78682
|
maxToolCalls: config4?.circuitBreaker?.maxToolCalls ?? config4?.maxToolCalls ?? DEFAULT_MAX_TOOL_CALLS,
|
|
78610
|
-
|
|
78611
|
-
repetitionThresholdPercent: config4?.circuitBreaker?.repetitionThresholdPercent ?? DEFAULT_CIRCUIT_BREAKER_REPETITION_THRESHOLD_PERCENT
|
|
78683
|
+
consecutiveThreshold: config4?.circuitBreaker?.consecutiveThreshold ?? DEFAULT_CIRCUIT_BREAKER_CONSECUTIVE_THRESHOLD
|
|
78612
78684
|
};
|
|
78613
78685
|
}
|
|
78614
78686
|
function recordToolCall(window, toolName, settings, toolInput) {
|
|
78615
|
-
const previous = window?.toolSignatures ?? [];
|
|
78616
78687
|
const signature = createToolCallSignature(toolName, toolInput);
|
|
78617
|
-
|
|
78688
|
+
if (window && window.lastSignature === signature) {
|
|
78689
|
+
return {
|
|
78690
|
+
lastSignature: signature,
|
|
78691
|
+
consecutiveCount: window.consecutiveCount + 1,
|
|
78692
|
+
threshold: settings.consecutiveThreshold
|
|
78693
|
+
};
|
|
78694
|
+
}
|
|
78618
78695
|
return {
|
|
78619
|
-
|
|
78620
|
-
|
|
78621
|
-
|
|
78696
|
+
lastSignature: signature,
|
|
78697
|
+
consecutiveCount: 1,
|
|
78698
|
+
threshold: settings.consecutiveThreshold
|
|
78622
78699
|
};
|
|
78623
78700
|
}
|
|
78624
78701
|
function sortObject2(obj) {
|
|
@@ -78645,36 +78722,13 @@ function createToolCallSignature(toolName, toolInput) {
|
|
|
78645
78722
|
return `${toolName}::${JSON.stringify(sortObject2(toolInput))}`;
|
|
78646
78723
|
}
|
|
78647
78724
|
function detectRepetitiveToolUse(window) {
|
|
78648
|
-
if (!window || window.
|
|
78649
|
-
return { triggered: false };
|
|
78650
|
-
}
|
|
78651
|
-
const counts = new Map;
|
|
78652
|
-
for (const signature of window.toolSignatures) {
|
|
78653
|
-
counts.set(signature, (counts.get(signature) ?? 0) + 1);
|
|
78654
|
-
}
|
|
78655
|
-
let repeatedTool;
|
|
78656
|
-
let repeatedCount = 0;
|
|
78657
|
-
for (const [toolName, count] of counts.entries()) {
|
|
78658
|
-
if (count > repeatedCount) {
|
|
78659
|
-
repeatedTool = toolName;
|
|
78660
|
-
repeatedCount = count;
|
|
78661
|
-
}
|
|
78662
|
-
}
|
|
78663
|
-
const sampleSize = window.toolSignatures.length;
|
|
78664
|
-
const minimumSampleSize = Math.min(window.windowSize, Math.ceil(window.windowSize * window.thresholdPercent / 100));
|
|
78665
|
-
if (sampleSize < minimumSampleSize) {
|
|
78666
|
-
return { triggered: false };
|
|
78667
|
-
}
|
|
78668
|
-
const thresholdCount = Math.ceil(sampleSize * window.thresholdPercent / 100);
|
|
78669
|
-
if (!repeatedTool || repeatedCount < thresholdCount) {
|
|
78725
|
+
if (!window || window.consecutiveCount < window.threshold) {
|
|
78670
78726
|
return { triggered: false };
|
|
78671
78727
|
}
|
|
78672
78728
|
return {
|
|
78673
78729
|
triggered: true,
|
|
78674
|
-
toolName:
|
|
78675
|
-
repeatedCount
|
|
78676
|
-
sampleSize,
|
|
78677
|
-
thresholdPercent: window.thresholdPercent
|
|
78730
|
+
toolName: window.lastSignature.split("::")[0],
|
|
78731
|
+
repeatedCount: window.consecutiveCount
|
|
78678
78732
|
};
|
|
78679
78733
|
}
|
|
78680
78734
|
|
|
@@ -78773,6 +78827,7 @@ class BackgroundManager {
|
|
|
78773
78827
|
preStartDescendantReservations;
|
|
78774
78828
|
enableParentSessionNotifications;
|
|
78775
78829
|
taskHistory = new TaskHistory;
|
|
78830
|
+
cachedCircuitBreakerSettings;
|
|
78776
78831
|
constructor(ctx, config4, options) {
|
|
78777
78832
|
this.tasks = new Map;
|
|
78778
78833
|
this.notifications = new Map;
|
|
@@ -79365,34 +79420,33 @@ class BackgroundManager {
|
|
|
79365
79420
|
}
|
|
79366
79421
|
task.progress.lastUpdate = new Date;
|
|
79367
79422
|
if (partInfo?.type === "tool" || partInfo?.tool) {
|
|
79368
|
-
const countedToolPartIDs = task.progress.countedToolPartIDs ??
|
|
79369
|
-
const shouldCountToolCall = !partInfo.id || partInfo.state?.status !== "running" || !countedToolPartIDs.
|
|
79423
|
+
const countedToolPartIDs = task.progress.countedToolPartIDs ?? new Set;
|
|
79424
|
+
const shouldCountToolCall = !partInfo.id || partInfo.state?.status !== "running" || !countedToolPartIDs.has(partInfo.id);
|
|
79370
79425
|
if (!shouldCountToolCall) {
|
|
79371
79426
|
return;
|
|
79372
79427
|
}
|
|
79373
79428
|
if (partInfo.id && partInfo.state?.status === "running") {
|
|
79374
|
-
|
|
79429
|
+
countedToolPartIDs.add(partInfo.id);
|
|
79430
|
+
task.progress.countedToolPartIDs = countedToolPartIDs;
|
|
79375
79431
|
}
|
|
79376
79432
|
task.progress.toolCalls += 1;
|
|
79377
79433
|
task.progress.lastTool = partInfo.tool;
|
|
79378
|
-
const circuitBreaker = resolveCircuitBreakerSettings(this.config);
|
|
79434
|
+
const circuitBreaker = this.cachedCircuitBreakerSettings ?? (this.cachedCircuitBreakerSettings = resolveCircuitBreakerSettings(this.config));
|
|
79379
79435
|
if (partInfo.tool) {
|
|
79380
79436
|
task.progress.toolCallWindow = recordToolCall(task.progress.toolCallWindow, partInfo.tool, circuitBreaker, partInfo.state?.input);
|
|
79381
79437
|
if (circuitBreaker.enabled) {
|
|
79382
79438
|
const loopDetection = detectRepetitiveToolUse(task.progress.toolCallWindow);
|
|
79383
79439
|
if (loopDetection.triggered) {
|
|
79384
|
-
log("[background-agent] Circuit breaker:
|
|
79440
|
+
log("[background-agent] Circuit breaker: consecutive tool usage detected", {
|
|
79385
79441
|
taskId: task.id,
|
|
79386
79442
|
agent: task.agent,
|
|
79387
79443
|
sessionID,
|
|
79388
79444
|
toolName: loopDetection.toolName,
|
|
79389
|
-
repeatedCount: loopDetection.repeatedCount
|
|
79390
|
-
sampleSize: loopDetection.sampleSize,
|
|
79391
|
-
thresholdPercent: loopDetection.thresholdPercent
|
|
79445
|
+
repeatedCount: loopDetection.repeatedCount
|
|
79392
79446
|
});
|
|
79393
79447
|
this.cancelTask(task.id, {
|
|
79394
79448
|
source: "circuit-breaker",
|
|
79395
|
-
reason: `Subagent
|
|
79449
|
+
reason: `Subagent called ${loopDetection.toolName} ${loopDetection.repeatedCount} consecutive times (threshold: ${circuitBreaker.consecutiveThreshold}). This usually indicates an infinite loop. The task was automatically cancelled to prevent excessive token usage.`
|
|
79396
79450
|
});
|
|
79397
79451
|
return;
|
|
79398
79452
|
}
|
|
@@ -80042,7 +80096,7 @@ Use \`background_output(task_id="${task.id}")\` to retrieve this result when rea
|
|
|
80042
80096
|
continue;
|
|
80043
80097
|
}
|
|
80044
80098
|
}
|
|
80045
|
-
if (sessionStatus && sessionStatus.type
|
|
80099
|
+
if (sessionStatus && isActiveSessionStatus(sessionStatus.type)) {
|
|
80046
80100
|
log("[background-agent] Session still running, relying on event-based progress:", {
|
|
80047
80101
|
taskId: task.id,
|
|
80048
80102
|
sessionID,
|
|
@@ -80051,6 +80105,17 @@ Use \`background_output(task_id="${task.id}")\` to retrieve this result when rea
|
|
|
80051
80105
|
});
|
|
80052
80106
|
continue;
|
|
80053
80107
|
}
|
|
80108
|
+
if (sessionStatus && isTerminalSessionStatus(sessionStatus.type)) {
|
|
80109
|
+
await this.tryCompleteTask(task, `polling (terminal session status: ${sessionStatus.type})`);
|
|
80110
|
+
continue;
|
|
80111
|
+
}
|
|
80112
|
+
if (sessionStatus && sessionStatus.type !== "idle") {
|
|
80113
|
+
log("[background-agent] Unknown session status, treating as potentially idle:", {
|
|
80114
|
+
taskId: task.id,
|
|
80115
|
+
sessionID,
|
|
80116
|
+
sessionStatus: sessionStatus.type
|
|
80117
|
+
});
|
|
80118
|
+
}
|
|
80054
80119
|
const completionSource = sessionStatus?.type === "idle" ? "polling (idle status)" : "polling (session gone from status)";
|
|
80055
80120
|
const hasValidOutput = await this.validateSessionHasOutput(sessionID);
|
|
80056
80121
|
if (!hasValidOutput) {
|
|
@@ -82707,8 +82772,8 @@ async function generateVerifier(length) {
|
|
|
82707
82772
|
return await random(length);
|
|
82708
82773
|
}
|
|
82709
82774
|
async function generateChallenge(code_verifier) {
|
|
82710
|
-
const
|
|
82711
|
-
return btoa(String.fromCharCode(...new Uint8Array(
|
|
82775
|
+
const buffer2 = await (await crypto3).subtle.digest("SHA-256", new TextEncoder().encode(code_verifier));
|
|
82776
|
+
return btoa(String.fromCharCode(...new Uint8Array(buffer2))).replace(/\//g, "_").replace(/\+/g, "-").replace(/=/g, "");
|
|
82712
82777
|
}
|
|
82713
82778
|
async function pkceChallenge(length) {
|
|
82714
82779
|
if (!length)
|
|
@@ -97809,10 +97874,7 @@ function createPluginInterface(args) {
|
|
|
97809
97874
|
const { ctx, pluginConfig, firstMessageVariantGate, managers, hooks: hooks2, tools } = args;
|
|
97810
97875
|
return {
|
|
97811
97876
|
tool: tools,
|
|
97812
|
-
"chat.params":
|
|
97813
|
-
const handler = createChatParamsHandler({ anthropicEffort: hooks2.anthropicEffort });
|
|
97814
|
-
await handler(input, output);
|
|
97815
|
-
},
|
|
97877
|
+
"chat.params": createChatParamsHandler({ anthropicEffort: hooks2.anthropicEffort }),
|
|
97816
97878
|
"chat.headers": createChatHeadersHandler({ ctx }),
|
|
97817
97879
|
"chat.message": createChatMessageHandler3({
|
|
97818
97880
|
ctx,
|