@@ -53,6 +53,19 @@ const resolveDelegationOnboarding = (state: ClmmState): OnboardingState => {
5353 return { step : 2 , key : DELEGATION_STEP_KEY } ;
5454} ;
5555
56+ function readConfigString (
57+ config : CopilotKitConfig ,
58+ key : 'thread_id' | 'checkpoint_id' | 'checkpoint_ns' ,
59+ ) : string | undefined {
60+ const root = config as { configurable ?: unknown } ;
61+ if ( ! root . configurable || typeof root . configurable !== 'object' ) {
62+ return undefined ;
63+ }
64+ const configurable = root . configurable as Record < string , unknown > ;
65+ const value = configurable [ key ] ;
66+ return typeof value === 'string' && value . length > 0 ? value : undefined ;
67+ }
68+
5669const HexSchema = z
5770 . string ( )
5871 . regex ( / ^ 0 x [ 0 - 9 a - f A - F ] * $ / u)
@@ -125,19 +138,33 @@ export const collectDelegationsNode = async (
125138 state : ClmmState ,
126139 config : CopilotKitConfig ,
127140) : Promise < ClmmUpdate | Command < string , ClmmUpdate > > => {
141+ const runMetadata = {
142+ threadId : readConfigString ( config , 'thread_id' ) ,
143+ checkpointId : readConfigString ( config , 'checkpoint_id' ) ,
144+ checkpointNamespace : readConfigString ( config , 'checkpoint_ns' ) ,
145+ } ;
128146 const delegationOnboarding = resolveDelegationOnboarding ( state ) ;
147+ const taskState = state . thread . task ?. taskStatus ?. state ;
148+ const taskMessage = state . thread . task ?. taskStatus ?. message ?. content ;
149+ const isAwaitingDelegationInput =
150+ taskState === 'input-required' &&
151+ typeof taskMessage === 'string' &&
152+ taskMessage . toLowerCase ( ) . includes ( 'delegation approval' ) ;
129153 logInfo ( 'collectDelegations: entering node' , {
154+ ...runMetadata ,
130155 delegationsBypassActive : state . thread . delegationsBypassActive === true ,
131156 hasDelegationBundle : Boolean ( state . thread . delegationBundle ) ,
132157 } ) ;
133158 logWarn ( 'collectDelegations: node entered' , {
159+ ...runMetadata ,
134160 onboardingStatus : state . thread . onboardingFlow ?. status ,
135161 onboardingStep : state . thread . onboarding ?. step ,
136162 onboardingKey : state . thread . onboarding ?. key ,
137163 delegationsBypassActive : state . thread . delegationsBypassActive === true ,
138164 hasDelegationBundle : Boolean ( state . thread . delegationBundle ) ,
139165 hasOperatorInput : Boolean ( state . thread . operatorInput ) ,
140166 hasFundingTokenInput : Boolean ( state . thread . fundingTokenInput ) ,
167+ isAwaitingDelegationInput,
141168 } ) ;
142169
143170 if ( state . thread . delegationsBypassActive === true ) {
@@ -235,6 +262,16 @@ export const collectDelegationsNode = async (
235262 nextTaskMessage : awaitingMessage ,
236263 } ) ;
237264 const hasRunnableConfig = Boolean ( ( config as { configurable ?: unknown } ) . configurable ) ;
265+ logInfo ( 'collectDelegations: pause transition prepared' , {
266+ ...runMetadata ,
267+ hasRunnableConfig,
268+ shouldPersistPendingState,
269+ isAwaitingDelegationInput,
270+ currentOnboardingStep : state . thread . onboarding ?. step ,
271+ currentOnboardingKey : state . thread . onboarding ?. key ,
272+ nextOnboardingStep : delegationOnboarding . step ,
273+ nextOnboardingKey : delegationOnboarding . key ,
274+ } ) ;
238275 const pauseSnapshotView = applyThreadPatch ( state , pendingView ) ;
239276 if ( hasRunnableConfig && shouldPersistPendingState ) {
240277 const mergedView = pauseSnapshotView ;
@@ -244,6 +281,10 @@ export const collectDelegationsNode = async (
244281 thread : mergedView ,
245282 metadata : {
246283 pauseMechanism : 'checkpoint-and-interrupt' ,
284+ ...runMetadata ,
285+ hasRunnableConfig,
286+ shouldPersistPendingState,
287+ isAwaitingDelegationInput,
247288 } ,
248289 } ) ;
249290 await copilotkitEmitState ( config , {
@@ -272,18 +313,30 @@ export const collectDelegationsNode = async (
272313 thread : pauseSnapshotView ,
273314 metadata : {
274315 pauseMechanism : 'interrupt' ,
316+ ...runMetadata ,
317+ hasRunnableConfig,
275318 checkpointPersisted : shouldPersistPendingState ,
319+ isAwaitingDelegationInput,
276320 } ,
277321 } ) ;
278322
279323 const interruptResult = await requestInterruptPayload ( {
280324 request,
281325 interrupt,
282326 } ) ;
327+ logInfo ( 'collectDelegations: interrupt payload received' , {
328+ ...runMetadata ,
329+ rawPayloadType : typeof interruptResult . raw ,
330+ hasDecodedPayload : interruptResult . decoded !== undefined ,
331+ } ) ;
283332 const parsed = DelegationSigningResponseSchema . safeParse ( interruptResult . decoded ) ;
284333 if ( ! parsed . success ) {
285334 const issues = parsed . error . issues . map ( ( issue ) => issue . message ) . join ( '; ' ) ;
286335 const failureMessage = `Invalid delegation signing response: ${ issues } ` ;
336+ logWarn ( 'collectDelegations: invalid delegation signing payload' , {
337+ ...runMetadata ,
338+ issues,
339+ } ) ;
287340 const { task, statusEvent } = buildTaskStatus ( awaitingInput . task , 'failed' , failureMessage ) ;
288341 const failedView = applyThreadPatch ( state , {
289342 task,
@@ -304,6 +357,9 @@ export const collectDelegationsNode = async (
304357 }
305358
306359 if ( parsed . data . outcome === 'rejected' ) {
360+ logWarn ( 'collectDelegations: delegation signing rejected by user' , {
361+ ...runMetadata ,
362+ } ) ;
307363 const { task, statusEvent } = buildTaskStatus (
308364 awaitingInput . task ,
309365 'failed' ,
@@ -344,6 +400,10 @@ export const collectDelegationsNode = async (
344400 descriptions : [ ...DELEGATION_DESCRIPTIONS ] ,
345401 warnings,
346402 } ;
403+ logInfo ( 'collectDelegations: delegation signing accepted' , {
404+ ...runMetadata ,
405+ signedDelegationCount : delegationBundle . delegations . length ,
406+ } ) ;
347407
348408 const { task, statusEvent } = buildTaskStatus (
349409 awaitingInput . task ,
0 commit comments