11import { describe , expect , test } from "bun:test"
22import { MessageV2 } from "../../src/session/message-v2"
3+ import type { Provider } from "../../src/provider/provider"
34
45const sessionID = "session"
6+ const model : Provider . Model = {
7+ id : "test-model" ,
8+ providerID : "test" ,
9+ api : {
10+ id : "test-model" ,
11+ url : "https://example.com" ,
12+ npm : "@ai-sdk/openai" ,
13+ } ,
14+ name : "Test Model" ,
15+ capabilities : {
16+ temperature : true ,
17+ reasoning : false ,
18+ attachment : false ,
19+ toolcall : true ,
20+ input : {
21+ text : true ,
22+ audio : false ,
23+ image : false ,
24+ video : false ,
25+ pdf : false ,
26+ } ,
27+ output : {
28+ text : true ,
29+ audio : false ,
30+ image : false ,
31+ video : false ,
32+ pdf : false ,
33+ } ,
34+ interleaved : false ,
35+ } ,
36+ cost : {
37+ input : 0 ,
38+ output : 0 ,
39+ cache : {
40+ read : 0 ,
41+ write : 0 ,
42+ } ,
43+ } ,
44+ limit : {
45+ context : 0 ,
46+ input : 0 ,
47+ output : 0 ,
48+ } ,
49+ status : "active" ,
50+ options : { } ,
51+ headers : { } ,
52+ release_date : "2026-01-01" ,
53+ }
554
655function userInfo ( id : string ) : MessageV2 . User {
756 return {
@@ -16,16 +65,22 @@ function userInfo(id: string): MessageV2.User {
1665 } as unknown as MessageV2 . User
1766}
1867
19- function assistantInfo ( id : string , parentID : string , error ?: MessageV2 . Assistant [ "error" ] ) : MessageV2 . Assistant {
68+ function assistantInfo (
69+ id : string ,
70+ parentID : string ,
71+ error ?: MessageV2 . Assistant [ "error" ] ,
72+ meta ?: { providerID : string ; modelID : string } ,
73+ ) : MessageV2 . Assistant {
74+ const infoModel = meta ?? { providerID : model . providerID , modelID : model . api . id }
2075 return {
2176 id,
2277 sessionID,
2378 role : "assistant" ,
2479 time : { created : 0 } ,
2580 error,
2681 parentID,
27- modelID : "model" ,
28- providerID : "provider" ,
82+ modelID : infoModel . modelID ,
83+ providerID : infoModel . providerID ,
2984 mode : "" ,
3085 agent : "agent" ,
3186 path : { cwd : "/" , root : "/" } ,
@@ -66,7 +121,7 @@ describe("session.message-v2.toModelMessage", () => {
66121 } ,
67122 ]
68123
69- expect ( MessageV2 . toModelMessages ( input ) ) . toStrictEqual ( [
124+ expect ( MessageV2 . toModelMessages ( input , model ) ) . toStrictEqual ( [
70125 {
71126 role : "user" ,
72127 content : [ { type : "text" , text : "hello" } ] ,
@@ -91,7 +146,7 @@ describe("session.message-v2.toModelMessage", () => {
91146 } ,
92147 ]
93148
94- expect ( MessageV2 . toModelMessages ( input ) ) . toStrictEqual ( [ ] )
149+ expect ( MessageV2 . toModelMessages ( input , model ) ) . toStrictEqual ( [ ] )
95150 } )
96151
97152 test ( "includes synthetic text parts" , ( ) => {
@@ -122,7 +177,7 @@ describe("session.message-v2.toModelMessage", () => {
122177 } ,
123178 ]
124179
125- expect ( MessageV2 . toModelMessages ( input ) ) . toStrictEqual ( [
180+ expect ( MessageV2 . toModelMessages ( input , model ) ) . toStrictEqual ( [
126181 {
127182 role : "user" ,
128183 content : [ { type : "text" , text : "hello" } ] ,
@@ -189,7 +244,7 @@ describe("session.message-v2.toModelMessage", () => {
189244 } ,
190245 ]
191246
192- expect ( MessageV2 . toModelMessages ( input ) ) . toStrictEqual ( [
247+ expect ( MessageV2 . toModelMessages ( input , model ) ) . toStrictEqual ( [
193248 {
194249 role : "user" ,
195250 content : [
@@ -259,7 +314,7 @@ describe("session.message-v2.toModelMessage", () => {
259314 } ,
260315 ]
261316
262- expect ( MessageV2 . toModelMessages ( input ) ) . toStrictEqual ( [
317+ expect ( MessageV2 . toModelMessages ( input , model ) ) . toStrictEqual ( [
263318 {
264319 role : "user" ,
265320 content : [ { type : "text" , text : "run tool" } ] ,
@@ -305,6 +360,81 @@ describe("session.message-v2.toModelMessage", () => {
305360 ] )
306361 } )
307362
363+ test ( "omits provider metadata when assistant model differs" , ( ) => {
364+ const userID = "m-user"
365+ const assistantID = "m-assistant"
366+
367+ const input : MessageV2 . WithParts [ ] = [
368+ {
369+ info : userInfo ( userID ) ,
370+ parts : [
371+ {
372+ ...basePart ( userID , "u1" ) ,
373+ type : "text" ,
374+ text : "run tool" ,
375+ } ,
376+ ] as MessageV2 . Part [ ] ,
377+ } ,
378+ {
379+ info : assistantInfo ( assistantID , userID , undefined , { providerID : "other" , modelID : "other" } ) ,
380+ parts : [
381+ {
382+ ...basePart ( assistantID , "a1" ) ,
383+ type : "text" ,
384+ text : "done" ,
385+ metadata : { openai : { assistant : "meta" } } ,
386+ } ,
387+ {
388+ ...basePart ( assistantID , "a2" ) ,
389+ type : "tool" ,
390+ callID : "call-1" ,
391+ tool : "bash" ,
392+ state : {
393+ status : "completed" ,
394+ input : { cmd : "ls" } ,
395+ output : "ok" ,
396+ title : "Bash" ,
397+ metadata : { } ,
398+ time : { start : 0 , end : 1 } ,
399+ } ,
400+ metadata : { openai : { tool : "meta" } } ,
401+ } ,
402+ ] as MessageV2 . Part [ ] ,
403+ } ,
404+ ]
405+
406+ expect ( MessageV2 . toModelMessages ( input , model ) ) . toStrictEqual ( [
407+ {
408+ role : "user" ,
409+ content : [ { type : "text" , text : "run tool" } ] ,
410+ } ,
411+ {
412+ role : "assistant" ,
413+ content : [
414+ { type : "text" , text : "done" } ,
415+ {
416+ type : "tool-call" ,
417+ toolCallId : "call-1" ,
418+ toolName : "bash" ,
419+ input : { cmd : "ls" } ,
420+ providerExecuted : undefined ,
421+ } ,
422+ ] ,
423+ } ,
424+ {
425+ role : "tool" ,
426+ content : [
427+ {
428+ type : "tool-result" ,
429+ toolCallId : "call-1" ,
430+ toolName : "bash" ,
431+ output : { type : "text" , value : "ok" } ,
432+ } ,
433+ ] ,
434+ } ,
435+ ] )
436+ } )
437+
308438 test ( "replaces compacted tool output with placeholder" , ( ) => {
309439 const userID = "m-user"
310440 const assistantID = "m-assistant"
@@ -341,7 +471,7 @@ describe("session.message-v2.toModelMessage", () => {
341471 } ,
342472 ]
343473
344- expect ( MessageV2 . toModelMessages ( input ) ) . toStrictEqual ( [
474+ expect ( MessageV2 . toModelMessages ( input , model ) ) . toStrictEqual ( [
345475 {
346476 role : "user" ,
347477 content : [ { type : "text" , text : "run tool" } ] ,
@@ -408,7 +538,7 @@ describe("session.message-v2.toModelMessage", () => {
408538 } ,
409539 ]
410540
411- expect ( MessageV2 . toModelMessages ( input ) ) . toStrictEqual ( [
541+ expect ( MessageV2 . toModelMessages ( input , model ) ) . toStrictEqual ( [
412542 {
413543 role : "user" ,
414544 content : [ { type : "text" , text : "run tool" } ] ,
@@ -461,7 +591,7 @@ describe("session.message-v2.toModelMessage", () => {
461591 } ,
462592 ]
463593
464- expect ( MessageV2 . toModelMessages ( input ) ) . toStrictEqual ( [ ] )
594+ expect ( MessageV2 . toModelMessages ( input , model ) ) . toStrictEqual ( [ ] )
465595 } )
466596
467597 test ( "includes aborted assistant messages only when they have non-step-start/reasoning content" , ( ) => {
@@ -504,7 +634,7 @@ describe("session.message-v2.toModelMessage", () => {
504634 } ,
505635 ]
506636
507- expect ( MessageV2 . toModelMessages ( input ) ) . toStrictEqual ( [
637+ expect ( MessageV2 . toModelMessages ( input , model ) ) . toStrictEqual ( [
508638 {
509639 role : "assistant" ,
510640 content : [
@@ -540,7 +670,7 @@ describe("session.message-v2.toModelMessage", () => {
540670 } ,
541671 ]
542672
543- expect ( MessageV2 . toModelMessages ( input ) ) . toStrictEqual ( [
673+ expect ( MessageV2 . toModelMessages ( input , model ) ) . toStrictEqual ( [
544674 {
545675 role : "assistant" ,
546676 content : [ { type : "text" , text : "first" } ] ,
@@ -567,7 +697,7 @@ describe("session.message-v2.toModelMessage", () => {
567697 } ,
568698 ]
569699
570- expect ( MessageV2 . toModelMessages ( input ) ) . toStrictEqual ( [ ] )
700+ expect ( MessageV2 . toModelMessages ( input , model ) ) . toStrictEqual ( [ ] )
571701 } )
572702
573703 test ( "converts pending/running tool calls to error results to prevent dangling tool_use" , ( ) => {
@@ -614,7 +744,7 @@ describe("session.message-v2.toModelMessage", () => {
614744 } ,
615745 ]
616746
617- const result = MessageV2 . toModelMessages ( input )
747+ const result = MessageV2 . toModelMessages ( input , model )
618748
619749 expect ( result ) . toStrictEqual ( [
620750 {
0 commit comments