@copilotkit/runtime 1.62.0 → 1.62.2-canary.1783457132

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 (76) hide show
  1. package/dist/package.cjs +2 -2
  2. package/dist/package.mjs +2 -2
  3. package/dist/v2/index.cjs +5 -1
  4. package/dist/v2/index.d.cts +2 -2
  5. package/dist/v2/index.d.mts +2 -2
  6. package/dist/v2/index.mjs +2 -2
  7. package/dist/v2/runtime/core/fetch-handler.cjs +27 -0
  8. package/dist/v2/runtime/core/fetch-handler.cjs.map +1 -1
  9. package/dist/v2/runtime/core/fetch-handler.d.cts.map +1 -1
  10. package/dist/v2/runtime/core/fetch-handler.d.mts.map +1 -1
  11. package/dist/v2/runtime/core/fetch-handler.mjs +27 -0
  12. package/dist/v2/runtime/core/fetch-handler.mjs.map +1 -1
  13. package/dist/v2/runtime/core/fetch-router.cjs +10 -0
  14. package/dist/v2/runtime/core/fetch-router.cjs.map +1 -1
  15. package/dist/v2/runtime/core/fetch-router.mjs +10 -0
  16. package/dist/v2/runtime/core/fetch-router.mjs.map +1 -1
  17. package/dist/v2/runtime/core/hooks.cjs.map +1 -1
  18. package/dist/v2/runtime/core/hooks.d.cts +7 -0
  19. package/dist/v2/runtime/core/hooks.d.cts.map +1 -1
  20. package/dist/v2/runtime/core/hooks.d.mts +7 -0
  21. package/dist/v2/runtime/core/hooks.d.mts.map +1 -1
  22. package/dist/v2/runtime/core/hooks.mjs.map +1 -1
  23. package/dist/v2/runtime/core/runtime.cjs +5 -0
  24. package/dist/v2/runtime/core/runtime.cjs.map +1 -1
  25. package/dist/v2/runtime/core/runtime.d.cts +21 -0
  26. package/dist/v2/runtime/core/runtime.d.cts.map +1 -1
  27. package/dist/v2/runtime/core/runtime.d.mts +21 -0
  28. package/dist/v2/runtime/core/runtime.d.mts.map +1 -1
  29. package/dist/v2/runtime/core/runtime.mjs +5 -0
  30. package/dist/v2/runtime/core/runtime.mjs.map +1 -1
  31. package/dist/v2/runtime/handlers/handle-connect.cjs +2 -1
  32. package/dist/v2/runtime/handlers/handle-connect.cjs.map +1 -1
  33. package/dist/v2/runtime/handlers/handle-connect.mjs +2 -1
  34. package/dist/v2/runtime/handlers/handle-connect.mjs.map +1 -1
  35. package/dist/v2/runtime/handlers/header-utils.cjs +169 -9
  36. package/dist/v2/runtime/handlers/header-utils.cjs.map +1 -1
  37. package/dist/v2/runtime/handlers/header-utils.d.cts +54 -0
  38. package/dist/v2/runtime/handlers/header-utils.d.cts.map +1 -0
  39. package/dist/v2/runtime/handlers/header-utils.d.mts +54 -0
  40. package/dist/v2/runtime/handlers/header-utils.d.mts.map +1 -0
  41. package/dist/v2/runtime/handlers/header-utils.mjs +168 -9
  42. package/dist/v2/runtime/handlers/header-utils.mjs.map +1 -1
  43. package/dist/v2/runtime/handlers/intelligence/memories.cjs +209 -0
  44. package/dist/v2/runtime/handlers/intelligence/memories.cjs.map +1 -0
  45. package/dist/v2/runtime/handlers/intelligence/memories.mjs +204 -0
  46. package/dist/v2/runtime/handlers/intelligence/memories.mjs.map +1 -0
  47. package/dist/v2/runtime/handlers/shared/agent-utils.cjs +18 -5
  48. package/dist/v2/runtime/handlers/shared/agent-utils.cjs.map +1 -1
  49. package/dist/v2/runtime/handlers/shared/agent-utils.mjs +18 -5
  50. package/dist/v2/runtime/handlers/shared/agent-utils.mjs.map +1 -1
  51. package/dist/v2/runtime/handlers/sse/connect.cjs +2 -2
  52. package/dist/v2/runtime/handlers/sse/connect.cjs.map +1 -1
  53. package/dist/v2/runtime/handlers/sse/connect.mjs +3 -3
  54. package/dist/v2/runtime/handlers/sse/connect.mjs.map +1 -1
  55. package/dist/v2/runtime/index.d.cts +1 -1
  56. package/dist/v2/runtime/index.d.mts +1 -1
  57. package/dist/v2/runtime/intelligence-platform/client.cjs +71 -2
  58. package/dist/v2/runtime/intelligence-platform/client.cjs.map +1 -1
  59. package/dist/v2/runtime/intelligence-platform/client.d.cts +112 -0
  60. package/dist/v2/runtime/intelligence-platform/client.d.cts.map +1 -1
  61. package/dist/v2/runtime/intelligence-platform/client.d.mts +112 -0
  62. package/dist/v2/runtime/intelligence-platform/client.d.mts.map +1 -1
  63. package/dist/v2/runtime/intelligence-platform/client.mjs +71 -2
  64. package/dist/v2/runtime/intelligence-platform/client.mjs.map +1 -1
  65. package/dist/v2/runtime/runner/in-memory.cjs +221 -37
  66. package/dist/v2/runtime/runner/in-memory.cjs.map +1 -1
  67. package/dist/v2/runtime/runner/in-memory.d.cts +164 -3
  68. package/dist/v2/runtime/runner/in-memory.d.cts.map +1 -1
  69. package/dist/v2/runtime/runner/in-memory.d.mts +164 -3
  70. package/dist/v2/runtime/runner/in-memory.d.mts.map +1 -1
  71. package/dist/v2/runtime/runner/in-memory.mjs +218 -38
  72. package/dist/v2/runtime/runner/in-memory.mjs.map +1 -1
  73. package/dist/v2/runtime/runner/index.d.cts +1 -1
  74. package/dist/v2/runtime/runner/index.d.mts +1 -1
  75. package/dist/v2/runtime/runner/index.mjs +1 -1
  76. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"agent-utils.mjs","names":[],"sources":["../../../../../src/v2/runtime/handlers/shared/agent-utils.ts"],"sourcesContent":["import type { AbstractAgent, RunAgentInput } from \"@ag-ui/client\";\nimport { RunAgentInputSchema } from \"@ag-ui/client\";\nimport { A2UIMiddleware } from \"@ag-ui/a2ui-middleware\";\nimport { MCPAppsMiddleware } from \"@ag-ui/mcp-apps-middleware\";\nimport { MCPMiddleware } from \"@ag-ui/mcp-middleware\";\nimport type { CopilotRuntimeLike } from \"../../core/runtime\";\nimport {\n isA2UIEnabled,\n isIntelligenceRuntime,\n resolveAgents,\n} from \"../../core/runtime\";\nimport { OpenGenerativeUIMiddleware } from \"../../open-generative-ui-middleware\";\nimport { INTELLIGENCE_USER_ID_HEADER } from \"../../intelligence-platform/client\";\nimport { extractForwardableHeaders } from \"../header-utils\";\nimport { resolveIntelligenceUser } from \"./resolve-intelligence-user\";\nimport { logger } from \"@copilotkit/shared\";\n\ntype MiddlewareCapableAgent = AbstractAgent & {\n use?: (middleware: unknown) => void;\n headers?: Record<string, string>;\n};\n\nexport interface RunAgentParameters {\n request: Request;\n runtime: CopilotRuntimeLike;\n agentId: string;\n}\n\nexport interface ConnectRequestBody extends RunAgentInput {\n lastSeenEventId?: string | null;\n}\n\nexport async function cloneAgentForRequest(\n runtime: CopilotRuntimeLike,\n agentId: string,\n request?: Request,\n): Promise<AbstractAgent | Response> {\n const agents = await resolveAgents(runtime.agents, request);\n\n if (!agents[agentId]) {\n return new Response(\n JSON.stringify({\n error: \"Agent not found\",\n message: `Agent '${agentId}' does not exist`,\n }),\n {\n status: 404,\n headers: { \"Content-Type\": \"application/json\" },\n },\n );\n }\n\n return (agents[agentId] as AbstractAgent).clone() as AbstractAgent;\n}\n\nexport function configureAgentForRequest(params: {\n runtime: CopilotRuntimeLike;\n request: Request;\n agentId: string;\n agent: AbstractAgent;\n /**\n * True when the React provider was given an A2UI catalog\n * (`<CopilotKit a2ui={{ catalog }}>`), forwarded per-run. A catalog alone is\n * enough to enable A2UI and inject the render tool — the developer no longer\n * has to also set `a2ui.injectA2UITool` on the runtime.\n */\n providerA2UIHasCatalog?: boolean;\n}): void {\n const { runtime, request, agentId, providerA2UIHasCatalog } = params;\n const agent = params.agent as MiddlewareCapableAgent;\n\n // A2UI is on when the runtime explicitly enables it, OR when the provider\n // forwarded a catalog — but an explicit `enabled: false` always wins (we\n // provide a quick default, never override a deeper opt-out).\n const a2uiEnabledByCatalog =\n !!providerA2UIHasCatalog && runtime.a2ui?.enabled !== false;\n\n if (isA2UIEnabled(runtime.a2ui) || a2uiEnabledByCatalog) {\n // `enabled` is a CopilotKit-level switch, not an A2UIMiddleware option —\n // drop it (alongside the agent filter) before forwarding to the middleware.\n const {\n agents: targetAgents,\n enabled: _enabled,\n injectA2UITool,\n ...a2uiOptions\n } = runtime.a2ui ?? {};\n const shouldApply = !targetAgents || targetAgents.includes(agentId);\n if (shouldApply && typeof agent.use === \"function\") {\n agent.use(\n new A2UIMiddleware({\n ...a2uiOptions,\n // Default render-tool injection on when a catalog is present and the\n // developer hasn't set it explicitly. `??` means an explicit value\n // (including `false`) is always respected.\n injectA2UITool:\n injectA2UITool ?? (providerA2UIHasCatalog ? true : undefined),\n }),\n );\n }\n }\n\n if (runtime.mcpApps?.servers?.length) {\n const mcpServers = runtime.mcpApps.servers\n .filter((server) => !server.agentId || server.agentId === agentId)\n .map((server) => {\n const mcpServer = { ...server };\n delete mcpServer.agentId;\n return mcpServer;\n });\n\n if (mcpServers.length > 0 && typeof agent.use === \"function\") {\n agent.use(new MCPAppsMiddleware({ mcpServers }));\n }\n }\n\n if (runtime.openGenerativeUI) {\n const config = runtime.openGenerativeUI;\n const targetAgents = typeof config === \"object\" ? config.agents : undefined;\n const shouldApply = !targetAgents || targetAgents.includes(agentId);\n if (shouldApply && typeof agent.use === \"function\") {\n agent.use(new OpenGenerativeUIMiddleware());\n }\n }\n\n agent.headers = {\n ...agent.headers,\n ...extractForwardableHeaders(request),\n };\n}\n\n/**\n * Attach the Intelligence platform's MCP tools to the agent run when\n * `CopilotKitIntelligence` was constructed with\n * `enableEnterpriseLearning: true`. Uses `@ag-ui/mcp-middleware`, so the\n * tools are available uniformly across agent frameworks (not just\n * `BuiltInAgent`).\n *\n * The middleware sits on a per-request agent clone, so the per-request\n * auth (Bearer apiKey + resolved user-id) is baked into the transport\n * headers at attach time. If user resolution fails, attachment is\n * skipped silently — the intelligence run handler will reject the\n * request with the same error. Note this means `identifyUser` is\n * resolved twice per learning-enabled run (here and in the run handler);\n * the callback is expected to be idempotent and side-effect-free.\n *\n * Intentionally split out from `configureAgentForRequest`: this is only\n * relevant to actual agent runs, not auxiliary flows like thread-name\n * generation (which has no need for MCP tools and shouldn't pay the\n * `listTools` round-trip).\n */\nexport async function attachIntelligenceEnterpriseLearning(params: {\n runtime: CopilotRuntimeLike;\n request: Request;\n agent: AbstractAgent;\n}): Promise<void> {\n const { runtime, request } = params;\n const agent = params.agent as MiddlewareCapableAgent;\n\n if (\n !isIntelligenceRuntime(runtime) ||\n !runtime.intelligence?.ɵisEnterpriseLearningEnabled?.()\n ) {\n return;\n }\n\n // Enterprise learning is enabled, but this agent's framework can't take\n // middleware — surface it rather than silently shipping a run with none\n // of the tools the operator opted into.\n if (typeof agent.use !== \"function\") {\n logger.warn(\n \"CopilotKitIntelligence.enableEnterpriseLearning is enabled, but the agent \" +\n \"does not support middleware (no `.use()` method); Intelligence tools were \" +\n \"not attached for this run.\",\n );\n return;\n }\n\n const userResult = await resolveIntelligenceUser({ runtime, request });\n if (userResult instanceof Response) return;\n\n agent.use(\n new MCPMiddleware([\n {\n type: \"http\",\n url: `${runtime.intelligence.ɵgetApiUrl()}/mcp`,\n serverId: \"intelligence\",\n headers: {\n Authorization: `Bearer ${runtime.intelligence.ɵgetApiKey()}`,\n [INTELLIGENCE_USER_ID_HEADER]: userResult.id,\n },\n },\n ]),\n );\n}\n\nexport async function parseRunRequest(\n request: Request,\n): Promise<RunAgentInput | Response> {\n try {\n const requestBody = await request.json();\n return RunAgentInputSchema.parse(requestBody);\n } catch (error) {\n logger.error(\"Invalid run request body:\", error);\n return new Response(\n JSON.stringify({\n error: \"Invalid request body\",\n details: error instanceof Error ? error.message : String(error),\n }),\n {\n status: 400,\n headers: { \"Content-Type\": \"application/json\" },\n },\n );\n }\n}\n\nexport async function parseConnectRequest(request: Request): Promise<\n | Response\n | {\n input: RunAgentInput;\n lastSeenEventId: string | null;\n }\n> {\n try {\n const requestBody = await request.json();\n const input = RunAgentInputSchema.parse(requestBody);\n let lastSeenEventId: string | null = null;\n\n if (\n \"lastSeenEventId\" in (requestBody as Record<string, unknown>) &&\n (typeof (requestBody as Record<string, unknown>).lastSeenEventId ===\n \"string\" ||\n (requestBody as Record<string, unknown>).lastSeenEventId === null)\n ) {\n lastSeenEventId =\n (requestBody as ConnectRequestBody).lastSeenEventId ?? null;\n }\n\n return { input, lastSeenEventId };\n } catch (error) {\n logger.error(\"Invalid connect request body:\", error);\n return new Response(\n JSON.stringify({\n error: \"Invalid request body\",\n details: error instanceof Error ? error.message : String(error),\n }),\n {\n status: 400,\n headers: { \"Content-Type\": \"application/json\" },\n },\n );\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"agent-utils.mjs","names":[],"sources":["../../../../../src/v2/runtime/handlers/shared/agent-utils.ts"],"sourcesContent":["import type { AbstractAgent, RunAgentInput } from \"@ag-ui/client\";\nimport { RunAgentInputSchema } from \"@ag-ui/client\";\nimport { A2UIMiddleware } from \"@ag-ui/a2ui-middleware\";\nimport { MCPAppsMiddleware } from \"@ag-ui/mcp-apps-middleware\";\nimport { MCPMiddleware } from \"@ag-ui/mcp-middleware\";\nimport type { CopilotRuntimeLike } from \"../../core/runtime\";\nimport {\n isA2UIEnabled,\n isIntelligenceRuntime,\n resolveAgents,\n} from \"../../core/runtime\";\nimport { OpenGenerativeUIMiddleware } from \"../../open-generative-ui-middleware\";\nimport { INTELLIGENCE_USER_ID_HEADER } from \"../../intelligence-platform/client\";\nimport {\n mergeForwardableHeaders,\n resolveForwardHeadersPolicy,\n} from \"../header-utils\";\nimport { resolveIntelligenceUser } from \"./resolve-intelligence-user\";\nimport { logger } from \"@copilotkit/shared\";\n\ntype MiddlewareCapableAgent = AbstractAgent & {\n use?: (middleware: unknown) => void;\n headers?: Record<string, string>;\n};\n\nexport interface RunAgentParameters {\n request: Request;\n runtime: CopilotRuntimeLike;\n agentId: string;\n}\n\nexport interface ConnectRequestBody extends RunAgentInput {\n lastSeenEventId?: string | null;\n}\n\n/**\n * Resolve `agentId` against the runtime's agents and return a per-request\n * clone of the matching agent.\n *\n * Dual return contract — both callers (`handle-run.ts`, `handle-connect.ts`)\n * depend on it:\n * - Returns a cloned `AbstractAgent` when the agent exists.\n * - Returns a 404 `Response` (`{ error: \"Agent not found\", ... }`) when the\n * agent is unknown. Callers MUST `instanceof Response`-check the result and\n * return it directly; this doubles as the connect/run path's agent-existence\n * guard, so skipping the check would let unknown agent ids slip through.\n *\n * The clone is what subsequent per-request mutation (middleware attach,\n * `agent.headers` merge) operates on, leaving the shared agent registration\n * untouched.\n */\nexport async function cloneAgentForRequest(\n runtime: CopilotRuntimeLike,\n agentId: string,\n request?: Request,\n): Promise<AbstractAgent | Response> {\n const agents = await resolveAgents(runtime.agents, request);\n\n if (!agents[agentId]) {\n return new Response(\n JSON.stringify({\n error: \"Agent not found\",\n message: `Agent '${agentId}' does not exist`,\n }),\n {\n status: 404,\n headers: { \"Content-Type\": \"application/json\" },\n },\n );\n }\n\n return (agents[agentId] as AbstractAgent).clone() as AbstractAgent;\n}\n\nexport function configureAgentForRequest(params: {\n runtime: CopilotRuntimeLike;\n request: Request;\n agentId: string;\n agent: AbstractAgent;\n /**\n * True when the React provider was given an A2UI catalog\n * (`<CopilotKit a2ui={{ catalog }}>`), forwarded per-run. A catalog alone is\n * enough to enable A2UI and inject the render tool — the developer no longer\n * has to also set `a2ui.injectA2UITool` on the runtime.\n */\n providerA2UIHasCatalog?: boolean;\n}): void {\n const { runtime, request, agentId, providerA2UIHasCatalog } = params;\n const agent = params.agent as MiddlewareCapableAgent;\n\n // A2UI is on when the runtime explicitly enables it, OR when the provider\n // forwarded a catalog — but an explicit `enabled: false` always wins (we\n // provide a quick default, never override a deeper opt-out).\n const a2uiEnabledByCatalog =\n !!providerA2UIHasCatalog && runtime.a2ui?.enabled !== false;\n\n if (isA2UIEnabled(runtime.a2ui) || a2uiEnabledByCatalog) {\n // `enabled` is a CopilotKit-level switch, not an A2UIMiddleware option —\n // drop it (alongside the agent filter) before forwarding to the middleware.\n const {\n agents: targetAgents,\n enabled: _enabled,\n injectA2UITool,\n ...a2uiOptions\n } = runtime.a2ui ?? {};\n const shouldApply = !targetAgents || targetAgents.includes(agentId);\n if (shouldApply && typeof agent.use === \"function\") {\n agent.use(\n new A2UIMiddleware({\n ...a2uiOptions,\n // Default render-tool injection on when a catalog is present and the\n // developer hasn't set it explicitly. `??` means an explicit value\n // (including `false`) is always respected.\n injectA2UITool:\n injectA2UITool ?? (providerA2UIHasCatalog ? true : undefined),\n }),\n );\n }\n }\n\n if (runtime.mcpApps?.servers?.length) {\n const mcpServers = runtime.mcpApps.servers\n .filter((server) => !server.agentId || server.agentId === agentId)\n .map((server) => {\n const mcpServer = { ...server };\n delete mcpServer.agentId;\n return mcpServer;\n });\n\n if (mcpServers.length > 0 && typeof agent.use === \"function\") {\n agent.use(new MCPAppsMiddleware({ mcpServers }));\n }\n }\n\n if (runtime.openGenerativeUI) {\n const config = runtime.openGenerativeUI;\n const targetAgents = typeof config === \"object\" ? config.agents : undefined;\n const shouldApply = !targetAgents || targetAgents.includes(agentId);\n if (shouldApply && typeof agent.use === \"function\") {\n agent.use(new OpenGenerativeUIMiddleware());\n }\n }\n\n // Forward eligible inbound headers onto the outgoing agent call under the\n // runtime's resolved forwarding policy (`authorization` / custom `x-*`, with\n // known infra/proxy/platform headers stripped by the default denylist —\n // #5712), but let headers the server explicitly configured on the agent WIN\n // on collision (case-insensitively): a server-set service-to-service token\n // (e.g. an IAM bearer) must never be silently overridden by a\n // browser/edge/platform-injected inbound header. See `mergeForwardableHeaders`\n // for the casing/duplicate-key rationale and `shouldForwardHeader` for breadth.\n agent.headers = mergeForwardableHeaders(\n agent.headers,\n request,\n // `forwardHeadersPolicy` is optional on the published `CopilotRuntimeLike`\n // interface (non-breaking minor release). Concrete runtimes always set it;\n // a policy-less external implementor falls back to the default resolved\n // policy (default-on denylist) so behavior stays identical and never derefs\n // undefined.\n runtime.forwardHeadersPolicy ?? resolveForwardHeadersPolicy(undefined),\n );\n}\n\n/**\n * Attach the Intelligence platform's MCP tools to the agent run when\n * `CopilotKitIntelligence` was constructed with\n * `enableEnterpriseLearning: true`. Uses `@ag-ui/mcp-middleware`, so the\n * tools are available uniformly across agent frameworks (not just\n * `BuiltInAgent`).\n *\n * The middleware sits on a per-request agent clone, so the per-request\n * auth (Bearer apiKey + resolved user-id) is baked into the transport\n * headers at attach time. If user resolution fails, attachment is\n * skipped silently — the intelligence run handler will reject the\n * request with the same error. Note this means `identifyUser` is\n * resolved twice per learning-enabled run (here and in the run handler);\n * the callback is expected to be idempotent and side-effect-free.\n *\n * Intentionally split out from `configureAgentForRequest`: this is only\n * relevant to actual agent runs, not auxiliary flows like thread-name\n * generation (which has no need for MCP tools and shouldn't pay the\n * `listTools` round-trip).\n */\nexport async function attachIntelligenceEnterpriseLearning(params: {\n runtime: CopilotRuntimeLike;\n request: Request;\n agent: AbstractAgent;\n}): Promise<void> {\n const { runtime, request } = params;\n const agent = params.agent as MiddlewareCapableAgent;\n\n if (\n !isIntelligenceRuntime(runtime) ||\n !runtime.intelligence?.ɵisEnterpriseLearningEnabled?.()\n ) {\n return;\n }\n\n // Enterprise learning is enabled, but this agent's framework can't take\n // middleware — surface it rather than silently shipping a run with none\n // of the tools the operator opted into.\n if (typeof agent.use !== \"function\") {\n logger.warn(\n \"CopilotKitIntelligence.enableEnterpriseLearning is enabled, but the agent \" +\n \"does not support middleware (no `.use()` method); Intelligence tools were \" +\n \"not attached for this run.\",\n );\n return;\n }\n\n const userResult = await resolveIntelligenceUser({ runtime, request });\n if (userResult instanceof Response) return;\n\n agent.use(\n new MCPMiddleware([\n {\n type: \"http\",\n url: `${runtime.intelligence.ɵgetApiUrl()}/mcp`,\n serverId: \"intelligence\",\n headers: {\n Authorization: `Bearer ${runtime.intelligence.ɵgetApiKey()}`,\n [INTELLIGENCE_USER_ID_HEADER]: userResult.id,\n },\n },\n ]),\n );\n}\n\nexport async function parseRunRequest(\n request: Request,\n): Promise<RunAgentInput | Response> {\n try {\n const requestBody = await request.json();\n return RunAgentInputSchema.parse(requestBody);\n } catch (error) {\n logger.error(\"Invalid run request body:\", error);\n return new Response(\n JSON.stringify({\n error: \"Invalid request body\",\n details: error instanceof Error ? error.message : String(error),\n }),\n {\n status: 400,\n headers: { \"Content-Type\": \"application/json\" },\n },\n );\n }\n}\n\nexport async function parseConnectRequest(request: Request): Promise<\n | Response\n | {\n input: RunAgentInput;\n lastSeenEventId: string | null;\n }\n> {\n try {\n const requestBody = await request.json();\n const input = RunAgentInputSchema.parse(requestBody);\n let lastSeenEventId: string | null = null;\n\n if (\n \"lastSeenEventId\" in (requestBody as Record<string, unknown>) &&\n (typeof (requestBody as Record<string, unknown>).lastSeenEventId ===\n \"string\" ||\n (requestBody as Record<string, unknown>).lastSeenEventId === null)\n ) {\n lastSeenEventId =\n (requestBody as ConnectRequestBody).lastSeenEventId ?? null;\n }\n\n return { input, lastSeenEventId };\n } catch (error) {\n logger.error(\"Invalid connect request body:\", error);\n return new Response(\n JSON.stringify({\n error: \"Invalid request body\",\n details: error instanceof Error ? error.message : String(error),\n }),\n {\n status: 400,\n headers: { \"Content-Type\": \"application/json\" },\n },\n );\n }\n}\n"],"mappings":"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"}
@@ -3,14 +3,14 @@ const require_header_utils = require('../header-utils.cjs');
3
3
  const require_sse_response = require('../shared/sse-response.cjs');
4
4
 
5
5
  //#region src/v2/runtime/handlers/sse/connect.ts
6
- function handleSseConnect({ runtime, request, agentId, threadId }) {
6
+ function handleSseConnect({ runtime, request, agentId, threadId, agent }) {
7
7
  return require_sse_response.createSseEventResponse({
8
8
  request,
9
9
  debugEventBus: runtime.debugEventBus,
10
10
  agentId,
11
11
  observableFactory: () => runtime.runner.connect({
12
12
  threadId,
13
- headers: require_header_utils.extractForwardableHeaders(request)
13
+ headers: require_header_utils.mergeForwardableHeaders(agent?.headers, request, runtime.forwardHeadersPolicy ?? require_header_utils.resolveForwardHeadersPolicy(void 0))
14
14
  })
15
15
  });
16
16
  }
@@ -1 +1 @@
1
- {"version":3,"file":"connect.cjs","names":["createSseEventResponse","extractForwardableHeaders"],"sources":["../../../../../src/v2/runtime/handlers/sse/connect.ts"],"sourcesContent":["import { CopilotRuntimeLike } from \"../../core/runtime\";\nimport { createSseEventResponse } from \"../shared/sse-response\";\nimport { extractForwardableHeaders } from \"../header-utils\";\n\ninterface HandleSseConnectParams {\n runtime: CopilotRuntimeLike;\n request: Request;\n agentId: string;\n threadId: string;\n}\n\nexport function handleSseConnect({\n runtime,\n request,\n agentId,\n threadId,\n}: HandleSseConnectParams): Response {\n return createSseEventResponse({\n request,\n debugEventBus: runtime.debugEventBus,\n // Forward the real agentId so debug envelopes reflect the agent the\n // route resolved to — not the literal string \"connect\".\n agentId,\n observableFactory: () =>\n runtime.runner.connect({\n threadId,\n headers: extractForwardableHeaders(request),\n }),\n });\n}\n"],"mappings":";;;;;AAWA,SAAgB,iBAAiB,EAC/B,SACA,SACA,SACA,YACmC;AACnC,QAAOA,4CAAuB;EAC5B;EACA,eAAe,QAAQ;EAGvB;EACA,yBACE,QAAQ,OAAO,QAAQ;GACrB;GACA,SAASC,+CAA0B,QAAQ;GAC5C,CAAC;EACL,CAAC"}
1
+ {"version":3,"file":"connect.cjs","names":["createSseEventResponse","mergeForwardableHeaders","resolveForwardHeadersPolicy"],"sources":["../../../../../src/v2/runtime/handlers/sse/connect.ts"],"sourcesContent":["import type { AbstractAgent } from \"@ag-ui/client\";\nimport type { CopilotRuntimeLike } from \"../../core/runtime\";\nimport { createSseEventResponse } from \"../shared/sse-response\";\nimport {\n mergeForwardableHeaders,\n resolveForwardHeadersPolicy,\n} from \"../header-utils\";\n\n/**\n * `headers` lives on the HTTP-backed agent configs (e.g. `HttpAgent`), not on\n * the base `AbstractAgent`. Mirror the runtime's own optional-headers shape so\n * we can read server-configured headers off the per-request clone without a\n * cast. See `agent-utils.ts`.\n */\ntype AgentWithHeaders = AbstractAgent & {\n headers?: Record<string, string>;\n};\n\ninterface HandleSseConnectParams {\n runtime: CopilotRuntimeLike;\n request: Request;\n agentId: string;\n threadId: string;\n /**\n * The per-request agent clone, carrying any server-configured `agent.headers`\n * (e.g. service-to-service auth). Used only to compute the merged header set\n * threaded into `runner.connect` below — see the note there for why that\n * merge is forward-looking plumbing rather than active outbound auth today.\n */\n agent?: AgentWithHeaders;\n}\n\nexport function handleSseConnect({\n runtime,\n request,\n agentId,\n threadId,\n agent,\n}: HandleSseConnectParams): Response {\n return createSseEventResponse({\n request,\n debugEventBus: runtime.debugEventBus,\n // Forward the real agentId so debug envelopes reflect the agent the\n // route resolved to — not the literal string \"connect\".\n agentId,\n observableFactory: () =>\n runtime.runner.connect({\n threadId,\n // Forward-looking plumbing: we compute the merged header set (server\n // `agent.headers` win on collision, case-insensitively; non-colliding\n // inbound headers still forward — see `mergeForwardableHeaders`, #5712)\n // and thread it into `runner.connect`. NO shipped runner consumes the\n // `headers` field of `AgentRunnerConnectRequest` today — every runner\n // (in-memory, intelligence, telemetry, sqlite) reads only `threadId`.\n // The real outbound header forwarding is the /run path, where\n // `cloneAgentForRequest` mutates `agent.headers` directly\n // (agent-utils.ts). This wiring exists so a future outbound-connecting\n // runner can pick the merged headers up without a route change; the\n // collision precedence noted here is purely about that merge, not about\n // middleware/mutation parity with /run.\n headers: mergeForwardableHeaders(\n agent?.headers,\n request,\n // Optional on `CopilotRuntimeLike` (non-breaking minor release);\n // coalesce a policy-less external implementor to the default resolved\n // policy (default-on denylist) instead of dereffing undefined.\n runtime.forwardHeadersPolicy ??\n resolveForwardHeadersPolicy(undefined),\n ),\n }),\n });\n}\n"],"mappings":";;;;;AAgCA,SAAgB,iBAAiB,EAC/B,SACA,SACA,SACA,UACA,SACmC;AACnC,QAAOA,4CAAuB;EAC5B;EACA,eAAe,QAAQ;EAGvB;EACA,yBACE,QAAQ,OAAO,QAAQ;GACrB;GAaA,SAASC,6CACP,OAAO,SACP,SAIA,QAAQ,wBACNC,iDAA4B,OAAU,CACzC;GACF,CAAC;EACL,CAAC"}
@@ -1,16 +1,16 @@
1
1
  import "reflect-metadata";
2
- import { extractForwardableHeaders } from "../header-utils.mjs";
2
+ import { mergeForwardableHeaders, resolveForwardHeadersPolicy } from "../header-utils.mjs";
3
3
  import { createSseEventResponse } from "../shared/sse-response.mjs";
4
4
 
5
5
  //#region src/v2/runtime/handlers/sse/connect.ts
6
- function handleSseConnect({ runtime, request, agentId, threadId }) {
6
+ function handleSseConnect({ runtime, request, agentId, threadId, agent }) {
7
7
  return createSseEventResponse({
8
8
  request,
9
9
  debugEventBus: runtime.debugEventBus,
10
10
  agentId,
11
11
  observableFactory: () => runtime.runner.connect({
12
12
  threadId,
13
- headers: extractForwardableHeaders(request)
13
+ headers: mergeForwardableHeaders(agent?.headers, request, runtime.forwardHeadersPolicy ?? resolveForwardHeadersPolicy(void 0))
14
14
  })
15
15
  });
16
16
  }
@@ -1 +1 @@
1
- {"version":3,"file":"connect.mjs","names":[],"sources":["../../../../../src/v2/runtime/handlers/sse/connect.ts"],"sourcesContent":["import { CopilotRuntimeLike } from \"../../core/runtime\";\nimport { createSseEventResponse } from \"../shared/sse-response\";\nimport { extractForwardableHeaders } from \"../header-utils\";\n\ninterface HandleSseConnectParams {\n runtime: CopilotRuntimeLike;\n request: Request;\n agentId: string;\n threadId: string;\n}\n\nexport function handleSseConnect({\n runtime,\n request,\n agentId,\n threadId,\n}: HandleSseConnectParams): Response {\n return createSseEventResponse({\n request,\n debugEventBus: runtime.debugEventBus,\n // Forward the real agentId so debug envelopes reflect the agent the\n // route resolved to — not the literal string \"connect\".\n agentId,\n observableFactory: () =>\n runtime.runner.connect({\n threadId,\n headers: extractForwardableHeaders(request),\n }),\n });\n}\n"],"mappings":";;;;;AAWA,SAAgB,iBAAiB,EAC/B,SACA,SACA,SACA,YACmC;AACnC,QAAO,uBAAuB;EAC5B;EACA,eAAe,QAAQ;EAGvB;EACA,yBACE,QAAQ,OAAO,QAAQ;GACrB;GACA,SAAS,0BAA0B,QAAQ;GAC5C,CAAC;EACL,CAAC"}
1
+ {"version":3,"file":"connect.mjs","names":[],"sources":["../../../../../src/v2/runtime/handlers/sse/connect.ts"],"sourcesContent":["import type { AbstractAgent } from \"@ag-ui/client\";\nimport type { CopilotRuntimeLike } from \"../../core/runtime\";\nimport { createSseEventResponse } from \"../shared/sse-response\";\nimport {\n mergeForwardableHeaders,\n resolveForwardHeadersPolicy,\n} from \"../header-utils\";\n\n/**\n * `headers` lives on the HTTP-backed agent configs (e.g. `HttpAgent`), not on\n * the base `AbstractAgent`. Mirror the runtime's own optional-headers shape so\n * we can read server-configured headers off the per-request clone without a\n * cast. See `agent-utils.ts`.\n */\ntype AgentWithHeaders = AbstractAgent & {\n headers?: Record<string, string>;\n};\n\ninterface HandleSseConnectParams {\n runtime: CopilotRuntimeLike;\n request: Request;\n agentId: string;\n threadId: string;\n /**\n * The per-request agent clone, carrying any server-configured `agent.headers`\n * (e.g. service-to-service auth). Used only to compute the merged header set\n * threaded into `runner.connect` below — see the note there for why that\n * merge is forward-looking plumbing rather than active outbound auth today.\n */\n agent?: AgentWithHeaders;\n}\n\nexport function handleSseConnect({\n runtime,\n request,\n agentId,\n threadId,\n agent,\n}: HandleSseConnectParams): Response {\n return createSseEventResponse({\n request,\n debugEventBus: runtime.debugEventBus,\n // Forward the real agentId so debug envelopes reflect the agent the\n // route resolved to — not the literal string \"connect\".\n agentId,\n observableFactory: () =>\n runtime.runner.connect({\n threadId,\n // Forward-looking plumbing: we compute the merged header set (server\n // `agent.headers` win on collision, case-insensitively; non-colliding\n // inbound headers still forward — see `mergeForwardableHeaders`, #5712)\n // and thread it into `runner.connect`. NO shipped runner consumes the\n // `headers` field of `AgentRunnerConnectRequest` today — every runner\n // (in-memory, intelligence, telemetry, sqlite) reads only `threadId`.\n // The real outbound header forwarding is the /run path, where\n // `cloneAgentForRequest` mutates `agent.headers` directly\n // (agent-utils.ts). This wiring exists so a future outbound-connecting\n // runner can pick the merged headers up without a route change; the\n // collision precedence noted here is purely about that merge, not about\n // middleware/mutation parity with /run.\n headers: mergeForwardableHeaders(\n agent?.headers,\n request,\n // Optional on `CopilotRuntimeLike` (non-breaking minor release);\n // coalesce a policy-less external implementor to the default resolved\n // policy (default-on denylist) instead of dereffing undefined.\n runtime.forwardHeadersPolicy ??\n resolveForwardHeadersPolicy(undefined),\n ),\n }),\n });\n}\n"],"mappings":";;;;;AAgCA,SAAgB,iBAAiB,EAC/B,SACA,SACA,SACA,UACA,SACmC;AACnC,QAAO,uBAAuB;EAC5B;EACA,eAAe,QAAQ;EAGvB;EACA,yBACE,QAAQ,OAAO,QAAQ;GACrB;GAaA,SAAS,wBACP,OAAO,SACP,SAIA,QAAQ,wBACN,4BAA4B,OAAU,CACzC;GACF,CAAC;EACL,CAAC"}
@@ -10,7 +10,7 @@ import { createCopilotEndpointSingleRoute } from "./endpoints/hono-single.cjs";
10
10
  import { CopilotExpressEndpointParams, createCopilotExpressHandler } from "./endpoints/express.cjs";
11
11
  import { createCopilotEndpointSingleRouteExpress } from "./endpoints/express-single.cjs";
12
12
  import "./endpoints/index.cjs";
13
- import { InMemoryAgentRunner, InMemoryThread } from "./runner/in-memory.cjs";
13
+ import { InMemoryAgentRunner, InMemoryLimits, InMemoryThread, ɵBoundedThreadStore, ɵGLOBAL_STORE, ɵINMEMORY_DEFAULTS, ɵestimateBytes } from "./runner/in-memory.cjs";
14
14
  import { IntelligenceAgentRunner, IntelligenceAgentRunnerOptions, RunnerStartupBoundary } from "./runner/intelligence.cjs";
15
15
  import { finalizeRunEvents } from "./runner/index.cjs";
16
16
  import { CopilotRuntimeFetchHandler, CopilotRuntimeHandlerOptions, createCopilotRuntimeHandler } from "./core/fetch-handler.cjs";
@@ -10,7 +10,7 @@ import { createCopilotEndpointSingleRoute } from "./endpoints/hono-single.mjs";
10
10
  import { CopilotExpressEndpointParams, createCopilotExpressHandler } from "./endpoints/express.mjs";
11
11
  import { createCopilotEndpointSingleRouteExpress } from "./endpoints/express-single.mjs";
12
12
  import "./endpoints/index.mjs";
13
- import { InMemoryAgentRunner, InMemoryThread } from "./runner/in-memory.mjs";
13
+ import { InMemoryAgentRunner, InMemoryLimits, InMemoryThread, ɵBoundedThreadStore, ɵGLOBAL_STORE, ɵINMEMORY_DEFAULTS, ɵestimateBytes } from "./runner/in-memory.mjs";
14
14
  import { IntelligenceAgentRunner, IntelligenceAgentRunnerOptions, RunnerStartupBoundary } from "./runner/intelligence.mjs";
15
15
  import { finalizeRunEvents } from "./runner/index.mjs";
16
16
  import { CopilotRuntimeFetchHandler, CopilotRuntimeHandlerOptions, createCopilotRuntimeHandler } from "./core/fetch-handler.mjs";
@@ -134,11 +134,12 @@ var CopilotKitIntelligence = class {
134
134
  ɵisEnterpriseLearningEnabled() {
135
135
  return this.#enterpriseLearningEnabled;
136
136
  }
137
- async #request(method, path, body) {
137
+ async #request(method, path, body, extraHeaders) {
138
138
  const url = `${this.#apiUrl}${path}`;
139
139
  const headers = {
140
140
  Authorization: `Bearer ${this.#apiKey}`,
141
- "Content-Type": "application/json"
141
+ "Content-Type": "application/json",
142
+ ...extraHeaders
142
143
  };
143
144
  const response = await fetch(url, {
144
145
  method,
@@ -189,10 +190,78 @@ var CopilotKitIntelligence = class {
189
190
  const qs = new URLSearchParams(query).toString();
190
191
  return this.#request("GET", `/api/threads?${qs}`);
191
192
  }
193
+ /**
194
+ * List the given user's long-term memories, newest first.
195
+ *
196
+ * The platform scopes by the opaque app user supplied in the
197
+ * `x-cpki-user-id` header (resolved by the runtime via `identifyUser`),
198
+ * not a query param. Pass `includeInvalidated` to also return retired rows.
199
+ *
200
+ * @returns The `{ memories }` envelope the client memory store consumes.
201
+ * @throws {@link PlatformRequestError} on non-2xx responses.
202
+ */
203
+ async listMemories(params) {
204
+ const qs = params.includeInvalidated ? "?includeInvalidated=true" : "";
205
+ return this.#request("GET", `/api/memories${qs}`, void 0, { [INTELLIGENCE_USER_ID_HEADER]: params.userId });
206
+ }
207
+ /**
208
+ * Create a memory for the given user (platform `POST /api/memories`).
209
+ * @returns The stored memory; `absorbed` is true if the content was merged
210
+ * into a near-duplicate rather than inserted as a new row.
211
+ * @throws {@link PlatformRequestError} on non-2xx responses.
212
+ */
213
+ async createMemory(params) {
214
+ return this.#request("POST", `/api/memories`, {
215
+ content: params.content,
216
+ kind: params.kind,
217
+ ...params.scope !== void 0 ? { scope: params.scope } : {},
218
+ sourceThreadIds: params.sourceThreadIds ?? []
219
+ }, { [INTELLIGENCE_USER_ID_HEADER]: params.userId });
220
+ }
221
+ /**
222
+ * Supersede an existing memory (platform `PATCH /api/memories/:id`). The
223
+ * `:id` row is retired and a new memory with the supplied content is
224
+ * inserted atomically.
225
+ * @returns The new memory plus `retiredId` (the id of the retired row).
226
+ * @throws {@link PlatformRequestError} on non-2xx responses (e.g. 404 when
227
+ * `:id` is not a live, same-scope memory for this user).
228
+ */
229
+ async updateMemory(params) {
230
+ return this.#request("PATCH", `/api/memories/${encodeURIComponent(params.id)}`, {
231
+ content: params.content,
232
+ kind: params.kind,
233
+ ...params.scope !== void 0 ? { scope: params.scope } : {},
234
+ sourceThreadIds: params.sourceThreadIds ?? []
235
+ }, { [INTELLIGENCE_USER_ID_HEADER]: params.userId });
236
+ }
237
+ /**
238
+ * Non-lossily retire (forget) a memory (platform `DELETE /api/memories/:id`).
239
+ * @throws {@link PlatformRequestError} on non-2xx responses.
240
+ */
241
+ async removeMemory(params) {
242
+ await this.#request("DELETE", `/api/memories/${encodeURIComponent(params.id)}`, void 0, { [INTELLIGENCE_USER_ID_HEADER]: params.userId });
243
+ }
192
244
  async ɵsubscribeToThreads(params) {
193
245
  return this.#request("POST", "/api/threads/subscribe", { userId: params.userId });
194
246
  }
195
247
  /**
248
+ * Mint memory-realtime join credentials (platform `POST
249
+ * /api/memories/subscribe`). Returns both the single-use `joinToken` and the
250
+ * per-user `joinCode` the client needs to build the
251
+ * `user_meta:memories:<joinCode>` channel topic.
252
+ *
253
+ * The user is supplied via the `x-cpki-user-id` header — the same way every
254
+ * other memory endpoint (`listMemories`/`createMemory`/…) identifies the app
255
+ * user — because the platform's memory routes resolve identity from that
256
+ * header, not the body. (This differs from `ɵsubscribeToThreads`, whose
257
+ * platform endpoint reads `userId` from the body.)
258
+ *
259
+ * @throws {@link PlatformRequestError} on non-2xx responses.
260
+ */
261
+ async ɵsubscribeToMemories(params) {
262
+ return this.#request("POST", "/api/memories/subscribe", void 0, { [INTELLIGENCE_USER_ID_HEADER]: params.userId });
263
+ }
264
+ /**
196
265
  * Update thread metadata (e.g. name).
197
266
  *
198
267
  * Triggers the `onThreadUpdated` lifecycle callback on success.
@@ -1 +1 @@
1
- {"version":3,"file":"client.cjs","names":["#apiUrl","#runnerWsUrl","#clientWsUrl","#apiKey","#enterpriseLearningEnabled","#threadCreatedListeners","#threadUpdatedListeners","#threadDeletedListeners","#request","#invokeLifecycleCallback"],"sources":["../../../../src/v2/runtime/intelligence-platform/client.ts"],"sourcesContent":["import { logger } from \"@copilotkit/shared\";\nimport { randomUUID } from \"crypto\";\n\n/**\n * Header name carrying the per-call end-user identity that the CopilotKit\n * Intelligence `/mcp` endpoint requires. Internal CopilotKit machinery —\n * `attachIntelligenceEnterpriseLearning` resolves the user via `identifyUser`\n * and bakes this header onto the `MCPMiddleware`'s transport config, so every\n * outbound MCP request stamps `X-Cpki-User-Id: <userId>`. Not part of the\n * public user API.\n *\n * @internal\n */\nexport const INTELLIGENCE_USER_ID_HEADER = \"x-cpki-user-id\";\n\n/**\n * Error thrown when an Intelligence platform HTTP request returns a non-2xx\n * status. Carries the HTTP {@link status} code so callers can branch on\n * specific failures (e.g. 404 for \"not found\", 409 for \"conflict\") without\n * parsing the error message string.\n *\n * @example\n * ```ts\n * try {\n * await intelligence.getThread({ threadId, userId });\n * } catch (error) {\n * if (error instanceof PlatformRequestError && error.status === 404) {\n * // thread does not exist yet\n * }\n * }\n * ```\n */\nexport class PlatformRequestError extends Error {\n constructor(\n message: string,\n /** The HTTP status code returned by the platform (e.g. 404, 409, 500). */\n public readonly status: number,\n ) {\n super(message);\n this.name = \"PlatformRequestError\";\n }\n}\n\n/**\n * Client for the CopilotKit Intelligence Platform REST API.\n *\n * Construct the client once and pass it to any consumers that need it\n * (e.g. `CopilotRuntime`, `IntelligenceAgentRunner`):\n *\n * ```ts\n * import { CopilotKitIntelligence, CopilotRuntime } from \"@copilotkit/runtime\";\n *\n * const intelligence = new CopilotKitIntelligence({\n * apiUrl: \"https://api.copilotkit.ai\",\n * wsUrl: \"wss://api.copilotkit.ai\",\n * apiKey: process.env.COPILOTKIT_API_KEY!,\n * });\n *\n * const runtime = new CopilotRuntime({\n * agents,\n * intelligence,\n * });\n * ```\n */\n\n/** Payload passed to `onThreadDeleted` listeners. */\nexport interface ThreadDeletedPayload {\n threadId: string;\n userId: string;\n agentId: string;\n}\n\nexport interface CopilotKitIntelligenceConfig {\n /** Base URL of the intelligence platform API, e.g. \"https://api.copilotkit.ai\" */\n apiUrl: string;\n /** Intelligence websocket base URL. Runner and client socket URLs are derived from this. */\n wsUrl: string;\n /** API key for authenticating with the intelligence platform */\n apiKey: string;\n /**\n * Enable Enterprise Learning — expose the Intelligence platform's\n * built-in tools (bash + thread/memory tools) to agent runs on an\n * intelligence runtime that resolve a user. Attached uniformly across\n * agent frameworks by `attachIntelligenceEnterpriseLearning` via\n * `@ag-ui/mcp-middleware`, with the resolved user-id and project apiKey\n * baked into the transport headers for that request's clone.\n *\n * Defaults to `false` — opt-in. Existing intelligence setups continue\n * to work without these tools unless they flip this flag.\n */\n enableEnterpriseLearning?: boolean;\n /**\n * Initial listener invoked after a thread is created.\n * Prefer {@link CopilotKitIntelligence.onThreadCreated} for multiple listeners.\n */\n onThreadCreated?: (thread: ThreadSummary) => void;\n /**\n * Initial listener invoked after a thread is updated.\n * Prefer {@link CopilotKitIntelligence.onThreadUpdated} for multiple listeners.\n */\n onThreadUpdated?: (thread: ThreadSummary) => void;\n /**\n * Initial listener invoked after a thread is deleted.\n * Prefer {@link CopilotKitIntelligence.onThreadDeleted} for multiple listeners.\n */\n onThreadDeleted?: (params: ThreadDeletedPayload) => void;\n}\n\n/**\n * Summary metadata for a single thread returned by the platform.\n *\n * This is the shape returned by list, get, create, and update operations.\n * It does not include the thread's message history — use\n * {@link CopilotKitIntelligence.getThreadMessages} for that.\n */\nexport interface ThreadSummary {\n /** Platform-assigned unique identifier. */\n id: string;\n /** Human-readable display name, or `null` if the thread has not been named. */\n name: string | null;\n /** ISO-8601 timestamp of the most recent agent run on this thread. */\n lastRunAt?: string;\n /** ISO-8601 timestamp of the most recent metadata update. */\n lastUpdatedAt?: string;\n /** ISO-8601 timestamp when the thread was created. */\n createdAt?: string;\n /** ISO-8601 timestamp when the thread was last updated. */\n updatedAt?: string;\n /** Whether the thread has been archived. Archived threads are excluded from default list results. */\n archived?: boolean;\n /** The agent that owns this thread. */\n agentId?: string;\n /** The user who created this thread. */\n createdById?: string;\n /** The organization this thread belongs to. */\n organizationId?: string;\n}\n\n/** Response from listing threads for a user/agent pair. */\nexport interface ListThreadsResponse {\n /** The matching threads, sorted by the platform's default ordering. */\n threads: ThreadSummary[];\n /** Join code for subscribing to realtime metadata updates for these threads. */\n joinCode: string;\n /** Short-lived token for authenticating the realtime subscription. */\n joinToken?: string;\n /** Opaque cursor for fetching the next page. `null` or absent when there are no more pages. */\n nextCursor?: string | null;\n}\n\n/**\n * Fields that can be updated on a thread via {@link CopilotKitIntelligence.updateThread}.\n *\n * Additional platform-specific fields can be passed as extra keys and will be\n * forwarded to the PATCH request body.\n */\nexport interface UpdateThreadRequest {\n /** New human-readable display name for the thread. */\n name?: string;\n [key: string]: unknown;\n}\n\n/** Parameters for creating a new thread via {@link CopilotKitIntelligence.createThread}. */\nexport interface CreateThreadRequest {\n /** Client-generated unique identifier for the new thread. */\n threadId: string;\n /** The user creating the thread. Used for authorization and scoping. */\n userId: string;\n /** The agent this thread belongs to. */\n agentId: string;\n /** Optional initial display name. If omitted, the thread is unnamed until explicitly renamed. */\n name?: string;\n}\n\n/** Credentials returned when locking or joining a thread's realtime channel. */\nexport interface ThreadConnectionResponse {\n /** Canonical platform thread identifier for the run or connection. */\n threadId: string;\n /** Canonical platform run identifier for an active run lock. */\n runId?: string;\n /** Short-lived token for authenticating the Phoenix channel join. */\n joinToken: string;\n /** Lock metadata echoed back by the platform. */\n lock?: ThreadLockInfo;\n}\n\nexport interface SubscribeToThreadsRequest {\n userId: string;\n}\n\nexport interface SubscribeToThreadsResponse {\n joinToken: string;\n}\n\nexport type ConnectThreadResponse = ThreadConnectionResponse | null;\n\nexport interface AcquireThreadLockResponse extends ThreadConnectionResponse {\n /** Canonical platform run identifier for the acquired lock. */\n runId: string;\n}\n\n/**\n * Parameters for annotating a thread event via\n * {@link CopilotKitIntelligence.annotate}. The runtime resolves `userId`\n * from the customer's BFF auth before calling this; the platform prefixes\n * it with the project id at write time.\n *\n * `payload` is the type-specific JSON blob for the annotation (e.g. a\n * `\"user_action\"` event carries the recorded fields, a\n * `\"set_learning_containers\"` event carries the container list). The exact\n * shape per type is validated by the Intelligence backend; canonical shapes\n * are documented on the Intelligence react-core side.\n */\nexport interface AnnotateParams {\n /** The user the annotation belongs to. */\n userId: string;\n /** The thread the annotation is associated with. May be unknown to the platform. */\n threadId: string;\n /**\n * Discriminator identifying the annotation type.\n * Must match a type known to the Intelligence platform\n * (e.g. `\"user_action\"`, `\"set_learning_containers\"`).\n */\n type: string;\n /** Type-specific payload. Shape varies by `type`. */\n payload?: unknown;\n /**\n * Caller-supplied idempotency key (any RFC-compliant UUID). When omitted,\n * a UUID is auto-generated. Every call hits the platform's idempotent\n * `PUT /connector/annotate/:clientEventId` endpoint; a retry with the\n * same id collapses to the original row.\n */\n clientEventId?: string;\n /** ISO-8601 client-asserted timestamp. Defaults to server NOW() when absent. */\n occurredAt?: string;\n}\n\n/** Response from {@link CopilotKitIntelligence.annotate}. */\nexport interface AnnotateResponse {\n /** Database id of the annotation row (BIGINT, returned as a string). */\n id: string;\n /**\n * True when the platform recognized the `clientEventId` as a retry of\n * a previous call and returned the original row id instead of inserting\n * a new one.\n */\n duplicate: boolean;\n}\n\n/** A single message within a thread's persisted history. */\nexport interface ThreadMessage {\n /** Unique identifier for this message. */\n id: string;\n /** Message role, e.g. `\"user\"`, `\"assistant\"`, `\"tool\"`. */\n role: string;\n /** Text content of the message. May be absent for tool-call-only messages. */\n content?: string;\n /** Tool calls initiated by this message (assistant role only). */\n toolCalls?: Array<{\n id: string;\n name: string;\n /** JSON-encoded arguments passed to the tool. */\n args: string;\n }>;\n /** For tool-result messages, the ID of the tool call this message responds to. */\n toolCallId?: string;\n}\n\n/** Response from {@link CopilotKitIntelligence.getThreadMessages}. */\nexport interface ThreadMessagesResponse {\n messages: ThreadMessage[];\n}\n\n/**\n * Persisted AG-UI event for the inspector's debugging views. The platform\n * stores raw events keyed by run; the `_inspect` route returns them in\n * replay order (oldest first) across every run that targeted the thread.\n */\nexport interface ThreadInspectEvent {\n type: string;\n [key: string]: unknown;\n}\n\n/**\n * Response from {@link CopilotKitIntelligence.getThreadEvents}. Mirrors the\n * `ThreadEventsResult` shape returned by the platform's\n * `GET /api/_inspect/threads/:id/events` endpoint.\n */\nexport interface ThreadEventsResponse {\n events: ThreadInspectEvent[];\n /** Row IDs the platform failed to decode (raw column corrupted). */\n decodeErrorRowIds: string[];\n /** True when the platform hit its per-thread event cap. */\n truncated: boolean;\n}\n\n/**\n * Response from {@link CopilotKitIntelligence.getThreadState}. Mirrors the\n * discriminated `ThreadStateResult` returned by the platform's\n * `GET /api/_inspect/threads/:id/state` endpoint, which folds RFC 6902\n * STATE_DELTA events on top of the latest STATE_SNAPSHOT.\n */\nexport type ThreadStateResponse =\n | { kind: \"no-snapshot\" }\n | { kind: \"snapshot-decode-error\" }\n | { kind: \"snapshot\"; state: unknown; skippedDeltas: number };\n\nexport interface AcquireThreadLockRequest {\n threadId: string;\n runId: string;\n userId: string;\n agentId: string;\n /** Custom Redis key prefix for the lock (default: \"thread\"). */\n lockKeyPrefix?: string;\n /** Lock TTL in seconds. When set, the lock auto-expires after this duration. */\n ttlSeconds?: number;\n}\n\nexport interface RenewThreadLockRequest {\n threadId: string;\n runId: string;\n /** New TTL to set on the lock in seconds. */\n ttlSeconds: number;\n /** Must match the prefix used when acquiring. */\n lockKeyPrefix?: string;\n}\n\nexport interface CleanupThreadLockRequest {\n threadId: string;\n runId: string;\n}\n\nexport interface RenewThreadLockResponse {\n ttlSeconds: number;\n}\n\nexport interface ThreadLockInfo {\n key: string;\n ttlSeconds: number | null;\n}\n\ninterface ThreadEnvelope {\n thread: ThreadSummary;\n}\n\nexport class CopilotKitIntelligence {\n #apiUrl: string;\n #runnerWsUrl: string;\n #clientWsUrl: string;\n #apiKey: string;\n #enterpriseLearningEnabled: boolean;\n #threadCreatedListeners = new Set<(thread: ThreadSummary) => void>();\n #threadUpdatedListeners = new Set<(thread: ThreadSummary) => void>();\n #threadDeletedListeners = new Set<(params: ThreadDeletedPayload) => void>();\n\n constructor(config: CopilotKitIntelligenceConfig) {\n const intelligenceWsUrl = normalizeIntelligenceWsUrl(config.wsUrl);\n\n this.#apiUrl = config.apiUrl.replace(/\\/$/, \"\");\n this.#runnerWsUrl = deriveRunnerWsUrl(intelligenceWsUrl);\n this.#clientWsUrl = deriveClientWsUrl(intelligenceWsUrl);\n this.#apiKey = config.apiKey;\n this.#enterpriseLearningEnabled = config.enableEnterpriseLearning ?? false;\n\n if (config.onThreadCreated) {\n this.onThreadCreated(config.onThreadCreated);\n }\n if (config.onThreadUpdated) {\n this.onThreadUpdated(config.onThreadUpdated);\n }\n if (config.onThreadDeleted) {\n this.onThreadDeleted(config.onThreadDeleted);\n }\n }\n\n /**\n * Register a listener invoked whenever a thread is created.\n *\n * Multiple listeners can be registered. Each call returns an unsubscribe\n * function that removes the listener when called.\n *\n * @param callback - Receives the newly created {@link ThreadSummary}.\n * @returns A function that removes this listener when called.\n *\n * @example\n * ```ts\n * const unsubscribe = intelligence.onThreadCreated((thread) => {\n * console.log(\"Thread created:\", thread.id);\n * });\n * // later…\n * unsubscribe();\n * ```\n */\n onThreadCreated(callback: (thread: ThreadSummary) => void): () => void {\n this.#threadCreatedListeners.add(callback);\n return () => {\n this.#threadCreatedListeners.delete(callback);\n };\n }\n\n /**\n * Register a listener invoked whenever a thread is updated (including archive).\n *\n * Multiple listeners can be registered. Each call returns an unsubscribe\n * function that removes the listener when called.\n *\n * @param callback - Receives the updated {@link ThreadSummary}.\n * @returns A function that removes this listener when called.\n */\n onThreadUpdated(callback: (thread: ThreadSummary) => void): () => void {\n this.#threadUpdatedListeners.add(callback);\n return () => {\n this.#threadUpdatedListeners.delete(callback);\n };\n }\n\n /**\n * Register a listener invoked whenever a thread is deleted.\n *\n * Multiple listeners can be registered. Each call returns an unsubscribe\n * function that removes the listener when called.\n *\n * @param callback - Receives the {@link ThreadDeletedPayload} identifying\n * the deleted thread.\n * @returns A function that removes this listener when called.\n */\n onThreadDeleted(\n callback: (params: ThreadDeletedPayload) => void,\n ): () => void {\n this.#threadDeletedListeners.add(callback);\n return () => {\n this.#threadDeletedListeners.delete(callback);\n };\n }\n\n ɵgetApiUrl(): string {\n return this.#apiUrl;\n }\n\n ɵgetRunnerWsUrl(): string {\n return this.#runnerWsUrl;\n }\n\n ɵgetClientWsUrl(): string {\n return this.#clientWsUrl;\n }\n\n ɵgetRunnerAuthToken(): string {\n return this.#apiKey;\n }\n\n /** @internal Used by `attachIntelligenceEnterpriseLearning` to populate `Authorization`. */\n ɵgetApiKey(): string {\n return this.#apiKey;\n }\n\n /** @internal Used by `attachIntelligenceEnterpriseLearning` to gate MCP attachment. */\n ɵisEnterpriseLearningEnabled(): boolean {\n return this.#enterpriseLearningEnabled;\n }\n\n async #request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const url = `${this.#apiUrl}${path}`;\n\n const headers: Record<string, string> = {\n Authorization: `Bearer ${this.#apiKey}`,\n \"Content-Type\": \"application/json\",\n };\n\n const response = await fetch(url, {\n method,\n headers,\n body: body ? JSON.stringify(body) : undefined,\n });\n\n if (!response.ok) {\n const text = await response.text().catch(() => \"\");\n logger.error(\n { status: response.status, body: text, path },\n \"Intelligence platform request failed\",\n );\n throw new PlatformRequestError(\n `Intelligence platform error ${response.status}: ${text || response.statusText}`,\n response.status,\n );\n }\n\n const text = await response.text();\n if (!text) {\n return undefined as T;\n }\n return JSON.parse(text) as T;\n }\n\n #invokeLifecycleCallback(\n callbackName: \"onThreadCreated\" | \"onThreadUpdated\" | \"onThreadDeleted\",\n payload: ThreadSummary | ThreadDeletedPayload,\n ): void {\n const listeners =\n callbackName === \"onThreadCreated\"\n ? this.#threadCreatedListeners\n : callbackName === \"onThreadUpdated\"\n ? this.#threadUpdatedListeners\n : this.#threadDeletedListeners;\n\n for (const callback of listeners) {\n try {\n (callback as (p: typeof payload) => void)(payload);\n } catch (error) {\n logger.error(\n { err: error, callbackName, payload },\n \"Intelligence lifecycle callback failed\",\n );\n }\n }\n }\n\n /**\n * List all non-archived threads for a given user and agent.\n *\n * @param params.userId - User whose threads to list.\n * @param params.agentId - Agent whose threads to list.\n * @returns The thread list along with realtime subscription credentials.\n * @throws {@link PlatformRequestError} on non-2xx responses.\n */\n async listThreads(params: {\n userId: string;\n agentId: string;\n includeArchived?: boolean;\n limit?: number;\n cursor?: string;\n }): Promise<ListThreadsResponse> {\n const query: Record<string, string> = {\n userId: params.userId,\n agentId: params.agentId,\n };\n if (params.includeArchived) query.includeArchived = \"true\";\n if (params.limit != null) query.limit = String(params.limit);\n if (params.cursor) query.cursor = params.cursor;\n\n const qs = new URLSearchParams(query).toString();\n return this.#request<ListThreadsResponse>(\"GET\", `/api/threads?${qs}`);\n }\n\n async ɵsubscribeToThreads(\n params: SubscribeToThreadsRequest,\n ): Promise<SubscribeToThreadsResponse> {\n return this.#request<SubscribeToThreadsResponse>(\n \"POST\",\n \"/api/threads/subscribe\",\n {\n userId: params.userId,\n },\n );\n }\n\n /**\n * Update thread metadata (e.g. name).\n *\n * Triggers the `onThreadUpdated` lifecycle callback on success.\n *\n * @returns The updated thread summary.\n * @throws {@link PlatformRequestError} on non-2xx responses.\n */\n async updateThread(params: {\n threadId: string;\n userId: string;\n agentId: string;\n updates: UpdateThreadRequest;\n }): Promise<ThreadSummary> {\n const response = await this.#request<ThreadEnvelope>(\n \"PATCH\",\n `/api/threads/${encodeURIComponent(params.threadId)}`,\n {\n userId: params.userId,\n agentId: params.agentId,\n ...params.updates,\n },\n );\n this.#invokeLifecycleCallback(\"onThreadUpdated\", response.thread);\n return response.thread;\n }\n\n /**\n * Create a new thread on the platform.\n *\n * Triggers the `onThreadCreated` lifecycle callback on success.\n *\n * @returns The newly created thread summary.\n * @throws {@link PlatformRequestError} with status 409 if a thread with the\n * same `threadId` already exists.\n */\n async createThread(params: CreateThreadRequest): Promise<ThreadSummary> {\n const response = await this.#request<ThreadEnvelope>(\n \"POST\",\n `/api/threads`,\n {\n threadId: params.threadId,\n userId: params.userId,\n agentId: params.agentId,\n ...(params.name !== undefined ? { name: params.name } : {}),\n },\n );\n this.#invokeLifecycleCallback(\"onThreadCreated\", response.thread);\n return response.thread;\n }\n\n /**\n * Fetch a single thread by ID.\n *\n * @returns The thread summary.\n * @throws {@link PlatformRequestError} with status 404 if the thread does\n * not exist.\n */\n async getThread(params: {\n threadId: string;\n userId: string;\n }): Promise<ThreadSummary> {\n const qs = new URLSearchParams({ userId: params.userId }).toString();\n const response = await this.#request<ThreadEnvelope>(\n \"GET\",\n `/api/threads/${encodeURIComponent(params.threadId)}?${qs}`,\n );\n return response.thread;\n }\n\n /**\n * Get an existing thread or create it if it does not exist.\n *\n * Handles the race where a concurrent request creates the thread between\n * the initial 404 and the subsequent `createThread` call by catching the\n * 409 Conflict and retrying the get.\n *\n * Triggers the `onThreadCreated` lifecycle callback when a new thread is\n * created.\n *\n * @returns An object containing the thread and a `created` flag indicating\n * whether the thread was newly created (`true`) or already existed (`false`).\n * @throws {@link PlatformRequestError} on non-2xx responses other than\n * 404 (get) and 409 (create race).\n */\n async getOrCreateThread(\n params: CreateThreadRequest,\n ): Promise<{ thread: ThreadSummary; created: boolean }> {\n try {\n const thread = await this.getThread({\n threadId: params.threadId,\n userId: params.userId,\n });\n return { thread, created: false };\n } catch (error) {\n if (!(error instanceof PlatformRequestError && error.status === 404)) {\n throw error;\n }\n }\n\n try {\n const thread = await this.createThread(params);\n return { thread, created: true };\n } catch (error) {\n // Another request created the thread between our get and create — retry get.\n if (error instanceof PlatformRequestError && error.status === 409) {\n const thread = await this.getThread({\n threadId: params.threadId,\n userId: params.userId,\n });\n return { thread, created: false };\n }\n throw error;\n }\n }\n\n /**\n * Fetch the full message history for a thread.\n *\n * @returns All persisted messages in chronological order.\n * @throws {@link PlatformRequestError} on non-2xx responses.\n */\n async getThreadMessages(params: {\n threadId: string;\n userId: string;\n }): Promise<ThreadMessagesResponse> {\n const qs = new URLSearchParams({ userId: params.userId }).toString();\n return this.#request<ThreadMessagesResponse>(\n \"GET\",\n `/api/threads/${encodeURIComponent(params.threadId)}/messages?${qs}`,\n );\n }\n\n /**\n * Fetch the persisted AG-UI event stream for a thread.\n *\n * Backed by the platform's `GET /api/_inspect/threads/:id/events`\n * introspection endpoint (see Intelligence PR #144). Events are returned\n * in replay order across every run that targeted the thread. The\n * `_inspect/` prefix flags this as debug-only — production code paths\n * must not depend on it.\n *\n * @throws {@link PlatformRequestError} on non-2xx responses.\n */\n async getThreadEvents(params: {\n threadId: string;\n }): Promise<ThreadEventsResponse> {\n return this.#request<ThreadEventsResponse>(\n \"GET\",\n `/api/_inspect/threads/${encodeURIComponent(params.threadId)}/events`,\n );\n }\n\n /**\n * Fetch the current agent state for a thread.\n *\n * Backed by the platform's `GET /api/_inspect/threads/:id/state`\n * introspection endpoint (see Intelligence PR #144). The platform folds\n * RFC 6902 STATE_DELTA events on top of the latest STATE_SNAPSHOT, so\n * the returned state reflects the thread's current state — not just the\n * last snapshot. The discriminated response distinguishes \"no snapshot\n * persisted yet\" from \"snapshot present\" so consumers can render the\n * correct empty state.\n *\n * @throws {@link PlatformRequestError} on non-2xx responses.\n */\n async getThreadState(params: {\n threadId: string;\n }): Promise<ThreadStateResponse> {\n return this.#request<ThreadStateResponse>(\n \"GET\",\n `/api/_inspect/threads/${encodeURIComponent(params.threadId)}/state`,\n );\n }\n\n /**\n * Mark a thread as archived.\n *\n * Archived threads are excluded from {@link listThreads} results.\n * Triggers the `onThreadUpdated` lifecycle callback on success.\n *\n * @throws {@link PlatformRequestError} on non-2xx responses.\n */\n async archiveThread(params: {\n threadId: string;\n userId: string;\n agentId: string;\n }): Promise<void> {\n const response = await this.#request<ThreadEnvelope>(\n \"PATCH\",\n `/api/threads/${encodeURIComponent(params.threadId)}`,\n { userId: params.userId, agentId: params.agentId, archived: true },\n );\n this.#invokeLifecycleCallback(\"onThreadUpdated\", response.thread);\n }\n\n /**\n * Permanently delete a thread and its message history.\n *\n * This is irreversible. Triggers the `onThreadDeleted` lifecycle callback\n * on success.\n *\n * @throws {@link PlatformRequestError} on non-2xx responses.\n */\n async deleteThread(params: {\n threadId: string;\n userId: string;\n agentId: string;\n }): Promise<void> {\n await this.#request<void>(\n \"DELETE\",\n `/api/threads/${encodeURIComponent(params.threadId)}`,\n {\n userId: params.userId,\n agentId: params.agentId,\n reason: `Deleted via CopilotKit runtime (userId=${params.userId}, agentId=${params.agentId})`,\n },\n );\n this.#invokeLifecycleCallback(\"onThreadDeleted\", params);\n }\n\n /**\n * Annotate a thread event on the Intelligence platform's general annotation\n * endpoint (`PUT /connector/annotate/:clientEventId`).\n *\n * This is the generalized replacement for the old\n * `PUT /connector/user-actions/record/:clientEventId` endpoint. It supports\n * multiple annotation types via the `type` discriminator:\n * - `\"user_action\"` — records a user UI interaction for the self-learning loop.\n * - `\"set_learning_containers\"` — sets the learning containers for a thread.\n *\n * `userId` must be resolved on the runtime side before calling this — the\n * platform prefixes it with the project id from the API key.\n *\n * Always hits the idempotent `PUT /connector/annotate/:clientEventId`\n * endpoint. A retry with the same `clientEventId` returns\n * `{ id: <original>, duplicate: true }` instead of creating a new row.\n * When `clientEventId` is omitted, a UUID is auto-generated for this call.\n *\n * @throws {@link PlatformRequestError} on non-2xx responses, OR when the\n * platform returns an empty 2xx body (which would otherwise corrupt the\n * caller's typed result).\n */\n async annotate(params: AnnotateParams): Promise<AnnotateResponse> {\n const clientEventId = params.clientEventId ?? randomUUID();\n const path = `/connector/annotate/${encodeURIComponent(clientEventId)}`;\n const body: Record<string, unknown> = {\n type: params.type,\n userId: params.userId,\n threadId: params.threadId,\n };\n if (params.payload !== undefined) {\n body.payload = params.payload;\n }\n if (params.occurredAt !== undefined) {\n body.occurredAt = params.occurredAt;\n }\n const response = await this.#request<AnnotateResponse | null | undefined>(\n \"PUT\",\n path,\n body,\n );\n // `== null` catches both `undefined` (empty body from `#request`)\n // and JSON `null` (which would otherwise corrupt the typed result\n // and surface as a `TypeError` deep in caller code).\n if (response == null) {\n logger.error(\n { path },\n \"annotate: Intelligence platform returned 200 with empty or null body\",\n );\n throw new PlatformRequestError(\n \"annotate: empty or null response body from Intelligence platform\",\n 502,\n );\n }\n return response;\n }\n\n async ɵacquireThreadLock(\n params: AcquireThreadLockRequest,\n ): Promise<AcquireThreadLockResponse> {\n return this.#request<AcquireThreadLockResponse>(\n \"POST\",\n `/api/threads/${encodeURIComponent(params.threadId)}/lock`,\n {\n runId: params.runId,\n userId: params.userId,\n agentId: params.agentId,\n ...(params.lockKeyPrefix !== undefined\n ? { lockKeyPrefix: params.lockKeyPrefix }\n : {}),\n ...(params.ttlSeconds !== undefined\n ? { ttlSeconds: params.ttlSeconds }\n : {}),\n },\n );\n }\n\n async ɵcleanupThreadLock(params: CleanupThreadLockRequest): Promise<void> {\n return this.#request<void>(\n \"DELETE\",\n `/api/threads/${encodeURIComponent(params.threadId)}/lock`,\n {\n runId: params.runId,\n },\n );\n }\n\n async ɵrenewThreadLock(\n params: RenewThreadLockRequest,\n ): Promise<RenewThreadLockResponse> {\n return this.#request<RenewThreadLockResponse>(\n \"PATCH\",\n `/api/threads/${encodeURIComponent(params.threadId)}/lock`,\n {\n runId: params.runId,\n ttlSeconds: params.ttlSeconds,\n ...(params.lockKeyPrefix !== undefined\n ? { lockKeyPrefix: params.lockKeyPrefix }\n : {}),\n },\n );\n }\n\n async ɵgetActiveJoinCode(params: {\n threadId: string;\n userId: string;\n }): Promise<ThreadConnectionResponse> {\n const qs = new URLSearchParams({ userId: params.userId }).toString();\n return this.#request<ThreadConnectionResponse>(\n \"GET\",\n `/api/threads/${encodeURIComponent(params.threadId)}/join-code?${qs}`,\n );\n }\n\n async ɵconnectThread(params: {\n threadId: string;\n userId: string;\n agentId: string;\n }): Promise<ConnectThreadResponse> {\n const result = await this.#request<ThreadConnectionResponse>(\n \"POST\",\n `/api/threads/${encodeURIComponent(params.threadId)}/connect`,\n {\n userId: params.userId,\n agentId: params.agentId,\n },\n );\n\n // request() returns undefined for empty/204 responses\n return result ?? null;\n }\n}\n\nfunction normalizeIntelligenceWsUrl(wsUrl: string): string {\n return wsUrl.replace(/\\/$/, \"\");\n}\n\nfunction deriveRunnerWsUrl(wsUrl: string): string {\n if (wsUrl.endsWith(\"/runner\")) {\n return wsUrl;\n }\n\n if (wsUrl.endsWith(\"/client\")) {\n return `${wsUrl.slice(0, -\"/client\".length)}/runner`;\n }\n\n return `${wsUrl}/runner`;\n}\n\nfunction deriveClientWsUrl(wsUrl: string): string {\n if (wsUrl.endsWith(\"/client\")) {\n return wsUrl;\n }\n\n if (wsUrl.endsWith(\"/runner\")) {\n return `${wsUrl.slice(0, -\"/runner\".length)}/client`;\n }\n\n return `${wsUrl}/client`;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"client.cjs","names":["#apiUrl","#runnerWsUrl","#clientWsUrl","#apiKey","#enterpriseLearningEnabled","#threadCreatedListeners","#threadUpdatedListeners","#threadDeletedListeners","#request","#invokeLifecycleCallback"],"sources":["../../../../src/v2/runtime/intelligence-platform/client.ts"],"sourcesContent":["import { logger } from \"@copilotkit/shared\";\nimport { randomUUID } from \"crypto\";\n\n/**\n * Header name carrying the per-call end-user identity that the CopilotKit\n * Intelligence `/mcp` endpoint requires. Internal CopilotKit machinery —\n * `attachIntelligenceEnterpriseLearning` resolves the user via `identifyUser`\n * and bakes this header onto the `MCPMiddleware`'s transport config, so every\n * outbound MCP request stamps `X-Cpki-User-Id: <userId>`. Not part of the\n * public user API.\n *\n * @internal\n */\nexport const INTELLIGENCE_USER_ID_HEADER = \"x-cpki-user-id\";\n\n/**\n * Error thrown when an Intelligence platform HTTP request returns a non-2xx\n * status. Carries the HTTP {@link status} code so callers can branch on\n * specific failures (e.g. 404 for \"not found\", 409 for \"conflict\") without\n * parsing the error message string.\n *\n * @example\n * ```ts\n * try {\n * await intelligence.getThread({ threadId, userId });\n * } catch (error) {\n * if (error instanceof PlatformRequestError && error.status === 404) {\n * // thread does not exist yet\n * }\n * }\n * ```\n */\nexport class PlatformRequestError extends Error {\n constructor(\n message: string,\n /** The HTTP status code returned by the platform (e.g. 404, 409, 500). */\n public readonly status: number,\n ) {\n super(message);\n this.name = \"PlatformRequestError\";\n }\n}\n\n/**\n * Client for the CopilotKit Intelligence Platform REST API.\n *\n * Construct the client once and pass it to any consumers that need it\n * (e.g. `CopilotRuntime`, `IntelligenceAgentRunner`):\n *\n * ```ts\n * import { CopilotKitIntelligence, CopilotRuntime } from \"@copilotkit/runtime\";\n *\n * const intelligence = new CopilotKitIntelligence({\n * apiUrl: \"https://api.copilotkit.ai\",\n * wsUrl: \"wss://api.copilotkit.ai\",\n * apiKey: process.env.COPILOTKIT_API_KEY!,\n * });\n *\n * const runtime = new CopilotRuntime({\n * agents,\n * intelligence,\n * });\n * ```\n */\n\n/** Payload passed to `onThreadDeleted` listeners. */\nexport interface ThreadDeletedPayload {\n threadId: string;\n userId: string;\n agentId: string;\n}\n\nexport interface CopilotKitIntelligenceConfig {\n /** Base URL of the intelligence platform API, e.g. \"https://api.copilotkit.ai\" */\n apiUrl: string;\n /** Intelligence websocket base URL. Runner and client socket URLs are derived from this. */\n wsUrl: string;\n /** API key for authenticating with the intelligence platform */\n apiKey: string;\n /**\n * Enable Enterprise Learning — expose the Intelligence platform's\n * built-in tools (bash + thread/memory tools) to agent runs on an\n * intelligence runtime that resolve a user. Attached uniformly across\n * agent frameworks by `attachIntelligenceEnterpriseLearning` via\n * `@ag-ui/mcp-middleware`, with the resolved user-id and project apiKey\n * baked into the transport headers for that request's clone.\n *\n * Defaults to `false` — opt-in. Existing intelligence setups continue\n * to work without these tools unless they flip this flag.\n */\n enableEnterpriseLearning?: boolean;\n /**\n * Initial listener invoked after a thread is created.\n * Prefer {@link CopilotKitIntelligence.onThreadCreated} for multiple listeners.\n */\n onThreadCreated?: (thread: ThreadSummary) => void;\n /**\n * Initial listener invoked after a thread is updated.\n * Prefer {@link CopilotKitIntelligence.onThreadUpdated} for multiple listeners.\n */\n onThreadUpdated?: (thread: ThreadSummary) => void;\n /**\n * Initial listener invoked after a thread is deleted.\n * Prefer {@link CopilotKitIntelligence.onThreadDeleted} for multiple listeners.\n */\n onThreadDeleted?: (params: ThreadDeletedPayload) => void;\n}\n\n/**\n * Summary metadata for a single thread returned by the platform.\n *\n * This is the shape returned by list, get, create, and update operations.\n * It does not include the thread's message history — use\n * {@link CopilotKitIntelligence.getThreadMessages} for that.\n */\nexport interface ThreadSummary {\n /** Platform-assigned unique identifier. */\n id: string;\n /** Human-readable display name, or `null` if the thread has not been named. */\n name: string | null;\n /** ISO-8601 timestamp of the most recent agent run on this thread. */\n lastRunAt?: string;\n /** ISO-8601 timestamp of the most recent metadata update. */\n lastUpdatedAt?: string;\n /** ISO-8601 timestamp when the thread was created. */\n createdAt?: string;\n /** ISO-8601 timestamp when the thread was last updated. */\n updatedAt?: string;\n /** Whether the thread has been archived. Archived threads are excluded from default list results. */\n archived?: boolean;\n /** The agent that owns this thread. */\n agentId?: string;\n /** The user who created this thread. */\n createdById?: string;\n /** The organization this thread belongs to. */\n organizationId?: string;\n}\n\n/** Response from listing threads for a user/agent pair. */\nexport interface ListThreadsResponse {\n /** The matching threads, sorted by the platform's default ordering. */\n threads: ThreadSummary[];\n /** Join code for subscribing to realtime metadata updates for these threads. */\n joinCode: string;\n /** Short-lived token for authenticating the realtime subscription. */\n joinToken?: string;\n /** Opaque cursor for fetching the next page. `null` or absent when there are no more pages. */\n nextCursor?: string | null;\n}\n\n/**\n * A single memory as returned by the platform's list endpoint. Mirrors the\n * public projection the client memory store consumes (tenant ids stripped).\n */\nexport interface MemorySummary {\n /** Platform-assigned unique identifier. */\n id: string;\n /** Memory kind, e.g. `\"topical\"`, `\"episodic\"`, `\"operational\"`. */\n kind: string;\n /** Memory scope: `\"user\"` (private) or `\"project\"` (shared). */\n scope: string;\n /** The remembered fact, preference, or procedure. */\n content: string;\n /** Ids of the threads this memory was learned from. */\n sourceThreadIds: string[];\n /** ISO-8601 timestamp when the memory was retired, or `null` if live. */\n invalidatedAt: string | null;\n}\n\n/** Response from {@link CopilotKitIntelligence.listMemories}. */\nexport interface ListMemoriesResponse {\n memories: MemorySummary[];\n}\n\n/**\n * Response from a create ({@link CopilotKitIntelligence.createMemory}) or\n * supersede ({@link CopilotKitIntelligence.updateMemory}) call: the stored\n * memory, plus the operation-specific marker the client store consumes.\n */\nexport interface SaveMemoryResponse extends MemorySummary {\n /** Create only: content was merged into a near-duplicate, not inserted new. */\n absorbed?: boolean;\n /** Supersede only: the id of the memory retired by this call. */\n retiredId?: string;\n}\n\n/**\n * Fields that can be updated on a thread via {@link CopilotKitIntelligence.updateThread}.\n *\n * Additional platform-specific fields can be passed as extra keys and will be\n * forwarded to the PATCH request body.\n */\nexport interface UpdateThreadRequest {\n /** New human-readable display name for the thread. */\n name?: string;\n [key: string]: unknown;\n}\n\n/** Parameters for creating a new thread via {@link CopilotKitIntelligence.createThread}. */\nexport interface CreateThreadRequest {\n /** Client-generated unique identifier for the new thread. */\n threadId: string;\n /** The user creating the thread. Used for authorization and scoping. */\n userId: string;\n /** The agent this thread belongs to. */\n agentId: string;\n /** Optional initial display name. If omitted, the thread is unnamed until explicitly renamed. */\n name?: string;\n}\n\n/** Credentials returned when locking or joining a thread's realtime channel. */\nexport interface ThreadConnectionResponse {\n /** Canonical platform thread identifier for the run or connection. */\n threadId: string;\n /** Canonical platform run identifier for an active run lock. */\n runId?: string;\n /** Short-lived token for authenticating the Phoenix channel join. */\n joinToken: string;\n /** Lock metadata echoed back by the platform. */\n lock?: ThreadLockInfo;\n}\n\nexport interface SubscribeToThreadsRequest {\n userId: string;\n}\n\nexport interface SubscribeToThreadsResponse {\n joinToken: string;\n}\n\nexport interface SubscribeToMemoriesRequest {\n userId: string;\n}\n\n/**\n * Memory subscribe returns both the token and the join code, unlike threads\n * (whose join code reaches the client via the thread-list response). Memory has\n * no list-borne code, so the code is delivered here and used to build the\n * `user_meta:memories:<joinCode>` channel topic.\n */\nexport interface SubscribeToMemoriesResponse {\n joinToken: string;\n joinCode: string;\n}\n\nexport type ConnectThreadResponse = ThreadConnectionResponse | null;\n\nexport interface AcquireThreadLockResponse extends ThreadConnectionResponse {\n /** Canonical platform run identifier for the acquired lock. */\n runId: string;\n}\n\n/**\n * Parameters for annotating a thread event via\n * {@link CopilotKitIntelligence.annotate}. The runtime resolves `userId`\n * from the customer's BFF auth before calling this; the platform prefixes\n * it with the project id at write time.\n *\n * `payload` is the type-specific JSON blob for the annotation (e.g. a\n * `\"user_action\"` event carries the recorded fields, a\n * `\"set_learning_containers\"` event carries the container list). The exact\n * shape per type is validated by the Intelligence backend; canonical shapes\n * are documented on the Intelligence react-core side.\n */\nexport interface AnnotateParams {\n /** The user the annotation belongs to. */\n userId: string;\n /** The thread the annotation is associated with. May be unknown to the platform. */\n threadId: string;\n /**\n * Discriminator identifying the annotation type.\n * Must match a type known to the Intelligence platform\n * (e.g. `\"user_action\"`, `\"set_learning_containers\"`).\n */\n type: string;\n /** Type-specific payload. Shape varies by `type`. */\n payload?: unknown;\n /**\n * Caller-supplied idempotency key (any RFC-compliant UUID). When omitted,\n * a UUID is auto-generated. Every call hits the platform's idempotent\n * `PUT /connector/annotate/:clientEventId` endpoint; a retry with the\n * same id collapses to the original row.\n */\n clientEventId?: string;\n /** ISO-8601 client-asserted timestamp. Defaults to server NOW() when absent. */\n occurredAt?: string;\n}\n\n/** Response from {@link CopilotKitIntelligence.annotate}. */\nexport interface AnnotateResponse {\n /** Database id of the annotation row (BIGINT, returned as a string). */\n id: string;\n /**\n * True when the platform recognized the `clientEventId` as a retry of\n * a previous call and returned the original row id instead of inserting\n * a new one.\n */\n duplicate: boolean;\n}\n\n/** A single message within a thread's persisted history. */\nexport interface ThreadMessage {\n /** Unique identifier for this message. */\n id: string;\n /** Message role, e.g. `\"user\"`, `\"assistant\"`, `\"tool\"`. */\n role: string;\n /** Text content of the message. May be absent for tool-call-only messages. */\n content?: string;\n /** Tool calls initiated by this message (assistant role only). */\n toolCalls?: Array<{\n id: string;\n name: string;\n /** JSON-encoded arguments passed to the tool. */\n args: string;\n }>;\n /** For tool-result messages, the ID of the tool call this message responds to. */\n toolCallId?: string;\n}\n\n/** Response from {@link CopilotKitIntelligence.getThreadMessages}. */\nexport interface ThreadMessagesResponse {\n messages: ThreadMessage[];\n}\n\n/**\n * Persisted AG-UI event for the inspector's debugging views. The platform\n * stores raw events keyed by run; the `_inspect` route returns them in\n * replay order (oldest first) across every run that targeted the thread.\n */\nexport interface ThreadInspectEvent {\n type: string;\n [key: string]: unknown;\n}\n\n/**\n * Response from {@link CopilotKitIntelligence.getThreadEvents}. Mirrors the\n * `ThreadEventsResult` shape returned by the platform's\n * `GET /api/_inspect/threads/:id/events` endpoint.\n */\nexport interface ThreadEventsResponse {\n events: ThreadInspectEvent[];\n /** Row IDs the platform failed to decode (raw column corrupted). */\n decodeErrorRowIds: string[];\n /** True when the platform hit its per-thread event cap. */\n truncated: boolean;\n}\n\n/**\n * Response from {@link CopilotKitIntelligence.getThreadState}. Mirrors the\n * discriminated `ThreadStateResult` returned by the platform's\n * `GET /api/_inspect/threads/:id/state` endpoint, which folds RFC 6902\n * STATE_DELTA events on top of the latest STATE_SNAPSHOT.\n */\nexport type ThreadStateResponse =\n | { kind: \"no-snapshot\" }\n | { kind: \"snapshot-decode-error\" }\n | { kind: \"snapshot\"; state: unknown; skippedDeltas: number };\n\nexport interface AcquireThreadLockRequest {\n threadId: string;\n runId: string;\n userId: string;\n agentId: string;\n /** Custom Redis key prefix for the lock (default: \"thread\"). */\n lockKeyPrefix?: string;\n /** Lock TTL in seconds. When set, the lock auto-expires after this duration. */\n ttlSeconds?: number;\n}\n\nexport interface RenewThreadLockRequest {\n threadId: string;\n runId: string;\n /** New TTL to set on the lock in seconds. */\n ttlSeconds: number;\n /** Must match the prefix used when acquiring. */\n lockKeyPrefix?: string;\n}\n\nexport interface CleanupThreadLockRequest {\n threadId: string;\n runId: string;\n}\n\nexport interface RenewThreadLockResponse {\n ttlSeconds: number;\n}\n\nexport interface ThreadLockInfo {\n key: string;\n ttlSeconds: number | null;\n}\n\ninterface ThreadEnvelope {\n thread: ThreadSummary;\n}\n\nexport class CopilotKitIntelligence {\n #apiUrl: string;\n #runnerWsUrl: string;\n #clientWsUrl: string;\n #apiKey: string;\n #enterpriseLearningEnabled: boolean;\n #threadCreatedListeners = new Set<(thread: ThreadSummary) => void>();\n #threadUpdatedListeners = new Set<(thread: ThreadSummary) => void>();\n #threadDeletedListeners = new Set<(params: ThreadDeletedPayload) => void>();\n\n constructor(config: CopilotKitIntelligenceConfig) {\n const intelligenceWsUrl = normalizeIntelligenceWsUrl(config.wsUrl);\n\n this.#apiUrl = config.apiUrl.replace(/\\/$/, \"\");\n this.#runnerWsUrl = deriveRunnerWsUrl(intelligenceWsUrl);\n this.#clientWsUrl = deriveClientWsUrl(intelligenceWsUrl);\n this.#apiKey = config.apiKey;\n this.#enterpriseLearningEnabled = config.enableEnterpriseLearning ?? false;\n\n if (config.onThreadCreated) {\n this.onThreadCreated(config.onThreadCreated);\n }\n if (config.onThreadUpdated) {\n this.onThreadUpdated(config.onThreadUpdated);\n }\n if (config.onThreadDeleted) {\n this.onThreadDeleted(config.onThreadDeleted);\n }\n }\n\n /**\n * Register a listener invoked whenever a thread is created.\n *\n * Multiple listeners can be registered. Each call returns an unsubscribe\n * function that removes the listener when called.\n *\n * @param callback - Receives the newly created {@link ThreadSummary}.\n * @returns A function that removes this listener when called.\n *\n * @example\n * ```ts\n * const unsubscribe = intelligence.onThreadCreated((thread) => {\n * console.log(\"Thread created:\", thread.id);\n * });\n * // later…\n * unsubscribe();\n * ```\n */\n onThreadCreated(callback: (thread: ThreadSummary) => void): () => void {\n this.#threadCreatedListeners.add(callback);\n return () => {\n this.#threadCreatedListeners.delete(callback);\n };\n }\n\n /**\n * Register a listener invoked whenever a thread is updated (including archive).\n *\n * Multiple listeners can be registered. Each call returns an unsubscribe\n * function that removes the listener when called.\n *\n * @param callback - Receives the updated {@link ThreadSummary}.\n * @returns A function that removes this listener when called.\n */\n onThreadUpdated(callback: (thread: ThreadSummary) => void): () => void {\n this.#threadUpdatedListeners.add(callback);\n return () => {\n this.#threadUpdatedListeners.delete(callback);\n };\n }\n\n /**\n * Register a listener invoked whenever a thread is deleted.\n *\n * Multiple listeners can be registered. Each call returns an unsubscribe\n * function that removes the listener when called.\n *\n * @param callback - Receives the {@link ThreadDeletedPayload} identifying\n * the deleted thread.\n * @returns A function that removes this listener when called.\n */\n onThreadDeleted(\n callback: (params: ThreadDeletedPayload) => void,\n ): () => void {\n this.#threadDeletedListeners.add(callback);\n return () => {\n this.#threadDeletedListeners.delete(callback);\n };\n }\n\n ɵgetApiUrl(): string {\n return this.#apiUrl;\n }\n\n ɵgetRunnerWsUrl(): string {\n return this.#runnerWsUrl;\n }\n\n ɵgetClientWsUrl(): string {\n return this.#clientWsUrl;\n }\n\n ɵgetRunnerAuthToken(): string {\n return this.#apiKey;\n }\n\n /** @internal Used by `attachIntelligenceEnterpriseLearning` to populate `Authorization`. */\n ɵgetApiKey(): string {\n return this.#apiKey;\n }\n\n /** @internal Used by `attachIntelligenceEnterpriseLearning` to gate MCP attachment. */\n ɵisEnterpriseLearningEnabled(): boolean {\n return this.#enterpriseLearningEnabled;\n }\n\n async #request<T>(\n method: string,\n path: string,\n body?: unknown,\n extraHeaders?: Record<string, string>,\n ): Promise<T> {\n const url = `${this.#apiUrl}${path}`;\n\n const headers: Record<string, string> = {\n Authorization: `Bearer ${this.#apiKey}`,\n \"Content-Type\": \"application/json\",\n ...extraHeaders,\n };\n\n const response = await fetch(url, {\n method,\n headers,\n body: body ? JSON.stringify(body) : undefined,\n });\n\n if (!response.ok) {\n const text = await response.text().catch(() => \"\");\n logger.error(\n { status: response.status, body: text, path },\n \"Intelligence platform request failed\",\n );\n throw new PlatformRequestError(\n `Intelligence platform error ${response.status}: ${text || response.statusText}`,\n response.status,\n );\n }\n\n const text = await response.text();\n if (!text) {\n return undefined as T;\n }\n return JSON.parse(text) as T;\n }\n\n #invokeLifecycleCallback(\n callbackName: \"onThreadCreated\" | \"onThreadUpdated\" | \"onThreadDeleted\",\n payload: ThreadSummary | ThreadDeletedPayload,\n ): void {\n const listeners =\n callbackName === \"onThreadCreated\"\n ? this.#threadCreatedListeners\n : callbackName === \"onThreadUpdated\"\n ? this.#threadUpdatedListeners\n : this.#threadDeletedListeners;\n\n for (const callback of listeners) {\n try {\n (callback as (p: typeof payload) => void)(payload);\n } catch (error) {\n logger.error(\n { err: error, callbackName, payload },\n \"Intelligence lifecycle callback failed\",\n );\n }\n }\n }\n\n /**\n * List all non-archived threads for a given user and agent.\n *\n * @param params.userId - User whose threads to list.\n * @param params.agentId - Agent whose threads to list.\n * @returns The thread list along with realtime subscription credentials.\n * @throws {@link PlatformRequestError} on non-2xx responses.\n */\n async listThreads(params: {\n userId: string;\n agentId: string;\n includeArchived?: boolean;\n limit?: number;\n cursor?: string;\n }): Promise<ListThreadsResponse> {\n const query: Record<string, string> = {\n userId: params.userId,\n agentId: params.agentId,\n };\n if (params.includeArchived) query.includeArchived = \"true\";\n if (params.limit != null) query.limit = String(params.limit);\n if (params.cursor) query.cursor = params.cursor;\n\n const qs = new URLSearchParams(query).toString();\n return this.#request<ListThreadsResponse>(\"GET\", `/api/threads?${qs}`);\n }\n\n /**\n * List the given user's long-term memories, newest first.\n *\n * The platform scopes by the opaque app user supplied in the\n * `x-cpki-user-id` header (resolved by the runtime via `identifyUser`),\n * not a query param. Pass `includeInvalidated` to also return retired rows.\n *\n * @returns The `{ memories }` envelope the client memory store consumes.\n * @throws {@link PlatformRequestError} on non-2xx responses.\n */\n async listMemories(params: {\n userId: string;\n includeInvalidated?: boolean;\n }): Promise<ListMemoriesResponse> {\n const qs = params.includeInvalidated ? \"?includeInvalidated=true\" : \"\";\n return this.#request<ListMemoriesResponse>(\n \"GET\",\n `/api/memories${qs}`,\n undefined,\n { [INTELLIGENCE_USER_ID_HEADER]: params.userId },\n );\n }\n\n /**\n * Create a memory for the given user (platform `POST /api/memories`).\n * @returns The stored memory; `absorbed` is true if the content was merged\n * into a near-duplicate rather than inserted as a new row.\n * @throws {@link PlatformRequestError} on non-2xx responses.\n */\n async createMemory(params: {\n userId: string;\n content: string;\n kind: string;\n /** Optional: when omitted, the platform applies its default (`\"user\"`). */\n scope?: string;\n sourceThreadIds?: string[];\n }): Promise<SaveMemoryResponse> {\n return this.#request<SaveMemoryResponse>(\n \"POST\",\n `/api/memories`,\n {\n content: params.content,\n kind: params.kind,\n ...(params.scope !== undefined ? { scope: params.scope } : {}),\n sourceThreadIds: params.sourceThreadIds ?? [],\n },\n { [INTELLIGENCE_USER_ID_HEADER]: params.userId },\n );\n }\n\n /**\n * Supersede an existing memory (platform `PATCH /api/memories/:id`). The\n * `:id` row is retired and a new memory with the supplied content is\n * inserted atomically.\n * @returns The new memory plus `retiredId` (the id of the retired row).\n * @throws {@link PlatformRequestError} on non-2xx responses (e.g. 404 when\n * `:id` is not a live, same-scope memory for this user).\n */\n async updateMemory(params: {\n userId: string;\n id: string;\n content: string;\n kind: string;\n /** Optional: when omitted, the platform applies its default (`\"user\"`). */\n scope?: string;\n sourceThreadIds?: string[];\n }): Promise<SaveMemoryResponse> {\n return this.#request<SaveMemoryResponse>(\n \"PATCH\",\n `/api/memories/${encodeURIComponent(params.id)}`,\n {\n content: params.content,\n kind: params.kind,\n ...(params.scope !== undefined ? { scope: params.scope } : {}),\n sourceThreadIds: params.sourceThreadIds ?? [],\n },\n { [INTELLIGENCE_USER_ID_HEADER]: params.userId },\n );\n }\n\n /**\n * Non-lossily retire (forget) a memory (platform `DELETE /api/memories/:id`).\n * @throws {@link PlatformRequestError} on non-2xx responses.\n */\n async removeMemory(params: { userId: string; id: string }): Promise<void> {\n await this.#request<void>(\n \"DELETE\",\n `/api/memories/${encodeURIComponent(params.id)}`,\n undefined,\n { [INTELLIGENCE_USER_ID_HEADER]: params.userId },\n );\n }\n\n async ɵsubscribeToThreads(\n params: SubscribeToThreadsRequest,\n ): Promise<SubscribeToThreadsResponse> {\n return this.#request<SubscribeToThreadsResponse>(\n \"POST\",\n \"/api/threads/subscribe\",\n {\n userId: params.userId,\n },\n );\n }\n\n /**\n * Mint memory-realtime join credentials (platform `POST\n * /api/memories/subscribe`). Returns both the single-use `joinToken` and the\n * per-user `joinCode` the client needs to build the\n * `user_meta:memories:<joinCode>` channel topic.\n *\n * The user is supplied via the `x-cpki-user-id` header — the same way every\n * other memory endpoint (`listMemories`/`createMemory`/…) identifies the app\n * user — because the platform's memory routes resolve identity from that\n * header, not the body. (This differs from `ɵsubscribeToThreads`, whose\n * platform endpoint reads `userId` from the body.)\n *\n * @throws {@link PlatformRequestError} on non-2xx responses.\n */\n async ɵsubscribeToMemories(\n params: SubscribeToMemoriesRequest,\n ): Promise<SubscribeToMemoriesResponse> {\n return this.#request<SubscribeToMemoriesResponse>(\n \"POST\",\n \"/api/memories/subscribe\",\n undefined,\n { [INTELLIGENCE_USER_ID_HEADER]: params.userId },\n );\n }\n\n /**\n * Update thread metadata (e.g. name).\n *\n * Triggers the `onThreadUpdated` lifecycle callback on success.\n *\n * @returns The updated thread summary.\n * @throws {@link PlatformRequestError} on non-2xx responses.\n */\n async updateThread(params: {\n threadId: string;\n userId: string;\n agentId: string;\n updates: UpdateThreadRequest;\n }): Promise<ThreadSummary> {\n const response = await this.#request<ThreadEnvelope>(\n \"PATCH\",\n `/api/threads/${encodeURIComponent(params.threadId)}`,\n {\n userId: params.userId,\n agentId: params.agentId,\n ...params.updates,\n },\n );\n this.#invokeLifecycleCallback(\"onThreadUpdated\", response.thread);\n return response.thread;\n }\n\n /**\n * Create a new thread on the platform.\n *\n * Triggers the `onThreadCreated` lifecycle callback on success.\n *\n * @returns The newly created thread summary.\n * @throws {@link PlatformRequestError} with status 409 if a thread with the\n * same `threadId` already exists.\n */\n async createThread(params: CreateThreadRequest): Promise<ThreadSummary> {\n const response = await this.#request<ThreadEnvelope>(\n \"POST\",\n `/api/threads`,\n {\n threadId: params.threadId,\n userId: params.userId,\n agentId: params.agentId,\n ...(params.name !== undefined ? { name: params.name } : {}),\n },\n );\n this.#invokeLifecycleCallback(\"onThreadCreated\", response.thread);\n return response.thread;\n }\n\n /**\n * Fetch a single thread by ID.\n *\n * @returns The thread summary.\n * @throws {@link PlatformRequestError} with status 404 if the thread does\n * not exist.\n */\n async getThread(params: {\n threadId: string;\n userId: string;\n }): Promise<ThreadSummary> {\n const qs = new URLSearchParams({ userId: params.userId }).toString();\n const response = await this.#request<ThreadEnvelope>(\n \"GET\",\n `/api/threads/${encodeURIComponent(params.threadId)}?${qs}`,\n );\n return response.thread;\n }\n\n /**\n * Get an existing thread or create it if it does not exist.\n *\n * Handles the race where a concurrent request creates the thread between\n * the initial 404 and the subsequent `createThread` call by catching the\n * 409 Conflict and retrying the get.\n *\n * Triggers the `onThreadCreated` lifecycle callback when a new thread is\n * created.\n *\n * @returns An object containing the thread and a `created` flag indicating\n * whether the thread was newly created (`true`) or already existed (`false`).\n * @throws {@link PlatformRequestError} on non-2xx responses other than\n * 404 (get) and 409 (create race).\n */\n async getOrCreateThread(\n params: CreateThreadRequest,\n ): Promise<{ thread: ThreadSummary; created: boolean }> {\n try {\n const thread = await this.getThread({\n threadId: params.threadId,\n userId: params.userId,\n });\n return { thread, created: false };\n } catch (error) {\n if (!(error instanceof PlatformRequestError && error.status === 404)) {\n throw error;\n }\n }\n\n try {\n const thread = await this.createThread(params);\n return { thread, created: true };\n } catch (error) {\n // Another request created the thread between our get and create — retry get.\n if (error instanceof PlatformRequestError && error.status === 409) {\n const thread = await this.getThread({\n threadId: params.threadId,\n userId: params.userId,\n });\n return { thread, created: false };\n }\n throw error;\n }\n }\n\n /**\n * Fetch the full message history for a thread.\n *\n * @returns All persisted messages in chronological order.\n * @throws {@link PlatformRequestError} on non-2xx responses.\n */\n async getThreadMessages(params: {\n threadId: string;\n userId: string;\n }): Promise<ThreadMessagesResponse> {\n const qs = new URLSearchParams({ userId: params.userId }).toString();\n return this.#request<ThreadMessagesResponse>(\n \"GET\",\n `/api/threads/${encodeURIComponent(params.threadId)}/messages?${qs}`,\n );\n }\n\n /**\n * Fetch the persisted AG-UI event stream for a thread.\n *\n * Backed by the platform's `GET /api/_inspect/threads/:id/events`\n * introspection endpoint (see Intelligence PR #144). Events are returned\n * in replay order across every run that targeted the thread. The\n * `_inspect/` prefix flags this as debug-only — production code paths\n * must not depend on it.\n *\n * @throws {@link PlatformRequestError} on non-2xx responses.\n */\n async getThreadEvents(params: {\n threadId: string;\n }): Promise<ThreadEventsResponse> {\n return this.#request<ThreadEventsResponse>(\n \"GET\",\n `/api/_inspect/threads/${encodeURIComponent(params.threadId)}/events`,\n );\n }\n\n /**\n * Fetch the current agent state for a thread.\n *\n * Backed by the platform's `GET /api/_inspect/threads/:id/state`\n * introspection endpoint (see Intelligence PR #144). The platform folds\n * RFC 6902 STATE_DELTA events on top of the latest STATE_SNAPSHOT, so\n * the returned state reflects the thread's current state — not just the\n * last snapshot. The discriminated response distinguishes \"no snapshot\n * persisted yet\" from \"snapshot present\" so consumers can render the\n * correct empty state.\n *\n * @throws {@link PlatformRequestError} on non-2xx responses.\n */\n async getThreadState(params: {\n threadId: string;\n }): Promise<ThreadStateResponse> {\n return this.#request<ThreadStateResponse>(\n \"GET\",\n `/api/_inspect/threads/${encodeURIComponent(params.threadId)}/state`,\n );\n }\n\n /**\n * Mark a thread as archived.\n *\n * Archived threads are excluded from {@link listThreads} results.\n * Triggers the `onThreadUpdated` lifecycle callback on success.\n *\n * @throws {@link PlatformRequestError} on non-2xx responses.\n */\n async archiveThread(params: {\n threadId: string;\n userId: string;\n agentId: string;\n }): Promise<void> {\n const response = await this.#request<ThreadEnvelope>(\n \"PATCH\",\n `/api/threads/${encodeURIComponent(params.threadId)}`,\n { userId: params.userId, agentId: params.agentId, archived: true },\n );\n this.#invokeLifecycleCallback(\"onThreadUpdated\", response.thread);\n }\n\n /**\n * Permanently delete a thread and its message history.\n *\n * This is irreversible. Triggers the `onThreadDeleted` lifecycle callback\n * on success.\n *\n * @throws {@link PlatformRequestError} on non-2xx responses.\n */\n async deleteThread(params: {\n threadId: string;\n userId: string;\n agentId: string;\n }): Promise<void> {\n await this.#request<void>(\n \"DELETE\",\n `/api/threads/${encodeURIComponent(params.threadId)}`,\n {\n userId: params.userId,\n agentId: params.agentId,\n reason: `Deleted via CopilotKit runtime (userId=${params.userId}, agentId=${params.agentId})`,\n },\n );\n this.#invokeLifecycleCallback(\"onThreadDeleted\", params);\n }\n\n /**\n * Annotate a thread event on the Intelligence platform's general annotation\n * endpoint (`PUT /connector/annotate/:clientEventId`).\n *\n * This is the generalized replacement for the old\n * `PUT /connector/user-actions/record/:clientEventId` endpoint. It supports\n * multiple annotation types via the `type` discriminator:\n * - `\"user_action\"` — records a user UI interaction for the self-learning loop.\n * - `\"set_learning_containers\"` — sets the learning containers for a thread.\n *\n * `userId` must be resolved on the runtime side before calling this — the\n * platform prefixes it with the project id from the API key.\n *\n * Always hits the idempotent `PUT /connector/annotate/:clientEventId`\n * endpoint. A retry with the same `clientEventId` returns\n * `{ id: <original>, duplicate: true }` instead of creating a new row.\n * When `clientEventId` is omitted, a UUID is auto-generated for this call.\n *\n * @throws {@link PlatformRequestError} on non-2xx responses, OR when the\n * platform returns an empty 2xx body (which would otherwise corrupt the\n * caller's typed result).\n */\n async annotate(params: AnnotateParams): Promise<AnnotateResponse> {\n const clientEventId = params.clientEventId ?? randomUUID();\n const path = `/connector/annotate/${encodeURIComponent(clientEventId)}`;\n const body: Record<string, unknown> = {\n type: params.type,\n userId: params.userId,\n threadId: params.threadId,\n };\n if (params.payload !== undefined) {\n body.payload = params.payload;\n }\n if (params.occurredAt !== undefined) {\n body.occurredAt = params.occurredAt;\n }\n const response = await this.#request<AnnotateResponse | null | undefined>(\n \"PUT\",\n path,\n body,\n );\n // `== null` catches both `undefined` (empty body from `#request`)\n // and JSON `null` (which would otherwise corrupt the typed result\n // and surface as a `TypeError` deep in caller code).\n if (response == null) {\n logger.error(\n { path },\n \"annotate: Intelligence platform returned 200 with empty or null body\",\n );\n throw new PlatformRequestError(\n \"annotate: empty or null response body from Intelligence platform\",\n 502,\n );\n }\n return response;\n }\n\n async ɵacquireThreadLock(\n params: AcquireThreadLockRequest,\n ): Promise<AcquireThreadLockResponse> {\n return this.#request<AcquireThreadLockResponse>(\n \"POST\",\n `/api/threads/${encodeURIComponent(params.threadId)}/lock`,\n {\n runId: params.runId,\n userId: params.userId,\n agentId: params.agentId,\n ...(params.lockKeyPrefix !== undefined\n ? { lockKeyPrefix: params.lockKeyPrefix }\n : {}),\n ...(params.ttlSeconds !== undefined\n ? { ttlSeconds: params.ttlSeconds }\n : {}),\n },\n );\n }\n\n async ɵcleanupThreadLock(params: CleanupThreadLockRequest): Promise<void> {\n return this.#request<void>(\n \"DELETE\",\n `/api/threads/${encodeURIComponent(params.threadId)}/lock`,\n {\n runId: params.runId,\n },\n );\n }\n\n async ɵrenewThreadLock(\n params: RenewThreadLockRequest,\n ): Promise<RenewThreadLockResponse> {\n return this.#request<RenewThreadLockResponse>(\n \"PATCH\",\n `/api/threads/${encodeURIComponent(params.threadId)}/lock`,\n {\n runId: params.runId,\n ttlSeconds: params.ttlSeconds,\n ...(params.lockKeyPrefix !== undefined\n ? { lockKeyPrefix: params.lockKeyPrefix }\n : {}),\n },\n );\n }\n\n async ɵgetActiveJoinCode(params: {\n threadId: string;\n userId: string;\n }): Promise<ThreadConnectionResponse> {\n const qs = new URLSearchParams({ userId: params.userId }).toString();\n return this.#request<ThreadConnectionResponse>(\n \"GET\",\n `/api/threads/${encodeURIComponent(params.threadId)}/join-code?${qs}`,\n );\n }\n\n async ɵconnectThread(params: {\n threadId: string;\n userId: string;\n agentId: string;\n }): Promise<ConnectThreadResponse> {\n const result = await this.#request<ThreadConnectionResponse>(\n \"POST\",\n `/api/threads/${encodeURIComponent(params.threadId)}/connect`,\n {\n userId: params.userId,\n agentId: params.agentId,\n },\n );\n\n // request() returns undefined for empty/204 responses\n return result ?? null;\n }\n}\n\nfunction normalizeIntelligenceWsUrl(wsUrl: string): string {\n return wsUrl.replace(/\\/$/, \"\");\n}\n\nfunction deriveRunnerWsUrl(wsUrl: string): string {\n if (wsUrl.endsWith(\"/runner\")) {\n return wsUrl;\n }\n\n if (wsUrl.endsWith(\"/client\")) {\n return `${wsUrl.slice(0, -\"/client\".length)}/runner`;\n }\n\n return `${wsUrl}/runner`;\n}\n\nfunction deriveClientWsUrl(wsUrl: string): string {\n if (wsUrl.endsWith(\"/client\")) {\n return wsUrl;\n }\n\n if (wsUrl.endsWith(\"/runner\")) {\n return `${wsUrl.slice(0, -\"/runner\".length)}/client`;\n }\n\n return `${wsUrl}/client`;\n}\n"],"mappings":"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"}
@@ -102,6 +102,39 @@ interface ListThreadsResponse {
102
102
  /** Opaque cursor for fetching the next page. `null` or absent when there are no more pages. */
103
103
  nextCursor?: string | null;
104
104
  }
105
+ /**
106
+ * A single memory as returned by the platform's list endpoint. Mirrors the
107
+ * public projection the client memory store consumes (tenant ids stripped).
108
+ */
109
+ interface MemorySummary {
110
+ /** Platform-assigned unique identifier. */
111
+ id: string;
112
+ /** Memory kind, e.g. `"topical"`, `"episodic"`, `"operational"`. */
113
+ kind: string;
114
+ /** Memory scope: `"user"` (private) or `"project"` (shared). */
115
+ scope: string;
116
+ /** The remembered fact, preference, or procedure. */
117
+ content: string;
118
+ /** Ids of the threads this memory was learned from. */
119
+ sourceThreadIds: string[];
120
+ /** ISO-8601 timestamp when the memory was retired, or `null` if live. */
121
+ invalidatedAt: string | null;
122
+ }
123
+ /** Response from {@link CopilotKitIntelligence.listMemories}. */
124
+ interface ListMemoriesResponse {
125
+ memories: MemorySummary[];
126
+ }
127
+ /**
128
+ * Response from a create ({@link CopilotKitIntelligence.createMemory}) or
129
+ * supersede ({@link CopilotKitIntelligence.updateMemory}) call: the stored
130
+ * memory, plus the operation-specific marker the client store consumes.
131
+ */
132
+ interface SaveMemoryResponse extends MemorySummary {
133
+ /** Create only: content was merged into a near-duplicate, not inserted new. */
134
+ absorbed?: boolean;
135
+ /** Supersede only: the id of the memory retired by this call. */
136
+ retiredId?: string;
137
+ }
105
138
  /**
106
139
  * Fields that can be updated on a thread via {@link CopilotKitIntelligence.updateThread}.
107
140
  *
@@ -141,6 +174,19 @@ interface SubscribeToThreadsRequest {
141
174
  interface SubscribeToThreadsResponse {
142
175
  joinToken: string;
143
176
  }
177
+ interface SubscribeToMemoriesRequest {
178
+ userId: string;
179
+ }
180
+ /**
181
+ * Memory subscribe returns both the token and the join code, unlike threads
182
+ * (whose join code reaches the client via the thread-list response). Memory has
183
+ * no list-borne code, so the code is delivered here and used to build the
184
+ * `user_meta:memories:<joinCode>` channel topic.
185
+ */
186
+ interface SubscribeToMemoriesResponse {
187
+ joinToken: string;
188
+ joinCode: string;
189
+ }
144
190
  type ConnectThreadResponse = ThreadConnectionResponse | null;
145
191
  interface AcquireThreadLockResponse extends ThreadConnectionResponse {
146
192
  /** Canonical platform run identifier for the acquired lock. */
@@ -344,7 +390,73 @@ declare class CopilotKitIntelligence {
344
390
  limit?: number;
345
391
  cursor?: string;
346
392
  }): Promise<ListThreadsResponse>;
393
+ /**
394
+ * List the given user's long-term memories, newest first.
395
+ *
396
+ * The platform scopes by the opaque app user supplied in the
397
+ * `x-cpki-user-id` header (resolved by the runtime via `identifyUser`),
398
+ * not a query param. Pass `includeInvalidated` to also return retired rows.
399
+ *
400
+ * @returns The `{ memories }` envelope the client memory store consumes.
401
+ * @throws {@link PlatformRequestError} on non-2xx responses.
402
+ */
403
+ listMemories(params: {
404
+ userId: string;
405
+ includeInvalidated?: boolean;
406
+ }): Promise<ListMemoriesResponse>;
407
+ /**
408
+ * Create a memory for the given user (platform `POST /api/memories`).
409
+ * @returns The stored memory; `absorbed` is true if the content was merged
410
+ * into a near-duplicate rather than inserted as a new row.
411
+ * @throws {@link PlatformRequestError} on non-2xx responses.
412
+ */
413
+ createMemory(params: {
414
+ userId: string;
415
+ content: string;
416
+ kind: string; /** Optional: when omitted, the platform applies its default (`"user"`). */
417
+ scope?: string;
418
+ sourceThreadIds?: string[];
419
+ }): Promise<SaveMemoryResponse>;
420
+ /**
421
+ * Supersede an existing memory (platform `PATCH /api/memories/:id`). The
422
+ * `:id` row is retired and a new memory with the supplied content is
423
+ * inserted atomically.
424
+ * @returns The new memory plus `retiredId` (the id of the retired row).
425
+ * @throws {@link PlatformRequestError} on non-2xx responses (e.g. 404 when
426
+ * `:id` is not a live, same-scope memory for this user).
427
+ */
428
+ updateMemory(params: {
429
+ userId: string;
430
+ id: string;
431
+ content: string;
432
+ kind: string; /** Optional: when omitted, the platform applies its default (`"user"`). */
433
+ scope?: string;
434
+ sourceThreadIds?: string[];
435
+ }): Promise<SaveMemoryResponse>;
436
+ /**
437
+ * Non-lossily retire (forget) a memory (platform `DELETE /api/memories/:id`).
438
+ * @throws {@link PlatformRequestError} on non-2xx responses.
439
+ */
440
+ removeMemory(params: {
441
+ userId: string;
442
+ id: string;
443
+ }): Promise<void>;
347
444
  ɵsubscribeToThreads(params: SubscribeToThreadsRequest): Promise<SubscribeToThreadsResponse>;
445
+ /**
446
+ * Mint memory-realtime join credentials (platform `POST
447
+ * /api/memories/subscribe`). Returns both the single-use `joinToken` and the
448
+ * per-user `joinCode` the client needs to build the
449
+ * `user_meta:memories:<joinCode>` channel topic.
450
+ *
451
+ * The user is supplied via the `x-cpki-user-id` header — the same way every
452
+ * other memory endpoint (`listMemories`/`createMemory`/…) identifies the app
453
+ * user — because the platform's memory routes resolve identity from that
454
+ * header, not the body. (This differs from `ɵsubscribeToThreads`, whose
455
+ * platform endpoint reads `userId` from the body.)
456
+ *
457
+ * @throws {@link PlatformRequestError} on non-2xx responses.
458
+ */
459
+ ɵsubscribeToMemories(params: SubscribeToMemoriesRequest): Promise<SubscribeToMemoriesResponse>;
348
460
  /**
349
461
  * Update thread metadata (e.g. name).
350
462
  *
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.cts","names":[],"sources":["../../../../src/v2/runtime/intelligence-platform/client.ts"],"mappings":"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"}
1
+ {"version":3,"file":"client.d.cts","names":[],"sources":["../../../../src/v2/runtime/intelligence-platform/client.ts"],"mappings":"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"}