@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.
- package/README.md +94 -3
- package/dist/anthropic/index.d.ts +3 -2
- package/dist/cerebras/index.d.ts +3 -2
- package/dist/chunk-3Q5VELKG.js +124 -0
- package/dist/chunk-3Q5VELKG.js.map +1 -0
- package/dist/{chunk-LTEMH3CI.js → chunk-5XPRVUOK.js} +6 -4
- package/dist/{chunk-LTEMH3CI.js.map → chunk-5XPRVUOK.js.map} +1 -1
- package/dist/chunk-7ULSRWDH.js +83 -0
- package/dist/chunk-7ULSRWDH.js.map +1 -0
- package/dist/{chunk-YQLR3XOA.js → chunk-BIBMNP7Y.js} +1 -75
- package/dist/chunk-BIBMNP7Y.js.map +1 -0
- package/dist/{chunk-7GTWHZY2.js → chunk-IDZR4ROP.js} +5 -3
- package/dist/{chunk-7GTWHZY2.js.map → chunk-IDZR4ROP.js.map} +1 -1
- package/dist/{chunk-4RX4VQCB.js → chunk-IIMTP3XC.js} +2 -2
- package/dist/{chunk-ZRVNAET3.js → chunk-KNBODIQU.js} +6 -3
- package/dist/chunk-KNBODIQU.js.map +1 -0
- package/dist/{chunk-FYSZFIZS.js → chunk-O32SBS6S.js} +5 -3
- package/dist/{chunk-FYSZFIZS.js.map → chunk-O32SBS6S.js.map} +1 -1
- package/dist/{chunk-BDXH6NQS.js → chunk-RDC5GYST.js} +5 -5
- package/dist/{chunk-5IWHCXKN.js → chunk-SAMIK4WZ.js} +2 -2
- package/dist/{chunk-EPB3GQNL.js → chunk-U6M3MXNI.js} +11 -2
- package/dist/chunk-U6M3MXNI.js.map +1 -0
- package/dist/{chunk-2YXFLRQ6.js → chunk-WNB5PSY6.js} +2 -2
- package/dist/{chunk-CRP6Y7NF.js → chunk-ZDYEDI2A.js} +2 -2
- package/dist/{embedding-CwZ1ZNWv.d.ts → embedding-iNQCeXfk.d.ts} +1 -1
- package/dist/google/index.d.ts +3 -2
- package/dist/groq/index.d.ts +3 -2
- package/dist/http/index.d.ts +4 -3
- package/dist/{image-stream-CeQHtjxS.d.ts → image-stream-ARno6XlS.d.ts} +1 -1
- package/dist/index.d.ts +8 -7
- package/dist/index.js +11 -2
- package/dist/index.js.map +1 -1
- package/dist/{llm-DS_-l71X.d.ts → llm-CZqlijjK.d.ts} +16 -9
- package/dist/middleware/logging/index.d.ts +3 -2
- package/dist/middleware/parsed-object/index.d.ts +3 -2
- package/dist/middleware/persistence/index.d.ts +3 -2
- package/dist/middleware/pubsub/index.d.ts +5 -4
- package/dist/middleware/pubsub/index.js +49 -3
- 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 +3 -2
- package/dist/middleware/pubsub/server/index.js +5 -5
- 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/ollama/index.d.ts +3 -2
- package/dist/openai/index.d.ts +3 -2
- package/dist/openrouter/index.d.ts +3 -2
- package/dist/proxy/index.d.ts +5 -4
- package/dist/proxy/index.js +10 -8
- package/dist/proxy/index.js.map +1 -1
- package/dist/proxy/server/express/index.d.ts +5 -4
- package/dist/proxy/server/express/index.js +3 -2
- package/dist/proxy/server/fastify/index.d.ts +5 -4
- package/dist/proxy/server/fastify/index.js +3 -2
- package/dist/proxy/server/h3/index.d.ts +19 -17
- package/dist/proxy/server/h3/index.js +3 -2
- package/dist/proxy/server/index.d.ts +5 -4
- package/dist/proxy/server/index.js +7 -6
- package/dist/proxy/server/webapi/index.d.ts +5 -4
- package/dist/proxy/server/webapi/index.js +3 -2
- package/dist/responses/index.d.ts +3 -2
- package/dist/{retry-CgoBNa51.d.ts → retry-C1eJbEMV.d.ts} +1 -1
- package/dist/{stream-sXhBtWjl.d.ts → stream-DVVUIKpz.d.ts} +3 -416
- package/dist/tool-D22EhP5F.d.ts +507 -0
- package/dist/{types-Cr4F0tVy.d.ts → types-CyXF0J7C.d.ts} +16 -3
- package/dist/utils/index.d.ts +65 -1
- package/dist/utils/index.js +15 -1
- package/dist/xai/index.d.ts +3 -2
- package/package.json +15 -3
- package/dist/chunk-EPB3GQNL.js.map +0 -1
- package/dist/chunk-YQLR3XOA.js.map +0 -1
- package/dist/chunk-ZRVNAET3.js.map +0 -1
- /package/dist/{chunk-4RX4VQCB.js.map → chunk-IIMTP3XC.js.map} +0 -0
- /package/dist/{chunk-BDXH6NQS.js.map → chunk-RDC5GYST.js.map} +0 -0
- /package/dist/{chunk-5IWHCXKN.js.map → chunk-SAMIK4WZ.js.map} +0 -0
- /package/dist/{chunk-2YXFLRQ6.js.map → chunk-WNB5PSY6.js.map} +0 -0
- /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
|
-
|
|
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.
|
|
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
|
package/dist/cerebras/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { e as Provider } from '../llm-
|
|
2
|
-
import '../stream-
|
|
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-
|
|
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-
|
|
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":";;;;;;;;;;;;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":[]}
|
|
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":[]}
|
|
@@ -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-
|
|
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":[]}
|