@combycode/llm-sdk 3.2.1 → 3.3.1
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 +216 -0
- package/dist/catalog/catalog.d.ts +14 -1
- package/dist/index.browser.js +5428 -1665
- package/dist/index.js +5428 -1665
- package/dist/llm/client-internal.d.ts +3 -1
- package/dist/llm/client.d.ts +10 -0
- package/dist/llm/providers/anthropic/messages.d.ts +32 -7
- package/dist/llm/providers/anthropic/response-registry.d.ts +2 -0
- package/dist/llm/providers/anthropic/stream-registry.d.ts +2 -0
- package/dist/llm/providers/google/generate.d.ts +7 -8
- package/dist/llm/providers/google/interactions-registry.d.ts +2 -0
- package/dist/llm/providers/google/interactions-stream-registry.d.ts +2 -0
- package/dist/llm/providers/google/interactions.d.ts +7 -5
- package/dist/llm/providers/google/response-registry.d.ts +2 -0
- package/dist/llm/providers/google/stream-registry.d.ts +2 -0
- package/dist/llm/providers/openai/completions.d.ts +21 -3
- package/dist/llm/providers/openai/response-registry.d.ts +2 -0
- package/dist/llm/providers/openai/responses-registry.d.ts +2 -0
- package/dist/llm/providers/openai/responses-stream-registry.d.ts +2 -0
- package/dist/llm/providers/openai/responses.d.ts +31 -3
- package/dist/llm/providers/openai/stream-registry.d.ts +2 -0
- package/dist/llm/providers/openrouter/completions.d.ts +11 -7
- package/dist/llm/providers/openrouter/response-registry.d.ts +2 -0
- package/dist/llm/providers/openrouter/stream-registry.d.ts +2 -0
- package/dist/llm/providers/response-registries.d.ts +5 -0
- package/dist/llm/providers/xai/completions.d.ts +1 -4
- package/dist/llm/providers/xai/responses-registry.d.ts +2 -0
- package/dist/llm/providers/xai/responses.d.ts +12 -0
- package/dist/llm/providers/xai/stream-registry.d.ts +2 -0
- package/dist/plugins/context-guard/facts.d.ts +9 -0
- package/dist/plugins/context-guard/tools.d.ts +3 -0
- package/dist/plugins/context-guard/types.d.ts +5 -0
- package/dist/util/audio-mime.d.ts +16 -0
- package/dist/util/compare.d.ts +13 -0
- package/dist/wire/interpreter.d.ts +2 -0
- package/dist/wire/response-interpreter.d.ts +156 -0
- package/dist/wire/response-specs.d.ts +7 -0
- package/dist/wire/stream-interpreter.d.ts +94 -0
- package/dist/wire/stream-specs.d.ts +8 -0
- package/package.json +4 -4
|
@@ -46,5 +46,7 @@ export interface ClientRouting {
|
|
|
46
46
|
readonly cacheName: string;
|
|
47
47
|
}
|
|
48
48
|
export declare function buildContext(client: LLMClient, options: ExecuteOptions): RequestContext;
|
|
49
|
-
export declare function resolveApi(provider: ProviderName, api?: ApiType | 'auto'
|
|
49
|
+
export declare function resolveApi(provider: ProviderName, api?: ApiType | 'auto',
|
|
50
|
+
/** The catalog's per-model preference, when the model is a known one. */
|
|
51
|
+
preferred?: ApiType | null): ApiType;
|
|
50
52
|
export declare function resolveAdapter(config: LLMClientConfig, api: ApiType): ProviderAdapter;
|
package/dist/llm/client.d.ts
CHANGED
|
@@ -88,6 +88,16 @@ export declare class LLMClient {
|
|
|
88
88
|
/** Anything the spec left out on purpose reaches the caller as a warning.
|
|
89
89
|
* Said once per request; the build already de-duplicates within one. */
|
|
90
90
|
private reportBuildNotes;
|
|
91
|
+
/** Drop `thinking: { mode: 'off' }` where the model cannot honour it, and say
|
|
92
|
+
* so. Returns the note, or null when there was nothing to adjust.
|
|
93
|
+
*
|
|
94
|
+
* Dropped rather than sent: the wire spec turns `off` into a real field
|
|
95
|
+
* (`thinkingBudget: 0` on 2.5, `thinkingLevel: MINIMAL` on 3.x), and the
|
|
96
|
+
* models flagged here answer 400 to it. The caller gets a request that works
|
|
97
|
+
* plus a warning that their instruction could not be followed, instead of a
|
|
98
|
+
* failed call — or, worse, the silence this replaced, where `off` was
|
|
99
|
+
* accepted, nothing was emitted, and the model reasoned anyway. */
|
|
100
|
+
private limitThinking;
|
|
91
101
|
complete(input: string | ContentPart[] | Message[], options?: ExecuteOptions): Promise<CompletionResponse>;
|
|
92
102
|
/** Run `complete` with a JSON Schema enforced via `structured`. Strips any
|
|
93
103
|
* leading/trailing markdown fences from the model reply, then JSON.parses
|
|
@@ -7,12 +7,37 @@ import type { SSEEvent } from '../../../network/types';
|
|
|
7
7
|
import type { ContentPart } from '../../types/messages';
|
|
8
8
|
import type { ProviderAdapter, ProviderHttpRequest } from '../../types/provider';
|
|
9
9
|
import type { NormalizedRequest } from '../../types/request';
|
|
10
|
-
import { type CompletionResponse } from '../../types/response';
|
|
10
|
+
import { type CompletionResponse, type FileOutput, type Usage } from '../../types/response';
|
|
11
11
|
import type { StreamEvent } from '../../types/stream';
|
|
12
12
|
export interface AnthropicAdapterConfig {
|
|
13
13
|
apiKey: string;
|
|
14
14
|
baseURL?: string;
|
|
15
15
|
}
|
|
16
|
+
/** Billed tier (response usage.service_tier) → {raw, catalog key}. Identity:
|
|
17
|
+
* the catalog is keyed by Anthropic's own billed names (standard|priority|batch). */
|
|
18
|
+
export declare function anthropicBilledTier(raw: unknown): {
|
|
19
|
+
serviceTier?: string;
|
|
20
|
+
pricingTier?: string;
|
|
21
|
+
};
|
|
22
|
+
/** Extract hosted code-execution output files from one content block. Shared by
|
|
23
|
+
* the buffered (`parseResponse`) and streamed (`content_block_start`) paths so
|
|
24
|
+
* both surface the exact same `FileOutput[]`. The current tool
|
|
25
|
+
* (code_execution_20260521) emits `bash_code_execution_tool_result` →
|
|
26
|
+
* `bash_code_execution_result` → `content[]` of `bash_code_execution_output`;
|
|
27
|
+
* older tool versions emit the `code_execution_*` equivalents. Both carry
|
|
28
|
+
* `file_id`. (`text_editor_code_execution_tool_result` blocks are file
|
|
29
|
+
* create/view/edit markers with no downloadable id, so they are not surfaced.) */
|
|
30
|
+
export declare function filesFromCodeExecBlock(block: Record<string, unknown>): FileOutput[];
|
|
31
|
+
/** Builtin-tool payload from a `server_tool_use` input: the code (code execution)
|
|
32
|
+
* or the query (web search). Shared by the buffered + streamed paths. */
|
|
33
|
+
export declare function builtinInputPayload(tool: string, input: Record<string, unknown> | undefined): {
|
|
34
|
+
code?: string;
|
|
35
|
+
query?: string;
|
|
36
|
+
url?: string;
|
|
37
|
+
};
|
|
38
|
+
/** stdout from a code-execution `*_tool_result` block's content, if present. */
|
|
39
|
+
export declare function resultStdout(content: unknown): string | undefined;
|
|
40
|
+
export declare function anthropicUsage(u: Record<string, unknown> | undefined): Usage;
|
|
16
41
|
export declare class AnthropicAdapter implements ProviderAdapter {
|
|
17
42
|
readonly name: "anthropic";
|
|
18
43
|
protected readonly apiKey: string;
|
|
@@ -42,12 +67,12 @@ export declare class AnthropicAdapter implements ProviderAdapter {
|
|
|
42
67
|
}, _req: NormalizedRequest, forceCache?: boolean): Record<string, unknown>;
|
|
43
68
|
private buildContentPart;
|
|
44
69
|
parseResponse(raw: unknown, latencyMs: number): CompletionResponse;
|
|
70
|
+
/** Stateless entry, as the ProviderAdapter interface requires: a fresh spec
|
|
71
|
+
* run per event, so nothing correlates across events. */
|
|
45
72
|
parseStreamEvent(event: SSEEvent): StreamEvent[];
|
|
46
|
-
/** Stateful
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
73
|
+
/** Stateful, and the one callers should use. Anthropic streams a
|
|
74
|
+
* `server_tool_use` input via `input_json_delta` and returns the result in a
|
|
75
|
+
* separate `*_tool_result` block, so the input has to be carried between
|
|
76
|
+
* them; the spec's `state` is where that lives now. */
|
|
50
77
|
createStreamParser(): (event: SSEEvent) => StreamEvent[];
|
|
51
|
-
private streamEvents;
|
|
52
|
-
private parseUsage;
|
|
53
78
|
}
|
|
@@ -3,12 +3,15 @@ import type { SSEEvent } from '../../../network/types';
|
|
|
3
3
|
import type { ContentPart } from '../../types/messages';
|
|
4
4
|
import type { ProviderAdapter, ProviderHttpRequest } from '../../types/provider';
|
|
5
5
|
import type { NormalizedRequest } from '../../types/request';
|
|
6
|
-
import { type CompletionResponse } from '../../types/response';
|
|
6
|
+
import { type CompletionResponse, type Usage } from '../../types/response';
|
|
7
7
|
import type { StreamEvent } from '../../types/stream';
|
|
8
8
|
export interface GoogleAdapterConfig {
|
|
9
9
|
apiKey: string;
|
|
10
10
|
baseURL?: string;
|
|
11
11
|
}
|
|
12
|
+
/** generateContent token usage. Exported so the spec-driven parser runs this
|
|
13
|
+
* and not a second copy of it. */
|
|
14
|
+
export declare function googleUsage(u: Record<string, unknown> | undefined): Usage;
|
|
12
15
|
export declare class GoogleAdapter implements ProviderAdapter {
|
|
13
16
|
readonly name: "google";
|
|
14
17
|
private readonly apiKey;
|
|
@@ -36,13 +39,9 @@ export declare class GoogleAdapter implements ProviderAdapter {
|
|
|
36
39
|
content: string | ContentPart[];
|
|
37
40
|
}): Record<string, unknown>;
|
|
38
41
|
parseResponse(raw: unknown, latencyMs: number): CompletionResponse;
|
|
42
|
+
/** Stateless entry, as the ProviderAdapter interface requires: a fresh spec
|
|
43
|
+
* run per event, so nothing correlates across events. */
|
|
39
44
|
parseStreamEvent(event: SSEEvent): StreamEvent[];
|
|
40
|
-
/** Stateful
|
|
41
|
-
* `codeExecutionResult`) and the produced file (`inlineData`) across parts and
|
|
42
|
-
* often across SSE events. The closure remembers "code execution began in this
|
|
43
|
-
* stream" so a later `inlineData` blob is routed to `files` (a code-exec
|
|
44
|
-
* artifact) rather than `media` (conversational output). */
|
|
45
|
+
/** Stateful, and the one callers should use. The code-execution flag latches across chunks and decides whether inlineData is an artifact or media. */
|
|
45
46
|
createStreamParser(): (event: SSEEvent) => StreamEvent[];
|
|
46
|
-
private streamEvents;
|
|
47
|
-
private parseUsage;
|
|
48
47
|
}
|
|
@@ -6,12 +6,15 @@ import type { SSEEvent } from '../../../network/types';
|
|
|
6
6
|
import type { Message } from '../../types/messages';
|
|
7
7
|
import type { ProviderAdapter, ProviderHttpRequest } from '../../types/provider';
|
|
8
8
|
import type { NormalizedRequest } from '../../types/request';
|
|
9
|
-
import { type CompletionResponse } from '../../types/response';
|
|
9
|
+
import { type CompletionResponse, type Usage } from '../../types/response';
|
|
10
10
|
import type { StreamEvent } from '../../types/stream';
|
|
11
11
|
export interface GoogleInteractionsAdapterConfig {
|
|
12
12
|
apiKey: string;
|
|
13
13
|
baseURL?: string;
|
|
14
14
|
}
|
|
15
|
+
/** Interactions token usage. Exported so the spec-driven parser runs this and
|
|
16
|
+
* not a second copy of it. */
|
|
17
|
+
export declare function googleInteractionsUsage(u: Record<string, unknown> | undefined): Usage;
|
|
15
18
|
export declare class GoogleInteractionsAdapter implements ProviderAdapter {
|
|
16
19
|
readonly name: "google";
|
|
17
20
|
private readonly apiKey;
|
|
@@ -37,10 +40,9 @@ export declare class GoogleInteractionsAdapter implements ProviderAdapter {
|
|
|
37
40
|
* `interaction.failed` finish the turn (usage under `interaction.usage`). A
|
|
38
41
|
* function call's `arguments_delta` carries no id, so we correlate it to the
|
|
39
42
|
* currently-open call id held in `state`. */
|
|
40
|
-
|
|
43
|
+
/** Stateless entry, as the ProviderAdapter interface requires: a fresh spec
|
|
44
|
+
* run per event, so nothing correlates across events. */
|
|
41
45
|
parseStreamEvent(event: SSEEvent): StreamEvent[];
|
|
42
|
-
/**
|
|
43
|
-
* and end to the call opened by its `step.start`. */
|
|
46
|
+
/** Stateful, and the one callers should use. The open call's id is carried between its fragments and its close. */
|
|
44
47
|
createStreamParser(): (event: SSEEvent) => StreamEvent[];
|
|
45
|
-
private parseUsage;
|
|
46
48
|
}
|
|
@@ -4,7 +4,7 @@ import type { Registry } from '../../../wire/interpreter';
|
|
|
4
4
|
import type { ContentPart } from '../../types/messages';
|
|
5
5
|
import type { ProviderAdapter, ProviderHttpRequest } from '../../types/provider';
|
|
6
6
|
import type { NormalizedRequest } from '../../types/request';
|
|
7
|
-
import { type CompletionResponse } from '../../types/response';
|
|
7
|
+
import { type CompletionResponse, type Usage } from '../../types/response';
|
|
8
8
|
import type { StreamEvent } from '../../types/stream';
|
|
9
9
|
export interface OpenAIAdapterConfig {
|
|
10
10
|
apiKey: string;
|
|
@@ -15,7 +15,16 @@ export interface OpenAIAdapterConfig {
|
|
|
15
15
|
* for backends that omit ids), stable across the stream's chunks. */
|
|
16
16
|
export interface OpenAIStreamState {
|
|
17
17
|
toolIdByIndex: Map<number, string>;
|
|
18
|
+
/** Open audio output: gpt-audio streams its reply as `delta.audio`, and the
|
|
19
|
+
* media_start/chunk/end trio has to be paired across events. */
|
|
20
|
+
audio?: {
|
|
21
|
+
open: boolean;
|
|
22
|
+
id?: string;
|
|
23
|
+
};
|
|
18
24
|
}
|
|
25
|
+
/** Token usage, from either Chat Completions or Responses naming. Exported so
|
|
26
|
+
* the spec-driven parser calls the same code rather than a second copy. */
|
|
27
|
+
export declare function openaiUsage(u: Record<string, unknown> | undefined): Usage;
|
|
19
28
|
export declare class OpenAIAdapter implements ProviderAdapter {
|
|
20
29
|
readonly name: ProviderAdapter['name'];
|
|
21
30
|
protected readonly apiKey: string;
|
|
@@ -46,10 +55,19 @@ export declare class OpenAIAdapter implements ProviderAdapter {
|
|
|
46
55
|
}): Record<string, unknown>[];
|
|
47
56
|
private buildMessage;
|
|
48
57
|
enableStreaming(providerReq: ProviderHttpRequest, _req: NormalizedRequest): void;
|
|
58
|
+
/** The response spec this adapter parses with. Overridden by OpenRouter,
|
|
59
|
+
* which is Chat Completions plus one rule. */
|
|
60
|
+
protected responseSpecId(): string;
|
|
61
|
+
protected responseRegistry(): Registry;
|
|
49
62
|
parseResponse(raw: unknown, latencyMs: number): CompletionResponse;
|
|
50
|
-
parseStreamEvent(event: SSEEvent, state?: OpenAIStreamState): StreamEvent[];
|
|
51
63
|
/** Per-stream: correlates streamed tool-call fragments by index and synthesizes
|
|
52
64
|
* a stable id for backends that omit tool-call ids (see `parseStreamEvent`). */
|
|
65
|
+
/** Stateless entry, as the ProviderAdapter interface requires: a fresh spec
|
|
66
|
+
* run per event, so nothing correlates across events. */
|
|
67
|
+
parseStreamEvent(event: SSEEvent): StreamEvent[];
|
|
68
|
+
/** Stateful, and the one callers should use. Tool-call fragments correlate by index because only the first carries an id. */
|
|
53
69
|
createStreamParser(): (event: SSEEvent) => StreamEvent[];
|
|
54
|
-
|
|
70
|
+
/** Overridden by OpenRouter, which appends its `:online` web-search pair. */
|
|
71
|
+
protected streamSpecId(): string;
|
|
72
|
+
protected streamRegistry(): Registry;
|
|
55
73
|
}
|
|
@@ -3,16 +3,32 @@
|
|
|
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 {
|
|
6
|
+
import type { Message, ToolCaller } from '../../types/messages';
|
|
7
7
|
import type { Registry } from '../../../wire/interpreter';
|
|
8
8
|
import type { ProviderAdapter, ProviderHttpRequest } from '../../types/provider';
|
|
9
9
|
import type { NormalizedRequest } from '../../types/request';
|
|
10
|
-
import { type CompletionResponse, type FileOutput, type Usage } from '../../types/response';
|
|
10
|
+
import { type BuiltinToolCall, type CompletionResponse, type FileOutput, type Usage } from '../../types/response';
|
|
11
11
|
import type { StreamEvent } from '../../types/stream';
|
|
12
12
|
export interface OpenAIResponsesAdapterConfig {
|
|
13
13
|
apiKey: string;
|
|
14
14
|
baseURL?: string;
|
|
15
15
|
}
|
|
16
|
+
export declare function fromWireCaller(raw: unknown): ToolCaller | undefined;
|
|
17
|
+
export declare function builtinCallFromResponsesItem(item: Record<string, unknown>): BuiltinToolCall | null;
|
|
18
|
+
/** Extract hosted code-execution output files from one Responses output item.
|
|
19
|
+
* Shared by the buffered (`parseResponse`) and streamed (`response.output_item.done`)
|
|
20
|
+
* paths so both surface the exact same `FileOutput[]`. Two sources:
|
|
21
|
+
* - `message` items → `container_file_citation` annotations (downloadable
|
|
22
|
+
* container files, fetched by file id from `/v1/containers/{cid}/files/{id}`);
|
|
23
|
+
* - `code_interpreter_call` items → image outputs returned by URL.
|
|
24
|
+
*
|
|
25
|
+
* Dedup: `plt.show()` makes OpenAI emit an auto-display container file ALONGSIDE the
|
|
26
|
+
* explicitly-saved one. When the same image was also saved, we drop the display
|
|
27
|
+
* duplicate (matches ChatGPT's own UI); a display-only run keeps its sole figure. */
|
|
28
|
+
export declare function filesFromResponsesOutputItem(item: Record<string, unknown>): FileOutput[];
|
|
29
|
+
/** Responses-API token usage. Exported so the spec-driven parser runs this and
|
|
30
|
+
* not a second copy of it. */
|
|
31
|
+
export declare function openaiResponsesUsage(u: Record<string, unknown> | undefined): Usage;
|
|
16
32
|
export declare class OpenAIResponsesAdapter implements ProviderAdapter {
|
|
17
33
|
readonly name: ProviderAdapter['name'];
|
|
18
34
|
protected readonly apiKey: string;
|
|
@@ -33,11 +49,23 @@ export declare class OpenAIResponsesAdapter implements ProviderAdapter {
|
|
|
33
49
|
/** Reached through the wire registry while building the request. */
|
|
34
50
|
buildInputItems(msg: Message, toolNames?: Map<string, string>): unknown[];
|
|
35
51
|
enableStreaming(providerReq: ProviderHttpRequest): void;
|
|
52
|
+
/** Overridden by xAI, whose Responses API is this one. */
|
|
53
|
+
protected responseSpecId(): string;
|
|
54
|
+
/** Overridden alongside the spec id: xAI extends file extraction, so its
|
|
55
|
+
* registry supplies a different `oaiRespFiles` -- the parse-side twin of its
|
|
56
|
+
* `filesFromOutputItem` override. */
|
|
57
|
+
protected responseRegistry(): Registry;
|
|
36
58
|
parseResponse(raw: unknown, latencyMs: number): CompletionResponse;
|
|
37
|
-
parseStreamEvent(event: SSEEvent, phaseByItem?: Map<string, AssistantPhase>): StreamEvent[];
|
|
38
59
|
/** Stateless — each output item finalizes with all its file annotations in a
|
|
39
60
|
* single response.output_item.done event. */
|
|
61
|
+
/** Stateless entry, as the ProviderAdapter interface requires: a fresh spec
|
|
62
|
+
* run per event, so nothing correlates across events. */
|
|
63
|
+
parseStreamEvent(event: SSEEvent): StreamEvent[];
|
|
64
|
+
/** Stateful, and the one callers should use. `phase` is announced once when an item is added but belongs on every text delta of that item, and the spec's state is where that is remembered. */
|
|
40
65
|
createStreamParser(): (event: SSEEvent) => StreamEvent[];
|
|
66
|
+
/** Overridden by xAI, which extends file extraction. */
|
|
67
|
+
protected streamSpecId(): string;
|
|
68
|
+
protected streamRegistry(): Registry;
|
|
41
69
|
/** Hosted code-execution output files from one output item. Overridable so
|
|
42
70
|
* Responses-compatible providers with a different file shape (e.g. xAI, which
|
|
43
71
|
* embeds files in the code-interpreter `logs` payload) can extend it. */
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
/** OpenRouter provider adapter — OpenAI-compatible with extensions. */
|
|
2
|
-
import type { SSEEvent } from '../../../network/types';
|
|
3
2
|
import type { ProviderAdapter } from '../../types/provider';
|
|
4
|
-
import type { CompletionResponse } from '../../types/response';
|
|
5
|
-
import type { StreamEvent } from '../../types/stream';
|
|
6
3
|
import { OpenAIAdapter } from '../openai/completions';
|
|
4
|
+
import type { Registry } from '../../../wire/interpreter';
|
|
7
5
|
export interface OpenRouterAdapterConfig {
|
|
8
6
|
apiKey: string;
|
|
9
7
|
baseURL?: string;
|
|
@@ -17,8 +15,14 @@ export declare class OpenRouterAdapter extends OpenAIAdapter {
|
|
|
17
15
|
* rename, the reasoning strip, the tier remap, the routing passthrough — is the
|
|
18
16
|
* `openrouter` overlay in the shared spec. Naming the flavor IS the override now. */
|
|
19
17
|
protected readonly wireFlavor: string;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
*
|
|
23
|
-
|
|
18
|
+
/** The `:online` web-search rule that used to live in an override is the
|
|
19
|
+
* `openrouter` delta of the shared response spec. Naming the spec IS the
|
|
20
|
+
* override now, exactly as `wireFlavor` is for the request side. */
|
|
21
|
+
protected responseSpecId(): string;
|
|
22
|
+
protected responseRegistry(): Registry;
|
|
23
|
+
/** The `:online` web-search pair is the `openrouter` delta of the shared
|
|
24
|
+
* stream spec, so naming the spec IS the override -- as it already is for the
|
|
25
|
+
* request side and the buffered response. */
|
|
26
|
+
protected streamSpecId(): string;
|
|
27
|
+
protected streamRegistry(): Registry;
|
|
24
28
|
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Registry } from '../../wire/interpreter';
|
|
2
|
+
export declare const RESPONSE_REGISTRIES: Record<string, Registry>;
|
|
3
|
+
/** Every name any response registry supplies. For checks that only ask "does
|
|
4
|
+
* this resolve anywhere", never for dispatch. */
|
|
5
|
+
export declare function allResponseNames(): Set<string>;
|
|
@@ -4,11 +4,9 @@
|
|
|
4
4
|
* - Reasoning via model variant (grok-*-reasoning), not reasoning param
|
|
5
5
|
* - Returns reasoning_content in message (plain text, unlike OpenAI which hides it)
|
|
6
6
|
*/
|
|
7
|
-
import type { SSEEvent } from '../../../network/types';
|
|
8
7
|
import type { ProviderAdapter } from '../../types/provider';
|
|
9
8
|
import type { CompletionResponse } from '../../types/response';
|
|
10
|
-
import
|
|
11
|
-
import { OpenAIAdapter, type OpenAIStreamState } from '../openai/completions';
|
|
9
|
+
import { OpenAIAdapter } from '../openai/completions';
|
|
12
10
|
export interface XAIAdapterConfig {
|
|
13
11
|
apiKey: string;
|
|
14
12
|
baseURL?: string;
|
|
@@ -22,5 +20,4 @@ export declare class XAIAdapter extends OpenAIAdapter {
|
|
|
22
20
|
* `xai` overlay in the shared spec. Naming the flavor IS the override now. */
|
|
23
21
|
protected readonly wireFlavor: string;
|
|
24
22
|
parseResponse(raw: unknown, latencyMs: number): CompletionResponse;
|
|
25
|
-
parseStreamEvent(event: SSEEvent, state?: OpenAIStreamState): StreamEvent[];
|
|
26
23
|
}
|
|
@@ -8,11 +8,23 @@
|
|
|
8
8
|
import type { ProviderAdapter } from '../../types/provider';
|
|
9
9
|
import type { FileOutput } from '../../types/response';
|
|
10
10
|
import { OpenAIResponsesAdapter } from '../openai/responses';
|
|
11
|
+
import type { Registry } from '../../../wire/interpreter';
|
|
11
12
|
export interface XAIResponsesAdapterConfig {
|
|
12
13
|
apiKey: string;
|
|
13
14
|
baseURL?: string;
|
|
14
15
|
}
|
|
16
|
+
/** xAI returns code-execution output files INLINE inside the `code_interpreter_call`
|
|
17
|
+
* `logs` payload (a JSON string: `{stdout, output_files:[{file_name, mime_type, data:[…bytes]}]}`),
|
|
18
|
+
* not as OpenAI-style `container_file_citation` annotations. Requires the request to
|
|
19
|
+
* ask for them via `include: ['code_interpreter_call.outputs']`. */
|
|
20
|
+
export declare function xaiCodeExecFiles(item: Record<string, unknown>): FileOutput[];
|
|
15
21
|
export declare class XAIResponsesAdapter extends OpenAIResponsesAdapter {
|
|
22
|
+
/** Identical to OpenAI's by inheritance, but addressed by its own id so the
|
|
23
|
+
* target has a spec of its own rather than a special case in the lookup. */
|
|
24
|
+
protected responseSpecId(): string;
|
|
25
|
+
protected responseRegistry(): Registry;
|
|
26
|
+
protected streamSpecId(): string;
|
|
27
|
+
protected streamRegistry(): Registry;
|
|
16
28
|
readonly name: ProviderAdapter['name'];
|
|
17
29
|
constructor(config: XAIResponsesAdapterConfig);
|
|
18
30
|
baseURL(): string;
|
|
@@ -3,6 +3,15 @@
|
|
|
3
3
|
* in this shape; consumers (renderFactsLayer, snapshots) read them. */
|
|
4
4
|
export declare const FACT_CATEGORIES: readonly ["name", "date", "time", "path", "url", "email", "phone", "address", "amount", "number", "identifier", "other"];
|
|
5
5
|
export type FactCategory = (typeof FACT_CATEGORIES)[number];
|
|
6
|
+
/** Narrow a parsed category to the union, falling back to `other`.
|
|
7
|
+
*
|
|
8
|
+
* Categories are read back out of a system prompt or off a fact-extract tool's
|
|
9
|
+
* JSON, so the string is model-influenced rather than ours. Casting it into
|
|
10
|
+
* `FactCategory` would type a value the union does not contain, and every
|
|
11
|
+
* consumer that switches on the category would then meet a branch it was
|
|
12
|
+
* compiled believing could not happen. `other` is the union's catch-all and is
|
|
13
|
+
* what an unrecognised category means. */
|
|
14
|
+
export declare function toFactCategory(raw: string): FactCategory;
|
|
6
15
|
export interface ExtractedFact {
|
|
7
16
|
/** Short descriptive label. Lowercase, snake_or_dotted notation. */
|
|
8
17
|
key: string;
|
|
@@ -30,6 +30,9 @@ export declare class StrategyToolsImpl implements StrategyTools {
|
|
|
30
30
|
middle: HistoryEntry[];
|
|
31
31
|
old: HistoryEntry[];
|
|
32
32
|
};
|
|
33
|
+
/** What the request weighs right now, including any compaction already
|
|
34
|
+
* applied in this call. */
|
|
35
|
+
measureCurrent(): number;
|
|
33
36
|
measure(items: readonly HistoryEntry[] | Message[]): number;
|
|
34
37
|
extractFacts(entries: readonly HistoryEntry[], categories?: string[]): Promise<ExtractedFact[]>;
|
|
35
38
|
summarize(entries: readonly HistoryEntry[], maxLength: number, focus?: string): Promise<string>;
|
|
@@ -82,6 +82,11 @@ export interface StrategyTools {
|
|
|
82
82
|
old: HistoryEntry[];
|
|
83
83
|
};
|
|
84
84
|
measure(items: readonly HistoryEntry[] | Message[]): number;
|
|
85
|
+
/** Tokens in the request AS IT STANDS, after whatever this strategy has
|
|
86
|
+
* already done to it. `ReactContext.current` is the count that TRIGGERED
|
|
87
|
+
* the compaction and no mutation updates it, so it is the wrong number to
|
|
88
|
+
* judge the compaction by. */
|
|
89
|
+
measureCurrent(): number;
|
|
85
90
|
extractFacts(entries: readonly HistoryEntry[], categories?: string[]): Promise<ExtractedFact[]>;
|
|
86
91
|
summarize(entries: readonly HistoryEntry[], maxLength: number, focus?: string): Promise<string>;
|
|
87
92
|
replaceRange(from: number, to: number, replacement: Message): void;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** Detect an audio clip's MIME type from its leading magic bytes.
|
|
2
|
+
*
|
|
3
|
+
* Same problem as `sniffImageMime`, from the opposite direction. OpenAI's chat
|
|
4
|
+
* completions return `message.audio` as `{ id, data, expires_at, transcript }`
|
|
5
|
+
* and NO `format` field, so the adapter's `audio/${format ?? 'wav'}` fell through
|
|
6
|
+
* to the default every single time: request mp3, receive mp3 bytes (`ID3...`),
|
|
7
|
+
* and get told it is `audio/wav`. Anything that trusts the label — an <audio>
|
|
8
|
+
* element, a file written to disk, a follow-up upload with a strict validator —
|
|
9
|
+
* is then working from a lie.
|
|
10
|
+
*
|
|
11
|
+
* The bytes are the only honest source here, and the caller's requested format is
|
|
12
|
+
* not available at parse time.
|
|
13
|
+
*
|
|
14
|
+
* Returns the CONTAINER, which is what a player needs: Opus arrives inside Ogg
|
|
15
|
+
* and is reported as `audio/ogg`. */
|
|
16
|
+
export declare function sniffAudioMime(b: Uint8Array): string | undefined;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** Ordering that does not depend on where the process is running.
|
|
2
|
+
*
|
|
3
|
+
* `String.prototype.localeCompare` with no locale argument reads the HOST's
|
|
4
|
+
* default locale, so the same inputs sort differently on different machines:
|
|
5
|
+
* under `sv-SE` or `tr-TR`, `ünique` sorts after `user-name` rather than next
|
|
6
|
+
* to `unique`. That is fine for a list shown to a person and wrong for
|
|
7
|
+
* anything whose order becomes bytes — a rendered system prompt changes
|
|
8
|
+
* content with the host's locale, which breaks reproducibility and misses the
|
|
9
|
+
* provider's prompt cache on a prefix that should have been identical.
|
|
10
|
+
*
|
|
11
|
+
* Codepoint order is not "nicer" than collation. It is the same everywhere,
|
|
12
|
+
* which is the only property these call sites actually need. */
|
|
13
|
+
export declare function byCodepoint(a: string, b: string): number;
|
|
@@ -270,6 +270,8 @@ export interface Registry {
|
|
|
270
270
|
}
|
|
271
271
|
export declare function getPath(root: any, path: string): any;
|
|
272
272
|
export declare function evalCond(cond: Cond | undefined, ctx: Ctx, reg: Registry): boolean;
|
|
273
|
+
export declare const OMIT: unique symbol;
|
|
274
|
+
export declare function evalTemplate(tpl: Json, ctx: Ctx, reg: Registry): Json | typeof OMIT;
|
|
273
275
|
export declare function resolveVariants(spec: WireSpec, model: string, reg: Registry): Set<string>;
|
|
274
276
|
export interface BuiltRequest {
|
|
275
277
|
body: Record<string, unknown>;
|