@providerprotocol/ai 0.0.26 → 0.0.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/anthropic/index.d.ts +1 -1
- package/dist/anthropic/index.js +38 -1
- package/dist/anthropic/index.js.map +1 -1
- package/dist/{chunk-6AZVUI6H.js → chunk-ILR2D5PN.js} +7 -1
- package/dist/chunk-ILR2D5PN.js.map +1 -0
- package/dist/{chunk-MKDLXV4O.js → chunk-NSE7QN3P.js} +1 -1
- package/dist/chunk-NSE7QN3P.js.map +1 -0
- package/dist/embedding-DtyOFIsS.d.ts +158 -0
- package/dist/google/index.d.ts +1 -1
- package/dist/google/index.js +41 -4
- package/dist/google/index.js.map +1 -1
- package/dist/http/index.d.ts +2 -2
- package/dist/index.d.ts +430 -669
- package/dist/index.js +627 -3
- package/dist/index.js.map +1 -1
- package/dist/llm-DgDEy9il.d.ts +3118 -0
- package/dist/ollama/index.d.ts +1 -1
- package/dist/ollama/index.js +2 -1
- package/dist/ollama/index.js.map +1 -1
- package/dist/openai/index.d.ts +1 -1
- package/dist/openai/index.js +70 -3
- package/dist/openai/index.js.map +1 -1
- package/dist/openrouter/index.d.ts +20 -2
- package/dist/openrouter/index.js +134 -13
- package/dist/openrouter/index.js.map +1 -1
- package/dist/proxy/index.d.ts +220 -3
- package/dist/proxy/index.js +817 -22
- package/dist/proxy/index.js.map +1 -1
- package/dist/{retry-DTfjXXPh.d.ts → retry-DXLQnTuU.d.ts} +1 -1
- package/dist/xai/index.d.ts +1 -1
- package/dist/xai/index.js +7 -3
- package/dist/xai/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-6AZVUI6H.js.map +0 -1
- package/dist/chunk-MKDLXV4O.js.map +0 -1
- package/dist/provider-x4RocsnK.d.ts +0 -1474
- package/dist/stream-ITNFNnO4.d.ts +0 -1080
package/dist/proxy/index.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
emptyUsage
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-NSE7QN3P.js";
|
|
4
|
+
import {
|
|
5
|
+
Image
|
|
6
|
+
} from "../chunk-WAKD3OO5.js";
|
|
4
7
|
import {
|
|
5
8
|
parseJsonResponse
|
|
6
9
|
} from "../chunk-Z6DKC37J.js";
|
|
@@ -9,7 +12,7 @@ import {
|
|
|
9
12
|
ToolResultMessage,
|
|
10
13
|
UserMessage,
|
|
11
14
|
createProvider
|
|
12
|
-
} from "../chunk-
|
|
15
|
+
} from "../chunk-ILR2D5PN.js";
|
|
13
16
|
import {
|
|
14
17
|
ErrorCode,
|
|
15
18
|
ModalityType,
|
|
@@ -20,6 +23,19 @@ import {
|
|
|
20
23
|
toError
|
|
21
24
|
} from "../chunk-QNJO7DSD.js";
|
|
22
25
|
|
|
26
|
+
// src/providers/proxy/headers.ts
|
|
27
|
+
function mergeHeaders(requestHeaders, defaultHeaders) {
|
|
28
|
+
const headers = { ...defaultHeaders };
|
|
29
|
+
if (requestHeaders) {
|
|
30
|
+
for (const [key, value] of Object.entries(requestHeaders)) {
|
|
31
|
+
if (value !== void 0) {
|
|
32
|
+
headers[key] = value;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return headers;
|
|
37
|
+
}
|
|
38
|
+
|
|
23
39
|
// src/providers/proxy/serialization.ts
|
|
24
40
|
function serializeMessage(m) {
|
|
25
41
|
const base = {
|
|
@@ -106,6 +122,7 @@ var PROXY_CAPABILITIES = {
|
|
|
106
122
|
tools: true,
|
|
107
123
|
structuredOutput: true,
|
|
108
124
|
imageInput: true,
|
|
125
|
+
documentInput: true,
|
|
109
126
|
videoInput: true,
|
|
110
127
|
audioInput: true
|
|
111
128
|
};
|
|
@@ -117,7 +134,8 @@ function createLLMHandler(options) {
|
|
|
117
134
|
providerRef = provider;
|
|
118
135
|
},
|
|
119
136
|
bind(modelId) {
|
|
120
|
-
|
|
137
|
+
const provider = providerRef;
|
|
138
|
+
if (!provider) {
|
|
121
139
|
throw new UPPError(
|
|
122
140
|
"Provider reference not set. Handler must be used with createProvider().",
|
|
123
141
|
ErrorCode.InvalidRequest,
|
|
@@ -129,10 +147,10 @@ function createLLMHandler(options) {
|
|
|
129
147
|
modelId,
|
|
130
148
|
capabilities: PROXY_CAPABILITIES,
|
|
131
149
|
get provider() {
|
|
132
|
-
return
|
|
150
|
+
return provider;
|
|
133
151
|
},
|
|
134
152
|
async complete(request) {
|
|
135
|
-
const body = serializeRequest(request);
|
|
153
|
+
const body = serializeRequest(request, modelId);
|
|
136
154
|
const headers = mergeHeaders(request.config.headers, defaultHeaders);
|
|
137
155
|
const response = await doFetch(
|
|
138
156
|
endpoint,
|
|
@@ -154,13 +172,24 @@ function createLLMHandler(options) {
|
|
|
154
172
|
return turnJSONToLLMResponse(data);
|
|
155
173
|
},
|
|
156
174
|
stream(request) {
|
|
157
|
-
const body = serializeRequest(request);
|
|
175
|
+
const body = serializeRequest(request, modelId);
|
|
158
176
|
const headers = mergeHeaders(request.config.headers, defaultHeaders);
|
|
159
177
|
let resolveResponse;
|
|
160
178
|
let rejectResponse;
|
|
179
|
+
let responseSettled = false;
|
|
161
180
|
const responsePromise = new Promise((resolve, reject) => {
|
|
162
|
-
resolveResponse =
|
|
163
|
-
|
|
181
|
+
resolveResponse = (value) => {
|
|
182
|
+
if (!responseSettled) {
|
|
183
|
+
responseSettled = true;
|
|
184
|
+
resolve(value);
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
rejectResponse = (error) => {
|
|
188
|
+
if (!responseSettled) {
|
|
189
|
+
responseSettled = true;
|
|
190
|
+
reject(error);
|
|
191
|
+
}
|
|
192
|
+
};
|
|
164
193
|
});
|
|
165
194
|
const generator = async function* () {
|
|
166
195
|
try {
|
|
@@ -245,6 +274,14 @@ function createLLMHandler(options) {
|
|
|
245
274
|
}
|
|
246
275
|
}
|
|
247
276
|
}
|
|
277
|
+
if (!responseSettled) {
|
|
278
|
+
rejectResponse(new UPPError(
|
|
279
|
+
"Stream ended without final response",
|
|
280
|
+
ErrorCode.InvalidResponse,
|
|
281
|
+
"proxy",
|
|
282
|
+
ModalityType.LLM
|
|
283
|
+
));
|
|
284
|
+
}
|
|
248
285
|
} catch (error) {
|
|
249
286
|
rejectResponse(toError(error));
|
|
250
287
|
throw error;
|
|
@@ -260,8 +297,9 @@ function createLLMHandler(options) {
|
|
|
260
297
|
}
|
|
261
298
|
};
|
|
262
299
|
}
|
|
263
|
-
function serializeRequest(request) {
|
|
300
|
+
function serializeRequest(request, modelId) {
|
|
264
301
|
return {
|
|
302
|
+
model: modelId,
|
|
265
303
|
messages: request.messages.map(serializeMessage),
|
|
266
304
|
system: request.system,
|
|
267
305
|
params: request.params,
|
|
@@ -274,17 +312,6 @@ function serializeRequest(request) {
|
|
|
274
312
|
structure: request.structure
|
|
275
313
|
};
|
|
276
314
|
}
|
|
277
|
-
function mergeHeaders(requestHeaders, defaultHeaders) {
|
|
278
|
-
const headers = { ...defaultHeaders };
|
|
279
|
-
if (requestHeaders) {
|
|
280
|
-
for (const [key, value] of Object.entries(requestHeaders)) {
|
|
281
|
-
if (value !== void 0) {
|
|
282
|
-
headers[key] = value;
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
return headers;
|
|
287
|
-
}
|
|
288
315
|
function turnJSONToLLMResponse(data) {
|
|
289
316
|
const messages = data.messages.map(deserializeMessage);
|
|
290
317
|
const lastAssistant = messages.filter((m) => m.type === "assistant").pop();
|
|
@@ -400,11 +427,542 @@ function mapOllamaStopReason(reason) {
|
|
|
400
427
|
return "end_turn";
|
|
401
428
|
}
|
|
402
429
|
|
|
430
|
+
// src/providers/proxy/serialization.media.ts
|
|
431
|
+
function serializeEmbeddingInput(input) {
|
|
432
|
+
if (typeof input === "string") {
|
|
433
|
+
return input;
|
|
434
|
+
}
|
|
435
|
+
if (input.type === "text") {
|
|
436
|
+
return { type: "text", text: input.text };
|
|
437
|
+
}
|
|
438
|
+
if (input.type === "image") {
|
|
439
|
+
const source = serializeUnknownImageSource(input.source, input.mimeType);
|
|
440
|
+
return { type: "image", source, mimeType: input.mimeType };
|
|
441
|
+
}
|
|
442
|
+
throw new UPPError(
|
|
443
|
+
"Unsupported embedding input type",
|
|
444
|
+
ErrorCode.InvalidRequest,
|
|
445
|
+
"proxy",
|
|
446
|
+
ModalityType.Embedding
|
|
447
|
+
);
|
|
448
|
+
}
|
|
449
|
+
function deserializeEmbeddingInput(input) {
|
|
450
|
+
if (typeof input === "string") {
|
|
451
|
+
return input;
|
|
452
|
+
}
|
|
453
|
+
if (input.type === "text") {
|
|
454
|
+
return { type: "text", text: input.text };
|
|
455
|
+
}
|
|
456
|
+
if (input.type === "image") {
|
|
457
|
+
return {
|
|
458
|
+
type: "image",
|
|
459
|
+
mimeType: input.mimeType,
|
|
460
|
+
source: deserializeImageSource(input.source)
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
throw new UPPError(
|
|
464
|
+
"Unsupported embedding input type",
|
|
465
|
+
ErrorCode.InvalidResponse,
|
|
466
|
+
"proxy",
|
|
467
|
+
ModalityType.Embedding
|
|
468
|
+
);
|
|
469
|
+
}
|
|
470
|
+
function serializeImage(image) {
|
|
471
|
+
const block = image.toBlock();
|
|
472
|
+
return {
|
|
473
|
+
source: serializeImageSource(block.source),
|
|
474
|
+
mimeType: block.mimeType,
|
|
475
|
+
width: block.width,
|
|
476
|
+
height: block.height
|
|
477
|
+
};
|
|
478
|
+
}
|
|
479
|
+
function deserializeImage(image) {
|
|
480
|
+
const block = {
|
|
481
|
+
type: "image",
|
|
482
|
+
source: deserializeImageSource(image.source),
|
|
483
|
+
mimeType: image.mimeType,
|
|
484
|
+
width: image.width,
|
|
485
|
+
height: image.height
|
|
486
|
+
};
|
|
487
|
+
return Image.fromBlock(block);
|
|
488
|
+
}
|
|
489
|
+
function serializeGeneratedImage(image) {
|
|
490
|
+
return {
|
|
491
|
+
image: serializeImage(image.image),
|
|
492
|
+
metadata: image.metadata
|
|
493
|
+
};
|
|
494
|
+
}
|
|
495
|
+
function deserializeGeneratedImage(image) {
|
|
496
|
+
return {
|
|
497
|
+
image: deserializeImage(image.image),
|
|
498
|
+
metadata: image.metadata
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
function serializeImageResult(result) {
|
|
502
|
+
return {
|
|
503
|
+
images: result.images.map(serializeGeneratedImage),
|
|
504
|
+
metadata: result.metadata,
|
|
505
|
+
usage: result.usage
|
|
506
|
+
};
|
|
507
|
+
}
|
|
508
|
+
function deserializeImageResponse(response) {
|
|
509
|
+
if (!response || typeof response !== "object" || !Array.isArray(response.images)) {
|
|
510
|
+
throw new UPPError(
|
|
511
|
+
"Invalid image response",
|
|
512
|
+
ErrorCode.InvalidResponse,
|
|
513
|
+
"proxy",
|
|
514
|
+
ModalityType.Image
|
|
515
|
+
);
|
|
516
|
+
}
|
|
517
|
+
return {
|
|
518
|
+
images: response.images.map(deserializeGeneratedImage),
|
|
519
|
+
metadata: response.metadata,
|
|
520
|
+
usage: response.usage
|
|
521
|
+
};
|
|
522
|
+
}
|
|
523
|
+
function serializeImageStreamEvent(event) {
|
|
524
|
+
if (event.type === "preview") {
|
|
525
|
+
return {
|
|
526
|
+
type: "preview",
|
|
527
|
+
index: event.index,
|
|
528
|
+
image: serializeImage(event.image),
|
|
529
|
+
metadata: event.metadata
|
|
530
|
+
};
|
|
531
|
+
}
|
|
532
|
+
return {
|
|
533
|
+
type: "complete",
|
|
534
|
+
index: event.index,
|
|
535
|
+
image: serializeGeneratedImage(event.image)
|
|
536
|
+
};
|
|
537
|
+
}
|
|
538
|
+
function deserializeImageStreamEvent(event) {
|
|
539
|
+
if (event.type === "preview") {
|
|
540
|
+
return {
|
|
541
|
+
type: "preview",
|
|
542
|
+
index: event.index,
|
|
543
|
+
image: deserializeImage(event.image),
|
|
544
|
+
metadata: event.metadata
|
|
545
|
+
};
|
|
546
|
+
}
|
|
547
|
+
return {
|
|
548
|
+
type: "complete",
|
|
549
|
+
index: event.index,
|
|
550
|
+
image: deserializeGeneratedImage(event.image)
|
|
551
|
+
};
|
|
552
|
+
}
|
|
553
|
+
function serializeImageSource(source) {
|
|
554
|
+
if (source.type === "base64") {
|
|
555
|
+
return { type: "base64", data: source.data };
|
|
556
|
+
}
|
|
557
|
+
if (source.type === "url") {
|
|
558
|
+
return { type: "url", url: source.url };
|
|
559
|
+
}
|
|
560
|
+
if (typeof source.data === "string") {
|
|
561
|
+
return { type: "base64", data: source.data };
|
|
562
|
+
}
|
|
563
|
+
if (source.data instanceof Uint8Array) {
|
|
564
|
+
return { type: "base64", data: bytesToBase64(source.data) };
|
|
565
|
+
}
|
|
566
|
+
return { type: "base64", data: bytesToBase64(Uint8Array.from(source.data)) };
|
|
567
|
+
}
|
|
568
|
+
function serializeUnknownImageSource(source, mimeType) {
|
|
569
|
+
if (source instanceof Image) {
|
|
570
|
+
return serializeImage(source).source;
|
|
571
|
+
}
|
|
572
|
+
if (isImageSource(source)) {
|
|
573
|
+
return serializeImageSource(source);
|
|
574
|
+
}
|
|
575
|
+
if (typeof source === "string") {
|
|
576
|
+
return { type: "base64", data: source };
|
|
577
|
+
}
|
|
578
|
+
throw new UPPError(
|
|
579
|
+
`Unsupported image source for ${mimeType}`,
|
|
580
|
+
ErrorCode.InvalidRequest,
|
|
581
|
+
"proxy",
|
|
582
|
+
ModalityType.Embedding
|
|
583
|
+
);
|
|
584
|
+
}
|
|
585
|
+
function deserializeImageSource(source) {
|
|
586
|
+
if (source.type === "base64") {
|
|
587
|
+
return { type: "base64", data: source.data };
|
|
588
|
+
}
|
|
589
|
+
if (source.type === "url") {
|
|
590
|
+
return { type: "url", url: source.url };
|
|
591
|
+
}
|
|
592
|
+
return { type: "bytes", data: coerceBytes(source.data) };
|
|
593
|
+
}
|
|
594
|
+
function isImageSource(value) {
|
|
595
|
+
if (!value || typeof value !== "object") {
|
|
596
|
+
return false;
|
|
597
|
+
}
|
|
598
|
+
const source = value;
|
|
599
|
+
if (source.type === "base64") {
|
|
600
|
+
return typeof source.data === "string";
|
|
601
|
+
}
|
|
602
|
+
if (source.type === "url") {
|
|
603
|
+
return typeof source.url === "string";
|
|
604
|
+
}
|
|
605
|
+
if (source.type === "bytes") {
|
|
606
|
+
return source.data instanceof Uint8Array || Array.isArray(source.data) || typeof source.data === "string";
|
|
607
|
+
}
|
|
608
|
+
return false;
|
|
609
|
+
}
|
|
610
|
+
function coerceBytes(data) {
|
|
611
|
+
if (typeof data === "string") {
|
|
612
|
+
return base64ToBytes(data);
|
|
613
|
+
}
|
|
614
|
+
return Uint8Array.from(data);
|
|
615
|
+
}
|
|
616
|
+
function bytesToBase64(bytes) {
|
|
617
|
+
const binary = Array.from(bytes).map((b) => String.fromCharCode(b)).join("");
|
|
618
|
+
return btoa(binary);
|
|
619
|
+
}
|
|
620
|
+
function base64ToBytes(base64) {
|
|
621
|
+
const binaryString = atob(base64);
|
|
622
|
+
return Uint8Array.from(binaryString, (c) => c.charCodeAt(0));
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
// src/providers/proxy/embedding.ts
|
|
626
|
+
var DEFAULT_MAX_BATCH_SIZE = Number.MAX_SAFE_INTEGER;
|
|
627
|
+
var DEFAULT_MAX_INPUT_LENGTH = Number.MAX_SAFE_INTEGER;
|
|
628
|
+
var DEFAULT_DIMENSIONS = 0;
|
|
629
|
+
function createEmbeddingHandler(options) {
|
|
630
|
+
const { endpoint, headers: defaultHeaders = {} } = options;
|
|
631
|
+
let providerRef = null;
|
|
632
|
+
return {
|
|
633
|
+
supportedInputs: ["text", "image"],
|
|
634
|
+
_setProvider(provider) {
|
|
635
|
+
providerRef = provider;
|
|
636
|
+
},
|
|
637
|
+
bind(modelId) {
|
|
638
|
+
const provider = providerRef;
|
|
639
|
+
if (!provider) {
|
|
640
|
+
throw new UPPError(
|
|
641
|
+
"Provider reference not set. Handler must be used with createProvider().",
|
|
642
|
+
ErrorCode.InvalidRequest,
|
|
643
|
+
"proxy",
|
|
644
|
+
ModalityType.Embedding
|
|
645
|
+
);
|
|
646
|
+
}
|
|
647
|
+
const model = {
|
|
648
|
+
modelId,
|
|
649
|
+
maxBatchSize: DEFAULT_MAX_BATCH_SIZE,
|
|
650
|
+
maxInputLength: DEFAULT_MAX_INPUT_LENGTH,
|
|
651
|
+
dimensions: DEFAULT_DIMENSIONS,
|
|
652
|
+
get provider() {
|
|
653
|
+
return provider;
|
|
654
|
+
},
|
|
655
|
+
async embed(request) {
|
|
656
|
+
const body = {
|
|
657
|
+
model: modelId,
|
|
658
|
+
inputs: request.inputs.map(serializeEmbeddingInput),
|
|
659
|
+
params: request.params
|
|
660
|
+
};
|
|
661
|
+
const headers = mergeHeaders(request.config.headers, defaultHeaders);
|
|
662
|
+
const response = await doFetch(
|
|
663
|
+
endpoint,
|
|
664
|
+
{
|
|
665
|
+
method: "POST",
|
|
666
|
+
headers: {
|
|
667
|
+
...headers,
|
|
668
|
+
"Content-Type": "application/json",
|
|
669
|
+
Accept: "application/json"
|
|
670
|
+
},
|
|
671
|
+
body: JSON.stringify(body),
|
|
672
|
+
signal: request.signal
|
|
673
|
+
},
|
|
674
|
+
request.config,
|
|
675
|
+
"proxy",
|
|
676
|
+
"embedding"
|
|
677
|
+
);
|
|
678
|
+
const data = await parseJsonResponse(
|
|
679
|
+
response,
|
|
680
|
+
"proxy",
|
|
681
|
+
"embedding"
|
|
682
|
+
);
|
|
683
|
+
return normalizeEmbeddingResponse(data);
|
|
684
|
+
}
|
|
685
|
+
};
|
|
686
|
+
return model;
|
|
687
|
+
}
|
|
688
|
+
};
|
|
689
|
+
}
|
|
690
|
+
function normalizeEmbeddingResponse(data) {
|
|
691
|
+
if (!data || typeof data !== "object" || !Array.isArray(data.embeddings)) {
|
|
692
|
+
throw new UPPError(
|
|
693
|
+
"Invalid embedding response",
|
|
694
|
+
ErrorCode.InvalidResponse,
|
|
695
|
+
"proxy",
|
|
696
|
+
ModalityType.Embedding
|
|
697
|
+
);
|
|
698
|
+
}
|
|
699
|
+
const embeddings = data.embeddings.map((embedding, index) => {
|
|
700
|
+
if (!embedding || typeof embedding !== "object") {
|
|
701
|
+
throw new UPPError(
|
|
702
|
+
"Invalid embedding entry",
|
|
703
|
+
ErrorCode.InvalidResponse,
|
|
704
|
+
"proxy",
|
|
705
|
+
ModalityType.Embedding
|
|
706
|
+
);
|
|
707
|
+
}
|
|
708
|
+
const vector = embedding.vector;
|
|
709
|
+
if (!Array.isArray(vector) && typeof vector !== "string") {
|
|
710
|
+
throw new UPPError(
|
|
711
|
+
"Invalid embedding vector",
|
|
712
|
+
ErrorCode.InvalidResponse,
|
|
713
|
+
"proxy",
|
|
714
|
+
ModalityType.Embedding
|
|
715
|
+
);
|
|
716
|
+
}
|
|
717
|
+
const resolvedIndex = typeof embedding.index === "number" ? embedding.index : index;
|
|
718
|
+
const tokens = typeof embedding.tokens === "number" ? embedding.tokens : void 0;
|
|
719
|
+
return {
|
|
720
|
+
vector,
|
|
721
|
+
index: resolvedIndex,
|
|
722
|
+
tokens,
|
|
723
|
+
metadata: embedding.metadata
|
|
724
|
+
};
|
|
725
|
+
});
|
|
726
|
+
const totalTokens = typeof data.usage?.totalTokens === "number" ? data.usage.totalTokens : 0;
|
|
727
|
+
return {
|
|
728
|
+
embeddings,
|
|
729
|
+
usage: { totalTokens },
|
|
730
|
+
metadata: data.metadata
|
|
731
|
+
};
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
// src/providers/proxy/image.ts
|
|
735
|
+
var PROXY_IMAGE_CAPABILITIES = {
|
|
736
|
+
generate: true,
|
|
737
|
+
streaming: true,
|
|
738
|
+
edit: true
|
|
739
|
+
};
|
|
740
|
+
function createImageHandler(options) {
|
|
741
|
+
const { endpoint, headers: defaultHeaders = {} } = options;
|
|
742
|
+
let providerRef = null;
|
|
743
|
+
return {
|
|
744
|
+
_setProvider(provider) {
|
|
745
|
+
providerRef = provider;
|
|
746
|
+
},
|
|
747
|
+
bind(modelId) {
|
|
748
|
+
const provider = providerRef;
|
|
749
|
+
if (!provider) {
|
|
750
|
+
throw new UPPError(
|
|
751
|
+
"Provider reference not set. Handler must be used with createProvider().",
|
|
752
|
+
ErrorCode.InvalidRequest,
|
|
753
|
+
"proxy",
|
|
754
|
+
ModalityType.Image
|
|
755
|
+
);
|
|
756
|
+
}
|
|
757
|
+
const model = {
|
|
758
|
+
modelId,
|
|
759
|
+
capabilities: PROXY_IMAGE_CAPABILITIES,
|
|
760
|
+
get provider() {
|
|
761
|
+
return provider;
|
|
762
|
+
},
|
|
763
|
+
async generate(request) {
|
|
764
|
+
const body = buildImageRequestBody(modelId, request);
|
|
765
|
+
return executeImageRequest(endpoint, body, request, defaultHeaders);
|
|
766
|
+
},
|
|
767
|
+
async edit(request) {
|
|
768
|
+
const body = buildImageEditRequestBody(modelId, request);
|
|
769
|
+
return executeImageRequest(endpoint, body, request, defaultHeaders);
|
|
770
|
+
}
|
|
771
|
+
};
|
|
772
|
+
model.stream = function stream(request) {
|
|
773
|
+
const body = buildImageRequestBody(modelId, request);
|
|
774
|
+
return executeImageStream(endpoint, body, request, defaultHeaders);
|
|
775
|
+
};
|
|
776
|
+
return model;
|
|
777
|
+
}
|
|
778
|
+
};
|
|
779
|
+
}
|
|
780
|
+
function buildImageRequestBody(modelId, request) {
|
|
781
|
+
return {
|
|
782
|
+
model: modelId,
|
|
783
|
+
prompt: request.prompt,
|
|
784
|
+
params: request.params
|
|
785
|
+
};
|
|
786
|
+
}
|
|
787
|
+
function buildImageEditRequestBody(modelId, request) {
|
|
788
|
+
return {
|
|
789
|
+
model: modelId,
|
|
790
|
+
prompt: request.prompt,
|
|
791
|
+
params: request.params,
|
|
792
|
+
image: serializeImage(request.image),
|
|
793
|
+
mask: request.mask ? serializeImage(request.mask) : void 0
|
|
794
|
+
};
|
|
795
|
+
}
|
|
796
|
+
async function executeImageRequest(endpoint, body, request, defaultHeaders) {
|
|
797
|
+
const headers = mergeHeaders(request.config.headers, defaultHeaders);
|
|
798
|
+
const response = await doFetch(
|
|
799
|
+
endpoint,
|
|
800
|
+
{
|
|
801
|
+
method: "POST",
|
|
802
|
+
headers: {
|
|
803
|
+
...headers,
|
|
804
|
+
"Content-Type": "application/json",
|
|
805
|
+
Accept: "application/json"
|
|
806
|
+
},
|
|
807
|
+
body: JSON.stringify(body),
|
|
808
|
+
signal: request.signal
|
|
809
|
+
},
|
|
810
|
+
request.config,
|
|
811
|
+
"proxy",
|
|
812
|
+
"image"
|
|
813
|
+
);
|
|
814
|
+
const data = await parseJsonResponse(
|
|
815
|
+
response,
|
|
816
|
+
"proxy",
|
|
817
|
+
"image"
|
|
818
|
+
);
|
|
819
|
+
return deserializeImageResponse(data);
|
|
820
|
+
}
|
|
821
|
+
function executeImageStream(endpoint, body, request, defaultHeaders) {
|
|
822
|
+
const headers = mergeHeaders(request.config.headers, defaultHeaders);
|
|
823
|
+
let resolveResponse;
|
|
824
|
+
let rejectResponse;
|
|
825
|
+
let responseSettled = false;
|
|
826
|
+
const responsePromise = new Promise((resolve, reject) => {
|
|
827
|
+
resolveResponse = (value) => {
|
|
828
|
+
if (!responseSettled) {
|
|
829
|
+
responseSettled = true;
|
|
830
|
+
resolve(value);
|
|
831
|
+
}
|
|
832
|
+
};
|
|
833
|
+
rejectResponse = (error) => {
|
|
834
|
+
if (!responseSettled) {
|
|
835
|
+
responseSettled = true;
|
|
836
|
+
reject(error);
|
|
837
|
+
}
|
|
838
|
+
};
|
|
839
|
+
});
|
|
840
|
+
const generator = async function* generator2() {
|
|
841
|
+
try {
|
|
842
|
+
const response = await doStreamFetch(
|
|
843
|
+
endpoint,
|
|
844
|
+
{
|
|
845
|
+
method: "POST",
|
|
846
|
+
headers: {
|
|
847
|
+
...headers,
|
|
848
|
+
"Content-Type": "application/json",
|
|
849
|
+
Accept: "text/event-stream"
|
|
850
|
+
},
|
|
851
|
+
body: JSON.stringify(body),
|
|
852
|
+
signal: request.signal
|
|
853
|
+
},
|
|
854
|
+
request.config,
|
|
855
|
+
"proxy",
|
|
856
|
+
"image"
|
|
857
|
+
);
|
|
858
|
+
if (!response.ok) {
|
|
859
|
+
throw await normalizeHttpError(response, "proxy", "image");
|
|
860
|
+
}
|
|
861
|
+
if (!response.body) {
|
|
862
|
+
throw new UPPError(
|
|
863
|
+
"Response body is null",
|
|
864
|
+
ErrorCode.ProviderError,
|
|
865
|
+
"proxy",
|
|
866
|
+
ModalityType.Image
|
|
867
|
+
);
|
|
868
|
+
}
|
|
869
|
+
const reader = response.body.getReader();
|
|
870
|
+
const decoder = new TextDecoder();
|
|
871
|
+
let buffer = "";
|
|
872
|
+
while (true) {
|
|
873
|
+
const { done, value } = await reader.read();
|
|
874
|
+
if (done) break;
|
|
875
|
+
buffer += decoder.decode(value, { stream: true });
|
|
876
|
+
const lines = buffer.split("\n");
|
|
877
|
+
buffer = lines.pop() ?? "";
|
|
878
|
+
for (const line of lines) {
|
|
879
|
+
if (!line.trim() || line.startsWith(":")) continue;
|
|
880
|
+
if (line.startsWith("data:")) {
|
|
881
|
+
let data = line.slice(5);
|
|
882
|
+
if (data.startsWith(" ")) {
|
|
883
|
+
data = data.slice(1);
|
|
884
|
+
}
|
|
885
|
+
if (data === "[DONE]") continue;
|
|
886
|
+
try {
|
|
887
|
+
const parsed = JSON.parse(data);
|
|
888
|
+
if (isImageResponsePayload(parsed)) {
|
|
889
|
+
resolveResponse(deserializeImageResponse(parsed));
|
|
890
|
+
} else {
|
|
891
|
+
yield deserializeImageStreamEvent(parsed);
|
|
892
|
+
}
|
|
893
|
+
} catch {
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
const remaining = decoder.decode();
|
|
899
|
+
if (remaining) {
|
|
900
|
+
buffer += remaining;
|
|
901
|
+
const lines = buffer.split("\n");
|
|
902
|
+
buffer = lines.pop() ?? "";
|
|
903
|
+
for (const line of lines) {
|
|
904
|
+
if (!line.trim() || line.startsWith(":")) continue;
|
|
905
|
+
if (line.startsWith("data:")) {
|
|
906
|
+
let data = line.slice(5);
|
|
907
|
+
if (data.startsWith(" ")) {
|
|
908
|
+
data = data.slice(1);
|
|
909
|
+
}
|
|
910
|
+
if (data === "[DONE]") continue;
|
|
911
|
+
try {
|
|
912
|
+
const parsed = JSON.parse(data);
|
|
913
|
+
if (isImageResponsePayload(parsed)) {
|
|
914
|
+
resolveResponse(deserializeImageResponse(parsed));
|
|
915
|
+
} else {
|
|
916
|
+
yield deserializeImageStreamEvent(parsed);
|
|
917
|
+
}
|
|
918
|
+
} catch {
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
if (!responseSettled) {
|
|
924
|
+
rejectResponse(new UPPError(
|
|
925
|
+
"Stream ended without final response",
|
|
926
|
+
ErrorCode.InvalidResponse,
|
|
927
|
+
"proxy",
|
|
928
|
+
ModalityType.Image
|
|
929
|
+
));
|
|
930
|
+
}
|
|
931
|
+
} catch (error) {
|
|
932
|
+
rejectResponse(toError(error));
|
|
933
|
+
throw error;
|
|
934
|
+
}
|
|
935
|
+
};
|
|
936
|
+
return {
|
|
937
|
+
[Symbol.asyncIterator]: generator,
|
|
938
|
+
response: responsePromise
|
|
939
|
+
};
|
|
940
|
+
}
|
|
941
|
+
function isImageResponsePayload(payload) {
|
|
942
|
+
return !!payload && typeof payload === "object" && "images" in payload && Array.isArray(payload.images);
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
// src/providers/proxy/server/image-stream.ts
|
|
946
|
+
function resolveImageResult(stream) {
|
|
947
|
+
if ("result" in stream) {
|
|
948
|
+
return stream.result;
|
|
949
|
+
}
|
|
950
|
+
return stream.response;
|
|
951
|
+
}
|
|
952
|
+
|
|
403
953
|
// src/providers/proxy/server/express.ts
|
|
404
954
|
function sendJSON(turn, res) {
|
|
405
955
|
res.setHeader("Content-Type", "application/json");
|
|
406
956
|
res.json(serializeTurn(turn));
|
|
407
957
|
}
|
|
958
|
+
function sendEmbeddingJSON(result, res) {
|
|
959
|
+
res.setHeader("Content-Type", "application/json");
|
|
960
|
+
res.json(result);
|
|
961
|
+
}
|
|
962
|
+
function sendImageJSON(result, res) {
|
|
963
|
+
res.setHeader("Content-Type", "application/json");
|
|
964
|
+
res.json(serializeImageResult(result));
|
|
965
|
+
}
|
|
408
966
|
function streamSSE(stream, res) {
|
|
409
967
|
res.setHeader("Content-Type", "text/event-stream");
|
|
410
968
|
res.setHeader("Cache-Control", "no-cache");
|
|
@@ -426,6 +984,33 @@ function streamSSE(stream, res) {
|
|
|
426
984
|
const message = error instanceof Error ? error.message : String(error);
|
|
427
985
|
res.write(`data: ${JSON.stringify({ error: message })}
|
|
428
986
|
|
|
987
|
+
`);
|
|
988
|
+
} finally {
|
|
989
|
+
res.end();
|
|
990
|
+
}
|
|
991
|
+
})();
|
|
992
|
+
}
|
|
993
|
+
function streamImageSSE(stream, res) {
|
|
994
|
+
res.setHeader("Content-Type", "text/event-stream");
|
|
995
|
+
res.setHeader("Cache-Control", "no-cache");
|
|
996
|
+
res.setHeader("Connection", "keep-alive");
|
|
997
|
+
(async () => {
|
|
998
|
+
try {
|
|
999
|
+
for await (const event of stream) {
|
|
1000
|
+
const serialized = serializeImageStreamEvent(event);
|
|
1001
|
+
res.write(`data: ${JSON.stringify(serialized)}
|
|
1002
|
+
|
|
1003
|
+
`);
|
|
1004
|
+
}
|
|
1005
|
+
const result = await resolveImageResult(stream);
|
|
1006
|
+
res.write(`data: ${JSON.stringify(serializeImageResult(result))}
|
|
1007
|
+
|
|
1008
|
+
`);
|
|
1009
|
+
res.write("data: [DONE]\n\n");
|
|
1010
|
+
} catch (error) {
|
|
1011
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1012
|
+
res.write(`data: ${JSON.stringify({ error: message })}
|
|
1013
|
+
|
|
429
1014
|
`);
|
|
430
1015
|
} finally {
|
|
431
1016
|
res.end();
|
|
@@ -437,7 +1022,10 @@ function sendError(message, status, res) {
|
|
|
437
1022
|
}
|
|
438
1023
|
var express = {
|
|
439
1024
|
sendJSON,
|
|
1025
|
+
sendEmbeddingJSON,
|
|
1026
|
+
sendImageJSON,
|
|
440
1027
|
streamSSE,
|
|
1028
|
+
streamImageSSE,
|
|
441
1029
|
sendError
|
|
442
1030
|
};
|
|
443
1031
|
|
|
@@ -445,6 +1033,12 @@ var express = {
|
|
|
445
1033
|
function sendJSON2(turn, reply) {
|
|
446
1034
|
return reply.header("Content-Type", "application/json").send(serializeTurn(turn));
|
|
447
1035
|
}
|
|
1036
|
+
function sendEmbeddingJSON2(result, reply) {
|
|
1037
|
+
return reply.header("Content-Type", "application/json").send(result);
|
|
1038
|
+
}
|
|
1039
|
+
function sendImageJSON2(result, reply) {
|
|
1040
|
+
return reply.header("Content-Type", "application/json").send(serializeImageResult(result));
|
|
1041
|
+
}
|
|
448
1042
|
function streamSSE2(stream, reply) {
|
|
449
1043
|
reply.header("Content-Type", "text/event-stream").header("Cache-Control", "no-cache").header("Connection", "keep-alive");
|
|
450
1044
|
const raw = reply.raw;
|
|
@@ -465,6 +1059,33 @@ function streamSSE2(stream, reply) {
|
|
|
465
1059
|
const message = error instanceof Error ? error.message : String(error);
|
|
466
1060
|
raw.write(`data: ${JSON.stringify({ error: message })}
|
|
467
1061
|
|
|
1062
|
+
`);
|
|
1063
|
+
} finally {
|
|
1064
|
+
raw.end();
|
|
1065
|
+
}
|
|
1066
|
+
})();
|
|
1067
|
+
return reply;
|
|
1068
|
+
}
|
|
1069
|
+
function streamImageSSE2(stream, reply) {
|
|
1070
|
+
reply.header("Content-Type", "text/event-stream").header("Cache-Control", "no-cache").header("Connection", "keep-alive");
|
|
1071
|
+
const raw = reply.raw;
|
|
1072
|
+
(async () => {
|
|
1073
|
+
try {
|
|
1074
|
+
for await (const event of stream) {
|
|
1075
|
+
const serialized = serializeImageStreamEvent(event);
|
|
1076
|
+
raw.write(`data: ${JSON.stringify(serialized)}
|
|
1077
|
+
|
|
1078
|
+
`);
|
|
1079
|
+
}
|
|
1080
|
+
const result = await resolveImageResult(stream);
|
|
1081
|
+
raw.write(`data: ${JSON.stringify(serializeImageResult(result))}
|
|
1082
|
+
|
|
1083
|
+
`);
|
|
1084
|
+
raw.write("data: [DONE]\n\n");
|
|
1085
|
+
} catch (error) {
|
|
1086
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1087
|
+
raw.write(`data: ${JSON.stringify({ error: message })}
|
|
1088
|
+
|
|
468
1089
|
`);
|
|
469
1090
|
} finally {
|
|
470
1091
|
raw.end();
|
|
@@ -477,7 +1098,10 @@ function sendError2(message, status, reply) {
|
|
|
477
1098
|
}
|
|
478
1099
|
var fastify = {
|
|
479
1100
|
sendJSON: sendJSON2,
|
|
1101
|
+
sendEmbeddingJSON: sendEmbeddingJSON2,
|
|
1102
|
+
sendImageJSON: sendImageJSON2,
|
|
480
1103
|
streamSSE: streamSSE2,
|
|
1104
|
+
streamImageSSE: streamImageSSE2,
|
|
481
1105
|
sendError: sendError2
|
|
482
1106
|
};
|
|
483
1107
|
|
|
@@ -486,6 +1110,14 @@ function sendJSON3(turn, event) {
|
|
|
486
1110
|
event.node.res.setHeader("Content-Type", "application/json");
|
|
487
1111
|
return serializeTurn(turn);
|
|
488
1112
|
}
|
|
1113
|
+
function sendEmbeddingJSON3(result, event) {
|
|
1114
|
+
event.node.res.setHeader("Content-Type", "application/json");
|
|
1115
|
+
return result;
|
|
1116
|
+
}
|
|
1117
|
+
function sendImageJSON3(result, event) {
|
|
1118
|
+
event.node.res.setHeader("Content-Type", "application/json");
|
|
1119
|
+
return serializeImageResult(result);
|
|
1120
|
+
}
|
|
489
1121
|
function streamSSE3(stream, event) {
|
|
490
1122
|
const res = event.node.res;
|
|
491
1123
|
res.setHeader("Content-Type", "text/event-stream");
|
|
@@ -508,6 +1140,34 @@ function streamSSE3(stream, event) {
|
|
|
508
1140
|
const message = error instanceof Error ? error.message : String(error);
|
|
509
1141
|
res.write(`data: ${JSON.stringify({ error: message })}
|
|
510
1142
|
|
|
1143
|
+
`);
|
|
1144
|
+
} finally {
|
|
1145
|
+
res.end();
|
|
1146
|
+
}
|
|
1147
|
+
})();
|
|
1148
|
+
}
|
|
1149
|
+
function streamImageSSE3(stream, event) {
|
|
1150
|
+
const res = event.node.res;
|
|
1151
|
+
res.setHeader("Content-Type", "text/event-stream");
|
|
1152
|
+
res.setHeader("Cache-Control", "no-cache");
|
|
1153
|
+
res.setHeader("Connection", "keep-alive");
|
|
1154
|
+
(async () => {
|
|
1155
|
+
try {
|
|
1156
|
+
for await (const evt of stream) {
|
|
1157
|
+
const serialized = serializeImageStreamEvent(evt);
|
|
1158
|
+
res.write(`data: ${JSON.stringify(serialized)}
|
|
1159
|
+
|
|
1160
|
+
`);
|
|
1161
|
+
}
|
|
1162
|
+
const result = await resolveImageResult(stream);
|
|
1163
|
+
res.write(`data: ${JSON.stringify(serializeImageResult(result))}
|
|
1164
|
+
|
|
1165
|
+
`);
|
|
1166
|
+
res.write("data: [DONE]\n\n");
|
|
1167
|
+
} catch (error) {
|
|
1168
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1169
|
+
res.write(`data: ${JSON.stringify({ error: message })}
|
|
1170
|
+
|
|
511
1171
|
`);
|
|
512
1172
|
} finally {
|
|
513
1173
|
res.end();
|
|
@@ -534,6 +1194,33 @@ function createSSEStream(stream) {
|
|
|
534
1194
|
const message = error instanceof Error ? error.message : String(error);
|
|
535
1195
|
controller.enqueue(encoder.encode(`data: ${JSON.stringify({ error: message })}
|
|
536
1196
|
|
|
1197
|
+
`));
|
|
1198
|
+
} finally {
|
|
1199
|
+
controller.close();
|
|
1200
|
+
}
|
|
1201
|
+
}
|
|
1202
|
+
});
|
|
1203
|
+
}
|
|
1204
|
+
function createImageSSEStream(stream) {
|
|
1205
|
+
const encoder = new TextEncoder();
|
|
1206
|
+
return new ReadableStream({
|
|
1207
|
+
async start(controller) {
|
|
1208
|
+
try {
|
|
1209
|
+
for await (const event of stream) {
|
|
1210
|
+
const serialized = serializeImageStreamEvent(event);
|
|
1211
|
+
controller.enqueue(encoder.encode(`data: ${JSON.stringify(serialized)}
|
|
1212
|
+
|
|
1213
|
+
`));
|
|
1214
|
+
}
|
|
1215
|
+
const result = await resolveImageResult(stream);
|
|
1216
|
+
controller.enqueue(encoder.encode(`data: ${JSON.stringify(serializeImageResult(result))}
|
|
1217
|
+
|
|
1218
|
+
`));
|
|
1219
|
+
controller.enqueue(encoder.encode("data: [DONE]\n\n"));
|
|
1220
|
+
} catch (error) {
|
|
1221
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1222
|
+
controller.enqueue(encoder.encode(`data: ${JSON.stringify({ error: message })}
|
|
1223
|
+
|
|
537
1224
|
`));
|
|
538
1225
|
} finally {
|
|
539
1226
|
controller.close();
|
|
@@ -546,8 +1233,12 @@ function sendError3(message, status, event) {
|
|
|
546
1233
|
}
|
|
547
1234
|
var h3 = {
|
|
548
1235
|
sendJSON: sendJSON3,
|
|
1236
|
+
sendEmbeddingJSON: sendEmbeddingJSON3,
|
|
1237
|
+
sendImageJSON: sendImageJSON3,
|
|
549
1238
|
streamSSE: streamSSE3,
|
|
1239
|
+
streamImageSSE: streamImageSSE3,
|
|
550
1240
|
createSSEStream,
|
|
1241
|
+
createImageSSEStream,
|
|
551
1242
|
sendError: sendError3
|
|
552
1243
|
};
|
|
553
1244
|
|
|
@@ -582,15 +1273,71 @@ function parseBody(body) {
|
|
|
582
1273
|
messages: data.messages.map(deserializeMessage),
|
|
583
1274
|
system: data.system,
|
|
584
1275
|
params: data.params,
|
|
1276
|
+
model: typeof data.model === "string" ? data.model : void 0,
|
|
585
1277
|
tools: data.tools,
|
|
586
1278
|
structure: data.structure
|
|
587
1279
|
};
|
|
588
1280
|
}
|
|
1281
|
+
function parseEmbeddingBody(body) {
|
|
1282
|
+
if (!body || typeof body !== "object") {
|
|
1283
|
+
throw new Error("Request body must be an object");
|
|
1284
|
+
}
|
|
1285
|
+
const data = body;
|
|
1286
|
+
if (!Array.isArray(data.inputs)) {
|
|
1287
|
+
throw new Error("Request body must have an inputs array");
|
|
1288
|
+
}
|
|
1289
|
+
const inputs = data.inputs.map(
|
|
1290
|
+
(input) => deserializeEmbeddingInput(input)
|
|
1291
|
+
);
|
|
1292
|
+
return {
|
|
1293
|
+
inputs,
|
|
1294
|
+
params: data.params,
|
|
1295
|
+
model: typeof data.model === "string" ? data.model : void 0
|
|
1296
|
+
};
|
|
1297
|
+
}
|
|
1298
|
+
function parseImageBody(body) {
|
|
1299
|
+
if (!body || typeof body !== "object") {
|
|
1300
|
+
throw new Error("Request body must be an object");
|
|
1301
|
+
}
|
|
1302
|
+
const data = body;
|
|
1303
|
+
const promptValue = data.prompt;
|
|
1304
|
+
let prompt;
|
|
1305
|
+
if (typeof promptValue === "string") {
|
|
1306
|
+
prompt = promptValue;
|
|
1307
|
+
} else if (promptValue && typeof promptValue === "object") {
|
|
1308
|
+
const promptObj = promptValue;
|
|
1309
|
+
if (typeof promptObj.prompt === "string") {
|
|
1310
|
+
prompt = promptObj.prompt;
|
|
1311
|
+
}
|
|
1312
|
+
}
|
|
1313
|
+
if (!prompt) {
|
|
1314
|
+
throw new Error("Request body must have a prompt string");
|
|
1315
|
+
}
|
|
1316
|
+
const image = data.image ? deserializeImage(data.image) : void 0;
|
|
1317
|
+
const mask = data.mask ? deserializeImage(data.mask) : void 0;
|
|
1318
|
+
return {
|
|
1319
|
+
prompt,
|
|
1320
|
+
params: data.params,
|
|
1321
|
+
model: typeof data.model === "string" ? data.model : void 0,
|
|
1322
|
+
image,
|
|
1323
|
+
mask
|
|
1324
|
+
};
|
|
1325
|
+
}
|
|
589
1326
|
function toJSON(turn) {
|
|
590
1327
|
return new Response(JSON.stringify(serializeTurn(turn)), {
|
|
591
1328
|
headers: { "Content-Type": "application/json" }
|
|
592
1329
|
});
|
|
593
1330
|
}
|
|
1331
|
+
function toEmbeddingJSON(result) {
|
|
1332
|
+
return new Response(JSON.stringify(result), {
|
|
1333
|
+
headers: { "Content-Type": "application/json" }
|
|
1334
|
+
});
|
|
1335
|
+
}
|
|
1336
|
+
function toImageJSON(result) {
|
|
1337
|
+
return new Response(JSON.stringify(serializeImageResult(result)), {
|
|
1338
|
+
headers: { "Content-Type": "application/json" }
|
|
1339
|
+
});
|
|
1340
|
+
}
|
|
594
1341
|
function toSSE(stream) {
|
|
595
1342
|
const encoder = new TextEncoder();
|
|
596
1343
|
const readable = new ReadableStream({
|
|
@@ -612,7 +1359,43 @@ function toSSE(stream) {
|
|
|
612
1359
|
controller.close();
|
|
613
1360
|
} catch (error) {
|
|
614
1361
|
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
615
|
-
controller.enqueue(encoder.encode(`data: {
|
|
1362
|
+
controller.enqueue(encoder.encode(`data: ${JSON.stringify({ error: errorMsg })}
|
|
1363
|
+
|
|
1364
|
+
`));
|
|
1365
|
+
controller.close();
|
|
1366
|
+
}
|
|
1367
|
+
}
|
|
1368
|
+
});
|
|
1369
|
+
return new Response(readable, {
|
|
1370
|
+
headers: {
|
|
1371
|
+
"Content-Type": "text/event-stream",
|
|
1372
|
+
"Cache-Control": "no-cache",
|
|
1373
|
+
Connection: "keep-alive"
|
|
1374
|
+
}
|
|
1375
|
+
});
|
|
1376
|
+
}
|
|
1377
|
+
function toImageSSE(stream) {
|
|
1378
|
+
const encoder = new TextEncoder();
|
|
1379
|
+
const readable = new ReadableStream({
|
|
1380
|
+
async start(controller) {
|
|
1381
|
+
try {
|
|
1382
|
+
for await (const event of stream) {
|
|
1383
|
+
const serialized = serializeImageStreamEvent(event);
|
|
1384
|
+
const data = `data: ${JSON.stringify(serialized)}
|
|
1385
|
+
|
|
1386
|
+
`;
|
|
1387
|
+
controller.enqueue(encoder.encode(data));
|
|
1388
|
+
}
|
|
1389
|
+
const result = await resolveImageResult(stream);
|
|
1390
|
+
const resultData = serializeImageResult(result);
|
|
1391
|
+
controller.enqueue(encoder.encode(`data: ${JSON.stringify(resultData)}
|
|
1392
|
+
|
|
1393
|
+
`));
|
|
1394
|
+
controller.enqueue(encoder.encode("data: [DONE]\n\n"));
|
|
1395
|
+
controller.close();
|
|
1396
|
+
} catch (error) {
|
|
1397
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
1398
|
+
controller.enqueue(encoder.encode(`data: ${JSON.stringify({ error: errorMsg })}
|
|
616
1399
|
|
|
617
1400
|
`));
|
|
618
1401
|
controller.close();
|
|
@@ -645,8 +1428,13 @@ function bindTools(schemas, implementations) {
|
|
|
645
1428
|
}
|
|
646
1429
|
var webapi = {
|
|
647
1430
|
parseBody,
|
|
1431
|
+
parseEmbeddingBody,
|
|
1432
|
+
parseImageBody,
|
|
648
1433
|
toJSON,
|
|
1434
|
+
toEmbeddingJSON,
|
|
1435
|
+
toImageJSON,
|
|
649
1436
|
toSSE,
|
|
1437
|
+
toImageSSE,
|
|
650
1438
|
toError: toError2,
|
|
651
1439
|
bindTools
|
|
652
1440
|
};
|
|
@@ -669,7 +1457,9 @@ function proxy(options) {
|
|
|
669
1457
|
name: "proxy",
|
|
670
1458
|
version: "1.0.0",
|
|
671
1459
|
handlers: {
|
|
672
|
-
llm: createLLMHandler(options)
|
|
1460
|
+
llm: createLLMHandler(options),
|
|
1461
|
+
embedding: createEmbeddingHandler(options),
|
|
1462
|
+
image: createImageHandler(options)
|
|
673
1463
|
}
|
|
674
1464
|
});
|
|
675
1465
|
}
|
|
@@ -684,13 +1474,18 @@ export {
|
|
|
684
1474
|
fastify,
|
|
685
1475
|
h3,
|
|
686
1476
|
parseBody,
|
|
1477
|
+
parseEmbeddingBody,
|
|
1478
|
+
parseImageBody,
|
|
687
1479
|
proxy,
|
|
688
1480
|
proxyModel,
|
|
689
1481
|
serializeMessage,
|
|
690
1482
|
serializeStreamEvent,
|
|
691
1483
|
serializeTurn,
|
|
692
1484
|
server,
|
|
1485
|
+
toEmbeddingJSON,
|
|
693
1486
|
toError2 as toError,
|
|
1487
|
+
toImageJSON,
|
|
1488
|
+
toImageSSE,
|
|
694
1489
|
toJSON,
|
|
695
1490
|
toSSE,
|
|
696
1491
|
webapi
|