@@ -28,7 +28,7 @@ import type {
28
28
PendingChat ,
29
29
UserChat ,
30
30
} from '@shared/models/IPlaygroundMessage' ;
31
- import type { LanguageModelV1 , LanguageModelV1CallWarning , LanguageModelV1StreamPart } from '@ai-sdk/provider' ;
31
+ import type { LanguageModelV2 , LanguageModelV2CallWarning , LanguageModelV2StreamPart } from '@ai-sdk/provider' ;
32
32
import { convertArrayToReadableStream } from '@ai-sdk/provider-utils/test' ;
33
33
import { ConversationRegistry } from '../../registries/ConversationRegistry' ;
34
34
import type { RpcExtension } from '@shared/messages/MessageProxy' ;
@@ -99,7 +99,7 @@ describe('aiSdk', () => {
99
99
type : 'tool-call' ,
100
100
toolCallId : 'call-001' ,
101
101
toolName : 'tool-1' ,
102
- args : { } ,
102
+ input : { } ,
103
103
} ,
104
104
] ,
105
105
} ,
@@ -110,7 +110,7 @@ describe('aiSdk', () => {
110
110
type : 'tool-result' ,
111
111
toolCallId : 'call-001' ,
112
112
toolName : 'tool-1' ,
113
- result : {
113
+ output : {
114
114
content : [ { type : 'text' , text : 'Success!!!' } ] ,
115
115
} ,
116
116
} ,
@@ -150,7 +150,7 @@ describe('aiSdk', () => {
150
150
expect . objectContaining ( {
151
151
model : expect . anything ( ) ,
152
152
temperature : 42 ,
153
- maxTokens : 37 ,
153
+ maxOutputTokens : 37 ,
154
154
topP : 13 ,
155
155
abortSignal : expect . any ( AbortSignal ) ,
156
156
messages : expect . any ( Array ) ,
@@ -178,10 +178,10 @@ describe('aiSdk', () => {
178
178
describe ( 'with stream error' , ( ) => {
179
179
beforeEach ( async ( ) => {
180
180
// eslint-disable-next-line sonarjs/no-nested-functions
181
- const doStream : LanguageModelV1 [ 'doStream' ] = async ( ) => {
181
+ const doStream : LanguageModelV2 [ 'doStream' ] = async ( ) => {
182
182
throw new Error ( 'The stream is kaput.' ) ;
183
183
} ;
184
- const model = new MockLanguageModelV1 ( { doStream } ) ;
184
+ const model = new MockLanguageModelV2 ( { doStream } ) ;
185
185
await new AiStreamProcessor ( conversationId , conversationRegistry ) . stream ( model ) . consumeStream ( ) ;
186
186
} ) ;
187
187
test ( 'appends a single message' , ( ) => {
@@ -194,7 +194,7 @@ describe('aiSdk', () => {
194
194
} ) ;
195
195
} ) ;
196
196
describe ( 'with single message stream' , ( ) => {
197
- let model : LanguageModelV1 ;
197
+ let model : LanguageModelV2 ;
198
198
beforeEach ( async ( ) => {
199
199
model = createTestModel ( {
200
200
stream : convertArrayToReadableStream ( [
@@ -204,10 +204,10 @@ describe('aiSdk', () => {
204
204
modelId : 'mock-model-id' ,
205
205
timestamp : new Date ( 0 ) ,
206
206
} ,
207
- { type : 'text-delta' , textDelta : 'Greetings' } ,
208
- { type : 'text-delta' , textDelta : ' professor ' } ,
209
- { type : 'text-delta' , textDelta : `Falken` } ,
210
- { type : 'finish' , finishReason : 'stop' , usage : { completionTokens : 133 , promptTokens : 7 } } ,
207
+ { type : 'text-delta' , id : 'id-1' , delta : 'Greetings' } ,
208
+ { type : 'text-delta' , id : 'id-2' , delta : ' professor ' } ,
209
+ { type : 'text-delta' , id : 'id-3' , delta : `Falken` } ,
210
+ { type : 'finish' , finishReason : 'stop' , usage : { outputTokens : 133 , inputTokens : 7 , totalTokens : 140 } } ,
211
211
] ) ,
212
212
} ) ;
213
213
await new AiStreamProcessor ( conversationId , conversationRegistry ) . stream ( model ) . consumeStream ( ) ;
@@ -230,53 +230,54 @@ describe('aiSdk', () => {
230
230
} ) ;
231
231
} ) ;
232
232
describe ( 'with wrapped generated multiple messages as stream' , ( ) => {
233
- let model : LanguageModelV1 ;
233
+ let model : LanguageModelV2 ;
234
234
let tools : ToolSet ;
235
235
let generateStep : number ;
236
236
237
237
beforeEach ( async ( ) => {
238
238
generateStep = 0 ;
239
239
model = wrapLanguageModel ( {
240
- model : new MockLanguageModelV1 ( {
241
- // This is the output that the simulateStreamingMiddleware expects for tool-calling
240
+ model : new MockLanguageModelV2 ( {
242
241
doGenerate : ( async ( ) => {
243
- // First call to the model returns a list of tool calls
244
242
if ( generateStep ++ === 0 ) {
245
243
return {
246
- rawCall : { rawPrompt : { } , rawSettings : { } } ,
247
- usage : { promptTokens : 1 , completionTokens : 1 } ,
248
- text : '' ,
249
- finishReason : 'tool-calls' ,
250
- toolCalls : [
244
+ content : [
251
245
{
252
- toolCallType : 'function ' ,
246
+ type : 'tool-call ' ,
253
247
toolCallId : 'call-001' ,
254
248
toolName : 'tool-1' ,
255
- args : '' ,
249
+ input : { } ,
256
250
} ,
257
251
{
258
- toolCallType : 'function ' ,
252
+ type : 'tool-call ' ,
259
253
toolCallId : 'call-002' ,
260
254
toolName : 'tool-1' ,
261
- args : '' ,
255
+ input : { } ,
262
256
} ,
263
257
] ,
258
+ finishReason : 'tool-calls' ,
259
+ usage : { inputTokens : 1 , outputTokens : 1 , totalTokens : 2 } ,
260
+ warnings : [ ] ,
264
261
} ;
265
262
}
266
- // Second call to the model returns the final human-readable result
267
263
return {
268
- rawCall : { rawPrompt : { } , rawSettings : { } } ,
264
+ content : [
265
+ {
266
+ type : 'text' ,
267
+ text : 'These are the results of you functions: huge success!' ,
268
+ } ,
269
+ ] ,
269
270
finishReason : 'stop' ,
270
- usage : { promptTokens : 133 , completionTokens : 7 } ,
271
- text : 'These are the results of you functions: huge success!' ,
271
+ usage : { inputTokens : 133 , outputTokens : 7 , totalTokens : 140 } ,
272
+ warnings : [ ] ,
272
273
} ;
273
- } ) as LanguageModelV1 [ 'doGenerate' ] ,
274
+ } ) as LanguageModelV2 [ 'doGenerate' ] ,
274
275
} ) ,
275
276
middleware : simulateStreamingMiddleware ( ) ,
276
277
} ) ;
277
278
tools = {
278
279
'tool-1' : tool ( {
279
- parameters : jsonSchema ( { type : 'object' } ) ,
280
+ inputSchema : jsonSchema ( { type : 'object' } ) ,
280
281
execute : async ( ) => 'successful result!' ,
281
282
} ) ,
282
283
} ;
@@ -303,19 +304,19 @@ describe('aiSdk', () => {
303
304
{ index : 2 , id : '4' , toolCallId : 'call-002' } ,
304
305
] ) ( `sets tool result message at $index for $toolCallId` , ( { index, id, toolCallId } ) => {
305
306
const message = conversationRegistry . get ( conversationId ) . messages [ index ] as AssistantChat ;
306
- expect ( message ) . toEqual ( {
307
- id,
308
- timestamp : expect . any ( Number ) ,
309
- completed : expect . any ( Number ) ,
310
- role : 'assistant' ,
311
- content : {
312
- type : 'tool-call' ,
313
- toolCallId,
314
- toolName : 'tool-1' ,
315
- args : { } ,
316
- result : 'successful result!' ,
317
- } ,
307
+ expect ( message . id ) . toEqual ( id ) ;
308
+ expect ( message . timestamp ) . toBeDefined ( ) ;
309
+ expect ( message . role ) . toEqual ( 'assistant' ) ;
310
+ expect ( message . content ) . toMatchObject ( {
311
+ type : 'tool-call' ,
312
+ toolCallId,
313
+ toolName : 'tool-1' ,
314
+ args : { } ,
318
315
} ) ;
316
+ if ( message . content && typeof message . content === 'object' && 'result' in message . content ) {
317
+ expect ( message . content . result ) . toEqual ( 'successful result!' ) ;
318
+ expect ( message . completed ) . toBeDefined ( ) ;
319
+ }
319
320
} ) ;
320
321
test ( 'appends final assistant message' , ( ) => {
321
322
const message = conversationRegistry . get ( conversationId ) . messages [ 3 ] as AssistantChat ;
@@ -324,30 +325,28 @@ describe('aiSdk', () => {
324
325
} ) ;
325
326
test ( 'setsUsage' , async ( ) => {
326
327
const conversation = conversationRegistry . get ( conversationId ) as Conversation ;
327
- expect ( conversation ?. usage ?. completion_tokens ) . toEqual ( 8 ) ;
328
- expect ( conversation ?. usage ?. prompt_tokens ) . toEqual ( 134 ) ;
328
+ expect ( conversation ?. usage ?. completion_tokens ) . toEqual ( 7 ) ;
329
+ expect ( conversation ?. usage ?. prompt_tokens ) . toEqual ( 133 ) ;
329
330
} ) ;
330
331
} ) ;
331
332
} ) ;
332
333
} ) ;
333
334
334
- export class MockLanguageModelV1 implements LanguageModelV1 {
335
- readonly specificationVersion = 'v1 ' ;
336
- readonly provider : LanguageModelV1 [ 'provider' ] ;
337
- readonly modelId : LanguageModelV1 [ 'modelId' ] ;
335
+ export class MockLanguageModelV2 implements LanguageModelV2 {
336
+ readonly specificationVersion = 'v2 ' ;
337
+ readonly provider : LanguageModelV2 [ 'provider' ] ;
338
+ readonly modelId : LanguageModelV2 [ 'modelId' ] ;
338
339
339
- supportsUrl : LanguageModelV1 [ 'supportsUrl' ] ;
340
- doGenerate : LanguageModelV1 [ 'doGenerate' ] ;
341
- doStream : LanguageModelV1 [ 'doStream' ] ;
340
+ supportedUrls : LanguageModelV2 [ 'supportedUrls' ] = { } ;
341
+ doGenerate : LanguageModelV2 [ 'doGenerate' ] ;
342
+ doStream : LanguageModelV2 [ 'doStream' ] ;
342
343
343
- readonly defaultObjectGenerationMode : LanguageModelV1 [ 'defaultObjectGenerationMode' ] ;
344
- readonly supportsStructuredOutputs : LanguageModelV1 [ 'supportsStructuredOutputs' ] ;
345
344
constructor ( {
346
345
doStream = notImplemented ,
347
346
doGenerate = notImplemented ,
348
347
} : {
349
- doStream ?: LanguageModelV1 [ 'doStream' ] ;
350
- doGenerate ?: LanguageModelV1 [ 'doGenerate' ] ;
348
+ doStream ?: LanguageModelV2 [ 'doStream' ] ;
349
+ doGenerate ?: LanguageModelV2 [ 'doGenerate' ] ;
351
350
} ) {
352
351
this . provider = 'mock-model-provider' ;
353
352
this . modelId = 'mock-model-id' ;
@@ -367,13 +366,13 @@ export function createTestModel({
367
366
request = undefined ,
368
367
warnings,
369
368
} : {
370
- stream ?: ReadableStream < LanguageModelV1StreamPart > ;
369
+ stream ?: ReadableStream < LanguageModelV2StreamPart > ;
371
370
rawResponse ?: { headers : Record < string , string > } ;
372
371
rawCall ?: { rawPrompt : string ; rawSettings : Record < string , unknown > } ;
373
372
request ?: { body : string } ;
374
- warnings ?: LanguageModelV1CallWarning [ ] ;
375
- } = { } ) : LanguageModelV1 {
376
- return new MockLanguageModelV1 ( {
373
+ warnings ?: LanguageModelV2CallWarning [ ] ;
374
+ } = { } ) : LanguageModelV2 {
375
+ return new MockLanguageModelV2 ( {
377
376
doStream : async ( ) => ( { stream, rawCall, rawResponse, request, warnings } ) ,
378
377
} ) ;
379
378
}
0 commit comments