@providerprotocol/ai 0.0.38 → 0.0.39

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.
Files changed (83) hide show
  1. package/README.md +94 -3
  2. package/dist/anthropic/index.d.ts +3 -2
  3. package/dist/cerebras/index.d.ts +3 -2
  4. package/dist/chunk-3Q5VELKG.js +124 -0
  5. package/dist/chunk-3Q5VELKG.js.map +1 -0
  6. package/dist/{chunk-LTEMH3CI.js → chunk-5XPRVUOK.js} +6 -4
  7. package/dist/{chunk-LTEMH3CI.js.map → chunk-5XPRVUOK.js.map} +1 -1
  8. package/dist/chunk-7ULSRWDH.js +83 -0
  9. package/dist/chunk-7ULSRWDH.js.map +1 -0
  10. package/dist/{chunk-YQLR3XOA.js → chunk-BIBMNP7Y.js} +1 -75
  11. package/dist/chunk-BIBMNP7Y.js.map +1 -0
  12. package/dist/{chunk-7GTWHZY2.js → chunk-IDZR4ROP.js} +5 -3
  13. package/dist/{chunk-7GTWHZY2.js.map → chunk-IDZR4ROP.js.map} +1 -1
  14. package/dist/{chunk-4RX4VQCB.js → chunk-IIMTP3XC.js} +2 -2
  15. package/dist/{chunk-ZRVNAET3.js → chunk-KNBODIQU.js} +6 -3
  16. package/dist/chunk-KNBODIQU.js.map +1 -0
  17. package/dist/{chunk-FYSZFIZS.js → chunk-O32SBS6S.js} +5 -3
  18. package/dist/{chunk-FYSZFIZS.js.map → chunk-O32SBS6S.js.map} +1 -1
  19. package/dist/{chunk-BDXH6NQS.js → chunk-RDC5GYST.js} +5 -5
  20. package/dist/{chunk-5IWHCXKN.js → chunk-SAMIK4WZ.js} +2 -2
  21. package/dist/{chunk-EPB3GQNL.js → chunk-U6M3MXNI.js} +11 -2
  22. package/dist/chunk-U6M3MXNI.js.map +1 -0
  23. package/dist/{chunk-2YXFLRQ6.js → chunk-WNB5PSY6.js} +2 -2
  24. package/dist/{chunk-CRP6Y7NF.js → chunk-ZDYEDI2A.js} +2 -2
  25. package/dist/{embedding-CwZ1ZNWv.d.ts → embedding-iNQCeXfk.d.ts} +1 -1
  26. package/dist/google/index.d.ts +3 -2
  27. package/dist/groq/index.d.ts +3 -2
  28. package/dist/http/index.d.ts +4 -3
  29. package/dist/{image-stream-CeQHtjxS.d.ts → image-stream-ARno6XlS.d.ts} +1 -1
  30. package/dist/index.d.ts +8 -7
  31. package/dist/index.js +11 -2
  32. package/dist/index.js.map +1 -1
  33. package/dist/{llm-DS_-l71X.d.ts → llm-CZqlijjK.d.ts} +16 -9
  34. package/dist/middleware/logging/index.d.ts +3 -2
  35. package/dist/middleware/parsed-object/index.d.ts +3 -2
  36. package/dist/middleware/persistence/index.d.ts +3 -2
  37. package/dist/middleware/pubsub/index.d.ts +5 -4
  38. package/dist/middleware/pubsub/index.js +49 -3
  39. package/dist/middleware/pubsub/index.js.map +1 -1
  40. package/dist/middleware/pubsub/server/express/index.d.ts +3 -2
  41. package/dist/middleware/pubsub/server/express/index.js +2 -2
  42. package/dist/middleware/pubsub/server/fastify/index.d.ts +3 -2
  43. package/dist/middleware/pubsub/server/fastify/index.js +2 -2
  44. package/dist/middleware/pubsub/server/h3/index.d.ts +3 -2
  45. package/dist/middleware/pubsub/server/h3/index.js +2 -2
  46. package/dist/middleware/pubsub/server/index.d.ts +3 -2
  47. package/dist/middleware/pubsub/server/index.js +5 -5
  48. package/dist/middleware/pubsub/server/webapi/index.d.ts +3 -2
  49. package/dist/middleware/pubsub/server/webapi/index.js +2 -2
  50. package/dist/moonshot/index.d.ts +3 -2
  51. package/dist/ollama/index.d.ts +3 -2
  52. package/dist/openai/index.d.ts +3 -2
  53. package/dist/openrouter/index.d.ts +3 -2
  54. package/dist/proxy/index.d.ts +5 -4
  55. package/dist/proxy/index.js +10 -8
  56. package/dist/proxy/index.js.map +1 -1
  57. package/dist/proxy/server/express/index.d.ts +5 -4
  58. package/dist/proxy/server/express/index.js +3 -2
  59. package/dist/proxy/server/fastify/index.d.ts +5 -4
  60. package/dist/proxy/server/fastify/index.js +3 -2
  61. package/dist/proxy/server/h3/index.d.ts +19 -17
  62. package/dist/proxy/server/h3/index.js +3 -2
  63. package/dist/proxy/server/index.d.ts +5 -4
  64. package/dist/proxy/server/index.js +7 -6
  65. package/dist/proxy/server/webapi/index.d.ts +5 -4
  66. package/dist/proxy/server/webapi/index.js +3 -2
  67. package/dist/responses/index.d.ts +3 -2
  68. package/dist/{retry-CgoBNa51.d.ts → retry-C1eJbEMV.d.ts} +1 -1
  69. package/dist/{stream-sXhBtWjl.d.ts → stream-DVVUIKpz.d.ts} +3 -416
  70. package/dist/tool-D22EhP5F.d.ts +507 -0
  71. package/dist/{types-Cr4F0tVy.d.ts → types-CyXF0J7C.d.ts} +16 -3
  72. package/dist/utils/index.d.ts +65 -1
  73. package/dist/utils/index.js +15 -1
  74. package/dist/xai/index.d.ts +3 -2
  75. package/package.json +15 -3
  76. package/dist/chunk-EPB3GQNL.js.map +0 -1
  77. package/dist/chunk-YQLR3XOA.js.map +0 -1
  78. package/dist/chunk-ZRVNAET3.js.map +0 -1
  79. /package/dist/{chunk-4RX4VQCB.js.map → chunk-IIMTP3XC.js.map} +0 -0
  80. /package/dist/{chunk-BDXH6NQS.js.map → chunk-RDC5GYST.js.map} +0 -0
  81. /package/dist/{chunk-5IWHCXKN.js.map → chunk-SAMIK4WZ.js.map} +0 -0
  82. /package/dist/{chunk-2YXFLRQ6.js.map → chunk-WNB5PSY6.js.map} +0 -0
  83. /package/dist/{chunk-CRP6Y7NF.js.map → chunk-ZDYEDI2A.js.map} +0 -0
package/README.md CHANGED
@@ -91,6 +91,21 @@ const t2 = await claude.generate(history, 'What is my name?');
91
91
  // Response: "Your name is Alice"
92
92
  ```
93
93
 
94
+ ### System-Only Inference
95
+
96
+ Both `generate()` and `stream()` can be called with no arguments for system-prompt-only inference:
97
+
98
+ ```typescript
99
+ const assistant = llm({
100
+ model: anthropic('claude-sonnet-4-20250514'),
101
+ system: 'You are a haiku generator. Generate a haiku about coding.',
102
+ });
103
+
104
+ // No user input needed
105
+ const turn = await assistant.generate();
106
+ console.log(turn.response.text);
107
+ ```
108
+
94
109
  ### Tools
95
110
 
96
111
  ```typescript
@@ -108,6 +123,27 @@ const turn = await claude.generate({
108
123
  }, 'What is the weather in Tokyo?');
109
124
  ```
110
125
 
126
+ #### Tools with Zod Parameters
127
+
128
+ Tool parameters also accept Zod schemas:
129
+
130
+ ```typescript
131
+ import { z } from 'zod';
132
+
133
+ const model = llm({
134
+ model: anthropic('claude-sonnet-4-20250514'),
135
+ tools: [{
136
+ name: 'get_weather',
137
+ description: 'Get weather for a location',
138
+ parameters: z.object({
139
+ location: z.string().describe('City name'),
140
+ units: z.enum(['celsius', 'fahrenheit']).optional(),
141
+ }),
142
+ run: async ({ location, units }) => fetchWeather(location, units),
143
+ }],
144
+ });
145
+ ```
146
+
111
147
  ### Structured Output
112
148
 
113
149
  ```typescript
@@ -130,6 +166,37 @@ const turn = await extractor.generate('John is 30 years old');
130
166
  console.log(turn.data); // { name: 'John', age: 30 }
131
167
  ```
132
168
 
169
+ #### Zod Schema Support
170
+
171
+ Structured output and tool parameters accept Zod schemas directly, with automatic conversion to JSON Schema:
172
+
173
+ ```typescript
174
+ import { llm } from '@providerprotocol/ai';
175
+ import { anthropic } from '@providerprotocol/ai/anthropic';
176
+ import { z } from 'zod';
177
+
178
+ const extractor = llm({
179
+ model: anthropic('claude-sonnet-4-20250514'),
180
+ structure: z.object({
181
+ name: z.string(),
182
+ age: z.number(),
183
+ tags: z.array(z.string()),
184
+ }),
185
+ });
186
+
187
+ const turn = await extractor.generate('Extract: John Doe, 30 years old, likes coding');
188
+ console.log(turn.data); // { name: "John Doe", age: 30, tags: ["coding"] }
189
+ ```
190
+
191
+ **Requirements:**
192
+ - Zod schemas must be object schemas (`z.object()`). Non-object schemas will throw an error.
193
+ - Zod is an optional peer dependency - install only if using Zod schemas:
194
+
195
+ ```bash
196
+ bun add zod # v4+ for native JSON Schema conversion
197
+ bun add zod zod-to-json-schema # v3 requires additional package
198
+ ```
199
+
133
200
  ### Multimodal Input
134
201
 
135
202
  ```typescript
@@ -750,9 +817,10 @@ const redisAdapter: PubSubAdapter = {
750
817
  async exists(streamId) { /* check if stream exists */ },
751
818
  async append(streamId, event) { /* append event, create lazily */ },
752
819
  async getEvents(streamId) { /* return events or [] */ },
753
- subscribe(streamId, onEvent, onComplete) { /* subscribe to live events */ },
820
+ subscribe(streamId, onEvent, onComplete, onFinalData) { /* subscribe to live events */ },
754
821
  publish(streamId, event) { /* broadcast to subscribers */ },
755
- async remove(streamId) { /* notify onComplete then delete */ },
822
+ setFinalData(streamId, data) { /* store final Turn data */ },
823
+ async remove(streamId) { /* notify onFinalData, onComplete, then delete */ },
756
824
  };
757
825
  ```
758
826
 
@@ -903,11 +971,12 @@ app.post('/ai', async (request, reply) => {
903
971
  });
904
972
 
905
973
  // Nuxt/H3 (server/api/ai.post.ts)
974
+ import { sendStream } from 'h3';
906
975
  import { h3 as h3Adapter, parseBody } from '@providerprotocol/ai/proxy';
907
976
  export default defineEventHandler(async (event) => {
908
977
  const { messages, system, params } = parseBody(await readBody(event));
909
978
  if (params?.stream) {
910
- return h3Adapter.streamSSE(claude.stream(messages, { system }), event);
979
+ return sendStream(event, h3Adapter.createSSEStream(claude.stream(messages, { system })));
911
980
  }
912
981
  return h3Adapter.sendJSON(await claude.generate(messages, { system }), event);
913
982
  });
@@ -1174,9 +1243,31 @@ import type {
1174
1243
  Middleware,
1175
1244
  MiddlewareContext,
1176
1245
  StreamContext,
1246
+
1247
+ // Schema types (Zod support)
1248
+ Structure,
1249
+ ZodLike,
1177
1250
  } from '@providerprotocol/ai';
1178
1251
  ```
1179
1252
 
1253
+ **Zod Utilities:**
1254
+
1255
+ ```typescript
1256
+ import {
1257
+ isZodSchema,
1258
+ isZodV4,
1259
+ zodToJSONSchema,
1260
+ zodToJSONSchemaSync,
1261
+ resolveStructure,
1262
+ resolveTools,
1263
+ } from '@providerprotocol/ai/utils';
1264
+
1265
+ // Type guard for Zod schemas
1266
+ if (isZodSchema(schema)) {
1267
+ const jsonSchema = zodToJSONSchemaSync(schema);
1268
+ }
1269
+ ```
1270
+
1180
1271
  **Type-Safe Enums:**
1181
1272
 
1182
1273
  ```typescript
@@ -1,5 +1,6 @@
1
- import { e as Provider } from '../llm-DS_-l71X.js';
2
- import '../stream-sXhBtWjl.js';
1
+ import { e as Provider } from '../llm-CZqlijjK.js';
2
+ import '../stream-DVVUIKpz.js';
3
+ import '../tool-D22EhP5F.js';
3
4
 
4
5
  /**
5
6
  * @fileoverview Anthropic API type definitions.
@@ -1,5 +1,6 @@
1
- import { e as Provider } from '../llm-DS_-l71X.js';
2
- import '../stream-sXhBtWjl.js';
1
+ import { e as Provider } from '../llm-CZqlijjK.js';
2
+ import '../stream-DVVUIKpz.js';
3
+ import '../tool-D22EhP5F.js';
3
4
 
4
5
  /**
5
6
  * @fileoverview Cerebras Provider Type Definitions
@@ -0,0 +1,124 @@
1
+ // src/utils/zod.ts
2
+ var cachedZod;
3
+ var cachedZodToJsonSchema;
4
+ try {
5
+ cachedZod = await import("zod");
6
+ } catch {
7
+ }
8
+ try {
9
+ const mod = await import("zod-to-json-schema");
10
+ cachedZodToJsonSchema = { zodToJsonSchema: mod.zodToJsonSchema };
11
+ } catch {
12
+ }
13
+ function isZodSchema(value) {
14
+ return value !== null && typeof value === "object" && "_def" in value && "parse" in value && typeof value.parse === "function";
15
+ }
16
+ function isZodV4(schema) {
17
+ return "_zod" in schema;
18
+ }
19
+ async function loadZod() {
20
+ if (!cachedZod) {
21
+ cachedZod = await import("zod");
22
+ }
23
+ return cachedZod;
24
+ }
25
+ async function loadZodToJsonSchema() {
26
+ if (!cachedZodToJsonSchema) {
27
+ const mod = await import("zod-to-json-schema");
28
+ cachedZodToJsonSchema = { zodToJsonSchema: mod.zodToJsonSchema };
29
+ }
30
+ return cachedZodToJsonSchema;
31
+ }
32
+ async function zodV4ToJSONSchema(schema) {
33
+ const z = await loadZod();
34
+ if (!("toJSONSchema" in z)) {
35
+ throw new Error(
36
+ "Zod v4+ required for native JSON Schema conversion. Install with: bun add zod@latest"
37
+ );
38
+ }
39
+ const jsonSchema = z.toJSONSchema(schema, { target: "draft-07" });
40
+ return jsonSchema;
41
+ }
42
+ function zodV4ToJSONSchemaSync(schema) {
43
+ if (!cachedZod) {
44
+ throw new Error(
45
+ "Zod module not loaded. Call zodToJSONSchema() first or ensure Zod is imported."
46
+ );
47
+ }
48
+ if (!("toJSONSchema" in cachedZod)) {
49
+ throw new Error(
50
+ "Zod v4+ required for native JSON Schema conversion. Install with: bun add zod@latest"
51
+ );
52
+ }
53
+ const jsonSchema = cachedZod.toJSONSchema(schema, { target: "draft-07" });
54
+ return jsonSchema;
55
+ }
56
+ async function zodV3ToJSONSchema(schema) {
57
+ const { zodToJsonSchema } = await loadZodToJsonSchema();
58
+ const jsonSchema = zodToJsonSchema(schema, {
59
+ $refStrategy: "none"
60
+ });
61
+ return jsonSchema;
62
+ }
63
+ function zodV3ToJSONSchemaSync(schema) {
64
+ if (!cachedZodToJsonSchema) {
65
+ throw new Error(
66
+ "zod-to-json-schema module not loaded. Call zodToJSONSchema() first."
67
+ );
68
+ }
69
+ const jsonSchema = cachedZodToJsonSchema.zodToJsonSchema(
70
+ schema,
71
+ {
72
+ $refStrategy: "none"
73
+ }
74
+ );
75
+ return jsonSchema;
76
+ }
77
+ async function zodToJSONSchema(schema) {
78
+ if (isZodV4(schema)) {
79
+ return zodV4ToJSONSchema(schema);
80
+ }
81
+ return zodV3ToJSONSchema(schema);
82
+ }
83
+ function zodToJSONSchemaSync(schema) {
84
+ if (isZodV4(schema)) {
85
+ return zodV4ToJSONSchemaSync(schema);
86
+ }
87
+ return zodV3ToJSONSchemaSync(schema);
88
+ }
89
+ function validateObjectSchema(schema, context) {
90
+ const s = schema;
91
+ if (s.type !== "object" || typeof s.properties !== "object" || s.properties === null) {
92
+ throw new Error(
93
+ `${context} must be an object schema with properties. Received schema with type: '${s.type ?? "undefined"}'. Use z.object({...}) for Zod schemas.`
94
+ );
95
+ }
96
+ }
97
+ function resolveStructure(structure) {
98
+ if (isZodSchema(structure)) {
99
+ const schema = zodToJSONSchemaSync(structure);
100
+ validateObjectSchema(schema, "Structure schema");
101
+ return schema;
102
+ }
103
+ return structure;
104
+ }
105
+ function resolveTools(tools) {
106
+ return tools.map((tool) => {
107
+ if (isZodSchema(tool.parameters)) {
108
+ const schema = zodToJSONSchemaSync(tool.parameters);
109
+ validateObjectSchema(schema, `Tool '${tool.name}' parameters`);
110
+ return { ...tool, parameters: schema };
111
+ }
112
+ return tool;
113
+ });
114
+ }
115
+
116
+ export {
117
+ isZodSchema,
118
+ isZodV4,
119
+ zodToJSONSchema,
120
+ zodToJSONSchemaSync,
121
+ resolveStructure,
122
+ resolveTools
123
+ };
124
+ //# sourceMappingURL=chunk-3Q5VELKG.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/zod.ts"],"sourcesContent":["/**\n * @fileoverview Zod schema utilities for structured output.\n *\n * Provides detection and conversion utilities for Zod schemas,\n * supporting both Zod v3 and v4 schemas.\n *\n * @module utils/zod\n */\n\nimport type { JSONSchema, ZodLike, ZodV3Like, ZodV4Like } from '../types/schema.ts';\nimport type { Tool, ToolInput } from '../types/tool.ts';\nimport type * as Zod from 'zod';\nimport type { zodToJsonSchema as ZodToJsonSchemaFn } from 'zod-to-json-schema';\n\n/** Cached Zod module for sync access */\nlet cachedZod: typeof Zod | undefined;\n\n/** Cached zod-to-json-schema module for sync access */\nlet cachedZodToJsonSchema: { zodToJsonSchema: typeof ZodToJsonSchemaFn } | undefined;\n\n// Pre-load modules at import time for sync access\n// Uses dynamic import which is ESM-compatible\ntry {\n cachedZod = await import('zod') as typeof Zod;\n} catch {\n // Zod not installed - will throw on use\n}\n\ntry {\n const mod = await import('zod-to-json-schema');\n cachedZodToJsonSchema = { zodToJsonSchema: mod.zodToJsonSchema as typeof ZodToJsonSchemaFn };\n} catch {\n // zod-to-json-schema not installed - will throw on use for v3\n}\n\n/**\n * Checks if a value is a Zod schema (v3 or v4).\n *\n * @param value - Value to check\n * @returns True if the value appears to be a Zod schema\n */\nexport function isZodSchema(value: unknown): value is ZodLike {\n return (\n value !== null &&\n typeof value === 'object' &&\n '_def' in value &&\n 'parse' in value &&\n typeof (value as ZodV3Like).parse === 'function'\n );\n}\n\n/**\n * Checks if a Zod schema is v4 or later.\n *\n * @param schema - Zod schema to check\n * @returns True if the schema is Zod v4+\n */\nexport function isZodV4(schema: ZodLike): schema is ZodV4Like {\n return '_zod' in schema;\n}\n\n/**\n * Loads and caches the Zod module.\n */\nasync function loadZod(): Promise<typeof Zod> {\n if (!cachedZod) {\n cachedZod = await import('zod') as typeof Zod;\n }\n return cachedZod;\n}\n\n/**\n * Loads and caches the zod-to-json-schema module.\n */\nasync function loadZodToJsonSchema(): Promise<{ zodToJsonSchema: typeof ZodToJsonSchemaFn }> {\n if (!cachedZodToJsonSchema) {\n const mod = await import('zod-to-json-schema');\n cachedZodToJsonSchema = { zodToJsonSchema: mod.zodToJsonSchema as typeof ZodToJsonSchemaFn };\n }\n return cachedZodToJsonSchema;\n}\n\n/**\n * Converts a Zod v4 schema to JSON Schema using native conversion.\n */\nasync function zodV4ToJSONSchema(schema: ZodV4Like): Promise<JSONSchema> {\n const z = await loadZod();\n if (!('toJSONSchema' in z)) {\n throw new Error(\n 'Zod v4+ required for native JSON Schema conversion. ' +\n 'Install with: bun add zod@latest',\n );\n }\n const jsonSchema = z.toJSONSchema(schema as Zod.ZodType, { target: 'draft-07' });\n return jsonSchema as JSONSchema;\n}\n\n/**\n * Synchronous version for v4 schemas.\n * Requires Zod to be cached via prior async load.\n */\nfunction zodV4ToJSONSchemaSync(schema: ZodV4Like): JSONSchema {\n if (!cachedZod) {\n throw new Error(\n 'Zod module not loaded. Call zodToJSONSchema() first or ensure Zod is imported.',\n );\n }\n if (!('toJSONSchema' in cachedZod)) {\n throw new Error(\n 'Zod v4+ required for native JSON Schema conversion. ' +\n 'Install with: bun add zod@latest',\n );\n }\n const jsonSchema = cachedZod.toJSONSchema(schema as Zod.ZodType, { target: 'draft-07' });\n return jsonSchema as JSONSchema;\n}\n\n/**\n * Converts a Zod v3 schema to JSON Schema using zod-to-json-schema.\n * Uses inline strategy to keep properties at root level for provider compatibility.\n */\nasync function zodV3ToJSONSchema(\n schema: ZodV3Like,\n): Promise<JSONSchema> {\n const { zodToJsonSchema } = await loadZodToJsonSchema();\n const jsonSchema = zodToJsonSchema(schema as Parameters<typeof zodToJsonSchema>[0], {\n $refStrategy: 'none',\n });\n return jsonSchema as unknown as JSONSchema;\n}\n\n/**\n * Synchronous version for v3 schemas.\n * Requires zod-to-json-schema to be cached via prior async load.\n */\nfunction zodV3ToJSONSchemaSync(schema: ZodV3Like): JSONSchema {\n if (!cachedZodToJsonSchema) {\n throw new Error(\n 'zod-to-json-schema module not loaded. Call zodToJSONSchema() first.',\n );\n }\n const jsonSchema = cachedZodToJsonSchema.zodToJsonSchema(\n schema as Parameters<typeof ZodToJsonSchemaFn>[0],\n {\n $refStrategy: 'none',\n },\n );\n return jsonSchema as unknown as JSONSchema;\n}\n\n/**\n * Converts a Zod schema to JSON Schema.\n *\n * For Zod v4+, uses native `z.toJSONSchema()`.\n * For Zod v3, uses `zod-to-json-schema` package.\n *\n * @param schema - Zod schema to convert\n * @returns JSON Schema representation\n * @throws Error if required dependencies are not installed\n */\nexport async function zodToJSONSchema(\n schema: ZodLike,\n): Promise<JSONSchema> {\n if (isZodV4(schema)) {\n return zodV4ToJSONSchema(schema);\n }\n return zodV3ToJSONSchema(schema);\n}\n\n/**\n * Synchronous version of zodToJSONSchema.\n * Requires modules to be cached via prior async load.\n *\n * @param schema - Zod schema to convert\n * @returns JSON Schema representation\n * @throws Error if modules not loaded or dependencies missing\n */\nexport function zodToJSONSchemaSync(\n schema: ZodLike,\n): JSONSchema {\n if (isZodV4(schema)) {\n return zodV4ToJSONSchemaSync(schema);\n }\n return zodV3ToJSONSchemaSync(schema);\n}\n\n/**\n * Validates that a schema is an object schema with properties.\n * Throws if the schema is not a valid object schema.\n */\nfunction validateObjectSchema(schema: unknown, context: string): asserts schema is JSONSchema {\n const s = schema as Record<string, unknown>;\n if (s.type !== 'object' || typeof s.properties !== 'object' || s.properties === null) {\n throw new Error(\n `${context} must be an object schema with properties. ` +\n `Received schema with type: '${s.type ?? 'undefined'}'. ` +\n 'Use z.object({...}) for Zod schemas.',\n );\n }\n}\n\n/**\n * Resolves a structure parameter that may be JSONSchema or Zod schema.\n * Validates that the result is an object schema.\n *\n * @param structure - JSONSchema or Zod schema (must be object type)\n * @returns Resolved JSONSchema\n * @throws Error if schema is not an object type\n */\nexport function resolveStructure(\n structure: JSONSchema | ZodLike,\n): JSONSchema {\n if (isZodSchema(structure)) {\n const schema = zodToJSONSchemaSync(structure);\n validateObjectSchema(schema, 'Structure schema');\n return schema;\n }\n return structure;\n}\n\n/**\n * Resolves an array of tools, converting any Zod parameters to JSONSchema.\n * Validates that each tool's parameters is an object schema.\n *\n * @param tools - Array of tools with Structure parameters\n * @returns Array of tools with resolved JSONSchema parameters\n * @throws Error if any tool parameters is not an object schema\n */\nexport function resolveTools(tools: ToolInput[]): Tool[] {\n return tools.map((tool) => {\n if (isZodSchema(tool.parameters)) {\n const schema = zodToJSONSchemaSync(tool.parameters);\n validateObjectSchema(schema, `Tool '${tool.name}' parameters`);\n return { ...tool, parameters: schema };\n }\n return tool as Tool;\n });\n}\n"],"mappings":"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","names":[]}
@@ -1,13 +1,15 @@
1
1
  import {
2
2
  deserializeEmbeddingInput,
3
3
  deserializeImage,
4
- deserializeMessage,
5
4
  resolveImageResult,
6
5
  serializeImageResult,
7
- serializeImageStreamEvent,
6
+ serializeImageStreamEvent
7
+ } from "./chunk-BIBMNP7Y.js";
8
+ import {
9
+ deserializeMessage,
8
10
  serializeStreamEvent,
9
11
  serializeTurn
10
- } from "./chunk-YQLR3XOA.js";
12
+ } from "./chunk-7ULSRWDH.js";
11
13
 
12
14
  // src/providers/proxy/server/webapi.ts
13
15
  function parseBody(body) {
@@ -219,4 +221,4 @@ export {
219
221
  bindTools,
220
222
  webapi
221
223
  };
222
- //# sourceMappingURL=chunk-LTEMH3CI.js.map
224
+ //# sourceMappingURL=chunk-5XPRVUOK.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/providers/proxy/server/webapi.ts"],"sourcesContent":["/**\n * @fileoverview Web API adapter for proxy server.\n *\n * Provides utilities for using PP proxy with Web API native frameworks\n * (Bun, Deno, Next.js App Router, Cloudflare Workers).\n *\n * These utilities return standard Web API Response objects that work\n * directly with modern runtimes.\n *\n * @module providers/proxy/server/webapi\n */\n\nimport type { Message } from '../../../types/messages.ts';\nimport type { EmbeddingInput } from '../../../types/provider.ts';\nimport type { Turn } from '../../../types/turn.ts';\nimport type { StreamResult } from '../../../types/stream.ts';\nimport type { MessageJSON } from '../../../types/messages.ts';\nimport type { JSONSchema } from '../../../types/schema.ts';\nimport type { Tool, ToolMetadata } from '../../../types/tool.ts';\nimport type { EmbeddingResult } from '../../../types/embedding.ts';\nimport type { ImageResult } from '../../../types/image.ts';\nimport {\n deserializeMessage,\n serializeTurn,\n serializeStreamEvent,\n} from '../serialization.ts';\nimport {\n deserializeEmbeddingInput,\n deserializeImage,\n serializeImageResult,\n serializeImageStreamEvent,\n type SerializedEmbeddingInput,\n type SerializedImage,\n} from '../serialization.media.ts';\nimport { resolveImageResult, type ImageStreamLike } from './image-stream.ts';\n\n/**\n * Parsed request body from a proxy HTTP request.\n * This is just the deserialized PP data from the request body.\n */\nexport interface ParsedRequest {\n messages: Message[];\n system?: string | unknown[];\n params?: Record<string, unknown>;\n model?: string;\n tools?: Array<{\n name: string;\n description: string;\n parameters: JSONSchema;\n metadata?: ToolMetadata;\n }>;\n structure?: JSONSchema;\n}\n\n/**\n * Parsed request body for embedding endpoints.\n */\nexport interface ParsedEmbeddingRequest {\n inputs: EmbeddingInput[];\n params?: Record<string, unknown>;\n model?: string;\n}\n\n/**\n * Parsed request body for image endpoints.\n */\nexport interface ParsedImageRequest {\n prompt: string;\n params?: Record<string, unknown>;\n model?: string;\n image?: ReturnType<typeof deserializeImage>;\n mask?: ReturnType<typeof deserializeImage>;\n}\n\n/**\n * Parse an HTTP request body into PP types.\n *\n * @param body - The JSON-parsed request body\n * @returns Deserialized PP data\n *\n * @example\n * ```typescript\n * const body = await req.json();\n * const { messages, system, params } = parseBody(body);\n *\n * const instance = llm({ model: anthropic('...'), system, params });\n * const turn = await instance.generate(messages);\n * ```\n */\nexport function parseBody(body: unknown): ParsedRequest {\n if (!body || typeof body !== 'object') {\n throw new Error('Request body must be an object');\n }\n\n const data = body as Record<string, unknown>;\n\n if (!Array.isArray(data.messages)) {\n throw new Error('Request body must have a messages array');\n }\n\n for (const message of data.messages) {\n if (!message || typeof message !== 'object') {\n throw new Error('Each message must be an object');\n }\n const msg = message as Record<string, unknown>;\n if (typeof msg.id !== 'string') {\n throw new Error('Each message must have a string id');\n }\n if (typeof msg.type !== 'string') {\n throw new Error('Each message must have a string type');\n }\n if (typeof msg.timestamp !== 'string') {\n throw new Error('Each message must have a string timestamp');\n }\n if ((msg.type === 'user' || msg.type === 'assistant') && !Array.isArray(msg.content)) {\n throw new Error('User and assistant messages must have a content array');\n }\n }\n\n return {\n messages: (data.messages as MessageJSON[]).map(deserializeMessage),\n system: data.system as string | unknown[] | undefined,\n params: data.params as Record<string, unknown> | undefined,\n model: typeof data.model === 'string' ? data.model : undefined,\n tools: data.tools as ParsedRequest['tools'],\n structure: data.structure as JSONSchema | undefined,\n };\n}\n\n/**\n * Parse an HTTP request body into embedding inputs.\n *\n * @param body - The JSON-parsed request body\n * @returns Parsed embedding request data\n */\nexport function parseEmbeddingBody(body: unknown): ParsedEmbeddingRequest {\n if (!body || typeof body !== 'object') {\n throw new Error('Request body must be an object');\n }\n\n const data = body as Record<string, unknown>;\n\n if (!Array.isArray(data.inputs)) {\n throw new Error('Request body must have an inputs array');\n }\n\n const inputs = data.inputs.map((input) =>\n deserializeEmbeddingInput(input as SerializedEmbeddingInput)\n );\n\n return {\n inputs,\n params: data.params as Record<string, unknown> | undefined,\n model: typeof data.model === 'string' ? data.model : undefined,\n };\n}\n\n/**\n * Parse an HTTP request body into image request data.\n *\n * @param body - The JSON-parsed request body\n * @returns Parsed image request data\n */\nexport function parseImageBody(body: unknown): ParsedImageRequest {\n if (!body || typeof body !== 'object') {\n throw new Error('Request body must be an object');\n }\n\n const data = body as Record<string, unknown>;\n const promptValue = data.prompt;\n\n let prompt: string | undefined;\n if (typeof promptValue === 'string') {\n prompt = promptValue;\n } else if (promptValue && typeof promptValue === 'object') {\n const promptObj = promptValue as Record<string, unknown>;\n if (typeof promptObj.prompt === 'string') {\n prompt = promptObj.prompt;\n }\n }\n\n if (!prompt) {\n throw new Error('Request body must have a prompt string');\n }\n\n const image = data.image ? deserializeImage(data.image as SerializedImage) : undefined;\n const mask = data.mask ? deserializeImage(data.mask as SerializedImage) : undefined;\n\n return {\n prompt,\n params: data.params as Record<string, unknown> | undefined,\n model: typeof data.model === 'string' ? data.model : undefined,\n image,\n mask,\n };\n}\n\n/**\n * Create a JSON Response from a Turn.\n *\n * @param turn - The completed inference turn\n * @returns HTTP Response with JSON body\n *\n * @example\n * ```typescript\n * const turn = await instance.generate(messages);\n * return toJSON(turn);\n * ```\n */\nexport function toJSON(turn: Turn): Response {\n return new Response(JSON.stringify(serializeTurn(turn)), {\n headers: { 'Content-Type': 'application/json' },\n });\n}\n\n/**\n * Create a JSON Response from an embedding result.\n *\n * @param result - The embedding result\n * @returns HTTP Response with JSON body\n */\nexport function toEmbeddingJSON(result: EmbeddingResult): Response {\n return new Response(JSON.stringify(result), {\n headers: { 'Content-Type': 'application/json' },\n });\n}\n\n/**\n * Create a JSON Response from an image result.\n *\n * @param result - The image result\n * @returns HTTP Response with JSON body\n */\nexport function toImageJSON(result: ImageResult): Response {\n return new Response(JSON.stringify(serializeImageResult(result)), {\n headers: { 'Content-Type': 'application/json' },\n });\n}\n\n/**\n * Create an SSE Response from a StreamResult.\n *\n * Streams PP StreamEvents as SSE, then sends the final Turn data.\n *\n * @param stream - The StreamResult from instance.stream()\n * @returns HTTP Response with SSE body\n *\n * @example\n * ```typescript\n * const stream = instance.stream(messages);\n * return toSSE(stream);\n * ```\n */\nexport function toSSE(stream: StreamResult): Response {\n const encoder = new TextEncoder();\n\n const readable = new ReadableStream({\n async start(controller) {\n try {\n for await (const event of stream) {\n const serialized = serializeStreamEvent(event);\n const data = `data: ${JSON.stringify(serialized)}\\n\\n`;\n controller.enqueue(encoder.encode(data));\n }\n\n // Send the final turn data\n const turn = await stream.turn;\n const turnData = serializeTurn(turn);\n controller.enqueue(encoder.encode(`data: ${JSON.stringify(turnData)}\\n\\n`));\n controller.enqueue(encoder.encode('data: [DONE]\\n\\n'));\n controller.close();\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n controller.enqueue(encoder.encode(`data: ${JSON.stringify({ error: errorMsg })}\\n\\n`));\n controller.close();\n }\n },\n });\n\n return new Response(readable, {\n headers: {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n Connection: 'keep-alive',\n },\n });\n}\n\n/**\n * Create an SSE Response from an ImageStreamResult.\n *\n * Streams image events as SSE, then sends the final image result.\n *\n * @param stream - The ImageStreamResult or ImageProviderStreamResult from image().stream()\n * @returns HTTP Response with SSE body\n */\nexport function toImageSSE(stream: ImageStreamLike): Response {\n const encoder = new TextEncoder();\n\n const readable = new ReadableStream({\n async start(controller) {\n try {\n for await (const event of stream) {\n const serialized = serializeImageStreamEvent(event);\n const data = `data: ${JSON.stringify(serialized)}\\n\\n`;\n controller.enqueue(encoder.encode(data));\n }\n\n const result = await resolveImageResult(stream);\n const resultData = serializeImageResult(result);\n controller.enqueue(encoder.encode(`data: ${JSON.stringify(resultData)}\\n\\n`));\n controller.enqueue(encoder.encode('data: [DONE]\\n\\n'));\n controller.close();\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n controller.enqueue(encoder.encode(`data: ${JSON.stringify({ error: errorMsg })}\\n\\n`));\n controller.close();\n }\n },\n });\n\n return new Response(readable, {\n headers: {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n Connection: 'keep-alive',\n },\n });\n}\n\n/**\n * Create an error Response.\n *\n * @param message - Error message\n * @param status - HTTP status code (default: 500)\n * @returns HTTP Response with error body\n */\nexport function toError(message: string, status = 500): Response {\n return new Response(JSON.stringify({ error: message }), {\n status,\n headers: { 'Content-Type': 'application/json' },\n });\n}\n\n/**\n * Bind tool schemas to implementation functions.\n *\n * Takes tool schemas from the request and binds them to your\n * server-side implementations.\n *\n * @param schemas - Tool schemas from the request\n * @param implementations - Map of tool name to implementation\n * @returns Array of complete Tool objects\n *\n * @example\n * ```typescript\n * const { tools: schemas } = parseBody(body);\n *\n * const tools = bindTools(schemas, {\n * get_weather: async ({ location }) => fetchWeather(location),\n * search: async ({ query }) => searchDB(query),\n * });\n *\n * const instance = llm({ model, tools });\n * ```\n */\nexport function bindTools(\n schemas: ParsedRequest['tools'],\n implementations: Record<string, (params: unknown) => unknown | Promise<unknown>>\n): Tool[] {\n if (!schemas) return [];\n\n return schemas.map((schema) => {\n const run = implementations[schema.name];\n if (!run) {\n throw new Error(`No implementation for tool: ${schema.name}`);\n }\n return { ...schema, run };\n });\n}\n\n/**\n * Web API adapter utilities.\n *\n * For use with Bun, Deno, Next.js App Router, Cloudflare Workers,\n * and other frameworks that support Web API Response.\n *\n * **Security Note:** The proxy works without configuration, meaning no\n * authentication by default. Always add your own auth layer in production.\n *\n * @example Basic usage\n * ```typescript\n * import { llm } from '@providerprotocol/ai';\n * import { anthropic } from '@providerprotocol/ai/anthropic';\n * import { parseBody, toJSON, toSSE } from '@providerprotocol/ai/proxy';\n *\n * // Bun.serve / Deno.serve / Next.js App Router\n * export async function POST(req: Request) {\n * const { messages, system } = parseBody(await req.json());\n * const instance = llm({ model: anthropic('claude-sonnet-4-20250514'), system });\n *\n * if (req.headers.get('accept')?.includes('text/event-stream')) {\n * return toSSE(instance.stream(messages));\n * }\n * return toJSON(await instance.generate(messages));\n * }\n * ```\n *\n * @example API Gateway with authentication\n * ```typescript\n * import { llm } from '@providerprotocol/ai';\n * import { anthropic } from '@providerprotocol/ai/anthropic';\n * import { ExponentialBackoff, RoundRobinKeys } from '@providerprotocol/ai/http';\n * import { parseBody, toJSON, toSSE, toError } from '@providerprotocol/ai/proxy';\n *\n * // Your platform's user validation\n * async function validateToken(token: string): Promise<{ id: string } | null> {\n * // Verify JWT, check database, etc.\n * return token ? { id: 'user-123' } : null;\n * }\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: new RoundRobinKeys([process.env.ANTHROPIC_KEY_1!, process.env.ANTHROPIC_KEY_2!]),\n * retryStrategy: new ExponentialBackoff({ maxAttempts: 3 }),\n * },\n * });\n *\n * Bun.serve({\n * port: 3000,\n * async fetch(req) {\n * // Authenticate with YOUR platform credentials\n * const token = req.headers.get('Authorization')?.replace('Bearer ', '');\n * const user = await validateToken(token ?? '');\n * if (!user) return toError('Unauthorized', 401);\n *\n * // Rate limit, track usage, bill user, etc.\n * // await trackUsage(user.id);\n *\n * const { messages, system, params } = parseBody(await req.json());\n *\n * if (params?.stream) {\n * return toSSE(claude.stream(messages, { system }));\n * }\n * return toJSON(await claude.generate(messages, { system }));\n * },\n * });\n * ```\n */\nexport const webapi = {\n parseBody,\n parseEmbeddingBody,\n parseImageBody,\n toJSON,\n toEmbeddingJSON,\n toImageJSON,\n toSSE,\n toImageSSE,\n toError,\n bindTools,\n};\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/providers/proxy/server/webapi.ts"],"sourcesContent":["/**\n * @fileoverview Web API adapter for proxy server.\n *\n * Provides utilities for using PP proxy with Web API native frameworks\n * (Bun, Deno, Next.js App Router, Cloudflare Workers).\n *\n * These utilities return standard Web API Response objects that work\n * directly with modern runtimes.\n *\n * @module providers/proxy/server/webapi\n */\n\nimport type { Message } from '../../../types/messages.ts';\nimport type { EmbeddingInput } from '../../../types/provider.ts';\nimport type { Turn } from '../../../types/turn.ts';\nimport type { StreamResult } from '../../../types/stream.ts';\nimport type { MessageJSON } from '../../../types/messages.ts';\nimport type { JSONSchema } from '../../../types/schema.ts';\nimport type { Tool, ToolMetadata } from '../../../types/tool.ts';\nimport type { EmbeddingResult } from '../../../types/embedding.ts';\nimport type { ImageResult } from '../../../types/image.ts';\nimport {\n deserializeMessage,\n serializeTurn,\n serializeStreamEvent,\n} from '../serialization.ts';\nimport {\n deserializeEmbeddingInput,\n deserializeImage,\n serializeImageResult,\n serializeImageStreamEvent,\n type SerializedEmbeddingInput,\n type SerializedImage,\n} from '../serialization.media.ts';\nimport { resolveImageResult, type ImageStreamLike } from './image-stream.ts';\n\n/**\n * Parsed request body from a proxy HTTP request.\n * This is just the deserialized PP data from the request body.\n */\nexport interface ParsedRequest {\n messages: Message[];\n system?: string | unknown[];\n params?: Record<string, unknown>;\n model?: string;\n tools?: Array<{\n name: string;\n description: string;\n parameters: JSONSchema;\n metadata?: ToolMetadata;\n }>;\n structure?: JSONSchema;\n}\n\n/**\n * Parsed request body for embedding endpoints.\n */\nexport interface ParsedEmbeddingRequest {\n inputs: EmbeddingInput[];\n params?: Record<string, unknown>;\n model?: string;\n}\n\n/**\n * Parsed request body for image endpoints.\n */\nexport interface ParsedImageRequest {\n prompt: string;\n params?: Record<string, unknown>;\n model?: string;\n image?: ReturnType<typeof deserializeImage>;\n mask?: ReturnType<typeof deserializeImage>;\n}\n\n/**\n * Parse an HTTP request body into PP types.\n *\n * @param body - The JSON-parsed request body\n * @returns Deserialized PP data\n *\n * @example\n * ```typescript\n * const body = await req.json();\n * const { messages, system, params } = parseBody(body);\n *\n * const instance = llm({ model: anthropic('...'), system, params });\n * const turn = await instance.generate(messages);\n * ```\n */\nexport function parseBody(body: unknown): ParsedRequest {\n if (!body || typeof body !== 'object') {\n throw new Error('Request body must be an object');\n }\n\n const data = body as Record<string, unknown>;\n\n if (!Array.isArray(data.messages)) {\n throw new Error('Request body must have a messages array');\n }\n\n for (const message of data.messages) {\n if (!message || typeof message !== 'object') {\n throw new Error('Each message must be an object');\n }\n const msg = message as Record<string, unknown>;\n if (typeof msg.id !== 'string') {\n throw new Error('Each message must have a string id');\n }\n if (typeof msg.type !== 'string') {\n throw new Error('Each message must have a string type');\n }\n if (typeof msg.timestamp !== 'string') {\n throw new Error('Each message must have a string timestamp');\n }\n if ((msg.type === 'user' || msg.type === 'assistant') && !Array.isArray(msg.content)) {\n throw new Error('User and assistant messages must have a content array');\n }\n }\n\n return {\n messages: (data.messages as MessageJSON[]).map(deserializeMessage),\n system: data.system as string | unknown[] | undefined,\n params: data.params as Record<string, unknown> | undefined,\n model: typeof data.model === 'string' ? data.model : undefined,\n tools: data.tools as ParsedRequest['tools'],\n structure: data.structure as JSONSchema | undefined,\n };\n}\n\n/**\n * Parse an HTTP request body into embedding inputs.\n *\n * @param body - The JSON-parsed request body\n * @returns Parsed embedding request data\n */\nexport function parseEmbeddingBody(body: unknown): ParsedEmbeddingRequest {\n if (!body || typeof body !== 'object') {\n throw new Error('Request body must be an object');\n }\n\n const data = body as Record<string, unknown>;\n\n if (!Array.isArray(data.inputs)) {\n throw new Error('Request body must have an inputs array');\n }\n\n const inputs = data.inputs.map((input) =>\n deserializeEmbeddingInput(input as SerializedEmbeddingInput)\n );\n\n return {\n inputs,\n params: data.params as Record<string, unknown> | undefined,\n model: typeof data.model === 'string' ? data.model : undefined,\n };\n}\n\n/**\n * Parse an HTTP request body into image request data.\n *\n * @param body - The JSON-parsed request body\n * @returns Parsed image request data\n */\nexport function parseImageBody(body: unknown): ParsedImageRequest {\n if (!body || typeof body !== 'object') {\n throw new Error('Request body must be an object');\n }\n\n const data = body as Record<string, unknown>;\n const promptValue = data.prompt;\n\n let prompt: string | undefined;\n if (typeof promptValue === 'string') {\n prompt = promptValue;\n } else if (promptValue && typeof promptValue === 'object') {\n const promptObj = promptValue as Record<string, unknown>;\n if (typeof promptObj.prompt === 'string') {\n prompt = promptObj.prompt;\n }\n }\n\n if (!prompt) {\n throw new Error('Request body must have a prompt string');\n }\n\n const image = data.image ? deserializeImage(data.image as SerializedImage) : undefined;\n const mask = data.mask ? deserializeImage(data.mask as SerializedImage) : undefined;\n\n return {\n prompt,\n params: data.params as Record<string, unknown> | undefined,\n model: typeof data.model === 'string' ? data.model : undefined,\n image,\n mask,\n };\n}\n\n/**\n * Create a JSON Response from a Turn.\n *\n * @param turn - The completed inference turn\n * @returns HTTP Response with JSON body\n *\n * @example\n * ```typescript\n * const turn = await instance.generate(messages);\n * return toJSON(turn);\n * ```\n */\nexport function toJSON(turn: Turn): Response {\n return new Response(JSON.stringify(serializeTurn(turn)), {\n headers: { 'Content-Type': 'application/json' },\n });\n}\n\n/**\n * Create a JSON Response from an embedding result.\n *\n * @param result - The embedding result\n * @returns HTTP Response with JSON body\n */\nexport function toEmbeddingJSON(result: EmbeddingResult): Response {\n return new Response(JSON.stringify(result), {\n headers: { 'Content-Type': 'application/json' },\n });\n}\n\n/**\n * Create a JSON Response from an image result.\n *\n * @param result - The image result\n * @returns HTTP Response with JSON body\n */\nexport function toImageJSON(result: ImageResult): Response {\n return new Response(JSON.stringify(serializeImageResult(result)), {\n headers: { 'Content-Type': 'application/json' },\n });\n}\n\n/**\n * Create an SSE Response from a StreamResult.\n *\n * Streams PP StreamEvents as SSE, then sends the final Turn data.\n *\n * @param stream - The StreamResult from instance.stream()\n * @returns HTTP Response with SSE body\n *\n * @example\n * ```typescript\n * const stream = instance.stream(messages);\n * return toSSE(stream);\n * ```\n */\nexport function toSSE(stream: StreamResult): Response {\n const encoder = new TextEncoder();\n\n const readable = new ReadableStream({\n async start(controller) {\n try {\n for await (const event of stream) {\n const serialized = serializeStreamEvent(event);\n const data = `data: ${JSON.stringify(serialized)}\\n\\n`;\n controller.enqueue(encoder.encode(data));\n }\n\n // Send the final turn data\n const turn = await stream.turn;\n const turnData = serializeTurn(turn);\n controller.enqueue(encoder.encode(`data: ${JSON.stringify(turnData)}\\n\\n`));\n controller.enqueue(encoder.encode('data: [DONE]\\n\\n'));\n controller.close();\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n controller.enqueue(encoder.encode(`data: ${JSON.stringify({ error: errorMsg })}\\n\\n`));\n controller.close();\n }\n },\n });\n\n return new Response(readable, {\n headers: {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n Connection: 'keep-alive',\n },\n });\n}\n\n/**\n * Create an SSE Response from an ImageStreamResult.\n *\n * Streams image events as SSE, then sends the final image result.\n *\n * @param stream - The ImageStreamResult or ImageProviderStreamResult from image().stream()\n * @returns HTTP Response with SSE body\n */\nexport function toImageSSE(stream: ImageStreamLike): Response {\n const encoder = new TextEncoder();\n\n const readable = new ReadableStream({\n async start(controller) {\n try {\n for await (const event of stream) {\n const serialized = serializeImageStreamEvent(event);\n const data = `data: ${JSON.stringify(serialized)}\\n\\n`;\n controller.enqueue(encoder.encode(data));\n }\n\n const result = await resolveImageResult(stream);\n const resultData = serializeImageResult(result);\n controller.enqueue(encoder.encode(`data: ${JSON.stringify(resultData)}\\n\\n`));\n controller.enqueue(encoder.encode('data: [DONE]\\n\\n'));\n controller.close();\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n controller.enqueue(encoder.encode(`data: ${JSON.stringify({ error: errorMsg })}\\n\\n`));\n controller.close();\n }\n },\n });\n\n return new Response(readable, {\n headers: {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n Connection: 'keep-alive',\n },\n });\n}\n\n/**\n * Create an error Response.\n *\n * @param message - Error message\n * @param status - HTTP status code (default: 500)\n * @returns HTTP Response with error body\n */\nexport function toError(message: string, status = 500): Response {\n return new Response(JSON.stringify({ error: message }), {\n status,\n headers: { 'Content-Type': 'application/json' },\n });\n}\n\n/**\n * Bind tool schemas to implementation functions.\n *\n * Takes tool schemas from the request and binds them to your\n * server-side implementations.\n *\n * @param schemas - Tool schemas from the request\n * @param implementations - Map of tool name to implementation\n * @returns Array of complete Tool objects\n *\n * @example\n * ```typescript\n * const { tools: schemas } = parseBody(body);\n *\n * const tools = bindTools(schemas, {\n * get_weather: async ({ location }) => fetchWeather(location),\n * search: async ({ query }) => searchDB(query),\n * });\n *\n * const instance = llm({ model, tools });\n * ```\n */\nexport function bindTools(\n schemas: ParsedRequest['tools'],\n implementations: Record<string, (params: unknown) => unknown | Promise<unknown>>\n): Tool[] {\n if (!schemas) return [];\n\n return schemas.map((schema) => {\n const run = implementations[schema.name];\n if (!run) {\n throw new Error(`No implementation for tool: ${schema.name}`);\n }\n return { ...schema, run };\n });\n}\n\n/**\n * Web API adapter utilities.\n *\n * For use with Bun, Deno, Next.js App Router, Cloudflare Workers,\n * and other frameworks that support Web API Response.\n *\n * **Security Note:** The proxy works without configuration, meaning no\n * authentication by default. Always add your own auth layer in production.\n *\n * @example Basic usage\n * ```typescript\n * import { llm } from '@providerprotocol/ai';\n * import { anthropic } from '@providerprotocol/ai/anthropic';\n * import { parseBody, toJSON, toSSE } from '@providerprotocol/ai/proxy';\n *\n * // Bun.serve / Deno.serve / Next.js App Router\n * export async function POST(req: Request) {\n * const { messages, system } = parseBody(await req.json());\n * const instance = llm({ model: anthropic('claude-sonnet-4-20250514'), system });\n *\n * if (req.headers.get('accept')?.includes('text/event-stream')) {\n * return toSSE(instance.stream(messages));\n * }\n * return toJSON(await instance.generate(messages));\n * }\n * ```\n *\n * @example API Gateway with authentication\n * ```typescript\n * import { llm } from '@providerprotocol/ai';\n * import { anthropic } from '@providerprotocol/ai/anthropic';\n * import { ExponentialBackoff, RoundRobinKeys } from '@providerprotocol/ai/http';\n * import { parseBody, toJSON, toSSE, toError } from '@providerprotocol/ai/proxy';\n *\n * // Your platform's user validation\n * async function validateToken(token: string): Promise<{ id: string } | null> {\n * // Verify JWT, check database, etc.\n * return token ? { id: 'user-123' } : null;\n * }\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: new RoundRobinKeys([process.env.ANTHROPIC_KEY_1!, process.env.ANTHROPIC_KEY_2!]),\n * retryStrategy: new ExponentialBackoff({ maxAttempts: 3 }),\n * },\n * });\n *\n * Bun.serve({\n * port: 3000,\n * async fetch(req) {\n * // Authenticate with YOUR platform credentials\n * const token = req.headers.get('Authorization')?.replace('Bearer ', '');\n * const user = await validateToken(token ?? '');\n * if (!user) return toError('Unauthorized', 401);\n *\n * // Rate limit, track usage, bill user, etc.\n * // await trackUsage(user.id);\n *\n * const { messages, system, params } = parseBody(await req.json());\n *\n * if (params?.stream) {\n * return toSSE(claude.stream(messages, { system }));\n * }\n * return toJSON(await claude.generate(messages, { system }));\n * },\n * });\n * ```\n */\nexport const webapi = {\n parseBody,\n parseEmbeddingBody,\n parseImageBody,\n toJSON,\n toEmbeddingJSON,\n toImageJSON,\n toSSE,\n toImageSSE,\n toError,\n bindTools,\n};\n"],"mappings":";;;;;;;;;;;;;;AAyFO,SAAS,UAAU,MAA8B;AACtD,MAAI,CAAC,QAAQ,OAAO,SAAS,UAAU;AACrC,UAAM,IAAI,MAAM,gCAAgC;AAAA,EAClD;AAEA,QAAM,OAAO;AAEb,MAAI,CAAC,MAAM,QAAQ,KAAK,QAAQ,GAAG;AACjC,UAAM,IAAI,MAAM,yCAAyC;AAAA,EAC3D;AAEA,aAAW,WAAW,KAAK,UAAU;AACnC,QAAI,CAAC,WAAW,OAAO,YAAY,UAAU;AAC3C,YAAM,IAAI,MAAM,gCAAgC;AAAA,IAClD;AACA,UAAM,MAAM;AACZ,QAAI,OAAO,IAAI,OAAO,UAAU;AAC9B,YAAM,IAAI,MAAM,oCAAoC;AAAA,IACtD;AACA,QAAI,OAAO,IAAI,SAAS,UAAU;AAChC,YAAM,IAAI,MAAM,sCAAsC;AAAA,IACxD;AACA,QAAI,OAAO,IAAI,cAAc,UAAU;AACrC,YAAM,IAAI,MAAM,2CAA2C;AAAA,IAC7D;AACA,SAAK,IAAI,SAAS,UAAU,IAAI,SAAS,gBAAgB,CAAC,MAAM,QAAQ,IAAI,OAAO,GAAG;AACpF,YAAM,IAAI,MAAM,uDAAuD;AAAA,IACzE;AAAA,EACF;AAEA,SAAO;AAAA,IACL,UAAW,KAAK,SAA2B,IAAI,kBAAkB;AAAA,IACjE,QAAQ,KAAK;AAAA,IACb,QAAQ,KAAK;AAAA,IACb,OAAO,OAAO,KAAK,UAAU,WAAW,KAAK,QAAQ;AAAA,IACrD,OAAO,KAAK;AAAA,IACZ,WAAW,KAAK;AAAA,EAClB;AACF;AAQO,SAAS,mBAAmB,MAAuC;AACxE,MAAI,CAAC,QAAQ,OAAO,SAAS,UAAU;AACrC,UAAM,IAAI,MAAM,gCAAgC;AAAA,EAClD;AAEA,QAAM,OAAO;AAEb,MAAI,CAAC,MAAM,QAAQ,KAAK,MAAM,GAAG;AAC/B,UAAM,IAAI,MAAM,wCAAwC;AAAA,EAC1D;AAEA,QAAM,SAAS,KAAK,OAAO;AAAA,IAAI,CAAC,UAC9B,0BAA0B,KAAiC;AAAA,EAC7D;AAEA,SAAO;AAAA,IACL;AAAA,IACA,QAAQ,KAAK;AAAA,IACb,OAAO,OAAO,KAAK,UAAU,WAAW,KAAK,QAAQ;AAAA,EACvD;AACF;AAQO,SAAS,eAAe,MAAmC;AAChE,MAAI,CAAC,QAAQ,OAAO,SAAS,UAAU;AACrC,UAAM,IAAI,MAAM,gCAAgC;AAAA,EAClD;AAEA,QAAM,OAAO;AACb,QAAM,cAAc,KAAK;AAEzB,MAAI;AACJ,MAAI,OAAO,gBAAgB,UAAU;AACnC,aAAS;AAAA,EACX,WAAW,eAAe,OAAO,gBAAgB,UAAU;AACzD,UAAM,YAAY;AAClB,QAAI,OAAO,UAAU,WAAW,UAAU;AACxC,eAAS,UAAU;AAAA,IACrB;AAAA,EACF;AAEA,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,MAAM,wCAAwC;AAAA,EAC1D;AAEA,QAAM,QAAQ,KAAK,QAAQ,iBAAiB,KAAK,KAAwB,IAAI;AAC7E,QAAM,OAAO,KAAK,OAAO,iBAAiB,KAAK,IAAuB,IAAI;AAE1E,SAAO;AAAA,IACL;AAAA,IACA,QAAQ,KAAK;AAAA,IACb,OAAO,OAAO,KAAK,UAAU,WAAW,KAAK,QAAQ;AAAA,IACrD;AAAA,IACA;AAAA,EACF;AACF;AAcO,SAAS,OAAO,MAAsB;AAC3C,SAAO,IAAI,SAAS,KAAK,UAAU,cAAc,IAAI,CAAC,GAAG;AAAA,IACvD,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,EAChD,CAAC;AACH;AAQO,SAAS,gBAAgB,QAAmC;AACjE,SAAO,IAAI,SAAS,KAAK,UAAU,MAAM,GAAG;AAAA,IAC1C,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,EAChD,CAAC;AACH;AAQO,SAAS,YAAY,QAA+B;AACzD,SAAO,IAAI,SAAS,KAAK,UAAU,qBAAqB,MAAM,CAAC,GAAG;AAAA,IAChE,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,EAChD,CAAC;AACH;AAgBO,SAAS,MAAM,QAAgC;AACpD,QAAM,UAAU,IAAI,YAAY;AAEhC,QAAM,WAAW,IAAI,eAAe;AAAA,IAClC,MAAM,MAAM,YAAY;AACtB,UAAI;AACF,yBAAiB,SAAS,QAAQ;AAChC,gBAAM,aAAa,qBAAqB,KAAK;AAC7C,gBAAM,OAAO,SAAS,KAAK,UAAU,UAAU,CAAC;AAAA;AAAA;AAChD,qBAAW,QAAQ,QAAQ,OAAO,IAAI,CAAC;AAAA,QACzC;AAGA,cAAM,OAAO,MAAM,OAAO;AAC1B,cAAM,WAAW,cAAc,IAAI;AACnC,mBAAW,QAAQ,QAAQ,OAAO,SAAS,KAAK,UAAU,QAAQ,CAAC;AAAA;AAAA,CAAM,CAAC;AAC1E,mBAAW,QAAQ,QAAQ,OAAO,kBAAkB,CAAC;AACrD,mBAAW,MAAM;AAAA,MACnB,SAAS,OAAO;AACd,cAAM,WAAW,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACtE,mBAAW,QAAQ,QAAQ,OAAO,SAAS,KAAK,UAAU,EAAE,OAAO,SAAS,CAAC,CAAC;AAAA;AAAA,CAAM,CAAC;AACrF,mBAAW,MAAM;AAAA,MACnB;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO,IAAI,SAAS,UAAU;AAAA,IAC5B,SAAS;AAAA,MACP,gBAAgB;AAAA,MAChB,iBAAiB;AAAA,MACjB,YAAY;AAAA,IACd;AAAA,EACF,CAAC;AACH;AAUO,SAAS,WAAW,QAAmC;AAC5D,QAAM,UAAU,IAAI,YAAY;AAEhC,QAAM,WAAW,IAAI,eAAe;AAAA,IAClC,MAAM,MAAM,YAAY;AACtB,UAAI;AACF,yBAAiB,SAAS,QAAQ;AAChC,gBAAM,aAAa,0BAA0B,KAAK;AAClD,gBAAM,OAAO,SAAS,KAAK,UAAU,UAAU,CAAC;AAAA;AAAA;AAChD,qBAAW,QAAQ,QAAQ,OAAO,IAAI,CAAC;AAAA,QACzC;AAEA,cAAM,SAAS,MAAM,mBAAmB,MAAM;AAC9C,cAAM,aAAa,qBAAqB,MAAM;AAC9C,mBAAW,QAAQ,QAAQ,OAAO,SAAS,KAAK,UAAU,UAAU,CAAC;AAAA;AAAA,CAAM,CAAC;AAC5E,mBAAW,QAAQ,QAAQ,OAAO,kBAAkB,CAAC;AACrD,mBAAW,MAAM;AAAA,MACnB,SAAS,OAAO;AACd,cAAM,WAAW,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACtE,mBAAW,QAAQ,QAAQ,OAAO,SAAS,KAAK,UAAU,EAAE,OAAO,SAAS,CAAC,CAAC;AAAA;AAAA,CAAM,CAAC;AACrF,mBAAW,MAAM;AAAA,MACnB;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO,IAAI,SAAS,UAAU;AAAA,IAC5B,SAAS;AAAA,MACP,gBAAgB;AAAA,MAChB,iBAAiB;AAAA,MACjB,YAAY;AAAA,IACd;AAAA,EACF,CAAC;AACH;AASO,SAAS,QAAQ,SAAiB,SAAS,KAAe;AAC/D,SAAO,IAAI,SAAS,KAAK,UAAU,EAAE,OAAO,QAAQ,CAAC,GAAG;AAAA,IACtD;AAAA,IACA,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,EAChD,CAAC;AACH;AAwBO,SAAS,UACd,SACA,iBACQ;AACR,MAAI,CAAC,QAAS,QAAO,CAAC;AAEtB,SAAO,QAAQ,IAAI,CAAC,WAAW;AAC7B,UAAM,MAAM,gBAAgB,OAAO,IAAI;AACvC,QAAI,CAAC,KAAK;AACR,YAAM,IAAI,MAAM,+BAA+B,OAAO,IAAI,EAAE;AAAA,IAC9D;AACA,WAAO,EAAE,GAAG,QAAQ,IAAI;AAAA,EAC1B,CAAC;AACH;AAwEO,IAAM,SAAS;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;","names":[]}
@@ -0,0 +1,83 @@
1
+ import {
2
+ deserializeStreamEvent,
3
+ serializeStreamEvent
4
+ } from "./chunk-ETBFOLQN.js";
5
+ import {
6
+ AssistantMessage,
7
+ ToolResultMessage,
8
+ UserMessage
9
+ } from "./chunk-WU4U6IHF.js";
10
+ import {
11
+ ErrorCode,
12
+ ModalityType,
13
+ UPPError
14
+ } from "./chunk-COS4ON4G.js";
15
+
16
+ // src/providers/proxy/serialization.ts
17
+ function serializeMessage(m) {
18
+ const base = {
19
+ id: m.id,
20
+ type: m.type,
21
+ content: [],
22
+ metadata: m.metadata,
23
+ timestamp: m.timestamp.toISOString()
24
+ };
25
+ if (m instanceof UserMessage) {
26
+ base.content = m.content;
27
+ } else if (m instanceof AssistantMessage) {
28
+ base.content = m.content;
29
+ base.toolCalls = m.toolCalls;
30
+ } else if (m instanceof ToolResultMessage) {
31
+ base.results = m.results;
32
+ }
33
+ return base;
34
+ }
35
+ function deserializeMessage(json) {
36
+ const options = {
37
+ id: json.id,
38
+ metadata: json.metadata
39
+ };
40
+ switch (json.type) {
41
+ case "user":
42
+ return new UserMessage(json.content, options);
43
+ case "assistant":
44
+ return new AssistantMessage(
45
+ json.content,
46
+ json.toolCalls,
47
+ options
48
+ );
49
+ case "tool_result":
50
+ return new ToolResultMessage(json.results ?? [], options);
51
+ default:
52
+ throw new UPPError(
53
+ `Unknown message type: ${json.type}`,
54
+ ErrorCode.InvalidResponse,
55
+ "proxy",
56
+ ModalityType.LLM
57
+ );
58
+ }
59
+ }
60
+ function serializeTurn(turn) {
61
+ return {
62
+ messages: turn.messages.map(serializeMessage),
63
+ toolExecutions: turn.toolExecutions,
64
+ usage: turn.usage,
65
+ cycles: turn.cycles,
66
+ data: turn.data
67
+ };
68
+ }
69
+ function serializeStreamEvent2(event) {
70
+ return serializeStreamEvent(event);
71
+ }
72
+ function deserializeStreamEvent2(event) {
73
+ return deserializeStreamEvent(event);
74
+ }
75
+
76
+ export {
77
+ serializeMessage,
78
+ deserializeMessage,
79
+ serializeTurn,
80
+ serializeStreamEvent2 as serializeStreamEvent,
81
+ deserializeStreamEvent2 as deserializeStreamEvent
82
+ };
83
+ //# sourceMappingURL=chunk-7ULSRWDH.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/providers/proxy/serialization.ts"],"sourcesContent":["/**\n * @fileoverview Serialization utilities for proxy transport.\n *\n * Handles converting PP types to/from JSON for HTTP transport.\n * These are pure functions with no side effects.\n *\n * @module providers/proxy/serialization\n */\n\nimport {\n UserMessage,\n AssistantMessage,\n ToolResultMessage,\n type Message,\n type MessageJSON,\n} from '../../types/messages.ts';\nimport type { UserContent, AssistantContent } from '../../types/content.ts';\nimport type { StreamEvent } from '../../types/stream.ts';\nimport type { Turn, TurnJSON } from '../../types/turn.ts';\nimport { UPPError, ErrorCode, ModalityType } from '../../types/errors.ts';\nimport {\n serializeStreamEvent as serializeStreamEventShared,\n deserializeStreamEvent as deserializeStreamEventShared,\n} from '../../stream/serialization.ts';\n\n/**\n * Convert a Message to MessageJSON format.\n */\nexport function serializeMessage(m: Message): MessageJSON {\n const base: MessageJSON = {\n id: m.id,\n type: m.type,\n content: [],\n metadata: m.metadata,\n timestamp: m.timestamp.toISOString(),\n };\n\n if (m instanceof UserMessage) {\n base.content = m.content;\n } else if (m instanceof AssistantMessage) {\n base.content = m.content;\n base.toolCalls = m.toolCalls;\n } else if (m instanceof ToolResultMessage) {\n base.results = m.results;\n }\n\n return base;\n}\n\n/**\n * Reconstruct a Message from MessageJSON format.\n */\nexport function deserializeMessage(json: MessageJSON): Message {\n const options = {\n id: json.id,\n metadata: json.metadata,\n };\n\n switch (json.type) {\n case 'user':\n return new UserMessage(json.content as UserContent[], options);\n case 'assistant':\n return new AssistantMessage(\n json.content as AssistantContent[],\n json.toolCalls,\n options\n );\n case 'tool_result':\n return new ToolResultMessage(json.results ?? [], options);\n default:\n throw new UPPError(\n `Unknown message type: ${json.type}`,\n ErrorCode.InvalidResponse,\n 'proxy',\n ModalityType.LLM\n );\n }\n}\n\n/**\n * Serialize a Turn to JSON-transportable format.\n */\nexport function serializeTurn(turn: Turn): TurnJSON {\n return {\n messages: turn.messages.map(serializeMessage),\n toolExecutions: turn.toolExecutions,\n usage: turn.usage,\n cycles: turn.cycles,\n data: turn.data,\n };\n}\n\n/**\n * Serialize a StreamEvent for JSON transport.\n * Converts Uint8Array data to base64 string.\n */\nexport function serializeStreamEvent(event: StreamEvent): StreamEvent {\n return serializeStreamEventShared(event);\n}\n\n/**\n * Deserialize a StreamEvent from JSON transport.\n * Converts base64 string data back to Uint8Array.\n */\nexport function deserializeStreamEvent(event: StreamEvent): StreamEvent {\n return deserializeStreamEventShared(event);\n}\n"],"mappings":";;;;;;;;;;;;;;;;AA4BO,SAAS,iBAAiB,GAAyB;AACxD,QAAM,OAAoB;AAAA,IACxB,IAAI,EAAE;AAAA,IACN,MAAM,EAAE;AAAA,IACR,SAAS,CAAC;AAAA,IACV,UAAU,EAAE;AAAA,IACZ,WAAW,EAAE,UAAU,YAAY;AAAA,EACrC;AAEA,MAAI,aAAa,aAAa;AAC5B,SAAK,UAAU,EAAE;AAAA,EACnB,WAAW,aAAa,kBAAkB;AACxC,SAAK,UAAU,EAAE;AACjB,SAAK,YAAY,EAAE;AAAA,EACrB,WAAW,aAAa,mBAAmB;AACzC,SAAK,UAAU,EAAE;AAAA,EACnB;AAEA,SAAO;AACT;AAKO,SAAS,mBAAmB,MAA4B;AAC7D,QAAM,UAAU;AAAA,IACd,IAAI,KAAK;AAAA,IACT,UAAU,KAAK;AAAA,EACjB;AAEA,UAAQ,KAAK,MAAM;AAAA,IACjB,KAAK;AACH,aAAO,IAAI,YAAY,KAAK,SAA0B,OAAO;AAAA,IAC/D,KAAK;AACH,aAAO,IAAI;AAAA,QACT,KAAK;AAAA,QACL,KAAK;AAAA,QACL;AAAA,MACF;AAAA,IACF,KAAK;AACH,aAAO,IAAI,kBAAkB,KAAK,WAAW,CAAC,GAAG,OAAO;AAAA,IAC1D;AACE,YAAM,IAAI;AAAA,QACR,yBAAyB,KAAK,IAAI;AAAA,QAClC,UAAU;AAAA,QACV;AAAA,QACA,aAAa;AAAA,MACf;AAAA,EACJ;AACF;AAKO,SAAS,cAAc,MAAsB;AAClD,SAAO;AAAA,IACL,UAAU,KAAK,SAAS,IAAI,gBAAgB;AAAA,IAC5C,gBAAgB,KAAK;AAAA,IACrB,OAAO,KAAK;AAAA,IACZ,QAAQ,KAAK;AAAA,IACb,MAAM,KAAK;AAAA,EACb;AACF;AAMO,SAASA,sBAAqB,OAAiC;AACpE,SAAO,qBAA2B,KAAK;AACzC;AAMO,SAASC,wBAAuB,OAAiC;AACtE,SAAO,uBAA6B,KAAK;AAC3C;","names":["serializeStreamEvent","deserializeStreamEvent"]}
@@ -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-YQLR3XOA.js.map
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":"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","names":[]}