@providerprotocol/ai 0.0.25 → 0.0.27

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