ai.matey.types 0.2.0
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/LICENSE +21 -0
- package/dist/cjs/adapters.js +16 -0
- package/dist/cjs/adapters.js.map +1 -0
- package/dist/cjs/bridge.js +32 -0
- package/dist/cjs/bridge.js.map +1 -0
- package/dist/cjs/errors.js +121 -0
- package/dist/cjs/errors.js.map +1 -0
- package/dist/cjs/index.js +44 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/ir.js +17 -0
- package/dist/cjs/ir.js.map +1 -0
- package/dist/cjs/middleware.js +11 -0
- package/dist/cjs/middleware.js.map +1 -0
- package/dist/cjs/model-runner.js +11 -0
- package/dist/cjs/model-runner.js.map +1 -0
- package/dist/cjs/model-translation.js +10 -0
- package/dist/cjs/model-translation.js.map +1 -0
- package/dist/cjs/models.js +11 -0
- package/dist/cjs/models.js.map +1 -0
- package/dist/cjs/router.js +93 -0
- package/dist/cjs/router.js.map +1 -0
- package/dist/cjs/streaming.js +28 -0
- package/dist/cjs/streaming.js.map +1 -0
- package/dist/esm/adapters.js +15 -0
- package/dist/esm/adapters.js.map +1 -0
- package/dist/esm/bridge.js +29 -0
- package/dist/esm/bridge.js.map +1 -0
- package/dist/esm/errors.js +118 -0
- package/dist/esm/errors.js.map +1 -0
- package/dist/esm/index.js +28 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/ir.js +16 -0
- package/dist/esm/ir.js.map +1 -0
- package/dist/esm/middleware.js +10 -0
- package/dist/esm/middleware.js.map +1 -0
- package/dist/esm/model-runner.js +10 -0
- package/dist/esm/model-runner.js.map +1 -0
- package/dist/esm/model-translation.js +9 -0
- package/dist/esm/model-translation.js.map +1 -0
- package/dist/esm/models.js +10 -0
- package/dist/esm/models.js.map +1 -0
- package/dist/esm/router.js +90 -0
- package/dist/esm/router.js.map +1 -0
- package/dist/esm/streaming.js +25 -0
- package/dist/esm/streaming.js.map +1 -0
- package/dist/types/adapters.d.ts +377 -0
- package/dist/types/adapters.d.ts.map +1 -0
- package/dist/types/bridge.d.ts +290 -0
- package/dist/types/bridge.d.ts.map +1 -0
- package/dist/types/errors.d.ts +380 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/index.d.ts +18 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/ir.d.ts +820 -0
- package/dist/types/ir.d.ts.map +1 -0
- package/dist/types/middleware.d.ts +256 -0
- package/dist/types/middleware.d.ts.map +1 -0
- package/dist/types/model-runner.d.ts +344 -0
- package/dist/types/model-runner.d.ts.map +1 -0
- package/dist/types/model-translation.d.ts +76 -0
- package/dist/types/model-translation.d.ts.map +1 -0
- package/dist/types/models.d.ts +160 -0
- package/dist/types/models.d.ts.map +1 -0
- package/dist/types/router.d.ts +526 -0
- package/dist/types/router.d.ts.map +1 -0
- package/dist/types/streaming.d.ts +96 -0
- package/dist/types/streaming.d.ts.map +1 -0
- package/package.json +64 -0
- package/readme.md +84 -0
|
@@ -0,0 +1,820 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Intermediate Representation (IR) Types
|
|
3
|
+
*
|
|
4
|
+
* The IR is the universal format that sits between frontend and backend adapters.
|
|
5
|
+
* It represents chat requests, responses, and streams in a normalized, provider-agnostic way.
|
|
6
|
+
*
|
|
7
|
+
* Design principles:
|
|
8
|
+
* - Provider-agnostic: No provider-specific fields in core types
|
|
9
|
+
* - Extensible: Support for metadata and custom fields
|
|
10
|
+
* - Type-safe: Use discriminated unions for runtime type checking
|
|
11
|
+
* - Stream-friendly: First-class support for streaming responses
|
|
12
|
+
*
|
|
13
|
+
* @module
|
|
14
|
+
*/
|
|
15
|
+
import type { StreamMode } from './streaming.js';
|
|
16
|
+
/**
|
|
17
|
+
* Message role in a conversation.
|
|
18
|
+
*
|
|
19
|
+
* Maps to roles across all major providers:
|
|
20
|
+
* - system: Initial instructions/context (some providers use special parameter)
|
|
21
|
+
* - user: Messages from the user
|
|
22
|
+
* - assistant: Messages from the AI
|
|
23
|
+
* - tool: Results from tool/function calls
|
|
24
|
+
*/
|
|
25
|
+
export type MessageRole = 'system' | 'user' | 'assistant' | 'tool';
|
|
26
|
+
/**
|
|
27
|
+
* Text content block.
|
|
28
|
+
*/
|
|
29
|
+
export interface TextContent {
|
|
30
|
+
readonly type: 'text';
|
|
31
|
+
readonly text: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Image content block.
|
|
35
|
+
*
|
|
36
|
+
* Supports both URLs and base64-encoded images.
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```typescript
|
|
40
|
+
* // Image from URL
|
|
41
|
+
* const imageUrl: ImageContent = {
|
|
42
|
+
* type: 'image',
|
|
43
|
+
* source: {
|
|
44
|
+
* type: 'url',
|
|
45
|
+
* url: 'https://example.com/image.jpg'
|
|
46
|
+
* }
|
|
47
|
+
* };
|
|
48
|
+
*
|
|
49
|
+
* // Base64 image
|
|
50
|
+
* const imageBase64: ImageContent = {
|
|
51
|
+
* type: 'image',
|
|
52
|
+
* source: {
|
|
53
|
+
* type: 'base64',
|
|
54
|
+
* mediaType: 'image/jpeg',
|
|
55
|
+
* data: 'iVBORw0KGgo...'
|
|
56
|
+
* }
|
|
57
|
+
* };
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
export interface ImageContent {
|
|
61
|
+
readonly type: 'image';
|
|
62
|
+
readonly source: {
|
|
63
|
+
readonly type: 'url';
|
|
64
|
+
readonly url: string;
|
|
65
|
+
} | {
|
|
66
|
+
readonly type: 'base64';
|
|
67
|
+
readonly mediaType: string;
|
|
68
|
+
readonly data: string;
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Tool use request (AI wants to call a tool).
|
|
73
|
+
*/
|
|
74
|
+
export interface ToolUseContent {
|
|
75
|
+
readonly type: 'tool_use';
|
|
76
|
+
readonly id: string;
|
|
77
|
+
readonly name: string;
|
|
78
|
+
readonly input: Record<string, unknown>;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Tool result (response from tool execution).
|
|
82
|
+
*/
|
|
83
|
+
export interface ToolResultContent {
|
|
84
|
+
readonly type: 'tool_result';
|
|
85
|
+
readonly toolUseId: string;
|
|
86
|
+
readonly content: string | TextContent[];
|
|
87
|
+
readonly isError?: boolean;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Union of all content types.
|
|
91
|
+
*
|
|
92
|
+
* Uses discriminated union pattern for type-safe content handling.
|
|
93
|
+
*/
|
|
94
|
+
export type MessageContent = TextContent | ImageContent | ToolUseContent | ToolResultContent;
|
|
95
|
+
/**
|
|
96
|
+
* A message in the conversation.
|
|
97
|
+
*
|
|
98
|
+
* Messages can have either simple string content or structured content blocks.
|
|
99
|
+
* The IR normalizes both formats into a consistent representation.
|
|
100
|
+
*
|
|
101
|
+
* @example
|
|
102
|
+
* ```typescript
|
|
103
|
+
* // Simple text message
|
|
104
|
+
* const textMessage: IRMessage = {
|
|
105
|
+
* role: 'user',
|
|
106
|
+
* content: 'Hello, AI!'
|
|
107
|
+
* };
|
|
108
|
+
*
|
|
109
|
+
* // Multi-modal message with image
|
|
110
|
+
* const multiModalMessage: IRMessage = {
|
|
111
|
+
* role: 'user',
|
|
112
|
+
* content: [
|
|
113
|
+
* { type: 'text', text: 'What is in this image?' },
|
|
114
|
+
* {
|
|
115
|
+
* type: 'image',
|
|
116
|
+
* source: {
|
|
117
|
+
* type: 'url',
|
|
118
|
+
* url: 'https://example.com/photo.jpg'
|
|
119
|
+
* }
|
|
120
|
+
* }
|
|
121
|
+
* ]
|
|
122
|
+
* };
|
|
123
|
+
*
|
|
124
|
+
* // System message
|
|
125
|
+
* const systemMessage: IRMessage = {
|
|
126
|
+
* role: 'system',
|
|
127
|
+
* content: 'You are a helpful assistant.'
|
|
128
|
+
* };
|
|
129
|
+
* ```
|
|
130
|
+
*/
|
|
131
|
+
export interface IRMessage {
|
|
132
|
+
/**
|
|
133
|
+
* Message role (system, user, assistant, tool).
|
|
134
|
+
*/
|
|
135
|
+
readonly role: MessageRole;
|
|
136
|
+
/**
|
|
137
|
+
* Message content.
|
|
138
|
+
* Can be a simple string or array of content blocks.
|
|
139
|
+
*/
|
|
140
|
+
readonly content: string | readonly MessageContent[];
|
|
141
|
+
/**
|
|
142
|
+
* Optional message name/identifier.
|
|
143
|
+
* Used for tool messages or multi-user scenarios.
|
|
144
|
+
*/
|
|
145
|
+
readonly name?: string;
|
|
146
|
+
/**
|
|
147
|
+
* Provider-specific metadata.
|
|
148
|
+
* Stored but not processed by IR.
|
|
149
|
+
*/
|
|
150
|
+
readonly metadata?: Record<string, unknown>;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* JSON Schema type definitions.
|
|
154
|
+
*/
|
|
155
|
+
export type JSONSchemaType = 'string' | 'number' | 'integer' | 'boolean' | 'object' | 'array' | 'null';
|
|
156
|
+
/**
|
|
157
|
+
* JSON Schema for tool parameters.
|
|
158
|
+
*
|
|
159
|
+
* Simplified schema supporting common validation patterns.
|
|
160
|
+
*/
|
|
161
|
+
export interface JSONSchema {
|
|
162
|
+
readonly type?: JSONSchemaType | readonly JSONSchemaType[];
|
|
163
|
+
readonly description?: string;
|
|
164
|
+
readonly enum?: readonly unknown[];
|
|
165
|
+
readonly const?: unknown;
|
|
166
|
+
readonly properties?: Record<string, JSONSchema>;
|
|
167
|
+
readonly required?: readonly string[];
|
|
168
|
+
readonly items?: JSONSchema;
|
|
169
|
+
readonly additionalProperties?: boolean | JSONSchema;
|
|
170
|
+
readonly minimum?: number;
|
|
171
|
+
readonly maximum?: number;
|
|
172
|
+
readonly minLength?: number;
|
|
173
|
+
readonly maxLength?: number;
|
|
174
|
+
readonly pattern?: string;
|
|
175
|
+
readonly format?: string;
|
|
176
|
+
readonly default?: unknown;
|
|
177
|
+
readonly examples?: readonly unknown[];
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Tool/function definition.
|
|
181
|
+
*
|
|
182
|
+
* Describes a tool that the AI can call.
|
|
183
|
+
*
|
|
184
|
+
* @example
|
|
185
|
+
* ```typescript
|
|
186
|
+
* const weatherTool: IRTool = {
|
|
187
|
+
* name: 'get_weather',
|
|
188
|
+
* description: 'Get current weather for a location',
|
|
189
|
+
* parameters: {
|
|
190
|
+
* type: 'object',
|
|
191
|
+
* properties: {
|
|
192
|
+
* location: {
|
|
193
|
+
* type: 'string',
|
|
194
|
+
* description: 'City name or coordinates'
|
|
195
|
+
* },
|
|
196
|
+
* units: {
|
|
197
|
+
* type: 'string',
|
|
198
|
+
* enum: ['celsius', 'fahrenheit'],
|
|
199
|
+
* default: 'celsius'
|
|
200
|
+
* }
|
|
201
|
+
* },
|
|
202
|
+
* required: ['location']
|
|
203
|
+
* }
|
|
204
|
+
* };
|
|
205
|
+
* ```
|
|
206
|
+
*/
|
|
207
|
+
export interface IRTool {
|
|
208
|
+
/**
|
|
209
|
+
* Tool name (must be valid identifier).
|
|
210
|
+
*/
|
|
211
|
+
readonly name: string;
|
|
212
|
+
/**
|
|
213
|
+
* Human-readable description of what the tool does.
|
|
214
|
+
*/
|
|
215
|
+
readonly description: string;
|
|
216
|
+
/**
|
|
217
|
+
* JSON Schema for tool parameters.
|
|
218
|
+
*/
|
|
219
|
+
readonly parameters: JSONSchema;
|
|
220
|
+
/**
|
|
221
|
+
* Provider-specific tool configuration.
|
|
222
|
+
*/
|
|
223
|
+
readonly metadata?: Record<string, unknown>;
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Normalized request parameters.
|
|
227
|
+
*
|
|
228
|
+
* Common parameters across all providers, normalized to consistent ranges.
|
|
229
|
+
* Provider-specific parameters can be added to `custom` field.
|
|
230
|
+
*
|
|
231
|
+
* @example
|
|
232
|
+
* ```typescript
|
|
233
|
+
* const params: IRParameters = {
|
|
234
|
+
* model: 'gpt-4',
|
|
235
|
+
* temperature: 0.7,
|
|
236
|
+
* maxTokens: 1000,
|
|
237
|
+
* topP: 0.9,
|
|
238
|
+
* frequencyPenalty: 0.0,
|
|
239
|
+
* presencePenalty: 0.0,
|
|
240
|
+
* stopSequences: ['\n\n', 'END']
|
|
241
|
+
* };
|
|
242
|
+
* ```
|
|
243
|
+
*/
|
|
244
|
+
export interface IRParameters {
|
|
245
|
+
/**
|
|
246
|
+
* Model identifier.
|
|
247
|
+
* Provider-specific model name.
|
|
248
|
+
*/
|
|
249
|
+
readonly model?: string;
|
|
250
|
+
/**
|
|
251
|
+
* Sampling temperature (0.0 to 2.0).
|
|
252
|
+
* Higher values make output more random.
|
|
253
|
+
* @default 0.7
|
|
254
|
+
*/
|
|
255
|
+
readonly temperature?: number;
|
|
256
|
+
/**
|
|
257
|
+
* Maximum tokens to generate.
|
|
258
|
+
* Actual limit depends on model and provider.
|
|
259
|
+
*/
|
|
260
|
+
readonly maxTokens?: number;
|
|
261
|
+
/**
|
|
262
|
+
* Nucleus sampling threshold (0.0 to 1.0).
|
|
263
|
+
* Alternative to temperature.
|
|
264
|
+
*/
|
|
265
|
+
readonly topP?: number;
|
|
266
|
+
/**
|
|
267
|
+
* Top-K sampling limit.
|
|
268
|
+
* Only consider top K tokens.
|
|
269
|
+
*/
|
|
270
|
+
readonly topK?: number;
|
|
271
|
+
/**
|
|
272
|
+
* Frequency penalty (-2.0 to 2.0).
|
|
273
|
+
* Penalize tokens based on frequency in text so far.
|
|
274
|
+
*/
|
|
275
|
+
readonly frequencyPenalty?: number;
|
|
276
|
+
/**
|
|
277
|
+
* Presence penalty (-2.0 to 2.0).
|
|
278
|
+
* Penalize tokens based on whether they appear in text so far.
|
|
279
|
+
*/
|
|
280
|
+
readonly presencePenalty?: number;
|
|
281
|
+
/**
|
|
282
|
+
* Stop sequences.
|
|
283
|
+
* Generation stops when any sequence is encountered.
|
|
284
|
+
*/
|
|
285
|
+
readonly stopSequences?: readonly string[];
|
|
286
|
+
/**
|
|
287
|
+
* Random seed for deterministic generation.
|
|
288
|
+
*/
|
|
289
|
+
readonly seed?: number;
|
|
290
|
+
/**
|
|
291
|
+
* User identifier for abuse monitoring.
|
|
292
|
+
*/
|
|
293
|
+
readonly user?: string;
|
|
294
|
+
/**
|
|
295
|
+
* Provider-specific parameters.
|
|
296
|
+
* Passed through to backend without modification.
|
|
297
|
+
*/
|
|
298
|
+
readonly custom?: Record<string, unknown>;
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* System message handling strategy.
|
|
302
|
+
*/
|
|
303
|
+
export type SystemMessageStrategy = 'separate-parameter' | 'in-messages' | 'prepend-user' | 'not-supported';
|
|
304
|
+
/**
|
|
305
|
+
* Adapter capabilities metadata.
|
|
306
|
+
*
|
|
307
|
+
* Describes what an adapter supports for routing and validation.
|
|
308
|
+
*
|
|
309
|
+
* @example
|
|
310
|
+
* ```typescript
|
|
311
|
+
* const openaiCapabilities: IRCapabilities = {
|
|
312
|
+
* streaming: true,
|
|
313
|
+
* multiModal: true,
|
|
314
|
+
* tools: true,
|
|
315
|
+
* maxContextTokens: 128000,
|
|
316
|
+
* supportedModels: ['gpt-4', 'gpt-4-turbo', 'gpt-3.5-turbo'],
|
|
317
|
+
* systemMessageStrategy: 'in-messages',
|
|
318
|
+
* supportsMultipleSystemMessages: true,
|
|
319
|
+
* supportsTemperature: true,
|
|
320
|
+
* supportsTopP: true,
|
|
321
|
+
* supportsTopK: false,
|
|
322
|
+
* supportsSeed: true
|
|
323
|
+
* };
|
|
324
|
+
* ```
|
|
325
|
+
*/
|
|
326
|
+
export interface IRCapabilities {
|
|
327
|
+
/**
|
|
328
|
+
* Supports streaming responses.
|
|
329
|
+
*/
|
|
330
|
+
readonly streaming: boolean;
|
|
331
|
+
/**
|
|
332
|
+
* Supports multi-modal content (images, etc.).
|
|
333
|
+
*/
|
|
334
|
+
readonly multiModal: boolean;
|
|
335
|
+
/**
|
|
336
|
+
* Supports tool/function calling.
|
|
337
|
+
*/
|
|
338
|
+
readonly tools?: boolean;
|
|
339
|
+
/**
|
|
340
|
+
* Maximum context window size (tokens).
|
|
341
|
+
*/
|
|
342
|
+
readonly maxContextTokens?: number;
|
|
343
|
+
/**
|
|
344
|
+
* List of supported model identifiers.
|
|
345
|
+
*/
|
|
346
|
+
readonly supportedModels?: readonly string[];
|
|
347
|
+
/**
|
|
348
|
+
* How system messages are handled.
|
|
349
|
+
*/
|
|
350
|
+
readonly systemMessageStrategy: SystemMessageStrategy;
|
|
351
|
+
/**
|
|
352
|
+
* Supports multiple system messages.
|
|
353
|
+
*/
|
|
354
|
+
readonly supportsMultipleSystemMessages: boolean;
|
|
355
|
+
/**
|
|
356
|
+
* Supports temperature parameter.
|
|
357
|
+
*/
|
|
358
|
+
readonly supportsTemperature?: boolean;
|
|
359
|
+
/**
|
|
360
|
+
* Supports topP parameter.
|
|
361
|
+
*/
|
|
362
|
+
readonly supportsTopP?: boolean;
|
|
363
|
+
/**
|
|
364
|
+
* Supports topK parameter.
|
|
365
|
+
*/
|
|
366
|
+
readonly supportsTopK?: boolean;
|
|
367
|
+
/**
|
|
368
|
+
* Supports seed parameter.
|
|
369
|
+
*/
|
|
370
|
+
readonly supportsSeed?: boolean;
|
|
371
|
+
/**
|
|
372
|
+
* Supports frequency penalty.
|
|
373
|
+
*/
|
|
374
|
+
readonly supportsFrequencyPenalty?: boolean;
|
|
375
|
+
/**
|
|
376
|
+
* Supports presence penalty.
|
|
377
|
+
*/
|
|
378
|
+
readonly supportsPresencePenalty?: boolean;
|
|
379
|
+
/**
|
|
380
|
+
* Maximum number of stop sequences.
|
|
381
|
+
*/
|
|
382
|
+
readonly maxStopSequences?: number;
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* Warning severity levels.
|
|
386
|
+
*/
|
|
387
|
+
export type WarningSeverity = 'info' | 'warning' | 'error';
|
|
388
|
+
/**
|
|
389
|
+
* Warning categories for semantic drift and compatibility issues.
|
|
390
|
+
*/
|
|
391
|
+
export type WarningCategory = 'parameter-normalized' | 'parameter-clamped' | 'parameter-unsupported' | 'capability-unsupported' | 'token-limit-exceeded' | 'stop-sequences-truncated' | 'system-message-transformed' | 'content-type-unsupported' | 'tool-unsupported' | 'model-substituted';
|
|
392
|
+
/**
|
|
393
|
+
* Semantic drift warning.
|
|
394
|
+
*
|
|
395
|
+
* Documents transformations and compatibility issues that occur
|
|
396
|
+
* when converting between provider formats.
|
|
397
|
+
*
|
|
398
|
+
* @example
|
|
399
|
+
* ```typescript
|
|
400
|
+
* const warning: IRWarning = {
|
|
401
|
+
* category: 'parameter-normalized',
|
|
402
|
+
* severity: 'info',
|
|
403
|
+
* message: 'Temperature normalized from 0-2 range to 0-1 range',
|
|
404
|
+
* field: 'temperature',
|
|
405
|
+
* originalValue: 1.5,
|
|
406
|
+
* transformedValue: 0.75,
|
|
407
|
+
* source: 'openai-backend'
|
|
408
|
+
* };
|
|
409
|
+
* ```
|
|
410
|
+
*/
|
|
411
|
+
export interface IRWarning {
|
|
412
|
+
/**
|
|
413
|
+
* Warning category.
|
|
414
|
+
*/
|
|
415
|
+
readonly category: WarningCategory;
|
|
416
|
+
/**
|
|
417
|
+
* Severity level.
|
|
418
|
+
*/
|
|
419
|
+
readonly severity: WarningSeverity;
|
|
420
|
+
/**
|
|
421
|
+
* Human-readable warning message.
|
|
422
|
+
*/
|
|
423
|
+
readonly message: string;
|
|
424
|
+
/**
|
|
425
|
+
* Field or parameter that caused the warning.
|
|
426
|
+
*/
|
|
427
|
+
readonly field?: string;
|
|
428
|
+
/**
|
|
429
|
+
* Original value before transformation.
|
|
430
|
+
*/
|
|
431
|
+
readonly originalValue?: unknown;
|
|
432
|
+
/**
|
|
433
|
+
* Transformed value after normalization.
|
|
434
|
+
*/
|
|
435
|
+
readonly transformedValue?: unknown;
|
|
436
|
+
/**
|
|
437
|
+
* Source adapter that generated the warning.
|
|
438
|
+
*/
|
|
439
|
+
readonly source?: string;
|
|
440
|
+
/**
|
|
441
|
+
* Additional context or details.
|
|
442
|
+
*/
|
|
443
|
+
readonly details?: Record<string, unknown>;
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* Provenance tracking for request/response chain.
|
|
447
|
+
*/
|
|
448
|
+
export interface IRProvenance {
|
|
449
|
+
/**
|
|
450
|
+
* Frontend adapter name.
|
|
451
|
+
*/
|
|
452
|
+
readonly frontend?: string;
|
|
453
|
+
/**
|
|
454
|
+
* Backend adapter name.
|
|
455
|
+
*/
|
|
456
|
+
readonly backend?: string;
|
|
457
|
+
/**
|
|
458
|
+
* Middleware chain (in order of execution).
|
|
459
|
+
*/
|
|
460
|
+
readonly middleware?: readonly string[];
|
|
461
|
+
/**
|
|
462
|
+
* Router name (if applicable).
|
|
463
|
+
*/
|
|
464
|
+
readonly router?: string;
|
|
465
|
+
}
|
|
466
|
+
/**
|
|
467
|
+
* Request/response metadata.
|
|
468
|
+
*
|
|
469
|
+
* Tracks provenance, timing, warnings, and custom metadata throughout the adapter chain.
|
|
470
|
+
*
|
|
471
|
+
* @example
|
|
472
|
+
* ```typescript
|
|
473
|
+
* const metadata: IRMetadata = {
|
|
474
|
+
* requestId: 'req_abc123',
|
|
475
|
+
* timestamp: Date.now(),
|
|
476
|
+
* provenance: {
|
|
477
|
+
* frontend: 'anthropic',
|
|
478
|
+
* backend: 'openai',
|
|
479
|
+
* middleware: ['logging', 'caching']
|
|
480
|
+
* },
|
|
481
|
+
* warnings: [
|
|
482
|
+
* {
|
|
483
|
+
* category: 'parameter-normalized',
|
|
484
|
+
* severity: 'info',
|
|
485
|
+
* message: 'Temperature scaled from 0-2 to 0-1 range',
|
|
486
|
+
* field: 'temperature'
|
|
487
|
+
* }
|
|
488
|
+
* ],
|
|
489
|
+
* custom: {
|
|
490
|
+
* userId: 'user_123',
|
|
491
|
+
* sessionId: 'session_456'
|
|
492
|
+
* }
|
|
493
|
+
* };
|
|
494
|
+
* ```
|
|
495
|
+
*/
|
|
496
|
+
export interface IRMetadata {
|
|
497
|
+
/**
|
|
498
|
+
* Unique request identifier.
|
|
499
|
+
* Generated by the client (frontend adapter or Bridge).
|
|
500
|
+
* Stable across retries and fallbacks for correlation.
|
|
501
|
+
*/
|
|
502
|
+
readonly requestId: string;
|
|
503
|
+
/**
|
|
504
|
+
* Provider's response identifier.
|
|
505
|
+
* Set by backend adapter from the provider's actual response ID.
|
|
506
|
+
* Examples: OpenAI's "chatcmpl-xxx", Anthropic's "msg_xxx".
|
|
507
|
+
* Useful for correlating with provider logs and billing.
|
|
508
|
+
*/
|
|
509
|
+
readonly providerResponseId?: string;
|
|
510
|
+
/**
|
|
511
|
+
* Request timestamp (milliseconds since epoch).
|
|
512
|
+
*/
|
|
513
|
+
readonly timestamp: number;
|
|
514
|
+
/**
|
|
515
|
+
* Adapter chain provenance.
|
|
516
|
+
*/
|
|
517
|
+
readonly provenance?: IRProvenance;
|
|
518
|
+
/**
|
|
519
|
+
* Semantic drift warnings collected during processing.
|
|
520
|
+
* Documents any transformations or compatibility issues.
|
|
521
|
+
*/
|
|
522
|
+
readonly warnings?: readonly IRWarning[];
|
|
523
|
+
/**
|
|
524
|
+
* Custom metadata fields.
|
|
525
|
+
* Can be used by middleware or application code.
|
|
526
|
+
*/
|
|
527
|
+
readonly custom?: Record<string, unknown>;
|
|
528
|
+
}
|
|
529
|
+
/**
|
|
530
|
+
* Universal chat completion request.
|
|
531
|
+
*
|
|
532
|
+
* This is the normalized format that all frontend adapters convert to
|
|
533
|
+
* and all backend adapters consume.
|
|
534
|
+
*
|
|
535
|
+
* @example
|
|
536
|
+
* ```typescript
|
|
537
|
+
* const request: IRChatRequest = {
|
|
538
|
+
* messages: [
|
|
539
|
+
* { role: 'system', content: 'You are helpful.' },
|
|
540
|
+
* { role: 'user', content: 'Hello!' }
|
|
541
|
+
* ],
|
|
542
|
+
* parameters: {
|
|
543
|
+
* model: 'gpt-4',
|
|
544
|
+
* temperature: 0.7,
|
|
545
|
+
* maxTokens: 1000
|
|
546
|
+
* },
|
|
547
|
+
* metadata: {
|
|
548
|
+
* requestId: 'req_abc123',
|
|
549
|
+
* timestamp: Date.now(),
|
|
550
|
+
* provenance: {
|
|
551
|
+
* frontend: 'openai'
|
|
552
|
+
* }
|
|
553
|
+
* },
|
|
554
|
+
* stream: false
|
|
555
|
+
* };
|
|
556
|
+
* ```
|
|
557
|
+
*/
|
|
558
|
+
export interface IRChatRequest {
|
|
559
|
+
/**
|
|
560
|
+
* Conversation messages.
|
|
561
|
+
* Must contain at least one message.
|
|
562
|
+
*/
|
|
563
|
+
readonly messages: readonly IRMessage[];
|
|
564
|
+
/**
|
|
565
|
+
* Tool/function definitions.
|
|
566
|
+
* Optional, for function calling.
|
|
567
|
+
*/
|
|
568
|
+
readonly tools?: readonly IRTool[];
|
|
569
|
+
/**
|
|
570
|
+
* Tool choice strategy.
|
|
571
|
+
* - 'auto': Model decides whether to call tools
|
|
572
|
+
* - 'required': Model must call a tool
|
|
573
|
+
* - 'none': Model cannot call tools
|
|
574
|
+
* - { name: string }: Force specific tool
|
|
575
|
+
*/
|
|
576
|
+
readonly toolChoice?: 'auto' | 'required' | 'none' | {
|
|
577
|
+
readonly name: string;
|
|
578
|
+
};
|
|
579
|
+
/**
|
|
580
|
+
* Request parameters.
|
|
581
|
+
*/
|
|
582
|
+
readonly parameters?: IRParameters;
|
|
583
|
+
/**
|
|
584
|
+
* Request metadata.
|
|
585
|
+
*/
|
|
586
|
+
readonly metadata: IRMetadata;
|
|
587
|
+
/**
|
|
588
|
+
* Whether to stream the response.
|
|
589
|
+
* @default false
|
|
590
|
+
*/
|
|
591
|
+
readonly stream?: boolean;
|
|
592
|
+
/**
|
|
593
|
+
* Preferred streaming mode (hint to backend).
|
|
594
|
+
*
|
|
595
|
+
* - `delta`: Request incremental chunks only (most efficient)
|
|
596
|
+
* - `accumulated`: Request full accumulated text in each chunk
|
|
597
|
+
*
|
|
598
|
+
* This is a preference hint - backends may choose to:
|
|
599
|
+
* - Provide only delta (always safe, universal)
|
|
600
|
+
* - Provide both delta and accumulated (maximum flexibility)
|
|
601
|
+
* - Provide only accumulated (if that's native format)
|
|
602
|
+
*
|
|
603
|
+
* Frontends and wrappers can convert between modes as needed.
|
|
604
|
+
*
|
|
605
|
+
* @default 'delta'
|
|
606
|
+
*/
|
|
607
|
+
readonly streamMode?: StreamMode;
|
|
608
|
+
}
|
|
609
|
+
/**
|
|
610
|
+
* Finish reason for generation.
|
|
611
|
+
*/
|
|
612
|
+
export type FinishReason = 'stop' | 'length' | 'tool_calls' | 'content_filter' | 'error' | 'cancelled';
|
|
613
|
+
/**
|
|
614
|
+
* Token usage statistics.
|
|
615
|
+
*/
|
|
616
|
+
export interface IRUsage {
|
|
617
|
+
/**
|
|
618
|
+
* Tokens in the prompt.
|
|
619
|
+
*/
|
|
620
|
+
readonly promptTokens: number;
|
|
621
|
+
/**
|
|
622
|
+
* Tokens in the completion.
|
|
623
|
+
*/
|
|
624
|
+
readonly completionTokens: number;
|
|
625
|
+
/**
|
|
626
|
+
* Total tokens (prompt + completion).
|
|
627
|
+
*/
|
|
628
|
+
readonly totalTokens: number;
|
|
629
|
+
/**
|
|
630
|
+
* Provider-specific usage details.
|
|
631
|
+
*/
|
|
632
|
+
readonly details?: Record<string, unknown>;
|
|
633
|
+
}
|
|
634
|
+
/**
|
|
635
|
+
* Universal chat completion response.
|
|
636
|
+
*
|
|
637
|
+
* Normalized format that all backend adapters convert to
|
|
638
|
+
* and all frontend adapters consume.
|
|
639
|
+
*
|
|
640
|
+
* @example
|
|
641
|
+
* ```typescript
|
|
642
|
+
* const response: IRChatResponse = {
|
|
643
|
+
* message: {
|
|
644
|
+
* role: 'assistant',
|
|
645
|
+
* content: 'Hello! How can I help you today?'
|
|
646
|
+
* },
|
|
647
|
+
* finishReason: 'stop',
|
|
648
|
+
* usage: {
|
|
649
|
+
* promptTokens: 15,
|
|
650
|
+
* completionTokens: 10,
|
|
651
|
+
* totalTokens: 25
|
|
652
|
+
* },
|
|
653
|
+
* metadata: {
|
|
654
|
+
* requestId: 'req_abc123',
|
|
655
|
+
* timestamp: Date.now(),
|
|
656
|
+
* provenance: {
|
|
657
|
+
* frontend: 'openai',
|
|
658
|
+
* backend: 'openai'
|
|
659
|
+
* }
|
|
660
|
+
* }
|
|
661
|
+
* };
|
|
662
|
+
* ```
|
|
663
|
+
*/
|
|
664
|
+
export interface IRChatResponse {
|
|
665
|
+
/**
|
|
666
|
+
* Generated message from the assistant.
|
|
667
|
+
*/
|
|
668
|
+
readonly message: IRMessage;
|
|
669
|
+
/**
|
|
670
|
+
* Why generation finished.
|
|
671
|
+
*/
|
|
672
|
+
readonly finishReason: FinishReason;
|
|
673
|
+
/**
|
|
674
|
+
* Token usage statistics.
|
|
675
|
+
*/
|
|
676
|
+
readonly usage?: IRUsage;
|
|
677
|
+
/**
|
|
678
|
+
* Response metadata.
|
|
679
|
+
* Includes original request metadata plus backend provenance.
|
|
680
|
+
*/
|
|
681
|
+
readonly metadata: IRMetadata;
|
|
682
|
+
/**
|
|
683
|
+
* Provider-specific response data.
|
|
684
|
+
*/
|
|
685
|
+
readonly raw?: Record<string, unknown>;
|
|
686
|
+
}
|
|
687
|
+
/**
|
|
688
|
+
* Stream chunk types.
|
|
689
|
+
*/
|
|
690
|
+
export type StreamChunkType = 'start' | 'content' | 'tool_use' | 'metadata' | 'done' | 'error';
|
|
691
|
+
/**
|
|
692
|
+
* Base stream chunk interface.
|
|
693
|
+
*/
|
|
694
|
+
export interface BaseStreamChunk {
|
|
695
|
+
readonly type: StreamChunkType;
|
|
696
|
+
readonly sequence: number;
|
|
697
|
+
}
|
|
698
|
+
/**
|
|
699
|
+
* Start of stream chunk.
|
|
700
|
+
*/
|
|
701
|
+
export interface StreamStartChunk extends BaseStreamChunk {
|
|
702
|
+
readonly type: 'start';
|
|
703
|
+
readonly metadata: IRMetadata;
|
|
704
|
+
}
|
|
705
|
+
/**
|
|
706
|
+
* Content chunk with flexible streaming support.
|
|
707
|
+
*
|
|
708
|
+
* Supports both delta (incremental) and accumulated (full text) streaming modes:
|
|
709
|
+
*
|
|
710
|
+
* **Delta Mode (default):**
|
|
711
|
+
* - `delta` contains only the new text generated in this chunk
|
|
712
|
+
* - Consumers must accumulate deltas to get full text
|
|
713
|
+
* - Most efficient for network and memory
|
|
714
|
+
*
|
|
715
|
+
* **Accumulated Mode (optional):**
|
|
716
|
+
* - `accumulated` contains all text generated so far
|
|
717
|
+
* - Each chunk has the complete text up to that point
|
|
718
|
+
* - Useful for UIs that want to replace text (Chrome AI style)
|
|
719
|
+
*
|
|
720
|
+
* **Backward Compatibility:**
|
|
721
|
+
* - `delta` is ALWAYS present (universal standard)
|
|
722
|
+
* - `accumulated` is optional (provided when backend configured for it)
|
|
723
|
+
*
|
|
724
|
+
* @example
|
|
725
|
+
* ```typescript
|
|
726
|
+
* // Delta-only chunk (standard)
|
|
727
|
+
* { type: 'content', delta: ' world', sequence: 2 }
|
|
728
|
+
*
|
|
729
|
+
* // With both formats (configured backend)
|
|
730
|
+
* { type: 'content', delta: ' world', accumulated: 'Hello world', sequence: 2 }
|
|
731
|
+
* ```
|
|
732
|
+
*/
|
|
733
|
+
export interface StreamContentChunk extends BaseStreamChunk {
|
|
734
|
+
readonly type: 'content';
|
|
735
|
+
/**
|
|
736
|
+
* Incremental text delta (new content only).
|
|
737
|
+
* ALWAYS present for maximum compatibility.
|
|
738
|
+
* Contains only the text generated in this chunk.
|
|
739
|
+
*/
|
|
740
|
+
readonly delta: string;
|
|
741
|
+
/**
|
|
742
|
+
* Accumulated text (full content so far).
|
|
743
|
+
* Optional - provided when backend is configured for accumulated mode.
|
|
744
|
+
* Contains all text generated from the start up to and including this chunk.
|
|
745
|
+
*/
|
|
746
|
+
readonly accumulated?: string;
|
|
747
|
+
readonly role?: 'assistant';
|
|
748
|
+
}
|
|
749
|
+
/**
|
|
750
|
+
* Tool use chunk.
|
|
751
|
+
*/
|
|
752
|
+
export interface StreamToolUseChunk extends BaseStreamChunk {
|
|
753
|
+
readonly type: 'tool_use';
|
|
754
|
+
readonly id: string;
|
|
755
|
+
readonly name: string;
|
|
756
|
+
readonly inputDelta?: string;
|
|
757
|
+
}
|
|
758
|
+
/**
|
|
759
|
+
* Metadata chunk (usage, etc.).
|
|
760
|
+
*/
|
|
761
|
+
export interface StreamMetadataChunk extends BaseStreamChunk {
|
|
762
|
+
readonly type: 'metadata';
|
|
763
|
+
readonly usage?: Partial<IRUsage>;
|
|
764
|
+
readonly metadata?: Partial<IRMetadata>;
|
|
765
|
+
}
|
|
766
|
+
/**
|
|
767
|
+
* Done chunk (end of stream).
|
|
768
|
+
*/
|
|
769
|
+
export interface StreamDoneChunk extends BaseStreamChunk {
|
|
770
|
+
readonly type: 'done';
|
|
771
|
+
readonly finishReason: FinishReason;
|
|
772
|
+
readonly usage?: IRUsage;
|
|
773
|
+
readonly message?: IRMessage;
|
|
774
|
+
}
|
|
775
|
+
/**
|
|
776
|
+
* Error chunk.
|
|
777
|
+
*/
|
|
778
|
+
export interface StreamErrorChunk extends BaseStreamChunk {
|
|
779
|
+
readonly type: 'error';
|
|
780
|
+
readonly error: {
|
|
781
|
+
readonly code: string;
|
|
782
|
+
readonly message: string;
|
|
783
|
+
readonly details?: Record<string, unknown>;
|
|
784
|
+
};
|
|
785
|
+
}
|
|
786
|
+
/**
|
|
787
|
+
* Union of all stream chunk types.
|
|
788
|
+
*
|
|
789
|
+
* Uses discriminated union for type-safe chunk handling.
|
|
790
|
+
*/
|
|
791
|
+
export type IRStreamChunk = StreamStartChunk | StreamContentChunk | StreamToolUseChunk | StreamMetadataChunk | StreamDoneChunk | StreamErrorChunk;
|
|
792
|
+
/**
|
|
793
|
+
* Async generator for streaming responses.
|
|
794
|
+
*
|
|
795
|
+
* Yields IR stream chunks as they arrive from the backend.
|
|
796
|
+
*
|
|
797
|
+
* @example
|
|
798
|
+
* ```typescript
|
|
799
|
+
* async function processStream(stream: IRChatStream) {
|
|
800
|
+
* for await (const chunk of stream) {
|
|
801
|
+
* switch (chunk.type) {
|
|
802
|
+
* case 'start':
|
|
803
|
+
* console.log('Stream started:', chunk.metadata.requestId);
|
|
804
|
+
* break;
|
|
805
|
+
* case 'content':
|
|
806
|
+
* process.stdout.write(chunk.delta);
|
|
807
|
+
* break;
|
|
808
|
+
* case 'done':
|
|
809
|
+
* console.log('\nStream finished:', chunk.finishReason);
|
|
810
|
+
* break;
|
|
811
|
+
* case 'error':
|
|
812
|
+
* console.error('Stream error:', chunk.error.message);
|
|
813
|
+
* break;
|
|
814
|
+
* }
|
|
815
|
+
* }
|
|
816
|
+
* }
|
|
817
|
+
* ```
|
|
818
|
+
*/
|
|
819
|
+
export type IRChatStream = AsyncGenerator<IRStreamChunk, void, undefined>;
|
|
820
|
+
//# sourceMappingURL=ir.d.ts.map
|