sparkecoder 0.1.122 → 0.1.124
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/agent/index.d.ts +3 -3
- package/dist/agent/index.js +67 -14
- package/dist/agent/index.js.map +1 -1
- package/dist/cli.js +201 -66
- package/dist/cli.js.map +1 -1
- package/dist/db/index.d.ts +2 -2
- package/dist/{index-DczYH89U.d.ts → index-Bcz0aCAR.d.ts} +104 -104
- package/dist/index.d.ts +5 -5
- package/dist/index.js +124 -24
- package/dist/index.js.map +1 -1
- package/dist/{schema-DxrKyetI.d.ts → schema-BWbWmfDQ.d.ts} +3 -3
- package/dist/{search-CVVfuBPZ.d.ts → search-DOzC4ojH.d.ts} +4 -4
- package/dist/server/index.js +124 -24
- package/dist/server/index.js.map +1 -1
- package/dist/skills/default/recording.md +2 -2
- package/dist/tools/index.d.ts +3 -3
- package/package.json +1 -1
- package/src/skills/default/recording.md +2 -2
- package/web/.next/BUILD_ID +1 -1
- package/web/.next/standalone/web/.next/BUILD_ID +1 -1
- package/web/.next/standalone/web/.next/build-manifest.json +2 -2
- package/web/.next/standalone/web/.next/prerender-manifest.json +3 -3
- package/web/.next/standalone/web/.next/server/app/(main)/agents/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/web/.next/server/app/(main)/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/web/.next/server/app/(main)/session/[id]/page.js.nft.json +1 -1
- package/web/.next/standalone/web/.next/server/app/(main)/session/[id]/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/web/.next/server/app/(main)/settings/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.html +2 -2
- package/web/.next/standalone/web/.next/server/app/_global-error.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.html +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/agents.html +1 -1
- package/web/.next/standalone/web/.next/server/app/agents.rsc +3 -3
- package/web/.next/standalone/web/.next/server/app/agents.segments/!KG1haW4p/agents/__PAGE__.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/agents.segments/!KG1haW4p/agents.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/agents.segments/!KG1haW4p.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/agents.segments/_full.segment.rsc +3 -3
- package/web/.next/standalone/web/.next/server/app/agents.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/agents.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/agents.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.html +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/installation.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs/installation/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs/installation.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.html +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/skills.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs/skills/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs/skills.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.html +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/tools.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs/tools/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs/tools.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.html +2 -2
- package/web/.next/standalone/web/.next/server/app/docs.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.segments/docs/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.segments/docs.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/index.html +1 -1
- package/web/.next/standalone/web/.next/server/app/index.rsc +3 -3
- package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p/__PAGE__.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/index.segments/_full.segment.rsc +3 -3
- package/web/.next/standalone/web/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.html +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.rsc +3 -3
- package/web/.next/standalone/web/.next/server/app/settings.segments/!KG1haW4p/settings/__PAGE__.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/settings.segments/!KG1haW4p/settings.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.segments/!KG1haW4p.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/settings.segments/_full.segment.rsc +3 -3
- package/web/.next/standalone/web/.next/server/app/settings.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_c87abaf4._.js → 2374f_12d55e68._.js} +1 -1
- package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_1f3f2d00._.js → 2374f_1c0639c2._.js} +1 -1
- package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_a0d5caeb._.js → 2374f_28cd6777._.js} +1 -1
- package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_570c34dc._.js → 2374f_5f47a9b7._.js} +1 -1
- package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_d8122230._.js → 2374f_aa218457._.js} +1 -1
- package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_9c560f3a._.js → 2374f_f678a96f._.js} +1 -1
- package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_38945fd9._.js → 2374f_fac4000d._.js} +1 -1
- package/web/.next/standalone/web/.next/server/chunks/ssr/{[root-of-the-server]__4de426bd._.js → [root-of-the-server]__e5911ea8._.js} +4 -4
- package/web/.next/standalone/web/.next/server/chunks/ssr/{web_62ca4286._.js → web_2966b3a3._.js} +2 -2
- package/web/.next/standalone/web/.next/server/chunks/ssr/web_4fe3c244._.js +1 -1
- package/web/.next/standalone/web/.next/server/pages/404.html +1 -1
- package/web/.next/standalone/web/.next/server/pages/500.html +2 -2
- package/web/.next/standalone/web/.next/server/server-reference-manifest.js +1 -1
- package/web/.next/standalone/web/.next/server/server-reference-manifest.json +1 -1
- package/web/.next/standalone/web/.next/static/chunks/{91988e253d5fa420.js → 4d95c15f712c9e06.js} +5 -5
- package/web/.next/standalone/web/.next/static/chunks/780c93257fac7d43.js +1 -0
- package/web/.next/standalone/web/.next/static/static/chunks/{91988e253d5fa420.js → 4d95c15f712c9e06.js} +5 -5
- package/web/.next/standalone/web/.next/static/static/chunks/780c93257fac7d43.js +1 -0
- package/web/.next/standalone/web/src/components/chat-interface.tsx +112 -1
- package/web/.next/static/chunks/{91988e253d5fa420.js → 4d95c15f712c9e06.js} +5 -5
- package/web/.next/static/chunks/780c93257fac7d43.js +1 -0
- package/web/.next/standalone/web/.next/static/chunks/f0f19357f3fb7cf8.js +0 -1
- package/web/.next/standalone/web/.next/static/static/chunks/f0f19357f3fb7cf8.js +0 -1
- package/web/.next/static/chunks/f0f19357f3fb7cf8.js +0 -1
- /package/web/.next/standalone/web/.next/static/{BEIBC9-dP0_AWGmRy97hJ → cYXZ7UzGc5TttFIXRRcSC}/_buildManifest.js +0 -0
- /package/web/.next/standalone/web/.next/static/{BEIBC9-dP0_AWGmRy97hJ → cYXZ7UzGc5TttFIXRRcSC}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/standalone/web/.next/static/{BEIBC9-dP0_AWGmRy97hJ → cYXZ7UzGc5TttFIXRRcSC}/_ssgManifest.js +0 -0
- /package/web/.next/standalone/web/.next/static/static/{BEIBC9-dP0_AWGmRy97hJ → cYXZ7UzGc5TttFIXRRcSC}/_buildManifest.js +0 -0
- /package/web/.next/standalone/web/.next/static/static/{BEIBC9-dP0_AWGmRy97hJ → cYXZ7UzGc5TttFIXRRcSC}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/standalone/web/.next/static/static/{BEIBC9-dP0_AWGmRy97hJ → cYXZ7UzGc5TttFIXRRcSC}/_ssgManifest.js +0 -0
- /package/web/.next/static/{BEIBC9-dP0_AWGmRy97hJ → cYXZ7UzGc5TttFIXRRcSC}/_buildManifest.js +0 -0
- /package/web/.next/static/{BEIBC9-dP0_AWGmRy97hJ → cYXZ7UzGc5TttFIXRRcSC}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{BEIBC9-dP0_AWGmRy97hJ → cYXZ7UzGc5TttFIXRRcSC}/_ssgManifest.js +0 -0
package/dist/index.js
CHANGED
|
@@ -7476,6 +7476,55 @@ function wrapToolsNeverThrow(tools) {
|
|
|
7476
7476
|
}
|
|
7477
7477
|
return wrapped;
|
|
7478
7478
|
}
|
|
7479
|
+
function ensureToolResultsFollowCalls(messages) {
|
|
7480
|
+
if (!Array.isArray(messages) || messages.length < 3) return messages;
|
|
7481
|
+
let mutated = false;
|
|
7482
|
+
const result = messages.slice();
|
|
7483
|
+
let i = 0;
|
|
7484
|
+
while (i < result.length) {
|
|
7485
|
+
const msg = result[i];
|
|
7486
|
+
if (msg?.role !== "assistant" || !Array.isArray(msg.content)) {
|
|
7487
|
+
i++;
|
|
7488
|
+
continue;
|
|
7489
|
+
}
|
|
7490
|
+
const callIds = /* @__PURE__ */ new Set();
|
|
7491
|
+
for (const part of msg.content) {
|
|
7492
|
+
if (part?.type === "tool-call" && typeof part.toolCallId === "string") {
|
|
7493
|
+
callIds.add(part.toolCallId);
|
|
7494
|
+
}
|
|
7495
|
+
}
|
|
7496
|
+
if (callIds.size === 0) {
|
|
7497
|
+
i++;
|
|
7498
|
+
continue;
|
|
7499
|
+
}
|
|
7500
|
+
let toolIdx = -1;
|
|
7501
|
+
for (let j = i + 1; j < result.length; j++) {
|
|
7502
|
+
const m = result[j];
|
|
7503
|
+
if (m?.role === "assistant" && Array.isArray(m.content) && m.content.some((p) => p?.type === "tool-call")) {
|
|
7504
|
+
break;
|
|
7505
|
+
}
|
|
7506
|
+
if (m?.role === "tool" && Array.isArray(m.content)) {
|
|
7507
|
+
const answersOne = m.content.some(
|
|
7508
|
+
(p) => p?.type === "tool-result" && typeof p.toolCallId === "string" && callIds.has(p.toolCallId)
|
|
7509
|
+
);
|
|
7510
|
+
if (answersOne) {
|
|
7511
|
+
toolIdx = j;
|
|
7512
|
+
break;
|
|
7513
|
+
}
|
|
7514
|
+
}
|
|
7515
|
+
}
|
|
7516
|
+
if (toolIdx > i + 1) {
|
|
7517
|
+
const [toolMsg] = result.splice(toolIdx, 1);
|
|
7518
|
+
result.splice(i + 1, 0, toolMsg);
|
|
7519
|
+
mutated = true;
|
|
7520
|
+
console.warn(
|
|
7521
|
+
`[tool-repair] Reordered tool-result message from index ${toolIdx} to ${i + 1} to immediately follow assistant tool-call(s) (${[...callIds].join(", ")}). ${toolIdx - i - 1} message(s) were wedged between them.`
|
|
7522
|
+
);
|
|
7523
|
+
}
|
|
7524
|
+
i++;
|
|
7525
|
+
}
|
|
7526
|
+
return mutated ? result : messages;
|
|
7527
|
+
}
|
|
7479
7528
|
function repairToolPairing(messages) {
|
|
7480
7529
|
const toolCallIds = /* @__PURE__ */ new Set();
|
|
7481
7530
|
const toolResultIds = /* @__PURE__ */ new Set();
|
|
@@ -7595,6 +7644,7 @@ ${summaryContent}`
|
|
|
7595
7644
|
];
|
|
7596
7645
|
}
|
|
7597
7646
|
messages = repairToolPairing(messages);
|
|
7647
|
+
messages = ensureToolResultsFollowCalls(messages);
|
|
7598
7648
|
messages = ensureEndsWithUserOrTool(messages);
|
|
7599
7649
|
return messages;
|
|
7600
7650
|
}
|
|
@@ -7789,7 +7839,7 @@ ${summaryContent}`
|
|
|
7789
7839
|
}
|
|
7790
7840
|
}
|
|
7791
7841
|
async addResponseMessages(messages) {
|
|
7792
|
-
const safe = repairToolPairing(messages);
|
|
7842
|
+
const safe = ensureToolResultsFollowCalls(repairToolPairing(messages));
|
|
7793
7843
|
await messageQueries.addMany(this.sessionId, safe);
|
|
7794
7844
|
try {
|
|
7795
7845
|
const { appendTurn: appendTurn2, flattenContent: flattenContent2 } = await Promise.resolve().then(() => (init_conversation_archive(), conversation_archive_exports));
|
|
@@ -9900,7 +9950,7 @@ ${prompt}` });
|
|
|
9900
9950
|
const config = getConfig();
|
|
9901
9951
|
const userContent = this.buildUserMessageContent(options.prompt, options.attachments);
|
|
9902
9952
|
if (!options.skipSaveUserMessage) {
|
|
9903
|
-
this.context.addUserMessage(userContent);
|
|
9953
|
+
await this.context.addUserMessage(userContent);
|
|
9904
9954
|
}
|
|
9905
9955
|
await sessionQueries.updateStatus(this.session.id, "active");
|
|
9906
9956
|
let systemPrompt = await buildSystemPrompt({
|
|
@@ -9948,9 +9998,10 @@ ${personality.trim()}`;
|
|
|
9948
9998
|
// aborted mid-tool). Repairing in `prepareStep` guarantees no orphan
|
|
9949
9999
|
// ever reaches the model and we never hit AI_MissingToolResultsError.
|
|
9950
10000
|
prepareStep: async ({ messages: stepMessages }) => {
|
|
9951
|
-
const
|
|
9952
|
-
|
|
9953
|
-
|
|
10001
|
+
const paired = repairToolPairing(stepMessages);
|
|
10002
|
+
const ordered = ensureToolResultsFollowCalls(paired);
|
|
10003
|
+
if (ordered === stepMessages) return {};
|
|
10004
|
+
return { messages: ordered };
|
|
9954
10005
|
},
|
|
9955
10006
|
onStepFinish: async (step) => {
|
|
9956
10007
|
options.onStepFinish?.(step);
|
|
@@ -9963,7 +10014,7 @@ ${personality.trim()}`;
|
|
|
9963
10014
|
const result = await stream;
|
|
9964
10015
|
const response = await result.response;
|
|
9965
10016
|
const responseMessages = response.messages;
|
|
9966
|
-
this.context.addResponseMessages(responseMessages);
|
|
10017
|
+
await this.context.addResponseMessages(responseMessages);
|
|
9967
10018
|
};
|
|
9968
10019
|
return {
|
|
9969
10020
|
sessionId: this.session.id,
|
|
@@ -9977,7 +10028,7 @@ ${personality.trim()}`;
|
|
|
9977
10028
|
*/
|
|
9978
10029
|
async run(options) {
|
|
9979
10030
|
const config = getConfig();
|
|
9980
|
-
this.context.addUserMessage(options.prompt);
|
|
10031
|
+
await this.context.addUserMessage(options.prompt);
|
|
9981
10032
|
const systemPrompt = await buildSystemPrompt({
|
|
9982
10033
|
workingDirectory: this.session.workingDirectory,
|
|
9983
10034
|
skillsDirectories: config.resolvedSkillsDirectories,
|
|
@@ -10001,13 +10052,14 @@ ${personality.trim()}`;
|
|
|
10001
10052
|
} : void 0,
|
|
10002
10053
|
// Repair tool pairing before every step (see `stream()` for full rationale).
|
|
10003
10054
|
prepareStep: async ({ messages: stepMessages }) => {
|
|
10004
|
-
const
|
|
10005
|
-
|
|
10006
|
-
|
|
10055
|
+
const paired = repairToolPairing(stepMessages);
|
|
10056
|
+
const ordered = ensureToolResultsFollowCalls(paired);
|
|
10057
|
+
if (ordered === stepMessages) return {};
|
|
10058
|
+
return { messages: ordered };
|
|
10007
10059
|
}
|
|
10008
10060
|
});
|
|
10009
10061
|
const responseMessages = result.response.messages;
|
|
10010
|
-
this.context.addResponseMessages(responseMessages);
|
|
10062
|
+
await this.context.addResponseMessages(responseMessages);
|
|
10011
10063
|
return {
|
|
10012
10064
|
text: result.text,
|
|
10013
10065
|
steps: result.steps
|
|
@@ -10190,9 +10242,10 @@ ${p.text}` : p.text;
|
|
|
10190
10242
|
// See the matching note in `stream()` — repair tool pairing before
|
|
10191
10243
|
// every step so we never feed the model an orphan tool-call.
|
|
10192
10244
|
prepareStep: async ({ messages: stepMessages }) => {
|
|
10193
|
-
const
|
|
10194
|
-
|
|
10195
|
-
|
|
10245
|
+
const paired = repairToolPairing(stepMessages);
|
|
10246
|
+
const ordered = ensureToolResultsFollowCalls(paired);
|
|
10247
|
+
if (ordered === stepMessages) return {};
|
|
10248
|
+
return { messages: ordered };
|
|
10196
10249
|
},
|
|
10197
10250
|
onStepFinish: async (step) => {
|
|
10198
10251
|
options.onStepFinish?.(step);
|
|
@@ -12063,31 +12116,44 @@ async function recoverFromMissingToolResults(sessionId, error) {
|
|
|
12063
12116
|
} catch (err) {
|
|
12064
12117
|
console.warn("[missing-tool-recovery] could not load messages:", err?.message || err);
|
|
12065
12118
|
}
|
|
12066
|
-
const
|
|
12119
|
+
const toolInfoByCallId = /* @__PURE__ */ new Map();
|
|
12120
|
+
const resultMessageIndexByCallId = /* @__PURE__ */ new Map();
|
|
12067
12121
|
const existingResultIds = /* @__PURE__ */ new Set();
|
|
12068
|
-
for (
|
|
12122
|
+
for (let idx = 0; idx < history.length; idx++) {
|
|
12123
|
+
const msg = history[idx];
|
|
12069
12124
|
if (!Array.isArray(msg.content)) continue;
|
|
12070
12125
|
for (const part of msg.content) {
|
|
12071
12126
|
if (part?.type === "tool-call" && typeof part.toolCallId === "string") {
|
|
12072
|
-
if (typeof part.toolName === "string")
|
|
12127
|
+
if (typeof part.toolName === "string") {
|
|
12128
|
+
toolInfoByCallId.set(part.toolCallId, { toolName: part.toolName, callMessageIndex: idx });
|
|
12129
|
+
}
|
|
12073
12130
|
}
|
|
12074
12131
|
if (part?.type === "tool-result" && typeof part.toolCallId === "string") {
|
|
12075
12132
|
existingResultIds.add(part.toolCallId);
|
|
12133
|
+
resultMessageIndexByCallId.set(part.toolCallId, idx);
|
|
12076
12134
|
}
|
|
12077
12135
|
}
|
|
12078
12136
|
}
|
|
12079
|
-
const resolved = toolCallIds.map((id) =>
|
|
12080
|
-
|
|
12081
|
-
|
|
12082
|
-
|
|
12083
|
-
|
|
12137
|
+
const resolved = toolCallIds.map((id) => {
|
|
12138
|
+
const info = toolInfoByCallId.get(id);
|
|
12139
|
+
const resultIdx = resultMessageIndexByCallId.get(id);
|
|
12140
|
+
const wedgedRoles = info && typeof resultIdx === "number" && resultIdx > info.callMessageIndex + 1 ? history.slice(info.callMessageIndex + 1, resultIdx).map((m) => m.role) : void 0;
|
|
12141
|
+
return {
|
|
12142
|
+
toolCallId: id,
|
|
12143
|
+
toolName: info?.toolName ?? "unknown",
|
|
12144
|
+
foundInAssistantMessage: !!info,
|
|
12145
|
+
callMessageIndex: info?.callMessageIndex,
|
|
12146
|
+
resultMessageIndex: resultIdx,
|
|
12147
|
+
wedgedMessageRoles: wedgedRoles
|
|
12148
|
+
};
|
|
12149
|
+
});
|
|
12084
12150
|
const stillOrphaned = toolCallIds.filter((id) => !existingResultIds.has(id));
|
|
12085
12151
|
let syntheticToolMessageSaved = false;
|
|
12086
12152
|
if (stillOrphaned.length > 0) {
|
|
12087
12153
|
const syntheticParts = stillOrphaned.map((id) => ({
|
|
12088
12154
|
type: "tool-result",
|
|
12089
12155
|
toolCallId: id,
|
|
12090
|
-
toolName:
|
|
12156
|
+
toolName: toolInfoByCallId.get(id)?.toolName ?? "unknown",
|
|
12091
12157
|
output: {
|
|
12092
12158
|
type: "text",
|
|
12093
12159
|
value: "[Auto-recovered: the original tool execution never produced a result (crash, timeout, or message stripped during context compaction). This synthetic placeholder lets the conversation continue.]"
|
|
@@ -12104,15 +12170,49 @@ async function recoverFromMissingToolResults(sessionId, error) {
|
|
|
12104
12170
|
}
|
|
12105
12171
|
}
|
|
12106
12172
|
const lastFewMessageRoles = history.slice(-6).map((m) => m.role);
|
|
12173
|
+
const first = resolved.find((r) => r.callMessageIndex !== void 0);
|
|
12174
|
+
let contextSnapshot;
|
|
12175
|
+
if (first?.callMessageIndex !== void 0) {
|
|
12176
|
+
const start = Math.max(0, first.callMessageIndex - 1);
|
|
12177
|
+
const end = Math.min(
|
|
12178
|
+
history.length,
|
|
12179
|
+
Math.max(first.callMessageIndex, first.resultMessageIndex ?? first.callMessageIndex) + 2
|
|
12180
|
+
);
|
|
12181
|
+
contextSnapshot = history.slice(start, end).map((m, offset) => ({
|
|
12182
|
+
index: start + offset,
|
|
12183
|
+
role: m.role,
|
|
12184
|
+
summary: summarizeContent(m.content)
|
|
12185
|
+
}));
|
|
12186
|
+
}
|
|
12187
|
+
const anyWedged = resolved.some((r) => r.wedgedMessageRoles && r.wedgedMessageRoles.length > 0);
|
|
12107
12188
|
return {
|
|
12108
12189
|
kind: "missing_tool_results",
|
|
12109
12190
|
toolCallIds,
|
|
12110
12191
|
resolved,
|
|
12111
12192
|
syntheticToolMessageSaved,
|
|
12112
12193
|
lastFewMessageRoles,
|
|
12113
|
-
|
|
12194
|
+
contextSnapshot,
|
|
12195
|
+
hint: anyWedged ? "A non-tool message was wedged between the assistant tool-call and its tool-result (likely a Slack/system inbox event that arrived mid-turn). " + (syntheticToolMessageSaved ? "Synthetic tool-result was added as a fallback, but the proper fix (now in place) is the reordering pass that moves tool-results to immediately follow their tool-calls." : "The reordering pass should fix this on the next turn; if not, revert to the previous checkpoint.") : syntheticToolMessageSaved ? "Synthetic tool-result(s) saved. Re-send your message to continue." : "Could not auto-recover; please reset the session or revert to the previous checkpoint."
|
|
12114
12196
|
};
|
|
12115
12197
|
}
|
|
12198
|
+
function summarizeContent(content) {
|
|
12199
|
+
if (typeof content === "string") {
|
|
12200
|
+
return content.length > 160 ? content.slice(0, 160) + "\u2026" : content;
|
|
12201
|
+
}
|
|
12202
|
+
if (!Array.isArray(content)) return String(content);
|
|
12203
|
+
const parts = content.map((p) => {
|
|
12204
|
+
if (!p || typeof p !== "object") return String(p);
|
|
12205
|
+
if (p.type === "text") {
|
|
12206
|
+
const t = String(p.text ?? "");
|
|
12207
|
+
return `text(${t.length > 80 ? t.slice(0, 80) + "\u2026" : t})`;
|
|
12208
|
+
}
|
|
12209
|
+
if (p.type === "tool-call") return `tool-call(${p.toolName}:${p.toolCallId})`;
|
|
12210
|
+
if (p.type === "tool-result") return `tool-result(${p.toolName ?? "?"}:${p.toolCallId})`;
|
|
12211
|
+
if (p.type === "reasoning") return "reasoning";
|
|
12212
|
+
return p.type ?? "unknown";
|
|
12213
|
+
});
|
|
12214
|
+
return parts.join(", ");
|
|
12215
|
+
}
|
|
12116
12216
|
|
|
12117
12217
|
// src/server/routes/agents.ts
|
|
12118
12218
|
init_agent();
|