@wingman-ai/gateway 0.4.1 → 0.4.3
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 +14 -0
- package/dist/agent/config/mcpClientManager.cjs +104 -1
- package/dist/agent/config/mcpClientManager.d.ts +30 -0
- package/dist/agent/config/mcpClientManager.js +104 -1
- package/dist/agent/config/modelFactory.cjs +10 -0
- package/dist/agent/config/modelFactory.js +10 -0
- package/dist/agent/config/xaiImageModel.cjs +242 -0
- package/dist/agent/config/xaiImageModel.d.ts +33 -0
- package/dist/agent/config/xaiImageModel.js +202 -0
- package/dist/agent/tests/mcpClientManager.test.cjs +116 -0
- package/dist/agent/tests/mcpClientManager.test.js +117 -1
- package/dist/agent/tests/mcpResourceTools.test.cjs +101 -0
- package/dist/agent/tests/mcpResourceTools.test.d.ts +1 -0
- package/dist/agent/tests/mcpResourceTools.test.js +95 -0
- package/dist/agent/tests/modelFactory.test.cjs +16 -2
- package/dist/agent/tests/modelFactory.test.js +16 -2
- package/dist/agent/tests/xaiImageModel.test.cjs +194 -0
- package/dist/agent/tests/xaiImageModel.test.d.ts +1 -0
- package/dist/agent/tests/xaiImageModel.test.js +188 -0
- package/dist/agent/tools/mcp_resources.cjs +111 -0
- package/dist/agent/tools/mcp_resources.d.ts +3 -0
- package/dist/agent/tools/mcp_resources.js +77 -0
- package/dist/bench/adapters/commandAdapter.cjs +93 -0
- package/dist/bench/adapters/commandAdapter.d.ts +6 -0
- package/dist/bench/adapters/commandAdapter.js +59 -0
- package/dist/bench/adapters/helpers.cjs +170 -0
- package/dist/bench/adapters/helpers.d.ts +7 -0
- package/dist/bench/adapters/helpers.js +133 -0
- package/dist/bench/adapters/index.cjs +41 -0
- package/dist/bench/adapters/index.d.ts +2 -0
- package/dist/bench/adapters/index.js +7 -0
- package/dist/bench/adapters/wingmanCliAdapter.cjs +100 -0
- package/dist/bench/adapters/wingmanCliAdapter.d.ts +6 -0
- package/dist/bench/adapters/wingmanCliAdapter.js +66 -0
- package/dist/bench/cleanup.cjs +122 -0
- package/dist/bench/cleanup.d.ts +9 -0
- package/dist/bench/cleanup.js +85 -0
- package/dist/bench/config.cjs +190 -0
- package/dist/bench/config.d.ts +2 -0
- package/dist/bench/config.js +156 -0
- package/dist/bench/index.cjs +43 -0
- package/dist/bench/index.d.ts +3 -0
- package/dist/bench/index.js +3 -0
- package/dist/bench/official.cjs +616 -0
- package/dist/bench/official.d.ts +80 -0
- package/dist/bench/official.js +546 -0
- package/dist/bench/officialCli.cjs +204 -0
- package/dist/bench/officialCli.d.ts +5 -0
- package/dist/bench/officialCli.js +170 -0
- package/dist/bench/process.cjs +78 -0
- package/dist/bench/process.d.ts +14 -0
- package/dist/bench/process.js +44 -0
- package/dist/bench/runner.cjs +237 -0
- package/dist/bench/runner.d.ts +7 -0
- package/dist/bench/runner.js +197 -0
- package/dist/bench/scoring.cjs +171 -0
- package/dist/bench/scoring.d.ts +9 -0
- package/dist/bench/scoring.js +137 -0
- package/dist/bench/types.cjs +18 -0
- package/dist/bench/types.d.ts +200 -0
- package/dist/bench/types.js +0 -0
- package/dist/bench/validator.cjs +92 -0
- package/dist/bench/validator.d.ts +2 -0
- package/dist/bench/validator.js +58 -0
- package/dist/cli/commands/init.cjs +135 -1
- package/dist/cli/commands/init.js +136 -2
- package/dist/cli/commands/skill.cjs +7 -3
- package/dist/cli/commands/skill.js +7 -3
- package/dist/cli/config/loader.cjs +7 -3
- package/dist/cli/config/loader.js +7 -3
- package/dist/cli/config/schema.cjs +63 -10
- package/dist/cli/config/schema.d.ts +64 -4
- package/dist/cli/config/schema.js +59 -9
- package/dist/cli/config/warnings.cjs +119 -51
- package/dist/cli/config/warnings.js +119 -51
- package/dist/cli/core/agentInvoker.cjs +58 -13
- package/dist/cli/core/agentInvoker.d.ts +1 -0
- package/dist/cli/core/agentInvoker.js +58 -13
- package/dist/cli/core/imagePersistence.cjs +17 -1
- package/dist/cli/core/imagePersistence.d.ts +2 -0
- package/dist/cli/core/imagePersistence.js +13 -3
- package/dist/cli/core/sessionManager.cjs +2 -0
- package/dist/cli/core/sessionManager.js +3 -1
- package/dist/cli/services/skillRepository.cjs +155 -69
- package/dist/cli/services/skillRepository.d.ts +7 -2
- package/dist/cli/services/skillRepository.js +155 -69
- package/dist/cli/services/skillService.cjs +93 -26
- package/dist/cli/services/skillService.d.ts +7 -0
- package/dist/cli/services/skillService.js +96 -29
- package/dist/cli/types/skill.d.ts +8 -3
- package/dist/cli/types.d.ts +18 -0
- package/dist/gateway/adapters/teams.cjs +419 -0
- package/dist/gateway/adapters/teams.d.ts +47 -0
- package/dist/gateway/adapters/teams.js +361 -0
- package/dist/gateway/http/sms.cjs +286 -0
- package/dist/gateway/http/sms.d.ts +4 -0
- package/dist/gateway/http/sms.js +249 -0
- package/dist/gateway/server.cjs +54 -3
- package/dist/gateway/server.d.ts +2 -0
- package/dist/gateway/server.js +54 -3
- package/dist/gateway/sms/commands.cjs +116 -0
- package/dist/gateway/sms/commands.d.ts +15 -0
- package/dist/gateway/sms/commands.js +79 -0
- package/dist/gateway/sms/control.cjs +118 -0
- package/dist/gateway/sms/control.d.ts +18 -0
- package/dist/gateway/sms/control.js +84 -0
- package/dist/gateway/sms/policyStore.cjs +198 -0
- package/dist/gateway/sms/policyStore.d.ts +37 -0
- package/dist/gateway/sms/policyStore.js +161 -0
- package/dist/providers/registry.cjs +1 -0
- package/dist/providers/registry.js +1 -0
- package/dist/skills/activation.cjs +92 -0
- package/dist/skills/activation.d.ts +12 -0
- package/dist/skills/activation.js +58 -0
- package/dist/skills/bin-requirements.cjs +63 -0
- package/dist/skills/bin-requirements.d.ts +3 -0
- package/dist/skills/bin-requirements.js +26 -0
- package/dist/skills/metadata.cjs +141 -0
- package/dist/skills/metadata.d.ts +29 -0
- package/dist/skills/metadata.js +104 -0
- package/dist/skills/overlay.cjs +75 -0
- package/dist/skills/overlay.d.ts +2 -0
- package/dist/skills/overlay.js +38 -0
- package/dist/tests/cli-config-loader.test.cjs +7 -3
- package/dist/tests/cli-config-loader.test.js +7 -3
- package/dist/tests/cli-config-warnings.test.cjs +41 -0
- package/dist/tests/cli-config-warnings.test.js +41 -0
- package/dist/tests/cli-init.test.cjs +86 -26
- package/dist/tests/cli-init.test.js +86 -26
- package/dist/tests/config-json-schema.test.cjs +12 -0
- package/dist/tests/config-json-schema.test.js +12 -0
- package/dist/tests/gateway-http-security.test.cjs +21 -0
- package/dist/tests/gateway-http-security.test.js +21 -0
- package/dist/tests/gateway-origin-policy.test.cjs +22 -0
- package/dist/tests/gateway-origin-policy.test.js +22 -0
- package/dist/tests/gateway.test.cjs +57 -0
- package/dist/tests/gateway.test.js +57 -0
- package/dist/tests/imagePersistence.test.cjs +26 -0
- package/dist/tests/imagePersistence.test.js +27 -1
- package/dist/tests/run-terminal-bench-official-script.test.cjs +61 -0
- package/dist/tests/run-terminal-bench-official-script.test.d.ts +1 -0
- package/dist/tests/run-terminal-bench-official-script.test.js +55 -0
- package/dist/tests/sessions-api.test.cjs +69 -1
- package/dist/tests/sessions-api.test.js +70 -2
- package/dist/tests/skill-activation.test.cjs +86 -0
- package/dist/tests/skill-activation.test.d.ts +1 -0
- package/dist/tests/skill-activation.test.js +80 -0
- package/dist/tests/skill-metadata.test.cjs +119 -0
- package/dist/tests/skill-metadata.test.d.ts +1 -0
- package/dist/tests/skill-metadata.test.js +113 -0
- package/dist/tests/skill-repository.test.cjs +363 -0
- package/dist/tests/skill-repository.test.js +363 -0
- package/dist/tests/sms-api.test.cjs +183 -0
- package/dist/tests/sms-api.test.d.ts +1 -0
- package/dist/tests/sms-api.test.js +177 -0
- package/dist/tests/sms-commands.test.cjs +90 -0
- package/dist/tests/sms-commands.test.d.ts +1 -0
- package/dist/tests/sms-commands.test.js +84 -0
- package/dist/tests/sms-policy-store.test.cjs +69 -0
- package/dist/tests/sms-policy-store.test.d.ts +1 -0
- package/dist/tests/sms-policy-store.test.js +63 -0
- package/dist/tests/teams-adapter.test.cjs +58 -0
- package/dist/tests/teams-adapter.test.d.ts +1 -0
- package/dist/tests/teams-adapter.test.js +52 -0
- package/dist/tests/terminal-bench-adapters-helpers.test.cjs +64 -0
- package/dist/tests/terminal-bench-adapters-helpers.test.d.ts +1 -0
- package/dist/tests/terminal-bench-adapters-helpers.test.js +58 -0
- package/dist/tests/terminal-bench-cleanup.test.cjs +93 -0
- package/dist/tests/terminal-bench-cleanup.test.d.ts +1 -0
- package/dist/tests/terminal-bench-cleanup.test.js +87 -0
- package/dist/tests/terminal-bench-config.test.cjs +62 -0
- package/dist/tests/terminal-bench-config.test.d.ts +1 -0
- package/dist/tests/terminal-bench-config.test.js +56 -0
- package/dist/tests/terminal-bench-official.test.cjs +194 -0
- package/dist/tests/terminal-bench-official.test.d.ts +1 -0
- package/dist/tests/terminal-bench-official.test.js +188 -0
- package/dist/tests/terminal-bench-runner.test.cjs +82 -0
- package/dist/tests/terminal-bench-runner.test.d.ts +1 -0
- package/dist/tests/terminal-bench-runner.test.js +76 -0
- package/dist/tests/terminal-bench-scoring.test.cjs +128 -0
- package/dist/tests/terminal-bench-scoring.test.d.ts +1 -0
- package/dist/tests/terminal-bench-scoring.test.js +122 -0
- package/dist/tools/mcp-fal-ai.cjs +1 -1
- package/dist/tools/mcp-fal-ai.js +1 -1
- package/dist/webui/assets/index-Cyg_Hs57.css +11 -0
- package/dist/webui/assets/{index-BMekSELC.js → index-DZXLLjaA.js} +109 -109
- package/dist/webui/index.html +2 -2
- package/package.json +14 -5
- package/skills/gog/SKILL.md +1 -1
- package/skills/weather/SKILL.md +1 -1
- package/templates/agents/game-dev/agent.md +122 -63
- package/templates/agents/game-dev/art-director.md +106 -0
- package/templates/agents/game-dev/game-designer.md +87 -0
- package/templates/agents/game-dev/scene-engineer.md +474 -0
- package/dist/webui/assets/index-Cwkg4DKj.css +0 -11
- package/skills/ui-registry/SKILL.md +0 -35
- package/templates/agents/game-dev/art-generation.md +0 -38
- package/templates/agents/game-dev/asset-refinement.md +0 -17
- package/templates/agents/game-dev/planning-idea.md +0 -17
- package/templates/agents/game-dev/ui-specialist.md +0 -17
|
@@ -18,6 +18,18 @@ const jsonSchema_cjs_namespaceObject = require("../cli/config/jsonSchema.cjs");
|
|
|
18
18
|
const scannerArgsDefault = schema.properties.skills.properties.security.properties.scannerArgs.default;
|
|
19
19
|
(0, external_vitest_namespaceObject.expect)(scannerArgsDefault).toContain("mcp-scan>=0.4,<0.5");
|
|
20
20
|
});
|
|
21
|
+
(0, external_vitest_namespaceObject.it)("exposes hybrid defaults for skill sources", ()=>{
|
|
22
|
+
const schema = (0, jsonSchema_cjs_namespaceObject.buildWingmanConfigJsonSchema)();
|
|
23
|
+
const repositoriesDefault = schema.properties.skills.properties.repositories.default;
|
|
24
|
+
const providerDefault = schema.properties.skills.properties.provider.default;
|
|
25
|
+
(0, external_vitest_namespaceObject.expect)(providerDefault).toBe("hybrid");
|
|
26
|
+
(0, external_vitest_namespaceObject.expect)(repositoriesDefault).toEqual([
|
|
27
|
+
{
|
|
28
|
+
owner: "RussellCanfield",
|
|
29
|
+
name: "wingman-ai"
|
|
30
|
+
}
|
|
31
|
+
]);
|
|
32
|
+
});
|
|
21
33
|
});
|
|
22
34
|
for(var __rspack_i in __webpack_exports__)exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
23
35
|
Object.defineProperty(exports, '__esModule', {
|
|
@@ -16,4 +16,16 @@ describe("wingman config json schema", ()=>{
|
|
|
16
16
|
const scannerArgsDefault = schema.properties.skills.properties.security.properties.scannerArgs.default;
|
|
17
17
|
expect(scannerArgsDefault).toContain("mcp-scan>=0.4,<0.5");
|
|
18
18
|
});
|
|
19
|
+
it("exposes hybrid defaults for skill sources", ()=>{
|
|
20
|
+
const schema = buildWingmanConfigJsonSchema();
|
|
21
|
+
const repositoriesDefault = schema.properties.skills.properties.repositories.default;
|
|
22
|
+
const providerDefault = schema.properties.skills.properties.provider.default;
|
|
23
|
+
expect(providerDefault).toBe("hybrid");
|
|
24
|
+
expect(repositoriesDefault).toEqual([
|
|
25
|
+
{
|
|
26
|
+
owner: "RussellCanfield",
|
|
27
|
+
name: "wingman-ai"
|
|
28
|
+
}
|
|
29
|
+
]);
|
|
30
|
+
});
|
|
19
31
|
});
|
|
@@ -93,6 +93,27 @@ function createTestSocket(initialData) {
|
|
|
93
93
|
(0, external_vitest_namespaceObject.expect)(allowed.status).toBe(204);
|
|
94
94
|
(0, external_vitest_namespaceObject.expect)(allowed.headers.get("access-control-allow-origin")).toBe("http://localhost:5173");
|
|
95
95
|
});
|
|
96
|
+
(0, external_vitest_namespaceObject.it)("allows tauri loopback origin preflight for desktop clients", async ()=>{
|
|
97
|
+
const server = createGateway({
|
|
98
|
+
host: "127.0.0.1",
|
|
99
|
+
port: 18789,
|
|
100
|
+
auth: {
|
|
101
|
+
mode: "token",
|
|
102
|
+
token: "test-token"
|
|
103
|
+
},
|
|
104
|
+
requireAuth: true
|
|
105
|
+
});
|
|
106
|
+
const internals = getGatewayInternals(server);
|
|
107
|
+
const allowed = await internals.handleUiRequest(new Request("http://127.0.0.1:18789/api/providers", {
|
|
108
|
+
method: "OPTIONS",
|
|
109
|
+
headers: {
|
|
110
|
+
Origin: "tauri://localhost",
|
|
111
|
+
"Access-Control-Request-Method": "GET"
|
|
112
|
+
}
|
|
113
|
+
}));
|
|
114
|
+
(0, external_vitest_namespaceObject.expect)(allowed.status).toBe(204);
|
|
115
|
+
(0, external_vitest_namespaceObject.expect)(allowed.headers.get("access-control-allow-origin")).toBe("tauri://localhost");
|
|
116
|
+
});
|
|
96
117
|
(0, external_vitest_namespaceObject.it)("does not trust tailscale identity headers on non-loopback hosts", ()=>{
|
|
97
118
|
const server = createGateway({
|
|
98
119
|
host: "0.0.0.0",
|
|
@@ -91,6 +91,27 @@ describe("gateway HTTP security", ()=>{
|
|
|
91
91
|
expect(allowed.status).toBe(204);
|
|
92
92
|
expect(allowed.headers.get("access-control-allow-origin")).toBe("http://localhost:5173");
|
|
93
93
|
});
|
|
94
|
+
it("allows tauri loopback origin preflight for desktop clients", async ()=>{
|
|
95
|
+
const server = createGateway({
|
|
96
|
+
host: "127.0.0.1",
|
|
97
|
+
port: 18789,
|
|
98
|
+
auth: {
|
|
99
|
+
mode: "token",
|
|
100
|
+
token: "test-token"
|
|
101
|
+
},
|
|
102
|
+
requireAuth: true
|
|
103
|
+
});
|
|
104
|
+
const internals = getGatewayInternals(server);
|
|
105
|
+
const allowed = await internals.handleUiRequest(new Request("http://127.0.0.1:18789/api/providers", {
|
|
106
|
+
method: "OPTIONS",
|
|
107
|
+
headers: {
|
|
108
|
+
Origin: "tauri://localhost",
|
|
109
|
+
"Access-Control-Request-Method": "GET"
|
|
110
|
+
}
|
|
111
|
+
}));
|
|
112
|
+
expect(allowed.status).toBe(204);
|
|
113
|
+
expect(allowed.headers.get("access-control-allow-origin")).toBe("tauri://localhost");
|
|
114
|
+
});
|
|
94
115
|
it("does not trust tailscale identity headers on non-loopback hosts", ()=>{
|
|
95
116
|
const server = createGateway({
|
|
96
117
|
host: "0.0.0.0",
|
|
@@ -20,6 +20,17 @@ const server_cjs_namespaceObject = require("../gateway/server.cjs");
|
|
|
20
20
|
});
|
|
21
21
|
(0, external_vitest_namespaceObject.expect)(allowed).toBe(true);
|
|
22
22
|
});
|
|
23
|
+
(0, external_vitest_namespaceObject.it)("allows tauri loopback origins for desktop clients", ()=>{
|
|
24
|
+
const allowed = (0, server_cjs_namespaceObject.isGatewayOriginAllowed)({
|
|
25
|
+
origin: "tauri://localhost",
|
|
26
|
+
requestUrl: "http://127.0.0.1:18789/api/sessions",
|
|
27
|
+
gatewayHost: "127.0.0.1",
|
|
28
|
+
gatewayPort: 18789,
|
|
29
|
+
controlUiEnabled: true,
|
|
30
|
+
controlUiPort: 18790
|
|
31
|
+
});
|
|
32
|
+
(0, external_vitest_namespaceObject.expect)(allowed).toBe(true);
|
|
33
|
+
});
|
|
23
34
|
(0, external_vitest_namespaceObject.it)("rejects unrelated internet origins", ()=>{
|
|
24
35
|
const allowed = (0, server_cjs_namespaceObject.isGatewayOriginAllowed)({
|
|
25
36
|
origin: "https://evil.example",
|
|
@@ -53,6 +64,17 @@ const server_cjs_namespaceObject = require("../gateway/server.cjs");
|
|
|
53
64
|
});
|
|
54
65
|
(0, external_vitest_namespaceObject.expect)(allowed).toBe(false);
|
|
55
66
|
});
|
|
67
|
+
(0, external_vitest_namespaceObject.it)("rejects tauri origins for non-loopback gateways", ()=>{
|
|
68
|
+
const allowed = (0, server_cjs_namespaceObject.isGatewayOriginAllowed)({
|
|
69
|
+
origin: "tauri://localhost",
|
|
70
|
+
requestUrl: "http://192.168.1.50:18789/api/sessions",
|
|
71
|
+
gatewayHost: "0.0.0.0",
|
|
72
|
+
gatewayPort: 18789,
|
|
73
|
+
controlUiEnabled: true,
|
|
74
|
+
controlUiPort: 18790
|
|
75
|
+
});
|
|
76
|
+
(0, external_vitest_namespaceObject.expect)(allowed).toBe(false);
|
|
77
|
+
});
|
|
56
78
|
});
|
|
57
79
|
for(var __rspack_i in __webpack_exports__)exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
58
80
|
Object.defineProperty(exports, '__esModule', {
|
|
@@ -18,6 +18,17 @@ describe("gateway origin policy", ()=>{
|
|
|
18
18
|
});
|
|
19
19
|
expect(allowed).toBe(true);
|
|
20
20
|
});
|
|
21
|
+
it("allows tauri loopback origins for desktop clients", ()=>{
|
|
22
|
+
const allowed = isGatewayOriginAllowed({
|
|
23
|
+
origin: "tauri://localhost",
|
|
24
|
+
requestUrl: "http://127.0.0.1:18789/api/sessions",
|
|
25
|
+
gatewayHost: "127.0.0.1",
|
|
26
|
+
gatewayPort: 18789,
|
|
27
|
+
controlUiEnabled: true,
|
|
28
|
+
controlUiPort: 18790
|
|
29
|
+
});
|
|
30
|
+
expect(allowed).toBe(true);
|
|
31
|
+
});
|
|
21
32
|
it("rejects unrelated internet origins", ()=>{
|
|
22
33
|
const allowed = isGatewayOriginAllowed({
|
|
23
34
|
origin: "https://evil.example",
|
|
@@ -51,4 +62,15 @@ describe("gateway origin policy", ()=>{
|
|
|
51
62
|
});
|
|
52
63
|
expect(allowed).toBe(false);
|
|
53
64
|
});
|
|
65
|
+
it("rejects tauri origins for non-loopback gateways", ()=>{
|
|
66
|
+
const allowed = isGatewayOriginAllowed({
|
|
67
|
+
origin: "tauri://localhost",
|
|
68
|
+
requestUrl: "http://192.168.1.50:18789/api/sessions",
|
|
69
|
+
gatewayHost: "0.0.0.0",
|
|
70
|
+
gatewayPort: 18789,
|
|
71
|
+
controlUiEnabled: true,
|
|
72
|
+
controlUiPort: 18790
|
|
73
|
+
});
|
|
74
|
+
expect(allowed).toBe(false);
|
|
75
|
+
});
|
|
54
76
|
});
|
|
@@ -22,6 +22,40 @@ external_vitest_namespaceObject.vi.mock("@/cli/core/agentInvoker.js", ()=>({
|
|
|
22
22
|
AgentInvoker: class {
|
|
23
23
|
async invokeAgent(_agentId, content, _sessionId, _attachments, options) {
|
|
24
24
|
if ("throw-no-event" === content) throw new Error("Synthetic invocation failure");
|
|
25
|
+
if ("stream-model-failure-no-error" === content) {
|
|
26
|
+
this.outputManager?.emitAgentStream?.({
|
|
27
|
+
event: "on_chain_end",
|
|
28
|
+
run_id: "model-failure-run-1",
|
|
29
|
+
name: "ChannelWrite<branch:to:todoListMiddleware.after_model>",
|
|
30
|
+
data: {
|
|
31
|
+
output: [
|
|
32
|
+
{
|
|
33
|
+
lg_name: "Command",
|
|
34
|
+
update: {
|
|
35
|
+
messages: [
|
|
36
|
+
{
|
|
37
|
+
type: "constructor",
|
|
38
|
+
id: [
|
|
39
|
+
"langchain_core",
|
|
40
|
+
"messages",
|
|
41
|
+
"AIMessage"
|
|
42
|
+
],
|
|
43
|
+
kwargs: {
|
|
44
|
+
id: "model-failure-msg-1",
|
|
45
|
+
content: "Model call failed after 3 attempts with Error: xAI image generation failed: Prompt len is larger than the maximum allowed length which is 8000"
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
]
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
],
|
|
52
|
+
input: {}
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
return {
|
|
56
|
+
streaming: true
|
|
57
|
+
};
|
|
58
|
+
}
|
|
25
59
|
const signal = options?.signal;
|
|
26
60
|
await new Promise((resolve)=>{
|
|
27
61
|
const timer = setTimeout(resolve, 75);
|
|
@@ -412,6 +446,29 @@ describeIfBun("Gateway", ()=>{
|
|
|
412
446
|
});
|
|
413
447
|
requester.close();
|
|
414
448
|
});
|
|
449
|
+
(0, external_vitest_namespaceObject.it)("does not auto-convert streamed model failure text into agent-error", async ()=>{
|
|
450
|
+
const requester = await connectClient("session-streamed-failure-requester");
|
|
451
|
+
const requestId = "req-streamed-failure-no-error";
|
|
452
|
+
const sessionId = "session-streamed-failure-no-error";
|
|
453
|
+
requester.send(JSON.stringify({
|
|
454
|
+
type: "req:agent",
|
|
455
|
+
id: requestId,
|
|
456
|
+
payload: {
|
|
457
|
+
agentId: "main",
|
|
458
|
+
sessionKey: sessionId,
|
|
459
|
+
content: "stream-model-failure-no-error"
|
|
460
|
+
},
|
|
461
|
+
timestamp: Date.now()
|
|
462
|
+
}));
|
|
463
|
+
const streamMsg = await waitForMessage(requester, (msg)=>"event:agent" === msg.type && msg.id === requestId && msg.payload?.type === "agent-stream" && msg.payload?.chunk?.event === "on_chain_end", 10000);
|
|
464
|
+
(0, external_vitest_namespaceObject.expect)(JSON.stringify(streamMsg.payload?.chunk?.data || {})).toContain("Model call failed after 3 attempts");
|
|
465
|
+
const completeMsg = await waitForMessage(requester, (msg)=>"event:agent" === msg.type && msg.id === requestId && msg.payload?.type === "agent-complete", 10000);
|
|
466
|
+
(0, external_vitest_namespaceObject.expect)(completeMsg.payload?.sessionId).toBe(sessionId);
|
|
467
|
+
(0, external_vitest_namespaceObject.expect)(completeMsg.payload?.agentId).toBe("main");
|
|
468
|
+
const terminalErrorEvents = await collectMessages(requester, (msg)=>"event:agent" === msg.type && msg.id === requestId && msg.payload?.type === "agent-error", 400);
|
|
469
|
+
(0, external_vitest_namespaceObject.expect)(terminalErrorEvents).toHaveLength(0);
|
|
470
|
+
requester.close();
|
|
471
|
+
});
|
|
415
472
|
(0, external_vitest_namespaceObject.it)("should emit a single agent-complete terminal event per request", async ()=>{
|
|
416
473
|
const requester = await connectClient("session-single-complete-requester");
|
|
417
474
|
const requestId = "req-single-complete";
|
|
@@ -20,6 +20,40 @@ vi.mock("@/cli/core/agentInvoker.js", ()=>({
|
|
|
20
20
|
AgentInvoker: class {
|
|
21
21
|
async invokeAgent(_agentId, content, _sessionId, _attachments, options) {
|
|
22
22
|
if ("throw-no-event" === content) throw new Error("Synthetic invocation failure");
|
|
23
|
+
if ("stream-model-failure-no-error" === content) {
|
|
24
|
+
this.outputManager?.emitAgentStream?.({
|
|
25
|
+
event: "on_chain_end",
|
|
26
|
+
run_id: "model-failure-run-1",
|
|
27
|
+
name: "ChannelWrite<branch:to:todoListMiddleware.after_model>",
|
|
28
|
+
data: {
|
|
29
|
+
output: [
|
|
30
|
+
{
|
|
31
|
+
lg_name: "Command",
|
|
32
|
+
update: {
|
|
33
|
+
messages: [
|
|
34
|
+
{
|
|
35
|
+
type: "constructor",
|
|
36
|
+
id: [
|
|
37
|
+
"langchain_core",
|
|
38
|
+
"messages",
|
|
39
|
+
"AIMessage"
|
|
40
|
+
],
|
|
41
|
+
kwargs: {
|
|
42
|
+
id: "model-failure-msg-1",
|
|
43
|
+
content: "Model call failed after 3 attempts with Error: xAI image generation failed: Prompt len is larger than the maximum allowed length which is 8000"
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
]
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
],
|
|
50
|
+
input: {}
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
return {
|
|
54
|
+
streaming: true
|
|
55
|
+
};
|
|
56
|
+
}
|
|
23
57
|
const signal = options?.signal;
|
|
24
58
|
await new Promise((resolve)=>{
|
|
25
59
|
const timer = setTimeout(resolve, 75);
|
|
@@ -410,6 +444,29 @@ describeIfBun("Gateway", ()=>{
|
|
|
410
444
|
});
|
|
411
445
|
requester.close();
|
|
412
446
|
});
|
|
447
|
+
it("does not auto-convert streamed model failure text into agent-error", async ()=>{
|
|
448
|
+
const requester = await connectClient("session-streamed-failure-requester");
|
|
449
|
+
const requestId = "req-streamed-failure-no-error";
|
|
450
|
+
const sessionId = "session-streamed-failure-no-error";
|
|
451
|
+
requester.send(JSON.stringify({
|
|
452
|
+
type: "req:agent",
|
|
453
|
+
id: requestId,
|
|
454
|
+
payload: {
|
|
455
|
+
agentId: "main",
|
|
456
|
+
sessionKey: sessionId,
|
|
457
|
+
content: "stream-model-failure-no-error"
|
|
458
|
+
},
|
|
459
|
+
timestamp: Date.now()
|
|
460
|
+
}));
|
|
461
|
+
const streamMsg = await waitForMessage(requester, (msg)=>"event:agent" === msg.type && msg.id === requestId && msg.payload?.type === "agent-stream" && msg.payload?.chunk?.event === "on_chain_end", 10000);
|
|
462
|
+
expect(JSON.stringify(streamMsg.payload?.chunk?.data || {})).toContain("Model call failed after 3 attempts");
|
|
463
|
+
const completeMsg = await waitForMessage(requester, (msg)=>"event:agent" === msg.type && msg.id === requestId && msg.payload?.type === "agent-complete", 10000);
|
|
464
|
+
expect(completeMsg.payload?.sessionId).toBe(sessionId);
|
|
465
|
+
expect(completeMsg.payload?.agentId).toBe("main");
|
|
466
|
+
const terminalErrorEvents = await collectMessages(requester, (msg)=>"event:agent" === msg.type && msg.id === requestId && msg.payload?.type === "agent-error", 400);
|
|
467
|
+
expect(terminalErrorEvents).toHaveLength(0);
|
|
468
|
+
requester.close();
|
|
469
|
+
});
|
|
413
470
|
it("should emit a single agent-complete terminal event per request", async ()=>{
|
|
414
471
|
const requester = await connectClient("session-single-complete-requester");
|
|
415
472
|
const requestId = "req-single-complete";
|
|
@@ -128,6 +128,32 @@ const PNG_DATA_URL = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQA
|
|
|
128
128
|
(0, external_vitest_namespaceObject.expect)(firstPath).toBeTruthy();
|
|
129
129
|
(0, external_vitest_namespaceObject.expect)(secondPath).toBe(firstPath);
|
|
130
130
|
});
|
|
131
|
+
(0, external_vitest_namespaceObject.it)("removes persisted session media directory", ()=>{
|
|
132
|
+
const tempDir = (0, external_node_fs_namespaceObject.mkdtempSync)((0, external_node_path_namespaceObject.join)((0, external_node_os_namespaceObject.tmpdir)(), "wingman-image-store-"));
|
|
133
|
+
tempDirs.push(tempDir);
|
|
134
|
+
const dbPath = (0, external_node_path_namespaceObject.join)(tempDir, "wingman.db");
|
|
135
|
+
const sessionId = "session-cleanup";
|
|
136
|
+
const messages = [
|
|
137
|
+
{
|
|
138
|
+
role: "assistant",
|
|
139
|
+
attachments: [
|
|
140
|
+
{
|
|
141
|
+
kind: "image",
|
|
142
|
+
dataUrl: PNG_DATA_URL
|
|
143
|
+
}
|
|
144
|
+
]
|
|
145
|
+
}
|
|
146
|
+
];
|
|
147
|
+
(0, imagePersistence_cjs_namespaceObject.persistAssistantImagesToDisk)({
|
|
148
|
+
dbPath,
|
|
149
|
+
sessionId,
|
|
150
|
+
messages
|
|
151
|
+
});
|
|
152
|
+
const mediaDir = (0, imagePersistence_cjs_namespaceObject.getSessionMediaDirectory)(dbPath, sessionId);
|
|
153
|
+
(0, external_vitest_namespaceObject.expect)((0, external_node_fs_namespaceObject.existsSync)(mediaDir)).toBe(true);
|
|
154
|
+
(0, imagePersistence_cjs_namespaceObject.removeSessionMediaDirectory)(dbPath, sessionId);
|
|
155
|
+
(0, external_vitest_namespaceObject.expect)((0, external_node_fs_namespaceObject.existsSync)(mediaDir)).toBe(false);
|
|
156
|
+
});
|
|
131
157
|
(0, external_vitest_namespaceObject.it)("parses base64 data URLs and resolves extensions", ()=>{
|
|
132
158
|
const parsed = (0, imagePersistence_cjs_namespaceObject.parseBase64DataUrl)(PNG_DATA_URL);
|
|
133
159
|
(0, external_vitest_namespaceObject.expect)(parsed?.mimeType).toBe("image/png");
|
|
@@ -2,7 +2,7 @@ import { existsSync, mkdtempSync, readFileSync, rmSync } from "node:fs";
|
|
|
2
2
|
import { tmpdir } from "node:os";
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import { afterEach, describe, expect, it } from "vitest";
|
|
5
|
-
import { parseBase64DataUrl, persistAssistantImagesToDisk, resolveImageExtension } from "../cli/core/imagePersistence.js";
|
|
5
|
+
import { getSessionMediaDirectory, parseBase64DataUrl, persistAssistantImagesToDisk, removeSessionMediaDirectory, resolveImageExtension } from "../cli/core/imagePersistence.js";
|
|
6
6
|
const PNG_DATA_URL = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO3X6S0AAAAASUVORK5CYII=";
|
|
7
7
|
describe("imagePersistence", ()=>{
|
|
8
8
|
const tempDirs = [];
|
|
@@ -126,6 +126,32 @@ describe("imagePersistence", ()=>{
|
|
|
126
126
|
expect(firstPath).toBeTruthy();
|
|
127
127
|
expect(secondPath).toBe(firstPath);
|
|
128
128
|
});
|
|
129
|
+
it("removes persisted session media directory", ()=>{
|
|
130
|
+
const tempDir = mkdtempSync(join(tmpdir(), "wingman-image-store-"));
|
|
131
|
+
tempDirs.push(tempDir);
|
|
132
|
+
const dbPath = join(tempDir, "wingman.db");
|
|
133
|
+
const sessionId = "session-cleanup";
|
|
134
|
+
const messages = [
|
|
135
|
+
{
|
|
136
|
+
role: "assistant",
|
|
137
|
+
attachments: [
|
|
138
|
+
{
|
|
139
|
+
kind: "image",
|
|
140
|
+
dataUrl: PNG_DATA_URL
|
|
141
|
+
}
|
|
142
|
+
]
|
|
143
|
+
}
|
|
144
|
+
];
|
|
145
|
+
persistAssistantImagesToDisk({
|
|
146
|
+
dbPath,
|
|
147
|
+
sessionId,
|
|
148
|
+
messages
|
|
149
|
+
});
|
|
150
|
+
const mediaDir = getSessionMediaDirectory(dbPath, sessionId);
|
|
151
|
+
expect(existsSync(mediaDir)).toBe(true);
|
|
152
|
+
removeSessionMediaDirectory(dbPath, sessionId);
|
|
153
|
+
expect(existsSync(mediaDir)).toBe(false);
|
|
154
|
+
});
|
|
129
155
|
it("parses base64 data URLs and resolves extensions", ()=>{
|
|
130
156
|
const parsed = parseBase64DataUrl(PNG_DATA_URL);
|
|
131
157
|
expect(parsed?.mimeType).toBe("image/png");
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_exports__ = {};
|
|
3
|
+
const external_node_path_namespaceObject = require("node:path");
|
|
4
|
+
const external_vitest_namespaceObject = require("vitest");
|
|
5
|
+
const officialCli_cjs_namespaceObject = require("../bench/officialCli.cjs");
|
|
6
|
+
(0, external_vitest_namespaceObject.describe)("run-terminal-bench-official cli args", ()=>{
|
|
7
|
+
(0, external_vitest_namespaceObject.it)("parses wingman bridge options", ()=>{
|
|
8
|
+
const parsed = (0, officialCli_cjs_namespaceObject.parseOfficialBenchArgs)([
|
|
9
|
+
"bun",
|
|
10
|
+
"run-terminal-bench-official.ts",
|
|
11
|
+
"--config",
|
|
12
|
+
"bench/config.tb2-wingman.json",
|
|
13
|
+
"--task-id",
|
|
14
|
+
"heterogeneous-dates",
|
|
15
|
+
"--n-attempts",
|
|
16
|
+
"3",
|
|
17
|
+
"--n-tasks",
|
|
18
|
+
"2",
|
|
19
|
+
"--wingman-agent",
|
|
20
|
+
"coding",
|
|
21
|
+
"--wingman-model",
|
|
22
|
+
"openai/gpt-5"
|
|
23
|
+
]);
|
|
24
|
+
(0, external_vitest_namespaceObject.expect)(parsed.configPath).toBe((0, external_node_path_namespaceObject.join)(process.cwd(), "bench/config.tb2-wingman.json"));
|
|
25
|
+
(0, external_vitest_namespaceObject.expect)(parsed.overrides.taskNames).toEqual([
|
|
26
|
+
"heterogeneous-dates"
|
|
27
|
+
]);
|
|
28
|
+
(0, external_vitest_namespaceObject.expect)(parsed.overrides.nAttempts).toBe(3);
|
|
29
|
+
(0, external_vitest_namespaceObject.expect)(parsed.overrides.nTasks).toBe(2);
|
|
30
|
+
(0, external_vitest_namespaceObject.expect)(parsed.overrides.agentKwargs).toEqual({
|
|
31
|
+
wingman_agent: "coding",
|
|
32
|
+
wingman_model: "openai:gpt-5"
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
(0, external_vitest_namespaceObject.it)("uses all dataset tasks when --all-tasks is set", ()=>{
|
|
36
|
+
const parsed = (0, officialCli_cjs_namespaceObject.parseOfficialBenchArgs)([
|
|
37
|
+
"bun",
|
|
38
|
+
"run-terminal-bench-official.ts",
|
|
39
|
+
"--task-name",
|
|
40
|
+
"heterogeneous-dates",
|
|
41
|
+
"--all-tasks"
|
|
42
|
+
]);
|
|
43
|
+
(0, external_vitest_namespaceObject.expect)(parsed.overrides.taskNames).toEqual([]);
|
|
44
|
+
});
|
|
45
|
+
(0, external_vitest_namespaceObject.it)("parses explicit registry options", ()=>{
|
|
46
|
+
const parsed = (0, officialCli_cjs_namespaceObject.parseOfficialBenchArgs)([
|
|
47
|
+
"bun",
|
|
48
|
+
"run-terminal-bench-official.ts",
|
|
49
|
+
"--registry-url",
|
|
50
|
+
"https://example.com/registry.json",
|
|
51
|
+
"--registry-path",
|
|
52
|
+
"/tmp/registry.json"
|
|
53
|
+
]);
|
|
54
|
+
(0, external_vitest_namespaceObject.expect)(parsed.overrides.registryUrl).toBe("https://example.com/registry.json");
|
|
55
|
+
(0, external_vitest_namespaceObject.expect)(parsed.overrides.registryPath).toBe("/tmp/registry.json");
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
for(var __rspack_i in __webpack_exports__)exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
59
|
+
Object.defineProperty(exports, '__esModule', {
|
|
60
|
+
value: true
|
|
61
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
import { describe, expect, it } from "vitest";
|
|
3
|
+
import { parseOfficialBenchArgs } from "../bench/officialCli.js";
|
|
4
|
+
describe("run-terminal-bench-official cli args", ()=>{
|
|
5
|
+
it("parses wingman bridge options", ()=>{
|
|
6
|
+
const parsed = parseOfficialBenchArgs([
|
|
7
|
+
"bun",
|
|
8
|
+
"run-terminal-bench-official.ts",
|
|
9
|
+
"--config",
|
|
10
|
+
"bench/config.tb2-wingman.json",
|
|
11
|
+
"--task-id",
|
|
12
|
+
"heterogeneous-dates",
|
|
13
|
+
"--n-attempts",
|
|
14
|
+
"3",
|
|
15
|
+
"--n-tasks",
|
|
16
|
+
"2",
|
|
17
|
+
"--wingman-agent",
|
|
18
|
+
"coding",
|
|
19
|
+
"--wingman-model",
|
|
20
|
+
"openai/gpt-5"
|
|
21
|
+
]);
|
|
22
|
+
expect(parsed.configPath).toBe(join(process.cwd(), "bench/config.tb2-wingman.json"));
|
|
23
|
+
expect(parsed.overrides.taskNames).toEqual([
|
|
24
|
+
"heterogeneous-dates"
|
|
25
|
+
]);
|
|
26
|
+
expect(parsed.overrides.nAttempts).toBe(3);
|
|
27
|
+
expect(parsed.overrides.nTasks).toBe(2);
|
|
28
|
+
expect(parsed.overrides.agentKwargs).toEqual({
|
|
29
|
+
wingman_agent: "coding",
|
|
30
|
+
wingman_model: "openai:gpt-5"
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
it("uses all dataset tasks when --all-tasks is set", ()=>{
|
|
34
|
+
const parsed = parseOfficialBenchArgs([
|
|
35
|
+
"bun",
|
|
36
|
+
"run-terminal-bench-official.ts",
|
|
37
|
+
"--task-name",
|
|
38
|
+
"heterogeneous-dates",
|
|
39
|
+
"--all-tasks"
|
|
40
|
+
]);
|
|
41
|
+
expect(parsed.overrides.taskNames).toEqual([]);
|
|
42
|
+
});
|
|
43
|
+
it("parses explicit registry options", ()=>{
|
|
44
|
+
const parsed = parseOfficialBenchArgs([
|
|
45
|
+
"bun",
|
|
46
|
+
"run-terminal-bench-official.ts",
|
|
47
|
+
"--registry-url",
|
|
48
|
+
"https://example.com/registry.json",
|
|
49
|
+
"--registry-path",
|
|
50
|
+
"/tmp/registry.json"
|
|
51
|
+
]);
|
|
52
|
+
expect(parsed.overrides.registryUrl).toBe("https://example.com/registry.json");
|
|
53
|
+
expect(parsed.overrides.registryPath).toBe("/tmp/registry.json");
|
|
54
|
+
});
|
|
55
|
+
});
|
|
@@ -4,6 +4,7 @@ const external_node_fs_namespaceObject = require("node:fs");
|
|
|
4
4
|
const external_node_os_namespaceObject = require("node:os");
|
|
5
5
|
const external_node_path_namespaceObject = require("node:path");
|
|
6
6
|
const external_vitest_namespaceObject = require("vitest");
|
|
7
|
+
const imagePersistence_cjs_namespaceObject = require("../cli/core/imagePersistence.cjs");
|
|
7
8
|
const sessionManager_cjs_namespaceObject = require("../cli/core/sessionManager.cjs");
|
|
8
9
|
const sessions_cjs_namespaceObject = require("../gateway/http/sessions.cjs");
|
|
9
10
|
const isBunRuntime = void 0 !== globalThis.Bun;
|
|
@@ -11,9 +12,11 @@ const describeIfBun = isBunRuntime ? external_vitest_namespaceObject.describe :
|
|
|
11
12
|
describeIfBun("sessions API", ()=>{
|
|
12
13
|
let manager;
|
|
13
14
|
let tempDir;
|
|
15
|
+
let dbPath;
|
|
16
|
+
const PNG_DATA_URL = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO3X6S0AAAAASUVORK5CYII=";
|
|
14
17
|
(0, external_vitest_namespaceObject.beforeEach)(async ()=>{
|
|
15
18
|
tempDir = (0, external_node_fs_namespaceObject.mkdtempSync)((0, external_node_path_namespaceObject.join)((0, external_node_os_namespaceObject.tmpdir)(), "wingman-sessions-"));
|
|
16
|
-
|
|
19
|
+
dbPath = (0, external_node_path_namespaceObject.join)(tempDir, "sessions.db");
|
|
17
20
|
manager = new sessionManager_cjs_namespaceObject.SessionManager(dbPath);
|
|
18
21
|
await manager.initialize();
|
|
19
22
|
});
|
|
@@ -45,6 +48,23 @@ describeIfBun("sessions API", ()=>{
|
|
|
45
48
|
(0, external_vitest_namespaceObject.expect)(createRes).not.toBeNull();
|
|
46
49
|
(0, external_vitest_namespaceObject.expect)(createRes?.ok).toBe(true);
|
|
47
50
|
const created = await createRes.json();
|
|
51
|
+
const mediaDir = (0, imagePersistence_cjs_namespaceObject.getSessionMediaDirectory)(dbPath, created.id);
|
|
52
|
+
(0, imagePersistence_cjs_namespaceObject.persistAssistantImagesToDisk)({
|
|
53
|
+
dbPath,
|
|
54
|
+
sessionId: created.id,
|
|
55
|
+
messages: [
|
|
56
|
+
{
|
|
57
|
+
role: "assistant",
|
|
58
|
+
attachments: [
|
|
59
|
+
{
|
|
60
|
+
kind: "image",
|
|
61
|
+
dataUrl: PNG_DATA_URL
|
|
62
|
+
}
|
|
63
|
+
]
|
|
64
|
+
}
|
|
65
|
+
]
|
|
66
|
+
});
|
|
67
|
+
(0, external_vitest_namespaceObject.expect)((0, external_node_fs_namespaceObject.existsSync)(mediaDir)).toBe(true);
|
|
48
68
|
manager.updateSession(created.id, {
|
|
49
69
|
messageCount: 2,
|
|
50
70
|
lastMessagePreview: "Hello"
|
|
@@ -57,10 +77,58 @@ describeIfBun("sessions API", ()=>{
|
|
|
57
77
|
(0, external_vitest_namespaceObject.expect)(deleteRes?.ok).toBe(true);
|
|
58
78
|
const payload = await deleteRes.json();
|
|
59
79
|
(0, external_vitest_namespaceObject.expect)(payload.messageCount).toBe(0);
|
|
80
|
+
(0, external_vitest_namespaceObject.expect)((0, external_node_fs_namespaceObject.existsSync)(mediaDir)).toBe(false);
|
|
60
81
|
const updated = manager.getSession(created.id);
|
|
61
82
|
(0, external_vitest_namespaceObject.expect)(updated?.messageCount).toBe(0);
|
|
62
83
|
(0, external_vitest_namespaceObject.expect)(updated?.lastMessagePreview).toBeNull();
|
|
63
84
|
});
|
|
85
|
+
(0, external_vitest_namespaceObject.it)("removes persisted session media when deleting a session", async ()=>{
|
|
86
|
+
const ctx = {
|
|
87
|
+
getSessionManager: async ()=>manager,
|
|
88
|
+
router: {
|
|
89
|
+
selectAgent: (agentId)=>agentId || "main"
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
const createReq = new Request("http://localhost/api/sessions", {
|
|
93
|
+
method: "POST",
|
|
94
|
+
headers: {
|
|
95
|
+
"Content-Type": "application/json"
|
|
96
|
+
},
|
|
97
|
+
body: JSON.stringify({
|
|
98
|
+
agentId: "main",
|
|
99
|
+
name: "Delete Session Media"
|
|
100
|
+
})
|
|
101
|
+
});
|
|
102
|
+
const createRes = await (0, sessions_cjs_namespaceObject.handleSessionsApi)(ctx, createReq, new URL(createReq.url));
|
|
103
|
+
(0, external_vitest_namespaceObject.expect)(createRes).not.toBeNull();
|
|
104
|
+
(0, external_vitest_namespaceObject.expect)(createRes?.ok).toBe(true);
|
|
105
|
+
const created = await createRes.json();
|
|
106
|
+
const mediaDir = (0, imagePersistence_cjs_namespaceObject.getSessionMediaDirectory)(dbPath, created.id);
|
|
107
|
+
(0, imagePersistence_cjs_namespaceObject.persistAssistantImagesToDisk)({
|
|
108
|
+
dbPath,
|
|
109
|
+
sessionId: created.id,
|
|
110
|
+
messages: [
|
|
111
|
+
{
|
|
112
|
+
role: "assistant",
|
|
113
|
+
attachments: [
|
|
114
|
+
{
|
|
115
|
+
kind: "image",
|
|
116
|
+
dataUrl: PNG_DATA_URL
|
|
117
|
+
}
|
|
118
|
+
]
|
|
119
|
+
}
|
|
120
|
+
]
|
|
121
|
+
});
|
|
122
|
+
(0, external_vitest_namespaceObject.expect)((0, external_node_fs_namespaceObject.existsSync)(mediaDir)).toBe(true);
|
|
123
|
+
const deleteReq = new Request(`http://localhost/api/sessions/${encodeURIComponent(created.id)}?agentId=main`, {
|
|
124
|
+
method: "DELETE"
|
|
125
|
+
});
|
|
126
|
+
const deleteRes = await (0, sessions_cjs_namespaceObject.handleSessionsApi)(ctx, deleteReq, new URL(deleteReq.url));
|
|
127
|
+
(0, external_vitest_namespaceObject.expect)(deleteRes).not.toBeNull();
|
|
128
|
+
(0, external_vitest_namespaceObject.expect)(deleteRes?.ok).toBe(true);
|
|
129
|
+
(0, external_vitest_namespaceObject.expect)((0, external_node_fs_namespaceObject.existsSync)(mediaDir)).toBe(false);
|
|
130
|
+
(0, external_vitest_namespaceObject.expect)(manager.getSession(created.id)).toBeNull();
|
|
131
|
+
});
|
|
64
132
|
(0, external_vitest_namespaceObject.it)("returns pending messages and clears them via DELETE", async ()=>{
|
|
65
133
|
const ctx = {
|
|
66
134
|
getSessionManager: async ()=>manager,
|