@combycode/llm-sdk 2.3.0 → 3.0.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 +373 -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 +8 -23
- 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/index.browser.js +17131 -4291
- package/dist/index.d.ts +1 -1
- package/dist/index.js +17131 -4291
- package/dist/llm/client-config.d.ts +8 -0
- package/dist/llm/client.d.ts +2 -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 +6 -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 +44 -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
|
@@ -62,13 +62,19 @@ export declare class HttpTransport extends BaseJsonRpcTransport implements McpTr
|
|
|
62
62
|
* two. The eventual JSON-RPC response has no pending entry to settle — its only meaning is "the
|
|
63
63
|
* stream ended", which is reported through `onEnd`. */
|
|
64
64
|
sendLongLivedRequest(method: string, params?: unknown, onEnd?: (error?: unknown) => void): Promise<number>;
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
*
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
65
|
+
/** The shared registry plus the two rules only MCP has. */
|
|
66
|
+
private readonly wireRegistry;
|
|
67
|
+
/** Build one MCP request from its spec.
|
|
68
|
+
*
|
|
69
|
+
* Everything that varies — the negotiated era, the session, the declared
|
|
70
|
+
* protocol version, a resolved bearer, the resumption cursor — is passed IN, so
|
|
71
|
+
* the spec decides which headers those facts produce. That decision used to be
|
|
72
|
+
* spread across three private helpers and the order in which their results were
|
|
73
|
+
* spread into an object literal.
|
|
74
|
+
*
|
|
75
|
+
* `provider` / `model` route and queue the call inside the NetworkEngine and are
|
|
76
|
+
* not part of the wire, so they wrap the spec's output. */
|
|
77
|
+
private request0;
|
|
72
78
|
private post;
|
|
73
79
|
}
|
|
74
80
|
/** Extract the JSON-RPC response matching `id` from a JSON or SSE body. */
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** The two MCP rules a spec cannot express as data, and where they live.
|
|
2
|
+
*
|
|
3
|
+
* Every other named spec rule sits in `src/llm/wire-transforms.ts`, but these
|
|
4
|
+
* cannot: `llm -> plugins` is a forbidden edge (the layer test names it), and MCP
|
|
5
|
+
* is a plugin. So the transport composes its own registry from the shared one
|
|
6
|
+
* rather than the shared one reaching down into MCP.
|
|
7
|
+
*
|
|
8
|
+
* Both are genuinely code rather than data:
|
|
9
|
+
*
|
|
10
|
+
* `mcpModern` — era is set only AFTER discovery succeeds, so a request has to be
|
|
11
|
+
* judged by the version it DECLARES as well. Keying on era alone left the
|
|
12
|
+
* `server/discover` probe itself half-modern, which a modern server rejects.
|
|
13
|
+
*
|
|
14
|
+
* `mcpNameHeader` — the subject lives under a different param per method (`name`
|
|
15
|
+
* for tools/call and prompts/get, `uri` for resources/read), so this is a lookup
|
|
16
|
+
* followed by a read at the key that lookup returned. A template can express a
|
|
17
|
+
* fixed path, not a computed one.
|
|
18
|
+
*/
|
|
19
|
+
import type { Registry } from '../../wire/interpreter';
|
|
20
|
+
/** Add the MCP rules to a base registry, leaving the base untouched. */
|
|
21
|
+
export declare function mcpWireRegistry(base: Registry): Registry;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** The upload part for a document: its bytes, and a name for them.
|
|
2
|
+
*
|
|
3
|
+
* All three hosted backends upload a document the same way — the text as a
|
|
4
|
+
* `text/plain` file — and all three had their own copy of this, which is how they
|
|
5
|
+
* came to disagree about nothing yet still had to be fixed three times.
|
|
6
|
+
*
|
|
7
|
+
* The fallback name is derived from the CONTENT. It used to be a random UUID,
|
|
8
|
+
* which made the request unreproducible: it could not be asserted in a test,
|
|
9
|
+
* frozen in a fixture, or matched against a log, and a retried upload arrived
|
|
10
|
+
* under a different name every time. A content hash keeps a retry idempotent
|
|
11
|
+
* while still separating two different documents.
|
|
12
|
+
*/
|
|
13
|
+
import type { MultipartFile } from '../../llm/wire-multipart';
|
|
14
|
+
import type { DocumentSource } from './types';
|
|
15
|
+
export declare function documentFile(source: DocumentSource): MultipartFile;
|
|
@@ -38,9 +38,14 @@ export declare class HostedGoogleRetrievalBackend implements RetrievalBackend {
|
|
|
38
38
|
private readonly fetch;
|
|
39
39
|
private readonly baseURL;
|
|
40
40
|
constructor(config: HostedGoogleRetrievalConfig);
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
/** File-search rules need no adapter handles. */
|
|
42
|
+
private readonly wireRegistry;
|
|
43
|
+
/** Build one file-search request from its spec, then add the engine metadata.
|
|
44
|
+
*
|
|
45
|
+
* `provider` / `model` / `responseType` route and queue the call inside the
|
|
46
|
+
* NetworkEngine; they are not part of the wire, so they wrap the spec's output
|
|
47
|
+
* rather than being described by it. */
|
|
48
|
+
private request;
|
|
44
49
|
createCorpus(opts: CreateCorpusOptions): Promise<CorpusRef>;
|
|
45
50
|
addDocument(corpus: CorpusRef, source: DocumentSource, opts?: AddDocumentOptions): Promise<DocumentRef>;
|
|
46
51
|
/** Poll a long-running Operation until done: true.
|
|
@@ -29,7 +29,15 @@ export declare class HostedOpenAIRetrievalBackend implements RetrievalBackend {
|
|
|
29
29
|
private readonly fetch;
|
|
30
30
|
private readonly baseURL;
|
|
31
31
|
constructor(config: HostedOpenAIRetrievalConfig);
|
|
32
|
-
|
|
32
|
+
/** Vector-store rules need no adapter handles. */
|
|
33
|
+
private readonly wireRegistry;
|
|
34
|
+
/** Build one vector-store request from its spec, then add the engine metadata.
|
|
35
|
+
*
|
|
36
|
+
* `provider` / `model` / `responseType` are how the NetworkEngine routes and
|
|
37
|
+
* queues the call — they are not part of the wire, so they are wrapped around
|
|
38
|
+
* the spec's output rather than described by it. A multipart spec names the
|
|
39
|
+
* fields but not the bytes, so an upload passes its file in here. */
|
|
40
|
+
private request;
|
|
33
41
|
createCorpus(opts: CreateCorpusOptions): Promise<CorpusRef>;
|
|
34
42
|
addDocument(corpus: CorpusRef, source: DocumentSource, opts?: AddDocumentOptions): Promise<DocumentRef>;
|
|
35
43
|
indexStatus(corpus: CorpusRef): Promise<IndexStatus>;
|
|
@@ -41,8 +41,14 @@ export declare class HostedXaiRetrievalBackend implements RetrievalBackend {
|
|
|
41
41
|
private readonly baseURL;
|
|
42
42
|
private readonly managementBaseURL;
|
|
43
43
|
constructor(config: HostedXaiRetrievalConfig);
|
|
44
|
-
|
|
45
|
-
private
|
|
44
|
+
/** Collection rules need no adapter handles. */
|
|
45
|
+
private readonly wireRegistry;
|
|
46
|
+
/** Build one collections request from its spec, then add the engine metadata.
|
|
47
|
+
*
|
|
48
|
+
* BOTH planes are handed to every spec: which host and which key a call uses is
|
|
49
|
+
* a property of the ENDPOINT, so the spec decides it rather than the caller
|
|
50
|
+
* picking a bearer helper and hoping it matches the URL it typed. */
|
|
51
|
+
private request;
|
|
46
52
|
createCorpus(opts: CreateCorpusOptions): Promise<CorpusRef>;
|
|
47
53
|
addDocument(corpus: CorpusRef, source: DocumentSource, opts?: AddDocumentOptions): Promise<DocumentRef>;
|
|
48
54
|
indexStatus(corpus: CorpusRef): Promise<IndexStatus>;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/** The wire specs the RUNTIME loads: chat only, resolved and memoised.
|
|
2
|
+
*
|
|
3
|
+
* Deliberately not `registry.ts`. That index imports all 71 specs — every media,
|
|
4
|
+
* realtime, files and batch spec included — so an adapter importing it would pull
|
|
5
|
+
* the whole set into every bundle whether or not anything reads them. Measured on
|
|
6
|
+
* the 2.3.0 build: interpreter + inherit + transforms is 18 KB minified, the nine
|
|
7
|
+
* chat specs add 15 KB, and all 71 specs add 41 KB. Chat-only is +2.7% on the
|
|
8
|
+
* bundle; everything is +4.8% for specs nothing executes yet.
|
|
9
|
+
*
|
|
10
|
+
* `registry.ts` stays as the complete index for the tests and the ports. This is
|
|
11
|
+
* the runtime's subset, and it grows a family at a time as each adapter is
|
|
12
|
+
* migrated — so what ships is always what runs.
|
|
13
|
+
*
|
|
14
|
+
* Chains are resolved once per id and cached: resolution walks `extends` and
|
|
15
|
+
* merges deltas, which is pure setup work and has no business happening per
|
|
16
|
+
* request.
|
|
17
|
+
*/
|
|
18
|
+
import type { WireSpec } from './interpreter';
|
|
19
|
+
/** The spec for `id`, with its inheritance chain already applied.
|
|
20
|
+
*
|
|
21
|
+
* Throws on an unknown id rather than falling back to something plausible: a
|
|
22
|
+
* silently-substituted spec is a wrong request sent confidently, which is the
|
|
23
|
+
* exact failure the specs exist to end. Callers pick the fallback themselves —
|
|
24
|
+
* see each adapter's DEFAULT_SPEC. */
|
|
25
|
+
export declare function chatSpec(id: string): WireSpec;
|
|
26
|
+
/** Whether a spec id is one the runtime can build. Lets an adapter fall back to
|
|
27
|
+
* its default instead of throwing when a catalog pin names a spec from a family
|
|
28
|
+
* that is not migrated yet. */
|
|
29
|
+
export declare const isChatSpec: (id: string | undefined) => id is string;
|
|
30
|
+
/** Ids the runtime carries — asserted by the tests so this list and the shipped
|
|
31
|
+
* spec files cannot drift apart unnoticed. */
|
|
32
|
+
export declare const CHAT_SPEC_IDS: readonly string[];
|
package/dist/wire/inherit.d.ts
CHANGED
|
@@ -32,10 +32,6 @@ export interface Deltas {
|
|
|
32
32
|
export type SpecDelta = Partial<WireSpec> & Deltas & {
|
|
33
33
|
id: string;
|
|
34
34
|
};
|
|
35
|
-
/** Apply one delta to a resolved spec. This is the whole of composition, and it
|
|
36
|
-
* is deliberately shared: a CHAIN picks the delta sequence by walking parents, a
|
|
37
|
-
* MATRIX picks it by selecting features. Behind the resolver they are the same
|
|
38
|
-
* operation — see `compose.ts`. */
|
|
39
35
|
export declare function applyDelta(base: WireSpec, delta: SpecDelta): WireSpec;
|
|
40
36
|
/** Resolve a spec id to its fully flattened form by walking `extends`. */
|
|
41
37
|
export declare function resolveSpec(id: string, byId: Map<string, SpecDelta>, seen?: Set<string>): WireSpec;
|
|
@@ -108,12 +108,43 @@ export interface WireSpec {
|
|
|
108
108
|
/** `json` (default), `multipart`, or `none` for GET/DELETE with no body.
|
|
109
109
|
* Multipart matters: a FormData body JSON-stringifies to `{}`, so comparing
|
|
110
110
|
* it as JSON would pass vacuously no matter what the fields are. */
|
|
111
|
-
|
|
111
|
+
/** `json` (default), `multipart`, `none` for a bodyless GET/DELETE, or
|
|
112
|
+
* `raw` when the body is caller-supplied BYTES the spec cannot describe —
|
|
113
|
+
* a file being streamed to an upload session. The spec still owns the URL,
|
|
114
|
+
* method and headers; only the payload comes from outside. */
|
|
115
|
+
bodyKind?: 'json' | 'multipart' | 'none' | 'raw' | 'form';
|
|
116
|
+
/** Headers in declaration order. An entry with `spread` merges an evaluated
|
|
117
|
+
* OBJECT of headers instead of setting one, which is what a caller-supplied
|
|
118
|
+
* header map or a resolved auth bundle is. Order is the whole point: it is
|
|
119
|
+
* what decides whether a configured `accept` overrides the default one or the
|
|
120
|
+
* other way round, and that was previously a property of which spread came
|
|
121
|
+
* later in a hand-written object literal. */
|
|
112
122
|
headers?: {
|
|
123
|
+
name?: string;
|
|
124
|
+
value?: Json;
|
|
125
|
+
when?: Cond;
|
|
126
|
+
spread?: Json;
|
|
127
|
+
}[];
|
|
128
|
+
/** Query parameters, appended to `url` (or `path`) in declaration order.
|
|
129
|
+
*
|
|
130
|
+
* Splicing them into the URL with `$join` works only while every parameter is
|
|
131
|
+
* present: `$join` propagates an omitted part, so one absent `pageToken` takes
|
|
132
|
+
* the whole URL with it. Declaring them separately lets a parameter drop out
|
|
133
|
+
* on its own, and puts the encoding in ONE place — the hand-written adapters
|
|
134
|
+
* disagreed about whether to call `encodeURIComponent`, which is how a page
|
|
135
|
+
* token with a `+` in it silently paged from the wrong place. */
|
|
136
|
+
query?: {
|
|
113
137
|
name: string;
|
|
114
138
|
value: Json;
|
|
115
139
|
when?: Cond;
|
|
116
140
|
}[];
|
|
141
|
+
/** How query values are escaped. `component` (default) percent-escapes
|
|
142
|
+
* everything, including a space as `%20`. `form` uses the
|
|
143
|
+
* application/x-www-form-urlencoded rules, where a space is `+` — which is
|
|
144
|
+
* what RFC 6749 prescribes for an OAuth authorization request, and what its
|
|
145
|
+
* servers are used to receiving. Both decode to the same string; they are not
|
|
146
|
+
* the same bytes, and a signature over the request would notice. */
|
|
147
|
+
queryEncoding?: 'component' | 'form';
|
|
117
148
|
};
|
|
118
149
|
/** Model-id → variant flags. The migration target is a catalog pin; the
|
|
119
150
|
* `idMatch` form is what today's regex helpers do, expressed as data.
|
|
@@ -141,6 +172,11 @@ export interface WireSpec {
|
|
|
141
172
|
value?: Json;
|
|
142
173
|
file?: boolean;
|
|
143
174
|
when?: Cond;
|
|
175
|
+
/** Emit ONE field per array element instead of a single array-valued
|
|
176
|
+
* field. Real forms use repeated keys for lists — OpenAI's transcription
|
|
177
|
+
* takes `languages[]` once per language — and a single field holding an
|
|
178
|
+
* array is a different request the server will not accept. */
|
|
179
|
+
repeat?: boolean;
|
|
144
180
|
}[];
|
|
145
181
|
/** Non-HTTP surfaces. A realtime session is not one request: it is a
|
|
146
182
|
* connection descriptor plus a sequence of outbound frames, so those are
|
|
@@ -205,8 +241,15 @@ export interface BuiltRequest {
|
|
|
205
241
|
path?: string;
|
|
206
242
|
url?: string;
|
|
207
243
|
method?: string;
|
|
244
|
+
/** The body is caller-supplied bytes (bodyKind 'raw'). */
|
|
245
|
+
rawBody?: boolean;
|
|
208
246
|
/** Present instead of a JSON body when bodyKind is 'multipart'. */
|
|
209
247
|
multipart?: MultipartField[];
|
|
248
|
+
/** The body is form-urlencoded: `body` holds the FIELDS, and the caller encodes
|
|
249
|
+
* them. Same split as multipart — the spec says what the form carries, the
|
|
250
|
+
* runtime does the encoding, and the frozen fixture stays readable as fields
|
|
251
|
+
* rather than as one percent-escaped string. */
|
|
252
|
+
formBody?: boolean;
|
|
210
253
|
/** True when the spec declares the request carries no body at all. */
|
|
211
254
|
noBody?: boolean;
|
|
212
255
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** The MCP Streamable-HTTP spec family.
|
|
2
|
+
*
|
|
3
|
+
* A sibling of the provider families, loaded separately for the same reason: an
|
|
4
|
+
* application that never talks to an MCP server should not carry these, and the
|
|
5
|
+
* generated `registry.ts` imports everything.
|
|
6
|
+
*
|
|
7
|
+
* MCP is the case that shows the spec format is about NETWORKING rather than about
|
|
8
|
+
* LLM providers — a JSON-RPC envelope, era-dependent routing headers and a
|
|
9
|
+
* long-lived stream are described by the same six constructs a chat request uses.
|
|
10
|
+
*/
|
|
11
|
+
import type { WireSpec } from './interpreter';
|
|
12
|
+
/** Resolve an MCP spec by id, flattening its `extends` chain. */
|
|
13
|
+
export declare function mcpSpec(id: string): WireSpec;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/** The media wire specs the RUNTIME loads, resolved and memoised.
|
|
2
|
+
*
|
|
3
|
+
* A sibling of `chat-specs.ts` and separate from it for the same reason that file
|
|
4
|
+
* is separate from `registry.ts`: the generated index imports all 71 specs, so any
|
|
5
|
+
* adapter reaching for it pulls in every family whether or not anything runs them.
|
|
6
|
+
* The runtime loads one family at a time, as each is migrated, so what ships is
|
|
7
|
+
* what executes.
|
|
8
|
+
*
|
|
9
|
+
* Only the leaves are exported — the `*.base` specs exist to be inherited from and
|
|
10
|
+
* are never built directly, so naming one is a mistake worth catching.
|
|
11
|
+
*/
|
|
12
|
+
import type { WireSpec } from './interpreter';
|
|
13
|
+
/** The media spec for `id`, with its inheritance chain applied.
|
|
14
|
+
*
|
|
15
|
+
* Throws on an unknown or abstract id rather than substituting something
|
|
16
|
+
* plausible: a quietly wrong endpoint is the failure mode the specs exist to end. */
|
|
17
|
+
export declare function mediaSpec(id: string): WireSpec;
|
|
18
|
+
/** Buildable media spec ids — asserted by the tests so this list and the shipped
|
|
19
|
+
* spec files cannot drift apart unnoticed. */
|
|
20
|
+
export declare const MEDIA_SPEC_IDS: readonly string[];
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/** Which spec builds a model's request when the catalog has no pin for it.
|
|
2
|
+
*
|
|
3
|
+
* Every catalogued model carries an explicit `wireSpec`, so this only decides for
|
|
4
|
+
* the models the catalog does not know: one released after this build, or an
|
|
5
|
+
* engine running without a catalog at all. That case is not an edge — it is how
|
|
6
|
+
* the SDK works on the day a provider ships something new — so it keeps a real
|
|
7
|
+
* answer rather than a guess.
|
|
8
|
+
*
|
|
9
|
+
* It is DATA, not code, for the same reason the specs are: the Python and Rust
|
|
10
|
+
* ports read this file instead of each re-implementing version arithmetic and
|
|
11
|
+
* drifting from it. Two versions of that arithmetic is exactly how the 2.2.1
|
|
12
|
+
* regression happened.
|
|
13
|
+
*
|
|
14
|
+
* Rules are ordered and the first match wins; `default` answers everything else.
|
|
15
|
+
*/
|
|
16
|
+
export interface PinRule {
|
|
17
|
+
/** Anchored regular expression, matched against the model id. */
|
|
18
|
+
match: string;
|
|
19
|
+
spec: string;
|
|
20
|
+
/** Why this band exists. Read by humans, not by the resolver. */
|
|
21
|
+
why?: string;
|
|
22
|
+
}
|
|
23
|
+
export interface ModelPins {
|
|
24
|
+
id: string;
|
|
25
|
+
rules?: PinRule[];
|
|
26
|
+
default: string;
|
|
27
|
+
}
|
|
28
|
+
/** The spec id for `model`, from an ordered rule table.
|
|
29
|
+
*
|
|
30
|
+
* The id is lower-cased and stripped of a `provider/` prefix first, because a
|
|
31
|
+
* caller may legitimately pass either form and a band must not depend on which. */
|
|
32
|
+
export declare function pinFor(model: string, pins: ModelPins): string;
|
|
33
|
+
export declare const ANTHROPIC_MESSAGE_PINS: ModelPins;
|
|
34
|
+
export declare const GOOGLE_GENERATE_PINS: ModelPins;
|
package/dist/wire/registry.d.ts
CHANGED
|
@@ -5,11 +5,13 @@
|
|
|
5
5
|
* is consumed by this SDK and by the Python and Rust ports, and a provider
|
|
6
6
|
* change is one reviewable diff rather than three code changes.
|
|
7
7
|
*
|
|
8
|
-
*
|
|
8
|
+
* GENERATED by scripts/gen-wire-registry.ts — do not hand-edit. Add a spec by
|
|
9
|
+
* dropping the JSON into src/wire/specs/ and running `bun run gen:registry`.
|
|
9
10
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
11
|
+
* This index is what the chain tests and the coverage audit enumerate. The
|
|
12
|
+
* ADAPTERS do not read it: each family has its own loader (chat-specs,
|
|
13
|
+
* media-specs, service-specs, retrieval-specs) so a chat call does not drag
|
|
14
|
+
* every batch and media spec into the bundle.
|
|
13
15
|
*/
|
|
14
16
|
import type { SpecDelta } from './inherit';
|
|
15
17
|
/** All shipped specs, keyed by `provider/api@version` id. */
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** The hosted-retrieval spec family: vector stores, file search stores, collections.
|
|
2
|
+
*
|
|
3
|
+
* A sibling of `chat-specs.ts`, `media-specs.ts` and `service-specs.ts`, split for
|
|
4
|
+
* the same reason: the generated `registry.ts` imports all 118 specs, so anything
|
|
5
|
+
* reaching for it drags every family into the bundle. An application that never
|
|
6
|
+
* builds a corpus should not carry these.
|
|
7
|
+
*
|
|
8
|
+
* Only leaves are buildable. The base specs exist to be inherited from — they
|
|
9
|
+
* carry auth and content-type and produce no endpoint of their own — so naming
|
|
10
|
+
* one is a mistake to catch, not a request to send.
|
|
11
|
+
*/
|
|
12
|
+
import type { WireSpec } from './interpreter';
|
|
13
|
+
/** Resolve a retrieval spec by id, flattening its `extends` chain. */
|
|
14
|
+
export declare function retrievalSpec(id: string): WireSpec;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** The remaining runtime spec families: embeddings, realtime, batch, files, and
|
|
2
|
+
* the media adapters that had no builder seam until now.
|
|
3
|
+
*
|
|
4
|
+
* A sibling of `chat-specs.ts` and `media-specs.ts`, split for the same reason:
|
|
5
|
+
* the generated `registry.ts` imports all 71 specs, so an adapter reaching for it
|
|
6
|
+
* drags every family into the bundle whether or not anything executes them. Each
|
|
7
|
+
* file here loads exactly what its adapters run.
|
|
8
|
+
*
|
|
9
|
+
* Only leaves are buildable. The `*.base` specs exist to be inherited from and
|
|
10
|
+
* produce no endpoint of their own, so naming one is a mistake to catch rather
|
|
11
|
+
* than a request to send.
|
|
12
|
+
*/
|
|
13
|
+
import type { WireSpec } from './interpreter';
|
|
14
|
+
/** The service spec for `id`, with its inheritance chain applied. Throws on an
|
|
15
|
+
* unknown or abstract id rather than substituting something plausible. */
|
|
16
|
+
export declare function serviceSpec(id: string): WireSpec;
|
|
17
|
+
/** Buildable ids, asserted by the tests so this list cannot drift from the files. */
|
|
18
|
+
export declare const SERVICE_SPEC_IDS: readonly string[];
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** The utility spec family: exact token counting, live model listing, file
|
|
2
|
+
* content retrieval, and the provenance check.
|
|
3
|
+
*
|
|
4
|
+
* Four small surfaces that share nothing except being requests. They are loaded
|
|
5
|
+
* together because each is a handful of specs and no consumer reaches one without
|
|
6
|
+
* reaching the layer that owns it.
|
|
7
|
+
*/
|
|
8
|
+
import type { WireSpec } from './interpreter';
|
|
9
|
+
/** Resolve a utility spec by id, flattening its `extends` chain. */
|
|
10
|
+
export declare function utilitySpec(id: string): WireSpec;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@combycode/llm-sdk",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "Unified, pluggable AI SDK for accessing the LLMs of every major provider (Anthropic, OpenAI, Google, xAI, OpenRouter) through one API. Cross-environment: Node, Bun, and the browser.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -43,8 +43,11 @@
|
|
|
43
43
|
"format": "biome format --write src tests",
|
|
44
44
|
"check": "biome check src tests",
|
|
45
45
|
"check:fix": "biome check --write src tests",
|
|
46
|
+
"gen:registry": "bun run scripts/gen-wire-registry.ts",
|
|
46
47
|
"gate": "bun run scripts/gate.ts",
|
|
47
48
|
"gate:selftest": "node ../../quality-gate/selftest.mjs",
|
|
49
|
+
"record:responses": "bun run scripts/record-responses.ts",
|
|
50
|
+
"derive:shapes": "bun run scripts/derive-response-shapes.ts",
|
|
48
51
|
"gate:snapshot": "bun run scripts/gate.ts --only api-snapshot --update"
|
|
49
52
|
},
|
|
50
53
|
"devDependencies": {
|