@wingman-ai/gateway 0.2.5 → 0.3.0
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/.wingman/agents/coding/agent.md +5 -0
- package/.wingman/agents/coding-v2/agent.md +58 -0
- package/.wingman/agents/game-dev/agent.md +94 -0
- package/.wingman/agents/game-dev/art-generation.md +37 -0
- package/.wingman/agents/game-dev/asset-refinement.md +17 -0
- package/.wingman/agents/game-dev/planning-idea.md +17 -0
- package/.wingman/agents/game-dev/ui-specialist.md +17 -0
- package/.wingman/agents/main/agent.md +2 -0
- package/README.md +1 -0
- package/dist/agent/config/agentConfig.d.ts +4 -0
- package/dist/agent/config/mcpClientManager.cjs +44 -10
- package/dist/agent/config/mcpClientManager.d.ts +6 -2
- package/dist/agent/config/mcpClientManager.js +44 -10
- package/dist/agent/config/toolRegistry.cjs +3 -1
- package/dist/agent/config/toolRegistry.js +3 -1
- package/dist/agent/tests/mcpClientManager.test.cjs +124 -0
- package/dist/agent/tests/mcpClientManager.test.d.ts +1 -0
- package/dist/agent/tests/mcpClientManager.test.js +118 -0
- package/dist/agent/tools/command_execute.cjs +1 -1
- package/dist/agent/tools/command_execute.js +1 -1
- package/dist/cli/config/schema.d.ts +2 -0
- package/dist/cli/core/agentInvoker.cjs +55 -66
- package/dist/cli/core/agentInvoker.d.ts +10 -13
- package/dist/cli/core/agentInvoker.js +42 -62
- package/dist/cli/core/imagePersistence.cjs +125 -0
- package/dist/cli/core/imagePersistence.d.ts +24 -0
- package/dist/cli/core/imagePersistence.js +85 -0
- package/dist/cli/core/sessionManager.cjs +297 -40
- package/dist/cli/core/sessionManager.d.ts +9 -0
- package/dist/cli/core/sessionManager.js +297 -40
- package/dist/debug/terminalProbe.cjs +57 -0
- package/dist/debug/terminalProbe.d.ts +10 -0
- package/dist/debug/terminalProbe.js +20 -0
- package/dist/debug/terminalProbeAuth.cjs +140 -0
- package/dist/debug/terminalProbeAuth.d.ts +20 -0
- package/dist/debug/terminalProbeAuth.js +97 -0
- package/dist/gateway/http/fs.cjs +19 -0
- package/dist/gateway/http/fs.js +19 -0
- package/dist/gateway/http/sessions.cjs +25 -5
- package/dist/gateway/http/sessions.js +25 -5
- package/dist/gateway/server.cjs +112 -11
- package/dist/gateway/server.d.ts +2 -0
- package/dist/gateway/server.js +112 -11
- package/dist/tests/agentInvokerSummarization.test.cjs +56 -37
- package/dist/tests/agentInvokerSummarization.test.js +58 -39
- package/dist/tests/agentInvokerWorkdir.test.cjs +50 -0
- package/dist/tests/agentInvokerWorkdir.test.js +52 -2
- package/dist/tests/cli-init.test.cjs +36 -0
- package/dist/tests/cli-init.test.js +36 -0
- package/dist/tests/falRuntime.test.cjs +78 -0
- package/dist/tests/falRuntime.test.d.ts +1 -0
- package/dist/tests/falRuntime.test.js +72 -0
- package/dist/tests/falSummary.test.cjs +51 -0
- package/dist/tests/falSummary.test.d.ts +1 -0
- package/dist/tests/falSummary.test.js +45 -0
- package/dist/tests/gateway.test.cjs +109 -1
- package/dist/tests/gateway.test.js +109 -1
- package/dist/tests/imagePersistence.test.cjs +143 -0
- package/dist/tests/imagePersistence.test.d.ts +1 -0
- package/dist/tests/imagePersistence.test.js +137 -0
- package/dist/tests/sessionMessageAttachments.test.cjs +30 -0
- package/dist/tests/sessionMessageAttachments.test.js +30 -0
- package/dist/tests/sessionStateMessages.test.cjs +126 -0
- package/dist/tests/sessionStateMessages.test.js +126 -0
- package/dist/tests/sessions-api.test.cjs +117 -3
- package/dist/tests/sessions-api.test.js +118 -4
- package/dist/tests/terminalProbe.test.cjs +45 -0
- package/dist/tests/terminalProbe.test.d.ts +1 -0
- package/dist/tests/terminalProbe.test.js +39 -0
- package/dist/tests/terminalProbeAuth.test.cjs +85 -0
- package/dist/tests/terminalProbeAuth.test.d.ts +1 -0
- package/dist/tests/terminalProbeAuth.test.js +79 -0
- package/dist/tools/fal/runtime.cjs +103 -0
- package/dist/tools/fal/runtime.d.ts +10 -0
- package/dist/tools/fal/runtime.js +60 -0
- package/dist/tools/fal/summary.cjs +78 -0
- package/dist/tools/fal/summary.d.ts +22 -0
- package/dist/tools/fal/summary.js +41 -0
- package/dist/tools/mcp-fal-ai.cjs +1041 -0
- package/dist/tools/mcp-fal-ai.d.ts +1 -0
- package/dist/tools/mcp-fal-ai.js +1025 -0
- package/dist/types/mcp.cjs +2 -0
- package/dist/types/mcp.d.ts +8 -0
- package/dist/types/mcp.js +3 -1
- package/dist/webui/assets/index-0nUBsUUq.js +278 -0
- package/dist/webui/assets/index-kk7OrD-G.css +11 -0
- package/dist/webui/index.html +2 -2
- package/package.json +11 -8
- package/dist/webui/assets/index-C7EuTbnE.js +0 -270
- package/dist/webui/assets/index-DVWQluit.css +0 -11
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_exports__ = {};
|
|
3
|
+
const external_node_fs_namespaceObject = require("node:fs");
|
|
4
|
+
const external_node_os_namespaceObject = require("node:os");
|
|
5
|
+
const external_node_path_namespaceObject = require("node:path");
|
|
6
|
+
const external_vitest_namespaceObject = require("vitest");
|
|
7
|
+
const imagePersistence_cjs_namespaceObject = require("../cli/core/imagePersistence.cjs");
|
|
8
|
+
const PNG_DATA_URL = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO3X6S0AAAAASUVORK5CYII=";
|
|
9
|
+
(0, external_vitest_namespaceObject.describe)("imagePersistence", ()=>{
|
|
10
|
+
const tempDirs = [];
|
|
11
|
+
(0, external_vitest_namespaceObject.afterEach)(()=>{
|
|
12
|
+
for (const dir of tempDirs)(0, external_node_fs_namespaceObject.rmSync)(dir, {
|
|
13
|
+
recursive: true,
|
|
14
|
+
force: true
|
|
15
|
+
});
|
|
16
|
+
tempDirs.length = 0;
|
|
17
|
+
});
|
|
18
|
+
(0, external_vitest_namespaceObject.it)("persists assistant image data URLs to disk", ()=>{
|
|
19
|
+
const tempDir = (0, external_node_fs_namespaceObject.mkdtempSync)((0, external_node_path_namespaceObject.join)((0, external_node_os_namespaceObject.tmpdir)(), "wingman-image-store-"));
|
|
20
|
+
tempDirs.push(tempDir);
|
|
21
|
+
const dbPath = (0, external_node_path_namespaceObject.join)(tempDir, "wingman.db");
|
|
22
|
+
const messages = [
|
|
23
|
+
{
|
|
24
|
+
role: "assistant",
|
|
25
|
+
attachments: [
|
|
26
|
+
{
|
|
27
|
+
kind: "image",
|
|
28
|
+
dataUrl: PNG_DATA_URL
|
|
29
|
+
}
|
|
30
|
+
]
|
|
31
|
+
}
|
|
32
|
+
];
|
|
33
|
+
(0, imagePersistence_cjs_namespaceObject.persistAssistantImagesToDisk)({
|
|
34
|
+
dbPath,
|
|
35
|
+
sessionId: "session-123",
|
|
36
|
+
messages
|
|
37
|
+
});
|
|
38
|
+
const attachment = messages[0].attachments?.[0];
|
|
39
|
+
(0, external_vitest_namespaceObject.expect)(typeof attachment?.path).toBe("string");
|
|
40
|
+
(0, external_vitest_namespaceObject.expect)(attachment?.mimeType).toBe("image/png");
|
|
41
|
+
(0, external_vitest_namespaceObject.expect)(typeof attachment?.size).toBe("number");
|
|
42
|
+
(0, external_vitest_namespaceObject.expect)(attachment?.size).toBeGreaterThan(0);
|
|
43
|
+
(0, external_vitest_namespaceObject.expect)((0, external_node_fs_namespaceObject.existsSync)(attachment.path)).toBe(true);
|
|
44
|
+
(0, external_vitest_namespaceObject.expect)((0, external_node_fs_namespaceObject.readFileSync)(attachment.path).length).toBe(attachment?.size);
|
|
45
|
+
});
|
|
46
|
+
(0, external_vitest_namespaceObject.it)("does not persist non-assistant images", ()=>{
|
|
47
|
+
const tempDir = (0, external_node_fs_namespaceObject.mkdtempSync)((0, external_node_path_namespaceObject.join)((0, external_node_os_namespaceObject.tmpdir)(), "wingman-image-store-"));
|
|
48
|
+
tempDirs.push(tempDir);
|
|
49
|
+
const dbPath = (0, external_node_path_namespaceObject.join)(tempDir, "wingman.db");
|
|
50
|
+
const messages = [
|
|
51
|
+
{
|
|
52
|
+
role: "user",
|
|
53
|
+
attachments: [
|
|
54
|
+
{
|
|
55
|
+
kind: "image",
|
|
56
|
+
dataUrl: PNG_DATA_URL
|
|
57
|
+
}
|
|
58
|
+
]
|
|
59
|
+
}
|
|
60
|
+
];
|
|
61
|
+
(0, imagePersistence_cjs_namespaceObject.persistAssistantImagesToDisk)({
|
|
62
|
+
dbPath,
|
|
63
|
+
sessionId: "session-123",
|
|
64
|
+
messages
|
|
65
|
+
});
|
|
66
|
+
(0, external_vitest_namespaceObject.expect)(messages[0].attachments?.[0].path).toBeUndefined();
|
|
67
|
+
});
|
|
68
|
+
(0, external_vitest_namespaceObject.it)("keeps remote image URLs untouched", ()=>{
|
|
69
|
+
const tempDir = (0, external_node_fs_namespaceObject.mkdtempSync)((0, external_node_path_namespaceObject.join)((0, external_node_os_namespaceObject.tmpdir)(), "wingman-image-store-"));
|
|
70
|
+
tempDirs.push(tempDir);
|
|
71
|
+
const dbPath = (0, external_node_path_namespaceObject.join)(tempDir, "wingman.db");
|
|
72
|
+
const messages = [
|
|
73
|
+
{
|
|
74
|
+
role: "assistant",
|
|
75
|
+
attachments: [
|
|
76
|
+
{
|
|
77
|
+
kind: "image",
|
|
78
|
+
dataUrl: "https://example.com/image.png"
|
|
79
|
+
}
|
|
80
|
+
]
|
|
81
|
+
}
|
|
82
|
+
];
|
|
83
|
+
(0, imagePersistence_cjs_namespaceObject.persistAssistantImagesToDisk)({
|
|
84
|
+
dbPath,
|
|
85
|
+
sessionId: "session-123",
|
|
86
|
+
messages
|
|
87
|
+
});
|
|
88
|
+
(0, external_vitest_namespaceObject.expect)(messages[0].attachments?.[0].path).toBeUndefined();
|
|
89
|
+
});
|
|
90
|
+
(0, external_vitest_namespaceObject.it)("derives deterministic file paths for repeated image payloads", ()=>{
|
|
91
|
+
const tempDir = (0, external_node_fs_namespaceObject.mkdtempSync)((0, external_node_path_namespaceObject.join)((0, external_node_os_namespaceObject.tmpdir)(), "wingman-image-store-"));
|
|
92
|
+
tempDirs.push(tempDir);
|
|
93
|
+
const dbPath = (0, external_node_path_namespaceObject.join)(tempDir, "wingman.db");
|
|
94
|
+
const messages = [
|
|
95
|
+
{
|
|
96
|
+
role: "assistant",
|
|
97
|
+
attachments: [
|
|
98
|
+
{
|
|
99
|
+
kind: "image",
|
|
100
|
+
dataUrl: PNG_DATA_URL
|
|
101
|
+
}
|
|
102
|
+
]
|
|
103
|
+
}
|
|
104
|
+
];
|
|
105
|
+
(0, imagePersistence_cjs_namespaceObject.persistAssistantImagesToDisk)({
|
|
106
|
+
dbPath,
|
|
107
|
+
sessionId: "session-123",
|
|
108
|
+
messages
|
|
109
|
+
});
|
|
110
|
+
const firstPath = messages[0].attachments?.[0].path;
|
|
111
|
+
const nextMessages = [
|
|
112
|
+
{
|
|
113
|
+
role: "assistant",
|
|
114
|
+
attachments: [
|
|
115
|
+
{
|
|
116
|
+
kind: "image",
|
|
117
|
+
dataUrl: PNG_DATA_URL
|
|
118
|
+
}
|
|
119
|
+
]
|
|
120
|
+
}
|
|
121
|
+
];
|
|
122
|
+
(0, imagePersistence_cjs_namespaceObject.persistAssistantImagesToDisk)({
|
|
123
|
+
dbPath,
|
|
124
|
+
sessionId: "session-123",
|
|
125
|
+
messages: nextMessages
|
|
126
|
+
});
|
|
127
|
+
const secondPath = nextMessages[0].attachments?.[0].path;
|
|
128
|
+
(0, external_vitest_namespaceObject.expect)(firstPath).toBeTruthy();
|
|
129
|
+
(0, external_vitest_namespaceObject.expect)(secondPath).toBe(firstPath);
|
|
130
|
+
});
|
|
131
|
+
(0, external_vitest_namespaceObject.it)("parses base64 data URLs and resolves extensions", ()=>{
|
|
132
|
+
const parsed = (0, imagePersistence_cjs_namespaceObject.parseBase64DataUrl)(PNG_DATA_URL);
|
|
133
|
+
(0, external_vitest_namespaceObject.expect)(parsed?.mimeType).toBe("image/png");
|
|
134
|
+
(0, external_vitest_namespaceObject.expect)(typeof parsed?.data).toBe("string");
|
|
135
|
+
(0, external_vitest_namespaceObject.expect)((0, imagePersistence_cjs_namespaceObject.resolveImageExtension)("image/jpeg")).toBe("jpg");
|
|
136
|
+
(0, external_vitest_namespaceObject.expect)((0, imagePersistence_cjs_namespaceObject.resolveImageExtension)("image/svg+xml")).toBe("svg");
|
|
137
|
+
(0, external_vitest_namespaceObject.expect)((0, imagePersistence_cjs_namespaceObject.resolveImageExtension)("image/custom+format")).toBe("customformat");
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
for(var __rspack_i in __webpack_exports__)exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
141
|
+
Object.defineProperty(exports, '__esModule', {
|
|
142
|
+
value: true
|
|
143
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { existsSync, mkdtempSync, readFileSync, rmSync } from "node:fs";
|
|
2
|
+
import { tmpdir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { afterEach, describe, expect, it } from "vitest";
|
|
5
|
+
import { parseBase64DataUrl, persistAssistantImagesToDisk, resolveImageExtension } from "../cli/core/imagePersistence.js";
|
|
6
|
+
const PNG_DATA_URL = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO3X6S0AAAAASUVORK5CYII=";
|
|
7
|
+
describe("imagePersistence", ()=>{
|
|
8
|
+
const tempDirs = [];
|
|
9
|
+
afterEach(()=>{
|
|
10
|
+
for (const dir of tempDirs)rmSync(dir, {
|
|
11
|
+
recursive: true,
|
|
12
|
+
force: true
|
|
13
|
+
});
|
|
14
|
+
tempDirs.length = 0;
|
|
15
|
+
});
|
|
16
|
+
it("persists assistant image data URLs to disk", ()=>{
|
|
17
|
+
const tempDir = mkdtempSync(join(tmpdir(), "wingman-image-store-"));
|
|
18
|
+
tempDirs.push(tempDir);
|
|
19
|
+
const dbPath = join(tempDir, "wingman.db");
|
|
20
|
+
const messages = [
|
|
21
|
+
{
|
|
22
|
+
role: "assistant",
|
|
23
|
+
attachments: [
|
|
24
|
+
{
|
|
25
|
+
kind: "image",
|
|
26
|
+
dataUrl: PNG_DATA_URL
|
|
27
|
+
}
|
|
28
|
+
]
|
|
29
|
+
}
|
|
30
|
+
];
|
|
31
|
+
persistAssistantImagesToDisk({
|
|
32
|
+
dbPath,
|
|
33
|
+
sessionId: "session-123",
|
|
34
|
+
messages
|
|
35
|
+
});
|
|
36
|
+
const attachment = messages[0].attachments?.[0];
|
|
37
|
+
expect(typeof attachment?.path).toBe("string");
|
|
38
|
+
expect(attachment?.mimeType).toBe("image/png");
|
|
39
|
+
expect(typeof attachment?.size).toBe("number");
|
|
40
|
+
expect(attachment?.size).toBeGreaterThan(0);
|
|
41
|
+
expect(existsSync(attachment.path)).toBe(true);
|
|
42
|
+
expect(readFileSync(attachment.path).length).toBe(attachment?.size);
|
|
43
|
+
});
|
|
44
|
+
it("does not persist non-assistant images", ()=>{
|
|
45
|
+
const tempDir = mkdtempSync(join(tmpdir(), "wingman-image-store-"));
|
|
46
|
+
tempDirs.push(tempDir);
|
|
47
|
+
const dbPath = join(tempDir, "wingman.db");
|
|
48
|
+
const messages = [
|
|
49
|
+
{
|
|
50
|
+
role: "user",
|
|
51
|
+
attachments: [
|
|
52
|
+
{
|
|
53
|
+
kind: "image",
|
|
54
|
+
dataUrl: PNG_DATA_URL
|
|
55
|
+
}
|
|
56
|
+
]
|
|
57
|
+
}
|
|
58
|
+
];
|
|
59
|
+
persistAssistantImagesToDisk({
|
|
60
|
+
dbPath,
|
|
61
|
+
sessionId: "session-123",
|
|
62
|
+
messages
|
|
63
|
+
});
|
|
64
|
+
expect(messages[0].attachments?.[0].path).toBeUndefined();
|
|
65
|
+
});
|
|
66
|
+
it("keeps remote image URLs untouched", ()=>{
|
|
67
|
+
const tempDir = mkdtempSync(join(tmpdir(), "wingman-image-store-"));
|
|
68
|
+
tempDirs.push(tempDir);
|
|
69
|
+
const dbPath = join(tempDir, "wingman.db");
|
|
70
|
+
const messages = [
|
|
71
|
+
{
|
|
72
|
+
role: "assistant",
|
|
73
|
+
attachments: [
|
|
74
|
+
{
|
|
75
|
+
kind: "image",
|
|
76
|
+
dataUrl: "https://example.com/image.png"
|
|
77
|
+
}
|
|
78
|
+
]
|
|
79
|
+
}
|
|
80
|
+
];
|
|
81
|
+
persistAssistantImagesToDisk({
|
|
82
|
+
dbPath,
|
|
83
|
+
sessionId: "session-123",
|
|
84
|
+
messages
|
|
85
|
+
});
|
|
86
|
+
expect(messages[0].attachments?.[0].path).toBeUndefined();
|
|
87
|
+
});
|
|
88
|
+
it("derives deterministic file paths for repeated image payloads", ()=>{
|
|
89
|
+
const tempDir = mkdtempSync(join(tmpdir(), "wingman-image-store-"));
|
|
90
|
+
tempDirs.push(tempDir);
|
|
91
|
+
const dbPath = join(tempDir, "wingman.db");
|
|
92
|
+
const messages = [
|
|
93
|
+
{
|
|
94
|
+
role: "assistant",
|
|
95
|
+
attachments: [
|
|
96
|
+
{
|
|
97
|
+
kind: "image",
|
|
98
|
+
dataUrl: PNG_DATA_URL
|
|
99
|
+
}
|
|
100
|
+
]
|
|
101
|
+
}
|
|
102
|
+
];
|
|
103
|
+
persistAssistantImagesToDisk({
|
|
104
|
+
dbPath,
|
|
105
|
+
sessionId: "session-123",
|
|
106
|
+
messages
|
|
107
|
+
});
|
|
108
|
+
const firstPath = messages[0].attachments?.[0].path;
|
|
109
|
+
const nextMessages = [
|
|
110
|
+
{
|
|
111
|
+
role: "assistant",
|
|
112
|
+
attachments: [
|
|
113
|
+
{
|
|
114
|
+
kind: "image",
|
|
115
|
+
dataUrl: PNG_DATA_URL
|
|
116
|
+
}
|
|
117
|
+
]
|
|
118
|
+
}
|
|
119
|
+
];
|
|
120
|
+
persistAssistantImagesToDisk({
|
|
121
|
+
dbPath,
|
|
122
|
+
sessionId: "session-123",
|
|
123
|
+
messages: nextMessages
|
|
124
|
+
});
|
|
125
|
+
const secondPath = nextMessages[0].attachments?.[0].path;
|
|
126
|
+
expect(firstPath).toBeTruthy();
|
|
127
|
+
expect(secondPath).toBe(firstPath);
|
|
128
|
+
});
|
|
129
|
+
it("parses base64 data URLs and resolves extensions", ()=>{
|
|
130
|
+
const parsed = parseBase64DataUrl(PNG_DATA_URL);
|
|
131
|
+
expect(parsed?.mimeType).toBe("image/png");
|
|
132
|
+
expect(typeof parsed?.data).toBe("string");
|
|
133
|
+
expect(resolveImageExtension("image/jpeg")).toBe("jpg");
|
|
134
|
+
expect(resolveImageExtension("image/svg+xml")).toBe("svg");
|
|
135
|
+
expect(resolveImageExtension("image/custom+format")).toBe("customformat");
|
|
136
|
+
});
|
|
137
|
+
});
|
|
@@ -50,6 +50,36 @@ const sessionManager_cjs_namespaceObject = require("../cli/core/sessionManager.c
|
|
|
50
50
|
}
|
|
51
51
|
]);
|
|
52
52
|
});
|
|
53
|
+
(0, external_vitest_namespaceObject.it)("extracts MCP image blocks with inline base64 payload", ()=>{
|
|
54
|
+
const blocks = [
|
|
55
|
+
{
|
|
56
|
+
type: "image",
|
|
57
|
+
mimeType: "image/png",
|
|
58
|
+
data: "abc123"
|
|
59
|
+
}
|
|
60
|
+
];
|
|
61
|
+
(0, external_vitest_namespaceObject.expect)((0, sessionManager_cjs_namespaceObject.extractImageAttachments)(blocks)).toEqual([
|
|
62
|
+
{
|
|
63
|
+
kind: "image",
|
|
64
|
+
dataUrl: "data:image/png;base64,abc123"
|
|
65
|
+
}
|
|
66
|
+
]);
|
|
67
|
+
});
|
|
68
|
+
(0, external_vitest_namespaceObject.it)("extracts resource_link image blocks", ()=>{
|
|
69
|
+
const blocks = [
|
|
70
|
+
{
|
|
71
|
+
type: "resource_link",
|
|
72
|
+
uri: "/api/fs/file?path=%2Ftmp%2Fgenerated.png",
|
|
73
|
+
mimeType: "image/png"
|
|
74
|
+
}
|
|
75
|
+
];
|
|
76
|
+
(0, external_vitest_namespaceObject.expect)((0, sessionManager_cjs_namespaceObject.extractImageAttachments)(blocks)).toEqual([
|
|
77
|
+
{
|
|
78
|
+
kind: "image",
|
|
79
|
+
dataUrl: "/api/fs/file?path=%2Ftmp%2Fgenerated.png"
|
|
80
|
+
}
|
|
81
|
+
]);
|
|
82
|
+
});
|
|
53
83
|
});
|
|
54
84
|
(0, external_vitest_namespaceObject.describe)("extractAttachments", ()=>{
|
|
55
85
|
(0, external_vitest_namespaceObject.it)("extracts input_audio blocks", ()=>{
|
|
@@ -48,6 +48,36 @@ describe("extractImageAttachments", ()=>{
|
|
|
48
48
|
}
|
|
49
49
|
]);
|
|
50
50
|
});
|
|
51
|
+
it("extracts MCP image blocks with inline base64 payload", ()=>{
|
|
52
|
+
const blocks = [
|
|
53
|
+
{
|
|
54
|
+
type: "image",
|
|
55
|
+
mimeType: "image/png",
|
|
56
|
+
data: "abc123"
|
|
57
|
+
}
|
|
58
|
+
];
|
|
59
|
+
expect(extractImageAttachments(blocks)).toEqual([
|
|
60
|
+
{
|
|
61
|
+
kind: "image",
|
|
62
|
+
dataUrl: "data:image/png;base64,abc123"
|
|
63
|
+
}
|
|
64
|
+
]);
|
|
65
|
+
});
|
|
66
|
+
it("extracts resource_link image blocks", ()=>{
|
|
67
|
+
const blocks = [
|
|
68
|
+
{
|
|
69
|
+
type: "resource_link",
|
|
70
|
+
uri: "/api/fs/file?path=%2Ftmp%2Fgenerated.png",
|
|
71
|
+
mimeType: "image/png"
|
|
72
|
+
}
|
|
73
|
+
];
|
|
74
|
+
expect(extractImageAttachments(blocks)).toEqual([
|
|
75
|
+
{
|
|
76
|
+
kind: "image",
|
|
77
|
+
dataUrl: "/api/fs/file?path=%2Ftmp%2Fgenerated.png"
|
|
78
|
+
}
|
|
79
|
+
]);
|
|
80
|
+
});
|
|
51
81
|
});
|
|
52
82
|
describe("extractAttachments", ()=>{
|
|
53
83
|
it("extracts input_audio blocks", ()=>{
|
|
@@ -103,6 +103,132 @@ const sessionManager_cjs_namespaceObject = require("../cli/core/sessionManager.c
|
|
|
103
103
|
content: "Here is the plan."
|
|
104
104
|
});
|
|
105
105
|
});
|
|
106
|
+
(0, external_vitest_namespaceObject.it)("promotes tool image outputs into assistant attachments", ()=>{
|
|
107
|
+
const state = {
|
|
108
|
+
createdAt: 3000,
|
|
109
|
+
values: {
|
|
110
|
+
messages: [
|
|
111
|
+
{
|
|
112
|
+
role: "user",
|
|
113
|
+
content: "Create a puppy image."
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
role: "tool",
|
|
117
|
+
content: JSON.stringify({
|
|
118
|
+
content: [
|
|
119
|
+
{
|
|
120
|
+
type: "text",
|
|
121
|
+
text: "Generated image."
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
type: "resource_link",
|
|
125
|
+
uri: "/api/fs/file?path=%2Ftmp%2Fpuppy.png",
|
|
126
|
+
mimeType: "image/png"
|
|
127
|
+
}
|
|
128
|
+
]
|
|
129
|
+
})
|
|
130
|
+
}
|
|
131
|
+
]
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
const result = (0, sessionManager_cjs_namespaceObject.extractMessagesFromState)(state);
|
|
135
|
+
(0, external_vitest_namespaceObject.expect)(result).not.toBeNull();
|
|
136
|
+
(0, external_vitest_namespaceObject.expect)(result).toHaveLength(2);
|
|
137
|
+
(0, external_vitest_namespaceObject.expect)(result?.[1]).toMatchObject({
|
|
138
|
+
role: "assistant",
|
|
139
|
+
content: "Generated image.",
|
|
140
|
+
attachments: [
|
|
141
|
+
{
|
|
142
|
+
kind: "image",
|
|
143
|
+
dataUrl: "/api/fs/file?path=%2Ftmp%2Fpuppy.png"
|
|
144
|
+
}
|
|
145
|
+
]
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
|
+
(0, external_vitest_namespaceObject.it)("extracts tool attachments when MCP payload is wrapped in a text block", ()=>{
|
|
149
|
+
const state = {
|
|
150
|
+
createdAt: 4000,
|
|
151
|
+
values: {
|
|
152
|
+
messages: [
|
|
153
|
+
{
|
|
154
|
+
role: "user",
|
|
155
|
+
content: "Generate a landscape image."
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
role: "tool",
|
|
159
|
+
content: [
|
|
160
|
+
{
|
|
161
|
+
type: "text",
|
|
162
|
+
text: JSON.stringify({
|
|
163
|
+
content: [
|
|
164
|
+
{
|
|
165
|
+
type: "text",
|
|
166
|
+
text: "Image ready."
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
type: "resource_link",
|
|
170
|
+
uri: "/api/fs/file?path=%2Ftmp%2Flandscape.png",
|
|
171
|
+
mimeType: "image/png"
|
|
172
|
+
}
|
|
173
|
+
]
|
|
174
|
+
})
|
|
175
|
+
}
|
|
176
|
+
]
|
|
177
|
+
}
|
|
178
|
+
]
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
const result = (0, sessionManager_cjs_namespaceObject.extractMessagesFromState)(state);
|
|
182
|
+
(0, external_vitest_namespaceObject.expect)(result).not.toBeNull();
|
|
183
|
+
(0, external_vitest_namespaceObject.expect)(result).toHaveLength(2);
|
|
184
|
+
(0, external_vitest_namespaceObject.expect)(result?.[1]).toMatchObject({
|
|
185
|
+
role: "assistant",
|
|
186
|
+
content: "Image ready.",
|
|
187
|
+
attachments: [
|
|
188
|
+
{
|
|
189
|
+
kind: "image",
|
|
190
|
+
dataUrl: "/api/fs/file?path=%2Ftmp%2Flandscape.png"
|
|
191
|
+
}
|
|
192
|
+
]
|
|
193
|
+
});
|
|
194
|
+
});
|
|
195
|
+
(0, external_vitest_namespaceObject.it)("extracts tool image attachments from artifact blocks", ()=>{
|
|
196
|
+
const state = {
|
|
197
|
+
createdAt: 5000,
|
|
198
|
+
values: {
|
|
199
|
+
messages: [
|
|
200
|
+
{
|
|
201
|
+
role: "user",
|
|
202
|
+
content: "Generate another image."
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
role: "tool",
|
|
206
|
+
content: "Generated image.",
|
|
207
|
+
artifact: [
|
|
208
|
+
{
|
|
209
|
+
type: "image",
|
|
210
|
+
mimeType: "image/png",
|
|
211
|
+
data: "abc123"
|
|
212
|
+
}
|
|
213
|
+
]
|
|
214
|
+
}
|
|
215
|
+
]
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
const result = (0, sessionManager_cjs_namespaceObject.extractMessagesFromState)(state);
|
|
219
|
+
(0, external_vitest_namespaceObject.expect)(result).not.toBeNull();
|
|
220
|
+
(0, external_vitest_namespaceObject.expect)(result).toHaveLength(2);
|
|
221
|
+
(0, external_vitest_namespaceObject.expect)(result?.[1]).toMatchObject({
|
|
222
|
+
role: "assistant",
|
|
223
|
+
content: "Generated image.",
|
|
224
|
+
attachments: [
|
|
225
|
+
{
|
|
226
|
+
kind: "image",
|
|
227
|
+
dataUrl: "data:image/png;base64,abc123"
|
|
228
|
+
}
|
|
229
|
+
]
|
|
230
|
+
});
|
|
231
|
+
});
|
|
106
232
|
});
|
|
107
233
|
for(var __rspack_i in __webpack_exports__)exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
108
234
|
Object.defineProperty(exports, '__esModule', {
|
|
@@ -101,4 +101,130 @@ describe("extractMessagesFromState", ()=>{
|
|
|
101
101
|
content: "Here is the plan."
|
|
102
102
|
});
|
|
103
103
|
});
|
|
104
|
+
it("promotes tool image outputs into assistant attachments", ()=>{
|
|
105
|
+
const state = {
|
|
106
|
+
createdAt: 3000,
|
|
107
|
+
values: {
|
|
108
|
+
messages: [
|
|
109
|
+
{
|
|
110
|
+
role: "user",
|
|
111
|
+
content: "Create a puppy image."
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
role: "tool",
|
|
115
|
+
content: JSON.stringify({
|
|
116
|
+
content: [
|
|
117
|
+
{
|
|
118
|
+
type: "text",
|
|
119
|
+
text: "Generated image."
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
type: "resource_link",
|
|
123
|
+
uri: "/api/fs/file?path=%2Ftmp%2Fpuppy.png",
|
|
124
|
+
mimeType: "image/png"
|
|
125
|
+
}
|
|
126
|
+
]
|
|
127
|
+
})
|
|
128
|
+
}
|
|
129
|
+
]
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
const result = extractMessagesFromState(state);
|
|
133
|
+
expect(result).not.toBeNull();
|
|
134
|
+
expect(result).toHaveLength(2);
|
|
135
|
+
expect(result?.[1]).toMatchObject({
|
|
136
|
+
role: "assistant",
|
|
137
|
+
content: "Generated image.",
|
|
138
|
+
attachments: [
|
|
139
|
+
{
|
|
140
|
+
kind: "image",
|
|
141
|
+
dataUrl: "/api/fs/file?path=%2Ftmp%2Fpuppy.png"
|
|
142
|
+
}
|
|
143
|
+
]
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
it("extracts tool attachments when MCP payload is wrapped in a text block", ()=>{
|
|
147
|
+
const state = {
|
|
148
|
+
createdAt: 4000,
|
|
149
|
+
values: {
|
|
150
|
+
messages: [
|
|
151
|
+
{
|
|
152
|
+
role: "user",
|
|
153
|
+
content: "Generate a landscape image."
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
role: "tool",
|
|
157
|
+
content: [
|
|
158
|
+
{
|
|
159
|
+
type: "text",
|
|
160
|
+
text: JSON.stringify({
|
|
161
|
+
content: [
|
|
162
|
+
{
|
|
163
|
+
type: "text",
|
|
164
|
+
text: "Image ready."
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
type: "resource_link",
|
|
168
|
+
uri: "/api/fs/file?path=%2Ftmp%2Flandscape.png",
|
|
169
|
+
mimeType: "image/png"
|
|
170
|
+
}
|
|
171
|
+
]
|
|
172
|
+
})
|
|
173
|
+
}
|
|
174
|
+
]
|
|
175
|
+
}
|
|
176
|
+
]
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
const result = extractMessagesFromState(state);
|
|
180
|
+
expect(result).not.toBeNull();
|
|
181
|
+
expect(result).toHaveLength(2);
|
|
182
|
+
expect(result?.[1]).toMatchObject({
|
|
183
|
+
role: "assistant",
|
|
184
|
+
content: "Image ready.",
|
|
185
|
+
attachments: [
|
|
186
|
+
{
|
|
187
|
+
kind: "image",
|
|
188
|
+
dataUrl: "/api/fs/file?path=%2Ftmp%2Flandscape.png"
|
|
189
|
+
}
|
|
190
|
+
]
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
it("extracts tool image attachments from artifact blocks", ()=>{
|
|
194
|
+
const state = {
|
|
195
|
+
createdAt: 5000,
|
|
196
|
+
values: {
|
|
197
|
+
messages: [
|
|
198
|
+
{
|
|
199
|
+
role: "user",
|
|
200
|
+
content: "Generate another image."
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
role: "tool",
|
|
204
|
+
content: "Generated image.",
|
|
205
|
+
artifact: [
|
|
206
|
+
{
|
|
207
|
+
type: "image",
|
|
208
|
+
mimeType: "image/png",
|
|
209
|
+
data: "abc123"
|
|
210
|
+
}
|
|
211
|
+
]
|
|
212
|
+
}
|
|
213
|
+
]
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
const result = extractMessagesFromState(state);
|
|
217
|
+
expect(result).not.toBeNull();
|
|
218
|
+
expect(result).toHaveLength(2);
|
|
219
|
+
expect(result?.[1]).toMatchObject({
|
|
220
|
+
role: "assistant",
|
|
221
|
+
content: "Generated image.",
|
|
222
|
+
attachments: [
|
|
223
|
+
{
|
|
224
|
+
kind: "image",
|
|
225
|
+
dataUrl: "data:image/png;base64,abc123"
|
|
226
|
+
}
|
|
227
|
+
]
|
|
228
|
+
});
|
|
229
|
+
});
|
|
104
230
|
});
|