@output.ai/llm 0.2.11 → 0.2.13-dev.pr306-3f50755
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/package.json +1 -1
- package/src/ai_sdk.js +3 -0
- package/src/ai_sdk.spec.js +2 -0
- package/src/generate_text_types.spec.ts +163 -0
- package/src/index.d.ts +26 -6
package/package.json
CHANGED
package/src/ai_sdk.js
CHANGED
|
@@ -51,6 +51,9 @@ const aiSdkOptionsFromPrompt = prompt => {
|
|
|
51
51
|
|
|
52
52
|
if ( prompt.config.maxTokens ) {
|
|
53
53
|
options.maxOutputTokens = prompt.config.maxTokens;
|
|
54
|
+
} else if ( prompt.config.provider === 'anthropic' ) {
|
|
55
|
+
// Override Anthropic SDK's low 4096 default - Claude models support up to 64k output tokens
|
|
56
|
+
options.maxOutputTokens = 64000;
|
|
54
57
|
}
|
|
55
58
|
|
|
56
59
|
const tools = loadTools( prompt );
|
package/src/ai_sdk.spec.js
CHANGED
|
@@ -221,6 +221,7 @@ describe( 'ai_sdk', () => {
|
|
|
221
221
|
expect( aiFns.generateText ).toHaveBeenCalledWith( {
|
|
222
222
|
model: 'MODEL',
|
|
223
223
|
messages: promptWithProviderOptions.messages,
|
|
224
|
+
maxOutputTokens: 64000,
|
|
224
225
|
providerOptions: {
|
|
225
226
|
thinking: {
|
|
226
227
|
type: 'enabled',
|
|
@@ -339,6 +340,7 @@ describe( 'ai_sdk', () => {
|
|
|
339
340
|
enum: [ 'A', 'B', 'C' ],
|
|
340
341
|
model: 'MODEL',
|
|
341
342
|
messages: promptWithMixedOptions.messages,
|
|
343
|
+
maxOutputTokens: 64000,
|
|
342
344
|
providerOptions: {
|
|
343
345
|
thinking: {
|
|
344
346
|
type: 'enabled',
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type-level tests for generateText multi-step options.
|
|
3
|
+
* These tests verify that TypeScript accepts the new options without casting to `any`.
|
|
4
|
+
*/
|
|
5
|
+
import { describe, it, expect, vi, expectTypeOf } from 'vitest';
|
|
6
|
+
import type { ToolSet } from 'ai';
|
|
7
|
+
import type { generateText, GenerateTextResult } from './index.d.ts';
|
|
8
|
+
|
|
9
|
+
// Mock generateText for type-checking tests
|
|
10
|
+
const mockGenerateText = vi.fn() as unknown as typeof generateText;
|
|
11
|
+
|
|
12
|
+
describe( 'generateText type definitions', () => {
|
|
13
|
+
describe( 'maxSteps option', () => {
|
|
14
|
+
it( 'should accept maxSteps as a valid option', () => {
|
|
15
|
+
// This function definition verifies TypeScript accepts maxSteps
|
|
16
|
+
const callWithMaxSteps = () =>
|
|
17
|
+
mockGenerateText( {
|
|
18
|
+
prompt: 'test-prompt',
|
|
19
|
+
maxSteps: 5
|
|
20
|
+
} );
|
|
21
|
+
|
|
22
|
+
expect( callWithMaxSteps ).toBeDefined();
|
|
23
|
+
} );
|
|
24
|
+
|
|
25
|
+
it( 'should accept maxSteps with tools', () => {
|
|
26
|
+
const callWithToolsAndMaxSteps = () =>
|
|
27
|
+
mockGenerateText( {
|
|
28
|
+
prompt: 'test-prompt',
|
|
29
|
+
tools: {} as ToolSet,
|
|
30
|
+
maxSteps: 5
|
|
31
|
+
} );
|
|
32
|
+
|
|
33
|
+
expect( callWithToolsAndMaxSteps ).toBeDefined();
|
|
34
|
+
} );
|
|
35
|
+
|
|
36
|
+
it( 'should accept maxSteps with variables and tools (user pattern)', () => {
|
|
37
|
+
// This test mimics the exact user pattern that was failing
|
|
38
|
+
const providerConfig = {
|
|
39
|
+
promptName: 'test-prompt',
|
|
40
|
+
tools: {} as ToolSet
|
|
41
|
+
};
|
|
42
|
+
const query = 'test query';
|
|
43
|
+
const input = {
|
|
44
|
+
successCriteria: 'Answer with relevant information',
|
|
45
|
+
sourceRequirements: '',
|
|
46
|
+
searchDepth: 'basic',
|
|
47
|
+
importance: 'low'
|
|
48
|
+
};
|
|
49
|
+
const previousFindings = '';
|
|
50
|
+
const iteration = 1;
|
|
51
|
+
|
|
52
|
+
const callWithUserPattern = () =>
|
|
53
|
+
mockGenerateText( {
|
|
54
|
+
prompt: providerConfig.promptName,
|
|
55
|
+
variables: {
|
|
56
|
+
query,
|
|
57
|
+
successCriteria: input.successCriteria || 'Answer with relevant information',
|
|
58
|
+
sourceRequirements: input.sourceRequirements || '',
|
|
59
|
+
searchDepth: input.searchDepth || 'basic',
|
|
60
|
+
priority: input.importance || 'low',
|
|
61
|
+
previousFindings: previousFindings || '',
|
|
62
|
+
iteration: String( iteration ),
|
|
63
|
+
currentDate: new Date().toISOString().split( 'T' )[0]
|
|
64
|
+
},
|
|
65
|
+
tools: providerConfig.tools,
|
|
66
|
+
maxSteps: 5 // Allow up to 5 tool execution rounds
|
|
67
|
+
} );
|
|
68
|
+
|
|
69
|
+
expect( callWithUserPattern ).toBeDefined();
|
|
70
|
+
} );
|
|
71
|
+
} );
|
|
72
|
+
|
|
73
|
+
describe( 'stopWhen option', () => {
|
|
74
|
+
it( 'should accept stopWhen callback', () => {
|
|
75
|
+
const callWithStopWhen = () =>
|
|
76
|
+
mockGenerateText( {
|
|
77
|
+
prompt: 'test-prompt',
|
|
78
|
+
tools: {} as ToolSet,
|
|
79
|
+
maxSteps: 10,
|
|
80
|
+
stopWhen: ( { steps } ) => steps.length >= 3
|
|
81
|
+
} );
|
|
82
|
+
|
|
83
|
+
expect( callWithStopWhen ).toBeDefined();
|
|
84
|
+
} );
|
|
85
|
+
} );
|
|
86
|
+
|
|
87
|
+
describe( 'onStepFinish callback', () => {
|
|
88
|
+
it( 'should accept onStepFinish callback', () => {
|
|
89
|
+
const callWithOnStepFinish = () =>
|
|
90
|
+
mockGenerateText( {
|
|
91
|
+
prompt: 'test-prompt',
|
|
92
|
+
tools: {} as ToolSet,
|
|
93
|
+
maxSteps: 5,
|
|
94
|
+
onStepFinish: async step => {
|
|
95
|
+
// step.text should be accessible
|
|
96
|
+
console.log( step.text );
|
|
97
|
+
}
|
|
98
|
+
} );
|
|
99
|
+
|
|
100
|
+
expect( callWithOnStepFinish ).toBeDefined();
|
|
101
|
+
} );
|
|
102
|
+
} );
|
|
103
|
+
|
|
104
|
+
describe( 'prepareStep callback', () => {
|
|
105
|
+
it( 'should accept prepareStep callback with correct parameters', () => {
|
|
106
|
+
const callWithPrepareStep = () =>
|
|
107
|
+
mockGenerateText( {
|
|
108
|
+
prompt: 'test-prompt',
|
|
109
|
+
tools: {} as ToolSet,
|
|
110
|
+
maxSteps: 5,
|
|
111
|
+
prepareStep: ( { steps, stepNumber } ) => {
|
|
112
|
+
// steps and stepNumber should be accessible
|
|
113
|
+
if ( stepNumber > 3 || steps.length > 2 ) {
|
|
114
|
+
return { toolChoice: 'none' as const };
|
|
115
|
+
}
|
|
116
|
+
return {};
|
|
117
|
+
}
|
|
118
|
+
} );
|
|
119
|
+
|
|
120
|
+
expect( callWithPrepareStep ).toBeDefined();
|
|
121
|
+
} );
|
|
122
|
+
} );
|
|
123
|
+
|
|
124
|
+
describe( 'GenerateTextResult type', () => {
|
|
125
|
+
it( 'should be generic over TOOLS', () => {
|
|
126
|
+
// Verify GenerateTextResult accepts a TOOLS type parameter
|
|
127
|
+
type Result = GenerateTextResult<ToolSet>;
|
|
128
|
+
|
|
129
|
+
// Result should have steps, text, and result properties
|
|
130
|
+
expectTypeOf<Result>().toHaveProperty( 'steps' );
|
|
131
|
+
expectTypeOf<Result>().toHaveProperty( 'text' );
|
|
132
|
+
expectTypeOf<Result>().toHaveProperty( 'result' );
|
|
133
|
+
} );
|
|
134
|
+
|
|
135
|
+
it( 'should have result as string alias for text', () => {
|
|
136
|
+
type Result = GenerateTextResult;
|
|
137
|
+
expectTypeOf<Result['result']>().toBeString();
|
|
138
|
+
expectTypeOf<Result['text']>().toBeString();
|
|
139
|
+
} );
|
|
140
|
+
} );
|
|
141
|
+
|
|
142
|
+
describe( 'combined multi-step options', () => {
|
|
143
|
+
it( 'should accept all multi-step options together', () => {
|
|
144
|
+
const callWithAllOptions = () =>
|
|
145
|
+
mockGenerateText( {
|
|
146
|
+
prompt: 'test-prompt',
|
|
147
|
+
variables: { topic: 'testing' },
|
|
148
|
+
tools: {} as ToolSet,
|
|
149
|
+
toolChoice: 'auto',
|
|
150
|
+
maxSteps: 5,
|
|
151
|
+
stopWhen: ( { steps } ) => steps.length >= 3,
|
|
152
|
+
onStepFinish: async step => {
|
|
153
|
+
console.log( 'Step:', step.text );
|
|
154
|
+
},
|
|
155
|
+
prepareStep: ( { stepNumber } ) => {
|
|
156
|
+
return stepNumber > 3 ? { toolChoice: 'required' as const } : {};
|
|
157
|
+
}
|
|
158
|
+
} );
|
|
159
|
+
|
|
160
|
+
expect( callWithAllOptions ).toBeDefined();
|
|
161
|
+
} );
|
|
162
|
+
} );
|
|
163
|
+
} );
|
package/src/index.d.ts
CHANGED
|
@@ -4,7 +4,10 @@ import type {
|
|
|
4
4
|
GenerateObjectResult as AIGenerateObjectResult,
|
|
5
5
|
CallSettings,
|
|
6
6
|
ToolSet,
|
|
7
|
-
ToolChoice
|
|
7
|
+
ToolChoice,
|
|
8
|
+
StopCondition,
|
|
9
|
+
GenerateTextOnStepFinishCallback,
|
|
10
|
+
PrepareStepFunction
|
|
8
11
|
} from 'ai';
|
|
9
12
|
|
|
10
13
|
/**
|
|
@@ -100,12 +103,20 @@ export type {
|
|
|
100
103
|
CallSettings,
|
|
101
104
|
ToolSet,
|
|
102
105
|
ToolChoice,
|
|
103
|
-
Tool
|
|
106
|
+
Tool,
|
|
107
|
+
StopCondition,
|
|
108
|
+
StepResult,
|
|
109
|
+
GenerateTextOnStepFinishCallback,
|
|
110
|
+
PrepareStepFunction,
|
|
111
|
+
PrepareStepResult
|
|
104
112
|
} from 'ai';
|
|
105
113
|
|
|
106
114
|
// Re-export the tool helper function for creating tools
|
|
107
115
|
export { tool } from 'ai';
|
|
108
116
|
|
|
117
|
+
// Re-export stop condition helpers for multi-step workflows
|
|
118
|
+
export { stepCountIs, hasToolCall } from 'ai';
|
|
119
|
+
|
|
109
120
|
/**
|
|
110
121
|
* Common AI SDK options that can be passed through to all generate functions.
|
|
111
122
|
* These options are passed directly to the underlying AI SDK call.
|
|
@@ -113,7 +124,7 @@ export { tool } from 'ai';
|
|
|
113
124
|
type AiSdkOptions = Partial<Omit<CallSettings, 'maxOutputTokens'>>;
|
|
114
125
|
|
|
115
126
|
/**
|
|
116
|
-
* AI SDK options specific to generateText, including tool calling support.
|
|
127
|
+
* AI SDK options specific to generateText, including tool calling and multi-step support.
|
|
117
128
|
* @typeParam TOOLS - The tools available for the model to call
|
|
118
129
|
*/
|
|
119
130
|
type GenerateTextAiSdkOptions<TOOLS extends ToolSet = ToolSet> = AiSdkOptions & {
|
|
@@ -123,14 +134,23 @@ type GenerateTextAiSdkOptions<TOOLS extends ToolSet = ToolSet> = AiSdkOptions &
|
|
|
123
134
|
toolChoice?: ToolChoice<TOOLS>;
|
|
124
135
|
/** Limit which tools are active without changing types */
|
|
125
136
|
activeTools?: Array<keyof TOOLS>;
|
|
137
|
+
/** Maximum number of automatic tool execution rounds (multi-step) */
|
|
138
|
+
maxSteps?: number;
|
|
139
|
+
/** Custom stop conditions for multi-step execution */
|
|
140
|
+
stopWhen?: StopCondition<TOOLS> | StopCondition<TOOLS>[];
|
|
141
|
+
/** Callback after each step completes */
|
|
142
|
+
onStepFinish?: GenerateTextOnStepFinishCallback<TOOLS>;
|
|
143
|
+
/** Customize each step before execution */
|
|
144
|
+
prepareStep?: PrepareStepFunction<TOOLS>;
|
|
126
145
|
};
|
|
127
146
|
|
|
128
147
|
/**
|
|
129
148
|
* Result from generateText including full AI SDK response metadata.
|
|
130
149
|
* Extends AI SDK's GenerateTextResult with a unified `result` field.
|
|
150
|
+
* @typeParam TOOLS - The tools available for the model to call (preserves typing on steps)
|
|
131
151
|
*/
|
|
132
|
-
export type GenerateTextResult =
|
|
133
|
-
AIGenerateTextResult<
|
|
152
|
+
export type GenerateTextResult<TOOLS extends ToolSet = ToolSet> =
|
|
153
|
+
AIGenerateTextResult<TOOLS, unknown> & {
|
|
134
154
|
/** Unified field name alias for 'text' - provides consistency across all generate* functions */
|
|
135
155
|
result: string;
|
|
136
156
|
};
|
|
@@ -177,7 +197,7 @@ export function generateText<TOOLS extends ToolSet = ToolSet>(
|
|
|
177
197
|
prompt: string,
|
|
178
198
|
variables?: Record<string, string | number | boolean>
|
|
179
199
|
} & GenerateTextAiSdkOptions<TOOLS>
|
|
180
|
-
): Promise<GenerateTextResult
|
|
200
|
+
): Promise<GenerateTextResult<TOOLS>>;
|
|
181
201
|
|
|
182
202
|
/**
|
|
183
203
|
* Use an LLM model to generate an object with a fixed schema.
|