scream-code 0.10.1 → 0.10.3
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.md +2 -2
- package/dist/{app-DVRLAZ8b.mjs → app-DkhRwgvY.mjs} +1023 -712
- package/dist/base64-js-DzVmk6Nb.mjs +95 -0
- package/dist/{chunk-apG1qJts.mjs → chunk-D90kvbyJ.mjs} +2 -1
- package/dist/{dist-0bMQWc-B.mjs → dist-AcjRoBBn.mjs} +1 -1
- package/dist/{from-CKE2n10i.mjs → from-BMeHuTTE.mjs} +1 -1
- package/dist/main.mjs +1 -1
- package/dist/markit-DG5XsAGz.mjs +56336 -0
- package/dist/{multipart-parser-BxHsVgPe.mjs → multipart-parser-_uHCprmc.mjs} +2 -2
- package/dist/{src-Dae4j3bv.mjs → src-BMbOMRuY.mjs} +3 -3
- package/dist/{text-input-dialog-Dk5xzj4F.mjs → text-input-dialog-C8_8qYYi.mjs} +1 -1
- package/dist/{text-input-dialog-D_xK0DJH.mjs → text-input-dialog-Cj7OClhs.mjs} +0 -20
- package/package.json +3 -2
|
@@ -3,25 +3,27 @@ import { fileURLToPath as __cjsShimFileURLToPath } from 'node:url';
|
|
|
3
3
|
import { dirname as __cjsShimDirname } from 'node:path';
|
|
4
4
|
const __filename = __cjsShimFileURLToPath(import.meta.url);
|
|
5
5
|
const __dirname = __cjsShimDirname(__filename);
|
|
6
|
-
import {
|
|
6
|
+
import { i as __require, o as __toESM, r as __exportAll, t as __commonJSMin } from "./chunk-D90kvbyJ.mjs";
|
|
7
7
|
import "./suppress-sqlite-warning-C2VB0doZ.mjs";
|
|
8
8
|
import { C as join$1, D as resolve$1, E as relative$1, S as isAbsolute$1, T as parse$7, a as isSupportedFile, b as basename$1, i as ingestFile, r as ingestDirectory, t as multiSearch, w as normalize, x as dirname$2, y as KnowledgeStore } from "./src-oeUnRY3N.mjs";
|
|
9
|
-
import {
|
|
9
|
+
import { t as require_base64_js } from "./base64-js-DzVmk6Nb.mjs";
|
|
10
|
+
import { a as setLocale, i as getLocale, n as assertScreamHostIdentity, o as t, r as createScreamDefaultHeaders, t as TextInputDialogComponent } from "./text-input-dialog-Cj7OClhs.mjs";
|
|
10
11
|
import { createRequire } from "node:module";
|
|
11
12
|
import { createHash, randomBytes, randomInt, randomUUID } from "node:crypto";
|
|
13
|
+
import * as fs$1 from "node:fs/promises";
|
|
12
14
|
import Jn, { access, appendFile, chmod, copyFile, cp, lstat, mkdir, mkdtemp, open, readFile, readdir, realpath, rename, rm, rmdir, stat, unlink, writeFile } from "node:fs/promises";
|
|
13
15
|
import I, { createWriteStream } from "fs";
|
|
14
16
|
import Vr, { EventEmitter } from "events";
|
|
15
17
|
import * as path$1$1 from "path";
|
|
16
18
|
import Xs, { dirname, parse } from "path";
|
|
17
19
|
import { Buffer as Buffer$1 } from "buffer";
|
|
18
|
-
import * as fs$
|
|
20
|
+
import * as fs$11 from "fs/promises";
|
|
19
21
|
import { writeFile as writeFile$1 } from "fs/promises";
|
|
20
22
|
import Ds, { PassThrough, Readable } from "node:stream";
|
|
21
23
|
import { finished, pipeline as pipeline$1 } from "node:stream/promises";
|
|
22
24
|
import * as vs from "zlib";
|
|
23
25
|
import Qr from "zlib";
|
|
24
|
-
import * as fs$
|
|
26
|
+
import * as fs$10 from "node:fs";
|
|
25
27
|
import Vt, { appendFileSync, chmodSync, closeSync, constants, createReadStream, createWriteStream as createWriteStream$1, existsSync, fsyncSync, mkdirSync, openSync, promises, readFileSync, readSync, realpathSync, renameSync, rmSync, statSync, unlinkSync, writeFileSync, writeSync } from "node:fs";
|
|
26
28
|
import * as path$8 from "node:path";
|
|
27
29
|
import path, { basename, dirname as dirname$1, extname, isAbsolute, join, posix, relative, resolve, sep, win32 } from "node:path";
|
|
@@ -684,6 +686,38 @@ var APIProviderRateLimitError = class extends APIStatusError {
|
|
|
684
686
|
}
|
|
685
687
|
};
|
|
686
688
|
/**
|
|
689
|
+
* HTTP status error meaning the conversation history sent to the provider
|
|
690
|
+
* has orphaned tool calls (an assistant `tool_calls` block whose matching
|
|
691
|
+
* tool results are missing). Recoverable only by rebuilding the history —
|
|
692
|
+
* retrying the same request always fails. Carried as a distinct class so
|
|
693
|
+
* callers can reset the session on THIS kind alone instead of sniffing
|
|
694
|
+
* error message text.
|
|
695
|
+
*/
|
|
696
|
+
var APIOrphanedToolCallError = class extends APIStatusError {
|
|
697
|
+
constructor(statusCode, message, requestId) {
|
|
698
|
+
super(statusCode, message, requestId);
|
|
699
|
+
this.name = "APIOrphanedToolCallError";
|
|
700
|
+
}
|
|
701
|
+
};
|
|
702
|
+
/**
|
|
703
|
+
* Message-text parity check shared by normalizeAPIStatusError and
|
|
704
|
+
* isOrphanedToolCallError. Mirrors the historical two-includes semantics:
|
|
705
|
+
* the fragments may appear in any order.
|
|
706
|
+
*/
|
|
707
|
+
function isOrphanedToolCallMessage(lowerMessage) {
|
|
708
|
+
return lowerMessage.includes("insufficient tool messages") || lowerMessage.includes("tool_calls") && lowerMessage.includes("followed by tool messages");
|
|
709
|
+
}
|
|
710
|
+
/**
|
|
711
|
+
* True when an error signals orphaned tool calls in the request history.
|
|
712
|
+
* instanceof is checked first (provider threw the typed error); the message
|
|
713
|
+
* patterns are the fallback for errors that crossed wrapping boundaries
|
|
714
|
+
* (session/RPC layers re-wrapping the provider error).
|
|
715
|
+
*/
|
|
716
|
+
function isOrphanedToolCallError(error) {
|
|
717
|
+
if (error instanceof APIOrphanedToolCallError) return true;
|
|
718
|
+
return isOrphanedToolCallMessage(errorMessage$5(error).toLowerCase());
|
|
719
|
+
}
|
|
720
|
+
/**
|
|
687
721
|
* The API returned an empty response (no content, no tool calls).
|
|
688
722
|
*/
|
|
689
723
|
var APIEmptyResponseError = class extends ChatProviderError {
|
|
@@ -720,6 +754,7 @@ function isContextOverflowErrorCode(code) {
|
|
|
720
754
|
function normalizeAPIStatusError(statusCode, message, requestId) {
|
|
721
755
|
if (statusCode === 429) return new APIProviderRateLimitError(message, requestId, parseRateLimitReason(message));
|
|
722
756
|
if (isContextOverflowStatusError(statusCode, message)) return new APIContextOverflowError(statusCode, message, requestId);
|
|
757
|
+
if (statusCode === 400 && isOrphanedToolCallMessage(message.toLowerCase())) return new APIOrphanedToolCallError(statusCode, message, requestId);
|
|
723
758
|
return new APIStatusError(statusCode, message, requestId);
|
|
724
759
|
}
|
|
725
760
|
function isContextOverflowStatusError(statusCode, message) {
|
|
@@ -727,6 +762,9 @@ function isContextOverflowStatusError(statusCode, message) {
|
|
|
727
762
|
const lowerMessage = message.toLowerCase();
|
|
728
763
|
return CONTEXT_OVERFLOW_MESSAGE_PATTERNS.some((pattern) => pattern.test(lowerMessage));
|
|
729
764
|
}
|
|
765
|
+
function errorMessage$5(error) {
|
|
766
|
+
return error instanceof Error ? error.message : String(error);
|
|
767
|
+
}
|
|
730
768
|
//#endregion
|
|
731
769
|
//#region ../../packages/ltod/src/providers/tool-call-id.ts
|
|
732
770
|
const EMPTY_TOOL_CALL_ID = "tool_call";
|
|
@@ -10293,12 +10331,12 @@ var require_gaxios = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
10293
10331
|
* @returns A proxy agent
|
|
10294
10332
|
*/
|
|
10295
10333
|
static async #getProxyAgent() {
|
|
10296
|
-
this.#proxyAgent ||= (await import("./dist-
|
|
10334
|
+
this.#proxyAgent ||= (await import("./dist-AcjRoBBn.mjs").then((m) => /* @__PURE__ */ __toESM(m.default))).HttpsProxyAgent;
|
|
10297
10335
|
return this.#proxyAgent;
|
|
10298
10336
|
}
|
|
10299
10337
|
static async #getFetch() {
|
|
10300
10338
|
const hasWindow = typeof window !== "undefined" && !!window;
|
|
10301
|
-
this.#fetch ||= hasWindow ? window.fetch : (await import("./src-
|
|
10339
|
+
this.#fetch ||= hasWindow ? window.fetch : (await import("./src-BMbOMRuY.mjs")).default;
|
|
10302
10340
|
return this.#fetch;
|
|
10303
10341
|
}
|
|
10304
10342
|
/**
|
|
@@ -12752,94 +12790,6 @@ var require_src$1 = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
12752
12790
|
__exportStar(require_gcp_residency(), exports);
|
|
12753
12791
|
}));
|
|
12754
12792
|
//#endregion
|
|
12755
|
-
//#region ../../node_modules/.pnpm/base64-js@1.5.1/node_modules/base64-js/index.js
|
|
12756
|
-
var require_base64_js = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
12757
|
-
exports.byteLength = byteLength;
|
|
12758
|
-
exports.toByteArray = toByteArray;
|
|
12759
|
-
exports.fromByteArray = fromByteArray;
|
|
12760
|
-
var lookup = [];
|
|
12761
|
-
var revLookup = [];
|
|
12762
|
-
var Arr = typeof Uint8Array !== "undefined" ? Uint8Array : Array;
|
|
12763
|
-
var code = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
12764
|
-
for (var i = 0, len = code.length; i < len; ++i) {
|
|
12765
|
-
lookup[i] = code[i];
|
|
12766
|
-
revLookup[code.charCodeAt(i)] = i;
|
|
12767
|
-
}
|
|
12768
|
-
revLookup["-".charCodeAt(0)] = 62;
|
|
12769
|
-
revLookup["_".charCodeAt(0)] = 63;
|
|
12770
|
-
function getLens(b64) {
|
|
12771
|
-
var len = b64.length;
|
|
12772
|
-
if (len % 4 > 0) throw new Error("Invalid string. Length must be a multiple of 4");
|
|
12773
|
-
var validLen = b64.indexOf("=");
|
|
12774
|
-
if (validLen === -1) validLen = len;
|
|
12775
|
-
var placeHoldersLen = validLen === len ? 0 : 4 - validLen % 4;
|
|
12776
|
-
return [validLen, placeHoldersLen];
|
|
12777
|
-
}
|
|
12778
|
-
function byteLength(b64) {
|
|
12779
|
-
var lens = getLens(b64);
|
|
12780
|
-
var validLen = lens[0];
|
|
12781
|
-
var placeHoldersLen = lens[1];
|
|
12782
|
-
return (validLen + placeHoldersLen) * 3 / 4 - placeHoldersLen;
|
|
12783
|
-
}
|
|
12784
|
-
function _byteLength(b64, validLen, placeHoldersLen) {
|
|
12785
|
-
return (validLen + placeHoldersLen) * 3 / 4 - placeHoldersLen;
|
|
12786
|
-
}
|
|
12787
|
-
function toByteArray(b64) {
|
|
12788
|
-
var tmp;
|
|
12789
|
-
var lens = getLens(b64);
|
|
12790
|
-
var validLen = lens[0];
|
|
12791
|
-
var placeHoldersLen = lens[1];
|
|
12792
|
-
var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen));
|
|
12793
|
-
var curByte = 0;
|
|
12794
|
-
var len = placeHoldersLen > 0 ? validLen - 4 : validLen;
|
|
12795
|
-
var i;
|
|
12796
|
-
for (i = 0; i < len; i += 4) {
|
|
12797
|
-
tmp = revLookup[b64.charCodeAt(i)] << 18 | revLookup[b64.charCodeAt(i + 1)] << 12 | revLookup[b64.charCodeAt(i + 2)] << 6 | revLookup[b64.charCodeAt(i + 3)];
|
|
12798
|
-
arr[curByte++] = tmp >> 16 & 255;
|
|
12799
|
-
arr[curByte++] = tmp >> 8 & 255;
|
|
12800
|
-
arr[curByte++] = tmp & 255;
|
|
12801
|
-
}
|
|
12802
|
-
if (placeHoldersLen === 2) {
|
|
12803
|
-
tmp = revLookup[b64.charCodeAt(i)] << 2 | revLookup[b64.charCodeAt(i + 1)] >> 4;
|
|
12804
|
-
arr[curByte++] = tmp & 255;
|
|
12805
|
-
}
|
|
12806
|
-
if (placeHoldersLen === 1) {
|
|
12807
|
-
tmp = revLookup[b64.charCodeAt(i)] << 10 | revLookup[b64.charCodeAt(i + 1)] << 4 | revLookup[b64.charCodeAt(i + 2)] >> 2;
|
|
12808
|
-
arr[curByte++] = tmp >> 8 & 255;
|
|
12809
|
-
arr[curByte++] = tmp & 255;
|
|
12810
|
-
}
|
|
12811
|
-
return arr;
|
|
12812
|
-
}
|
|
12813
|
-
function tripletToBase64(num) {
|
|
12814
|
-
return lookup[num >> 18 & 63] + lookup[num >> 12 & 63] + lookup[num >> 6 & 63] + lookup[num & 63];
|
|
12815
|
-
}
|
|
12816
|
-
function encodeChunk(uint8, start, end) {
|
|
12817
|
-
var tmp;
|
|
12818
|
-
var output = [];
|
|
12819
|
-
for (var i = start; i < end; i += 3) {
|
|
12820
|
-
tmp = (uint8[i] << 16 & 16711680) + (uint8[i + 1] << 8 & 65280) + (uint8[i + 2] & 255);
|
|
12821
|
-
output.push(tripletToBase64(tmp));
|
|
12822
|
-
}
|
|
12823
|
-
return output.join("");
|
|
12824
|
-
}
|
|
12825
|
-
function fromByteArray(uint8) {
|
|
12826
|
-
var tmp;
|
|
12827
|
-
var len = uint8.length;
|
|
12828
|
-
var extraBytes = len % 3;
|
|
12829
|
-
var parts = [];
|
|
12830
|
-
var maxChunkLength = 16383;
|
|
12831
|
-
for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) parts.push(encodeChunk(uint8, i, i + maxChunkLength > len2 ? len2 : i + maxChunkLength));
|
|
12832
|
-
if (extraBytes === 1) {
|
|
12833
|
-
tmp = uint8[len - 1];
|
|
12834
|
-
parts.push(lookup[tmp >> 2] + lookup[tmp << 4 & 63] + "==");
|
|
12835
|
-
} else if (extraBytes === 2) {
|
|
12836
|
-
tmp = (uint8[len - 2] << 8) + uint8[len - 1];
|
|
12837
|
-
parts.push(lookup[tmp >> 10] + lookup[tmp >> 4 & 63] + lookup[tmp << 2 & 63] + "=");
|
|
12838
|
-
}
|
|
12839
|
-
return parts.join("");
|
|
12840
|
-
}
|
|
12841
|
-
}));
|
|
12842
|
-
//#endregion
|
|
12843
12793
|
//#region ../../node_modules/.pnpm/google-auth-library@10.6.2/node_modules/google-auth-library/build/src/crypto/shared.js
|
|
12844
12794
|
var require_shared$1 = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
12845
12795
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -13207,7 +13157,7 @@ var require_util$1 = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
13207
13157
|
exports.removeUndefinedValuesInObject = removeUndefinedValuesInObject;
|
|
13208
13158
|
exports.isValidFile = isValidFile;
|
|
13209
13159
|
exports.getWellKnownCertificateConfigFileLocation = getWellKnownCertificateConfigFileLocation;
|
|
13210
|
-
const fs$
|
|
13160
|
+
const fs$17 = __require("fs");
|
|
13211
13161
|
const os$2 = __require("os");
|
|
13212
13162
|
const path$13 = __require("path");
|
|
13213
13163
|
const WELL_KNOWN_CERTIFICATE_CONFIG_FILE = "certificate_config.json";
|
|
@@ -13327,7 +13277,7 @@ var require_util$1 = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
13327
13277
|
*/
|
|
13328
13278
|
async function isValidFile(filePath) {
|
|
13329
13279
|
try {
|
|
13330
|
-
return (await fs$
|
|
13280
|
+
return (await fs$17.promises.lstat(filePath)).isFile();
|
|
13331
13281
|
} catch (e) {
|
|
13332
13282
|
return false;
|
|
13333
13283
|
}
|
|
@@ -15041,10 +14991,10 @@ var require_getCredentials = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
15041
14991
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15042
14992
|
exports.getCredentials = getCredentials;
|
|
15043
14993
|
const path$12 = __require("path");
|
|
15044
|
-
const fs$
|
|
14994
|
+
const fs$16 = __require("fs");
|
|
15045
14995
|
const util_1$1 = __require("util");
|
|
15046
14996
|
const errorWithCode_1 = require_errorWithCode();
|
|
15047
|
-
const readFile = fs$
|
|
14997
|
+
const readFile = fs$16.readFile ? (0, util_1$1.promisify)(fs$16.readFile) : async () => {
|
|
15048
14998
|
throw new errorWithCode_1.ErrorWithCode("use key rather than keyFile.", "MISSING_CREDENTIALS");
|
|
15049
14999
|
};
|
|
15050
15000
|
var ExtensionFiles;
|
|
@@ -16592,10 +16542,10 @@ var require_filesubjecttokensupplier = /* @__PURE__ */ __commonJSMin(((exports)
|
|
|
16592
16542
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16593
16543
|
exports.FileSubjectTokenSupplier = void 0;
|
|
16594
16544
|
const util_1 = __require("util");
|
|
16595
|
-
const fs$
|
|
16596
|
-
const readFile = (0, util_1.promisify)(fs$
|
|
16597
|
-
const realpath = (0, util_1.promisify)(fs$
|
|
16598
|
-
const lstat = (0, util_1.promisify)(fs$
|
|
16545
|
+
const fs$15 = __require("fs");
|
|
16546
|
+
const readFile = (0, util_1.promisify)(fs$15.readFile ?? (() => {}));
|
|
16547
|
+
const realpath = (0, util_1.promisify)(fs$15.realpath ?? (() => {}));
|
|
16548
|
+
const lstat = (0, util_1.promisify)(fs$15.lstat ?? (() => {}));
|
|
16599
16549
|
/**
|
|
16600
16550
|
* Internal subject token supplier implementation used when a file location
|
|
16601
16551
|
* is configured in the credential configuration used to build an {@link IdentityPoolClient}
|
|
@@ -16697,7 +16647,7 @@ var require_certificatesubjecttokensupplier = /* @__PURE__ */ __commonJSMin(((ex
|
|
|
16697
16647
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16698
16648
|
exports.CertificateSubjectTokenSupplier = exports.InvalidConfigurationError = exports.CertificateSourceUnavailableError = exports.CERTIFICATE_CONFIGURATION_ENV_VARIABLE = void 0;
|
|
16699
16649
|
const util_1 = require_util$1();
|
|
16700
|
-
const fs$
|
|
16650
|
+
const fs$14 = __require("fs");
|
|
16701
16651
|
const crypto_1 = __require("crypto");
|
|
16702
16652
|
const https$1 = __require("https");
|
|
16703
16653
|
exports.CERTIFICATE_CONFIGURATION_ENV_VARIABLE = "GOOGLE_API_CERTIFICATE_CONFIG";
|
|
@@ -16792,7 +16742,7 @@ var require_certificatesubjecttokensupplier = /* @__PURE__ */ __commonJSMin(((ex
|
|
|
16792
16742
|
const configPath = this.certificateConfigPath;
|
|
16793
16743
|
let fileContents;
|
|
16794
16744
|
try {
|
|
16795
|
-
fileContents = await fs$
|
|
16745
|
+
fileContents = await fs$14.promises.readFile(configPath, "utf8");
|
|
16796
16746
|
} catch (err) {
|
|
16797
16747
|
throw new CertificateSourceUnavailableError(`Failed to read certificate config file at: ${configPath}`);
|
|
16798
16748
|
}
|
|
@@ -16817,13 +16767,13 @@ var require_certificatesubjecttokensupplier = /* @__PURE__ */ __commonJSMin(((ex
|
|
|
16817
16767
|
async #getKeyAndCert(certPath, keyPath) {
|
|
16818
16768
|
let cert, key;
|
|
16819
16769
|
try {
|
|
16820
|
-
cert = await fs$
|
|
16770
|
+
cert = await fs$14.promises.readFile(certPath);
|
|
16821
16771
|
new crypto_1.X509Certificate(cert);
|
|
16822
16772
|
} catch (err) {
|
|
16823
16773
|
throw new CertificateSourceUnavailableError(`Failed to read certificate file at ${certPath}: ${err instanceof Error ? err.message : String(err)}`);
|
|
16824
16774
|
}
|
|
16825
16775
|
try {
|
|
16826
|
-
key = await fs$
|
|
16776
|
+
key = await fs$14.promises.readFile(keyPath);
|
|
16827
16777
|
(0, crypto_1.createPrivateKey)(key);
|
|
16828
16778
|
} catch (err) {
|
|
16829
16779
|
throw new CertificateSourceUnavailableError(`Failed to read private key file at ${keyPath}: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -16842,7 +16792,7 @@ var require_certificatesubjecttokensupplier = /* @__PURE__ */ __commonJSMin(((ex
|
|
|
16842
16792
|
const leafCert = new crypto_1.X509Certificate(leafCertBuffer);
|
|
16843
16793
|
if (!this.trustChainPath) return JSON.stringify([leafCert.raw.toString("base64")]);
|
|
16844
16794
|
try {
|
|
16845
|
-
const chainCerts = ((await fs$
|
|
16795
|
+
const chainCerts = ((await fs$14.promises.readFile(this.trustChainPath, "utf8")).match(/-----BEGIN CERTIFICATE-----[^-]+-----END CERTIFICATE-----/g) ?? []).map((pem, index) => {
|
|
16846
16796
|
try {
|
|
16847
16797
|
return new crypto_1.X509Certificate(pem);
|
|
16848
16798
|
} catch (err) {
|
|
@@ -17503,7 +17453,7 @@ var require_pluggable_auth_handler = /* @__PURE__ */ __commonJSMin(((exports) =>
|
|
|
17503
17453
|
exports.PluggableAuthHandler = exports.ExecutableError = void 0;
|
|
17504
17454
|
const executable_response_1 = require_executable_response();
|
|
17505
17455
|
const childProcess = __require("child_process");
|
|
17506
|
-
const fs$
|
|
17456
|
+
const fs$13 = __require("fs");
|
|
17507
17457
|
/**
|
|
17508
17458
|
* Error thrown from the executable run by PluggableAuthClient.
|
|
17509
17459
|
*/
|
|
@@ -17580,12 +17530,12 @@ var require_pluggable_auth_handler = /* @__PURE__ */ __commonJSMin(((exports) =>
|
|
|
17580
17530
|
if (!this.outputFile || this.outputFile.length === 0) return;
|
|
17581
17531
|
let filePath;
|
|
17582
17532
|
try {
|
|
17583
|
-
filePath = await fs$
|
|
17533
|
+
filePath = await fs$13.promises.realpath(this.outputFile);
|
|
17584
17534
|
} catch {
|
|
17585
17535
|
return;
|
|
17586
17536
|
}
|
|
17587
|
-
if (!(await fs$
|
|
17588
|
-
const responseString = await fs$
|
|
17537
|
+
if (!(await fs$13.promises.lstat(filePath)).isFile()) return;
|
|
17538
|
+
const responseString = await fs$13.promises.readFile(filePath, { encoding: "utf8" });
|
|
17589
17539
|
if (responseString === "") return;
|
|
17590
17540
|
try {
|
|
17591
17541
|
const responseJson = JSON.parse(responseString);
|
|
@@ -18007,7 +17957,7 @@ var require_googleauth = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
18007
17957
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18008
17958
|
exports.GoogleAuth = exports.GoogleAuthExceptionMessages = void 0;
|
|
18009
17959
|
const child_process_1 = __require("child_process");
|
|
18010
|
-
const fs$
|
|
17960
|
+
const fs$12 = __require("fs");
|
|
18011
17961
|
const gaxios_1 = require_src$3();
|
|
18012
17962
|
const gcpMetadata = require_src$1();
|
|
18013
17963
|
const os$1 = __require("os");
|
|
@@ -18255,7 +18205,7 @@ var require_googleauth = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
18255
18205
|
}
|
|
18256
18206
|
if (location) {
|
|
18257
18207
|
location = path$11.join(location, "gcloud", "application_default_credentials.json");
|
|
18258
|
-
if (!fs$
|
|
18208
|
+
if (!fs$12.existsSync(location)) location = null;
|
|
18259
18209
|
}
|
|
18260
18210
|
if (!location) return null;
|
|
18261
18211
|
return await this._getApplicationCredentialsFromFilePath(location, options);
|
|
@@ -18269,13 +18219,13 @@ var require_googleauth = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
18269
18219
|
async _getApplicationCredentialsFromFilePath(filePath, options = {}) {
|
|
18270
18220
|
if (!filePath || filePath.length === 0) throw new Error("The file path is invalid.");
|
|
18271
18221
|
try {
|
|
18272
|
-
filePath = fs$
|
|
18273
|
-
if (!fs$
|
|
18222
|
+
filePath = fs$12.realpathSync(filePath);
|
|
18223
|
+
if (!fs$12.lstatSync(filePath).isFile()) throw new Error();
|
|
18274
18224
|
} catch (err) {
|
|
18275
18225
|
if (err instanceof Error) err.message = `The file at ${filePath} does not exist, or it is not a file. ${err.message}`;
|
|
18276
18226
|
throw err;
|
|
18277
18227
|
}
|
|
18278
|
-
const readStream = fs$
|
|
18228
|
+
const readStream = fs$12.createReadStream(filePath);
|
|
18279
18229
|
return this.fromStream(readStream, options);
|
|
18280
18230
|
}
|
|
18281
18231
|
/**
|
|
@@ -18542,7 +18492,7 @@ var require_googleauth = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
18542
18492
|
if (this.jsonContent) return this._cacheClientFromJSON(this.jsonContent, this.clientOptions);
|
|
18543
18493
|
else if (this.keyFilename) {
|
|
18544
18494
|
const filePath = path$11.resolve(this.keyFilename);
|
|
18545
|
-
const stream = fs$
|
|
18495
|
+
const stream = fs$12.createReadStream(filePath);
|
|
18546
18496
|
return await this.fromStreamAsync(stream, this.clientOptions);
|
|
18547
18497
|
} else if (this.apiKey) {
|
|
18548
18498
|
const client = await this.fromAPIKey(this.apiKey, this.clientOptions);
|
|
@@ -37287,7 +37237,7 @@ var NodeUploader = class {
|
|
|
37287
37237
|
type: void 0
|
|
37288
37238
|
};
|
|
37289
37239
|
if (typeof file === "string") {
|
|
37290
|
-
fileStat.size = (await fs$
|
|
37240
|
+
fileStat.size = (await fs$11.stat(file)).size;
|
|
37291
37241
|
fileStat.type = this.inferMimeType(file);
|
|
37292
37242
|
return fileStat;
|
|
37293
37243
|
} else return await getBlobStat(file);
|
|
@@ -37419,7 +37369,7 @@ var NodeUploader = class {
|
|
|
37419
37369
|
let fileHandle;
|
|
37420
37370
|
const fileName = path$1$1.basename(file);
|
|
37421
37371
|
try {
|
|
37422
|
-
fileHandle = await fs$
|
|
37372
|
+
fileHandle = await fs$11.open(file, "r");
|
|
37423
37373
|
if (!fileHandle) throw new Error(`Failed to open file`);
|
|
37424
37374
|
fileSize = (await fileHandle.stat()).size;
|
|
37425
37375
|
while (offset < fileSize) {
|
|
@@ -48186,11 +48136,11 @@ var ScreamFiles = class {
|
|
|
48186
48136
|
async uploadVideo(input, options) {
|
|
48187
48137
|
let file;
|
|
48188
48138
|
if (typeof input === "string") {
|
|
48189
|
-
if (!fs$
|
|
48139
|
+
if (!fs$10.existsSync(input)) throw new ChatProviderError(`Video file not found: ${input}`);
|
|
48190
48140
|
const filename = path$8.basename(input);
|
|
48191
48141
|
const mimeType = guessMimeTypeFromExt(filename);
|
|
48192
48142
|
if (mimeType === void 0 || !mimeType.startsWith("video/")) throw new ChatProviderError(`ScreamFiles.uploadVideo: file extension does not indicate a video type: ${filename}`);
|
|
48193
|
-
const data = await fs$
|
|
48143
|
+
const data = await fs$10.promises.readFile(input);
|
|
48194
48144
|
const blob = new Blob([new Uint8Array(data)], { type: mimeType });
|
|
48195
48145
|
file = new File([blob], filename, { type: mimeType });
|
|
48196
48146
|
} else {
|
|
@@ -49877,7 +49827,7 @@ async function generate(provider, systemPrompt, tools, history, callbacks, optio
|
|
|
49877
49827
|
if (options?.signal?.aborted) throwAbortError();
|
|
49878
49828
|
options?.onRequestStart?.();
|
|
49879
49829
|
const stream = await provider.generate(systemPrompt, tools, history, options);
|
|
49880
|
-
await throwIfAborted(options?.signal, stream);
|
|
49830
|
+
await throwIfAborted$1(options?.signal, stream);
|
|
49881
49831
|
const idleTimeoutMs = getStreamIdleTimeoutMs();
|
|
49882
49832
|
const firstItemTimeoutMs = getStreamFirstItemTimeoutMs(idleTimeoutMs);
|
|
49883
49833
|
const watchedStream = iterateWithIdleTimeout(stream, {
|
|
@@ -49888,10 +49838,10 @@ async function generate(provider, systemPrompt, tools, history, callbacks, optio
|
|
|
49888
49838
|
firstItemErrorMessage: `Stream stalled — no first token within ${firstItemTimeoutMs ?? 0}ms. Provider: ${provider.name}, model: ${provider.modelName}`
|
|
49889
49839
|
});
|
|
49890
49840
|
for await (const part of watchedStream) {
|
|
49891
|
-
await throwIfAborted(options?.signal, stream);
|
|
49841
|
+
await throwIfAborted$1(options?.signal, stream);
|
|
49892
49842
|
if (callbacks?.onMessagePart !== void 0) {
|
|
49893
49843
|
await callbacks.onMessagePart(deepCopyPart(part));
|
|
49894
|
-
await throwIfAborted(options?.signal, stream);
|
|
49844
|
+
await throwIfAborted$1(options?.signal, stream);
|
|
49895
49845
|
}
|
|
49896
49846
|
if (isToolCallPart(part) && part.index !== void 0 && !isPendingToolCallAtIndex(pendingPart, part.index)) {
|
|
49897
49847
|
const arrayIdx = toolCallIndexMap.get(part.index);
|
|
@@ -49907,7 +49857,7 @@ async function generate(provider, systemPrompt, tools, history, callbacks, optio
|
|
|
49907
49857
|
pendingPart = part;
|
|
49908
49858
|
}
|
|
49909
49859
|
}
|
|
49910
|
-
await throwIfAborted(options?.signal, stream);
|
|
49860
|
+
await throwIfAborted$1(options?.signal, stream);
|
|
49911
49861
|
options?.onStreamEnd?.();
|
|
49912
49862
|
if (pendingPart !== null) flushPart(message, pendingPart, toolCallIndexMap);
|
|
49913
49863
|
if (message.content.length === 0 && message.toolCalls.length === 0) throw new APIEmptyResponseError(`The API returned an empty response (no content, no tool calls). Provider: ${provider.name}, model: ${provider.modelName}. Common causes: the model's max output tokens are set too low, the model does not support this request format, or the provider/proxy returned an empty stream. Try again, switch models, or check provider settings.`);
|
|
@@ -49916,7 +49866,7 @@ async function generate(provider, systemPrompt, tools, history, callbacks, optio
|
|
|
49916
49866
|
const hasToolCalls = message.toolCalls.length > 0;
|
|
49917
49867
|
if (hasThink && !hasText && !hasToolCalls) throw new APIEmptyResponseError(`The API returned a response containing only thinking content without any text or tool calls. This usually indicates the stream was interrupted or the output token budget was exhausted during reasoning. Provider: ${provider.name}, model: ${provider.modelName}. If this persists, reduce reasoning effort or switch to a model with a larger output budget.`);
|
|
49918
49868
|
if (callbacks?.onToolCall !== void 0) for (const toolCall of message.toolCalls) {
|
|
49919
|
-
await throwIfAborted(options?.signal, stream);
|
|
49869
|
+
await throwIfAborted$1(options?.signal, stream);
|
|
49920
49870
|
await callbacks.onToolCall(toolCall);
|
|
49921
49871
|
}
|
|
49922
49872
|
return {
|
|
@@ -49933,7 +49883,7 @@ function throwAbortError() {
|
|
|
49933
49883
|
async function cancelStream(stream) {
|
|
49934
49884
|
await stream[Symbol.asyncIterator]().return?.();
|
|
49935
49885
|
}
|
|
49936
|
-
async function throwIfAborted(signal, stream) {
|
|
49886
|
+
async function throwIfAborted$1(signal, stream) {
|
|
49937
49887
|
if (!signal?.aborted) return;
|
|
49938
49888
|
if (stream !== void 0) await cancelStream(stream);
|
|
49939
49889
|
throwAbortError();
|
|
@@ -50295,7 +50245,7 @@ async function syncDir(dirPath) {
|
|
|
50295
50245
|
*/
|
|
50296
50246
|
function syncFd(fd) {
|
|
50297
50247
|
return new Promise((resolve, reject) => {
|
|
50298
|
-
fs$
|
|
50248
|
+
fs$10.fsync(fd, (err) => {
|
|
50299
50249
|
if (err) {
|
|
50300
50250
|
reject(err);
|
|
50301
50251
|
return;
|
|
@@ -50903,7 +50853,7 @@ function isAbortError$1(err) {
|
|
|
50903
50853
|
if (err instanceof Error) return err.name === "AbortError";
|
|
50904
50854
|
return false;
|
|
50905
50855
|
}
|
|
50906
|
-
function errorMessage$
|
|
50856
|
+
function errorMessage$4(err) {
|
|
50907
50857
|
if (err instanceof Error) return err.message;
|
|
50908
50858
|
return String(err);
|
|
50909
50859
|
}
|
|
@@ -62543,8 +62493,8 @@ function parseSkillText(options) {
|
|
|
62543
62493
|
if (!isRecord$6(frontmatter)) throw new SkillParseError(`Frontmatter in ${options.skillMdPath} must be a mapping at the top level`);
|
|
62544
62494
|
const metadata = normalizeMetadata(frontmatter);
|
|
62545
62495
|
if (!isSupportedSkillType(metadata.type)) throw new UnsupportedSkillTypeError(metadata.type ?? String(frontmatter["type"]));
|
|
62546
|
-
const name = nonEmptyString$
|
|
62547
|
-
const description = nonEmptyString$
|
|
62496
|
+
const name = nonEmptyString$1(metadata.name);
|
|
62497
|
+
const description = nonEmptyString$1(metadata.description);
|
|
62548
62498
|
if (isDirectorySkill && (name === void 0 || description === void 0)) throw new SkillParseError(`Missing required frontmatter field ${name === void 0 ? "\"name\"" : "\"description\""} in ${options.skillMdPath}`);
|
|
62549
62499
|
const skillPath = resolve$1(options.skillMdPath);
|
|
62550
62500
|
const content = parsed.body.trim();
|
|
@@ -62604,11 +62554,11 @@ function normalizeMetadata(raw) {
|
|
|
62604
62554
|
const key = METADATA_ALIASES[rawKey] ?? rawKey;
|
|
62605
62555
|
out[key] = value;
|
|
62606
62556
|
}
|
|
62607
|
-
const type = nonEmptyString$
|
|
62557
|
+
const type = nonEmptyString$1(out["type"]);
|
|
62608
62558
|
if (type !== void 0) out["type"] = type;
|
|
62609
|
-
const name = nonEmptyString$
|
|
62559
|
+
const name = nonEmptyString$1(out["name"]);
|
|
62610
62560
|
if (name !== void 0) out["name"] = name;
|
|
62611
|
-
const description = nonEmptyString$
|
|
62561
|
+
const description = nonEmptyString$1(out["description"]);
|
|
62612
62562
|
if (description !== void 0) out["description"] = description;
|
|
62613
62563
|
return out;
|
|
62614
62564
|
}
|
|
@@ -62650,7 +62600,7 @@ function tokenizeArgs(raw) {
|
|
|
62650
62600
|
if (hasContent) out.push(current);
|
|
62651
62601
|
return out;
|
|
62652
62602
|
}
|
|
62653
|
-
function nonEmptyString$
|
|
62603
|
+
function nonEmptyString$1(value) {
|
|
62654
62604
|
return typeof value === "string" && value.trim() !== "" ? value.trim() : void 0;
|
|
62655
62605
|
}
|
|
62656
62606
|
function isRecord$6(value) {
|
|
@@ -66860,7 +66810,7 @@ var require_node_loaders = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
66860
66810
|
};
|
|
66861
66811
|
return _setPrototypeOf(o, p);
|
|
66862
66812
|
}
|
|
66863
|
-
var fs$
|
|
66813
|
+
var fs$9 = __require("fs");
|
|
66864
66814
|
var path$6 = __require("path");
|
|
66865
66815
|
var Loader = require_loader();
|
|
66866
66816
|
var PrecompiledLoader = require_precompiled_loader().PrecompiledLoader;
|
|
@@ -66884,7 +66834,7 @@ var require_node_loaders = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
66884
66834
|
} catch (e) {
|
|
66885
66835
|
throw new Error("watch requires chokidar to be installed");
|
|
66886
66836
|
}
|
|
66887
|
-
var paths = _this.searchPaths.filter(fs$
|
|
66837
|
+
var paths = _this.searchPaths.filter(fs$9.existsSync);
|
|
66888
66838
|
var watcher = chokidar.watch(paths);
|
|
66889
66839
|
watcher.on("all", function(event, fullname) {
|
|
66890
66840
|
fullname = path$6.resolve(fullname);
|
|
@@ -66903,7 +66853,7 @@ var require_node_loaders = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
66903
66853
|
for (var i = 0; i < paths.length; i++) {
|
|
66904
66854
|
var basePath = path$6.resolve(paths[i]);
|
|
66905
66855
|
var p = path$6.resolve(paths[i], name);
|
|
66906
|
-
if (p.indexOf(basePath) === 0 && fs$
|
|
66856
|
+
if (p.indexOf(basePath) === 0 && fs$9.existsSync(p)) {
|
|
66907
66857
|
fullpath = p;
|
|
66908
66858
|
break;
|
|
66909
66859
|
}
|
|
@@ -66911,7 +66861,7 @@ var require_node_loaders = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
66911
66861
|
if (!fullpath) return null;
|
|
66912
66862
|
this.pathsToNames[fullpath] = name;
|
|
66913
66863
|
var source = {
|
|
66914
|
-
src: fs$
|
|
66864
|
+
src: fs$9.readFileSync(fullpath, "utf-8"),
|
|
66915
66865
|
path: fullpath,
|
|
66916
66866
|
noCache: this.noCache
|
|
66917
66867
|
};
|
|
@@ -66959,7 +66909,7 @@ var require_node_loaders = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
66959
66909
|
}
|
|
66960
66910
|
this.pathsToNames[fullpath] = name;
|
|
66961
66911
|
var source = {
|
|
66962
|
-
src: fs$
|
|
66912
|
+
src: fs$9.readFileSync(fullpath, "utf-8"),
|
|
66963
66913
|
path: fullpath,
|
|
66964
66914
|
noCache: this.noCache
|
|
66965
66915
|
};
|
|
@@ -67703,7 +67653,7 @@ var require_precompile_global = /* @__PURE__ */ __commonJSMin(((exports, module)
|
|
|
67703
67653
|
//#endregion
|
|
67704
67654
|
//#region ../../node_modules/.pnpm/nunjucks@3.2.4/node_modules/nunjucks/src/precompile.js
|
|
67705
67655
|
var require_precompile = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
67706
|
-
var fs$
|
|
67656
|
+
var fs$8 = __require("fs");
|
|
67707
67657
|
var path$4 = __require("path");
|
|
67708
67658
|
var _prettifyError = require_lib$1()._prettifyError;
|
|
67709
67659
|
var compiler = require_compiler();
|
|
@@ -67728,27 +67678,27 @@ var require_precompile = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
67728
67678
|
var env = opts.env || new Environment([]);
|
|
67729
67679
|
var wrapper = opts.wrapper || precompileGlobal;
|
|
67730
67680
|
if (opts.isString) return precompileString(input, opts);
|
|
67731
|
-
var pathStats = fs$
|
|
67681
|
+
var pathStats = fs$8.existsSync(input) && fs$8.statSync(input);
|
|
67732
67682
|
var precompiled = [];
|
|
67733
67683
|
var templates = [];
|
|
67734
67684
|
function addTemplates(dir) {
|
|
67735
|
-
fs$
|
|
67685
|
+
fs$8.readdirSync(dir).forEach(function(file) {
|
|
67736
67686
|
var filepath = path$4.join(dir, file);
|
|
67737
67687
|
var subpath = filepath.substr(path$4.join(input, "/").length);
|
|
67738
|
-
var stat = fs$
|
|
67688
|
+
var stat = fs$8.statSync(filepath);
|
|
67739
67689
|
if (stat && stat.isDirectory()) {
|
|
67740
67690
|
subpath += "/";
|
|
67741
67691
|
if (!match(subpath, opts.exclude)) addTemplates(filepath);
|
|
67742
67692
|
} else if (match(subpath, opts.include)) templates.push(filepath);
|
|
67743
67693
|
});
|
|
67744
67694
|
}
|
|
67745
|
-
if (pathStats.isFile()) precompiled.push(_precompile(fs$
|
|
67695
|
+
if (pathStats.isFile()) precompiled.push(_precompile(fs$8.readFileSync(input, "utf-8"), opts.name || input, env));
|
|
67746
67696
|
else if (pathStats.isDirectory()) {
|
|
67747
67697
|
addTemplates(input);
|
|
67748
67698
|
for (var i = 0; i < templates.length; i++) {
|
|
67749
67699
|
var name = templates[i].replace(path$4.join(input, "/"), "");
|
|
67750
67700
|
try {
|
|
67751
|
-
precompiled.push(_precompile(fs$
|
|
67701
|
+
precompiled.push(_precompile(fs$8.readFileSync(templates[i], "utf-8"), name, env));
|
|
67752
67702
|
} catch (e) {
|
|
67753
67703
|
if (opts.force) console.error(e);
|
|
67754
67704
|
else throw e;
|
|
@@ -68224,7 +68174,7 @@ var require_pend = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
68224
68174
|
//#endregion
|
|
68225
68175
|
//#region ../../node_modules/.pnpm/yauzl@3.3.1/node_modules/yauzl/fd-slicer.js
|
|
68226
68176
|
var require_fd_slicer = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
68227
|
-
var fs$
|
|
68177
|
+
var fs$7 = __require("fs");
|
|
68228
68178
|
var util$2 = __require("util");
|
|
68229
68179
|
var stream = __require("stream");
|
|
68230
68180
|
var Readable = stream.Readable;
|
|
@@ -68244,7 +68194,7 @@ var require_fd_slicer = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
68244
68194
|
FdSlicer.prototype.read = function(buffer, offset, length, position, callback) {
|
|
68245
68195
|
var self = this;
|
|
68246
68196
|
self.pend.go(function(cb) {
|
|
68247
|
-
fs$
|
|
68197
|
+
fs$7.read(self.fd, buffer, offset, length, position, function(err, bytesRead, buffer) {
|
|
68248
68198
|
cb();
|
|
68249
68199
|
callback(err, bytesRead, buffer);
|
|
68250
68200
|
});
|
|
@@ -68261,7 +68211,7 @@ var require_fd_slicer = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
68261
68211
|
self.refCount -= 1;
|
|
68262
68212
|
if (self.refCount < 0) throw new Error("invalid unref");
|
|
68263
68213
|
if (self.refCount > 0) return;
|
|
68264
|
-
fs$
|
|
68214
|
+
fs$7.close(self.fd, onCloseDone);
|
|
68265
68215
|
function onCloseDone(err) {
|
|
68266
68216
|
if (err) self.emit("error", err);
|
|
68267
68217
|
else self.emit("close");
|
|
@@ -68288,7 +68238,7 @@ var require_fd_slicer = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
68288
68238
|
}
|
|
68289
68239
|
self.context.pend.go(function(cb) {
|
|
68290
68240
|
var buffer = Buffer.allocUnsafe(toRead);
|
|
68291
|
-
fs$
|
|
68241
|
+
fs$7.read(self.context.fd, buffer, 0, toRead, self.pos, function(err, bytesRead) {
|
|
68292
68242
|
if (err) self.destroy(err);
|
|
68293
68243
|
else if (bytesRead === 0) {
|
|
68294
68244
|
self.push(null);
|
|
@@ -69652,17 +69602,13 @@ const HookDefSchema = z.object({
|
|
|
69652
69602
|
command: z.string().min(1),
|
|
69653
69603
|
timeout: z.number().int().min(1).max(600).optional()
|
|
69654
69604
|
}).strict();
|
|
69655
|
-
const ScreamCliServiceConfigSchema = z.object({
|
|
69656
|
-
baseUrl: z.string().optional(),
|
|
69657
|
-
apiKey: z.string().optional(),
|
|
69658
|
-
oauth: OAuthRefSchema.optional(),
|
|
69659
|
-
customHeaders: StringRecordSchema.optional()
|
|
69660
|
-
});
|
|
69661
69605
|
const DuckDuckGoConfigSchema = z.object({ enabled: z.boolean().default(true) });
|
|
69606
|
+
const DomesticSearchConfigSchema = z.object({ enabled: z.boolean().default(true) });
|
|
69662
69607
|
const ServicesConfigSchema = z.object({
|
|
69663
|
-
|
|
69664
|
-
|
|
69665
|
-
|
|
69608
|
+
duckduckgo: DuckDuckGoConfigSchema.optional(),
|
|
69609
|
+
sogou: DomesticSearchConfigSchema.optional(),
|
|
69610
|
+
so360: DomesticSearchConfigSchema.optional(),
|
|
69611
|
+
baidu: DomesticSearchConfigSchema.optional()
|
|
69666
69612
|
});
|
|
69667
69613
|
const McpServerCommonFields = {
|
|
69668
69614
|
enabled: z.boolean().optional(),
|
|
@@ -69736,12 +69682,13 @@ const ThinkingConfigPatchSchema = ThinkingConfigSchema.partial();
|
|
|
69736
69682
|
const PermissionConfigPatchSchema = PermissionConfigSchema.partial();
|
|
69737
69683
|
const LoopControlPatchSchema = LoopControlSchema.partial();
|
|
69738
69684
|
const BackgroundConfigPatchSchema = BackgroundConfigSchema.partial();
|
|
69739
|
-
const ScreamCliServiceConfigPatchSchema = ScreamCliServiceConfigSchema.partial();
|
|
69740
69685
|
const DuckDuckGoConfigPatchSchema = DuckDuckGoConfigSchema.partial();
|
|
69686
|
+
const DomesticSearchConfigPatchSchema = DomesticSearchConfigSchema.partial();
|
|
69741
69687
|
const ServicesConfigPatchSchema = z.object({
|
|
69742
|
-
|
|
69743
|
-
|
|
69744
|
-
|
|
69688
|
+
duckduckgo: DuckDuckGoConfigPatchSchema.optional(),
|
|
69689
|
+
sogou: DomesticSearchConfigPatchSchema.optional(),
|
|
69690
|
+
so360: DomesticSearchConfigPatchSchema.optional(),
|
|
69691
|
+
baidu: DomesticSearchConfigPatchSchema.optional()
|
|
69745
69692
|
});
|
|
69746
69693
|
const ScreamConfigPatchSchema = z.object({
|
|
69747
69694
|
providers: z.record(z.string(), ProviderConfigPatchSchema).optional(),
|
|
@@ -74223,7 +74170,7 @@ var mi = class {
|
|
|
74223
74170
|
K(Hn, Wn, Gn, Zn, (s, t) => {
|
|
74224
74171
|
if (!t?.length) throw new TypeError("no paths specified to add to archive");
|
|
74225
74172
|
});
|
|
74226
|
-
var dr = (process.env.__FAKE_PLATFORM__ || process.platform) === "win32", { O_CREAT: ur, O_NOFOLLOW: lr, O_TRUNC: mr, O_WRONLY: pr } = I.constants, Er = Number(process.env.__FAKE_FS_O_FILENAME__) || I.constants.UV_FS_O_FILEMAP || 0, Vn = dr && !!Er, $n = 512 * 1024, Xn = Er | mr | ur | pr, cr = !dr && typeof lr == "number" ? lr | mr | ur | pr : null, fs$
|
|
74173
|
+
var dr = (process.env.__FAKE_PLATFORM__ || process.platform) === "win32", { O_CREAT: ur, O_NOFOLLOW: lr, O_TRUNC: mr, O_WRONLY: pr } = I.constants, Er = Number(process.env.__FAKE_FS_O_FILENAME__) || I.constants.UV_FS_O_FILEMAP || 0, Vn = dr && !!Er, $n = 512 * 1024, Xn = Er | mr | ur | pr, cr = !dr && typeof lr == "number" ? lr | mr | ur | pr : null, fs$5 = cr !== null ? () => cr : Vn ? (s) => s < $n ? Xn : "w" : () => "w";
|
|
74227
74174
|
var ds = (s, t, e) => {
|
|
74228
74175
|
try {
|
|
74229
74176
|
return Vt.lchownSync(s, t, e);
|
|
@@ -74591,7 +74538,7 @@ var Or = Symbol("onEntry"), Rs = Symbol("checkFs"), Tr = Symbol("checkFs2"), gs
|
|
|
74591
74538
|
}
|
|
74592
74539
|
[bs](t, e) {
|
|
74593
74540
|
let i = typeof t.mode == "number" ? t.mode & 4095 : this.fmode, r = new tt(String(t.absolute), {
|
|
74594
|
-
flags: fs$
|
|
74541
|
+
flags: fs$5(t.size),
|
|
74595
74542
|
mode: i,
|
|
74596
74543
|
autoClose: !1
|
|
74597
74544
|
});
|
|
@@ -74795,7 +74742,7 @@ var Or = Symbol("onEntry"), Rs = Symbol("checkFs"), Tr = Symbol("checkFs2"), gs
|
|
|
74795
74742
|
(h || a) && this[O](h || a, t), e();
|
|
74796
74743
|
}, n;
|
|
74797
74744
|
try {
|
|
74798
|
-
n = Vt.openSync(String(t.absolute), fs$
|
|
74745
|
+
n = Vt.openSync(String(t.absolute), fs$5(t.size), i);
|
|
74799
74746
|
} catch (h) {
|
|
74800
74747
|
return r(h);
|
|
74801
74748
|
}
|
|
@@ -76163,7 +76110,7 @@ const FTYP_VIDEO_BRANDS = Object.freeze({
|
|
|
76163
76110
|
"3gp7": "video/3gpp",
|
|
76164
76111
|
"3g2": "video/3gpp2"
|
|
76165
76112
|
});
|
|
76166
|
-
function toBuffer(data) {
|
|
76113
|
+
function toBuffer$1(data) {
|
|
76167
76114
|
return Buffer.isBuffer(data) ? data : Buffer.from(data.buffer, data.byteOffset, data.byteLength);
|
|
76168
76115
|
}
|
|
76169
76116
|
function startsWith(buf, prefix) {
|
|
@@ -76178,7 +76125,7 @@ function sniffFtypBrand(header) {
|
|
|
76178
76125
|
return header.subarray(8, 12).toString("latin1").toLowerCase().replaceAll(/[\s\u0000]+$/g, "").trim();
|
|
76179
76126
|
}
|
|
76180
76127
|
function sniffMediaFromMagic(data) {
|
|
76181
|
-
const buf = toBuffer(data);
|
|
76128
|
+
const buf = toBuffer$1(data);
|
|
76182
76129
|
const header = buf.length > 512 ? buf.subarray(0, 512) : buf;
|
|
76183
76130
|
if (startsWith(header, [
|
|
76184
76131
|
137,
|
|
@@ -76290,7 +76237,7 @@ function sniffMediaFromMagic(data) {
|
|
|
76290
76237
|
* when the supplied buffer is too short to cover it.
|
|
76291
76238
|
*/
|
|
76292
76239
|
function sniffImageDimensions(data) {
|
|
76293
|
-
const buf = toBuffer(data);
|
|
76240
|
+
const buf = toBuffer$1(data);
|
|
76294
76241
|
if (startsWith(buf, [
|
|
76295
76242
|
137,
|
|
76296
76243
|
80,
|
|
@@ -76375,7 +76322,7 @@ function detectFileType(path, header) {
|
|
|
76375
76322
|
mimeType: VIDEO_MIME_BY_SUFFIX$1[suffix]
|
|
76376
76323
|
};
|
|
76377
76324
|
if (header !== void 0) {
|
|
76378
|
-
const buf = toBuffer(header);
|
|
76325
|
+
const buf = toBuffer$1(header);
|
|
76379
76326
|
const sniffed = sniffMediaFromMagic(buf);
|
|
76380
76327
|
if (sniffed) {
|
|
76381
76328
|
if (mediaHint) {
|
|
@@ -78352,9 +78299,12 @@ var WebSearchTool = class {
|
|
|
78352
78299
|
execute: (ctx) => this.execution(args, ctx)
|
|
78353
78300
|
};
|
|
78354
78301
|
}
|
|
78355
|
-
async execution(args, { toolCallId }) {
|
|
78302
|
+
async execution(args, { signal, toolCallId }) {
|
|
78356
78303
|
try {
|
|
78357
|
-
const opts = {
|
|
78304
|
+
const opts = {
|
|
78305
|
+
signal,
|
|
78306
|
+
toolCallId
|
|
78307
|
+
};
|
|
78358
78308
|
if (args.limit !== void 0) opts.limit = args.limit;
|
|
78359
78309
|
if (args.include_content !== void 0) opts.includeContent = args.include_content;
|
|
78360
78310
|
const results = await this.provider.search(args.query, opts);
|
|
@@ -81146,7 +81096,7 @@ async function runHook(command, input, options) {
|
|
|
81146
81096
|
detached: process.platform !== "win32"
|
|
81147
81097
|
});
|
|
81148
81098
|
} catch (error) {
|
|
81149
|
-
return allowResult({ stderr: errorMessage$
|
|
81099
|
+
return allowResult({ stderr: errorMessage$3(error) });
|
|
81150
81100
|
}
|
|
81151
81101
|
return new Promise((resolve) => {
|
|
81152
81102
|
let stdout = "";
|
|
@@ -81194,7 +81144,7 @@ async function runHook(command, input, options) {
|
|
|
81194
81144
|
child.on("error", (error) => {
|
|
81195
81145
|
settle(allowResult({
|
|
81196
81146
|
stdout,
|
|
81197
|
-
stderr: stderr + errorMessage$
|
|
81147
|
+
stderr: stderr + errorMessage$3(error)
|
|
81198
81148
|
}));
|
|
81199
81149
|
});
|
|
81200
81150
|
child.on("close", (code) => {
|
|
@@ -81290,7 +81240,7 @@ function tryKillProcess(child, signal) {
|
|
|
81290
81240
|
function isRecord$5(value) {
|
|
81291
81241
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
81292
81242
|
}
|
|
81293
|
-
function errorMessage$
|
|
81243
|
+
function errorMessage$3(error) {
|
|
81294
81244
|
return error instanceof Error ? error.message : String(error);
|
|
81295
81245
|
}
|
|
81296
81246
|
//#endregion
|
|
@@ -92177,6 +92127,7 @@ var ToolScheduler = class {
|
|
|
92177
92127
|
//#endregion
|
|
92178
92128
|
//#region ../../packages/agent-core/src/loop/tool-call.ts
|
|
92179
92129
|
const GRACE_TIMEOUT_MS = 2e3;
|
|
92130
|
+
const STEER_POLL_INTERVAL_MS = 150;
|
|
92180
92131
|
const TOOL_OUTPUT_EMPTY = "Tool output is empty.";
|
|
92181
92132
|
const TOOL_OUTPUT_NON_TEXT = "Tool returned non-text content.";
|
|
92182
92133
|
const validators = /* @__PURE__ */ new WeakMap();
|
|
@@ -92196,15 +92147,29 @@ async function runToolCallBatch(step, response) {
|
|
|
92196
92147
|
const scheduler = new ToolScheduler();
|
|
92197
92148
|
const pendingResults = [];
|
|
92198
92149
|
let stopTurn = false;
|
|
92150
|
+
const steerController = step.hasPendingSteer !== void 0 ? new AbortController() : void 0;
|
|
92151
|
+
const effectiveStep = steerController === void 0 ? step : {
|
|
92152
|
+
...step,
|
|
92153
|
+
signal: AbortSignal.any([step.signal, steerController.signal])
|
|
92154
|
+
};
|
|
92155
|
+
const abortOnSteer = () => {
|
|
92156
|
+
if (step.hasPendingSteer?.() === true && steerController !== void 0 && !steerController.signal.aborted) steerController.abort(userCancellationReason());
|
|
92157
|
+
};
|
|
92158
|
+
abortOnSteer();
|
|
92159
|
+
const steerPoll = steerController === void 0 ? void 0 : setInterval(() => {
|
|
92160
|
+
try {
|
|
92161
|
+
abortOnSteer();
|
|
92162
|
+
} catch {}
|
|
92163
|
+
}, STEER_POLL_INTERVAL_MS);
|
|
92199
92164
|
try {
|
|
92200
92165
|
for (let index = 0; index < calls.length; index += 1) {
|
|
92201
92166
|
const call = calls[index];
|
|
92202
|
-
if (
|
|
92167
|
+
if (effectiveStep.signal.aborted) {
|
|
92203
92168
|
await dispatchToolCall(step, call, call.args);
|
|
92204
|
-
pendingResults.push(Promise.resolve(makeErrorToolResult(call, call.args, abortedToolOutput(call.toolName,
|
|
92169
|
+
pendingResults.push(Promise.resolve(makeErrorToolResult(call, call.args, abortedToolOutput(call.toolName, effectiveStep.signal))));
|
|
92205
92170
|
continue;
|
|
92206
92171
|
}
|
|
92207
|
-
const prepared = await prepareToolCall(
|
|
92172
|
+
const prepared = await prepareToolCall(effectiveStep, call);
|
|
92208
92173
|
pendingResults.push(scheduler.add(prepared.task));
|
|
92209
92174
|
if (prepared.stopBatchAfterThis === true) {
|
|
92210
92175
|
stopTurn = true;
|
|
@@ -92216,7 +92181,7 @@ async function runToolCallBatch(step, response) {
|
|
|
92216
92181
|
}
|
|
92217
92182
|
}
|
|
92218
92183
|
for (const pendingResult of pendingResults) {
|
|
92219
|
-
const result = await finalizePendingToolResult(
|
|
92184
|
+
const result = await finalizePendingToolResult(effectiveStep, await pendingResult);
|
|
92220
92185
|
if (result.stopTurn === true) stopTurn = true;
|
|
92221
92186
|
await step.dispatchEvent({
|
|
92222
92187
|
type: "tool.result",
|
|
@@ -92226,6 +92191,7 @@ async function runToolCallBatch(step, response) {
|
|
|
92226
92191
|
});
|
|
92227
92192
|
}
|
|
92228
92193
|
} finally {
|
|
92194
|
+
if (steerPoll !== void 0) clearInterval(steerPoll);
|
|
92229
92195
|
await Promise.allSettled(pendingResults);
|
|
92230
92196
|
}
|
|
92231
92197
|
return { stopTurn };
|
|
@@ -92289,7 +92255,7 @@ function parseToolCallArguments(raw) {
|
|
|
92289
92255
|
} catch {
|
|
92290
92256
|
return {
|
|
92291
92257
|
success: false,
|
|
92292
|
-
error: errorMessage$
|
|
92258
|
+
error: errorMessage$4(error)
|
|
92293
92259
|
};
|
|
92294
92260
|
}
|
|
92295
92261
|
}
|
|
@@ -92369,7 +92335,7 @@ async function prepareToolCall(step, call) {
|
|
|
92369
92335
|
toolCallId: call.toolCall.id,
|
|
92370
92336
|
error
|
|
92371
92337
|
});
|
|
92372
|
-
return settleError(effectiveArgs, error instanceof PathSecurityError ? error.message : `Tool "${call.toolName}" failed to resolve execution: ${errorMessage$
|
|
92338
|
+
return settleError(effectiveArgs, error instanceof PathSecurityError ? error.message : `Tool "${call.toolName}" failed to resolve execution: ${errorMessage$4(error)}`);
|
|
92373
92339
|
}
|
|
92374
92340
|
const displayFields = toolCallDisplayFieldsFromExecution(execution);
|
|
92375
92341
|
const settleAborted = () => settleError(effectiveArgs, abortedToolOutput(call.toolName, step.signal), displayFields);
|
|
@@ -92428,7 +92394,7 @@ async function runPrepareToolExecutionHook(step, call) {
|
|
|
92428
92394
|
return {
|
|
92429
92395
|
kind: "hookFailed",
|
|
92430
92396
|
args,
|
|
92431
|
-
output: `prepareToolExecution hook failed for "${call.toolName}": ${errorMessage$
|
|
92397
|
+
output: `prepareToolExecution hook failed for "${call.toolName}": ${errorMessage$4(error)}`
|
|
92432
92398
|
};
|
|
92433
92399
|
}
|
|
92434
92400
|
const effectiveArgs = hookResult?.updatedArgs ?? args;
|
|
@@ -92469,7 +92435,7 @@ async function runAuthorizeToolExecutionHook(step, call, args, execution) {
|
|
|
92469
92435
|
};
|
|
92470
92436
|
return {
|
|
92471
92437
|
block: true,
|
|
92472
|
-
reason: `authorizeToolExecution hook failed for "${call.toolName}": ${errorMessage$
|
|
92438
|
+
reason: `authorizeToolExecution hook failed for "${call.toolName}": ${errorMessage$4(error)}`
|
|
92473
92439
|
};
|
|
92474
92440
|
}
|
|
92475
92441
|
}
|
|
@@ -92496,7 +92462,7 @@ async function runRunnableToolCall(step, call, effectiveArgs, metadata, executio
|
|
|
92496
92462
|
toolCallId: toolCall.id,
|
|
92497
92463
|
error
|
|
92498
92464
|
});
|
|
92499
|
-
return makeErrorToolResult(call, effectiveArgs, aborted ? abortedToolOutput(toolName, signal) : `Tool "${toolName}" failed: ${errorMessage$
|
|
92465
|
+
return makeErrorToolResult(call, effectiveArgs, aborted ? abortedToolOutput(toolName, signal) : `Tool "${toolName}" failed: ${errorMessage$4(error)}`);
|
|
92500
92466
|
}
|
|
92501
92467
|
return makeToolResult(call, effectiveArgs, toolResult);
|
|
92502
92468
|
}
|
|
@@ -92528,7 +92494,7 @@ async function finalizePendingToolResult(step, pendingResult) {
|
|
|
92528
92494
|
toolCallId: pendingResult.toolCall.id,
|
|
92529
92495
|
error
|
|
92530
92496
|
});
|
|
92531
|
-
const output = aborted ? `Tool "${pendingResult.toolName}" aborted during finalizeToolResult hook.` : `finalizeToolResult hook failed for "${pendingResult.toolName}": ${errorMessage$
|
|
92497
|
+
const output = aborted ? `Tool "${pendingResult.toolName}" aborted during finalizeToolResult hook.` : `finalizeToolResult hook failed for "${pendingResult.toolName}": ${errorMessage$4(error)}`;
|
|
92532
92498
|
return {
|
|
92533
92499
|
...pendingResult,
|
|
92534
92500
|
stopTurn: pendingResult.stopTurn,
|
|
@@ -92698,7 +92664,8 @@ async function executeLoopStep(deps) {
|
|
|
92698
92664
|
signal,
|
|
92699
92665
|
turnId,
|
|
92700
92666
|
currentStep,
|
|
92701
|
-
stepUuid
|
|
92667
|
+
stepUuid,
|
|
92668
|
+
hasPendingSteer: deps.hasPendingSteer
|
|
92702
92669
|
};
|
|
92703
92670
|
await dispatchEvent({
|
|
92704
92671
|
type: "step.begin",
|
|
@@ -92860,7 +92827,8 @@ async function runTurn(input) {
|
|
|
92860
92827
|
log,
|
|
92861
92828
|
currentStep: steps,
|
|
92862
92829
|
maxRetryAttempts,
|
|
92863
|
-
recordUsage: recordStepUsage
|
|
92830
|
+
recordUsage: recordStepUsage,
|
|
92831
|
+
hasPendingSteer: input.hasPendingSteer
|
|
92864
92832
|
});
|
|
92865
92833
|
activeStep = void 0;
|
|
92866
92834
|
if (stepResult.stopReason === "tool_use") continue;
|
|
@@ -92884,7 +92852,7 @@ async function runTurn(input) {
|
|
|
92884
92852
|
usage
|
|
92885
92853
|
};
|
|
92886
92854
|
}
|
|
92887
|
-
dispatchEvent(makeInterruptedEvent(isMaxStepsExceededError(error) ? "max_steps" : "error", steps, activeStep, errorMessage$
|
|
92855
|
+
dispatchEvent(makeInterruptedEvent(isMaxStepsExceededError(error) ? "max_steps" : "error", steps, activeStep, errorMessage$4(error)));
|
|
92888
92856
|
throw error;
|
|
92889
92857
|
}
|
|
92890
92858
|
return {
|
|
@@ -97914,7 +97882,7 @@ var TurnFlow = class {
|
|
|
97914
97882
|
});
|
|
97915
97883
|
return this.launch(input, origin);
|
|
97916
97884
|
}
|
|
97917
|
-
steer(input, origin = USER_PROMPT_ORIGIN) {
|
|
97885
|
+
steer(input, origin = USER_PROMPT_ORIGIN, opts) {
|
|
97918
97886
|
this.agent.records.logRecord({
|
|
97919
97887
|
type: "turn.steer",
|
|
97920
97888
|
input,
|
|
@@ -97923,7 +97891,8 @@ var TurnFlow = class {
|
|
|
97923
97891
|
if (this.activeTurn) {
|
|
97924
97892
|
this.steerBuffer.push({
|
|
97925
97893
|
input,
|
|
97926
|
-
origin
|
|
97894
|
+
origin,
|
|
97895
|
+
interrupt: opts?.interrupt
|
|
97927
97896
|
});
|
|
97928
97897
|
return null;
|
|
97929
97898
|
}
|
|
@@ -98245,6 +98214,7 @@ var TurnFlow = class {
|
|
|
98245
98214
|
log: this.agent.log,
|
|
98246
98215
|
maxSteps: loopControl?.maxStepsPerTurn,
|
|
98247
98216
|
maxRetryAttempts: loopControl?.maxRetriesPerStep,
|
|
98217
|
+
hasPendingSteer: () => this.steerBuffer.some((steer) => steer.origin.kind === "user" && steer.interrupt !== false),
|
|
98248
98218
|
hooks: {
|
|
98249
98219
|
beforeStep: async ({ signal: stepSignal, stepNumber }) => {
|
|
98250
98220
|
this.flushSteerBuffer();
|
|
@@ -99236,7 +99206,7 @@ var Agent = class {
|
|
|
99236
99206
|
this.turn.prompt(payload.input);
|
|
99237
99207
|
},
|
|
99238
99208
|
steer: (payload) => {
|
|
99239
|
-
this.turn.steer(payload.input);
|
|
99209
|
+
this.turn.steer(payload.input, USER_PROMPT_ORIGIN, { interrupt: payload.interrupt });
|
|
99240
99210
|
},
|
|
99241
99211
|
cancel: (payload) => {
|
|
99242
99212
|
this.turn.cancel(payload.turnId);
|
|
@@ -99968,17 +99938,18 @@ function permissionRuleToToml(rule) {
|
|
|
99968
99938
|
}
|
|
99969
99939
|
function servicesToToml(services, rawServices) {
|
|
99970
99940
|
const out = cloneRecord(rawServices);
|
|
99971
|
-
|
|
99972
|
-
|
|
99973
|
-
|
|
99974
|
-
|
|
99975
|
-
|
|
99976
|
-
|
|
99977
|
-
|
|
99978
|
-
|
|
99979
|
-
|
|
99980
|
-
|
|
99981
|
-
|
|
99941
|
+
for (const key of [
|
|
99942
|
+
"duckduckgo",
|
|
99943
|
+
"sogou",
|
|
99944
|
+
"so360",
|
|
99945
|
+
"baidu"
|
|
99946
|
+
]) {
|
|
99947
|
+
const toggle = services[key];
|
|
99948
|
+
if (toggle?.enabled !== void 0) out[key] = {
|
|
99949
|
+
...isPlainObject$1(out[key]) ? out[key] : {},
|
|
99950
|
+
enabled: toggle.enabled
|
|
99951
|
+
};
|
|
99952
|
+
}
|
|
99982
99953
|
return out;
|
|
99983
99954
|
}
|
|
99984
99955
|
function loopControlToToml(loopControl, rawLoopControl) {
|
|
@@ -102425,7 +102396,7 @@ function buildMcpHttpHeaders(config, envLookup) {
|
|
|
102425
102396
|
var require_windows = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
102426
102397
|
module.exports = isexe;
|
|
102427
102398
|
isexe.sync = sync;
|
|
102428
|
-
var fs$
|
|
102399
|
+
var fs$4 = __require("fs");
|
|
102429
102400
|
function checkPathExt(path, options) {
|
|
102430
102401
|
var pathext = options.pathExt !== void 0 ? options.pathExt : process.env.PATHEXT;
|
|
102431
102402
|
if (!pathext) return true;
|
|
@@ -102442,12 +102413,12 @@ var require_windows = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
102442
102413
|
return checkPathExt(path, options);
|
|
102443
102414
|
}
|
|
102444
102415
|
function isexe(path, options, cb) {
|
|
102445
|
-
fs$
|
|
102416
|
+
fs$4.stat(path, function(er, stat) {
|
|
102446
102417
|
cb(er, er ? false : checkStat(stat, path, options));
|
|
102447
102418
|
});
|
|
102448
102419
|
}
|
|
102449
102420
|
function sync(path, options) {
|
|
102450
|
-
return checkStat(fs$
|
|
102421
|
+
return checkStat(fs$4.statSync(path), path, options);
|
|
102451
102422
|
}
|
|
102452
102423
|
}));
|
|
102453
102424
|
//#endregion
|
|
@@ -102455,14 +102426,14 @@ var require_windows = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
102455
102426
|
var require_mode = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
102456
102427
|
module.exports = isexe;
|
|
102457
102428
|
isexe.sync = sync;
|
|
102458
|
-
var fs$
|
|
102429
|
+
var fs$3 = __require("fs");
|
|
102459
102430
|
function isexe(path, options, cb) {
|
|
102460
|
-
fs$
|
|
102431
|
+
fs$3.stat(path, function(er, stat) {
|
|
102461
102432
|
cb(er, er ? false : checkStat(stat, options));
|
|
102462
102433
|
});
|
|
102463
102434
|
}
|
|
102464
102435
|
function sync(path, options) {
|
|
102465
|
-
return checkStat(fs$
|
|
102436
|
+
return checkStat(fs$3.statSync(path), options);
|
|
102466
102437
|
}
|
|
102467
102438
|
function checkStat(stat, options) {
|
|
102468
102439
|
return stat.isFile() && checkMode(stat, options);
|
|
@@ -102677,16 +102648,16 @@ var require_shebang_command = /* @__PURE__ */ __commonJSMin(((exports, module) =
|
|
|
102677
102648
|
//#endregion
|
|
102678
102649
|
//#region ../../node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/readShebang.js
|
|
102679
102650
|
var require_readShebang = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
102680
|
-
const fs$
|
|
102651
|
+
const fs$2 = __require("fs");
|
|
102681
102652
|
const shebangCommand = require_shebang_command();
|
|
102682
102653
|
function readShebang(command) {
|
|
102683
102654
|
const size = 150;
|
|
102684
102655
|
const buffer = Buffer.alloc(size);
|
|
102685
102656
|
let fd;
|
|
102686
102657
|
try {
|
|
102687
|
-
fd = fs$
|
|
102688
|
-
fs$
|
|
102689
|
-
fs$
|
|
102658
|
+
fd = fs$2.openSync(command, "r");
|
|
102659
|
+
fs$2.readSync(fd, buffer, 0, size, 0);
|
|
102660
|
+
fs$2.closeSync(fd);
|
|
102690
102661
|
} catch (e) {}
|
|
102691
102662
|
return shebangCommand(buffer.toString());
|
|
102692
102663
|
}
|
|
@@ -117199,6 +117170,243 @@ function Document() {
|
|
|
117199
117170
|
illegalConstructor();
|
|
117200
117171
|
}
|
|
117201
117172
|
setPrototypeOf(Document, Document$1).prototype = Document$1.prototype;
|
|
117173
|
+
/** `.tmp` files older than this are treated as orphaned writes and swept. */
|
|
117174
|
+
const TMP_ORPHAN_MAX_AGE_MS = 300 * 1e3;
|
|
117175
|
+
function documentConversionCacheDir() {
|
|
117176
|
+
return path$8.join(resolveScreamHome(), "cache", "document-conversion");
|
|
117177
|
+
}
|
|
117178
|
+
function isEnoent(error) {
|
|
117179
|
+
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
117180
|
+
}
|
|
117181
|
+
function markitConversionCacheKey(bytes, extension) {
|
|
117182
|
+
const safeExtension = (extension.trim().toLowerCase().replace(/^\.+/, "") || "bin").replace(/[^a-z0-9]+/g, "_") || "bin";
|
|
117183
|
+
const safeVersion = getCoreVersion().replace(/[^a-z0-9]+/gi, "_");
|
|
117184
|
+
const digest = createHash("sha256").update(bytes).digest("hex");
|
|
117185
|
+
return `v${String(1)}-${safeVersion}-${safeExtension}-${digest}`;
|
|
117186
|
+
}
|
|
117187
|
+
function cacheEntryPath(key) {
|
|
117188
|
+
return path$8.join(documentConversionCacheDir(), `${key}.json`);
|
|
117189
|
+
}
|
|
117190
|
+
function errorMessage$2(error) {
|
|
117191
|
+
return error instanceof Error ? error.message : String(error);
|
|
117192
|
+
}
|
|
117193
|
+
function parseCacheEntry(raw) {
|
|
117194
|
+
const parsed = JSON.parse(raw);
|
|
117195
|
+
if (typeof parsed !== "object" || parsed === null) return null;
|
|
117196
|
+
if (!("version" in parsed) || parsed.version !== 1) return null;
|
|
117197
|
+
if (!("content" in parsed) || typeof parsed.content !== "string" || parsed.content.length === 0) return null;
|
|
117198
|
+
return {
|
|
117199
|
+
version: 1,
|
|
117200
|
+
content: parsed.content
|
|
117201
|
+
};
|
|
117202
|
+
}
|
|
117203
|
+
async function readMarkitConversionCache(key) {
|
|
117204
|
+
const target = cacheEntryPath(key);
|
|
117205
|
+
let raw;
|
|
117206
|
+
try {
|
|
117207
|
+
raw = await fs$1.readFile(target, "utf8");
|
|
117208
|
+
} catch (error) {
|
|
117209
|
+
if (!isEnoent(error)) log.debug("document conversion cache read failed", { error: errorMessage$2(error) });
|
|
117210
|
+
return { status: "miss" };
|
|
117211
|
+
}
|
|
117212
|
+
let entry;
|
|
117213
|
+
try {
|
|
117214
|
+
entry = parseCacheEntry(raw);
|
|
117215
|
+
} catch (error) {
|
|
117216
|
+
log.debug("document conversion cache read failed", { error: errorMessage$2(error) });
|
|
117217
|
+
entry = null;
|
|
117218
|
+
}
|
|
117219
|
+
if (entry === null) {
|
|
117220
|
+
await fs$1.rm(target, { force: true }).catch(() => void 0);
|
|
117221
|
+
return { status: "miss" };
|
|
117222
|
+
}
|
|
117223
|
+
return {
|
|
117224
|
+
status: "hit",
|
|
117225
|
+
content: entry.content
|
|
117226
|
+
};
|
|
117227
|
+
}
|
|
117228
|
+
async function pruneMarkitConversionCache(cacheDir) {
|
|
117229
|
+
let names;
|
|
117230
|
+
try {
|
|
117231
|
+
names = await fs$1.readdir(cacheDir);
|
|
117232
|
+
} catch (error) {
|
|
117233
|
+
if (!isEnoent(error)) log.debug("document conversion cache prune failed", { error: errorMessage$2(error) });
|
|
117234
|
+
return;
|
|
117235
|
+
}
|
|
117236
|
+
const now = Date.now();
|
|
117237
|
+
const entries = [];
|
|
117238
|
+
let totalBytes = 0;
|
|
117239
|
+
for (const name of names) {
|
|
117240
|
+
const entryPath = path$8.join(cacheDir, name);
|
|
117241
|
+
let stat;
|
|
117242
|
+
try {
|
|
117243
|
+
stat = await fs$1.stat(entryPath);
|
|
117244
|
+
} catch (error) {
|
|
117245
|
+
if (!isEnoent(error)) log.debug("document conversion cache prune failed", { error: errorMessage$2(error) });
|
|
117246
|
+
continue;
|
|
117247
|
+
}
|
|
117248
|
+
if (!stat.isFile()) continue;
|
|
117249
|
+
if (name.endsWith(".tmp")) {
|
|
117250
|
+
if (now - stat.mtimeMs > TMP_ORPHAN_MAX_AGE_MS) await fs$1.rm(entryPath, { force: true }).catch(() => void 0);
|
|
117251
|
+
continue;
|
|
117252
|
+
}
|
|
117253
|
+
if (!name.endsWith(".json")) continue;
|
|
117254
|
+
entries.push({
|
|
117255
|
+
path: entryPath,
|
|
117256
|
+
size: stat.size,
|
|
117257
|
+
mtimeMs: stat.mtimeMs
|
|
117258
|
+
});
|
|
117259
|
+
totalBytes += stat.size;
|
|
117260
|
+
}
|
|
117261
|
+
if (totalBytes <= 268435456) return;
|
|
117262
|
+
entries.sort((a, b) => a.mtimeMs - b.mtimeMs);
|
|
117263
|
+
for (const entry of entries) {
|
|
117264
|
+
if (totalBytes <= 268435456) break;
|
|
117265
|
+
try {
|
|
117266
|
+
await fs$1.rm(entry.path, { force: true });
|
|
117267
|
+
totalBytes -= entry.size;
|
|
117268
|
+
} catch (error) {
|
|
117269
|
+
if (!isEnoent(error)) log.debug("document conversion cache prune failed", { error: errorMessage$2(error) });
|
|
117270
|
+
}
|
|
117271
|
+
}
|
|
117272
|
+
}
|
|
117273
|
+
async function writeMarkitConversionCache(key, content) {
|
|
117274
|
+
const cacheDir = documentConversionCacheDir();
|
|
117275
|
+
const target = path$8.join(cacheDir, `${key}.json`);
|
|
117276
|
+
const tempPath = path$8.join(cacheDir, `${key}.${String(process.pid)}.${String(Date.now())}.${randomUUID()}.tmp`);
|
|
117277
|
+
const payload = JSON.stringify({
|
|
117278
|
+
version: 1,
|
|
117279
|
+
content
|
|
117280
|
+
});
|
|
117281
|
+
try {
|
|
117282
|
+
await fs$1.mkdir(cacheDir, { recursive: true });
|
|
117283
|
+
await fs$1.writeFile(tempPath, payload);
|
|
117284
|
+
await fs$1.rename(tempPath, target);
|
|
117285
|
+
} catch (error) {
|
|
117286
|
+
await fs$1.rm(tempPath, { force: true }).catch(() => void 0);
|
|
117287
|
+
log.debug("document conversion cache write failed", { error: errorMessage$2(error) });
|
|
117288
|
+
return;
|
|
117289
|
+
}
|
|
117290
|
+
pruneMarkitConversionCache(cacheDir).catch((error) => {
|
|
117291
|
+
log.debug("document conversion cache prune failed", { error: errorMessage$2(error) });
|
|
117292
|
+
});
|
|
117293
|
+
}
|
|
117294
|
+
//#endregion
|
|
117295
|
+
//#region ../../packages/agent-core/src/utils/markit.ts
|
|
117296
|
+
function logMuPdfWasmOutput(stream, values) {
|
|
117297
|
+
const message = values.length === 1 && typeof values[0] === "string" ? values[0] : values.map(String).join(" ");
|
|
117298
|
+
log.debug("mupdf wasm output", {
|
|
117299
|
+
stream,
|
|
117300
|
+
message
|
|
117301
|
+
});
|
|
117302
|
+
}
|
|
117303
|
+
function installMuPdfWasmLogger() {
|
|
117304
|
+
const globalScope = globalThis;
|
|
117305
|
+
const moduleConfig = globalScope.$libmupdf_wasm_Module ?? {};
|
|
117306
|
+
moduleConfig.print = (...values) => logMuPdfWasmOutput("stdout", values);
|
|
117307
|
+
moduleConfig.printErr = (...values) => logMuPdfWasmOutput("stderr", values);
|
|
117308
|
+
globalScope.$libmupdf_wasm_Module = moduleConfig;
|
|
117309
|
+
}
|
|
117310
|
+
installMuPdfWasmLogger();
|
|
117311
|
+
let markit = async () => {
|
|
117312
|
+
const promise = import("./markit-DG5XsAGz.mjs").then(({ Markit }) => {
|
|
117313
|
+
const instance = new Markit();
|
|
117314
|
+
markit = () => instance;
|
|
117315
|
+
return instance;
|
|
117316
|
+
});
|
|
117317
|
+
markit = () => promise;
|
|
117318
|
+
return promise;
|
|
117319
|
+
};
|
|
117320
|
+
function normalizeExtension(extension) {
|
|
117321
|
+
const trimmed = extension.trim().toLowerCase();
|
|
117322
|
+
if (!trimmed) return ".bin";
|
|
117323
|
+
return trimmed.startsWith(".") ? trimmed : `.${trimmed}`;
|
|
117324
|
+
}
|
|
117325
|
+
function normalizeError(error) {
|
|
117326
|
+
if (error instanceof Error && error.message.trim().length > 0) return error.message.trim();
|
|
117327
|
+
return "Conversion failed";
|
|
117328
|
+
}
|
|
117329
|
+
function isAbort(error) {
|
|
117330
|
+
return error instanceof Error && error.name === "AbortError";
|
|
117331
|
+
}
|
|
117332
|
+
async function untilAborted(signal, task) {
|
|
117333
|
+
if (signal === void 0) return task();
|
|
117334
|
+
signal.throwIfAborted();
|
|
117335
|
+
return new Promise((resolve, reject) => {
|
|
117336
|
+
const onAbort = () => {
|
|
117337
|
+
reject(abortError());
|
|
117338
|
+
};
|
|
117339
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
117340
|
+
task().then(resolve, reject).finally(() => {
|
|
117341
|
+
signal.removeEventListener("abort", onAbort);
|
|
117342
|
+
});
|
|
117343
|
+
});
|
|
117344
|
+
}
|
|
117345
|
+
async function runMarkitConversion(task, signal) {
|
|
117346
|
+
try {
|
|
117347
|
+
const instance = await markit();
|
|
117348
|
+
return await untilAborted(signal, () => task(instance));
|
|
117349
|
+
} catch (error) {
|
|
117350
|
+
if (isAbort(error)) throw abortError();
|
|
117351
|
+
throw error;
|
|
117352
|
+
}
|
|
117353
|
+
}
|
|
117354
|
+
function finalizeConversion(markdown) {
|
|
117355
|
+
if (typeof markdown === "string" && markdown.length > 0) return {
|
|
117356
|
+
content: markdown,
|
|
117357
|
+
ok: true
|
|
117358
|
+
};
|
|
117359
|
+
return {
|
|
117360
|
+
content: "",
|
|
117361
|
+
ok: false,
|
|
117362
|
+
error: "Conversion produced no output"
|
|
117363
|
+
};
|
|
117364
|
+
}
|
|
117365
|
+
function toBuffer(bytes) {
|
|
117366
|
+
return Buffer.isBuffer(bytes) ? bytes : Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
117367
|
+
}
|
|
117368
|
+
function throwIfAborted(signal) {
|
|
117369
|
+
if (signal?.aborted) throw abortError();
|
|
117370
|
+
}
|
|
117371
|
+
async function runCachedBufferConversion(bytes, streamInfo, signal, cacheEnabled = true) {
|
|
117372
|
+
const cacheKey = cacheEnabled ? markitConversionCacheKey(bytes, streamInfo.extension ?? streamInfo.mimetype ?? ".bin") : void 0;
|
|
117373
|
+
if (cacheKey !== void 0) {
|
|
117374
|
+
throwIfAborted(signal);
|
|
117375
|
+
const cached = await readMarkitConversionCache(cacheKey);
|
|
117376
|
+
throwIfAborted(signal);
|
|
117377
|
+
if (cached.status === "hit") return {
|
|
117378
|
+
content: cached.content,
|
|
117379
|
+
ok: true,
|
|
117380
|
+
cache: "hit"
|
|
117381
|
+
};
|
|
117382
|
+
}
|
|
117383
|
+
throwIfAborted(signal);
|
|
117384
|
+
let result;
|
|
117385
|
+
try {
|
|
117386
|
+
result = await runMarkitConversion((markitInstance) => markitInstance.convert(toBuffer(bytes), streamInfo), signal);
|
|
117387
|
+
} catch (error) {
|
|
117388
|
+
if (isAbort(error)) throw abortError();
|
|
117389
|
+
return {
|
|
117390
|
+
content: "",
|
|
117391
|
+
ok: false,
|
|
117392
|
+
error: normalizeError(error),
|
|
117393
|
+
cache: cacheEnabled ? "miss" : "skipped"
|
|
117394
|
+
};
|
|
117395
|
+
}
|
|
117396
|
+
const finalized = finalizeConversion(result.markdown);
|
|
117397
|
+
if (finalized.ok && cacheKey !== void 0) await writeMarkitConversionCache(cacheKey, finalized.content);
|
|
117398
|
+
return {
|
|
117399
|
+
...finalized,
|
|
117400
|
+
cache: cacheEnabled ? "miss" : "skipped"
|
|
117401
|
+
};
|
|
117402
|
+
}
|
|
117403
|
+
async function convertBufferWithMarkit(buffer, extension, signal, options) {
|
|
117404
|
+
const normalizedExtension = normalizeExtension(extension);
|
|
117405
|
+
return runCachedBufferConversion(buffer, {
|
|
117406
|
+
extension: normalizedExtension,
|
|
117407
|
+
filename: `input${normalizedExtension}`
|
|
117408
|
+
}, signal, options?.useCache ?? true);
|
|
117409
|
+
}
|
|
117202
117410
|
//#endregion
|
|
117203
117411
|
//#region ../../packages/agent-core/src/tools/providers/local-fetch-url.ts
|
|
117204
117412
|
/**
|
|
@@ -117216,6 +117424,49 @@ setPrototypeOf(Document, Document$1).prototype = Document$1.prototype;
|
|
|
117216
117424
|
* common content containers (`<article>` / `<main>` / `<body>`)
|
|
117217
117425
|
* before throwing a "meaningful content" error.
|
|
117218
117426
|
*/
|
|
117427
|
+
/** Document types the markit engine converts to markdown. */
|
|
117428
|
+
const CONVERTIBLE_EXTENSIONS = new Set([
|
|
117429
|
+
".pdf",
|
|
117430
|
+
".docx",
|
|
117431
|
+
".pptx",
|
|
117432
|
+
".xlsx",
|
|
117433
|
+
".epub"
|
|
117434
|
+
]);
|
|
117435
|
+
const CONVERTIBLE_MIME_PREFIXES = [
|
|
117436
|
+
["application/pdf", ".pdf"],
|
|
117437
|
+
["application/x-pdf", ".pdf"],
|
|
117438
|
+
["application/vnd.openxmlformats-officedocument.wordprocessingml.document", ".docx"],
|
|
117439
|
+
["application/vnd.openxmlformats-officedocument.presentationml.presentation", ".pptx"],
|
|
117440
|
+
["application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", ".xlsx"],
|
|
117441
|
+
["application/epub+zip", ".epub"]
|
|
117442
|
+
];
|
|
117443
|
+
/**
|
|
117444
|
+
* Decide whether a response is a convertible document, from Content-Type
|
|
117445
|
+
* first and the URL path extension as fallback. `confident: true` means the
|
|
117446
|
+
* Content-Type itself declared a document type (conversion failure is a real
|
|
117447
|
+
* error); `confident: false` means only the URL extension matched (an HTML
|
|
117448
|
+
* page at a .pdf URL must fall back to normal extraction).
|
|
117449
|
+
*/
|
|
117450
|
+
function resolveDocumentExtension(url, contentType) {
|
|
117451
|
+
for (const [prefix, extension] of CONVERTIBLE_MIME_PREFIXES) if (contentType.startsWith(prefix)) return {
|
|
117452
|
+
extension,
|
|
117453
|
+
confident: true
|
|
117454
|
+
};
|
|
117455
|
+
if (contentType.length > 0 && !contentType.startsWith("application/octet-stream") && !contentType.startsWith("binary/octet-stream")) return;
|
|
117456
|
+
try {
|
|
117457
|
+
const pathname = new URL(url).pathname.toLowerCase();
|
|
117458
|
+
const dot = pathname.lastIndexOf(".");
|
|
117459
|
+
if (dot >= 0) {
|
|
117460
|
+
const extension = pathname.slice(dot);
|
|
117461
|
+
if (CONVERTIBLE_EXTENSIONS.has(extension)) return {
|
|
117462
|
+
extension,
|
|
117463
|
+
confident: false
|
|
117464
|
+
};
|
|
117465
|
+
}
|
|
117466
|
+
} catch {}
|
|
117467
|
+
}
|
|
117468
|
+
/** Hard ceiling for one markit conversion (omp uses 20s; allow slow hosts). */
|
|
117469
|
+
const CONVERSION_TIMEOUT_MS = 3e4;
|
|
117219
117470
|
const DEFAULT_USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36";
|
|
117220
117471
|
const DEFAULT_MAX_BYTES = 10 * 1024 * 1024;
|
|
117221
117472
|
const FETCH_TIMEOUT_MS = 3e4;
|
|
@@ -117281,7 +117532,7 @@ function isPrivateIp(ip) {
|
|
|
117281
117532
|
}
|
|
117282
117533
|
return lower === "::1" || lower === "::" || lower.startsWith("fe80:") || lower.startsWith("fc") || lower.startsWith("fd");
|
|
117283
117534
|
}
|
|
117284
|
-
function cacheKey
|
|
117535
|
+
function cacheKey(url, allowPrivate, maxBytes, userAgent) {
|
|
117285
117536
|
return `local:${url}:${String(allowPrivate)}:${String(maxBytes)}:${userAgent}`;
|
|
117286
117537
|
}
|
|
117287
117538
|
const defaultDnsLookup = async (hostname) => {
|
|
@@ -117303,7 +117554,7 @@ var LocalFetchURLProvider = class {
|
|
|
117303
117554
|
this.dnsLookup = options.dnsLookup ?? defaultDnsLookup;
|
|
117304
117555
|
}
|
|
117305
117556
|
async fetch(url, _options) {
|
|
117306
|
-
const key = cacheKey
|
|
117557
|
+
const key = cacheKey(url, this.allowPrivateAddresses, this.maxBytes, this.userAgent);
|
|
117307
117558
|
const cached = this.cache.get(key);
|
|
117308
117559
|
if (cached !== void 0) return cached;
|
|
117309
117560
|
await assertSafeFetchTarget(url, this.allowPrivateAddresses, this.dnsLookup);
|
|
@@ -117329,10 +117580,16 @@ var LocalFetchURLProvider = class {
|
|
|
117329
117580
|
throw new Error(`Response body too large: ${String(cl)} bytes exceeds maxBytes (${String(this.maxBytes)}).`);
|
|
117330
117581
|
}
|
|
117331
117582
|
}
|
|
117583
|
+
const contentType = (response.headers.get("content-type") ?? "").toLowerCase();
|
|
117584
|
+
const documentExtension = resolveDocumentExtension(url, contentType);
|
|
117585
|
+
if (documentExtension !== void 0) return this.fetchDocument(response, documentExtension.extension, contentType, documentExtension.confident);
|
|
117332
117586
|
const body = await response.text();
|
|
117333
117587
|
const actualBytes = Buffer.byteLength(body, "utf8");
|
|
117334
117588
|
if (actualBytes > this.maxBytes) throw new Error(`Response body too large: ${String(actualBytes)} bytes exceeds maxBytes (${String(this.maxBytes)}).`);
|
|
117335
|
-
|
|
117589
|
+
return this.extractTextResponse(body, contentType);
|
|
117590
|
+
}
|
|
117591
|
+
/** Text-path extraction shared by the normal flow and the document fallback. */
|
|
117592
|
+
extractTextResponse(body, contentType) {
|
|
117336
117593
|
if (contentType.startsWith("text/plain") || contentType.startsWith("text/markdown")) return {
|
|
117337
117594
|
content: body,
|
|
117338
117595
|
kind: "passthrough"
|
|
@@ -117342,6 +117599,28 @@ var LocalFetchURLProvider = class {
|
|
|
117342
117599
|
kind: "extracted"
|
|
117343
117600
|
};
|
|
117344
117601
|
}
|
|
117602
|
+
/**
|
|
117603
|
+
* Fetch a convertible document (PDF/Office) as binary and convert it to
|
|
117604
|
+
* markdown via the markit engine (lazy-loaded, cached on disk).
|
|
117605
|
+
*
|
|
117606
|
+
* `confident` distinguishes detection strength: a convertible Content-Type
|
|
117607
|
+
* means conversion failure is a real error (corrupt document), while an
|
|
117608
|
+
* extension-only guess (e.g. an HTML viewer page at a .pdf URL) falls back
|
|
117609
|
+
* to the normal text extraction path instead of erroring (omp's behavior).
|
|
117610
|
+
*/
|
|
117611
|
+
async fetchDocument(response, extension, contentType, confident) {
|
|
117612
|
+
const bytes = new Uint8Array(await response.arrayBuffer());
|
|
117613
|
+
if (bytes.byteLength > this.maxBytes) throw new Error(`Response body too large: ${String(bytes.byteLength)} bytes exceeds maxBytes (${String(this.maxBytes)}).`);
|
|
117614
|
+
const converted = await convertBufferWithMarkit(bytes, extension, AbortSignal.timeout(CONVERSION_TIMEOUT_MS));
|
|
117615
|
+
if (!converted.ok) {
|
|
117616
|
+
if (!confident) return this.extractTextResponse(new TextDecoder().decode(bytes), contentType);
|
|
117617
|
+
throw new Error(`Document conversion failed (${extension}): ${converted.error ?? "unknown error"}`);
|
|
117618
|
+
}
|
|
117619
|
+
return {
|
|
117620
|
+
content: converted.content,
|
|
117621
|
+
kind: "extracted"
|
|
117622
|
+
};
|
|
117623
|
+
}
|
|
117345
117624
|
extractMainContent(html) {
|
|
117346
117625
|
const primary = parseHTML(html);
|
|
117347
117626
|
try {
|
|
@@ -117362,268 +117641,220 @@ var LocalFetchURLProvider = class {
|
|
|
117362
117641
|
}
|
|
117363
117642
|
};
|
|
117364
117643
|
//#endregion
|
|
117365
|
-
//#region ../../packages/agent-core/src/tools/providers/
|
|
117644
|
+
//#region ../../packages/agent-core/src/tools/providers/search-timeout.ts
|
|
117366
117645
|
/**
|
|
117367
|
-
*
|
|
117646
|
+
* Hard timeout for outbound web-search requests (omp pattern).
|
|
117368
117647
|
*
|
|
117369
|
-
*
|
|
117370
|
-
*
|
|
117371
|
-
*
|
|
117372
|
-
*
|
|
117373
|
-
|
|
117374
|
-
|
|
117375
|
-
|
|
117376
|
-
|
|
117377
|
-
|
|
117378
|
-
|
|
117379
|
-
*/
|
|
117380
|
-
function cacheKey(baseUrl, url) {
|
|
117381
|
-
return `cli:${baseUrl}:${url}`;
|
|
117382
|
-
}
|
|
117383
|
-
var ScreamCliFetchURLProvider = class {
|
|
117384
|
-
tokenProvider;
|
|
117385
|
-
apiKey;
|
|
117386
|
-
baseUrl;
|
|
117387
|
-
defaultHeaders;
|
|
117388
|
-
customHeaders;
|
|
117389
|
-
localFallback;
|
|
117390
|
-
fetchImpl;
|
|
117391
|
-
cache;
|
|
117392
|
-
constructor(options) {
|
|
117393
|
-
this.tokenProvider = options.tokenProvider;
|
|
117394
|
-
this.apiKey = options.apiKey;
|
|
117395
|
-
this.baseUrl = options.baseUrl;
|
|
117396
|
-
this.defaultHeaders = options.defaultHeaders ?? {};
|
|
117397
|
-
this.customHeaders = options.customHeaders ?? {};
|
|
117398
|
-
this.localFallback = options.localFallback;
|
|
117399
|
-
this.fetchImpl = options.fetchImpl ?? globalThis.fetch.bind(globalThis);
|
|
117400
|
-
this.cache = options.cache ?? new FetchCache();
|
|
117401
|
-
}
|
|
117402
|
-
async fetch(url, options) {
|
|
117403
|
-
const key = cacheKey(this.baseUrl, url);
|
|
117404
|
-
const cached = this.cache.get(key);
|
|
117405
|
-
if (cached !== void 0) return cached;
|
|
117406
|
-
const result = await this.fetchFresh(url, options?.toolCallId);
|
|
117407
|
-
this.cache.set(key, result);
|
|
117408
|
-
return result;
|
|
117409
|
-
}
|
|
117410
|
-
async fetchFresh(url, toolCallId) {
|
|
117411
|
-
try {
|
|
117412
|
-
return {
|
|
117413
|
-
content: await this.fetchViaScreamCli(url, toolCallId),
|
|
117414
|
-
kind: "extracted"
|
|
117415
|
-
};
|
|
117416
|
-
} catch {
|
|
117417
|
-
return this.localFallback.fetch(url, { toolCallId });
|
|
117418
|
-
}
|
|
117419
|
-
}
|
|
117420
|
-
async fetchViaScreamCli(url, toolCallId) {
|
|
117421
|
-
const bodyJson = JSON.stringify({ url });
|
|
117422
|
-
const response = await this.post(bodyJson, toolCallId);
|
|
117423
|
-
if (response.status !== 200) {
|
|
117424
|
-
let detail = "";
|
|
117425
|
-
try {
|
|
117426
|
-
detail = await response.text();
|
|
117427
|
-
} catch {}
|
|
117428
|
-
throw new HttpFetchError(response.status, `ScreamCli fetch request failed: HTTP ${String(response.status)}. ${detail}`.trim());
|
|
117429
|
-
}
|
|
117430
|
-
return response.text();
|
|
117431
|
-
}
|
|
117432
|
-
async post(bodyJson, toolCallId) {
|
|
117433
|
-
const accessToken = await this.resolveApiKey();
|
|
117434
|
-
return this.fetchImpl(this.baseUrl, {
|
|
117435
|
-
method: "POST",
|
|
117436
|
-
headers: {
|
|
117437
|
-
...this.defaultHeaders,
|
|
117438
|
-
Authorization: `Bearer ${accessToken}`,
|
|
117439
|
-
Accept: "text/markdown",
|
|
117440
|
-
"Content-Type": "application/json",
|
|
117441
|
-
...toolCallId !== void 0 && toolCallId.length > 0 ? { "X-Msh-Tool-Call-Id": toolCallId } : {},
|
|
117442
|
-
...this.customHeaders
|
|
117443
|
-
},
|
|
117444
|
-
body: bodyJson
|
|
117445
|
-
});
|
|
117446
|
-
}
|
|
117447
|
-
async resolveApiKey() {
|
|
117448
|
-
if (this.tokenProvider !== void 0) try {
|
|
117449
|
-
const token = await this.tokenProvider.getAccessToken();
|
|
117450
|
-
if (token.trim().length > 0) return token;
|
|
117451
|
-
if (this.apiKey !== void 0 && this.apiKey.length > 0) return this.apiKey;
|
|
117452
|
-
} catch (error) {
|
|
117453
|
-
if (this.apiKey !== void 0 && this.apiKey.length > 0) return this.apiKey;
|
|
117454
|
-
throw error;
|
|
117455
|
-
}
|
|
117456
|
-
if (this.apiKey !== void 0 && this.apiKey.length > 0) return this.apiKey;
|
|
117457
|
-
throw new Error("ScreamCli fetch service is not configured: missing API key or token provider.");
|
|
117458
|
-
}
|
|
117459
|
-
};
|
|
117648
|
+
* A stalled TCP/TLS connection can keep an undici fetch pending for minutes;
|
|
117649
|
+
* composing the caller's signal with a fixed ceiling guarantees the request
|
|
117650
|
+
* settles. Fires as a `TimeoutError` DOMException, which the tool layer maps
|
|
117651
|
+
* to "Search timed out".
|
|
117652
|
+
*/
|
|
117653
|
+
const SEARCH_HARD_TIMEOUT_MS = 6e4;
|
|
117654
|
+
function withHardTimeout(signal, ms = SEARCH_HARD_TIMEOUT_MS) {
|
|
117655
|
+
const timeout = AbortSignal.timeout(ms);
|
|
117656
|
+
return signal !== void 0 ? AbortSignal.any([signal, timeout]) : timeout;
|
|
117657
|
+
}
|
|
117460
117658
|
//#endregion
|
|
117461
117659
|
//#region ../../packages/agent-core/src/tools/providers/duckduckgo-search.ts
|
|
117660
|
+
const DUCKDUCKGO_HTML_URL = "https://html.duckduckgo.com/html/";
|
|
117661
|
+
/**
|
|
117662
|
+
* Browser-like UA so DDG serves the standard results page instead of the
|
|
117663
|
+
* mobile/noscript variants, and is less likely to trip bot detection.
|
|
117664
|
+
* DDG answers automation it suspects with HTTP 202 plus an anomaly modal;
|
|
117665
|
+
* the body check (not the status) is the reliable signal.
|
|
117666
|
+
*/
|
|
117667
|
+
const BROWSER_USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/149.0.0.0 Safari/537.36";
|
|
117462
117668
|
var DuckDuckGoSearchProvider = class {
|
|
117669
|
+
name = "duckduckgo";
|
|
117463
117670
|
fetchImpl;
|
|
117464
117671
|
constructor(options = {}) {
|
|
117465
117672
|
this.fetchImpl = options.fetchImpl ?? globalThis.fetch.bind(globalThis);
|
|
117466
117673
|
}
|
|
117467
117674
|
async search(query, options) {
|
|
117468
117675
|
const limit = options?.limit ?? 5;
|
|
117469
|
-
|
|
117470
|
-
|
|
117471
|
-
|
|
117472
|
-
|
|
117473
|
-
|
|
117474
|
-
|
|
117475
|
-
|
|
117476
|
-
|
|
117477
|
-
|
|
117478
|
-
|
|
117479
|
-
|
|
117480
|
-
|
|
117481
|
-
|
|
117482
|
-
|
|
117483
|
-
|
|
117484
|
-
|
|
117485
|
-
|
|
117486
|
-
|
|
117487
|
-
|
|
117488
|
-
if (response.status !==
|
|
117489
|
-
|
|
117490
|
-
|
|
117491
|
-
}
|
|
117492
|
-
let json;
|
|
117493
|
-
try {
|
|
117494
|
-
json = await response.json();
|
|
117495
|
-
} catch {
|
|
117496
|
-
return [];
|
|
117497
|
-
}
|
|
117498
|
-
return this.buildApiResults(json, limit);
|
|
117499
|
-
}
|
|
117500
|
-
buildApiResults(json, limit) {
|
|
117501
|
-
const results = [];
|
|
117502
|
-
if (json.AbstractText && json.AbstractURL && json.AbstractText.trim().length > 0) results.push({
|
|
117503
|
-
title: json.Heading && json.Heading.trim().length > 0 ? json.Heading : json.AbstractSource ?? "DuckDuckGo",
|
|
117504
|
-
url: json.AbstractURL,
|
|
117505
|
-
snippet: json.AbstractText
|
|
117506
|
-
});
|
|
117507
|
-
if (json.RelatedTopics && json.RelatedTopics.length > 0) {
|
|
117508
|
-
const flattened = flattenRelatedTopics(json.RelatedTopics);
|
|
117509
|
-
for (const topic of flattened) {
|
|
117510
|
-
if (results.length >= limit) break;
|
|
117511
|
-
const url = topic.FirstURL ?? "";
|
|
117512
|
-
const text = topic.Text ?? "";
|
|
117513
|
-
if (url === "" || text === "") continue;
|
|
117514
|
-
results.push({
|
|
117515
|
-
title: text,
|
|
117516
|
-
url,
|
|
117517
|
-
snippet: text
|
|
117518
|
-
});
|
|
117519
|
-
}
|
|
117520
|
-
}
|
|
117521
|
-
return results.slice(0, limit);
|
|
117522
|
-
}
|
|
117523
|
-
/**
|
|
117524
|
-
* Scrape DuckDuckGo Lite search results.
|
|
117525
|
-
*
|
|
117526
|
-
* Lite is a minimal HTML table with no JavaScript, designed for basic
|
|
117527
|
-
* browsers. It may return a CAPTCHA page from datacenter IPs — in that
|
|
117528
|
-
* case we return `[]` so the caller can fall through.
|
|
117529
|
-
*/
|
|
117530
|
-
async searchViaLite(query, limit) {
|
|
117531
|
-
const url = `https://lite.duckduckgo.com/lite/?q=${encodeURIComponent(query)}`;
|
|
117532
|
-
let response;
|
|
117533
|
-
try {
|
|
117534
|
-
response = await this.fetchImpl(url);
|
|
117535
|
-
} catch {
|
|
117536
|
-
return [];
|
|
117537
|
-
}
|
|
117538
|
-
if (response.status !== 200) {
|
|
117539
|
-
await drainBody(response);
|
|
117540
|
-
return [];
|
|
117541
|
-
}
|
|
117542
|
-
let html;
|
|
117543
|
-
try {
|
|
117544
|
-
html = await response.text();
|
|
117545
|
-
} catch {
|
|
117546
|
-
return [];
|
|
117547
|
-
}
|
|
117548
|
-
if (isCaptchaPage(html)) return [];
|
|
117549
|
-
return parseLiteResults(html, limit);
|
|
117676
|
+
const form = new URLSearchParams({
|
|
117677
|
+
q: query,
|
|
117678
|
+
kl: "us-en"
|
|
117679
|
+
});
|
|
117680
|
+
form.set("b", "");
|
|
117681
|
+
const response = await this.fetchImpl(DUCKDUCKGO_HTML_URL, {
|
|
117682
|
+
method: "POST",
|
|
117683
|
+
body: form.toString(),
|
|
117684
|
+
headers: {
|
|
117685
|
+
Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8",
|
|
117686
|
+
"Accept-Language": "en,en-US;q=0.9",
|
|
117687
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
117688
|
+
Referer: "https://html.duckduckgo.com/",
|
|
117689
|
+
"Upgrade-Insecure-Requests": "1",
|
|
117690
|
+
"User-Agent": BROWSER_USER_AGENT
|
|
117691
|
+
},
|
|
117692
|
+
signal: withHardTimeout(options?.signal)
|
|
117693
|
+
});
|
|
117694
|
+
const html = await response.text();
|
|
117695
|
+
if (!response.ok && response.status !== 202) throw new Error(`DuckDuckGo request failed: HTTP ${String(response.status)}`);
|
|
117696
|
+
if (isAnomalyResponse(html)) throw new Error("DuckDuckGo blocked the request with a bot-detection challenge (common from datacenter/shared-egress IPs)");
|
|
117697
|
+
return parseHtmlResults(html).slice(0, limit);
|
|
117550
117698
|
}
|
|
117551
117699
|
};
|
|
117552
|
-
/**
|
|
117553
|
-
|
|
117554
|
-
|
|
117555
|
-
* The API nests topics in two ways:
|
|
117556
|
-
* - A direct topic has `FirstURL` + `Text` (may lack `Topics`).
|
|
117557
|
-
* - A category group has a `Name` and nested `Topics[]`.
|
|
117558
|
-
* We walk both shapes, returning a flat list of leaf topics.
|
|
117559
|
-
*/
|
|
117560
|
-
function flattenRelatedTopics(topics) {
|
|
117561
|
-
const out = [];
|
|
117562
|
-
for (const topic of topics) if (topic.Topics && topic.Topics.length > 0) out.push(...flattenRelatedTopics(topic.Topics));
|
|
117563
|
-
else if (topic.FirstURL) out.push(topic);
|
|
117564
|
-
return out;
|
|
117700
|
+
/** `true` when DDG returned the bot-challenge modal instead of results. */
|
|
117701
|
+
function isAnomalyResponse(html) {
|
|
117702
|
+
return html.includes("anomaly-modal") || html.includes("anomaly.js");
|
|
117565
117703
|
}
|
|
117566
117704
|
/**
|
|
117567
|
-
*
|
|
117705
|
+
* Each result lives in a `<div class="result …">` container with
|
|
117706
|
+
* `<a class="result__a">` for the title link and an optional
|
|
117707
|
+
* `<a|div|span class="result__snippet">` sibling for the preview text.
|
|
117708
|
+
* Sponsored rows, missing snippets, and the pagination row are tolerated.
|
|
117568
117709
|
*/
|
|
117569
|
-
|
|
117570
|
-
|
|
117710
|
+
const RESULT_BLOCK_RE = /<div\b[^>]*\bclass="[^"]*\bresult\b[^"]*"[^>]*>([\s\S]*?)(?=<div\b[^>]*\bclass="[^"]*\bresult\b|<div\b[^>]*\bclass="[^"]*\bnav-link\b|$)/g;
|
|
117711
|
+
const RESULT_TITLE_RE = /<a\b[^>]*\bclass="[^"]*\bresult__a\b[^"]*"[^>]*\bhref="([^"]+)"[^>]*>([\s\S]*?)<\/a>/;
|
|
117712
|
+
const RESULT_SNIPPET_RE = /<(?:a|div|span)\b[^>]*\bclass="[^"]*\bresult__snippet\b[^"]*"[^>]*>([\s\S]*?)<\/(?:a|div|span)>/;
|
|
117713
|
+
/** Strip inline tags (DDG wraps query terms in `<b>`) and decode entities. */
|
|
117714
|
+
function decodeHtmlText$1(value) {
|
|
117715
|
+
return value.replace(/<[^>]*>/g, " ").replace(/&#(\d+);/g, (_, code) => String.fromCharCode(Number(code))).replace(/&#x([0-9a-f]+);/gi, (_, code) => String.fromCharCode(Number.parseInt(code, 16))).replace(/ /gi, " ").replace(/&/gi, "&").replace(/</gi, "<").replace(/>/gi, ">").replace(/"/gi, "\"").replace(/'|'/gi, "'").replace(/\s+/g, " ").trim();
|
|
117571
117716
|
}
|
|
117572
117717
|
/**
|
|
117573
|
-
*
|
|
117574
|
-
*
|
|
117575
|
-
*
|
|
117576
|
-
*
|
|
117577
|
-
* The Lite markup is intentionally minimal (no JS, no CSS classes beyond a
|
|
117578
|
-
* handful of utility names), so a DOM parser is unnecessary overhead.
|
|
117718
|
+
* Resolve a DDG result href to the underlying target URL. DDG routes
|
|
117719
|
+
* outbound clicks through `//duckduckgo.com/l/?uddg=<encoded>`; handles
|
|
117720
|
+
* redirect wrappers, protocol-relative links, and plain absolute URLs.
|
|
117579
117721
|
*/
|
|
117580
|
-
|
|
117581
|
-
|
|
117582
|
-
|
|
117583
|
-
|
|
117584
|
-
|
|
117585
|
-
|
|
117586
|
-
/** Unwrap a DuckDuckGo redirect URL to the real target if possible. */
|
|
117587
|
-
function unwrapDdgRedirect(url) {
|
|
117588
|
-
const uddgMatch = url.match(/[?&]uddg=([^&]+)/);
|
|
117589
|
-
if (uddgMatch?.[1]) try {
|
|
117590
|
-
return decodeURIComponent(uddgMatch[1]);
|
|
117722
|
+
function unwrapResultUrl(href) {
|
|
117723
|
+
if (href === "") return void 0;
|
|
117724
|
+
const decoded = href.replace(/&/gi, "&");
|
|
117725
|
+
const wrapMatch = decoded.match(/[?&]uddg=([^&]+)/);
|
|
117726
|
+
if (wrapMatch?.[1] !== void 0) try {
|
|
117727
|
+
return decodeURIComponent(wrapMatch[1]);
|
|
117591
117728
|
} catch {
|
|
117592
|
-
return
|
|
117729
|
+
return;
|
|
117593
117730
|
}
|
|
117594
|
-
return
|
|
117731
|
+
if (decoded.startsWith("//")) return `https:${decoded}`;
|
|
117732
|
+
if (decoded.startsWith("http://") || decoded.startsWith("https://")) return decoded;
|
|
117595
117733
|
}
|
|
117596
|
-
function
|
|
117734
|
+
function parseHtmlResults(html) {
|
|
117597
117735
|
const results = [];
|
|
117598
|
-
const
|
|
117599
|
-
for (const match of
|
|
117600
|
-
|
|
117601
|
-
const
|
|
117602
|
-
|
|
117603
|
-
|
|
117736
|
+
const seen = /* @__PURE__ */ new Set();
|
|
117737
|
+
for (const match of html.matchAll(RESULT_BLOCK_RE)) {
|
|
117738
|
+
const block = match[1] ?? "";
|
|
117739
|
+
const title = RESULT_TITLE_RE.exec(block);
|
|
117740
|
+
if (title === null) continue;
|
|
117741
|
+
const url = unwrapResultUrl(title[1] ?? "");
|
|
117742
|
+
if (url === void 0 || seen.has(url)) continue;
|
|
117743
|
+
const titleText = decodeHtmlText$1(title[2] ?? "");
|
|
117744
|
+
if (titleText === "") continue;
|
|
117745
|
+
seen.add(url);
|
|
117746
|
+
const snippet = RESULT_SNIPPET_RE.exec(block);
|
|
117747
|
+
const snippetText = snippet !== null ? decodeHtmlText$1(snippet[1] ?? "") : "";
|
|
117604
117748
|
results.push({
|
|
117605
|
-
title,
|
|
117606
|
-
url
|
|
117607
|
-
snippet:
|
|
117749
|
+
title: titleText,
|
|
117750
|
+
url,
|
|
117751
|
+
snippet: snippetText !== "" ? snippetText : titleText
|
|
117608
117752
|
});
|
|
117609
117753
|
}
|
|
117610
|
-
const snippetMatches = html.matchAll(LITE_SNIPPET_RE);
|
|
117611
|
-
let snippetIndex = 0;
|
|
117612
|
-
for (const match of snippetMatches) {
|
|
117613
|
-
if (snippetIndex >= results.length) break;
|
|
117614
|
-
const snippet = stripHtmlAndDecode(match[1] ?? "");
|
|
117615
|
-
const entry = results[snippetIndex];
|
|
117616
|
-
if (entry && snippet.length > 0) entry.snippet = snippet;
|
|
117617
|
-
snippetIndex++;
|
|
117618
|
-
}
|
|
117619
117754
|
return results;
|
|
117620
117755
|
}
|
|
117621
|
-
|
|
117622
|
-
|
|
117623
|
-
|
|
117624
|
-
|
|
117625
|
-
|
|
117756
|
+
//#endregion
|
|
117757
|
+
//#region ../../packages/agent-core/src/tools/providers/domestic-search.ts
|
|
117758
|
+
const BROWSER_HEADERS = {
|
|
117759
|
+
Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
|
|
117760
|
+
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
|
|
117761
|
+
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/149.0.0.0 Safari/537.36"
|
|
117762
|
+
};
|
|
117763
|
+
/** Strip inline tags and decode the common named/numeric entities. */
|
|
117764
|
+
function decodeHtmlText(value) {
|
|
117765
|
+
return value.replace(/<[^>]*>/g, " ").replace(/&#(\d+);/g, (_, code) => String.fromCharCode(Number(code))).replace(/&#x([0-9a-f]+);/gi, (_, code) => String.fromCharCode(Number.parseInt(code, 16))).replace(/ /gi, " ").replace(/&/gi, "&").replace(/</gi, "<").replace(/>/gi, ">").replace(/"/gi, "\"").replace(/'|'/gi, "'").replace(/\s+/g, " ").trim();
|
|
117626
117766
|
}
|
|
117767
|
+
async function searchEngine(spec, fetchImpl, query, options) {
|
|
117768
|
+
const limit = options?.limit ?? 5;
|
|
117769
|
+
const response = await fetchImpl(spec.url(query), {
|
|
117770
|
+
headers: BROWSER_HEADERS,
|
|
117771
|
+
signal: withHardTimeout(options?.signal)
|
|
117772
|
+
});
|
|
117773
|
+
const html = await response.text();
|
|
117774
|
+
if (!response.ok) throw new Error(`${spec.label} request failed: HTTP ${String(response.status)}`);
|
|
117775
|
+
if (spec.botMarkers.some((m) => html.includes(m))) throw new Error(`${spec.label} blocked the request with an anti-bot challenge`);
|
|
117776
|
+
const results = [];
|
|
117777
|
+
const seen = /* @__PURE__ */ new Set();
|
|
117778
|
+
for (const match of html.matchAll(spec.blockRe)) {
|
|
117779
|
+
if (results.length >= limit) break;
|
|
117780
|
+
const block = match[1] ?? "";
|
|
117781
|
+
const title = spec.titleRe.exec(block);
|
|
117782
|
+
if (title === null) continue;
|
|
117783
|
+
const rawHref = (title[1] ?? "").replace(/&/gi, "&");
|
|
117784
|
+
const url = spec.normalizeUrl !== void 0 ? spec.normalizeUrl(rawHref) : rawHref;
|
|
117785
|
+
if (url === void 0 || url === "" || seen.has(url)) continue;
|
|
117786
|
+
const titleText = decodeHtmlText(title[2] ?? "");
|
|
117787
|
+
if (titleText === "") continue;
|
|
117788
|
+
seen.add(url);
|
|
117789
|
+
const snippetMatch = spec.snippetRe === void 0 ? null : spec.snippetRe.exec(block);
|
|
117790
|
+
const snippetText = snippetMatch !== null ? decodeHtmlText(snippetMatch[1] ?? "") : "";
|
|
117791
|
+
results.push({
|
|
117792
|
+
title: titleText,
|
|
117793
|
+
url,
|
|
117794
|
+
snippet: snippetText !== "" ? snippetText : titleText
|
|
117795
|
+
});
|
|
117796
|
+
}
|
|
117797
|
+
return results;
|
|
117798
|
+
}
|
|
117799
|
+
const SOGOU = {
|
|
117800
|
+
label: "Sogou",
|
|
117801
|
+
url: (q) => `https://www.sogou.com/web?query=${encodeURIComponent(q)}`,
|
|
117802
|
+
blockRe: /<div\b[^>]*\bclass="[^"]*\b(?:vrwrap|rb)\b[^"]*"[^>]*>([\s\S]*?)(?=<div\b[^>]*\bclass="[^"]*\b(?:vrwrap|rb)\b|$)/g,
|
|
117803
|
+
titleRe: /<h3[^>]*>[\s\S]*?<a[^>]*href="([^"]+)"[^>]*>([\s\S]*?)<\/a>/,
|
|
117804
|
+
snippetRe: /<(?:p|div)\b[^>]*\bclass="[^"]*\b(?:str-text|str_info|text-layout)\b[^"]*"[^>]*>([\s\S]*?)<\/(?:p|div)>/,
|
|
117805
|
+
normalizeUrl: (href) => {
|
|
117806
|
+
if (href.startsWith("/link?")) return `https://www.sogou.com${href}`;
|
|
117807
|
+
if (href.includes("sogou.com/sogou?")) return void 0;
|
|
117808
|
+
if (href.startsWith("http://") || href.startsWith("https://")) return href;
|
|
117809
|
+
},
|
|
117810
|
+
botMarkers: ["antispider", "异常访问请求"]
|
|
117811
|
+
};
|
|
117812
|
+
var SogouSearchProvider = class {
|
|
117813
|
+
name = "sogou";
|
|
117814
|
+
fetchImpl;
|
|
117815
|
+
constructor(options = {}) {
|
|
117816
|
+
this.fetchImpl = options.fetchImpl ?? globalThis.fetch.bind(globalThis);
|
|
117817
|
+
}
|
|
117818
|
+
search(query, options) {
|
|
117819
|
+
return searchEngine(SOGOU, this.fetchImpl, query, options);
|
|
117820
|
+
}
|
|
117821
|
+
};
|
|
117822
|
+
const SO360 = {
|
|
117823
|
+
label: "360 Search",
|
|
117824
|
+
url: (q) => `https://www.so.com/s?q=${encodeURIComponent(q)}`,
|
|
117825
|
+
blockRe: /<li\b[^>]*\bclass="[^"]*\bres-list\b[^"]*"[^>]*>([\s\S]*?)(?=<li\b[^>]*\bclass="[^"]*\bres-list\b|$)/g,
|
|
117826
|
+
titleRe: /<h3[^>]*class="[^"]*\bres-title\b[^"]*"[^>]*>[\s\S]*?<a[^>]*href="([^"]+)"[^>]*>([\s\S]*?)<\/a>/,
|
|
117827
|
+
snippetRe: /<p\b[^>]*\bclass="[^"]*\bres-desc\b[^"]*"[^>]*>([\s\S]*?)<\/p>/,
|
|
117828
|
+
botMarkers: ["安全验证"]
|
|
117829
|
+
};
|
|
117830
|
+
var So360SearchProvider = class {
|
|
117831
|
+
name = "360";
|
|
117832
|
+
fetchImpl;
|
|
117833
|
+
constructor(options = {}) {
|
|
117834
|
+
this.fetchImpl = options.fetchImpl ?? globalThis.fetch.bind(globalThis);
|
|
117835
|
+
}
|
|
117836
|
+
search(query, options) {
|
|
117837
|
+
return searchEngine(SO360, this.fetchImpl, query, options);
|
|
117838
|
+
}
|
|
117839
|
+
};
|
|
117840
|
+
const BAIDU = {
|
|
117841
|
+
label: "Baidu",
|
|
117842
|
+
url: (q) => `https://www.baidu.com/s?wd=${encodeURIComponent(q)}`,
|
|
117843
|
+
blockRe: /<div\b[^>]*\bclass="[^"]*\bc-container\b[^"]*"[^>]*>([\s\S]*?)(?=<div\b[^>]*\bclass="[^"]*\bc-container\b|$)/g,
|
|
117844
|
+
titleRe: /<h3[^>]*class="[^"]*\bt\b[^"]*"[^>]*>[\s\S]*?<a[^>]*href="([^"]+)"[^>]*>([\s\S]*?)<\/a>/,
|
|
117845
|
+
snippetRe: /<(?:span|div)\b[^>]*\bclass="[^"]*\b(?:c-abstract|content-right)[^"]*\b[^"]*"[^>]*>([\s\S]*?)<\/(?:span|div)>/,
|
|
117846
|
+
botMarkers: ["百度安全验证", "wappass.baidu.com"]
|
|
117847
|
+
};
|
|
117848
|
+
var BaiduSearchProvider = class {
|
|
117849
|
+
name = "baidu";
|
|
117850
|
+
fetchImpl;
|
|
117851
|
+
constructor(options = {}) {
|
|
117852
|
+
this.fetchImpl = options.fetchImpl ?? globalThis.fetch.bind(globalThis);
|
|
117853
|
+
}
|
|
117854
|
+
search(query, options) {
|
|
117855
|
+
return searchEngine(BAIDU, this.fetchImpl, query, options);
|
|
117856
|
+
}
|
|
117857
|
+
};
|
|
117627
117858
|
//#endregion
|
|
117628
117859
|
//#region ../../packages/agent-core/src/tools/providers/fallback-search.ts
|
|
117629
117860
|
var FallbackSearchProvider = class {
|
|
@@ -117633,94 +117864,31 @@ var FallbackSearchProvider = class {
|
|
|
117633
117864
|
this.providers = providers;
|
|
117634
117865
|
}
|
|
117635
117866
|
async search(query, options) {
|
|
117636
|
-
|
|
117637
|
-
|
|
117638
|
-
|
|
117639
|
-
|
|
117640
|
-
|
|
117641
|
-
|
|
117642
|
-
|
|
117643
|
-
|
|
117644
|
-
|
|
117645
|
-
|
|
117646
|
-
|
|
117647
|
-
|
|
117648
|
-
|
|
117649
|
-
|
|
117650
|
-
|
|
117651
|
-
|
|
117652
|
-
|
|
117653
|
-
fetchImpl;
|
|
117654
|
-
constructor(options) {
|
|
117655
|
-
this.tokenProvider = options.tokenProvider;
|
|
117656
|
-
this.apiKey = options.apiKey;
|
|
117657
|
-
this.baseUrl = options.baseUrl;
|
|
117658
|
-
this.defaultHeaders = options.defaultHeaders ?? {};
|
|
117659
|
-
this.customHeaders = options.customHeaders ?? {};
|
|
117660
|
-
this.fetchImpl = options.fetchImpl ?? globalThis.fetch.bind(globalThis);
|
|
117661
|
-
}
|
|
117662
|
-
async search(query, options) {
|
|
117663
|
-
const body = {
|
|
117664
|
-
text_query: query,
|
|
117665
|
-
limit: options?.limit ?? 5,
|
|
117666
|
-
enable_page_crawling: options?.includeContent ?? false,
|
|
117667
|
-
timeout_seconds: 30
|
|
117668
|
-
};
|
|
117669
|
-
const bodyJson = JSON.stringify(body);
|
|
117670
|
-
const toolCallId = options?.toolCallId;
|
|
117671
|
-
const response = await this.post(bodyJson, toolCallId);
|
|
117672
|
-
if (response.status === 401) {
|
|
117673
|
-
const detail = await safeReadText(response);
|
|
117674
|
-
throw new Error(`ScreamCli search request failed: HTTP 401 (auth/unauthorized). ${detail}`.trim());
|
|
117675
|
-
}
|
|
117676
|
-
if (response.status !== 200) {
|
|
117677
|
-
const detail = await safeReadText(response);
|
|
117678
|
-
throw new Error(`ScreamCli search request failed: HTTP ${String(response.status)}. ${detail}`.trim());
|
|
117679
|
-
}
|
|
117680
|
-
const json = await response.json();
|
|
117681
|
-
return (Array.isArray(json.search_results) ? json.search_results : []).map((r) => {
|
|
117682
|
-
const out = {
|
|
117683
|
-
title: r.title ?? "",
|
|
117684
|
-
url: r.url ?? "",
|
|
117685
|
-
snippet: r.snippet ?? ""
|
|
117686
|
-
};
|
|
117687
|
-
if (typeof r.date === "string" && r.date.length > 0) out.date = r.date;
|
|
117688
|
-
if (typeof r.content === "string" && r.content.length > 0) out.content = r.content;
|
|
117689
|
-
return out;
|
|
117690
|
-
});
|
|
117691
|
-
}
|
|
117692
|
-
async post(bodyJson, toolCallId) {
|
|
117693
|
-
const accessToken = await this.resolveApiKey();
|
|
117694
|
-
return this.fetchImpl(this.baseUrl, {
|
|
117695
|
-
method: "POST",
|
|
117696
|
-
headers: {
|
|
117697
|
-
...this.defaultHeaders,
|
|
117698
|
-
Authorization: `Bearer ${accessToken}`,
|
|
117699
|
-
"Content-Type": "application/json",
|
|
117700
|
-
...toolCallId !== void 0 && toolCallId.length > 0 ? { "X-Msh-Tool-Call-Id": toolCallId } : {},
|
|
117701
|
-
...this.customHeaders
|
|
117702
|
-
},
|
|
117703
|
-
body: bodyJson
|
|
117704
|
-
});
|
|
117705
|
-
}
|
|
117706
|
-
async resolveApiKey() {
|
|
117707
|
-
if (this.tokenProvider !== void 0) try {
|
|
117708
|
-
return await this.tokenProvider.getAccessToken();
|
|
117709
|
-
} catch (error) {
|
|
117710
|
-
if (this.apiKey !== void 0 && this.apiKey.length > 0) return this.apiKey;
|
|
117711
|
-
throw error;
|
|
117867
|
+
const failures = [];
|
|
117868
|
+
for (const [index, provider] of this.providers.entries()) {
|
|
117869
|
+
options?.signal?.throwIfAborted();
|
|
117870
|
+
try {
|
|
117871
|
+
const results = await provider.search(query, options);
|
|
117872
|
+
if (results.length > 0) return results;
|
|
117873
|
+
failures.push({
|
|
117874
|
+
provider: provider.name ?? `provider ${String(index + 1)}`,
|
|
117875
|
+
reason: "no results"
|
|
117876
|
+
});
|
|
117877
|
+
} catch (error) {
|
|
117878
|
+
options?.signal?.throwIfAborted();
|
|
117879
|
+
failures.push({
|
|
117880
|
+
provider: provider.name ?? `provider ${String(index + 1)}`,
|
|
117881
|
+
reason: error instanceof Error ? error.message : String(error)
|
|
117882
|
+
});
|
|
117883
|
+
}
|
|
117712
117884
|
}
|
|
117713
|
-
if (
|
|
117714
|
-
|
|
117885
|
+
if (failures.every((f) => f.reason === "no results")) return [];
|
|
117886
|
+
const last = failures[failures.length - 1];
|
|
117887
|
+
if (this.providers.length === 1 && last !== void 0) throw new Error(last.reason);
|
|
117888
|
+
const summary = failures.map((f) => `${f.provider}: ${f.reason}`).join("; ");
|
|
117889
|
+
throw new Error(`All web search providers failed — ${summary}`);
|
|
117715
117890
|
}
|
|
117716
117891
|
};
|
|
117717
|
-
async function safeReadText(response) {
|
|
117718
|
-
try {
|
|
117719
|
-
return await response.text();
|
|
117720
|
-
} catch {
|
|
117721
|
-
return "";
|
|
117722
|
-
}
|
|
117723
|
-
}
|
|
117724
117892
|
//#endregion
|
|
117725
117893
|
//#region ../../packages/agent-core/src/session/export/manifest.ts
|
|
117726
117894
|
const WIRE_PROTOCOL_VERSION = "1.3";
|
|
@@ -118910,7 +119078,7 @@ function providerApiKey(provider) {
|
|
|
118910
119078
|
case "openai_responses": return providerValue(provider.apiKey, provider.env, "OPENAI_API_KEY");
|
|
118911
119079
|
case "scream": return providerValue(provider.apiKey, provider.env, "SCREAM_API_KEY");
|
|
118912
119080
|
case "google-genai": return providerValue(provider.apiKey, provider.env, "GOOGLE_API_KEY");
|
|
118913
|
-
case "vertexai": return nonEmptyString
|
|
119081
|
+
case "vertexai": return nonEmptyString(provider.apiKey) ?? envValue(provider.env, "VERTEXAI_API_KEY") ?? envValue(provider.env, "GOOGLE_API_KEY");
|
|
118914
119082
|
default: {
|
|
118915
119083
|
const exhaustive = provider.type;
|
|
118916
119084
|
throw new ScreamError(ErrorCodes.MODEL_CONFIG_INVALID, `Unsupported provider type: ${String(exhaustive)}`);
|
|
@@ -118927,21 +119095,21 @@ function vertexAILocation(provider) {
|
|
|
118927
119095
|
return envValue(provider.env, "GOOGLE_CLOUD_LOCATION") ?? locationFromVertexAIBaseUrl(provider.baseUrl);
|
|
118928
119096
|
}
|
|
118929
119097
|
function providerValue(configured, env, envKey) {
|
|
118930
|
-
return nonEmptyString
|
|
119098
|
+
return nonEmptyString(configured) ?? envValue(env, envKey);
|
|
118931
119099
|
}
|
|
118932
119100
|
function envValue(env, key) {
|
|
118933
|
-
return nonEmptyString
|
|
119101
|
+
return nonEmptyString(env?.[key]);
|
|
118934
119102
|
}
|
|
118935
|
-
function nonEmptyString
|
|
119103
|
+
function nonEmptyString(value) {
|
|
118936
119104
|
const trimmed = value?.trim();
|
|
118937
119105
|
return trimmed === void 0 || trimmed.length === 0 ? void 0 : trimmed;
|
|
118938
119106
|
}
|
|
118939
119107
|
function locationFromVertexAIBaseUrl(baseUrl) {
|
|
118940
|
-
const url = nonEmptyString
|
|
119108
|
+
const url = nonEmptyString(baseUrl);
|
|
118941
119109
|
if (url === void 0) return void 0;
|
|
118942
119110
|
try {
|
|
118943
119111
|
const host = new URL(url).hostname;
|
|
118944
|
-
return host.endsWith("-aiplatform.googleapis.com") ? nonEmptyString
|
|
119112
|
+
return host.endsWith("-aiplatform.googleapis.com") ? nonEmptyString(host.slice(0, -26)) : void 0;
|
|
118945
119113
|
} catch {
|
|
118946
119114
|
return;
|
|
118947
119115
|
}
|
|
@@ -120486,7 +120654,6 @@ function waitForSpawn(child) {
|
|
|
120486
120654
|
new AsyncLocalStorage();
|
|
120487
120655
|
//#endregion
|
|
120488
120656
|
//#region ../../packages/agent-core/src/rpc/core-impl.ts
|
|
120489
|
-
const SCREAM_CODE_PROVIDER_NAME = "managed:scream-code";
|
|
120490
120657
|
var ScreamCore = class {
|
|
120491
120658
|
rpcClient;
|
|
120492
120659
|
sdk;
|
|
@@ -120967,11 +121134,7 @@ var ScreamCore = class {
|
|
|
120967
121134
|
}
|
|
120968
121135
|
async resolveRuntime(config) {
|
|
120969
121136
|
if (this.runtime !== void 0) return this.runtime;
|
|
120970
|
-
const runtime = await createRuntimeConfig({
|
|
120971
|
-
config,
|
|
120972
|
-
screamRequestHeaders: this.screamRequestHeaders,
|
|
120973
|
-
resolveOAuthTokenProvider: this.resolveOAuthTokenProvider
|
|
120974
|
-
});
|
|
121137
|
+
const runtime = await createRuntimeConfig({ config });
|
|
120975
121138
|
this.runtime = runtime;
|
|
120976
121139
|
return runtime;
|
|
120977
121140
|
}
|
|
@@ -121028,42 +121191,20 @@ var ScreamCore = class {
|
|
|
121028
121191
|
}
|
|
121029
121192
|
};
|
|
121030
121193
|
async function createRuntimeConfig(input) {
|
|
121031
|
-
const fetchCache = new FetchCache();
|
|
121032
|
-
const localFetcher = new LocalFetchURLProvider({ cache: fetchCache });
|
|
121033
|
-
const fetchService = input.config.services?.screamCliFetch;
|
|
121034
121194
|
return {
|
|
121035
|
-
urlFetcher:
|
|
121036
|
-
baseUrl: fetchService.baseUrl,
|
|
121037
|
-
localFallback: localFetcher,
|
|
121038
|
-
defaultHeaders: input.screamRequestHeaders,
|
|
121039
|
-
cache: fetchCache,
|
|
121040
|
-
...serviceCredentials(fetchService, input.resolveOAuthTokenProvider)
|
|
121041
|
-
}),
|
|
121195
|
+
urlFetcher: new LocalFetchURLProvider({ cache: new FetchCache() }),
|
|
121042
121196
|
webSearcher: buildWebSearcher(input)
|
|
121043
121197
|
};
|
|
121044
121198
|
}
|
|
121045
121199
|
function buildWebSearcher(input) {
|
|
121046
|
-
const
|
|
121047
|
-
const
|
|
121048
|
-
|
|
121049
|
-
|
|
121050
|
-
|
|
121051
|
-
|
|
121052
|
-
|
|
121053
|
-
|
|
121054
|
-
if (screamProvider && ddgProvider) return new FallbackSearchProvider([screamProvider, ddgProvider]);
|
|
121055
|
-
return screamProvider ?? ddgProvider;
|
|
121056
|
-
}
|
|
121057
|
-
function serviceCredentials(service, resolveOAuthTokenProvider) {
|
|
121058
|
-
return {
|
|
121059
|
-
apiKey: nonEmptyString(service.apiKey),
|
|
121060
|
-
tokenProvider: service.oauth !== void 0 ? resolveOAuthTokenProvider?.(SCREAM_CODE_PROVIDER_NAME, service.oauth) : void 0,
|
|
121061
|
-
customHeaders: service.customHeaders
|
|
121062
|
-
};
|
|
121063
|
-
}
|
|
121064
|
-
function nonEmptyString(value) {
|
|
121065
|
-
const trimmed = value?.trim();
|
|
121066
|
-
return trimmed === void 0 || trimmed.length === 0 ? void 0 : trimmed;
|
|
121200
|
+
const services = input.config.services;
|
|
121201
|
+
const providers = [];
|
|
121202
|
+
if (services?.duckduckgo?.enabled !== false) providers.push(new DuckDuckGoSearchProvider());
|
|
121203
|
+
if (services?.sogou?.enabled !== false) providers.push(new SogouSearchProvider());
|
|
121204
|
+
if (services?.so360?.enabled !== false) providers.push(new So360SearchProvider());
|
|
121205
|
+
if (services?.baidu?.enabled !== false) providers.push(new BaiduSearchProvider());
|
|
121206
|
+
if (providers.length === 0) return void 0;
|
|
121207
|
+
return providers.length === 1 ? providers[0] : new FallbackSearchProvider(providers);
|
|
121067
121208
|
}
|
|
121068
121209
|
function requiredWorkDir(operation, value) {
|
|
121069
121210
|
if (typeof value !== "string" || value.trim() === "") throw new ScreamError(ErrorCodes.REQUEST_WORK_DIR_REQUIRED, `${operation} requires workDir`);
|
|
@@ -121264,7 +121405,8 @@ var SDKRpcClient = class {
|
|
|
121264
121405
|
return (await this.getRpc()).steer({
|
|
121265
121406
|
sessionId: input.sessionId,
|
|
121266
121407
|
agentId: this.interactiveAgentId,
|
|
121267
|
-
input: input.input
|
|
121408
|
+
input: input.input,
|
|
121409
|
+
interrupt: input.interrupt
|
|
121268
121410
|
});
|
|
121269
121411
|
}
|
|
121270
121412
|
async generateAgentsMd(input) {
|
|
@@ -121756,11 +121898,12 @@ var Session = class {
|
|
|
121756
121898
|
input: normalizePromptInput(input)
|
|
121757
121899
|
});
|
|
121758
121900
|
}
|
|
121759
|
-
async steer(input) {
|
|
121901
|
+
async steer(input, opts) {
|
|
121760
121902
|
this.ensureOpen();
|
|
121761
121903
|
await this.rpc.steer({
|
|
121762
121904
|
sessionId: this.id,
|
|
121763
|
-
input: normalizePromptInput(input)
|
|
121905
|
+
input: normalizePromptInput(input),
|
|
121906
|
+
interrupt: opts?.interrupt
|
|
121764
121907
|
});
|
|
121765
121908
|
}
|
|
121766
121909
|
async init(targetDir) {
|
|
@@ -122527,7 +122670,7 @@ function optionalBuildString(value) {
|
|
|
122527
122670
|
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
122528
122671
|
}
|
|
122529
122672
|
const SCREAM_BUILD_INFO = {
|
|
122530
|
-
version: optionalBuildString("0.10.
|
|
122673
|
+
version: optionalBuildString("0.10.3"),
|
|
122531
122674
|
channel: optionalBuildString(""),
|
|
122532
122675
|
commit: optionalBuildString(""),
|
|
122533
122676
|
buildTarget: optionalBuildString("darwin-arm64")
|
|
@@ -123434,15 +123577,13 @@ const BRAILLE_SPINNER_FRAMES = [
|
|
|
123434
123577
|
"⠇",
|
|
123435
123578
|
"⠏"
|
|
123436
123579
|
];
|
|
123437
|
-
const
|
|
123438
|
-
"
|
|
123439
|
-
"
|
|
123440
|
-
"
|
|
123441
|
-
"
|
|
123442
|
-
"
|
|
123443
|
-
"
|
|
123444
|
-
"",
|
|
123445
|
-
"💭"
|
|
123580
|
+
const PIXEL_PULSE_FRAMES = [
|
|
123581
|
+
"█",
|
|
123582
|
+
"▓",
|
|
123583
|
+
"▒",
|
|
123584
|
+
"░",
|
|
123585
|
+
"▒",
|
|
123586
|
+
"▓"
|
|
123446
123587
|
];
|
|
123447
123588
|
const PULSE_WAVE_FRAMES = [
|
|
123448
123589
|
{
|
|
@@ -123877,12 +124018,13 @@ function isManagedUsageProvider(providerKey) {
|
|
|
123877
124018
|
//#region src/tui/constant/streaming.ts
|
|
123878
124019
|
const STREAMING_ARGS_FIELD_RE = /"(path|file_path|command|pattern|query|url|description|title|name)"\s*:\s*"((?:\\.|[^"\\])*)"/g;
|
|
123879
124020
|
const STREAMING_ARGS_PREVIEW_MAX_CHARS = 8 * 1024;
|
|
124021
|
+
const STREAMING_ARGS_BUFFER_MAX_CHARS = 1024 * 1024;
|
|
123880
124022
|
//#endregion
|
|
123881
124023
|
//#region src/tui/utils/event-payload.ts
|
|
123882
124024
|
function appendStreamingArgsPreview(current, next) {
|
|
123883
|
-
const existing = (current ?? "").slice(0,
|
|
124025
|
+
const existing = (current ?? "").slice(0, STREAMING_ARGS_BUFFER_MAX_CHARS);
|
|
123884
124026
|
if (next === null || next === void 0 || next.length === 0) return existing;
|
|
123885
|
-
const remaining =
|
|
124027
|
+
const remaining = STREAMING_ARGS_BUFFER_MAX_CHARS - existing.length;
|
|
123886
124028
|
if (remaining <= 0) return existing;
|
|
123887
124029
|
return `${existing}${next.slice(0, remaining)}`;
|
|
123888
124030
|
}
|
|
@@ -125808,7 +125950,7 @@ var FooterComponent = class {
|
|
|
125808
125950
|
gitCache;
|
|
125809
125951
|
gitCacheWorkDir;
|
|
125810
125952
|
transientHint = null;
|
|
125811
|
-
|
|
125953
|
+
statusTimer = null;
|
|
125812
125954
|
/**
|
|
125813
125955
|
* Non-terminal background-task counts split by kind so the footer can
|
|
125814
125956
|
* render two distinct badges. `bashTasks` covers `bash-*` BPM tasks
|
|
@@ -125827,15 +125969,13 @@ var FooterComponent = class {
|
|
|
125827
125969
|
this.gitCache = createGitStatusCache(state.workDir, { onChange: this.onGitStatusChange });
|
|
125828
125970
|
}
|
|
125829
125971
|
setState(state) {
|
|
125830
|
-
const
|
|
125972
|
+
const prevPhase = this.state?.streamingPhase;
|
|
125831
125973
|
if (state.workDir !== this.gitCacheWorkDir) {
|
|
125832
125974
|
this.gitCacheWorkDir = state.workDir;
|
|
125833
125975
|
this.gitCache = createGitStatusCache(state.workDir, { onChange: this.onGitStatusChange });
|
|
125834
125976
|
}
|
|
125835
125977
|
this.state = state;
|
|
125836
|
-
|
|
125837
|
-
if (isThinking && !wasThinking) this.#startShimmer();
|
|
125838
|
-
else if (!isThinking && wasThinking) this.#stopShimmer();
|
|
125978
|
+
if (state.streamingPhase !== prevPhase) this.#restartStatusTimer(state.streamingPhase);
|
|
125839
125979
|
}
|
|
125840
125980
|
setColors(colors) {
|
|
125841
125981
|
this.colors = colors;
|
|
@@ -125860,29 +126000,29 @@ var FooterComponent = class {
|
|
|
125860
126000
|
}
|
|
125861
126001
|
invalidate() {}
|
|
125862
126002
|
/**
|
|
125863
|
-
* Stop the
|
|
126003
|
+
* Stop the status timer. Idempotent — safe to call even when
|
|
125864
126004
|
* the timer isn't running. Call this when the component is disposed.
|
|
125865
126005
|
*/
|
|
125866
126006
|
dispose() {
|
|
125867
|
-
this.#
|
|
126007
|
+
this.#stopStatusTimer();
|
|
125868
126008
|
}
|
|
125869
|
-
#
|
|
125870
|
-
|
|
125871
|
-
|
|
125872
|
-
|
|
125873
|
-
|
|
126009
|
+
#restartStatusTimer(phase) {
|
|
126010
|
+
this.#stopStatusTimer();
|
|
126011
|
+
if (phase === "idle") return;
|
|
126012
|
+
const intervalMs = phase === "thinking" ? 1e3 / 30 : SPINNER_TICK_MS;
|
|
126013
|
+
this.statusTimer = setInterval(() => {
|
|
126014
|
+
this.ui.requestComponentRender(this);
|
|
126015
|
+
}, intervalMs);
|
|
125874
126016
|
}
|
|
125875
|
-
#
|
|
125876
|
-
if (!this.
|
|
125877
|
-
clearInterval(this.
|
|
125878
|
-
this.
|
|
126017
|
+
#stopStatusTimer() {
|
|
126018
|
+
if (!this.statusTimer) return;
|
|
126019
|
+
clearInterval(this.statusTimer);
|
|
126020
|
+
this.statusTimer = null;
|
|
125879
126021
|
}
|
|
125880
126022
|
render(width) {
|
|
125881
126023
|
const colors = this.colors;
|
|
125882
126024
|
const state = this.state;
|
|
125883
126025
|
const left = [];
|
|
125884
|
-
if (state.permissionMode === "auto") left.push(chalk.hex(colors.warning).bold(t("badge.auto")));
|
|
125885
|
-
if (state.permissionMode === "yolo") left.push(chalk.hex(colors.warning).bold(t("badge.yes")));
|
|
125886
126026
|
if (state.planMode !== "off") {
|
|
125887
126027
|
const isFusion = state.planMode === "fusionplan";
|
|
125888
126028
|
left.push(chalk.hex(isFusion ? colors.fusionPlanMode : colors.planMode).bold(isFusion ? t("badge.fusion") : t("badge.plan")));
|
|
@@ -126214,6 +126354,21 @@ const lightColors = {
|
|
|
126214
126354
|
function getColorPalette(theme) {
|
|
126215
126355
|
return theme === "dark" ? darkColors : lightColors;
|
|
126216
126356
|
}
|
|
126357
|
+
/**
|
|
126358
|
+
* True when a hex background is light enough to need dark text on top
|
|
126359
|
+
* (relative luminance above 0.5). Shared by badge/tag renderers so a
|
|
126360
|
+
* fluorescent-green block never gets unreadable white text.
|
|
126361
|
+
*/
|
|
126362
|
+
function isLightBgHex(hex) {
|
|
126363
|
+
const r = parseInt(hex.slice(1, 3), 16);
|
|
126364
|
+
const g = parseInt(hex.slice(3, 5), 16);
|
|
126365
|
+
const b = parseInt(hex.slice(5, 7), 16);
|
|
126366
|
+
return (.299 * r + .587 * g + .114 * b) / 255 > .5;
|
|
126367
|
+
}
|
|
126368
|
+
/** Foreground colour with readable contrast on the given hex background. */
|
|
126369
|
+
function contrastTextHex(bgHex) {
|
|
126370
|
+
return isLightBgHex(bgHex) ? "#000000" : "#FFFFFF";
|
|
126371
|
+
}
|
|
126217
126372
|
//#endregion
|
|
126218
126373
|
//#region src/tui/theme/styles.ts
|
|
126219
126374
|
/**
|
|
@@ -126766,7 +126921,6 @@ async function handleYoloCommand(host, args) {
|
|
|
126766
126921
|
}
|
|
126767
126922
|
await session.setPermission("yolo");
|
|
126768
126923
|
host.setAppState({ permissionMode: "yolo" });
|
|
126769
|
-
host.showNotice(t("config.yolo_on"), t("config.yolo_on_desc"));
|
|
126770
126924
|
return;
|
|
126771
126925
|
}
|
|
126772
126926
|
if (subcmd === "off") {
|
|
@@ -126776,17 +126930,14 @@ async function handleYoloCommand(host, args) {
|
|
|
126776
126930
|
}
|
|
126777
126931
|
await session.setPermission("manual");
|
|
126778
126932
|
host.setAppState({ permissionMode: "manual" });
|
|
126779
|
-
host.showNotice(t("config.yolo_off"));
|
|
126780
126933
|
return;
|
|
126781
126934
|
}
|
|
126782
126935
|
if (currentMode === "yolo") {
|
|
126783
126936
|
await session.setPermission("manual");
|
|
126784
126937
|
host.setAppState({ permissionMode: "manual" });
|
|
126785
|
-
host.showNotice(t("config.yolo_off"));
|
|
126786
126938
|
} else {
|
|
126787
126939
|
await session.setPermission("yolo");
|
|
126788
126940
|
host.setAppState({ permissionMode: "yolo" });
|
|
126789
|
-
host.showNotice(t("config.yolo_toggle_on"), t("config.yolo_toggle_on_desc"));
|
|
126790
126941
|
}
|
|
126791
126942
|
}
|
|
126792
126943
|
async function handleAutoCommand(host, args) {
|
|
@@ -126804,7 +126955,6 @@ async function handleAutoCommand(host, args) {
|
|
|
126804
126955
|
}
|
|
126805
126956
|
await session.setPermission("auto");
|
|
126806
126957
|
host.setAppState({ permissionMode: "auto" });
|
|
126807
|
-
host.showNotice(t("config.auto_on"), t("config.auto_on_desc"));
|
|
126808
126958
|
return;
|
|
126809
126959
|
}
|
|
126810
126960
|
if (subcmd === "off") {
|
|
@@ -126814,17 +126964,14 @@ async function handleAutoCommand(host, args) {
|
|
|
126814
126964
|
}
|
|
126815
126965
|
await session.setPermission("manual");
|
|
126816
126966
|
host.setAppState({ permissionMode: "manual" });
|
|
126817
|
-
host.showNotice(t("config.auto_off"));
|
|
126818
126967
|
return;
|
|
126819
126968
|
}
|
|
126820
126969
|
if (currentMode === "auto") {
|
|
126821
126970
|
await session.setPermission("manual");
|
|
126822
126971
|
host.setAppState({ permissionMode: "manual" });
|
|
126823
|
-
host.showNotice(t("config.auto_off"));
|
|
126824
126972
|
} else {
|
|
126825
126973
|
await session.setPermission("auto");
|
|
126826
126974
|
host.setAppState({ permissionMode: "auto" });
|
|
126827
|
-
host.showNotice(t("config.auto_toggle_on"), t("config.auto_toggle_on_desc"));
|
|
126828
126975
|
}
|
|
126829
126976
|
}
|
|
126830
126977
|
async function handleWolfpackCommand(host, args) {
|
|
@@ -127827,7 +127974,7 @@ async function createGoal(host, parsed) {
|
|
|
127827
127974
|
await showGoalConfigWizard(host, session, parsed.objective, parsed.replace);
|
|
127828
127975
|
}
|
|
127829
127976
|
async function showGoalConfigWizard(host, session, objective, replace) {
|
|
127830
|
-
const { TextInputDialogComponent } = await import("./text-input-dialog-
|
|
127977
|
+
const { TextInputDialogComponent } = await import("./text-input-dialog-C8_8qYYi.mjs");
|
|
127831
127978
|
const turnInput = await promptNumber(host, TextInputDialogComponent, {
|
|
127832
127979
|
title: t("goal.wizard_title", { objective }),
|
|
127833
127980
|
subtitle: t("goal.budget_turns_hint"),
|
|
@@ -128576,7 +128723,7 @@ var AssistantMessageComponent = class {
|
|
|
128576
128723
|
const age = Date.now() - (this.fadeStartMs ?? 0);
|
|
128577
128724
|
this.cachedWidth = void 0;
|
|
128578
128725
|
this.cachedLines = void 0;
|
|
128579
|
-
this.ui?.
|
|
128726
|
+
this.ui?.requestComponentRender(this);
|
|
128580
128727
|
if (age >= 1200) this.stopFade();
|
|
128581
128728
|
}, FADE_TICK_MS);
|
|
128582
128729
|
this.ui.requestRender();
|
|
@@ -129057,7 +129204,7 @@ var ThinkingComponent = class {
|
|
|
129057
129204
|
if (this.ui === void 0 || this.spinnerInterval !== void 0) return;
|
|
129058
129205
|
this.spinnerInterval = setInterval(() => {
|
|
129059
129206
|
this.spinnerFrame = (this.spinnerFrame + 1) % BRAILLE_SPINNER_FRAMES.length;
|
|
129060
|
-
this.ui?.
|
|
129207
|
+
this.ui?.requestComponentRender(this);
|
|
129061
129208
|
}, 80);
|
|
129062
129209
|
}
|
|
129063
129210
|
stopSpinner() {
|
|
@@ -130244,23 +130391,20 @@ function unescapeJsonString(s) {
|
|
|
130244
130391
|
});
|
|
130245
130392
|
}
|
|
130246
130393
|
/**
|
|
130247
|
-
*
|
|
130248
|
-
*
|
|
130249
|
-
*
|
|
130250
|
-
*
|
|
130251
|
-
*
|
|
130394
|
+
* Scan a JSON string value starting at `start` (just after the opening
|
|
130395
|
+
* quote), unescaping into plain text. Stops at the closing quote or at
|
|
130396
|
+
* `end`, tolerating truncation (an incomplete escape at the boundary
|
|
130397
|
+
* simply ends the scan). Shared by the partial-args extractor and the
|
|
130398
|
+
* Write streaming tail preview.
|
|
130252
130399
|
*/
|
|
130253
|
-
function
|
|
130254
|
-
const match = new RegExp(`"${key}"\\s*:\\s*"`).exec(text);
|
|
130255
|
-
if (match === null) return void 0;
|
|
130256
|
-
const start = match.index + match[0].length;
|
|
130400
|
+
function unescapeJsonStringValue(text, start, end = text.length) {
|
|
130257
130401
|
let out = "";
|
|
130258
130402
|
let i = start;
|
|
130259
|
-
while (i <
|
|
130403
|
+
while (i < end) {
|
|
130260
130404
|
const ch = text[i];
|
|
130261
130405
|
if (ch === "\\") {
|
|
130262
130406
|
const next = text[i + 1];
|
|
130263
|
-
if (next === void 0) return out;
|
|
130407
|
+
if (next === void 0 || i + 1 >= end) return out;
|
|
130264
130408
|
switch (next) {
|
|
130265
130409
|
case "n":
|
|
130266
130410
|
out += "\n";
|
|
@@ -130287,7 +130431,7 @@ function extractPartialStringField(text, key) {
|
|
|
130287
130431
|
out += "/";
|
|
130288
130432
|
break;
|
|
130289
130433
|
case "u": {
|
|
130290
|
-
if (i + 5 >=
|
|
130434
|
+
if (i + 5 >= end) return out;
|
|
130291
130435
|
const hex = text.slice(i + 2, i + 6);
|
|
130292
130436
|
const code = Number.parseInt(hex, 16);
|
|
130293
130437
|
if (Number.isNaN(code)) return out;
|
|
@@ -130306,6 +130450,16 @@ function extractPartialStringField(text, key) {
|
|
|
130306
130450
|
}
|
|
130307
130451
|
return out;
|
|
130308
130452
|
}
|
|
130453
|
+
/**
|
|
130454
|
+
* Pull the live value of a JSON string field out of partially-streamed
|
|
130455
|
+
* arguments, even if the closing quote hasn't arrived yet. Returns
|
|
130456
|
+
* `undefined` if the field hasn't started streaming yet.
|
|
130457
|
+
*/
|
|
130458
|
+
function extractPartialStringField(text, key) {
|
|
130459
|
+
const match = new RegExp(`"${key}"\\s*:\\s*"`).exec(text);
|
|
130460
|
+
if (match === null) return void 0;
|
|
130461
|
+
return unescapeJsonStringValue(text, match.index + match[0].length);
|
|
130462
|
+
}
|
|
130309
130463
|
function parseArgsPreview(value) {
|
|
130310
130464
|
const previewText = value.slice(0, STREAMING_ARGS_PREVIEW_MAX_CHARS);
|
|
130311
130465
|
if (previewText.trim().length === 0) return {};
|
|
@@ -130448,6 +130602,11 @@ var ToolCallComponent = class ToolCallComponent extends CachedContainer {
|
|
|
130448
130602
|
subagentEndedAtMs;
|
|
130449
130603
|
progressLines = [];
|
|
130450
130604
|
static MAX_PROGRESS_LINES = 24;
|
|
130605
|
+
writeStreamContentStart = -1;
|
|
130606
|
+
writeStreamNlScanOffset = 0;
|
|
130607
|
+
writeStreamNlCount = 0;
|
|
130608
|
+
writeStreamLang;
|
|
130609
|
+
static WRITE_STREAM_TAIL_RAW_CHARS = 4096;
|
|
130451
130610
|
/**
|
|
130452
130611
|
* Registered by a group container (`AgentGroupComponent` or
|
|
130453
130612
|
* `ReadGroupComponent`) when this component is borrowed as a hidden state
|
|
@@ -131217,21 +131376,12 @@ var ToolCallComponent = class ToolCallComponent extends CachedContainer {
|
|
|
131217
131376
|
const name = this.toolCall.name;
|
|
131218
131377
|
const previewText = streamText.slice(0, STREAMING_ARGS_PREVIEW_MAX_CHARS);
|
|
131219
131378
|
if (name === "Write") {
|
|
131220
|
-
|
|
131221
|
-
if (content === void 0 || content.length === 0) return;
|
|
131222
|
-
const allLines = highlightLines(content, langFromPath(extractPartialStringField(previewText, "file_path") ?? extractPartialStringField(previewText, "path") ?? ""));
|
|
131223
|
-
const maxLines = 10;
|
|
131224
|
-
const scrollLines = allLines.length > maxLines ? allLines.slice(allLines.length - maxLines) : allLines;
|
|
131225
|
-
for (const [i, line] of scrollLines.entries()) {
|
|
131226
|
-
const originalLineNumber = allLines.length > maxLines ? allLines.length - maxLines + i : i;
|
|
131227
|
-
const lineNum = chalk.dim(String(originalLineNumber + 1).padStart(4) + " ");
|
|
131228
|
-
this.addChild(new Text(lineNum + line, 2, 0));
|
|
131229
|
-
}
|
|
131379
|
+
this.buildWriteStreamingPreview(streamText);
|
|
131230
131380
|
return;
|
|
131231
131381
|
}
|
|
131232
131382
|
if (name === "Edit") {
|
|
131233
131383
|
const filePath = extractPartialStringField(previewText, "file_path") ?? extractPartialStringField(previewText, "path") ?? "";
|
|
131234
|
-
const bytes = Buffer.byteLength(
|
|
131384
|
+
const bytes = Buffer.byteLength(streamText, "utf8");
|
|
131235
131385
|
const startedAtMs = this.toolCall.streamingStartedAtMs;
|
|
131236
131386
|
const elapsedSeconds = startedAtMs === void 0 ? 0 : Math.max(0, Math.floor((Date.now() - startedAtMs) / 1e3));
|
|
131237
131387
|
const progress = t("toolcall.preparing_changes", {
|
|
@@ -131253,6 +131403,54 @@ var ToolCallComponent = class ToolCallComponent extends CachedContainer {
|
|
|
131253
131403
|
}));
|
|
131254
131404
|
}
|
|
131255
131405
|
}
|
|
131406
|
+
/**
|
|
131407
|
+
* Live Write preview: renders the last COMMAND_PREVIEW_LINES lines of the
|
|
131408
|
+
* file being written, reading from the TAIL of the accumulating args JSON
|
|
131409
|
+
* so the window keeps scrolling for arbitrarily large files (the old
|
|
131410
|
+
* head-bounded preview visibly froze once args passed 8KB). Line numbers
|
|
131411
|
+
* stay exact via an incremental newline counter. Per-frame cost is
|
|
131412
|
+
* O(delta + tail), independent of total file size.
|
|
131413
|
+
*/
|
|
131414
|
+
buildWriteStreamingPreview(streamText) {
|
|
131415
|
+
if (streamText.length < this.writeStreamNlScanOffset) {
|
|
131416
|
+
this.writeStreamContentStart = -1;
|
|
131417
|
+
this.writeStreamLang = void 0;
|
|
131418
|
+
}
|
|
131419
|
+
if (this.writeStreamContentStart < 0) {
|
|
131420
|
+
const opener = /"content"\s*:\s*"/.exec(streamText);
|
|
131421
|
+
if (opener === null) return;
|
|
131422
|
+
this.writeStreamContentStart = opener.index + opener[0].length;
|
|
131423
|
+
this.writeStreamNlScanOffset = this.writeStreamContentStart;
|
|
131424
|
+
this.writeStreamNlCount = 0;
|
|
131425
|
+
const filePath = extractPartialStringField(streamText, "file_path") ?? extractPartialStringField(streamText, "path") ?? "";
|
|
131426
|
+
this.writeStreamLang = langFromPath(filePath);
|
|
131427
|
+
}
|
|
131428
|
+
const contentStart = this.writeStreamContentStart;
|
|
131429
|
+
const tailStart = Math.max(contentStart, streamText.length - ToolCallComponent.WRITE_STREAM_TAIL_RAW_CHARS);
|
|
131430
|
+
while (this.writeStreamNlScanOffset < tailStart) {
|
|
131431
|
+
const idx = streamText.indexOf("\\n", this.writeStreamNlScanOffset);
|
|
131432
|
+
if (idx === -1 || idx >= tailStart) break;
|
|
131433
|
+
this.writeStreamNlCount++;
|
|
131434
|
+
this.writeStreamNlScanOffset = idx + 2;
|
|
131435
|
+
}
|
|
131436
|
+
let fragmentStart = tailStart;
|
|
131437
|
+
if (tailStart > contentStart) {
|
|
131438
|
+
const firstNl = streamText.indexOf("\\n", tailStart);
|
|
131439
|
+
if (firstNl === -1) return;
|
|
131440
|
+
fragmentStart = firstNl + 2;
|
|
131441
|
+
}
|
|
131442
|
+
const fragmentEnd = Math.min(streamText.length, fragmentStart + ToolCallComponent.WRITE_STREAM_TAIL_RAW_CHARS);
|
|
131443
|
+
const fragment = unescapeJsonStringValue(streamText, fragmentStart, fragmentEnd);
|
|
131444
|
+
if (fragment.length === 0) return;
|
|
131445
|
+
const lines = highlightLines(fragment, this.writeStreamLang);
|
|
131446
|
+
const displayLines = lines.slice(-10);
|
|
131447
|
+
const firstFragmentLineNo = this.writeStreamNlCount + (tailStart > contentStart ? 2 : 1);
|
|
131448
|
+
const skipped = lines.length - displayLines.length;
|
|
131449
|
+
for (const [i, line] of displayLines.entries()) {
|
|
131450
|
+
const lineNum = chalk.dim(String(firstFragmentLineNo + skipped + i).padStart(4) + " ");
|
|
131451
|
+
this.addChild(new Text(lineNum + line, 2, 0));
|
|
131452
|
+
}
|
|
131453
|
+
}
|
|
131256
131454
|
buildPlanPreview() {
|
|
131257
131455
|
const plan = this.resolvePlanForPreview();
|
|
131258
131456
|
if (plan.length === 0) return;
|
|
@@ -133194,15 +133392,11 @@ var MoonLoader = class extends Text {
|
|
|
133194
133392
|
currentFrame = 0;
|
|
133195
133393
|
intervalId = null;
|
|
133196
133394
|
ui;
|
|
133197
|
-
frames;
|
|
133198
|
-
interval;
|
|
133199
133395
|
colorFn;
|
|
133200
133396
|
label;
|
|
133201
|
-
constructor(ui,
|
|
133397
|
+
constructor(ui, colorFn, label = "") {
|
|
133202
133398
|
super("", 1, 0);
|
|
133203
133399
|
this.ui = ui;
|
|
133204
|
-
this.frames = style === "moon" ? [...MOON_SPINNER_FRAMES] : [...BRAILLE_SPINNER_FRAMES];
|
|
133205
|
-
this.interval = style === "moon" ? 120 : 80;
|
|
133206
133400
|
this.colorFn = colorFn;
|
|
133207
133401
|
this.label = label;
|
|
133208
133402
|
this.start();
|
|
@@ -133210,9 +133404,9 @@ var MoonLoader = class extends Text {
|
|
|
133210
133404
|
start() {
|
|
133211
133405
|
this.updateDisplay();
|
|
133212
133406
|
this.intervalId = setInterval(() => {
|
|
133213
|
-
this.currentFrame = (this.currentFrame + 1) %
|
|
133407
|
+
this.currentFrame = (this.currentFrame + 1) % BRAILLE_SPINNER_FRAMES.length;
|
|
133214
133408
|
this.updateDisplay();
|
|
133215
|
-
},
|
|
133409
|
+
}, 80);
|
|
133216
133410
|
}
|
|
133217
133411
|
stop() {
|
|
133218
133412
|
if (this.intervalId) {
|
|
@@ -133229,10 +133423,10 @@ var MoonLoader = class extends Text {
|
|
|
133229
133423
|
this.updateDisplay();
|
|
133230
133424
|
}
|
|
133231
133425
|
updateDisplay() {
|
|
133232
|
-
const frame =
|
|
133426
|
+
const frame = BRAILLE_SPINNER_FRAMES[this.currentFrame];
|
|
133233
133427
|
const coloredFrame = this.colorFn ? this.colorFn(frame) : frame;
|
|
133234
133428
|
this.setText(this.label ? `${coloredFrame} ${this.label}` : coloredFrame);
|
|
133235
|
-
this.ui.
|
|
133429
|
+
this.ui.requestComponentRender(this);
|
|
133236
133430
|
}
|
|
133237
133431
|
};
|
|
133238
133432
|
//#endregion
|
|
@@ -133438,7 +133632,7 @@ var SkillCenterLoadingComponent = class extends Container {
|
|
|
133438
133632
|
this.label = label;
|
|
133439
133633
|
this.host = host;
|
|
133440
133634
|
const tint = (s) => chalk.hex(host.state.theme.colors.primary)(s);
|
|
133441
|
-
this.loader = new MoonLoader(host.state.ui,
|
|
133635
|
+
this.loader = new MoonLoader(host.state.ui, tint, this.label);
|
|
133442
133636
|
this.addChild(new Spacer(1));
|
|
133443
133637
|
this.addChild(this.loader);
|
|
133444
133638
|
}
|
|
@@ -137023,6 +137217,16 @@ var EditorKeyboardController = class {
|
|
|
137023
137217
|
host.restoreEditor();
|
|
137024
137218
|
return;
|
|
137025
137219
|
}
|
|
137220
|
+
if (host.state.queuedMessages.length > 0) {
|
|
137221
|
+
const restored = host.state.queuedMessages.map((m) => m.text.trim()).filter((text) => text.length > 0);
|
|
137222
|
+
host.clearQueuedMessages();
|
|
137223
|
+
const existing = host.state.editor.getText();
|
|
137224
|
+
const parts = [...restored, existing].filter((s) => s.trim().length > 0);
|
|
137225
|
+
host.state.editor.setText(parts.join("\n"));
|
|
137226
|
+
host.updateQueueDisplay();
|
|
137227
|
+
host.state.ui.requestRender();
|
|
137228
|
+
return;
|
|
137229
|
+
}
|
|
137026
137230
|
if (host.state.appState.isCompacting) {
|
|
137027
137231
|
this.cancelCurrentCompaction();
|
|
137028
137232
|
return;
|
|
@@ -137817,6 +138021,7 @@ var SessionEventHandler = class {
|
|
|
137817
138021
|
handleStepCompleted(event) {
|
|
137818
138022
|
this.host.streamingUI.flushNow();
|
|
137819
138023
|
this.maybeShowDebugTiming(event);
|
|
138024
|
+
this.drainQueuedMessagesIntoSteer();
|
|
137820
138025
|
if (event.finishReason !== "max_tokens") return;
|
|
137821
138026
|
const title = this.host.streamingUI.markStepTruncated(String(event.turnId), event.step) > 0 ? t("handler.max_tokens_truncated") : t("handler.max_tokens_no_tool");
|
|
137822
138027
|
const detail = this.isAnthropicSessionActive() ? t("handler.max_tokens_hint") : void 0;
|
|
@@ -137827,6 +138032,40 @@ var SessionEventHandler = class {
|
|
|
137827
138032
|
const text = formatStepDebugTiming(event);
|
|
137828
138033
|
if (text !== void 0) this.host.showStatus(text);
|
|
137829
138034
|
}
|
|
138035
|
+
/**
|
|
138036
|
+
* Auto-insert queued messages at the step boundary. The current step has
|
|
138037
|
+
* finished, so queued input is steered in with interrupt: false — it
|
|
138038
|
+
* never kills in-flight tools; it reaches the model at the next call.
|
|
138039
|
+
* Race-safe by design: if the turn already ended between the event and
|
|
138040
|
+
* the steer call, the core launches a fresh turn with the message.
|
|
138041
|
+
* (Ctrl+S remains the immediate-interrupt path.)
|
|
138042
|
+
*
|
|
138043
|
+
* Skipped while `deferUserMessages` is set: /init and make-skill run
|
|
138044
|
+
* system-triggered flows whose steps must not receive user input.
|
|
138045
|
+
*/
|
|
138046
|
+
drainQueuedMessagesIntoSteer() {
|
|
138047
|
+
const { state } = this.host;
|
|
138048
|
+
const session = this.host.session;
|
|
138049
|
+
if (session === void 0 || state.appState.isCompacting || this.host.deferUserMessages) return;
|
|
138050
|
+
const items = state.queuedMessages;
|
|
138051
|
+
if (items.length === 0) return;
|
|
138052
|
+
state.queuedMessages = [];
|
|
138053
|
+
this.host.updateQueueDisplay();
|
|
138054
|
+
for (const item of items) {
|
|
138055
|
+
this.host.appendTranscriptEntry({
|
|
138056
|
+
id: nextTranscriptId(),
|
|
138057
|
+
kind: "user",
|
|
138058
|
+
turnId: this.host.streamingUI.getTurnContext().turnId,
|
|
138059
|
+
renderMode: "plain",
|
|
138060
|
+
content: item.text,
|
|
138061
|
+
...item.imageAttachmentIds !== void 0 && item.imageAttachmentIds.length > 0 ? { imageAttachmentIds: item.imageAttachmentIds } : {}
|
|
138062
|
+
});
|
|
138063
|
+
session.steer(item.parts ?? item.text, { interrupt: false }).catch((error) => {
|
|
138064
|
+
const message = formatErrorMessage(error);
|
|
138065
|
+
this.host.showError(t("input.guide_failed", { message }));
|
|
138066
|
+
});
|
|
138067
|
+
}
|
|
138068
|
+
}
|
|
137830
138069
|
isAnthropicSessionActive() {
|
|
137831
138070
|
const { state } = this.host;
|
|
137832
138071
|
const providerKey = state.appState.availableModels[state.appState.model]?.provider;
|
|
@@ -138009,7 +138248,7 @@ var SessionEventHandler = class {
|
|
|
138009
138248
|
return;
|
|
138010
138249
|
}
|
|
138011
138250
|
const tint = (s) => chalk.hex(state.theme.colors.textMuted)(s);
|
|
138012
|
-
const spinner = new MoonLoader(state.ui,
|
|
138251
|
+
const spinner = new MoonLoader(state.ui, tint, label);
|
|
138013
138252
|
state.transcriptContainer.addChild(spinner);
|
|
138014
138253
|
this.mcpServerStatusSpinners.set(name, spinner);
|
|
138015
138254
|
state.ui.requestRender();
|
|
@@ -141148,7 +141387,7 @@ var TranscriptController = class TranscriptController {
|
|
|
141148
141387
|
}
|
|
141149
141388
|
showProgressSpinner(label) {
|
|
141150
141389
|
const tint = (s) => chalk.hex(this.host.state.theme.colors.primary)(s);
|
|
141151
|
-
const spinner = new MoonLoader(this.host.state.ui,
|
|
141390
|
+
const spinner = new MoonLoader(this.host.state.ui, tint, label);
|
|
141152
141391
|
const spacer = new Spacer(1);
|
|
141153
141392
|
const container = this.host.state.transcriptContainer;
|
|
141154
141393
|
container.addChild(spacer);
|
|
@@ -141506,7 +141745,7 @@ var PulseWaveLoader = class extends Text {
|
|
|
141506
141745
|
2
|
|
141507
141746
|
].map((idx) => this.renderCell(idx, step.active, step.forward));
|
|
141508
141747
|
this.setText(cells.join(" "));
|
|
141509
|
-
this.ui.
|
|
141748
|
+
this.ui.requestComponentRender(this);
|
|
141510
141749
|
}
|
|
141511
141750
|
renderCell(index, active, forward) {
|
|
141512
141751
|
const distance = forward ? active - index : index - active;
|
|
@@ -141763,7 +142002,7 @@ var LifecycleController = class LifecycleController {
|
|
|
141763
142002
|
this.stopPulseWave();
|
|
141764
142003
|
break;
|
|
141765
142004
|
case "composing": {
|
|
141766
|
-
const spinner = this.ensureActivitySpinner("
|
|
142005
|
+
const spinner = this.ensureActivitySpinner("working...", (s) => chalk.hex(state.theme.colors.primary)(s));
|
|
141767
142006
|
state.activityContainer.addChild(new ActivityPaneComponent({
|
|
141768
142007
|
mode: "composing",
|
|
141769
142008
|
spinner
|
|
@@ -141805,14 +142044,10 @@ var LifecycleController = class LifecycleController {
|
|
|
141805
142044
|
this.host.state.terminal.setProgress(active);
|
|
141806
142045
|
this.host.state.terminalState.progressActive = active;
|
|
141807
142046
|
}
|
|
141808
|
-
ensureActivitySpinner(
|
|
141809
|
-
if (this.host.state.activitySpinner?.style !== style) this.stopActivitySpinner();
|
|
142047
|
+
ensureActivitySpinner(label = "", colorFn) {
|
|
141810
142048
|
if (this.host.state.activitySpinner === null) {
|
|
141811
|
-
const instance = new MoonLoader(this.host.state.ui,
|
|
141812
|
-
this.host.state.activitySpinner = {
|
|
141813
|
-
instance,
|
|
141814
|
-
style
|
|
141815
|
-
};
|
|
142049
|
+
const instance = new MoonLoader(this.host.state.ui, colorFn, label);
|
|
142050
|
+
this.host.state.activitySpinner = { instance };
|
|
141816
142051
|
return instance;
|
|
141817
142052
|
}
|
|
141818
142053
|
this.host.state.activitySpinner.instance.setLabel(label);
|
|
@@ -143105,6 +143340,8 @@ var CustomEditor = class extends Editor {
|
|
|
143105
143340
|
thinking = false;
|
|
143106
143341
|
/** Current thinking effort level (e.g. low, medium, high). Used to annotate the think label. */
|
|
143107
143342
|
thinkingLevel = "off";
|
|
143343
|
+
/** Current permission mode — always shown as a badge at the top-left of the input box border. */
|
|
143344
|
+
permissionMode = "manual";
|
|
143108
143345
|
/** Current border colour hex — kept in sync with borderColor by the host. */
|
|
143109
143346
|
borderHex = "";
|
|
143110
143347
|
consumingPaste = false;
|
|
@@ -143165,7 +143402,13 @@ var CustomEditor = class extends Editor {
|
|
|
143165
143402
|
const withPrompt = injectPromptSymbol(firstContent);
|
|
143166
143403
|
if (withPrompt !== void 0) lines[firstContentIdx] = withPrompt;
|
|
143167
143404
|
}
|
|
143168
|
-
|
|
143405
|
+
injectBorderBadges(lines, width, {
|
|
143406
|
+
mode: this.permissionMode,
|
|
143407
|
+
thinking: this.thinking,
|
|
143408
|
+
thinkingLevel: this.thinkingLevel,
|
|
143409
|
+
paint: this.borderColor ?? ((s) => s),
|
|
143410
|
+
borderHex: this.borderHex
|
|
143411
|
+
});
|
|
143169
143412
|
return lines;
|
|
143170
143413
|
}
|
|
143171
143414
|
handleInput(data) {
|
|
@@ -143298,34 +143541,47 @@ function injectPromptSymbol(line) {
|
|
|
143298
143541
|
return "> " + line.slice(2);
|
|
143299
143542
|
}
|
|
143300
143543
|
const THINK_LABEL_MIN_WIDTH = 14;
|
|
143544
|
+
const MODE_BADGE_MIN_WIDTH = 10;
|
|
143301
143545
|
function isLightBg(hex) {
|
|
143302
143546
|
const r = parseInt(hex.slice(1, 3), 16);
|
|
143303
143547
|
const g = parseInt(hex.slice(3, 5), 16);
|
|
143304
143548
|
const b = parseInt(hex.slice(5, 7), 16);
|
|
143305
143549
|
return (.299 * r + .587 * g + .114 * b) / 255 > .5;
|
|
143306
143550
|
}
|
|
143551
|
+
function makeBadge(label, bgHex) {
|
|
143552
|
+
return bgHex ? chalk.bgHex(bgHex).hex(isLightBg(bgHex) ? "#000000" : "#FFFFFF")(label) : chalk.bgBlack.white(label);
|
|
143553
|
+
}
|
|
143307
143554
|
/**
|
|
143308
|
-
*
|
|
143309
|
-
*
|
|
143310
|
-
*
|
|
143311
|
-
*
|
|
143312
|
-
*
|
|
143313
|
-
*
|
|
143314
|
-
*
|
|
143555
|
+
* Compose the editor's top border line with up to two badges: the
|
|
143556
|
+
* permission mode badge at the left (always shown) and the think badge at
|
|
143557
|
+
* the right (only when thinking is enabled). Each badge is a solid colour
|
|
143558
|
+
* block with black/white text picked by background luminance. When the
|
|
143559
|
+
* editor is scrolled, pi-tui's `↑ N more` indicator keeps the line — it
|
|
143560
|
+
* signals hidden content, which matters more than the badges. On narrow
|
|
143561
|
+
* terminals the think badge drops first, then the mode badge.
|
|
143315
143562
|
*/
|
|
143316
|
-
function
|
|
143317
|
-
if (width < THINK_LABEL_MIN_WIDTH) return;
|
|
143563
|
+
function injectBorderBadges(lines, width, opts) {
|
|
143318
143564
|
const topIdx = lines.findIndex((line) => {
|
|
143319
143565
|
const plain = stripSgr(line);
|
|
143320
143566
|
return plain.length > 0 && plain[0] === "─";
|
|
143321
143567
|
});
|
|
143322
143568
|
if (topIdx === -1) return;
|
|
143323
|
-
|
|
143324
|
-
const
|
|
143325
|
-
|
|
143326
|
-
|
|
143327
|
-
if (
|
|
143328
|
-
|
|
143569
|
+
if (stripSgr(lines[topIdx]).includes("↑")) return;
|
|
143570
|
+
const { paint } = opts;
|
|
143571
|
+
let left = "";
|
|
143572
|
+
let right = paint("─");
|
|
143573
|
+
if (width >= MODE_BADGE_MIN_WIDTH) {
|
|
143574
|
+
const badgeText = ` ${opts.mode} `;
|
|
143575
|
+
left = paint("──") + (opts.borderHex ? chalk.hex(opts.borderHex).bold(badgeText) : paint(badgeText));
|
|
143576
|
+
}
|
|
143577
|
+
if (opts.thinking && width >= THINK_LABEL_MIN_WIDTH) right = makeBadge(opts.thinkingLevel !== "off" ? ` Think ${opts.thinkingLevel} ` : " Think ", opts.borderHex) + paint("─");
|
|
143578
|
+
const fill = width - visibleWidth(left) - visibleWidth(right);
|
|
143579
|
+
if (fill < 0) {
|
|
143580
|
+
const modeOnlyFill = width - visibleWidth(left) - 1;
|
|
143581
|
+
lines[topIdx] = modeOnlyFill >= 0 ? left + paint("─".repeat(modeOnlyFill)) + paint("─") : paint("─".repeat(width));
|
|
143582
|
+
return;
|
|
143583
|
+
}
|
|
143584
|
+
lines[topIdx] = left + paint("─".repeat(fill)) + right;
|
|
143329
143585
|
}
|
|
143330
143586
|
//#endregion
|
|
143331
143587
|
//#region src/tui/utils/terminal-state.ts
|
|
@@ -143566,6 +143822,7 @@ function createTUIState(options) {
|
|
|
143566
143822
|
const editor = new CustomEditor(ui, theme.colors);
|
|
143567
143823
|
editor.thinking = initialAppState.thinkingLevel !== "off";
|
|
143568
143824
|
editor.thinkingLevel = initialAppState.thinkingLevel;
|
|
143825
|
+
editor.permissionMode = initialAppState.permissionMode ?? "manual";
|
|
143569
143826
|
return {
|
|
143570
143827
|
ui,
|
|
143571
143828
|
terminal,
|
|
@@ -144406,7 +144663,10 @@ var ApprovalPanelComponent = class extends Container {
|
|
|
144406
144663
|
onToggleToolOutput;
|
|
144407
144664
|
onTogglePlanExpand;
|
|
144408
144665
|
onOpenPreview;
|
|
144409
|
-
|
|
144666
|
+
ui;
|
|
144667
|
+
animFrame = 0;
|
|
144668
|
+
intervalId = null;
|
|
144669
|
+
constructor(request, onResponse, colors, onToggleToolOutput, onTogglePlanExpand, onOpenPreview, ui) {
|
|
144410
144670
|
super();
|
|
144411
144671
|
this.request = request;
|
|
144412
144672
|
this.onResponse = onResponse;
|
|
@@ -144414,6 +144674,7 @@ var ApprovalPanelComponent = class extends Container {
|
|
|
144414
144674
|
this.onToggleToolOutput = onToggleToolOutput;
|
|
144415
144675
|
this.onTogglePlanExpand = onTogglePlanExpand;
|
|
144416
144676
|
this.onOpenPreview = onOpenPreview;
|
|
144677
|
+
this.ui = ui;
|
|
144417
144678
|
this.feedbackInput.onSubmit = (value) => {
|
|
144418
144679
|
this.submit(this.selectedIndex, value);
|
|
144419
144680
|
};
|
|
@@ -144421,10 +144682,22 @@ var ApprovalPanelComponent = class extends Container {
|
|
|
144421
144682
|
this.feedbackMode = false;
|
|
144422
144683
|
this.feedbackInput.setValue("");
|
|
144423
144684
|
};
|
|
144685
|
+
if (this.ui !== void 0) this.intervalId = setInterval(() => {
|
|
144686
|
+
this.animFrame = (this.animFrame + 1) % PIXEL_PULSE_FRAMES.length;
|
|
144687
|
+
this.ui?.requestComponentRender(this);
|
|
144688
|
+
}, 100);
|
|
144689
|
+
}
|
|
144690
|
+
/** Stop the selection pulse. Idempotent; called on submit and on hide. */
|
|
144691
|
+
stop() {
|
|
144692
|
+
if (this.intervalId !== null) {
|
|
144693
|
+
clearInterval(this.intervalId);
|
|
144694
|
+
this.intervalId = null;
|
|
144695
|
+
}
|
|
144424
144696
|
}
|
|
144425
144697
|
submit(index, feedback = "") {
|
|
144426
144698
|
const option = this.choiceAt(index);
|
|
144427
144699
|
if (!option) return;
|
|
144700
|
+
this.stop();
|
|
144428
144701
|
this.onResponse({
|
|
144429
144702
|
response: option.response,
|
|
144430
144703
|
feedback: feedback || void 0,
|
|
@@ -144441,6 +144714,7 @@ var ApprovalPanelComponent = class extends Container {
|
|
|
144441
144714
|
}
|
|
144442
144715
|
handleInput(data) {
|
|
144443
144716
|
if (matchesKey(data, Key.escape) || matchesKey(data, Key.ctrl("c")) || matchesKey(data, Key.ctrl("d"))) {
|
|
144717
|
+
this.stop();
|
|
144444
144718
|
this.onResponse({ response: "rejected" });
|
|
144445
144719
|
return;
|
|
144446
144720
|
}
|
|
@@ -144491,11 +144765,9 @@ var ApprovalPanelComponent = class extends Container {
|
|
|
144491
144765
|
this.feedbackInput.focused = this.focused && this.feedbackMode;
|
|
144492
144766
|
const { data } = this.request;
|
|
144493
144767
|
const blockStyles = makeBlockStyles(this.colors);
|
|
144494
|
-
const borderColor = chalk.hex(this.colors.
|
|
144495
|
-
const borderColorBold = chalk.bold.hex(this.colors.
|
|
144496
|
-
const selectColorBold = chalk.bold.hex(this.colors.accent);
|
|
144768
|
+
const borderColor = chalk.hex(this.colors.primary);
|
|
144769
|
+
const borderColorBold = chalk.bold.hex(this.colors.primary);
|
|
144497
144770
|
const dim = chalk.hex(this.colors.textDim);
|
|
144498
|
-
const strong = chalk.hex(this.colors.textStrong);
|
|
144499
144771
|
const horizontalBar = borderColor("─".repeat(width));
|
|
144500
144772
|
const indent = (s) => ` ${s}`;
|
|
144501
144773
|
const title = headerFor(data.tool_name);
|
|
@@ -144520,8 +144792,11 @@ var ApprovalPanelComponent = class extends Container {
|
|
|
144520
144792
|
const num = idx + 1;
|
|
144521
144793
|
const labelWithNum = `${String(num)}. ${option.label}`;
|
|
144522
144794
|
if (this.feedbackMode && option.requires_feedback === true && isSelected) lines.push(indent(this.renderInlineFeedbackLine(width - 2, labelWithNum)));
|
|
144523
|
-
else if (isSelected)
|
|
144524
|
-
|
|
144795
|
+
else if (isSelected) {
|
|
144796
|
+
const indicator = chalk.hex(this.colors.primary)(PIXEL_PULSE_FRAMES[this.animFrame]);
|
|
144797
|
+
const selectedLabel = chalk.bold.hex(this.colors.primary)(labelWithNum);
|
|
144798
|
+
lines.push(indent(`${indicator} ${selectedLabel}`));
|
|
144799
|
+
} else lines.push(indent(dim(` ${labelWithNum}`)));
|
|
144525
144800
|
}
|
|
144526
144801
|
lines.push("");
|
|
144527
144802
|
if (this.feedbackMode) lines.push(indent(dim(t("approval.feedback_hint"))));
|
|
@@ -144550,8 +144825,7 @@ var ApprovalPanelComponent = class extends Container {
|
|
|
144550
144825
|
if (this.selectedIndex < 0 || this.selectedIndex >= count) this.selectedIndex = Math.max(0, Math.min(this.selectedIndex, count - 1));
|
|
144551
144826
|
}
|
|
144552
144827
|
renderInlineFeedbackLine(width, labelWithNum) {
|
|
144553
|
-
const
|
|
144554
|
-
const prefix = `${selectColorBold("▶")} ${selectColorBold(labelWithNum)} `;
|
|
144828
|
+
const prefix = `${chalk.hex(this.colors.primary)(PIXEL_PULSE_FRAMES[this.animFrame])} ${chalk.bold.hex(this.colors.primary)(labelWithNum)} `;
|
|
144555
144829
|
const inputWidth = Math.max(4, width - visibleWidth(prefix) + 2);
|
|
144556
144830
|
const inputLine = this.feedbackInput.render(inputWidth)[0] ?? "> ";
|
|
144557
144831
|
return prefix + (inputLine.startsWith("> ") ? inputLine.slice(2) : inputLine);
|
|
@@ -145522,7 +145796,10 @@ var QuestionDialogComponent = class extends Container {
|
|
|
145522
145796
|
answers;
|
|
145523
145797
|
onToggleToolOutput;
|
|
145524
145798
|
onTogglePlanExpand;
|
|
145525
|
-
|
|
145799
|
+
ui;
|
|
145800
|
+
animFrame = 0;
|
|
145801
|
+
intervalId = null;
|
|
145802
|
+
constructor(request, onAnswer, colors, maxVisibleOptions = 6, onToggleToolOutput, onTogglePlanExpand, ui) {
|
|
145526
145803
|
super();
|
|
145527
145804
|
this.request = request;
|
|
145528
145805
|
this.onAnswer = onAnswer;
|
|
@@ -145530,6 +145807,7 @@ var QuestionDialogComponent = class extends Container {
|
|
|
145530
145807
|
this.maxVisibleOptions = maxVisibleOptions;
|
|
145531
145808
|
this.onToggleToolOutput = onToggleToolOutput;
|
|
145532
145809
|
this.onTogglePlanExpand = onTogglePlanExpand;
|
|
145810
|
+
this.ui = ui;
|
|
145533
145811
|
this.otherInput.onSubmit = (value) => {
|
|
145534
145812
|
this.commitOtherInput(value, "enter");
|
|
145535
145813
|
};
|
|
@@ -145540,14 +145818,33 @@ var QuestionDialogComponent = class extends Container {
|
|
|
145540
145818
|
this.otherDrafts = Array.from({ length: total }, () => "");
|
|
145541
145819
|
this.committedOtherValues = Array.from({ length: total }, () => void 0);
|
|
145542
145820
|
this.answers = Array.from({ length: total }, () => void 0);
|
|
145821
|
+
if (this.ui !== void 0) this.intervalId = setInterval(() => {
|
|
145822
|
+
this.animFrame = (this.animFrame + 1) % PIXEL_PULSE_FRAMES.length;
|
|
145823
|
+
this.ui?.requestComponentRender(this);
|
|
145824
|
+
}, 100);
|
|
145825
|
+
}
|
|
145826
|
+
/** Stop the wizard pulse. Idempotent; called on respond and on hide. */
|
|
145827
|
+
stop() {
|
|
145828
|
+
if (this.intervalId !== null) {
|
|
145829
|
+
clearInterval(this.intervalId);
|
|
145830
|
+
this.intervalId = null;
|
|
145831
|
+
}
|
|
145832
|
+
}
|
|
145833
|
+
respond(response) {
|
|
145834
|
+
this.stop();
|
|
145835
|
+
this.onAnswer(response);
|
|
145836
|
+
}
|
|
145837
|
+
/** Breathing pixel block in the brand fluorescent green. */
|
|
145838
|
+
pulseBlock() {
|
|
145839
|
+
return chalk.hex(this.colors.primary)(PIXEL_PULSE_FRAMES[this.animFrame]);
|
|
145543
145840
|
}
|
|
145544
145841
|
handleInput(data) {
|
|
145545
145842
|
if (matchesKey(data, Key.escape)) {
|
|
145546
|
-
this.
|
|
145843
|
+
this.respond({ answers: [] });
|
|
145547
145844
|
return;
|
|
145548
145845
|
}
|
|
145549
145846
|
if (matchesKey(data, Key.ctrl("c")) || matchesKey(data, Key.ctrl("d"))) {
|
|
145550
|
-
this.
|
|
145847
|
+
this.respond({ answers: [] });
|
|
145551
145848
|
return;
|
|
145552
145849
|
}
|
|
145553
145850
|
if (matchesKey(data, Key.ctrl("o"))) {
|
|
@@ -145772,7 +146069,7 @@ var QuestionDialogComponent = class extends Container {
|
|
|
145772
146069
|
}
|
|
145773
146070
|
executeSubmitAction(actionIdx, method) {
|
|
145774
146071
|
if (actionIdx === 1) {
|
|
145775
|
-
this.
|
|
146072
|
+
this.respond({ answers: [] });
|
|
145776
146073
|
return;
|
|
145777
146074
|
}
|
|
145778
146075
|
this.reviewMessage = void 0;
|
|
@@ -145784,7 +146081,7 @@ var QuestionDialogComponent = class extends Container {
|
|
|
145784
146081
|
const answer = this.answers[i];
|
|
145785
146082
|
if (answer !== void 0 && answer.length > 0) out[i] = answer;
|
|
145786
146083
|
}
|
|
145787
|
-
this.
|
|
146084
|
+
this.respond({
|
|
145788
146085
|
answers: out,
|
|
145789
146086
|
method: this.lastAnswerMethod ?? method
|
|
145790
146087
|
});
|
|
@@ -145840,20 +146137,23 @@ var QuestionDialogComponent = class extends Container {
|
|
|
145840
146137
|
const label = this.renderOptionLabel(questionIdx, option, isCursor);
|
|
145841
146138
|
let tone;
|
|
145842
146139
|
let prefix;
|
|
146140
|
+
const pulse = this.pulseBlock();
|
|
146141
|
+
const primaryBold = chalk.hex(this.colors.primary).bold;
|
|
145843
146142
|
if (question.multi_select) {
|
|
145844
|
-
|
|
146143
|
+
const checked = isSelected ? "✓" : " ";
|
|
146144
|
+
prefix = isCursor ? ` ${pulse} [${checked}] ` : ` [${checked}] `;
|
|
145845
146145
|
if (isSelected && isCursor) tone = (s) => success.bold(s);
|
|
145846
146146
|
else if (isSelected) tone = success;
|
|
145847
|
-
else if (isCursor) tone =
|
|
146147
|
+
else if (isCursor) tone = primaryBold;
|
|
145848
146148
|
else tone = dim;
|
|
145849
146149
|
} else if (isSelected && this.isAnswered(questionIdx)) {
|
|
145850
|
-
prefix = isCursor ? `
|
|
146150
|
+
prefix = isCursor ? ` ${pulse} ${String(num)}. ` : ` ✓ ${String(num)}. `;
|
|
145851
146151
|
tone = isCursor ? (s) => success.bold(s) : success;
|
|
145852
146152
|
} else if (isCursor) {
|
|
145853
|
-
prefix = `
|
|
145854
|
-
tone =
|
|
146153
|
+
prefix = ` ${pulse} ${String(num)}. `;
|
|
146154
|
+
tone = primaryBold;
|
|
145855
146155
|
} else {
|
|
145856
|
-
prefix = `
|
|
146156
|
+
prefix = ` ${String(num)}. `;
|
|
145857
146157
|
tone = dim;
|
|
145858
146158
|
}
|
|
145859
146159
|
const continuation = " ".repeat(visibleWidth(prefix));
|
|
@@ -145903,8 +146203,8 @@ var QuestionDialogComponent = class extends Container {
|
|
|
145903
146203
|
const label = t(SUBMIT_ACTIONS_KEYS[i]);
|
|
145904
146204
|
if (label === void 0) continue;
|
|
145905
146205
|
const num = i + 1;
|
|
145906
|
-
if (i === this.submitActionIdx) lines.push(
|
|
145907
|
-
else lines.push(dim(`
|
|
146206
|
+
if (i === this.submitActionIdx) lines.push(chalk.hex(this.colors.primary).bold(` ${this.pulseBlock()} ${String(num)}. ${label}`));
|
|
146207
|
+
else lines.push(dim(` ${String(num)}. ${label}`));
|
|
145908
146208
|
}
|
|
145909
146209
|
lines.push("");
|
|
145910
146210
|
lines.push(this.buildSubmitHint(dim));
|
|
@@ -145913,18 +146213,18 @@ var QuestionDialogComponent = class extends Container {
|
|
|
145913
146213
|
}
|
|
145914
146214
|
pushTabs(lines) {
|
|
145915
146215
|
const dim = chalk.hex(this.colors.textDim);
|
|
145916
|
-
const active = chalk.bgHex(this.colors.primary).hex(this.colors.
|
|
146216
|
+
const active = chalk.bgHex(this.colors.primary).hex(contrastTextHex(this.colors.primary)).bold;
|
|
145917
146217
|
const tabs = [];
|
|
145918
146218
|
for (let i = 0; i < this.request.data.questions.length; i++) {
|
|
145919
146219
|
const question = this.request.data.questions[i];
|
|
145920
146220
|
if (question === void 0) continue;
|
|
145921
146221
|
const label = question.header !== void 0 && question.header.length > 0 ? question.header : `Q${String(i + 1)}`;
|
|
145922
|
-
if (i === this.currentTab) tabs.push(active(` ${label} `));
|
|
146222
|
+
if (i === this.currentTab) tabs.push(active(` ${PIXEL_PULSE_FRAMES[this.animFrame]} ${label} `));
|
|
145923
146223
|
else if (this.isAnswered(i)) tabs.push(chalk.hex(this.colors.success)(`(✓) ${label}`));
|
|
145924
146224
|
else tabs.push(dim(`(○) ${label}`));
|
|
145925
146225
|
}
|
|
145926
146226
|
const submitLabel = t("question.submit");
|
|
145927
|
-
if (this.isSubmitTab()) tabs.push(active(` ${submitLabel} `));
|
|
146227
|
+
if (this.isSubmitTab()) tabs.push(active(` ${PIXEL_PULSE_FRAMES[this.animFrame]} ${submitLabel} `));
|
|
145928
146228
|
else tabs.push(dim(` ${submitLabel} `));
|
|
145929
146229
|
lines.push(` ${tabs.join(" ")}`);
|
|
145930
146230
|
}
|
|
@@ -146010,12 +146310,13 @@ var QuestionDialogComponent = class extends Container {
|
|
|
146010
146310
|
const question = this.request.data.questions[questionIdx];
|
|
146011
146311
|
if (question === void 0) return option.label;
|
|
146012
146312
|
let prefix;
|
|
146313
|
+
const pulse = this.pulseBlock();
|
|
146013
146314
|
if (question.multi_select) {
|
|
146014
|
-
const body = ` [${isSelected ? "✓" : " "}] ${option.label}: `;
|
|
146015
|
-
prefix = isSelected ? chalk.hex(this.colors.success).bold(body) : chalk.hex(this.colors.primary)(body);
|
|
146315
|
+
const body = ` ${pulse} [${isSelected ? "✓" : " "}] ${option.label}: `;
|
|
146316
|
+
prefix = isSelected ? chalk.hex(this.colors.success).bold(body) : chalk.hex(this.colors.primary).bold(body);
|
|
146016
146317
|
} else {
|
|
146017
|
-
const body = `
|
|
146018
|
-
prefix = isSelected && this.isAnswered(questionIdx) ? chalk.hex(this.colors.success).bold(body) : chalk.hex(this.colors.primary)(body);
|
|
146318
|
+
const body = ` ${pulse} ${String(num)}. ${option.label}: `;
|
|
146319
|
+
prefix = isSelected && this.isAnswered(questionIdx) ? chalk.hex(this.colors.success).bold(body) : chalk.hex(this.colors.primary).bold(body);
|
|
146019
146320
|
}
|
|
146020
146321
|
const inputWidth = Math.max(4, width - visibleWidth(prefix) + 2);
|
|
146021
146322
|
const inputLine = this.otherInput.render(inputWidth)[0] ?? "> ";
|
|
@@ -146049,6 +146350,7 @@ var QuestionDialogComponent = class extends Container {
|
|
|
146049
146350
|
var DialogManager = class {
|
|
146050
146351
|
host;
|
|
146051
146352
|
activeApprovalPanel;
|
|
146353
|
+
activeQuestionDialog;
|
|
146052
146354
|
approvalPreview;
|
|
146053
146355
|
constructor(host) {
|
|
146054
146356
|
this.host = host;
|
|
@@ -146181,12 +146483,14 @@ var DialogManager = class {
|
|
|
146181
146483
|
this.restoreEditor();
|
|
146182
146484
|
}
|
|
146183
146485
|
showApprovalPanel(payload) {
|
|
146486
|
+
this.activeApprovalPanel?.stop();
|
|
146184
146487
|
this.host.patchLivePane({ pendingApproval: { data: payload } });
|
|
146185
146488
|
notifyTerminalOnce(this.host.state, `approval:${payload.id}`, {
|
|
146186
146489
|
title: t("dialog.approval_title"),
|
|
146187
146490
|
body: payload.tool_name
|
|
146188
146491
|
});
|
|
146189
146492
|
const panel = new ApprovalPanelComponent({ data: payload }, (response) => {
|
|
146493
|
+
panel.stop();
|
|
146190
146494
|
this.host.approvalController.respond(adaptPanelResponse(response));
|
|
146191
146495
|
}, this.host.state.theme.colors, () => {
|
|
146192
146496
|
this.host.toggleToolOutputExpansion();
|
|
@@ -146194,12 +146498,13 @@ var DialogManager = class {
|
|
|
146194
146498
|
this.host.togglePlanExpansion();
|
|
146195
146499
|
}, (block) => {
|
|
146196
146500
|
this.openApprovalPreview(panel, block);
|
|
146197
|
-
});
|
|
146501
|
+
}, this.host.state.ui);
|
|
146198
146502
|
this.activeApprovalPanel = panel;
|
|
146199
146503
|
this.mountEditorReplacement(panel);
|
|
146200
146504
|
}
|
|
146201
146505
|
hideApprovalPanel() {
|
|
146202
146506
|
if (this.approvalPreview !== void 0) this.closeApprovalPreview();
|
|
146507
|
+
this.activeApprovalPanel?.stop();
|
|
146203
146508
|
this.activeApprovalPanel = void 0;
|
|
146204
146509
|
this.host.patchLivePane({ pendingApproval: null });
|
|
146205
146510
|
this.restoreEditor();
|
|
@@ -146234,21 +146539,26 @@ var DialogManager = class {
|
|
|
146234
146539
|
this.host.state.ui.requestRender(true);
|
|
146235
146540
|
}
|
|
146236
146541
|
showQuestionDialog(payload) {
|
|
146542
|
+
this.activeQuestionDialog?.stop();
|
|
146237
146543
|
this.host.patchLivePane({ pendingQuestion: { data: payload } });
|
|
146238
146544
|
notifyTerminalOnce(this.host.state, `question:${payload.id}`, {
|
|
146239
146545
|
title: t("dialog.question_title"),
|
|
146240
146546
|
body: payload.questions[0]?.question
|
|
146241
146547
|
});
|
|
146242
146548
|
const dialog = new QuestionDialogComponent({ data: payload }, (response) => {
|
|
146549
|
+
dialog.stop();
|
|
146243
146550
|
this.host.questionController.respond(response);
|
|
146244
146551
|
}, this.host.state.theme.colors, void 0, () => {
|
|
146245
146552
|
this.host.toggleToolOutputExpansion();
|
|
146246
146553
|
}, () => {
|
|
146247
146554
|
this.host.togglePlanExpansion();
|
|
146248
|
-
});
|
|
146555
|
+
}, this.host.state.ui);
|
|
146556
|
+
this.activeQuestionDialog = dialog;
|
|
146249
146557
|
this.mountEditorReplacement(dialog);
|
|
146250
146558
|
}
|
|
146251
146559
|
hideQuestionDialog() {
|
|
146560
|
+
this.activeQuestionDialog?.stop();
|
|
146561
|
+
this.activeQuestionDialog = void 0;
|
|
146252
146562
|
this.host.patchLivePane({ pendingQuestion: null });
|
|
146253
146563
|
this.restoreEditor();
|
|
146254
146564
|
}
|
|
@@ -146661,6 +146971,7 @@ var ScreamTUI = class {
|
|
|
146661
146971
|
this.state.editor.thinking = patch.thinkingLevel !== "off";
|
|
146662
146972
|
this.state.editor.thinkingLevel = patch.thinkingLevel ?? "off";
|
|
146663
146973
|
}
|
|
146974
|
+
if ("permissionMode" in patch) this.state.editor.permissionMode = patch.permissionMode ?? "manual";
|
|
146664
146975
|
if ("streamingPhase" in patch && patch.streamingPhase !== "idle") {
|
|
146665
146976
|
this.transcriptController.stopWelcomeBreathing();
|
|
146666
146977
|
this.inputController.stopBreathingForStreaming();
|
|
@@ -148055,7 +148366,7 @@ async function runStreamJson(opts) {
|
|
|
148055
148366
|
});
|
|
148056
148367
|
session.prompt(userText).catch((error) => {
|
|
148057
148368
|
const msg = error instanceof Error ? error.message : String(error);
|
|
148058
|
-
if (
|
|
148369
|
+
if (isOrphanedToolCallError(error)) {
|
|
148059
148370
|
log.warn("stream-json: resetting session after tool call mismatch", {
|
|
148060
148371
|
sessionId: session?.id,
|
|
148061
148372
|
error: msg
|