ai-sdk-ollama 3.8.0 → 3.8.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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.8.1
4
+
5
+ ### Patch Changes
6
+
7
+ - aeafdd6: - Update `generateText` to detect and use the stable `output` option instead of the deprecated `experimental_output` when `enableToolsWithStructuredOutput` is enabled, including a two-phase tools + structured output path and an integration test to guard this behavior.
8
+
3
9
  ## 3.8.0
4
10
 
5
11
  ### Minor Changes
@@ -17066,6 +17066,17 @@ var ollama = createOllama();
17066
17066
 
17067
17067
  // src/functions/generate-text.ts
17068
17068
  var import_ai3 = require("ai");
17069
+ function resultWithOverrides(base, overrides) {
17070
+ const descriptors = {};
17071
+ for (const key of Object.keys(overrides)) {
17072
+ descriptors[key] = {
17073
+ value: overrides[key],
17074
+ enumerable: true,
17075
+ configurable: true
17076
+ };
17077
+ }
17078
+ return Object.create(base, descriptors);
17079
+ }
17069
17080
  async function generateText(options) {
17070
17081
  const { enhancedOptions = {}, ...generateTextOptions } = options;
17071
17082
  const {
@@ -17076,33 +17087,42 @@ async function generateText(options) {
17076
17087
  enableToolsWithStructuredOutput = false
17077
17088
  } = enhancedOptions;
17078
17089
  const hasTools = generateTextOptions.tools && Object.keys(generateTextOptions.tools).length > 0;
17079
- const hasExperimentalOutput = "experimental_output" in generateTextOptions;
17090
+ const hasOutput = "output" in generateTextOptions;
17080
17091
  const requiresTools = generateTextOptions.toolChoice === "required" || typeof generateTextOptions.toolChoice === "object" && "type" in generateTextOptions.toolChoice && generateTextOptions.toolChoice.type === "tool";
17081
- if (enableToolsWithStructuredOutput && hasExperimentalOutput && requiresTools && hasTools) {
17082
- const toolResult = await (0, import_ai3.generateText)({
17083
- ...generateTextOptions,
17084
- experimental_output: void 0
17085
- });
17092
+ if (enableToolsWithStructuredOutput && hasOutput && requiresTools && hasTools) {
17093
+ const phase1Options = Object.fromEntries(
17094
+ Object.entries(generateTextOptions).filter(([key]) => key !== "output")
17095
+ );
17096
+ const toolResult = await (0, import_ai3.generateText)(
17097
+ phase1Options
17098
+ );
17086
17099
  if (toolResult.toolCalls && toolResult.toolCalls.length > 0) {
17087
17100
  const toolContext = toolResult.toolResults?.map(
17088
- (tr, i) => `${toolResult.toolCalls?.[i]?.toolName}: ${JSON.stringify(tr.output || tr)}`
17101
+ (tr, i) => `${toolResult.toolCalls?.[i]?.toolName}: ${JSON.stringify(tr.output ?? tr)}`
17089
17102
  ).join("\n");
17090
- const contextualPrompt = typeof generateTextOptions.prompt === "string" ? `${generateTextOptions.prompt}
17103
+ const toolResultsSuffix = `
17091
17104
 
17092
17105
  Tool Results:
17093
17106
  ${toolContext}
17094
17107
 
17095
- Please provide a structured response based on these tool results.` : generateTextOptions.prompt;
17096
- const _generateTextOptions = {
17097
- ...generateTextOptions,
17098
- prompt: contextualPrompt,
17099
- tools: void 0,
17100
- toolChoice: void 0
17101
- };
17108
+ Please provide a structured response based on these tool results.`;
17109
+ const phase2Base = Object.fromEntries(
17110
+ Object.entries(generateTextOptions).filter(
17111
+ ([key]) => key !== "tools" && key !== "toolChoice"
17112
+ )
17113
+ );
17114
+ const phase2OptionsWithPrompt = typeof phase2Base.prompt === "string" ? { ...phase2Base, prompt: phase2Base.prompt + toolResultsSuffix } : phase2Base.messages ? {
17115
+ ...phase2Base,
17116
+ prompt: void 0,
17117
+ messages: [
17118
+ ...phase2Base.messages,
17119
+ { role: "user", content: toolResultsSuffix.trim() }
17120
+ ]
17121
+ } : phase2Base;
17102
17122
  const structuredResult = await (0, import_ai3.generateText)(
17103
- _generateTextOptions
17123
+ phase2OptionsWithPrompt
17104
17124
  );
17105
- const enhancedResult = Object.assign(structuredResult, {
17125
+ const enhancedResult = resultWithOverrides(structuredResult, {
17106
17126
  toolCalls: toolResult.toolCalls,
17107
17127
  toolResults: toolResult.toolResults,
17108
17128
  staticToolCalls: toolResult.staticToolCalls,
@@ -17110,9 +17130,9 @@ Please provide a structured response based on these tool results.` : generateTex
17110
17130
  staticToolResults: toolResult.staticToolResults,
17111
17131
  dynamicToolResults: toolResult.dynamicToolResults,
17112
17132
  usage: {
17113
- inputTokens: (toolResult.usage.inputTokens || 0) + (structuredResult.usage.inputTokens || 0),
17114
- outputTokens: (toolResult.usage.outputTokens || 0) + (structuredResult.usage.outputTokens || 0),
17115
- totalTokens: (toolResult.usage.totalTokens || 0) + (structuredResult.usage.totalTokens || 0)
17133
+ inputTokens: (toolResult.usage.inputTokens ?? 0) + (structuredResult.usage.inputTokens ?? 0),
17134
+ outputTokens: (toolResult.usage.outputTokens ?? 0) + (structuredResult.usage.outputTokens ?? 0),
17135
+ totalTokens: (toolResult.usage.totalTokens ?? 0) + (structuredResult.usage.totalTokens ?? 0)
17116
17136
  }
17117
17137
  });
17118
17138
  return enhancedResult;
@@ -17123,7 +17143,9 @@ Please provide a structured response based on these tool results.` : generateTex
17123
17143
  // Only set stopWhen default if user didn't provide one and tools are enabled
17124
17144
  stopWhen: generateTextOptions.stopWhen ?? (hasTools ? (0, import_ai3.stepCountIs)(5) : void 0)
17125
17145
  });
17126
- const toolsWereCalled = result.steps?.some((step) => step.toolCalls && step.toolCalls.length > 0) ?? false;
17146
+ const toolsWereCalled = result.steps?.some(
17147
+ (step) => step.toolCalls && step.toolCalls.length > 0
17148
+ ) ?? false;
17127
17149
  const hasMinimalText = !result.text || result.text.trim().length < minResponseLength;
17128
17150
  if (!hasTools || !toolsWereCalled || !hasMinimalText || !enableSynthesis) {
17129
17151
  return result;
@@ -17155,11 +17177,16 @@ Tool results:
17155
17177
  ${toolContext}
17156
17178
 
17157
17179
  ${synthesisPrompt}`;
17158
- const { tools, prompt, messages, ...baseOptions } = generateTextOptions;
17159
- const synthesisOptions = messages ? {
17180
+ const generateOptions = generateTextOptions;
17181
+ const baseOptions = Object.fromEntries(
17182
+ Object.entries(generateOptions).filter(
17183
+ ([key]) => key !== "tools" && key !== "prompt" && key !== "messages"
17184
+ )
17185
+ );
17186
+ const synthesisOptions = generateOptions.messages ? {
17160
17187
  ...baseOptions,
17161
17188
  messages: [
17162
- ...messages || [],
17189
+ ...generateOptions.messages || [],
17163
17190
  { role: "user", content: fullSynthesisPrompt }
17164
17191
  ]
17165
17192
  } : {
@@ -17170,12 +17197,12 @@ ${synthesisPrompt}`;
17170
17197
  synthesisOptions
17171
17198
  );
17172
17199
  if (synthesisResult.text && synthesisResult.text.trim().length >= minResponseLength) {
17173
- const enhancedResult = Object.assign(result, {
17200
+ const enhancedResult = resultWithOverrides(result, {
17174
17201
  text: synthesisResult.text,
17175
17202
  usage: {
17176
- inputTokens: (result.usage.inputTokens || 0) + (synthesisResult.usage.inputTokens || 0),
17177
- outputTokens: (result.usage.outputTokens || 0) + (synthesisResult.usage.outputTokens || 0),
17178
- totalTokens: (result.usage.totalTokens || 0) + (synthesisResult.usage.totalTokens || 0)
17203
+ inputTokens: (result.usage.inputTokens ?? 0) + (synthesisResult.usage.inputTokens ?? 0),
17204
+ outputTokens: (result.usage.outputTokens ?? 0) + (synthesisResult.usage.outputTokens ?? 0),
17205
+ totalTokens: (result.usage.totalTokens ?? 0) + (synthesisResult.usage.totalTokens ?? 0)
17179
17206
  }
17180
17207
  });
17181
17208
  return enhancedResult;