@aeye/openai 0.3.10 → 0.7.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/aeye-openai.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # @aeye/openai
2
2
 
3
- One-line purpose: OpenAI provider for the `@aeye/ai` framework — chat, vision, reasoning, tools, structured output, image generation/edit, transcription, speech, and embeddings via the official `openai` SDK. Also the base class for any OpenAI-compatible provider.
3
+ One-line purpose: OpenAI provider for the `@aeye/ai` framework — chat (Chat Completions or the Responses API), vision, reasoning, tools, hosted tools, structured output, audio output, image generation/edit, transcription, speech, and embeddings via the official `openai` SDK. Also the base class for any OpenAI-compatible provider.
4
4
 
5
5
  ## When to use
6
6
 
7
- - You want to call OpenAI (GPT-4o, GPT-4, o-series, DALL-E, gpt-image, Whisper, TTS, text-embedding-3-*) through `@aeye/ai`.
7
+ - You want to call OpenAI (GPT-5.x, GPT-6, GPT-4.1, gpt-audio, GPT Image, gpt-transcribe, TTS, text-embedding-3-*) through `@aeye/ai`.
8
8
  - You need a base class to build an OpenAI-compatible provider (Azure OpenAI, OpenRouter, local OpenAI-shaped endpoints). `@aeye/openrouter` is built this way.
9
9
 
10
10
  ## Install / import
@@ -28,7 +28,7 @@ import {
28
28
  } from '@aeye/openai';
29
29
  ```
30
30
 
31
- `@aeye/ai` and `@aeye/core` are peer/runtime dependencies (they ship as `dependencies`). The `openai` SDK and `zod` are also dependencies.
31
+ `@aeye/ai` and `@aeye/core` are peer/runtime dependencies (they ship as `dependencies`). The `openai` SDK (v7) and `zod` are also dependencies. Requires Node >= 22.
32
32
 
33
33
  ## Register with an `@aeye/ai` instance
34
34
 
@@ -55,7 +55,7 @@ console.log(response.content);
55
55
  // Explicit model selection is done via metadata, not the provider
56
56
  const r2 = await ai.chat.get(
57
57
  { messages: [{ role: 'user', content: 'Hi' }] },
58
- { metadata: { model: 'openai/gpt-4o' } }
58
+ { metadata: { model: 'openai/gpt-5.4-mini' } }
59
59
  );
60
60
  ```
61
61
 
@@ -66,7 +66,7 @@ const executor = openai.createExecutor();
66
66
  const res = await executor(
67
67
  { messages: [{ role: 'user', content: 'Hello!' }] },
68
68
  {}, // AIContext
69
- { model: 'gpt-4o' } // AIMetadata
69
+ { model: 'gpt-5.4-mini' } // AIMetadata
70
70
  );
71
71
  ```
72
72
 
@@ -85,37 +85,46 @@ const res = await executor(
85
85
  | `organization` | `string` | Org ID |
86
86
  | `project` | `string` | Project ID |
87
87
  | `store` | `boolean` | Allow OpenAI to store call contents. Defaults to `false` |
88
+ | `api` | `'auto' \| 'chat' \| 'responses'` | Which API chat uses. `auto` (default) picks Responses for Responses-only models (registry `metadata.responsesOnly`, else by id: codex, pre-5.6 pro, deep-research, computer-use), `hostedTools`, a tool with `format`/`defer`/`async`, `reason.mode`/`summary`/`context`, or tools with a reasoning `effort` other than `none` |
88
89
  | `retry` | `RetryConfig` | Per-provider retry (maxRetries, initialDelay, retryableStatuses, etc.) |
89
90
  | `retryEvents` | `RetryEvents` | Retry lifecycle callbacks (e.g. `onRetry`) |
90
91
  | `hooks` | `OpenAIHooks` | Per-operation `beforeRequest` / `afterRequest` / `onError` |
91
- | `defaultModels` | object | Fallback model per capability: `chat`, `imageGenerate`, `imageEdit`, `imageAnalyze`, `transcription`, `speech`, `embedding` |
92
+ | `defaultModels` | object | Fallback model per capability: `chat`, `imageGenerate`, `imageEdit`, `imageAnalyze`, `transcription`, `speech`, `embedding`. Built-in defaults (the protected `defaults` property, overridable by subclasses): `gpt-image-2`, `gpt-5.4-mini` (image analysis), `gpt-transcribe`, `gpt-4o-mini-tts`, `text-embedding-3-small`; no chat default |
92
93
 
93
94
  Retry config can also be overridden per request via `request.extra.retry` / `request.extra.retryEvents`.
94
95
 
95
96
  ### Hooks
96
97
 
97
- `OpenAIHooks` has a block per operation: `chat`, `imageGenerate`, `imageEdit`, `imageAnalyze`, `transcribe`, `speech`, `embed`. Each block may define `beforeRequest(request, params, ctx, metadata)`, `afterRequest(request, params, response, ctx, metadata)`, and `onError(request, params, error, ctx, metadata)`. The `params` argument is the raw OpenAI SDK params, so you can inspect/mutate the exact wire payload.
98
+ `OpenAIHooks` has a block per operation in `OpenAIOperations`: `chat`, `responses`, `imageGenerate`, `imageEdit`, `transcribe`, `speech`, `embed`, `rerank` (used by subclasses such as OpenRouter), `decide`. Image analysis runs as chat and reports through the `chat` (or `responses`) hooks. Each block may define `beforeRequest(request, params, ctx, metadata)`, `afterRequest(request, params, response, ctx, metadata)`, and `onError(request, params, error, ctx, metadata)`. The `params` argument is the raw OpenAI SDK params, so you can inspect/mutate the exact wire payload.
98
99
 
99
100
  ## Supported capabilities
100
101
 
101
102
  | Capability | API surface | Models |
102
103
  |-----------|-------------|--------|
103
- | Chat (+ streaming) | `ai.chat.get` / `ai.chat.stream` | GPT-4o, GPT-4, GPT-3.5, o-series |
104
- | Vision | `ai.chat` with `image` content | GPT-4o / GPT-4V |
105
- | Reasoning | `ai.chat` with `request.reason.effort` → `reasoning_effort` | o1, o3-mini, etc. |
106
- | Tools / function calling | `ai.chat` with `tools` | GPT-4o, GPT-4 |
107
- | Structured output | `ai.chat` with a schema `responseFormat` | GPT-4o (strict json_schema) |
108
- | Image generation | `ai.image.generate` | `dall-e-2`, `dall-e-3`, `gpt-image-*` |
109
- | Image edit | `ai.image.edit` | `dall-e-2`, `gpt-image-*` |
110
- | Transcription (+ stream) | `ai.transcribe` | `whisper-1`, gpt-4o transcribe |
111
- | Speech / TTS | `ai.speech` | `tts-1`, `tts-1-hd`, gpt-4o-mini-tts |
104
+ | Chat (+ streaming) | `ai.chat.get` / `ai.chat.stream` | GPT-5.x, GPT-6, GPT-4.1, o3 |
105
+ | Vision / files | `ai.chat` with `image` / `file` content (`detail`, `name`) | GPT-5.x, GPT-6, GPT-4.1 |
106
+ | Reasoning | `ai.chat` with `request.reason` — `effort` (`none`..`max`, clamped to the model's `reasoningEfforts`) → `reasoning_effort`; `summary`/`mode`/`context` use Responses | GPT-5.x, GPT-6, o3 |
107
+ | Tools / function calling | `ai.chat` with `tools` | GPT-5.x, GPT-6, GPT-4.1 |
108
+ | Hosted tools | `ai.chat` with `hostedTools` (Responses): `web_search` (allowedDomains only), `file_search`, `code_interpreter`, `image_generation`, `mcp`; `web_fetch` rejected | Responses models |
109
+ | Structured output | `ai.chat` with a schema `responseFormat` | GPT-5.x, GPT-6, GPT-4.1 (strict json_schema) |
110
+ | Audio output | `ai.chat` with `modalities: ['text', 'audio']` + `audio: { voice, format }` | `gpt-audio-1.5` |
111
+ | Image generation (+ stream) | `ai.image.generate` | GPT Image (`gpt-image-2`) |
112
+ | Image edit (+ stream) | `ai.image.edit` (`image` + `references`, `mask`, `inputFidelity`) | GPT Image (`gpt-image-2`) |
113
+ | Transcription (+ stream) | `ai.transcribe` (incl. `diarized_json` + `knownSpeakers`) | `gpt-transcribe`, `gpt-4o-transcribe-diarize`, `whisper-1` |
114
+ | Speech / TTS | `ai.speech` (any voice, incl. custom voice ids) | `gpt-4o-mini-tts`, `tts-1`, `tts-1-hd` |
112
115
  | Embeddings | `ai.embed` | `text-embedding-3-small` / `-large` |
113
116
 
117
+ Other request fields passed through: `seed`, `verbosity`, `serviceTier`, `metadata` (Chat Completions sends it only when `store` is on), `moderate` (inline `omni-moderation-latest`), `cacheBreakpoint` on content. Responses carry `citations`, `images`, `audio`, `moderation`, `serviceTier`; `usage` counts cache writes, audio, reasoning, and hosted tool calls once each.
118
+
119
+ Through Responses, reasoning comes back encrypted (`include: reasoning.encrypted_content`, unless `store` is on) as `openai-responses-v1` reasoning details and is replayed from the assistant message's `reasoning` on later turns — only when that reasoning's `provider` is this provider's `name` or unset, so reasoning from OpenRouter or Bedrock is never sent to OpenAI.
120
+
121
+ Other wire details: `toolsOneAtATime` sends `parallel_tool_calls: false`, and Chat Completions otherwise omits the parameter (o3 rejects it); an assistant turn of only tool calls is sent with no content, not an empty text part.
122
+
114
123
  ### Strict / structured output
115
124
 
116
- The provider only emits OpenAI-shaped strict schemas (`supportedStrictFamilies = {'openai'}`). Strict mode for a tool or structured output engages only when the resolved model's strict format is `openai` **and** the model declares the `toolsStrict` / `structured` capability; otherwise it silently falls back to a lenient (non-strict) schema. A shared `SchemaBudget` is used so tools and the response format cooperate on per-request limits.
125
+ The provider only emits OpenAI-shaped strict schemas (`supportedStrictFamilies = {'openai'}`). Strict mode for a tool or structured output engages only when the resolved model's strict format is `openai` **and** the model declares the `toolsStrict` / `structured` capability; otherwise it silently falls back to the family's non-strict descriptor. When selection supplies only a model id (no `ModelInfo`), the family is still resolved from the id, so the family's non-strict dialect is kept; strict needs the `ModelInfo` capabilities. A shared `SchemaBudget` is used so tools and the response format cooperate on per-request limits. A non-strict `json_schema` response format is sent to the Responses API with an explicit `strict: false`, because Responses treats an unflagged one as strict.
117
126
 
118
- That default is correct for api.openai.com, which speaks exactly one dialect. **A subclass that fronts other providers' models must widen it** — `supportedStrictFamilies` is the gate on the whole family resolution, so leaving it at `{'openai'}` sends every other family's tool schemas out as LENIENT no matter what the model declares. `OpenRouterProvider` sets `{'openai', 'anthropic', 'google'}` for this reason; `AWSProvider` does the same.
127
+ That default is correct for api.openai.com, which speaks exactly one dialect. **A subclass that fronts other providers' models must widen it** — `supportedStrictFamilies` is the gate on the whole family resolution, so leaving it at `{'openai'}` sends every other family's tool schemas out as LENIENT no matter what the model declares. `OpenRouterProvider` sets `{'openai', 'anthropic', 'google', 'xai'}` for this reason; `AWSProvider` sets `{'openai', 'anthropic', 'google'}`.
119
128
 
120
129
  ## Usage examples
121
130
 
@@ -158,8 +167,12 @@ await ai.embed.get({ texts: ['Hello world'] });
158
167
  - `convertModel(model)` — enrich `ModelInfo`.
159
168
  - `listModels(config)` — custom model discovery.
160
169
  - `augmentChatRequest` / `augmentChatMessage` / `augmentChatContent` / `augmentChatChunk` / `augmentChatResponse` — inject provider-specific params and parse extra response fields.
170
+ - `chatHeaders(params)` — extra HTTP headers per Chat Completions request (none by default).
171
+ - `send` / `finish` — run a custom operation through the provider's hooks and retries.
161
172
  - `augmentImageGenerateRequest`, `augmentImageEditRequest`, `augmentTranscriptionRequest`, `augmentSpeechRequest`, `augmentEmbeddingRequest`.
162
173
  - `supportedStrictFamilies` — widen accepted strict descriptor families.
174
+ - `usesResponses(request, modelId, config, model?)` — decide when chat goes to the Responses API.
175
+ - `defaults` — the built-in default model id per operation.
163
176
 
164
177
  ```typescript
165
178
  class AzureProvider extends OpenAIProvider {
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Conversions from OpenAI wire shapes to @aeye shapes, shared by the Chat
3
+ * Completions, Responses, and media endpoints.
4
+ */
5
+ import type { AudioFormat, Citation, Moderation, ServiceTier, Usage } from '@aeye/core';
6
+ import OpenAI from 'openai';
7
+ /**
8
+ * Token totals as an endpoint reports them, before splitting into Usage
9
+ * categories. Detail counts are subsets of their total.
10
+ */
11
+ export interface TokenCounts {
12
+ input?: number;
13
+ output?: number;
14
+ cached?: number;
15
+ cacheWrite?: number;
16
+ audioInput?: number;
17
+ reasoning?: number;
18
+ audioOutput?: number;
19
+ }
20
+ /**
21
+ * Splits token totals into Usage categories so each token is counted once:
22
+ * cache reads and writes and audio come out of the input total; reasoning
23
+ * and audio output come out of the output total.
24
+ */
25
+ export declare function toUsage(counts: TokenCounts): Usage;
26
+ /**
27
+ * Usage reported by Chat Completions (and OpenAI-compatible endpoints).
28
+ */
29
+ export declare function chatUsage(usage: OpenAI.CompletionUsage): Usage;
30
+ /**
31
+ * Usage reported by the Responses API.
32
+ */
33
+ export declare function responsesUsage(usage: OpenAI.Responses.ResponseUsage): Usage;
34
+ /**
35
+ * Usage reported by transcription: tokens for token-billed models, seconds
36
+ * for duration-billed ones (OpenAI-compatible routers may omit `type`).
37
+ */
38
+ export declare function transcriptionUsage(usage: OpenAI.Audio.Transcription.Tokens | OpenAI.Audio.Transcription.Duration): Usage;
39
+ /**
40
+ * The tier a response reports it ran on.
41
+ */
42
+ export declare function toServiceTier(tier: string | null | undefined): ServiceTier | undefined;
43
+ /**
44
+ * A URL citation, as both Chat Completions and Responses report them.
45
+ */
46
+ export declare function toCitation(citation: {
47
+ url: string;
48
+ title?: string;
49
+ start_index?: number;
50
+ end_index?: number;
51
+ }): Citation;
52
+ /**
53
+ * One side of a moderation verdict, as both Chat Completions and Responses
54
+ * report it: results, or an error when moderation itself failed.
55
+ */
56
+ interface WireModerationSide {
57
+ type: string;
58
+ results?: Array<{
59
+ flagged: boolean;
60
+ categories: {
61
+ [category: string]: boolean;
62
+ };
63
+ }>;
64
+ }
65
+ /**
66
+ * Moderation verdicts for the input and the output.
67
+ */
68
+ export declare function toModeration(moderation: {
69
+ input: WireModerationSide;
70
+ output: WireModerationSide;
71
+ }): Moderation;
72
+ /**
73
+ * The model OpenAI runs moderation with when a request asks for it.
74
+ */
75
+ export declare const MODERATION_MODEL = "omni-moderation-latest";
76
+ /**
77
+ * Chat Completions names 16-bit PCM `pcm16`.
78
+ */
79
+ export declare function toChatAudioFormat(format: AudioFormat): OpenAI.Chat.ChatCompletionAudioParam['format'];
80
+ export {};
81
+ //# sourceMappingURL=convert.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"convert.d.ts","sourceRoot":"","sources":["../src/convert.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU,EAAoB,WAAW,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAC1G,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,MAAM,EAAE,WAAW,GAAG,KAAK,CAoBlD;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,eAAe,GAAG,KAAK,CAU9D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,SAAS,CAAC,aAAa,GAAG,KAAK,CAQ3E;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,QAAQ,GAAG,KAAK,CAIxH;AAcD;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,CAEtF;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,QAAQ,CAExH;AAED;;;GAGG;AACH,UAAU,kBAAkB;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,UAAU,EAAE;YAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAA;SAAE,CAAA;KAAE,CAAC,CAAC;CACpF;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,UAAU,EAAE;IAAE,KAAK,EAAE,kBAAkB,CAAC;IAAC,MAAM,EAAE,kBAAkB,CAAA;CAAE,GAAG,UAAU,CAM9G;AAED;;GAEG;AACH,eAAO,MAAM,gBAAgB,2BAA2B,CAAC;AAEzD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,wBAAwB,CAAC,QAAQ,CAAC,CAErG"}
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Conversions from OpenAI wire shapes to @aeye shapes, shared by the Chat
3
+ * Completions, Responses, and media endpoints.
4
+ */
5
+ /**
6
+ * Splits token totals into Usage categories so each token is counted once:
7
+ * cache reads and writes and audio come out of the input total; reasoning
8
+ * and audio output come out of the output total.
9
+ */
10
+ export function toUsage(counts) {
11
+ const nonZero = (n = 0) => n > 0 ? n : undefined;
12
+ const usage = {};
13
+ const text = {
14
+ input: nonZero((counts.input ?? 0) - (counts.cached ?? 0) - (counts.cacheWrite ?? 0) - (counts.audioInput ?? 0)),
15
+ output: nonZero((counts.output ?? 0) - (counts.reasoning ?? 0) - (counts.audioOutput ?? 0)),
16
+ cached: nonZero(counts.cached),
17
+ cacheWrite: nonZero(counts.cacheWrite),
18
+ };
19
+ if (text.input || text.output || text.cached || text.cacheWrite) {
20
+ usage.text = text;
21
+ }
22
+ if (counts.reasoning) {
23
+ usage.reasoning = { output: counts.reasoning };
24
+ }
25
+ if (counts.audioInput || counts.audioOutput) {
26
+ usage.audio = { input: nonZero(counts.audioInput), output: nonZero(counts.audioOutput) };
27
+ }
28
+ return usage;
29
+ }
30
+ /**
31
+ * Usage reported by Chat Completions (and OpenAI-compatible endpoints).
32
+ */
33
+ export function chatUsage(usage) {
34
+ return toUsage({
35
+ input: usage.prompt_tokens,
36
+ output: usage.completion_tokens,
37
+ cached: usage.prompt_tokens_details?.cached_tokens,
38
+ cacheWrite: usage.prompt_tokens_details?.cache_write_tokens,
39
+ audioInput: usage.prompt_tokens_details?.audio_tokens,
40
+ reasoning: usage.completion_tokens_details?.reasoning_tokens,
41
+ audioOutput: usage.completion_tokens_details?.audio_tokens,
42
+ });
43
+ }
44
+ /**
45
+ * Usage reported by the Responses API.
46
+ */
47
+ export function responsesUsage(usage) {
48
+ return toUsage({
49
+ input: usage.input_tokens,
50
+ output: usage.output_tokens,
51
+ cached: usage.input_tokens_details.cached_tokens,
52
+ cacheWrite: usage.input_tokens_details.cache_write_tokens,
53
+ reasoning: usage.output_tokens_details.reasoning_tokens,
54
+ });
55
+ }
56
+ /**
57
+ * Usage reported by transcription: tokens for token-billed models, seconds
58
+ * for duration-billed ones (OpenAI-compatible routers may omit `type`).
59
+ */
60
+ export function transcriptionUsage(usage) {
61
+ return 'seconds' in usage
62
+ ? { audio: { seconds: usage.seconds } }
63
+ : toUsage({ input: usage.input_tokens, output: usage.output_tokens, audioInput: usage.input_token_details?.audio_tokens });
64
+ }
65
+ /**
66
+ * Wire tiers to @aeye tiers. `priority` is the older name for `fast`.
67
+ */
68
+ const SERVICE_TIERS = {
69
+ auto: 'auto',
70
+ default: 'default',
71
+ flex: 'flex',
72
+ fast: 'fast',
73
+ priority: 'fast',
74
+ scale: 'scale',
75
+ };
76
+ /**
77
+ * The tier a response reports it ran on.
78
+ */
79
+ export function toServiceTier(tier) {
80
+ return tier ? SERVICE_TIERS[tier] : undefined;
81
+ }
82
+ /**
83
+ * A URL citation, as both Chat Completions and Responses report them.
84
+ */
85
+ export function toCitation(citation) {
86
+ return { url: citation.url, title: citation.title, start: citation.start_index, end: citation.end_index };
87
+ }
88
+ /**
89
+ * Moderation verdicts for the input and the output.
90
+ */
91
+ export function toModeration(moderation) {
92
+ const side = ({ results }) => results && {
93
+ flagged: results.some(result => result.flagged),
94
+ categories: [...new Set(results.flatMap(result => Object.keys(result.categories).filter(category => result.categories[category])))],
95
+ };
96
+ return { input: side(moderation.input), output: side(moderation.output) };
97
+ }
98
+ /**
99
+ * The model OpenAI runs moderation with when a request asks for it.
100
+ */
101
+ export const MODERATION_MODEL = 'omni-moderation-latest';
102
+ /**
103
+ * Chat Completions names 16-bit PCM `pcm16`.
104
+ */
105
+ export function toChatAudioFormat(format) {
106
+ return format === 'pcm' ? 'pcm16' : format;
107
+ }
108
+ //# sourceMappingURL=convert.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"convert.js","sourceRoot":"","sources":["../src/convert.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,110 @@
1
+ /**
2
+ * The Decisions API's wire shapes, which the SDK does not type yet, and
3
+ * their conversion to and from @aeye decisions.
4
+ */
5
+ import type { DecisionAnswer, DecisionQuestion } from '@aeye/ai';
6
+ import OpenAI from 'openai';
7
+ /**
8
+ * A question as the Decisions API takes it.
9
+ */
10
+ export type OpenAIDecisionQuestion = {
11
+ name: string;
12
+ instructions: string;
13
+ } & ({
14
+ type: 'predicate';
15
+ } | {
16
+ type: 'choice';
17
+ choices: Array<{
18
+ value: string;
19
+ description?: string;
20
+ }>;
21
+ } | {
22
+ type: 'score';
23
+ levels: Array<{
24
+ label: string;
25
+ description?: string;
26
+ }>;
27
+ });
28
+ /**
29
+ * Parameters of a decision request.
30
+ */
31
+ export interface OpenAIDecisionParams {
32
+ model: string;
33
+ input: string | OpenAI.Responses.ResponseInputItem[];
34
+ questions: OpenAIDecisionQuestion[];
35
+ }
36
+ /**
37
+ * An answer as the Decisions API returns it.
38
+ */
39
+ export type OpenAIDecisionAnswer = {
40
+ name: string;
41
+ } & ({
42
+ type: 'predicate';
43
+ probability: number;
44
+ } | {
45
+ type: 'choice';
46
+ choice: string;
47
+ probabilities: Array<{
48
+ value: string;
49
+ probability: number;
50
+ }>;
51
+ confidence: number;
52
+ } | {
53
+ type: 'score';
54
+ score: number;
55
+ probabilities: Array<{
56
+ value: number;
57
+ label: string;
58
+ probability: number;
59
+ }>;
60
+ confidence: number;
61
+ } | {
62
+ type: 'refusal';
63
+ });
64
+ /**
65
+ * A decision as the Decisions API returns it.
66
+ */
67
+ export interface OpenAIDecision {
68
+ model: string;
69
+ answers: OpenAIDecisionAnswer[];
70
+ usage: OpenAI.Responses.ResponseUsage;
71
+ }
72
+ /**
73
+ * A question in the System One decision protocol (TypeSafe's), which
74
+ * OpenRouter's decisions endpoint speaks: a predicate is a `noul`
75
+ * question, and choices and levels are its criteria.
76
+ */
77
+ export type SystemOneQuestion = {
78
+ type: 'noul';
79
+ instructions: string;
80
+ } | {
81
+ type: 'choice';
82
+ instructions: string;
83
+ criteria: Record<string, string>;
84
+ } | {
85
+ type: 'score';
86
+ instructions: string;
87
+ criteria: string[];
88
+ };
89
+ /**
90
+ * Parameters of a System One decision request: the evidence as `state`,
91
+ * and questions by name.
92
+ */
93
+ export interface SystemOneDecisionParams {
94
+ model: string;
95
+ state: string | OpenAI.Chat.ChatCompletionMessageParam[];
96
+ questions: Record<string, SystemOneQuestion>;
97
+ }
98
+ /**
99
+ * A question in System One's shape.
100
+ */
101
+ export declare function toSystemOneQuestion(question: DecisionQuestion): SystemOneQuestion;
102
+ /**
103
+ * A named question in the Decisions API's shape.
104
+ */
105
+ export declare function toDecisionQuestion(name: string, question: DecisionQuestion): OpenAIDecisionQuestion;
106
+ /**
107
+ * An answer in @aeye's shape. Score probabilities come back in level order.
108
+ */
109
+ export declare function toDecisionAnswer(answer: OpenAIDecisionAnswer): DecisionAnswer;
110
+ //# sourceMappingURL=decisions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decisions.d.ts","sourceRoot":"","sources":["../src/decisions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * The Decisions API's wire shapes, which the SDK does not type yet, and
3
+ * their conversion to and from @aeye decisions.
4
+ */
5
+ /**
6
+ * A question in System One's shape.
7
+ */
8
+ export function toSystemOneQuestion(question) {
9
+ const { instructions } = question;
10
+ switch (question.type) {
11
+ case 'predicate':
12
+ return { type: 'noul', instructions };
13
+ case 'choice':
14
+ return { type: 'choice', instructions, criteria: question.choices };
15
+ case 'score':
16
+ return { type: 'score', instructions, criteria: question.levels };
17
+ }
18
+ }
19
+ /**
20
+ * A named question in the Decisions API's shape.
21
+ */
22
+ export function toDecisionQuestion(name, question) {
23
+ const { instructions } = question;
24
+ switch (question.type) {
25
+ case 'predicate':
26
+ return { name, type: 'predicate', instructions };
27
+ case 'choice':
28
+ return { name, type: 'choice', instructions, choices: Object.entries(question.choices).map(([value, description]) => ({ value, description: description || undefined })) };
29
+ case 'score':
30
+ return { name, type: 'score', instructions, levels: question.levels.map(label => ({ label })) };
31
+ }
32
+ }
33
+ /**
34
+ * An answer in @aeye's shape. Score probabilities come back in level order.
35
+ */
36
+ export function toDecisionAnswer(answer) {
37
+ switch (answer.type) {
38
+ case 'predicate':
39
+ return { type: 'predicate', probability: answer.probability };
40
+ case 'choice':
41
+ return { type: 'choice', choice: answer.choice, probabilities: Object.fromEntries(answer.probabilities.map(p => [p.value, p.probability])), confidence: answer.confidence };
42
+ case 'score':
43
+ return { type: 'score', score: answer.score, probabilities: answer.probabilities.map(p => p.probability), confidence: answer.confidence };
44
+ case 'refusal':
45
+ return { type: 'refusal' };
46
+ }
47
+ }
48
+ //# sourceMappingURL=decisions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decisions.js","sourceRoot":"","sources":["../src/decisions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA8DH;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,QAA0B;IAC5D,MAAM,EAAE,YAAY,EAAE,GAAG,QAAQ,CAAC;IAClC,QAAQ,QAAQ,CAAC,IAAI,EAAE,CAAC;QACtB,KAAK,WAAW;YACd,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC;QACxC,KAAK,QAAQ;YACX,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,QAAQ,CAAC,OAAO,EAAE,CAAC;QACtE,KAAK,OAAO;YACV,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC;IACtE,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAY,EAAE,QAA0B;IACzE,MAAM,EAAE,YAAY,EAAE,GAAG,QAAQ,CAAC;IAClC,QAAQ,QAAQ,CAAC,IAAI,EAAE,CAAC;QACtB,KAAK,WAAW;YACd,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC;QACnD,KAAK,QAAQ;YACX,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,WAAW,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,WAAW,IAAI,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC;QAC7K,KAAK,OAAO;YACV,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC;IACpG,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAA4B;IAC3D,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,KAAK,WAAW;YACd,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC;QAChE,KAAK,QAAQ;YACX,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC;QAC9K,KAAK,OAAO;YACV,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,aAAa,EAAE,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC;QAC5I,KAAK,SAAS;YACZ,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IAC/B,CAAC;AACH,CAAC"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * GPT Image request parameters and usage, shared by generation and editing.
3
+ * DALL·E models were retired, so every image model takes the GPT Image shape.
4
+ */
5
+ import type { ImageOutputOptions, ModelInfo } from '@aeye/ai';
6
+ import type { Usage } from '@aeye/core';
7
+ /**
8
+ * Parameters shared by image generation and editing. `auto` and exact
9
+ * sizes pass through; other sizes snap to the nearest one the model takes.
10
+ */
11
+ export declare function imageParams(request: ImageOutputOptions, modelId: string, model: ModelInfo | undefined): {
12
+ model: string;
13
+ prompt: string;
14
+ n: number | undefined;
15
+ size: string | undefined;
16
+ quality: import("@aeye/ai").ImageQuality | undefined;
17
+ background: "auto" | "transparent" | "opaque" | undefined;
18
+ output_format: "png" | "jpeg" | "webp" | undefined;
19
+ output_compression: number | undefined;
20
+ user: string | undefined;
21
+ };
22
+ /**
23
+ * How many partial images a streaming request asks for.
24
+ */
25
+ export declare function partialImages(request: ImageOutputOptions): number;
26
+ /**
27
+ * What image responses and completed stream events report about the image.
28
+ */
29
+ interface ImageResult {
30
+ usage?: {
31
+ output_tokens: number;
32
+ input_tokens_details: {
33
+ image_tokens: number;
34
+ text_tokens: number;
35
+ };
36
+ };
37
+ quality?: string;
38
+ size?: string;
39
+ }
40
+ /**
41
+ * Usage of an image response: tokens as reported, plus one output entry per
42
+ * image with the quality and size actually produced, for models priced per
43
+ * image.
44
+ */
45
+ export declare function imageUsage(response: ImageResult, count: number): Usage;
46
+ export {};
47
+ //# sourceMappingURL=images.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"images.d.ts","sourceRoot":"","sources":["../src/images.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC9D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AA8CxC;;;GAGG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,kBAAkB,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,SAAS;;;;;;;;;;EAarG;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,kBAAkB,GAAG,MAAM,CAEjE;AAED;;GAEG;AACH,UAAU,WAAW;IACnB,KAAK,CAAC,EAAE;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,oBAAoB,EAAE;YAAE,YAAY,EAAE,MAAM,CAAC;YAAC,WAAW,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAC;IACvG,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,GAAG,KAAK,CAatE"}
package/dist/images.js ADDED
@@ -0,0 +1,80 @@
1
+ /**
2
+ * GPT Image request parameters and usage, shared by generation and editing.
3
+ * DALL·E models were retired, so every image model takes the GPT Image shape.
4
+ */
5
+ /**
6
+ * Sizes every GPT Image model accepts, for models the registry has no sizes for.
7
+ */
8
+ const DEFAULT_SIZES = [
9
+ { width: 1024, height: 1024 },
10
+ { width: 1536, height: 1024 },
11
+ { width: 1024, height: 1536 },
12
+ ];
13
+ /**
14
+ * Most images one request may produce.
15
+ */
16
+ const MAX_IMAGES = 10;
17
+ /**
18
+ * Most partial images a streaming request may produce.
19
+ */
20
+ const MAX_PARTIAL_IMAGES = 3;
21
+ /**
22
+ * The size closest in aspect ratio to the requested one, then the largest.
23
+ */
24
+ function nearestSize(requested, sizes) {
25
+ const [width, height] = requested.split('x').map(Number);
26
+ const ratio = width / height;
27
+ const [closest] = [...sizes].sort((a, b) => Math.abs(a.width / a.height - ratio) - Math.abs(b.width / b.height - ratio) ||
28
+ b.width * b.height - a.width * a.height);
29
+ return `${closest.width}x${closest.height}`;
30
+ }
31
+ /**
32
+ * The sizes the registry prices for a model.
33
+ */
34
+ function pricedSizes(model) {
35
+ return model?.pricing.image?.output?.flatMap(quality => quality.sizes) ?? [];
36
+ }
37
+ /**
38
+ * Parameters shared by image generation and editing. `auto` and exact
39
+ * sizes pass through; other sizes snap to the nearest one the model takes.
40
+ */
41
+ export function imageParams(request, modelId, model) {
42
+ const sizes = pricedSizes(model);
43
+ return {
44
+ model: modelId,
45
+ prompt: request.prompt,
46
+ n: request.n === undefined ? undefined : Math.min(Math.max(request.n, 1), MAX_IMAGES),
47
+ size: !request.size || request.size === 'auto' ? request.size : nearestSize(request.size, sizes.length ? sizes : DEFAULT_SIZES),
48
+ quality: request.quality,
49
+ background: request.background,
50
+ output_format: request.outputFormat,
51
+ output_compression: request.outputCompression,
52
+ user: request.userIdentifier,
53
+ };
54
+ }
55
+ /**
56
+ * How many partial images a streaming request asks for.
57
+ */
58
+ export function partialImages(request) {
59
+ return Math.max(1, Math.min(MAX_PARTIAL_IMAGES, request.streamCount ?? 2));
60
+ }
61
+ /**
62
+ * Usage of an image response: tokens as reported, plus one output entry per
63
+ * image with the quality and size actually produced, for models priced per
64
+ * image.
65
+ */
66
+ export function imageUsage(response, count) {
67
+ const [width, height] = (response.size ?? '').split('x').map(Number);
68
+ const details = response.usage?.input_tokens_details;
69
+ return {
70
+ text: details && { input: details.text_tokens },
71
+ image: {
72
+ input: details?.image_tokens,
73
+ tokens: response.usage?.output_tokens,
74
+ output: response.quality && width && height
75
+ ? [{ quality: response.quality, size: { width, height }, count }]
76
+ : undefined,
77
+ },
78
+ };
79
+ }
80
+ //# sourceMappingURL=images.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"images.js","sourceRoot":"","sources":["../src/images.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export * from './openai';
2
+ export { type SystemOneDecisionParams, type SystemOneQuestion, toSystemOneQuestion } from './decisions';
2
3
  export * from './types';
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,OAAO,EAAE,KAAK,uBAAuB,EAAE,KAAK,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACxG,cAAc,SAAS,CAAC"}
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
1
  export * from './openai';
2
+ export { toSystemOneQuestion } from './decisions';
2
3
  export * from './types';
3
4
  //# sourceMappingURL=index.js.map