@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/README.md +1076 -921
- package/aeye-openai.md +31 -18
- package/dist/convert.d.ts +81 -0
- package/dist/convert.d.ts.map +1 -0
- package/dist/convert.js +108 -0
- package/dist/convert.js.map +1 -0
- package/dist/decisions.d.ts +110 -0
- package/dist/decisions.d.ts.map +1 -0
- package/dist/decisions.js +48 -0
- package/dist/decisions.js.map +1 -0
- package/dist/images.d.ts +47 -0
- package/dist/images.d.ts.map +1 -0
- package/dist/images.js +80 -0
- package/dist/images.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/openai.d.ts +452 -206
- package/dist/openai.d.ts.map +1 -1
- package/dist/openai.js +912 -1424
- package/dist/openai.js.map +1 -1
- package/dist/responses.d.ts +67 -0
- package/dist/responses.d.ts.map +1 -0
- package/dist/responses.js +236 -0
- package/dist/responses.js.map +1 -0
- package/package.json +6 -6
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-
|
|
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-
|
|
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-
|
|
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
|
|
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-
|
|
104
|
-
| Vision | `ai.chat` with `image` content | GPT-
|
|
105
|
-
| Reasoning | `ai.chat` with `request.reason
|
|
106
|
-
| Tools / function calling | `ai.chat` with `tools` | GPT-
|
|
107
|
-
|
|
|
108
|
-
|
|
|
109
|
-
|
|
|
110
|
-
|
|
|
111
|
-
|
|
|
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
|
|
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`
|
|
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"}
|
package/dist/convert.js
ADDED
|
@@ -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"}
|
package/dist/images.d.ts
ADDED
|
@@ -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":"AAAA;;;GAGG;AAUH;;GAEG;AACH,MAAM,aAAa,GAAW;IAC5B,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE;IAC7B,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE;IAC7B,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE;CAC9B,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,GAAG,EAAE,CAAC;AAEtB;;GAEG;AACH,MAAM,kBAAkB,GAAG,CAAC,CAAC;AAE7B;;GAEG;AACH,SAAS,WAAW,CAAC,SAAiB,EAAE,KAAa;IACnD,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACzD,MAAM,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;IAC7B,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CACzC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,MAAM,GAAG,KAAK,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,MAAM,GAAG,KAAK,CAAC;QAC3E,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,MAAM,CACxC,CAAC;IACF,OAAO,GAAG,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;AAC9C,CAAC;AAED;;GAEG;AACH,SAAS,WAAW,CAAC,KAA4B;IAC/C,OAAO,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;AAC/E,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,OAA2B,EAAE,OAAe,EAAE,KAA4B;IACpG,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IACjC,OAAO;QACL,KAAK,EAAE,OAAO;QACd,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,CAAC,EAAE,OAAO,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,CAAC;QACrF,IAAI,EAAE,CAAC,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC;QAC/H,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,aAAa,EAAE,OAAO,CAAC,YAAY;QACnC,kBAAkB,EAAE,OAAO,CAAC,iBAAiB;QAC7C,IAAI,EAAE,OAAO,CAAC,cAAc;KAC7B,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,OAA2B;IACvD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,kBAAkB,EAAE,OAAO,CAAC,WAAW,IAAI,CAAC,CAAC,CAAC,CAAC;AAC7E,CAAC;AAWD;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,QAAqB,EAAE,KAAa;IAC7D,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACrE,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,EAAE,oBAAoB,CAAC;IACrD,OAAO;QACL,IAAI,EAAE,OAAO,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,WAAW,EAAE;QAC/C,KAAK,EAAE;YACL,KAAK,EAAE,OAAO,EAAE,YAAY;YAC5B,MAAM,EAAE,QAAQ,CAAC,KAAK,EAAE,aAAa;YACrC,MAAM,EAAE,QAAQ,CAAC,OAAO,IAAI,KAAK,IAAI,MAAM;gBACzC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,CAAC;gBACjE,CAAC,CAAC,SAAS;SACd;KACF,CAAC;AACJ,CAAC"}
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -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