@providerprotocol/ai 0.0.38 → 0.0.40
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 +363 -37
- package/dist/anthropic/index.d.ts +3 -2
- package/dist/anthropic/index.js +7 -5
- package/dist/anthropic/index.js.map +1 -1
- package/dist/cerebras/index.d.ts +3 -2
- package/dist/cerebras/index.js +7 -5
- package/dist/cerebras/index.js.map +1 -1
- package/dist/chunk-3Q5VELKG.js +124 -0
- package/dist/chunk-3Q5VELKG.js.map +1 -0
- package/dist/{chunk-WU4U6IHF.js → chunk-6QCV4WXF.js} +4 -13
- package/dist/chunk-6QCV4WXF.js.map +1 -0
- package/dist/{chunk-LTEMH3CI.js → chunk-AC3VHSZJ.js} +6 -4
- package/dist/{chunk-LTEMH3CI.js.map → chunk-AC3VHSZJ.js.map} +1 -1
- package/dist/{chunk-YQLR3XOA.js → chunk-BIBMNP7Y.js} +1 -75
- package/dist/chunk-BIBMNP7Y.js.map +1 -0
- package/dist/{chunk-CRP6Y7NF.js → chunk-CWGTARDE.js} +2 -2
- package/dist/{chunk-ZRVNAET3.js → chunk-DI47UY2H.js} +6 -3
- package/dist/chunk-DI47UY2H.js.map +1 -0
- package/dist/{chunk-7GTWHZY2.js → chunk-EHR3LIPS.js} +5 -3
- package/dist/{chunk-7GTWHZY2.js.map → chunk-EHR3LIPS.js.map} +1 -1
- package/dist/chunk-EY2LLDGY.js +94 -0
- package/dist/chunk-EY2LLDGY.js.map +1 -0
- package/dist/{chunk-MJI74VEJ.js → chunk-F5ENANMJ.js} +18 -2
- package/dist/chunk-F5ENANMJ.js.map +1 -0
- package/dist/chunk-IKJH5ZSJ.js +1 -0
- package/dist/chunk-IKJH5ZSJ.js.map +1 -0
- package/dist/{chunk-4RX4VQCB.js → chunk-KBI45OXI.js} +2 -2
- package/dist/{chunk-5IWHCXKN.js → chunk-KVUOTFYZ.js} +2 -2
- package/dist/{chunk-EPB3GQNL.js → chunk-L6QWKFGE.js} +13 -3
- package/dist/chunk-L6QWKFGE.js.map +1 -0
- package/dist/{chunk-BDXH6NQS.js → chunk-N4LAFGLX.js} +7 -7
- package/dist/{chunk-ZKNPQBIE.js → chunk-R3T2IYOU.js} +5 -3
- package/dist/{chunk-ZKNPQBIE.js.map → chunk-R3T2IYOU.js.map} +1 -1
- package/dist/chunk-U2G5PHHL.js +25 -0
- package/dist/chunk-U2G5PHHL.js.map +1 -0
- package/dist/{chunk-SBGZJVTJ.js → chunk-VQZPADW6.js} +100 -33
- package/dist/chunk-VQZPADW6.js.map +1 -0
- package/dist/{chunk-FYSZFIZS.js → chunk-XTWBAL42.js} +5 -3
- package/dist/{chunk-FYSZFIZS.js.map → chunk-XTWBAL42.js.map} +1 -1
- package/dist/{chunk-2YXFLRQ6.js → chunk-ZMESKGUY.js} +2 -2
- package/dist/chunk-ZSZVWLGE.js +83 -0
- package/dist/chunk-ZSZVWLGE.js.map +1 -0
- package/dist/{embedding-CwZ1ZNWv.d.ts → embedding-ts1npsDg.d.ts} +1 -1
- package/dist/google/index.d.ts +38 -3
- package/dist/google/index.js +5 -4
- package/dist/google/index.js.map +1 -1
- package/dist/groq/index.d.ts +3 -2
- package/dist/groq/index.js +7 -5
- package/dist/groq/index.js.map +1 -1
- package/dist/http/index.d.ts +5 -4
- package/dist/http/index.js +19 -22
- package/dist/{image-stream-CeQHtjxS.d.ts → image-stream-BPml2YZZ.d.ts} +1 -1
- package/dist/index.d.ts +8 -7
- package/dist/index.js +316 -113
- package/dist/index.js.map +1 -1
- package/dist/{llm-DS_-l71X.d.ts → llm-BWLaTzzY.d.ts} +89 -36
- package/dist/middleware/logging/index.d.ts +3 -2
- package/dist/middleware/logging/index.js +3 -0
- package/dist/middleware/logging/index.js.map +1 -1
- package/dist/middleware/parsed-object/index.d.ts +3 -2
- package/dist/middleware/parsed-object/index.js +5 -1
- package/dist/middleware/parsed-object/index.js.map +1 -1
- package/dist/middleware/persistence/index.d.ts +3 -2
- package/dist/middleware/persistence/index.js +3 -2
- package/dist/middleware/persistence/index.js.map +1 -1
- package/dist/middleware/pipeline/index.d.ts +195 -0
- package/dist/middleware/pipeline/index.js +61 -0
- package/dist/middleware/pipeline/index.js.map +1 -0
- package/dist/middleware/pubsub/index.d.ts +13 -10
- package/dist/middleware/pubsub/index.js +78 -6
- package/dist/middleware/pubsub/index.js.map +1 -1
- package/dist/middleware/pubsub/server/express/index.d.ts +3 -2
- package/dist/middleware/pubsub/server/express/index.js +2 -2
- package/dist/middleware/pubsub/server/fastify/index.d.ts +3 -2
- package/dist/middleware/pubsub/server/fastify/index.js +2 -2
- package/dist/middleware/pubsub/server/h3/index.d.ts +3 -2
- package/dist/middleware/pubsub/server/h3/index.js +2 -2
- package/dist/middleware/pubsub/server/index.d.ts +50 -8
- package/dist/middleware/pubsub/server/index.js +5 -5
- package/dist/middleware/pubsub/server/index.js.map +1 -1
- package/dist/middleware/pubsub/server/webapi/index.d.ts +3 -2
- package/dist/middleware/pubsub/server/webapi/index.js +2 -2
- package/dist/moonshot/index.d.ts +3 -2
- package/dist/moonshot/index.js +7 -5
- package/dist/moonshot/index.js.map +1 -1
- package/dist/ollama/index.d.ts +24 -3
- package/dist/ollama/index.js +5 -4
- package/dist/ollama/index.js.map +1 -1
- package/dist/openai/index.d.ts +65 -3
- package/dist/openai/index.js +7 -5
- package/dist/openai/index.js.map +1 -1
- package/dist/openrouter/index.d.ts +4 -3
- package/dist/openrouter/index.js +7 -5
- package/dist/openrouter/index.js.map +1 -1
- package/dist/proxy/index.d.ts +5 -4
- package/dist/proxy/index.js +20 -17
- package/dist/proxy/index.js.map +1 -1
- package/dist/proxy/server/express/index.d.ts +8 -8
- package/dist/proxy/server/express/index.js +5 -3
- package/dist/proxy/server/fastify/index.d.ts +8 -8
- package/dist/proxy/server/fastify/index.js +5 -3
- package/dist/proxy/server/h3/index.d.ts +22 -21
- package/dist/proxy/server/h3/index.js +5 -3
- package/dist/proxy/server/index.d.ts +5 -4
- package/dist/proxy/server/index.js +15 -13
- package/dist/proxy/server/webapi/index.d.ts +8 -8
- package/dist/proxy/server/webapi/index.js +5 -3
- package/dist/responses/index.d.ts +3 -2
- package/dist/responses/index.js +7 -5
- package/dist/responses/index.js.map +1 -1
- package/dist/retry-DVfdPLIB.d.ts +322 -0
- package/dist/{stream-sXhBtWjl.d.ts → stream-bBd_4Ipu.d.ts} +29 -419
- package/dist/tool-BmAfKNBq.d.ts +507 -0
- package/dist/{types-Cr4F0tVy.d.ts → types-nTwlpyJE.d.ts} +28 -3
- package/dist/utils/index.d.ts +129 -1
- package/dist/utils/index.js +28 -1
- package/dist/xai/index.d.ts +3 -2
- package/dist/xai/index.js +7 -5
- package/dist/xai/index.js.map +1 -1
- package/package.json +20 -3
- package/dist/chunk-ARVM24K2.js +0 -128
- package/dist/chunk-ARVM24K2.js.map +0 -1
- package/dist/chunk-EPB3GQNL.js.map +0 -1
- package/dist/chunk-MJI74VEJ.js.map +0 -1
- package/dist/chunk-SBGZJVTJ.js.map +0 -1
- package/dist/chunk-WU4U6IHF.js.map +0 -1
- package/dist/chunk-Y5H7C5J4.js +0 -263
- package/dist/chunk-Y5H7C5J4.js.map +0 -1
- package/dist/chunk-YQLR3XOA.js.map +0 -1
- package/dist/chunk-ZRVNAET3.js.map +0 -1
- package/dist/retry-CgoBNa51.d.ts +0 -531
- /package/dist/{chunk-CRP6Y7NF.js.map → chunk-CWGTARDE.js.map} +0 -0
- /package/dist/{chunk-4RX4VQCB.js.map → chunk-KBI45OXI.js.map} +0 -0
- /package/dist/{chunk-5IWHCXKN.js.map → chunk-KVUOTFYZ.js.map} +0 -0
- /package/dist/{chunk-BDXH6NQS.js.map → chunk-N4LAFGLX.js.map} +0 -0
- /package/dist/{chunk-2YXFLRQ6.js.map → chunk-ZMESKGUY.js.map} +0 -0
|
@@ -1,81 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
deserializeStreamEvent,
|
|
3
|
-
serializeStreamEvent
|
|
4
|
-
} from "./chunk-ETBFOLQN.js";
|
|
5
1
|
import {
|
|
6
2
|
Image
|
|
7
3
|
} from "./chunk-N5DX5JW3.js";
|
|
8
|
-
import {
|
|
9
|
-
AssistantMessage,
|
|
10
|
-
ToolResultMessage,
|
|
11
|
-
UserMessage
|
|
12
|
-
} from "./chunk-WU4U6IHF.js";
|
|
13
4
|
import {
|
|
14
5
|
ErrorCode,
|
|
15
6
|
ModalityType,
|
|
16
7
|
UPPError
|
|
17
8
|
} from "./chunk-COS4ON4G.js";
|
|
18
9
|
|
|
19
|
-
// src/providers/proxy/serialization.ts
|
|
20
|
-
function serializeMessage(m) {
|
|
21
|
-
const base = {
|
|
22
|
-
id: m.id,
|
|
23
|
-
type: m.type,
|
|
24
|
-
content: [],
|
|
25
|
-
metadata: m.metadata,
|
|
26
|
-
timestamp: m.timestamp.toISOString()
|
|
27
|
-
};
|
|
28
|
-
if (m instanceof UserMessage) {
|
|
29
|
-
base.content = m.content;
|
|
30
|
-
} else if (m instanceof AssistantMessage) {
|
|
31
|
-
base.content = m.content;
|
|
32
|
-
base.toolCalls = m.toolCalls;
|
|
33
|
-
} else if (m instanceof ToolResultMessage) {
|
|
34
|
-
base.results = m.results;
|
|
35
|
-
}
|
|
36
|
-
return base;
|
|
37
|
-
}
|
|
38
|
-
function deserializeMessage(json) {
|
|
39
|
-
const options = {
|
|
40
|
-
id: json.id,
|
|
41
|
-
metadata: json.metadata
|
|
42
|
-
};
|
|
43
|
-
switch (json.type) {
|
|
44
|
-
case "user":
|
|
45
|
-
return new UserMessage(json.content, options);
|
|
46
|
-
case "assistant":
|
|
47
|
-
return new AssistantMessage(
|
|
48
|
-
json.content,
|
|
49
|
-
json.toolCalls,
|
|
50
|
-
options
|
|
51
|
-
);
|
|
52
|
-
case "tool_result":
|
|
53
|
-
return new ToolResultMessage(json.results ?? [], options);
|
|
54
|
-
default:
|
|
55
|
-
throw new UPPError(
|
|
56
|
-
`Unknown message type: ${json.type}`,
|
|
57
|
-
ErrorCode.InvalidResponse,
|
|
58
|
-
"proxy",
|
|
59
|
-
ModalityType.LLM
|
|
60
|
-
);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
function serializeTurn(turn) {
|
|
64
|
-
return {
|
|
65
|
-
messages: turn.messages.map(serializeMessage),
|
|
66
|
-
toolExecutions: turn.toolExecutions,
|
|
67
|
-
usage: turn.usage,
|
|
68
|
-
cycles: turn.cycles,
|
|
69
|
-
data: turn.data
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
function serializeStreamEvent2(event) {
|
|
73
|
-
return serializeStreamEvent(event);
|
|
74
|
-
}
|
|
75
|
-
function deserializeStreamEvent2(event) {
|
|
76
|
-
return deserializeStreamEvent(event);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
10
|
// src/providers/proxy/serialization.media.ts
|
|
80
11
|
function bytesToBase64(bytes) {
|
|
81
12
|
const binary = Array.from(bytes).map((b) => String.fromCharCode(b)).join("");
|
|
@@ -280,11 +211,6 @@ function resolveImageResult(stream) {
|
|
|
280
211
|
}
|
|
281
212
|
|
|
282
213
|
export {
|
|
283
|
-
serializeMessage,
|
|
284
|
-
deserializeMessage,
|
|
285
|
-
serializeTurn,
|
|
286
|
-
serializeStreamEvent2 as serializeStreamEvent,
|
|
287
|
-
deserializeStreamEvent2 as deserializeStreamEvent,
|
|
288
214
|
serializeImage,
|
|
289
215
|
serializeEmbeddingInput,
|
|
290
216
|
deserializeEmbeddingInput,
|
|
@@ -295,4 +221,4 @@ export {
|
|
|
295
221
|
deserializeImageStreamEvent,
|
|
296
222
|
resolveImageResult
|
|
297
223
|
};
|
|
298
|
-
//# sourceMappingURL=chunk-
|
|
224
|
+
//# sourceMappingURL=chunk-BIBMNP7Y.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/providers/proxy/serialization.media.ts","../src/providers/proxy/server/image-stream.ts"],"sourcesContent":["/**\n * @fileoverview Media serialization utilities for proxy transport.\n *\n * Handles converting embedding inputs and image results/events to/from JSON\n * for HTTP transport. These are pure functions with no side effects.\n *\n * @module providers/proxy/serialization.media\n */\n\nimport type { ImageSource, ImageBlock } from '../../types/content.ts';\nimport type { EmbeddingInput } from '../../types/provider.ts';\nimport type {\n ImageStreamEvent,\n GeneratedImage,\n ImageResponse,\n ImageResult,\n ImageUsage,\n} from '../../types/image.ts';\nimport { Image } from '../../core/media/Image.ts';\nimport { UPPError, ErrorCode, ModalityType } from '../../types/errors.ts';\n\nexport type SerializedImageSource =\n | { type: 'base64'; data: string }\n | { type: 'url'; url: string }\n | { type: 'bytes'; data: number[] | string };\n\nexport interface SerializedImage {\n source: SerializedImageSource;\n mimeType: string;\n width?: number;\n height?: number;\n}\n\nexport interface SerializedGeneratedImage {\n image: SerializedImage;\n metadata?: Record<string, unknown>;\n}\n\nexport interface SerializedImageResponse {\n images: SerializedGeneratedImage[];\n metadata?: Record<string, unknown>;\n usage?: ImageUsage;\n}\n\nexport type SerializedImageStreamEvent =\n | { type: 'preview'; image: SerializedImage; index: number; metadata?: Record<string, unknown> }\n | { type: 'complete'; image: SerializedGeneratedImage; index: number };\n\nexport type SerializedEmbeddingInput =\n | string\n | { type: 'text'; text: string }\n | { type: 'image'; source: SerializedImageSource; mimeType: string };\n\nfunction bytesToBase64(bytes: Uint8Array): string {\n const binary = Array.from(bytes)\n .map((b) => String.fromCharCode(b))\n .join('');\n return btoa(binary);\n}\n\nfunction base64ToBytes(base64: string): Uint8Array {\n const binaryString = atob(base64);\n return Uint8Array.from(binaryString, (c) => c.charCodeAt(0));\n}\n\nfunction coerceBytes(data: number[] | string): Uint8Array {\n if (typeof data === 'string') {\n return base64ToBytes(data);\n }\n return Uint8Array.from(data);\n}\n\nfunction isImageSource(value: unknown): value is ImageSource {\n if (!value || typeof value !== 'object') {\n return false;\n }\n\n const source = value as Record<string, unknown>;\n if (source.type === 'base64') {\n return typeof source.data === 'string';\n }\n if (source.type === 'url') {\n return typeof source.url === 'string';\n }\n if (source.type === 'bytes') {\n return source.data instanceof Uint8Array || Array.isArray(source.data) || typeof source.data === 'string';\n }\n return false;\n}\n\ntype ImageSourceLike = ImageSource | SerializedImageSource;\n\nfunction serializeImageSource(source: ImageSourceLike): SerializedImageSource {\n if (source.type === 'base64') {\n return { type: 'base64', data: source.data };\n }\n if (source.type === 'url') {\n return { type: 'url', url: source.url };\n }\n if (typeof source.data === 'string') {\n return { type: 'base64', data: source.data };\n }\n if (source.data instanceof Uint8Array) {\n return { type: 'base64', data: bytesToBase64(source.data) };\n }\n return { type: 'base64', data: bytesToBase64(Uint8Array.from(source.data)) };\n}\n\nfunction deserializeImageSource(source: SerializedImageSource): ImageSource {\n if (source.type === 'base64') {\n return { type: 'base64', data: source.data };\n }\n if (source.type === 'url') {\n return { type: 'url', url: source.url };\n }\n return { type: 'bytes', data: coerceBytes(source.data) };\n}\n\n/**\n * Serialize an Image for JSON transport.\n */\nexport function serializeImage(image: Image): SerializedImage {\n const block = image.toBlock();\n return {\n source: serializeImageSource(block.source),\n mimeType: block.mimeType,\n width: block.width,\n height: block.height,\n };\n}\n\nfunction serializeUnknownImageSource(\n source: unknown,\n mimeType: string\n): SerializedImageSource {\n if (source instanceof Image) {\n return serializeImage(source).source;\n }\n\n if (isImageSource(source)) {\n return serializeImageSource(source);\n }\n\n if (typeof source === 'string') {\n return { type: 'base64', data: source };\n }\n\n throw new UPPError(\n `Unsupported image source for ${mimeType}`,\n ErrorCode.InvalidRequest,\n 'proxy',\n ModalityType.Embedding\n );\n}\n\n/**\n * Serialize an EmbeddingInput for JSON transport.\n */\nexport function serializeEmbeddingInput(input: EmbeddingInput): SerializedEmbeddingInput {\n if (typeof input === 'string') {\n return input;\n }\n\n if (input.type === 'text') {\n return { type: 'text', text: input.text };\n }\n\n if (input.type === 'image') {\n const source = serializeUnknownImageSource(input.source, input.mimeType);\n return { type: 'image', source, mimeType: input.mimeType };\n }\n\n throw new UPPError(\n 'Unsupported embedding input type',\n ErrorCode.InvalidRequest,\n 'proxy',\n ModalityType.Embedding\n );\n}\n\n/**\n * Deserialize an EmbeddingInput from JSON transport.\n */\nexport function deserializeEmbeddingInput(input: SerializedEmbeddingInput): EmbeddingInput {\n if (typeof input === 'string') {\n return input;\n }\n\n if (input.type === 'text') {\n return { type: 'text', text: input.text };\n }\n\n if (input.type === 'image') {\n return {\n type: 'image',\n mimeType: input.mimeType,\n source: deserializeImageSource(input.source),\n };\n }\n\n throw new UPPError(\n 'Unsupported embedding input type',\n ErrorCode.InvalidResponse,\n 'proxy',\n ModalityType.Embedding\n );\n}\n\n/**\n * Deserialize an Image from JSON transport.\n */\nexport function deserializeImage(image: SerializedImage): Image {\n const block: ImageBlock = {\n type: 'image',\n source: deserializeImageSource(image.source),\n mimeType: image.mimeType,\n width: image.width,\n height: image.height,\n };\n return Image.fromBlock(block);\n}\n\n/**\n * Serialize a GeneratedImage for JSON transport.\n */\nexport function serializeGeneratedImage(image: GeneratedImage): SerializedGeneratedImage {\n return {\n image: serializeImage(image.image),\n metadata: image.metadata,\n };\n}\n\n/**\n * Deserialize a GeneratedImage from JSON transport.\n */\nexport function deserializeGeneratedImage(image: SerializedGeneratedImage): GeneratedImage {\n return {\n image: deserializeImage(image.image),\n metadata: image.metadata,\n };\n}\n\n/**\n * Serialize an ImageResult or ImageResponse for JSON transport.\n */\nexport function serializeImageResult(\n result: ImageResult | ImageResponse\n): SerializedImageResponse {\n return {\n images: result.images.map(serializeGeneratedImage),\n metadata: result.metadata,\n usage: result.usage,\n };\n}\n\n/**\n * Deserialize an ImageResponse from JSON transport.\n */\nexport function deserializeImageResponse(\n response: SerializedImageResponse\n): ImageResponse {\n if (!response || typeof response !== 'object' || !Array.isArray(response.images)) {\n throw new UPPError(\n 'Invalid image response',\n ErrorCode.InvalidResponse,\n 'proxy',\n ModalityType.Image\n );\n }\n\n return {\n images: response.images.map(deserializeGeneratedImage),\n metadata: response.metadata,\n usage: response.usage,\n };\n}\n\n/**\n * Serialize an ImageStreamEvent for JSON transport.\n */\nexport function serializeImageStreamEvent(\n event: ImageStreamEvent\n): SerializedImageStreamEvent {\n if (event.type === 'preview') {\n return {\n type: 'preview',\n index: event.index,\n image: serializeImage(event.image),\n metadata: event.metadata,\n };\n }\n\n return {\n type: 'complete',\n index: event.index,\n image: serializeGeneratedImage(event.image),\n };\n}\n\n/**\n * Deserialize an ImageStreamEvent from JSON transport.\n */\nexport function deserializeImageStreamEvent(\n event: SerializedImageStreamEvent\n): ImageStreamEvent {\n if (event.type === 'preview') {\n return {\n type: 'preview',\n index: event.index,\n image: deserializeImage(event.image),\n metadata: event.metadata,\n };\n }\n\n return {\n type: 'complete',\n index: event.index,\n image: deserializeGeneratedImage(event.image),\n };\n}\n","/**\n * @fileoverview Image stream helpers for proxy server adapters.\n *\n * @module providers/proxy/server/image-stream\n */\n\nimport type {\n ImageStreamResult,\n ImageProviderStreamResult,\n ImageResult,\n} from '../../../types/image.ts';\n\nexport type ImageStreamLike = ImageStreamResult | ImageProviderStreamResult;\n\n/**\n * Resolve the final image result from either core or provider stream types.\n */\nexport function resolveImageResult(stream: ImageStreamLike): Promise<ImageResult> {\n if ('result' in stream) {\n return stream.result;\n }\n return stream.response;\n}\n"],"mappings":";;;;;;;;;;AAqDA,SAAS,cAAc,OAA2B;AAChD,QAAM,SAAS,MAAM,KAAK,KAAK,EAC5B,IAAI,CAAC,MAAM,OAAO,aAAa,CAAC,CAAC,EACjC,KAAK,EAAE;AACV,SAAO,KAAK,MAAM;AACpB;AAEA,SAAS,cAAc,QAA4B;AACjD,QAAM,eAAe,KAAK,MAAM;AAChC,SAAO,WAAW,KAAK,cAAc,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;AAC7D;AAEA,SAAS,YAAY,MAAqC;AACxD,MAAI,OAAO,SAAS,UAAU;AAC5B,WAAO,cAAc,IAAI;AAAA,EAC3B;AACA,SAAO,WAAW,KAAK,IAAI;AAC7B;AAEA,SAAS,cAAc,OAAsC;AAC3D,MAAI,CAAC,SAAS,OAAO,UAAU,UAAU;AACvC,WAAO;AAAA,EACT;AAEA,QAAM,SAAS;AACf,MAAI,OAAO,SAAS,UAAU;AAC5B,WAAO,OAAO,OAAO,SAAS;AAAA,EAChC;AACA,MAAI,OAAO,SAAS,OAAO;AACzB,WAAO,OAAO,OAAO,QAAQ;AAAA,EAC/B;AACA,MAAI,OAAO,SAAS,SAAS;AAC3B,WAAO,OAAO,gBAAgB,cAAc,MAAM,QAAQ,OAAO,IAAI,KAAK,OAAO,OAAO,SAAS;AAAA,EACnG;AACA,SAAO;AACT;AAIA,SAAS,qBAAqB,QAAgD;AAC5E,MAAI,OAAO,SAAS,UAAU;AAC5B,WAAO,EAAE,MAAM,UAAU,MAAM,OAAO,KAAK;AAAA,EAC7C;AACA,MAAI,OAAO,SAAS,OAAO;AACzB,WAAO,EAAE,MAAM,OAAO,KAAK,OAAO,IAAI;AAAA,EACxC;AACA,MAAI,OAAO,OAAO,SAAS,UAAU;AACnC,WAAO,EAAE,MAAM,UAAU,MAAM,OAAO,KAAK;AAAA,EAC7C;AACA,MAAI,OAAO,gBAAgB,YAAY;AACrC,WAAO,EAAE,MAAM,UAAU,MAAM,cAAc,OAAO,IAAI,EAAE;AAAA,EAC5D;AACA,SAAO,EAAE,MAAM,UAAU,MAAM,cAAc,WAAW,KAAK,OAAO,IAAI,CAAC,EAAE;AAC7E;AAEA,SAAS,uBAAuB,QAA4C;AAC1E,MAAI,OAAO,SAAS,UAAU;AAC5B,WAAO,EAAE,MAAM,UAAU,MAAM,OAAO,KAAK;AAAA,EAC7C;AACA,MAAI,OAAO,SAAS,OAAO;AACzB,WAAO,EAAE,MAAM,OAAO,KAAK,OAAO,IAAI;AAAA,EACxC;AACA,SAAO,EAAE,MAAM,SAAS,MAAM,YAAY,OAAO,IAAI,EAAE;AACzD;AAKO,SAAS,eAAe,OAA+B;AAC5D,QAAM,QAAQ,MAAM,QAAQ;AAC5B,SAAO;AAAA,IACL,QAAQ,qBAAqB,MAAM,MAAM;AAAA,IACzC,UAAU,MAAM;AAAA,IAChB,OAAO,MAAM;AAAA,IACb,QAAQ,MAAM;AAAA,EAChB;AACF;AAEA,SAAS,4BACP,QACA,UACuB;AACvB,MAAI,kBAAkB,OAAO;AAC3B,WAAO,eAAe,MAAM,EAAE;AAAA,EAChC;AAEA,MAAI,cAAc,MAAM,GAAG;AACzB,WAAO,qBAAqB,MAAM;AAAA,EACpC;AAEA,MAAI,OAAO,WAAW,UAAU;AAC9B,WAAO,EAAE,MAAM,UAAU,MAAM,OAAO;AAAA,EACxC;AAEA,QAAM,IAAI;AAAA,IACR,gCAAgC,QAAQ;AAAA,IACxC,UAAU;AAAA,IACV;AAAA,IACA,aAAa;AAAA,EACf;AACF;AAKO,SAAS,wBAAwB,OAAiD;AACvF,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO;AAAA,EACT;AAEA,MAAI,MAAM,SAAS,QAAQ;AACzB,WAAO,EAAE,MAAM,QAAQ,MAAM,MAAM,KAAK;AAAA,EAC1C;AAEA,MAAI,MAAM,SAAS,SAAS;AAC1B,UAAM,SAAS,4BAA4B,MAAM,QAAQ,MAAM,QAAQ;AACvE,WAAO,EAAE,MAAM,SAAS,QAAQ,UAAU,MAAM,SAAS;AAAA,EAC3D;AAEA,QAAM,IAAI;AAAA,IACR;AAAA,IACA,UAAU;AAAA,IACV;AAAA,IACA,aAAa;AAAA,EACf;AACF;AAKO,SAAS,0BAA0B,OAAiD;AACzF,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO;AAAA,EACT;AAEA,MAAI,MAAM,SAAS,QAAQ;AACzB,WAAO,EAAE,MAAM,QAAQ,MAAM,MAAM,KAAK;AAAA,EAC1C;AAEA,MAAI,MAAM,SAAS,SAAS;AAC1B,WAAO;AAAA,MACL,MAAM;AAAA,MACN,UAAU,MAAM;AAAA,MAChB,QAAQ,uBAAuB,MAAM,MAAM;AAAA,IAC7C;AAAA,EACF;AAEA,QAAM,IAAI;AAAA,IACR;AAAA,IACA,UAAU;AAAA,IACV;AAAA,IACA,aAAa;AAAA,EACf;AACF;AAKO,SAAS,iBAAiB,OAA+B;AAC9D,QAAM,QAAoB;AAAA,IACxB,MAAM;AAAA,IACN,QAAQ,uBAAuB,MAAM,MAAM;AAAA,IAC3C,UAAU,MAAM;AAAA,IAChB,OAAO,MAAM;AAAA,IACb,QAAQ,MAAM;AAAA,EAChB;AACA,SAAO,MAAM,UAAU,KAAK;AAC9B;AAKO,SAAS,wBAAwB,OAAiD;AACvF,SAAO;AAAA,IACL,OAAO,eAAe,MAAM,KAAK;AAAA,IACjC,UAAU,MAAM;AAAA,EAClB;AACF;AAKO,SAAS,0BAA0B,OAAiD;AACzF,SAAO;AAAA,IACL,OAAO,iBAAiB,MAAM,KAAK;AAAA,IACnC,UAAU,MAAM;AAAA,EAClB;AACF;AAKO,SAAS,qBACd,QACyB;AACzB,SAAO;AAAA,IACL,QAAQ,OAAO,OAAO,IAAI,uBAAuB;AAAA,IACjD,UAAU,OAAO;AAAA,IACjB,OAAO,OAAO;AAAA,EAChB;AACF;AAKO,SAAS,yBACd,UACe;AACf,MAAI,CAAC,YAAY,OAAO,aAAa,YAAY,CAAC,MAAM,QAAQ,SAAS,MAAM,GAAG;AAChF,UAAM,IAAI;AAAA,MACR;AAAA,MACA,UAAU;AAAA,MACV;AAAA,MACA,aAAa;AAAA,IACf;AAAA,EACF;AAEA,SAAO;AAAA,IACL,QAAQ,SAAS,OAAO,IAAI,yBAAyB;AAAA,IACrD,UAAU,SAAS;AAAA,IACnB,OAAO,SAAS;AAAA,EAClB;AACF;AAKO,SAAS,0BACd,OAC4B;AAC5B,MAAI,MAAM,SAAS,WAAW;AAC5B,WAAO;AAAA,MACL,MAAM;AAAA,MACN,OAAO,MAAM;AAAA,MACb,OAAO,eAAe,MAAM,KAAK;AAAA,MACjC,UAAU,MAAM;AAAA,IAClB;AAAA,EACF;AAEA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAO,MAAM;AAAA,IACb,OAAO,wBAAwB,MAAM,KAAK;AAAA,EAC5C;AACF;AAKO,SAAS,4BACd,OACkB;AAClB,MAAI,MAAM,SAAS,WAAW;AAC5B,WAAO;AAAA,MACL,MAAM;AAAA,MACN,OAAO,MAAM;AAAA,MACb,OAAO,iBAAiB,MAAM,KAAK;AAAA,MACnC,UAAU,MAAM;AAAA,IAClB;AAAA,EACF;AAEA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAO,MAAM;AAAA,IACb,OAAO,0BAA0B,MAAM,KAAK;AAAA,EAC9C;AACF;;;AC9SO,SAAS,mBAAmB,QAA+C;AAChF,MAAI,YAAY,QAAQ;AACtB,WAAO,OAAO;AAAA,EAChB;AACA,SAAO,OAAO;AAChB;","names":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
runSubscriberStream
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-L6QWKFGE.js";
|
|
4
4
|
|
|
5
5
|
// src/middleware/pubsub/server/fastify.ts
|
|
6
6
|
async function streamSubscriber(streamId, adapter, reply) {
|
|
@@ -28,4 +28,4 @@ export {
|
|
|
28
28
|
streamSubscriber,
|
|
29
29
|
fastify
|
|
30
30
|
};
|
|
31
|
-
//# sourceMappingURL=chunk-
|
|
31
|
+
//# sourceMappingURL=chunk-CWGTARDE.js.map
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
resolveImageResult,
|
|
3
3
|
serializeImageResult,
|
|
4
|
-
serializeImageStreamEvent
|
|
4
|
+
serializeImageStreamEvent
|
|
5
|
+
} from "./chunk-BIBMNP7Y.js";
|
|
6
|
+
import {
|
|
5
7
|
serializeStreamEvent,
|
|
6
8
|
serializeTurn
|
|
7
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-ZSZVWLGE.js";
|
|
8
10
|
|
|
9
11
|
// src/providers/proxy/server/h3.ts
|
|
10
12
|
function sendJSON(turn, event) {
|
|
@@ -130,6 +132,7 @@ function createImageSSEStream(stream) {
|
|
|
130
132
|
});
|
|
131
133
|
}
|
|
132
134
|
function sendError(message, status, event) {
|
|
135
|
+
event.node.res.statusCode = status;
|
|
133
136
|
return { error: message, statusCode: status };
|
|
134
137
|
}
|
|
135
138
|
var h3 = {
|
|
@@ -154,4 +157,4 @@ export {
|
|
|
154
157
|
sendError,
|
|
155
158
|
h3
|
|
156
159
|
};
|
|
157
|
-
//# sourceMappingURL=chunk-
|
|
160
|
+
//# sourceMappingURL=chunk-DI47UY2H.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/providers/proxy/server/h3.ts"],"sourcesContent":["/**\n * @fileoverview H3/Nitro/Nuxt adapter for proxy server.\n *\n * Provides utilities for using PP proxy with H3-based servers\n * (Nuxt, Nitro, or standalone H3).\n *\n * @module providers/proxy/server/h3\n */\n\nimport type { Turn } from '../../../types/turn.ts';\nimport type { StreamResult } from '../../../types/stream.ts';\nimport type { EmbeddingResult } from '../../../types/embedding.ts';\nimport type { ImageResult } from '../../../types/image.ts';\nimport { serializeTurn, serializeStreamEvent } from '../serialization.ts';\nimport { serializeImageResult, serializeImageStreamEvent } from '../serialization.media.ts';\nimport { resolveImageResult, type ImageStreamLike } from './image-stream.ts';\n\n/**\n * H3 Event interface (minimal type to avoid dependency).\n */\ninterface H3Event {\n node: {\n res: {\n statusCode: number;\n setHeader(name: string, value: string): void;\n write(chunk: string): boolean;\n end(): void;\n };\n };\n}\n\n/**\n * Send a Turn as JSON response.\n *\n * @param turn - The completed inference turn\n * @param event - H3 event object\n * @returns Serialized turn data\n *\n * @example\n * ```typescript\n * const turn = await instance.generate(messages);\n * return h3Adapter.sendJSON(turn, event);\n * ```\n */\nexport function sendJSON(turn: Turn, event: H3Event): unknown {\n event.node.res.setHeader('Content-Type', 'application/json');\n return serializeTurn(turn);\n}\n\n/**\n * Send an EmbeddingResult as JSON response.\n *\n * @param result - The embedding result\n * @param event - H3 event object\n * @returns Serialized result data\n */\nexport function sendEmbeddingJSON(result: EmbeddingResult, event: H3Event): unknown {\n event.node.res.setHeader('Content-Type', 'application/json');\n return result;\n}\n\n/**\n * Send an ImageResult as JSON response.\n *\n * @param result - The image result\n * @param event - H3 event object\n * @returns Serialized image result data\n */\nexport function sendImageJSON(result: ImageResult, event: H3Event): unknown {\n event.node.res.setHeader('Content-Type', 'application/json');\n return serializeImageResult(result);\n}\n\n/**\n * Stream a StreamResult as Server-Sent Events.\n *\n * Note: For better H3/Nuxt integration, prefer using `createSSEStream` with `sendStream`:\n * ```typescript\n * import { sendStream } from 'h3';\n * return sendStream(event, h3Adapter.createSSEStream(stream));\n * ```\n *\n * @param stream - The StreamResult from instance.stream()\n * @param event - H3 event object\n */\nexport function streamSSE(stream: StreamResult, event: H3Event): void {\n const res = event.node.res;\n res.setHeader('Content-Type', 'text/event-stream');\n res.setHeader('Cache-Control', 'no-cache');\n res.setHeader('Connection', 'keep-alive');\n\n (async () => {\n try {\n for await (const evt of stream) {\n const serialized = serializeStreamEvent(evt);\n res.write(`data: ${JSON.stringify(serialized)}\\n\\n`);\n }\n\n const turn = await stream.turn;\n res.write(`data: ${JSON.stringify(serializeTurn(turn))}\\n\\n`);\n res.write('data: [DONE]\\n\\n');\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n res.write(`data: ${JSON.stringify({ error: message })}\\n\\n`);\n } finally {\n res.end();\n }\n })();\n}\n\n/**\n * Stream an ImageStreamResult as Server-Sent Events.\n *\n * @param stream - The ImageStreamResult or ImageProviderStreamResult from image().stream()\n * @param event - H3 event object\n */\nexport function streamImageSSE(stream: ImageStreamLike, event: H3Event): void {\n const res = event.node.res;\n res.setHeader('Content-Type', 'text/event-stream');\n res.setHeader('Cache-Control', 'no-cache');\n res.setHeader('Connection', 'keep-alive');\n\n (async () => {\n try {\n for await (const evt of stream) {\n const serialized = serializeImageStreamEvent(evt);\n res.write(`data: ${JSON.stringify(serialized)}\\n\\n`);\n }\n\n const result = await resolveImageResult(stream);\n res.write(`data: ${JSON.stringify(serializeImageResult(result))}\\n\\n`);\n res.write('data: [DONE]\\n\\n');\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n res.write(`data: ${JSON.stringify({ error: message })}\\n\\n`);\n } finally {\n res.end();\n }\n })();\n}\n\n/**\n * Create a ReadableStream for H3's sendStream utility.\n *\n * Use this with H3's sendStream for better integration:\n * ```typescript\n * import { sendStream } from 'h3';\n * return sendStream(event, h3Adapter.createSSEStream(stream));\n * ```\n *\n * @param stream - The StreamResult from instance.stream()\n * @returns A ReadableStream of SSE data\n */\nexport function createSSEStream(stream: StreamResult): ReadableStream<Uint8Array> {\n const encoder = new TextEncoder();\n\n return new ReadableStream({\n async start(controller) {\n try {\n for await (const event of stream) {\n const serialized = serializeStreamEvent(event);\n controller.enqueue(encoder.encode(`data: ${JSON.stringify(serialized)}\\n\\n`));\n }\n\n const turn = await stream.turn;\n controller.enqueue(encoder.encode(`data: ${JSON.stringify(serializeTurn(turn))}\\n\\n`));\n controller.enqueue(encoder.encode('data: [DONE]\\n\\n'));\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n controller.enqueue(encoder.encode(`data: ${JSON.stringify({ error: message })}\\n\\n`));\n } finally {\n controller.close();\n }\n },\n });\n}\n\n/**\n * Create a ReadableStream for image SSE data.\n *\n * @param stream - The ImageStreamResult or ImageProviderStreamResult from image().stream()\n * @returns A ReadableStream of SSE data\n */\nexport function createImageSSEStream(stream: ImageStreamLike): ReadableStream<Uint8Array> {\n const encoder = new TextEncoder();\n\n return new ReadableStream({\n async start(controller) {\n try {\n for await (const event of stream) {\n const serialized = serializeImageStreamEvent(event);\n controller.enqueue(encoder.encode(`data: ${JSON.stringify(serialized)}\\n\\n`));\n }\n\n const result = await resolveImageResult(stream);\n controller.enqueue(encoder.encode(`data: ${JSON.stringify(serializeImageResult(result))}\\n\\n`));\n controller.enqueue(encoder.encode('data: [DONE]\\n\\n'));\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n controller.enqueue(encoder.encode(`data: ${JSON.stringify({ error: message })}\\n\\n`));\n } finally {\n controller.close();\n }\n },\n });\n}\n\n/**\n * Send an error response with proper HTTP status.\n *\n * @param message - Error message\n * @param status - HTTP status code\n * @param event - H3 event object\n * @returns Error object for H3 to serialize\n */\nexport function sendError(message: string, status: number, event: H3Event): { error: string; statusCode: number } {\n event.node.res.statusCode = status;\n return { error: message, statusCode: status };\n}\n\n/**\n * H3/Nitro/Nuxt adapter utilities.\n *\n * @example Basic usage\n * ```typescript\n * // Nuxt server route: server/api/ai.post.ts\n * import { sendStream } from 'h3';\n * import { llm } from '@providerprotocol/ai';\n * import { anthropic } from '@providerprotocol/ai/anthropic';\n * import { parseBody, h3 as h3Adapter } from '@providerprotocol/ai/proxy';\n *\n * export default defineEventHandler(async (event) => {\n * const body = await readBody(event);\n * const { messages, system, params } = parseBody(body);\n * const instance = llm({ model: anthropic('claude-sonnet-4-20250514'), system });\n *\n * const wantsStream = getHeader(event, 'accept')?.includes('text/event-stream');\n * if (wantsStream) {\n * return sendStream(event, h3Adapter.createSSEStream(instance.stream(messages)));\n * } else {\n * const turn = await instance.generate(messages);\n * return h3Adapter.sendJSON(turn, event);\n * }\n * });\n * ```\n *\n * @example API Gateway with authentication (Nuxt)\n * ```typescript\n * // server/api/ai.post.ts\n * import { sendStream } from 'h3';\n * import { llm, exponentialBackoff, roundRobinKeys } from '@providerprotocol/ai';\n * import { anthropic } from '@providerprotocol/ai/anthropic';\n * import { parseBody, h3 as h3Adapter } from '@providerprotocol/ai/proxy';\n *\n * // Server manages AI provider keys - users never see them\n * const claude = llm({\n * model: anthropic('claude-sonnet-4-20250514'),\n * config: {\n * apiKey: roundRobinKeys([\n * process.env.ANTHROPIC_KEY_1!,\n * process.env.ANTHROPIC_KEY_2!,\n * ]),\n * retryStrategy: exponentialBackoff({ maxAttempts: 3 }),\n * },\n * });\n *\n * export default defineEventHandler(async (event) => {\n * // Authenticate with your platform credentials\n * const token = getHeader(event, 'authorization')?.replace('Bearer ', '');\n * const user = await validatePlatformToken(token);\n * if (!user) {\n * throw createError({ statusCode: 401, message: 'Unauthorized' });\n * }\n *\n * // Track usage per user\n * // await trackUsage(user.id);\n *\n * const body = await readBody(event);\n * const { messages, system, params } = parseBody(body);\n *\n * if (params?.stream) {\n * return sendStream(event, h3Adapter.createSSEStream(claude.stream(messages, { system })));\n * }\n * const turn = await claude.generate(messages, { system });\n * return h3Adapter.sendJSON(turn, event);\n * });\n * ```\n */\nexport const h3 = {\n sendJSON,\n sendEmbeddingJSON,\n sendImageJSON,\n streamSSE,\n streamImageSSE,\n createSSEStream,\n createImageSSEStream,\n sendError,\n};\n"],"mappings":"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","names":[]}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
resolveImageResult,
|
|
3
3
|
serializeImageResult,
|
|
4
|
-
serializeImageStreamEvent
|
|
4
|
+
serializeImageStreamEvent
|
|
5
|
+
} from "./chunk-BIBMNP7Y.js";
|
|
6
|
+
import {
|
|
5
7
|
serializeStreamEvent,
|
|
6
8
|
serializeTurn
|
|
7
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-ZSZVWLGE.js";
|
|
8
10
|
|
|
9
11
|
// src/providers/proxy/server/fastify.ts
|
|
10
12
|
function sendJSON(turn, reply) {
|
|
@@ -91,4 +93,4 @@ export {
|
|
|
91
93
|
sendError,
|
|
92
94
|
fastify
|
|
93
95
|
};
|
|
94
|
-
//# sourceMappingURL=chunk-
|
|
96
|
+
//# sourceMappingURL=chunk-EHR3LIPS.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/providers/proxy/server/fastify.ts"],"sourcesContent":["/**\n * @fileoverview Fastify adapter for proxy server.\n *\n * Provides utilities for using PP proxy with Fastify servers.\n * These adapters convert PP types to Fastify-compatible responses.\n *\n * @module providers/proxy/server/fastify\n */\n\nimport type { Turn } from '../../../types/turn.ts';\nimport type { StreamResult } from '../../../types/stream.ts';\nimport type { EmbeddingResult } from '../../../types/embedding.ts';\nimport type { ImageResult } from '../../../types/image.ts';\nimport { serializeTurn, serializeStreamEvent } from '../serialization.ts';\nimport { serializeImageResult, serializeImageStreamEvent } from '../serialization.media.ts';\nimport { resolveImageResult, type ImageStreamLike } from './image-stream.ts';\n\n/**\n * Fastify Reply interface (minimal type to avoid dependency).\n */\ninterface FastifyReply {\n header(name: string, value: string): FastifyReply;\n status(code: number): FastifyReply;\n send(payload: unknown): FastifyReply;\n raw: {\n write(chunk: string): boolean;\n end(): void;\n };\n}\n\n/**\n * Send a Turn as JSON response.\n *\n * @param turn - The completed inference turn\n * @param reply - Fastify reply object\n *\n * @example\n * ```typescript\n * const turn = await instance.generate(messages);\n * return fastifyAdapter.sendJSON(turn, reply);\n * ```\n */\nexport function sendJSON(turn: Turn, reply: FastifyReply): FastifyReply {\n return reply\n .header('Content-Type', 'application/json')\n .send(serializeTurn(turn));\n}\n\n/**\n * Send an EmbeddingResult as JSON response.\n *\n * @param result - The embedding result\n * @param reply - Fastify reply object\n */\nexport function sendEmbeddingJSON(result: EmbeddingResult, reply: FastifyReply): FastifyReply {\n return reply\n .header('Content-Type', 'application/json')\n .send(result);\n}\n\n/**\n * Send an ImageResult as JSON response.\n *\n * @param result - The image result\n * @param reply - Fastify reply object\n */\nexport function sendImageJSON(result: ImageResult, reply: FastifyReply): FastifyReply {\n return reply\n .header('Content-Type', 'application/json')\n .send(serializeImageResult(result));\n}\n\n/**\n * Stream a StreamResult as Server-Sent Events.\n *\n * @param stream - The StreamResult from instance.stream()\n * @param reply - Fastify reply object\n *\n * @example\n * ```typescript\n * const stream = instance.stream(messages);\n * return fastifyAdapter.streamSSE(stream, reply);\n * ```\n */\nexport function streamSSE(stream: StreamResult, reply: FastifyReply): FastifyReply {\n reply\n .header('Content-Type', 'text/event-stream')\n .header('Cache-Control', 'no-cache')\n .header('Connection', 'keep-alive');\n\n const raw = reply.raw;\n\n (async () => {\n try {\n for await (const event of stream) {\n const serialized = serializeStreamEvent(event);\n raw.write(`data: ${JSON.stringify(serialized)}\\n\\n`);\n }\n\n const turn = await stream.turn;\n raw.write(`data: ${JSON.stringify(serializeTurn(turn))}\\n\\n`);\n raw.write('data: [DONE]\\n\\n');\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n raw.write(`data: ${JSON.stringify({ error: message })}\\n\\n`);\n } finally {\n raw.end();\n }\n })();\n\n return reply;\n}\n\n/**\n * Stream an ImageStreamResult as Server-Sent Events.\n *\n * @param stream - The ImageStreamResult or ImageProviderStreamResult from image().stream()\n * @param reply - Fastify reply object\n */\nexport function streamImageSSE(stream: ImageStreamLike, reply: FastifyReply): FastifyReply {\n reply\n .header('Content-Type', 'text/event-stream')\n .header('Cache-Control', 'no-cache')\n .header('Connection', 'keep-alive');\n\n const raw = reply.raw;\n\n (async () => {\n try {\n for await (const event of stream) {\n const serialized = serializeImageStreamEvent(event);\n raw.write(`data: ${JSON.stringify(serialized)}\\n\\n`);\n }\n\n const result = await resolveImageResult(stream);\n raw.write(`data: ${JSON.stringify(serializeImageResult(result))}\\n\\n`);\n raw.write('data: [DONE]\\n\\n');\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n raw.write(`data: ${JSON.stringify({ error: message })}\\n\\n`);\n } finally {\n raw.end();\n }\n })();\n\n return reply;\n}\n\n/**\n * Send an error response.\n *\n * @param message - Error message\n * @param status - HTTP status code\n * @param reply - Fastify reply object\n */\nexport function sendError(message: string, status: number, reply: FastifyReply): FastifyReply {\n return reply.status(status).send({ error: message });\n}\n\n/**\n * Fastify adapter utilities.\n *\n * @example Basic usage\n * ```typescript\n * import Fastify from 'fastify';\n * import { llm } from '@providerprotocol/ai';\n * import { anthropic } from '@providerprotocol/ai/anthropic';\n * import { parseBody } from '@providerprotocol/ai/proxy';\n * import { fastify as fastifyAdapter } from '@providerprotocol/ai/proxy/server';\n *\n * const app = Fastify();\n *\n * app.post('/api/ai', async (request, reply) => {\n * const { messages, system, params } = parseBody(request.body);\n * const instance = llm({ model: anthropic('claude-sonnet-4-20250514'), system });\n *\n * if (request.headers.accept?.includes('text/event-stream')) {\n * return fastifyAdapter.streamSSE(instance.stream(messages), reply);\n * } else {\n * const turn = await instance.generate(messages);\n * return fastifyAdapter.sendJSON(turn, reply);\n * }\n * });\n * ```\n *\n * @example API Gateway with authentication\n * ```typescript\n * import Fastify from 'fastify';\n * import { llm } from '@providerprotocol/ai';\n * import { anthropic } from '@providerprotocol/ai/anthropic';\n * import {
|
|
1
|
+
{"version":3,"sources":["../src/providers/proxy/server/fastify.ts"],"sourcesContent":["/**\n * @fileoverview Fastify adapter for proxy server.\n *\n * Provides utilities for using PP proxy with Fastify servers.\n * These adapters convert PP types to Fastify-compatible responses.\n *\n * @module providers/proxy/server/fastify\n */\n\nimport type { Turn } from '../../../types/turn.ts';\nimport type { StreamResult } from '../../../types/stream.ts';\nimport type { EmbeddingResult } from '../../../types/embedding.ts';\nimport type { ImageResult } from '../../../types/image.ts';\nimport { serializeTurn, serializeStreamEvent } from '../serialization.ts';\nimport { serializeImageResult, serializeImageStreamEvent } from '../serialization.media.ts';\nimport { resolveImageResult, type ImageStreamLike } from './image-stream.ts';\n\n/**\n * Fastify Reply interface (minimal type to avoid dependency).\n */\ninterface FastifyReply {\n header(name: string, value: string): FastifyReply;\n status(code: number): FastifyReply;\n send(payload: unknown): FastifyReply;\n raw: {\n write(chunk: string): boolean;\n end(): void;\n };\n}\n\n/**\n * Send a Turn as JSON response.\n *\n * @param turn - The completed inference turn\n * @param reply - Fastify reply object\n *\n * @example\n * ```typescript\n * const turn = await instance.generate(messages);\n * return fastifyAdapter.sendJSON(turn, reply);\n * ```\n */\nexport function sendJSON(turn: Turn, reply: FastifyReply): FastifyReply {\n return reply\n .header('Content-Type', 'application/json')\n .send(serializeTurn(turn));\n}\n\n/**\n * Send an EmbeddingResult as JSON response.\n *\n * @param result - The embedding result\n * @param reply - Fastify reply object\n */\nexport function sendEmbeddingJSON(result: EmbeddingResult, reply: FastifyReply): FastifyReply {\n return reply\n .header('Content-Type', 'application/json')\n .send(result);\n}\n\n/**\n * Send an ImageResult as JSON response.\n *\n * @param result - The image result\n * @param reply - Fastify reply object\n */\nexport function sendImageJSON(result: ImageResult, reply: FastifyReply): FastifyReply {\n return reply\n .header('Content-Type', 'application/json')\n .send(serializeImageResult(result));\n}\n\n/**\n * Stream a StreamResult as Server-Sent Events.\n *\n * @param stream - The StreamResult from instance.stream()\n * @param reply - Fastify reply object\n *\n * @example\n * ```typescript\n * const stream = instance.stream(messages);\n * return fastifyAdapter.streamSSE(stream, reply);\n * ```\n */\nexport function streamSSE(stream: StreamResult, reply: FastifyReply): FastifyReply {\n reply\n .header('Content-Type', 'text/event-stream')\n .header('Cache-Control', 'no-cache')\n .header('Connection', 'keep-alive');\n\n const raw = reply.raw;\n\n (async () => {\n try {\n for await (const event of stream) {\n const serialized = serializeStreamEvent(event);\n raw.write(`data: ${JSON.stringify(serialized)}\\n\\n`);\n }\n\n const turn = await stream.turn;\n raw.write(`data: ${JSON.stringify(serializeTurn(turn))}\\n\\n`);\n raw.write('data: [DONE]\\n\\n');\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n raw.write(`data: ${JSON.stringify({ error: message })}\\n\\n`);\n } finally {\n raw.end();\n }\n })();\n\n return reply;\n}\n\n/**\n * Stream an ImageStreamResult as Server-Sent Events.\n *\n * @param stream - The ImageStreamResult or ImageProviderStreamResult from image().stream()\n * @param reply - Fastify reply object\n */\nexport function streamImageSSE(stream: ImageStreamLike, reply: FastifyReply): FastifyReply {\n reply\n .header('Content-Type', 'text/event-stream')\n .header('Cache-Control', 'no-cache')\n .header('Connection', 'keep-alive');\n\n const raw = reply.raw;\n\n (async () => {\n try {\n for await (const event of stream) {\n const serialized = serializeImageStreamEvent(event);\n raw.write(`data: ${JSON.stringify(serialized)}\\n\\n`);\n }\n\n const result = await resolveImageResult(stream);\n raw.write(`data: ${JSON.stringify(serializeImageResult(result))}\\n\\n`);\n raw.write('data: [DONE]\\n\\n');\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n raw.write(`data: ${JSON.stringify({ error: message })}\\n\\n`);\n } finally {\n raw.end();\n }\n })();\n\n return reply;\n}\n\n/**\n * Send an error response.\n *\n * @param message - Error message\n * @param status - HTTP status code\n * @param reply - Fastify reply object\n */\nexport function sendError(message: string, status: number, reply: FastifyReply): FastifyReply {\n return reply.status(status).send({ error: message });\n}\n\n/**\n * Fastify adapter utilities.\n *\n * @example Basic usage\n * ```typescript\n * import Fastify from 'fastify';\n * import { llm } from '@providerprotocol/ai';\n * import { anthropic } from '@providerprotocol/ai/anthropic';\n * import { parseBody } from '@providerprotocol/ai/proxy';\n * import { fastify as fastifyAdapter } from '@providerprotocol/ai/proxy/server';\n *\n * const app = Fastify();\n *\n * app.post('/api/ai', async (request, reply) => {\n * const { messages, system, params } = parseBody(request.body);\n * const instance = llm({ model: anthropic('claude-sonnet-4-20250514'), system });\n *\n * if (request.headers.accept?.includes('text/event-stream')) {\n * return fastifyAdapter.streamSSE(instance.stream(messages), reply);\n * } else {\n * const turn = await instance.generate(messages);\n * return fastifyAdapter.sendJSON(turn, reply);\n * }\n * });\n * ```\n *\n * @example API Gateway with authentication\n * ```typescript\n * import Fastify from 'fastify';\n * import { llm, exponentialBackoff, roundRobinKeys } from '@providerprotocol/ai';\n * import { anthropic } from '@providerprotocol/ai/anthropic';\n * import { parseBody } from '@providerprotocol/ai/proxy';\n * import { fastify as fastifyAdapter } from '@providerprotocol/ai/proxy/server';\n *\n * const app = Fastify();\n *\n * // Server manages AI provider keys - users never see them\n * const claude = llm({\n * model: anthropic('claude-sonnet-4-20250514'),\n * config: {\n * apiKey: roundRobinKeys([process.env.ANTHROPIC_KEY_1!, process.env.ANTHROPIC_KEY_2!]),\n * retryStrategy: exponentialBackoff({ maxAttempts: 3 }),\n * },\n * });\n *\n * // Auth hook for your platform\n * app.addHook('preHandler', async (request, reply) => {\n * const token = request.headers.authorization?.replace('Bearer ', '');\n * const user = await validatePlatformToken(token);\n * if (!user) {\n * reply.status(401).send({ error: 'Unauthorized' });\n * return;\n * }\n * request.user = user;\n * });\n *\n * app.post('/api/ai', async (request, reply) => {\n * // Track usage per user\n * // await trackUsage(request.user.id);\n *\n * const { messages, system, params } = parseBody(request.body);\n *\n * if (params?.stream) {\n * return fastifyAdapter.streamSSE(claude.stream(messages, { system }), reply);\n * }\n * const turn = await claude.generate(messages, { system });\n * return fastifyAdapter.sendJSON(turn, reply);\n * });\n * ```\n */\nexport const fastify = {\n sendJSON,\n sendEmbeddingJSON,\n sendImageJSON,\n streamSSE,\n streamImageSSE,\n sendError,\n};\n"],"mappings":";;;;;;;;;;;AA0CO,SAAS,SAAS,MAAY,OAAmC;AACtE,SAAO,MACJ,OAAO,gBAAgB,kBAAkB,EACzC,KAAK,cAAc,IAAI,CAAC;AAC7B;AAQO,SAAS,kBAAkB,QAAyB,OAAmC;AAC5F,SAAO,MACJ,OAAO,gBAAgB,kBAAkB,EACzC,KAAK,MAAM;AAChB;AAQO,SAAS,cAAc,QAAqB,OAAmC;AACpF,SAAO,MACJ,OAAO,gBAAgB,kBAAkB,EACzC,KAAK,qBAAqB,MAAM,CAAC;AACtC;AAcO,SAAS,UAAU,QAAsB,OAAmC;AACjF,QACG,OAAO,gBAAgB,mBAAmB,EAC1C,OAAO,iBAAiB,UAAU,EAClC,OAAO,cAAc,YAAY;AAEpC,QAAM,MAAM,MAAM;AAElB,GAAC,YAAY;AACX,QAAI;AACF,uBAAiB,SAAS,QAAQ;AAChC,cAAM,aAAa,qBAAqB,KAAK;AAC7C,YAAI,MAAM,SAAS,KAAK,UAAU,UAAU,CAAC;AAAA;AAAA,CAAM;AAAA,MACrD;AAEA,YAAM,OAAO,MAAM,OAAO;AAC1B,UAAI,MAAM,SAAS,KAAK,UAAU,cAAc,IAAI,CAAC,CAAC;AAAA;AAAA,CAAM;AAC5D,UAAI,MAAM,kBAAkB;AAAA,IAC9B,SAAS,OAAO;AACd,YAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,UAAI,MAAM,SAAS,KAAK,UAAU,EAAE,OAAO,QAAQ,CAAC,CAAC;AAAA;AAAA,CAAM;AAAA,IAC7D,UAAE;AACA,UAAI,IAAI;AAAA,IACV;AAAA,EACF,GAAG;AAEH,SAAO;AACT;AAQO,SAAS,eAAe,QAAyB,OAAmC;AACzF,QACG,OAAO,gBAAgB,mBAAmB,EAC1C,OAAO,iBAAiB,UAAU,EAClC,OAAO,cAAc,YAAY;AAEpC,QAAM,MAAM,MAAM;AAElB,GAAC,YAAY;AACX,QAAI;AACF,uBAAiB,SAAS,QAAQ;AAChC,cAAM,aAAa,0BAA0B,KAAK;AAClD,YAAI,MAAM,SAAS,KAAK,UAAU,UAAU,CAAC;AAAA;AAAA,CAAM;AAAA,MACrD;AAEA,YAAM,SAAS,MAAM,mBAAmB,MAAM;AAC9C,UAAI,MAAM,SAAS,KAAK,UAAU,qBAAqB,MAAM,CAAC,CAAC;AAAA;AAAA,CAAM;AACrE,UAAI,MAAM,kBAAkB;AAAA,IAC9B,SAAS,OAAO;AACd,YAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,UAAI,MAAM,SAAS,KAAK,UAAU,EAAE,OAAO,QAAQ,CAAC,CAAC;AAAA;AAAA,CAAM;AAAA,IAC7D,UAAE;AACA,UAAI,IAAI;AAAA,IACV;AAAA,EACF,GAAG;AAEH,SAAO;AACT;AASO,SAAS,UAAU,SAAiB,QAAgB,OAAmC;AAC5F,SAAO,MAAM,OAAO,MAAM,EAAE,KAAK,EAAE,OAAO,QAAQ,CAAC;AACrD;AAwEO,IAAM,UAAU;AAAA,EACrB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;","names":[]}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ErrorCode,
|
|
3
|
+
UPPError
|
|
4
|
+
} from "./chunk-COS4ON4G.js";
|
|
5
|
+
|
|
6
|
+
// src/http/keys.ts
|
|
7
|
+
function roundRobinKeys(keys) {
|
|
8
|
+
if (keys.length === 0) {
|
|
9
|
+
throw new Error("roundRobinKeys requires at least one key");
|
|
10
|
+
}
|
|
11
|
+
const snapshot = [...keys];
|
|
12
|
+
let index = 0;
|
|
13
|
+
return {
|
|
14
|
+
getKey() {
|
|
15
|
+
const key = snapshot[index];
|
|
16
|
+
index = (index + 1) % snapshot.length;
|
|
17
|
+
return key;
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
function weightedKeys(keys) {
|
|
22
|
+
if (keys.length === 0) {
|
|
23
|
+
throw new Error("weightedKeys requires at least one key");
|
|
24
|
+
}
|
|
25
|
+
const snapshot = keys.map((k) => ({ ...k }));
|
|
26
|
+
const totalWeight = snapshot.reduce((sum, k) => sum + k.weight, 0);
|
|
27
|
+
if (totalWeight <= 0) {
|
|
28
|
+
throw new Error("weightedKeys requires at least one key with a positive weight");
|
|
29
|
+
}
|
|
30
|
+
return {
|
|
31
|
+
getKey() {
|
|
32
|
+
const random = Math.random() * totalWeight;
|
|
33
|
+
let cumulative = 0;
|
|
34
|
+
for (const entry of snapshot) {
|
|
35
|
+
cumulative += entry.weight;
|
|
36
|
+
if (random <= cumulative) {
|
|
37
|
+
return entry.key;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return snapshot[snapshot.length - 1].key;
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
function dynamicKey(selector) {
|
|
45
|
+
return {
|
|
46
|
+
async getKey() {
|
|
47
|
+
return selector();
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
function maskApiKey(key) {
|
|
52
|
+
if (key.length <= 8) {
|
|
53
|
+
return "***";
|
|
54
|
+
}
|
|
55
|
+
return `${key.slice(0, 4)}...${key.slice(-4)}`;
|
|
56
|
+
}
|
|
57
|
+
function isKeyStrategy(value) {
|
|
58
|
+
return typeof value === "object" && value !== null && "getKey" in value && typeof value.getKey === "function";
|
|
59
|
+
}
|
|
60
|
+
async function resolveApiKey(config, envVar, provider = "unknown", modality = "llm") {
|
|
61
|
+
const { apiKey } = config;
|
|
62
|
+
if (apiKey !== void 0) {
|
|
63
|
+
if (typeof apiKey === "string") {
|
|
64
|
+
return apiKey;
|
|
65
|
+
}
|
|
66
|
+
if (typeof apiKey === "function") {
|
|
67
|
+
return apiKey();
|
|
68
|
+
}
|
|
69
|
+
if (isKeyStrategy(apiKey)) {
|
|
70
|
+
return apiKey.getKey();
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (envVar) {
|
|
74
|
+
const envValue = process.env[envVar];
|
|
75
|
+
if (envValue) {
|
|
76
|
+
return envValue;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
throw new UPPError(
|
|
80
|
+
envVar ? `API key not found. Set ${envVar} environment variable or provide apiKey in config.` : "API key not found. Provide apiKey in config.",
|
|
81
|
+
ErrorCode.AuthenticationFailed,
|
|
82
|
+
provider,
|
|
83
|
+
modality
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export {
|
|
88
|
+
roundRobinKeys,
|
|
89
|
+
weightedKeys,
|
|
90
|
+
dynamicKey,
|
|
91
|
+
maskApiKey,
|
|
92
|
+
resolveApiKey
|
|
93
|
+
};
|
|
94
|
+
//# sourceMappingURL=chunk-EY2LLDGY.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/http/keys.ts"],"sourcesContent":["/**\n * API key management strategies for load balancing and dynamic key selection.\n * @module http/keys\n */\n\nimport type { ProviderConfig, KeyStrategy } from '../types/provider.ts';\nimport { ErrorCode, UPPError, type Modality } from '../types/errors.ts';\n\n/**\n * Creates a key strategy that distributes API requests across multiple keys\n * using round-robin selection.\n *\n * Each call to `getKey()` returns the next key in sequence, cycling back to\n * the first key after reaching the end. This provides even distribution of requests\n * across all available keys, which is useful for:\n * - Spreading rate limits across multiple API keys\n * - Load balancing between different accounts\n * - Maximizing throughput when multiple keys are available\n *\n * @param keys - Array of API keys to rotate through\n * @returns A {@link KeyStrategy} that cycles through the provided keys\n * @throws {Error} When the keys array is empty\n *\n * @example\n * ```typescript\n * const keys = roundRobinKeys([\n * 'sk-key-1',\n * 'sk-key-2',\n * 'sk-key-3'\n * ]);\n *\n * keys.getKey(); // Returns 'sk-key-1'\n * keys.getKey(); // Returns 'sk-key-2'\n * keys.getKey(); // Returns 'sk-key-3'\n * keys.getKey(); // Returns 'sk-key-1' (cycles back)\n * ```\n */\nexport function roundRobinKeys(keys: string[]): KeyStrategy {\n if (keys.length === 0) {\n throw new Error('roundRobinKeys requires at least one key');\n }\n const snapshot = [...keys];\n let index = 0;\n return {\n getKey(): string {\n const key = snapshot[index]!;\n index = (index + 1) % snapshot.length;\n return key;\n },\n };\n}\n\n/**\n * Creates a key strategy that selects API keys using weighted random probability.\n *\n * Each key is assigned a weight that determines its probability of being selected.\n * Higher weights mean higher selection probability. This is useful for:\n * - Preferring higher-tier API keys with better rate limits\n * - Gradually migrating traffic between old and new keys\n * - A/B testing different API accounts\n * - Directing more traffic to keys with higher quotas\n *\n * The selection probability for each key is: weight / totalWeight\n *\n * @param keys - Array of key-weight pairs defining selection probabilities\n * @returns A {@link KeyStrategy} that selects keys by weighted probability\n * @throws {Error} When the keys array is empty\n *\n * @example\n * ```typescript\n * const keys = weightedKeys([\n * { key: 'sk-premium', weight: 70 }, // 70% of requests\n * { key: 'sk-standard', weight: 20 }, // 20% of requests\n * { key: 'sk-backup', weight: 10 } // 10% of requests\n * ]);\n *\n * // Configure provider with weighted key selection\n * const provider = createOpenAI({\n * apiKey: keys\n * });\n * ```\n */\nexport function weightedKeys(keys: Array<{ key: string; weight: number }>): KeyStrategy {\n if (keys.length === 0) {\n throw new Error('weightedKeys requires at least one key');\n }\n const snapshot = keys.map((k) => ({ ...k }));\n const totalWeight = snapshot.reduce((sum, k) => sum + k.weight, 0);\n if (totalWeight <= 0) {\n throw new Error('weightedKeys requires at least one key with a positive weight');\n }\n return {\n getKey(): string {\n const random = Math.random() * totalWeight;\n let cumulative = 0;\n\n for (const entry of snapshot) {\n cumulative += entry.weight;\n if (random <= cumulative) {\n return entry.key;\n }\n }\n\n return snapshot[snapshot.length - 1]!.key;\n },\n };\n}\n\n/**\n * Creates a key strategy that delegates key selection to a user-provided function,\n * enabling advanced scenarios such as:\n * - Fetching keys from a secrets manager (AWS Secrets Manager, HashiCorp Vault)\n * - Rotating keys based on external state or configuration\n * - Selecting keys based on request context or time of day\n * - Implementing custom load balancing algorithms\n *\n * The selector function can be synchronous or asynchronous.\n *\n * @param selector - Function that returns an API key (sync or async)\n * @returns A {@link KeyStrategy} that delegates to the selector function\n *\n * @example\n * ```typescript\n * // Fetch key from environment based on current mode\n * const envKey = dynamicKey(() => {\n * return process.env.NODE_ENV === 'production'\n * ? process.env.PROD_API_KEY!\n * : process.env.DEV_API_KEY!;\n * });\n *\n * // Async key fetching from a secrets manager\n * const vaultKey = dynamicKey(async () => {\n * const secret = await vault.read('secret/openai');\n * return secret.data.apiKey;\n * });\n *\n * // Time-based key rotation\n * const timedKey = dynamicKey(() => {\n * const hour = new Date().getHours();\n * return hour < 12 ? morningKey : afternoonKey;\n * });\n * ```\n */\nexport function dynamicKey(selector: () => string | Promise<string>): KeyStrategy {\n return {\n async getKey(): Promise<string> {\n return selector();\n },\n };\n}\n\n/**\n * Masks an API key for safe logging.\n * Shows first 4 and last 4 characters with ellipsis, or '***' for short keys.\n *\n * @param key - The API key to mask\n * @returns Masked key like \"sk-ab...yz12\" or \"***\" for short keys\n *\n * @example\n * ```typescript\n * maskApiKey('sk-abc123def456xyz789'); // 'sk-a...z789'\n * maskApiKey('short'); // '***'\n * ```\n */\nexport function maskApiKey(key: string): string {\n if (key.length <= 8) {\n return '***';\n }\n return `${key.slice(0, 4)}...${key.slice(-4)}`;\n}\n\n/**\n * Type guard to check if a value implements the KeyStrategy interface.\n *\n * @param value - The value to check\n * @returns True if the value has a getKey method\n */\nfunction isKeyStrategy(value: unknown): value is KeyStrategy {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'getKey' in value &&\n typeof (value as KeyStrategy).getKey === 'function'\n );\n}\n\n/**\n * Resolves an API key from provider configuration with multiple fallback options.\n *\n * This function handles various key specification methods in priority order:\n * 1. Direct string key in config.apiKey\n * 2. Function returning a key (sync or async) in config.apiKey\n * 3. KeyStrategy instance in config.apiKey (roundRobinKeys, weightedKeys, dynamicKey)\n * 4. Environment variable fallback (if envVar parameter is provided)\n *\n * @param config - Provider configuration containing the apiKey option\n * @param envVar - Optional environment variable name to check as fallback\n * @param provider - Provider identifier for error context (default: 'unknown')\n * @param modality - Request modality for error context (default: 'llm')\n * @returns The resolved API key string\n *\n * @throws {UPPError} AUTHENTICATION_FAILED - When no valid key is found\n *\n * @example\n * ```typescript\n * // Direct key in config\n * const key1 = await resolveApiKey({ apiKey: 'sk-...' }, 'OPENAI_API_KEY', 'openai');\n *\n * // Function-based key\n * const key2 = await resolveApiKey({ apiKey: () => getKeyFromVault() }, undefined, 'anthropic');\n *\n * // KeyStrategy instance\n * const key3 = await resolveApiKey({\n * apiKey: roundRobinKeys(['sk-1', 'sk-2', 'sk-3'])\n * }, 'OPENAI_API_KEY', 'openai');\n *\n * // Environment variable fallback\n * const key4 = await resolveApiKey({}, 'ANTHROPIC_API_KEY', 'anthropic');\n * ```\n */\nexport async function resolveApiKey(\n config: ProviderConfig,\n envVar?: string,\n provider = 'unknown',\n modality: Modality = 'llm'\n): Promise<string> {\n const { apiKey } = config;\n\n if (apiKey !== undefined) {\n if (typeof apiKey === 'string') {\n return apiKey;\n }\n\n if (typeof apiKey === 'function') {\n return apiKey();\n }\n\n if (isKeyStrategy(apiKey)) {\n return apiKey.getKey();\n }\n }\n\n if (envVar) {\n const envValue = process.env[envVar];\n if (envValue) {\n return envValue;\n }\n }\n\n throw new UPPError(\n envVar\n ? `API key not found. Set ${envVar} environment variable or provide apiKey in config.`\n : 'API key not found. Provide apiKey in config.',\n ErrorCode.AuthenticationFailed,\n provider,\n modality\n );\n}\n"],"mappings":";;;;;;AAqCO,SAAS,eAAe,MAA6B;AAC1D,MAAI,KAAK,WAAW,GAAG;AACrB,UAAM,IAAI,MAAM,0CAA0C;AAAA,EAC5D;AACA,QAAM,WAAW,CAAC,GAAG,IAAI;AACzB,MAAI,QAAQ;AACZ,SAAO;AAAA,IACL,SAAiB;AACf,YAAM,MAAM,SAAS,KAAK;AAC1B,eAAS,QAAQ,KAAK,SAAS;AAC/B,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAgCO,SAAS,aAAa,MAA2D;AACtF,MAAI,KAAK,WAAW,GAAG;AACrB,UAAM,IAAI,MAAM,wCAAwC;AAAA,EAC1D;AACA,QAAM,WAAW,KAAK,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE;AAC3C,QAAM,cAAc,SAAS,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,QAAQ,CAAC;AACjE,MAAI,eAAe,GAAG;AACpB,UAAM,IAAI,MAAM,+DAA+D;AAAA,EACjF;AACA,SAAO;AAAA,IACL,SAAiB;AACf,YAAM,SAAS,KAAK,OAAO,IAAI;AAC/B,UAAI,aAAa;AAEjB,iBAAW,SAAS,UAAU;AAC5B,sBAAc,MAAM;AACpB,YAAI,UAAU,YAAY;AACxB,iBAAO,MAAM;AAAA,QACf;AAAA,MACF;AAEA,aAAO,SAAS,SAAS,SAAS,CAAC,EAAG;AAAA,IACxC;AAAA,EACF;AACF;AAqCO,SAAS,WAAW,UAAuD;AAChF,SAAO;AAAA,IACL,MAAM,SAA0B;AAC9B,aAAO,SAAS;AAAA,IAClB;AAAA,EACF;AACF;AAeO,SAAS,WAAW,KAAqB;AAC9C,MAAI,IAAI,UAAU,GAAG;AACnB,WAAO;AAAA,EACT;AACA,SAAO,GAAG,IAAI,MAAM,GAAG,CAAC,CAAC,MAAM,IAAI,MAAM,EAAE,CAAC;AAC9C;AAQA,SAAS,cAAc,OAAsC;AAC3D,SACE,OAAO,UAAU,YACjB,UAAU,QACV,YAAY,SACZ,OAAQ,MAAsB,WAAW;AAE7C;AAoCA,eAAsB,cACpB,QACA,QACA,WAAW,WACX,WAAqB,OACJ;AACjB,QAAM,EAAE,OAAO,IAAI;AAEnB,MAAI,WAAW,QAAW;AACxB,QAAI,OAAO,WAAW,UAAU;AAC9B,aAAO;AAAA,IACT;AAEA,QAAI,OAAO,WAAW,YAAY;AAChC,aAAO,OAAO;AAAA,IAChB;AAEA,QAAI,cAAc,MAAM,GAAG;AACzB,aAAO,OAAO,OAAO;AAAA,IACvB;AAAA,EACF;AAEA,MAAI,QAAQ;AACV,UAAM,WAAW,QAAQ,IAAI,MAAM;AACnC,QAAI,UAAU;AACZ,aAAO;AAAA,IACT;AAAA,EACF;AAEA,QAAM,IAAI;AAAA,IACR,SACI,0BAA0B,MAAM,uDAChC;AAAA,IACJ,UAAU;AAAA,IACV;AAAA,IACA;AAAA,EACF;AACF;","names":[]}
|
|
@@ -18,6 +18,8 @@ var StreamEventType = {
|
|
|
18
18
|
ToolExecutionStart: "tool_execution_start",
|
|
19
19
|
/** Tool execution has completed */
|
|
20
20
|
ToolExecutionEnd: "tool_execution_end",
|
|
21
|
+
/** Stream is being retried after an error */
|
|
22
|
+
StreamRetry: "stream_retry",
|
|
21
23
|
/** Beginning of a message */
|
|
22
24
|
MessageStart: "message_start",
|
|
23
25
|
/** End of a message */
|
|
@@ -137,6 +139,19 @@ function toolExecutionEnd(toolCallId, toolName, result, isError, timestamp, inde
|
|
|
137
139
|
delta: { toolCallId, toolName, result, isError, timestamp }
|
|
138
140
|
};
|
|
139
141
|
}
|
|
142
|
+
function streamRetry(attempt, maxAttempts, error, timestamp) {
|
|
143
|
+
const serializedError = {
|
|
144
|
+
message: error.message
|
|
145
|
+
};
|
|
146
|
+
if ("code" in error && typeof error.code === "string") {
|
|
147
|
+
serializedError.code = error.code;
|
|
148
|
+
}
|
|
149
|
+
return {
|
|
150
|
+
type: StreamEventType.StreamRetry,
|
|
151
|
+
index: 0,
|
|
152
|
+
delta: { attempt, maxAttempts, error: serializedError, timestamp }
|
|
153
|
+
};
|
|
154
|
+
}
|
|
140
155
|
|
|
141
156
|
export {
|
|
142
157
|
StreamEventType,
|
|
@@ -149,6 +164,7 @@ export {
|
|
|
149
164
|
contentBlockStart,
|
|
150
165
|
contentBlockStop,
|
|
151
166
|
toolExecutionStart,
|
|
152
|
-
toolExecutionEnd
|
|
167
|
+
toolExecutionEnd,
|
|
168
|
+
streamRetry
|
|
153
169
|
};
|
|
154
|
-
//# sourceMappingURL=chunk-
|
|
170
|
+
//# sourceMappingURL=chunk-F5ENANMJ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/types/stream.ts"],"sourcesContent":["/**\n * @fileoverview Streaming types for real-time LLM responses.\n *\n * Defines the event types and interfaces for streaming LLM inference,\n * including text deltas, tool call deltas, and control events.\n *\n * @module types/stream\n */\n\nimport type { Turn } from './turn.ts';\n\n/**\n * Stream event type constants.\n *\n * Use these constants instead of raw strings for type-safe event handling:\n *\n * @example\n * ```typescript\n * import { StreamEventType } from 'upp';\n *\n * for await (const event of stream) {\n * if (event.type === StreamEventType.TextDelta) {\n * process.stdout.write(event.delta.text ?? '');\n * }\n * }\n * ```\n */\nexport const StreamEventType = {\n /** Incremental text output */\n TextDelta: 'text_delta',\n /** Incremental reasoning/thinking output */\n ReasoningDelta: 'reasoning_delta',\n /** Incremental image data */\n ImageDelta: 'image_delta',\n /** Incremental audio data */\n AudioDelta: 'audio_delta',\n /** Incremental video data */\n VideoDelta: 'video_delta',\n /** Incremental tool call data (arguments being streamed) */\n ToolCallDelta: 'tool_call_delta',\n /** Incremental structured object data (for structured output responses) */\n ObjectDelta: 'object_delta',\n /** Tool execution has started (may be emitted after completion in some implementations) */\n ToolExecutionStart: 'tool_execution_start',\n /** Tool execution has completed */\n ToolExecutionEnd: 'tool_execution_end',\n /** Stream is being retried after an error */\n StreamRetry: 'stream_retry',\n /** Beginning of a message */\n MessageStart: 'message_start',\n /** End of a message */\n MessageStop: 'message_stop',\n /** Beginning of a content block */\n ContentBlockStart: 'content_block_start',\n /** End of a content block */\n ContentBlockStop: 'content_block_stop',\n} as const;\n\n/**\n * Stream event type discriminator union.\n *\n * This type is derived from {@link StreamEventType} constants. Use `StreamEventType.TextDelta`\n * for constants or `type MyType = StreamEventType` for type annotations.\n */\nexport type StreamEventType = (typeof StreamEventType)[keyof typeof StreamEventType];\n\n/**\n * Event delta data payload.\n *\n * Contains the type-specific data for a streaming event.\n * Different fields are populated depending on the event type:\n *\n * | Event Type | Fields |\n * |------------|--------|\n * | `text_delta` | `text` |\n * | `reasoning_delta` | `text` |\n * | `object_delta` | `text` |\n * | `image_delta` | `data` |\n * | `audio_delta` | `data` |\n * | `video_delta` | `data` |\n * | `tool_call_delta` | `toolCallId`, `toolName`, `argumentsJson` |\n * | `tool_execution_start` | `toolCallId`, `toolName`, `timestamp` |\n * | `tool_execution_end` | `toolCallId`, `toolName`, `result`, `isError`, `timestamp` |\n * | `stream_retry` | `attempt`, `maxAttempts`, `error`, `timestamp` |\n * | `message_start` | (none) |\n * | `message_stop` | (none) |\n * | `content_block_start` | (none) |\n * | `content_block_stop` | (none) |\n *\n * Custom event types (via middleware) may extend EventDelta with additional fields.\n * See {@link @providerprotocol/ai/middleware/flow!FlowStageDelta} for an example.\n */\nexport interface EventDelta {\n /** Incremental text content (text_delta, reasoning_delta, object_delta) */\n text?: string;\n\n /** Incremental binary data (image_delta, audio_delta, video_delta) */\n data?: Uint8Array;\n\n /** Tool call identifier (tool_call_delta, tool_execution_start/end) */\n toolCallId?: string;\n\n /** Tool name (tool_call_delta, tool_execution_start/end) */\n toolName?: string;\n\n /** Incremental JSON arguments string (tool_call_delta) */\n argumentsJson?: string;\n\n /** Tool execution result (tool_execution_end) */\n result?: unknown;\n\n /** Whether tool execution resulted in an error (tool_execution_end) */\n isError?: boolean;\n\n /** Timestamp in milliseconds (tool_execution_start/end, stream_retry) */\n timestamp?: number;\n\n /** Current retry attempt number (stream_retry, 1-indexed) */\n attempt?: number;\n\n /** Maximum number of retry attempts configured (stream_retry) */\n maxAttempts?: number;\n\n /** Error that triggered the retry (stream_retry) - serialized for JSON transport */\n error?: { message: string; code?: string };\n}\n\n/**\n * A single streaming event from the LLM.\n *\n * Events are emitted in order as the model generates output,\n * allowing for real-time display of responses.\n *\n * @example\n * ```typescript\n * import { StreamEventType } from 'upp';\n *\n * for await (const event of stream) {\n * if (event.type === StreamEventType.TextDelta) {\n * process.stdout.write(event.delta.text ?? '');\n * } else if (event.type === StreamEventType.ToolCallDelta) {\n * console.log('Tool:', event.delta.toolName);\n * }\n * }\n * ```\n */\nexport interface StreamEvent {\n /**\n * Event type discriminator.\n *\n * Uses `StreamEventType | (string & Record<never, never>)` to allow custom\n * event types (like 'flow_stage') while preserving autocomplete for known types.\n * The `(string & Record<never, never>)` pattern is a TypeScript idiom that\n * widens the type to accept any string without losing the literal type union\n * in IDE autocomplete suggestions.\n */\n type: StreamEventType | (string & Record<never, never>);\n\n /** Index of the content block this event belongs to */\n index: number;\n\n /** Event-specific data payload */\n delta: EventDelta;\n}\n\n/**\n * Stream result - an async iterable that also provides the final turn.\n *\n * Allows consuming streaming events while also awaiting the complete\n * Turn result after streaming finishes. Implements `PromiseLike<Turn>`\n * for direct awaiting with automatic stream consumption.\n *\n * @typeParam TData - Type of the structured output data\n *\n * @example\n * ```typescript\n * import { StreamEventType } from 'upp';\n *\n * const stream = instance.stream('Tell me a story');\n *\n * // Option 1: Consume streaming events manually\n * for await (const event of stream) {\n * if (event.type === StreamEventType.TextDelta) {\n * process.stdout.write(event.delta.text ?? '');\n * }\n * }\n * const turn = await stream.turn;\n *\n * // Option 2: Just await the turn (auto-drains the stream)\n * const turn = await instance.stream('Tell me a story');\n *\n * // Option 3: Fire-and-forget with callback\n * instance.stream('Tell me a story').then(turn => saveToDB(turn));\n * ```\n */\nexport interface StreamResult<TData = unknown>\n extends AsyncIterable<StreamEvent>, PromiseLike<Turn<TData>> {\n /**\n * Promise that resolves to the complete Turn after streaming finishes.\n * Rejects if the stream is aborted or terminated early.\n *\n * Accessing `turn` auto-drains the stream if it has not been iterated yet.\n */\n readonly turn: Promise<Turn<TData>>;\n\n /**\n * Aborts the stream, stopping further events and cancelling the request.\n * This will cause {@link StreamResult.turn} to reject.\n */\n abort(): void;\n}\n\n/**\n * Creates a StreamResult from an async generator and completion promise.\n *\n * @typeParam TData - Type of the structured output data\n * @param generator - Async generator that yields stream events\n * @param turnPromiseOrFactory - Promise or factory that resolves to the complete Turn\n * @param abortController - Controller for aborting the stream\n * @returns A StreamResult that can be iterated and awaited\n *\n * @example\n * ```typescript\n * const abortController = new AbortController();\n * const stream = createStreamResult(\n * eventGenerator(),\n * turnPromise,\n * abortController\n * );\n *\n * // Can be awaited directly (auto-drains)\n * const turn = await stream;\n *\n * // Or iterated manually\n * for await (const event of stream) { ... }\n * const turn = await stream.turn;\n * ```\n */\nexport function createStreamResult<TData = unknown>(\n generator: AsyncGenerator<StreamEvent, void, unknown>,\n turnPromiseOrFactory: Promise<Turn<TData>> | (() => Promise<Turn<TData>>),\n abortController: AbortController\n): StreamResult<TData> {\n let cachedTurn: Promise<Turn<TData>> | null = null;\n let drainStarted = false;\n let iteratorStarted = false;\n\n const getTurn = (): Promise<Turn<TData>> => {\n if (typeof turnPromiseOrFactory === 'function') {\n if (!cachedTurn) {\n cachedTurn = turnPromiseOrFactory();\n }\n return cachedTurn;\n }\n return turnPromiseOrFactory;\n };\n\n const drain = (): void => {\n if (drainStarted) return;\n drainStarted = true;\n void (async () => {\n try {\n let done = false;\n while (!done) {\n const result = await generator.next();\n done = result.done ?? false;\n }\n } catch {\n // Errors are surfaced via turn promise\n }\n })();\n };\n\n return {\n [Symbol.asyncIterator]() {\n iteratorStarted = true;\n return generator;\n },\n get turn() {\n if (!iteratorStarted) {\n drain();\n }\n return getTurn();\n },\n abort() {\n abortController.abort();\n },\n then<TResult1 = Turn<TData>, TResult2 = never>(\n onfulfilled?: ((value: Turn<TData>) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null\n ): Promise<TResult1 | TResult2> {\n drain();\n return getTurn().then(onfulfilled, onrejected);\n },\n };\n}\n\n/**\n * Creates a text delta stream event.\n *\n * @param text - The incremental text content\n * @param index - Content block index (default: 0)\n * @returns A text_delta StreamEvent\n */\nexport function textDelta(text: string, index = 0): StreamEvent {\n return {\n type: StreamEventType.TextDelta,\n index,\n delta: { text },\n };\n}\n\n/**\n * Creates a tool call delta stream event.\n *\n * @param toolCallId - Unique identifier for the tool call\n * @param toolName - Name of the tool being called\n * @param argumentsJson - Incremental JSON arguments string\n * @param index - Content block index (default: 0)\n * @returns A tool_call_delta StreamEvent\n */\nexport function toolCallDelta(\n toolCallId: string,\n toolName: string,\n argumentsJson: string,\n index = 0\n): StreamEvent {\n return {\n type: StreamEventType.ToolCallDelta,\n index,\n delta: { toolCallId, toolName, argumentsJson },\n };\n}\n\n/**\n * Creates an object delta stream event for structured output responses.\n *\n * @param text - The incremental text content\n * @param index - Content block index (default: 0)\n * @returns An object_delta StreamEvent\n */\nexport function objectDelta(text: string, index = 0): StreamEvent {\n return {\n type: StreamEventType.ObjectDelta,\n index,\n delta: { text },\n };\n}\n\n/**\n * Creates a message start stream event.\n *\n * @returns A message_start StreamEvent\n */\nexport function messageStart(): StreamEvent {\n return {\n type: StreamEventType.MessageStart,\n index: 0,\n delta: {},\n };\n}\n\n/**\n * Creates a message stop stream event.\n *\n * @returns A message_stop StreamEvent\n */\nexport function messageStop(): StreamEvent {\n return {\n type: StreamEventType.MessageStop,\n index: 0,\n delta: {},\n };\n}\n\n/**\n * Creates a content block start stream event.\n *\n * @param index - The content block index starting\n * @returns A content_block_start StreamEvent\n */\nexport function contentBlockStart(index: number): StreamEvent {\n return {\n type: StreamEventType.ContentBlockStart,\n index,\n delta: {},\n };\n}\n\n/**\n * Creates a content block stop stream event.\n *\n * @param index - The content block index stopping\n * @returns A content_block_stop StreamEvent\n */\nexport function contentBlockStop(index: number): StreamEvent {\n return {\n type: StreamEventType.ContentBlockStop,\n index,\n delta: {},\n };\n}\n\n/**\n * Creates a tool execution start stream event.\n *\n * @param toolCallId - Unique identifier for the tool call\n * @param toolName - Name of the tool being executed\n * @param timestamp - Start timestamp in milliseconds\n * @param index - Content block index (default: 0)\n * @returns A tool_execution_start StreamEvent\n */\nexport function toolExecutionStart(\n toolCallId: string,\n toolName: string,\n timestamp: number,\n index = 0\n): StreamEvent {\n return {\n type: StreamEventType.ToolExecutionStart,\n index,\n delta: { toolCallId, toolName, timestamp },\n };\n}\n\n/**\n * Creates a tool execution end stream event.\n *\n * @param toolCallId - Unique identifier for the tool call\n * @param toolName - Name of the tool that was executed\n * @param result - The result from the tool execution\n * @param isError - Whether the execution resulted in an error\n * @param timestamp - End timestamp in milliseconds\n * @param index - Content block index (default: 0)\n * @returns A tool_execution_end StreamEvent\n */\nexport function toolExecutionEnd(\n toolCallId: string,\n toolName: string,\n result: unknown,\n isError: boolean,\n timestamp: number,\n index = 0\n): StreamEvent {\n return {\n type: StreamEventType.ToolExecutionEnd,\n index,\n delta: { toolCallId, toolName, result, isError, timestamp },\n };\n}\n\n/**\n * Creates a stream retry event.\n *\n * Emitted when a streaming request is being retried after an error.\n * This allows consumers to reset UI state or notify users of retry attempts.\n *\n * @param attempt - Current retry attempt number (1-indexed)\n * @param maxAttempts - Maximum number of retry attempts configured\n * @param error - The error that triggered the retry\n * @param timestamp - Timestamp in milliseconds when retry was initiated\n * @returns A stream_retry StreamEvent\n */\nexport function streamRetry(\n attempt: number,\n maxAttempts: number,\n error: Error,\n timestamp: number\n): StreamEvent {\n // Serialize error for JSON transport (Error properties are non-enumerable)\n const serializedError: { message: string; code?: string } = {\n message: error.message,\n };\n // Include error code if present (e.g., UPPError)\n if ('code' in error && typeof error.code === 'string') {\n serializedError.code = error.code;\n }\n\n return {\n type: StreamEventType.StreamRetry,\n index: 0,\n delta: { attempt, maxAttempts, error: serializedError, timestamp },\n };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=chunk-IKJH5ZSJ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
runSubscriberStream
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-L6QWKFGE.js";
|
|
4
4
|
|
|
5
5
|
// src/middleware/pubsub/server/h3.ts
|
|
6
6
|
async function streamSubscriber(streamId, adapter, event) {
|
|
@@ -28,4 +28,4 @@ export {
|
|
|
28
28
|
streamSubscriber,
|
|
29
29
|
h3
|
|
30
30
|
};
|
|
31
|
-
//# sourceMappingURL=chunk-
|
|
31
|
+
//# sourceMappingURL=chunk-KBI45OXI.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
runSubscriberStream
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-L6QWKFGE.js";
|
|
4
4
|
|
|
5
5
|
// src/middleware/pubsub/server/express.ts
|
|
6
6
|
async function streamSubscriber(streamId, adapter, res) {
|
|
@@ -27,4 +27,4 @@ export {
|
|
|
27
27
|
streamSubscriber,
|
|
28
28
|
express
|
|
29
29
|
};
|
|
30
|
-
//# sourceMappingURL=chunk-
|
|
30
|
+
//# sourceMappingURL=chunk-KVUOTFYZ.js.map
|
|
@@ -24,6 +24,7 @@ async function runSubscriberStream(streamId, adapter, writer, options = {}) {
|
|
|
24
24
|
let resolveWait = null;
|
|
25
25
|
let completed = false;
|
|
26
26
|
let lastSentCursor = -1;
|
|
27
|
+
let finalData = void 0;
|
|
27
28
|
const onEvent = (event, cursor) => {
|
|
28
29
|
queue.push({ event, cursor: cursor ?? null });
|
|
29
30
|
resolveWait?.();
|
|
@@ -32,7 +33,10 @@ async function runSubscriberStream(streamId, adapter, writer, options = {}) {
|
|
|
32
33
|
completed = true;
|
|
33
34
|
resolveWait?.();
|
|
34
35
|
};
|
|
35
|
-
const
|
|
36
|
+
const onFinalData = (data) => {
|
|
37
|
+
finalData = data;
|
|
38
|
+
};
|
|
39
|
+
const unsubscribe = adapter.subscribe(streamId, onEvent, onComplete, onFinalData);
|
|
36
40
|
const onAbort = () => {
|
|
37
41
|
completed = true;
|
|
38
42
|
resolveWait?.();
|
|
@@ -75,11 +79,12 @@ async function runSubscriberStream(streamId, adapter, writer, options = {}) {
|
|
|
75
79
|
});
|
|
76
80
|
try {
|
|
77
81
|
const events = await adapter.getEvents(streamId);
|
|
82
|
+
const cursorBase = adapter.getCursorBase(streamId);
|
|
78
83
|
for (const event of events) {
|
|
79
84
|
if (signal?.aborted) break;
|
|
80
85
|
writer.write(formatSSE(event));
|
|
81
86
|
}
|
|
82
|
-
lastSentCursor = events.length - 1;
|
|
87
|
+
lastSentCursor = cursorBase + events.length - 1;
|
|
83
88
|
dropReplayDuplicates();
|
|
84
89
|
if (signal?.aborted) {
|
|
85
90
|
writer.end();
|
|
@@ -98,6 +103,11 @@ async function runSubscriberStream(streamId, adapter, writer, options = {}) {
|
|
|
98
103
|
unsubscribe();
|
|
99
104
|
}
|
|
100
105
|
if (!signal?.aborted) {
|
|
106
|
+
if (finalData !== void 0) {
|
|
107
|
+
writer.write(`data: ${JSON.stringify(finalData)}
|
|
108
|
+
|
|
109
|
+
`);
|
|
110
|
+
}
|
|
101
111
|
writer.write("data: [DONE]\n\n");
|
|
102
112
|
}
|
|
103
113
|
writer.end();
|
|
@@ -115,4 +125,4 @@ async function runSubscriberStream(streamId, adapter, writer, options = {}) {
|
|
|
115
125
|
export {
|
|
116
126
|
runSubscriberStream
|
|
117
127
|
};
|
|
118
|
-
//# sourceMappingURL=chunk-
|
|
128
|
+
//# sourceMappingURL=chunk-L6QWKFGE.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/middleware/pubsub/server/shared.ts"],"sourcesContent":["/**\n * @fileoverview Shared utilities for pub-sub server adapters.\n *\n * @module middleware/pubsub/server/shared\n * @internal\n */\n\nimport type { StreamEvent } from '../../../types/stream.ts';\nimport type { PubSubAdapter } from '../types.ts';\nimport { serializeStreamEvent } from '../../../stream/serialization.ts';\n\n/**\n * Writer interface for abstracting how data is written to responses.\n * @internal\n */\nexport interface StreamWriter {\n write(data: string): void;\n end(): void;\n}\n\n/**\n * Options for runSubscriberStream.\n * @internal\n */\nexport interface StreamOptions {\n signal?: AbortSignal;\n}\n\n/**\n * Formats a stream event as an SSE data line.\n */\nexport function formatSSE(event: StreamEvent): string {\n const serialized = serializeStreamEvent(event);\n return `data: ${JSON.stringify(serialized)}\\n\\n`;\n}\n\n/**\n * Core subscriber stream logic shared across all adapters.\n *\n * Handles:\n * 1. Subscribing to live events and completion signal\n * 2. Replaying buffered events (empty if stream just started)\n * 3. Processing live events until completion signal\n * 4. Final cleanup\n * 5. Client disconnect via AbortSignal\n *\n * @internal\n */\nexport async function runSubscriberStream(\n streamId: string,\n adapter: PubSubAdapter,\n writer: StreamWriter,\n options: StreamOptions = {}\n): Promise<void> {\n const { signal } = options;\n\n if (signal?.aborted) {\n writer.end();\n return;\n }\n\n try {\n if (signal?.aborted) {\n writer.end();\n return;\n }\n\n const queue: Array<{ event: StreamEvent; cursor: number | null }> = [];\n let resolveWait: (() => void) | null = null;\n let completed = false;\n let lastSentCursor = -1;\n let finalData: unknown = undefined;\n\n const onEvent = (event: StreamEvent, cursor?: number): void => {\n queue.push({ event, cursor: cursor ?? null });\n resolveWait?.();\n };\n\n const onComplete = (): void => {\n completed = true;\n resolveWait?.();\n };\n\n const onFinalData = (data: unknown): void => {\n finalData = data;\n };\n\n const unsubscribe = adapter.subscribe(streamId, onEvent, onComplete, onFinalData);\n\n const onAbort = (): void => {\n completed = true;\n resolveWait?.();\n };\n signal?.addEventListener('abort', onAbort);\n\n const drainQueue = (): void => {\n while (queue.length > 0 && !signal?.aborted) {\n const item = queue.shift();\n if (!item) break;\n const { event, cursor } = item;\n if (cursor !== null && cursor <= lastSentCursor) continue;\n writer.write(formatSSE(event));\n if (cursor !== null && cursor > lastSentCursor) {\n lastSentCursor = cursor;\n }\n }\n };\n\n const dropReplayDuplicates = (): void => {\n if (queue.length === 0) return;\n const filtered: Array<{ event: StreamEvent; cursor: number | null }> = [];\n for (const item of queue) {\n if (item.cursor !== null && item.cursor <= lastSentCursor) continue;\n filtered.push(item);\n }\n queue.length = 0;\n queue.push(...filtered);\n };\n\n const waitForSignal = (): Promise<void> => new Promise((resolve) => {\n let settled = false;\n\n const settle = (): void => {\n if (settled) return;\n settled = true;\n resolveWait = null;\n resolve();\n };\n\n resolveWait = settle;\n\n if (completed || signal?.aborted || queue.length > 0) {\n settle();\n }\n });\n\n try {\n const events = await adapter.getEvents(streamId);\n const cursorBase = adapter.getCursorBase(streamId);\n\n for (const event of events) {\n if (signal?.aborted) break;\n writer.write(formatSSE(event));\n }\n\n // Use cursor base to set lastSentCursor correctly after clear operations\n // Events have cursors of cursorBase + index, so after replay the last cursor is cursorBase + length - 1\n lastSentCursor = cursorBase + events.length - 1;\n dropReplayDuplicates();\n\n if (signal?.aborted) {\n writer.end();\n return;\n }\n\n // Wait for events or completion signal\n while (!completed && !signal?.aborted) {\n drainQueue();\n if (completed || signal?.aborted) break;\n await waitForSignal();\n }\n\n if (!signal?.aborted) {\n drainQueue();\n }\n } finally {\n signal?.removeEventListener('abort', onAbort);\n unsubscribe();\n }\n\n if (!signal?.aborted) {\n // Emit final data (Turn) if available before [DONE]\n if (finalData !== undefined) {\n writer.write(`data: ${JSON.stringify(finalData)}\\n\\n`);\n }\n writer.write('data: [DONE]\\n\\n');\n }\n writer.end();\n } catch (error) {\n if (!signal?.aborted) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n writer.write(`data: ${JSON.stringify({ error: errorMsg })}\\n\\n`);\n }\n writer.end();\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
+
import {
|
|
2
|
+
webapi
|
|
3
|
+
} from "./chunk-AC3VHSZJ.js";
|
|
1
4
|
import {
|
|
2
5
|
express
|
|
3
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-XTWBAL42.js";
|
|
4
7
|
import {
|
|
5
8
|
h3
|
|
6
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-DI47UY2H.js";
|
|
7
10
|
import {
|
|
8
11
|
fastify
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import {
|
|
11
|
-
webapi
|
|
12
|
-
} from "./chunk-LTEMH3CI.js";
|
|
12
|
+
} from "./chunk-EHR3LIPS.js";
|
|
13
13
|
|
|
14
14
|
// src/providers/proxy/server/index.ts
|
|
15
15
|
var server = {
|
|
@@ -26,4 +26,4 @@ var server = {
|
|
|
26
26
|
export {
|
|
27
27
|
server
|
|
28
28
|
};
|
|
29
|
-
//# sourceMappingURL=chunk-
|
|
29
|
+
//# sourceMappingURL=chunk-N4LAFGLX.js.map
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AssistantMessage,
|
|
3
3
|
ToolResultMessage,
|
|
4
|
-
UserMessage
|
|
4
|
+
UserMessage
|
|
5
|
+
} from "./chunk-6QCV4WXF.js";
|
|
6
|
+
import {
|
|
5
7
|
generateId
|
|
6
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-U2G5PHHL.js";
|
|
7
9
|
|
|
8
10
|
// src/types/thread.ts
|
|
9
11
|
var Thread = class _Thread {
|
|
@@ -262,4 +264,4 @@ var Thread = class _Thread {
|
|
|
262
264
|
export {
|
|
263
265
|
Thread
|
|
264
266
|
};
|
|
265
|
-
//# sourceMappingURL=chunk-
|
|
267
|
+
//# sourceMappingURL=chunk-R3T2IYOU.js.map
|