@combycode/llm-sdk 2.3.0 → 3.1.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/CHANGELOG.md +429 -0
- package/MIGRATION.md +130 -0
- package/dist/bus/hook-bus.d.ts +13 -3
- package/dist/bus/hook-map.d.ts +24 -0
- package/dist/catalog/catalog.d.ts +23 -26
- package/dist/helpers/client-resolver.d.ts +21 -2
- package/dist/helpers/count-tokens.d.ts +1 -1
- package/dist/helpers/engine.d.ts +27 -5
- package/dist/helpers/select-model.d.ts +35 -0
- package/dist/index.browser.js +17394 -4392
- package/dist/index.d.ts +3 -3
- package/dist/index.js +17394 -4392
- package/dist/llm/client-config.d.ts +8 -0
- package/dist/llm/client.d.ts +5 -0
- package/dist/llm/providers/anthropic/batch.d.ts +13 -2
- package/dist/llm/providers/anthropic/constants.d.ts +8 -43
- package/dist/llm/providers/anthropic/files.d.ts +13 -2
- package/dist/llm/providers/anthropic/messages.d.ts +18 -1
- package/dist/llm/providers/google/batch.d.ts +14 -1
- package/dist/llm/providers/google/constants.d.ts +6 -15
- package/dist/llm/providers/google/embeddings.d.ts +8 -1
- package/dist/llm/providers/google/files.d.ts +19 -1
- package/dist/llm/providers/google/generate.d.ts +15 -1
- package/dist/llm/providers/google/interactions.d.ts +5 -1
- package/dist/llm/providers/google/media.d.ts +26 -3
- package/dist/llm/providers/openai/batch.d.ts +19 -2
- package/dist/llm/providers/openai/completions.d.ts +13 -1
- package/dist/llm/providers/openai/embeddings.d.ts +13 -1
- package/dist/llm/providers/openai/files.d.ts +13 -2
- package/dist/llm/providers/openai/media.d.ts +21 -1
- package/dist/llm/providers/openai/moderations.d.ts +11 -1
- package/dist/llm/providers/openai/realtime.d.ts +3 -0
- package/dist/llm/providers/openai/responses.d.ts +10 -2
- package/dist/llm/providers/openai/transcription.d.ts +7 -1
- package/dist/llm/providers/openrouter/completions.d.ts +5 -3
- package/dist/llm/providers/openrouter/embeddings.d.ts +3 -0
- package/dist/llm/providers/openrouter/media.d.ts +14 -4
- package/dist/llm/providers/openrouter/responses.d.ts +5 -3
- package/dist/llm/providers/xai/batch.d.ts +13 -2
- package/dist/llm/providers/xai/completions.d.ts +5 -3
- package/dist/llm/providers/xai/files.d.ts +13 -2
- package/dist/llm/providers/xai/media.d.ts +28 -10
- package/dist/llm/providers/xai/responses.d.ts +5 -3
- package/dist/llm/response-shape.d.ts +96 -0
- package/dist/llm/types/provider.d.ts +11 -0
- package/dist/llm/types/request.d.ts +5 -6
- package/dist/llm/wire-multipart.d.ts +26 -0
- package/dist/{wire/transforms.d.ts → llm/wire-transforms.d.ts} +11 -5
- package/dist/plugins/context-measurer/counter/count-api.d.ts +39 -5
- package/dist/plugins/context-measurer/counter/hybrid.d.ts +33 -0
- package/dist/plugins/context-measurer/counter/tiktoken.d.ts +7 -0
- package/dist/plugins/mcp/transport-http.d.ts +13 -7
- package/dist/plugins/mcp/wire-rules.d.ts +21 -0
- package/dist/plugins/retrieval/document-file.d.ts +15 -0
- package/dist/plugins/retrieval/hosted-google.d.ts +8 -3
- package/dist/plugins/retrieval/hosted-openai.d.ts +9 -1
- package/dist/plugins/retrieval/hosted-xai.d.ts +8 -2
- package/dist/wire/chat-specs.d.ts +32 -0
- package/dist/wire/inherit.d.ts +0 -4
- package/dist/wire/interpreter.d.ts +84 -1
- package/dist/wire/mcp-specs.d.ts +13 -0
- package/dist/wire/media-specs.d.ts +20 -0
- package/dist/wire/pins.d.ts +34 -0
- package/dist/wire/registry.d.ts +6 -4
- package/dist/wire/retrieval-specs.d.ts +14 -0
- package/dist/wire/service-specs.d.ts +18 -0
- package/dist/wire/utility-specs.d.ts +10 -0
- package/package.json +4 -1
|
@@ -34,4 +34,12 @@ export interface LLMClientConfig {
|
|
|
34
34
|
* createLLM supplies `engine.catalog`. An empty catalog still yields correct
|
|
35
35
|
* provider-level defaults, so this is optional. */
|
|
36
36
|
catalog?: ModelCatalog;
|
|
37
|
+
/** Warn when a provider's response stops looking like the one we learned to
|
|
38
|
+
* read — a field we have never seen, a field that was always there and is now
|
|
39
|
+
* absent, or a discriminator carrying a value nothing branches on.
|
|
40
|
+
*
|
|
41
|
+
* OFF by default and never changes what is parsed: it only emits `onWarning`.
|
|
42
|
+
* `createEngine({ checkResponseShapes: true })` turns it on for every client
|
|
43
|
+
* the engine builds. See `src/llm/response-shape.ts`. */
|
|
44
|
+
checkResponseShapes?: boolean;
|
|
37
45
|
}
|
package/dist/llm/client.d.ts
CHANGED
|
@@ -38,6 +38,8 @@ export declare class LLMClient {
|
|
|
38
38
|
readonly mode: 'foreground' | 'background';
|
|
39
39
|
readonly batchable: boolean;
|
|
40
40
|
private readonly adapter;
|
|
41
|
+
/** Present only when the caller asked for the shape check. */
|
|
42
|
+
private readonly shapeChecker?;
|
|
41
43
|
private readonly apiKey;
|
|
42
44
|
private readonly fetchFn;
|
|
43
45
|
private readonly fetchStreamFn;
|
|
@@ -83,6 +85,9 @@ export declare class LLMClient {
|
|
|
83
85
|
* files piped straight to a file / GridFS / HTTP response without buffering. */
|
|
84
86
|
streamFile(file: FileOutput): Promise<FileStream>;
|
|
85
87
|
/** Submit a request. Returns the parsed CompletionResponse. */
|
|
88
|
+
/** Anything the spec left out on purpose reaches the caller as a warning.
|
|
89
|
+
* Said once per request; the build already de-duplicates within one. */
|
|
90
|
+
private reportBuildNotes;
|
|
86
91
|
complete(input: string | ContentPart[] | Message[], options?: ExecuteOptions): Promise<CompletionResponse>;
|
|
87
92
|
/** Run `complete` with a JSON Schema enforced via `structured`. Strips any
|
|
88
93
|
* leading/trailing markdown fences from the model reply, then JSON.parses
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** Anthropic batch adapter — POST /v1/messages/batches with inline requests.
|
|
2
2
|
* All HTTP flows through the injected EngineFetch (NetworkEngine queue). */
|
|
3
|
-
import type { EngineFetch } from '../../../network/types';
|
|
3
|
+
import type { EngineFetch, HttpRequest } from '../../../network/types';
|
|
4
4
|
import type { BatchProviderAdapter, BatchRequest, BatchResult, BatchStatus } from '../../../plugins/batch/types';
|
|
5
5
|
export interface AnthropicBatchAdapterConfig {
|
|
6
6
|
apiKey: string;
|
|
@@ -11,7 +11,18 @@ export declare class AnthropicBatchAdapter implements BatchProviderAdapter {
|
|
|
11
11
|
private readonly apiKey;
|
|
12
12
|
private readonly baseURL;
|
|
13
13
|
constructor(config: AnthropicBatchAdapterConfig);
|
|
14
|
-
|
|
14
|
+
/** Batch rules need no adapter handles: the requests are mapped by the spec. */
|
|
15
|
+
private readonly wireRegistry;
|
|
16
|
+
/** Build one batch request from its spec, then add the engine metadata.
|
|
17
|
+
* Every batch call is routed under the `batch` model name for queueing. */
|
|
18
|
+
private fromSpec;
|
|
19
|
+
buildSubmitRequest(requests: BatchRequest[]): HttpRequest;
|
|
20
|
+
buildStatusRequest(batchId: string): HttpRequest;
|
|
21
|
+
/** Results stream back as JSONL, so this one decodes as TEXT. Forcing `json`
|
|
22
|
+
* here would have broken every batch read — caught by the frozen corpus, not
|
|
23
|
+
* by any type. */
|
|
24
|
+
buildResultsRequest(batchId: string): HttpRequest;
|
|
25
|
+
buildCancelRequest(batchId: string): HttpRequest;
|
|
15
26
|
submit(requests: BatchRequest[], fetch: EngineFetch): Promise<string>;
|
|
16
27
|
getStatus(batchId: string, fetch: EngineFetch): Promise<BatchStatus>;
|
|
17
28
|
getResults(batchId: string, fetch: EngineFetch): Promise<BatchResult[]>;
|
|
@@ -1,45 +1,10 @@
|
|
|
1
|
-
/** Anthropic provider constants.
|
|
1
|
+
/** Anthropic provider constants.
|
|
2
|
+
*
|
|
3
|
+
* The thinking-shape and top_k band helpers that used to live here are gone: that
|
|
4
|
+
* knowledge is now `src/wire/pins/anthropic.messages.json`, and the token budgets
|
|
5
|
+
* are a `$table` inside the chain specs. Both were version arithmetic in
|
|
6
|
+
* TypeScript, which the Python and Rust ports would have had to re-implement and
|
|
7
|
+
* keep in step - and one copy drifting is exactly how 2.2.1 shipped the wrong
|
|
8
|
+
* thinking shape. */
|
|
2
9
|
/** The Anthropic API version header sent on every request. */
|
|
3
10
|
export declare const ANTHROPIC_API_VERSION = "2023-06-01";
|
|
4
|
-
/**
|
|
5
|
-
* Token budgets for Anthropic extended thinking by effort level.
|
|
6
|
-
* Used to set budget_tokens in the `thinking` request param.
|
|
7
|
-
*/
|
|
8
|
-
export declare const ANTHROPIC_THINKING_BUDGETS: Record<string, number>;
|
|
9
|
-
/**
|
|
10
|
-
* Budget applied when no effort level is specified or when the level is
|
|
11
|
-
* unrecognised.
|
|
12
|
-
*/
|
|
13
|
-
export declare const DEFAULT_ANTHROPIC_THINKING_BUDGET = 2048;
|
|
14
|
-
/**
|
|
15
|
-
* The version at which `thinking: {type:'adaptive'}` takes over from
|
|
16
|
-
* `{type:'enabled', budget_tokens}`.
|
|
17
|
-
*
|
|
18
|
-
* There is no shape that works everywhere, and the direction reversed under us. This
|
|
19
|
-
* adapter used to send the budgeted form to every model, on the reasoning that it was the
|
|
20
|
-
* universally accepted one — true when it was written. Anthropic then REMOVED
|
|
21
|
-
* `budget_tokens` on 4.7 and later: Sonnet 5, Opus 5/4.8/4.7 and Fable 5 reject it with a
|
|
22
|
-
* 400 ("thinking.type.enabled is not supported for this model"). Meanwhile the older half
|
|
23
|
-
* — Haiku 4.5, Sonnet 4.5, Opus 4.x — has no `adaptive` at all and still requires the
|
|
24
|
-
* budget. So the shape must be chosen per model.
|
|
25
|
-
*
|
|
26
|
-
* 4.6 is the boundary: it accepts both and prefers `adaptive`, everything above requires
|
|
27
|
-
* `adaptive`, everything below requires the budget.
|
|
28
|
-
*/
|
|
29
|
-
export declare const ANTHROPIC_ADAPTIVE_THINKING_MIN: {
|
|
30
|
-
readonly major: 4;
|
|
31
|
-
readonly minor: 6;
|
|
32
|
-
};
|
|
33
|
-
/**
|
|
34
|
-
* Pick the `thinking` shape for a model id.
|
|
35
|
-
*
|
|
36
|
-
* Parsed from the id rather than read from the catalog on purpose: the catalog is optional
|
|
37
|
-
* (an engine can run with none), `buildRequest` has no access to it, and its per-model
|
|
38
|
-
* `reasoning` block does not currently distinguish the two shapes anyway.
|
|
39
|
-
*
|
|
40
|
-
* An unrecognised id gets `adaptive`, because `budget_tokens` is the shape being retired —
|
|
41
|
-
* an id we do not recognise is far likelier to be newer than us than older.
|
|
42
|
-
*/
|
|
43
|
-
export declare function anthropicThinkingShape(model: string): 'adaptive' | 'budgeted';
|
|
44
|
-
/** True when this Anthropic model still accepts `top_k` (see ANTHROPIC_TOP_K_MODELS). */
|
|
45
|
-
export declare function anthropicAcceptsTopK(model: string): boolean;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** Anthropic file adapter — POST /v1/files (beta).
|
|
2
2
|
* All HTTP flows through the injected EngineFetch (NetworkEngine queue). */
|
|
3
|
-
import type { EngineFetch } from '../../../network/types';
|
|
3
|
+
import type { EngineFetch, HttpRequest } from '../../../network/types';
|
|
4
4
|
import type { FileAttachment } from '../../../plugins/files/attachment';
|
|
5
5
|
import type { FileProviderAdapter, FileUploadResult, RemoteFileInfo } from '../../../plugins/files/provider-adapter';
|
|
6
6
|
export interface AnthropicFileAdapterConfig {
|
|
@@ -15,7 +15,18 @@ export declare class AnthropicFileAdapter implements FileProviderAdapter {
|
|
|
15
15
|
private readonly apiKey;
|
|
16
16
|
private readonly baseURL;
|
|
17
17
|
constructor(config: AnthropicFileAdapterConfig);
|
|
18
|
-
|
|
18
|
+
/** File rules need no adapter handles. */
|
|
19
|
+
private readonly wireRegistry;
|
|
20
|
+
/** Build one file request from its spec, then add the engine metadata.
|
|
21
|
+
*
|
|
22
|
+
* A multipart spec describes the FIELDS but not the bytes, so an upload passes
|
|
23
|
+
* its attachment in and the descriptor is filled here. `bodyKind: none` arrives
|
|
24
|
+
* as `noBody`; the engine wants the field simply absent. */
|
|
25
|
+
private fromSpec;
|
|
26
|
+
buildUploadRequest(file: FileAttachment, data: Uint8Array): HttpRequest;
|
|
27
|
+
buildDeleteRequest(remoteId: string): HttpRequest;
|
|
28
|
+
buildGetInfoRequest(remoteId: string): HttpRequest;
|
|
29
|
+
buildListRequest(): HttpRequest;
|
|
19
30
|
upload(file: FileAttachment, fetch: EngineFetch): Promise<FileUploadResult>;
|
|
20
31
|
delete(remoteId: string, fetch: EngineFetch): Promise<void>;
|
|
21
32
|
getInfo(remoteId: string, fetch: EngineFetch): Promise<RemoteFileInfo | null>;
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* of CompletionRequest (same shape, renamed for v2 to reflect it's the
|
|
5
5
|
* internal normalized form LLMClient hands to the adapter). */
|
|
6
6
|
import type { SSEEvent } from '../../../network/types';
|
|
7
|
+
import type { ContentPart } from '../../types/messages';
|
|
7
8
|
import type { ProviderAdapter, ProviderHttpRequest } from '../../types/provider';
|
|
8
9
|
import type { NormalizedRequest } from '../../types/request';
|
|
9
10
|
import { type CompletionResponse } from '../../types/response';
|
|
@@ -19,10 +20,26 @@ export declare class AnthropicAdapter implements ProviderAdapter {
|
|
|
19
20
|
constructor(config: AnthropicAdapterConfig);
|
|
20
21
|
authHeaders(): Record<string, string>;
|
|
21
22
|
baseURL(): string;
|
|
23
|
+
/** Named code the spec cannot express as data — message and content assembly.
|
|
24
|
+
* Built once, carrying only this adapter, since only Anthropic rules run. */
|
|
25
|
+
private readonly wireRegistry;
|
|
22
26
|
completionPath(): string;
|
|
27
|
+
/** The spec that builds this model's request.
|
|
28
|
+
*
|
|
29
|
+
* The catalog pin decides when there is one. Without it — an engine running
|
|
30
|
+
* with no catalog, or a model released after this build — the band comes from
|
|
31
|
+
* the pin TABLE, which is data (`src/wire/pins/`) rather than version
|
|
32
|
+
* arithmetic in TypeScript, so the Python and Rust ports derive the same node
|
|
33
|
+
* from the same file instead of each re-implementing it. */
|
|
34
|
+
private specIdFor;
|
|
23
35
|
buildRequest(req: NormalizedRequest): ProviderHttpRequest;
|
|
24
36
|
enableStreaming(providerReq: ProviderHttpRequest, _req: NormalizedRequest): void;
|
|
25
|
-
|
|
37
|
+
/** Reached through the wire registry while building this adapter's own request. */
|
|
38
|
+
buildMessage(msg: {
|
|
39
|
+
role: string;
|
|
40
|
+
content: string | ContentPart[];
|
|
41
|
+
cache?: boolean;
|
|
42
|
+
}, _req: NormalizedRequest, forceCache?: boolean): Record<string, unknown>;
|
|
26
43
|
private buildContentPart;
|
|
27
44
|
parseResponse(raw: unknown, latencyMs: number): CompletionResponse;
|
|
28
45
|
parseStreamEvent(event: SSEEvent): StreamEvent[];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** Google batch adapter — inline batchGenerateContent.
|
|
2
2
|
* All HTTP flows through the injected EngineFetch (NetworkEngine queue). */
|
|
3
|
-
import type { EngineFetch } from '../../../network/types';
|
|
3
|
+
import type { EngineFetch, HttpRequest } from '../../../network/types';
|
|
4
4
|
import type { BatchProviderAdapter, BatchRequest, BatchResult, BatchStatus } from '../../../plugins/batch/types';
|
|
5
5
|
export interface GoogleBatchAdapterConfig {
|
|
6
6
|
apiKey: string;
|
|
@@ -13,6 +13,19 @@ export declare class GoogleBatchAdapter implements BatchProviderAdapter {
|
|
|
13
13
|
private readonly model;
|
|
14
14
|
private readonly baseURL;
|
|
15
15
|
constructor(config: GoogleBatchAdapterConfig);
|
|
16
|
+
/** Batch rules need no adapter handles: the request list is mapped by the spec. */
|
|
17
|
+
private readonly wireRegistry;
|
|
18
|
+
/** Build one batch request from its spec, then add the engine metadata.
|
|
19
|
+
*
|
|
20
|
+
* `bodyKind: none` in a spec means no body at all: the interpreter reports that
|
|
21
|
+
* as `noBody`, and the engine wants the field simply absent. */
|
|
22
|
+
private fromSpec;
|
|
23
|
+
buildSubmitRequest(requests: BatchRequest[]): HttpRequest;
|
|
24
|
+
buildStatusRequest(batchId: string): HttpRequest;
|
|
25
|
+
buildCancelRequest(batchId: string): HttpRequest;
|
|
26
|
+
/** Google returns results inline on the batch resource, so this is the same
|
|
27
|
+
* wire as getStatus - two operations that happen to share one request. */
|
|
28
|
+
buildResultsRequest(batchId: string): HttpRequest;
|
|
16
29
|
submit(requests: BatchRequest[], fetch: EngineFetch): Promise<string>;
|
|
17
30
|
getStatus(batchId: string, fetch: EngineFetch): Promise<BatchStatus>;
|
|
18
31
|
getResults(batchId: string, fetch: EngineFetch): Promise<BatchResult[]>;
|
|
@@ -1,18 +1,9 @@
|
|
|
1
|
-
/** Google provider constants.
|
|
2
|
-
|
|
3
|
-
*
|
|
4
|
-
* `
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Map from unified thinking effort to a Gemini `thinkingBudget` (token count).
|
|
9
|
-
* Gemini **2.5** models only accept a token budget — they 400 on `thinkingLevel`
|
|
10
|
-
* ("Thinking level is not supported for this model", live-verified 2026-07-16).
|
|
11
|
-
* Values sit inside the 2.5 range (flash/flash-lite cap ~24576, pro ~32768).
|
|
12
|
-
*/
|
|
13
|
-
export declare const GOOGLE_THINKING_BUDGETS: Record<string, number>;
|
|
14
|
-
/** Gemini 2.5 series uses `thinkingBudget`; 3.x+ uses `thinkingLevel`. */
|
|
15
|
-
export declare function googleUsesThinkingBudget(model: string): boolean;
|
|
1
|
+
/** Google provider constants.
|
|
2
|
+
*
|
|
3
|
+
* The thinking-control tables and the 2.5-vs-3.x band test have moved into data:
|
|
4
|
+
* the effort maps are `$table`s in the chain specs, and the band is
|
|
5
|
+
* `src/wire/pins/google.generate.json`. Only the Interactions map remains here,
|
|
6
|
+
* because its lowercase enum is read by code the specs do not own. */
|
|
16
7
|
/**
|
|
17
8
|
* Effort → Interactions `thinking_level`. The Interactions API uses **lowercase**
|
|
18
9
|
* values (`minimal`/`low`/`medium`/`high`) — distinct from generateContent's
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** Google embeddings adapter — POST /v1beta/models/{model}:embedContent.
|
|
2
2
|
* One call per input text (batch via a simple loop). */
|
|
3
|
-
import type { EngineFetch } from '../../../network/types';
|
|
3
|
+
import type { EngineFetch, HttpRequest } from '../../../network/types';
|
|
4
4
|
import type { EmbedRequest, EmbedResult, EmbeddingProviderAdapter } from '../../../plugins/embeddings/types';
|
|
5
5
|
export interface GoogleEmbeddingAdapterConfig {
|
|
6
6
|
apiKey: string;
|
|
@@ -11,5 +11,12 @@ export declare class GoogleEmbeddingAdapter implements EmbeddingProviderAdapter
|
|
|
11
11
|
private readonly apiKey;
|
|
12
12
|
private readonly baseURL;
|
|
13
13
|
constructor(config: GoogleEmbeddingAdapterConfig);
|
|
14
|
+
/** One request, for ONE input text.
|
|
15
|
+
*
|
|
16
|
+
* Google embeds a single text per call, so `embed` loops and this builds one
|
|
17
|
+
* iteration. The spec's input context is `{ model, text }` accordingly. */
|
|
18
|
+
buildEmbedRequest(req: EmbedRequest, text: string): HttpRequest;
|
|
19
|
+
/** Named code the spec cannot express as data — the models/ path prefix. */
|
|
20
|
+
private readonly wireRegistry;
|
|
14
21
|
embed(req: EmbedRequest, fetch: EngineFetch): Promise<EmbedResult>;
|
|
15
22
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** Google file adapter — resumable upload to Files API. 48h auto-delete.
|
|
2
2
|
* All HTTP flows through the injected EngineFetch (NetworkEngine queue). */
|
|
3
|
-
import type { EngineFetch } from '../../../network/types';
|
|
3
|
+
import type { EngineFetch, HttpRequest } from '../../../network/types';
|
|
4
4
|
import type { FileAttachment } from '../../../plugins/files/attachment';
|
|
5
5
|
import type { FileProviderAdapter, FileUploadResult, RemoteFileInfo } from '../../../plugins/files/provider-adapter';
|
|
6
6
|
/** Reduce any form of Google file id to the bare name the REST path wants.
|
|
@@ -30,6 +30,24 @@ export declare class GoogleFileAdapter implements FileProviderAdapter {
|
|
|
30
30
|
private readonly apiKey;
|
|
31
31
|
private readonly baseURL;
|
|
32
32
|
constructor(config: GoogleFileAdapterConfig);
|
|
33
|
+
/** File rules need no adapter handles. */
|
|
34
|
+
private readonly wireRegistry;
|
|
35
|
+
/** Build one file request from its spec, then add the engine metadata.
|
|
36
|
+
*
|
|
37
|
+
* A multipart spec describes the FIELDS but not the bytes, so an upload passes
|
|
38
|
+
* its attachment in and the descriptor is filled here. `bodyKind: none` arrives
|
|
39
|
+
* as `noBody`; the engine wants the field simply absent. */
|
|
40
|
+
private fromSpec;
|
|
41
|
+
/** Step ONE of the resumable upload. The second call goes to a URL the server
|
|
42
|
+
* returns in a response header, so no spec can describe it — it stays here. */
|
|
43
|
+
buildStartUploadRequest(file: FileAttachment, byteLength: number): HttpRequest;
|
|
44
|
+
/** Step TWO of the resumable upload. The URL came back in a response header, so
|
|
45
|
+
* it is an INPUT to the spec rather than something the spec can build - the same
|
|
46
|
+
* way batchId is. */
|
|
47
|
+
buildFinishUploadRequest(uploadUrl: string, file: FileAttachment, data: Uint8Array): HttpRequest;
|
|
48
|
+
buildDeleteRequest(remoteId: string): HttpRequest;
|
|
49
|
+
buildGetInfoRequest(remoteId: string): HttpRequest;
|
|
50
|
+
buildListRequest(): HttpRequest;
|
|
33
51
|
upload(file: FileAttachment, fetch: EngineFetch): Promise<FileUploadResult>;
|
|
34
52
|
delete(remoteId: string, fetch: EngineFetch): Promise<void>;
|
|
35
53
|
getInfo(remoteId: string, fetch: EngineFetch): Promise<RemoteFileInfo | null>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/** Google Gemini provider adapter (generateContent API). */
|
|
2
2
|
import type { SSEEvent } from '../../../network/types';
|
|
3
|
+
import type { ContentPart } from '../../types/messages';
|
|
3
4
|
import type { ProviderAdapter, ProviderHttpRequest } from '../../types/provider';
|
|
4
5
|
import type { NormalizedRequest } from '../../types/request';
|
|
5
6
|
import { type CompletionResponse } from '../../types/response';
|
|
@@ -16,11 +17,24 @@ export declare class GoogleAdapter implements ProviderAdapter {
|
|
|
16
17
|
authHeaders(): Record<string, string>;
|
|
17
18
|
baseURL(): string;
|
|
18
19
|
completionPath(): string;
|
|
20
|
+
/** Named code the spec cannot express as data — content assembly. */
|
|
21
|
+
private readonly wireRegistry;
|
|
22
|
+
/** The spec that builds this model's request.
|
|
23
|
+
*
|
|
24
|
+
* Two nodes, keyed on the one thing that differs on the wire: 2.5 takes a token
|
|
25
|
+
* `thinkingBudget` and 400s on `thinkingLevel`, 3.x takes the level. Catalog pin
|
|
26
|
+
* first, then the pin TABLE — data rather than a regex in TypeScript, so the
|
|
27
|
+
* ports read the same rule. */
|
|
28
|
+
private specIdFor;
|
|
19
29
|
buildRequest(req: NormalizedRequest): ProviderHttpRequest;
|
|
20
30
|
enableStreaming(providerReq: ProviderHttpRequest, req: NormalizedRequest): void;
|
|
21
31
|
/** Map tool call IDs to function names (Google needs name in functionResponse) */
|
|
22
32
|
private toolCallNames;
|
|
23
|
-
|
|
33
|
+
/** Reached through the wire registry while building this adapter's own request. */
|
|
34
|
+
buildContent(msg: {
|
|
35
|
+
role: string;
|
|
36
|
+
content: string | ContentPart[];
|
|
37
|
+
}): Record<string, unknown>;
|
|
24
38
|
parseResponse(raw: unknown, latencyMs: number): CompletionResponse;
|
|
25
39
|
parseStreamEvent(event: SSEEvent): StreamEvent[];
|
|
26
40
|
/** Stateful — Google splits the code-execution marker (`executableCode` /
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* Modern API: input, system_instruction, outputs (plural), function_result,
|
|
4
4
|
* previous_interaction_id for stateful, 72h retention. */
|
|
5
5
|
import type { SSEEvent } from '../../../network/types';
|
|
6
|
+
import type { Message } from '../../types/messages';
|
|
6
7
|
import type { ProviderAdapter, ProviderHttpRequest } from '../../types/provider';
|
|
7
8
|
import type { NormalizedRequest } from '../../types/request';
|
|
8
9
|
import { type CompletionResponse } from '../../types/response';
|
|
@@ -19,8 +20,11 @@ export declare class GoogleInteractionsAdapter implements ProviderAdapter {
|
|
|
19
20
|
authHeaders(): Record<string, string>;
|
|
20
21
|
baseURL(): string;
|
|
21
22
|
completionPath(): string;
|
|
23
|
+
/** Named code the spec cannot express as data — input-item assembly. */
|
|
24
|
+
private readonly wireRegistry;
|
|
22
25
|
buildRequest(req: NormalizedRequest): ProviderHttpRequest;
|
|
23
|
-
|
|
26
|
+
/** Reached through the wire registry while building the request. */
|
|
27
|
+
buildInputItems(msg: Message): unknown[];
|
|
24
28
|
/** Track tool call IDs → names for function_result */
|
|
25
29
|
private toolCallNames;
|
|
26
30
|
enableStreaming(providerReq: ProviderHttpRequest): void;
|
|
@@ -12,22 +12,45 @@ export declare class GoogleMediaAdapter implements MediaProviderAdapter {
|
|
|
12
12
|
private readonly baseURL;
|
|
13
13
|
constructor(config: GoogleMediaAdapterConfig);
|
|
14
14
|
capabilities(): MediaCapabilities;
|
|
15
|
+
/** Named code the specs cannot express as data — image-source normalisation. */
|
|
16
|
+
private readonly wireRegistry;
|
|
17
|
+
/** Build one media request from its spec, then add the engine metadata.
|
|
18
|
+
*
|
|
19
|
+
* `provider`, `model` and `responseType` are engine concerns, not wire: nothing
|
|
20
|
+
* a provider sees, so the specs do not model them. Every Google media response
|
|
21
|
+
* is JSON, including Veo's operation handle and the base64 inline data. */
|
|
22
|
+
/** Build one media request from its spec, then add the engine metadata.
|
|
23
|
+
*
|
|
24
|
+
* `bodyKind: none` arrives as `noBody`; the engine wants the field absent. */
|
|
25
|
+
private fromSpec;
|
|
26
|
+
/** Veo returns a long-running operation; these poll and cancel it. */
|
|
27
|
+
buildOperationStatusRequest(operationId: string): HttpRequest;
|
|
28
|
+
buildOperationCancelRequest(operationId: string): HttpRequest;
|
|
29
|
+
/** Google appends the key to the download URI too, which is why fetching the
|
|
30
|
+
* generated bytes is a spec rather than a bare GET. */
|
|
31
|
+
buildDownloadRequest(downloadUrl: string): HttpRequest;
|
|
32
|
+
/** Imagen image generation: the Vertex-style `:predict` envelope. */
|
|
15
33
|
/** Imagen image generation: the Vertex-style `:predict` envelope. */
|
|
16
34
|
buildImagenRequest(req: ImageGenRequest, model?: string): HttpRequest;
|
|
17
35
|
/** The inline-media path shared by gemini image generation, editing and TTS. */
|
|
18
36
|
buildGenerateContentRequest(model: string, text: string, generationConfig: Record<string, unknown>, extraParts?: Array<Record<string, unknown>>): HttpRequest;
|
|
19
37
|
/** Veo video submission — a long-running operation, hence the endpoint. */
|
|
38
|
+
/** Veo video submission — a long-running operation, hence the endpoint. */
|
|
20
39
|
buildVideoRequest(req: VideoGenRequest, model?: string): HttpRequest;
|
|
21
|
-
/** `generationConfig` for the gemini image paths — generation and editing take
|
|
22
|
-
* the same one. */
|
|
23
|
-
private imageGenerationConfig;
|
|
24
40
|
/** The complete image request, whichever of the two Google image paths applies:
|
|
25
41
|
* Imagen models use `:predict`, gemini-* models generate inline via
|
|
26
42
|
* `:generateContent` steered by responseModalities. */
|
|
43
|
+
/** The complete image request, whichever of the two Google image paths applies.
|
|
44
|
+
*
|
|
45
|
+
* Imagen models use `:predict`; gemini-* models generate inline via
|
|
46
|
+
* `:generateContent` steered by responseModalities. Different endpoint, body and
|
|
47
|
+
* response — the fork is a genuine wire difference, not a preference. */
|
|
27
48
|
buildImageRequest(req: ImageGenRequest, model?: string): HttpRequest;
|
|
28
49
|
/** Gemini TTS: the same inline path with an AUDIO modality and a speechConfig. */
|
|
50
|
+
/** Gemini TTS: the inline path with an AUDIO modality and a speechConfig. */
|
|
29
51
|
buildAudioRequest(req: AudioGenRequest, model?: string): HttpRequest;
|
|
30
52
|
/** Image-to-image edit: image generation plus the source image as a second part. */
|
|
53
|
+
/** Image-to-image edit: image generation plus the source image as a second part. */
|
|
31
54
|
buildEditImageRequest(req: ImageEditRequest, model?: string): HttpRequest;
|
|
32
55
|
generateImage(req: ImageGenRequest, fetch: EngineFetch): Promise<RawMediaResult[]>;
|
|
33
56
|
generateAudio(req: AudioGenRequest, fetch: EngineFetch): Promise<RawMediaResult>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** OpenAI batch adapter — upload JSONL file, create batch, poll, download results.
|
|
2
2
|
* All HTTP flows through the injected EngineFetch (NetworkEngine queue). */
|
|
3
|
-
import type { EngineFetch } from '../../../network/types';
|
|
3
|
+
import type { EngineFetch, HttpRequest } from '../../../network/types';
|
|
4
4
|
import type { BatchProviderAdapter, BatchRequest, BatchResult, BatchStatus } from '../../../plugins/batch/types';
|
|
5
5
|
export interface OpenAIBatchAdapterConfig {
|
|
6
6
|
apiKey: string;
|
|
@@ -11,7 +11,24 @@ export declare class OpenAIBatchAdapter implements BatchProviderAdapter {
|
|
|
11
11
|
private readonly apiKey;
|
|
12
12
|
private readonly baseURL;
|
|
13
13
|
constructor(config: OpenAIBatchAdapterConfig);
|
|
14
|
-
|
|
14
|
+
/** Batch rules need no adapter handles: the request list is mapped by the spec. */
|
|
15
|
+
private readonly wireRegistry;
|
|
16
|
+
/** Build one batch request from its spec, then add the engine metadata.
|
|
17
|
+
*
|
|
18
|
+
* `bodyKind: none` in a spec means no body at all: the interpreter reports that
|
|
19
|
+
* as `noBody`, and the engine wants the field simply absent. */
|
|
20
|
+
private fromSpec;
|
|
21
|
+
/** The FIRST call of submit: the requests go up as a JSONL file. The spec names
|
|
22
|
+
* the multipart fields; the bytes are the serialised batch. */
|
|
23
|
+
buildUploadJsonlRequest(jsonl: string): HttpRequest;
|
|
24
|
+
/** The SECOND call of submit: the JSONL is uploaded first, then the batch is
|
|
25
|
+
* created referencing that file id. */
|
|
26
|
+
buildCreateRequest(fileId: string): HttpRequest;
|
|
27
|
+
buildStatusRequest(batchId: string): HttpRequest;
|
|
28
|
+
buildCancelRequest(batchId: string): HttpRequest;
|
|
29
|
+
/** The SECOND call of the results flow: the output file is JSONL, so it decodes
|
|
30
|
+
* as text. The first call is buildStatusRequest, which yields the file id. */
|
|
31
|
+
buildResultsFileRequest(fileId: string): HttpRequest;
|
|
15
32
|
submit(requests: BatchRequest[], fetch: EngineFetch): Promise<string>;
|
|
16
33
|
getStatus(batchId: string, fetch: EngineFetch): Promise<BatchStatus>;
|
|
17
34
|
getResults(batchId: string, fetch: EngineFetch): Promise<BatchResult[]>;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
/** OpenAI provider adapter (Chat Completions API). */
|
|
2
2
|
import type { SSEEvent } from '../../../network/types';
|
|
3
|
+
import type { Registry } from '../../../wire/interpreter';
|
|
4
|
+
import type { ContentPart } from '../../types/messages';
|
|
3
5
|
import type { ProviderAdapter, ProviderHttpRequest } from '../../types/provider';
|
|
4
6
|
import type { NormalizedRequest } from '../../types/request';
|
|
5
7
|
import { type CompletionResponse } from '../../types/response';
|
|
@@ -22,6 +24,12 @@ export declare class OpenAIAdapter implements ProviderAdapter {
|
|
|
22
24
|
authHeaders(): Record<string, string>;
|
|
23
25
|
baseURL(): string;
|
|
24
26
|
completionPath(): string;
|
|
27
|
+
/** Named code the spec cannot express as data — message/input assembly. Carries
|
|
28
|
+
* `this`, so a subclass drives the same rules with its own overrides. */
|
|
29
|
+
protected readonly wireRegistry: Registry;
|
|
30
|
+
/** Which flavor overlay patches the shared spec. Subclasses for
|
|
31
|
+
* OpenAI-compatible backends override this and nothing else. */
|
|
32
|
+
protected readonly wireFlavor: string;
|
|
25
33
|
buildRequest(req: NormalizedRequest): ProviderHttpRequest;
|
|
26
34
|
/** One universal message can become SEVERAL chat-completions messages.
|
|
27
35
|
*
|
|
@@ -31,7 +39,11 @@ export declare class OpenAIAdapter implements ProviderAdapter {
|
|
|
31
39
|
* the rest unanswered and the provider rejected the whole request with
|
|
32
40
|
* "No tool output found for function call <id>" — so parallel tools were broken on
|
|
33
41
|
* every chat-completions backend. */
|
|
34
|
-
|
|
42
|
+
/** Reached through the wire registry while building the request. */
|
|
43
|
+
buildMessages(msg: {
|
|
44
|
+
role: string;
|
|
45
|
+
content: string | ContentPart[];
|
|
46
|
+
}): Record<string, unknown>[];
|
|
35
47
|
private buildMessage;
|
|
36
48
|
enableStreaming(providerReq: ProviderHttpRequest, _req: NormalizedRequest): void;
|
|
37
49
|
parseResponse(raw: unknown, latencyMs: number): CompletionResponse;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/** OpenAI embeddings adapter — POST /v1/embeddings. Also the base for the
|
|
2
2
|
* OpenAI-compatible OpenRouter adapter. */
|
|
3
|
-
import type { EngineFetch } from '../../../network/types';
|
|
3
|
+
import type { EngineFetch, HttpRequest } from '../../../network/types';
|
|
4
|
+
import type { Registry } from '../../../wire/interpreter';
|
|
4
5
|
import type { EmbedRequest, EmbedResult, EmbeddingProviderAdapter } from '../../../plugins/embeddings/types';
|
|
5
6
|
export interface OpenAIEmbeddingAdapterConfig {
|
|
6
7
|
apiKey: string;
|
|
@@ -11,6 +12,17 @@ export declare class OpenAIEmbeddingAdapter implements EmbeddingProviderAdapter
|
|
|
11
12
|
protected readonly apiKey: string;
|
|
12
13
|
protected readonly _baseURL: string;
|
|
13
14
|
constructor(config: OpenAIEmbeddingAdapterConfig);
|
|
15
|
+
/** Named code the spec cannot express as data — the array coercion. */
|
|
16
|
+
protected readonly wireRegistry: Registry;
|
|
14
17
|
protected embeddingsPath(): string;
|
|
18
|
+
/** Which spec builds the request. OpenRouter is the same wire on a different
|
|
19
|
+
* host and path, expressed as a one-line override of this spec. */
|
|
20
|
+
protected specId(): string;
|
|
21
|
+
/** The request, built and inspectable without performing it.
|
|
22
|
+
*
|
|
23
|
+
* `input` is always an array on the wire even when the caller passes one
|
|
24
|
+
* string, which is the sort of rule that belongs in data rather than in a
|
|
25
|
+
* ternary nobody re-reads. */
|
|
26
|
+
buildEmbedRequest(req: EmbedRequest): HttpRequest;
|
|
15
27
|
embed(req: EmbedRequest, fetch: EngineFetch): Promise<EmbedResult>;
|
|
16
28
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** OpenAI file adapter — POST /v1/files.
|
|
2
2
|
* All HTTP flows through the injected EngineFetch (NetworkEngine queue). */
|
|
3
|
-
import type { EngineFetch } from '../../../network/types';
|
|
3
|
+
import type { EngineFetch, HttpRequest } from '../../../network/types';
|
|
4
4
|
import type { FileAttachment } from '../../../plugins/files/attachment';
|
|
5
5
|
import type { FileProviderAdapter, FileUploadResult, RemoteFileInfo } from '../../../plugins/files/provider-adapter';
|
|
6
6
|
export interface OpenAIFileAdapterConfig {
|
|
@@ -15,7 +15,18 @@ export declare class OpenAIFileAdapter implements FileProviderAdapter {
|
|
|
15
15
|
private readonly apiKey;
|
|
16
16
|
private readonly baseURL;
|
|
17
17
|
constructor(config: OpenAIFileAdapterConfig);
|
|
18
|
-
|
|
18
|
+
/** File rules need no adapter handles. */
|
|
19
|
+
private readonly wireRegistry;
|
|
20
|
+
/** Build one file request from its spec, then add the engine metadata.
|
|
21
|
+
*
|
|
22
|
+
* A multipart spec describes the FIELDS but not the bytes, so an upload passes
|
|
23
|
+
* its attachment in and the descriptor is filled here. `bodyKind: none` arrives
|
|
24
|
+
* as `noBody`; the engine wants the field simply absent. */
|
|
25
|
+
private fromSpec;
|
|
26
|
+
buildUploadRequest(file: FileAttachment, data: Uint8Array): Promise<HttpRequest>;
|
|
27
|
+
buildDeleteRequest(remoteId: string): Promise<HttpRequest>;
|
|
28
|
+
buildGetInfoRequest(remoteId: string): Promise<HttpRequest>;
|
|
29
|
+
buildListRequest(): Promise<HttpRequest>;
|
|
19
30
|
upload(file: FileAttachment, fetch: EngineFetch): Promise<FileUploadResult>;
|
|
20
31
|
delete(remoteId: string, fetch: EngineFetch): Promise<void>;
|
|
21
32
|
getInfo(remoteId: string, fetch: EngineFetch): Promise<RemoteFileInfo | null>;
|
|
@@ -13,16 +13,36 @@ export declare class OpenAIMediaAdapter implements MediaProviderAdapter {
|
|
|
13
13
|
private readonly baseURL;
|
|
14
14
|
constructor(config: OpenAIMediaAdapterConfig);
|
|
15
15
|
capabilities(): MediaCapabilities;
|
|
16
|
-
|
|
16
|
+
/** Named code the specs cannot express as data — image-source normalisation. */
|
|
17
|
+
private readonly wireRegistry;
|
|
18
|
+
/** Build one media request from its spec, then add the engine metadata.
|
|
19
|
+
*
|
|
20
|
+
* `provider`, `model` and `responseType` are NOT wire: the NetworkEngine routes
|
|
21
|
+
* and decodes with them and no provider ever sees them, so the specs do not
|
|
22
|
+
* model them and this layer keeps supplying them. */
|
|
23
|
+
private fromSpec;
|
|
17
24
|
/** Text-to-image. */
|
|
25
|
+
/** Text-to-image.
|
|
26
|
+
*
|
|
27
|
+
* The spec forks by family, and the fork is real: gpt-image-1 always returns
|
|
28
|
+
* b64_json and REJECTS `response_format`, while dall-e-3 / dall-e-2 still
|
|
29
|
+
* require it. */
|
|
18
30
|
buildGenerateImageRequest(req: ImageGenRequest, model?: string): HttpRequest;
|
|
19
31
|
/** Image-to-image edit. Generation's field set minus `style`, plus the source
|
|
20
32
|
* image and an optional mask. */
|
|
33
|
+
/** Image-to-image edit. */
|
|
21
34
|
buildEditImageRequest(req: ImageEditRequest, model?: string): HttpRequest;
|
|
22
35
|
/** TTS. `responseType` is arraybuffer because the response is audio bytes. */
|
|
36
|
+
/** TTS. `responseType` is arraybuffer because the response is audio bytes —
|
|
37
|
+
* transport decoding, which is the engine's business rather than the wire's. */
|
|
23
38
|
buildAudioRequest(req: AudioGenRequest, model: string): HttpRequest;
|
|
24
39
|
/** Sora video submission. `seconds` goes on the wire as a string. */
|
|
40
|
+
/** Sora video submission. */
|
|
25
41
|
buildVideoRequest(req: VideoGenRequest, model?: string): HttpRequest;
|
|
42
|
+
/** Poll a Sora job. */
|
|
43
|
+
buildVideoStatusRequest(videoId: string): HttpRequest;
|
|
44
|
+
/** Download the finished video: bytes, hence arraybuffer. */
|
|
45
|
+
buildVideoContentRequest(videoId: string): HttpRequest;
|
|
26
46
|
generateImage(req: ImageGenRequest, fetch: EngineFetch): Promise<RawMediaResult[]>;
|
|
27
47
|
/** Parse `/v1/images/{generations,edits}` response → RawMediaResult[], with
|
|
28
48
|
* the request-level usage attached to the first item (billed once). */
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Supports text and image+text content-part input as described in
|
|
3
3
|
* https://platform.openai.com/docs/api-reference/moderations/create
|
|
4
4
|
* All HTTP flows through the injected EngineFetch. */
|
|
5
|
-
import type { EngineFetch } from '../../../network/types';
|
|
5
|
+
import type { EngineFetch, HttpRequest } from '../../../network/types';
|
|
6
6
|
import type { ModerationContentPart, ModerationResult } from '../../../helpers/moderate-types';
|
|
7
7
|
export interface OpenAIModerationAdapterConfig {
|
|
8
8
|
apiKey: string;
|
|
@@ -15,5 +15,15 @@ export declare class OpenAIModerationAdapter {
|
|
|
15
15
|
private readonly apiKey;
|
|
16
16
|
private readonly baseURL;
|
|
17
17
|
constructor(config: OpenAIModerationAdapterConfig);
|
|
18
|
+
/** Named code these specs need. */
|
|
19
|
+
private readonly wireRegistry;
|
|
20
|
+
/** Build one request from its spec, then add the engine metadata.
|
|
21
|
+
*
|
|
22
|
+
* `bodyKind: none` arrives as `noBody` and `raw` as `rawBody`; the engine wants
|
|
23
|
+
* the body field absent in the first case and the caller's bytes in the second. */
|
|
24
|
+
private fromSpec;
|
|
25
|
+
/** Report-only classification. `input` reaches the wire untouched: string,
|
|
26
|
+
* array of strings, or content parts are all accepted. */
|
|
27
|
+
buildModerateRequest(input: string | string[] | ModerationContentPart | ModerationContentPart[], model: string): HttpRequest;
|
|
18
28
|
moderate(input: string | string[] | ModerationContentPart | ModerationContentPart[], model: string, fetch: EngineFetch): Promise<ModerationResult[]>;
|
|
19
29
|
}
|
|
@@ -24,6 +24,9 @@ export declare class OpenAIRealtimeAdapter implements RealtimeProviderAdapter {
|
|
|
24
24
|
* without opening a socket. Note the auth: OpenAI carries the key in a
|
|
25
25
|
* SUBPROTOCOL, not a header or query param, because browsers cannot set
|
|
26
26
|
* WebSocket headers. */
|
|
27
|
+
/** The WebSocket descriptor. Note the auth: OpenAI carries the key in a
|
|
28
|
+
* SUBPROTOCOL, not a header or query param, because browsers cannot set
|
|
29
|
+
* WebSocket headers — which is why the spec models `protocols` at all. */
|
|
27
30
|
buildConnectRequest(config: RealtimeSessionConfig): WsRequest;
|
|
28
31
|
connect(config: RealtimeSessionConfig, connect: EngineConnect): RealtimeSession;
|
|
29
32
|
}
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
* Modern API: input (not messages), instructions (not system role),
|
|
4
4
|
* output items (not choices), function_call/function_call_output for tools. */
|
|
5
5
|
import type { SSEEvent } from '../../../network/types';
|
|
6
|
-
import type { AssistantPhase } from '../../types/messages';
|
|
6
|
+
import type { AssistantPhase, Message } from '../../types/messages';
|
|
7
|
+
import type { Registry } from '../../../wire/interpreter';
|
|
7
8
|
import type { ProviderAdapter, ProviderHttpRequest } from '../../types/provider';
|
|
8
9
|
import type { NormalizedRequest } from '../../types/request';
|
|
9
10
|
import { type CompletionResponse, type FileOutput, type Usage } from '../../types/response';
|
|
@@ -20,10 +21,17 @@ export declare class OpenAIResponsesAdapter implements ProviderAdapter {
|
|
|
20
21
|
authHeaders(): Record<string, string>;
|
|
21
22
|
baseURL(): string;
|
|
22
23
|
completionPath(): string;
|
|
24
|
+
/** Named code the spec cannot express as data — message/input assembly. Carries
|
|
25
|
+
* `this`, so a subclass drives the same rules with its own overrides. */
|
|
26
|
+
protected readonly wireRegistry: Registry;
|
|
27
|
+
/** Which flavor overlay patches the shared spec. Subclasses for
|
|
28
|
+
* OpenAI-compatible backends override this and nothing else. */
|
|
29
|
+
protected readonly wireFlavor: string;
|
|
23
30
|
buildRequest(req: NormalizedRequest): ProviderHttpRequest;
|
|
24
31
|
/** Convert a universal Message to Responses API input items.
|
|
25
32
|
* `toolNames` is threaded across messages so a tool result can name its originating call. */
|
|
26
|
-
|
|
33
|
+
/** Reached through the wire registry while building the request. */
|
|
34
|
+
buildInputItems(msg: Message, toolNames?: Map<string, string>): unknown[];
|
|
27
35
|
enableStreaming(providerReq: ProviderHttpRequest): void;
|
|
28
36
|
parseResponse(raw: unknown, latencyMs: number): CompletionResponse;
|
|
29
37
|
parseStreamEvent(event: SSEEvent, phaseByItem?: Map<string, AssistantPhase>): StreamEvent[];
|