sparkecoder 0.1.122 → 0.1.123
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 +124 -24
- 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/tools/index.d.ts +3 -3
- package/package.json +1 -1
- 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/_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 +1 -1
- package/web/.next/standalone/web/.next/server/app/agents.segments/!KG1haW4p/agents/__PAGE__.segment.rsc +1 -1
- 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 +1 -1
- package/web/.next/standalone/web/.next/server/app/agents.segments/_full.segment.rsc +1 -1
- 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 +1 -1
- package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/index.segments/_full.segment.rsc +1 -1
- 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 +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.segments/!KG1haW4p/settings/__PAGE__.segment.rsc +1 -1
- 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 +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.segments/_full.segment.rsc +1 -1
- 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/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/{BEIBC9-dP0_AWGmRy97hJ → MP4p8_EldjbZ69dONoEcM}/_buildManifest.js +0 -0
- /package/web/.next/standalone/web/.next/static/{BEIBC9-dP0_AWGmRy97hJ → MP4p8_EldjbZ69dONoEcM}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/standalone/web/.next/static/{BEIBC9-dP0_AWGmRy97hJ → MP4p8_EldjbZ69dONoEcM}/_ssgManifest.js +0 -0
- /package/web/.next/standalone/web/.next/static/static/{BEIBC9-dP0_AWGmRy97hJ → MP4p8_EldjbZ69dONoEcM}/_buildManifest.js +0 -0
- /package/web/.next/standalone/web/.next/static/static/{BEIBC9-dP0_AWGmRy97hJ → MP4p8_EldjbZ69dONoEcM}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/standalone/web/.next/static/static/{BEIBC9-dP0_AWGmRy97hJ → MP4p8_EldjbZ69dONoEcM}/_ssgManifest.js +0 -0
- /package/web/.next/static/{BEIBC9-dP0_AWGmRy97hJ → MP4p8_EldjbZ69dONoEcM}/_buildManifest.js +0 -0
- /package/web/.next/static/{BEIBC9-dP0_AWGmRy97hJ → MP4p8_EldjbZ69dONoEcM}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{BEIBC9-dP0_AWGmRy97hJ → MP4p8_EldjbZ69dONoEcM}/_ssgManifest.js +0 -0
package/dist/cli.js
CHANGED
|
@@ -8202,6 +8202,55 @@ function wrapToolsNeverThrow(tools) {
|
|
|
8202
8202
|
}
|
|
8203
8203
|
return wrapped;
|
|
8204
8204
|
}
|
|
8205
|
+
function ensureToolResultsFollowCalls(messages) {
|
|
8206
|
+
if (!Array.isArray(messages) || messages.length < 3) return messages;
|
|
8207
|
+
let mutated = false;
|
|
8208
|
+
const result = messages.slice();
|
|
8209
|
+
let i = 0;
|
|
8210
|
+
while (i < result.length) {
|
|
8211
|
+
const msg = result[i];
|
|
8212
|
+
if (msg?.role !== "assistant" || !Array.isArray(msg.content)) {
|
|
8213
|
+
i++;
|
|
8214
|
+
continue;
|
|
8215
|
+
}
|
|
8216
|
+
const callIds = /* @__PURE__ */ new Set();
|
|
8217
|
+
for (const part of msg.content) {
|
|
8218
|
+
if (part?.type === "tool-call" && typeof part.toolCallId === "string") {
|
|
8219
|
+
callIds.add(part.toolCallId);
|
|
8220
|
+
}
|
|
8221
|
+
}
|
|
8222
|
+
if (callIds.size === 0) {
|
|
8223
|
+
i++;
|
|
8224
|
+
continue;
|
|
8225
|
+
}
|
|
8226
|
+
let toolIdx = -1;
|
|
8227
|
+
for (let j = i + 1; j < result.length; j++) {
|
|
8228
|
+
const m = result[j];
|
|
8229
|
+
if (m?.role === "assistant" && Array.isArray(m.content) && m.content.some((p) => p?.type === "tool-call")) {
|
|
8230
|
+
break;
|
|
8231
|
+
}
|
|
8232
|
+
if (m?.role === "tool" && Array.isArray(m.content)) {
|
|
8233
|
+
const answersOne = m.content.some(
|
|
8234
|
+
(p) => p?.type === "tool-result" && typeof p.toolCallId === "string" && callIds.has(p.toolCallId)
|
|
8235
|
+
);
|
|
8236
|
+
if (answersOne) {
|
|
8237
|
+
toolIdx = j;
|
|
8238
|
+
break;
|
|
8239
|
+
}
|
|
8240
|
+
}
|
|
8241
|
+
}
|
|
8242
|
+
if (toolIdx > i + 1) {
|
|
8243
|
+
const [toolMsg] = result.splice(toolIdx, 1);
|
|
8244
|
+
result.splice(i + 1, 0, toolMsg);
|
|
8245
|
+
mutated = true;
|
|
8246
|
+
console.warn(
|
|
8247
|
+
`[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.`
|
|
8248
|
+
);
|
|
8249
|
+
}
|
|
8250
|
+
i++;
|
|
8251
|
+
}
|
|
8252
|
+
return mutated ? result : messages;
|
|
8253
|
+
}
|
|
8205
8254
|
function repairToolPairing(messages) {
|
|
8206
8255
|
const toolCallIds = /* @__PURE__ */ new Set();
|
|
8207
8256
|
const toolResultIds = /* @__PURE__ */ new Set();
|
|
@@ -8321,6 +8370,7 @@ ${summaryContent}`
|
|
|
8321
8370
|
];
|
|
8322
8371
|
}
|
|
8323
8372
|
messages = repairToolPairing(messages);
|
|
8373
|
+
messages = ensureToolResultsFollowCalls(messages);
|
|
8324
8374
|
messages = ensureEndsWithUserOrTool(messages);
|
|
8325
8375
|
return messages;
|
|
8326
8376
|
}
|
|
@@ -8515,7 +8565,7 @@ ${summaryContent}`
|
|
|
8515
8565
|
}
|
|
8516
8566
|
}
|
|
8517
8567
|
async addResponseMessages(messages) {
|
|
8518
|
-
const safe = repairToolPairing(messages);
|
|
8568
|
+
const safe = ensureToolResultsFollowCalls(repairToolPairing(messages));
|
|
8519
8569
|
await messageQueries.addMany(this.sessionId, safe);
|
|
8520
8570
|
try {
|
|
8521
8571
|
const { appendTurn: appendTurn2, flattenContent: flattenContent2 } = await Promise.resolve().then(() => (init_conversation_archive(), conversation_archive_exports));
|
|
@@ -10626,7 +10676,7 @@ ${prompt}` });
|
|
|
10626
10676
|
const config = getConfig();
|
|
10627
10677
|
const userContent = this.buildUserMessageContent(options.prompt, options.attachments);
|
|
10628
10678
|
if (!options.skipSaveUserMessage) {
|
|
10629
|
-
this.context.addUserMessage(userContent);
|
|
10679
|
+
await this.context.addUserMessage(userContent);
|
|
10630
10680
|
}
|
|
10631
10681
|
await sessionQueries.updateStatus(this.session.id, "active");
|
|
10632
10682
|
let systemPrompt = await buildSystemPrompt({
|
|
@@ -10674,9 +10724,10 @@ ${personality.trim()}`;
|
|
|
10674
10724
|
// aborted mid-tool). Repairing in `prepareStep` guarantees no orphan
|
|
10675
10725
|
// ever reaches the model and we never hit AI_MissingToolResultsError.
|
|
10676
10726
|
prepareStep: async ({ messages: stepMessages }) => {
|
|
10677
|
-
const
|
|
10678
|
-
|
|
10679
|
-
|
|
10727
|
+
const paired = repairToolPairing(stepMessages);
|
|
10728
|
+
const ordered = ensureToolResultsFollowCalls(paired);
|
|
10729
|
+
if (ordered === stepMessages) return {};
|
|
10730
|
+
return { messages: ordered };
|
|
10680
10731
|
},
|
|
10681
10732
|
onStepFinish: async (step) => {
|
|
10682
10733
|
options.onStepFinish?.(step);
|
|
@@ -10689,7 +10740,7 @@ ${personality.trim()}`;
|
|
|
10689
10740
|
const result = await stream;
|
|
10690
10741
|
const response = await result.response;
|
|
10691
10742
|
const responseMessages = response.messages;
|
|
10692
|
-
this.context.addResponseMessages(responseMessages);
|
|
10743
|
+
await this.context.addResponseMessages(responseMessages);
|
|
10693
10744
|
};
|
|
10694
10745
|
return {
|
|
10695
10746
|
sessionId: this.session.id,
|
|
@@ -10703,7 +10754,7 @@ ${personality.trim()}`;
|
|
|
10703
10754
|
*/
|
|
10704
10755
|
async run(options) {
|
|
10705
10756
|
const config = getConfig();
|
|
10706
|
-
this.context.addUserMessage(options.prompt);
|
|
10757
|
+
await this.context.addUserMessage(options.prompt);
|
|
10707
10758
|
const systemPrompt = await buildSystemPrompt({
|
|
10708
10759
|
workingDirectory: this.session.workingDirectory,
|
|
10709
10760
|
skillsDirectories: config.resolvedSkillsDirectories,
|
|
@@ -10727,13 +10778,14 @@ ${personality.trim()}`;
|
|
|
10727
10778
|
} : void 0,
|
|
10728
10779
|
// Repair tool pairing before every step (see `stream()` for full rationale).
|
|
10729
10780
|
prepareStep: async ({ messages: stepMessages }) => {
|
|
10730
|
-
const
|
|
10731
|
-
|
|
10732
|
-
|
|
10781
|
+
const paired = repairToolPairing(stepMessages);
|
|
10782
|
+
const ordered = ensureToolResultsFollowCalls(paired);
|
|
10783
|
+
if (ordered === stepMessages) return {};
|
|
10784
|
+
return { messages: ordered };
|
|
10733
10785
|
}
|
|
10734
10786
|
});
|
|
10735
10787
|
const responseMessages = result.response.messages;
|
|
10736
|
-
this.context.addResponseMessages(responseMessages);
|
|
10788
|
+
await this.context.addResponseMessages(responseMessages);
|
|
10737
10789
|
return {
|
|
10738
10790
|
text: result.text,
|
|
10739
10791
|
steps: result.steps
|
|
@@ -10916,9 +10968,10 @@ ${p.text}` : p.text;
|
|
|
10916
10968
|
// See the matching note in `stream()` — repair tool pairing before
|
|
10917
10969
|
// every step so we never feed the model an orphan tool-call.
|
|
10918
10970
|
prepareStep: async ({ messages: stepMessages }) => {
|
|
10919
|
-
const
|
|
10920
|
-
|
|
10921
|
-
|
|
10971
|
+
const paired = repairToolPairing(stepMessages);
|
|
10972
|
+
const ordered = ensureToolResultsFollowCalls(paired);
|
|
10973
|
+
if (ordered === stepMessages) return {};
|
|
10974
|
+
return { messages: ordered };
|
|
10922
10975
|
},
|
|
10923
10976
|
onStepFinish: async (step) => {
|
|
10924
10977
|
options.onStepFinish?.(step);
|
|
@@ -13014,31 +13067,44 @@ async function recoverFromMissingToolResults(sessionId, error) {
|
|
|
13014
13067
|
} catch (err) {
|
|
13015
13068
|
console.warn("[missing-tool-recovery] could not load messages:", err?.message || err);
|
|
13016
13069
|
}
|
|
13017
|
-
const
|
|
13070
|
+
const toolInfoByCallId = /* @__PURE__ */ new Map();
|
|
13071
|
+
const resultMessageIndexByCallId = /* @__PURE__ */ new Map();
|
|
13018
13072
|
const existingResultIds = /* @__PURE__ */ new Set();
|
|
13019
|
-
for (
|
|
13073
|
+
for (let idx = 0; idx < history.length; idx++) {
|
|
13074
|
+
const msg = history[idx];
|
|
13020
13075
|
if (!Array.isArray(msg.content)) continue;
|
|
13021
13076
|
for (const part of msg.content) {
|
|
13022
13077
|
if (part?.type === "tool-call" && typeof part.toolCallId === "string") {
|
|
13023
|
-
if (typeof part.toolName === "string")
|
|
13078
|
+
if (typeof part.toolName === "string") {
|
|
13079
|
+
toolInfoByCallId.set(part.toolCallId, { toolName: part.toolName, callMessageIndex: idx });
|
|
13080
|
+
}
|
|
13024
13081
|
}
|
|
13025
13082
|
if (part?.type === "tool-result" && typeof part.toolCallId === "string") {
|
|
13026
13083
|
existingResultIds.add(part.toolCallId);
|
|
13084
|
+
resultMessageIndexByCallId.set(part.toolCallId, idx);
|
|
13027
13085
|
}
|
|
13028
13086
|
}
|
|
13029
13087
|
}
|
|
13030
|
-
const resolved = toolCallIds.map((id) =>
|
|
13031
|
-
|
|
13032
|
-
|
|
13033
|
-
|
|
13034
|
-
|
|
13088
|
+
const resolved = toolCallIds.map((id) => {
|
|
13089
|
+
const info = toolInfoByCallId.get(id);
|
|
13090
|
+
const resultIdx = resultMessageIndexByCallId.get(id);
|
|
13091
|
+
const wedgedRoles = info && typeof resultIdx === "number" && resultIdx > info.callMessageIndex + 1 ? history.slice(info.callMessageIndex + 1, resultIdx).map((m) => m.role) : void 0;
|
|
13092
|
+
return {
|
|
13093
|
+
toolCallId: id,
|
|
13094
|
+
toolName: info?.toolName ?? "unknown",
|
|
13095
|
+
foundInAssistantMessage: !!info,
|
|
13096
|
+
callMessageIndex: info?.callMessageIndex,
|
|
13097
|
+
resultMessageIndex: resultIdx,
|
|
13098
|
+
wedgedMessageRoles: wedgedRoles
|
|
13099
|
+
};
|
|
13100
|
+
});
|
|
13035
13101
|
const stillOrphaned = toolCallIds.filter((id) => !existingResultIds.has(id));
|
|
13036
13102
|
let syntheticToolMessageSaved = false;
|
|
13037
13103
|
if (stillOrphaned.length > 0) {
|
|
13038
13104
|
const syntheticParts = stillOrphaned.map((id) => ({
|
|
13039
13105
|
type: "tool-result",
|
|
13040
13106
|
toolCallId: id,
|
|
13041
|
-
toolName:
|
|
13107
|
+
toolName: toolInfoByCallId.get(id)?.toolName ?? "unknown",
|
|
13042
13108
|
output: {
|
|
13043
13109
|
type: "text",
|
|
13044
13110
|
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.]"
|
|
@@ -13055,15 +13121,49 @@ async function recoverFromMissingToolResults(sessionId, error) {
|
|
|
13055
13121
|
}
|
|
13056
13122
|
}
|
|
13057
13123
|
const lastFewMessageRoles = history.slice(-6).map((m) => m.role);
|
|
13124
|
+
const first = resolved.find((r) => r.callMessageIndex !== void 0);
|
|
13125
|
+
let contextSnapshot;
|
|
13126
|
+
if (first?.callMessageIndex !== void 0) {
|
|
13127
|
+
const start = Math.max(0, first.callMessageIndex - 1);
|
|
13128
|
+
const end = Math.min(
|
|
13129
|
+
history.length,
|
|
13130
|
+
Math.max(first.callMessageIndex, first.resultMessageIndex ?? first.callMessageIndex) + 2
|
|
13131
|
+
);
|
|
13132
|
+
contextSnapshot = history.slice(start, end).map((m, offset) => ({
|
|
13133
|
+
index: start + offset,
|
|
13134
|
+
role: m.role,
|
|
13135
|
+
summary: summarizeContent(m.content)
|
|
13136
|
+
}));
|
|
13137
|
+
}
|
|
13138
|
+
const anyWedged = resolved.some((r) => r.wedgedMessageRoles && r.wedgedMessageRoles.length > 0);
|
|
13058
13139
|
return {
|
|
13059
13140
|
kind: "missing_tool_results",
|
|
13060
13141
|
toolCallIds,
|
|
13061
13142
|
resolved,
|
|
13062
13143
|
syntheticToolMessageSaved,
|
|
13063
13144
|
lastFewMessageRoles,
|
|
13064
|
-
|
|
13145
|
+
contextSnapshot,
|
|
13146
|
+
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."
|
|
13065
13147
|
};
|
|
13066
13148
|
}
|
|
13149
|
+
function summarizeContent(content) {
|
|
13150
|
+
if (typeof content === "string") {
|
|
13151
|
+
return content.length > 160 ? content.slice(0, 160) + "\u2026" : content;
|
|
13152
|
+
}
|
|
13153
|
+
if (!Array.isArray(content)) return String(content);
|
|
13154
|
+
const parts = content.map((p) => {
|
|
13155
|
+
if (!p || typeof p !== "object") return String(p);
|
|
13156
|
+
if (p.type === "text") {
|
|
13157
|
+
const t = String(p.text ?? "");
|
|
13158
|
+
return `text(${t.length > 80 ? t.slice(0, 80) + "\u2026" : t})`;
|
|
13159
|
+
}
|
|
13160
|
+
if (p.type === "tool-call") return `tool-call(${p.toolName}:${p.toolCallId})`;
|
|
13161
|
+
if (p.type === "tool-result") return `tool-result(${p.toolName ?? "?"}:${p.toolCallId})`;
|
|
13162
|
+
if (p.type === "reasoning") return "reasoning";
|
|
13163
|
+
return p.type ?? "unknown";
|
|
13164
|
+
});
|
|
13165
|
+
return parts.join(", ");
|
|
13166
|
+
}
|
|
13067
13167
|
|
|
13068
13168
|
// src/server/routes/agents.ts
|
|
13069
13169
|
init_agent();
|