@@ -2,104 +2,14 @@ import { describe, it, expect } from 'vitest'
22import { stripToSpec } from '../src/strip-to-spec-middleware'
33import type { StreamChunk } from '../src/types'
44
5- /**
6- * Helper to create a StreamChunk with the given type and fields.
7- */
8- function makeChunk ( type : string , fields : Record < string , unknown > ) : StreamChunk {
5+ function makeChunk (
6+ type : string ,
7+ fields : Record < string , unknown > ,
8+ ) : StreamChunk {
99 return { type, timestamp : Date . now ( ) , ...fields } as unknown as StreamChunk
1010}
1111
1212describe ( 'stripToSpec' , ( ) => {
13- // =========================================================================
14- // Always stripped: rawEvent (debug payload, potentially large)
15- // =========================================================================
16-
17- it ( 'strips rawEvent from all events' , ( ) => {
18- const chunk = makeChunk ( 'TEXT_MESSAGE_START' , {
19- messageId : 'msg-1' ,
20- role : 'assistant' ,
21- rawEvent : { some : 'raw data' } ,
22- model : 'gpt-4o' ,
23- } )
24- const result = stripToSpec ( chunk ) as Record < string , unknown >
25- expect ( result ) . not . toHaveProperty ( 'rawEvent' )
26- // model is kept (passthrough)
27- expect ( result ) . toHaveProperty ( 'model' , 'gpt-4o' )
28- expect ( result ) . toHaveProperty ( 'messageId' , 'msg-1' )
29- } )
30-
31- // =========================================================================
32- // Deprecated aliases stripped: toolName, stepId, state, error (nested)
33- // =========================================================================
34-
35- it ( 'strips deprecated toolName from TOOL_CALL_START, keeps toolCallName' , ( ) => {
36- const chunk = makeChunk ( 'TOOL_CALL_START' , {
37- toolCallId : 'tc-1' ,
38- toolCallName : 'getTodos' ,
39- toolName : 'getTodos' ,
40- index : 0 ,
41- providerMetadata : { foo : 'bar' } ,
42- model : 'gpt-4o' ,
43- } )
44- const result = stripToSpec ( chunk ) as Record < string , unknown >
45- expect ( result ) . not . toHaveProperty ( 'toolName' )
46- // These extras are kept (passthrough)
47- expect ( result ) . toHaveProperty ( 'toolCallName' , 'getTodos' )
48- expect ( result ) . toHaveProperty ( 'index' , 0 )
49- expect ( result ) . toHaveProperty ( 'providerMetadata' )
50- expect ( result ) . toHaveProperty ( 'model' , 'gpt-4o' )
51- } )
52-
53- it ( 'strips deprecated toolName from TOOL_CALL_END, keeps extras' , ( ) => {
54- const chunk = makeChunk ( 'TOOL_CALL_END' , {
55- toolCallId : 'tc-1' ,
56- toolName : 'getTodos' ,
57- toolCallName : 'getTodos' ,
58- input : { userId : '123' } ,
59- result : '[{"id":"1","title":"Buy milk"}]' ,
60- model : 'gpt-4o' ,
61- } )
62- const result = stripToSpec ( chunk ) as Record < string , unknown >
63- expect ( result ) . not . toHaveProperty ( 'toolName' )
64- // These extras are kept (passthrough)
65- expect ( result ) . toHaveProperty ( 'toolCallName' , 'getTodos' )
66- expect ( result ) . toHaveProperty ( 'input' )
67- expect ( result ) . toHaveProperty ( 'result' )
68- expect ( result ) . toHaveProperty ( 'model' , 'gpt-4o' )
69- } )
70-
71- it ( 'strips deprecated stepId from STEP_STARTED, keeps stepName and extras' , ( ) => {
72- const chunk = makeChunk ( 'STEP_STARTED' , {
73- stepName : 'thinking' ,
74- stepId : 'step-1' ,
75- stepType : 'thinking' ,
76- model : 'gpt-4o' ,
77- } )
78- const result = stripToSpec ( chunk ) as Record < string , unknown >
79- expect ( result ) . not . toHaveProperty ( 'stepId' )
80- // These extras are kept (passthrough)
81- expect ( result ) . toHaveProperty ( 'stepName' , 'thinking' )
82- expect ( result ) . toHaveProperty ( 'stepType' , 'thinking' )
83- expect ( result ) . toHaveProperty ( 'model' , 'gpt-4o' )
84- } )
85-
86- it ( 'strips deprecated stepId from STEP_FINISHED, keeps extras' , ( ) => {
87- const chunk = makeChunk ( 'STEP_FINISHED' , {
88- stepName : 'thinking' ,
89- stepId : 'step-1' ,
90- delta : 'some thinking' ,
91- content : 'accumulated thinking' ,
92- model : 'gpt-4o' ,
93- } )
94- const result = stripToSpec ( chunk ) as Record < string , unknown >
95- expect ( result ) . not . toHaveProperty ( 'stepId' )
96- // These extras are kept (passthrough)
97- expect ( result ) . toHaveProperty ( 'stepName' , 'thinking' )
98- expect ( result ) . toHaveProperty ( 'delta' , 'some thinking' )
99- expect ( result ) . toHaveProperty ( 'content' , 'accumulated thinking' )
100- expect ( result ) . toHaveProperty ( 'model' , 'gpt-4o' )
101- } )
102-
10313 it ( 'strips deprecated nested error from RUN_ERROR, keeps flat message/code' , ( ) => {
10414 const chunk = makeChunk ( 'RUN_ERROR' , {
10515 message : 'Something went wrong' ,
@@ -114,106 +24,47 @@ describe('stripToSpec', () => {
11424 expect ( result ) . toHaveProperty ( 'model' , 'gpt-4o' )
11525 } )
11626
117- it ( 'strips deprecated state from STATE_SNAPSHOT, keeps snapshot' , ( ) => {
118- const chunk = makeChunk ( 'STATE_SNAPSHOT' , {
119- snapshot : { count : 42 } ,
120- state : { count : 42 } ,
121- model : 'gpt-4o' ,
122- } )
123- const result = stripToSpec ( chunk ) as Record < string , unknown >
124- expect ( result ) . not . toHaveProperty ( 'state' )
125- expect ( result ) . toHaveProperty ( 'snapshot' )
126- expect ( result ) . toHaveProperty ( 'model' , 'gpt-4o' )
127- } )
128-
129- // =========================================================================
130- // Extras preserved (passthrough allows them)
131- // =========================================================================
132-
133- it ( 'keeps model, content on TEXT_MESSAGE_CONTENT' , ( ) => {
134- const chunk = makeChunk ( 'TEXT_MESSAGE_CONTENT' , {
135- messageId : 'msg-1' ,
136- delta : 'Hello' ,
137- content : 'Hello World' ,
138- model : 'gpt-4o' ,
139- } )
140- const result = stripToSpec ( chunk ) as Record < string , unknown >
141- expect ( result ) . toHaveProperty ( 'delta' , 'Hello' )
142- expect ( result ) . toHaveProperty ( 'content' , 'Hello World' )
143- expect ( result ) . toHaveProperty ( 'model' , 'gpt-4o' )
144- } )
145-
146- it ( 'keeps args on TOOL_CALL_ARGS' , ( ) => {
147- const chunk = makeChunk ( 'TOOL_CALL_ARGS' , {
27+ it ( 'passes through all other events unchanged' , ( ) => {
28+ const chunk = makeChunk ( 'TOOL_CALL_START' , {
14829 toolCallId : 'tc-1' ,
149- delta : '{"userId":' ,
150- args : '{"userId":' ,
30+ toolCallName : 'getTodos' ,
31+ toolName : 'getTodos' ,
32+ index : 0 ,
33+ providerMetadata : { foo : 'bar' } ,
15134 model : 'gpt-4o' ,
15235 } )
153- const result = stripToSpec ( chunk ) as Record < string , unknown >
154- expect ( result ) . toHaveProperty ( 'args' , '{"userId":' )
155- expect ( result ) . toHaveProperty ( 'delta' , '{"userId":' )
156- expect ( result ) . toHaveProperty ( 'model' , 'gpt-4o' )
36+ const result = stripToSpec ( chunk )
37+ expect ( result ) . toBe ( chunk ) // same reference, no copy
15738 } )
15839
159- it ( 'keeps finishReason and usage on RUN_FINISHED ' , ( ) => {
40+ it ( 'keeps model, content, finishReason, usage, result, etc. ' , ( ) => {
16041 const chunk = makeChunk ( 'RUN_FINISHED' , {
16142 runId : 'run-1' ,
43+ threadId : 'thread-1' ,
16244 model : 'gpt-4o' ,
16345 finishReason : 'stop' ,
16446 usage : { promptTokens : 100 , completionTokens : 50 , totalTokens : 150 } ,
16547 } )
16648 const result = stripToSpec ( chunk ) as Record < string , unknown >
49+ expect ( result ) . toHaveProperty ( 'model' , 'gpt-4o' )
16750 expect ( result ) . toHaveProperty ( 'finishReason' , 'stop' )
16851 expect ( result ) . toHaveProperty ( 'usage' )
169- expect ( result ) . toHaveProperty ( 'model' , 'gpt-4o' )
170- } )
171-
172- it ( 'keeps model on RUN_STARTED' , ( ) => {
173- const chunk = makeChunk ( 'RUN_STARTED' , {
174- runId : 'run-1' ,
175- threadId : 'thread-1' ,
176- model : 'gpt-4o' ,
177- } )
178- const result = stripToSpec ( chunk ) as Record < string , unknown >
179- expect ( result ) . toHaveProperty ( 'model' , 'gpt-4o' )
180- expect ( result ) . toHaveProperty ( 'threadId' , 'thread-1' )
181- } )
182-
183- it ( 'passes through REASONING events unchanged (except rawEvent)' , ( ) => {
184- const chunk = makeChunk ( 'REASONING_MESSAGE_CONTENT' , {
185- messageId : 'msg-1' ,
186- delta : 'Let me think...' ,
187- model : 'gpt-4o' ,
188- } )
189- const result = stripToSpec ( chunk ) as Record < string , unknown >
190- expect ( result ) . toHaveProperty ( 'delta' , 'Let me think...' )
191- expect ( result ) . toHaveProperty ( 'model' , 'gpt-4o' )
19252 } )
19353
194- it ( 'passes through TOOL_CALL_RESULT unchanged (except rawEvent )' , ( ) => {
195- const chunk = makeChunk ( 'TOOL_CALL_RESULT ' , {
54+ it ( 'keeps toolName, stepId, and other deprecated aliases (passthrough )' , ( ) => {
55+ const chunk = makeChunk ( 'TOOL_CALL_END ' , {
19656 toolCallId : 'tc-1' ,
197- messageId : 'msg-result-1' ,
198- content : '{"items":[]}' ,
199- role : 'tool' ,
57+ toolCallName : 'getTodos' ,
58+ toolName : 'getTodos' ,
59+ input : { userId : '123' } ,
60+ result : '{"items":[]}' ,
20061 model : 'gpt-4o' ,
20162 } )
20263 const result = stripToSpec ( chunk ) as Record < string , unknown >
64+ expect ( result ) . toHaveProperty ( 'toolName' , 'getTodos' )
65+ expect ( result ) . toHaveProperty ( 'toolCallName' , 'getTodos' )
66+ expect ( result ) . toHaveProperty ( 'input' )
67+ expect ( result ) . toHaveProperty ( 'result' )
20368 expect ( result ) . toHaveProperty ( 'model' , 'gpt-4o' )
204- expect ( result ) . toHaveProperty ( 'content' , '{"items":[]}' )
205- } )
206-
207- it ( 'strips rawEvent even when combined with type-specific strips' , ( ) => {
208- const chunk = makeChunk ( 'TOOL_CALL_START' , {
209- toolCallId : 'tc-1' ,
210- toolCallName : 'foo' ,
211- toolName : 'foo' ,
212- rawEvent : { originalPayload : true } ,
213- } )
214- const result = stripToSpec ( chunk ) as Record < string , unknown >
215- expect ( result ) . not . toHaveProperty ( 'rawEvent' )
216- expect ( result ) . not . toHaveProperty ( 'toolName' )
217- expect ( result ) . toHaveProperty ( 'toolCallName' , 'foo' )
21869 } )
21970} )
0 commit comments