@miraiclip/assistant 0.1.2 → 0.2.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/dist/index.d.ts CHANGED
@@ -10,6 +10,12 @@ interface ToolCall {
10
10
  id: string;
11
11
  name: string;
12
12
  arguments: Record<string, unknown>;
13
+ /**
14
+ * Opaque data the adapter that produced the call needs back when the
15
+ * conversation is replayed (Gemini thought signatures, Anthropic thinking
16
+ * blocks). Keep it with the call; other adapters ignore it.
17
+ */
18
+ meta?: Record<string, unknown>;
13
19
  }
14
20
  type ChatMessage = {
15
21
  role: "system";
@@ -59,18 +65,28 @@ interface ChatOptions {
59
65
  /** Streaming text, as it arrives (adapters that can't stream call it once). */
60
66
  onText?: (delta: string) => void;
61
67
  }
68
+ interface ModelEntry {
69
+ id: string;
70
+ label?: string;
71
+ }
62
72
  interface ChatModelInfo {
63
73
  /** Adapter id, e.g. "openai". Alphanumeric with - or _. */
64
74
  id: string;
65
75
  label: string;
66
76
  /** Models this adapter serves; the first is the default. */
67
- models?: {
77
+ models?: ModelEntry[];
78
+ /** For a model that routes to several providers (`routedChatModel`): which ones. */
79
+ providers?: {
68
80
  id: string;
69
- label?: string;
81
+ label: string;
70
82
  }[];
71
83
  }
72
84
  interface ChatModel extends ChatModelInfo {
73
85
  complete(request: ChatRequest, options?: ChatOptions): Promise<ChatResponse>;
86
+ /** Every model the account behind this adapter can use, live from the vendor (for model pickers). */
87
+ listModels?(options?: {
88
+ signal?: AbortSignal;
89
+ }): Promise<ModelEntry[]>;
74
90
  }
75
91
  /** An error from a model vendor, carrying its HTTP status when there was one. */
76
92
  declare class ChatModelError extends Error {
@@ -82,6 +98,16 @@ type FetchLike = (url: string, init?: RequestInit) => Promise<Response>;
82
98
  /** Check an adapter's shape once, at registration. */
83
99
  declare function defineChatModel<M extends ChatModel>(model: M): M;
84
100
 
101
+ /**
102
+ * Plumbing the vendor adapters share: POST with retries on rate limits and
103
+ * server errors, server-sent-event reading, and tool-argument parsing.
104
+ */
105
+
106
+ /** Parse a tool call's JSON arguments; unparseable JSON is reported to the model as a tool error. */
107
+ declare function parseToolArguments(raw: string): Record<string, unknown>;
108
+ /** How long the server asked us to wait (Retry-After header, or "try again in 1.2s / 350ms"), else exponential backoff. */
109
+ declare function retryDelayMs(res: Pick<Response, "headers">, message: string, attempt: number): number;
110
+
85
111
  /**
86
112
  * OpenAI adapter, over the Chat Completions API with function calling.
87
113
  *
@@ -99,7 +125,7 @@ interface OpenAIChatModelOptions {
99
125
  label?: string;
100
126
  }[];
101
127
  /** API key. Omit for local servers that don't need one. Keep it server-side (see `createChatHandler`). */
102
- apiKey?: string;
128
+ apiKey?: string | undefined;
103
129
  /** Default https://api.openai.com/v1. Any OpenAI-compatible base URL works. */
104
130
  baseUrl?: string;
105
131
  organization?: string;
@@ -115,6 +141,13 @@ interface OpenAIChatModelOptions {
115
141
  * backing off 1 s, 2 s, 4 s… (capped at 30 s). Default 4; 0 disables.
116
142
  */
117
143
  maxRetries?: number;
144
+ /**
145
+ * The request field for the output cap: "max_completion_tokens" (default;
146
+ * OpenAI) or "max_tokens" (what most other compatible servers read).
147
+ */
148
+ maxTokensField?: "max_completion_tokens" | "max_tokens";
149
+ /** Ask for token usage at the end of a stream (default true; turn off for servers that reject `stream_options`). */
150
+ streamUsage?: boolean;
118
151
  /** Adapter id / label (default "openai" / "OpenAI"), e.g. "ollama" when pointing elsewhere. */
119
152
  id?: string;
120
153
  label?: string;
@@ -141,56 +174,349 @@ type OpenAIMessage = {
141
174
  };
142
175
  /** Neutral messages → Chat Completions messages. */
143
176
  declare function toOpenAIMessages(messages: readonly ChatMessage[]): OpenAIMessage[];
144
- /** Parse a tool call's JSON arguments; unparseable JSON is reported to the model as a tool error. */
145
- declare function parseToolArguments(raw: string): Record<string, unknown>;
146
- /** How long the server asked us to wait (Retry-After header, or "try again in 1.2s / 350ms"), else exponential backoff. */
147
- declare function retryDelayMs(res: Pick<Response, "headers">, message: string, attempt: number): number;
148
177
  declare function openAIChatModel(options: OpenAIChatModelOptions): ChatModel;
149
178
 
179
+ /**
180
+ * Anthropic adapter, over the Messages API with tool use.
181
+ *
182
+ * System messages become the top-level `system` prompt; tool results are
183
+ * grouped into one user turn, as the API expects. When extended thinking is
184
+ * on (`params: { thinking: … }`), the thinking blocks of a tool-using turn
185
+ * ride on the first tool call's `meta` and are sent back on the next request,
186
+ * which the API requires.
187
+ */
188
+
189
+ interface AnthropicChatModelOptions {
190
+ /** Model id, e.g. "claude-sonnet-5-5". Required: model names change faster than this package. */
191
+ model: string;
192
+ /** Other models the app may pick per request (`ChatRequest.model`). */
193
+ models?: {
194
+ id: string;
195
+ label?: string;
196
+ }[];
197
+ /** API key. Keep it server-side (see `createChatHandler`) unless it's the user's own key in their own browser (`browser`). */
198
+ apiKey?: string | undefined;
199
+ /** Default https://api.anthropic.com (requests go to `{baseUrl}/v1/messages`). */
200
+ baseUrl?: string;
201
+ /** `anthropic-version` header (default "2023-06-01"). */
202
+ version?: string;
203
+ /** `anthropic-beta` flags, joined with commas. */
204
+ betas?: string[];
205
+ headers?: Record<string, string>;
206
+ /** Default request fields merged into every call (e.g. `{ thinking: { type: "enabled", budget_tokens: 4000 } }`). */
207
+ params?: Record<string, unknown>;
208
+ /** The API requires an output cap; used when a request sets none (default 8192). */
209
+ maxOutputTokens?: number;
210
+ /** Stream responses (default true). */
211
+ stream?: boolean;
212
+ /** Retries on 429, 5xx and 529 (overloaded), as the server asks. Default 4; 0 disables. */
213
+ maxRetries?: number;
214
+ /**
215
+ * Calling from a browser with the user's own key: sends the header the API
216
+ * needs to allow cross-origin requests. Never ship your own key this way.
217
+ */
218
+ browser?: boolean;
219
+ /** Adapter id / label (default "anthropic" / "Anthropic"). */
220
+ id?: string;
221
+ label?: string;
222
+ fetch?: FetchLike;
223
+ }
224
+ type Block = {
225
+ type: "text";
226
+ text: string;
227
+ } | {
228
+ type: "tool_use";
229
+ id: string;
230
+ name: string;
231
+ input: Record<string, unknown>;
232
+ } | {
233
+ type: "tool_result";
234
+ tool_use_id: string;
235
+ content: string;
236
+ } | {
237
+ type: "thinking";
238
+ thinking: string;
239
+ signature: string;
240
+ } | {
241
+ type: "redacted_thinking";
242
+ data: string;
243
+ };
244
+ type AnthropicMessage = {
245
+ role: "user" | "assistant";
246
+ content: Block[];
247
+ };
248
+ /** Neutral messages → `{ system, messages }` for the Messages API. */
249
+ declare function toAnthropicMessages(messages: readonly ChatMessage[]): {
250
+ system: string;
251
+ messages: AnthropicMessage[];
252
+ };
253
+ declare function anthropicChatModel(options: AnthropicChatModelOptions): ChatModel;
254
+
255
+ /**
256
+ * Google Gemini adapter, over the Gemini API's `generateContent` with
257
+ * function calling.
258
+ *
259
+ * Tools are sent as full JSON Schema (`parametersJsonSchema`), so the same
260
+ * schemas the other adapters use work unchanged. Gemini's thought signatures
261
+ * (required when thinking models call tools) ride on each tool call's `meta`
262
+ * and are sent back exactly as received.
263
+ */
264
+
265
+ interface GeminiChatModelOptions {
266
+ /** Model id, e.g. "gemini-3.8-flash". Required: model names change faster than this package. */
267
+ model: string;
268
+ /** Other models the app may pick per request (`ChatRequest.model`). */
269
+ models?: {
270
+ id: string;
271
+ label?: string;
272
+ }[];
273
+ /** Gemini API key. Keep it server-side (see `createChatHandler`) unless it's the user's own key in their own browser. */
274
+ apiKey?: string | undefined;
275
+ /** Default https://generativelanguage.googleapis.com/v1beta. */
276
+ baseUrl?: string;
277
+ headers?: Record<string, string>;
278
+ /** Default request fields merged into every call; `generationConfig` is merged key by key (e.g. `{ generationConfig: { temperature: 0.2 } }`). */
279
+ params?: Record<string, unknown>;
280
+ /** Stream responses (default true). */
281
+ stream?: boolean;
282
+ /** Retries on 429 and 5xx, as the server asks. Default 4; 0 disables. */
283
+ maxRetries?: number;
284
+ /** Adapter id / label (default "gemini" / "Google Gemini"). */
285
+ id?: string;
286
+ label?: string;
287
+ fetch?: FetchLike;
288
+ }
289
+ type Part = {
290
+ text?: string;
291
+ thought?: boolean;
292
+ thoughtSignature?: string;
293
+ functionCall?: {
294
+ id?: string;
295
+ name: string;
296
+ args?: Record<string, unknown>;
297
+ };
298
+ functionResponse?: {
299
+ id?: string;
300
+ name: string;
301
+ response: Record<string, unknown>;
302
+ };
303
+ };
304
+ type GeminiContent = {
305
+ role: "user" | "model";
306
+ parts: Part[];
307
+ };
308
+ /** Neutral messages → `{ systemInstruction, contents }` for `generateContent`. */
309
+ declare function toGeminiContents(messages: readonly ChatMessage[]): {
310
+ system: string;
311
+ contents: GeminiContent[];
312
+ };
313
+ declare function geminiChatModel(options: GeminiChatModelOptions): ChatModel;
314
+
315
+ type ProviderApi = "openai" | "anthropic" | "gemini";
316
+ interface AiProviderInfo {
317
+ /** Id used in configs, env names and "provider/model" references. */
318
+ id: string;
319
+ label: string;
320
+ /** Which wire format it speaks. */
321
+ api: ProviderApi;
322
+ /** API root; `openai-compatible` has none (you give it). */
323
+ baseUrl?: string;
324
+ /** Whether calls need an API key (local servers don't). */
325
+ needsKey: boolean;
326
+ /** Runs on the user's machine (Ollama, LM Studio): reachable from that machine only. */
327
+ local?: boolean;
328
+ /** Where a user creates a key. */
329
+ keyUrl?: string;
330
+ /** Env var prefix: `{PREFIX}_API_KEY`, `{PREFIX}_MODEL`, `{PREFIX}_BASE_URL`, `{PREFIX}_MODELS`. */
331
+ env: string;
332
+ /** Used when no model is named. Providers without one need a model picked (env or UI). */
333
+ defaultModel?: string;
334
+ /** A few good picks to show before the live list loads. */
335
+ models?: ModelEntry[];
336
+ /** Accepts calls straight from a browser (CORS) with the user's own key. */
337
+ browser?: boolean;
338
+ /** OpenAI-format servers: the output-cap field and whether `stream_options` is accepted. */
339
+ maxTokensField?: "max_completion_tokens" | "max_tokens";
340
+ streamUsage?: boolean;
341
+ }
342
+ /**
343
+ * The built-in provider catalog. Model ids are suggestions as of release; the
344
+ * live list comes from each provider (`ChatModel.listModels`).
345
+ */
346
+ declare const AI_PROVIDERS: readonly AiProviderInfo[];
347
+ /** A provider from the catalog, or undefined. */
348
+ declare function aiProvider(id: string): AiProviderInfo | undefined;
349
+ interface CreateChatModelOptions {
350
+ /** A catalog id (`AI_PROVIDERS`): "openai", "anthropic", "gemini", "openrouter", "ollama", "openai-compatible", … */
351
+ provider: string;
352
+ apiKey?: string | undefined;
353
+ /** Model id (default: the provider's `defaultModel`; required for providers without one). */
354
+ model?: string | undefined;
355
+ /** Other models to offer (default: the catalog's suggestions). */
356
+ models?: ModelEntry[];
357
+ /** Override the API root (required for "openai-compatible"). */
358
+ baseUrl?: string | undefined;
359
+ headers?: Record<string, string>;
360
+ /** Default request fields for every call (vendor-specific). */
361
+ params?: Record<string, unknown>;
362
+ stream?: boolean;
363
+ maxRetries?: number;
364
+ /** Calling from the browser with the user's own key (sets what the vendor needs for CORS). */
365
+ browser?: boolean;
366
+ /** Adapter id / label (default: the provider's). */
367
+ id?: string;
368
+ label?: string;
369
+ fetch?: FetchLike;
370
+ }
371
+ /** One `ChatModel` for any provider in the catalog. */
372
+ declare function createChatModel(options: CreateChatModelOptions): ChatModel;
373
+ interface ChatModelsFromEnvOptions {
374
+ /** Only these providers (default: all). */
375
+ providers?: string[];
376
+ /** Told about providers that have a key but couldn't be set up (e.g. no model). */
377
+ onSkip?: (provider: string, reason: string) => void;
378
+ fetch?: FetchLike;
379
+ }
380
+ /**
381
+ * A model for every provider configured in `env` (`process.env`, Vite's
382
+ * `loadEnv`, a Worker's bindings):
383
+ *
384
+ * {PREFIX}_API_KEY enables a hosted provider (GEMINI also reads GOOGLE_API_KEY)
385
+ * {PREFIX}_MODEL its default model (required where the catalog has none)
386
+ * {PREFIX}_MODELS more models to offer, comma-separated
387
+ * {PREFIX}_BASE_URL another API root (a proxy, a gateway, a regional endpoint)
388
+ *
389
+ * Local servers (OLLAMA, LMSTUDIO) are enabled by their _MODEL or _BASE_URL.
390
+ * OPENAI_BASE_URL alone keeps its old meaning: an OpenAI-compatible server
391
+ * (label OPENAI_LABEL), key optional. Order follows the catalog, so the
392
+ * first entry makes a sensible default.
393
+ */
394
+ declare function chatModelsFromEnv(env: Record<string, string | undefined>, options?: ChatModelsFromEnvOptions): ChatModel[];
395
+ /** "anthropic/claude-sonnet-5-5" → { provider: "anthropic", model: "claude-sonnet-5-5" } when the prefix is a known id. */
396
+ declare function splitModelRef(ref: string, providerIds: Iterable<string>): {
397
+ provider?: string;
398
+ model: string;
399
+ };
400
+ interface RoutedChatModelOptions {
401
+ id?: string;
402
+ label?: string;
403
+ /** Adapter id used when a request names no provider (default: the first). */
404
+ default?: string;
405
+ }
406
+ /**
407
+ * Several providers as one `ChatModel`. Its models are "provider/model"
408
+ * (`anthropic/claude-sonnet-5-5`, `openrouter/meta-llama/…`); a request's
409
+ * `model` picks the adapter and the model. A bare model id goes to the
410
+ * adapter that lists it, else to the default adapter; no model → the default
411
+ * adapter's default model.
412
+ */
413
+ declare function routedChatModel(models: readonly ChatModel[], options?: RoutedChatModelOptions): ChatModel;
414
+
150
415
  /**
151
416
  * Keys stay on the server: run the real model adapter in your backend behind
152
417
  * `createChatHandler`, and give the browser `remoteChatModel(endpoint)` — a
153
418
  * proxy with the same `ChatModel` shape. The agent loop and the tools run in
154
419
  * the browser, next to the project; only model calls cross the network.
155
420
  *
156
- * GET {base}/ → { id, label, models }
421
+ * GET {base}/ → { id, label, models, providers?, userKeys? }
422
+ * GET {base}/models → { models } (live from the vendor when it can list them)
157
423
  * POST {base}/chat { request: ChatRequest } →
158
424
  * application/x-ndjson, one JSON object per line:
159
425
  * { "type": "text", "delta": "…" } (as it streams)
160
426
  * { "type": "done", "response": ChatResponse }
161
427
  * { "type": "error", "error": "…", "status": 401 }
162
- * errors before streaming → { error } with 400 / 404 / 413, or the vendor's status
428
+ * errors before streaming → { error } with 400 / 401 / 403 / 404 / 413, or the vendor's status
429
+ *
430
+ * Bring your own key (`userKeys`): a request may carry the user's own
431
+ * provider and key in headers (`x-ai-provider`, `x-ai-key`, optionally
432
+ * `x-ai-base-url`). The handler builds a model for that one request and
433
+ * forgets the key — it's never stored or logged. Use it for plans where
434
+ * customers pay their AI vendor directly.
163
435
  *
164
436
  * Fetch-API handler (`Request` → `Response`): mounts in Node 18+, edge
165
437
  * runtimes, Next, Hono, Express (via an adapter).
166
438
  */
167
439
 
440
+ /** Header names a request uses to bring the user's own key. */
441
+ declare const USER_KEY_HEADERS: {
442
+ readonly provider: "x-ai-provider";
443
+ readonly key: "x-ai-key";
444
+ readonly baseUrl: "x-ai-base-url";
445
+ };
446
+ /** The user's own provider settings, as the browser sends them. */
447
+ interface UserCredentials {
448
+ provider: string;
449
+ apiKey?: string;
450
+ /** Only honored when the server allows it (`userKeys.allowBaseUrl`). */
451
+ baseUrl?: string;
452
+ }
453
+ interface UserKeyOptions {
454
+ /** Providers users may bring a key for (default: every hosted provider in the catalog). */
455
+ providers?: string[];
456
+ /**
457
+ * Let users send their own API root (OpenAI-compatible servers, gateways).
458
+ * Off by default: your server would call whatever URL a user sends.
459
+ */
460
+ allowBaseUrl?: boolean;
461
+ /** Refuse requests without the user's own key, even when the server has a model. */
462
+ required?: boolean;
463
+ /** Build the model for a user's key (default `createChatModel`): add headers, pin params, wrap with limits. */
464
+ create?: (options: CreateChatModelOptions, request: Request) => ChatModel;
465
+ fetch?: FetchLike;
466
+ }
168
467
  interface ChatHandlerOptions {
169
468
  /** Path prefix the handler is mounted at, e.g. "/api/assistant". */
170
469
  basePath?: string;
171
470
  /** Reject request bodies larger than this (default 2 MB). */
172
471
  maxBodyBytes?: number;
173
- /** Return a Response to refuse a request (auth, rate limits); undefined to allow. */
472
+ /** Return a Response to refuse a request (auth, rate limits, plan checks); undefined to allow. */
174
473
  authorize?: (request: Request) => Promise<Response | undefined> | Response | undefined;
175
474
  /** Adjust each request server-side (pin a model, cap tokens, add instructions). */
176
475
  prepare?: (request: ChatRequest) => ChatRequest;
476
+ /** Accept the user's own provider key per request (see the module note). Off by default. */
477
+ userKeys?: boolean | UserKeyOptions;
478
+ }
479
+ /** What `GET {base}/` tells the browser about bring-your-own-key. */
480
+ interface UserKeyInfo {
481
+ providers: Pick<AiProviderInfo, "id" | "label" | "needsKey" | "keyUrl" | "defaultModel" | "models">[];
482
+ allowBaseUrl: boolean;
483
+ required: boolean;
484
+ }
485
+ /**
486
+ * @param model The server's own model (its keys, from env or config), or
487
+ * `null` when every user brings their own key (`userKeys` must be on).
488
+ */
489
+ declare function createChatHandler(model: ChatModel | null, options?: ChatHandlerOptions): (request: Request) => Promise<Response | null>;
490
+ /** What the server said about itself (`GET {base}/`). */
491
+ interface RemoteModelInfo {
492
+ id: string;
493
+ label: string;
494
+ models?: ModelEntry[];
495
+ providers?: {
496
+ id: string;
497
+ label: string;
498
+ }[];
499
+ userKeys?: UserKeyInfo;
500
+ /** The server has no model of its own (or requires user keys): calls need the user's key. */
501
+ needsKey?: boolean;
177
502
  }
178
- declare function createChatHandler(model: ChatModel, options?: ChatHandlerOptions): (request: Request) => Promise<Response | null>;
179
503
  interface RemoteChatModelOptions {
180
504
  fetch?: FetchLike;
181
505
  headers?: Record<string, string>;
182
506
  /** Skip the GET for model info (id/label/models default to "remote"). */
183
- info?: {
184
- id: string;
185
- label: string;
186
- models?: {
187
- id: string;
188
- label?: string;
189
- }[];
190
- };
507
+ info?: RemoteModelInfo;
508
+ /**
509
+ * The user's own provider key, read on every call (so a settings change
510
+ * applies at once). Return nothing to use the server's model.
511
+ */
512
+ credentials?: () => UserCredentials | null | undefined;
191
513
  }
192
- /** The model a backend serves, as a browser-side `ChatModel`. */
193
- declare function remoteChatModel(endpoint: string, options?: RemoteChatModelOptions): Promise<ChatModel>;
514
+ /** Headers carrying the user's own key, for any request to a `createChatHandler` server. */
515
+ declare function userKeyHeaders(credentials: UserCredentials | null | undefined): Record<string, string>;
516
+ /** The model a backend serves, as a browser-side `ChatModel` (plus what the server said about itself in `info`). */
517
+ declare function remoteChatModel(endpoint: string, options?: RemoteChatModelOptions): Promise<ChatModel & {
518
+ info: RemoteModelInfo;
519
+ }>;
194
520
 
195
521
  interface RateLimitOptions {
196
522
  /** Tokens per rolling minute across every caller of this model (input + output). */
@@ -245,7 +571,8 @@ declare function defineTool(tool: AssistantTool): AssistantTool;
245
571
  /**
246
572
  * Adopt tools that come as definitions plus one runner — e.g.
247
573
  * `@miraiclip/audio-sources`' `audioToolDefinitions` + `runAudioTool`.
248
- * Accepts `{ name, description, input_schema }` or OpenAI function tools.
574
+ * Accepts `{ name, description, input_schema }`, OpenAI function tools or
575
+ * Gemini function declarations.
249
576
  */
250
577
  declare function toolsFromDefinitions(definitions: readonly unknown[], run: (name: string, input: Record<string, unknown>, ctx: ToolContext) => Promise<{
251
578
  ok: boolean;
@@ -404,4 +731,4 @@ declare function scriptedChatModel(steps: ScriptStep[], options?: {
404
731
  requests: ChatRequest[];
405
732
  };
406
733
 
407
- export { type Assistant, type AssistantEvent, type AssistantOptions, type AssistantTool, type AssistantTurn, BACKGROUND_TEMPLATE, type ChatHandlerOptions, type ChatMessage, type ChatModel, ChatModelError, type ChatModelInfo, type ChatOptions, type ChatRequest, type ChatResponse, type ChatUsage, type CommitResult, DEFAULT_INSTRUCTIONS, type EditorToolsOptions, type FetchLike, type ForkOptions, type OpenAIChatModelOptions, type RateLimitOptions, type RecordingProject, type RemoteChatModelOptions, type ScriptStep, type ToolCall, type ToolContext, type ToolOutput, type ToolSpec, type TurnOptions, type UnknownFields, applyChecked, applyCommandsSchema, commitFork, createAssistant, createChatHandler, defineChatModel, defineTool, describeCommands, describeForAssistant, editorTools, forkProject, openAIChatModel, parseToolArguments, rateLimitedChatModel, remoteChatModel, retryDelayMs, scriptedChatModel, toOpenAIMessages, toolsFromDefinitions, unknownFields, withExplicitIds };
734
+ export { AI_PROVIDERS, type AiProviderInfo, type AnthropicChatModelOptions, type Assistant, type AssistantEvent, type AssistantOptions, type AssistantTool, type AssistantTurn, BACKGROUND_TEMPLATE, type ChatHandlerOptions, type ChatMessage, type ChatModel, ChatModelError, type ChatModelInfo, type ChatModelsFromEnvOptions, type ChatOptions, type ChatRequest, type ChatResponse, type ChatUsage, type CommitResult, type CreateChatModelOptions, DEFAULT_INSTRUCTIONS, type EditorToolsOptions, type FetchLike, type ForkOptions, type GeminiChatModelOptions, type ModelEntry, type OpenAIChatModelOptions, type ProviderApi, type RateLimitOptions, type RecordingProject, type RemoteChatModelOptions, type RemoteModelInfo, type RoutedChatModelOptions, type ScriptStep, type ToolCall, type ToolContext, type ToolOutput, type ToolSpec, type TurnOptions, USER_KEY_HEADERS, type UnknownFields, type UserCredentials, type UserKeyInfo, type UserKeyOptions, aiProvider, anthropicChatModel, applyChecked, applyCommandsSchema, chatModelsFromEnv, commitFork, createAssistant, createChatHandler, createChatModel, defineChatModel, defineTool, describeCommands, describeForAssistant, editorTools, forkProject, geminiChatModel, openAIChatModel, parseToolArguments, rateLimitedChatModel, remoteChatModel, retryDelayMs, routedChatModel, scriptedChatModel, splitModelRef, toAnthropicMessages, toGeminiContents, toOpenAIMessages, toolsFromDefinitions, unknownFields, userKeyHeaders, withExplicitIds };