@anuma/sdk 6.27.0 → 6.27.1
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/expo/index.cjs +73 -30
- package/dist/expo/index.mjs +71 -30
- package/dist/react/index.cjs +153 -110
- package/dist/react/index.mjs +151 -110
- package/dist/server/index.cjs +66 -1
- package/dist/server/index.mjs +66 -1
- package/package.json +1 -1
package/dist/expo/index.cjs
CHANGED
|
@@ -5534,6 +5534,36 @@ init_clientConfig();
|
|
|
5534
5534
|
// src/lib/chat/toolLoop.ts
|
|
5535
5535
|
init_clientConfig();
|
|
5536
5536
|
init_redactor();
|
|
5537
|
+
|
|
5538
|
+
// src/lib/storage/mcpImages.ts
|
|
5539
|
+
var IMAGE_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
5540
|
+
"AnumaMediaMCP-anuma_create_image",
|
|
5541
|
+
"anuma_create_image",
|
|
5542
|
+
// Deprecated anuma-image-mcp tools, retained so images in already-stored
|
|
5543
|
+
// conversations still re-materialize on replay.
|
|
5544
|
+
"AnumaImageMCP-generate_cloud_image",
|
|
5545
|
+
"AnumaImageMCP-edit_cloud_image",
|
|
5546
|
+
"generate_cloud_image",
|
|
5547
|
+
"edit_cloud_image"
|
|
5548
|
+
]);
|
|
5549
|
+
function toolOutputForModel(name, output) {
|
|
5550
|
+
if (!name || !IMAGE_TOOL_NAMES.has(name)) return output;
|
|
5551
|
+
try {
|
|
5552
|
+
const {
|
|
5553
|
+
imageUrl: _imageUrl,
|
|
5554
|
+
url: _url,
|
|
5555
|
+
output_images: _outputImages,
|
|
5556
|
+
...rest
|
|
5557
|
+
} = JSON.parse(output);
|
|
5558
|
+
return JSON.stringify(rest);
|
|
5559
|
+
} catch {
|
|
5560
|
+
return output;
|
|
5561
|
+
}
|
|
5562
|
+
}
|
|
5563
|
+
var VIDEO_EXTENSIONS = ["mp4", "webm", "mov"];
|
|
5564
|
+
var VIDEO_EXTENSION_RE = new RegExp(`\\.(${VIDEO_EXTENSIONS.join("|")})(?:[?#]|$)`, "i");
|
|
5565
|
+
|
|
5566
|
+
// src/lib/chat/toolLoop.ts
|
|
5537
5567
|
init_endpointOverride();
|
|
5538
5568
|
|
|
5539
5569
|
// src/lib/chat/runHooks.ts
|
|
@@ -7667,6 +7697,40 @@ function extractLastUserText(messages) {
|
|
|
7667
7697
|
function isToolErrorResult(result) {
|
|
7668
7698
|
return result !== null && typeof result === "object" && "error" in result && typeof result.error === "string";
|
|
7669
7699
|
}
|
|
7700
|
+
function serverToolCallMessages(events, messages, skipIds) {
|
|
7701
|
+
const seen = new Set(skipIds);
|
|
7702
|
+
for (const m of messages) {
|
|
7703
|
+
if (m.tool_call_id) seen.add(m.tool_call_id);
|
|
7704
|
+
for (const tc of m.tool_calls ?? []) if (tc.id) seen.add(tc.id);
|
|
7705
|
+
}
|
|
7706
|
+
const executed = [];
|
|
7707
|
+
for (const event of events ?? []) {
|
|
7708
|
+
if (!event.id || event.output === void 0 || event.output === null || seen.has(event.id)) {
|
|
7709
|
+
continue;
|
|
7710
|
+
}
|
|
7711
|
+
seen.add(event.id);
|
|
7712
|
+
executed.push(event);
|
|
7713
|
+
}
|
|
7714
|
+
if (executed.length === 0) return [];
|
|
7715
|
+
return [
|
|
7716
|
+
{
|
|
7717
|
+
role: "assistant",
|
|
7718
|
+
content: void 0,
|
|
7719
|
+
tool_calls: executed.map((event) => ({
|
|
7720
|
+
id: event.id,
|
|
7721
|
+
type: "function",
|
|
7722
|
+
function: { name: event.name, arguments: event.arguments }
|
|
7723
|
+
}))
|
|
7724
|
+
},
|
|
7725
|
+
...executed.map(
|
|
7726
|
+
(event) => ({
|
|
7727
|
+
role: "tool",
|
|
7728
|
+
tool_call_id: event.id,
|
|
7729
|
+
content: [{ type: "text", text: toolOutputForModel(event.name, event.output ?? "") }]
|
|
7730
|
+
})
|
|
7731
|
+
)
|
|
7732
|
+
];
|
|
7733
|
+
}
|
|
7670
7734
|
function getToolName(tool) {
|
|
7671
7735
|
const func = tool.function;
|
|
7672
7736
|
const nestedName = func?.name;
|
|
@@ -8436,7 +8500,14 @@ Executing tool: ${toolInfo}
|
|
|
8436
8500
|
}
|
|
8437
8501
|
}))
|
|
8438
8502
|
};
|
|
8439
|
-
const toolResultMessages = [
|
|
8503
|
+
const toolResultMessages = [
|
|
8504
|
+
...serverToolCallMessages(
|
|
8505
|
+
currentAccumulator.toolCallEvents,
|
|
8506
|
+
currentMessages,
|
|
8507
|
+
new Set(toolCallsToExecute.map((tc) => tc.id))
|
|
8508
|
+
),
|
|
8509
|
+
assistantMessage
|
|
8510
|
+
];
|
|
8440
8511
|
for (const execResult of continueResults) {
|
|
8441
8512
|
const resultContent = execResult.error ? `Error: ${execResult.error}` : safeJsonStringify(execResult.result);
|
|
8442
8513
|
toolResultMessages.push({
|
|
@@ -10631,20 +10702,6 @@ function generateMediaId() {
|
|
|
10631
10702
|
// src/lib/db/media/operations.ts
|
|
10632
10703
|
var import_watermelondb7 = require("@nozbe/watermelondb");
|
|
10633
10704
|
|
|
10634
|
-
// src/lib/storage/mcpImages.ts
|
|
10635
|
-
var IMAGE_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
10636
|
-
"AnumaMediaMCP-anuma_create_image",
|
|
10637
|
-
"anuma_create_image",
|
|
10638
|
-
// Deprecated anuma-image-mcp tools, retained so images in already-stored
|
|
10639
|
-
// conversations still re-materialize on replay.
|
|
10640
|
-
"AnumaImageMCP-generate_cloud_image",
|
|
10641
|
-
"AnumaImageMCP-edit_cloud_image",
|
|
10642
|
-
"generate_cloud_image",
|
|
10643
|
-
"edit_cloud_image"
|
|
10644
|
-
]);
|
|
10645
|
-
var VIDEO_EXTENSIONS = ["mp4", "webm", "mov"];
|
|
10646
|
-
var VIDEO_EXTENSION_RE = new RegExp(`\\.(${VIDEO_EXTENSIONS.join("|")})(?:[?#]|$)`, "i");
|
|
10647
|
-
|
|
10648
10705
|
// src/lib/storage/opfs.ts
|
|
10649
10706
|
function isOPFSSupported() {
|
|
10650
10707
|
return typeof navigator !== "undefined" && "storage" in navigator && "getDirectory" in navigator.storage;
|
|
@@ -21190,24 +21247,10 @@ function storedToLlmapiMessage(stored) {
|
|
|
21190
21247
|
});
|
|
21191
21248
|
for (const event of stored.toolCallEvents) {
|
|
21192
21249
|
if (event.id && event.output !== void 0 && event.output !== null) {
|
|
21193
|
-
let toolOutput = event.output;
|
|
21194
|
-
if (event.name && IMAGE_TOOL_NAMES.has(event.name)) {
|
|
21195
|
-
try {
|
|
21196
|
-
const parsed = JSON.parse(toolOutput);
|
|
21197
|
-
const {
|
|
21198
|
-
imageUrl: _imageUrl,
|
|
21199
|
-
url: _url,
|
|
21200
|
-
output_images: _outputImages,
|
|
21201
|
-
...rest
|
|
21202
|
-
} = parsed;
|
|
21203
|
-
toolOutput = JSON.stringify(rest);
|
|
21204
|
-
} catch {
|
|
21205
|
-
}
|
|
21206
|
-
}
|
|
21207
21250
|
messages.push({
|
|
21208
21251
|
role: "tool",
|
|
21209
21252
|
tool_call_id: event.id,
|
|
21210
|
-
content: [{ type: "text", text:
|
|
21253
|
+
content: [{ type: "text", text: toolOutputForModel(event.name, event.output) }]
|
|
21211
21254
|
});
|
|
21212
21255
|
}
|
|
21213
21256
|
}
|
package/dist/expo/index.mjs
CHANGED
|
@@ -3937,6 +3937,34 @@ function createWebSearchPreProcessor(options = {}) {
|
|
|
3937
3937
|
};
|
|
3938
3938
|
}
|
|
3939
3939
|
|
|
3940
|
+
// src/lib/storage/mcpImages.ts
|
|
3941
|
+
var IMAGE_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
3942
|
+
"AnumaMediaMCP-anuma_create_image",
|
|
3943
|
+
"anuma_create_image",
|
|
3944
|
+
// Deprecated anuma-image-mcp tools, retained so images in already-stored
|
|
3945
|
+
// conversations still re-materialize on replay.
|
|
3946
|
+
"AnumaImageMCP-generate_cloud_image",
|
|
3947
|
+
"AnumaImageMCP-edit_cloud_image",
|
|
3948
|
+
"generate_cloud_image",
|
|
3949
|
+
"edit_cloud_image"
|
|
3950
|
+
]);
|
|
3951
|
+
function toolOutputForModel(name, output) {
|
|
3952
|
+
if (!name || !IMAGE_TOOL_NAMES.has(name)) return output;
|
|
3953
|
+
try {
|
|
3954
|
+
const {
|
|
3955
|
+
imageUrl: _imageUrl,
|
|
3956
|
+
url: _url,
|
|
3957
|
+
output_images: _outputImages,
|
|
3958
|
+
...rest
|
|
3959
|
+
} = JSON.parse(output);
|
|
3960
|
+
return JSON.stringify(rest);
|
|
3961
|
+
} catch {
|
|
3962
|
+
return output;
|
|
3963
|
+
}
|
|
3964
|
+
}
|
|
3965
|
+
var VIDEO_EXTENSIONS = ["mp4", "webm", "mov"];
|
|
3966
|
+
var VIDEO_EXTENSION_RE = new RegExp(`\\.(${VIDEO_EXTENSIONS.join("|")})(?:[?#]|$)`, "i");
|
|
3967
|
+
|
|
3940
3968
|
// src/lib/chat/runHooks.ts
|
|
3941
3969
|
function composeHooks(hooks) {
|
|
3942
3970
|
const handlers = hooks.filter((h) => h !== void 0 && h !== null);
|
|
@@ -6067,6 +6095,40 @@ function extractLastUserText(messages) {
|
|
|
6067
6095
|
function isToolErrorResult(result) {
|
|
6068
6096
|
return result !== null && typeof result === "object" && "error" in result && typeof result.error === "string";
|
|
6069
6097
|
}
|
|
6098
|
+
function serverToolCallMessages(events, messages, skipIds) {
|
|
6099
|
+
const seen = new Set(skipIds);
|
|
6100
|
+
for (const m of messages) {
|
|
6101
|
+
if (m.tool_call_id) seen.add(m.tool_call_id);
|
|
6102
|
+
for (const tc of m.tool_calls ?? []) if (tc.id) seen.add(tc.id);
|
|
6103
|
+
}
|
|
6104
|
+
const executed = [];
|
|
6105
|
+
for (const event of events ?? []) {
|
|
6106
|
+
if (!event.id || event.output === void 0 || event.output === null || seen.has(event.id)) {
|
|
6107
|
+
continue;
|
|
6108
|
+
}
|
|
6109
|
+
seen.add(event.id);
|
|
6110
|
+
executed.push(event);
|
|
6111
|
+
}
|
|
6112
|
+
if (executed.length === 0) return [];
|
|
6113
|
+
return [
|
|
6114
|
+
{
|
|
6115
|
+
role: "assistant",
|
|
6116
|
+
content: void 0,
|
|
6117
|
+
tool_calls: executed.map((event) => ({
|
|
6118
|
+
id: event.id,
|
|
6119
|
+
type: "function",
|
|
6120
|
+
function: { name: event.name, arguments: event.arguments }
|
|
6121
|
+
}))
|
|
6122
|
+
},
|
|
6123
|
+
...executed.map(
|
|
6124
|
+
(event) => ({
|
|
6125
|
+
role: "tool",
|
|
6126
|
+
tool_call_id: event.id,
|
|
6127
|
+
content: [{ type: "text", text: toolOutputForModel(event.name, event.output ?? "") }]
|
|
6128
|
+
})
|
|
6129
|
+
)
|
|
6130
|
+
];
|
|
6131
|
+
}
|
|
6070
6132
|
function getToolName(tool) {
|
|
6071
6133
|
const func = tool.function;
|
|
6072
6134
|
const nestedName = func?.name;
|
|
@@ -6836,7 +6898,14 @@ Executing tool: ${toolInfo}
|
|
|
6836
6898
|
}
|
|
6837
6899
|
}))
|
|
6838
6900
|
};
|
|
6839
|
-
const toolResultMessages = [
|
|
6901
|
+
const toolResultMessages = [
|
|
6902
|
+
...serverToolCallMessages(
|
|
6903
|
+
currentAccumulator.toolCallEvents,
|
|
6904
|
+
currentMessages,
|
|
6905
|
+
new Set(toolCallsToExecute.map((tc) => tc.id))
|
|
6906
|
+
),
|
|
6907
|
+
assistantMessage
|
|
6908
|
+
];
|
|
6840
6909
|
for (const execResult of continueResults) {
|
|
6841
6910
|
const resultContent = execResult.error ? `Error: ${execResult.error}` : safeJsonStringify(execResult.result);
|
|
6842
6911
|
toolResultMessages.push({
|
|
@@ -9019,20 +9088,6 @@ function generateMediaId() {
|
|
|
9019
9088
|
// src/lib/db/media/operations.ts
|
|
9020
9089
|
import { Q as Q3 } from "@nozbe/watermelondb";
|
|
9021
9090
|
|
|
9022
|
-
// src/lib/storage/mcpImages.ts
|
|
9023
|
-
var IMAGE_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
9024
|
-
"AnumaMediaMCP-anuma_create_image",
|
|
9025
|
-
"anuma_create_image",
|
|
9026
|
-
// Deprecated anuma-image-mcp tools, retained so images in already-stored
|
|
9027
|
-
// conversations still re-materialize on replay.
|
|
9028
|
-
"AnumaImageMCP-generate_cloud_image",
|
|
9029
|
-
"AnumaImageMCP-edit_cloud_image",
|
|
9030
|
-
"generate_cloud_image",
|
|
9031
|
-
"edit_cloud_image"
|
|
9032
|
-
]);
|
|
9033
|
-
var VIDEO_EXTENSIONS = ["mp4", "webm", "mov"];
|
|
9034
|
-
var VIDEO_EXTENSION_RE = new RegExp(`\\.(${VIDEO_EXTENSIONS.join("|")})(?:[?#]|$)`, "i");
|
|
9035
|
-
|
|
9036
9091
|
// src/lib/storage/opfs.ts
|
|
9037
9092
|
function isOPFSSupported() {
|
|
9038
9093
|
return typeof navigator !== "undefined" && "storage" in navigator && "getDirectory" in navigator.storage;
|
|
@@ -19522,24 +19577,10 @@ function storedToLlmapiMessage(stored) {
|
|
|
19522
19577
|
});
|
|
19523
19578
|
for (const event of stored.toolCallEvents) {
|
|
19524
19579
|
if (event.id && event.output !== void 0 && event.output !== null) {
|
|
19525
|
-
let toolOutput = event.output;
|
|
19526
|
-
if (event.name && IMAGE_TOOL_NAMES.has(event.name)) {
|
|
19527
|
-
try {
|
|
19528
|
-
const parsed = JSON.parse(toolOutput);
|
|
19529
|
-
const {
|
|
19530
|
-
imageUrl: _imageUrl,
|
|
19531
|
-
url: _url,
|
|
19532
|
-
output_images: _outputImages,
|
|
19533
|
-
...rest
|
|
19534
|
-
} = parsed;
|
|
19535
|
-
toolOutput = JSON.stringify(rest);
|
|
19536
|
-
} catch {
|
|
19537
|
-
}
|
|
19538
|
-
}
|
|
19539
19580
|
messages.push({
|
|
19540
19581
|
role: "tool",
|
|
19541
19582
|
tool_call_id: event.id,
|
|
19542
|
-
content: [{ type: "text", text:
|
|
19583
|
+
content: [{ type: "text", text: toolOutputForModel(event.name, event.output) }]
|
|
19543
19584
|
});
|
|
19544
19585
|
}
|
|
19545
19586
|
}
|
package/dist/react/index.cjs
CHANGED
|
@@ -5844,6 +5844,116 @@ async function chunkAndEmbedAllMessages(ctx, options, filter) {
|
|
|
5844
5844
|
|
|
5845
5845
|
// src/lib/chat/toolLoop.ts
|
|
5846
5846
|
init_redactor();
|
|
5847
|
+
|
|
5848
|
+
// src/lib/storage/mcpImages.ts
|
|
5849
|
+
var IMAGE_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
5850
|
+
"AnumaMediaMCP-anuma_create_image",
|
|
5851
|
+
"anuma_create_image",
|
|
5852
|
+
// Deprecated anuma-image-mcp tools, retained so images in already-stored
|
|
5853
|
+
// conversations still re-materialize on replay.
|
|
5854
|
+
"AnumaImageMCP-generate_cloud_image",
|
|
5855
|
+
"AnumaImageMCP-edit_cloud_image",
|
|
5856
|
+
"generate_cloud_image",
|
|
5857
|
+
"edit_cloud_image"
|
|
5858
|
+
]);
|
|
5859
|
+
function toolOutputForModel(name, output) {
|
|
5860
|
+
if (!name || !IMAGE_TOOL_NAMES.has(name)) return output;
|
|
5861
|
+
try {
|
|
5862
|
+
const {
|
|
5863
|
+
imageUrl: _imageUrl,
|
|
5864
|
+
url: _url,
|
|
5865
|
+
output_images: _outputImages,
|
|
5866
|
+
...rest
|
|
5867
|
+
} = JSON.parse(output);
|
|
5868
|
+
return JSON.stringify(rest);
|
|
5869
|
+
} catch {
|
|
5870
|
+
return output;
|
|
5871
|
+
}
|
|
5872
|
+
}
|
|
5873
|
+
var VIDEO_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
5874
|
+
"AnumaMediaMCP-anuma_create_video",
|
|
5875
|
+
"AnumaFalMCP-fal_generate_video",
|
|
5876
|
+
"anuma_create_video",
|
|
5877
|
+
"fal_generate_video"
|
|
5878
|
+
]);
|
|
5879
|
+
var VIDEO_EXTENSIONS = ["mp4", "webm", "mov"];
|
|
5880
|
+
var VIDEO_EXTENSION_RE = new RegExp(`\\.(${VIDEO_EXTENSIONS.join("|")})(?:[?#]|$)`, "i");
|
|
5881
|
+
function videoExtensionOf(value) {
|
|
5882
|
+
return value?.match(VIDEO_EXTENSION_RE)?.[1]?.toLowerCase() ?? null;
|
|
5883
|
+
}
|
|
5884
|
+
function classifyUrl(url) {
|
|
5885
|
+
return VIDEO_EXTENSION_RE.test(url) ? "video" : "image";
|
|
5886
|
+
}
|
|
5887
|
+
function extractMCPImageUrls(content, toolCallEvents, mcpR2Domain) {
|
|
5888
|
+
const urls = [];
|
|
5889
|
+
if (toolCallEvents && toolCallEvents.length > 0) {
|
|
5890
|
+
for (const event of toolCallEvents) {
|
|
5891
|
+
if (!event.name) continue;
|
|
5892
|
+
if (IMAGE_TOOL_NAMES.has(event.name)) {
|
|
5893
|
+
try {
|
|
5894
|
+
const output = JSON.parse(event.output || "{}");
|
|
5895
|
+
const model = output.model || "image";
|
|
5896
|
+
const imageUrls = [
|
|
5897
|
+
...new Set(
|
|
5898
|
+
[
|
|
5899
|
+
...output.output_images?.map((i) => i.url) ?? [],
|
|
5900
|
+
output.imageUrl,
|
|
5901
|
+
output.url
|
|
5902
|
+
].filter((u) => Boolean(u))
|
|
5903
|
+
)
|
|
5904
|
+
];
|
|
5905
|
+
for (const url of imageUrls) {
|
|
5906
|
+
urls.push({ url, model, mediaType: "image" });
|
|
5907
|
+
}
|
|
5908
|
+
} catch {
|
|
5909
|
+
}
|
|
5910
|
+
} else if (VIDEO_TOOL_NAMES.has(event.name)) {
|
|
5911
|
+
try {
|
|
5912
|
+
const output = JSON.parse(event.output || "{}");
|
|
5913
|
+
const model = output.model || "video";
|
|
5914
|
+
const videoUrls = [
|
|
5915
|
+
...new Set(
|
|
5916
|
+
[
|
|
5917
|
+
...output.videos?.map((v) => v.video_url) ?? [],
|
|
5918
|
+
output.videoUrl,
|
|
5919
|
+
output.url
|
|
5920
|
+
].filter((u) => Boolean(u))
|
|
5921
|
+
)
|
|
5922
|
+
];
|
|
5923
|
+
for (const url of videoUrls) {
|
|
5924
|
+
urls.push({ url, model, mediaType: "video" });
|
|
5925
|
+
}
|
|
5926
|
+
} catch {
|
|
5927
|
+
}
|
|
5928
|
+
}
|
|
5929
|
+
}
|
|
5930
|
+
}
|
|
5931
|
+
if (urls.length === 0 && content) {
|
|
5932
|
+
const escaped = mcpR2Domain.replace(/\./g, "\\.");
|
|
5933
|
+
const patterns = [
|
|
5934
|
+
new RegExp(`https://${escaped}[^\\s"'<>)\\]]+`, "gi"),
|
|
5935
|
+
// Require the proxy's <svc>/<token> shape (>=2 path segments after
|
|
5936
|
+
// /api/v1/media/) so a third-party URL that only shallowly contains
|
|
5937
|
+
// /api/v1/media/ isn't returned as a portal media asset.
|
|
5938
|
+
new RegExp(`https?://[^\\s"'<>)\\]]+/api/v1/media/[^/\\s"'<>)\\]]+/[^\\s"'<>)\\]]+`, "gi")
|
|
5939
|
+
];
|
|
5940
|
+
const matches = patterns.flatMap((re) => content.match(re) ?? []);
|
|
5941
|
+
if (matches.length > 0) {
|
|
5942
|
+
const seen = /* @__PURE__ */ new Set();
|
|
5943
|
+
for (const url of matches) {
|
|
5944
|
+
const normalized = url.replace(/[)"'>\s]+$/, "");
|
|
5945
|
+
if (!seen.has(normalized)) {
|
|
5946
|
+
seen.add(normalized);
|
|
5947
|
+
const mediaType = classifyUrl(normalized);
|
|
5948
|
+
urls.push({ url: normalized, model: "image", mediaType });
|
|
5949
|
+
}
|
|
5950
|
+
}
|
|
5951
|
+
}
|
|
5952
|
+
}
|
|
5953
|
+
return urls;
|
|
5954
|
+
}
|
|
5955
|
+
|
|
5956
|
+
// src/lib/chat/toolLoop.ts
|
|
5847
5957
|
init_endpointOverride();
|
|
5848
5958
|
|
|
5849
5959
|
// src/lib/chat/runHooks.ts
|
|
@@ -7977,6 +8087,40 @@ function extractLastUserText(messages) {
|
|
|
7977
8087
|
function isToolErrorResult(result) {
|
|
7978
8088
|
return result !== null && typeof result === "object" && "error" in result && typeof result.error === "string";
|
|
7979
8089
|
}
|
|
8090
|
+
function serverToolCallMessages(events, messages, skipIds) {
|
|
8091
|
+
const seen = new Set(skipIds);
|
|
8092
|
+
for (const m of messages) {
|
|
8093
|
+
if (m.tool_call_id) seen.add(m.tool_call_id);
|
|
8094
|
+
for (const tc of m.tool_calls ?? []) if (tc.id) seen.add(tc.id);
|
|
8095
|
+
}
|
|
8096
|
+
const executed = [];
|
|
8097
|
+
for (const event of events ?? []) {
|
|
8098
|
+
if (!event.id || event.output === void 0 || event.output === null || seen.has(event.id)) {
|
|
8099
|
+
continue;
|
|
8100
|
+
}
|
|
8101
|
+
seen.add(event.id);
|
|
8102
|
+
executed.push(event);
|
|
8103
|
+
}
|
|
8104
|
+
if (executed.length === 0) return [];
|
|
8105
|
+
return [
|
|
8106
|
+
{
|
|
8107
|
+
role: "assistant",
|
|
8108
|
+
content: void 0,
|
|
8109
|
+
tool_calls: executed.map((event) => ({
|
|
8110
|
+
id: event.id,
|
|
8111
|
+
type: "function",
|
|
8112
|
+
function: { name: event.name, arguments: event.arguments }
|
|
8113
|
+
}))
|
|
8114
|
+
},
|
|
8115
|
+
...executed.map(
|
|
8116
|
+
(event) => ({
|
|
8117
|
+
role: "tool",
|
|
8118
|
+
tool_call_id: event.id,
|
|
8119
|
+
content: [{ type: "text", text: toolOutputForModel(event.name, event.output ?? "") }]
|
|
8120
|
+
})
|
|
8121
|
+
)
|
|
8122
|
+
];
|
|
8123
|
+
}
|
|
7980
8124
|
function getToolName(tool) {
|
|
7981
8125
|
const func = tool.function;
|
|
7982
8126
|
const nestedName = func?.name;
|
|
@@ -8746,7 +8890,14 @@ Executing tool: ${toolInfo}
|
|
|
8746
8890
|
}
|
|
8747
8891
|
}))
|
|
8748
8892
|
};
|
|
8749
|
-
const toolResultMessages = [
|
|
8893
|
+
const toolResultMessages = [
|
|
8894
|
+
...serverToolCallMessages(
|
|
8895
|
+
currentAccumulator.toolCallEvents,
|
|
8896
|
+
currentMessages,
|
|
8897
|
+
new Set(toolCallsToExecute.map((tc) => tc.id))
|
|
8898
|
+
),
|
|
8899
|
+
assistantMessage
|
|
8900
|
+
];
|
|
8750
8901
|
for (const execResult of continueResults) {
|
|
8751
8902
|
const resultContent = execResult.error ? `Error: ${execResult.error}` : safeJsonStringify(execResult.result);
|
|
8752
8903
|
toolResultMessages.push({
|
|
@@ -11423,100 +11574,6 @@ function isSupportedMediaType(mimeType) {
|
|
|
11423
11574
|
var import_watermelondb8 = require("@nozbe/watermelondb");
|
|
11424
11575
|
init_logger();
|
|
11425
11576
|
|
|
11426
|
-
// src/lib/storage/mcpImages.ts
|
|
11427
|
-
var IMAGE_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
11428
|
-
"AnumaMediaMCP-anuma_create_image",
|
|
11429
|
-
"anuma_create_image",
|
|
11430
|
-
// Deprecated anuma-image-mcp tools, retained so images in already-stored
|
|
11431
|
-
// conversations still re-materialize on replay.
|
|
11432
|
-
"AnumaImageMCP-generate_cloud_image",
|
|
11433
|
-
"AnumaImageMCP-edit_cloud_image",
|
|
11434
|
-
"generate_cloud_image",
|
|
11435
|
-
"edit_cloud_image"
|
|
11436
|
-
]);
|
|
11437
|
-
var VIDEO_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
11438
|
-
"AnumaMediaMCP-anuma_create_video",
|
|
11439
|
-
"AnumaFalMCP-fal_generate_video",
|
|
11440
|
-
"anuma_create_video",
|
|
11441
|
-
"fal_generate_video"
|
|
11442
|
-
]);
|
|
11443
|
-
var VIDEO_EXTENSIONS = ["mp4", "webm", "mov"];
|
|
11444
|
-
var VIDEO_EXTENSION_RE = new RegExp(`\\.(${VIDEO_EXTENSIONS.join("|")})(?:[?#]|$)`, "i");
|
|
11445
|
-
function videoExtensionOf(value) {
|
|
11446
|
-
return value?.match(VIDEO_EXTENSION_RE)?.[1]?.toLowerCase() ?? null;
|
|
11447
|
-
}
|
|
11448
|
-
function classifyUrl(url) {
|
|
11449
|
-
return VIDEO_EXTENSION_RE.test(url) ? "video" : "image";
|
|
11450
|
-
}
|
|
11451
|
-
function extractMCPImageUrls(content, toolCallEvents, mcpR2Domain) {
|
|
11452
|
-
const urls = [];
|
|
11453
|
-
if (toolCallEvents && toolCallEvents.length > 0) {
|
|
11454
|
-
for (const event of toolCallEvents) {
|
|
11455
|
-
if (!event.name) continue;
|
|
11456
|
-
if (IMAGE_TOOL_NAMES.has(event.name)) {
|
|
11457
|
-
try {
|
|
11458
|
-
const output = JSON.parse(event.output || "{}");
|
|
11459
|
-
const model = output.model || "image";
|
|
11460
|
-
const imageUrls = [
|
|
11461
|
-
...new Set(
|
|
11462
|
-
[
|
|
11463
|
-
...output.output_images?.map((i) => i.url) ?? [],
|
|
11464
|
-
output.imageUrl,
|
|
11465
|
-
output.url
|
|
11466
|
-
].filter((u) => Boolean(u))
|
|
11467
|
-
)
|
|
11468
|
-
];
|
|
11469
|
-
for (const url of imageUrls) {
|
|
11470
|
-
urls.push({ url, model, mediaType: "image" });
|
|
11471
|
-
}
|
|
11472
|
-
} catch {
|
|
11473
|
-
}
|
|
11474
|
-
} else if (VIDEO_TOOL_NAMES.has(event.name)) {
|
|
11475
|
-
try {
|
|
11476
|
-
const output = JSON.parse(event.output || "{}");
|
|
11477
|
-
const model = output.model || "video";
|
|
11478
|
-
const videoUrls = [
|
|
11479
|
-
...new Set(
|
|
11480
|
-
[
|
|
11481
|
-
...output.videos?.map((v) => v.video_url) ?? [],
|
|
11482
|
-
output.videoUrl,
|
|
11483
|
-
output.url
|
|
11484
|
-
].filter((u) => Boolean(u))
|
|
11485
|
-
)
|
|
11486
|
-
];
|
|
11487
|
-
for (const url of videoUrls) {
|
|
11488
|
-
urls.push({ url, model, mediaType: "video" });
|
|
11489
|
-
}
|
|
11490
|
-
} catch {
|
|
11491
|
-
}
|
|
11492
|
-
}
|
|
11493
|
-
}
|
|
11494
|
-
}
|
|
11495
|
-
if (urls.length === 0 && content) {
|
|
11496
|
-
const escaped = mcpR2Domain.replace(/\./g, "\\.");
|
|
11497
|
-
const patterns = [
|
|
11498
|
-
new RegExp(`https://${escaped}[^\\s"'<>)\\]]+`, "gi"),
|
|
11499
|
-
// Require the proxy's <svc>/<token> shape (>=2 path segments after
|
|
11500
|
-
// /api/v1/media/) so a third-party URL that only shallowly contains
|
|
11501
|
-
// /api/v1/media/ isn't returned as a portal media asset.
|
|
11502
|
-
new RegExp(`https?://[^\\s"'<>)\\]]+/api/v1/media/[^/\\s"'<>)\\]]+/[^\\s"'<>)\\]]+`, "gi")
|
|
11503
|
-
];
|
|
11504
|
-
const matches = patterns.flatMap((re) => content.match(re) ?? []);
|
|
11505
|
-
if (matches.length > 0) {
|
|
11506
|
-
const seen = /* @__PURE__ */ new Set();
|
|
11507
|
-
for (const url of matches) {
|
|
11508
|
-
const normalized = url.replace(/[)"'>\s]+$/, "");
|
|
11509
|
-
if (!seen.has(normalized)) {
|
|
11510
|
-
seen.add(normalized);
|
|
11511
|
-
const mediaType = classifyUrl(normalized);
|
|
11512
|
-
urls.push({ url: normalized, model: "image", mediaType });
|
|
11513
|
-
}
|
|
11514
|
-
}
|
|
11515
|
-
}
|
|
11516
|
-
}
|
|
11517
|
-
return urls;
|
|
11518
|
-
}
|
|
11519
|
-
|
|
11520
11577
|
// src/lib/storage/opfs.ts
|
|
11521
11578
|
init_logger();
|
|
11522
11579
|
var FILE_PLACEHOLDER_PREFIX = "__SDKFILE__";
|
|
@@ -23976,24 +24033,10 @@ async function storedToLlmapiMessage(stored, encryptionKey, resolveMediaByIds) {
|
|
|
23976
24033
|
});
|
|
23977
24034
|
for (const event of stored.toolCallEvents) {
|
|
23978
24035
|
if (event.id && event.output !== void 0 && event.output !== null) {
|
|
23979
|
-
let toolOutput = event.output;
|
|
23980
|
-
if (event.name && IMAGE_TOOL_NAMES.has(event.name)) {
|
|
23981
|
-
try {
|
|
23982
|
-
const parsed = JSON.parse(toolOutput);
|
|
23983
|
-
const {
|
|
23984
|
-
imageUrl: _imageUrl,
|
|
23985
|
-
url: _url,
|
|
23986
|
-
output_images: _outputImages,
|
|
23987
|
-
...rest
|
|
23988
|
-
} = parsed;
|
|
23989
|
-
toolOutput = JSON.stringify(rest);
|
|
23990
|
-
} catch {
|
|
23991
|
-
}
|
|
23992
|
-
}
|
|
23993
24036
|
messages.push({
|
|
23994
24037
|
role: "tool",
|
|
23995
24038
|
tool_call_id: event.id,
|
|
23996
|
-
content: [{ type: "text", text:
|
|
24039
|
+
content: [{ type: "text", text: toolOutputForModel(event.name, event.output) }]
|
|
23997
24040
|
});
|
|
23998
24041
|
}
|
|
23999
24042
|
}
|
package/dist/react/index.mjs
CHANGED
|
@@ -3986,6 +3986,114 @@ async function chunkAndEmbedAllMessages(ctx, options, filter) {
|
|
|
3986
3986
|
return embeddedCount;
|
|
3987
3987
|
}
|
|
3988
3988
|
|
|
3989
|
+
// src/lib/storage/mcpImages.ts
|
|
3990
|
+
var IMAGE_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
3991
|
+
"AnumaMediaMCP-anuma_create_image",
|
|
3992
|
+
"anuma_create_image",
|
|
3993
|
+
// Deprecated anuma-image-mcp tools, retained so images in already-stored
|
|
3994
|
+
// conversations still re-materialize on replay.
|
|
3995
|
+
"AnumaImageMCP-generate_cloud_image",
|
|
3996
|
+
"AnumaImageMCP-edit_cloud_image",
|
|
3997
|
+
"generate_cloud_image",
|
|
3998
|
+
"edit_cloud_image"
|
|
3999
|
+
]);
|
|
4000
|
+
function toolOutputForModel(name, output) {
|
|
4001
|
+
if (!name || !IMAGE_TOOL_NAMES.has(name)) return output;
|
|
4002
|
+
try {
|
|
4003
|
+
const {
|
|
4004
|
+
imageUrl: _imageUrl,
|
|
4005
|
+
url: _url,
|
|
4006
|
+
output_images: _outputImages,
|
|
4007
|
+
...rest
|
|
4008
|
+
} = JSON.parse(output);
|
|
4009
|
+
return JSON.stringify(rest);
|
|
4010
|
+
} catch {
|
|
4011
|
+
return output;
|
|
4012
|
+
}
|
|
4013
|
+
}
|
|
4014
|
+
var VIDEO_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
4015
|
+
"AnumaMediaMCP-anuma_create_video",
|
|
4016
|
+
"AnumaFalMCP-fal_generate_video",
|
|
4017
|
+
"anuma_create_video",
|
|
4018
|
+
"fal_generate_video"
|
|
4019
|
+
]);
|
|
4020
|
+
var VIDEO_EXTENSIONS = ["mp4", "webm", "mov"];
|
|
4021
|
+
var VIDEO_EXTENSION_RE = new RegExp(`\\.(${VIDEO_EXTENSIONS.join("|")})(?:[?#]|$)`, "i");
|
|
4022
|
+
function videoExtensionOf(value) {
|
|
4023
|
+
return value?.match(VIDEO_EXTENSION_RE)?.[1]?.toLowerCase() ?? null;
|
|
4024
|
+
}
|
|
4025
|
+
function classifyUrl(url) {
|
|
4026
|
+
return VIDEO_EXTENSION_RE.test(url) ? "video" : "image";
|
|
4027
|
+
}
|
|
4028
|
+
function extractMCPImageUrls(content, toolCallEvents, mcpR2Domain) {
|
|
4029
|
+
const urls = [];
|
|
4030
|
+
if (toolCallEvents && toolCallEvents.length > 0) {
|
|
4031
|
+
for (const event of toolCallEvents) {
|
|
4032
|
+
if (!event.name) continue;
|
|
4033
|
+
if (IMAGE_TOOL_NAMES.has(event.name)) {
|
|
4034
|
+
try {
|
|
4035
|
+
const output = JSON.parse(event.output || "{}");
|
|
4036
|
+
const model = output.model || "image";
|
|
4037
|
+
const imageUrls = [
|
|
4038
|
+
...new Set(
|
|
4039
|
+
[
|
|
4040
|
+
...output.output_images?.map((i) => i.url) ?? [],
|
|
4041
|
+
output.imageUrl,
|
|
4042
|
+
output.url
|
|
4043
|
+
].filter((u) => Boolean(u))
|
|
4044
|
+
)
|
|
4045
|
+
];
|
|
4046
|
+
for (const url of imageUrls) {
|
|
4047
|
+
urls.push({ url, model, mediaType: "image" });
|
|
4048
|
+
}
|
|
4049
|
+
} catch {
|
|
4050
|
+
}
|
|
4051
|
+
} else if (VIDEO_TOOL_NAMES.has(event.name)) {
|
|
4052
|
+
try {
|
|
4053
|
+
const output = JSON.parse(event.output || "{}");
|
|
4054
|
+
const model = output.model || "video";
|
|
4055
|
+
const videoUrls = [
|
|
4056
|
+
...new Set(
|
|
4057
|
+
[
|
|
4058
|
+
...output.videos?.map((v) => v.video_url) ?? [],
|
|
4059
|
+
output.videoUrl,
|
|
4060
|
+
output.url
|
|
4061
|
+
].filter((u) => Boolean(u))
|
|
4062
|
+
)
|
|
4063
|
+
];
|
|
4064
|
+
for (const url of videoUrls) {
|
|
4065
|
+
urls.push({ url, model, mediaType: "video" });
|
|
4066
|
+
}
|
|
4067
|
+
} catch {
|
|
4068
|
+
}
|
|
4069
|
+
}
|
|
4070
|
+
}
|
|
4071
|
+
}
|
|
4072
|
+
if (urls.length === 0 && content) {
|
|
4073
|
+
const escaped = mcpR2Domain.replace(/\./g, "\\.");
|
|
4074
|
+
const patterns = [
|
|
4075
|
+
new RegExp(`https://${escaped}[^\\s"'<>)\\]]+`, "gi"),
|
|
4076
|
+
// Require the proxy's <svc>/<token> shape (>=2 path segments after
|
|
4077
|
+
// /api/v1/media/) so a third-party URL that only shallowly contains
|
|
4078
|
+
// /api/v1/media/ isn't returned as a portal media asset.
|
|
4079
|
+
new RegExp(`https?://[^\\s"'<>)\\]]+/api/v1/media/[^/\\s"'<>)\\]]+/[^\\s"'<>)\\]]+`, "gi")
|
|
4080
|
+
];
|
|
4081
|
+
const matches = patterns.flatMap((re) => content.match(re) ?? []);
|
|
4082
|
+
if (matches.length > 0) {
|
|
4083
|
+
const seen = /* @__PURE__ */ new Set();
|
|
4084
|
+
for (const url of matches) {
|
|
4085
|
+
const normalized = url.replace(/[)"'>\s]+$/, "");
|
|
4086
|
+
if (!seen.has(normalized)) {
|
|
4087
|
+
seen.add(normalized);
|
|
4088
|
+
const mediaType = classifyUrl(normalized);
|
|
4089
|
+
urls.push({ url: normalized, model: "image", mediaType });
|
|
4090
|
+
}
|
|
4091
|
+
}
|
|
4092
|
+
}
|
|
4093
|
+
}
|
|
4094
|
+
return urls;
|
|
4095
|
+
}
|
|
4096
|
+
|
|
3989
4097
|
// src/lib/chat/runHooks.ts
|
|
3990
4098
|
function composeHooks(hooks) {
|
|
3991
4099
|
const handlers = hooks.filter((h) => h !== void 0 && h !== null);
|
|
@@ -6116,6 +6224,40 @@ function extractLastUserText(messages) {
|
|
|
6116
6224
|
function isToolErrorResult(result) {
|
|
6117
6225
|
return result !== null && typeof result === "object" && "error" in result && typeof result.error === "string";
|
|
6118
6226
|
}
|
|
6227
|
+
function serverToolCallMessages(events, messages, skipIds) {
|
|
6228
|
+
const seen = new Set(skipIds);
|
|
6229
|
+
for (const m of messages) {
|
|
6230
|
+
if (m.tool_call_id) seen.add(m.tool_call_id);
|
|
6231
|
+
for (const tc of m.tool_calls ?? []) if (tc.id) seen.add(tc.id);
|
|
6232
|
+
}
|
|
6233
|
+
const executed = [];
|
|
6234
|
+
for (const event of events ?? []) {
|
|
6235
|
+
if (!event.id || event.output === void 0 || event.output === null || seen.has(event.id)) {
|
|
6236
|
+
continue;
|
|
6237
|
+
}
|
|
6238
|
+
seen.add(event.id);
|
|
6239
|
+
executed.push(event);
|
|
6240
|
+
}
|
|
6241
|
+
if (executed.length === 0) return [];
|
|
6242
|
+
return [
|
|
6243
|
+
{
|
|
6244
|
+
role: "assistant",
|
|
6245
|
+
content: void 0,
|
|
6246
|
+
tool_calls: executed.map((event) => ({
|
|
6247
|
+
id: event.id,
|
|
6248
|
+
type: "function",
|
|
6249
|
+
function: { name: event.name, arguments: event.arguments }
|
|
6250
|
+
}))
|
|
6251
|
+
},
|
|
6252
|
+
...executed.map(
|
|
6253
|
+
(event) => ({
|
|
6254
|
+
role: "tool",
|
|
6255
|
+
tool_call_id: event.id,
|
|
6256
|
+
content: [{ type: "text", text: toolOutputForModel(event.name, event.output ?? "") }]
|
|
6257
|
+
})
|
|
6258
|
+
)
|
|
6259
|
+
];
|
|
6260
|
+
}
|
|
6119
6261
|
function getToolName(tool) {
|
|
6120
6262
|
const func = tool.function;
|
|
6121
6263
|
const nestedName = func?.name;
|
|
@@ -6885,7 +7027,14 @@ Executing tool: ${toolInfo}
|
|
|
6885
7027
|
}
|
|
6886
7028
|
}))
|
|
6887
7029
|
};
|
|
6888
|
-
const toolResultMessages = [
|
|
7030
|
+
const toolResultMessages = [
|
|
7031
|
+
...serverToolCallMessages(
|
|
7032
|
+
currentAccumulator.toolCallEvents,
|
|
7033
|
+
currentMessages,
|
|
7034
|
+
new Set(toolCallsToExecute.map((tc) => tc.id))
|
|
7035
|
+
),
|
|
7036
|
+
assistantMessage
|
|
7037
|
+
];
|
|
6889
7038
|
for (const execResult of continueResults) {
|
|
6890
7039
|
const resultContent = execResult.error ? `Error: ${execResult.error}` : safeJsonStringify(execResult.result);
|
|
6891
7040
|
toolResultMessages.push({
|
|
@@ -9568,100 +9717,6 @@ function isSupportedMediaType(mimeType) {
|
|
|
9568
9717
|
// src/lib/db/media/operations.ts
|
|
9569
9718
|
import { Q as Q4 } from "@nozbe/watermelondb";
|
|
9570
9719
|
|
|
9571
|
-
// src/lib/storage/mcpImages.ts
|
|
9572
|
-
var IMAGE_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
9573
|
-
"AnumaMediaMCP-anuma_create_image",
|
|
9574
|
-
"anuma_create_image",
|
|
9575
|
-
// Deprecated anuma-image-mcp tools, retained so images in already-stored
|
|
9576
|
-
// conversations still re-materialize on replay.
|
|
9577
|
-
"AnumaImageMCP-generate_cloud_image",
|
|
9578
|
-
"AnumaImageMCP-edit_cloud_image",
|
|
9579
|
-
"generate_cloud_image",
|
|
9580
|
-
"edit_cloud_image"
|
|
9581
|
-
]);
|
|
9582
|
-
var VIDEO_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
9583
|
-
"AnumaMediaMCP-anuma_create_video",
|
|
9584
|
-
"AnumaFalMCP-fal_generate_video",
|
|
9585
|
-
"anuma_create_video",
|
|
9586
|
-
"fal_generate_video"
|
|
9587
|
-
]);
|
|
9588
|
-
var VIDEO_EXTENSIONS = ["mp4", "webm", "mov"];
|
|
9589
|
-
var VIDEO_EXTENSION_RE = new RegExp(`\\.(${VIDEO_EXTENSIONS.join("|")})(?:[?#]|$)`, "i");
|
|
9590
|
-
function videoExtensionOf(value) {
|
|
9591
|
-
return value?.match(VIDEO_EXTENSION_RE)?.[1]?.toLowerCase() ?? null;
|
|
9592
|
-
}
|
|
9593
|
-
function classifyUrl(url) {
|
|
9594
|
-
return VIDEO_EXTENSION_RE.test(url) ? "video" : "image";
|
|
9595
|
-
}
|
|
9596
|
-
function extractMCPImageUrls(content, toolCallEvents, mcpR2Domain) {
|
|
9597
|
-
const urls = [];
|
|
9598
|
-
if (toolCallEvents && toolCallEvents.length > 0) {
|
|
9599
|
-
for (const event of toolCallEvents) {
|
|
9600
|
-
if (!event.name) continue;
|
|
9601
|
-
if (IMAGE_TOOL_NAMES.has(event.name)) {
|
|
9602
|
-
try {
|
|
9603
|
-
const output = JSON.parse(event.output || "{}");
|
|
9604
|
-
const model = output.model || "image";
|
|
9605
|
-
const imageUrls = [
|
|
9606
|
-
...new Set(
|
|
9607
|
-
[
|
|
9608
|
-
...output.output_images?.map((i) => i.url) ?? [],
|
|
9609
|
-
output.imageUrl,
|
|
9610
|
-
output.url
|
|
9611
|
-
].filter((u) => Boolean(u))
|
|
9612
|
-
)
|
|
9613
|
-
];
|
|
9614
|
-
for (const url of imageUrls) {
|
|
9615
|
-
urls.push({ url, model, mediaType: "image" });
|
|
9616
|
-
}
|
|
9617
|
-
} catch {
|
|
9618
|
-
}
|
|
9619
|
-
} else if (VIDEO_TOOL_NAMES.has(event.name)) {
|
|
9620
|
-
try {
|
|
9621
|
-
const output = JSON.parse(event.output || "{}");
|
|
9622
|
-
const model = output.model || "video";
|
|
9623
|
-
const videoUrls = [
|
|
9624
|
-
...new Set(
|
|
9625
|
-
[
|
|
9626
|
-
...output.videos?.map((v) => v.video_url) ?? [],
|
|
9627
|
-
output.videoUrl,
|
|
9628
|
-
output.url
|
|
9629
|
-
].filter((u) => Boolean(u))
|
|
9630
|
-
)
|
|
9631
|
-
];
|
|
9632
|
-
for (const url of videoUrls) {
|
|
9633
|
-
urls.push({ url, model, mediaType: "video" });
|
|
9634
|
-
}
|
|
9635
|
-
} catch {
|
|
9636
|
-
}
|
|
9637
|
-
}
|
|
9638
|
-
}
|
|
9639
|
-
}
|
|
9640
|
-
if (urls.length === 0 && content) {
|
|
9641
|
-
const escaped = mcpR2Domain.replace(/\./g, "\\.");
|
|
9642
|
-
const patterns = [
|
|
9643
|
-
new RegExp(`https://${escaped}[^\\s"'<>)\\]]+`, "gi"),
|
|
9644
|
-
// Require the proxy's <svc>/<token> shape (>=2 path segments after
|
|
9645
|
-
// /api/v1/media/) so a third-party URL that only shallowly contains
|
|
9646
|
-
// /api/v1/media/ isn't returned as a portal media asset.
|
|
9647
|
-
new RegExp(`https?://[^\\s"'<>)\\]]+/api/v1/media/[^/\\s"'<>)\\]]+/[^\\s"'<>)\\]]+`, "gi")
|
|
9648
|
-
];
|
|
9649
|
-
const matches = patterns.flatMap((re) => content.match(re) ?? []);
|
|
9650
|
-
if (matches.length > 0) {
|
|
9651
|
-
const seen = /* @__PURE__ */ new Set();
|
|
9652
|
-
for (const url of matches) {
|
|
9653
|
-
const normalized = url.replace(/[)"'>\s]+$/, "");
|
|
9654
|
-
if (!seen.has(normalized)) {
|
|
9655
|
-
seen.add(normalized);
|
|
9656
|
-
const mediaType = classifyUrl(normalized);
|
|
9657
|
-
urls.push({ url: normalized, model: "image", mediaType });
|
|
9658
|
-
}
|
|
9659
|
-
}
|
|
9660
|
-
}
|
|
9661
|
-
}
|
|
9662
|
-
return urls;
|
|
9663
|
-
}
|
|
9664
|
-
|
|
9665
9720
|
// src/lib/storage/opfs.ts
|
|
9666
9721
|
var FILE_PLACEHOLDER_PREFIX = "__SDKFILE__";
|
|
9667
9722
|
var FILE_PLACEHOLDER_SUFFIX = "__";
|
|
@@ -22053,24 +22108,10 @@ async function storedToLlmapiMessage(stored, encryptionKey, resolveMediaByIds) {
|
|
|
22053
22108
|
});
|
|
22054
22109
|
for (const event of stored.toolCallEvents) {
|
|
22055
22110
|
if (event.id && event.output !== void 0 && event.output !== null) {
|
|
22056
|
-
let toolOutput = event.output;
|
|
22057
|
-
if (event.name && IMAGE_TOOL_NAMES.has(event.name)) {
|
|
22058
|
-
try {
|
|
22059
|
-
const parsed = JSON.parse(toolOutput);
|
|
22060
|
-
const {
|
|
22061
|
-
imageUrl: _imageUrl,
|
|
22062
|
-
url: _url,
|
|
22063
|
-
output_images: _outputImages,
|
|
22064
|
-
...rest
|
|
22065
|
-
} = parsed;
|
|
22066
|
-
toolOutput = JSON.stringify(rest);
|
|
22067
|
-
} catch {
|
|
22068
|
-
}
|
|
22069
|
-
}
|
|
22070
22111
|
messages.push({
|
|
22071
22112
|
role: "tool",
|
|
22072
22113
|
tool_call_id: event.id,
|
|
22073
|
-
content: [{ type: "text", text:
|
|
22114
|
+
content: [{ type: "text", text: toolOutputForModel(event.name, event.output) }]
|
|
22074
22115
|
});
|
|
22075
22116
|
}
|
|
22076
22117
|
}
|
package/dist/server/index.cjs
CHANGED
|
@@ -23358,6 +23358,30 @@ var import_watermelondb20 = __toESM(require_watermelondb());
|
|
|
23358
23358
|
init_logger();
|
|
23359
23359
|
|
|
23360
23360
|
// src/lib/storage/mcpImages.ts
|
|
23361
|
+
var IMAGE_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
23362
|
+
"AnumaMediaMCP-anuma_create_image",
|
|
23363
|
+
"anuma_create_image",
|
|
23364
|
+
// Deprecated anuma-image-mcp tools, retained so images in already-stored
|
|
23365
|
+
// conversations still re-materialize on replay.
|
|
23366
|
+
"AnumaImageMCP-generate_cloud_image",
|
|
23367
|
+
"AnumaImageMCP-edit_cloud_image",
|
|
23368
|
+
"generate_cloud_image",
|
|
23369
|
+
"edit_cloud_image"
|
|
23370
|
+
]);
|
|
23371
|
+
function toolOutputForModel(name, output) {
|
|
23372
|
+
if (!name || !IMAGE_TOOL_NAMES.has(name)) return output;
|
|
23373
|
+
try {
|
|
23374
|
+
const {
|
|
23375
|
+
imageUrl: _imageUrl,
|
|
23376
|
+
url: _url,
|
|
23377
|
+
output_images: _outputImages,
|
|
23378
|
+
...rest
|
|
23379
|
+
} = JSON.parse(output);
|
|
23380
|
+
return JSON.stringify(rest);
|
|
23381
|
+
} catch {
|
|
23382
|
+
return output;
|
|
23383
|
+
}
|
|
23384
|
+
}
|
|
23361
23385
|
var VIDEO_EXTENSIONS = ["mp4", "webm", "mov"];
|
|
23362
23386
|
var VIDEO_EXTENSION_RE = new RegExp(`\\.(${VIDEO_EXTENSIONS.join("|")})(?:[?#]|$)`, "i");
|
|
23363
23387
|
function videoExtensionOf(value) {
|
|
@@ -37102,6 +37126,40 @@ function extractLastUserText(messages) {
|
|
|
37102
37126
|
function isToolErrorResult(result) {
|
|
37103
37127
|
return result !== null && typeof result === "object" && "error" in result && typeof result.error === "string";
|
|
37104
37128
|
}
|
|
37129
|
+
function serverToolCallMessages(events, messages, skipIds) {
|
|
37130
|
+
const seen = new Set(skipIds);
|
|
37131
|
+
for (const m of messages) {
|
|
37132
|
+
if (m.tool_call_id) seen.add(m.tool_call_id);
|
|
37133
|
+
for (const tc of m.tool_calls ?? []) if (tc.id) seen.add(tc.id);
|
|
37134
|
+
}
|
|
37135
|
+
const executed = [];
|
|
37136
|
+
for (const event of events ?? []) {
|
|
37137
|
+
if (!event.id || event.output === void 0 || event.output === null || seen.has(event.id)) {
|
|
37138
|
+
continue;
|
|
37139
|
+
}
|
|
37140
|
+
seen.add(event.id);
|
|
37141
|
+
executed.push(event);
|
|
37142
|
+
}
|
|
37143
|
+
if (executed.length === 0) return [];
|
|
37144
|
+
return [
|
|
37145
|
+
{
|
|
37146
|
+
role: "assistant",
|
|
37147
|
+
content: void 0,
|
|
37148
|
+
tool_calls: executed.map((event) => ({
|
|
37149
|
+
id: event.id,
|
|
37150
|
+
type: "function",
|
|
37151
|
+
function: { name: event.name, arguments: event.arguments }
|
|
37152
|
+
}))
|
|
37153
|
+
},
|
|
37154
|
+
...executed.map(
|
|
37155
|
+
(event) => ({
|
|
37156
|
+
role: "tool",
|
|
37157
|
+
tool_call_id: event.id,
|
|
37158
|
+
content: [{ type: "text", text: toolOutputForModel(event.name, event.output ?? "") }]
|
|
37159
|
+
})
|
|
37160
|
+
)
|
|
37161
|
+
];
|
|
37162
|
+
}
|
|
37105
37163
|
function getToolName(tool) {
|
|
37106
37164
|
const func = tool.function;
|
|
37107
37165
|
const nestedName = func?.name;
|
|
@@ -37871,7 +37929,14 @@ Executing tool: ${toolInfo}
|
|
|
37871
37929
|
}
|
|
37872
37930
|
}))
|
|
37873
37931
|
};
|
|
37874
|
-
const toolResultMessages = [
|
|
37932
|
+
const toolResultMessages = [
|
|
37933
|
+
...serverToolCallMessages(
|
|
37934
|
+
currentAccumulator.toolCallEvents,
|
|
37935
|
+
currentMessages,
|
|
37936
|
+
new Set(toolCallsToExecute.map((tc) => tc.id))
|
|
37937
|
+
),
|
|
37938
|
+
assistantMessage
|
|
37939
|
+
];
|
|
37875
37940
|
for (const execResult of continueResults) {
|
|
37876
37941
|
const resultContent = execResult.error ? `Error: ${execResult.error}` : safeJsonStringify(execResult.result);
|
|
37877
37942
|
toolResultMessages.push({
|
package/dist/server/index.mjs
CHANGED
|
@@ -21672,6 +21672,30 @@ function isSupportedMediaType(mimeType) {
|
|
|
21672
21672
|
var import_watermelondb20 = __toESM(require_watermelondb());
|
|
21673
21673
|
|
|
21674
21674
|
// src/lib/storage/mcpImages.ts
|
|
21675
|
+
var IMAGE_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
21676
|
+
"AnumaMediaMCP-anuma_create_image",
|
|
21677
|
+
"anuma_create_image",
|
|
21678
|
+
// Deprecated anuma-image-mcp tools, retained so images in already-stored
|
|
21679
|
+
// conversations still re-materialize on replay.
|
|
21680
|
+
"AnumaImageMCP-generate_cloud_image",
|
|
21681
|
+
"AnumaImageMCP-edit_cloud_image",
|
|
21682
|
+
"generate_cloud_image",
|
|
21683
|
+
"edit_cloud_image"
|
|
21684
|
+
]);
|
|
21685
|
+
function toolOutputForModel(name, output) {
|
|
21686
|
+
if (!name || !IMAGE_TOOL_NAMES.has(name)) return output;
|
|
21687
|
+
try {
|
|
21688
|
+
const {
|
|
21689
|
+
imageUrl: _imageUrl,
|
|
21690
|
+
url: _url,
|
|
21691
|
+
output_images: _outputImages,
|
|
21692
|
+
...rest
|
|
21693
|
+
} = JSON.parse(output);
|
|
21694
|
+
return JSON.stringify(rest);
|
|
21695
|
+
} catch {
|
|
21696
|
+
return output;
|
|
21697
|
+
}
|
|
21698
|
+
}
|
|
21675
21699
|
var VIDEO_EXTENSIONS = ["mp4", "webm", "mov"];
|
|
21676
21700
|
var VIDEO_EXTENSION_RE = new RegExp(`\\.(${VIDEO_EXTENSIONS.join("|")})(?:[?#]|$)`, "i");
|
|
21677
21701
|
function videoExtensionOf(value) {
|
|
@@ -35349,6 +35373,40 @@ function extractLastUserText(messages) {
|
|
|
35349
35373
|
function isToolErrorResult(result) {
|
|
35350
35374
|
return result !== null && typeof result === "object" && "error" in result && typeof result.error === "string";
|
|
35351
35375
|
}
|
|
35376
|
+
function serverToolCallMessages(events, messages, skipIds) {
|
|
35377
|
+
const seen = new Set(skipIds);
|
|
35378
|
+
for (const m of messages) {
|
|
35379
|
+
if (m.tool_call_id) seen.add(m.tool_call_id);
|
|
35380
|
+
for (const tc of m.tool_calls ?? []) if (tc.id) seen.add(tc.id);
|
|
35381
|
+
}
|
|
35382
|
+
const executed = [];
|
|
35383
|
+
for (const event of events ?? []) {
|
|
35384
|
+
if (!event.id || event.output === void 0 || event.output === null || seen.has(event.id)) {
|
|
35385
|
+
continue;
|
|
35386
|
+
}
|
|
35387
|
+
seen.add(event.id);
|
|
35388
|
+
executed.push(event);
|
|
35389
|
+
}
|
|
35390
|
+
if (executed.length === 0) return [];
|
|
35391
|
+
return [
|
|
35392
|
+
{
|
|
35393
|
+
role: "assistant",
|
|
35394
|
+
content: void 0,
|
|
35395
|
+
tool_calls: executed.map((event) => ({
|
|
35396
|
+
id: event.id,
|
|
35397
|
+
type: "function",
|
|
35398
|
+
function: { name: event.name, arguments: event.arguments }
|
|
35399
|
+
}))
|
|
35400
|
+
},
|
|
35401
|
+
...executed.map(
|
|
35402
|
+
(event) => ({
|
|
35403
|
+
role: "tool",
|
|
35404
|
+
tool_call_id: event.id,
|
|
35405
|
+
content: [{ type: "text", text: toolOutputForModel(event.name, event.output ?? "") }]
|
|
35406
|
+
})
|
|
35407
|
+
)
|
|
35408
|
+
];
|
|
35409
|
+
}
|
|
35352
35410
|
function getToolName(tool) {
|
|
35353
35411
|
const func = tool.function;
|
|
35354
35412
|
const nestedName = func?.name;
|
|
@@ -36118,7 +36176,14 @@ Executing tool: ${toolInfo}
|
|
|
36118
36176
|
}
|
|
36119
36177
|
}))
|
|
36120
36178
|
};
|
|
36121
|
-
const toolResultMessages = [
|
|
36179
|
+
const toolResultMessages = [
|
|
36180
|
+
...serverToolCallMessages(
|
|
36181
|
+
currentAccumulator.toolCallEvents,
|
|
36182
|
+
currentMessages,
|
|
36183
|
+
new Set(toolCallsToExecute.map((tc) => tc.id))
|
|
36184
|
+
),
|
|
36185
|
+
assistantMessage
|
|
36186
|
+
];
|
|
36122
36187
|
for (const execResult of continueResults) {
|
|
36123
36188
|
const resultContent = execResult.error ? `Error: ${execResult.error}` : safeJsonStringify(execResult.result);
|
|
36124
36189
|
toolResultMessages.push({
|