@@ -37,6 +37,11 @@ function findCohereSpan(
3737 return spans . find ( ( candidate ) => candidate . output !== undefined ) ?? spans [ 0 ] ;
3838}
3939
40+ function isCohereProviderLimitError ( error : unknown ) : boolean {
41+ const message = error instanceof Error ? error . message : String ( error ?? "" ) ;
42+ return message . includes ( "TooManyRequestsError" ) || message . includes ( "429" ) ;
43+ }
44+
4045function buildSpanSummary (
4146 events : CapturedLogEvent [ ] ,
4247 supportsThinking : boolean ,
@@ -110,23 +115,42 @@ export function defineCohereInstrumentationAssertions(options: {
110115
111116 describe ( options . name , ( ) => {
112117 let events : CapturedLogEvent [ ] = [ ] ;
118+ let providerSkipReason : string | undefined ;
113119
114120 beforeAll ( async ( ) => {
115121 await withScenarioHarness ( async ( harness ) => {
116- await options . runScenario ( harness ) ;
122+ try {
123+ await options . runScenario ( harness ) ;
124+ } catch ( error ) {
125+ if ( isCohereProviderLimitError ( error ) ) {
126+ providerSkipReason =
127+ "Cohere provider returned a rate or quota limit error" ;
128+ return ;
129+ }
130+
131+ throw error ;
132+ }
117133 events = harness . events ( ) ;
118134 } ) ;
119135 } , options . timeoutMs ) ;
120136
121- test ( "captures the scenario root span" , testConfig , ( ) => {
137+ test ( "captures the scenario root span" , testConfig , ( context ) => {
138+ if ( providerSkipReason ) {
139+ context . skip ( ) ;
140+ }
141+
122142 const root = findLatestSpan ( events , ROOT_NAME ) ;
123143 expect ( root ) . toBeDefined ( ) ;
124144 expect ( root ?. row . metadata ) . toMatchObject ( {
125145 scenario : SCENARIO_NAME ,
126146 } ) ;
127147 } ) ;
128148
129- test ( "captures chat and chatStream spans" , testConfig , ( ) => {
149+ test ( "captures chat and chatStream spans" , testConfig , ( context ) => {
150+ if ( providerSkipReason ) {
151+ context . skip ( ) ;
152+ }
153+
130154 const chatOperation = findLatestSpan ( events , "cohere-chat-operation" ) ;
131155 const chatSpan = findCohereSpan (
132156 events ,
@@ -159,60 +183,73 @@ export function defineCohereInstrumentationAssertions(options: {
159183 } ) ;
160184
161185 if ( options . supportsThinking ) {
162- test ( "captures reasoning content for chatStream" , testConfig , ( ) => {
163- const root = findLatestSpan ( events , ROOT_NAME ) ;
164- const operation = findLatestSpan (
165- events ,
166- "cohere-chat-stream-thinking-operation" ,
167- ) ;
168- const span = findCohereSpan (
169- events ,
170- operation ?. span . id ,
171- "cohere.chatStream" ,
172- ) ;
173- const output = span ?. output as
174- | {
175- content ?: Array < {
176- text ?: string ;
177- thinking ?: string ;
178- type ?: string ;
179- } > ;
180- }
181- | undefined ;
182- const metrics = ( span ?. metrics ?? { } ) as Record < string , unknown > ;
183-
184- expect ( operation ) . toBeDefined ( ) ;
185- expect ( span ) . toBeDefined ( ) ;
186- expect ( operation ?. span . parentIds ) . toEqual ( [ root ?. span . id ?? "" ] ) ;
187- expect ( span ?. row . metadata ) . toMatchObject ( {
188- model : "command-a-reasoning-08-2025" ,
189- provider : "cohere" ,
190- thinking : {
191- tokenBudget : 128 ,
192- type : "enabled" ,
193- } ,
194- } ) ;
195- expect ( metrics ) . toMatchObject ( {
196- completion_tokens : expect . any ( Number ) ,
197- prompt_tokens : expect . any ( Number ) ,
198- reasoning_tokens : expect . any ( Number ) ,
199- time_to_first_token : expect . any ( Number ) ,
200- } ) ;
201- expect (
202- output ?. content ?. some (
203- ( block ) =>
204- block . type === "thinking" && typeof block . thinking === "string" ,
205- ) ,
206- ) . toBe ( true ) ;
207- expect (
208- output ?. content ?. some (
209- ( block ) => block . type === "text" && typeof block . text === "string" ,
210- ) ,
211- ) . toBe ( true ) ;
212- } ) ;
186+ test (
187+ "captures reasoning content for chatStream" ,
188+ testConfig ,
189+ ( context ) => {
190+ if ( providerSkipReason ) {
191+ context . skip ( ) ;
192+ }
193+
194+ const root = findLatestSpan ( events , ROOT_NAME ) ;
195+ const operation = findLatestSpan (
196+ events ,
197+ "cohere-chat-stream-thinking-operation" ,
198+ ) ;
199+ const span = findCohereSpan (
200+ events ,
201+ operation ?. span . id ,
202+ "cohere.chatStream" ,
203+ ) ;
204+ const output = span ?. output as
205+ | {
206+ content ?: Array < {
207+ text ?: string ;
208+ thinking ?: string ;
209+ type ?: string ;
210+ } > ;
211+ }
212+ | undefined ;
213+ const metrics = ( span ?. metrics ?? { } ) as Record < string , unknown > ;
214+
215+ expect ( operation ) . toBeDefined ( ) ;
216+ expect ( span ) . toBeDefined ( ) ;
217+ expect ( operation ?. span . parentIds ) . toEqual ( [ root ?. span . id ?? "" ] ) ;
218+ expect ( span ?. row . metadata ) . toMatchObject ( {
219+ model : "command-a-reasoning-08-2025" ,
220+ provider : "cohere" ,
221+ thinking : {
222+ tokenBudget : 128 ,
223+ type : "enabled" ,
224+ } ,
225+ } ) ;
226+ expect ( metrics ) . toMatchObject ( {
227+ completion_tokens : expect . any ( Number ) ,
228+ prompt_tokens : expect . any ( Number ) ,
229+ reasoning_tokens : expect . any ( Number ) ,
230+ time_to_first_token : expect . any ( Number ) ,
231+ } ) ;
232+ expect (
233+ output ?. content ?. some (
234+ ( block ) =>
235+ block . type === "thinking" && typeof block . thinking === "string" ,
236+ ) ,
237+ ) . toBe ( true ) ;
238+ expect (
239+ output ?. content ?. some (
240+ ( block ) =>
241+ block . type === "text" && typeof block . text === "string" ,
242+ ) ,
243+ ) . toBe ( true ) ;
244+ } ,
245+ ) ;
213246 }
214247
215- test ( "captures embed span" , testConfig , ( ) => {
248+ test ( "captures embed span" , testConfig , ( context ) => {
249+ if ( providerSkipReason ) {
250+ context . skip ( ) ;
251+ }
252+
216253 const operation = findLatestSpan ( events , "cohere-embed-operation" ) ;
217254 const span = findCohereSpan ( events , operation ?. span . id , "cohere.embed" ) ;
218255 const output = span ?. output as { embedding_length ?: number } | undefined ;
@@ -226,7 +263,11 @@ export function defineCohereInstrumentationAssertions(options: {
226263 expect ( output ?. embedding_length ) . toBeGreaterThan ( 0 ) ;
227264 } ) ;
228265
229- test ( "captures rerank span" , testConfig , ( ) => {
266+ test ( "captures rerank span" , testConfig , ( context ) => {
267+ if ( providerSkipReason ) {
268+ context . skip ( ) ;
269+ }
270+
230271 const operation = findLatestSpan ( events , "cohere-rerank-operation" ) ;
231272 const span = findCohereSpan ( events , operation ?. span . id , "cohere.rerank" ) ;
232273
@@ -242,7 +283,11 @@ export function defineCohereInstrumentationAssertions(options: {
242283 } ) ;
243284 } ) ;
244285
245- test ( "matches span snapshot" , testConfig , async ( ) => {
286+ test ( "matches span snapshot" , testConfig , async ( context ) => {
287+ if ( providerSkipReason ) {
288+ context . skip ( ) ;
289+ }
290+
246291 await expect (
247292 formatJsonFileSnapshot (
248293 buildSpanSummary ( events , options . supportsThinking ) ,
0 commit comments