@~lyre/ai-agents 0.4.0 → 0.5.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/dist/index.d.ts CHANGED
@@ -91,6 +91,31 @@ type RunParams = {
91
91
  temperature?: number;
92
92
  /** Max number of tool-call iterations before bailing. Default 8. */
93
93
  maxSteps?: number;
94
+ /**
95
+ * Optional schema-constrained final output. When set, the run uses tools AND forces the model's
96
+ * FINAL answer to be a JSON object matching this schema (AI SDK `Output.object`) — i.e. call tools,
97
+ * read their results, then produce a validated object. The validated object is surfaced on the
98
+ * `finish` stream event as `object` (and on `RunResult.object`). Generating the object counts as a
99
+ * step, so keep `maxSteps` high enough for tool calls + the object step. Omit for free-text runs.
100
+ */
101
+ output?: {
102
+ schema: z.ZodSchema<any>;
103
+ name?: string;
104
+ description?: string;
105
+ };
106
+ /**
107
+ * Tool-selection policy for the FIRST step (AI SDK / OpenAI `tool_choice`):
108
+ * - `'auto'` (default): the model decides whether to call a tool.
109
+ * - `'required'`: the model MUST call a tool before it can answer — use this to force a data
110
+ * round-trip so the model can't fabricate an answer (e.g. a canvas with placeholder values).
111
+ * - `'none'`: the model must not call tools.
112
+ * - `{ toolName }`: force a specific tool.
113
+ * Only the first step is constrained; later steps fall back to `auto` so the model can stop calling
114
+ * tools and produce its final (optionally schema-constrained) answer.
115
+ */
116
+ toolChoice?: 'auto' | 'required' | 'none' | {
117
+ toolName: string;
118
+ };
94
119
  /** Forwarded to tool `execute(input, context)`. */
95
120
  context?: Record<string, any>;
96
121
  };
@@ -112,6 +137,8 @@ type RunResult = {
112
137
  toolName: string;
113
138
  output: unknown;
114
139
  }[];
140
+ /** The schema-validated final object, present only when the run was given `output`. */
141
+ object?: unknown;
115
142
  raw: any;
116
143
  };
117
144
  type StreamEvent = {
@@ -140,6 +167,8 @@ type StreamEvent = {
140
167
  outputTokens: number;
141
168
  totalTokens: number;
142
169
  };
170
+ /** The schema-validated final object, present only when the run was given `output`. */
171
+ object?: unknown;
143
172
  } | {
144
173
  type: 'error';
145
174
  error: unknown;
package/dist/index.js CHANGED
@@ -60,6 +60,12 @@ var PROVIDERS = {
60
60
  // Grok
61
61
  google: (apiKey, id) => createGoogleGenerativeAI({ apiKey })(id)
62
62
  };
63
+ var PROVIDER_ENV = {
64
+ anthropic: "ANTHROPIC_API_KEY",
65
+ openai: "OPENAI_API_KEY",
66
+ xai: "XAI_API_KEY",
67
+ google: "GOOGLE_GENERATIVE_AI_API_KEY"
68
+ };
63
69
  var SUPPORTED_PROVIDERS = Object.keys(PROVIDERS);
64
70
  function resolveModelString(model, apiKey) {
65
71
  const slash = model.indexOf("/");
@@ -67,7 +73,10 @@ function resolveModelString(model, apiKey) {
67
73
  const provider = model.slice(0, slash);
68
74
  const modelId = model.slice(slash + 1);
69
75
  const factory = PROVIDERS[provider];
70
- if (factory && apiKey && modelId) return factory(apiKey, modelId);
76
+ if (!factory || !modelId) return model;
77
+ const envKey = typeof process !== "undefined" ? process.env?.[PROVIDER_ENV[provider]] : void 0;
78
+ const key = envKey || apiKey;
79
+ if (key) return factory(key, modelId);
71
80
  return model;
72
81
  }
73
82
 
@@ -102,6 +111,21 @@ function buildTools(registry, agent, context) {
102
111
  }
103
112
  return out;
104
113
  }
114
+ function buildRunOptions(params) {
115
+ const opts = {};
116
+ if (params.output) {
117
+ opts.output = Output.object({
118
+ schema: params.output.schema,
119
+ name: params.output.name,
120
+ description: params.output.description
121
+ });
122
+ }
123
+ if (params.toolChoice && params.toolChoice !== "auto") {
124
+ opts.toolChoice = params.toolChoice;
125
+ opts.prepareStep = ({ stepNumber }) => stepNumber === 0 ? { toolChoice: params.toolChoice } : { toolChoice: "auto" };
126
+ }
127
+ return opts;
128
+ }
105
129
  async function run(registry, params, defaults) {
106
130
  const agent = registry.resolveAgent(params.agent);
107
131
  const messages = buildMessages(agent, params);
@@ -110,6 +134,7 @@ async function run(registry, params, defaults) {
110
134
  model: resolveModel(agent, defaults),
111
135
  messages,
112
136
  tools,
137
+ ...buildRunOptions(params),
113
138
  temperature: params.temperature ?? agent.temperature,
114
139
  maxOutputTokens: params.maxOutputTokens ?? agent.maxOutputTokens,
115
140
  stopWhen: ({ steps }) => steps.length >= (params.maxSteps ?? 8),
@@ -133,6 +158,7 @@ async function run(registry, params, defaults) {
133
158
  toolName: r.toolName,
134
159
  output: r.output
135
160
  })),
161
+ ...params.output ? { object: result.experimental_output } : {},
136
162
  raw: result
137
163
  };
138
164
  }
@@ -144,6 +170,7 @@ async function* runStream(registry, params, defaults) {
144
170
  model: resolveModel(agent, defaults),
145
171
  messages,
146
172
  tools,
173
+ ...buildRunOptions(params),
147
174
  temperature: params.temperature ?? agent.temperature,
148
175
  maxOutputTokens: params.maxOutputTokens ?? agent.maxOutputTokens,
149
176
  stopWhen: ({ steps }) => steps.length >= (params.maxSteps ?? 8),
@@ -190,6 +217,10 @@ async function* runStream(registry, params, defaults) {
190
217
  break;
191
218
  case "finish": {
192
219
  const finalUsage = part.totalUsage ?? part.usage;
220
+ let object;
221
+ if (params.output) {
222
+ object = await result.experimental_output;
223
+ }
193
224
  yield {
194
225
  type: "finish",
195
226
  finishReason: part.finishReason,
@@ -197,7 +228,8 @@ async function* runStream(registry, params, defaults) {
197
228
  inputTokens: finalUsage?.inputTokens ?? accumulatedUsage.inputTokens,
198
229
  outputTokens: finalUsage?.outputTokens ?? accumulatedUsage.outputTokens,
199
230
  totalTokens: finalUsage?.totalTokens ?? accumulatedUsage.totalTokens
200
- }
231
+ },
232
+ ...params.output ? { object } : {}
201
233
  };
202
234
  break;
203
235
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@~lyre/ai-agents",
3
- "version": "0.4.0",
3
+ "version": "0.5.1",
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,