@copilotkit/runtime 1.56.5 → 1.57.0-canary.1778078321

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 (84) hide show
  1. package/dist/agent/index.cjs +20 -2
  2. package/dist/agent/index.cjs.map +1 -1
  3. package/dist/agent/index.d.cts +9 -16
  4. package/dist/agent/index.d.cts.map +1 -1
  5. package/dist/agent/index.d.mts +9 -16
  6. package/dist/agent/index.d.mts.map +1 -1
  7. package/dist/agent/index.mjs +21 -3
  8. package/dist/agent/index.mjs.map +1 -1
  9. package/dist/package.cjs +1 -1
  10. package/dist/package.mjs +1 -1
  11. package/dist/v2/index.d.cts +3 -3
  12. package/dist/v2/index.d.mts +3 -3
  13. package/dist/v2/runtime/core/fetch-handler.cjs +16 -0
  14. package/dist/v2/runtime/core/fetch-handler.cjs.map +1 -1
  15. package/dist/v2/runtime/core/fetch-handler.d.cts.map +1 -1
  16. package/dist/v2/runtime/core/fetch-handler.d.mts.map +1 -1
  17. package/dist/v2/runtime/core/fetch-handler.mjs +17 -1
  18. package/dist/v2/runtime/core/fetch-handler.mjs.map +1 -1
  19. package/dist/v2/runtime/core/fetch-router.cjs +18 -1
  20. package/dist/v2/runtime/core/fetch-router.cjs.map +1 -1
  21. package/dist/v2/runtime/core/fetch-router.mjs +18 -1
  22. package/dist/v2/runtime/core/fetch-router.mjs.map +1 -1
  23. package/dist/v2/runtime/core/hooks.cjs.map +1 -1
  24. package/dist/v2/runtime/core/hooks.d.cts +8 -0
  25. package/dist/v2/runtime/core/hooks.d.cts.map +1 -1
  26. package/dist/v2/runtime/core/hooks.d.mts +8 -0
  27. package/dist/v2/runtime/core/hooks.d.mts.map +1 -1
  28. package/dist/v2/runtime/core/hooks.mjs.map +1 -1
  29. package/dist/v2/runtime/handlers/handle-run.cjs +1 -0
  30. package/dist/v2/runtime/handlers/handle-run.cjs.map +1 -1
  31. package/dist/v2/runtime/handlers/handle-run.mjs +1 -0
  32. package/dist/v2/runtime/handlers/handle-run.mjs.map +1 -1
  33. package/dist/v2/runtime/handlers/intelligence/run.cjs +10 -1
  34. package/dist/v2/runtime/handlers/intelligence/run.cjs.map +1 -1
  35. package/dist/v2/runtime/handlers/intelligence/run.mjs +10 -1
  36. package/dist/v2/runtime/handlers/intelligence/run.mjs.map +1 -1
  37. package/dist/v2/runtime/handlers/intelligence/threads.cjs +124 -12
  38. package/dist/v2/runtime/handlers/intelligence/threads.cjs.map +1 -1
  39. package/dist/v2/runtime/handlers/intelligence/threads.mjs +122 -13
  40. package/dist/v2/runtime/handlers/intelligence/threads.mjs.map +1 -1
  41. package/dist/v2/runtime/handlers/shared/agent-utils.cjs.map +1 -1
  42. package/dist/v2/runtime/handlers/shared/agent-utils.mjs.map +1 -1
  43. package/dist/v2/runtime/index.d.cts +3 -2
  44. package/dist/v2/runtime/index.d.cts.map +1 -1
  45. package/dist/v2/runtime/index.d.mts +3 -2
  46. package/dist/v2/runtime/index.d.mts.map +1 -1
  47. package/dist/v2/runtime/intelligence-platform/client.cjs +40 -0
  48. package/dist/v2/runtime/intelligence-platform/client.cjs.map +1 -1
  49. package/dist/v2/runtime/intelligence-platform/client.d.cts +83 -0
  50. package/dist/v2/runtime/intelligence-platform/client.d.cts.map +1 -1
  51. package/dist/v2/runtime/intelligence-platform/client.d.mts +83 -0
  52. package/dist/v2/runtime/intelligence-platform/client.d.mts.map +1 -1
  53. package/dist/v2/runtime/intelligence-platform/client.mjs +40 -0
  54. package/dist/v2/runtime/intelligence-platform/client.mjs.map +1 -1
  55. package/dist/v2/runtime/runner/in-memory.cjs +94 -22
  56. package/dist/v2/runtime/runner/in-memory.cjs.map +1 -1
  57. package/dist/v2/runtime/runner/in-memory.d.cts +65 -2
  58. package/dist/v2/runtime/runner/in-memory.d.cts.map +1 -1
  59. package/dist/v2/runtime/runner/in-memory.d.mts +65 -2
  60. package/dist/v2/runtime/runner/in-memory.d.mts.map +1 -1
  61. package/dist/v2/runtime/runner/in-memory.mjs +94 -22
  62. package/dist/v2/runtime/runner/in-memory.mjs.map +1 -1
  63. package/dist/v2/runtime/runner/index.d.cts +1 -1
  64. package/dist/v2/runtime/runner/index.d.mts +1 -1
  65. package/package.json +2 -2
  66. package/src/agent/__tests__/mcp-clients.test.ts +11 -25
  67. package/src/agent/index.ts +67 -32
  68. package/src/v2/runtime/__tests__/fetch-handler-validation.test.ts +68 -0
  69. package/src/v2/runtime/__tests__/fetch-router.test.ts +46 -0
  70. package/src/v2/runtime/__tests__/handle-run.test.ts +97 -1
  71. package/src/v2/runtime/__tests__/handle-threads.test.ts +493 -13
  72. package/src/v2/runtime/core/fetch-handler.ts +19 -0
  73. package/src/v2/runtime/core/fetch-router.ts +33 -1
  74. package/src/v2/runtime/core/hooks.ts +3 -0
  75. package/src/v2/runtime/handlers/handle-run.ts +4 -0
  76. package/src/v2/runtime/handlers/handle-threads.ts +3 -0
  77. package/src/v2/runtime/handlers/intelligence/run.ts +27 -5
  78. package/src/v2/runtime/handlers/intelligence/threads.ts +200 -41
  79. package/src/v2/runtime/handlers/shared/agent-utils.ts +4 -6
  80. package/src/v2/runtime/index.ts +5 -0
  81. package/src/v2/runtime/intelligence-platform/__tests__/intelligence-mcp-helper.test.ts +239 -0
  82. package/src/v2/runtime/intelligence-platform/client.ts +113 -0
  83. package/src/v2/runtime/runner/__tests__/in-memory-runner.test.ts +417 -3
  84. package/src/v2/runtime/runner/in-memory.ts +137 -51
@@ -48,12 +48,15 @@ import { handleGetRuntimeInfo } from "../handlers/get-runtime-info";
48
48
  import { handleTranscribe } from "../handlers/handle-transcribe";
49
49
  import { handleDebugEvents } from "../handlers/handle-debug-events";
50
50
  import {
51
+ handleClearThreads,
51
52
  handleListThreads,
52
53
  handleSubscribeToThreads,
53
54
  handleUpdateThread,
54
55
  handleArchiveThread,
55
56
  handleDeleteThread,
56
57
  handleGetThreadMessages,
58
+ handleGetThreadEvents,
59
+ handleGetThreadState,
57
60
  } from "../handlers/handle-threads";
58
61
  import {
59
62
  parseMethodCall,
@@ -318,6 +321,8 @@ function dispatchRoute(
318
321
  return handleGetRuntimeInfo({ runtime, request });
319
322
  case "transcribe":
320
323
  return handleTranscribe({ runtime, request });
324
+ case "threads/clear":
325
+ return Promise.resolve(handleClearThreads({ runtime, request }));
321
326
  case "threads/list":
322
327
  return handleListThreads({ runtime, request });
323
328
  case "threads/subscribe":
@@ -343,6 +348,18 @@ function dispatchRoute(
343
348
  request,
344
349
  threadId: route.threadId,
345
350
  });
351
+ case "threads/events":
352
+ return handleGetThreadEvents({
353
+ runtime,
354
+ request,
355
+ threadId: route.threadId,
356
+ });
357
+ case "threads/state":
358
+ return handleGetThreadState({
359
+ runtime,
360
+ request,
361
+ threadId: route.threadId,
362
+ });
346
363
  case "cpk-debug-events":
347
364
  return Promise.resolve(handleDebugEvents({ runtime, request }));
348
365
  }
@@ -420,6 +437,8 @@ function validateHttpMethod(
420
437
  case "info":
421
438
  case "threads/list":
422
439
  case "threads/messages":
440
+ case "threads/events":
441
+ case "threads/state":
423
442
  case "cpk-debug-events":
424
443
  if (method === "GET") return null;
425
444
  return jsonResponse({ error: "Method not allowed" }, 405, {
@@ -139,6 +139,28 @@ function matchSegments(path: string): RouteInfo | null {
139
139
  return { method: "threads/messages", threadId };
140
140
  }
141
141
 
142
+ // /threads/:threadId/events (3 segments)
143
+ if (
144
+ len >= 3 &&
145
+ segments[len - 3] === "threads" &&
146
+ segments[len - 1] === "events"
147
+ ) {
148
+ const threadId = safeDecodeURIComponent(segments[len - 2]!);
149
+ if (!threadId) return null;
150
+ return { method: "threads/events", threadId };
151
+ }
152
+
153
+ // /threads/:threadId/state (3 segments)
154
+ if (
155
+ len >= 3 &&
156
+ segments[len - 3] === "threads" &&
157
+ segments[len - 1] === "state"
158
+ ) {
159
+ const threadId = safeDecodeURIComponent(segments[len - 2]!);
160
+ if (!threadId) return null;
161
+ return { method: "threads/state", threadId };
162
+ }
163
+
142
164
  // /threads/:threadId/archive (3 segments)
143
165
  if (
144
166
  len >= 3 &&
@@ -150,11 +172,21 @@ function matchSegments(path: string): RouteInfo | null {
150
172
  return { method: "threads/archive", threadId };
151
173
  }
152
174
 
175
+ // /threads/clear (2 segments) — wipe in-memory thread history
176
+ if (
177
+ len >= 2 &&
178
+ segments[len - 2] === "threads" &&
179
+ segments[len - 1] === "clear"
180
+ ) {
181
+ return { method: "threads/clear" };
182
+ }
183
+
153
184
  // /threads/:threadId (2 segments) — update or delete
154
185
  if (
155
186
  len >= 2 &&
156
187
  segments[len - 2] === "threads" &&
157
- segments[len - 1] !== "subscribe"
188
+ segments[len - 1] !== "subscribe" &&
189
+ segments[len - 1] !== "clear"
158
190
  ) {
159
191
  const threadId = safeDecodeURIComponent(segments[len - 1]!);
160
192
  if (!threadId) return null;
@@ -44,6 +44,9 @@ export type RouteInfo =
44
44
  | { method: "threads/update"; threadId: string }
45
45
  | { method: "threads/archive"; threadId: string }
46
46
  | { method: "threads/messages"; threadId: string }
47
+ | { method: "threads/events"; threadId: string }
48
+ | { method: "threads/state"; threadId: string }
49
+ | { method: "threads/clear" }
47
50
  | { method: "cpk-debug-events" };
48
51
 
49
52
  /* ------------------------------------------------------------------------------------------------
@@ -35,6 +35,10 @@ export async function handleRunAgent({
35
35
  return agent;
36
36
  }
37
37
 
38
+ // Ensure the clone carries the registry key so InMemoryAgentRunner can
39
+ // tag historic runs with the correct agentId for filtering.
40
+ agent.agentId = agentId;
41
+
38
42
  configureAgentForRequest({ runtime, request, agentId, agent });
39
43
 
40
44
  if (
@@ -1,7 +1,10 @@
1
1
  export {
2
2
  handleArchiveThread,
3
+ handleClearThreads,
3
4
  handleDeleteThread,
5
+ handleGetThreadEvents,
4
6
  handleGetThreadMessages,
7
+ handleGetThreadState,
5
8
  handleListThreads,
6
9
  handleSubscribeToThreads,
7
10
  handleUpdateThread,
@@ -1,18 +1,18 @@
1
- import {
1
+ import type {
2
2
  AbstractAgent,
3
3
  BaseEvent,
4
- EventType,
5
4
  Message,
6
5
  RunAgentInput,
7
6
  } from "@ag-ui/client";
8
- import { CopilotIntelligenceRuntimeLike } from "../../core/runtime";
7
+ import { EventType } from "@ag-ui/client";
8
+ import type { CopilotIntelligenceRuntimeLike } from "../../core/runtime";
9
9
  import { generateThreadNameForNewThread } from "./thread-names";
10
10
  import { logger } from "@copilotkit/shared";
11
11
  import { telemetry } from "../../telemetry";
12
12
  import { resolveIntelligenceUser } from "../shared/resolve-intelligence-user";
13
13
  import { isHandlerResponse } from "../shared/json-response";
14
- import { AgentRunnerRunRequest } from "../../runner/agent-runner";
15
- import { Observable } from "rxjs";
14
+ import type { AgentRunnerRunRequest } from "../../runner/agent-runner";
15
+ import type { Observable } from "rxjs";
16
16
 
17
17
  /**
18
18
  * Builds browser-facing realtime connection metadata owned by the runtime.
@@ -161,10 +161,32 @@ export async function handleIntelligenceRun({
161
161
  );
162
162
  }
163
163
 
164
+ // When Intelligence has `mcpServer: true`, hand the agent the per-request
165
+ // bits it needs to attach the platform's MCP server: the resolved user-id,
166
+ // the project Bearer (`apiKey`), and the MCP URL. These ride through
167
+ // `forwardedProps.copilotkitIntelligence` so the agent doesn't need a
168
+ // typed reference to the Intelligence client. `BuiltInAgent` reads the
169
+ // bag and builds a per-request MCP config with a closure-baked fetch;
170
+ // non-BuiltInAgent agents naturally ignore the key.
171
+ const copilotkitIntelligenceProps =
172
+ runtime.intelligence.ɵisMcpServerEnabled?.()
173
+ ? {
174
+ copilotkitIntelligence: {
175
+ userId,
176
+ apiKey: runtime.intelligence.ɵgetApiKey(),
177
+ mcpUrl: `${runtime.intelligence.ɵgetApiUrl()}/mcp`,
178
+ },
179
+ }
180
+ : {};
181
+
164
182
  const canonicalInput: RunAgentInput = {
165
183
  ...input,
166
184
  threadId: canonicalThreadId,
167
185
  runId: canonicalRunId,
186
+ forwardedProps: {
187
+ ...input.forwardedProps,
188
+ ...copilotkitIntelligenceProps,
189
+ },
168
190
  };
169
191
 
170
192
  let persistedInputMessages: Message[] | undefined;
@@ -7,6 +7,7 @@ import { logger } from "@copilotkit/shared";
7
7
  import { errorResponse, isHandlerResponse } from "../shared/json-response";
8
8
  import { isValidIdentifier } from "../shared/intelligence-utils";
9
9
  import { resolveIntelligenceUser } from "../shared/resolve-intelligence-user";
10
+ import { InMemoryAgentRunner } from "../../runner/in-memory";
10
11
 
11
12
  interface ThreadsHandlerParams {
12
13
  runtime: CopilotRuntimeLike;
@@ -73,40 +74,70 @@ export async function handleListThreads({
73
74
  runtime,
74
75
  request,
75
76
  }: ThreadsHandlerParams): Promise<Response> {
76
- const intelligenceRuntime = requireIntelligenceRuntime(runtime);
77
- if (isHandlerResponse(intelligenceRuntime)) {
78
- return intelligenceRuntime;
77
+ // Intelligence platform path
78
+ if (isIntelligenceRuntime(runtime)) {
79
+ try {
80
+ const url = new URL(request.url);
81
+ const agentId = url.searchParams.get("agentId");
82
+ const includeArchived =
83
+ url.searchParams.get("includeArchived") === "true";
84
+ const limitParam = url.searchParams.get("limit");
85
+ const cursor = url.searchParams.get("cursor");
86
+ const user = await resolveIntelligenceUser({ runtime, request });
87
+ if (isHandlerResponse(user)) return user;
88
+
89
+ if (!isValidIdentifier(agentId)) {
90
+ return errorResponse("Valid agentId query param is required", 400);
91
+ }
92
+
93
+ const data = await runtime.intelligence.listThreads({
94
+ userId: user.id,
95
+ agentId,
96
+ ...(includeArchived ? { includeArchived: true } : {}),
97
+ ...(limitParam ? { limit: Number(limitParam) } : {}),
98
+ ...(cursor ? { cursor } : {}),
99
+ });
100
+
101
+ return Response.json(data);
102
+ } catch (error) {
103
+ logger.error({ err: error }, "Error listing threads");
104
+ return errorResponse("Failed to list threads", 500);
105
+ }
79
106
  }
80
107
 
81
- try {
108
+ // Local in-memory fallback — useful for local development without Intelligence
109
+ if (runtime.runner instanceof InMemoryAgentRunner) {
82
110
  const url = new URL(request.url);
83
111
  const agentId = url.searchParams.get("agentId");
84
- const includeArchived = url.searchParams.get("includeArchived") === "true";
85
- const limitParam = url.searchParams.get("limit");
86
- const cursor = url.searchParams.get("cursor");
87
- const user = await resolveIntelligenceUser({
88
- runtime: intelligenceRuntime,
89
- request,
90
- });
91
- if (isHandlerResponse(user)) return user;
92
-
93
- if (!isValidIdentifier(agentId)) {
94
- return errorResponse("Valid agentId query param is required", 400);
112
+ let threads = runtime.runner.listThreads();
113
+ if (agentId) {
114
+ threads = threads.filter((t) => t.agentId === agentId);
95
115
  }
116
+ return Response.json({ threads, nextCursor: null });
117
+ }
96
118
 
97
- const data = await intelligenceRuntime.intelligence.listThreads({
98
- userId: user.id,
99
- agentId,
100
- ...(includeArchived ? { includeArchived: true } : {}),
101
- ...(limitParam ? { limit: Number(limitParam) } : {}),
102
- ...(cursor ? { cursor } : {}),
103
- });
119
+ return errorResponse(
120
+ "Missing CopilotKitIntelligence configuration. Thread operations require a CopilotKitIntelligence instance to be provided in CopilotRuntime options.",
121
+ 422,
122
+ );
123
+ }
104
124
 
105
- return Response.json(data);
106
- } catch (error) {
107
- logger.error({ err: error }, "Error listing threads");
108
- return errorResponse("Failed to list threads", 500);
125
+ /**
126
+ * Clears all in-memory thread history for the local-dev InMemory fallback.
127
+ *
128
+ * The local-dev fallback exposes this so consumers (e.g. the demo's Clear
129
+ * button) can wipe in-memory thread history without restarting the runtime.
130
+ * Intentionally a no-op when the Intelligence platform is configured: real
131
+ * thread history lives in the database and must not be wiped by a
132
+ * client-side page load.
133
+ */
134
+ export function handleClearThreads({
135
+ runtime,
136
+ }: ThreadsHandlerParams): Response {
137
+ if (runtime.runner instanceof InMemoryAgentRunner) {
138
+ runtime.runner.clearThreads();
109
139
  }
140
+ return new Response(null, { status: 204 });
110
141
  }
111
142
 
112
143
  export async function handleUpdateThread({
@@ -237,25 +268,153 @@ export async function handleGetThreadMessages({
237
268
  request,
238
269
  threadId,
239
270
  }: ThreadMutationParams): Promise<Response> {
240
- const intelligenceRuntime = requireIntelligenceRuntime(runtime);
241
- if (isHandlerResponse(intelligenceRuntime)) {
242
- return intelligenceRuntime;
271
+ // Intelligence platform path
272
+ if (isIntelligenceRuntime(runtime)) {
273
+ try {
274
+ const user = await resolveIntelligenceUser({ runtime, request });
275
+ if (isHandlerResponse(user)) return user;
276
+
277
+ const data = await runtime.intelligence.getThreadMessages({ threadId });
278
+ return Response.json(data);
279
+ } catch (error) {
280
+ logger.error({ err: error, threadId }, "Error fetching thread messages");
281
+ return errorResponse("Failed to fetch thread messages", 500);
282
+ }
243
283
  }
244
284
 
245
- try {
246
- const user = await resolveIntelligenceUser({
247
- runtime: intelligenceRuntime,
248
- request,
285
+ // Local in-memory fallback — useful for local development without Intelligence
286
+ if (runtime.runner instanceof InMemoryAgentRunner) {
287
+ const messages = runtime.runner.getThreadMessages(threadId);
288
+ // Map ag-ui Message objects to the same shape the Intelligence platform
289
+ // returns. Switching on the discriminant `role` lets each branch read
290
+ // the narrowed message arm directly, instead of laundering through
291
+ // `Record<string, unknown>` and chained `as` casts.
292
+ const mapped = messages.map((msg) => {
293
+ switch (msg.role) {
294
+ case "assistant": {
295
+ const toolCalls = msg.toolCalls ?? [];
296
+ return {
297
+ id: msg.id,
298
+ role: msg.role,
299
+ ...(msg.content !== undefined ? { content: msg.content } : {}),
300
+ ...(toolCalls.length > 0
301
+ ? {
302
+ toolCalls: toolCalls.map((tc) => ({
303
+ id: tc.id,
304
+ name: tc.function.name,
305
+ args: tc.function.arguments,
306
+ })),
307
+ }
308
+ : {}),
309
+ };
310
+ }
311
+ case "tool":
312
+ return {
313
+ id: msg.id,
314
+ role: msg.role,
315
+ content: msg.content,
316
+ toolCallId: msg.toolCallId,
317
+ };
318
+ default:
319
+ return {
320
+ id: msg.id,
321
+ role: msg.role,
322
+ ...("content" in msg && msg.content !== undefined
323
+ ? { content: msg.content }
324
+ : {}),
325
+ };
326
+ }
249
327
  });
250
- if (isHandlerResponse(user)) return user;
328
+ return Response.json({ messages: mapped });
329
+ }
251
330
 
252
- const data = await intelligenceRuntime.intelligence.getThreadMessages({
253
- threadId,
254
- });
331
+ return errorResponse(
332
+ "Missing CopilotKitIntelligence configuration. Thread operations require a CopilotKitIntelligence instance to be provided in CopilotRuntime options.",
333
+ 422,
334
+ );
335
+ }
255
336
 
256
- return Response.json(data);
257
- } catch (error) {
258
- logger.error({ err: error, threadId }, "Error getting thread messages");
259
- return errorResponse("Failed to get thread messages", 500);
337
+ export async function handleGetThreadEvents({
338
+ runtime,
339
+ request,
340
+ threadId,
341
+ }: ThreadMutationParams): Promise<Response> {
342
+ // Intelligence platform path. Delegates to the platform's `_inspect`
343
+ // endpoint (Intelligence PR #144). Auth still flows through the standard
344
+ // identifyUser → API key path; threadId scoping happens server-side.
345
+ if (isIntelligenceRuntime(runtime)) {
346
+ try {
347
+ const user = await resolveIntelligenceUser({ runtime, request });
348
+ if (isHandlerResponse(user)) return user;
349
+
350
+ const data = await runtime.intelligence.getThreadEvents({ threadId });
351
+ // Strip platform-internal fields (`decodeErrorRowIds`, `truncated`)
352
+ // before returning to the inspector — those describe persistence-side
353
+ // concerns the inspector currently has no UI for. The shape becomes
354
+ // `{ events }`, matching the in-memory branch below.
355
+ return Response.json({ events: data.events });
356
+ } catch (error) {
357
+ logger.error({ err: error, threadId }, "Error fetching thread events");
358
+ return errorResponse("Failed to fetch thread events", 500);
359
+ }
360
+ }
361
+
362
+ // Local in-memory fallback
363
+ if (runtime.runner instanceof InMemoryAgentRunner) {
364
+ try {
365
+ const events = runtime.runner.getThreadEvents(threadId);
366
+ return Response.json({ events });
367
+ } catch (error) {
368
+ logger.error({ err: error, threadId }, "Error fetching thread events");
369
+ return errorResponse("Failed to fetch thread events", 500);
370
+ }
260
371
  }
372
+
373
+ return errorResponse(
374
+ "Missing CopilotKitIntelligence configuration. Thread operations require a CopilotKitIntelligence instance to be provided in CopilotRuntime options.",
375
+ 422,
376
+ );
377
+ }
378
+
379
+ export async function handleGetThreadState({
380
+ runtime,
381
+ request,
382
+ threadId,
383
+ }: ThreadMutationParams): Promise<Response> {
384
+ // Intelligence platform path. Delegates to the platform's `_inspect`
385
+ // state endpoint, which folds STATE_DELTA events onto the latest
386
+ // STATE_SNAPSHOT to return the thread's current state.
387
+ if (isIntelligenceRuntime(runtime)) {
388
+ try {
389
+ const user = await resolveIntelligenceUser({ runtime, request });
390
+ if (isHandlerResponse(user)) return user;
391
+
392
+ const data = await runtime.intelligence.getThreadState({ threadId });
393
+ // Flatten the discriminated `ThreadStateResult` to the wire shape the
394
+ // inspector consumes (`{ state: <value> | null }`). Missing snapshot
395
+ // and decode-error both surface as `null`; the inspector renders an
396
+ // empty state branch for null and the platform's decode-error case is
397
+ // already logged platform-side.
398
+ const state = data.kind === "snapshot" ? data.state : null;
399
+ return Response.json({ state });
400
+ } catch (error) {
401
+ logger.error({ err: error, threadId }, "Error fetching thread state");
402
+ return errorResponse("Failed to fetch thread state", 500);
403
+ }
404
+ }
405
+
406
+ if (runtime.runner instanceof InMemoryAgentRunner) {
407
+ try {
408
+ const state = runtime.runner.getThreadState(threadId);
409
+ return Response.json({ state });
410
+ } catch (error) {
411
+ logger.error({ err: error, threadId }, "Error fetching thread state");
412
+ return errorResponse("Failed to fetch thread state", 500);
413
+ }
414
+ }
415
+
416
+ return errorResponse(
417
+ "Missing CopilotKitIntelligence configuration. Thread operations require a CopilotKitIntelligence instance to be provided in CopilotRuntime options.",
418
+ 422,
419
+ );
261
420
  }
@@ -1,11 +1,9 @@
1
- import {
2
- AbstractAgent,
3
- RunAgentInput,
4
- RunAgentInputSchema,
5
- } from "@ag-ui/client";
1
+ import type { AbstractAgent, RunAgentInput } from "@ag-ui/client";
2
+ import { RunAgentInputSchema } from "@ag-ui/client";
6
3
  import { A2UIMiddleware } from "@ag-ui/a2ui-middleware";
7
4
  import { MCPAppsMiddleware } from "@ag-ui/mcp-apps-middleware";
8
- import { CopilotRuntimeLike, resolveAgents } from "../../core/runtime";
5
+ import type { CopilotRuntimeLike } from "../../core/runtime";
6
+ import { resolveAgents } from "../../core/runtime";
9
7
  import { OpenGenerativeUIMiddleware } from "../../open-generative-ui-middleware";
10
8
  import { extractForwardableHeaders } from "../header-utils";
11
9
  import { logger } from "@copilotkit/shared";
@@ -19,6 +19,11 @@ export {
19
19
  type UpdateThreadRequest,
20
20
  } from "./intelligence-platform";
21
21
 
22
+ // Re-export `@ai-sdk/mcp` stable types so consumers don't need to depend on
23
+ // it directly to type their MCP wiring. `MCPClient` is the value users pass
24
+ // into `mcpClients`; `MCPTransport` is the contract for custom transports.
25
+ export type { MCPClient, MCPTransport } from "@ai-sdk/mcp";
26
+
22
27
  // Export framework-agnostic fetch handler
23
28
  export { createCopilotRuntimeHandler } from "./core/fetch-handler";
24
29
  export type {