@copilotkit/runtime 1.77.0 → 1.77.1

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 (78) hide show
  1. package/dist/_virtual/_rolldown/runtime.mjs +1 -25
  2. package/dist/lib/runtime/copilot-runtime.cjs +1 -0
  3. package/dist/lib/runtime/copilot-runtime.cjs.map +1 -1
  4. package/dist/lib/runtime/copilot-runtime.d.cts +1 -0
  5. package/dist/lib/runtime/copilot-runtime.d.cts.map +1 -1
  6. package/dist/lib/runtime/copilot-runtime.d.mts +1 -0
  7. package/dist/lib/runtime/copilot-runtime.d.mts.map +1 -1
  8. package/dist/lib/runtime/copilot-runtime.mjs +1 -0
  9. package/dist/lib/runtime/copilot-runtime.mjs.map +1 -1
  10. package/dist/lib/telemetry-client.cjs +1 -1
  11. package/dist/lib/telemetry-client.mjs +1 -1
  12. package/dist/package.cjs +5 -5
  13. package/dist/package.mjs +5 -5
  14. package/dist/v2/runtime/core/channel-manager.cjs +15 -15
  15. package/dist/v2/runtime/core/channel-manager.cjs.map +1 -1
  16. package/dist/v2/runtime/core/channel-manager.d.cts.map +1 -1
  17. package/dist/v2/runtime/core/channel-manager.d.mts.map +1 -1
  18. package/dist/v2/runtime/core/channel-manager.mjs +15 -15
  19. package/dist/v2/runtime/core/channel-manager.mjs.map +1 -1
  20. package/dist/v2/runtime/core/package-info.cjs +10 -0
  21. package/dist/v2/runtime/core/package-info.cjs.map +1 -0
  22. package/dist/v2/runtime/core/package-info.mjs +8 -0
  23. package/dist/v2/runtime/core/package-info.mjs.map +1 -0
  24. package/dist/v2/runtime/core/runtime.cjs +4 -4
  25. package/dist/v2/runtime/core/runtime.cjs.map +1 -1
  26. package/dist/v2/runtime/core/runtime.d.cts +7 -1
  27. package/dist/v2/runtime/core/runtime.d.cts.map +1 -1
  28. package/dist/v2/runtime/core/runtime.d.mts +7 -1
  29. package/dist/v2/runtime/core/runtime.d.mts.map +1 -1
  30. package/dist/v2/runtime/core/runtime.mjs +4 -5
  31. package/dist/v2/runtime/core/runtime.mjs.map +1 -1
  32. package/dist/v2/runtime/handlers/intelligence/memories.cjs +5 -17
  33. package/dist/v2/runtime/handlers/intelligence/memories.cjs.map +1 -1
  34. package/dist/v2/runtime/handlers/intelligence/memories.mjs +5 -17
  35. package/dist/v2/runtime/handlers/intelligence/memories.mjs.map +1 -1
  36. package/dist/v2/runtime/handlers/intelligence/run.cjs +43 -16
  37. package/dist/v2/runtime/handlers/intelligence/run.cjs.map +1 -1
  38. package/dist/v2/runtime/handlers/intelligence/run.mjs +43 -16
  39. package/dist/v2/runtime/handlers/intelligence/run.mjs.map +1 -1
  40. package/dist/v2/runtime/handlers/intelligence/threads.cjs +4 -3
  41. package/dist/v2/runtime/handlers/intelligence/threads.cjs.map +1 -1
  42. package/dist/v2/runtime/handlers/intelligence/threads.mjs +4 -3
  43. package/dist/v2/runtime/handlers/intelligence/threads.mjs.map +1 -1
  44. package/dist/v2/runtime/handlers/shared/mcp-apps-servers.cjs +1 -2
  45. package/dist/v2/runtime/handlers/shared/mcp-apps-servers.cjs.map +1 -1
  46. package/dist/v2/runtime/handlers/shared/mcp-apps-servers.mjs +1 -2
  47. package/dist/v2/runtime/handlers/shared/mcp-apps-servers.mjs.map +1 -1
  48. package/dist/v2/runtime/handlers/shared/platform-error.cjs +40 -0
  49. package/dist/v2/runtime/handlers/shared/platform-error.cjs.map +1 -0
  50. package/dist/v2/runtime/handlers/shared/platform-error.mjs +40 -0
  51. package/dist/v2/runtime/handlers/shared/platform-error.mjs.map +1 -0
  52. package/dist/v2/runtime/intelligence-platform/client.cjs +23 -4
  53. package/dist/v2/runtime/intelligence-platform/client.cjs.map +1 -1
  54. package/dist/v2/runtime/intelligence-platform/client.d.cts +21 -0
  55. package/dist/v2/runtime/intelligence-platform/client.d.cts.map +1 -1
  56. package/dist/v2/runtime/intelligence-platform/client.d.mts +21 -0
  57. package/dist/v2/runtime/intelligence-platform/client.d.mts.map +1 -1
  58. package/dist/v2/runtime/intelligence-platform/client.mjs +23 -4
  59. package/dist/v2/runtime/intelligence-platform/client.mjs.map +1 -1
  60. package/dist/v2/runtime/intelligence-platform/thread-lock-heartbeat.cjs +143 -0
  61. package/dist/v2/runtime/intelligence-platform/thread-lock-heartbeat.cjs.map +1 -0
  62. package/dist/v2/runtime/intelligence-platform/thread-lock-heartbeat.mjs +142 -0
  63. package/dist/v2/runtime/intelligence-platform/thread-lock-heartbeat.mjs.map +1 -0
  64. package/dist/v2/runtime/runner/intelligence.cjs +8 -1
  65. package/dist/v2/runtime/runner/intelligence.cjs.map +1 -1
  66. package/dist/v2/runtime/runner/intelligence.d.cts +12 -0
  67. package/dist/v2/runtime/runner/intelligence.d.cts.map +1 -1
  68. package/dist/v2/runtime/runner/intelligence.d.mts +12 -0
  69. package/dist/v2/runtime/runner/intelligence.d.mts.map +1 -1
  70. package/dist/v2/runtime/runner/intelligence.mjs +8 -1
  71. package/dist/v2/runtime/runner/intelligence.mjs.map +1 -1
  72. package/dist/v2/runtime/telemetry/telemetry-client.cjs +3 -4
  73. package/dist/v2/runtime/telemetry/telemetry-client.cjs.map +1 -1
  74. package/dist/v2/runtime/telemetry/telemetry-client.d.cts.map +1 -1
  75. package/dist/v2/runtime/telemetry/telemetry-client.d.mts.map +1 -1
  76. package/dist/v2/runtime/telemetry/telemetry-client.mjs +3 -5
  77. package/dist/v2/runtime/telemetry/telemetry-client.mjs.map +1 -1
  78. package/package.json +6 -6
@@ -13,6 +13,12 @@ interface IntelligenceAgentRunnerOptions {
13
13
  maxReconnectMs?: number;
14
14
  /** Max delay (ms) for channel rejoin backoff. @default 30_000 */
15
15
  maxRejoinMs?: number;
16
+ /**
17
+ * Interval (ms) between Phoenix heartbeats on the runner WebSocket. Keep it
18
+ * below the idle timeout of any proxy between the runtime and Intelligence.
19
+ * @default 15_000
20
+ */
21
+ heartbeatIntervalMs?: number;
16
22
  }
17
23
  interface RunnerStartupBoundary {
18
24
  events: Observable<BaseEvent>;
@@ -42,6 +48,12 @@ declare class IntelligenceAgentRunner extends AgentRunner {
42
48
  * socket.disconnect() in an onError handler will set
43
49
  * closeWasClean = true and reset the reconnect timer — permanently
44
50
  * killing retries.
51
+ *
52
+ * heartbeatIntervalMs — how often Phoenix pings the server
53
+ * (default 15s). Phoenix's own default is 30s, which equals a common
54
+ * reverse-proxy WebSocket idle timeout (e.g. Azure Application Gateway
55
+ * behind AGIC), so a run that emits no events for 30s would have its
56
+ * socket dropped by the proxy. The proxy timeout must exceed this value.
45
57
  */
46
58
  private createSocket;
47
59
  private createRunnerEventPayload;
@@ -1 +1 @@
1
- {"version":3,"file":"intelligence.d.mts","names":[],"sources":["../../../../src/v2/runtime/runner/intelligence.ts"],"mappings":";;;;;;UAqBiB,8BAAA;EAA8B;EAE7C,GAAA;EAF6C;EAI7C,SAAA;EAAA;EAEA,cAAA;EAEA;EAAA,WAAA;AAAA;AAAA,UAGe,qBAAA;EACf,MAAA,EAAQ,UAAA,CAAW,SAAA;EACnB,OAAA,EAAS,OAAA;AAAA;AAAA,cA6CE,uBAAA,SAAgC,WAAA;EAAA,QACnC,OAAA;EAAA,QACA,OAAA;cAEI,OAAA,EAAS,8BAAA;EAlDrB;;;;;;;AA8CF;;;;;;;;;;;;;;EA9CE,QA6EQ,YAAA;EAAA,QAgBA,wBAAA;EAAA,QAqBA,0BAAA;EApE8C;EAAA,QA+E9C,yBAAA;EAAA,QAQA,mBAAA;EA4BR,GAAA,CAAI,OAAA,EAAS,qBAAA,GAAwB,UAAA,CAAW,SAAA;EAIhD,sBAAA,CACE,OAAA,EAAS,qBAAA,GACR,qBAAA;EAAA,QAiBK,mBAAA;EA4OR,OAAA,CAAQ,OAAA,EAAS,yBAAA,GAA4B,UAAA,CAAW,SAAA;EA4CxD,SAAA,CAAU,OAAA,EAAS,2BAAA,GAA8B,OAAA;EAnYzC;EAyYR,IAAA,CAAK,OAAA,EAAS,sBAAA,GAAyB,OAAA;EAAA,QA0DzB,eAAA;EAnZN;EAAA,QA+gBA,gBAAA;EAAA,QAkBA,qBAAA;EAAA,QAqDA,yBAAA;EAAA,QAgCA,yBAAA;EAAA,QA0BA,sBAAA;EAAA,QAOA,yBAAA;EAAA,QA0BA,sBAAA;EAAA,QAOA,sBAAA;EAAA,QAOA,mBAAA;EAAA,QAiCA,sBAAA;EAAA,QAuBA,qBAAA;EAAA,QA8BA,mBAAA;EAAA,QAgBA,aAAA;EAAA,QAKA,cAAA;EAAA,QAKA,wBAAA;EAAA,QAWA,oBAAA;EAAA,QAWA,uBAAA;EAAA,QAQA,qBAAA;EAAA,QA+BA,UAAA;EAAA,QAaA,2BAAA;EAAA,QAkBA,oBAAA;EAljBM;;;;;;;EAAA,QA6jBN,YAAA;AAAA"}
1
+ {"version":3,"file":"intelligence.d.mts","names":[],"sources":["../../../../src/v2/runtime/runner/intelligence.ts"],"mappings":";;;;;;UAqBiB,8BAAA;EAA8B;EAE7C,GAAA;EAF6C;EAI7C,SAAA;EAAA;EAEA,cAAA;EAEA;EAAA,WAAA;EAMmB;;AAGrB;;;EAHE,mBAAA;AAAA;AAAA,UAGe,qBAAA;EACf,MAAA,EAAQ,UAAA,CAAW,SAAA;EACnB,OAAA,EAAS,OAAA;AAAA;AAAA,cA6CE,uBAAA,SAAgC,WAAA;EAAA,QACnC,OAAA;EAAA,QACA,OAAA;cAEI,OAAA,EAAS,8BAAA;EAjDL;;AA6ClB;;;;;;;;;;;;;;;;;;;;;;;;;EA7CkB,QAkFR,YAAA;EAAA,QAiBA,wBAAA;EAAA,QAqBA,0BAAA;EAWA;EAAA,QAAA,yBAAA;EAAA,QAQA,mBAAA;EA4BR,GAAA,CAAI,OAAA,EAAS,qBAAA,GAAwB,UAAA,CAAW,SAAA;EAIhD,sBAAA,CACE,OAAA,EAAS,qBAAA,GACR,qBAAA;EAAA,QAiBK,mBAAA;EA4OR,OAAA,CAAQ,OAAA,EAAS,yBAAA,GAA4B,UAAA,CAAW,SAAA;EA4CxD,SAAA,CAAU,OAAA,EAAS,2BAAA,GAA8B,OAAA;EA1StC;EAgTX,IAAA,CAAK,OAAA,EAAS,sBAAA,GAAyB,OAAA;EAAA,QA0DzB,eAAA;EAxVN;EAAA,QAodA,gBAAA;EAAA,QAkBA,qBAAA;EAAA,QAqDA,yBAAA;EAAA,QAgCA,yBAAA;EAAA,QA0BA,sBAAA;EAAA,QAOA,yBAAA;EAAA,QA0BA,sBAAA;EAAA,QAOA,sBAAA;EAAA,QAOA,mBAAA;EAAA,QAiCA,sBAAA;EAAA,QAuBA,qBAAA;EAAA,QA8BA,mBAAA;EAAA,QAgBA,aAAA;EAAA,QAKA,cAAA;EAAA,QAKA,wBAAA;EAAA,QAWA,oBAAA;EAAA,QAWA,uBAAA;EAAA,QAQA,qBAAA;EAAA,QA+BA,UAAA;EAAA,QAaA,2BAAA;EAAA,QAkBA,oBAAA;EAnNA;;;;;;;EAAA,QA8NA,YAAA;AAAA"}
@@ -40,12 +40,19 @@ var IntelligenceAgentRunner = class extends AgentRunner {
40
40
  * socket.disconnect() in an onError handler will set
41
41
  * closeWasClean = true and reset the reconnect timer — permanently
42
42
  * killing retries.
43
+ *
44
+ * heartbeatIntervalMs — how often Phoenix pings the server
45
+ * (default 15s). Phoenix's own default is 30s, which equals a common
46
+ * reverse-proxy WebSocket idle timeout (e.g. Azure Application Gateway
47
+ * behind AGIC), so a run that emits no events for 30s would have its
48
+ * socket dropped by the proxy. The proxy timeout must exceed this value.
43
49
  */
44
50
  createSocket(authToken = this.options.authToken) {
45
51
  const socket = new Socket(this.options.url, {
46
52
  ...authToken ? { authToken } : {},
47
53
  reconnectAfterMs: phoenixExponentialBackoff(100, this.options.maxReconnectMs ?? 1e4),
48
- rejoinAfterMs: phoenixExponentialBackoff(1e3, this.options.maxRejoinMs ?? 3e4)
54
+ rejoinAfterMs: phoenixExponentialBackoff(1e3, this.options.maxRejoinMs ?? 3e4),
55
+ heartbeatIntervalMs: this.options.heartbeatIntervalMs ?? 15e3
49
56
  });
50
57
  socket.connect();
51
58
  return socket;
@@ -1 +1 @@
1
- {"version":3,"file":"intelligence.mjs","names":["randomUUID"],"sources":["../../../../src/v2/runtime/runner/intelligence.ts"],"sourcesContent":["import type {\n AgentRunnerConnectRequest,\n AgentRunnerIsRunningRequest,\n AgentRunnerRunRequest,\n} from \"./agent-runner\";\nimport { AgentRunner } from \"./agent-runner\";\nimport type { AgentRunnerStopRequest } from \"./agent-runner\";\nimport { Observable } from \"rxjs\";\nimport type { AbstractAgent, BaseEvent, RunStartedEvent } from \"@ag-ui/client\";\nimport { EventType } from \"@ag-ui/client\";\nimport {\n finalizeRunEvents,\n stripIntelligenceRoutingFields,\n AG_UI_CHANNEL_EVENT,\n phoenixExponentialBackoff,\n logger,\n} from \"@copilotkit/shared\";\nimport type { Channel } from \"phoenix\";\nimport { Socket } from \"phoenix\";\nimport { randomUUID } from \"node:crypto\";\n\nexport interface IntelligenceAgentRunnerOptions {\n /** Phoenix runner websocket URL, e.g. \"ws://localhost:4000/runner\" */\n url: string;\n /** Optional Phoenix socket auth token used during websocket connect. */\n authToken?: string;\n /** Max delay (ms) for WebSocket reconnect backoff. @default 10_000 */\n maxReconnectMs?: number;\n /** Max delay (ms) for channel rejoin backoff. @default 30_000 */\n maxRejoinMs?: number;\n}\n\nexport interface RunnerStartupBoundary {\n events: Observable<BaseEvent>;\n startup: Promise<void>;\n}\n\ninterface ThreadState {\n threadId: string;\n runId: string;\n socket: Socket;\n channel: Channel;\n isRunning: boolean;\n stopRequested: boolean;\n agent: AbstractAgent | null;\n currentEvents: BaseEvent[];\n nextEventSeq: number;\n hasRunStarted: boolean;\n hasJoined: boolean;\n supportsRunnerEventBatch: boolean;\n producerFinished: boolean;\n cancellation: Promise<void>;\n cancelRun: () => void;\n completion: Promise<boolean>;\n resolveCompletion: (completed: boolean) => void;\n stopTimer: ReturnType<typeof setTimeout> | null;\n pendingEvents: Map<\n string,\n { payload: Record<string, unknown>; queuedAt: number }\n >;\n activeEventBatch: { eventIds: string[]; attempt: number } | null;\n nextEventPushAttempt: number;\n eventRetryTimer: ReturnType<typeof setTimeout> | null;\n eventFlushTimer: ReturnType<typeof setTimeout> | null;\n eventDeadlineTimer: ReturnType<typeof setTimeout> | null;\n socketReconnectWatchdog: ReturnType<typeof setTimeout> | null;\n eventRetryAttempt: number;\n completeRun: () => void;\n failRun: (error: Error) => void;\n}\n\nconst MAX_CONSECUTIVE_SOCKET_ERRORS = 5;\nconst EVENT_RETRY_BASE_MS = 100;\nconst EVENT_RETRY_MAX_MS = 2_000;\nconst RUNNER_EVENT_BATCH_CAPABILITY = \"runner_event_batch_v1\";\nconst MAX_RUNNER_EVENT_BATCH_SIZE = 32;\nconst RUNNER_EVENT_BATCH_FLUSH_MS = 5;\nconst EVENT_DURABILITY_DEADLINE_MS = 60_000;\n\nexport class IntelligenceAgentRunner extends AgentRunner {\n private options: IntelligenceAgentRunnerOptions;\n private threads = new Map<string, ThreadState>();\n\n constructor(options: IntelligenceAgentRunnerOptions) {\n super();\n // Store config — sockets are created per-run, not eagerly.\n this.options = options;\n }\n\n /**\n * Create a new Phoenix socket with explicit exponential backoff.\n *\n * Each run/connect gets its own socket so that:\n * - A socket failure only affects a single thread, not all threads.\n * - Cleanup is simple: channel.leave() + socket.disconnect() tears\n * down everything for that run with no shared-state concerns.\n * - Each run gets its own independent retry budget.\n *\n * reconnectAfterMs — delay before Phoenix reconnects the WebSocket\n * after an unclean close. 100ms base, doubling up to maxReconnectMs (default 10s).\n *\n * rejoinAfterMs — delay before Phoenix re-joins a channel that\n * entered the \"errored\" state. 1s base, doubling up to maxRejoinMs (default 30s).\n *\n * These are set explicitly because Phoenix's default schedule is a\n * fixed stepped array (not exponential), and any code that calls\n * socket.disconnect() in an onError handler will set\n * closeWasClean = true and reset the reconnect timer — permanently\n * killing retries.\n */\n private createSocket(authToken = this.options.authToken): Socket {\n const socket = new Socket(this.options.url, {\n ...(authToken ? { authToken } : {}),\n reconnectAfterMs: phoenixExponentialBackoff(\n 100,\n this.options.maxReconnectMs ?? 10_000,\n ),\n rejoinAfterMs: phoenixExponentialBackoff(\n 1_000,\n this.options.maxRejoinMs ?? 30_000,\n ),\n });\n socket.connect();\n return socket;\n }\n\n private createRunnerEventPayload(\n event: BaseEvent,\n request: AgentRunnerRunRequest,\n state: ThreadState,\n ): Record<string, unknown> {\n const canonicalEvent = this.stampRunnerMetadata(\n this.stampCanonicalRunOwnership(event, request),\n state,\n );\n const payload = {\n ...(canonicalEvent as Record<string, unknown>),\n };\n\n payload.threadId = request.threadId;\n payload.runId = request.input.runId;\n payload.thread_id = request.threadId;\n payload.run_id = request.input.runId;\n\n return payload;\n }\n\n private stampCanonicalRunOwnership(\n event: BaseEvent,\n request: AgentRunnerRunRequest,\n ): BaseEvent {\n const eventRecord = event as BaseEvent & Record<string, unknown>;\n eventRecord.threadId = request.threadId;\n eventRecord.runId = request.input.runId;\n return eventRecord;\n }\n\n /** Remove agent-controlled durable identity before the runtime assigns it. */\n private withoutAgentEventIdentity(event: BaseEvent): BaseEvent {\n const source = event as BaseEvent & { metadata?: Record<string, unknown> };\n const metadata = { ...source.metadata };\n delete metadata.cpki_event_id;\n delete metadata.cpki_event_seq;\n return { ...source, metadata };\n }\n\n private stampRunnerMetadata(event: BaseEvent, state: ThreadState): BaseEvent {\n const eventRecord = event as BaseEvent & {\n metadata?: Record<string, unknown>;\n };\n\n const existingMetadata = eventRecord.metadata ?? {};\n const hasEventId = typeof existingMetadata.cpki_event_id === \"string\";\n const hasEventSeq = typeof existingMetadata.cpki_event_seq === \"number\";\n\n if (hasEventId && hasEventSeq) {\n const eventSeq = existingMetadata.cpki_event_seq as number;\n state.nextEventSeq = Math.max(state.nextEventSeq, eventSeq + 1);\n return eventRecord;\n }\n\n const eventSeq = state.nextEventSeq++;\n\n eventRecord.metadata = {\n ...existingMetadata,\n cpki_event_id:\n typeof existingMetadata.cpki_event_id === \"string\"\n ? existingMetadata.cpki_event_id\n : randomUUID(),\n cpki_event_seq: eventSeq,\n };\n return eventRecord;\n }\n\n run(request: AgentRunnerRunRequest): Observable<BaseEvent> {\n return this.createRunObservable(request);\n }\n\n runWithStartupBoundary(\n request: AgentRunnerRunRequest,\n ): RunnerStartupBoundary {\n let resolveStartup: (() => void) | undefined;\n let rejectStartup: ((reason: Error) => void) | undefined;\n const startup = new Promise<void>((resolve, reject) => {\n resolveStartup = resolve;\n rejectStartup = reject;\n });\n\n return {\n events: this.createRunObservable(request, {\n resolveStartup: () => resolveStartup?.(),\n rejectStartup: (error) => rejectStartup?.(error),\n }),\n startup,\n };\n }\n\n private createRunObservable(\n request: AgentRunnerRunRequest,\n startupBoundary?: {\n resolveStartup: () => void;\n rejectStartup: (error: Error) => void;\n },\n ): Observable<BaseEvent> {\n const { threadId, agent, input } = request;\n\n const existing = this.threads.get(threadId);\n if (existing?.isRunning) {\n throw new Error(\"Thread already running\");\n }\n\n return new Observable((observer) => {\n if (this.threads.get(threadId)?.isRunning) {\n observer.error(new Error(\"Thread already running\"));\n return;\n }\n\n const socket = this.createSocket(request.authToken);\n\n const channel = socket.channel(`ingestion:${input.runId}`, {\n thread_id: threadId,\n run_id: input.runId,\n });\n\n let cancelRun!: () => void;\n const cancellation = new Promise<void>((resolve) => {\n cancelRun = resolve;\n });\n let resolveCompletion!: (completed: boolean) => void;\n const completion = new Promise<boolean>((resolve) => {\n resolveCompletion = resolve;\n });\n const state: ThreadState = {\n threadId,\n runId: input.runId,\n socket,\n channel,\n isRunning: true,\n stopRequested: false,\n agent,\n currentEvents: [],\n nextEventSeq: 1,\n hasRunStarted: false,\n hasJoined: false,\n supportsRunnerEventBatch: false,\n producerFinished: false,\n cancellation,\n cancelRun,\n completion,\n resolveCompletion,\n stopTimer: null,\n pendingEvents: new Map(),\n activeEventBatch: null,\n nextEventPushAttempt: 0,\n eventRetryTimer: null,\n eventFlushTimer: null,\n eventDeadlineTimer: null,\n socketReconnectWatchdog: null,\n eventRetryAttempt: 0,\n completeRun: () => observer.complete(),\n failRun: (error) => {\n startupBoundary?.rejectStartup(error);\n observer.error(error);\n },\n };\n this.threads.set(threadId, state);\n\n let consecutiveSocketErrors = 0;\n let plannedRestart = false;\n\n socket.onClose((event) => {\n if (!this.isCurrentThreadState(threadId, state)) {\n return;\n }\n plannedRestart = plannedRestart || event?.code === 1012;\n if (event?.code !== 1000 && state.socketReconnectWatchdog === null) {\n state.socketReconnectWatchdog = setTimeout(() => {\n state.socketReconnectWatchdog = null;\n if (!state.isRunning || socket.isConnected()) {\n return;\n }\n socket.disconnect(() => {\n if (state.isRunning && !socket.isConnected()) {\n socket.connect();\n }\n });\n }, 1_000);\n }\n });\n socket.onOpen(() => {\n if (!this.isCurrentThreadState(threadId, state)) {\n return;\n }\n if (state.socketReconnectWatchdog !== null) {\n clearTimeout(state.socketReconnectWatchdog);\n state.socketReconnectWatchdog = null;\n }\n consecutiveSocketErrors = 0;\n plannedRestart = false;\n });\n socket.onError(() => {\n if (!this.isCurrentThreadState(threadId, state)) {\n return;\n }\n // Once the gateway has accepted the run, transport recovery is not a\n // terminal condition. The agent may still be producing the\n // authoritative answer while Phoenix reconnects and replays durable\n // events, so an arbitrary socket-error count must not abort it.\n if (plannedRestart || state.hasJoined) {\n return;\n }\n\n consecutiveSocketErrors += 1;\n if (consecutiveSocketErrors >= MAX_CONSECUTIVE_SOCKET_ERRORS) {\n state.agent?.abortRun();\n }\n });\n\n // Listen for custom \"stop\" events pushed by the client over the\n // channel. This must be registered before channel.join() so the\n // handler is in place by the time the server starts relaying messages.\n // The client sends the stop event before leaving the channel, so the\n // runner is guaranteed to receive it while still joined.\n channel.on(AG_UI_CHANNEL_EVENT, (payload: BaseEvent) => {\n if (\n this.isCurrentThreadState(threadId, state) &&\n payload.type === EventType.CUSTOM &&\n (payload as BaseEvent & { name?: string }).name === \"stop\"\n ) {\n this.stop({ threadId, runId: state.runId }).catch((error) => {\n logger.error(\n { err: error, threadId, runId: state.runId },\n \"Failed to stop Intelligence run\",\n );\n });\n }\n });\n\n channel\n .join()\n .receive(\"ok\", (response) => {\n if (!this.isCurrentThreadState(threadId, state)) {\n return;\n }\n const supportsRunnerEventBatch =\n this.supportsRunnerEventBatch(response);\n const activeEventBatch =\n state.supportsRunnerEventBatch === supportsRunnerEventBatch\n ? state.activeEventBatch\n : null;\n state.supportsRunnerEventBatch = supportsRunnerEventBatch;\n if (state.hasJoined) {\n this.resetPendingEventRetry(state);\n if (activeEventBatch !== null) {\n state.activeEventBatch = activeEventBatch;\n this.retryActiveEventBatch(state);\n } else {\n this.replayPendingEvents(state);\n }\n return;\n }\n\n state.hasJoined = true;\n startupBoundary?.resolveStartup();\n void this.executeAgentRun(request, state, threadId, (event) => {\n observer.next(stripIntelligenceRoutingFields(event));\n });\n })\n .receive(\"error\", (resp) => {\n if (!this.isCurrentThreadState(threadId, state)) {\n return;\n }\n if (state.hasJoined) {\n if (this.isPermanentEventFailure(resp)) {\n const reason =\n typeof (resp as { reason?: unknown }).reason === \"string\"\n ? `: ${(resp as { reason: string }).reason}`\n : \"\";\n this.failThread(\n threadId,\n state,\n new Error(\n `Gateway permanently rejected channel rejoin${reason}`,\n ),\n );\n }\n return;\n }\n if (this.isRetryableJoinError(resp)) {\n return;\n }\n\n const error = new Error(\n `Failed to join channel: ${JSON.stringify(resp)}`,\n );\n const errorEvent = {\n type: EventType.RUN_ERROR,\n message: error.message,\n code: \"CHANNEL_JOIN_ERROR\",\n } as BaseEvent;\n observer.next(errorEvent);\n state.currentEvents.push(errorEvent);\n this.removeThread(threadId, state);\n startupBoundary?.rejectStartup(error);\n observer.complete();\n })\n .receive(\"timeout\", () => {\n if (!this.isCurrentThreadState(threadId, state)) {\n return;\n }\n if (state.hasJoined) {\n return;\n }\n\n const error = new Error(\"Timed out joining channel\");\n const errorEvent = {\n type: EventType.RUN_ERROR,\n message: error.message,\n code: \"CHANNEL_JOIN_TIMEOUT\",\n } as BaseEvent;\n observer.next(errorEvent);\n state.currentEvents.push(errorEvent);\n this.removeThread(threadId, state);\n startupBoundary?.rejectStartup(error);\n observer.complete();\n });\n\n return () => {\n this.removeThread(threadId, state);\n };\n });\n }\n\n connect(request: AgentRunnerConnectRequest): Observable<BaseEvent> {\n const { threadId } = request;\n\n return new Observable((observer) => {\n const socket = this.createSocket();\n\n const channel = socket.channel(`thread:${threadId}`);\n\n channel.on(\"ag_ui_event\", (payload: BaseEvent) => {\n observer.next(payload);\n\n if (\n payload.type === EventType.RUN_FINISHED ||\n payload.type === EventType.RUN_ERROR\n ) {\n observer.complete();\n }\n });\n\n const cleanup = () => {\n channel.leave();\n socket.disconnect();\n };\n\n channel\n .join()\n .receive(\"ok\", () => undefined)\n .receive(\"error\", (resp) => {\n observer.error(\n new Error(`Failed to join channel: ${JSON.stringify(resp)}`),\n );\n cleanup();\n })\n .receive(\"timeout\", () => {\n observer.error(new Error(\"Timed out joining channel\"));\n cleanup();\n });\n\n return () => {\n cleanup();\n };\n });\n }\n\n isRunning(request: AgentRunnerIsRunningRequest): Promise<boolean> {\n const state = this.threads.get(request.threadId);\n return Promise.resolve(state?.isRunning ?? false);\n }\n\n /** Stops this run and waits until its terminal events have been acknowledged. */\n stop(request: AgentRunnerStopRequest): Promise<boolean | undefined> {\n const state = this.threads.get(request.threadId);\n if (!state || !state.isRunning || state.stopRequested) {\n return Promise.resolve(false);\n }\n if (request.runId !== undefined && state.runId !== request.runId) {\n return Promise.resolve(false);\n }\n\n state.stopRequested = true;\n\n // Fence output before abort: adapters may emit synchronously, throw, or\n // ignore cancellation. Finalization must not depend on their cooperation.\n state.cancelRun();\n state.stopTimer = setTimeout(() => {\n this.failThread(\n state.threadId,\n state,\n new Error(\"Timed out stopping Intelligence run\"),\n );\n }, EVENT_DURABILITY_DEADLINE_MS);\n\n // Direct local abort — the runtime is the authority.\n if (state.agent) {\n try {\n state.agent.abortRun();\n } catch {\n // The local run is still fenced and must deliver its terminal events.\n }\n // Older AG-UI agents may not expose detachActiveRun. The cancellation\n // race still finalizes their run without waiting for the producer.\n if (typeof state.agent.detachActiveRun === \"function\") {\n try {\n Promise.resolve(state.agent.detachActiveRun()).catch((error) => {\n logger.warn(\n { err: error, threadId: state.threadId, runId: state.runId },\n \"Failed to detach stopped agent\",\n );\n });\n } catch (error) {\n logger.warn(\n { err: error, threadId: state.threadId, runId: state.runId },\n \"Failed to detach stopped agent\",\n );\n }\n }\n }\n\n return state.completion.then((completed) => {\n if (!completed) {\n throw new Error(\n \"Intelligence run stopped before terminal events were acknowledged\",\n );\n }\n return true;\n });\n }\n\n private async executeAgentRun(\n request: AgentRunnerRunRequest,\n state: ThreadState,\n threadId: string,\n onRunError: (event: BaseEvent) => void,\n ): Promise<void> {\n const { currentEvents } = state;\n const pushCanonicalEvent = (event: BaseEvent): void => {\n if (!this.isCurrentThreadState(threadId, state)) {\n return;\n }\n const canonicalEvent = this.stampRunnerMetadata(\n this.stampCanonicalRunOwnership(\n this.withoutAgentEventIdentity(event),\n request,\n ),\n state,\n );\n currentEvents.push(canonicalEvent);\n\n if (canonicalEvent.type === EventType.RUN_STARTED) {\n state.hasRunStarted = true;\n }\n\n this.queueRunnerEvent(\n this.createRunnerEventPayload(canonicalEvent, request, state),\n state,\n );\n // Notify the request handler without publishing the persisted error twice.\n // An agent may emit RUN_ERROR and complete normally instead of throwing.\n if (canonicalEvent.type === EventType.RUN_ERROR) {\n onRunError(canonicalEvent);\n }\n };\n\n const getPersistedInputMessages = () =>\n request.persistedInputMessages ?? request.input.messages;\n\n const buildRunStartedEvent = (\n source?: RunStartedEvent,\n ): RunStartedEvent => {\n const baseInput = source?.input ?? request.input;\n const persistedInputMessages = getPersistedInputMessages();\n const event =\n source ??\n ({\n type: EventType.RUN_STARTED,\n threadId: request.threadId,\n runId: request.input.runId,\n } as RunStartedEvent);\n event.threadId = request.threadId;\n event.runId = request.input.runId;\n event.input = {\n ...baseInput,\n threadId: request.threadId,\n runId: request.input.runId,\n ...(persistedInputMessages !== undefined\n ? { messages: persistedInputMessages }\n : {}),\n };\n return event;\n };\n\n const ensureRunStarted = (): void => {\n if (!state.hasRunStarted) {\n state.hasRunStarted = true;\n pushCanonicalEvent(buildRunStartedEvent());\n }\n };\n\n try {\n if (state.stopRequested) return;\n const backendThreadId = request.backendThreadId ?? request.threadId;\n request.agent.threadId = backendThreadId;\n await Promise.race([\n request.agent.runAgent(request.input, {\n onEvent: ({ event }: { event: BaseEvent }) => {\n if (state.stopRequested || state.producerFinished) return;\n if (event.type === EventType.RUN_STARTED) {\n pushCanonicalEvent(\n buildRunStartedEvent(event as RunStartedEvent),\n );\n return;\n }\n\n ensureRunStarted();\n pushCanonicalEvent(event);\n },\n }),\n state.cancellation,\n ]);\n } catch (error) {\n if (state.stopRequested || !this.isCurrentThreadState(threadId, state)) {\n return;\n }\n ensureRunStarted();\n const existingError = currentEvents.find(\n (event) => event.type === EventType.RUN_ERROR,\n );\n if (!existingError) {\n const errorEvent = {\n type: EventType.RUN_ERROR,\n message: error instanceof Error ? error.message : String(error),\n } as BaseEvent;\n pushCanonicalEvent(errorEvent);\n }\n } finally {\n if (!this.isCurrentThreadState(threadId, state)) {\n return;\n }\n ensureRunStarted();\n const appended = finalizeRunEvents(currentEvents, {\n stopRequested: state.stopRequested,\n protocolVersion: request.input.protocolVersion,\n });\n for (const event of appended) {\n pushCanonicalEvent(event);\n }\n state.producerFinished = true;\n this.completeWhenDurable(threadId, state);\n }\n }\n\n /** Queue one immutable event payload until Redis-backed gateway acknowledgement. */\n private queueRunnerEvent(\n payload: Record<string, unknown>,\n state: ThreadState,\n ): void {\n if (!this.isCurrentThreadState(state.threadId, state)) {\n return;\n }\n const eventId = this.runnerEventId(payload);\n if (!state.pendingEvents.has(eventId)) {\n state.pendingEvents.set(eventId, {\n payload: structuredClone(payload),\n queuedAt: Date.now(),\n });\n }\n this.scheduleEventDeadline(state);\n this.replayPendingEvents(state);\n }\n\n private pushPendingEventBatch(\n eventIds: string[],\n events: Array<{ payload: Record<string, unknown>; queuedAt: number }>,\n state: ThreadState,\n ): void {\n if (\n !this.isCurrentThreadState(state.threadId, state) ||\n this.failIfEventDeadlineExceeded(state) ||\n state.channel.state !== \"joined\" ||\n !state.socket.isConnected()\n ) {\n return;\n }\n\n const attempt = ++state.nextEventPushAttempt;\n state.activeEventBatch = { eventIds, attempt };\n const payloads = events.map((event) => event.payload);\n const isBatch = state.supportsRunnerEventBatch;\n\n state.channel\n .push(\n isBatch ? \"events\" : \"event\",\n isBatch ? { events: payloads } : payloads[0],\n )\n .receive(\"ok\", () => {\n if (\n !this.isCurrentThreadState(state.threadId, state) ||\n state.activeEventBatch?.attempt !== attempt\n ) {\n return;\n }\n if (this.failIfEventDeadlineExceeded(state)) {\n return;\n }\n for (const eventId of eventIds) {\n state.pendingEvents.delete(eventId);\n }\n state.activeEventBatch = null;\n state.eventRetryAttempt = 0;\n if (state.pendingEvents.size === 0) {\n this.clearPendingEventRetry(state);\n this.clearPendingEventFlush(state);\n }\n this.scheduleEventDeadline(state);\n this.completeWhenDurable(state.threadId, state);\n this.replayPendingEvents(state);\n })\n .receive(\"error\", (response) =>\n this.handlePendingEventFailure(state, attempt, response),\n )\n .receive(\"timeout\", () => this.handlePendingEventFailure(state, attempt));\n }\n\n private handlePendingEventFailure(\n state: ThreadState,\n attempt: number,\n response?: unknown,\n ): void {\n if (\n !this.isCurrentThreadState(state.threadId, state) ||\n state.activeEventBatch?.attempt !== attempt\n ) {\n return;\n }\n\n if (this.failIfEventDeadlineExceeded(state)) {\n return;\n }\n if (this.isPermanentEventFailure(response)) {\n const reason =\n typeof response === \"object\" &&\n response !== null &&\n typeof (response as { reason?: unknown }).reason === \"string\"\n ? (response as { reason: string }).reason\n : \"permanent_gateway_rejection\";\n this.failThread(\n state.threadId,\n state,\n new Error(`Runner event durability failed: ${reason}`),\n );\n return;\n }\n this.schedulePendingEventRetry(state);\n }\n\n private schedulePendingEventRetry(state: ThreadState): void {\n if (\n !this.isCurrentThreadState(state.threadId, state) ||\n state.pendingEvents.size === 0 ||\n state.eventRetryTimer !== null\n ) {\n return;\n }\n\n const delay = Math.min(\n EVENT_RETRY_BASE_MS * 2 ** state.eventRetryAttempt,\n EVENT_RETRY_MAX_MS,\n );\n state.eventRetryAttempt += 1;\n state.eventRetryTimer = setTimeout(() => {\n state.eventRetryTimer = null;\n if (\n !this.isCurrentThreadState(state.threadId, state) ||\n state.pendingEvents.size === 0\n ) {\n return;\n }\n this.retryActiveEventBatch(state);\n }, delay);\n }\n\n private clearPendingEventRetry(state: ThreadState): void {\n if (state.eventRetryTimer !== null) {\n clearTimeout(state.eventRetryTimer);\n state.eventRetryTimer = null;\n }\n }\n\n private schedulePendingEventFlush(state: ThreadState): void {\n if (\n !this.isCurrentThreadState(state.threadId, state) ||\n state.pendingEvents.size === 0 ||\n state.activeEventBatch !== null ||\n state.eventFlushTimer !== null\n ) {\n return;\n }\n\n const oldestQueuedAt = Math.min(\n ...[...state.pendingEvents.values()].map((event) => event.queuedAt),\n );\n const delay = Math.max(\n 0,\n oldestQueuedAt + RUNNER_EVENT_BATCH_FLUSH_MS - Date.now(),\n );\n state.eventFlushTimer = setTimeout(() => {\n state.eventFlushTimer = null;\n if (!this.isCurrentThreadState(state.threadId, state)) {\n return;\n }\n this.flushPendingEventBatch(state);\n }, delay);\n }\n\n private clearPendingEventFlush(state: ThreadState): void {\n if (state.eventFlushTimer !== null) {\n clearTimeout(state.eventFlushTimer);\n state.eventFlushTimer = null;\n }\n }\n\n private resetPendingEventRetry(state: ThreadState): void {\n this.clearPendingEventRetry(state);\n this.clearPendingEventFlush(state);\n state.eventRetryAttempt = 0;\n state.activeEventBatch = null;\n }\n\n private replayPendingEvents(state: ThreadState): void {\n if (\n !this.isCurrentThreadState(state.threadId, state) ||\n state.activeEventBatch !== null\n ) {\n return;\n }\n\n const pendingEvents = [...state.pendingEvents.entries()].sort(\n ([, left], [, right]) =>\n this.runnerEventSeq(left.payload) - this.runnerEventSeq(right.payload),\n );\n if (pendingEvents.length === 0) {\n return;\n }\n\n const batchSize = state.supportsRunnerEventBatch\n ? MAX_RUNNER_EVENT_BATCH_SIZE\n : 1;\n if (!state.supportsRunnerEventBatch || pendingEvents.length >= batchSize) {\n this.clearPendingEventFlush(state);\n const batch = pendingEvents.slice(0, batchSize);\n this.pushPendingEventBatch(\n batch.map(([eventId]) => eventId),\n batch.map(([, event]) => event),\n state,\n );\n return;\n }\n\n this.schedulePendingEventFlush(state);\n }\n\n private flushPendingEventBatch(state: ThreadState): void {\n if (\n !this.isCurrentThreadState(state.threadId, state) ||\n state.activeEventBatch !== null ||\n state.pendingEvents.size === 0\n ) {\n return;\n }\n\n const batch = [...state.pendingEvents.entries()]\n .sort(\n ([, left], [, right]) =>\n this.runnerEventSeq(left.payload) -\n this.runnerEventSeq(right.payload),\n )\n .slice(0, MAX_RUNNER_EVENT_BATCH_SIZE);\n this.pushPendingEventBatch(\n batch.map(([eventId]) => eventId),\n batch.map(([, event]) => event),\n state,\n );\n }\n\n private retryActiveEventBatch(state: ThreadState): void {\n if (\n !this.isCurrentThreadState(state.threadId, state) ||\n this.failIfEventDeadlineExceeded(state)\n ) {\n return;\n }\n const activeBatch = state.activeEventBatch;\n if (activeBatch === null) {\n this.replayPendingEvents(state);\n return;\n }\n\n const events = activeBatch.eventIds\n .map((eventId) => state.pendingEvents.get(eventId))\n .filter(\n (\n event,\n ): event is { payload: Record<string, unknown>; queuedAt: number } =>\n event !== undefined,\n );\n if (events.length !== activeBatch.eventIds.length) {\n state.activeEventBatch = null;\n this.replayPendingEvents(state);\n return;\n }\n\n this.pushPendingEventBatch(activeBatch.eventIds, events, state);\n }\n\n private completeWhenDurable(threadId: string, state: ThreadState): void {\n if (\n !this.isCurrentThreadState(threadId, state) ||\n !state.producerFinished ||\n state.pendingEvents.size !== 0\n ) {\n return;\n }\n if (this.threads.get(threadId) !== state) {\n return;\n }\n\n this.removeThread(threadId, state, true);\n state.completeRun();\n }\n\n private runnerEventId(payload: Record<string, unknown>): string {\n const metadata = payload.metadata as Record<string, unknown>;\n return metadata.cpki_event_id as string;\n }\n\n private runnerEventSeq(payload: Record<string, unknown>): number {\n const metadata = payload.metadata as Record<string, unknown>;\n return metadata.cpki_event_seq as number;\n }\n\n private supportsRunnerEventBatch(response: unknown): boolean {\n if (typeof response !== \"object\" || response === null) {\n return false;\n }\n const capabilities = (response as { capabilities?: unknown }).capabilities;\n return (\n Array.isArray(capabilities) &&\n capabilities.includes(RUNNER_EVENT_BATCH_CAPABILITY)\n );\n }\n\n private isRetryableJoinError(response: unknown): boolean {\n if (typeof response !== \"object\" || response === null) {\n return false;\n }\n const value = response as { reason?: unknown; retryable?: unknown };\n if (value.retryable === false) {\n return false;\n }\n return value.retryable === true || value.reason === \"gateway_draining\";\n }\n\n private isPermanentEventFailure(response: unknown): boolean {\n return (\n typeof response === \"object\" &&\n response !== null &&\n (response as { retryable?: unknown }).retryable === false\n );\n }\n\n private scheduleEventDeadline(state: ThreadState): void {\n if (state.eventDeadlineTimer !== null) {\n clearTimeout(state.eventDeadlineTimer);\n state.eventDeadlineTimer = null;\n }\n if (\n !this.isCurrentThreadState(state.threadId, state) ||\n state.pendingEvents.size === 0\n ) {\n return;\n }\n\n const oldestQueuedAt = Math.min(\n ...[...state.pendingEvents.values()].map((event) => event.queuedAt),\n );\n const deadline = oldestQueuedAt + EVENT_DURABILITY_DEADLINE_MS;\n state.eventDeadlineTimer = setTimeout(\n () => {\n state.eventDeadlineTimer = null;\n if (!this.isCurrentThreadState(state.threadId, state)) {\n return;\n }\n\n if (!this.failIfEventDeadlineExceeded(state)) {\n this.scheduleEventDeadline(state);\n }\n },\n Math.max(0, deadline - Date.now()),\n );\n }\n\n private failThread(threadId: string, state: ThreadState, error: Error): void {\n if (!this.isCurrentThreadState(threadId, state)) {\n return;\n }\n this.removeThread(threadId, state);\n try {\n state.agent?.abortRun();\n } catch {\n // The terminal durability error must still reach the subscriber.\n }\n state.failRun(error);\n }\n\n private failIfEventDeadlineExceeded(state: ThreadState): boolean {\n if (state.pendingEvents.size === 0) {\n return false;\n }\n const oldestQueuedAt = Math.min(\n ...[...state.pendingEvents.values()].map((event) => event.queuedAt),\n );\n if (Date.now() < oldestQueuedAt + EVENT_DURABILITY_DEADLINE_MS) {\n return false;\n }\n this.failThread(\n state.threadId,\n state,\n new Error(\"Timed out trying to durably deliver runner events\"),\n );\n return true;\n }\n\n private isCurrentThreadState(threadId: string, state: ThreadState): boolean {\n return state.isRunning && this.threads.get(threadId) === state;\n }\n\n /**\n * Tear down all resources for a thread: leave the channel,\n * disconnect the per-run socket, and remove the thread state.\n *\n * Idempotent — safe to call multiple times for the same threadId\n * (e.g. from join error handlers, finalize, and Observable teardown).\n */\n private removeThread(\n threadId: string,\n state: ThreadState,\n completed = false,\n ): void {\n if (this.threads.get(threadId) !== state) {\n return;\n }\n\n // Delete first so concurrent calls see the entry as already removed.\n this.threads.delete(threadId);\n state.isRunning = false;\n state.resolveCompletion(completed);\n if (state.stopTimer !== null) {\n clearTimeout(state.stopTimer);\n state.stopTimer = null;\n }\n this.clearPendingEventRetry(state);\n this.clearPendingEventFlush(state);\n if (state.eventDeadlineTimer !== null) {\n clearTimeout(state.eventDeadlineTimer);\n state.eventDeadlineTimer = null;\n }\n state.activeEventBatch = null;\n if (state.socketReconnectWatchdog !== null) {\n clearTimeout(state.socketReconnectWatchdog);\n state.socketReconnectWatchdog = null;\n }\n\n try {\n state.channel.leave();\n } catch {\n // Channel may already be closed/left.\n }\n try {\n state.socket.disconnect();\n } catch {\n // Socket may already be disconnected.\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"intelligence.mjs","names":["randomUUID"],"sources":["../../../../src/v2/runtime/runner/intelligence.ts"],"sourcesContent":["import type {\n AgentRunnerConnectRequest,\n AgentRunnerIsRunningRequest,\n AgentRunnerRunRequest,\n} from \"./agent-runner\";\nimport { AgentRunner } from \"./agent-runner\";\nimport type { AgentRunnerStopRequest } from \"./agent-runner\";\nimport { Observable } from \"rxjs\";\nimport type { AbstractAgent, BaseEvent, RunStartedEvent } from \"@ag-ui/client\";\nimport { EventType } from \"@ag-ui/client\";\nimport {\n finalizeRunEvents,\n stripIntelligenceRoutingFields,\n AG_UI_CHANNEL_EVENT,\n phoenixExponentialBackoff,\n logger,\n} from \"@copilotkit/shared\";\nimport type { Channel } from \"phoenix\";\nimport { Socket } from \"phoenix\";\nimport { randomUUID } from \"node:crypto\";\n\nexport interface IntelligenceAgentRunnerOptions {\n /** Phoenix runner websocket URL, e.g. \"ws://localhost:4000/runner\" */\n url: string;\n /** Optional Phoenix socket auth token used during websocket connect. */\n authToken?: string;\n /** Max delay (ms) for WebSocket reconnect backoff. @default 10_000 */\n maxReconnectMs?: number;\n /** Max delay (ms) for channel rejoin backoff. @default 30_000 */\n maxRejoinMs?: number;\n /**\n * Interval (ms) between Phoenix heartbeats on the runner WebSocket. Keep it\n * below the idle timeout of any proxy between the runtime and Intelligence.\n * @default 15_000\n */\n heartbeatIntervalMs?: number;\n}\n\nexport interface RunnerStartupBoundary {\n events: Observable<BaseEvent>;\n startup: Promise<void>;\n}\n\ninterface ThreadState {\n threadId: string;\n runId: string;\n socket: Socket;\n channel: Channel;\n isRunning: boolean;\n stopRequested: boolean;\n agent: AbstractAgent | null;\n currentEvents: BaseEvent[];\n nextEventSeq: number;\n hasRunStarted: boolean;\n hasJoined: boolean;\n supportsRunnerEventBatch: boolean;\n producerFinished: boolean;\n cancellation: Promise<void>;\n cancelRun: () => void;\n completion: Promise<boolean>;\n resolveCompletion: (completed: boolean) => void;\n stopTimer: ReturnType<typeof setTimeout> | null;\n pendingEvents: Map<\n string,\n { payload: Record<string, unknown>; queuedAt: number }\n >;\n activeEventBatch: { eventIds: string[]; attempt: number } | null;\n nextEventPushAttempt: number;\n eventRetryTimer: ReturnType<typeof setTimeout> | null;\n eventFlushTimer: ReturnType<typeof setTimeout> | null;\n eventDeadlineTimer: ReturnType<typeof setTimeout> | null;\n socketReconnectWatchdog: ReturnType<typeof setTimeout> | null;\n eventRetryAttempt: number;\n completeRun: () => void;\n failRun: (error: Error) => void;\n}\n\nconst MAX_CONSECUTIVE_SOCKET_ERRORS = 5;\nconst EVENT_RETRY_BASE_MS = 100;\nconst EVENT_RETRY_MAX_MS = 2_000;\nconst RUNNER_EVENT_BATCH_CAPABILITY = \"runner_event_batch_v1\";\nconst MAX_RUNNER_EVENT_BATCH_SIZE = 32;\nconst RUNNER_EVENT_BATCH_FLUSH_MS = 5;\nconst EVENT_DURABILITY_DEADLINE_MS = 60_000;\n\nexport class IntelligenceAgentRunner extends AgentRunner {\n private options: IntelligenceAgentRunnerOptions;\n private threads = new Map<string, ThreadState>();\n\n constructor(options: IntelligenceAgentRunnerOptions) {\n super();\n // Store config — sockets are created per-run, not eagerly.\n this.options = options;\n }\n\n /**\n * Create a new Phoenix socket with explicit exponential backoff.\n *\n * Each run/connect gets its own socket so that:\n * - A socket failure only affects a single thread, not all threads.\n * - Cleanup is simple: channel.leave() + socket.disconnect() tears\n * down everything for that run with no shared-state concerns.\n * - Each run gets its own independent retry budget.\n *\n * reconnectAfterMs — delay before Phoenix reconnects the WebSocket\n * after an unclean close. 100ms base, doubling up to maxReconnectMs (default 10s).\n *\n * rejoinAfterMs — delay before Phoenix re-joins a channel that\n * entered the \"errored\" state. 1s base, doubling up to maxRejoinMs (default 30s).\n *\n * These are set explicitly because Phoenix's default schedule is a\n * fixed stepped array (not exponential), and any code that calls\n * socket.disconnect() in an onError handler will set\n * closeWasClean = true and reset the reconnect timer — permanently\n * killing retries.\n *\n * heartbeatIntervalMs — how often Phoenix pings the server\n * (default 15s). Phoenix's own default is 30s, which equals a common\n * reverse-proxy WebSocket idle timeout (e.g. Azure Application Gateway\n * behind AGIC), so a run that emits no events for 30s would have its\n * socket dropped by the proxy. The proxy timeout must exceed this value.\n */\n private createSocket(authToken = this.options.authToken): Socket {\n const socket = new Socket(this.options.url, {\n ...(authToken ? { authToken } : {}),\n reconnectAfterMs: phoenixExponentialBackoff(\n 100,\n this.options.maxReconnectMs ?? 10_000,\n ),\n rejoinAfterMs: phoenixExponentialBackoff(\n 1_000,\n this.options.maxRejoinMs ?? 30_000,\n ),\n heartbeatIntervalMs: this.options.heartbeatIntervalMs ?? 15_000,\n });\n socket.connect();\n return socket;\n }\n\n private createRunnerEventPayload(\n event: BaseEvent,\n request: AgentRunnerRunRequest,\n state: ThreadState,\n ): Record<string, unknown> {\n const canonicalEvent = this.stampRunnerMetadata(\n this.stampCanonicalRunOwnership(event, request),\n state,\n );\n const payload = {\n ...(canonicalEvent as Record<string, unknown>),\n };\n\n payload.threadId = request.threadId;\n payload.runId = request.input.runId;\n payload.thread_id = request.threadId;\n payload.run_id = request.input.runId;\n\n return payload;\n }\n\n private stampCanonicalRunOwnership(\n event: BaseEvent,\n request: AgentRunnerRunRequest,\n ): BaseEvent {\n const eventRecord = event as BaseEvent & Record<string, unknown>;\n eventRecord.threadId = request.threadId;\n eventRecord.runId = request.input.runId;\n return eventRecord;\n }\n\n /** Remove agent-controlled durable identity before the runtime assigns it. */\n private withoutAgentEventIdentity(event: BaseEvent): BaseEvent {\n const source = event as BaseEvent & { metadata?: Record<string, unknown> };\n const metadata = { ...source.metadata };\n delete metadata.cpki_event_id;\n delete metadata.cpki_event_seq;\n return { ...source, metadata };\n }\n\n private stampRunnerMetadata(event: BaseEvent, state: ThreadState): BaseEvent {\n const eventRecord = event as BaseEvent & {\n metadata?: Record<string, unknown>;\n };\n\n const existingMetadata = eventRecord.metadata ?? {};\n const hasEventId = typeof existingMetadata.cpki_event_id === \"string\";\n const hasEventSeq = typeof existingMetadata.cpki_event_seq === \"number\";\n\n if (hasEventId && hasEventSeq) {\n const eventSeq = existingMetadata.cpki_event_seq as number;\n state.nextEventSeq = Math.max(state.nextEventSeq, eventSeq + 1);\n return eventRecord;\n }\n\n const eventSeq = state.nextEventSeq++;\n\n eventRecord.metadata = {\n ...existingMetadata,\n cpki_event_id:\n typeof existingMetadata.cpki_event_id === \"string\"\n ? existingMetadata.cpki_event_id\n : randomUUID(),\n cpki_event_seq: eventSeq,\n };\n return eventRecord;\n }\n\n run(request: AgentRunnerRunRequest): Observable<BaseEvent> {\n return this.createRunObservable(request);\n }\n\n runWithStartupBoundary(\n request: AgentRunnerRunRequest,\n ): RunnerStartupBoundary {\n let resolveStartup: (() => void) | undefined;\n let rejectStartup: ((reason: Error) => void) | undefined;\n const startup = new Promise<void>((resolve, reject) => {\n resolveStartup = resolve;\n rejectStartup = reject;\n });\n\n return {\n events: this.createRunObservable(request, {\n resolveStartup: () => resolveStartup?.(),\n rejectStartup: (error) => rejectStartup?.(error),\n }),\n startup,\n };\n }\n\n private createRunObservable(\n request: AgentRunnerRunRequest,\n startupBoundary?: {\n resolveStartup: () => void;\n rejectStartup: (error: Error) => void;\n },\n ): Observable<BaseEvent> {\n const { threadId, agent, input } = request;\n\n const existing = this.threads.get(threadId);\n if (existing?.isRunning) {\n throw new Error(\"Thread already running\");\n }\n\n return new Observable((observer) => {\n if (this.threads.get(threadId)?.isRunning) {\n observer.error(new Error(\"Thread already running\"));\n return;\n }\n\n const socket = this.createSocket(request.authToken);\n\n const channel = socket.channel(`ingestion:${input.runId}`, {\n thread_id: threadId,\n run_id: input.runId,\n });\n\n let cancelRun!: () => void;\n const cancellation = new Promise<void>((resolve) => {\n cancelRun = resolve;\n });\n let resolveCompletion!: (completed: boolean) => void;\n const completion = new Promise<boolean>((resolve) => {\n resolveCompletion = resolve;\n });\n const state: ThreadState = {\n threadId,\n runId: input.runId,\n socket,\n channel,\n isRunning: true,\n stopRequested: false,\n agent,\n currentEvents: [],\n nextEventSeq: 1,\n hasRunStarted: false,\n hasJoined: false,\n supportsRunnerEventBatch: false,\n producerFinished: false,\n cancellation,\n cancelRun,\n completion,\n resolveCompletion,\n stopTimer: null,\n pendingEvents: new Map(),\n activeEventBatch: null,\n nextEventPushAttempt: 0,\n eventRetryTimer: null,\n eventFlushTimer: null,\n eventDeadlineTimer: null,\n socketReconnectWatchdog: null,\n eventRetryAttempt: 0,\n completeRun: () => observer.complete(),\n failRun: (error) => {\n startupBoundary?.rejectStartup(error);\n observer.error(error);\n },\n };\n this.threads.set(threadId, state);\n\n let consecutiveSocketErrors = 0;\n let plannedRestart = false;\n\n socket.onClose((event) => {\n if (!this.isCurrentThreadState(threadId, state)) {\n return;\n }\n plannedRestart = plannedRestart || event?.code === 1012;\n if (event?.code !== 1000 && state.socketReconnectWatchdog === null) {\n state.socketReconnectWatchdog = setTimeout(() => {\n state.socketReconnectWatchdog = null;\n if (!state.isRunning || socket.isConnected()) {\n return;\n }\n socket.disconnect(() => {\n if (state.isRunning && !socket.isConnected()) {\n socket.connect();\n }\n });\n }, 1_000);\n }\n });\n socket.onOpen(() => {\n if (!this.isCurrentThreadState(threadId, state)) {\n return;\n }\n if (state.socketReconnectWatchdog !== null) {\n clearTimeout(state.socketReconnectWatchdog);\n state.socketReconnectWatchdog = null;\n }\n consecutiveSocketErrors = 0;\n plannedRestart = false;\n });\n socket.onError(() => {\n if (!this.isCurrentThreadState(threadId, state)) {\n return;\n }\n // Once the gateway has accepted the run, transport recovery is not a\n // terminal condition. The agent may still be producing the\n // authoritative answer while Phoenix reconnects and replays durable\n // events, so an arbitrary socket-error count must not abort it.\n if (plannedRestart || state.hasJoined) {\n return;\n }\n\n consecutiveSocketErrors += 1;\n if (consecutiveSocketErrors >= MAX_CONSECUTIVE_SOCKET_ERRORS) {\n state.agent?.abortRun();\n }\n });\n\n // Listen for custom \"stop\" events pushed by the client over the\n // channel. This must be registered before channel.join() so the\n // handler is in place by the time the server starts relaying messages.\n // The client sends the stop event before leaving the channel, so the\n // runner is guaranteed to receive it while still joined.\n channel.on(AG_UI_CHANNEL_EVENT, (payload: BaseEvent) => {\n if (\n this.isCurrentThreadState(threadId, state) &&\n payload.type === EventType.CUSTOM &&\n (payload as BaseEvent & { name?: string }).name === \"stop\"\n ) {\n this.stop({ threadId, runId: state.runId }).catch((error) => {\n logger.error(\n { err: error, threadId, runId: state.runId },\n \"Failed to stop Intelligence run\",\n );\n });\n }\n });\n\n channel\n .join()\n .receive(\"ok\", (response) => {\n if (!this.isCurrentThreadState(threadId, state)) {\n return;\n }\n const supportsRunnerEventBatch =\n this.supportsRunnerEventBatch(response);\n const activeEventBatch =\n state.supportsRunnerEventBatch === supportsRunnerEventBatch\n ? state.activeEventBatch\n : null;\n state.supportsRunnerEventBatch = supportsRunnerEventBatch;\n if (state.hasJoined) {\n this.resetPendingEventRetry(state);\n if (activeEventBatch !== null) {\n state.activeEventBatch = activeEventBatch;\n this.retryActiveEventBatch(state);\n } else {\n this.replayPendingEvents(state);\n }\n return;\n }\n\n state.hasJoined = true;\n startupBoundary?.resolveStartup();\n void this.executeAgentRun(request, state, threadId, (event) => {\n observer.next(stripIntelligenceRoutingFields(event));\n });\n })\n .receive(\"error\", (resp) => {\n if (!this.isCurrentThreadState(threadId, state)) {\n return;\n }\n if (state.hasJoined) {\n if (this.isPermanentEventFailure(resp)) {\n const reason =\n typeof (resp as { reason?: unknown }).reason === \"string\"\n ? `: ${(resp as { reason: string }).reason}`\n : \"\";\n this.failThread(\n threadId,\n state,\n new Error(\n `Gateway permanently rejected channel rejoin${reason}`,\n ),\n );\n }\n return;\n }\n if (this.isRetryableJoinError(resp)) {\n return;\n }\n\n const error = new Error(\n `Failed to join channel: ${JSON.stringify(resp)}`,\n );\n const errorEvent = {\n type: EventType.RUN_ERROR,\n message: error.message,\n code: \"CHANNEL_JOIN_ERROR\",\n } as BaseEvent;\n observer.next(errorEvent);\n state.currentEvents.push(errorEvent);\n this.removeThread(threadId, state);\n startupBoundary?.rejectStartup(error);\n observer.complete();\n })\n .receive(\"timeout\", () => {\n if (!this.isCurrentThreadState(threadId, state)) {\n return;\n }\n if (state.hasJoined) {\n return;\n }\n\n const error = new Error(\"Timed out joining channel\");\n const errorEvent = {\n type: EventType.RUN_ERROR,\n message: error.message,\n code: \"CHANNEL_JOIN_TIMEOUT\",\n } as BaseEvent;\n observer.next(errorEvent);\n state.currentEvents.push(errorEvent);\n this.removeThread(threadId, state);\n startupBoundary?.rejectStartup(error);\n observer.complete();\n });\n\n return () => {\n this.removeThread(threadId, state);\n };\n });\n }\n\n connect(request: AgentRunnerConnectRequest): Observable<BaseEvent> {\n const { threadId } = request;\n\n return new Observable((observer) => {\n const socket = this.createSocket();\n\n const channel = socket.channel(`thread:${threadId}`);\n\n channel.on(\"ag_ui_event\", (payload: BaseEvent) => {\n observer.next(payload);\n\n if (\n payload.type === EventType.RUN_FINISHED ||\n payload.type === EventType.RUN_ERROR\n ) {\n observer.complete();\n }\n });\n\n const cleanup = () => {\n channel.leave();\n socket.disconnect();\n };\n\n channel\n .join()\n .receive(\"ok\", () => undefined)\n .receive(\"error\", (resp) => {\n observer.error(\n new Error(`Failed to join channel: ${JSON.stringify(resp)}`),\n );\n cleanup();\n })\n .receive(\"timeout\", () => {\n observer.error(new Error(\"Timed out joining channel\"));\n cleanup();\n });\n\n return () => {\n cleanup();\n };\n });\n }\n\n isRunning(request: AgentRunnerIsRunningRequest): Promise<boolean> {\n const state = this.threads.get(request.threadId);\n return Promise.resolve(state?.isRunning ?? false);\n }\n\n /** Stops this run and waits until its terminal events have been acknowledged. */\n stop(request: AgentRunnerStopRequest): Promise<boolean | undefined> {\n const state = this.threads.get(request.threadId);\n if (!state || !state.isRunning || state.stopRequested) {\n return Promise.resolve(false);\n }\n if (request.runId !== undefined && state.runId !== request.runId) {\n return Promise.resolve(false);\n }\n\n state.stopRequested = true;\n\n // Fence output before abort: adapters may emit synchronously, throw, or\n // ignore cancellation. Finalization must not depend on their cooperation.\n state.cancelRun();\n state.stopTimer = setTimeout(() => {\n this.failThread(\n state.threadId,\n state,\n new Error(\"Timed out stopping Intelligence run\"),\n );\n }, EVENT_DURABILITY_DEADLINE_MS);\n\n // Direct local abort — the runtime is the authority.\n if (state.agent) {\n try {\n state.agent.abortRun();\n } catch {\n // The local run is still fenced and must deliver its terminal events.\n }\n // Older AG-UI agents may not expose detachActiveRun. The cancellation\n // race still finalizes their run without waiting for the producer.\n if (typeof state.agent.detachActiveRun === \"function\") {\n try {\n Promise.resolve(state.agent.detachActiveRun()).catch((error) => {\n logger.warn(\n { err: error, threadId: state.threadId, runId: state.runId },\n \"Failed to detach stopped agent\",\n );\n });\n } catch (error) {\n logger.warn(\n { err: error, threadId: state.threadId, runId: state.runId },\n \"Failed to detach stopped agent\",\n );\n }\n }\n }\n\n return state.completion.then((completed) => {\n if (!completed) {\n throw new Error(\n \"Intelligence run stopped before terminal events were acknowledged\",\n );\n }\n return true;\n });\n }\n\n private async executeAgentRun(\n request: AgentRunnerRunRequest,\n state: ThreadState,\n threadId: string,\n onRunError: (event: BaseEvent) => void,\n ): Promise<void> {\n const { currentEvents } = state;\n const pushCanonicalEvent = (event: BaseEvent): void => {\n if (!this.isCurrentThreadState(threadId, state)) {\n return;\n }\n const canonicalEvent = this.stampRunnerMetadata(\n this.stampCanonicalRunOwnership(\n this.withoutAgentEventIdentity(event),\n request,\n ),\n state,\n );\n currentEvents.push(canonicalEvent);\n\n if (canonicalEvent.type === EventType.RUN_STARTED) {\n state.hasRunStarted = true;\n }\n\n this.queueRunnerEvent(\n this.createRunnerEventPayload(canonicalEvent, request, state),\n state,\n );\n // Notify the request handler without publishing the persisted error twice.\n // An agent may emit RUN_ERROR and complete normally instead of throwing.\n if (canonicalEvent.type === EventType.RUN_ERROR) {\n onRunError(canonicalEvent);\n }\n };\n\n const getPersistedInputMessages = () =>\n request.persistedInputMessages ?? request.input.messages;\n\n const buildRunStartedEvent = (\n source?: RunStartedEvent,\n ): RunStartedEvent => {\n const baseInput = source?.input ?? request.input;\n const persistedInputMessages = getPersistedInputMessages();\n const event =\n source ??\n ({\n type: EventType.RUN_STARTED,\n threadId: request.threadId,\n runId: request.input.runId,\n } as RunStartedEvent);\n event.threadId = request.threadId;\n event.runId = request.input.runId;\n event.input = {\n ...baseInput,\n threadId: request.threadId,\n runId: request.input.runId,\n ...(persistedInputMessages !== undefined\n ? { messages: persistedInputMessages }\n : {}),\n };\n return event;\n };\n\n const ensureRunStarted = (): void => {\n if (!state.hasRunStarted) {\n state.hasRunStarted = true;\n pushCanonicalEvent(buildRunStartedEvent());\n }\n };\n\n try {\n if (state.stopRequested) return;\n const backendThreadId = request.backendThreadId ?? request.threadId;\n request.agent.threadId = backendThreadId;\n await Promise.race([\n request.agent.runAgent(request.input, {\n onEvent: ({ event }: { event: BaseEvent }) => {\n if (state.stopRequested || state.producerFinished) return;\n if (event.type === EventType.RUN_STARTED) {\n pushCanonicalEvent(\n buildRunStartedEvent(event as RunStartedEvent),\n );\n return;\n }\n\n ensureRunStarted();\n pushCanonicalEvent(event);\n },\n }),\n state.cancellation,\n ]);\n } catch (error) {\n if (state.stopRequested || !this.isCurrentThreadState(threadId, state)) {\n return;\n }\n ensureRunStarted();\n const existingError = currentEvents.find(\n (event) => event.type === EventType.RUN_ERROR,\n );\n if (!existingError) {\n const errorEvent = {\n type: EventType.RUN_ERROR,\n message: error instanceof Error ? error.message : String(error),\n } as BaseEvent;\n pushCanonicalEvent(errorEvent);\n }\n } finally {\n if (!this.isCurrentThreadState(threadId, state)) {\n return;\n }\n ensureRunStarted();\n const appended = finalizeRunEvents(currentEvents, {\n stopRequested: state.stopRequested,\n protocolVersion: request.input.protocolVersion,\n });\n for (const event of appended) {\n pushCanonicalEvent(event);\n }\n state.producerFinished = true;\n this.completeWhenDurable(threadId, state);\n }\n }\n\n /** Queue one immutable event payload until Redis-backed gateway acknowledgement. */\n private queueRunnerEvent(\n payload: Record<string, unknown>,\n state: ThreadState,\n ): void {\n if (!this.isCurrentThreadState(state.threadId, state)) {\n return;\n }\n const eventId = this.runnerEventId(payload);\n if (!state.pendingEvents.has(eventId)) {\n state.pendingEvents.set(eventId, {\n payload: structuredClone(payload),\n queuedAt: Date.now(),\n });\n }\n this.scheduleEventDeadline(state);\n this.replayPendingEvents(state);\n }\n\n private pushPendingEventBatch(\n eventIds: string[],\n events: Array<{ payload: Record<string, unknown>; queuedAt: number }>,\n state: ThreadState,\n ): void {\n if (\n !this.isCurrentThreadState(state.threadId, state) ||\n this.failIfEventDeadlineExceeded(state) ||\n state.channel.state !== \"joined\" ||\n !state.socket.isConnected()\n ) {\n return;\n }\n\n const attempt = ++state.nextEventPushAttempt;\n state.activeEventBatch = { eventIds, attempt };\n const payloads = events.map((event) => event.payload);\n const isBatch = state.supportsRunnerEventBatch;\n\n state.channel\n .push(\n isBatch ? \"events\" : \"event\",\n isBatch ? { events: payloads } : payloads[0],\n )\n .receive(\"ok\", () => {\n if (\n !this.isCurrentThreadState(state.threadId, state) ||\n state.activeEventBatch?.attempt !== attempt\n ) {\n return;\n }\n if (this.failIfEventDeadlineExceeded(state)) {\n return;\n }\n for (const eventId of eventIds) {\n state.pendingEvents.delete(eventId);\n }\n state.activeEventBatch = null;\n state.eventRetryAttempt = 0;\n if (state.pendingEvents.size === 0) {\n this.clearPendingEventRetry(state);\n this.clearPendingEventFlush(state);\n }\n this.scheduleEventDeadline(state);\n this.completeWhenDurable(state.threadId, state);\n this.replayPendingEvents(state);\n })\n .receive(\"error\", (response) =>\n this.handlePendingEventFailure(state, attempt, response),\n )\n .receive(\"timeout\", () => this.handlePendingEventFailure(state, attempt));\n }\n\n private handlePendingEventFailure(\n state: ThreadState,\n attempt: number,\n response?: unknown,\n ): void {\n if (\n !this.isCurrentThreadState(state.threadId, state) ||\n state.activeEventBatch?.attempt !== attempt\n ) {\n return;\n }\n\n if (this.failIfEventDeadlineExceeded(state)) {\n return;\n }\n if (this.isPermanentEventFailure(response)) {\n const reason =\n typeof response === \"object\" &&\n response !== null &&\n typeof (response as { reason?: unknown }).reason === \"string\"\n ? (response as { reason: string }).reason\n : \"permanent_gateway_rejection\";\n this.failThread(\n state.threadId,\n state,\n new Error(`Runner event durability failed: ${reason}`),\n );\n return;\n }\n this.schedulePendingEventRetry(state);\n }\n\n private schedulePendingEventRetry(state: ThreadState): void {\n if (\n !this.isCurrentThreadState(state.threadId, state) ||\n state.pendingEvents.size === 0 ||\n state.eventRetryTimer !== null\n ) {\n return;\n }\n\n const delay = Math.min(\n EVENT_RETRY_BASE_MS * 2 ** state.eventRetryAttempt,\n EVENT_RETRY_MAX_MS,\n );\n state.eventRetryAttempt += 1;\n state.eventRetryTimer = setTimeout(() => {\n state.eventRetryTimer = null;\n if (\n !this.isCurrentThreadState(state.threadId, state) ||\n state.pendingEvents.size === 0\n ) {\n return;\n }\n this.retryActiveEventBatch(state);\n }, delay);\n }\n\n private clearPendingEventRetry(state: ThreadState): void {\n if (state.eventRetryTimer !== null) {\n clearTimeout(state.eventRetryTimer);\n state.eventRetryTimer = null;\n }\n }\n\n private schedulePendingEventFlush(state: ThreadState): void {\n if (\n !this.isCurrentThreadState(state.threadId, state) ||\n state.pendingEvents.size === 0 ||\n state.activeEventBatch !== null ||\n state.eventFlushTimer !== null\n ) {\n return;\n }\n\n const oldestQueuedAt = Math.min(\n ...[...state.pendingEvents.values()].map((event) => event.queuedAt),\n );\n const delay = Math.max(\n 0,\n oldestQueuedAt + RUNNER_EVENT_BATCH_FLUSH_MS - Date.now(),\n );\n state.eventFlushTimer = setTimeout(() => {\n state.eventFlushTimer = null;\n if (!this.isCurrentThreadState(state.threadId, state)) {\n return;\n }\n this.flushPendingEventBatch(state);\n }, delay);\n }\n\n private clearPendingEventFlush(state: ThreadState): void {\n if (state.eventFlushTimer !== null) {\n clearTimeout(state.eventFlushTimer);\n state.eventFlushTimer = null;\n }\n }\n\n private resetPendingEventRetry(state: ThreadState): void {\n this.clearPendingEventRetry(state);\n this.clearPendingEventFlush(state);\n state.eventRetryAttempt = 0;\n state.activeEventBatch = null;\n }\n\n private replayPendingEvents(state: ThreadState): void {\n if (\n !this.isCurrentThreadState(state.threadId, state) ||\n state.activeEventBatch !== null\n ) {\n return;\n }\n\n const pendingEvents = [...state.pendingEvents.entries()].sort(\n ([, left], [, right]) =>\n this.runnerEventSeq(left.payload) - this.runnerEventSeq(right.payload),\n );\n if (pendingEvents.length === 0) {\n return;\n }\n\n const batchSize = state.supportsRunnerEventBatch\n ? MAX_RUNNER_EVENT_BATCH_SIZE\n : 1;\n if (!state.supportsRunnerEventBatch || pendingEvents.length >= batchSize) {\n this.clearPendingEventFlush(state);\n const batch = pendingEvents.slice(0, batchSize);\n this.pushPendingEventBatch(\n batch.map(([eventId]) => eventId),\n batch.map(([, event]) => event),\n state,\n );\n return;\n }\n\n this.schedulePendingEventFlush(state);\n }\n\n private flushPendingEventBatch(state: ThreadState): void {\n if (\n !this.isCurrentThreadState(state.threadId, state) ||\n state.activeEventBatch !== null ||\n state.pendingEvents.size === 0\n ) {\n return;\n }\n\n const batch = [...state.pendingEvents.entries()]\n .sort(\n ([, left], [, right]) =>\n this.runnerEventSeq(left.payload) -\n this.runnerEventSeq(right.payload),\n )\n .slice(0, MAX_RUNNER_EVENT_BATCH_SIZE);\n this.pushPendingEventBatch(\n batch.map(([eventId]) => eventId),\n batch.map(([, event]) => event),\n state,\n );\n }\n\n private retryActiveEventBatch(state: ThreadState): void {\n if (\n !this.isCurrentThreadState(state.threadId, state) ||\n this.failIfEventDeadlineExceeded(state)\n ) {\n return;\n }\n const activeBatch = state.activeEventBatch;\n if (activeBatch === null) {\n this.replayPendingEvents(state);\n return;\n }\n\n const events = activeBatch.eventIds\n .map((eventId) => state.pendingEvents.get(eventId))\n .filter(\n (\n event,\n ): event is { payload: Record<string, unknown>; queuedAt: number } =>\n event !== undefined,\n );\n if (events.length !== activeBatch.eventIds.length) {\n state.activeEventBatch = null;\n this.replayPendingEvents(state);\n return;\n }\n\n this.pushPendingEventBatch(activeBatch.eventIds, events, state);\n }\n\n private completeWhenDurable(threadId: string, state: ThreadState): void {\n if (\n !this.isCurrentThreadState(threadId, state) ||\n !state.producerFinished ||\n state.pendingEvents.size !== 0\n ) {\n return;\n }\n if (this.threads.get(threadId) !== state) {\n return;\n }\n\n this.removeThread(threadId, state, true);\n state.completeRun();\n }\n\n private runnerEventId(payload: Record<string, unknown>): string {\n const metadata = payload.metadata as Record<string, unknown>;\n return metadata.cpki_event_id as string;\n }\n\n private runnerEventSeq(payload: Record<string, unknown>): number {\n const metadata = payload.metadata as Record<string, unknown>;\n return metadata.cpki_event_seq as number;\n }\n\n private supportsRunnerEventBatch(response: unknown): boolean {\n if (typeof response !== \"object\" || response === null) {\n return false;\n }\n const capabilities = (response as { capabilities?: unknown }).capabilities;\n return (\n Array.isArray(capabilities) &&\n capabilities.includes(RUNNER_EVENT_BATCH_CAPABILITY)\n );\n }\n\n private isRetryableJoinError(response: unknown): boolean {\n if (typeof response !== \"object\" || response === null) {\n return false;\n }\n const value = response as { reason?: unknown; retryable?: unknown };\n if (value.retryable === false) {\n return false;\n }\n return value.retryable === true || value.reason === \"gateway_draining\";\n }\n\n private isPermanentEventFailure(response: unknown): boolean {\n return (\n typeof response === \"object\" &&\n response !== null &&\n (response as { retryable?: unknown }).retryable === false\n );\n }\n\n private scheduleEventDeadline(state: ThreadState): void {\n if (state.eventDeadlineTimer !== null) {\n clearTimeout(state.eventDeadlineTimer);\n state.eventDeadlineTimer = null;\n }\n if (\n !this.isCurrentThreadState(state.threadId, state) ||\n state.pendingEvents.size === 0\n ) {\n return;\n }\n\n const oldestQueuedAt = Math.min(\n ...[...state.pendingEvents.values()].map((event) => event.queuedAt),\n );\n const deadline = oldestQueuedAt + EVENT_DURABILITY_DEADLINE_MS;\n state.eventDeadlineTimer = setTimeout(\n () => {\n state.eventDeadlineTimer = null;\n if (!this.isCurrentThreadState(state.threadId, state)) {\n return;\n }\n\n if (!this.failIfEventDeadlineExceeded(state)) {\n this.scheduleEventDeadline(state);\n }\n },\n Math.max(0, deadline - Date.now()),\n );\n }\n\n private failThread(threadId: string, state: ThreadState, error: Error): void {\n if (!this.isCurrentThreadState(threadId, state)) {\n return;\n }\n this.removeThread(threadId, state);\n try {\n state.agent?.abortRun();\n } catch {\n // The terminal durability error must still reach the subscriber.\n }\n state.failRun(error);\n }\n\n private failIfEventDeadlineExceeded(state: ThreadState): boolean {\n if (state.pendingEvents.size === 0) {\n return false;\n }\n const oldestQueuedAt = Math.min(\n ...[...state.pendingEvents.values()].map((event) => event.queuedAt),\n );\n if (Date.now() < oldestQueuedAt + EVENT_DURABILITY_DEADLINE_MS) {\n return false;\n }\n this.failThread(\n state.threadId,\n state,\n new Error(\"Timed out trying to durably deliver runner events\"),\n );\n return true;\n }\n\n private isCurrentThreadState(threadId: string, state: ThreadState): boolean {\n return state.isRunning && this.threads.get(threadId) === state;\n }\n\n /**\n * Tear down all resources for a thread: leave the channel,\n * disconnect the per-run socket, and remove the thread state.\n *\n * Idempotent — safe to call multiple times for the same threadId\n * (e.g. from join error handlers, finalize, and Observable teardown).\n */\n private removeThread(\n threadId: string,\n state: ThreadState,\n completed = false,\n ): void {\n if (this.threads.get(threadId) !== state) {\n return;\n }\n\n // Delete first so concurrent calls see the entry as already removed.\n this.threads.delete(threadId);\n state.isRunning = false;\n state.resolveCompletion(completed);\n if (state.stopTimer !== null) {\n clearTimeout(state.stopTimer);\n state.stopTimer = null;\n }\n this.clearPendingEventRetry(state);\n this.clearPendingEventFlush(state);\n if (state.eventDeadlineTimer !== null) {\n clearTimeout(state.eventDeadlineTimer);\n state.eventDeadlineTimer = null;\n }\n state.activeEventBatch = null;\n if (state.socketReconnectWatchdog !== null) {\n clearTimeout(state.socketReconnectWatchdog);\n state.socketReconnectWatchdog = null;\n }\n\n try {\n state.channel.leave();\n } catch {\n // Channel may already be closed/left.\n }\n try {\n state.socket.disconnect();\n } catch {\n // Socket may already be disconnected.\n }\n }\n}\n"],"mappings":";;;;;;;;;AA6EA,MAAM,gCAAgC;AACtC,MAAM,sBAAsB;AAC5B,MAAM,qBAAqB;AAC3B,MAAM,gCAAgC;AACtC,MAAM,8BAA8B;AACpC,MAAM,8BAA8B;AACpC,MAAM,+BAA+B;AAErC,IAAa,0BAAb,cAA6C,YAAY;CAIvD,YAAY,SAAyC;AACnD,SAAO;iCAHS,IAAI,KAA0B;AAK9C,OAAK,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8BjB,AAAQ,aAAa,YAAY,KAAK,QAAQ,WAAmB;EAC/D,MAAM,SAAS,IAAI,OAAO,KAAK,QAAQ,KAAK;GAC1C,GAAI,YAAY,EAAE,WAAW,GAAG,EAAE;GAClC,kBAAkB,0BAChB,KACA,KAAK,QAAQ,kBAAkB,IAChC;GACD,eAAe,0BACb,KACA,KAAK,QAAQ,eAAe,IAC7B;GACD,qBAAqB,KAAK,QAAQ,uBAAuB;GAC1D,CAAC;AACF,SAAO,SAAS;AAChB,SAAO;;CAGT,AAAQ,yBACN,OACA,SACA,OACyB;EAKzB,MAAM,UAAU,EACd,GALqB,KAAK,oBAC1B,KAAK,2BAA2B,OAAO,QAAQ,EAC/C,MACD,EAGA;AAED,UAAQ,WAAW,QAAQ;AAC3B,UAAQ,QAAQ,QAAQ,MAAM;AAC9B,UAAQ,YAAY,QAAQ;AAC5B,UAAQ,SAAS,QAAQ,MAAM;AAE/B,SAAO;;CAGT,AAAQ,2BACN,OACA,SACW;EACX,MAAM,cAAc;AACpB,cAAY,WAAW,QAAQ;AAC/B,cAAY,QAAQ,QAAQ,MAAM;AAClC,SAAO;;;CAIT,AAAQ,0BAA0B,OAA6B;EAC7D,MAAM,SAAS;EACf,MAAM,WAAW,EAAE,GAAG,OAAO,UAAU;AACvC,SAAO,SAAS;AAChB,SAAO,SAAS;AAChB,SAAO;GAAE,GAAG;GAAQ;GAAU;;CAGhC,AAAQ,oBAAoB,OAAkB,OAA+B;EAC3E,MAAM,cAAc;EAIpB,MAAM,mBAAmB,YAAY,YAAY,EAAE;EACnD,MAAM,aAAa,OAAO,iBAAiB,kBAAkB;EAC7D,MAAM,cAAc,OAAO,iBAAiB,mBAAmB;AAE/D,MAAI,cAAc,aAAa;GAC7B,MAAM,WAAW,iBAAiB;AAClC,SAAM,eAAe,KAAK,IAAI,MAAM,cAAc,WAAW,EAAE;AAC/D,UAAO;;EAGT,MAAM,WAAW,MAAM;AAEvB,cAAY,WAAW;GACrB,GAAG;GACH,eACE,OAAO,iBAAiB,kBAAkB,WACtC,iBAAiB,gBACjBA,cAAY;GAClB,gBAAgB;GACjB;AACD,SAAO;;CAGT,IAAI,SAAuD;AACzD,SAAO,KAAK,oBAAoB,QAAQ;;CAG1C,uBACE,SACuB;EACvB,IAAI;EACJ,IAAI;EACJ,MAAM,UAAU,IAAI,SAAe,SAAS,WAAW;AACrD,oBAAiB;AACjB,mBAAgB;IAChB;AAEF,SAAO;GACL,QAAQ,KAAK,oBAAoB,SAAS;IACxC,sBAAsB,kBAAkB;IACxC,gBAAgB,UAAU,gBAAgB,MAAM;IACjD,CAAC;GACF;GACD;;CAGH,AAAQ,oBACN,SACA,iBAIuB;EACvB,MAAM,EAAE,UAAU,OAAO,UAAU;AAGnC,MADiB,KAAK,QAAQ,IAAI,SAAS,EAC7B,UACZ,OAAM,IAAI,MAAM,yBAAyB;AAG3C,SAAO,IAAI,YAAY,aAAa;AAClC,OAAI,KAAK,QAAQ,IAAI,SAAS,EAAE,WAAW;AACzC,aAAS,sBAAM,IAAI,MAAM,yBAAyB,CAAC;AACnD;;GAGF,MAAM,SAAS,KAAK,aAAa,QAAQ,UAAU;GAEnD,MAAM,UAAU,OAAO,QAAQ,aAAa,MAAM,SAAS;IACzD,WAAW;IACX,QAAQ,MAAM;IACf,CAAC;GAEF,IAAI;GACJ,MAAM,eAAe,IAAI,SAAe,YAAY;AAClD,gBAAY;KACZ;GACF,IAAI;GACJ,MAAM,aAAa,IAAI,SAAkB,YAAY;AACnD,wBAAoB;KACpB;GACF,MAAM,QAAqB;IACzB;IACA,OAAO,MAAM;IACb;IACA;IACA,WAAW;IACX,eAAe;IACf;IACA,eAAe,EAAE;IACjB,cAAc;IACd,eAAe;IACf,WAAW;IACX,0BAA0B;IAC1B,kBAAkB;IAClB;IACA;IACA;IACA;IACA,WAAW;IACX,+BAAe,IAAI,KAAK;IACxB,kBAAkB;IAClB,sBAAsB;IACtB,iBAAiB;IACjB,iBAAiB;IACjB,oBAAoB;IACpB,yBAAyB;IACzB,mBAAmB;IACnB,mBAAmB,SAAS,UAAU;IACtC,UAAU,UAAU;AAClB,sBAAiB,cAAc,MAAM;AACrC,cAAS,MAAM,MAAM;;IAExB;AACD,QAAK,QAAQ,IAAI,UAAU,MAAM;GAEjC,IAAI,0BAA0B;GAC9B,IAAI,iBAAiB;AAErB,UAAO,SAAS,UAAU;AACxB,QAAI,CAAC,KAAK,qBAAqB,UAAU,MAAM,CAC7C;AAEF,qBAAiB,kBAAkB,OAAO,SAAS;AACnD,QAAI,OAAO,SAAS,OAAQ,MAAM,4BAA4B,KAC5D,OAAM,0BAA0B,iBAAiB;AAC/C,WAAM,0BAA0B;AAChC,SAAI,CAAC,MAAM,aAAa,OAAO,aAAa,CAC1C;AAEF,YAAO,iBAAiB;AACtB,UAAI,MAAM,aAAa,CAAC,OAAO,aAAa,CAC1C,QAAO,SAAS;OAElB;OACD,IAAM;KAEX;AACF,UAAO,aAAa;AAClB,QAAI,CAAC,KAAK,qBAAqB,UAAU,MAAM,CAC7C;AAEF,QAAI,MAAM,4BAA4B,MAAM;AAC1C,kBAAa,MAAM,wBAAwB;AAC3C,WAAM,0BAA0B;;AAElC,8BAA0B;AAC1B,qBAAiB;KACjB;AACF,UAAO,cAAc;AACnB,QAAI,CAAC,KAAK,qBAAqB,UAAU,MAAM,CAC7C;AAMF,QAAI,kBAAkB,MAAM,UAC1B;AAGF,+BAA2B;AAC3B,QAAI,2BAA2B,8BAC7B,OAAM,OAAO,UAAU;KAEzB;AAOF,WAAQ,GAAG,sBAAsB,YAAuB;AACtD,QACE,KAAK,qBAAqB,UAAU,MAAM,IAC1C,QAAQ,SAAS,UAAU,UAC1B,QAA0C,SAAS,OAEpD,MAAK,KAAK;KAAE;KAAU,OAAO,MAAM;KAAO,CAAC,CAAC,OAAO,UAAU;AAC3D,YAAO,MACL;MAAE,KAAK;MAAO;MAAU,OAAO,MAAM;MAAO,EAC5C,kCACD;MACD;KAEJ;AAEF,WACG,MAAM,CACN,QAAQ,OAAO,aAAa;AAC3B,QAAI,CAAC,KAAK,qBAAqB,UAAU,MAAM,CAC7C;IAEF,MAAM,2BACJ,KAAK,yBAAyB,SAAS;IACzC,MAAM,mBACJ,MAAM,6BAA6B,2BAC/B,MAAM,mBACN;AACN,UAAM,2BAA2B;AACjC,QAAI,MAAM,WAAW;AACnB,UAAK,uBAAuB,MAAM;AAClC,SAAI,qBAAqB,MAAM;AAC7B,YAAM,mBAAmB;AACzB,WAAK,sBAAsB,MAAM;WAEjC,MAAK,oBAAoB,MAAM;AAEjC;;AAGF,UAAM,YAAY;AAClB,qBAAiB,gBAAgB;AACjC,IAAK,KAAK,gBAAgB,SAAS,OAAO,WAAW,UAAU;AAC7D,cAAS,KAAK,+BAA+B,MAAM,CAAC;MACpD;KACF,CACD,QAAQ,UAAU,SAAS;AAC1B,QAAI,CAAC,KAAK,qBAAqB,UAAU,MAAM,CAC7C;AAEF,QAAI,MAAM,WAAW;AACnB,SAAI,KAAK,wBAAwB,KAAK,EAAE;MACtC,MAAM,SACJ,OAAQ,KAA8B,WAAW,WAC7C,KAAM,KAA4B,WAClC;AACN,WAAK,WACH,UACA,uBACA,IAAI,MACF,8CAA8C,SAC/C,CACF;;AAEH;;AAEF,QAAI,KAAK,qBAAqB,KAAK,CACjC;IAGF,MAAM,wBAAQ,IAAI,MAChB,2BAA2B,KAAK,UAAU,KAAK,GAChD;IACD,MAAM,aAAa;KACjB,MAAM,UAAU;KAChB,SAAS,MAAM;KACf,MAAM;KACP;AACD,aAAS,KAAK,WAAW;AACzB,UAAM,cAAc,KAAK,WAAW;AACpC,SAAK,aAAa,UAAU,MAAM;AAClC,qBAAiB,cAAc,MAAM;AACrC,aAAS,UAAU;KACnB,CACD,QAAQ,iBAAiB;AACxB,QAAI,CAAC,KAAK,qBAAqB,UAAU,MAAM,CAC7C;AAEF,QAAI,MAAM,UACR;IAGF,MAAM,wBAAQ,IAAI,MAAM,4BAA4B;IACpD,MAAM,aAAa;KACjB,MAAM,UAAU;KAChB,SAAS,MAAM;KACf,MAAM;KACP;AACD,aAAS,KAAK,WAAW;AACzB,UAAM,cAAc,KAAK,WAAW;AACpC,SAAK,aAAa,UAAU,MAAM;AAClC,qBAAiB,cAAc,MAAM;AACrC,aAAS,UAAU;KACnB;AAEJ,gBAAa;AACX,SAAK,aAAa,UAAU,MAAM;;IAEpC;;CAGJ,QAAQ,SAA2D;EACjE,MAAM,EAAE,aAAa;AAErB,SAAO,IAAI,YAAY,aAAa;GAClC,MAAM,SAAS,KAAK,cAAc;GAElC,MAAM,UAAU,OAAO,QAAQ,UAAU,WAAW;AAEpD,WAAQ,GAAG,gBAAgB,YAAuB;AAChD,aAAS,KAAK,QAAQ;AAEtB,QACE,QAAQ,SAAS,UAAU,gBAC3B,QAAQ,SAAS,UAAU,UAE3B,UAAS,UAAU;KAErB;GAEF,MAAM,gBAAgB;AACpB,YAAQ,OAAO;AACf,WAAO,YAAY;;AAGrB,WACG,MAAM,CACN,QAAQ,YAAY,OAAU,CAC9B,QAAQ,UAAU,SAAS;AAC1B,aAAS,sBACP,IAAI,MAAM,2BAA2B,KAAK,UAAU,KAAK,GAAG,CAC7D;AACD,aAAS;KACT,CACD,QAAQ,iBAAiB;AACxB,aAAS,sBAAM,IAAI,MAAM,4BAA4B,CAAC;AACtD,aAAS;KACT;AAEJ,gBAAa;AACX,aAAS;;IAEX;;CAGJ,UAAU,SAAwD;EAChE,MAAM,QAAQ,KAAK,QAAQ,IAAI,QAAQ,SAAS;AAChD,SAAO,QAAQ,QAAQ,OAAO,aAAa,MAAM;;;CAInD,KAAK,SAA+D;EAClE,MAAM,QAAQ,KAAK,QAAQ,IAAI,QAAQ,SAAS;AAChD,MAAI,CAAC,SAAS,CAAC,MAAM,aAAa,MAAM,cACtC,QAAO,QAAQ,QAAQ,MAAM;AAE/B,MAAI,QAAQ,UAAU,UAAa,MAAM,UAAU,QAAQ,MACzD,QAAO,QAAQ,QAAQ,MAAM;AAG/B,QAAM,gBAAgB;AAItB,QAAM,WAAW;AACjB,QAAM,YAAY,iBAAiB;AACjC,QAAK,WACH,MAAM,UACN,uBACA,IAAI,MAAM,sCAAsC,CACjD;KACA,6BAA6B;AAGhC,MAAI,MAAM,OAAO;AACf,OAAI;AACF,UAAM,MAAM,UAAU;WAChB;AAKR,OAAI,OAAO,MAAM,MAAM,oBAAoB,WACzC,KAAI;AACF,YAAQ,QAAQ,MAAM,MAAM,iBAAiB,CAAC,CAAC,OAAO,UAAU;AAC9D,YAAO,KACL;MAAE,KAAK;MAAO,UAAU,MAAM;MAAU,OAAO,MAAM;MAAO,EAC5D,iCACD;MACD;YACK,OAAO;AACd,WAAO,KACL;KAAE,KAAK;KAAO,UAAU,MAAM;KAAU,OAAO,MAAM;KAAO,EAC5D,iCACD;;;AAKP,SAAO,MAAM,WAAW,MAAM,cAAc;AAC1C,OAAI,CAAC,UACH,OAAM,IAAI,MACR,oEACD;AAEH,UAAO;IACP;;CAGJ,MAAc,gBACZ,SACA,OACA,UACA,YACe;EACf,MAAM,EAAE,kBAAkB;EAC1B,MAAM,sBAAsB,UAA2B;AACrD,OAAI,CAAC,KAAK,qBAAqB,UAAU,MAAM,CAC7C;GAEF,MAAM,iBAAiB,KAAK,oBAC1B,KAAK,2BACH,KAAK,0BAA0B,MAAM,EACrC,QACD,EACD,MACD;AACD,iBAAc,KAAK,eAAe;AAElC,OAAI,eAAe,SAAS,UAAU,YACpC,OAAM,gBAAgB;AAGxB,QAAK,iBACH,KAAK,yBAAyB,gBAAgB,SAAS,MAAM,EAC7D,MACD;AAGD,OAAI,eAAe,SAAS,UAAU,UACpC,YAAW,eAAe;;EAI9B,MAAM,kCACJ,QAAQ,0BAA0B,QAAQ,MAAM;EAElD,MAAM,wBACJ,WACoB;GACpB,MAAM,YAAY,QAAQ,SAAS,QAAQ;GAC3C,MAAM,yBAAyB,2BAA2B;GAC1D,MAAM,QACJ,UACC;IACC,MAAM,UAAU;IAChB,UAAU,QAAQ;IAClB,OAAO,QAAQ,MAAM;IACtB;AACH,SAAM,WAAW,QAAQ;AACzB,SAAM,QAAQ,QAAQ,MAAM;AAC5B,SAAM,QAAQ;IACZ,GAAG;IACH,UAAU,QAAQ;IAClB,OAAO,QAAQ,MAAM;IACrB,GAAI,2BAA2B,SAC3B,EAAE,UAAU,wBAAwB,GACpC,EAAE;IACP;AACD,UAAO;;EAGT,MAAM,yBAA+B;AACnC,OAAI,CAAC,MAAM,eAAe;AACxB,UAAM,gBAAgB;AACtB,uBAAmB,sBAAsB,CAAC;;;AAI9C,MAAI;AACF,OAAI,MAAM,cAAe;GACzB,MAAM,kBAAkB,QAAQ,mBAAmB,QAAQ;AAC3D,WAAQ,MAAM,WAAW;AACzB,SAAM,QAAQ,KAAK,CACjB,QAAQ,MAAM,SAAS,QAAQ,OAAO,EACpC,UAAU,EAAE,YAAkC;AAC5C,QAAI,MAAM,iBAAiB,MAAM,iBAAkB;AACnD,QAAI,MAAM,SAAS,UAAU,aAAa;AACxC,wBACE,qBAAqB,MAAyB,CAC/C;AACD;;AAGF,sBAAkB;AAClB,uBAAmB,MAAM;MAE5B,CAAC,EACF,MAAM,aACP,CAAC;WACK,OAAO;AACd,OAAI,MAAM,iBAAiB,CAAC,KAAK,qBAAqB,UAAU,MAAM,CACpE;AAEF,qBAAkB;AAIlB,OAAI,CAHkB,cAAc,MACjC,UAAU,MAAM,SAAS,UAAU,UACrC,CAMC,oBAJmB;IACjB,MAAM,UAAU;IAChB,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;IAChE,CAC6B;YAExB;AACR,OAAI,CAAC,KAAK,qBAAqB,UAAU,MAAM,CAC7C;AAEF,qBAAkB;GAClB,MAAM,WAAW,kBAAkB,eAAe;IAChD,eAAe,MAAM;IACrB,iBAAiB,QAAQ,MAAM;IAChC,CAAC;AACF,QAAK,MAAM,SAAS,SAClB,oBAAmB,MAAM;AAE3B,SAAM,mBAAmB;AACzB,QAAK,oBAAoB,UAAU,MAAM;;;;CAK7C,AAAQ,iBACN,SACA,OACM;AACN,MAAI,CAAC,KAAK,qBAAqB,MAAM,UAAU,MAAM,CACnD;EAEF,MAAM,UAAU,KAAK,cAAc,QAAQ;AAC3C,MAAI,CAAC,MAAM,cAAc,IAAI,QAAQ,CACnC,OAAM,cAAc,IAAI,SAAS;GAC/B,SAAS,gBAAgB,QAAQ;GACjC,UAAU,KAAK,KAAK;GACrB,CAAC;AAEJ,OAAK,sBAAsB,MAAM;AACjC,OAAK,oBAAoB,MAAM;;CAGjC,AAAQ,sBACN,UACA,QACA,OACM;AACN,MACE,CAAC,KAAK,qBAAqB,MAAM,UAAU,MAAM,IACjD,KAAK,4BAA4B,MAAM,IACvC,MAAM,QAAQ,UAAU,YACxB,CAAC,MAAM,OAAO,aAAa,CAE3B;EAGF,MAAM,UAAU,EAAE,MAAM;AACxB,QAAM,mBAAmB;GAAE;GAAU;GAAS;EAC9C,MAAM,WAAW,OAAO,KAAK,UAAU,MAAM,QAAQ;EACrD,MAAM,UAAU,MAAM;AAEtB,QAAM,QACH,KACC,UAAU,WAAW,SACrB,UAAU,EAAE,QAAQ,UAAU,GAAG,SAAS,GAC3C,CACA,QAAQ,YAAY;AACnB,OACE,CAAC,KAAK,qBAAqB,MAAM,UAAU,MAAM,IACjD,MAAM,kBAAkB,YAAY,QAEpC;AAEF,OAAI,KAAK,4BAA4B,MAAM,CACzC;AAEF,QAAK,MAAM,WAAW,SACpB,OAAM,cAAc,OAAO,QAAQ;AAErC,SAAM,mBAAmB;AACzB,SAAM,oBAAoB;AAC1B,OAAI,MAAM,cAAc,SAAS,GAAG;AAClC,SAAK,uBAAuB,MAAM;AAClC,SAAK,uBAAuB,MAAM;;AAEpC,QAAK,sBAAsB,MAAM;AACjC,QAAK,oBAAoB,MAAM,UAAU,MAAM;AAC/C,QAAK,oBAAoB,MAAM;IAC/B,CACD,QAAQ,UAAU,aACjB,KAAK,0BAA0B,OAAO,SAAS,SAAS,CACzD,CACA,QAAQ,iBAAiB,KAAK,0BAA0B,OAAO,QAAQ,CAAC;;CAG7E,AAAQ,0BACN,OACA,SACA,UACM;AACN,MACE,CAAC,KAAK,qBAAqB,MAAM,UAAU,MAAM,IACjD,MAAM,kBAAkB,YAAY,QAEpC;AAGF,MAAI,KAAK,4BAA4B,MAAM,CACzC;AAEF,MAAI,KAAK,wBAAwB,SAAS,EAAE;GAC1C,MAAM,SACJ,OAAO,aAAa,YACpB,aAAa,QACb,OAAQ,SAAkC,WAAW,WAChD,SAAgC,SACjC;AACN,QAAK,WACH,MAAM,UACN,uBACA,IAAI,MAAM,mCAAmC,SAAS,CACvD;AACD;;AAEF,OAAK,0BAA0B,MAAM;;CAGvC,AAAQ,0BAA0B,OAA0B;AAC1D,MACE,CAAC,KAAK,qBAAqB,MAAM,UAAU,MAAM,IACjD,MAAM,cAAc,SAAS,KAC7B,MAAM,oBAAoB,KAE1B;EAGF,MAAM,QAAQ,KAAK,IACjB,sBAAsB,KAAK,MAAM,mBACjC,mBACD;AACD,QAAM,qBAAqB;AAC3B,QAAM,kBAAkB,iBAAiB;AACvC,SAAM,kBAAkB;AACxB,OACE,CAAC,KAAK,qBAAqB,MAAM,UAAU,MAAM,IACjD,MAAM,cAAc,SAAS,EAE7B;AAEF,QAAK,sBAAsB,MAAM;KAChC,MAAM;;CAGX,AAAQ,uBAAuB,OAA0B;AACvD,MAAI,MAAM,oBAAoB,MAAM;AAClC,gBAAa,MAAM,gBAAgB;AACnC,SAAM,kBAAkB;;;CAI5B,AAAQ,0BAA0B,OAA0B;AAC1D,MACE,CAAC,KAAK,qBAAqB,MAAM,UAAU,MAAM,IACjD,MAAM,cAAc,SAAS,KAC7B,MAAM,qBAAqB,QAC3B,MAAM,oBAAoB,KAE1B;EAGF,MAAM,iBAAiB,KAAK,IAC1B,GAAG,CAAC,GAAG,MAAM,cAAc,QAAQ,CAAC,CAAC,KAAK,UAAU,MAAM,SAAS,CACpE;EACD,MAAM,QAAQ,KAAK,IACjB,GACA,iBAAiB,8BAA8B,KAAK,KAAK,CAC1D;AACD,QAAM,kBAAkB,iBAAiB;AACvC,SAAM,kBAAkB;AACxB,OAAI,CAAC,KAAK,qBAAqB,MAAM,UAAU,MAAM,CACnD;AAEF,QAAK,uBAAuB,MAAM;KACjC,MAAM;;CAGX,AAAQ,uBAAuB,OAA0B;AACvD,MAAI,MAAM,oBAAoB,MAAM;AAClC,gBAAa,MAAM,gBAAgB;AACnC,SAAM,kBAAkB;;;CAI5B,AAAQ,uBAAuB,OAA0B;AACvD,OAAK,uBAAuB,MAAM;AAClC,OAAK,uBAAuB,MAAM;AAClC,QAAM,oBAAoB;AAC1B,QAAM,mBAAmB;;CAG3B,AAAQ,oBAAoB,OAA0B;AACpD,MACE,CAAC,KAAK,qBAAqB,MAAM,UAAU,MAAM,IACjD,MAAM,qBAAqB,KAE3B;EAGF,MAAM,gBAAgB,CAAC,GAAG,MAAM,cAAc,SAAS,CAAC,CAAC,MACtD,GAAG,OAAO,GAAG,WACZ,KAAK,eAAe,KAAK,QAAQ,GAAG,KAAK,eAAe,MAAM,QAAQ,CACzE;AACD,MAAI,cAAc,WAAW,EAC3B;EAGF,MAAM,YAAY,MAAM,2BACpB,8BACA;AACJ,MAAI,CAAC,MAAM,4BAA4B,cAAc,UAAU,WAAW;AACxE,QAAK,uBAAuB,MAAM;GAClC,MAAM,QAAQ,cAAc,MAAM,GAAG,UAAU;AAC/C,QAAK,sBACH,MAAM,KAAK,CAAC,aAAa,QAAQ,EACjC,MAAM,KAAK,GAAG,WAAW,MAAM,EAC/B,MACD;AACD;;AAGF,OAAK,0BAA0B,MAAM;;CAGvC,AAAQ,uBAAuB,OAA0B;AACvD,MACE,CAAC,KAAK,qBAAqB,MAAM,UAAU,MAAM,IACjD,MAAM,qBAAqB,QAC3B,MAAM,cAAc,SAAS,EAE7B;EAGF,MAAM,QAAQ,CAAC,GAAG,MAAM,cAAc,SAAS,CAAC,CAC7C,MACE,GAAG,OAAO,GAAG,WACZ,KAAK,eAAe,KAAK,QAAQ,GACjC,KAAK,eAAe,MAAM,QAAQ,CACrC,CACA,MAAM,GAAG,4BAA4B;AACxC,OAAK,sBACH,MAAM,KAAK,CAAC,aAAa,QAAQ,EACjC,MAAM,KAAK,GAAG,WAAW,MAAM,EAC/B,MACD;;CAGH,AAAQ,sBAAsB,OAA0B;AACtD,MACE,CAAC,KAAK,qBAAqB,MAAM,UAAU,MAAM,IACjD,KAAK,4BAA4B,MAAM,CAEvC;EAEF,MAAM,cAAc,MAAM;AAC1B,MAAI,gBAAgB,MAAM;AACxB,QAAK,oBAAoB,MAAM;AAC/B;;EAGF,MAAM,SAAS,YAAY,SACxB,KAAK,YAAY,MAAM,cAAc,IAAI,QAAQ,CAAC,CAClD,QAEG,UAEA,UAAU,OACb;AACH,MAAI,OAAO,WAAW,YAAY,SAAS,QAAQ;AACjD,SAAM,mBAAmB;AACzB,QAAK,oBAAoB,MAAM;AAC/B;;AAGF,OAAK,sBAAsB,YAAY,UAAU,QAAQ,MAAM;;CAGjE,AAAQ,oBAAoB,UAAkB,OAA0B;AACtE,MACE,CAAC,KAAK,qBAAqB,UAAU,MAAM,IAC3C,CAAC,MAAM,oBACP,MAAM,cAAc,SAAS,EAE7B;AAEF,MAAI,KAAK,QAAQ,IAAI,SAAS,KAAK,MACjC;AAGF,OAAK,aAAa,UAAU,OAAO,KAAK;AACxC,QAAM,aAAa;;CAGrB,AAAQ,cAAc,SAA0C;AAE9D,SADiB,QAAQ,SACT;;CAGlB,AAAQ,eAAe,SAA0C;AAE/D,SADiB,QAAQ,SACT;;CAGlB,AAAQ,yBAAyB,UAA4B;AAC3D,MAAI,OAAO,aAAa,YAAY,aAAa,KAC/C,QAAO;EAET,MAAM,eAAgB,SAAwC;AAC9D,SACE,MAAM,QAAQ,aAAa,IAC3B,aAAa,SAAS,8BAA8B;;CAIxD,AAAQ,qBAAqB,UAA4B;AACvD,MAAI,OAAO,aAAa,YAAY,aAAa,KAC/C,QAAO;EAET,MAAM,QAAQ;AACd,MAAI,MAAM,cAAc,MACtB,QAAO;AAET,SAAO,MAAM,cAAc,QAAQ,MAAM,WAAW;;CAGtD,AAAQ,wBAAwB,UAA4B;AAC1D,SACE,OAAO,aAAa,YACpB,aAAa,QACZ,SAAqC,cAAc;;CAIxD,AAAQ,sBAAsB,OAA0B;AACtD,MAAI,MAAM,uBAAuB,MAAM;AACrC,gBAAa,MAAM,mBAAmB;AACtC,SAAM,qBAAqB;;AAE7B,MACE,CAAC,KAAK,qBAAqB,MAAM,UAAU,MAAM,IACjD,MAAM,cAAc,SAAS,EAE7B;EAMF,MAAM,WAHiB,KAAK,IAC1B,GAAG,CAAC,GAAG,MAAM,cAAc,QAAQ,CAAC,CAAC,KAAK,UAAU,MAAM,SAAS,CACpE,GACiC;AAClC,QAAM,qBAAqB,iBACnB;AACJ,SAAM,qBAAqB;AAC3B,OAAI,CAAC,KAAK,qBAAqB,MAAM,UAAU,MAAM,CACnD;AAGF,OAAI,CAAC,KAAK,4BAA4B,MAAM,CAC1C,MAAK,sBAAsB,MAAM;KAGrC,KAAK,IAAI,GAAG,WAAW,KAAK,KAAK,CAAC,CACnC;;CAGH,AAAQ,WAAW,UAAkB,OAAoB,OAAoB;AAC3E,MAAI,CAAC,KAAK,qBAAqB,UAAU,MAAM,CAC7C;AAEF,OAAK,aAAa,UAAU,MAAM;AAClC,MAAI;AACF,SAAM,OAAO,UAAU;UACjB;AAGR,QAAM,QAAQ,MAAM;;CAGtB,AAAQ,4BAA4B,OAA6B;AAC/D,MAAI,MAAM,cAAc,SAAS,EAC/B,QAAO;EAET,MAAM,iBAAiB,KAAK,IAC1B,GAAG,CAAC,GAAG,MAAM,cAAc,QAAQ,CAAC,CAAC,KAAK,UAAU,MAAM,SAAS,CACpE;AACD,MAAI,KAAK,KAAK,GAAG,iBAAiB,6BAChC,QAAO;AAET,OAAK,WACH,MAAM,UACN,uBACA,IAAI,MAAM,oDAAoD,CAC/D;AACD,SAAO;;CAGT,AAAQ,qBAAqB,UAAkB,OAA6B;AAC1E,SAAO,MAAM,aAAa,KAAK,QAAQ,IAAI,SAAS,KAAK;;;;;;;;;CAU3D,AAAQ,aACN,UACA,OACA,YAAY,OACN;AACN,MAAI,KAAK,QAAQ,IAAI,SAAS,KAAK,MACjC;AAIF,OAAK,QAAQ,OAAO,SAAS;AAC7B,QAAM,YAAY;AAClB,QAAM,kBAAkB,UAAU;AAClC,MAAI,MAAM,cAAc,MAAM;AAC5B,gBAAa,MAAM,UAAU;AAC7B,SAAM,YAAY;;AAEpB,OAAK,uBAAuB,MAAM;AAClC,OAAK,uBAAuB,MAAM;AAClC,MAAI,MAAM,uBAAuB,MAAM;AACrC,gBAAa,MAAM,mBAAmB;AACtC,SAAM,qBAAqB;;AAE7B,QAAM,mBAAmB;AACzB,MAAI,MAAM,4BAA4B,MAAM;AAC1C,gBAAa,MAAM,wBAAwB;AAC3C,SAAM,0BAA0B;;AAGlC,MAAI;AACF,SAAM,QAAQ,OAAO;UACf;AAGR,MAAI;AACF,SAAM,OAAO,YAAY;UACnB"}
@@ -1,10 +1,9 @@
1
1
  require("reflect-metadata");
2
2
  const require_runtime = require('../../../_virtual/_rolldown/runtime.cjs');
3
- const require_package$1 = require('../../../package.cjs');
3
+ const require_package_info = require('../core/package-info.cjs');
4
4
  let _copilotkit_shared = require("@copilotkit/shared");
5
5
 
6
6
  //#region src/v2/runtime/telemetry/telemetry-client.ts
7
- var import_package = /* @__PURE__ */ require_runtime.__toESM(require_package$1.default);
8
7
  function isTelemetryDisabled() {
9
8
  return process.env.COPILOTKIT_TELEMETRY_DISABLED === "true" || process.env.COPILOTKIT_TELEMETRY_DISABLED === "1" || process.env.DO_NOT_TRACK === "true" || process.env.DO_NOT_TRACK === "1";
10
9
  }
@@ -75,8 +74,8 @@ var TelemetryClient = class {
75
74
  telemetry_surface: _copilotkit_shared.TELEMETRY_SURFACE_V2,
76
75
  telemetry_transport: "lambda"
77
76
  },
78
- packageName: import_package.name,
79
- packageVersion: import_package.version,
77
+ packageName: require_package_info.RUNTIME_PACKAGE_NAME,
78
+ packageVersion: require_package_info.RUNTIME_PACKAGE_VERSION,
80
79
  telemetryId: identity.telemetryId ?? void 0,
81
80
  licenseToken: identity.licenseToken ?? void 0
82
81
  });
@@ -1 +1 @@
1
- {"version":3,"file":"telemetry-client.cjs","names":["lambdaClient","TELEMETRY_EMITTER_V2","TELEMETRY_SURFACE_V2","packageJson"],"sources":["../../../../src/v2/runtime/telemetry/telemetry-client.ts"],"sourcesContent":["import type { AnalyticsEvents } from \"./events\";\nimport {\n lambdaClient,\n parseAndWarnTelemetryId,\n computeSamplingMeta,\n TELEMETRY_EMITTER_V2,\n TELEMETRY_SURFACE_V2,\n} from \"@copilotkit/shared\";\nimport * as packageJson from \"../../../../package.json\";\nimport { firstNonBlankTelemetryId } from \"./telemetry-identity\";\n\n/** Transport identity and sampling authority resolved for one runtime. */\nexport interface TelemetryIdentity {\n telemetryId?: string;\n licenseToken?: string;\n}\n\n/** Capture-only telemetry client bound to one runtime identity. */\nexport interface TelemetryCapture {\n capture<K extends keyof AnalyticsEvents>(\n event: K,\n properties: AnalyticsEvents[K],\n ): Promise<void>;\n}\n\ninterface ResolvedTelemetryIdentity {\n telemetryId: string | null;\n licenseToken: string | null;\n licenseTelemetryId: string | null;\n}\n\nexport function isTelemetryDisabled(): boolean {\n return (\n (process.env as Record<string, string | undefined>)\n .COPILOTKIT_TELEMETRY_DISABLED === \"true\" ||\n (process.env as Record<string, string | undefined>)\n .COPILOTKIT_TELEMETRY_DISABLED === \"1\" ||\n (process.env as Record<string, string | undefined>).DO_NOT_TRACK ===\n \"true\" ||\n (process.env as Record<string, string | undefined>).DO_NOT_TRACK === \"1\"\n );\n}\n\nexport class TelemetryClient {\n private telemetryDisabled: boolean = false;\n // Opt-down for anonymous events, defaulting to 1: the sink is ours, so a\n // real count beats one extrapolated from a fraction of the population.\n // It stays configurable because it is the cross-SDK lever for reducing or\n // stopping anonymous volume — the Go, Python, Ruby, and .NET runtimes all\n // expose it, and the cross-language conformance suite drives it to 0 to\n // assert silence. Identified callers bypass it.\n private sampleRate: number = 1;\n // EIP / Intelligence license token (Ed25519-signed JWT). Kept separate\n // from standalone identity so the transport receives only the selected\n // identity source.\n private licenseToken: string | null = null;\n // Standalone identity sent as a transport claim. It does not make an\n // event identified.\n private telemetryId: string | null = null;\n // License-derived identity. This client sends every event either way;\n // the id is what sets telemetry_identified on the sampling block, which\n // is how the two populations stay separable downstream.\n private licenseTelemetryId: string | null = null;\n // Properties merged into every event this client sends.\n //\n // For facts about the caller that are true for the whole process rather than\n // for one event: which product is embedding the runtime, for instance. A\n // distribution built on top of this can then be told apart in the existing\n // events instead of sending its own, which is the difference between one\n // extra field and a second pipeline nobody asked for.\n //\n // Sent as `global_properties`, a field of its own, so these stay separable\n // from an event's own properties all the way to the sink.\n //\n // Do not reuse a key an event already sets: the fanout spreads this bag last\n // for `oss.runtime.*`, so a collision resolves in favour of the global and\n // does so silently. Names here should describe the caller, not the call.\n private globalProperties: Record<string, unknown> = {};\n\n constructor({\n telemetryDisabled,\n sampleRate,\n }: {\n telemetryDisabled?: boolean;\n sampleRate?: number;\n } = {}) {\n this.telemetryDisabled = telemetryDisabled || isTelemetryDisabled();\n this.setSampleRate(sampleRate);\n }\n\n private shouldSendEvent() {\n if (this.sampleRate >= 1) return true;\n return Math.random() < this.sampleRate;\n }\n\n /**\n * Add properties carried by every subsequent event.\n *\n * Merged rather than replaced, so two callers setting different fields do not\n * erase each other. Set once at runtime construction in practice; nothing\n * here is per-request.\n */\n setGlobalProperties(properties: Record<string, unknown>) {\n this.globalProperties = { ...this.globalProperties, ...properties };\n }\n\n /** Atomically replace the process-wide telemetry identity. */\n setTelemetryIdentity(identity: TelemetryIdentity): void {\n const resolvedIdentity = this.resolveTelemetryIdentity(identity);\n this.telemetryId = resolvedIdentity.telemetryId;\n this.licenseToken = resolvedIdentity.licenseToken;\n this.licenseTelemetryId = resolvedIdentity.licenseTelemetryId;\n }\n\n /** @deprecated Prefer {@link setTelemetryIdentity}. */\n setLicenseToken(licenseToken: string): void {\n this.setTelemetryIdentity({ licenseToken });\n }\n\n /** Create an immutable capture scope for one Runtime instance. */\n createScope(identity: TelemetryIdentity): TelemetryCapture {\n const resolvedIdentity = this.resolveTelemetryIdentity(identity);\n return {\n capture: <K extends keyof AnalyticsEvents>(\n event: K,\n properties: AnalyticsEvents[K],\n ) => this.captureWithIdentity(event, properties, resolvedIdentity),\n };\n }\n\n async capture<K extends keyof AnalyticsEvents>(\n event: K,\n properties: AnalyticsEvents[K],\n ): Promise<void> {\n return this.captureWithIdentity(event, properties, {\n telemetryId: this.telemetryId,\n licenseToken: this.licenseToken,\n licenseTelemetryId: this.licenseTelemetryId,\n });\n }\n\n private async captureWithIdentity<K extends keyof AnalyticsEvents>(\n event: K,\n properties: AnalyticsEvents[K],\n identity: ResolvedTelemetryIdentity,\n ): Promise<void> {\n if (this.telemetryDisabled) return;\n // Nothing is gated at the default rate of 1. A caller who dialled it\n // down means it, and identified callers are exempt either way.\n if (!identity.licenseTelemetryId && !this.shouldSendEvent()) return;\n\n await lambdaClient.send({\n event,\n properties: properties as Record<string, unknown>,\n // Its own field on the wire rather than folded into `properties`, which\n // is what the sink expects: for `oss.runtime.*` the fanout treats\n // `global_properties` as the SDK's pass-through bag and spreads it into\n // the analytics event, and v1's client sends package name and version the\n // same way. Folding it in would work and would put a process-level fact\n // in the per-event slot, where nothing downstream expects to find one.\n // Sampling metadata rides in the same slot, as it does in v1. It\n // reads 1/1 unless a caller dialled the rate down, and is stamped\n // either way: a consumer summing sampleWeight across emitters must\n // not find the field missing on a quarter of the rows, which is the\n // state that made ~24% of runtime volume unweightable (OSS-1017).\n globalProperties: {\n ...this.globalProperties,\n ...computeSamplingMeta({\n telemetryId: identity.licenseTelemetryId,\n sampleRate: this.sampleRate,\n }),\n telemetry_emitter: TELEMETRY_EMITTER_V2,\n // Constant here: a v1 request never reaches this client. The v1\n // entrypoint hands its own capture scope to the V2 runtime it\n // builds, so v1 traffic is emitted by the v1 client and stamped\n // v1 there — which is also what keeps it on the Segment wire.\n telemetry_surface: TELEMETRY_SURFACE_V2,\n // This client has one transport, so the marker is constant here. It\n // is stamped anyway so the property means the same thing on every\n // event whichever client produced it (OSS-1019).\n telemetry_transport: \"lambda\",\n },\n packageName: packageJson.name,\n packageVersion: packageJson.version,\n telemetryId: identity.telemetryId ?? undefined,\n licenseToken: identity.licenseToken ?? undefined,\n });\n }\n\n private resolveTelemetryIdentity(\n identity: TelemetryIdentity,\n ): ResolvedTelemetryIdentity {\n const telemetryId = firstNonBlankTelemetryId(identity.telemetryId);\n if (telemetryId !== undefined) {\n return {\n telemetryId,\n licenseToken: null,\n licenseTelemetryId: null,\n };\n }\n\n return {\n telemetryId: null,\n licenseToken: identity.licenseToken ?? null,\n licenseTelemetryId: identity.licenseToken\n ? parseAndWarnTelemetryId(identity.licenseToken)\n : null,\n };\n }\n\n private setSampleRate(sampleRate: number | undefined) {\n let _sampleRate: number;\n\n _sampleRate = sampleRate ?? 1;\n\n if (process.env.COPILOTKIT_TELEMETRY_SAMPLE_RATE) {\n _sampleRate = parseFloat(process.env.COPILOTKIT_TELEMETRY_SAMPLE_RATE);\n }\n\n // Number.isNaN guards against parseFloat(\"nonsense\") slipping past the\n // range check (all NaN comparisons are false), which would silently\n // drop every anonymous event with no signal.\n if (Number.isNaN(_sampleRate) || _sampleRate < 0 || _sampleRate > 1) {\n throw new Error(\"Sample rate must be between 0 and 1\");\n }\n\n this.sampleRate = _sampleRate;\n }\n}\n\nconst telemetry = new TelemetryClient();\nexport default telemetry;\n"],"mappings":";;;;;;;AA+BA,SAAgB,sBAA+B;AAC7C,QACG,QAAQ,IACN,kCAAkC,UACpC,QAAQ,IACN,kCAAkC,OACpC,QAAQ,IAA2C,iBAClD,UACD,QAAQ,IAA2C,iBAAiB;;AAIzE,IAAa,kBAAb,MAA6B;CAoC3B,YAAY,EACV,mBACA,eAIE,EAAE,EAAE;2BAzC6B;oBAOR;sBAIS;qBAGD;4BAIO;0BAeQ,EAAE;AASpD,OAAK,oBAAoB,qBAAqB,qBAAqB;AACnE,OAAK,cAAc,WAAW;;CAGhC,AAAQ,kBAAkB;AACxB,MAAI,KAAK,cAAc,EAAG,QAAO;AACjC,SAAO,KAAK,QAAQ,GAAG,KAAK;;;;;;;;;CAU9B,oBAAoB,YAAqC;AACvD,OAAK,mBAAmB;GAAE,GAAG,KAAK;GAAkB,GAAG;GAAY;;;CAIrE,qBAAqB,UAAmC;EACtD,MAAM,mBAAmB,KAAK,yBAAyB,SAAS;AAChE,OAAK,cAAc,iBAAiB;AACpC,OAAK,eAAe,iBAAiB;AACrC,OAAK,qBAAqB,iBAAiB;;;CAI7C,gBAAgB,cAA4B;AAC1C,OAAK,qBAAqB,EAAE,cAAc,CAAC;;;CAI7C,YAAY,UAA+C;EACzD,MAAM,mBAAmB,KAAK,yBAAyB,SAAS;AAChE,SAAO,EACL,UACE,OACA,eACG,KAAK,oBAAoB,OAAO,YAAY,iBAAiB,EACnE;;CAGH,MAAM,QACJ,OACA,YACe;AACf,SAAO,KAAK,oBAAoB,OAAO,YAAY;GACjD,aAAa,KAAK;GAClB,cAAc,KAAK;GACnB,oBAAoB,KAAK;GAC1B,CAAC;;CAGJ,MAAc,oBACZ,OACA,YACA,UACe;AACf,MAAI,KAAK,kBAAmB;AAG5B,MAAI,CAAC,SAAS,sBAAsB,CAAC,KAAK,iBAAiB,CAAE;AAE7D,QAAMA,gCAAa,KAAK;GACtB;GACY;GAYZ,kBAAkB;IAChB,GAAG,KAAK;IACR,+CAAuB;KACrB,aAAa,SAAS;KACtB,YAAY,KAAK;KAClB,CAAC;IACF,mBAAmBC;IAKnB,mBAAmBC;IAInB,qBAAqB;IACtB;GACD,aAAaC,eAAY;GACzB,gBAAgBA,eAAY;GAC5B,aAAa,SAAS,eAAe;GACrC,cAAc,SAAS,gBAAgB;GACxC,CAAC;;CAGJ,AAAQ,yBACN,UAC2B;EAC3B,MAAM,+DAAuC,SAAS,YAAY;AAClE,MAAI,gBAAgB,OAClB,QAAO;GACL;GACA,cAAc;GACd,oBAAoB;GACrB;AAGH,SAAO;GACL,aAAa;GACb,cAAc,SAAS,gBAAgB;GACvC,oBAAoB,SAAS,+DACD,SAAS,aAAa,GAC9C;GACL;;CAGH,AAAQ,cAAc,YAAgC;EACpD,IAAI;AAEJ,gBAAc,cAAc;AAE5B,MAAI,QAAQ,IAAI,iCACd,eAAc,WAAW,QAAQ,IAAI,iCAAiC;AAMxE,MAAI,OAAO,MAAM,YAAY,IAAI,cAAc,KAAK,cAAc,EAChE,OAAM,IAAI,MAAM,sCAAsC;AAGxD,OAAK,aAAa;;;AAItB,MAAM,YAAY,IAAI,iBAAiB"}
1
+ {"version":3,"file":"telemetry-client.cjs","names":["lambdaClient","TELEMETRY_EMITTER_V2","TELEMETRY_SURFACE_V2","RUNTIME_PACKAGE_NAME","RUNTIME_PACKAGE_VERSION"],"sources":["../../../../src/v2/runtime/telemetry/telemetry-client.ts"],"sourcesContent":["import type { AnalyticsEvents } from \"./events\";\nimport {\n lambdaClient,\n parseAndWarnTelemetryId,\n computeSamplingMeta,\n TELEMETRY_EMITTER_V2,\n TELEMETRY_SURFACE_V2,\n} from \"@copilotkit/shared\";\nimport {\n RUNTIME_PACKAGE_NAME,\n RUNTIME_PACKAGE_VERSION,\n} from \"../core/package-info\";\nimport { firstNonBlankTelemetryId } from \"./telemetry-identity\";\n\n/** Transport identity and sampling authority resolved for one runtime. */\nexport interface TelemetryIdentity {\n telemetryId?: string;\n licenseToken?: string;\n}\n\n/** Capture-only telemetry client bound to one runtime identity. */\nexport interface TelemetryCapture {\n capture<K extends keyof AnalyticsEvents>(\n event: K,\n properties: AnalyticsEvents[K],\n ): Promise<void>;\n}\n\ninterface ResolvedTelemetryIdentity {\n telemetryId: string | null;\n licenseToken: string | null;\n licenseTelemetryId: string | null;\n}\n\nexport function isTelemetryDisabled(): boolean {\n return (\n (process.env as Record<string, string | undefined>)\n .COPILOTKIT_TELEMETRY_DISABLED === \"true\" ||\n (process.env as Record<string, string | undefined>)\n .COPILOTKIT_TELEMETRY_DISABLED === \"1\" ||\n (process.env as Record<string, string | undefined>).DO_NOT_TRACK ===\n \"true\" ||\n (process.env as Record<string, string | undefined>).DO_NOT_TRACK === \"1\"\n );\n}\n\nexport class TelemetryClient {\n private telemetryDisabled: boolean = false;\n // Opt-down for anonymous events, defaulting to 1: the sink is ours, so a\n // real count beats one extrapolated from a fraction of the population.\n // It stays configurable because it is the cross-SDK lever for reducing or\n // stopping anonymous volume — the Go, Python, Ruby, and .NET runtimes all\n // expose it, and the cross-language conformance suite drives it to 0 to\n // assert silence. Identified callers bypass it.\n private sampleRate: number = 1;\n // EIP / Intelligence license token (Ed25519-signed JWT). Kept separate\n // from standalone identity so the transport receives only the selected\n // identity source.\n private licenseToken: string | null = null;\n // Standalone identity sent as a transport claim. It does not make an\n // event identified.\n private telemetryId: string | null = null;\n // License-derived identity. This client sends every event either way;\n // the id is what sets telemetry_identified on the sampling block, which\n // is how the two populations stay separable downstream.\n private licenseTelemetryId: string | null = null;\n // Properties merged into every event this client sends.\n //\n // For facts about the caller that are true for the whole process rather than\n // for one event: which product is embedding the runtime, for instance. A\n // distribution built on top of this can then be told apart in the existing\n // events instead of sending its own, which is the difference between one\n // extra field and a second pipeline nobody asked for.\n //\n // Sent as `global_properties`, a field of its own, so these stay separable\n // from an event's own properties all the way to the sink.\n //\n // Do not reuse a key an event already sets: the fanout spreads this bag last\n // for `oss.runtime.*`, so a collision resolves in favour of the global and\n // does so silently. Names here should describe the caller, not the call.\n private globalProperties: Record<string, unknown> = {};\n\n constructor({\n telemetryDisabled,\n sampleRate,\n }: {\n telemetryDisabled?: boolean;\n sampleRate?: number;\n } = {}) {\n this.telemetryDisabled = telemetryDisabled || isTelemetryDisabled();\n this.setSampleRate(sampleRate);\n }\n\n private shouldSendEvent() {\n if (this.sampleRate >= 1) return true;\n return Math.random() < this.sampleRate;\n }\n\n /**\n * Add properties carried by every subsequent event.\n *\n * Merged rather than replaced, so two callers setting different fields do not\n * erase each other. Set once at runtime construction in practice; nothing\n * here is per-request.\n */\n setGlobalProperties(properties: Record<string, unknown>) {\n this.globalProperties = { ...this.globalProperties, ...properties };\n }\n\n /** Atomically replace the process-wide telemetry identity. */\n setTelemetryIdentity(identity: TelemetryIdentity): void {\n const resolvedIdentity = this.resolveTelemetryIdentity(identity);\n this.telemetryId = resolvedIdentity.telemetryId;\n this.licenseToken = resolvedIdentity.licenseToken;\n this.licenseTelemetryId = resolvedIdentity.licenseTelemetryId;\n }\n\n /** @deprecated Prefer {@link setTelemetryIdentity}. */\n setLicenseToken(licenseToken: string): void {\n this.setTelemetryIdentity({ licenseToken });\n }\n\n /** Create an immutable capture scope for one Runtime instance. */\n createScope(identity: TelemetryIdentity): TelemetryCapture {\n const resolvedIdentity = this.resolveTelemetryIdentity(identity);\n return {\n capture: <K extends keyof AnalyticsEvents>(\n event: K,\n properties: AnalyticsEvents[K],\n ) => this.captureWithIdentity(event, properties, resolvedIdentity),\n };\n }\n\n async capture<K extends keyof AnalyticsEvents>(\n event: K,\n properties: AnalyticsEvents[K],\n ): Promise<void> {\n return this.captureWithIdentity(event, properties, {\n telemetryId: this.telemetryId,\n licenseToken: this.licenseToken,\n licenseTelemetryId: this.licenseTelemetryId,\n });\n }\n\n private async captureWithIdentity<K extends keyof AnalyticsEvents>(\n event: K,\n properties: AnalyticsEvents[K],\n identity: ResolvedTelemetryIdentity,\n ): Promise<void> {\n if (this.telemetryDisabled) return;\n // Nothing is gated at the default rate of 1. A caller who dialled it\n // down means it, and identified callers are exempt either way.\n if (!identity.licenseTelemetryId && !this.shouldSendEvent()) return;\n\n await lambdaClient.send({\n event,\n properties: properties as Record<string, unknown>,\n // Its own field on the wire rather than folded into `properties`, which\n // is what the sink expects: for `oss.runtime.*` the fanout treats\n // `global_properties` as the SDK's pass-through bag and spreads it into\n // the analytics event, and v1's client sends package name and version the\n // same way. Folding it in would work and would put a process-level fact\n // in the per-event slot, where nothing downstream expects to find one.\n // Sampling metadata rides in the same slot, as it does in v1. It\n // reads 1/1 unless a caller dialled the rate down, and is stamped\n // either way: a consumer summing sampleWeight across emitters must\n // not find the field missing on a quarter of the rows, which is the\n // state that made ~24% of runtime volume unweightable (OSS-1017).\n globalProperties: {\n ...this.globalProperties,\n ...computeSamplingMeta({\n telemetryId: identity.licenseTelemetryId,\n sampleRate: this.sampleRate,\n }),\n telemetry_emitter: TELEMETRY_EMITTER_V2,\n // Constant here: a v1 request never reaches this client. The v1\n // entrypoint hands its own capture scope to the V2 runtime it\n // builds, so v1 traffic is emitted by the v1 client and stamped\n // v1 there — which is also what keeps it on the Segment wire.\n telemetry_surface: TELEMETRY_SURFACE_V2,\n // This client has one transport, so the marker is constant here. It\n // is stamped anyway so the property means the same thing on every\n // event whichever client produced it (OSS-1019).\n telemetry_transport: \"lambda\",\n },\n packageName: RUNTIME_PACKAGE_NAME,\n packageVersion: RUNTIME_PACKAGE_VERSION,\n telemetryId: identity.telemetryId ?? undefined,\n licenseToken: identity.licenseToken ?? undefined,\n });\n }\n\n private resolveTelemetryIdentity(\n identity: TelemetryIdentity,\n ): ResolvedTelemetryIdentity {\n const telemetryId = firstNonBlankTelemetryId(identity.telemetryId);\n if (telemetryId !== undefined) {\n return {\n telemetryId,\n licenseToken: null,\n licenseTelemetryId: null,\n };\n }\n\n return {\n telemetryId: null,\n licenseToken: identity.licenseToken ?? null,\n licenseTelemetryId: identity.licenseToken\n ? parseAndWarnTelemetryId(identity.licenseToken)\n : null,\n };\n }\n\n private setSampleRate(sampleRate: number | undefined) {\n let _sampleRate: number;\n\n _sampleRate = sampleRate ?? 1;\n\n if (process.env.COPILOTKIT_TELEMETRY_SAMPLE_RATE) {\n _sampleRate = parseFloat(process.env.COPILOTKIT_TELEMETRY_SAMPLE_RATE);\n }\n\n // Number.isNaN guards against parseFloat(\"nonsense\") slipping past the\n // range check (all NaN comparisons are false), which would silently\n // drop every anonymous event with no signal.\n if (Number.isNaN(_sampleRate) || _sampleRate < 0 || _sampleRate > 1) {\n throw new Error(\"Sample rate must be between 0 and 1\");\n }\n\n this.sampleRate = _sampleRate;\n }\n}\n\nconst telemetry = new TelemetryClient();\nexport default telemetry;\n"],"mappings":";;;;;;AAkCA,SAAgB,sBAA+B;AAC7C,QACG,QAAQ,IACN,kCAAkC,UACpC,QAAQ,IACN,kCAAkC,OACpC,QAAQ,IAA2C,iBAClD,UACD,QAAQ,IAA2C,iBAAiB;;AAIzE,IAAa,kBAAb,MAA6B;CAoC3B,YAAY,EACV,mBACA,eAIE,EAAE,EAAE;2BAzC6B;oBAOR;sBAIS;qBAGD;4BAIO;0BAeQ,EAAE;AASpD,OAAK,oBAAoB,qBAAqB,qBAAqB;AACnE,OAAK,cAAc,WAAW;;CAGhC,AAAQ,kBAAkB;AACxB,MAAI,KAAK,cAAc,EAAG,QAAO;AACjC,SAAO,KAAK,QAAQ,GAAG,KAAK;;;;;;;;;CAU9B,oBAAoB,YAAqC;AACvD,OAAK,mBAAmB;GAAE,GAAG,KAAK;GAAkB,GAAG;GAAY;;;CAIrE,qBAAqB,UAAmC;EACtD,MAAM,mBAAmB,KAAK,yBAAyB,SAAS;AAChE,OAAK,cAAc,iBAAiB;AACpC,OAAK,eAAe,iBAAiB;AACrC,OAAK,qBAAqB,iBAAiB;;;CAI7C,gBAAgB,cAA4B;AAC1C,OAAK,qBAAqB,EAAE,cAAc,CAAC;;;CAI7C,YAAY,UAA+C;EACzD,MAAM,mBAAmB,KAAK,yBAAyB,SAAS;AAChE,SAAO,EACL,UACE,OACA,eACG,KAAK,oBAAoB,OAAO,YAAY,iBAAiB,EACnE;;CAGH,MAAM,QACJ,OACA,YACe;AACf,SAAO,KAAK,oBAAoB,OAAO,YAAY;GACjD,aAAa,KAAK;GAClB,cAAc,KAAK;GACnB,oBAAoB,KAAK;GAC1B,CAAC;;CAGJ,MAAc,oBACZ,OACA,YACA,UACe;AACf,MAAI,KAAK,kBAAmB;AAG5B,MAAI,CAAC,SAAS,sBAAsB,CAAC,KAAK,iBAAiB,CAAE;AAE7D,QAAMA,gCAAa,KAAK;GACtB;GACY;GAYZ,kBAAkB;IAChB,GAAG,KAAK;IACR,+CAAuB;KACrB,aAAa,SAAS;KACtB,YAAY,KAAK;KAClB,CAAC;IACF,mBAAmBC;IAKnB,mBAAmBC;IAInB,qBAAqB;IACtB;GACD,aAAaC;GACb,gBAAgBC;GAChB,aAAa,SAAS,eAAe;GACrC,cAAc,SAAS,gBAAgB;GACxC,CAAC;;CAGJ,AAAQ,yBACN,UAC2B;EAC3B,MAAM,+DAAuC,SAAS,YAAY;AAClE,MAAI,gBAAgB,OAClB,QAAO;GACL;GACA,cAAc;GACd,oBAAoB;GACrB;AAGH,SAAO;GACL,aAAa;GACb,cAAc,SAAS,gBAAgB;GACvC,oBAAoB,SAAS,+DACD,SAAS,aAAa,GAC9C;GACL;;CAGH,AAAQ,cAAc,YAAgC;EACpD,IAAI;AAEJ,gBAAc,cAAc;AAE5B,MAAI,QAAQ,IAAI,iCACd,eAAc,WAAW,QAAQ,IAAI,iCAAiC;AAMxE,MAAI,OAAO,MAAM,YAAY,IAAI,cAAc,KAAK,cAAc,EAChE,OAAM,IAAI,MAAM,sCAAsC;AAGxD,OAAK,aAAa;;;AAItB,MAAM,YAAY,IAAI,iBAAiB"}
@@ -1 +1 @@
1
- {"version":3,"file":"telemetry-client.d.cts","names":[],"sources":["../../../../src/v2/runtime/telemetry/telemetry-client.ts"],"mappings":";;;;;UAkBiB,gBAAA;EACf,OAAA,iBAAwB,eAAA,EACtB,KAAA,EAAO,CAAA,EACP,UAAA,EAAY,eAAA,CAAgB,CAAA,IAC3B,OAAA;AAAA"}
1
+ {"version":3,"file":"telemetry-client.d.cts","names":[],"sources":["../../../../src/v2/runtime/telemetry/telemetry-client.ts"],"mappings":";;;;;UAqBiB,gBAAA;EACf,OAAA,iBAAwB,eAAA,EACtB,KAAA,EAAO,CAAA,EACP,UAAA,EAAY,eAAA,CAAgB,CAAA,IAC3B,OAAA;AAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"telemetry-client.d.mts","names":[],"sources":["../../../../src/v2/runtime/telemetry/telemetry-client.ts"],"mappings":";;;;;UAkBiB,gBAAA;EACf,OAAA,iBAAwB,eAAA,EACtB,KAAA,EAAO,CAAA,EACP,UAAA,EAAY,eAAA,CAAgB,CAAA,IAC3B,OAAA;AAAA"}
1
+ {"version":3,"file":"telemetry-client.d.mts","names":[],"sources":["../../../../src/v2/runtime/telemetry/telemetry-client.ts"],"mappings":";;;;;UAqBiB,gBAAA;EACf,OAAA,iBAAwB,eAAA,EACtB,KAAA,EAAO,CAAA,EACP,UAAA,EAAY,eAAA,CAAgB,CAAA,IAC3B,OAAA;AAAA"}
@@ -1,11 +1,9 @@
1
1
  import "reflect-metadata";
2
- import { __toESM } from "../../../_virtual/_rolldown/runtime.mjs";
3
- import { require_package } from "../../../package.mjs";
2
+ import { RUNTIME_PACKAGE_NAME, RUNTIME_PACKAGE_VERSION } from "../core/package-info.mjs";
4
3
  import { firstNonBlankTelemetryId } from "./telemetry-identity.mjs";
5
4
  import { TELEMETRY_EMITTER_V2, TELEMETRY_SURFACE_V2, computeSamplingMeta, lambdaClient, parseAndWarnTelemetryId } from "@copilotkit/shared";
6
5
 
7
6
  //#region src/v2/runtime/telemetry/telemetry-client.ts
8
- var import_package = /* @__PURE__ */ __toESM(require_package());
9
7
  function isTelemetryDisabled() {
10
8
  return process.env.COPILOTKIT_TELEMETRY_DISABLED === "true" || process.env.COPILOTKIT_TELEMETRY_DISABLED === "1" || process.env.DO_NOT_TRACK === "true" || process.env.DO_NOT_TRACK === "1";
11
9
  }
@@ -76,8 +74,8 @@ var TelemetryClient = class {
76
74
  telemetry_surface: TELEMETRY_SURFACE_V2,
77
75
  telemetry_transport: "lambda"
78
76
  },
79
- packageName: import_package.name,
80
- packageVersion: import_package.version,
77
+ packageName: RUNTIME_PACKAGE_NAME,
78
+ packageVersion: RUNTIME_PACKAGE_VERSION,
81
79
  telemetryId: identity.telemetryId ?? void 0,
82
80
  licenseToken: identity.licenseToken ?? void 0
83
81
  });
@@ -1 +1 @@
1
- {"version":3,"file":"telemetry-client.mjs","names":["packageJson"],"sources":["../../../../src/v2/runtime/telemetry/telemetry-client.ts"],"sourcesContent":["import type { AnalyticsEvents } from \"./events\";\nimport {\n lambdaClient,\n parseAndWarnTelemetryId,\n computeSamplingMeta,\n TELEMETRY_EMITTER_V2,\n TELEMETRY_SURFACE_V2,\n} from \"@copilotkit/shared\";\nimport * as packageJson from \"../../../../package.json\";\nimport { firstNonBlankTelemetryId } from \"./telemetry-identity\";\n\n/** Transport identity and sampling authority resolved for one runtime. */\nexport interface TelemetryIdentity {\n telemetryId?: string;\n licenseToken?: string;\n}\n\n/** Capture-only telemetry client bound to one runtime identity. */\nexport interface TelemetryCapture {\n capture<K extends keyof AnalyticsEvents>(\n event: K,\n properties: AnalyticsEvents[K],\n ): Promise<void>;\n}\n\ninterface ResolvedTelemetryIdentity {\n telemetryId: string | null;\n licenseToken: string | null;\n licenseTelemetryId: string | null;\n}\n\nexport function isTelemetryDisabled(): boolean {\n return (\n (process.env as Record<string, string | undefined>)\n .COPILOTKIT_TELEMETRY_DISABLED === \"true\" ||\n (process.env as Record<string, string | undefined>)\n .COPILOTKIT_TELEMETRY_DISABLED === \"1\" ||\n (process.env as Record<string, string | undefined>).DO_NOT_TRACK ===\n \"true\" ||\n (process.env as Record<string, string | undefined>).DO_NOT_TRACK === \"1\"\n );\n}\n\nexport class TelemetryClient {\n private telemetryDisabled: boolean = false;\n // Opt-down for anonymous events, defaulting to 1: the sink is ours, so a\n // real count beats one extrapolated from a fraction of the population.\n // It stays configurable because it is the cross-SDK lever for reducing or\n // stopping anonymous volume — the Go, Python, Ruby, and .NET runtimes all\n // expose it, and the cross-language conformance suite drives it to 0 to\n // assert silence. Identified callers bypass it.\n private sampleRate: number = 1;\n // EIP / Intelligence license token (Ed25519-signed JWT). Kept separate\n // from standalone identity so the transport receives only the selected\n // identity source.\n private licenseToken: string | null = null;\n // Standalone identity sent as a transport claim. It does not make an\n // event identified.\n private telemetryId: string | null = null;\n // License-derived identity. This client sends every event either way;\n // the id is what sets telemetry_identified on the sampling block, which\n // is how the two populations stay separable downstream.\n private licenseTelemetryId: string | null = null;\n // Properties merged into every event this client sends.\n //\n // For facts about the caller that are true for the whole process rather than\n // for one event: which product is embedding the runtime, for instance. A\n // distribution built on top of this can then be told apart in the existing\n // events instead of sending its own, which is the difference between one\n // extra field and a second pipeline nobody asked for.\n //\n // Sent as `global_properties`, a field of its own, so these stay separable\n // from an event's own properties all the way to the sink.\n //\n // Do not reuse a key an event already sets: the fanout spreads this bag last\n // for `oss.runtime.*`, so a collision resolves in favour of the global and\n // does so silently. Names here should describe the caller, not the call.\n private globalProperties: Record<string, unknown> = {};\n\n constructor({\n telemetryDisabled,\n sampleRate,\n }: {\n telemetryDisabled?: boolean;\n sampleRate?: number;\n } = {}) {\n this.telemetryDisabled = telemetryDisabled || isTelemetryDisabled();\n this.setSampleRate(sampleRate);\n }\n\n private shouldSendEvent() {\n if (this.sampleRate >= 1) return true;\n return Math.random() < this.sampleRate;\n }\n\n /**\n * Add properties carried by every subsequent event.\n *\n * Merged rather than replaced, so two callers setting different fields do not\n * erase each other. Set once at runtime construction in practice; nothing\n * here is per-request.\n */\n setGlobalProperties(properties: Record<string, unknown>) {\n this.globalProperties = { ...this.globalProperties, ...properties };\n }\n\n /** Atomically replace the process-wide telemetry identity. */\n setTelemetryIdentity(identity: TelemetryIdentity): void {\n const resolvedIdentity = this.resolveTelemetryIdentity(identity);\n this.telemetryId = resolvedIdentity.telemetryId;\n this.licenseToken = resolvedIdentity.licenseToken;\n this.licenseTelemetryId = resolvedIdentity.licenseTelemetryId;\n }\n\n /** @deprecated Prefer {@link setTelemetryIdentity}. */\n setLicenseToken(licenseToken: string): void {\n this.setTelemetryIdentity({ licenseToken });\n }\n\n /** Create an immutable capture scope for one Runtime instance. */\n createScope(identity: TelemetryIdentity): TelemetryCapture {\n const resolvedIdentity = this.resolveTelemetryIdentity(identity);\n return {\n capture: <K extends keyof AnalyticsEvents>(\n event: K,\n properties: AnalyticsEvents[K],\n ) => this.captureWithIdentity(event, properties, resolvedIdentity),\n };\n }\n\n async capture<K extends keyof AnalyticsEvents>(\n event: K,\n properties: AnalyticsEvents[K],\n ): Promise<void> {\n return this.captureWithIdentity(event, properties, {\n telemetryId: this.telemetryId,\n licenseToken: this.licenseToken,\n licenseTelemetryId: this.licenseTelemetryId,\n });\n }\n\n private async captureWithIdentity<K extends keyof AnalyticsEvents>(\n event: K,\n properties: AnalyticsEvents[K],\n identity: ResolvedTelemetryIdentity,\n ): Promise<void> {\n if (this.telemetryDisabled) return;\n // Nothing is gated at the default rate of 1. A caller who dialled it\n // down means it, and identified callers are exempt either way.\n if (!identity.licenseTelemetryId && !this.shouldSendEvent()) return;\n\n await lambdaClient.send({\n event,\n properties: properties as Record<string, unknown>,\n // Its own field on the wire rather than folded into `properties`, which\n // is what the sink expects: for `oss.runtime.*` the fanout treats\n // `global_properties` as the SDK's pass-through bag and spreads it into\n // the analytics event, and v1's client sends package name and version the\n // same way. Folding it in would work and would put a process-level fact\n // in the per-event slot, where nothing downstream expects to find one.\n // Sampling metadata rides in the same slot, as it does in v1. It\n // reads 1/1 unless a caller dialled the rate down, and is stamped\n // either way: a consumer summing sampleWeight across emitters must\n // not find the field missing on a quarter of the rows, which is the\n // state that made ~24% of runtime volume unweightable (OSS-1017).\n globalProperties: {\n ...this.globalProperties,\n ...computeSamplingMeta({\n telemetryId: identity.licenseTelemetryId,\n sampleRate: this.sampleRate,\n }),\n telemetry_emitter: TELEMETRY_EMITTER_V2,\n // Constant here: a v1 request never reaches this client. The v1\n // entrypoint hands its own capture scope to the V2 runtime it\n // builds, so v1 traffic is emitted by the v1 client and stamped\n // v1 there — which is also what keeps it on the Segment wire.\n telemetry_surface: TELEMETRY_SURFACE_V2,\n // This client has one transport, so the marker is constant here. It\n // is stamped anyway so the property means the same thing on every\n // event whichever client produced it (OSS-1019).\n telemetry_transport: \"lambda\",\n },\n packageName: packageJson.name,\n packageVersion: packageJson.version,\n telemetryId: identity.telemetryId ?? undefined,\n licenseToken: identity.licenseToken ?? undefined,\n });\n }\n\n private resolveTelemetryIdentity(\n identity: TelemetryIdentity,\n ): ResolvedTelemetryIdentity {\n const telemetryId = firstNonBlankTelemetryId(identity.telemetryId);\n if (telemetryId !== undefined) {\n return {\n telemetryId,\n licenseToken: null,\n licenseTelemetryId: null,\n };\n }\n\n return {\n telemetryId: null,\n licenseToken: identity.licenseToken ?? null,\n licenseTelemetryId: identity.licenseToken\n ? parseAndWarnTelemetryId(identity.licenseToken)\n : null,\n };\n }\n\n private setSampleRate(sampleRate: number | undefined) {\n let _sampleRate: number;\n\n _sampleRate = sampleRate ?? 1;\n\n if (process.env.COPILOTKIT_TELEMETRY_SAMPLE_RATE) {\n _sampleRate = parseFloat(process.env.COPILOTKIT_TELEMETRY_SAMPLE_RATE);\n }\n\n // Number.isNaN guards against parseFloat(\"nonsense\") slipping past the\n // range check (all NaN comparisons are false), which would silently\n // drop every anonymous event with no signal.\n if (Number.isNaN(_sampleRate) || _sampleRate < 0 || _sampleRate > 1) {\n throw new Error(\"Sample rate must be between 0 and 1\");\n }\n\n this.sampleRate = _sampleRate;\n }\n}\n\nconst telemetry = new TelemetryClient();\nexport default telemetry;\n"],"mappings":";;;;;;;;AA+BA,SAAgB,sBAA+B;AAC7C,QACG,QAAQ,IACN,kCAAkC,UACpC,QAAQ,IACN,kCAAkC,OACpC,QAAQ,IAA2C,iBAClD,UACD,QAAQ,IAA2C,iBAAiB;;AAIzE,IAAa,kBAAb,MAA6B;CAoC3B,YAAY,EACV,mBACA,eAIE,EAAE,EAAE;2BAzC6B;oBAOR;sBAIS;qBAGD;4BAIO;0BAeQ,EAAE;AASpD,OAAK,oBAAoB,qBAAqB,qBAAqB;AACnE,OAAK,cAAc,WAAW;;CAGhC,AAAQ,kBAAkB;AACxB,MAAI,KAAK,cAAc,EAAG,QAAO;AACjC,SAAO,KAAK,QAAQ,GAAG,KAAK;;;;;;;;;CAU9B,oBAAoB,YAAqC;AACvD,OAAK,mBAAmB;GAAE,GAAG,KAAK;GAAkB,GAAG;GAAY;;;CAIrE,qBAAqB,UAAmC;EACtD,MAAM,mBAAmB,KAAK,yBAAyB,SAAS;AAChE,OAAK,cAAc,iBAAiB;AACpC,OAAK,eAAe,iBAAiB;AACrC,OAAK,qBAAqB,iBAAiB;;;CAI7C,gBAAgB,cAA4B;AAC1C,OAAK,qBAAqB,EAAE,cAAc,CAAC;;;CAI7C,YAAY,UAA+C;EACzD,MAAM,mBAAmB,KAAK,yBAAyB,SAAS;AAChE,SAAO,EACL,UACE,OACA,eACG,KAAK,oBAAoB,OAAO,YAAY,iBAAiB,EACnE;;CAGH,MAAM,QACJ,OACA,YACe;AACf,SAAO,KAAK,oBAAoB,OAAO,YAAY;GACjD,aAAa,KAAK;GAClB,cAAc,KAAK;GACnB,oBAAoB,KAAK;GAC1B,CAAC;;CAGJ,MAAc,oBACZ,OACA,YACA,UACe;AACf,MAAI,KAAK,kBAAmB;AAG5B,MAAI,CAAC,SAAS,sBAAsB,CAAC,KAAK,iBAAiB,CAAE;AAE7D,QAAM,aAAa,KAAK;GACtB;GACY;GAYZ,kBAAkB;IAChB,GAAG,KAAK;IACR,GAAG,oBAAoB;KACrB,aAAa,SAAS;KACtB,YAAY,KAAK;KAClB,CAAC;IACF,mBAAmB;IAKnB,mBAAmB;IAInB,qBAAqB;IACtB;GACD,aAAaA,eAAY;GACzB,gBAAgBA,eAAY;GAC5B,aAAa,SAAS,eAAe;GACrC,cAAc,SAAS,gBAAgB;GACxC,CAAC;;CAGJ,AAAQ,yBACN,UAC2B;EAC3B,MAAM,cAAc,yBAAyB,SAAS,YAAY;AAClE,MAAI,gBAAgB,OAClB,QAAO;GACL;GACA,cAAc;GACd,oBAAoB;GACrB;AAGH,SAAO;GACL,aAAa;GACb,cAAc,SAAS,gBAAgB;GACvC,oBAAoB,SAAS,eACzB,wBAAwB,SAAS,aAAa,GAC9C;GACL;;CAGH,AAAQ,cAAc,YAAgC;EACpD,IAAI;AAEJ,gBAAc,cAAc;AAE5B,MAAI,QAAQ,IAAI,iCACd,eAAc,WAAW,QAAQ,IAAI,iCAAiC;AAMxE,MAAI,OAAO,MAAM,YAAY,IAAI,cAAc,KAAK,cAAc,EAChE,OAAM,IAAI,MAAM,sCAAsC;AAGxD,OAAK,aAAa;;;AAItB,MAAM,YAAY,IAAI,iBAAiB"}
1
+ {"version":3,"file":"telemetry-client.mjs","names":[],"sources":["../../../../src/v2/runtime/telemetry/telemetry-client.ts"],"sourcesContent":["import type { AnalyticsEvents } from \"./events\";\nimport {\n lambdaClient,\n parseAndWarnTelemetryId,\n computeSamplingMeta,\n TELEMETRY_EMITTER_V2,\n TELEMETRY_SURFACE_V2,\n} from \"@copilotkit/shared\";\nimport {\n RUNTIME_PACKAGE_NAME,\n RUNTIME_PACKAGE_VERSION,\n} from \"../core/package-info\";\nimport { firstNonBlankTelemetryId } from \"./telemetry-identity\";\n\n/** Transport identity and sampling authority resolved for one runtime. */\nexport interface TelemetryIdentity {\n telemetryId?: string;\n licenseToken?: string;\n}\n\n/** Capture-only telemetry client bound to one runtime identity. */\nexport interface TelemetryCapture {\n capture<K extends keyof AnalyticsEvents>(\n event: K,\n properties: AnalyticsEvents[K],\n ): Promise<void>;\n}\n\ninterface ResolvedTelemetryIdentity {\n telemetryId: string | null;\n licenseToken: string | null;\n licenseTelemetryId: string | null;\n}\n\nexport function isTelemetryDisabled(): boolean {\n return (\n (process.env as Record<string, string | undefined>)\n .COPILOTKIT_TELEMETRY_DISABLED === \"true\" ||\n (process.env as Record<string, string | undefined>)\n .COPILOTKIT_TELEMETRY_DISABLED === \"1\" ||\n (process.env as Record<string, string | undefined>).DO_NOT_TRACK ===\n \"true\" ||\n (process.env as Record<string, string | undefined>).DO_NOT_TRACK === \"1\"\n );\n}\n\nexport class TelemetryClient {\n private telemetryDisabled: boolean = false;\n // Opt-down for anonymous events, defaulting to 1: the sink is ours, so a\n // real count beats one extrapolated from a fraction of the population.\n // It stays configurable because it is the cross-SDK lever for reducing or\n // stopping anonymous volume — the Go, Python, Ruby, and .NET runtimes all\n // expose it, and the cross-language conformance suite drives it to 0 to\n // assert silence. Identified callers bypass it.\n private sampleRate: number = 1;\n // EIP / Intelligence license token (Ed25519-signed JWT). Kept separate\n // from standalone identity so the transport receives only the selected\n // identity source.\n private licenseToken: string | null = null;\n // Standalone identity sent as a transport claim. It does not make an\n // event identified.\n private telemetryId: string | null = null;\n // License-derived identity. This client sends every event either way;\n // the id is what sets telemetry_identified on the sampling block, which\n // is how the two populations stay separable downstream.\n private licenseTelemetryId: string | null = null;\n // Properties merged into every event this client sends.\n //\n // For facts about the caller that are true for the whole process rather than\n // for one event: which product is embedding the runtime, for instance. A\n // distribution built on top of this can then be told apart in the existing\n // events instead of sending its own, which is the difference between one\n // extra field and a second pipeline nobody asked for.\n //\n // Sent as `global_properties`, a field of its own, so these stay separable\n // from an event's own properties all the way to the sink.\n //\n // Do not reuse a key an event already sets: the fanout spreads this bag last\n // for `oss.runtime.*`, so a collision resolves in favour of the global and\n // does so silently. Names here should describe the caller, not the call.\n private globalProperties: Record<string, unknown> = {};\n\n constructor({\n telemetryDisabled,\n sampleRate,\n }: {\n telemetryDisabled?: boolean;\n sampleRate?: number;\n } = {}) {\n this.telemetryDisabled = telemetryDisabled || isTelemetryDisabled();\n this.setSampleRate(sampleRate);\n }\n\n private shouldSendEvent() {\n if (this.sampleRate >= 1) return true;\n return Math.random() < this.sampleRate;\n }\n\n /**\n * Add properties carried by every subsequent event.\n *\n * Merged rather than replaced, so two callers setting different fields do not\n * erase each other. Set once at runtime construction in practice; nothing\n * here is per-request.\n */\n setGlobalProperties(properties: Record<string, unknown>) {\n this.globalProperties = { ...this.globalProperties, ...properties };\n }\n\n /** Atomically replace the process-wide telemetry identity. */\n setTelemetryIdentity(identity: TelemetryIdentity): void {\n const resolvedIdentity = this.resolveTelemetryIdentity(identity);\n this.telemetryId = resolvedIdentity.telemetryId;\n this.licenseToken = resolvedIdentity.licenseToken;\n this.licenseTelemetryId = resolvedIdentity.licenseTelemetryId;\n }\n\n /** @deprecated Prefer {@link setTelemetryIdentity}. */\n setLicenseToken(licenseToken: string): void {\n this.setTelemetryIdentity({ licenseToken });\n }\n\n /** Create an immutable capture scope for one Runtime instance. */\n createScope(identity: TelemetryIdentity): TelemetryCapture {\n const resolvedIdentity = this.resolveTelemetryIdentity(identity);\n return {\n capture: <K extends keyof AnalyticsEvents>(\n event: K,\n properties: AnalyticsEvents[K],\n ) => this.captureWithIdentity(event, properties, resolvedIdentity),\n };\n }\n\n async capture<K extends keyof AnalyticsEvents>(\n event: K,\n properties: AnalyticsEvents[K],\n ): Promise<void> {\n return this.captureWithIdentity(event, properties, {\n telemetryId: this.telemetryId,\n licenseToken: this.licenseToken,\n licenseTelemetryId: this.licenseTelemetryId,\n });\n }\n\n private async captureWithIdentity<K extends keyof AnalyticsEvents>(\n event: K,\n properties: AnalyticsEvents[K],\n identity: ResolvedTelemetryIdentity,\n ): Promise<void> {\n if (this.telemetryDisabled) return;\n // Nothing is gated at the default rate of 1. A caller who dialled it\n // down means it, and identified callers are exempt either way.\n if (!identity.licenseTelemetryId && !this.shouldSendEvent()) return;\n\n await lambdaClient.send({\n event,\n properties: properties as Record<string, unknown>,\n // Its own field on the wire rather than folded into `properties`, which\n // is what the sink expects: for `oss.runtime.*` the fanout treats\n // `global_properties` as the SDK's pass-through bag and spreads it into\n // the analytics event, and v1's client sends package name and version the\n // same way. Folding it in would work and would put a process-level fact\n // in the per-event slot, where nothing downstream expects to find one.\n // Sampling metadata rides in the same slot, as it does in v1. It\n // reads 1/1 unless a caller dialled the rate down, and is stamped\n // either way: a consumer summing sampleWeight across emitters must\n // not find the field missing on a quarter of the rows, which is the\n // state that made ~24% of runtime volume unweightable (OSS-1017).\n globalProperties: {\n ...this.globalProperties,\n ...computeSamplingMeta({\n telemetryId: identity.licenseTelemetryId,\n sampleRate: this.sampleRate,\n }),\n telemetry_emitter: TELEMETRY_EMITTER_V2,\n // Constant here: a v1 request never reaches this client. The v1\n // entrypoint hands its own capture scope to the V2 runtime it\n // builds, so v1 traffic is emitted by the v1 client and stamped\n // v1 there — which is also what keeps it on the Segment wire.\n telemetry_surface: TELEMETRY_SURFACE_V2,\n // This client has one transport, so the marker is constant here. It\n // is stamped anyway so the property means the same thing on every\n // event whichever client produced it (OSS-1019).\n telemetry_transport: \"lambda\",\n },\n packageName: RUNTIME_PACKAGE_NAME,\n packageVersion: RUNTIME_PACKAGE_VERSION,\n telemetryId: identity.telemetryId ?? undefined,\n licenseToken: identity.licenseToken ?? undefined,\n });\n }\n\n private resolveTelemetryIdentity(\n identity: TelemetryIdentity,\n ): ResolvedTelemetryIdentity {\n const telemetryId = firstNonBlankTelemetryId(identity.telemetryId);\n if (telemetryId !== undefined) {\n return {\n telemetryId,\n licenseToken: null,\n licenseTelemetryId: null,\n };\n }\n\n return {\n telemetryId: null,\n licenseToken: identity.licenseToken ?? null,\n licenseTelemetryId: identity.licenseToken\n ? parseAndWarnTelemetryId(identity.licenseToken)\n : null,\n };\n }\n\n private setSampleRate(sampleRate: number | undefined) {\n let _sampleRate: number;\n\n _sampleRate = sampleRate ?? 1;\n\n if (process.env.COPILOTKIT_TELEMETRY_SAMPLE_RATE) {\n _sampleRate = parseFloat(process.env.COPILOTKIT_TELEMETRY_SAMPLE_RATE);\n }\n\n // Number.isNaN guards against parseFloat(\"nonsense\") slipping past the\n // range check (all NaN comparisons are false), which would silently\n // drop every anonymous event with no signal.\n if (Number.isNaN(_sampleRate) || _sampleRate < 0 || _sampleRate > 1) {\n throw new Error(\"Sample rate must be between 0 and 1\");\n }\n\n this.sampleRate = _sampleRate;\n }\n}\n\nconst telemetry = new TelemetryClient();\nexport default telemetry;\n"],"mappings":";;;;;;AAkCA,SAAgB,sBAA+B;AAC7C,QACG,QAAQ,IACN,kCAAkC,UACpC,QAAQ,IACN,kCAAkC,OACpC,QAAQ,IAA2C,iBAClD,UACD,QAAQ,IAA2C,iBAAiB;;AAIzE,IAAa,kBAAb,MAA6B;CAoC3B,YAAY,EACV,mBACA,eAIE,EAAE,EAAE;2BAzC6B;oBAOR;sBAIS;qBAGD;4BAIO;0BAeQ,EAAE;AASpD,OAAK,oBAAoB,qBAAqB,qBAAqB;AACnE,OAAK,cAAc,WAAW;;CAGhC,AAAQ,kBAAkB;AACxB,MAAI,KAAK,cAAc,EAAG,QAAO;AACjC,SAAO,KAAK,QAAQ,GAAG,KAAK;;;;;;;;;CAU9B,oBAAoB,YAAqC;AACvD,OAAK,mBAAmB;GAAE,GAAG,KAAK;GAAkB,GAAG;GAAY;;;CAIrE,qBAAqB,UAAmC;EACtD,MAAM,mBAAmB,KAAK,yBAAyB,SAAS;AAChE,OAAK,cAAc,iBAAiB;AACpC,OAAK,eAAe,iBAAiB;AACrC,OAAK,qBAAqB,iBAAiB;;;CAI7C,gBAAgB,cAA4B;AAC1C,OAAK,qBAAqB,EAAE,cAAc,CAAC;;;CAI7C,YAAY,UAA+C;EACzD,MAAM,mBAAmB,KAAK,yBAAyB,SAAS;AAChE,SAAO,EACL,UACE,OACA,eACG,KAAK,oBAAoB,OAAO,YAAY,iBAAiB,EACnE;;CAGH,MAAM,QACJ,OACA,YACe;AACf,SAAO,KAAK,oBAAoB,OAAO,YAAY;GACjD,aAAa,KAAK;GAClB,cAAc,KAAK;GACnB,oBAAoB,KAAK;GAC1B,CAAC;;CAGJ,MAAc,oBACZ,OACA,YACA,UACe;AACf,MAAI,KAAK,kBAAmB;AAG5B,MAAI,CAAC,SAAS,sBAAsB,CAAC,KAAK,iBAAiB,CAAE;AAE7D,QAAM,aAAa,KAAK;GACtB;GACY;GAYZ,kBAAkB;IAChB,GAAG,KAAK;IACR,GAAG,oBAAoB;KACrB,aAAa,SAAS;KACtB,YAAY,KAAK;KAClB,CAAC;IACF,mBAAmB;IAKnB,mBAAmB;IAInB,qBAAqB;IACtB;GACD,aAAa;GACb,gBAAgB;GAChB,aAAa,SAAS,eAAe;GACrC,cAAc,SAAS,gBAAgB;GACxC,CAAC;;CAGJ,AAAQ,yBACN,UAC2B;EAC3B,MAAM,cAAc,yBAAyB,SAAS,YAAY;AAClE,MAAI,gBAAgB,OAClB,QAAO;GACL;GACA,cAAc;GACd,oBAAoB;GACrB;AAGH,SAAO;GACL,aAAa;GACb,cAAc,SAAS,gBAAgB;GACvC,oBAAoB,SAAS,eACzB,wBAAwB,SAAS,aAAa,GAC9C;GACL;;CAGH,AAAQ,cAAc,YAAgC;EACpD,IAAI;AAEJ,gBAAc,cAAc;AAE5B,MAAI,QAAQ,IAAI,iCACd,eAAc,WAAW,QAAQ,IAAI,iCAAiC;AAMxE,MAAI,OAAO,MAAM,YAAY,IAAI,cAAc,KAAK,cAAc,EAChE,OAAM,IAAI,MAAM,sCAAsC;AAGxD,OAAK,aAAa;;;AAItB,MAAM,YAAY,IAAI,iBAAiB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@copilotkit/runtime",
3
- "version": "1.77.0",
3
+ "version": "1.77.1",
4
4
  "private": false,
5
5
  "keywords": [
6
6
  "ai",
@@ -69,9 +69,9 @@
69
69
  },
70
70
  "dependencies": {
71
71
  "@ag-ui/a2ui-middleware": "0.0.10",
72
- "@ag-ui/client": "1.0.1",
73
- "@ag-ui/core": "1.0.1",
74
- "@ag-ui/encoder": "1.0.1",
72
+ "@ag-ui/client": "1.0.2",
73
+ "@ag-ui/core": "1.0.2",
74
+ "@ag-ui/encoder": "1.0.2",
75
75
  "@ag-ui/langgraph": "0.0.44",
76
76
  "@ag-ui/mcp-apps-middleware": "^0.1.1",
77
77
  "@ag-ui/mcp-middleware": "0.0.2",
@@ -111,7 +111,7 @@
111
111
  "yauzl": "2.10.0",
112
112
  "@copilotkit/channels-core": "^0.11.0",
113
113
  "@copilotkit/channels-intelligence": "0.11.0",
114
- "@copilotkit/shared": "1.77.0"
114
+ "@copilotkit/shared": "1.77.1"
115
115
  },
116
116
  "devDependencies": {
117
117
  "@copilotkit/aimock": "latest",
@@ -203,7 +203,7 @@
203
203
  "generate-graphql-schema": "node -e \"const fs=require('fs');fs.rmSync('__snapshots__',{recursive:true,force:true})\" && ts-node --transpile-only ./scripts/generate-gql-schema.ts",
204
204
  "link:global": "pnpm link --global",
205
205
  "unlink:global": "pnpm unlink --global",
206
- "check-dts": "tsx ../../scripts/validate-dts-ambient.ts dist && tsx ../../scripts/validate-dts-imports.ts dist && tsx ../../scripts/validate-optional-peer-entries.ts . && tsc --noEmit -p type-fixtures/express4/tsconfig.json && tsc --noEmit -p type-fixtures/express5/tsconfig.json",
206
+ "check-dts": "tsx ../../scripts/validate-dts-ambient.ts dist && tsx ../../scripts/validate-dts-imports.ts dist && tsx ../../scripts/validate-optional-peer-entries.ts . && tsx ../../scripts/validate-module-scope-create-require.ts . && tsc --noEmit -p type-fixtures/express4/tsconfig.json && tsc --noEmit -p type-fixtures/express5/tsconfig.json",
207
207
  "publint": "publint .",
208
208
  "attw": "attw --pack . --profile node16"
209
209
  }