@wingman-ai/gateway 0.2.5 → 0.3.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/README.md +9 -0
- package/dist/agent/config/agentConfig.cjs +12 -0
- package/dist/agent/config/agentConfig.d.ts +26 -0
- package/dist/agent/config/agentConfig.js +10 -1
- package/dist/agent/config/agentLoader.cjs +9 -0
- package/dist/agent/config/agentLoader.js +9 -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 +20 -1
- package/dist/agent/config/toolRegistry.d.ts +15 -0
- package/dist/agent/config/toolRegistry.js +20 -1
- package/dist/agent/tests/agentConfig.test.cjs +6 -1
- package/dist/agent/tests/agentConfig.test.js +6 -1
- package/dist/agent/tests/browserControlHelpers.test.cjs +35 -0
- package/dist/agent/tests/browserControlHelpers.test.d.ts +1 -0
- package/dist/agent/tests/browserControlHelpers.test.js +29 -0
- package/dist/agent/tests/browserControlTool.test.cjs +2117 -0
- package/dist/agent/tests/browserControlTool.test.d.ts +1 -0
- package/dist/agent/tests/browserControlTool.test.js +2111 -0
- 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/tests/toolRegistry.test.cjs +6 -0
- package/dist/agent/tests/toolRegistry.test.js +6 -0
- package/dist/agent/tools/browser_control.cjs +1282 -0
- package/dist/agent/tools/browser_control.d.ts +478 -0
- package/dist/agent/tools/browser_control.js +1242 -0
- package/dist/agent/tools/command_execute.cjs +1 -1
- package/dist/agent/tools/command_execute.js +1 -1
- package/dist/cli/commands/agent.cjs +16 -2
- package/dist/cli/commands/agent.js +16 -2
- package/dist/cli/commands/browser.cjs +603 -0
- package/dist/cli/commands/browser.d.ts +13 -0
- package/dist/cli/commands/browser.js +566 -0
- package/dist/cli/commands/gateway.cjs +18 -7
- package/dist/cli/commands/gateway.d.ts +5 -1
- package/dist/cli/commands/gateway.js +18 -7
- package/dist/cli/commands/init.cjs +134 -45
- package/dist/cli/commands/init.js +134 -45
- package/dist/cli/commands/skill.cjs +3 -2
- package/dist/cli/commands/skill.js +3 -2
- package/dist/cli/config/loader.cjs +15 -0
- package/dist/cli/config/loader.js +15 -0
- package/dist/cli/config/schema.cjs +51 -2
- package/dist/cli/config/schema.d.ts +51 -0
- package/dist/cli/config/schema.js +44 -1
- 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/cli/core/workspace.cjs +89 -0
- package/dist/cli/core/workspace.d.ts +1 -0
- package/dist/cli/core/workspace.js +55 -0
- package/dist/cli/index.cjs +53 -5
- package/dist/cli/index.js +53 -5
- package/dist/cli/types/browser.cjs +18 -0
- package/dist/cli/types/browser.d.ts +9 -0
- package/dist/cli/types/browser.js +0 -0
- 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/browserRelayServer.cjs +338 -0
- package/dist/gateway/browserRelayServer.d.ts +38 -0
- package/dist/gateway/browserRelayServer.js +301 -0
- package/dist/gateway/http/agents.cjs +22 -0
- package/dist/gateway/http/agents.js +22 -0
- package/dist/gateway/http/fs.cjs +76 -0
- package/dist/gateway/http/fs.js +77 -1
- package/dist/gateway/http/sessions.cjs +25 -5
- package/dist/gateway/http/sessions.js +25 -5
- package/dist/gateway/server.cjs +155 -17
- package/dist/gateway/server.d.ts +6 -1
- package/dist/gateway/server.js +148 -16
- package/dist/gateway/transport/websocket.cjs +45 -10
- package/dist/gateway/transport/websocket.d.ts +1 -0
- package/dist/gateway/transport/websocket.js +41 -9
- package/dist/gateway/types.d.ts +4 -0
- 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/agents-api.test.cjs +52 -0
- package/dist/tests/agents-api.test.js +53 -1
- package/dist/tests/browser-command.test.cjs +264 -0
- package/dist/tests/browser-command.test.d.ts +1 -0
- package/dist/tests/browser-command.test.js +258 -0
- package/dist/tests/browser-relay-server.test.cjs +20 -0
- package/dist/tests/browser-relay-server.test.d.ts +1 -0
- package/dist/tests/browser-relay-server.test.js +14 -0
- package/dist/tests/cli-config-loader.test.cjs +43 -0
- package/dist/tests/cli-config-loader.test.js +43 -0
- package/dist/tests/cli-init.test.cjs +61 -2
- package/dist/tests/cli-init.test.js +61 -2
- package/dist/tests/cli-workspace-root.test.cjs +114 -0
- package/dist/tests/cli-workspace-root.test.d.ts +1 -0
- package/dist/tests/cli-workspace-root.test.js +108 -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/fs-api.test.cjs +138 -0
- package/dist/tests/fs-api.test.d.ts +1 -0
- package/dist/tests/fs-api.test.js +132 -0
- package/dist/tests/gateway-command-workspace.test.cjs +150 -0
- package/dist/tests/gateway-command-workspace.test.d.ts +1 -0
- package/dist/tests/gateway-command-workspace.test.js +144 -0
- package/dist/tests/gateway-request-execution-overrides.test.cjs +42 -0
- package/dist/tests/gateway-request-execution-overrides.test.d.ts +1 -0
- package/dist/tests/gateway-request-execution-overrides.test.js +36 -0
- package/dist/tests/gateway.test.cjs +140 -1
- package/dist/tests/gateway.test.js +140 -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/tests/websocket-transport.test.cjs +31 -0
- package/dist/tests/websocket-transport.test.d.ts +1 -0
- package/dist/tests/websocket-transport.test.js +25 -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-BW9nM0J2.css +11 -0
- package/dist/webui/assets/index-C8-oboEC.js +278 -0
- package/dist/webui/index.html +2 -2
- package/extensions/wingman-browser-extension/README.md +27 -0
- package/extensions/wingman-browser-extension/background.js +416 -0
- package/extensions/wingman-browser-extension/manifest.json +19 -0
- package/extensions/wingman-browser-extension/options.html +156 -0
- package/extensions/wingman-browser-extension/options.js +106 -0
- package/package.json +18 -13
- package/{.wingman → templates}/agents/README.md +2 -1
- package/{.wingman → templates}/agents/coding/agent.md +5 -1
- package/{.wingman → templates}/agents/coding-v2/agent.md +58 -1
- package/templates/agents/game-dev/agent.md +101 -0
- package/templates/agents/game-dev/art-generation.md +38 -0
- package/templates/agents/game-dev/asset-refinement.md +17 -0
- package/templates/agents/game-dev/planning-idea.md +17 -0
- package/templates/agents/game-dev/ui-specialist.md +17 -0
- package/templates/agents/main/agent.md +29 -0
- package/{.wingman → templates}/agents/researcher/agent.md +9 -0
- package/{.wingman → templates}/agents/stock-trader/agent.md +1 -0
- package/.wingman/agents/main/agent.md +0 -22
- package/dist/webui/assets/index-C7EuTbnE.js +0 -270
- package/dist/webui/assets/index-DVWQluit.css +0 -11
- /package/{.wingman → templates}/agents/coding-v2/implementor.md +0 -0
- /package/{.wingman → templates}/agents/stock-trader/chain-curator.md +0 -0
- /package/{.wingman → templates}/agents/stock-trader/goal-translator.md +0 -0
- /package/{.wingman → templates}/agents/stock-trader/guardrails-veto.md +0 -0
- /package/{.wingman → templates}/agents/stock-trader/path-planner.md +0 -0
- /package/{.wingman → templates}/agents/stock-trader/regime-analyst.md +0 -0
- /package/{.wingman → templates}/agents/stock-trader/risk.md +0 -0
- /package/{.wingman → templates}/agents/stock-trader/selection.md +0 -0
- /package/{.wingman → templates}/agents/stock-trader/strategy-composer.md +0 -0
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.d = (exports1, definition)=>{
|
|
5
|
+
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: definition[key]
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
})();
|
|
11
|
+
(()=>{
|
|
12
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
13
|
+
})();
|
|
14
|
+
(()=>{
|
|
15
|
+
__webpack_require__.r = (exports1)=>{
|
|
16
|
+
if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
17
|
+
value: 'Module'
|
|
18
|
+
});
|
|
19
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
20
|
+
value: true
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
})();
|
|
24
|
+
var __webpack_exports__ = {};
|
|
25
|
+
__webpack_require__.r(__webpack_exports__);
|
|
26
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
27
|
+
persistAssistantImagesToDisk: ()=>persistAssistantImagesToDisk,
|
|
28
|
+
parseBase64DataUrl: ()=>parseBase64DataUrl,
|
|
29
|
+
resolveImageExtension: ()=>resolveImageExtension
|
|
30
|
+
});
|
|
31
|
+
const external_node_crypto_namespaceObject = require("node:crypto");
|
|
32
|
+
const external_node_fs_namespaceObject = require("node:fs");
|
|
33
|
+
const external_node_path_namespaceObject = require("node:path");
|
|
34
|
+
const DATA_URL_BASE64_PATTERN = /^data:([^;,]+);base64,(.+)$/i;
|
|
35
|
+
function persistAssistantImagesToDisk(input) {
|
|
36
|
+
if (!input.messages.length) return;
|
|
37
|
+
const mediaRoot = (0, external_node_path_namespaceObject.join)((0, external_node_path_namespaceObject.dirname)(input.dbPath), "media", sanitizePathSegment(input.sessionId));
|
|
38
|
+
for (const message of input.messages)if ("assistant" === message.role) {
|
|
39
|
+
if (Array.isArray(message.attachments) && 0 !== message.attachments.length) for (const attachment of message.attachments){
|
|
40
|
+
if (!attachment || "image" !== attachment.kind) continue;
|
|
41
|
+
if (attachment.path) continue;
|
|
42
|
+
const parsed = parseBase64DataUrl(attachment.dataUrl);
|
|
43
|
+
if (!parsed) continue;
|
|
44
|
+
if (!parsed.mimeType.toLowerCase().startsWith("image/")) continue;
|
|
45
|
+
let bytes;
|
|
46
|
+
try {
|
|
47
|
+
bytes = Buffer.from(parsed.data, "base64");
|
|
48
|
+
} catch {
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
if (0 === bytes.length) continue;
|
|
52
|
+
const extension = resolveImageExtension(parsed.mimeType);
|
|
53
|
+
const hash = (0, external_node_crypto_namespaceObject.createHash)("sha256").update(bytes).digest("hex").slice(0, 20);
|
|
54
|
+
const filename = `${hash}.${extension}`;
|
|
55
|
+
const outputPath = (0, external_node_path_namespaceObject.join)(mediaRoot, filename);
|
|
56
|
+
if (!(0, external_node_fs_namespaceObject.existsSync)(outputPath)) {
|
|
57
|
+
(0, external_node_fs_namespaceObject.mkdirSync)(mediaRoot, {
|
|
58
|
+
recursive: true
|
|
59
|
+
});
|
|
60
|
+
(0, external_node_fs_namespaceObject.writeFileSync)(outputPath, bytes);
|
|
61
|
+
}
|
|
62
|
+
attachment.path = outputPath;
|
|
63
|
+
if (!attachment.mimeType) attachment.mimeType = parsed.mimeType;
|
|
64
|
+
if ("number" != typeof attachment.size || attachment.size <= 0) attachment.size = bytes.length;
|
|
65
|
+
if (!attachment.name) attachment.name = `image-${hash.slice(0, 8)}.${extension}`;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function parseBase64DataUrl(dataUrl) {
|
|
70
|
+
if ("string" != typeof dataUrl) return null;
|
|
71
|
+
const match = dataUrl.match(DATA_URL_BASE64_PATTERN);
|
|
72
|
+
if (!match) return null;
|
|
73
|
+
return {
|
|
74
|
+
mimeType: match[1].trim().toLowerCase(),
|
|
75
|
+
data: match[2].trim()
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
function resolveImageExtension(mimeType) {
|
|
79
|
+
const normalized = (mimeType || "").trim().toLowerCase();
|
|
80
|
+
switch(normalized){
|
|
81
|
+
case "image/jpeg":
|
|
82
|
+
return "jpg";
|
|
83
|
+
case "image/png":
|
|
84
|
+
return "png";
|
|
85
|
+
case "image/webp":
|
|
86
|
+
return "webp";
|
|
87
|
+
case "image/gif":
|
|
88
|
+
return "gif";
|
|
89
|
+
case "image/svg+xml":
|
|
90
|
+
return "svg";
|
|
91
|
+
case "image/bmp":
|
|
92
|
+
return "bmp";
|
|
93
|
+
case "image/tiff":
|
|
94
|
+
return "tiff";
|
|
95
|
+
case "image/heic":
|
|
96
|
+
return "heic";
|
|
97
|
+
case "image/heif":
|
|
98
|
+
return "heif";
|
|
99
|
+
case "image/avif":
|
|
100
|
+
return "avif";
|
|
101
|
+
default:
|
|
102
|
+
{
|
|
103
|
+
const subtype = normalized.split("/")[1] || "";
|
|
104
|
+
const sanitized = subtype.replace(/[^a-z0-9]/g, "");
|
|
105
|
+
return sanitized || "img";
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
function sanitizePathSegment(value) {
|
|
110
|
+
const normalized = (value || "").trim();
|
|
111
|
+
if (!normalized) return "default-session";
|
|
112
|
+
const sanitized = normalized.replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
113
|
+
return sanitized.slice(0, 120) || "default-session";
|
|
114
|
+
}
|
|
115
|
+
exports.parseBase64DataUrl = __webpack_exports__.parseBase64DataUrl;
|
|
116
|
+
exports.persistAssistantImagesToDisk = __webpack_exports__.persistAssistantImagesToDisk;
|
|
117
|
+
exports.resolveImageExtension = __webpack_exports__.resolveImageExtension;
|
|
118
|
+
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
119
|
+
"parseBase64DataUrl",
|
|
120
|
+
"persistAssistantImagesToDisk",
|
|
121
|
+
"resolveImageExtension"
|
|
122
|
+
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
123
|
+
Object.defineProperty(exports, '__esModule', {
|
|
124
|
+
value: true
|
|
125
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface PersistableAttachment {
|
|
2
|
+
kind: "image" | "audio" | "file";
|
|
3
|
+
dataUrl: string;
|
|
4
|
+
mimeType?: string;
|
|
5
|
+
name?: string;
|
|
6
|
+
size?: number;
|
|
7
|
+
path?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface PersistableMessage {
|
|
10
|
+
role: "user" | "assistant";
|
|
11
|
+
attachments?: PersistableAttachment[];
|
|
12
|
+
}
|
|
13
|
+
type ParsedDataUrl = {
|
|
14
|
+
mimeType: string;
|
|
15
|
+
data: string;
|
|
16
|
+
};
|
|
17
|
+
export declare function persistAssistantImagesToDisk(input: {
|
|
18
|
+
dbPath: string;
|
|
19
|
+
sessionId: string;
|
|
20
|
+
messages: PersistableMessage[];
|
|
21
|
+
}): void;
|
|
22
|
+
export declare function parseBase64DataUrl(dataUrl: string): ParsedDataUrl | null;
|
|
23
|
+
export declare function resolveImageExtension(mimeType: string): string;
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { dirname, join } from "node:path";
|
|
4
|
+
const DATA_URL_BASE64_PATTERN = /^data:([^;,]+);base64,(.+)$/i;
|
|
5
|
+
function persistAssistantImagesToDisk(input) {
|
|
6
|
+
if (!input.messages.length) return;
|
|
7
|
+
const mediaRoot = join(dirname(input.dbPath), "media", sanitizePathSegment(input.sessionId));
|
|
8
|
+
for (const message of input.messages)if ("assistant" === message.role) {
|
|
9
|
+
if (Array.isArray(message.attachments) && 0 !== message.attachments.length) for (const attachment of message.attachments){
|
|
10
|
+
if (!attachment || "image" !== attachment.kind) continue;
|
|
11
|
+
if (attachment.path) continue;
|
|
12
|
+
const parsed = parseBase64DataUrl(attachment.dataUrl);
|
|
13
|
+
if (!parsed) continue;
|
|
14
|
+
if (!parsed.mimeType.toLowerCase().startsWith("image/")) continue;
|
|
15
|
+
let bytes;
|
|
16
|
+
try {
|
|
17
|
+
bytes = Buffer.from(parsed.data, "base64");
|
|
18
|
+
} catch {
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
if (0 === bytes.length) continue;
|
|
22
|
+
const extension = resolveImageExtension(parsed.mimeType);
|
|
23
|
+
const hash = createHash("sha256").update(bytes).digest("hex").slice(0, 20);
|
|
24
|
+
const filename = `${hash}.${extension}`;
|
|
25
|
+
const outputPath = join(mediaRoot, filename);
|
|
26
|
+
if (!existsSync(outputPath)) {
|
|
27
|
+
mkdirSync(mediaRoot, {
|
|
28
|
+
recursive: true
|
|
29
|
+
});
|
|
30
|
+
writeFileSync(outputPath, bytes);
|
|
31
|
+
}
|
|
32
|
+
attachment.path = outputPath;
|
|
33
|
+
if (!attachment.mimeType) attachment.mimeType = parsed.mimeType;
|
|
34
|
+
if ("number" != typeof attachment.size || attachment.size <= 0) attachment.size = bytes.length;
|
|
35
|
+
if (!attachment.name) attachment.name = `image-${hash.slice(0, 8)}.${extension}`;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function parseBase64DataUrl(dataUrl) {
|
|
40
|
+
if ("string" != typeof dataUrl) return null;
|
|
41
|
+
const match = dataUrl.match(DATA_URL_BASE64_PATTERN);
|
|
42
|
+
if (!match) return null;
|
|
43
|
+
return {
|
|
44
|
+
mimeType: match[1].trim().toLowerCase(),
|
|
45
|
+
data: match[2].trim()
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function resolveImageExtension(mimeType) {
|
|
49
|
+
const normalized = (mimeType || "").trim().toLowerCase();
|
|
50
|
+
switch(normalized){
|
|
51
|
+
case "image/jpeg":
|
|
52
|
+
return "jpg";
|
|
53
|
+
case "image/png":
|
|
54
|
+
return "png";
|
|
55
|
+
case "image/webp":
|
|
56
|
+
return "webp";
|
|
57
|
+
case "image/gif":
|
|
58
|
+
return "gif";
|
|
59
|
+
case "image/svg+xml":
|
|
60
|
+
return "svg";
|
|
61
|
+
case "image/bmp":
|
|
62
|
+
return "bmp";
|
|
63
|
+
case "image/tiff":
|
|
64
|
+
return "tiff";
|
|
65
|
+
case "image/heic":
|
|
66
|
+
return "heic";
|
|
67
|
+
case "image/heif":
|
|
68
|
+
return "heif";
|
|
69
|
+
case "image/avif":
|
|
70
|
+
return "avif";
|
|
71
|
+
default:
|
|
72
|
+
{
|
|
73
|
+
const subtype = normalized.split("/")[1] || "";
|
|
74
|
+
const sanitized = subtype.replace(/[^a-z0-9]/g, "");
|
|
75
|
+
return sanitized || "img";
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function sanitizePathSegment(value) {
|
|
80
|
+
const normalized = (value || "").trim();
|
|
81
|
+
if (!normalized) return "default-session";
|
|
82
|
+
const sanitized = normalized.replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
83
|
+
return sanitized.slice(0, 120) || "default-session";
|
|
84
|
+
}
|
|
85
|
+
export { parseBase64DataUrl, persistAssistantImagesToDisk, resolveImageExtension };
|