@~lyre/ai-agents 0.2.0 → 0.4.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
@@ -1,4 +1,5 @@
1
1
  import { z } from 'zod';
2
+ import { LanguageModel } from 'ai';
2
3
  export { sanitizeRichHtml } from './sanitize.js';
3
4
 
4
5
  /**
@@ -42,11 +43,25 @@ type Message = {
42
43
  role: 'assistant';
43
44
  content: string;
44
45
  };
46
+ /**
47
+ * Client-level defaults applied to every run. `apiKey` is a single generic key the package uses
48
+ * to construct whichever provider a `provider/model` string names (see providers.ts), so consumers
49
+ * never import `@ai-sdk/*`. `model` is the default model when an agent doesn't specify one.
50
+ */
51
+ type ClientDefaults = {
52
+ apiKey?: string;
53
+ model?: ModelLike;
54
+ };
45
55
  type AgentDefinition = {
46
56
  /** Stable identifier; used as the lookup key. Defaults to `name`. */
47
57
  id?: string;
48
58
  name: string;
49
- model: ModelLike;
59
+ /**
60
+ * Model to use. A `provider/model` string (e.g. 'anthropic/claude-sonnet-4-5', 'openai/gpt-4o',
61
+ * 'xai/grok-2-latest') is resolved to a provider using the client's generic `apiKey`; a
62
+ * `LanguageModel` instance is used as-is. Optional — falls back to the client default model.
63
+ */
64
+ model?: ModelLike;
50
65
  /** System prompt. Inserted as a `system` message when no system message is in the history. */
51
66
  instructions?: string;
52
67
  temperature?: number;
@@ -62,7 +77,7 @@ type AgentDefinition = {
62
77
  providerOptions?: Record<string, Record<string, any>>;
63
78
  metadata?: Record<string, any>;
64
79
  };
65
- type Agent = Required<Pick<AgentDefinition, 'id' | 'name' | 'model' | 'instructions'>> & Omit<AgentDefinition, 'id' | 'name' | 'model' | 'instructions'>;
80
+ type Agent = Required<Pick<AgentDefinition, 'id' | 'name' | 'instructions'>> & Omit<AgentDefinition, 'id' | 'name' | 'instructions'>;
66
81
  type RunParams = {
67
82
  /** Agent id, name, or definition object. */
68
83
  agent: string | AgentDefinition;
@@ -181,7 +196,8 @@ declare class Registry {
181
196
  */
182
197
  declare class AiAgentsClient {
183
198
  private readonly registry;
184
- constructor();
199
+ private readonly defaults;
200
+ constructor(config?: ClientDefaults);
185
201
  registerTool<I, O>(tool: ToolDefinition<I, O>): ToolDefinition<I, O>;
186
202
  createAgent(definition: AgentDefinition): Agent;
187
203
  run(params: RunParams): Promise<RunResult>;
@@ -195,20 +211,33 @@ declare class AiAgentsClient {
195
211
  get raw(): Registry;
196
212
  }
197
213
  /**
198
- * Factory. Provider auth comes from environment variables. To explicitly configure
199
- * provider clients (e.g., for testing), pass `LanguageModel` instances to
200
- * `createAgent({ model })` instead of string identifiers.
214
+ * Factory. Pass a single generic `{ apiKey, model }` and the package constructs whichever
215
+ * provider the model's `provider/` prefix names so apps never import `@ai-sdk/*`. Omit the
216
+ * config to fall back to the Vercel AI SDK's own env-var/gateway resolution, or pass a
217
+ * `LanguageModel` instance via `createAgent({ model })` for fully custom wiring.
201
218
  */
202
- declare function createClient(): AiAgentsClient;
219
+ declare function createClient(config?: ClientDefaults): AiAgentsClient;
203
220
 
204
- declare function run(registry: Registry, params: RunParams): Promise<RunResult>;
205
- declare function runStream(registry: Registry, params: RunParams): AsyncGenerator<StreamEvent, void, unknown>;
221
+ declare function run(registry: Registry, params: RunParams, defaults?: ClientDefaults): Promise<RunResult>;
222
+ declare function runStream(registry: Registry, params: RunParams, defaults?: ClientDefaults): AsyncGenerator<StreamEvent, void, unknown>;
206
223
  /**
207
224
  * Schema-constrained structured generation. Single-shot (no tools): the model is
208
225
  * forced to return JSON matching `params.inputSchema`, validated by the AI SDK before
209
226
  * it resolves. Use this for analysis/extraction where you want a typed object instead
210
227
  * of free text. Additive — does not touch `run`/`runStream`.
211
228
  */
212
- declare function runObject<T>(registry: Registry, params: RunObjectParams<T>): Promise<RunObjectResult<T>>;
229
+ declare function runObject<T>(registry: Registry, params: RunObjectParams<T>, defaults?: ClientDefaults): Promise<RunObjectResult<T>>;
230
+
231
+ /** Provider prefixes this package can construct directly from a generic API key. */
232
+ declare const SUPPORTED_PROVIDERS: string[];
233
+ /**
234
+ * Turn a `provider/model` string (e.g. 'anthropic/claude-sonnet-4-5', 'openai/gpt-4o',
235
+ * 'xai/grok-2-latest') into a concrete provider model, using a single generic `apiKey`.
236
+ *
237
+ * Falls back to returning the original string when there's no recognizable provider prefix,
238
+ * the provider is unknown, or no `apiKey` is given — in which case the Vercel AI SDK resolves
239
+ * it itself (its gateway / provider-specific env vars). This keeps existing string usage working.
240
+ */
241
+ declare function resolveModelString(model: string, apiKey?: string): LanguageModel | string;
213
242
 
214
- export { type Agent, type AgentDefinition, AiAgentsClient, type Message, type ModelId, type ModelLike, Registry, type RunObjectParams, type RunObjectResult, type RunParams, type RunResult, type StreamEvent, type ToolContext, type ToolDefinition, createClient, run, runObject, runStream };
243
+ export { type Agent, type AgentDefinition, AiAgentsClient, type ClientDefaults, type Message, type ModelId, type ModelLike, Registry, type RunObjectParams, type RunObjectResult, type RunParams, type RunResult, SUPPORTED_PROVIDERS, type StreamEvent, type ToolContext, type ToolDefinition, createClient, resolveModelString, run, runObject, runStream };
package/dist/index.js CHANGED
@@ -46,9 +46,36 @@ var Registry = class {
46
46
  };
47
47
 
48
48
  // src/run.ts
49
- import { generateObject, generateText, streamText, tool } from "ai";
50
- function resolveModel(agent) {
51
- return agent.model;
49
+ import { generateText, streamText, tool, Output } from "ai";
50
+
51
+ // src/providers.ts
52
+ import { createAnthropic } from "@ai-sdk/anthropic";
53
+ import { createOpenAI } from "@ai-sdk/openai";
54
+ import { createXai } from "@ai-sdk/xai";
55
+ import { createGoogleGenerativeAI } from "@ai-sdk/google";
56
+ var PROVIDERS = {
57
+ anthropic: (apiKey, id) => createAnthropic({ apiKey })(id),
58
+ openai: (apiKey, id) => createOpenAI({ apiKey })(id),
59
+ xai: (apiKey, id) => createXai({ apiKey })(id),
60
+ // Grok
61
+ google: (apiKey, id) => createGoogleGenerativeAI({ apiKey })(id)
62
+ };
63
+ var SUPPORTED_PROVIDERS = Object.keys(PROVIDERS);
64
+ function resolveModelString(model, apiKey) {
65
+ const slash = model.indexOf("/");
66
+ if (slash <= 0) return model;
67
+ const provider = model.slice(0, slash);
68
+ const modelId = model.slice(slash + 1);
69
+ const factory = PROVIDERS[provider];
70
+ if (factory && apiKey && modelId) return factory(apiKey, modelId);
71
+ return model;
72
+ }
73
+
74
+ // src/run.ts
75
+ function resolveModel(agent, defaults) {
76
+ const model = agent.model ?? defaults?.model;
77
+ if (typeof model === "string") return resolveModelString(model, defaults?.apiKey);
78
+ return model;
52
79
  }
53
80
  function buildMessages(agent, params) {
54
81
  const messages = [];
@@ -75,12 +102,12 @@ function buildTools(registry, agent, context) {
75
102
  }
76
103
  return out;
77
104
  }
78
- async function run(registry, params) {
105
+ async function run(registry, params, defaults) {
79
106
  const agent = registry.resolveAgent(params.agent);
80
107
  const messages = buildMessages(agent, params);
81
108
  const tools = buildTools(registry, agent, params.context ?? {});
82
109
  const result = await generateText({
83
- model: resolveModel(agent),
110
+ model: resolveModel(agent, defaults),
84
111
  messages,
85
112
  tools,
86
113
  temperature: params.temperature ?? agent.temperature,
@@ -109,12 +136,12 @@ async function run(registry, params) {
109
136
  raw: result
110
137
  };
111
138
  }
112
- async function* runStream(registry, params) {
139
+ async function* runStream(registry, params, defaults) {
113
140
  const agent = registry.resolveAgent(params.agent);
114
141
  const messages = buildMessages(agent, params);
115
142
  const tools = buildTools(registry, agent, params.context ?? {});
116
143
  const result = streamText({
117
- model: resolveModel(agent),
144
+ model: resolveModel(agent, defaults),
118
145
  messages,
119
146
  tools,
120
147
  temperature: params.temperature ?? agent.temperature,
@@ -122,11 +149,21 @@ async function* runStream(registry, params) {
122
149
  stopWhen: ({ steps }) => steps.length >= (params.maxSteps ?? 8),
123
150
  providerOptions: agent.providerOptions
124
151
  });
152
+ const accumulatedUsage = { inputTokens: 0, outputTokens: 0, totalTokens: 0 };
153
+ const addUsage = (u) => {
154
+ if (!u) return;
155
+ accumulatedUsage.inputTokens += u.inputTokens ?? 0;
156
+ accumulatedUsage.outputTokens += u.outputTokens ?? 0;
157
+ accumulatedUsage.totalTokens += u.totalTokens ?? 0;
158
+ };
125
159
  for await (const part of result.fullStream) {
126
160
  switch (part.type) {
127
161
  case "text-delta":
128
162
  yield { type: "text-delta", text: part.text ?? part.delta ?? "" };
129
163
  break;
164
+ case "finish-step":
165
+ addUsage(part.usage);
166
+ break;
130
167
  case "tool-call":
131
168
  yield {
132
169
  type: "tool-call",
@@ -151,38 +188,42 @@ async function* runStream(registry, params) {
151
188
  error: part.error
152
189
  };
153
190
  break;
154
- case "finish":
191
+ case "finish": {
192
+ const finalUsage = part.totalUsage ?? part.usage;
155
193
  yield {
156
194
  type: "finish",
157
195
  finishReason: part.finishReason,
158
196
  usage: {
159
- inputTokens: part.usage?.inputTokens ?? 0,
160
- outputTokens: part.usage?.outputTokens ?? 0,
161
- totalTokens: part.usage?.totalTokens ?? 0
197
+ inputTokens: finalUsage?.inputTokens ?? accumulatedUsage.inputTokens,
198
+ outputTokens: finalUsage?.outputTokens ?? accumulatedUsage.outputTokens,
199
+ totalTokens: finalUsage?.totalTokens ?? accumulatedUsage.totalTokens
162
200
  }
163
201
  };
164
202
  break;
203
+ }
165
204
  case "error":
166
205
  yield { type: "error", error: part.error };
167
206
  break;
168
207
  }
169
208
  }
170
209
  }
171
- async function runObject(registry, params) {
210
+ async function runObject(registry, params, defaults) {
172
211
  const agent = registry.resolveAgent(params.agent);
173
212
  const messages = buildMessages(agent, params);
174
- const result = await generateObject({
175
- model: resolveModel(agent),
213
+ const result = await generateText({
214
+ model: resolveModel(agent, defaults),
176
215
  messages,
177
- schema: params.inputSchema,
178
- schemaName: params.schemaName,
179
- schemaDescription: params.schemaDescription,
216
+ output: Output.object({
217
+ schema: params.inputSchema,
218
+ name: params.schemaName,
219
+ description: params.schemaDescription
220
+ }),
180
221
  temperature: params.temperature ?? agent.temperature,
181
222
  maxOutputTokens: params.maxOutputTokens ?? agent.maxOutputTokens,
182
223
  providerOptions: agent.providerOptions
183
224
  });
184
225
  return {
185
- object: result.object,
226
+ object: result.output,
186
227
  finishReason: result.finishReason ?? "stop",
187
228
  usage: {
188
229
  inputTokens: result.usage?.inputTokens ?? 0,
@@ -196,8 +237,10 @@ async function runObject(registry, params) {
196
237
  // src/client.ts
197
238
  var AiAgentsClient = class {
198
239
  registry;
199
- constructor() {
240
+ defaults;
241
+ constructor(config) {
200
242
  this.registry = new Registry();
243
+ this.defaults = { apiKey: config?.apiKey, model: config?.model };
201
244
  }
202
245
  registerTool(tool2) {
203
246
  return this.registry.registerTool(tool2);
@@ -206,30 +249,32 @@ var AiAgentsClient = class {
206
249
  return this.registry.createAgent(definition);
207
250
  }
208
251
  async run(params) {
209
- return run(this.registry, params);
252
+ return run(this.registry, params, this.defaults);
210
253
  }
211
254
  runStream(params) {
212
- return runStream(this.registry, params);
255
+ return runStream(this.registry, params, this.defaults);
213
256
  }
214
257
  /**
215
258
  * Schema-constrained structured generation. Returns a validated, typed object
216
259
  * instead of free text. Single-shot (no tools). Added in 0.2.0.
217
260
  */
218
261
  async runObject(params) {
219
- return runObject(this.registry, params);
262
+ return runObject(this.registry, params, this.defaults);
220
263
  }
221
264
  /** Direct access to the underlying registry for advanced introspection. */
222
265
  get raw() {
223
266
  return this.registry;
224
267
  }
225
268
  };
226
- function createClient() {
227
- return new AiAgentsClient();
269
+ function createClient(config) {
270
+ return new AiAgentsClient(config);
228
271
  }
229
272
  export {
230
273
  AiAgentsClient,
231
274
  Registry,
275
+ SUPPORTED_PROVIDERS,
232
276
  createClient,
277
+ resolveModelString,
233
278
  run,
234
279
  runObject,
235
280
  runStream,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@~lyre/ai-agents",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "description": "Multi-provider AI agents SDK for SvelteKit + Node. Thin agent/tool/run/runStream surface over the Vercel AI SDK — OpenAI, Anthropic, Google Gemini, Mistral, Cohere. Zod-typed tools, full streaming event surface, optional HTML sanitizer.",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -48,13 +48,18 @@
48
48
  "build": "tsup src/index.ts src/sanitize.ts --format esm --dts --clean",
49
49
  "check": "tsc --noEmit"
50
50
  },
51
+ "dependencies": {
52
+ "@ai-sdk/anthropic": "^2.0.0",
53
+ "@ai-sdk/google": "^2.0.0",
54
+ "@ai-sdk/openai": "^2.0.0",
55
+ "@ai-sdk/xai": "^2.0.0",
56
+ "ai": "^6.0.0"
57
+ },
51
58
  "peerDependencies": {
52
- "ai": "^6.0.0",
53
59
  "zod": "^3.23.0 || ^4.0.0"
54
60
  },
55
61
  "devDependencies": {
56
62
  "@types/node": "^22",
57
- "ai": "^6.0.0",
58
63
  "tsup": "^8.3.5",
59
64
  "typescript": "^6.0.2",
60
65
  "zod": "^4.0.0"