@@ -44,44 +44,57 @@ function waitForVerdict (promise, verdict) {
4444 : promise
4545}
4646
47+ /**
48+ * Runs the output verdict for a parsed response and finishes the span with it. Finishing after the
49+ * verdict lets a block propagate to anthropic.request and keeps the span wrapping its child.
50+ *
51+ * @param {object } ctx
52+ * @param {object } result
53+ * @param {(body: object) => Promise<void>|undefined } getVerdict
54+ * @param {object|string } [returnedResult]
55+ * @returns {object|string|Promise<object|string> }
56+ */
57+ function finishResult ( ctx , result , getVerdict , returnedResult = result ) {
58+ const verdict = getVerdict ( result )
59+ if ( ! verdict ) {
60+ finish ( ctx , result , null )
61+ return returnedResult
62+ }
63+
64+ return verdict . then ( ( ) => {
65+ finish ( ctx , result , null )
66+ return returnedResult
67+ } )
68+ }
69+
4770/**
4871 * @param {object } response
4972 * @param {'json'|'text' } method
5073 * @param {object } ctx
51- * @param {(body: object|string ) => Promise<void>|undefined } getVerdict
74+ * @param {(body: object) => Promise<void>|undefined } getVerdict
5275 */
5376function wrapResponseReader ( response , method , ctx , getVerdict ) {
5477 if ( typeof response [ method ] !== 'function' ) return
5578
5679 shimmer . wrap ( response , method , original => function ( ...args ) {
5780 return original . apply ( this , args )
58- . then ( body => finishResult ( ctx , body , getVerdict ) )
81+ . then ( body => {
82+ if ( method === 'json' ) return finishResult ( ctx , body , getVerdict )
83+
84+ try {
85+ return finishResult ( ctx , JSON . parse ( body ) , getVerdict , body )
86+ } catch {
87+ finish ( ctx )
88+ return body
89+ }
90+ } )
5991 . catch ( error => {
6092 if ( ! ctx . finished ) finish ( ctx , null , error )
6193 throw error
6294 } )
6395 } )
6496}
6597
66- /**
67- * @param {object } ctx
68- * @param {object|string } result
69- * @param {(body: object|string) => Promise<void>|undefined } getVerdict
70- * @returns {object|string|Promise<object|string> }
71- */
72- function finishResult ( ctx , result , getVerdict ) {
73- const verdict = getVerdict ( result )
74- if ( ! verdict ) {
75- finish ( ctx , result , null )
76- return result
77- }
78-
79- return verdict . then ( ( ) => {
80- finish ( ctx , result , null )
81- return result
82- } )
83- }
84-
8598function wrapStreamIterator ( iterator , ctx ) {
8699 return function ( ...args ) {
87100 const itr = iterator . apply ( this , args )
@@ -175,24 +188,30 @@ function wrapCreate (create) {
175188 return parseResult
176189 } )
177190
178- // Gate raw access; output evaluation supports only the common json() and text() readers.
179- shimmer . wrap ( apiPromise , 'asResponse' , origAsResponse => function ( ...asResponseArgs ) {
180- return waitForVerdict ( origAsResponse . apply ( this , asResponseArgs ) , getBeforeVerdict ( ) )
181- . then ( response => {
182- if ( ! stream && wrappedResponse !== response ) {
183- wrappedResponse = response
184- wrapResponseReader ( response , 'json' , ctx , getAfterVerdict )
185- wrapResponseReader ( response , 'text' , ctx , getAfterVerdict )
186- }
187-
188- if ( afterVerdict ) return afterVerdict . then ( ( ) => response )
189- return response
190- } )
191- . catch ( error => {
192- if ( ! ctx . finished ) finish ( ctx , null , error )
193- throw error
194- } )
195- } )
191+ if ( typeof apiPromise . asResponse === 'function' ) {
192+ shimmer . wrap ( apiPromise , 'asResponse' , origAsResponse => function ( ...asResponseArgs ) {
193+ return waitForVerdict ( origAsResponse . apply ( this , asResponseArgs ) , getBeforeVerdict ( ) )
194+ . then ( response => {
195+ // Raw output evaluation supports the common json() and text() readers only.
196+ if ( ! stream &&
197+ ( anthropicTracingChannel . start . hasSubscribers ||
198+ afterVerdict ||
199+ messagesAfterChannel . hasSubscribers ) &&
200+ wrappedResponse !== response ) {
201+ wrappedResponse = response
202+ wrapResponseReader ( response , 'json' , ctx , getAfterVerdict )
203+ wrapResponseReader ( response , 'text' , ctx , getAfterVerdict )
204+ }
205+
206+ if ( afterVerdict ) return afterVerdict . then ( ( ) => response )
207+ return response
208+ } )
209+ . catch ( error => {
210+ if ( ! ctx . finished ) finish ( ctx , null , error )
211+ throw error
212+ } )
213+ } )
214+ }
196215
197216 anthropicTracingChannel . end . publish ( ctx )
198217
0 commit comments