@~lyre/ai-agents 0.5.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
@@ -111,6 +111,21 @@ function buildTools(registry, agent, context) {
111
111
  }
112
112
  return out;
113
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
+ }
114
129
  async function run(registry, params, defaults) {
115
130
  const agent = registry.resolveAgent(params.agent);
116
131
  const messages = buildMessages(agent, params);
@@ -119,6 +134,7 @@ async function run(registry, params, defaults) {
119
134
  model: resolveModel(agent, defaults),
120
135
  messages,
121
136
  tools,
137
+ ...buildRunOptions(params),
122
138
  temperature: params.temperature ?? agent.temperature,
123
139
  maxOutputTokens: params.maxOutputTokens ?? agent.maxOutputTokens,
124
140
  stopWhen: ({ steps }) => steps.length >= (params.maxSteps ?? 8),
@@ -142,6 +158,7 @@ async function run(registry, params, defaults) {
142
158
  toolName: r.toolName,
143
159
  output: r.output
144
160
  })),
161
+ ...params.output ? { object: result.experimental_output } : {},
145
162
  raw: result
146
163
  };
147
164
  }
@@ -153,6 +170,7 @@ async function* runStream(registry, params, defaults) {
153
170
  model: resolveModel(agent, defaults),
154
171
  messages,
155
172
  tools,
173
+ ...buildRunOptions(params),
156
174
  temperature: params.temperature ?? agent.temperature,
157
175
  maxOutputTokens: params.maxOutputTokens ?? agent.maxOutputTokens,
158
176
  stopWhen: ({ steps }) => steps.length >= (params.maxSteps ?? 8),
@@ -199,6 +217,10 @@ async function* runStream(registry, params, defaults) {
199
217
  break;
200
218
  case "finish": {
201
219
  const finalUsage = part.totalUsage ?? part.usage;
220
+ let object;
221
+ if (params.output) {
222
+ object = await result.experimental_output;
223
+ }
202
224
  yield {
203
225
  type: "finish",
204
226
  finishReason: part.finishReason,
@@ -206,7 +228,8 @@ async function* runStream(registry, params, defaults) {
206
228
  inputTokens: finalUsage?.inputTokens ?? accumulatedUsage.inputTokens,
207
229
  outputTokens: finalUsage?.outputTokens ?? accumulatedUsage.outputTokens,
208
230
  totalTokens: finalUsage?.totalTokens ?? accumulatedUsage.totalTokens
209
- }
231
+ },
232
+ ...params.output ? { object } : {}
210
233
  };
211
234
  break;
212
235
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@~lyre/ai-agents",
3
- "version": "0.5.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,