@introspection-sdk/introspection-node 0.4.1 → 0.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/.turbo/turbo-check-types.log +4 -0
  3. package/.turbo/turbo-lint.log +5 -0
  4. package/dist/ai-sdk-integration.d.ts.map +1 -1
  5. package/dist/ai-sdk-integration.js +2 -2
  6. package/dist/claude-hooks.d.ts.map +1 -1
  7. package/dist/claude-hooks.js +3 -3
  8. package/dist/client.d.ts +42 -132
  9. package/dist/client.d.ts.map +1 -1
  10. package/dist/client.js +66 -365
  11. package/dist/client.js.map +1 -0
  12. package/dist/converters/claude.d.ts +5 -1
  13. package/dist/converters/claude.d.ts.map +1 -1
  14. package/dist/converters/claude.js +7 -0
  15. package/dist/converters/claude.js.map +1 -0
  16. package/dist/converters/gemini.d.ts +90 -0
  17. package/dist/converters/gemini.d.ts.map +1 -0
  18. package/dist/converters/gemini.js +171 -0
  19. package/dist/converters/gemini.js.map +1 -0
  20. package/dist/converters/index.d.ts +1 -1
  21. package/dist/converters/index.d.ts.map +1 -1
  22. package/dist/converters/index.js +2 -1
  23. package/dist/converters/index.js.map +1 -0
  24. package/dist/converters/openai.js +1 -0
  25. package/dist/converters/openai.js.map +1 -0
  26. package/dist/converters/openclaw.d.ts +16 -0
  27. package/dist/converters/openclaw.d.ts.map +1 -0
  28. package/dist/converters/openclaw.js +49 -0
  29. package/dist/converters/openinference.js +1 -0
  30. package/dist/converters/openinference.js.map +1 -0
  31. package/dist/converters/vercel.d.ts.map +1 -1
  32. package/dist/converters/vercel.js +31 -3
  33. package/dist/converters/vercel.js.map +1 -0
  34. package/dist/http.d.ts +36 -0
  35. package/dist/http.d.ts.map +1 -0
  36. package/dist/http.js +145 -0
  37. package/dist/http.js.map +1 -0
  38. package/dist/index.d.ts +24 -27
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js +22 -32
  41. package/dist/index.js.map +1 -0
  42. package/dist/langchain-handler.d.ts.map +1 -1
  43. package/dist/langchain-handler.js +2 -2
  44. package/dist/mastra-exporter.d.ts.map +1 -1
  45. package/dist/mastra-exporter.js +2 -2
  46. package/dist/otel/anthropic.d.ts +62 -0
  47. package/dist/otel/anthropic.d.ts.map +1 -0
  48. package/dist/otel/anthropic.js +425 -0
  49. package/dist/otel/anthropic.js.map +1 -0
  50. package/dist/otel/claude-hooks.d.ts +346 -0
  51. package/dist/otel/claude-hooks.d.ts.map +1 -0
  52. package/dist/otel/claude-hooks.js +645 -0
  53. package/dist/otel/claude-hooks.js.map +1 -0
  54. package/dist/otel/claude-wrapper.d.ts +93 -0
  55. package/dist/otel/claude-wrapper.d.ts.map +1 -0
  56. package/dist/otel/claude-wrapper.js +155 -0
  57. package/dist/otel/claude-wrapper.js.map +1 -0
  58. package/dist/otel/gemini.d.ts +48 -0
  59. package/dist/otel/gemini.d.ts.map +1 -0
  60. package/dist/otel/gemini.js +297 -0
  61. package/dist/otel/gemini.js.map +1 -0
  62. package/dist/otel/index.d.ts +27 -0
  63. package/dist/otel/index.d.ts.map +1 -0
  64. package/dist/otel/index.js +33 -0
  65. package/dist/otel/index.js.map +1 -0
  66. package/dist/otel/langchain-handler.d.ts +112 -0
  67. package/dist/otel/langchain-handler.d.ts.map +1 -0
  68. package/dist/otel/langchain-handler.js +555 -0
  69. package/dist/otel/langchain-handler.js.map +1 -0
  70. package/dist/otel/logs.d.ts +82 -0
  71. package/dist/otel/logs.d.ts.map +1 -0
  72. package/dist/otel/logs.js +271 -0
  73. package/dist/otel/logs.js.map +1 -0
  74. package/dist/otel/mastra-exporter.d.ts +87 -0
  75. package/dist/otel/mastra-exporter.d.ts.map +1 -0
  76. package/dist/otel/mastra-exporter.js +525 -0
  77. package/dist/otel/mastra-exporter.js.map +1 -0
  78. package/dist/otel/pi.d.ts +59 -0
  79. package/dist/otel/pi.d.ts.map +1 -0
  80. package/dist/otel/pi.js +67 -0
  81. package/dist/otel/pi.js.map +1 -0
  82. package/dist/otel/setup.d.ts +23 -0
  83. package/dist/otel/setup.d.ts.map +1 -0
  84. package/dist/otel/setup.js +127 -0
  85. package/dist/otel/setup.js.map +1 -0
  86. package/dist/otel/span-processor.d.ts +62 -0
  87. package/dist/otel/span-processor.d.ts.map +1 -0
  88. package/dist/otel/span-processor.js +319 -0
  89. package/dist/otel/span-processor.js.map +1 -0
  90. package/dist/otel/tracing-processor.d.ts +139 -0
  91. package/dist/otel/tracing-processor.d.ts.map +1 -0
  92. package/dist/otel/tracing-processor.js +418 -0
  93. package/dist/otel/tracing-processor.js.map +1 -0
  94. package/dist/resources/experiments.d.ts +31 -0
  95. package/dist/resources/experiments.d.ts.map +1 -0
  96. package/dist/resources/experiments.js +133 -0
  97. package/dist/resources/experiments.js.map +1 -0
  98. package/dist/resources/recipes.d.ts +22 -0
  99. package/dist/resources/recipes.d.ts.map +1 -0
  100. package/dist/resources/recipes.js +61 -0
  101. package/dist/resources/recipes.js.map +1 -0
  102. package/dist/resources/runtimes.d.ts +76 -0
  103. package/dist/resources/runtimes.d.ts.map +1 -0
  104. package/dist/resources/runtimes.js +179 -0
  105. package/dist/resources/runtimes.js.map +1 -0
  106. package/dist/runner-resources/files.d.ts +35 -0
  107. package/dist/runner-resources/files.d.ts.map +1 -0
  108. package/dist/runner-resources/files.js +131 -0
  109. package/dist/runner-resources/files.js.map +1 -0
  110. package/dist/runner-resources/tasks.d.ts +39 -0
  111. package/dist/runner-resources/tasks.d.ts.map +1 -0
  112. package/dist/runner-resources/tasks.js +129 -0
  113. package/dist/runner-resources/tasks.js.map +1 -0
  114. package/dist/runner.d.ts +80 -0
  115. package/dist/runner.d.ts.map +1 -0
  116. package/dist/runner.js +159 -0
  117. package/dist/runner.js.map +1 -0
  118. package/dist/span-processor.d.ts.map +1 -1
  119. package/dist/span-processor.js +3 -3
  120. package/dist/streaming.d.ts +8 -0
  121. package/dist/streaming.d.ts.map +1 -0
  122. package/dist/streaming.js +67 -0
  123. package/dist/streaming.js.map +1 -0
  124. package/dist/tracing-processor.d.ts.map +1 -1
  125. package/dist/tracing-processor.js +3 -3
  126. package/dist/types/genai.d.ts +165 -0
  127. package/dist/types/genai.d.ts.map +1 -0
  128. package/dist/types/genai.js +82 -0
  129. package/dist/types.js +1 -0
  130. package/dist/types.js.map +1 -0
  131. package/dist/utils.d.ts +1 -0
  132. package/dist/utils.d.ts.map +1 -1
  133. package/dist/utils.js +14 -0
  134. package/dist/utils.js.map +1 -0
  135. package/dist/version.js +1 -0
  136. package/dist/version.js.map +1 -0
  137. package/package.json +83 -25
  138. package/src/client.ts +76 -471
  139. package/src/converters/claude.ts +11 -1
  140. package/src/converters/gemini.ts +243 -0
  141. package/src/converters/index.ts +13 -7
  142. package/src/converters/vercel.ts +41 -3
  143. package/src/http.ts +163 -0
  144. package/src/index.ts +110 -75
  145. package/src/{anthropic.ts → otel/anthropic.ts} +95 -8
  146. package/src/{claude-hooks.ts → otel/claude-hooks.ts} +125 -24
  147. package/src/{claude-wrapper.ts → otel/claude-wrapper.ts} +1 -1
  148. package/src/otel/gemini.ts +397 -0
  149. package/src/otel/index.ts +80 -0
  150. package/src/{langchain-handler.ts → otel/langchain-handler.ts} +56 -7
  151. package/src/otel/logs.ts +394 -0
  152. package/src/{mastra-exporter.ts → otel/mastra-exporter.ts} +86 -23
  153. package/src/otel/pi.ts +88 -0
  154. package/src/otel/setup.ts +174 -0
  155. package/src/{span-processor.ts → otel/span-processor.ts} +17 -10
  156. package/src/{tracing-processor.ts → otel/tracing-processor.ts} +100 -23
  157. package/src/resources/experiments.ts +170 -0
  158. package/src/resources/recipes.ts +73 -0
  159. package/src/resources/runtimes.ts +231 -0
  160. package/src/runner-resources/files.ts +163 -0
  161. package/src/runner-resources/tasks.ts +156 -0
  162. package/src/runner.ts +194 -0
  163. package/src/streaming.ts +57 -0
  164. package/src/utils.ts +15 -0
  165. package/src/ai-sdk-integration.ts +0 -689
  166. package/src/converters/ai-sdk.ts +0 -323
@@ -9,10 +9,12 @@
9
9
 
10
10
  import {
11
11
  context as otelContext,
12
+ propagation,
12
13
  trace as otelTrace,
13
14
  Span as OtelSpan,
14
15
  SpanKind,
15
16
  SpanStatusCode,
17
+ type Attributes,
16
18
  } from "@opentelemetry/api";
17
19
  import {
18
20
  BasicTracerProvider,
@@ -28,12 +30,12 @@ import {
28
30
  } from "@opentelemetry/resources";
29
31
  import { ATTR_SERVICE_NAME } from "@opentelemetry/semantic-conventions";
30
32
 
31
- import { logger } from "./utils.js";
32
- import { VERSION } from "./version.js";
33
+ import { logger, withOtlpHttpsProxy } from "../utils.js";
34
+ import { VERSION } from "../version.js";
33
35
  import {
34
36
  convertClaudeSessionToOtelAttributes,
35
37
  type ClaudeContentBlock,
36
- } from "./converters/claude.js";
38
+ } from "../converters/claude.js";
37
39
 
38
40
  // ---------------------------------------------------------------------------
39
41
  // Claude Agent SDK Hook types
@@ -241,6 +243,8 @@ export interface ClaudeAssistantMessage {
241
243
  usage?: {
242
244
  input_tokens?: number;
243
245
  output_tokens?: number;
246
+ cache_read_input_tokens?: number;
247
+ cache_creation_input_tokens?: number;
244
248
  };
245
249
  content?: Array<{ type: string; text?: string }>;
246
250
  };
@@ -271,12 +275,16 @@ export interface ClaudeHooksAdvancedOptions {
271
275
  export interface IntrospectionClaudeHooksOptions {
272
276
  /** Authentication token (env: INTROSPECTION_TOKEN) */
273
277
  token?: string;
274
- /** Base URL for the API (env: INTROSPECTION_BASE_URL) */
278
+ /** Base URL for the API (env: INTROSPECTION_BASE_OTEL_URL) */
275
279
  baseUrl?: string;
276
280
  /** Service name for the OTel resource (defaults to "claude-agent") */
277
281
  serviceName?: string;
278
282
  /** Agent name set on session spans as gen_ai.agent.name (defaults to serviceName) */
279
283
  agentName?: string;
284
+ /** Agent ID set on session spans as gen_ai.agent.id */
285
+ agentId?: string;
286
+ /** Conversation ID set on session spans as gen_ai.conversation.id */
287
+ conversationId?: string;
280
288
  /** Additional headers to include in requests */
281
289
  additionalHeaders?: Record<string, string>;
282
290
  /** Advanced options for testing and customization */
@@ -319,6 +327,8 @@ export class IntrospectionClaudeHooks {
319
327
  private _tracerProvider: BasicTracerProvider;
320
328
  private _tracer: ReturnType<BasicTracerProvider["getTracer"]>;
321
329
  private _agentName: string;
330
+ private _agentId?: string;
331
+ private _conversationId?: string;
322
332
  private _sessionSpans: Map<string, OtelSpan> = new Map();
323
333
  private _toolSpans: Map<string, OtelSpan> = new Map();
324
334
  private _subagentSpans: Map<string, OtelSpan> = new Map();
@@ -327,6 +337,8 @@ export class IntrospectionClaudeHooks {
327
337
  {
328
338
  input: number;
329
339
  output: number;
340
+ cacheRead: number;
341
+ cacheCreation: number;
330
342
  cost?: number;
331
343
  model?: string;
332
344
  inputPrompt?: string;
@@ -343,6 +355,8 @@ export class IntrospectionClaudeHooks {
343
355
  const advanced = options.advanced;
344
356
  const serviceName = options.serviceName || "claude-agent";
345
357
  this._agentName = options.agentName || serviceName;
358
+ this._agentId = options.agentId;
359
+ this._conversationId = options.conversationId;
346
360
  const resource = defaultResource().merge(
347
361
  resourceFromAttributes({ [ATTR_SERVICE_NAME]: serviceName }),
348
362
  );
@@ -355,7 +369,7 @@ export class IntrospectionClaudeHooks {
355
369
 
356
370
  const baseUrl =
357
371
  options.baseUrl ||
358
- process.env.INTROSPECTION_BASE_URL ||
372
+ process.env.INTROSPECTION_BASE_OTEL_URL ||
359
373
  "https://otel.introspection.dev";
360
374
 
361
375
  const headers: Record<string, string> = {
@@ -372,10 +386,12 @@ export class IntrospectionClaudeHooks {
372
386
  `IntrospectionClaudeHooks initialized: service=${serviceName}, endpoint=${endpoint}`,
373
387
  );
374
388
 
375
- const spanExporter = new OTLPTraceExporter({
376
- url: endpoint,
377
- headers,
378
- });
389
+ const spanExporter = new OTLPTraceExporter(
390
+ withOtlpHttpsProxy({
391
+ url: endpoint,
392
+ headers,
393
+ }),
394
+ );
379
395
 
380
396
  // Default to sequential export for dev/staging tokens.
381
397
  const useSimple =
@@ -453,6 +469,32 @@ export class IntrospectionClaudeHooks {
453
469
  };
454
470
  }
455
471
 
472
+ /**
473
+ * Resolve effective agent / conversation identity for a session, in order
474
+ * of precedence: OTel baggage on the active context > constructor option >
475
+ * the Claude session ID. Lets callers override identity per-invocation via
476
+ * `IntrospectionClient.withAgent()` / `.withConversation()` without
477
+ * having to construct a new hooks instance per call.
478
+ *
479
+ * Requires an active context manager — see {@link setupTracing}.
480
+ */
481
+ private _resolveIdentity(sessionId: string): {
482
+ agentName: string;
483
+ agentId?: string;
484
+ conversationId: string;
485
+ } {
486
+ const baggage = propagation.getBaggage(otelContext.active());
487
+ const baggageAgentName = baggage?.getEntry("gen_ai.agent.name")?.value;
488
+ const baggageAgentId = baggage?.getEntry("gen_ai.agent.id")?.value;
489
+ const baggageConvId = baggage?.getEntry("gen_ai.conversation.id")?.value;
490
+
491
+ return {
492
+ agentName: baggageAgentName || this._agentName,
493
+ agentId: baggageAgentId || this._agentId,
494
+ conversationId: baggageConvId || this._conversationId || sessionId,
495
+ };
496
+ }
497
+
456
498
  /**
457
499
  * Set the input prompt for a session so it appears as
458
500
  * `gen_ai.input.messages` on the session span.
@@ -468,6 +510,8 @@ export class IntrospectionClaudeHooks {
468
510
  const existing = this._sessionUsage.get(sessionId) || {
469
511
  input: 0,
470
512
  output: 0,
513
+ cacheRead: 0,
514
+ cacheCreation: 0,
471
515
  };
472
516
  existing.inputPrompt = prompt;
473
517
  this._sessionUsage.set(sessionId, existing);
@@ -494,12 +538,17 @@ export class IntrospectionClaudeHooks {
494
538
  const existing = this._sessionUsage.get(sessionId) || {
495
539
  input: 0,
496
540
  output: 0,
541
+ cacheRead: 0,
542
+ cacheCreation: 0,
497
543
  };
498
544
  existing.systemInstructions = instructions;
499
545
  this._sessionUsage.set(sessionId, existing);
500
546
  } else {
501
547
  this._pendingSystemInstructions = instructions;
502
548
  }
549
+ logger.info(
550
+ `System instructions set (${instructions.length} chars)${sessionId ? ` for session ${sessionId}` : " (pending)"}`,
551
+ );
503
552
  }
504
553
 
505
554
  private _pendingSystemInstructions?: string;
@@ -528,6 +577,8 @@ export class IntrospectionClaudeHooks {
528
577
  const existing = this._sessionUsage.get(sessionId) || {
529
578
  input: 0,
530
579
  output: 0,
580
+ cacheRead: 0,
581
+ cacheCreation: 0,
531
582
  };
532
583
 
533
584
  // Track usage
@@ -535,6 +586,8 @@ export class IntrospectionClaudeHooks {
535
586
  if (usage) {
536
587
  existing.input += usage.input_tokens || 0;
537
588
  existing.output += usage.output_tokens || 0;
589
+ existing.cacheRead += usage.cache_read_input_tokens || 0;
590
+ existing.cacheCreation += usage.cache_creation_input_tokens || 0;
538
591
  if (assistantMsg.message?.model) {
539
592
  existing.model = assistantMsg.message.model;
540
593
  }
@@ -573,12 +626,31 @@ export class IntrospectionClaudeHooks {
573
626
  const existing = this._sessionUsage.get(sessionId) || {
574
627
  input: 0,
575
628
  output: 0,
629
+ cacheRead: 0,
630
+ cacheCreation: 0,
576
631
  };
577
632
 
578
633
  if (resultMsg.usage) {
579
634
  // Result message has final totals
580
635
  existing.input = resultMsg.usage.input_tokens || existing.input;
581
636
  existing.output = resultMsg.usage.output_tokens || existing.output;
637
+ if (resultMsg.usage.cache_read_input_tokens != null) {
638
+ existing.cacheRead = resultMsg.usage.cache_read_input_tokens;
639
+ }
640
+ if (resultMsg.usage.cache_creation_input_tokens != null) {
641
+ existing.cacheCreation = resultMsg.usage.cache_creation_input_tokens;
642
+ }
643
+ }
644
+ // Fallback: aggregate cache tokens from per-model breakdown when top-level usage omits them
645
+ if (
646
+ resultMsg.modelUsage &&
647
+ existing.cacheRead === 0 &&
648
+ existing.cacheCreation === 0
649
+ ) {
650
+ for (const modelData of Object.values(resultMsg.modelUsage)) {
651
+ existing.cacheRead += modelData.cacheReadInputTokens || 0;
652
+ existing.cacheCreation += modelData.cacheCreationInputTokens || 0;
653
+ }
582
654
  }
583
655
  if (resultMsg.total_cost_usd !== undefined) {
584
656
  existing.cost = resultMsg.total_cost_usd;
@@ -615,16 +687,23 @@ export class IntrospectionClaudeHooks {
615
687
  }
616
688
 
617
689
  logger.debug(`Starting session span from init message: ${sessionId}`);
690
+ const ids = this._resolveIdentity(sessionId);
691
+ const attrs: Attributes = {
692
+ "gen_ai.system": "anthropic",
693
+ "gen_ai.operation.name": "chat",
694
+ "gen_ai.agent.name": ids.agentName,
695
+ "gen_ai.conversation.id": ids.conversationId,
696
+ "claude.session_id": sessionId,
697
+ "claude.source": "message",
698
+ };
699
+
700
+ if (ids.agentId) {
701
+ attrs["gen_ai.agent.id"] = ids.agentId;
702
+ }
618
703
 
619
704
  const span = this._tracer.startSpan("claude.session", {
620
705
  kind: SpanKind.CLIENT,
621
- attributes: {
622
- "gen_ai.system": "anthropic",
623
- "gen_ai.operation.name": "chat",
624
- "gen_ai.agent.name": this._agentName,
625
- "claude.session_id": sessionId,
626
- "claude.source": "message",
627
- },
706
+ attributes: attrs,
628
707
  });
629
708
 
630
709
  // Add model if present in init message
@@ -649,12 +728,14 @@ export class IntrospectionClaudeHooks {
649
728
  const sessionData: {
650
729
  input: number;
651
730
  output: number;
731
+ cacheRead: number;
732
+ cacheCreation: number;
652
733
  model?: string;
653
734
  inputPrompt?: string;
654
735
  responseContent?: string;
655
736
  toolNames?: string[];
656
737
  systemInstructions?: string;
657
- } = { input: 0, output: 0, model };
738
+ } = { input: 0, output: 0, cacheRead: 0, cacheCreation: 0, model };
658
739
 
659
740
  if (tools && tools.length > 0) {
660
741
  sessionData.toolNames = tools;
@@ -699,6 +780,8 @@ export class IntrospectionClaudeHooks {
699
780
  model: usage?.model,
700
781
  inputTokens: usage?.input,
701
782
  outputTokens: usage?.output,
783
+ cacheReadInputTokens: usage?.cacheRead || undefined,
784
+ cacheCreationInputTokens: usage?.cacheCreation || undefined,
702
785
  costUsd: usage?.cost,
703
786
  stopReason: usage?.stopReason,
704
787
  responseId: usage?.responseId,
@@ -745,15 +828,27 @@ export class IntrospectionClaudeHooks {
745
828
  const sessionInput = input as SessionStartHookInput;
746
829
  logger.debug(`SessionStart hook: ${sessionInput.session_id}`);
747
830
 
831
+ // Resolve identity via _resolveIdentity so baggage on the active context
832
+ // takes precedence over constructor defaults, matching the message-init
833
+ // path in _startSessionFromMessage. Without this, the SessionStart hook
834
+ // would always stamp the constructor-time agentName / sessionId even
835
+ // when the caller wrapped the query in withAgent() / withConversation().
836
+ const ids = this._resolveIdentity(sessionInput.session_id);
837
+ const attrs: Attributes = {
838
+ "gen_ai.system": "anthropic",
839
+ "gen_ai.operation.name": "chat",
840
+ "gen_ai.agent.name": ids.agentName,
841
+ "gen_ai.conversation.id": ids.conversationId,
842
+ "claude.session_id": sessionInput.session_id,
843
+ "claude.source": sessionInput.source,
844
+ };
845
+ if (ids.agentId) {
846
+ attrs["gen_ai.agent.id"] = ids.agentId;
847
+ }
848
+
748
849
  const span = this._tracer.startSpan("claude.session", {
749
850
  kind: SpanKind.CLIENT,
750
- attributes: {
751
- "gen_ai.system": "anthropic",
752
- "gen_ai.operation.name": "chat",
753
- "gen_ai.agent.name": this._agentName,
754
- "claude.session_id": sessionInput.session_id,
755
- "claude.source": sessionInput.source,
756
- },
851
+ attributes: attrs,
757
852
  });
758
853
 
759
854
  if (sessionInput.model) {
@@ -769,11 +864,15 @@ export class IntrospectionClaudeHooks {
769
864
  const sessionUsage: {
770
865
  input: number;
771
866
  output: number;
867
+ cacheRead: number;
868
+ cacheCreation: number;
772
869
  inputPrompt?: string;
773
870
  systemInstructions?: string;
774
871
  } = {
775
872
  input: 0,
776
873
  output: 0,
874
+ cacheRead: 0,
875
+ cacheCreation: 0,
777
876
  };
778
877
  if (this._pendingInputPrompt) {
779
878
  sessionUsage.inputPrompt = this._pendingInputPrompt;
@@ -811,6 +910,8 @@ export class IntrospectionClaudeHooks {
811
910
  model: usage.model,
812
911
  inputTokens: usage.input,
813
912
  outputTokens: usage.output,
913
+ cacheReadInputTokens: usage.cacheRead || undefined,
914
+ cacheCreationInputTokens: usage.cacheCreation || undefined,
814
915
  costUsd: usage.cost,
815
916
  stopReason: usage.stopReason,
816
917
  responseId: usage.responseId,
@@ -26,7 +26,7 @@ import {
26
26
  type ClaudeHooksConfig,
27
27
  type ClaudeSDKMessage,
28
28
  } from "./claude-hooks.js";
29
- import { logger } from "./utils.js";
29
+ import { logger } from "../utils.js";
30
30
 
31
31
  // --- Public types ---
32
32