crispy-recall 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/embed-pending.js +53 -37
- package/dist/recall.js +67 -35
- package/dist/stop-hook.js +18 -5
- package/package.json +1 -1
package/dist/embed-pending.js
CHANGED
|
@@ -5552,6 +5552,9 @@ function normalizePath(p) {
|
|
|
5552
5552
|
return normalized;
|
|
5553
5553
|
}
|
|
5554
5554
|
|
|
5555
|
+
// src/recall/message-ingest.ts
|
|
5556
|
+
init_log();
|
|
5557
|
+
|
|
5555
5558
|
// src/adapters/claude/jsonl-reader.ts
|
|
5556
5559
|
var fs = __toESM(require("fs"));
|
|
5557
5560
|
init_log();
|
|
@@ -5962,8 +5965,7 @@ function emitFunctionCall(payload, base, outputIndex, _counter) {
|
|
|
5962
5965
|
const outputRecord = outputIndex.get(callId);
|
|
5963
5966
|
if (outputRecord) {
|
|
5964
5967
|
const outputPayload = outputRecord.payload;
|
|
5965
|
-
const
|
|
5966
|
-
const { exitCode, body } = parseExecOutputHeader(rawOutput);
|
|
5968
|
+
const { exitCode, body } = parseExecOutputHeader(outputPayload.output);
|
|
5967
5969
|
const isError = exitCode !== 0;
|
|
5968
5970
|
const toolResult = {
|
|
5969
5971
|
type: "tool_result",
|
|
@@ -6101,7 +6103,7 @@ function emitApplyPatch(callId, input, base, outputIndex) {
|
|
|
6101
6103
|
return entries;
|
|
6102
6104
|
}
|
|
6103
6105
|
function buildCustomToolResult(parentUuid, callId, outputRecord, base) {
|
|
6104
|
-
const rawOutput = outputRecord.payload.output;
|
|
6106
|
+
const rawOutput = coerceOutputText(outputRecord.payload.output);
|
|
6105
6107
|
let content;
|
|
6106
6108
|
let isError = false;
|
|
6107
6109
|
try {
|
|
@@ -6182,7 +6184,7 @@ function emitOrphanedOutput(payload, subtype, base, outputIndex, _counter) {
|
|
|
6182
6184
|
return [];
|
|
6183
6185
|
if (!outputIndex.has(callId))
|
|
6184
6186
|
return [];
|
|
6185
|
-
const rawOutput = payload.output;
|
|
6187
|
+
const rawOutput = coerceOutputText(payload.output);
|
|
6186
6188
|
let content;
|
|
6187
6189
|
let isError = false;
|
|
6188
6190
|
if (subtype === "function_call_output") {
|
|
@@ -6295,7 +6297,18 @@ function mapFunctionCall(name, args) {
|
|
|
6295
6297
|
return { toolName: name, toolInput: args };
|
|
6296
6298
|
}
|
|
6297
6299
|
}
|
|
6298
|
-
function
|
|
6300
|
+
function coerceOutputText(output) {
|
|
6301
|
+
if (typeof output === "string")
|
|
6302
|
+
return output;
|
|
6303
|
+
if (Array.isArray(output)) {
|
|
6304
|
+
return output.map(
|
|
6305
|
+
(item) => item && typeof item === "object" && typeof item.text === "string" ? item.text : ""
|
|
6306
|
+
).filter(Boolean).join("\n");
|
|
6307
|
+
}
|
|
6308
|
+
return "";
|
|
6309
|
+
}
|
|
6310
|
+
function parseExecOutputHeader(rawOutput) {
|
|
6311
|
+
const output = coerceOutputText(rawOutput);
|
|
6299
6312
|
if (!output)
|
|
6300
6313
|
return { exitCode: 0, body: "" };
|
|
6301
6314
|
const currentMatch = output.match(/Process exited with code (\d+)/);
|
|
@@ -6460,6 +6473,39 @@ async function ingestSessionMessages(sessionId, transcriptPath, vendor, options)
|
|
|
6460
6473
|
}
|
|
6461
6474
|
var MAX_EMBED_CHARS = 14e3;
|
|
6462
6475
|
var MAX_EMBED_BATCH = 10;
|
|
6476
|
+
var SAFE_EMBED_CHARS = 6e3;
|
|
6477
|
+
async function embedRowsResilient(rows) {
|
|
6478
|
+
const { embedBatch: embedBatch2 } = await Promise.resolve().then(() => (init_embedder(), embedder_exports));
|
|
6479
|
+
const { quantizeToQ8: quantizeToQ82, computeNorm: computeNorm2 } = await Promise.resolve().then(() => (init_quantize(), quantize_exports));
|
|
6480
|
+
const toRecord = (messageId, f32) => {
|
|
6481
|
+
const { q8, scale } = quantizeToQ82(f32);
|
|
6482
|
+
return { messageId, embeddingQ8: q8, norm: computeNorm2(f32), quantScale: scale };
|
|
6483
|
+
};
|
|
6484
|
+
try {
|
|
6485
|
+
const vectors = await embedBatch2(rows.map((r) => r.text));
|
|
6486
|
+
return rows.map((r, j) => toRecord(r.messageId, vectors[j]));
|
|
6487
|
+
} catch {
|
|
6488
|
+
const records = [];
|
|
6489
|
+
for (const r of rows) {
|
|
6490
|
+
try {
|
|
6491
|
+
const [v] = await embedBatch2([r.text]);
|
|
6492
|
+
records.push(toRecord(r.messageId, v));
|
|
6493
|
+
} catch {
|
|
6494
|
+
try {
|
|
6495
|
+
const [v] = await embedBatch2([r.text.slice(0, SAFE_EMBED_CHARS)]);
|
|
6496
|
+
records.push(toRecord(r.messageId, v));
|
|
6497
|
+
} catch (err) {
|
|
6498
|
+
log({
|
|
6499
|
+
source: "recall:embed",
|
|
6500
|
+
level: "warn",
|
|
6501
|
+
summary: `skipped message ${r.messageId} (embed failed even at ${SAFE_EMBED_CHARS} chars): ${err.message}`
|
|
6502
|
+
});
|
|
6503
|
+
}
|
|
6504
|
+
}
|
|
6505
|
+
}
|
|
6506
|
+
return records;
|
|
6507
|
+
}
|
|
6508
|
+
}
|
|
6463
6509
|
async function embedSessionMessages(sessionId, force) {
|
|
6464
6510
|
const d = getDb(dbPath());
|
|
6465
6511
|
const rows = d.all(
|
|
@@ -6484,22 +6530,7 @@ async function embedSessionMessages(sessionId, force) {
|
|
|
6484
6530
|
if (validRows.length > MAX_EMBED_BATCH) {
|
|
6485
6531
|
validRows.length = MAX_EMBED_BATCH;
|
|
6486
6532
|
}
|
|
6487
|
-
const
|
|
6488
|
-
const { quantizeToQ8: quantizeToQ82, computeNorm: computeNorm2 } = await Promise.resolve().then(() => (init_quantize(), quantize_exports));
|
|
6489
|
-
const texts = validRows.map((r) => r.text);
|
|
6490
|
-
const vectors = await embedBatch2(texts);
|
|
6491
|
-
const records = [];
|
|
6492
|
-
for (let j = 0; j < validRows.length; j++) {
|
|
6493
|
-
const f32 = vectors[j];
|
|
6494
|
-
const { q8, scale } = quantizeToQ82(f32);
|
|
6495
|
-
const norm = computeNorm2(f32);
|
|
6496
|
-
records.push({
|
|
6497
|
-
messageId: validRows[j].messageId,
|
|
6498
|
-
embeddingQ8: q8,
|
|
6499
|
-
norm,
|
|
6500
|
-
quantScale: scale
|
|
6501
|
-
});
|
|
6502
|
-
}
|
|
6533
|
+
const records = await embedRowsResilient(validRows);
|
|
6503
6534
|
insertMessageVectors(records);
|
|
6504
6535
|
return records.length;
|
|
6505
6536
|
}
|
|
@@ -6518,22 +6549,7 @@ async function embedMessageBatch(messages) {
|
|
|
6518
6549
|
}
|
|
6519
6550
|
if (truncated.length === 0)
|
|
6520
6551
|
return 0;
|
|
6521
|
-
const
|
|
6522
|
-
const { quantizeToQ8: quantizeToQ82, computeNorm: computeNorm2 } = await Promise.resolve().then(() => (init_quantize(), quantize_exports));
|
|
6523
|
-
const texts = truncated.map((r) => r.text);
|
|
6524
|
-
const vectors = await embedBatch2(texts);
|
|
6525
|
-
const records = [];
|
|
6526
|
-
for (let j = 0; j < truncated.length; j++) {
|
|
6527
|
-
const f32 = vectors[j];
|
|
6528
|
-
const { q8, scale } = quantizeToQ82(f32);
|
|
6529
|
-
const norm = computeNorm2(f32);
|
|
6530
|
-
records.push({
|
|
6531
|
-
messageId: truncated[j].messageId,
|
|
6532
|
-
embeddingQ8: q8,
|
|
6533
|
-
norm,
|
|
6534
|
-
quantScale: scale
|
|
6535
|
-
});
|
|
6536
|
-
}
|
|
6552
|
+
const records = await embedRowsResilient(truncated);
|
|
6537
6553
|
insertMessageVectors(records);
|
|
6538
6554
|
return records.length;
|
|
6539
6555
|
}
|
package/dist/recall.js
CHANGED
|
@@ -13157,8 +13157,7 @@ function emitFunctionCall(payload, base, outputIndex, _counter) {
|
|
|
13157
13157
|
const outputRecord = outputIndex.get(callId);
|
|
13158
13158
|
if (outputRecord) {
|
|
13159
13159
|
const outputPayload = outputRecord.payload;
|
|
13160
|
-
const
|
|
13161
|
-
const { exitCode, body } = parseExecOutputHeader(rawOutput);
|
|
13160
|
+
const { exitCode, body } = parseExecOutputHeader(outputPayload.output);
|
|
13162
13161
|
const isError = exitCode !== 0;
|
|
13163
13162
|
const toolResult = {
|
|
13164
13163
|
type: "tool_result",
|
|
@@ -13296,7 +13295,7 @@ function emitApplyPatch(callId, input, base, outputIndex) {
|
|
|
13296
13295
|
return entries;
|
|
13297
13296
|
}
|
|
13298
13297
|
function buildCustomToolResult(parentUuid, callId, outputRecord, base) {
|
|
13299
|
-
const rawOutput = outputRecord.payload.output;
|
|
13298
|
+
const rawOutput = coerceOutputText(outputRecord.payload.output);
|
|
13300
13299
|
let content;
|
|
13301
13300
|
let isError = false;
|
|
13302
13301
|
try {
|
|
@@ -13377,7 +13376,7 @@ function emitOrphanedOutput(payload, subtype, base, outputIndex, _counter) {
|
|
|
13377
13376
|
return [];
|
|
13378
13377
|
if (!outputIndex.has(callId))
|
|
13379
13378
|
return [];
|
|
13380
|
-
const rawOutput = payload.output;
|
|
13379
|
+
const rawOutput = coerceOutputText(payload.output);
|
|
13381
13380
|
let content;
|
|
13382
13381
|
let isError = false;
|
|
13383
13382
|
if (subtype === "function_call_output") {
|
|
@@ -13490,7 +13489,18 @@ function mapFunctionCall(name, args) {
|
|
|
13490
13489
|
return { toolName: name, toolInput: args };
|
|
13491
13490
|
}
|
|
13492
13491
|
}
|
|
13493
|
-
function
|
|
13492
|
+
function coerceOutputText(output) {
|
|
13493
|
+
if (typeof output === "string")
|
|
13494
|
+
return output;
|
|
13495
|
+
if (Array.isArray(output)) {
|
|
13496
|
+
return output.map(
|
|
13497
|
+
(item) => item && typeof item === "object" && typeof item.text === "string" ? item.text : ""
|
|
13498
|
+
).filter(Boolean).join("\n");
|
|
13499
|
+
}
|
|
13500
|
+
return "";
|
|
13501
|
+
}
|
|
13502
|
+
function parseExecOutputHeader(rawOutput) {
|
|
13503
|
+
const output = coerceOutputText(rawOutput);
|
|
13494
13504
|
if (!output)
|
|
13495
13505
|
return { exitCode: 0, body: "" };
|
|
13496
13506
|
const currentMatch = output.match(/Process exited with code (\d+)/);
|
|
@@ -13658,6 +13668,38 @@ async function ingestSessionMessages(sessionId, transcriptPath, vendor, options)
|
|
|
13658
13668
|
skipped: false
|
|
13659
13669
|
};
|
|
13660
13670
|
}
|
|
13671
|
+
async function embedRowsResilient(rows) {
|
|
13672
|
+
const { embedBatch: embedBatch2 } = await Promise.resolve().then(() => (init_embedder(), embedder_exports));
|
|
13673
|
+
const { quantizeToQ8: quantizeToQ82, computeNorm: computeNorm2 } = await Promise.resolve().then(() => (init_quantize(), quantize_exports));
|
|
13674
|
+
const toRecord = (messageId, f32) => {
|
|
13675
|
+
const { q8, scale } = quantizeToQ82(f32);
|
|
13676
|
+
return { messageId, embeddingQ8: q8, norm: computeNorm2(f32), quantScale: scale };
|
|
13677
|
+
};
|
|
13678
|
+
try {
|
|
13679
|
+
const vectors = await embedBatch2(rows.map((r2) => r2.text));
|
|
13680
|
+
return rows.map((r2, j2) => toRecord(r2.messageId, vectors[j2]));
|
|
13681
|
+
} catch {
|
|
13682
|
+
const records = [];
|
|
13683
|
+
for (const r2 of rows) {
|
|
13684
|
+
try {
|
|
13685
|
+
const [v2] = await embedBatch2([r2.text]);
|
|
13686
|
+
records.push(toRecord(r2.messageId, v2));
|
|
13687
|
+
} catch {
|
|
13688
|
+
try {
|
|
13689
|
+
const [v2] = await embedBatch2([r2.text.slice(0, SAFE_EMBED_CHARS)]);
|
|
13690
|
+
records.push(toRecord(r2.messageId, v2));
|
|
13691
|
+
} catch (err) {
|
|
13692
|
+
log({
|
|
13693
|
+
source: "recall:embed",
|
|
13694
|
+
level: "warn",
|
|
13695
|
+
summary: `skipped message ${r2.messageId} (embed failed even at ${SAFE_EMBED_CHARS} chars): ${err.message}`
|
|
13696
|
+
});
|
|
13697
|
+
}
|
|
13698
|
+
}
|
|
13699
|
+
}
|
|
13700
|
+
return records;
|
|
13701
|
+
}
|
|
13702
|
+
}
|
|
13661
13703
|
async function embedMessageBatch(messages) {
|
|
13662
13704
|
if (messages.length === 0)
|
|
13663
13705
|
return 0;
|
|
@@ -13673,26 +13715,11 @@ async function embedMessageBatch(messages) {
|
|
|
13673
13715
|
}
|
|
13674
13716
|
if (truncated.length === 0)
|
|
13675
13717
|
return 0;
|
|
13676
|
-
const
|
|
13677
|
-
const { quantizeToQ8: quantizeToQ82, computeNorm: computeNorm2 } = await Promise.resolve().then(() => (init_quantize(), quantize_exports));
|
|
13678
|
-
const texts = truncated.map((r2) => r2.text);
|
|
13679
|
-
const vectors = await embedBatch2(texts);
|
|
13680
|
-
const records = [];
|
|
13681
|
-
for (let j2 = 0; j2 < truncated.length; j2++) {
|
|
13682
|
-
const f32 = vectors[j2];
|
|
13683
|
-
const { q8, scale } = quantizeToQ82(f32);
|
|
13684
|
-
const norm = computeNorm2(f32);
|
|
13685
|
-
records.push({
|
|
13686
|
-
messageId: truncated[j2].messageId,
|
|
13687
|
-
embeddingQ8: q8,
|
|
13688
|
-
norm,
|
|
13689
|
-
quantScale: scale
|
|
13690
|
-
});
|
|
13691
|
-
}
|
|
13718
|
+
const records = await embedRowsResilient(truncated);
|
|
13692
13719
|
insertMessageVectors(records);
|
|
13693
13720
|
return records.length;
|
|
13694
13721
|
}
|
|
13695
|
-
var MAX_EMBED_CHARS;
|
|
13722
|
+
var MAX_EMBED_CHARS, SAFE_EMBED_CHARS;
|
|
13696
13723
|
var init_message_ingest = __esm({
|
|
13697
13724
|
"src/recall/message-ingest.ts"() {
|
|
13698
13725
|
"use strict";
|
|
@@ -13701,11 +13728,13 @@ var init_message_ingest = __esm({
|
|
|
13701
13728
|
init_db();
|
|
13702
13729
|
init_paths();
|
|
13703
13730
|
init_url_path_resolver();
|
|
13731
|
+
init_log();
|
|
13704
13732
|
init_jsonl_reader();
|
|
13705
13733
|
init_claude_entry_adapter();
|
|
13706
13734
|
init_codex_jsonl_reader();
|
|
13707
13735
|
init_codex_jsonl_adapter();
|
|
13708
13736
|
MAX_EMBED_CHARS = 14e3;
|
|
13737
|
+
SAFE_EMBED_CHARS = 6e3;
|
|
13709
13738
|
}
|
|
13710
13739
|
});
|
|
13711
13740
|
|
|
@@ -14924,8 +14953,8 @@ function cudaAssetUrl() {
|
|
|
14924
14953
|
const tag = version ? `download/v${version}` : "latest/download";
|
|
14925
14954
|
return `https://github.com/${owner}/${repo}/releases/${tag}/${CUDA_ASSET_NAME}`;
|
|
14926
14955
|
}
|
|
14927
|
-
function
|
|
14928
|
-
return (0, import_node_path9.join)(
|
|
14956
|
+
function cudaBackendLib() {
|
|
14957
|
+
return (0, import_node_path9.join)(binDir(), "libggml-cuda.so");
|
|
14929
14958
|
}
|
|
14930
14959
|
async function readVram() {
|
|
14931
14960
|
try {
|
|
@@ -14957,7 +14986,7 @@ async function detectGpu(opts = {}) {
|
|
|
14957
14986
|
if (p === "win32" && a3 === "x64") {
|
|
14958
14987
|
return { ...base, cudaAvailable: "prebuilt", plannedMode: "gpu" };
|
|
14959
14988
|
}
|
|
14960
|
-
if (p === "linux" && a3 === "x64" && (0, import_node_fs9.existsSync)(
|
|
14989
|
+
if (p === "linux" && a3 === "x64" && (0, import_node_fs9.existsSync)(cudaBackendLib())) {
|
|
14961
14990
|
return { ...base, cudaAvailable: "reuse-existing", plannedMode: "gpu" };
|
|
14962
14991
|
}
|
|
14963
14992
|
if (p === "linux" && a3 === "x64") {
|
|
@@ -14966,10 +14995,7 @@ async function detectGpu(opts = {}) {
|
|
|
14966
14995
|
return { ...base, cudaAvailable: "none", plannedMode: "cpu" };
|
|
14967
14996
|
}
|
|
14968
14997
|
function stderrIndicatesOffload(stderr) {
|
|
14969
|
-
|
|
14970
|
-
return true;
|
|
14971
|
-
const m2 = /offloaded\s+(\d+)\s*\/\s*\d+\s+layers?\s+to\s+GPU/i.exec(stderr);
|
|
14972
|
-
return m2 ? Number(m2[1]) > 0 : false;
|
|
14998
|
+
return /ggml_cuda_init|found\s+\d+\s+CUDA\s+devices|loaded CUDA backend|using device CUDA|CUDA0[^\n]*buffer/i.test(stderr);
|
|
14973
14999
|
}
|
|
14974
15000
|
async function defaultProbe(args) {
|
|
14975
15001
|
const { binaryPath: binaryPath2, modelPath, libDir, ngl, platform: platform2 } = args;
|
|
@@ -15044,7 +15070,7 @@ async function runGpuPhase(opts = {}) {
|
|
|
15044
15070
|
return { mode, libDir: libDir2, ngl: mode === "gpu" ? DEFAULT_NGL : 0, cudaAvailable: info.cudaAvailable, ...reason ? { reason } : {} };
|
|
15045
15071
|
};
|
|
15046
15072
|
if (info.plannedMode === "cpu") {
|
|
15047
|
-
const reason = info.detected && info.vendor === "nvidia" ? "NVIDIA GPU detected but no usable CUDA libs (no prebuilt for this platform; no ~/.recall/bin-cuda
|
|
15073
|
+
const reason = info.detected && info.vendor === "nvidia" ? "NVIDIA GPU detected but no usable CUDA libs (no prebuilt for this platform; no ~/.recall/bin/libggml-cuda.so present)" : void 0;
|
|
15048
15074
|
return persist("cpu", null, reason);
|
|
15049
15075
|
}
|
|
15050
15076
|
if (info.cudaAvailable === "metal") {
|
|
@@ -15052,7 +15078,7 @@ async function runGpuPhase(opts = {}) {
|
|
|
15052
15078
|
}
|
|
15053
15079
|
let libDir;
|
|
15054
15080
|
if (info.cudaAvailable === "reuse-existing") {
|
|
15055
|
-
libDir =
|
|
15081
|
+
libDir = binDir();
|
|
15056
15082
|
} else if (info.cudaAvailable === "prebuilt" && p === "win32") {
|
|
15057
15083
|
libDir = binDir();
|
|
15058
15084
|
} else if (info.cudaAvailable === "prebuilt") {
|
|
@@ -15087,8 +15113,8 @@ async function runGpuPhase(opts = {}) {
|
|
|
15087
15113
|
}
|
|
15088
15114
|
}
|
|
15089
15115
|
async function defaultStage(args) {
|
|
15090
|
-
const target =
|
|
15091
|
-
const libPath = (
|
|
15116
|
+
const target = binDir();
|
|
15117
|
+
const libPath = cudaBackendLib();
|
|
15092
15118
|
if ((0, import_node_fs9.existsSync)(libPath))
|
|
15093
15119
|
return target;
|
|
15094
15120
|
if (args.offline)
|
|
@@ -15607,12 +15633,18 @@ var init_claudemd_nudge = __esm({
|
|
|
15607
15633
|
// src/installer/install.ts
|
|
15608
15634
|
var install_exports = {};
|
|
15609
15635
|
__export(install_exports, {
|
|
15636
|
+
defaultDistDir: () => defaultDistDir,
|
|
15610
15637
|
runInstall: () => runInstall
|
|
15611
15638
|
});
|
|
15612
15639
|
function defaultDistDir() {
|
|
15613
15640
|
const argv1 = process.argv[1];
|
|
15614
|
-
if (argv1)
|
|
15615
|
-
|
|
15641
|
+
if (argv1) {
|
|
15642
|
+
try {
|
|
15643
|
+
return (0, import_node_path11.dirname)((0, import_node_fs12.realpathSync)(argv1));
|
|
15644
|
+
} catch {
|
|
15645
|
+
return (0, import_node_path11.dirname)(argv1);
|
|
15646
|
+
}
|
|
15647
|
+
}
|
|
15616
15648
|
return __dirname;
|
|
15617
15649
|
}
|
|
15618
15650
|
function resolveTemplatePath(explicit) {
|
package/dist/stop-hook.js
CHANGED
|
@@ -1807,6 +1807,9 @@ function normalizePath(p) {
|
|
|
1807
1807
|
return normalized;
|
|
1808
1808
|
}
|
|
1809
1809
|
|
|
1810
|
+
// src/recall/message-ingest.ts
|
|
1811
|
+
init_log();
|
|
1812
|
+
|
|
1810
1813
|
// src/adapters/claude/jsonl-reader.ts
|
|
1811
1814
|
var fs = __toESM(require("fs"));
|
|
1812
1815
|
init_log();
|
|
@@ -2217,8 +2220,7 @@ function emitFunctionCall(payload, base, outputIndex, _counter) {
|
|
|
2217
2220
|
const outputRecord = outputIndex.get(callId);
|
|
2218
2221
|
if (outputRecord) {
|
|
2219
2222
|
const outputPayload = outputRecord.payload;
|
|
2220
|
-
const
|
|
2221
|
-
const { exitCode, body } = parseExecOutputHeader(rawOutput);
|
|
2223
|
+
const { exitCode, body } = parseExecOutputHeader(outputPayload.output);
|
|
2222
2224
|
const isError = exitCode !== 0;
|
|
2223
2225
|
const toolResult = {
|
|
2224
2226
|
type: "tool_result",
|
|
@@ -2356,7 +2358,7 @@ function emitApplyPatch(callId, input, base, outputIndex) {
|
|
|
2356
2358
|
return entries;
|
|
2357
2359
|
}
|
|
2358
2360
|
function buildCustomToolResult(parentUuid, callId, outputRecord, base) {
|
|
2359
|
-
const rawOutput = outputRecord.payload.output;
|
|
2361
|
+
const rawOutput = coerceOutputText(outputRecord.payload.output);
|
|
2360
2362
|
let content;
|
|
2361
2363
|
let isError = false;
|
|
2362
2364
|
try {
|
|
@@ -2437,7 +2439,7 @@ function emitOrphanedOutput(payload, subtype, base, outputIndex, _counter) {
|
|
|
2437
2439
|
return [];
|
|
2438
2440
|
if (!outputIndex.has(callId))
|
|
2439
2441
|
return [];
|
|
2440
|
-
const rawOutput = payload.output;
|
|
2442
|
+
const rawOutput = coerceOutputText(payload.output);
|
|
2441
2443
|
let content;
|
|
2442
2444
|
let isError = false;
|
|
2443
2445
|
if (subtype === "function_call_output") {
|
|
@@ -2550,7 +2552,18 @@ function mapFunctionCall(name, args) {
|
|
|
2550
2552
|
return { toolName: name, toolInput: args };
|
|
2551
2553
|
}
|
|
2552
2554
|
}
|
|
2553
|
-
function
|
|
2555
|
+
function coerceOutputText(output) {
|
|
2556
|
+
if (typeof output === "string")
|
|
2557
|
+
return output;
|
|
2558
|
+
if (Array.isArray(output)) {
|
|
2559
|
+
return output.map(
|
|
2560
|
+
(item) => item && typeof item === "object" && typeof item.text === "string" ? item.text : ""
|
|
2561
|
+
).filter(Boolean).join("\n");
|
|
2562
|
+
}
|
|
2563
|
+
return "";
|
|
2564
|
+
}
|
|
2565
|
+
function parseExecOutputHeader(rawOutput) {
|
|
2566
|
+
const output = coerceOutputText(rawOutput);
|
|
2554
2567
|
if (!output)
|
|
2555
2568
|
return { exitCode: 0, body: "" };
|
|
2556
2569
|
const currentMatch = output.match(/Process exited with code (\d+)/);
|
package/package.json
CHANGED