mirror of
https://github.com/binaricat/Netcatty.git
synced 2026-10-29 18:11:40 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8222f42116 | ||
|
|
1a18c90ad6 |
No files matched your search
@@ -1,5 +1,8 @@
|
||||
import assert from "node:assert/strict";
|
||||
import test from "node:test";
|
||||
import { generateText, streamText } from "ai";
|
||||
import { buildCattySdkMessages, createContinuationContext } from "./harness/turnDrivers/cattyMessageBuilder";
|
||||
import { ToolOutputStore } from "./harness/toolOutputStore";
|
||||
|
||||
import { createModelFromConfig, resolveProviderEndpoint } from "./sdk/providers";
|
||||
import type { ProviderConfig } from "./types";
|
||||
@@ -280,3 +283,43 @@ test("SDK requests forward custom headers and scope OpenCode sessions", async (t
|
||||
}
|
||||
assert.equal(requests.length, 16);
|
||||
});
|
||||
|
||||
test("OpenAI Chat sends inline image attachments as data URLs through the bridge", async (t) => {
|
||||
const browserGlobal = globalThis as typeof globalThis & { window?: unknown };
|
||||
const originalWindow = browserGlobal.window;
|
||||
t.after(() => { browserGlobal.window = originalWindow; });
|
||||
const requests: Array<{ url: string; body: Record<string, unknown> }> = [];
|
||||
Reflect.set(globalThis, "window", { netcatty: {
|
||||
aiFetch: async (url: string, _method: string, _headers: Record<string, string>, body: string) => {
|
||||
requests.push({ url, body: JSON.parse(body) });
|
||||
return { ok: false, status: 400, data: '{"error":{"message":"captured request"}}' };
|
||||
},
|
||||
aiChatStream: async (_requestId: string, url: string, _headers: Record<string, string>, body: string) => {
|
||||
requests.push({ url, body: JSON.parse(body) });
|
||||
return { ok: false, error: "captured request" };
|
||||
},
|
||||
onAiStreamData: () => () => {},
|
||||
onAiStreamEnd: () => () => {},
|
||||
onAiStreamError: () => () => {},
|
||||
} });
|
||||
|
||||
for (const [mediaType, base64Data] of [["image/png", "iVBORw0KGgo="], ["image/jpeg", "/9j/4A=="]]) {
|
||||
const messages = buildCattySdkMessages({
|
||||
allMessages: [], includeCurrentUserMessage: true, trimmed: "Read this image",
|
||||
attachments: [{ mediaType, base64Data }],
|
||||
continuationContext: createContinuationContext("p", "openai", "m", false),
|
||||
chatSessionId: "images", toolOutputStore: new ToolOutputStore(), fieldsByMessage: new Map(),
|
||||
});
|
||||
const model = createModelFromConfig(makeConfig({ openaiApi: "chat", apiKey: "test-key", baseURL: "https://example.test/v1" }));
|
||||
await assert.rejects(generateText({ model, messages, maxRetries: 0 }), /captured request/);
|
||||
await assert.rejects(async () => await streamText({ model, messages, maxRetries: 0, onError: () => {} }).text);
|
||||
for (const request of requests.slice(-2)) {
|
||||
assert.equal(request.url, "https://example.test/v1/chat/completions");
|
||||
assert.deepEqual(request.body.messages, [{ role: "user", content: [
|
||||
{ type: "text", text: "Read this image" },
|
||||
{ type: "image_url", image_url: { url: `data:${mediaType};base64,${base64Data}` } },
|
||||
] }]);
|
||||
}
|
||||
}
|
||||
assert.equal(requests.length, 4);
|
||||
});
|
||||
Generated
+36
-6
@@ -16,7 +16,7 @@
|
||||
"dependencies": {
|
||||
"@ai-sdk/anthropic": "^4.0.0",
|
||||
"@ai-sdk/google": "^4.0.0",
|
||||
"@ai-sdk/openai": "^4.0.0",
|
||||
"@ai-sdk/openai": "4.0.8",
|
||||
"@aws-sdk/client-s3": "^3.956.0",
|
||||
"@eslint-community/regexpp": "4.12.2",
|
||||
"@fontsource/jetbrains-mono": "^5.2.8",
|
||||
@@ -197,13 +197,43 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@ai-sdk/openai": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@ai-sdk/openai/-/openai-4.0.0.tgz",
|
||||
"integrity": "sha512-XcI/bJEG+Ymx8ZwQMY9GE9waHdEcSzT6wn2o+YW80hOQPf8IAGQvdNWKaD0mxLi6AmOM0L01y/p626w7rImblQ==",
|
||||
"version": "4.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@ai-sdk/openai/-/openai-4.0.8.tgz",
|
||||
"integrity": "sha512-yW2UuS6jlu2LRYCd+cSpVdu/umf+QjypihYAiGvKk5HnpqQf21ffNjFbke9xo9jhT+TBt2YR30Fs5Sy0md/dfA==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@ai-sdk/provider": "4.0.0",
|
||||
"@ai-sdk/provider-utils": "5.0.0"
|
||||
"@ai-sdk/provider": "4.0.2",
|
||||
"@ai-sdk/provider-utils": "5.0.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=22"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"zod": "^3.25.76 || ^4.1.8"
|
||||
}
|
||||
},
|
||||
"node_modules/@ai-sdk/openai/node_modules/@ai-sdk/provider": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@ai-sdk/provider/-/provider-4.0.2.tgz",
|
||||
"integrity": "sha512-pfPoy9J1B1xV7cqJ8MYHOsDYrMv5tR3+EMNfI249OhkD2uRakvav3Fo7XpD2luuN/YNCBY7KfEQc7vEV7KEtyw==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"json-schema": "^0.4.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=22"
|
||||
}
|
||||
},
|
||||
"node_modules/@ai-sdk/openai/node_modules/@ai-sdk/provider-utils": {
|
||||
"version": "5.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@ai-sdk/provider-utils/-/provider-utils-5.0.5.tgz",
|
||||
"integrity": "sha512-oI0t3dvCoqWNV1I8o1Rybi2DXDvHES5r/TrwtJW90tuFLVepgJlftPxrcjh8vaSvjqC2diTuA2vXyjKAyHJm4A==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@ai-sdk/provider": "4.0.2",
|
||||
"@standard-schema/spec": "^1.1.0",
|
||||
"@workflow/serde": "4.1.0",
|
||||
"eventsource-parser": "^3.0.8"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=22"
|
||||
|
||||
+1
-1
@@ -76,7 +76,7 @@
|
||||
"dependencies": {
|
||||
"@ai-sdk/anthropic": "^4.0.0",
|
||||
"@ai-sdk/google": "^4.0.0",
|
||||
"@ai-sdk/openai": "^4.0.0",
|
||||
"@ai-sdk/openai": "4.0.8",
|
||||
"@aws-sdk/client-s3": "^3.956.0",
|
||||
"@eslint-community/regexpp": "4.12.2",
|
||||
"@fontsource/jetbrains-mono": "^5.2.8",
|
||||
|
||||
Reference in new issue
Block a user