agent-accelerator 0.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.
Files changed (46) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1220 -0
  3. package/SYSTEM_PROMPT.md +14 -0
  4. package/SYSTEM_PROMPT_AGENT.md +34 -0
  5. package/SYSTEM_PROMPT_TOOLS.md +9 -0
  6. package/bunfig.toml +2 -0
  7. package/package.json +59 -0
  8. package/src/agent/agent.ts +615 -0
  9. package/src/agent/context.ts +161 -0
  10. package/src/agent/delegation.ts +481 -0
  11. package/src/agent/loop.ts +569 -0
  12. package/src/agent/subagent.ts +83 -0
  13. package/src/ai-sdk/converters.ts +342 -0
  14. package/src/ai-sdk/errors.ts +122 -0
  15. package/src/ai-sdk/executor.ts +454 -0
  16. package/src/ai-sdk/index.ts +55 -0
  17. package/src/ai-sdk/model-provider.ts +303 -0
  18. package/src/ai-sdk/options.ts +306 -0
  19. package/src/ai-sdk/provider.ts +415 -0
  20. package/src/ai-sdk/registry.ts +416 -0
  21. package/src/data/README.md +84 -0
  22. package/src/index.ts +190 -0
  23. package/src/models/catalog-cache.ts +273 -0
  24. package/src/models/catalog.ts +503 -0
  25. package/src/streaming/event-stream.ts +211 -0
  26. package/src/streaming/sse-parser.ts +97 -0
  27. package/src/tokens/counter.ts +136 -0
  28. package/src/tools/executor.ts +365 -0
  29. package/src/tools/schema.ts +221 -0
  30. package/src/tools/tool.ts +101 -0
  31. package/src/types/agent.ts +87 -0
  32. package/src/types/core.ts +86 -0
  33. package/src/types/message.ts +115 -0
  34. package/src/types/model.ts +212 -0
  35. package/src/types/provider-payloads.ts +434 -0
  36. package/src/types/response.ts +158 -0
  37. package/src/types/tool.ts +61 -0
  38. package/src/utils/base64.ts +27 -0
  39. package/src/utils/cache.ts +146 -0
  40. package/src/utils/env.ts +78 -0
  41. package/src/utils/headers.ts +110 -0
  42. package/src/utils/media.ts +137 -0
  43. package/src/utils/serialization.ts +91 -0
  44. package/src/utils/session.ts +26 -0
  45. package/src/utils/thought-signature.ts +27 -0
  46. package/tsconfig.json +31 -0
@@ -0,0 +1,416 @@
1
+ import type { Provider, ProviderId, ModelSpec } from "../types/model.ts";
2
+ import type { ThinkingLevel } from "../types/core.ts";
3
+ import {
4
+ GoogleAiSdkProvider,
5
+ OpenCodeAiSdkProvider,
6
+ OpenRouterAiSdkProvider,
7
+ OpenAiAiSdkProvider,
8
+ CustomAiSdkProvider,
9
+ } from "./model-provider.ts";
10
+ import { getModelFromCatalog } from "../models/catalog.ts";
11
+ import { getEnv } from "../utils/env.ts";
12
+
13
+ const providerRegistry = new Map<ProviderId, Provider>();
14
+
15
+ // Initialize default supported providers powered purely by Vercel AI SDK
16
+ const googleProvider = new GoogleAiSdkProvider();
17
+ const opencodeProvider = new OpenCodeAiSdkProvider();
18
+ const openrouterProvider = new OpenRouterAiSdkProvider();
19
+ const openaiProvider = new OpenAiAiSdkProvider();
20
+
21
+ providerRegistry.set("google", googleProvider);
22
+ providerRegistry.set("gemini", googleProvider);
23
+ providerRegistry.set("opencode", opencodeProvider);
24
+ providerRegistry.set("opencode-go", opencodeProvider);
25
+ providerRegistry.set("openrouter", openrouterProvider);
26
+ providerRegistry.set("openai", openaiProvider);
27
+
28
+ // ---------------------------------------------------------------------------
29
+ // Unified multi-provider layer powered purely by Vercel AI SDK
30
+ // Any `MODEL="<prefix>/<model-id>"` works without SDK changes as long as
31
+ // `{PREFIX}_API_KEY` (+ optional `{PREFIX}_BASE_URL`) is set. Examples:
32
+ // MODEL="groq/llama-3.3-70b-versatile" + GROQ_API_KEY + GROQ_BASE_URL
33
+ // MODEL="cerebras/gpt-oss-120b" + CEREBRAS_API_KEY + CEREBRAS_BASE_URL
34
+ // MODEL="ollama/qwen2.5-coder" + OLLAMA_BASE_URL (key optional for local)
35
+ // ---------------------------------------------------------------------------
36
+ const FIRST_CLASS = new Set([
37
+ "google",
38
+ "gemini",
39
+ "opencode",
40
+ "opencode-go",
41
+ "openrouter",
42
+ "openai",
43
+ ]);
44
+
45
+ /**
46
+ * Normalizes a provider prefix for registry lookup and environment resolution.
47
+ * @example `const prefix = normalizeProviderPrefix(" Groq/llama ");`
48
+ */
49
+ export function normalizeProviderPrefix(prefix: string): string {
50
+ return prefix.trim().toLowerCase();
51
+ }
52
+
53
+ /**
54
+ * Get-or-create an OpenAI-compatible provider for any prefix backed by Vercel AI SDK.
55
+ * Cached, so repeated `resolveModel("groq/...")` calls reuse one instance.
56
+ */
57
+ /**
58
+ * Registers or retrieves an OpenAI-compatible provider for any custom prefix.
59
+ *
60
+ * @example `const groq = ensureCustomProvider("groq", { baseUrl: "https://api.groq.com/openai/v1" });`
61
+ */
62
+ export function ensureCustomProvider(
63
+ prefix: string,
64
+ opts?: { baseUrl?: string; apiKey?: string; name?: string }
65
+ ): Provider {
66
+ const id = normalizeProviderPrefix(prefix) as ProviderId;
67
+ const existing = providerRegistry.get(id);
68
+ if (existing && !FIRST_CLASS.has(id.toLowerCase())) return existing;
69
+ if (existing && opts?.baseUrl === undefined && opts?.apiKey === undefined) {
70
+ return existing;
71
+ }
72
+ const created = new CustomAiSdkProvider(id, opts);
73
+ providerRegistry.set(id, created);
74
+ return created;
75
+ }
76
+
77
+ /**
78
+ * Retrieves a provider by ID.
79
+ * Unknown ids auto-create an OpenAI-compatible provider (unified layer),
80
+ * so `getProvider("groq")` works after setting `GROQ_API_KEY`/`GROQ_BASE_URL`.
81
+ */
82
+ /**
83
+ * Retrieves a first-class provider or lazily creates a custom compatible provider.
84
+ *
85
+ * @example `const provider = getProvider("google");`
86
+ */
87
+ export function getProvider(id: ProviderId | string): Provider {
88
+ const key = String(id).trim() as ProviderId;
89
+ const provider = providerRegistry.get(key);
90
+ if (provider) return provider;
91
+ if (!key) {
92
+ throw new Error(
93
+ `Provider '' is not supported or not registered. Available first-support providers: google, opencode, openrouter, openai — or any custom prefix via {PREFIX}_API_KEY + {PREFIX}_BASE_URL.`
94
+ );
95
+ }
96
+ // Unified layer: lazily create OpenAI-compatible provider for any custom prefix.
97
+ return ensureCustomProvider(key);
98
+ }
99
+
100
+ /** Provider/model pair returned by resolveModel. */
101
+ export interface ResolvedModel {
102
+ provider: Provider;
103
+ modelId: string;
104
+ modelSpec?: ModelSpec;
105
+ }
106
+
107
+ /**
108
+ * Resolves a model string (e.g. "google/model-id", "opencode/model-id", "openrouter/scope/model:variant")
109
+ * or ModelSpec into provider instance and model ID using Vercel AI SDK provider layer.
110
+ */
111
+ /**
112
+ * Resolves `provider/model`, catalog specs, scoped OpenRouter IDs, and custom prefixes.
113
+ *
114
+ * @example `const { provider, modelId } = resolveModel("openai/gpt-4o");`
115
+ */
116
+ export function resolveModel(model: string | ModelSpec): ResolvedModel {
117
+ if (!model || (typeof model === "string" && !model.trim())) {
118
+ throw new Error(
119
+ "[Agent Accelerator] No model specified. Please specify 'model' in Agent configuration or set the MODEL environment variable."
120
+ );
121
+ }
122
+
123
+ if (typeof model === "object" && model !== null && "provider" in model) {
124
+ const provider = getProvider(model.provider);
125
+ // Enrich with catalog if available
126
+ const catalogSpec = getModelFromCatalog(model.provider, model.id);
127
+ return {
128
+ provider,
129
+ modelId: model.id,
130
+ modelSpec: catalogSpec || model,
131
+ };
132
+ }
133
+
134
+ const modelStr = String(model).trim();
135
+
136
+ // Try catalog first for any provider/model
137
+ const tryCatalogLookup = (prov: string, mid: string): ModelSpec | undefined => {
138
+ return (
139
+ getModelFromCatalog(prov, mid) ||
140
+ getModelFromCatalog(prov.toLowerCase(), mid) ||
141
+ getModelFromCatalog(mid, mid)
142
+ );
143
+ };
144
+
145
+ const hasCustomOpenAIBase = !!(getEnv("OPENAI_BASE_URL") || getEnv("OPENAI_API_BASE"));
146
+
147
+ // Explicit prefix with slash — deterministic
148
+ if (modelStr.includes("/")) {
149
+ const parts = modelStr.split("/");
150
+ const providerPrefix = parts[0]!.toLowerCase();
151
+ const remainingModel = parts.slice(1).join("/");
152
+
153
+ // 1. Explicit openai/ prefix ALWAYS routes to OpenAI provider
154
+ if (providerPrefix === "openai") {
155
+ const p = getProvider("openai");
156
+ const spec =
157
+ p.getModel(remainingModel) ||
158
+ getModelFromCatalog("openai", remainingModel) ||
159
+ getModelFromCatalog(remainingModel, remainingModel);
160
+ return { provider: p, modelId: remainingModel, modelSpec: spec as ModelSpec };
161
+ }
162
+
163
+ // 2. Unified layer: any non-first-class prefix routes to auto-created custom provider
164
+ const isExplicitOther = [
165
+ "google",
166
+ "gemini",
167
+ "opencode",
168
+ "opencode-go",
169
+ "openrouter",
170
+ ].includes(providerPrefix);
171
+
172
+ if (!isExplicitOther && providerPrefix !== "openai") {
173
+ const envName = providerPrefix.toUpperCase().replace(/[^A-Z0-9]/g, "_");
174
+ const hasDedicatedEnv = !!(
175
+ getEnv(`${envName}_BASE_URL`) ||
176
+ getEnv(`${envName}_BASEURL`) ||
177
+ getEnv(`${envName}_API_BASE`) ||
178
+ getEnv(`${envName}_API_KEY`) ||
179
+ getEnv(`${envName}_BASE_API_KEY`)
180
+ );
181
+
182
+ const looksLikeOpenRouterScope =
183
+ parts.length === 2 && modelStr.includes(":") && !hasDedicatedEnv;
184
+
185
+ if (!looksLikeOpenRouterScope) {
186
+ if (hasCustomOpenAIBase && !hasDedicatedEnv) {
187
+ const p = getProvider("openai");
188
+ const spec = p.getModel(remainingModel) || getModelFromCatalog(remainingModel, remainingModel);
189
+ return { provider: p, modelId: remainingModel, modelSpec: spec as ModelSpec };
190
+ }
191
+ const custom = ensureCustomProvider(providerPrefix);
192
+ const spec =
193
+ custom.getModel(remainingModel) ||
194
+ custom.getModel(modelStr) ||
195
+ tryCatalogLookup(providerPrefix, remainingModel) ||
196
+ tryCatalogLookup(providerPrefix, modelStr) ||
197
+ getModelFromCatalog(remainingModel, remainingModel);
198
+ return { provider: custom, modelId: remainingModel, modelSpec: spec as ModelSpec };
199
+ }
200
+ }
201
+
202
+ if (providerPrefix === "google" || providerPrefix === "gemini") {
203
+ const p = getProvider("google");
204
+ const spec =
205
+ p.getModel(remainingModel) ||
206
+ getModelFromCatalog("google", remainingModel) ||
207
+ getModelFromCatalog(remainingModel, remainingModel);
208
+ return { provider: p, modelId: remainingModel, modelSpec: spec as ModelSpec };
209
+ }
210
+
211
+ if (
212
+ providerPrefix === "opencode" ||
213
+ providerPrefix === "opencode-go"
214
+ ) {
215
+ const p = getProvider("opencode");
216
+ const spec =
217
+ p.getModel(remainingModel) ||
218
+ getModelFromCatalog("opencode", remainingModel) ||
219
+ getModelFromCatalog(remainingModel, remainingModel);
220
+ return { provider: p, modelId: remainingModel, modelSpec: spec as ModelSpec };
221
+ }
222
+
223
+ if (providerPrefix === "openrouter") {
224
+ const p = getProvider("openrouter");
225
+ const spec =
226
+ p.getModel(remainingModel) ||
227
+ getModelFromCatalog("openrouter", remainingModel) ||
228
+ getModelFromCatalog(remainingModel, remainingModel);
229
+ return { provider: p, modelId: remainingModel, modelSpec: spec as ModelSpec };
230
+ }
231
+
232
+ // Scoped OpenRouter models like "scope/model:variant" without openrouter prefix
233
+ if (parts.length === 2 && modelStr.includes(":")) {
234
+ const p = getProvider("openrouter");
235
+ const spec = p.getModel(modelStr) || tryCatalogLookup("openrouter", modelStr);
236
+ return { provider: p, modelId: modelStr, modelSpec: spec as ModelSpec };
237
+ }
238
+
239
+ // Check catalog for this exact provider/model
240
+ const catalogSpec =
241
+ tryCatalogLookup(providerPrefix, remainingModel) ||
242
+ tryCatalogLookup(providerPrefix, modelStr);
243
+ if (catalogSpec) {
244
+ const internalProvider = getProvider(catalogSpec.provider);
245
+ return { provider: internalProvider, modelId: catalogSpec.id, modelSpec: catalogSpec };
246
+ }
247
+
248
+ // Unknown provider prefix — try catalog with priority
249
+ const prioritizedUnknown =
250
+ tryCatalogLookup(providerPrefix, remainingModel) ||
251
+ tryCatalogLookup("google", remainingModel) ||
252
+ tryCatalogLookup("opencode", remainingModel) ||
253
+ tryCatalogLookup("openai", remainingModel) ||
254
+ tryCatalogLookup("openrouter", remainingModel) ||
255
+ getModelFromCatalog(modelStr, modelStr);
256
+ if (prioritizedUnknown) {
257
+ const internalProvider = getProvider(prioritizedUnknown.provider);
258
+ return {
259
+ provider: internalProvider,
260
+ modelId: prioritizedUnknown.id,
261
+ modelSpec: prioritizedUnknown,
262
+ };
263
+ }
264
+
265
+ // Fallback custom provider
266
+ const fallbackCustom = ensureCustomProvider(providerPrefix);
267
+ const fallbackSpec =
268
+ fallbackCustom.getModel(remainingModel) || fallbackCustom.getModel(modelStr);
269
+ return {
270
+ provider: fallbackCustom,
271
+ modelId: remainingModel,
272
+ modelSpec: fallbackSpec as ModelSpec,
273
+ };
274
+ }
275
+
276
+ // When OPENAI_BASE_URL is set: trust user completely
277
+ if (hasCustomOpenAIBase) {
278
+ const p = getProvider("openai");
279
+ const spec = p.getModel(modelStr) || getModelFromCatalog(modelStr, modelStr);
280
+ return { provider: p, modelId: modelStr, modelSpec: spec as ModelSpec };
281
+ }
282
+
283
+ // No slash — try catalog with internal provider priority
284
+ const prioritized =
285
+ tryCatalogLookup("google", modelStr) ||
286
+ tryCatalogLookup("opencode", modelStr) ||
287
+ tryCatalogLookup("openai", modelStr) ||
288
+ tryCatalogLookup("openrouter", modelStr) ||
289
+ getModelFromCatalog(modelStr, modelStr);
290
+ if (prioritized) {
291
+ const internalProvider = getProvider(prioritized.provider);
292
+ return { provider: internalProvider, modelId: prioritized.id, modelSpec: prioritized };
293
+ }
294
+
295
+ // Fallback to openrouter
296
+ const p = getProvider("openrouter");
297
+ return { provider: p, modelId: modelStr, modelSpec: p.getModel(modelStr) };
298
+ }
299
+
300
+ /** Configuration accepted by the ModelProvider helper family. */
301
+ export interface ModelProviderConfig {
302
+ apiKey?: string;
303
+ thinkingLevel?: ThinkingLevel;
304
+ baseUrl?: string;
305
+ }
306
+
307
+ /** Serializable model/provider selection returned by ModelProvider helpers. */
308
+ export interface ModelProviderInstance {
309
+ model: string;
310
+ apiKey?: string;
311
+ baseUrl?: string;
312
+ thinkingLevel?: ThinkingLevel;
313
+ }
314
+
315
+ /**
316
+ * ModelProvider builder helper for python-like and expressive syntax
317
+ */
318
+ /**
319
+ * Provider/model builder helpers for expressive configuration.
320
+ *
321
+ * @example `new Agent({ model: ModelProvider.GoogleGenAI("gemini-3.5-flash-lite") })`
322
+ */
323
+ export const ModelProvider = {
324
+ /** Builds a Google AI Studio model selection. @example `ModelProvider.GoogleGenAI("gemini-3.5-flash-lite")` */
325
+ GoogleGenAI(
326
+ model: string,
327
+ apiKey?: string,
328
+ options?: { thinkingLevel?: ThinkingLevel; baseUrl?: string }
329
+ ): ModelProviderInstance {
330
+ return {
331
+ model: model.startsWith("google/") ? model : `google/${model}`,
332
+ apiKey,
333
+ baseUrl: options?.baseUrl,
334
+ thinkingLevel: options?.thinkingLevel,
335
+ };
336
+ },
337
+
338
+ /** Builds an OpenCode model selection. @example `ModelProvider.OpenCode("kimi-k2.5")` */
339
+ OpenCode(
340
+ model: string,
341
+ apiKey?: string,
342
+ options?: { thinkingLevel?: ThinkingLevel; baseUrl?: string }
343
+ ): ModelProviderInstance {
344
+ return {
345
+ model: model.startsWith("opencode") ? model : `opencode/${model}`,
346
+ apiKey,
347
+ baseUrl: options?.baseUrl,
348
+ thinkingLevel: options?.thinkingLevel,
349
+ };
350
+ },
351
+
352
+ /** Builds an OpenRouter model selection. @example `ModelProvider.OpenRouter("openai/gpt-4o")` */
353
+ OpenRouter(
354
+ model: string,
355
+ apiKey?: string,
356
+ options?: { thinkingLevel?: ThinkingLevel; baseUrl?: string }
357
+ ): ModelProviderInstance {
358
+ return {
359
+ model: model.startsWith("openrouter/") ? model : `openrouter/${model}`,
360
+ apiKey,
361
+ baseUrl: options?.baseUrl,
362
+ thinkingLevel: options?.thinkingLevel,
363
+ };
364
+ },
365
+
366
+ /** Builds an OpenAI model selection. @example `ModelProvider.OpenAI("gpt-4o")` */
367
+ OpenAI(
368
+ model: string,
369
+ apiKey?: string,
370
+ options?: { thinkingLevel?: ThinkingLevel; baseUrl?: string }
371
+ ): ModelProviderInstance {
372
+ return {
373
+ model: model.startsWith("openai/") ? model : `openai/${model}`,
374
+ apiKey,
375
+ baseUrl: options?.baseUrl,
376
+ thinkingLevel: options?.thinkingLevel,
377
+ };
378
+ },
379
+
380
+ /** Builds an arbitrary OpenAI-compatible model selection. @example `ModelProvider.Custom("groq/llama-3.3-70b-versatile")` */
381
+ Custom(
382
+ model: string,
383
+ apiKey?: string,
384
+ options?: { thinkingLevel?: ThinkingLevel; baseUrl?: string }
385
+ ): ModelProviderInstance {
386
+ const normalized = model.includes("/") ? model : `custom/${model}`;
387
+ const prefix = normalized.split("/")[0]!;
388
+ try {
389
+ ensureCustomProvider(prefix, { baseUrl: options?.baseUrl, apiKey });
390
+ } catch {}
391
+ return {
392
+ model: normalized,
393
+ apiKey,
394
+ baseUrl: options?.baseUrl,
395
+ thinkingLevel: options?.thinkingLevel,
396
+ };
397
+ },
398
+
399
+ /** Alias for Custom for explicit OpenAI-compatible endpoints. @example `ModelProvider.OpenAICompatible("ollama/qwen2.5-coder")` */
400
+ OpenAICompatible(
401
+ model: string,
402
+ apiKey?: string,
403
+ options?: { thinkingLevel?: ThinkingLevel; baseUrl?: string }
404
+ ): ModelProviderInstance {
405
+ return ModelProvider.Custom(model, apiKey, options);
406
+ },
407
+
408
+ /** Alias for Custom for generic local/hosted endpoints. @example `ModelProvider.Generic("my-provider/model-id")` */
409
+ Generic(
410
+ model: string,
411
+ apiKey?: string,
412
+ options?: { thinkingLevel?: ThinkingLevel; baseUrl?: string }
413
+ ): ModelProviderInstance {
414
+ return ModelProvider.Custom(model, apiKey, options);
415
+ },
416
+ };
@@ -0,0 +1,84 @@
1
+ # Model Catalog Cache (`src/data/`)
2
+
3
+ This directory is the local destination for the dynamic model catalog cache used by **Agent Accelerator**.
4
+
5
+ Agent Accelerator references a catalog of **7,500+ models across 200+ providers** for token limits, context windows, modality support, reasoning configurations, and per-token pricing (input, output, cache-read, cache-write).
6
+
7
+ ---
8
+
9
+ ## Zero-Bloat Distribution Architecture
10
+
11
+ To keep the repository and published npm/Bun package lightweight and blazing fast:
12
+
13
+ 1. **Excluded from Production Package & Git**:
14
+ * The ~4.5 MB full catalog snapshot (`models-cache.json` / `models.dev.json`) is **never** committed to git and is **excluded** from the npm/Bun distribution bundle.
15
+ * Both files are tracked in `.gitignore` and `.npmignore`.
16
+
17
+ 2. **Dynamic 12-Hour Automated TTL Cache**:
18
+ * On agent execution (`runAgentLoop` / `streamAgentLoop`), Agent Accelerator checks the status of `src/data/models-cache.json`.
19
+ * **Cache Hit (< 12h)**: Instant memory/disk load with zero network overhead.
20
+ * **Cache Miss / Expired (≥ 12h)**: Automatically downloads the latest catalog directly from `https://models.dev/api.json`, caches it to `src/data/models-cache.json`, and loads the catalog into memory.
21
+ * **Resilience**: If an existing cache exists on disk, temporary upstream network issues will safely continue using the local cached copy.
22
+
23
+ ---
24
+
25
+ ## Developer Controls & Management
26
+
27
+ ### 1. CLI Script
28
+
29
+ You can manually inspect or refresh the model catalog anytime via the developer CLI script:
30
+
31
+ ```bash
32
+ # Refresh catalog if expired (or download if missing)
33
+ bun run update-models
34
+
35
+ # Force download regardless of age
36
+ bun run update-models --force
37
+
38
+ # Custom TTL (e.g., 24 hours)
39
+ bun scripts/update-models.ts --ttl=24h
40
+ ```
41
+
42
+ ---
43
+
44
+ ### 2. Programmatic API
45
+
46
+ All catalog cache lifecycle controls are exported from the root package:
47
+
48
+ ```typescript
49
+ import {
50
+ refreshModelCatalog,
51
+ ensureModelCatalogFresh,
52
+ getCatalogStatus,
53
+ setCatalogTTL,
54
+ getModelFromCatalog,
55
+ } from "agent-accelerator";
56
+
57
+ // 1. Check current cache status
58
+ const status = getCatalogStatus();
59
+ console.log(status);
60
+ // {
61
+ // isExpired: false,
62
+ // cachedAt: 1773400000000,
63
+ // ttlMs: 43200000,
64
+ // modelCount: 7696,
65
+ // providerCount: 213,
66
+ // source: "cache"
67
+ // }
68
+
69
+ // 2. Refresh on-demand (e.g. in a cron job or startup hook)
70
+ await refreshModelCatalog({ force: true });
71
+
72
+ // 3. Customize runtime TTL (e.g., 6 hours)
73
+ setCatalogTTL(6 * 60 * 60 * 1000);
74
+ ```
75
+
76
+ ---
77
+
78
+ ## Structure
79
+
80
+ ```text
81
+ src/data/
82
+ ├── README.md # This documentation
83
+ └── models-cache.json # Auto-generated on first run (gitignored, excluded from bundle)
84
+ ```
package/src/index.ts ADDED
@@ -0,0 +1,190 @@
1
+ import { z } from "zod";
2
+
3
+ // Core Agent & Tool Classes
4
+ export { Agent, SubAgentModelError } from "./agent/agent.ts";
5
+ export { SubAgent } from "./agent/subagent.ts";
6
+ export type { SubAgentConfig } from "./agent/subagent.ts";
7
+ export { tool, toStandardToolDeclarations } from "./tools/tool.ts";
8
+ export type { CreateToolOptions } from "./tools/tool.ts";
9
+ export { zodToJsonSchema, cleanJsonSchema } from "./tools/schema.ts";
10
+ export { executeToolCalls } from "./tools/executor.ts";
11
+
12
+ // Multi-Agent Delegation & Tools
13
+ export {
14
+ buildAgentTools,
15
+ createSubagentSpawnTool,
16
+ } from "./agent/delegation.ts";
17
+ export type { DynamicSubagentTask } from "./agent/delegation.ts";
18
+
19
+ // Providers & Registry — unified multi-provider layer powered by Vercel AI SDK
20
+ export {
21
+ getProvider,
22
+ resolveModel,
23
+ ModelProvider,
24
+ ensureCustomProvider,
25
+ normalizeProviderPrefix,
26
+ } from "./ai-sdk/registry.ts";
27
+ export {
28
+ getModelFromCatalog,
29
+ getModelThinkingInfo,
30
+ validateModelThinking,
31
+ getModelsForProvider,
32
+ ThinkingLevelError,
33
+ refreshModelCatalog,
34
+ ensureModelCatalogFresh,
35
+ getCatalogStatus,
36
+ setCatalogTTL,
37
+ getCatalogTTL,
38
+ getCacheDir,
39
+ getCacheFilePath,
40
+ DEFAULT_CATALOG_TTL_MS,
41
+ type CatalogStatus,
42
+ type RefreshCatalogOptions,
43
+ } from "./models/catalog.ts";
44
+ export { AiSdkBaseProvider as BaseProvider } from "./ai-sdk/model-provider.ts";
45
+ export {
46
+ mapThinkingToReasoning,
47
+ resolveEffectiveThinking,
48
+ mapToolChoice,
49
+ mapThinkingToProviderOptions,
50
+ mapServiceTierToProviderOptions,
51
+ mapCacheToProviderOptions,
52
+ buildAiSdkCallOptions,
53
+ withAiSdkRetries,
54
+ isTransientAiSdkError,
55
+ } from "./ai-sdk/options.ts";
56
+ export { toConciseProviderError, assertModalitiesSupported } from "./ai-sdk/errors.ts";
57
+
58
+ // Provider Implementations powered by Vercel AI SDK
59
+ export {
60
+ GoogleAIStudioProvider,
61
+ GoogleAiSdkProvider,
62
+ OpenCodeProvider,
63
+ OpenCodeAiSdkProvider,
64
+ OpenRouterProvider,
65
+ OpenRouterAiSdkProvider,
66
+ OpenAIProvider,
67
+ OpenAiAiSdkProvider,
68
+ OpenAICompatibleProvider,
69
+ CustomAiSdkProvider,
70
+ AiSdkBaseProvider,
71
+ createOpenAICompatibleProvider,
72
+ createCustomProvider,
73
+ CustomProvider,
74
+ createGenericModelSpec,
75
+ } from "./ai-sdk/model-provider.ts";
76
+ export type { CustomProviderOptions } from "./ai-sdk/model-provider.ts";
77
+
78
+ export {
79
+ GOOGLE_MODELS,
80
+ OPENAI_MODELS,
81
+ OPENCODE_MODELS,
82
+ OPENROUTER_MODELS,
83
+ } from "./models/catalog.ts";
84
+
85
+ export {
86
+ isValidThoughtSignature,
87
+ retainThoughtSignature,
88
+ extractGoogleThoughtSignature,
89
+ } from "./utils/thought-signature.ts";
90
+
91
+ export { stripSchemaForGoogle } from "./tools/schema.ts";
92
+
93
+ export {
94
+ createExplicitCache,
95
+ retentionToTtlSeconds,
96
+ getPromptCacheRetention,
97
+ clampCacheKey,
98
+ } from "./utils/cache.ts";
99
+ export type {
100
+ CreateExplicitCacheOptions,
101
+ CachedContentMetadata,
102
+ } from "./utils/cache.ts";
103
+
104
+
105
+ export {
106
+ countTokens,
107
+ estimateTokensFromText,
108
+ estimateTokensFromMessage,
109
+ estimateTokensFromPart,
110
+ } from "./tokens/counter.ts";
111
+
112
+ // Streaming & Events
113
+ export { AssistantMessageEventStream } from "./streaming/event-stream.ts";
114
+ export { SSEParser } from "./streaming/sse-parser.ts";
115
+
116
+ // Responses
117
+ export { AgentResponse } from "./types/response.ts";
118
+
119
+ // Utilities
120
+ export { createSessionId } from "./utils/session.ts";
121
+ export { getApiKey, getEnv } from "./utils/env.ts";
122
+ export { buildSessionHeaders } from "./utils/headers.ts";
123
+ export { normalizeMediaInput, inferMimeType } from "./utils/media.ts";
124
+ export { base64ToBytes, bytesToBase64 } from "./utils/base64.ts";
125
+ export { toJsonSafe, safeStringify } from "./utils/serialization.ts";
126
+
127
+ // Re-export Zod
128
+ export { z };
129
+
130
+ // TypeScript Type Exports
131
+ export type {
132
+ ThinkingLevel,
133
+ ThinkingConfig,
134
+ CacheRetention,
135
+ CacheConfig,
136
+ ServiceTier,
137
+ TokenUsage,
138
+ } from "./types/core.ts";
139
+
140
+ export type {
141
+ Message,
142
+ MessageRole,
143
+ ContentPart,
144
+ TextPart,
145
+ ImagePart,
146
+ AudioPart,
147
+ VideoPart,
148
+ FilePart,
149
+ ToolCallPart,
150
+ ToolResultPart,
151
+ ThinkingPart,
152
+ ProviderContext,
153
+ } from "./types/message.ts";
154
+
155
+ export type {
156
+ ToolDefinition,
157
+ ToolExecuteFn,
158
+ ToolExecutionContext,
159
+ ToolCallRecord,
160
+ ToolResultRecord,
161
+ StandardToolDeclaration,
162
+ } from "./types/tool.ts";
163
+
164
+ export type {
165
+ ModelSpec,
166
+ ModelCapabilities,
167
+ Provider,
168
+ ProviderId,
169
+ ProviderRequestOptions,
170
+ ProviderGenerateResult,
171
+ ProviderRawData,
172
+ } from "./types/model.ts";
173
+
174
+ export type {
175
+ AgentResponseJSON,
176
+ SubAgentExecutionMetadata,
177
+ StreamEvent,
178
+ StreamEventType,
179
+ } from "./types/response.ts";
180
+
181
+ export type {
182
+ AgentConfig,
183
+ AgentRunOptions,
184
+ DynamicSubagentsConfig,
185
+ } from "./types/agent.ts";
186
+
187
+ export type {
188
+ ModelProviderInstance,
189
+ ModelProviderConfig,
190
+ } from "./ai-sdk/registry.ts";