@xopcai/xopc 0.0.158 → 0.0.159
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/browser-ext/manifest.json +1 -1
- package/dist/extensions/dashscope/src/image-generation-provider.js +1 -1
- package/dist/extensions/fal/src/image-generation-provider.js +1 -1
- package/dist/extensions/google/src/image-generation-provider.js +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{action-boundary-settings-panel-2p1f4-KA.js → action-boundary-settings-panel-CaRK2vIy.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-BIl6X2b_.js → agent-avatar-dicebear-BeVf03hx.js} +1 -1
- package/dist/gateway/static/root/assets/{agents-bnkKH9EI.js → agents-P05C4A-3.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-CZxw161D.js → app-management-settings-panel-BG2ulMYw.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-CRXNlDhH.js → appearance-settings-0Kjenr2T.js} +1 -1
- package/dist/gateway/static/root/assets/{apps-page-l4ripRNG.js → apps-page-DANGrBpN.js} +1 -1
- package/dist/gateway/static/root/assets/{archive-plugin-CpVshjXu.js → archive-plugin-ChiNnH1e.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-M9WqqJnQ.js → attachment-load-pbBlQR-g.js} +1 -1
- package/dist/gateway/static/root/assets/{automation-suggestion-card-CYMsAsYf.js → automation-suggestion-card-CTZDOyDy.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-Kny7tLiF.js → automations-page-BXfGL_cm.js} +1 -1
- package/dist/gateway/static/root/assets/{binary-plugins-Cjn3zb4u.js → binary-plugins-BeZGzpGF.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-BPKdquaV.js → block-editor-BnDmhN5Z.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-settings-page-vr1tXAab.js → browser-settings-page-534luV0B.js} +1 -1
- package/dist/gateway/static/root/assets/{capability-presets-api-Bzkcsyzn.js → capability-presets-api-Ii36j_7v.js} +1 -1
- package/dist/gateway/static/root/assets/{capability-presets-settings-panel-D4rH4Dax.js → capability-presets-settings-panel-Cl3dw4yh.js} +1 -1
- package/dist/gateway/static/root/assets/{channels-settings-Tlhbi5eh.js → channels-settings-M91zFJVi.js} +1 -1
- package/dist/gateway/static/root/assets/{connector-logo-ljPKdYKh.js → connector-logo-CiLxuZ8S.js} +1 -1
- package/dist/gateway/static/root/assets/{connectors-page-_XfvjXoY.js → connectors-page-CV5UulW6.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-DKUlAgm7.js → desktop-pet-Cil2eSpW.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-aWWzjdza.js → desktop-pet-settings-DwsC6l5F.js} +1 -1
- package/dist/gateway/static/root/assets/{directory-picker-path-field-Dmy1035j.js → directory-picker-path-field-CC2VL5Mc.js} +1 -1
- package/dist/gateway/static/root/assets/{dreaming-settings-tT4WkBkd.js → dreaming-settings-KY7ZfVsy.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-CL79q8AH.js → extension-debug-page-C8KBeucs.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-hq80wkFI.js → extension-page-CV-5Kcyk.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-BV-9GDfT.js → extension-settings-page-DvUtDrAu.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-api-CFqoN2NW.js → gateway-config-api-DXfVeJLc.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-settings-DzR-kM91.js → gateway-settings-BpJ0v56l.js} +1 -1
- package/dist/gateway/static/root/assets/{goal-create-dialog-BLjHRtqe.js → goal-create-dialog-lMHD-2CX.js} +1 -1
- package/dist/gateway/static/root/assets/{goal-detail-page-BRxeujXh.js → goal-detail-page-yPmF-G7b.js} +1 -1
- package/dist/gateway/static/root/assets/{goals-config-api--qJ4qlRq.js → goals-config-api-P8VhLqYF.js} +1 -1
- package/dist/gateway/static/root/assets/{goals-page-BaZ3aw4u.js → goals-page-BHTCKobG.js} +1 -1
- package/dist/gateway/static/root/assets/{goals-settings-h7x9h5lb.js → goals-settings-DHXyaH_O.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-settings-71IhhM3s.js → heartbeat-settings-CNckP_Dv.js} +1 -1
- package/dist/gateway/static/root/assets/index-BgZhEOkN.css +1 -0
- package/dist/gateway/static/root/assets/{index-EXa_i6BT.js → index-BuqGh2SW.js} +65 -65
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-BZGmHvLu.js → keyboard-shortcuts-settings-jXmv1RVX.js} +1 -1
- package/dist/gateway/static/root/assets/{local-app-workbench-page-lUpd6lSo.js → local-app-workbench-page-zpp_wciE.js} +1 -1
- package/dist/gateway/static/root/assets/{local-apps-page-CiLqrMIh.js → local-apps-page-Cs5LKjtc.js} +1 -1
- package/dist/gateway/static/root/assets/{logs-page-FPDTmcWe.js → logs-page-B4CRYqYR.js} +1 -1
- package/dist/gateway/static/root/assets/{markdown-split-r1HPWfCU.js → markdown-split-BFqeSNte.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-D74kd3hn.js → media-plugins-Cc8379gq.js} +1 -1
- package/dist/gateway/static/root/assets/{models-hub-panel-BXrdePhv.js → models-hub-panel-1hdoAoB_.js} +1 -1
- package/dist/gateway/static/root/assets/{notes-page-Dgu02514.js → notes-page-DlGU4ipo.js} +1 -1
- package/dist/gateway/static/root/assets/{notes-workbench-D-EAhXv1.js → notes-workbench-DQEAZTA5.js} +2 -2
- package/dist/gateway/static/root/assets/{page-tabs-hinRdDy3.js → page-tabs-kFOswGlG.js} +1 -1
- package/dist/gateway/static/root/assets/{preview-open-alternatives-C7fw3oGy.js → preview-open-alternatives-CvjuvABg.js} +1 -1
- package/dist/gateway/static/root/assets/{project-detail-page-BjpB1wrp.js → project-detail-page-Bp9bC7A6.js} +1 -1
- package/dist/gateway/static/root/assets/{projects-page-BxyjqOfC.js → projects-page-RNorFXTw.js} +1 -1
- package/dist/gateway/static/root/assets/{remote-access-hub-BFv6Upke.js → remote-access-hub-BqRTcM_6.js} +1 -1
- package/dist/gateway/static/root/assets/{save-bar-controls-C3aU8-vO.js → save-bar-controls-DwrD7ODx.js} +1 -1
- package/dist/gateway/static/root/assets/{schedule-field-DjegExFD.js → schedule-field-Ba4WzTmE.js} +1 -1
- package/dist/gateway/static/root/assets/{schema-form-DLubnsql.js → schema-form-DvydL8eF.js} +1 -1
- package/dist/gateway/static/root/assets/{sessions-page-BX4DH8J7.js → sessions-page-B2EfW1cm.js} +1 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-CklL85T4.js +1 -0
- package/dist/gateway/static/root/assets/{settings-collapsible-section-3syQHsNR.js → settings-collapsible-section-LaQqGGej.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-form-section-D4DCZzKg.js → settings-form-section-DruI__qO.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-loading-skeleton-c5K85ylS.js → settings-loading-skeleton-UvA-eDhF.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-DNiDlaRq.js → settings-page-5oCGSebm.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-layout-iTRY1Hy-.js → settings-page-layout-DG-XMIPu.js} +1 -1
- package/dist/gateway/static/root/assets/{setup-status-panel-BH4xQKM9.js → setup-status-panel-D3my1HgB.js} +1 -1
- package/dist/gateway/static/root/assets/{share-preview-page-B88Afrhe.js → share-preview-page-FLVeTrRt.js} +1 -1
- package/dist/gateway/static/root/assets/{shares-settings-B6kKkvOb.js → shares-settings-DVxgjrsP.js} +1 -1
- package/dist/gateway/static/root/assets/{skill-reload-api-DtjS-nUK.js → skill-reload-api-Bcu58ZaF.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page-CQEoPv0u.js → skills-page-CDd-84FE.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-DtpTq837.js → system-settings-panel-CeK93xVi.js} +1 -1
- package/dist/gateway/static/root/assets/{typed-models-lib-ndEnUP3b.js → typed-models-lib-D1Lr2gG0.js} +1 -1
- package/dist/gateway/static/root/assets/{user-context-page-Dn2T3itn.js → user-context-page-1OyJnTyR.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-api-key-field-wtWc3SfN.js → voice-api-key-field-B2ncRwHS.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-page-Ckxhj66e.js → work-discovery-page-BZlY4PZL.js} +1 -1
- package/dist/gateway/static/root/assets/{work-item-detail-page-_1QgGPNw.js → work-item-detail-page-DPXMrneY.js} +1 -1
- package/dist/gateway/static/root/assets/{work-page-BPdf2iuv.js → work-page-CTERoqyv.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-ukmpkj66.js → workflow-run-setup-panel-Bynqe4kV.js} +1 -1
- package/dist/gateway/static/root/assets/{workflows-page-DdKTx0Hs.js → workflows-page-CLgsnqFQ.js} +1 -1
- package/dist/gateway/static/root/index.html +2 -2
- package/dist/package.js +1 -1
- package/dist/src/agent/embedded/session-tool-result-guard.js +14 -0
- package/dist/src/agent/image/generation/openai-compatible-image-provider.js +1 -1
- package/dist/src/agent/service/process-direct-streaming.js +1 -1
- package/dist/src/agent/tools/image-generate-tool.js +10 -3
- package/dist/src/agent/tools/send-media.js +20 -70
- package/dist/src/agent/tools/tool-media.d.ts +9 -0
- package/dist/src/agent/tools/tool-media.js +58 -0
- package/dist/src/config/agent-profile.js +1 -1
- package/dist/src/gateway/agent-run-relay.d.ts +2 -0
- package/dist/src/gateway/agent-run-relay.js +114 -14
- package/dist/src/gateway/agents-admin.js +1 -1
- package/dist/src/gateway/chat-stream/mapper.d.ts +1 -1
- package/dist/src/gateway/chat-stream/mapper.js +27 -42
- package/dist/src/gateway/chat-stream/thinking-delta-coalescer.d.ts +7 -0
- package/dist/src/gateway/chat-stream/thinking-delta-coalescer.js +103 -0
- package/dist/src/gateway/hono/sse.d.ts +1 -1
- package/dist/src/gateway/hono/sse.js +1 -1
- package/dist/src/gateway/service/run-gateway-agent.js +5 -1
- package/dist/src/media/session-references.js +9 -6
- package/dist/src/session/client-history.d.ts +1 -0
- package/dist/src/session/client-history.js +56 -12
- package/dist/src/session/types.d.ts +1 -0
- package/package.json +1 -1
- package/dist/gateway/static/root/assets/index-gpwk8Nro.css +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-CJ9MbRP8.js +0 -1
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
//#region src/gateway/chat-stream/thinking-delta-coalescer.ts
|
|
2
|
+
const DEFAULT_WINDOW_MS = 24;
|
|
3
|
+
const DEFAULT_MAX_CHARS = 256;
|
|
4
|
+
function isThinkingDelta(event) {
|
|
5
|
+
return event.type === "thinking_delta";
|
|
6
|
+
}
|
|
7
|
+
function belongsToSameThinkingStream(left, right) {
|
|
8
|
+
return left.runId === right.runId && left.sessionKey === right.sessionKey && left.payload.messageId === right.payload.messageId;
|
|
9
|
+
}
|
|
10
|
+
function mergeThinkingDelta(left, right) {
|
|
11
|
+
return {
|
|
12
|
+
...left,
|
|
13
|
+
payload: {
|
|
14
|
+
...left.payload,
|
|
15
|
+
delta: left.payload.delta + right.payload.delta
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
async function nextBeforeDeadline(next, deadlineAt) {
|
|
20
|
+
let timer;
|
|
21
|
+
try {
|
|
22
|
+
return await Promise.race([next.then((result) => ({
|
|
23
|
+
kind: "next",
|
|
24
|
+
result
|
|
25
|
+
})), new Promise((resolve) => {
|
|
26
|
+
timer = setTimeout(() => resolve({ kind: "timeout" }), Math.max(0, deadlineAt - Date.now()));
|
|
27
|
+
})]);
|
|
28
|
+
} finally {
|
|
29
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
async function* coalesceThinkingDeltas(source, options = {}) {
|
|
33
|
+
const windowMs = options.windowMs ?? DEFAULT_WINDOW_MS;
|
|
34
|
+
const maxChars = options.maxChars ?? DEFAULT_MAX_CHARS;
|
|
35
|
+
if (!Number.isFinite(windowMs) || windowMs <= 0) throw new Error("thinking delta coalescer windowMs must be greater than zero");
|
|
36
|
+
if (!Number.isInteger(maxChars) || maxChars <= 0) throw new Error("thinking delta coalescer maxChars must be a positive integer");
|
|
37
|
+
const iterator = source[Symbol.asyncIterator]();
|
|
38
|
+
let next = iterator.next();
|
|
39
|
+
let pending;
|
|
40
|
+
let deadlineAt = 0;
|
|
41
|
+
try {
|
|
42
|
+
while (true) {
|
|
43
|
+
if (!pending) {
|
|
44
|
+
const result = await next;
|
|
45
|
+
if (result.done) break;
|
|
46
|
+
next = iterator.next();
|
|
47
|
+
if (!isThinkingDelta(result.value)) {
|
|
48
|
+
yield result.value;
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
pending = result.value;
|
|
52
|
+
deadlineAt = Date.now() + windowMs;
|
|
53
|
+
if (pending.payload.delta.length >= maxChars) {
|
|
54
|
+
yield pending;
|
|
55
|
+
pending = void 0;
|
|
56
|
+
}
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
const outcome = await nextBeforeDeadline(next, deadlineAt);
|
|
60
|
+
if (outcome.kind === "timeout") {
|
|
61
|
+
yield pending;
|
|
62
|
+
pending = void 0;
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
const result = outcome.result;
|
|
66
|
+
if (result.done) {
|
|
67
|
+
yield pending;
|
|
68
|
+
pending = void 0;
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
next = iterator.next();
|
|
72
|
+
const event = result.value;
|
|
73
|
+
if (!isThinkingDelta(event) || !belongsToSameThinkingStream(pending, event)) {
|
|
74
|
+
yield pending;
|
|
75
|
+
pending = void 0;
|
|
76
|
+
if (isThinkingDelta(event)) {
|
|
77
|
+
pending = event;
|
|
78
|
+
deadlineAt = Date.now() + windowMs;
|
|
79
|
+
if (pending.payload.delta.length >= maxChars) {
|
|
80
|
+
yield pending;
|
|
81
|
+
pending = void 0;
|
|
82
|
+
}
|
|
83
|
+
} else yield event;
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
pending = mergeThinkingDelta(pending, event);
|
|
87
|
+
if (pending.payload.delta.length >= maxChars) {
|
|
88
|
+
yield pending;
|
|
89
|
+
pending = void 0;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
} catch (error) {
|
|
93
|
+
if (pending) {
|
|
94
|
+
yield pending;
|
|
95
|
+
pending = void 0;
|
|
96
|
+
}
|
|
97
|
+
throw error;
|
|
98
|
+
} finally {
|
|
99
|
+
await iterator.return?.();
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
//#endregion
|
|
103
|
+
export { coalesceThinkingDeltas };
|
|
@@ -23,7 +23,7 @@ export declare function createAgentSSEHandler(config: SSEHandlerConfig): (c: Con
|
|
|
23
23
|
* POST /api/agent/resume — Re-attach to an in-progress agent run via SSE.
|
|
24
24
|
*
|
|
25
25
|
* Request body: { runId, sessionKey }
|
|
26
|
-
* The relay replays
|
|
26
|
+
* The relay replays retained buffered events from the beginning and then live-tails
|
|
27
27
|
* until the run completes.
|
|
28
28
|
*
|
|
29
29
|
* SSE events are identical to those from POST /api/agent.
|
|
@@ -168,7 +168,7 @@ function createAgentSSEHandler(config) {
|
|
|
168
168
|
* POST /api/agent/resume — Re-attach to an in-progress agent run via SSE.
|
|
169
169
|
*
|
|
170
170
|
* Request body: { runId, sessionKey }
|
|
171
|
-
* The relay replays
|
|
171
|
+
* The relay replays retained buffered events from the beginning and then live-tails
|
|
172
172
|
* until the run completes.
|
|
173
173
|
*
|
|
174
174
|
* SSE events are identical to those from POST /api/agent.
|
|
@@ -7,6 +7,7 @@ import { shouldSkipWebchatInboundByAbortCutoff } from "../../session/abort-cutof
|
|
|
7
7
|
import "../chat-limits.js";
|
|
8
8
|
import { resolveWebchatSessionKey } from "../resolve-webchat-session-key.js";
|
|
9
9
|
import { ChatStreamMapper } from "../chat-stream/mapper.js";
|
|
10
|
+
import { coalesceThinkingDeltas } from "../chat-stream/thinking-delta-coalescer.js";
|
|
10
11
|
import crypto from "crypto";
|
|
11
12
|
//#region src/gateway/service/run-gateway-agent.ts
|
|
12
13
|
init_logger();
|
|
@@ -90,7 +91,10 @@ async function* runGatewayAgent(deps, message, channel, chatId, attachments, thi
|
|
|
90
91
|
signal: mergedSignal,
|
|
91
92
|
runId
|
|
92
93
|
});
|
|
93
|
-
|
|
94
|
+
const mappedEvents = (async function* () {
|
|
95
|
+
for await (const event of eventStream) yield* mapper.map(event);
|
|
96
|
+
})();
|
|
97
|
+
for await (const event of coalesceThinkingDeltas(mappedEvents)) yield* emitAndYield([event]);
|
|
94
98
|
const endStatus = mergedSignal.aborted ? "cancelled" : "success";
|
|
95
99
|
const endSummary = mergedSignal.aborted ? "Interrupted" : "Message processed successfully";
|
|
96
100
|
yield* emitAndYield(mapper.end(endStatus, endSummary));
|
|
@@ -1,25 +1,28 @@
|
|
|
1
1
|
import { tryParseMediaUri } from "./uri.js";
|
|
2
2
|
import { deleteMediaBuffer } from "./store.js";
|
|
3
3
|
//#region src/media/session-references.ts
|
|
4
|
-
function collectFromValue(value, out) {
|
|
4
|
+
function collectFromValue(value, out, seen) {
|
|
5
5
|
if (!value) return;
|
|
6
6
|
if (typeof value === "string") {
|
|
7
7
|
if (value.startsWith("media://")) out.add(value.trim());
|
|
8
8
|
return;
|
|
9
9
|
}
|
|
10
10
|
if (Array.isArray(value)) {
|
|
11
|
-
|
|
11
|
+
if (seen.has(value)) return;
|
|
12
|
+
seen.add(value);
|
|
13
|
+
for (const item of value) collectFromValue(item, out, seen);
|
|
12
14
|
return;
|
|
13
15
|
}
|
|
14
16
|
if (typeof value !== "object") return;
|
|
17
|
+
if (seen.has(value)) return;
|
|
18
|
+
seen.add(value);
|
|
15
19
|
const record = value;
|
|
16
|
-
|
|
17
|
-
if (Array.isArray(record.media)) collectFromValue(record.media, out);
|
|
18
|
-
if (Array.isArray(record.attachments)) collectFromValue(record.attachments, out);
|
|
20
|
+
for (const nested of Object.values(record)) collectFromValue(nested, out, seen);
|
|
19
21
|
}
|
|
20
22
|
function collectMediaUrisFromMessages(messages) {
|
|
21
23
|
const out = /* @__PURE__ */ new Set();
|
|
22
|
-
|
|
24
|
+
const seen = /* @__PURE__ */ new WeakSet();
|
|
25
|
+
for (const message of messages) collectFromValue(message, out, seen);
|
|
23
26
|
return out;
|
|
24
27
|
}
|
|
25
28
|
function messagesReferenceMediaUri(messages, uri) {
|
|
@@ -33,22 +33,65 @@ function collectToolResults(messages) {
|
|
|
33
33
|
if (!id || typeof id !== "string") continue;
|
|
34
34
|
map.set(id, {
|
|
35
35
|
text: flattenMessageContent(m.content),
|
|
36
|
-
isError: m.isError
|
|
36
|
+
isError: m.isError,
|
|
37
|
+
details: m.details
|
|
37
38
|
});
|
|
38
39
|
}
|
|
39
40
|
return map;
|
|
40
41
|
}
|
|
41
|
-
function
|
|
42
|
-
if (!tool_calls?.length) return void 0;
|
|
42
|
+
function collectMessageToolCalls(content, openAiToolCalls, rawToolCalls) {
|
|
43
43
|
const out = [];
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
const seen = /* @__PURE__ */ new Set();
|
|
45
|
+
const add = (call) => {
|
|
46
|
+
const key = call.id ? `id:${call.id}` : `position:${out.length}`;
|
|
47
|
+
if (seen.has(key)) return;
|
|
48
|
+
seen.add(key);
|
|
49
|
+
out.push(call);
|
|
50
|
+
};
|
|
51
|
+
for (const call of openAiToolCalls ?? []) add({
|
|
52
|
+
id: call.id,
|
|
53
|
+
name: call.function.name,
|
|
54
|
+
args: safeJsonParseArguments(call.function.arguments)
|
|
55
|
+
});
|
|
56
|
+
for (const item of Array.isArray(rawToolCalls) ? rawToolCalls : []) {
|
|
57
|
+
if (!item || typeof item !== "object") continue;
|
|
58
|
+
const call = item;
|
|
59
|
+
const name = typeof call.name === "string" ? call.name : void 0;
|
|
60
|
+
if (!name) continue;
|
|
61
|
+
add({
|
|
62
|
+
id: typeof call.id === "string" ? call.id : void 0,
|
|
63
|
+
name,
|
|
64
|
+
args: call.args ?? call.arguments ?? call.input
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
for (const item of Array.isArray(content) ? content : []) {
|
|
68
|
+
if (!item || typeof item !== "object") continue;
|
|
69
|
+
const call = item;
|
|
70
|
+
if (call.type !== "toolCall" && call.type !== "tool_use" && call.type !== "tool_call") continue;
|
|
71
|
+
const fn = call.function && typeof call.function === "object" ? call.function : void 0;
|
|
72
|
+
const name = typeof call.name === "string" ? call.name : typeof fn?.name === "string" ? fn.name : void 0;
|
|
73
|
+
if (!name) continue;
|
|
74
|
+
const rawArgs = call.arguments ?? call.args ?? call.input ?? fn?.arguments;
|
|
75
|
+
add({
|
|
76
|
+
id: typeof call.id === "string" ? call.id : void 0,
|
|
77
|
+
name,
|
|
78
|
+
args: typeof rawArgs === "string" ? safeJsonParseArguments(rawArgs) : rawArgs
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
return out.length ? out : void 0;
|
|
82
|
+
}
|
|
83
|
+
function toolCallsWithResults(toolCalls, results) {
|
|
84
|
+
if (!toolCalls?.length) return void 0;
|
|
85
|
+
const out = [];
|
|
86
|
+
for (const call of toolCalls) {
|
|
87
|
+
const res = call.id ? results.get(call.id) : void 0;
|
|
46
88
|
out.push({
|
|
47
|
-
id:
|
|
48
|
-
name:
|
|
49
|
-
args:
|
|
89
|
+
id: call.id,
|
|
90
|
+
name: call.name,
|
|
91
|
+
args: call.args,
|
|
50
92
|
result: res?.text,
|
|
51
|
-
isError: res?.isError
|
|
93
|
+
isError: res?.isError,
|
|
94
|
+
details: res?.details
|
|
52
95
|
});
|
|
53
96
|
}
|
|
54
97
|
return out.length ? out : void 0;
|
|
@@ -74,7 +117,7 @@ function messagesToClientHistory(messages, opts) {
|
|
|
74
117
|
}
|
|
75
118
|
if (m.role === "assistant") {
|
|
76
119
|
const text = flattenMessageContent(m.content);
|
|
77
|
-
const toolCalls = toolCallsWithResults(m.tool_calls, results);
|
|
120
|
+
const toolCalls = toolCallsWithResults(collectMessageToolCalls(m.content, m.tool_calls), results);
|
|
78
121
|
out.push({
|
|
79
122
|
role: "assistant",
|
|
80
123
|
content: text,
|
|
@@ -108,7 +151,8 @@ function collectHistoryToolResults(messages) {
|
|
|
108
151
|
if (!id || typeof id !== "string") continue;
|
|
109
152
|
map.set(id, {
|
|
110
153
|
text: flattenMessageContent(m.content ?? ""),
|
|
111
|
-
isError: m.isError
|
|
154
|
+
isError: m.isError,
|
|
155
|
+
details: m.details
|
|
112
156
|
});
|
|
113
157
|
}
|
|
114
158
|
return map;
|
|
@@ -380,7 +424,7 @@ function transcriptRowsToClientHistory(rows, opts) {
|
|
|
380
424
|
...rawContent ? { rawContent } : {},
|
|
381
425
|
...displayIndex !== void 0 ? { displayIndex } : {},
|
|
382
426
|
timestamp: parseTimestampValue(messageRow.timestamp),
|
|
383
|
-
toolCalls: toolCallsWithResults(messageRow.tool_calls
|
|
427
|
+
toolCalls: toolCallsWithResults(collectMessageToolCalls(messageRow.content, messageRow.tool_calls, messageRow.toolCalls), results)
|
|
384
428
|
});
|
|
385
429
|
}
|
|
386
430
|
return out;
|
package/package.json
CHANGED