@copilotkit/runtime 1.70.0 → 1.70.2
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.
- package/dist/agent/converters/aisdk.cjs +26 -2
- package/dist/agent/converters/aisdk.cjs.map +1 -1
- package/dist/agent/converters/aisdk.d.cts +2 -1
- package/dist/agent/converters/aisdk.d.cts.map +1 -1
- package/dist/agent/converters/aisdk.d.mts +2 -1
- package/dist/agent/converters/aisdk.d.mts.map +1 -1
- package/dist/agent/converters/aisdk.mjs +26 -3
- package/dist/agent/converters/aisdk.mjs.map +1 -1
- package/dist/agent/converters/tanstack.cjs +32 -2
- package/dist/agent/converters/tanstack.cjs.map +1 -1
- package/dist/agent/converters/tanstack.d.cts +2 -1
- package/dist/agent/converters/tanstack.d.cts.map +1 -1
- package/dist/agent/converters/tanstack.d.mts +2 -1
- package/dist/agent/converters/tanstack.d.mts.map +1 -1
- package/dist/agent/converters/tanstack.mjs +32 -2
- package/dist/agent/converters/tanstack.mjs.map +1 -1
- package/dist/agent/converters/usage.cjs +63 -0
- package/dist/agent/converters/usage.cjs.map +1 -0
- package/dist/agent/converters/usage.d.cts +18 -0
- package/dist/agent/converters/usage.d.cts.map +1 -0
- package/dist/agent/converters/usage.d.mts +18 -0
- package/dist/agent/converters/usage.d.mts.map +1 -0
- package/dist/agent/converters/usage.mjs +57 -0
- package/dist/agent/converters/usage.mjs.map +1 -0
- package/dist/agent/index.cjs +22 -4
- package/dist/agent/index.cjs.map +1 -1
- package/dist/agent/index.d.cts.map +1 -1
- package/dist/agent/index.d.mts.map +1 -1
- package/dist/agent/index.mjs +23 -5
- package/dist/agent/index.mjs.map +1 -1
- package/dist/lib/logger.cjs +1 -4
- package/dist/lib/logger.cjs.map +1 -1
- package/dist/lib/logger.mjs +1 -4
- package/dist/lib/logger.mjs.map +1 -1
- package/dist/lib/telemetry-client.cjs +2 -2
- package/dist/lib/telemetry-client.cjs.map +1 -1
- package/dist/lib/telemetry-client.mjs +1 -1
- package/dist/lib/telemetry-client.mjs.map +1 -1
- package/dist/package.cjs +2 -2
- package/dist/package.mjs +2 -2
- package/dist/v2/runtime/core/fetch-handler.cjs +92 -15
- package/dist/v2/runtime/core/fetch-handler.cjs.map +1 -1
- package/dist/v2/runtime/core/fetch-handler.d.cts +7 -0
- package/dist/v2/runtime/core/fetch-handler.d.cts.map +1 -1
- package/dist/v2/runtime/core/fetch-handler.d.mts +7 -0
- package/dist/v2/runtime/core/fetch-handler.d.mts.map +1 -1
- package/dist/v2/runtime/core/fetch-handler.mjs +93 -16
- package/dist/v2/runtime/core/fetch-handler.mjs.map +1 -1
- package/dist/v2/runtime/core/fetch-router.cjs +1 -0
- package/dist/v2/runtime/core/fetch-router.cjs.map +1 -1
- package/dist/v2/runtime/core/fetch-router.mjs +1 -0
- package/dist/v2/runtime/core/fetch-router.mjs.map +1 -1
- package/dist/v2/runtime/core/hooks.cjs.map +1 -1
- package/dist/v2/runtime/core/hooks.d.cts +2 -0
- package/dist/v2/runtime/core/hooks.d.cts.map +1 -1
- package/dist/v2/runtime/core/hooks.d.mts +2 -0
- package/dist/v2/runtime/core/hooks.d.mts.map +1 -1
- package/dist/v2/runtime/core/hooks.mjs.map +1 -1
- package/dist/v2/runtime/endpoints/express.cjs +2 -1
- package/dist/v2/runtime/endpoints/express.cjs.map +1 -1
- package/dist/v2/runtime/endpoints/express.d.cts +6 -0
- package/dist/v2/runtime/endpoints/express.d.cts.map +1 -1
- package/dist/v2/runtime/endpoints/express.d.mts +6 -0
- package/dist/v2/runtime/endpoints/express.d.mts.map +1 -1
- package/dist/v2/runtime/endpoints/express.mjs +2 -1
- package/dist/v2/runtime/endpoints/express.mjs.map +1 -1
- package/dist/v2/runtime/endpoints/hono.cjs +2 -1
- package/dist/v2/runtime/endpoints/hono.cjs.map +1 -1
- package/dist/v2/runtime/endpoints/hono.d.cts +6 -0
- package/dist/v2/runtime/endpoints/hono.d.cts.map +1 -1
- package/dist/v2/runtime/endpoints/hono.d.mts +6 -0
- package/dist/v2/runtime/endpoints/hono.d.mts.map +1 -1
- package/dist/v2/runtime/endpoints/hono.mjs +2 -1
- package/dist/v2/runtime/endpoints/hono.mjs.map +1 -1
- package/dist/v2/runtime/endpoints/single-route-helpers.cjs +29 -1
- package/dist/v2/runtime/endpoints/single-route-helpers.cjs.map +1 -1
- package/dist/v2/runtime/endpoints/single-route-helpers.mjs +29 -2
- package/dist/v2/runtime/endpoints/single-route-helpers.mjs.map +1 -1
- package/dist/v2/runtime/handlers/get-runtime-info.cjs +8 -3
- package/dist/v2/runtime/handlers/get-runtime-info.cjs.map +1 -1
- package/dist/v2/runtime/handlers/get-runtime-info.mjs +8 -3
- package/dist/v2/runtime/handlers/get-runtime-info.mjs.map +1 -1
- package/dist/v2/runtime/handlers/handle-inspector-learning.cjs +56 -0
- package/dist/v2/runtime/handlers/handle-inspector-learning.cjs.map +1 -0
- package/dist/v2/runtime/handlers/handle-inspector-learning.mjs +55 -0
- package/dist/v2/runtime/handlers/handle-inspector-learning.mjs.map +1 -0
- package/dist/v2/runtime/handlers/shared/sse-response.cjs +1 -1
- package/dist/v2/runtime/handlers/shared/sse-response.cjs.map +1 -1
- package/dist/v2/runtime/handlers/shared/sse-response.mjs +1 -1
- package/dist/v2/runtime/handlers/shared/sse-response.mjs.map +1 -1
- package/dist/v2/runtime/intelligence-platform/client.cjs +49 -1
- package/dist/v2/runtime/intelligence-platform/client.cjs.map +1 -1
- package/dist/v2/runtime/intelligence-platform/client.d.cts +5 -1
- package/dist/v2/runtime/intelligence-platform/client.d.cts.map +1 -1
- package/dist/v2/runtime/intelligence-platform/client.d.mts +5 -1
- package/dist/v2/runtime/intelligence-platform/client.d.mts.map +1 -1
- package/dist/v2/runtime/intelligence-platform/client.mjs +50 -2
- package/dist/v2/runtime/intelligence-platform/client.mjs.map +1 -1
- package/dist/v2/runtime/telemetry/telemetry-client.mjs +2 -2
- package/dist/v2/runtime/telemetry/telemetry-client.mjs.map +1 -1
- package/package.json +6 -6
- package/skills/runtime/SKILL.md +1 -1
- package/skills/runtime/references/intelligence-mode.md +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.d.cts","names":[],"sources":["../../../../src/v2/runtime/core/hooks.ts"],"mappings":";;;;;KAmCY,SAAA;EACN,MAAA;EAAqB,OAAA;AAAA;EACrB,MAAA;EAAyB,OAAA;AAAA;EACzB,MAAA;EAAyB,OAAA;AAAA;EACzB,MAAA;EAAsB,OAAA;EAAiB,QAAA;AAAA;EACvC,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;EAA0B,QAAA;AAAA;EAC1B,MAAA;EAA2B,QAAA;AAAA;EAC3B,MAAA;EAA4B,QAAA;AAAA;EAC5B,MAAA;EAA0B,QAAA;AAAA;EAC1B,MAAA;EAAyB,QAAA;AAAA;EACzB,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;EAA2B,QAAA;AAAA;EAC3B,MAAA;AAAA;EACA,MAAA;AAAA;AAAA,UAMW,WAAA;
|
|
1
|
+
{"version":3,"file":"hooks.d.cts","names":[],"sources":["../../../../src/v2/runtime/core/hooks.ts"],"mappings":";;;;;KAmCY,SAAA;EACN,MAAA;EAAqB,OAAA;AAAA;EACrB,MAAA;EAAyB,OAAA;AAAA;EACzB,MAAA;EAAyB,OAAA;AAAA;EACzB,MAAA;EAAsB,OAAA;EAAiB,QAAA;AAAA;EACvC,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;EAA0B,QAAA;AAAA;EAC1B,MAAA;EAA2B,QAAA;AAAA;EAC3B,MAAA;EAA4B,QAAA;AAAA;EAC5B,MAAA;EAA0B,QAAA;AAAA;EAC1B,MAAA;EAAyB,QAAA;AAAA;EACzB,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;EAA2B,QAAA;AAAA;EAC3B,MAAA;AAAA;EACA,MAAA;AAAA;AAAA,UAMW,WAAA;EAyBE;EAvBjB,OAAA,EAAS,OAAA;EA8BM;EA5Bf,IAAA;;EAEA,OAAA,EAAS,kBAAA;AAAA;AAAA,UAGM,kBAAA,SAA2B,WAAA;EAyClB;EAvCxB,KAAA,EAAO,SAAA;AAAA;AAAA,UAGQ,mBAAA,SAA4B,WAAA;EA4Ca;EA1CxD,QAAA,EAAU,QAAA;EAgDM;EA9ChB,KAAA,EAAO,SAAA;AAAA;AAAA,UAGQ,gBAAA,SAAyB,WAAA;EA2CS;EAzCjD,KAAA;EAiBkB;EAflB,KAAA,GAAQ,SAAA;AAAA;AAAA,UAOO,mBAAA;EAkBf;;;;;;;EAVA,SAAA,IAAa,GAAA,EAAK,WAAA,KAAgB,YAAA,CAAa,OAAA;EAkBJ;;;;;;;;EAR3C,eAAA,IAAmB,GAAA,EAAK,kBAAA,KAAuB,YAAA,CAAa,OAAA;;;;;;;EAQ5D,UAAA,IAAc,GAAA,EAAK,mBAAA,KAAwB,YAAA,CAAa,QAAA;;;;;EAMxD,OAAA,IAAW,GAAA,EAAK,gBAAA,KAAqB,YAAA,CAAa,QAAA;AAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.d.mts","names":[],"sources":["../../../../src/v2/runtime/core/hooks.ts"],"mappings":";;;;;KAmCY,SAAA;EACN,MAAA;EAAqB,OAAA;AAAA;EACrB,MAAA;EAAyB,OAAA;AAAA;EACzB,MAAA;EAAyB,OAAA;AAAA;EACzB,MAAA;EAAsB,OAAA;EAAiB,QAAA;AAAA;EACvC,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;EAA0B,QAAA;AAAA;EAC1B,MAAA;EAA2B,QAAA;AAAA;EAC3B,MAAA;EAA4B,QAAA;AAAA;EAC5B,MAAA;EAA0B,QAAA;AAAA;EAC1B,MAAA;EAAyB,QAAA;AAAA;EACzB,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;EAA2B,QAAA;AAAA;EAC3B,MAAA;AAAA;EACA,MAAA;AAAA;AAAA,UAMW,WAAA;
|
|
1
|
+
{"version":3,"file":"hooks.d.mts","names":[],"sources":["../../../../src/v2/runtime/core/hooks.ts"],"mappings":";;;;;KAmCY,SAAA;EACN,MAAA;EAAqB,OAAA;AAAA;EACrB,MAAA;EAAyB,OAAA;AAAA;EACzB,MAAA;EAAyB,OAAA;AAAA;EACzB,MAAA;EAAsB,OAAA;EAAiB,QAAA;AAAA;EACvC,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;EAA0B,QAAA;AAAA;EAC1B,MAAA;EAA2B,QAAA;AAAA;EAC3B,MAAA;EAA4B,QAAA;AAAA;EAC5B,MAAA;EAA0B,QAAA;AAAA;EAC1B,MAAA;EAAyB,QAAA;AAAA;EACzB,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;EAA2B,QAAA;AAAA;EAC3B,MAAA;AAAA;EACA,MAAA;AAAA;AAAA,UAMW,WAAA;EAyBE;EAvBjB,OAAA,EAAS,OAAA;EA8BM;EA5Bf,IAAA;;EAEA,OAAA,EAAS,kBAAA;AAAA;AAAA,UAGM,kBAAA,SAA2B,WAAA;EAyClB;EAvCxB,KAAA,EAAO,SAAA;AAAA;AAAA,UAGQ,mBAAA,SAA4B,WAAA;EA4Ca;EA1CxD,QAAA,EAAU,QAAA;EAgDM;EA9ChB,KAAA,EAAO,SAAA;AAAA;AAAA,UAGQ,gBAAA,SAAyB,WAAA;EA2CS;EAzCjD,KAAA;EAiBkB;EAflB,KAAA,GAAQ,SAAA;AAAA;AAAA,UAOO,mBAAA;EAkBf;;;;;;;EAVA,SAAA,IAAa,GAAA,EAAK,WAAA,KAAgB,YAAA,CAAa,OAAA;EAkBJ;;;;;;;;EAR3C,eAAA,IAAmB,GAAA,EAAK,kBAAA,KAAuB,YAAA,CAAa,OAAA;;;;;;;EAQ5D,UAAA,IAAc,GAAA,EAAK,mBAAA,KAAwB,YAAA,CAAa,QAAA;;;;;EAMxD,OAAA,IAAW,GAAA,EAAK,gBAAA,KAAqB,YAAA,CAAa,QAAA;AAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.mjs","names":[],"sources":["../../../../src/v2/runtime/core/hooks.ts"],"sourcesContent":["/**\n * Lifecycle hooks for CopilotKit runtime request processing.\n *\n * Hooks let you intercept requests at various stages of the pipeline:\n * - `onRequest`: Before routing — auth, correlation IDs, header injection\n * - `onBeforeHandler`: After routing — route-specific authorization\n * - `onResponse`: After handler — add headers, log, set cookies\n * - `onError`: On error — custom error responses\n *\n * @example\n * ```typescript\n * const handler = createCopilotRuntimeHandler({\n * runtime,\n * hooks: {\n * onRequest: async ({ request }) => {\n * const token = request.headers.get(\"authorization\");\n * if (!token) throw new Response(\"Unauthorized\", { status: 401 });\n * },\n * onResponse: async ({ response }) => {\n * const headers = new Headers(response.headers);\n * headers.set(\"x-copilot-version\", \"2.0\");\n * return new Response(response.body, { ...response, headers });\n * },\n * },\n * });\n * ```\n */\n\nimport type { MaybePromise } from \"@copilotkit/shared\";\nimport type { CopilotRuntimeLike } from \"./runtime\";\n\n/* ------------------------------------------------------------------------------------------------\n * Route info\n * --------------------------------------------------------------------------------------------- */\n\nexport type RouteInfo =\n | { method: \"agent/run\"; agentId: string }\n | { method: \"agent/suggest\"; agentId: string }\n | { method: \"agent/connect\"; agentId: string }\n | { method: \"agent/stop\"; agentId: string; threadId: string }\n | { method: \"info\" }\n | { method: \"inspector/metadata\" }\n | { method: \"transcribe\" }\n | { method: \"threads/list\" }\n | { method: \"threads/subscribe\" }\n | { method: \"threads/update\"; threadId: string }\n | { method: \"threads/archive\"; threadId: string }\n | { method: \"threads/messages\"; threadId: string }\n | { method: \"threads/events\"; threadId: string }\n | { method: \"threads/state\"; threadId: string }\n | { method: \"threads/clear\" }\n | { method: \"memories/list\" }\n | { method: \"memories/recall\" }\n | { method: \"memories/subscribe\" }\n | { method: \"memories/mutate\"; memoryId: string }\n | { method: \"annotate\" }\n | { method: \"cpk-debug-events\" };\n\n/* ------------------------------------------------------------------------------------------------\n * Hook contexts\n * --------------------------------------------------------------------------------------------- */\n\nexport interface HookContext {\n /** The incoming Fetch Request (possibly modified by prior hooks). */\n request: Request;\n /** The resolved URL pathname. */\n path: string;\n /** The CopilotRuntimeLike instance. */\n runtime: CopilotRuntimeLike;\n}\n\nexport interface HandlerHookContext extends HookContext {\n /** The resolved route information. */\n route: RouteInfo;\n}\n\nexport interface ResponseHookContext extends HookContext {\n /** The Response produced by the handler. */\n response: Response;\n /** The resolved route information. */\n route: RouteInfo;\n}\n\nexport interface ErrorHookContext extends HookContext {\n /** The error that occurred. */\n error: unknown;\n /** The route info, if routing had already succeeded. */\n route?: RouteInfo;\n}\n\n/* ------------------------------------------------------------------------------------------------\n * Hooks interface\n * --------------------------------------------------------------------------------------------- */\n\nexport interface CopilotRuntimeHooks {\n /**\n * Called at the start of every request, before routing.\n * Use to validate auth, attach headers, initialize correlation IDs, etc.\n *\n * Return a modified Request to replace the original, or void to continue.\n * Throw a Response to short-circuit with an early response.\n */\n onRequest?: (ctx: HookContext) => MaybePromise<Request | void>;\n\n /**\n * Called after routing is resolved but before the handler executes.\n * Receives the resolved route info (method, agentId, threadId).\n *\n * Use to do route-specific authorization, attach headers for agent calls, etc.\n * Return a modified Request or void.\n * Throw a Response to short-circuit.\n */\n onBeforeHandler?: (ctx: HandlerHookContext) => MaybePromise<Request | void>;\n\n /**\n * Called after the handler produces a Response, before it's sent to the client.\n * Use to set cookies, add debugging headers, log, etc.\n *\n * Return a modified Response to replace the original, or void.\n */\n onResponse?: (ctx: ResponseHookContext) => MaybePromise<Response | void>;\n\n /**\n * Called when an error occurs during request processing.\n * Return a Response to override the default error response, or void to use the default.\n */\n onError?: (ctx: ErrorHookContext) => MaybePromise<Response | void>;\n}\n\n/* ------------------------------------------------------------------------------------------------\n * Internal hook runners\n * --------------------------------------------------------------------------------------------- */\n\nexport async function runOnRequest(\n hooks: CopilotRuntimeHooks | undefined,\n ctx: HookContext,\n): Promise<Request> {\n if (!hooks?.onRequest) return ctx.request;\n const result = await hooks.onRequest(ctx);\n return result instanceof Request ? result : ctx.request;\n}\n\nexport async function runOnBeforeHandler(\n hooks: CopilotRuntimeHooks | undefined,\n ctx: HandlerHookContext,\n): Promise<Request> {\n if (!hooks?.onBeforeHandler) return ctx.request;\n const result = await hooks.onBeforeHandler(ctx);\n return result instanceof Request ? result : ctx.request;\n}\n\nexport async function runOnResponse(\n hooks: CopilotRuntimeHooks | undefined,\n ctx: ResponseHookContext,\n): Promise<Response> {\n if (!hooks?.onResponse) return ctx.response;\n const result = await hooks.onResponse(ctx);\n return result instanceof Response ? result : ctx.response;\n}\n\nexport async function runOnError(\n hooks: CopilotRuntimeHooks | undefined,\n ctx: ErrorHookContext,\n): Promise<Response | void> {\n if (!hooks?.onError) return;\n return hooks.onError(ctx);\n}\n"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"hooks.mjs","names":[],"sources":["../../../../src/v2/runtime/core/hooks.ts"],"sourcesContent":["/**\n * Lifecycle hooks for CopilotKit runtime request processing.\n *\n * Hooks let you intercept requests at various stages of the pipeline:\n * - `onRequest`: Before routing — auth, correlation IDs, header injection\n * - `onBeforeHandler`: After routing — route-specific authorization\n * - `onResponse`: After handler — add headers, log, set cookies\n * - `onError`: On error — custom error responses\n *\n * @example\n * ```typescript\n * const handler = createCopilotRuntimeHandler({\n * runtime,\n * hooks: {\n * onRequest: async ({ request }) => {\n * const token = request.headers.get(\"authorization\");\n * if (!token) throw new Response(\"Unauthorized\", { status: 401 });\n * },\n * onResponse: async ({ response }) => {\n * const headers = new Headers(response.headers);\n * headers.set(\"x-copilot-version\", \"2.0\");\n * return new Response(response.body, { ...response, headers });\n * },\n * },\n * });\n * ```\n */\n\nimport type { MaybePromise } from \"@copilotkit/shared\";\nimport type { CopilotRuntimeLike } from \"./runtime\";\n\n/* ------------------------------------------------------------------------------------------------\n * Route info\n * --------------------------------------------------------------------------------------------- */\n\nexport type RouteInfo =\n | { method: \"agent/run\"; agentId: string }\n | { method: \"agent/suggest\"; agentId: string }\n | { method: \"agent/connect\"; agentId: string }\n | { method: \"agent/stop\"; agentId: string; threadId: string }\n | { method: \"info\" }\n | { method: \"inspector/metadata\" }\n | { method: \"inspector/learning\" }\n | { method: \"transcribe\" }\n | { method: \"threads/list\" }\n | { method: \"threads/subscribe\" }\n | { method: \"threads/update\"; threadId: string }\n | { method: \"threads/archive\"; threadId: string }\n | { method: \"threads/messages\"; threadId: string }\n | { method: \"threads/events\"; threadId: string }\n | { method: \"threads/state\"; threadId: string }\n | { method: \"threads/clear\" }\n | { method: \"memories/list\" }\n | { method: \"memories/recall\" }\n | { method: \"memories/subscribe\" }\n | { method: \"memories/mutate\"; memoryId: string }\n | { method: \"annotate\" }\n | { method: \"cpk-debug-events\" };\n\n/* ------------------------------------------------------------------------------------------------\n * Hook contexts\n * --------------------------------------------------------------------------------------------- */\n\nexport interface HookContext {\n /** The incoming Fetch Request (possibly modified by prior hooks). */\n request: Request;\n /** The resolved URL pathname. */\n path: string;\n /** The CopilotRuntimeLike instance. */\n runtime: CopilotRuntimeLike;\n}\n\nexport interface HandlerHookContext extends HookContext {\n /** The resolved route information. */\n route: RouteInfo;\n}\n\nexport interface ResponseHookContext extends HookContext {\n /** The Response produced by the handler. */\n response: Response;\n /** The resolved route information. */\n route: RouteInfo;\n}\n\nexport interface ErrorHookContext extends HookContext {\n /** The error that occurred. */\n error: unknown;\n /** The route info, if routing had already succeeded. */\n route?: RouteInfo;\n}\n\n/* ------------------------------------------------------------------------------------------------\n * Hooks interface\n * --------------------------------------------------------------------------------------------- */\n\nexport interface CopilotRuntimeHooks {\n /**\n * Called at the start of every request, before routing.\n * Use to validate auth, attach headers, initialize correlation IDs, etc.\n *\n * Return a modified Request to replace the original, or void to continue.\n * Throw a Response to short-circuit with an early response.\n */\n onRequest?: (ctx: HookContext) => MaybePromise<Request | void>;\n\n /**\n * Called after routing is resolved but before the handler executes.\n * Receives the resolved route info (method, agentId, threadId).\n *\n * Use to do route-specific authorization, attach headers for agent calls, etc.\n * Return a modified Request or void.\n * Throw a Response to short-circuit.\n */\n onBeforeHandler?: (ctx: HandlerHookContext) => MaybePromise<Request | void>;\n\n /**\n * Called after the handler produces a Response, before it's sent to the client.\n * Use to set cookies, add debugging headers, log, etc.\n *\n * Return a modified Response to replace the original, or void.\n */\n onResponse?: (ctx: ResponseHookContext) => MaybePromise<Response | void>;\n\n /**\n * Called when an error occurs during request processing.\n * Return a Response to override the default error response, or void to use the default.\n */\n onError?: (ctx: ErrorHookContext) => MaybePromise<Response | void>;\n}\n\n/* ------------------------------------------------------------------------------------------------\n * Internal hook runners\n * --------------------------------------------------------------------------------------------- */\n\nexport async function runOnRequest(\n hooks: CopilotRuntimeHooks | undefined,\n ctx: HookContext,\n): Promise<Request> {\n if (!hooks?.onRequest) return ctx.request;\n const result = await hooks.onRequest(ctx);\n return result instanceof Request ? result : ctx.request;\n}\n\nexport async function runOnBeforeHandler(\n hooks: CopilotRuntimeHooks | undefined,\n ctx: HandlerHookContext,\n): Promise<Request> {\n if (!hooks?.onBeforeHandler) return ctx.request;\n const result = await hooks.onBeforeHandler(ctx);\n return result instanceof Request ? result : ctx.request;\n}\n\nexport async function runOnResponse(\n hooks: CopilotRuntimeHooks | undefined,\n ctx: ResponseHookContext,\n): Promise<Response> {\n if (!hooks?.onResponse) return ctx.response;\n const result = await hooks.onResponse(ctx);\n return result instanceof Response ? result : ctx.response;\n}\n\nexport async function runOnError(\n hooks: CopilotRuntimeHooks | undefined,\n ctx: ErrorHookContext,\n): Promise<Response | void> {\n if (!hooks?.onError) return;\n return hooks.onError(ctx);\n}\n"],"mappings":";;AAsIA,eAAsB,aACpB,OACA,KACkB;AAClB,KAAI,CAAC,OAAO,UAAW,QAAO,IAAI;CAClC,MAAM,SAAS,MAAM,MAAM,UAAU,IAAI;AACzC,QAAO,kBAAkB,UAAU,SAAS,IAAI;;AAGlD,eAAsB,mBACpB,OACA,KACkB;AAClB,KAAI,CAAC,OAAO,gBAAiB,QAAO,IAAI;CACxC,MAAM,SAAS,MAAM,MAAM,gBAAgB,IAAI;AAC/C,QAAO,kBAAkB,UAAU,SAAS,IAAI;;AAGlD,eAAsB,cACpB,OACA,KACmB;AACnB,KAAI,CAAC,OAAO,WAAY,QAAO,IAAI;CACnC,MAAM,SAAS,MAAM,MAAM,WAAW,IAAI;AAC1C,QAAO,kBAAkB,WAAW,SAAS,IAAI;;AAGnD,eAAsB,WACpB,OACA,KAC0B;AAC1B,KAAI,CAAC,OAAO,QAAS;AACrB,QAAO,MAAM,QAAQ,IAAI"}
|
|
@@ -9,7 +9,7 @@ let cors = require("cors");
|
|
|
9
9
|
cors = require_runtime.__toESM(cors);
|
|
10
10
|
|
|
11
11
|
//#region src/v2/runtime/endpoints/express.ts
|
|
12
|
-
function createCopilotExpressHandler({ runtime, basePath, mode = "multi-route", cors: corsOption = true, hooks, activateChannels, __channelEngine }) {
|
|
12
|
+
function createCopilotExpressHandler({ runtime, basePath, mode = "multi-route", cors: corsOption = true, hooks, inspectorLearning, activateChannels, __channelEngine }) {
|
|
13
13
|
const normalizedBase = normalizeBasePath(basePath);
|
|
14
14
|
const handler = require_fetch_handler.createCopilotRuntimeHandler({
|
|
15
15
|
runtime,
|
|
@@ -17,6 +17,7 @@ function createCopilotExpressHandler({ runtime, basePath, mode = "multi-route",
|
|
|
17
17
|
mode,
|
|
18
18
|
cors: false,
|
|
19
19
|
hooks,
|
|
20
|
+
inspectorLearning,
|
|
20
21
|
activateChannels,
|
|
21
22
|
__channelEngine
|
|
22
23
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"express.cjs","names":["createCopilotRuntimeHandler","createExpressNodeHandler"],"sources":["../../../../src/v2/runtime/endpoints/express.ts"],"sourcesContent":["import express from \"express\";\nimport type {\n Request as ExpressRequest,\n Response as ExpressResponse,\n NextFunction,\n Router,\n} from \"express\";\nimport cors from \"cors\";\nimport type { CorsOptions } from \"cors\";\nimport type { CopilotRuntimeLike } from \"../core/runtime\";\nimport { createCopilotRuntimeHandler } from \"../core/fetch-handler\";\nimport type {\n ActivateChannelEngine,\n ChannelsControl,\n} from \"../core/channel-manager\";\nimport { createExpressNodeHandler } from \"./express-fetch-bridge\";\nimport { autoStartChannels } from \"./auto-start-channels\";\nimport type { CopilotRuntimeHooks } from \"../core/hooks\";\n\n/**\n * An Express {@link Router} that may also carry an optional\n * {@link ChannelsControl} surface. The Router object itself is request-scoped\n * middleware, but an Express app can only run inside a long-running\n * `http.Server` — so this wrapper is a lifecycle-owning host like\n * `createCopilotNodeListener`: it STARTS activation of the runtime's declared\n * managed Channels at creation, and `.channels` is here to observe (`ready()`)\n * or tear down (`stop()`) that activation.\n */\nexport type CopilotExpressRouter = Router & { channels?: ChannelsControl };\n\nexport interface CopilotExpressEndpointParams {\n runtime: CopilotRuntimeLike;\n basePath: string;\n\n /**\n * Endpoint mode.\n * - `\"multi-route\"` (default): separate routes for each operation\n * - `\"single-route\"`: single POST endpoint with JSON envelope dispatch\n */\n mode?: \"multi-route\" | \"single-route\";\n\n /**\n * CORS configuration for the Express router.\n * - `true` (default): permissive CORS (`origin: \"*\"`, all methods, all headers).\n * - `false`: no CORS middleware is applied — handle it yourself.\n * - object: passed directly to the Express `cors()` middleware.\n */\n cors?: boolean | CorsOptions;\n\n /**\n * Lifecycle hooks for request processing.\n */\n hooks?: CopilotRuntimeHooks;\n\n /**\n * Whether the underlying handler builds the control surface for the runtime's\n * declared managed Channels — and, because Express is a long-running host,\n * starts their activation at creation. Defaults to `true`. Set `false` to\n * build no surface and open no socket (tests, short-lived scripts). See\n * `CopilotRuntimeHandlerOptions.activateChannels`.\n */\n activateChannels?: boolean;\n\n /**\n * @internal Test seam: inject a fake Channel activation engine. Forwarded\n * to `createCopilotRuntimeHandler`. Not part of the public API.\n */\n __channelEngine?: ActivateChannelEngine;\n}\n\n/**\n * Creates an Express router that serves the CopilotKit runtime.\n *\n * In **multi-route** mode (default) the router exposes:\n * - `GET {basePath}/info` — runtime info\n * - `POST {basePath}/agent/:agentId/run` — start an agent run\n * - `POST {basePath}/agent/:agentId/connect` — connect to an agent run\n * - `POST {basePath}/agent/:agentId/stop/:threadId` — stop an agent run\n * - `POST {basePath}/transcribe` — transcribe audio\n *\n * In **single-route** mode a single `POST {basePath}` endpoint accepts a JSON\n * envelope `{ method, params, body }` and dispatches to the appropriate handler.\n *\n * @example\n * ```typescript\n * import express from \"express\";\n * import { CopilotRuntime } from \"@copilotkit/runtime/v2\";\n * import { createCopilotExpressHandler } from \"@copilotkit/runtime/v2/express\";\n *\n * const runtime = new CopilotRuntime({\n * agents: { default: new BuiltInAgent({ model: \"openai/gpt-4o-mini\" }) },\n * });\n *\n * const app = express();\n * app.use(createCopilotExpressHandler({\n * runtime,\n * basePath: \"/api/copilotkit\",\n * cors: true,\n * }));\n * app.listen(4000);\n * ```\n *\n * @example Single-route mode with lifecycle hooks\n * ```typescript\n * app.use(createCopilotExpressHandler({\n * runtime,\n * basePath: \"/api/copilotkit\",\n * mode: \"single-route\",\n * hooks: {\n * onRequest: ({ request }) => {\n * if (!request.headers.get(\"authorization\")) {\n * throw new Response(\"Unauthorized\", { status: 401 });\n * }\n * },\n * },\n * }));\n * ```\n */\n/** @deprecated Use `createCopilotExpressHandler` instead. */\nexport { createCopilotExpressHandler as createCopilotEndpointExpress };\n\nexport function createCopilotExpressHandler({\n runtime,\n basePath,\n mode = \"multi-route\",\n cors: corsOption = true,\n hooks,\n activateChannels,\n __channelEngine,\n}: CopilotExpressEndpointParams): CopilotExpressRouter {\n const normalizedBase = normalizeBasePath(basePath);\n\n const handler = createCopilotRuntimeHandler({\n runtime,\n basePath: normalizedBase,\n mode,\n cors: false, // CORS is handled at the Express middleware layer\n hooks,\n activateChannels,\n __channelEngine,\n });\n\n const nodeHandler = createExpressNodeHandler(handler);\n\n const expressHandler = async (\n req: ExpressRequest,\n res: ExpressResponse,\n next: NextFunction,\n ) => {\n try {\n await nodeHandler(req, res);\n } catch (err) {\n next(err);\n }\n };\n\n const router = express.Router();\n\n // CORS middleware\n if (corsOption) {\n const corsConfig: CorsOptions =\n corsOption === true\n ? {\n origin: \"*\",\n methods: [\n \"GET\",\n \"HEAD\",\n \"PUT\",\n \"POST\",\n \"DELETE\",\n \"PATCH\",\n \"OPTIONS\",\n ],\n allowedHeaders: [\"*\"],\n }\n : corsOption;\n router.use(cors(corsConfig));\n }\n\n // Route mounting\n if (mode === \"single-route\") {\n router.post(normalizedBase, expressHandler);\n router.options(normalizedBase, expressHandler);\n } else if (normalizedBase === \"/\") {\n router.all(/.*/, expressHandler);\n } else {\n router.all(\n new RegExp(`^${escapeRegExp(normalizedBase)}(\\\\/.*)?$`),\n expressHandler,\n );\n }\n\n const exposedRouter: CopilotExpressRouter = router;\n exposedRouter.channels = handler.channels;\n autoStartChannels(exposedRouter.channels);\n return exposedRouter;\n}\n\nfunction escapeRegExp(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nfunction normalizeBasePath(path: string): string {\n if (!path) {\n throw new Error(\"basePath must be provided for Express endpoint\");\n }\n\n if (!path.startsWith(\"/\")) {\n return `/${path}`;\n }\n\n if (path.length > 1 && path.endsWith(\"/\")) {\n return path.slice(0, -1);\n }\n\n return path;\n}\n"],"mappings":";;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"express.cjs","names":["createCopilotRuntimeHandler","createExpressNodeHandler"],"sources":["../../../../src/v2/runtime/endpoints/express.ts"],"sourcesContent":["import express from \"express\";\nimport type {\n Request as ExpressRequest,\n Response as ExpressResponse,\n NextFunction,\n Router,\n} from \"express\";\nimport cors from \"cors\";\nimport type { CorsOptions } from \"cors\";\nimport type { CopilotRuntimeLike } from \"../core/runtime\";\nimport { createCopilotRuntimeHandler } from \"../core/fetch-handler\";\nimport type {\n ActivateChannelEngine,\n ChannelsControl,\n} from \"../core/channel-manager\";\nimport { createExpressNodeHandler } from \"./express-fetch-bridge\";\nimport { autoStartChannels } from \"./auto-start-channels\";\nimport type { CopilotRuntimeHooks } from \"../core/hooks\";\n\n/**\n * An Express {@link Router} that may also carry an optional\n * {@link ChannelsControl} surface. The Router object itself is request-scoped\n * middleware, but an Express app can only run inside a long-running\n * `http.Server` — so this wrapper is a lifecycle-owning host like\n * `createCopilotNodeListener`: it STARTS activation of the runtime's declared\n * managed Channels at creation, and `.channels` is here to observe (`ready()`)\n * or tear down (`stop()`) that activation.\n */\nexport type CopilotExpressRouter = Router & { channels?: ChannelsControl };\n\nexport interface CopilotExpressEndpointParams {\n runtime: CopilotRuntimeLike;\n basePath: string;\n\n /**\n * Endpoint mode.\n * - `\"multi-route\"` (default): separate routes for each operation\n * - `\"single-route\"`: single POST endpoint with JSON envelope dispatch\n */\n mode?: \"multi-route\" | \"single-route\";\n\n /**\n * CORS configuration for the Express router.\n * - `true` (default): permissive CORS (`origin: \"*\"`, all methods, all headers).\n * - `false`: no CORS middleware is applied — handle it yourself.\n * - object: passed directly to the Express `cors()` middleware.\n */\n cors?: boolean | CorsOptions;\n\n /**\n * Lifecycle hooks for request processing.\n */\n hooks?: CopilotRuntimeHooks;\n\n /**\n * Whether to expose the debug-gated Inspector Learning snapshot route.\n * Defaults to `false`.\n */\n inspectorLearning?: boolean;\n\n /**\n * Whether the underlying handler builds the control surface for the runtime's\n * declared managed Channels — and, because Express is a long-running host,\n * starts their activation at creation. Defaults to `true`. Set `false` to\n * build no surface and open no socket (tests, short-lived scripts). See\n * `CopilotRuntimeHandlerOptions.activateChannels`.\n */\n activateChannels?: boolean;\n\n /**\n * @internal Test seam: inject a fake Channel activation engine. Forwarded\n * to `createCopilotRuntimeHandler`. Not part of the public API.\n */\n __channelEngine?: ActivateChannelEngine;\n}\n\n/**\n * Creates an Express router that serves the CopilotKit runtime.\n *\n * In **multi-route** mode (default) the router exposes:\n * - `GET {basePath}/info` — runtime info\n * - `POST {basePath}/agent/:agentId/run` — start an agent run\n * - `POST {basePath}/agent/:agentId/connect` — connect to an agent run\n * - `POST {basePath}/agent/:agentId/stop/:threadId` — stop an agent run\n * - `POST {basePath}/transcribe` — transcribe audio\n *\n * In **single-route** mode a single `POST {basePath}` endpoint accepts a JSON\n * envelope `{ method, params, body }` and dispatches to the appropriate handler.\n *\n * @example\n * ```typescript\n * import express from \"express\";\n * import { CopilotRuntime } from \"@copilotkit/runtime/v2\";\n * import { createCopilotExpressHandler } from \"@copilotkit/runtime/v2/express\";\n *\n * const runtime = new CopilotRuntime({\n * agents: { default: new BuiltInAgent({ model: \"openai/gpt-4o-mini\" }) },\n * });\n *\n * const app = express();\n * app.use(createCopilotExpressHandler({\n * runtime,\n * basePath: \"/api/copilotkit\",\n * cors: true,\n * }));\n * app.listen(4000);\n * ```\n *\n * @example Single-route mode with lifecycle hooks\n * ```typescript\n * app.use(createCopilotExpressHandler({\n * runtime,\n * basePath: \"/api/copilotkit\",\n * mode: \"single-route\",\n * hooks: {\n * onRequest: ({ request }) => {\n * if (!request.headers.get(\"authorization\")) {\n * throw new Response(\"Unauthorized\", { status: 401 });\n * }\n * },\n * },\n * }));\n * ```\n */\n/** @deprecated Use `createCopilotExpressHandler` instead. */\nexport { createCopilotExpressHandler as createCopilotEndpointExpress };\n\nexport function createCopilotExpressHandler({\n runtime,\n basePath,\n mode = \"multi-route\",\n cors: corsOption = true,\n hooks,\n inspectorLearning,\n activateChannels,\n __channelEngine,\n}: CopilotExpressEndpointParams): CopilotExpressRouter {\n const normalizedBase = normalizeBasePath(basePath);\n\n const handler = createCopilotRuntimeHandler({\n runtime,\n basePath: normalizedBase,\n mode,\n cors: false, // CORS is handled at the Express middleware layer\n hooks,\n inspectorLearning,\n activateChannels,\n __channelEngine,\n });\n\n const nodeHandler = createExpressNodeHandler(handler);\n\n const expressHandler = async (\n req: ExpressRequest,\n res: ExpressResponse,\n next: NextFunction,\n ) => {\n try {\n await nodeHandler(req, res);\n } catch (err) {\n next(err);\n }\n };\n\n const router = express.Router();\n\n // CORS middleware\n if (corsOption) {\n const corsConfig: CorsOptions =\n corsOption === true\n ? {\n origin: \"*\",\n methods: [\n \"GET\",\n \"HEAD\",\n \"PUT\",\n \"POST\",\n \"DELETE\",\n \"PATCH\",\n \"OPTIONS\",\n ],\n allowedHeaders: [\"*\"],\n }\n : corsOption;\n router.use(cors(corsConfig));\n }\n\n // Route mounting\n if (mode === \"single-route\") {\n router.post(normalizedBase, expressHandler);\n router.options(normalizedBase, expressHandler);\n } else if (normalizedBase === \"/\") {\n router.all(/.*/, expressHandler);\n } else {\n router.all(\n new RegExp(`^${escapeRegExp(normalizedBase)}(\\\\/.*)?$`),\n expressHandler,\n );\n }\n\n const exposedRouter: CopilotExpressRouter = router;\n exposedRouter.channels = handler.channels;\n autoStartChannels(exposedRouter.channels);\n return exposedRouter;\n}\n\nfunction escapeRegExp(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nfunction normalizeBasePath(path: string): string {\n if (!path) {\n throw new Error(\"basePath must be provided for Express endpoint\");\n }\n\n if (!path.startsWith(\"/\")) {\n return `/${path}`;\n }\n\n if (path.length > 1 && path.endsWith(\"/\")) {\n return path.slice(0, -1);\n }\n\n return path;\n}\n"],"mappings":";;;;;;;;;;;AA+HA,SAAgB,4BAA4B,EAC1C,SACA,UACA,OAAO,eACP,MAAM,aAAa,MACnB,OACA,mBACA,kBACA,mBACqD;CACrD,MAAM,iBAAiB,kBAAkB,SAAS;CAElD,MAAM,UAAUA,kDAA4B;EAC1C;EACA,UAAU;EACV;EACA,MAAM;EACN;EACA;EACA;EACA;EACD,CAAC;CAEF,MAAM,cAAcC,sDAAyB,QAAQ;CAErD,MAAM,iBAAiB,OACrB,KACA,KACA,SACG;AACH,MAAI;AACF,SAAM,YAAY,KAAK,IAAI;WACpB,KAAK;AACZ,QAAK,IAAI;;;CAIb,MAAM,SAAS,gBAAQ,QAAQ;AAG/B,KAAI,YAAY;EACd,MAAM,aACJ,eAAe,OACX;GACE,QAAQ;GACR,SAAS;IACP;IACA;IACA;IACA;IACA;IACA;IACA;IACD;GACD,gBAAgB,CAAC,IAAI;GACtB,GACD;AACN,SAAO,sBAAS,WAAW,CAAC;;AAI9B,KAAI,SAAS,gBAAgB;AAC3B,SAAO,KAAK,gBAAgB,eAAe;AAC3C,SAAO,QAAQ,gBAAgB,eAAe;YACrC,mBAAmB,IAC5B,QAAO,IAAI,MAAM,eAAe;KAEhC,QAAO,IACL,IAAI,OAAO,IAAI,aAAa,eAAe,CAAC,WAAW,EACvD,eACD;CAGH,MAAM,gBAAsC;AAC5C,eAAc,WAAW,QAAQ;AACjC,+CAAkB,cAAc,SAAS;AACzC,QAAO;;AAGT,SAAS,aAAa,GAAmB;AACvC,QAAO,EAAE,QAAQ,uBAAuB,OAAO;;AAGjD,SAAS,kBAAkB,MAAsB;AAC/C,KAAI,CAAC,KACH,OAAM,IAAI,MAAM,iDAAiD;AAGnE,KAAI,CAAC,KAAK,WAAW,IAAI,CACvB,QAAO,IAAI;AAGb,KAAI,KAAK,SAAS,KAAK,KAAK,SAAS,IAAI,CACvC,QAAO,KAAK,MAAM,GAAG,GAAG;AAG1B,QAAO"}
|
|
@@ -38,6 +38,11 @@ interface CopilotExpressEndpointParams {
|
|
|
38
38
|
* Lifecycle hooks for request processing.
|
|
39
39
|
*/
|
|
40
40
|
hooks?: CopilotRuntimeHooks;
|
|
41
|
+
/**
|
|
42
|
+
* Whether to expose the debug-gated Inspector Learning snapshot route.
|
|
43
|
+
* Defaults to `false`.
|
|
44
|
+
*/
|
|
45
|
+
inspectorLearning?: boolean;
|
|
41
46
|
/**
|
|
42
47
|
* Whether the underlying handler builds the control surface for the runtime's
|
|
43
48
|
* declared managed Channels — and, because Express is a long-running host,
|
|
@@ -58,6 +63,7 @@ declare function createCopilotExpressHandler({
|
|
|
58
63
|
mode,
|
|
59
64
|
cors: corsOption,
|
|
60
65
|
hooks,
|
|
66
|
+
inspectorLearning,
|
|
61
67
|
activateChannels,
|
|
62
68
|
__channelEngine
|
|
63
69
|
}: CopilotExpressEndpointParams): CopilotExpressRouter;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"express.d.cts","names":[],"sources":["../../../../src/v2/runtime/endpoints/express.ts"],"mappings":";;;;;;;;;;AA4BA;;;;;;;KAAY,oBAAA,GAAuB,MAAA;EAAW,QAAA,GAAW,eAAA;AAAA;AAAA,UAExC,4BAAA;EACf,OAAA,EAAS,kBAAA;EACT,QAAA;EAeiB;;;;;EARjB,IAAA;EARS;;;;;;EAgBT,IAAA,aAAiB,WAAA;
|
|
1
|
+
{"version":3,"file":"express.d.cts","names":[],"sources":["../../../../src/v2/runtime/endpoints/express.ts"],"mappings":";;;;;;;;;;AA4BA;;;;;;;KAAY,oBAAA,GAAuB,MAAA;EAAW,QAAA,GAAW,eAAA;AAAA;AAAA,UAExC,4BAAA;EACf,OAAA,EAAS,kBAAA;EACT,QAAA;EAeiB;;;;;EARjB,IAAA;EARS;;;;;;EAgBT,IAAA,aAAiB,WAAA;EAWjB;;;EANA,KAAA,GAAQ,mBAAA;EAqB+B;;AAsDzC;;EArEE,iBAAA;EAsEA;;;;;;;EA7DA,gBAAA;EAqEC;;;;EA/DD,eAAA,GAAkB,qBAAA;AAAA;AAAA,iBAsDJ,2BAAA,CAAA;EACd,OAAA;EACA,QAAA;EACA,IAAA;EACA,IAAA,EAAM,UAAA;EACN,KAAA;EACA,iBAAA;EACA,gBAAA;EACA;AAAA,GACC,4BAAA,GAA+B,oBAAA"}
|
|
@@ -38,6 +38,11 @@ interface CopilotExpressEndpointParams {
|
|
|
38
38
|
* Lifecycle hooks for request processing.
|
|
39
39
|
*/
|
|
40
40
|
hooks?: CopilotRuntimeHooks;
|
|
41
|
+
/**
|
|
42
|
+
* Whether to expose the debug-gated Inspector Learning snapshot route.
|
|
43
|
+
* Defaults to `false`.
|
|
44
|
+
*/
|
|
45
|
+
inspectorLearning?: boolean;
|
|
41
46
|
/**
|
|
42
47
|
* Whether the underlying handler builds the control surface for the runtime's
|
|
43
48
|
* declared managed Channels — and, because Express is a long-running host,
|
|
@@ -58,6 +63,7 @@ declare function createCopilotExpressHandler({
|
|
|
58
63
|
mode,
|
|
59
64
|
cors: corsOption,
|
|
60
65
|
hooks,
|
|
66
|
+
inspectorLearning,
|
|
61
67
|
activateChannels,
|
|
62
68
|
__channelEngine
|
|
63
69
|
}: CopilotExpressEndpointParams): CopilotExpressRouter;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"express.d.mts","names":[],"sources":["../../../../src/v2/runtime/endpoints/express.ts"],"mappings":";;;;;;;;;;AA4BA;;;;;;;KAAY,oBAAA,GAAuB,MAAA;EAAW,QAAA,GAAW,eAAA;AAAA;AAAA,UAExC,4BAAA;EACf,OAAA,EAAS,kBAAA;EACT,QAAA;EAeiB;;;;;EARjB,IAAA;EARS;;;;;;EAgBT,IAAA,aAAiB,WAAA;
|
|
1
|
+
{"version":3,"file":"express.d.mts","names":[],"sources":["../../../../src/v2/runtime/endpoints/express.ts"],"mappings":";;;;;;;;;;AA4BA;;;;;;;KAAY,oBAAA,GAAuB,MAAA;EAAW,QAAA,GAAW,eAAA;AAAA;AAAA,UAExC,4BAAA;EACf,OAAA,EAAS,kBAAA;EACT,QAAA;EAeiB;;;;;EARjB,IAAA;EARS;;;;;;EAgBT,IAAA,aAAiB,WAAA;EAWjB;;;EANA,KAAA,GAAQ,mBAAA;EAqB+B;;AAsDzC;;EArEE,iBAAA;EAsEA;;;;;;;EA7DA,gBAAA;EAqEC;;;;EA/DD,eAAA,GAAkB,qBAAA;AAAA;AAAA,iBAsDJ,2BAAA,CAAA;EACd,OAAA;EACA,QAAA;EACA,IAAA;EACA,IAAA,EAAM,UAAA;EACN,KAAA;EACA,iBAAA;EACA,gBAAA;EACA;AAAA,GACC,4BAAA,GAA+B,oBAAA"}
|
|
@@ -6,7 +6,7 @@ import express from "express";
|
|
|
6
6
|
import cors from "cors";
|
|
7
7
|
|
|
8
8
|
//#region src/v2/runtime/endpoints/express.ts
|
|
9
|
-
function createCopilotExpressHandler({ runtime, basePath, mode = "multi-route", cors: corsOption = true, hooks, activateChannels, __channelEngine }) {
|
|
9
|
+
function createCopilotExpressHandler({ runtime, basePath, mode = "multi-route", cors: corsOption = true, hooks, inspectorLearning, activateChannels, __channelEngine }) {
|
|
10
10
|
const normalizedBase = normalizeBasePath(basePath);
|
|
11
11
|
const handler = createCopilotRuntimeHandler({
|
|
12
12
|
runtime,
|
|
@@ -14,6 +14,7 @@ function createCopilotExpressHandler({ runtime, basePath, mode = "multi-route",
|
|
|
14
14
|
mode,
|
|
15
15
|
cors: false,
|
|
16
16
|
hooks,
|
|
17
|
+
inspectorLearning,
|
|
17
18
|
activateChannels,
|
|
18
19
|
__channelEngine
|
|
19
20
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"express.mjs","names":[],"sources":["../../../../src/v2/runtime/endpoints/express.ts"],"sourcesContent":["import express from \"express\";\nimport type {\n Request as ExpressRequest,\n Response as ExpressResponse,\n NextFunction,\n Router,\n} from \"express\";\nimport cors from \"cors\";\nimport type { CorsOptions } from \"cors\";\nimport type { CopilotRuntimeLike } from \"../core/runtime\";\nimport { createCopilotRuntimeHandler } from \"../core/fetch-handler\";\nimport type {\n ActivateChannelEngine,\n ChannelsControl,\n} from \"../core/channel-manager\";\nimport { createExpressNodeHandler } from \"./express-fetch-bridge\";\nimport { autoStartChannels } from \"./auto-start-channels\";\nimport type { CopilotRuntimeHooks } from \"../core/hooks\";\n\n/**\n * An Express {@link Router} that may also carry an optional\n * {@link ChannelsControl} surface. The Router object itself is request-scoped\n * middleware, but an Express app can only run inside a long-running\n * `http.Server` — so this wrapper is a lifecycle-owning host like\n * `createCopilotNodeListener`: it STARTS activation of the runtime's declared\n * managed Channels at creation, and `.channels` is here to observe (`ready()`)\n * or tear down (`stop()`) that activation.\n */\nexport type CopilotExpressRouter = Router & { channels?: ChannelsControl };\n\nexport interface CopilotExpressEndpointParams {\n runtime: CopilotRuntimeLike;\n basePath: string;\n\n /**\n * Endpoint mode.\n * - `\"multi-route\"` (default): separate routes for each operation\n * - `\"single-route\"`: single POST endpoint with JSON envelope dispatch\n */\n mode?: \"multi-route\" | \"single-route\";\n\n /**\n * CORS configuration for the Express router.\n * - `true` (default): permissive CORS (`origin: \"*\"`, all methods, all headers).\n * - `false`: no CORS middleware is applied — handle it yourself.\n * - object: passed directly to the Express `cors()` middleware.\n */\n cors?: boolean | CorsOptions;\n\n /**\n * Lifecycle hooks for request processing.\n */\n hooks?: CopilotRuntimeHooks;\n\n /**\n * Whether the underlying handler builds the control surface for the runtime's\n * declared managed Channels — and, because Express is a long-running host,\n * starts their activation at creation. Defaults to `true`. Set `false` to\n * build no surface and open no socket (tests, short-lived scripts). See\n * `CopilotRuntimeHandlerOptions.activateChannels`.\n */\n activateChannels?: boolean;\n\n /**\n * @internal Test seam: inject a fake Channel activation engine. Forwarded\n * to `createCopilotRuntimeHandler`. Not part of the public API.\n */\n __channelEngine?: ActivateChannelEngine;\n}\n\n/**\n * Creates an Express router that serves the CopilotKit runtime.\n *\n * In **multi-route** mode (default) the router exposes:\n * - `GET {basePath}/info` — runtime info\n * - `POST {basePath}/agent/:agentId/run` — start an agent run\n * - `POST {basePath}/agent/:agentId/connect` — connect to an agent run\n * - `POST {basePath}/agent/:agentId/stop/:threadId` — stop an agent run\n * - `POST {basePath}/transcribe` — transcribe audio\n *\n * In **single-route** mode a single `POST {basePath}` endpoint accepts a JSON\n * envelope `{ method, params, body }` and dispatches to the appropriate handler.\n *\n * @example\n * ```typescript\n * import express from \"express\";\n * import { CopilotRuntime } from \"@copilotkit/runtime/v2\";\n * import { createCopilotExpressHandler } from \"@copilotkit/runtime/v2/express\";\n *\n * const runtime = new CopilotRuntime({\n * agents: { default: new BuiltInAgent({ model: \"openai/gpt-4o-mini\" }) },\n * });\n *\n * const app = express();\n * app.use(createCopilotExpressHandler({\n * runtime,\n * basePath: \"/api/copilotkit\",\n * cors: true,\n * }));\n * app.listen(4000);\n * ```\n *\n * @example Single-route mode with lifecycle hooks\n * ```typescript\n * app.use(createCopilotExpressHandler({\n * runtime,\n * basePath: \"/api/copilotkit\",\n * mode: \"single-route\",\n * hooks: {\n * onRequest: ({ request }) => {\n * if (!request.headers.get(\"authorization\")) {\n * throw new Response(\"Unauthorized\", { status: 401 });\n * }\n * },\n * },\n * }));\n * ```\n */\n/** @deprecated Use `createCopilotExpressHandler` instead. */\nexport { createCopilotExpressHandler as createCopilotEndpointExpress };\n\nexport function createCopilotExpressHandler({\n runtime,\n basePath,\n mode = \"multi-route\",\n cors: corsOption = true,\n hooks,\n activateChannels,\n __channelEngine,\n}: CopilotExpressEndpointParams): CopilotExpressRouter {\n const normalizedBase = normalizeBasePath(basePath);\n\n const handler = createCopilotRuntimeHandler({\n runtime,\n basePath: normalizedBase,\n mode,\n cors: false, // CORS is handled at the Express middleware layer\n hooks,\n activateChannels,\n __channelEngine,\n });\n\n const nodeHandler = createExpressNodeHandler(handler);\n\n const expressHandler = async (\n req: ExpressRequest,\n res: ExpressResponse,\n next: NextFunction,\n ) => {\n try {\n await nodeHandler(req, res);\n } catch (err) {\n next(err);\n }\n };\n\n const router = express.Router();\n\n // CORS middleware\n if (corsOption) {\n const corsConfig: CorsOptions =\n corsOption === true\n ? {\n origin: \"*\",\n methods: [\n \"GET\",\n \"HEAD\",\n \"PUT\",\n \"POST\",\n \"DELETE\",\n \"PATCH\",\n \"OPTIONS\",\n ],\n allowedHeaders: [\"*\"],\n }\n : corsOption;\n router.use(cors(corsConfig));\n }\n\n // Route mounting\n if (mode === \"single-route\") {\n router.post(normalizedBase, expressHandler);\n router.options(normalizedBase, expressHandler);\n } else if (normalizedBase === \"/\") {\n router.all(/.*/, expressHandler);\n } else {\n router.all(\n new RegExp(`^${escapeRegExp(normalizedBase)}(\\\\/.*)?$`),\n expressHandler,\n );\n }\n\n const exposedRouter: CopilotExpressRouter = router;\n exposedRouter.channels = handler.channels;\n autoStartChannels(exposedRouter.channels);\n return exposedRouter;\n}\n\nfunction escapeRegExp(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nfunction normalizeBasePath(path: string): string {\n if (!path) {\n throw new Error(\"basePath must be provided for Express endpoint\");\n }\n\n if (!path.startsWith(\"/\")) {\n return `/${path}`;\n }\n\n if (path.length > 1 && path.endsWith(\"/\")) {\n return path.slice(0, -1);\n }\n\n return path;\n}\n"],"mappings":";;;;;;;;
|
|
1
|
+
{"version":3,"file":"express.mjs","names":[],"sources":["../../../../src/v2/runtime/endpoints/express.ts"],"sourcesContent":["import express from \"express\";\nimport type {\n Request as ExpressRequest,\n Response as ExpressResponse,\n NextFunction,\n Router,\n} from \"express\";\nimport cors from \"cors\";\nimport type { CorsOptions } from \"cors\";\nimport type { CopilotRuntimeLike } from \"../core/runtime\";\nimport { createCopilotRuntimeHandler } from \"../core/fetch-handler\";\nimport type {\n ActivateChannelEngine,\n ChannelsControl,\n} from \"../core/channel-manager\";\nimport { createExpressNodeHandler } from \"./express-fetch-bridge\";\nimport { autoStartChannels } from \"./auto-start-channels\";\nimport type { CopilotRuntimeHooks } from \"../core/hooks\";\n\n/**\n * An Express {@link Router} that may also carry an optional\n * {@link ChannelsControl} surface. The Router object itself is request-scoped\n * middleware, but an Express app can only run inside a long-running\n * `http.Server` — so this wrapper is a lifecycle-owning host like\n * `createCopilotNodeListener`: it STARTS activation of the runtime's declared\n * managed Channels at creation, and `.channels` is here to observe (`ready()`)\n * or tear down (`stop()`) that activation.\n */\nexport type CopilotExpressRouter = Router & { channels?: ChannelsControl };\n\nexport interface CopilotExpressEndpointParams {\n runtime: CopilotRuntimeLike;\n basePath: string;\n\n /**\n * Endpoint mode.\n * - `\"multi-route\"` (default): separate routes for each operation\n * - `\"single-route\"`: single POST endpoint with JSON envelope dispatch\n */\n mode?: \"multi-route\" | \"single-route\";\n\n /**\n * CORS configuration for the Express router.\n * - `true` (default): permissive CORS (`origin: \"*\"`, all methods, all headers).\n * - `false`: no CORS middleware is applied — handle it yourself.\n * - object: passed directly to the Express `cors()` middleware.\n */\n cors?: boolean | CorsOptions;\n\n /**\n * Lifecycle hooks for request processing.\n */\n hooks?: CopilotRuntimeHooks;\n\n /**\n * Whether to expose the debug-gated Inspector Learning snapshot route.\n * Defaults to `false`.\n */\n inspectorLearning?: boolean;\n\n /**\n * Whether the underlying handler builds the control surface for the runtime's\n * declared managed Channels — and, because Express is a long-running host,\n * starts their activation at creation. Defaults to `true`. Set `false` to\n * build no surface and open no socket (tests, short-lived scripts). See\n * `CopilotRuntimeHandlerOptions.activateChannels`.\n */\n activateChannels?: boolean;\n\n /**\n * @internal Test seam: inject a fake Channel activation engine. Forwarded\n * to `createCopilotRuntimeHandler`. Not part of the public API.\n */\n __channelEngine?: ActivateChannelEngine;\n}\n\n/**\n * Creates an Express router that serves the CopilotKit runtime.\n *\n * In **multi-route** mode (default) the router exposes:\n * - `GET {basePath}/info` — runtime info\n * - `POST {basePath}/agent/:agentId/run` — start an agent run\n * - `POST {basePath}/agent/:agentId/connect` — connect to an agent run\n * - `POST {basePath}/agent/:agentId/stop/:threadId` — stop an agent run\n * - `POST {basePath}/transcribe` — transcribe audio\n *\n * In **single-route** mode a single `POST {basePath}` endpoint accepts a JSON\n * envelope `{ method, params, body }` and dispatches to the appropriate handler.\n *\n * @example\n * ```typescript\n * import express from \"express\";\n * import { CopilotRuntime } from \"@copilotkit/runtime/v2\";\n * import { createCopilotExpressHandler } from \"@copilotkit/runtime/v2/express\";\n *\n * const runtime = new CopilotRuntime({\n * agents: { default: new BuiltInAgent({ model: \"openai/gpt-4o-mini\" }) },\n * });\n *\n * const app = express();\n * app.use(createCopilotExpressHandler({\n * runtime,\n * basePath: \"/api/copilotkit\",\n * cors: true,\n * }));\n * app.listen(4000);\n * ```\n *\n * @example Single-route mode with lifecycle hooks\n * ```typescript\n * app.use(createCopilotExpressHandler({\n * runtime,\n * basePath: \"/api/copilotkit\",\n * mode: \"single-route\",\n * hooks: {\n * onRequest: ({ request }) => {\n * if (!request.headers.get(\"authorization\")) {\n * throw new Response(\"Unauthorized\", { status: 401 });\n * }\n * },\n * },\n * }));\n * ```\n */\n/** @deprecated Use `createCopilotExpressHandler` instead. */\nexport { createCopilotExpressHandler as createCopilotEndpointExpress };\n\nexport function createCopilotExpressHandler({\n runtime,\n basePath,\n mode = \"multi-route\",\n cors: corsOption = true,\n hooks,\n inspectorLearning,\n activateChannels,\n __channelEngine,\n}: CopilotExpressEndpointParams): CopilotExpressRouter {\n const normalizedBase = normalizeBasePath(basePath);\n\n const handler = createCopilotRuntimeHandler({\n runtime,\n basePath: normalizedBase,\n mode,\n cors: false, // CORS is handled at the Express middleware layer\n hooks,\n inspectorLearning,\n activateChannels,\n __channelEngine,\n });\n\n const nodeHandler = createExpressNodeHandler(handler);\n\n const expressHandler = async (\n req: ExpressRequest,\n res: ExpressResponse,\n next: NextFunction,\n ) => {\n try {\n await nodeHandler(req, res);\n } catch (err) {\n next(err);\n }\n };\n\n const router = express.Router();\n\n // CORS middleware\n if (corsOption) {\n const corsConfig: CorsOptions =\n corsOption === true\n ? {\n origin: \"*\",\n methods: [\n \"GET\",\n \"HEAD\",\n \"PUT\",\n \"POST\",\n \"DELETE\",\n \"PATCH\",\n \"OPTIONS\",\n ],\n allowedHeaders: [\"*\"],\n }\n : corsOption;\n router.use(cors(corsConfig));\n }\n\n // Route mounting\n if (mode === \"single-route\") {\n router.post(normalizedBase, expressHandler);\n router.options(normalizedBase, expressHandler);\n } else if (normalizedBase === \"/\") {\n router.all(/.*/, expressHandler);\n } else {\n router.all(\n new RegExp(`^${escapeRegExp(normalizedBase)}(\\\\/.*)?$`),\n expressHandler,\n );\n }\n\n const exposedRouter: CopilotExpressRouter = router;\n exposedRouter.channels = handler.channels;\n autoStartChannels(exposedRouter.channels);\n return exposedRouter;\n}\n\nfunction escapeRegExp(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nfunction normalizeBasePath(path: string): string {\n if (!path) {\n throw new Error(\"basePath must be provided for Express endpoint\");\n }\n\n if (!path.startsWith(\"/\")) {\n return `/${path}`;\n }\n\n if (path.length > 1 && path.endsWith(\"/\")) {\n return path.slice(0, -1);\n }\n\n return path;\n}\n"],"mappings":";;;;;;;;AA+HA,SAAgB,4BAA4B,EAC1C,SACA,UACA,OAAO,eACP,MAAM,aAAa,MACnB,OACA,mBACA,kBACA,mBACqD;CACrD,MAAM,iBAAiB,kBAAkB,SAAS;CAElD,MAAM,UAAU,4BAA4B;EAC1C;EACA,UAAU;EACV;EACA,MAAM;EACN;EACA;EACA;EACA;EACD,CAAC;CAEF,MAAM,cAAc,yBAAyB,QAAQ;CAErD,MAAM,iBAAiB,OACrB,KACA,KACA,SACG;AACH,MAAI;AACF,SAAM,YAAY,KAAK,IAAI;WACpB,KAAK;AACZ,QAAK,IAAI;;;CAIb,MAAM,SAAS,QAAQ,QAAQ;AAG/B,KAAI,YAAY;EACd,MAAM,aACJ,eAAe,OACX;GACE,QAAQ;GACR,SAAS;IACP;IACA;IACA;IACA;IACA;IACA;IACA;IACD;GACD,gBAAgB,CAAC,IAAI;GACtB,GACD;AACN,SAAO,IAAI,KAAK,WAAW,CAAC;;AAI9B,KAAI,SAAS,gBAAgB;AAC3B,SAAO,KAAK,gBAAgB,eAAe;AAC3C,SAAO,QAAQ,gBAAgB,eAAe;YACrC,mBAAmB,IAC5B,QAAO,IAAI,MAAM,eAAe;KAEhC,QAAO,IACL,IAAI,OAAO,IAAI,aAAa,eAAe,CAAC,WAAW,EACvD,eACD;CAGH,MAAM,gBAAsC;AAC5C,eAAc,WAAW,QAAQ;AACjC,mBAAkB,cAAc,SAAS;AACzC,QAAO;;AAGT,SAAS,aAAa,GAAmB;AACvC,QAAO,EAAE,QAAQ,uBAAuB,OAAO;;AAGjD,SAAS,kBAAkB,MAAsB;AAC/C,KAAI,CAAC,KACH,OAAM,IAAI,MAAM,iDAAiD;AAGnE,KAAI,CAAC,KAAK,WAAW,IAAI,CACvB,QAAO,IAAI;AAGb,KAAI,KAAK,SAAS,KAAK,KAAK,SAAS,IAAI,CACvC,QAAO,KAAK,MAAM,GAAG,GAAG;AAG1B,QAAO"}
|
|
@@ -6,13 +6,14 @@ let hono = require("hono");
|
|
|
6
6
|
//#region src/v2/runtime/endpoints/hono.ts
|
|
7
7
|
/** @deprecated Use `createCopilotHonoHandler` instead. */
|
|
8
8
|
const createCopilotEndpoint = createCopilotHonoHandler;
|
|
9
|
-
function createCopilotHonoHandler({ runtime, basePath, mode = "multi-route", cors: corsConfig, hooks, activateChannels, __channelEngine }) {
|
|
9
|
+
function createCopilotHonoHandler({ runtime, basePath, mode = "multi-route", cors: corsConfig, hooks, inspectorLearning, activateChannels, __channelEngine }) {
|
|
10
10
|
const handler = require_fetch_handler.createCopilotRuntimeHandler({
|
|
11
11
|
runtime,
|
|
12
12
|
basePath,
|
|
13
13
|
mode,
|
|
14
14
|
cors: corsConfig ? toFetchCorsConfig(corsConfig) : true,
|
|
15
15
|
hooks,
|
|
16
|
+
inspectorLearning,
|
|
16
17
|
activateChannels,
|
|
17
18
|
__channelEngine
|
|
18
19
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hono.cjs","names":["createCopilotRuntimeHandler","Hono"],"sources":["../../../../src/v2/runtime/endpoints/hono.ts"],"sourcesContent":["import { Hono } from \"hono\";\nimport type { CopilotRuntimeLike } from \"../core/runtime\";\nimport { createCopilotRuntimeHandler } from \"../core/fetch-handler\";\nimport type { CopilotCorsConfig } from \"../core/fetch-cors\";\nimport type { CopilotRuntimeHooks } from \"../core/hooks\";\nimport type {\n ActivateChannelEngine,\n ChannelsControl,\n} from \"../core/channel-manager\";\n\n/**\n * A Hono app that may also carry an optional {@link ChannelsControl} surface.\n *\n * Unlike the Node and Express wrappers — which own a process and therefore START\n * managed-Channel activation at creation (OSS-641) — this wrapper stays LAZY:\n * activation is triggered by the first `app.channels.ready()` and never before.\n * A Hono app is multi-runtime and is our edge/serverless surface in practice:\n * every Next.js App Router route handler in `examples/showcases/*` builds one at\n * module scope, and those isolates freeze and recycle per request. Auto-starting\n * there would mint a competing listener for the same Channel on every cold\n * start, which is exactly what the lazy design exists to prevent (see the\n * `createCopilotRuntimeHandler` TSDoc).\n *\n * So on a LONG-RUNNING Hono host (`@hono/node-server`, Bun, Deno) calling\n * `await app.channels.ready()` once at startup is REQUIRED to connect declared\n * Channels; on an edge/serverless host do NOT call it.\n */\nexport type CopilotHonoApp = Hono & { channels?: ChannelsControl };\n\n/**\n * CORS configuration for CopilotKit endpoints.\n * When using credentials (e.g., HTTP-only cookies), you must specify an explicit origin.\n */\nexport interface CopilotEndpointCorsConfig {\n /**\n * Allowed origin(s) for CORS. Can be:\n * - A string: exact origin (e.g., \"https://myapp.com\")\n * - An array: list of allowed origins\n * - A function: dynamic origin resolution\n *\n * Note: When credentials is true, origin cannot be \"*\"\n */\n origin:\n | string\n | string[]\n | ((origin: string, c: any) => string | undefined | null);\n /**\n * Whether to allow credentials (cookies, HTTP authentication).\n * When true, origin must be explicitly specified (not \"*\").\n */\n credentials?: boolean;\n}\n\ninterface CopilotEndpointParams {\n runtime: CopilotRuntimeLike;\n basePath: string;\n\n /**\n * Endpoint mode.\n * - `\"multi-route\"` (default): separate routes for each operation\n * - `\"single-route\"`: single POST endpoint with JSON envelope dispatch\n */\n mode?: \"multi-route\" | \"single-route\";\n\n /**\n * Optional CORS configuration. When not provided, defaults to allowing all origins without credentials.\n * To support HTTP-only cookies, provide cors config with credentials: true and explicit origin.\n */\n cors?: CopilotEndpointCorsConfig;\n /**\n * Lifecycle hooks for request processing.\n */\n hooks?: CopilotRuntimeHooks;\n\n /**\n * Whether the underlying handler builds the control surface for the runtime's\n * declared managed Channels. Defaults to `true`. Building it opens no\n * connection — activation is deferred to the first `channels.ready()`. See\n * `CopilotRuntimeHandlerOptions.activateChannels`.\n */\n activateChannels?: boolean;\n\n /**\n * @internal Test seam: inject a fake Channel activation engine. Forwarded\n * to `createCopilotRuntimeHandler`. Not part of the public API.\n */\n __channelEngine?: ActivateChannelEngine;\n}\n/** @deprecated Use `createCopilotHonoHandler` instead. */\nexport const createCopilotEndpoint = createCopilotHonoHandler;\n\nexport function createCopilotHonoHandler({\n runtime,\n basePath,\n mode = \"multi-route\",\n cors: corsConfig,\n hooks,\n activateChannels,\n __channelEngine,\n}: CopilotEndpointParams): CopilotHonoApp {\n const handler = createCopilotRuntimeHandler({\n runtime,\n basePath,\n mode,\n cors: corsConfig ? toFetchCorsConfig(corsConfig) : true,\n hooks,\n activateChannels,\n __channelEngine,\n });\n\n const app = new Hono();\n\n const scopedApp: CopilotHonoApp = app\n .basePath(basePath)\n .all(\"*\", async (c) => handler(c.req.raw));\n scopedApp.channels = handler.channels;\n return scopedApp;\n}\n\n/**\n * Convert Hono-specific CORS config to the fetch handler's CopilotCorsConfig.\n */\nexport function toFetchCorsConfig(\n config: CopilotEndpointCorsConfig,\n): CopilotCorsConfig {\n const origin = config.origin;\n return {\n origin:\n typeof origin === \"function\"\n ? (reqOrigin: string) => origin(reqOrigin, undefined) ?? null\n : origin,\n credentials: config.credentials,\n };\n}\n"],"mappings":";;;;;;;
|
|
1
|
+
{"version":3,"file":"hono.cjs","names":["createCopilotRuntimeHandler","Hono"],"sources":["../../../../src/v2/runtime/endpoints/hono.ts"],"sourcesContent":["import { Hono } from \"hono\";\nimport type { CopilotRuntimeLike } from \"../core/runtime\";\nimport { createCopilotRuntimeHandler } from \"../core/fetch-handler\";\nimport type { CopilotCorsConfig } from \"../core/fetch-cors\";\nimport type { CopilotRuntimeHooks } from \"../core/hooks\";\nimport type {\n ActivateChannelEngine,\n ChannelsControl,\n} from \"../core/channel-manager\";\n\n/**\n * A Hono app that may also carry an optional {@link ChannelsControl} surface.\n *\n * Unlike the Node and Express wrappers — which own a process and therefore START\n * managed-Channel activation at creation (OSS-641) — this wrapper stays LAZY:\n * activation is triggered by the first `app.channels.ready()` and never before.\n * A Hono app is multi-runtime and is our edge/serverless surface in practice:\n * every Next.js App Router route handler in `examples/showcases/*` builds one at\n * module scope, and those isolates freeze and recycle per request. Auto-starting\n * there would mint a competing listener for the same Channel on every cold\n * start, which is exactly what the lazy design exists to prevent (see the\n * `createCopilotRuntimeHandler` TSDoc).\n *\n * So on a LONG-RUNNING Hono host (`@hono/node-server`, Bun, Deno) calling\n * `await app.channels.ready()` once at startup is REQUIRED to connect declared\n * Channels; on an edge/serverless host do NOT call it.\n */\nexport type CopilotHonoApp = Hono & { channels?: ChannelsControl };\n\n/**\n * CORS configuration for CopilotKit endpoints.\n * When using credentials (e.g., HTTP-only cookies), you must specify an explicit origin.\n */\nexport interface CopilotEndpointCorsConfig {\n /**\n * Allowed origin(s) for CORS. Can be:\n * - A string: exact origin (e.g., \"https://myapp.com\")\n * - An array: list of allowed origins\n * - A function: dynamic origin resolution\n *\n * Note: When credentials is true, origin cannot be \"*\"\n */\n origin:\n | string\n | string[]\n | ((origin: string, c: any) => string | undefined | null);\n /**\n * Whether to allow credentials (cookies, HTTP authentication).\n * When true, origin must be explicitly specified (not \"*\").\n */\n credentials?: boolean;\n}\n\ninterface CopilotEndpointParams {\n runtime: CopilotRuntimeLike;\n basePath: string;\n\n /**\n * Endpoint mode.\n * - `\"multi-route\"` (default): separate routes for each operation\n * - `\"single-route\"`: single POST endpoint with JSON envelope dispatch\n */\n mode?: \"multi-route\" | \"single-route\";\n\n /**\n * Optional CORS configuration. When not provided, defaults to allowing all origins without credentials.\n * To support HTTP-only cookies, provide cors config with credentials: true and explicit origin.\n */\n cors?: CopilotEndpointCorsConfig;\n /**\n * Lifecycle hooks for request processing.\n */\n hooks?: CopilotRuntimeHooks;\n\n /**\n * Whether to expose the debug-gated Inspector Learning snapshot route.\n * Defaults to `false`.\n */\n inspectorLearning?: boolean;\n\n /**\n * Whether the underlying handler builds the control surface for the runtime's\n * declared managed Channels. Defaults to `true`. Building it opens no\n * connection — activation is deferred to the first `channels.ready()`. See\n * `CopilotRuntimeHandlerOptions.activateChannels`.\n */\n activateChannels?: boolean;\n\n /**\n * @internal Test seam: inject a fake Channel activation engine. Forwarded\n * to `createCopilotRuntimeHandler`. Not part of the public API.\n */\n __channelEngine?: ActivateChannelEngine;\n}\n/** @deprecated Use `createCopilotHonoHandler` instead. */\nexport const createCopilotEndpoint = createCopilotHonoHandler;\n\nexport function createCopilotHonoHandler({\n runtime,\n basePath,\n mode = \"multi-route\",\n cors: corsConfig,\n hooks,\n inspectorLearning,\n activateChannels,\n __channelEngine,\n}: CopilotEndpointParams): CopilotHonoApp {\n const handler = createCopilotRuntimeHandler({\n runtime,\n basePath,\n mode,\n cors: corsConfig ? toFetchCorsConfig(corsConfig) : true,\n hooks,\n inspectorLearning,\n activateChannels,\n __channelEngine,\n });\n\n const app = new Hono();\n\n const scopedApp: CopilotHonoApp = app\n .basePath(basePath)\n .all(\"*\", async (c) => handler(c.req.raw));\n scopedApp.channels = handler.channels;\n return scopedApp;\n}\n\n/**\n * Convert Hono-specific CORS config to the fetch handler's CopilotCorsConfig.\n */\nexport function toFetchCorsConfig(\n config: CopilotEndpointCorsConfig,\n): CopilotCorsConfig {\n const origin = config.origin;\n return {\n origin:\n typeof origin === \"function\"\n ? (reqOrigin: string) => origin(reqOrigin, undefined) ?? null\n : origin,\n credentials: config.credentials,\n };\n}\n"],"mappings":";;;;;;;AA+FA,MAAa,wBAAwB;AAErC,SAAgB,yBAAyB,EACvC,SACA,UACA,OAAO,eACP,MAAM,YACN,OACA,mBACA,kBACA,mBACwC;CACxC,MAAM,UAAUA,kDAA4B;EAC1C;EACA;EACA;EACA,MAAM,aAAa,kBAAkB,WAAW,GAAG;EACnD;EACA;EACA;EACA;EACD,CAAC;CAIF,MAAM,YAFM,IAAIC,WAAM,CAGnB,SAAS,SAAS,CAClB,IAAI,KAAK,OAAO,MAAM,QAAQ,EAAE,IAAI,IAAI,CAAC;AAC5C,WAAU,WAAW,QAAQ;AAC7B,QAAO;;;;;AAMT,SAAgB,kBACd,QACmB;CACnB,MAAM,SAAS,OAAO;AACtB,QAAO;EACL,QACE,OAAO,WAAW,cACb,cAAsB,OAAO,WAAW,OAAU,IAAI,OACvD;EACN,aAAa,OAAO;EACrB"}
|
|
@@ -64,6 +64,11 @@ interface CopilotEndpointParams {
|
|
|
64
64
|
* Lifecycle hooks for request processing.
|
|
65
65
|
*/
|
|
66
66
|
hooks?: CopilotRuntimeHooks;
|
|
67
|
+
/**
|
|
68
|
+
* Whether to expose the debug-gated Inspector Learning snapshot route.
|
|
69
|
+
* Defaults to `false`.
|
|
70
|
+
*/
|
|
71
|
+
inspectorLearning?: boolean;
|
|
67
72
|
/**
|
|
68
73
|
* Whether the underlying handler builds the control surface for the runtime's
|
|
69
74
|
* declared managed Channels. Defaults to `true`. Building it opens no
|
|
@@ -85,6 +90,7 @@ declare function createCopilotHonoHandler({
|
|
|
85
90
|
mode,
|
|
86
91
|
cors: corsConfig,
|
|
87
92
|
hooks,
|
|
93
|
+
inspectorLearning,
|
|
88
94
|
activateChannels,
|
|
89
95
|
__channelEngine
|
|
90
96
|
}: CopilotEndpointParams): CopilotHonoApp;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hono.d.cts","names":[],"sources":["../../../../src/v2/runtime/endpoints/hono.ts"],"mappings":";;;;;;;;;;AA2BA;;;;;;;;;AAMA;;;;;;KANY,cAAA,GAAiB,IAAA;EAAS,QAAA,GAAW,eAAA;AAAA;;AAwBhD;;;UAlBgB,yBAAA;EAmCR;;;;;;;;EA1BP,MAAA,wBAGM,MAAA,UAAgB,CAAA;EAuBtB;;;;EAlBA,WAAA;AAAA;AAAA,UAGQ,qBAAA;EACR,OAAA,EAAS,kBAAA;EACT,QAAA;
|
|
1
|
+
{"version":3,"file":"hono.d.cts","names":[],"sources":["../../../../src/v2/runtime/endpoints/hono.ts"],"mappings":";;;;;;;;;;AA2BA;;;;;;;;;AAMA;;;;;;KANY,cAAA,GAAiB,IAAA;EAAS,QAAA,GAAW,eAAA;AAAA;;AAwBhD;;;UAlBgB,yBAAA;EAmCR;;;;;;;;EA1BP,MAAA,wBAGM,MAAA,UAAgB,CAAA;EAuBtB;;;;EAlBA,WAAA;AAAA;AAAA,UAGQ,qBAAA;EACR,OAAA,EAAS,kBAAA;EACT,QAAA;EAqCuC;AAGzC;;;;EAjCE,IAAA;EAmCc;;;;EA7Bd,IAAA,GAAO,yBAAA;EAgCP;;;EA5BA,KAAA,GAAQ,mBAAA;EAgCR;;;;EA1BA,iBAAA;EA4BuC;;;;;;EApBvC,gBAAA;EAeA;;;;EATA,eAAA,GAAkB,qBAAA;AAAA;;cAGP,qBAAA,SAAqB,wBAAA;AAAA,iBAElB,wBAAA,CAAA;EACd,OAAA;EACA,QAAA;EACA,IAAA;EACA,IAAA,EAAM,UAAA;EACN,KAAA;EACA,iBAAA;EACA,gBAAA;EACA;AAAA,GACC,qBAAA,GAAwB,cAAA;;;;iBAwBX,iBAAA,CACd,MAAA,EAAQ,yBAAA,GACP,iBAAA"}
|
|
@@ -64,6 +64,11 @@ interface CopilotEndpointParams {
|
|
|
64
64
|
* Lifecycle hooks for request processing.
|
|
65
65
|
*/
|
|
66
66
|
hooks?: CopilotRuntimeHooks;
|
|
67
|
+
/**
|
|
68
|
+
* Whether to expose the debug-gated Inspector Learning snapshot route.
|
|
69
|
+
* Defaults to `false`.
|
|
70
|
+
*/
|
|
71
|
+
inspectorLearning?: boolean;
|
|
67
72
|
/**
|
|
68
73
|
* Whether the underlying handler builds the control surface for the runtime's
|
|
69
74
|
* declared managed Channels. Defaults to `true`. Building it opens no
|
|
@@ -85,6 +90,7 @@ declare function createCopilotHonoHandler({
|
|
|
85
90
|
mode,
|
|
86
91
|
cors: corsConfig,
|
|
87
92
|
hooks,
|
|
93
|
+
inspectorLearning,
|
|
88
94
|
activateChannels,
|
|
89
95
|
__channelEngine
|
|
90
96
|
}: CopilotEndpointParams): CopilotHonoApp;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hono.d.mts","names":[],"sources":["../../../../src/v2/runtime/endpoints/hono.ts"],"mappings":";;;;;;;;;;AA2BA;;;;;;;;;AAMA;;;;;;KANY,cAAA,GAAiB,IAAA;EAAS,QAAA,GAAW,eAAA;AAAA;;AAwBhD;;;UAlBgB,yBAAA;EAmCR;;;;;;;;EA1BP,MAAA,wBAGM,MAAA,UAAgB,CAAA;EAuBtB;;;;EAlBA,WAAA;AAAA;AAAA,UAGQ,qBAAA;EACR,OAAA,EAAS,kBAAA;EACT,QAAA;
|
|
1
|
+
{"version":3,"file":"hono.d.mts","names":[],"sources":["../../../../src/v2/runtime/endpoints/hono.ts"],"mappings":";;;;;;;;;;AA2BA;;;;;;;;;AAMA;;;;;;KANY,cAAA,GAAiB,IAAA;EAAS,QAAA,GAAW,eAAA;AAAA;;AAwBhD;;;UAlBgB,yBAAA;EAmCR;;;;;;;;EA1BP,MAAA,wBAGM,MAAA,UAAgB,CAAA;EAuBtB;;;;EAlBA,WAAA;AAAA;AAAA,UAGQ,qBAAA;EACR,OAAA,EAAS,kBAAA;EACT,QAAA;EAqCuC;AAGzC;;;;EAjCE,IAAA;EAmCc;;;;EA7Bd,IAAA,GAAO,yBAAA;EAgCP;;;EA5BA,KAAA,GAAQ,mBAAA;EAgCR;;;;EA1BA,iBAAA;EA4BuC;;;;;;EApBvC,gBAAA;EAeA;;;;EATA,eAAA,GAAkB,qBAAA;AAAA;;cAGP,qBAAA,SAAqB,wBAAA;AAAA,iBAElB,wBAAA,CAAA;EACd,OAAA;EACA,QAAA;EACA,IAAA;EACA,IAAA,EAAM,UAAA;EACN,KAAA;EACA,iBAAA;EACA,gBAAA;EACA;AAAA,GACC,qBAAA,GAAwB,cAAA;;;;iBAwBX,iBAAA,CACd,MAAA,EAAQ,yBAAA,GACP,iBAAA"}
|
|
@@ -5,13 +5,14 @@ import { Hono } from "hono";
|
|
|
5
5
|
//#region src/v2/runtime/endpoints/hono.ts
|
|
6
6
|
/** @deprecated Use `createCopilotHonoHandler` instead. */
|
|
7
7
|
const createCopilotEndpoint = createCopilotHonoHandler;
|
|
8
|
-
function createCopilotHonoHandler({ runtime, basePath, mode = "multi-route", cors: corsConfig, hooks, activateChannels, __channelEngine }) {
|
|
8
|
+
function createCopilotHonoHandler({ runtime, basePath, mode = "multi-route", cors: corsConfig, hooks, inspectorLearning, activateChannels, __channelEngine }) {
|
|
9
9
|
const handler = createCopilotRuntimeHandler({
|
|
10
10
|
runtime,
|
|
11
11
|
basePath,
|
|
12
12
|
mode,
|
|
13
13
|
cors: corsConfig ? toFetchCorsConfig(corsConfig) : true,
|
|
14
14
|
hooks,
|
|
15
|
+
inspectorLearning,
|
|
15
16
|
activateChannels,
|
|
16
17
|
__channelEngine
|
|
17
18
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hono.mjs","names":[],"sources":["../../../../src/v2/runtime/endpoints/hono.ts"],"sourcesContent":["import { Hono } from \"hono\";\nimport type { CopilotRuntimeLike } from \"../core/runtime\";\nimport { createCopilotRuntimeHandler } from \"../core/fetch-handler\";\nimport type { CopilotCorsConfig } from \"../core/fetch-cors\";\nimport type { CopilotRuntimeHooks } from \"../core/hooks\";\nimport type {\n ActivateChannelEngine,\n ChannelsControl,\n} from \"../core/channel-manager\";\n\n/**\n * A Hono app that may also carry an optional {@link ChannelsControl} surface.\n *\n * Unlike the Node and Express wrappers — which own a process and therefore START\n * managed-Channel activation at creation (OSS-641) — this wrapper stays LAZY:\n * activation is triggered by the first `app.channels.ready()` and never before.\n * A Hono app is multi-runtime and is our edge/serverless surface in practice:\n * every Next.js App Router route handler in `examples/showcases/*` builds one at\n * module scope, and those isolates freeze and recycle per request. Auto-starting\n * there would mint a competing listener for the same Channel on every cold\n * start, which is exactly what the lazy design exists to prevent (see the\n * `createCopilotRuntimeHandler` TSDoc).\n *\n * So on a LONG-RUNNING Hono host (`@hono/node-server`, Bun, Deno) calling\n * `await app.channels.ready()` once at startup is REQUIRED to connect declared\n * Channels; on an edge/serverless host do NOT call it.\n */\nexport type CopilotHonoApp = Hono & { channels?: ChannelsControl };\n\n/**\n * CORS configuration for CopilotKit endpoints.\n * When using credentials (e.g., HTTP-only cookies), you must specify an explicit origin.\n */\nexport interface CopilotEndpointCorsConfig {\n /**\n * Allowed origin(s) for CORS. Can be:\n * - A string: exact origin (e.g., \"https://myapp.com\")\n * - An array: list of allowed origins\n * - A function: dynamic origin resolution\n *\n * Note: When credentials is true, origin cannot be \"*\"\n */\n origin:\n | string\n | string[]\n | ((origin: string, c: any) => string | undefined | null);\n /**\n * Whether to allow credentials (cookies, HTTP authentication).\n * When true, origin must be explicitly specified (not \"*\").\n */\n credentials?: boolean;\n}\n\ninterface CopilotEndpointParams {\n runtime: CopilotRuntimeLike;\n basePath: string;\n\n /**\n * Endpoint mode.\n * - `\"multi-route\"` (default): separate routes for each operation\n * - `\"single-route\"`: single POST endpoint with JSON envelope dispatch\n */\n mode?: \"multi-route\" | \"single-route\";\n\n /**\n * Optional CORS configuration. When not provided, defaults to allowing all origins without credentials.\n * To support HTTP-only cookies, provide cors config with credentials: true and explicit origin.\n */\n cors?: CopilotEndpointCorsConfig;\n /**\n * Lifecycle hooks for request processing.\n */\n hooks?: CopilotRuntimeHooks;\n\n /**\n * Whether the underlying handler builds the control surface for the runtime's\n * declared managed Channels. Defaults to `true`. Building it opens no\n * connection — activation is deferred to the first `channels.ready()`. See\n * `CopilotRuntimeHandlerOptions.activateChannels`.\n */\n activateChannels?: boolean;\n\n /**\n * @internal Test seam: inject a fake Channel activation engine. Forwarded\n * to `createCopilotRuntimeHandler`. Not part of the public API.\n */\n __channelEngine?: ActivateChannelEngine;\n}\n/** @deprecated Use `createCopilotHonoHandler` instead. */\nexport const createCopilotEndpoint = createCopilotHonoHandler;\n\nexport function createCopilotHonoHandler({\n runtime,\n basePath,\n mode = \"multi-route\",\n cors: corsConfig,\n hooks,\n activateChannels,\n __channelEngine,\n}: CopilotEndpointParams): CopilotHonoApp {\n const handler = createCopilotRuntimeHandler({\n runtime,\n basePath,\n mode,\n cors: corsConfig ? toFetchCorsConfig(corsConfig) : true,\n hooks,\n activateChannels,\n __channelEngine,\n });\n\n const app = new Hono();\n\n const scopedApp: CopilotHonoApp = app\n .basePath(basePath)\n .all(\"*\", async (c) => handler(c.req.raw));\n scopedApp.channels = handler.channels;\n return scopedApp;\n}\n\n/**\n * Convert Hono-specific CORS config to the fetch handler's CopilotCorsConfig.\n */\nexport function toFetchCorsConfig(\n config: CopilotEndpointCorsConfig,\n): CopilotCorsConfig {\n const origin = config.origin;\n return {\n origin:\n typeof origin === \"function\"\n ? (reqOrigin: string) => origin(reqOrigin, undefined) ?? null\n : origin,\n credentials: config.credentials,\n };\n}\n"],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"hono.mjs","names":[],"sources":["../../../../src/v2/runtime/endpoints/hono.ts"],"sourcesContent":["import { Hono } from \"hono\";\nimport type { CopilotRuntimeLike } from \"../core/runtime\";\nimport { createCopilotRuntimeHandler } from \"../core/fetch-handler\";\nimport type { CopilotCorsConfig } from \"../core/fetch-cors\";\nimport type { CopilotRuntimeHooks } from \"../core/hooks\";\nimport type {\n ActivateChannelEngine,\n ChannelsControl,\n} from \"../core/channel-manager\";\n\n/**\n * A Hono app that may also carry an optional {@link ChannelsControl} surface.\n *\n * Unlike the Node and Express wrappers — which own a process and therefore START\n * managed-Channel activation at creation (OSS-641) — this wrapper stays LAZY:\n * activation is triggered by the first `app.channels.ready()` and never before.\n * A Hono app is multi-runtime and is our edge/serverless surface in practice:\n * every Next.js App Router route handler in `examples/showcases/*` builds one at\n * module scope, and those isolates freeze and recycle per request. Auto-starting\n * there would mint a competing listener for the same Channel on every cold\n * start, which is exactly what the lazy design exists to prevent (see the\n * `createCopilotRuntimeHandler` TSDoc).\n *\n * So on a LONG-RUNNING Hono host (`@hono/node-server`, Bun, Deno) calling\n * `await app.channels.ready()` once at startup is REQUIRED to connect declared\n * Channels; on an edge/serverless host do NOT call it.\n */\nexport type CopilotHonoApp = Hono & { channels?: ChannelsControl };\n\n/**\n * CORS configuration for CopilotKit endpoints.\n * When using credentials (e.g., HTTP-only cookies), you must specify an explicit origin.\n */\nexport interface CopilotEndpointCorsConfig {\n /**\n * Allowed origin(s) for CORS. Can be:\n * - A string: exact origin (e.g., \"https://myapp.com\")\n * - An array: list of allowed origins\n * - A function: dynamic origin resolution\n *\n * Note: When credentials is true, origin cannot be \"*\"\n */\n origin:\n | string\n | string[]\n | ((origin: string, c: any) => string | undefined | null);\n /**\n * Whether to allow credentials (cookies, HTTP authentication).\n * When true, origin must be explicitly specified (not \"*\").\n */\n credentials?: boolean;\n}\n\ninterface CopilotEndpointParams {\n runtime: CopilotRuntimeLike;\n basePath: string;\n\n /**\n * Endpoint mode.\n * - `\"multi-route\"` (default): separate routes for each operation\n * - `\"single-route\"`: single POST endpoint with JSON envelope dispatch\n */\n mode?: \"multi-route\" | \"single-route\";\n\n /**\n * Optional CORS configuration. When not provided, defaults to allowing all origins without credentials.\n * To support HTTP-only cookies, provide cors config with credentials: true and explicit origin.\n */\n cors?: CopilotEndpointCorsConfig;\n /**\n * Lifecycle hooks for request processing.\n */\n hooks?: CopilotRuntimeHooks;\n\n /**\n * Whether to expose the debug-gated Inspector Learning snapshot route.\n * Defaults to `false`.\n */\n inspectorLearning?: boolean;\n\n /**\n * Whether the underlying handler builds the control surface for the runtime's\n * declared managed Channels. Defaults to `true`. Building it opens no\n * connection — activation is deferred to the first `channels.ready()`. See\n * `CopilotRuntimeHandlerOptions.activateChannels`.\n */\n activateChannels?: boolean;\n\n /**\n * @internal Test seam: inject a fake Channel activation engine. Forwarded\n * to `createCopilotRuntimeHandler`. Not part of the public API.\n */\n __channelEngine?: ActivateChannelEngine;\n}\n/** @deprecated Use `createCopilotHonoHandler` instead. */\nexport const createCopilotEndpoint = createCopilotHonoHandler;\n\nexport function createCopilotHonoHandler({\n runtime,\n basePath,\n mode = \"multi-route\",\n cors: corsConfig,\n hooks,\n inspectorLearning,\n activateChannels,\n __channelEngine,\n}: CopilotEndpointParams): CopilotHonoApp {\n const handler = createCopilotRuntimeHandler({\n runtime,\n basePath,\n mode,\n cors: corsConfig ? toFetchCorsConfig(corsConfig) : true,\n hooks,\n inspectorLearning,\n activateChannels,\n __channelEngine,\n });\n\n const app = new Hono();\n\n const scopedApp: CopilotHonoApp = app\n .basePath(basePath)\n .all(\"*\", async (c) => handler(c.req.raw));\n scopedApp.channels = handler.channels;\n return scopedApp;\n}\n\n/**\n * Convert Hono-specific CORS config to the fetch handler's CopilotCorsConfig.\n */\nexport function toFetchCorsConfig(\n config: CopilotEndpointCorsConfig,\n): CopilotCorsConfig {\n const origin = config.origin;\n return {\n origin:\n typeof origin === \"function\"\n ? (reqOrigin: string) => origin(reqOrigin, undefined) ?? null\n : origin,\n credentials: config.credentials,\n };\n}\n"],"mappings":";;;;;;AA+FA,MAAa,wBAAwB;AAErC,SAAgB,yBAAyB,EACvC,SACA,UACA,OAAO,eACP,MAAM,YACN,OACA,mBACA,kBACA,mBACwC;CACxC,MAAM,UAAU,4BAA4B;EAC1C;EACA;EACA;EACA,MAAM,aAAa,kBAAkB,WAAW,GAAG;EACnD;EACA;EACA;EACA;EACD,CAAC;CAIF,MAAM,YAFM,IAAI,MAAM,CAGnB,SAAS,SAAS,CAClB,IAAI,KAAK,OAAO,MAAM,QAAQ,EAAE,IAAI,IAAI,CAAC;AAC5C,WAAU,WAAW,QAAQ;AAC7B,QAAO;;;;;AAMT,SAAgB,kBACd,QACmB;CACnB,MAAM,SAAS,OAAO;AACtB,QAAO;EACL,QACE,OAAO,WAAW,cACb,cAAsB,OAAO,WAAW,OAAU,IAAI,OACvD;EACN,aAAa,OAAO;EACrB"}
|
|
@@ -8,7 +8,9 @@ const METHOD_NAMES = [
|
|
|
8
8
|
"agent/stop",
|
|
9
9
|
"info",
|
|
10
10
|
"inspector/metadata",
|
|
11
|
-
"
|
|
11
|
+
"inspector/learning",
|
|
12
|
+
"transcribe",
|
|
13
|
+
"resource/request"
|
|
12
14
|
];
|
|
13
15
|
/**
|
|
14
16
|
* Detect a single-route JSON envelope on a request the multi-route router
|
|
@@ -73,6 +75,31 @@ function createJsonRequest(base, body) {
|
|
|
73
75
|
signal: base.signal
|
|
74
76
|
});
|
|
75
77
|
}
|
|
78
|
+
/**
|
|
79
|
+
* Rebuild a resource request carried inside the single-route JSON envelope.
|
|
80
|
+
*
|
|
81
|
+
* The resource path must stay relative to the mounted Runtime. This prevents
|
|
82
|
+
* the envelope from becoming an open HTTP proxy while preserving the method,
|
|
83
|
+
* query string, headers, and cancellation signal used by the REST handler.
|
|
84
|
+
*/
|
|
85
|
+
function createResourceRequest(base, path, httpMethod, body) {
|
|
86
|
+
if (!path.startsWith("/") || path.startsWith("//")) throw createResponseError("Resource path must be Runtime-relative", 400);
|
|
87
|
+
const resourceUrl = new URL(path, "http://copilotkit.resource");
|
|
88
|
+
if (resourceUrl.origin !== "http://copilotkit.resource") throw createResponseError("Resource path must be Runtime-relative", 400);
|
|
89
|
+
const targetUrl = new URL(base.url);
|
|
90
|
+
targetUrl.pathname = `${targetUrl.pathname.replace(/\/$/, "")}${resourceUrl.pathname}`;
|
|
91
|
+
targetUrl.search = resourceUrl.search;
|
|
92
|
+
const method = httpMethod.toUpperCase();
|
|
93
|
+
const headers = new Headers(base.headers);
|
|
94
|
+
headers.delete("content-length");
|
|
95
|
+
const hasBody = method !== "GET" && method !== "HEAD" && body != null;
|
|
96
|
+
return new Request(targetUrl, {
|
|
97
|
+
method,
|
|
98
|
+
headers,
|
|
99
|
+
...hasBody ? { body: serializeJsonBody(body) } : {},
|
|
100
|
+
signal: base.signal
|
|
101
|
+
});
|
|
102
|
+
}
|
|
76
103
|
function createResponseError(message, status) {
|
|
77
104
|
return new Response(JSON.stringify({
|
|
78
105
|
error: "invalid_request",
|
|
@@ -96,6 +123,7 @@ function serializeJsonBody(body) {
|
|
|
96
123
|
|
|
97
124
|
//#endregion
|
|
98
125
|
exports.createJsonRequest = createJsonRequest;
|
|
126
|
+
exports.createResourceRequest = createResourceRequest;
|
|
99
127
|
exports.detectSingleRouteEnvelope = detectSingleRouteEnvelope;
|
|
100
128
|
exports.expectString = expectString;
|
|
101
129
|
exports.parseMethodCall = parseMethodCall;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"single-route-helpers.cjs","names":[],"sources":["../../../../src/v2/runtime/endpoints/single-route-helpers.ts"],"sourcesContent":["const METHOD_NAMES = [\n \"agent/run\",\n \"agent/suggest\",\n \"agent/connect\",\n \"agent/stop\",\n \"info\",\n \"inspector/metadata\",\n \"transcribe\",\n] as const;\n\nexport type EndpointMethod = (typeof METHOD_NAMES)[number];\n\ninterface JsonEnvelope {\n method?: string;\n params?: Record<string, unknown>;\n body?: unknown;\n}\n\nexport interface MethodCall {\n method: EndpointMethod;\n params?: Record<string, unknown>;\n body?: unknown;\n}\n\n/**\n * Detect a single-route JSON envelope on a request the multi-route router\n * could not match.\n *\n * A single-endpoint client (`useSingleEndpoint` on the frontend provider)\n * POSTs `{ method, params, body }` at the base path. A multi-route runtime\n * matches no route for that path and would otherwise answer a bare 404, giving\n * the developer nothing to go on. Recognising the envelope here lets the\n * handler name the actual cause instead.\n *\n * Deliberately conservative: it reports a method only for a POST carrying a\n * JSON body whose `method` is one the single-route endpoint actually accepts.\n * Anything else is a genuine 404 and must stay one.\n *\n * @returns The envelope's method name, or `null` if this is not an envelope.\n */\nexport async function detectSingleRouteEnvelope(\n request: Request,\n): Promise<EndpointMethod | null> {\n if (request.method !== \"POST\") return null;\n\n const contentType = request.headers.get(\"content-type\") || \"\";\n if (!contentType.includes(\"application/json\")) return null;\n\n let envelope: unknown;\n try {\n envelope = await request.clone().json();\n } catch {\n return null;\n }\n\n if (typeof envelope !== \"object\" || envelope === null) return null;\n\n const method = (envelope as JsonEnvelope).method;\n if (typeof method !== \"string\") return null;\n if (!(METHOD_NAMES as readonly string[]).includes(method)) return null;\n\n return method as EndpointMethod;\n}\n\nexport async function parseMethodCall(request: Request): Promise<MethodCall> {\n const contentType = request.headers.get(\"content-type\") || \"\";\n\n if (!contentType.includes(\"application/json\")) {\n throw createResponseError(\n \"Single-route endpoint expects JSON payloads\",\n 415,\n );\n }\n\n let jsonEnvelope: JsonEnvelope;\n try {\n jsonEnvelope = (await request.clone().json()) as JsonEnvelope;\n } catch {\n throw createResponseError(\"Invalid JSON payload\", 400);\n }\n\n const method = validateMethod(jsonEnvelope.method);\n\n return {\n method,\n params: jsonEnvelope.params,\n body: jsonEnvelope.body,\n };\n}\n\nexport function expectString(\n params: Record<string, unknown> | undefined,\n key: string,\n): string {\n const value = params?.[key];\n if (typeof value === \"string\" && value.trim().length > 0) {\n return value;\n }\n\n throw createResponseError(`Missing or invalid parameter '${key}'`, 400);\n}\n\nexport function createJsonRequest(base: Request, body: unknown): Request {\n if (body === undefined || body === null) {\n throw createResponseError(\"Missing request body for JSON handler\", 400);\n }\n\n const headers = new Headers(base.headers);\n headers.set(\"content-type\", \"application/json\");\n headers.delete(\"content-length\");\n\n const serializedBody = serializeJsonBody(body);\n\n return new Request(base.url, {\n method: \"POST\",\n headers,\n body: serializedBody,\n signal: base.signal,\n });\n}\n\nexport function createResponseError(message: string, status: number): Response {\n return new Response(\n JSON.stringify({\n error: \"invalid_request\",\n message,\n }),\n {\n status,\n headers: {\n \"Content-Type\": \"application/json\",\n },\n },\n );\n}\n\nfunction validateMethod(method: string | undefined): EndpointMethod {\n if (!method) {\n throw createResponseError(\"Missing method field\", 400);\n }\n\n if ((METHOD_NAMES as readonly string[]).includes(method)) {\n return method as EndpointMethod;\n }\n\n throw createResponseError(`Unsupported method '${method}'`, 400);\n}\n\nfunction serializeJsonBody(body: unknown): BodyInit {\n if (typeof body === \"string\") {\n return body;\n }\n\n if (\n body instanceof Blob ||\n body instanceof ArrayBuffer ||\n body instanceof Uint8Array\n ) {\n // Uint8Array<ArrayBufferLike> is a valid fetch body at runtime, but the\n // DOM lib's BodyInit only admits ArrayBuffer-backed views.\n return body as BodyInit;\n }\n\n if (body instanceof FormData || body instanceof URLSearchParams) {\n return body;\n }\n\n return JSON.stringify(body);\n}\n"],"mappings":";;;AAAA,MAAM,eAAe;CACnB;CACA;CACA;CACA;CACA;CACA;CACA;CACD;;;;;;;;;;;;;;;;;AAgCD,eAAsB,0BACpB,SACgC;AAChC,KAAI,QAAQ,WAAW,OAAQ,QAAO;AAGtC,KAAI,EADgB,QAAQ,QAAQ,IAAI,eAAe,IAAI,IAC1C,SAAS,mBAAmB,CAAE,QAAO;CAEtD,IAAI;AACJ,KAAI;AACF,aAAW,MAAM,QAAQ,OAAO,CAAC,MAAM;SACjC;AACN,SAAO;;AAGT,KAAI,OAAO,aAAa,YAAY,aAAa,KAAM,QAAO;CAE9D,MAAM,SAAU,SAA0B;AAC1C,KAAI,OAAO,WAAW,SAAU,QAAO;AACvC,KAAI,CAAE,aAAmC,SAAS,OAAO,CAAE,QAAO;AAElE,QAAO;;AAGT,eAAsB,gBAAgB,SAAuC;AAG3E,KAAI,EAFgB,QAAQ,QAAQ,IAAI,eAAe,IAAI,IAE1C,SAAS,mBAAmB,CAC3C,OAAM,oBACJ,+CACA,IACD;CAGH,IAAI;AACJ,KAAI;AACF,iBAAgB,MAAM,QAAQ,OAAO,CAAC,MAAM;SACtC;AACN,QAAM,oBAAoB,wBAAwB,IAAI;;AAKxD,QAAO;EACL,QAHa,eAAe,aAAa,OAAO;EAIhD,QAAQ,aAAa;EACrB,MAAM,aAAa;EACpB;;AAGH,SAAgB,aACd,QACA,KACQ;CACR,MAAM,QAAQ,SAAS;AACvB,KAAI,OAAO,UAAU,YAAY,MAAM,MAAM,CAAC,SAAS,EACrD,QAAO;AAGT,OAAM,oBAAoB,iCAAiC,IAAI,IAAI,IAAI;;AAGzE,SAAgB,kBAAkB,MAAe,MAAwB;AACvE,KAAI,SAAS,UAAa,SAAS,KACjC,OAAM,oBAAoB,yCAAyC,IAAI;CAGzE,MAAM,UAAU,IAAI,QAAQ,KAAK,QAAQ;AACzC,SAAQ,IAAI,gBAAgB,mBAAmB;AAC/C,SAAQ,OAAO,iBAAiB;CAEhC,MAAM,iBAAiB,kBAAkB,KAAK;AAE9C,QAAO,IAAI,QAAQ,KAAK,KAAK;EAC3B,QAAQ;EACR;EACA,MAAM;EACN,QAAQ,KAAK;EACd,CAAC;;AAGJ,SAAgB,oBAAoB,SAAiB,QAA0B;AAC7E,QAAO,IAAI,SACT,KAAK,UAAU;EACb,OAAO;EACP;EACD,CAAC,EACF;EACE;EACA,SAAS,EACP,gBAAgB,oBACjB;EACF,CACF;;AAGH,SAAS,eAAe,QAA4C;AAClE,KAAI,CAAC,OACH,OAAM,oBAAoB,wBAAwB,IAAI;AAGxD,KAAK,aAAmC,SAAS,OAAO,CACtD,QAAO;AAGT,OAAM,oBAAoB,uBAAuB,OAAO,IAAI,IAAI;;AAGlE,SAAS,kBAAkB,MAAyB;AAClD,KAAI,OAAO,SAAS,SAClB,QAAO;AAGT,KACE,gBAAgB,QAChB,gBAAgB,eAChB,gBAAgB,WAIhB,QAAO;AAGT,KAAI,gBAAgB,YAAY,gBAAgB,gBAC9C,QAAO;AAGT,QAAO,KAAK,UAAU,KAAK"}
|
|
1
|
+
{"version":3,"file":"single-route-helpers.cjs","names":[],"sources":["../../../../src/v2/runtime/endpoints/single-route-helpers.ts"],"sourcesContent":["const METHOD_NAMES = [\n \"agent/run\",\n \"agent/suggest\",\n \"agent/connect\",\n \"agent/stop\",\n \"info\",\n \"inspector/metadata\",\n \"inspector/learning\",\n \"transcribe\",\n \"resource/request\",\n] as const;\n\nexport type EndpointMethod = (typeof METHOD_NAMES)[number];\n\ninterface JsonEnvelope {\n method?: string;\n params?: Record<string, unknown>;\n body?: unknown;\n}\n\nexport interface MethodCall {\n method: EndpointMethod;\n params?: Record<string, unknown>;\n body?: unknown;\n}\n\n/**\n * Detect a single-route JSON envelope on a request the multi-route router\n * could not match.\n *\n * A single-endpoint client (`useSingleEndpoint` on the frontend provider)\n * POSTs `{ method, params, body }` at the base path. A multi-route runtime\n * matches no route for that path and would otherwise answer a bare 404, giving\n * the developer nothing to go on. Recognising the envelope here lets the\n * handler name the actual cause instead.\n *\n * Deliberately conservative: it reports a method only for a POST carrying a\n * JSON body whose `method` is one the single-route endpoint actually accepts.\n * Anything else is a genuine 404 and must stay one.\n *\n * @returns The envelope's method name, or `null` if this is not an envelope.\n */\nexport async function detectSingleRouteEnvelope(\n request: Request,\n): Promise<EndpointMethod | null> {\n if (request.method !== \"POST\") return null;\n\n const contentType = request.headers.get(\"content-type\") || \"\";\n if (!contentType.includes(\"application/json\")) return null;\n\n let envelope: unknown;\n try {\n envelope = await request.clone().json();\n } catch {\n return null;\n }\n\n if (typeof envelope !== \"object\" || envelope === null) return null;\n\n const method = (envelope as JsonEnvelope).method;\n if (typeof method !== \"string\") return null;\n if (!(METHOD_NAMES as readonly string[]).includes(method)) return null;\n\n return method as EndpointMethod;\n}\n\nexport async function parseMethodCall(request: Request): Promise<MethodCall> {\n const contentType = request.headers.get(\"content-type\") || \"\";\n\n if (!contentType.includes(\"application/json\")) {\n throw createResponseError(\n \"Single-route endpoint expects JSON payloads\",\n 415,\n );\n }\n\n let jsonEnvelope: JsonEnvelope;\n try {\n jsonEnvelope = (await request.clone().json()) as JsonEnvelope;\n } catch {\n throw createResponseError(\"Invalid JSON payload\", 400);\n }\n\n const method = validateMethod(jsonEnvelope.method);\n\n return {\n method,\n params: jsonEnvelope.params,\n body: jsonEnvelope.body,\n };\n}\n\nexport function expectString(\n params: Record<string, unknown> | undefined,\n key: string,\n): string {\n const value = params?.[key];\n if (typeof value === \"string\" && value.trim().length > 0) {\n return value;\n }\n\n throw createResponseError(`Missing or invalid parameter '${key}'`, 400);\n}\n\nexport function createJsonRequest(base: Request, body: unknown): Request {\n if (body === undefined || body === null) {\n throw createResponseError(\"Missing request body for JSON handler\", 400);\n }\n\n const headers = new Headers(base.headers);\n headers.set(\"content-type\", \"application/json\");\n headers.delete(\"content-length\");\n\n const serializedBody = serializeJsonBody(body);\n\n return new Request(base.url, {\n method: \"POST\",\n headers,\n body: serializedBody,\n signal: base.signal,\n });\n}\n\n/**\n * Rebuild a resource request carried inside the single-route JSON envelope.\n *\n * The resource path must stay relative to the mounted Runtime. This prevents\n * the envelope from becoming an open HTTP proxy while preserving the method,\n * query string, headers, and cancellation signal used by the REST handler.\n */\nexport function createResourceRequest(\n base: Request,\n path: string,\n httpMethod: string,\n body: unknown,\n): Request {\n if (!path.startsWith(\"/\") || path.startsWith(\"//\")) {\n throw createResponseError(\"Resource path must be Runtime-relative\", 400);\n }\n\n const resourceUrl = new URL(path, \"http://copilotkit.resource\");\n if (resourceUrl.origin !== \"http://copilotkit.resource\") {\n throw createResponseError(\"Resource path must be Runtime-relative\", 400);\n }\n\n const targetUrl = new URL(base.url);\n targetUrl.pathname = `${targetUrl.pathname.replace(/\\/$/, \"\")}${resourceUrl.pathname}`;\n targetUrl.search = resourceUrl.search;\n\n const method = httpMethod.toUpperCase();\n const headers = new Headers(base.headers);\n headers.delete(\"content-length\");\n const hasBody = method !== \"GET\" && method !== \"HEAD\" && body != null;\n\n return new Request(targetUrl, {\n method,\n headers,\n ...(hasBody ? { body: serializeJsonBody(body) } : {}),\n signal: base.signal,\n });\n}\n\nexport function createResponseError(message: string, status: number): Response {\n return new Response(\n JSON.stringify({\n error: \"invalid_request\",\n message,\n }),\n {\n status,\n headers: {\n \"Content-Type\": \"application/json\",\n },\n },\n );\n}\n\nfunction validateMethod(method: string | undefined): EndpointMethod {\n if (!method) {\n throw createResponseError(\"Missing method field\", 400);\n }\n\n if ((METHOD_NAMES as readonly string[]).includes(method)) {\n return method as EndpointMethod;\n }\n\n throw createResponseError(`Unsupported method '${method}'`, 400);\n}\n\nfunction serializeJsonBody(body: unknown): BodyInit {\n if (typeof body === \"string\") {\n return body;\n }\n\n if (\n body instanceof Blob ||\n body instanceof ArrayBuffer ||\n body instanceof Uint8Array\n ) {\n // Uint8Array<ArrayBufferLike> is a valid fetch body at runtime, but the\n // DOM lib's BodyInit only admits ArrayBuffer-backed views.\n return body as BodyInit;\n }\n\n if (body instanceof FormData || body instanceof URLSearchParams) {\n return body;\n }\n\n return JSON.stringify(body);\n}\n"],"mappings":";;;AAAA,MAAM,eAAe;CACnB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;;;;;;;;;;;;;;;;;AAgCD,eAAsB,0BACpB,SACgC;AAChC,KAAI,QAAQ,WAAW,OAAQ,QAAO;AAGtC,KAAI,EADgB,QAAQ,QAAQ,IAAI,eAAe,IAAI,IAC1C,SAAS,mBAAmB,CAAE,QAAO;CAEtD,IAAI;AACJ,KAAI;AACF,aAAW,MAAM,QAAQ,OAAO,CAAC,MAAM;SACjC;AACN,SAAO;;AAGT,KAAI,OAAO,aAAa,YAAY,aAAa,KAAM,QAAO;CAE9D,MAAM,SAAU,SAA0B;AAC1C,KAAI,OAAO,WAAW,SAAU,QAAO;AACvC,KAAI,CAAE,aAAmC,SAAS,OAAO,CAAE,QAAO;AAElE,QAAO;;AAGT,eAAsB,gBAAgB,SAAuC;AAG3E,KAAI,EAFgB,QAAQ,QAAQ,IAAI,eAAe,IAAI,IAE1C,SAAS,mBAAmB,CAC3C,OAAM,oBACJ,+CACA,IACD;CAGH,IAAI;AACJ,KAAI;AACF,iBAAgB,MAAM,QAAQ,OAAO,CAAC,MAAM;SACtC;AACN,QAAM,oBAAoB,wBAAwB,IAAI;;AAKxD,QAAO;EACL,QAHa,eAAe,aAAa,OAAO;EAIhD,QAAQ,aAAa;EACrB,MAAM,aAAa;EACpB;;AAGH,SAAgB,aACd,QACA,KACQ;CACR,MAAM,QAAQ,SAAS;AACvB,KAAI,OAAO,UAAU,YAAY,MAAM,MAAM,CAAC,SAAS,EACrD,QAAO;AAGT,OAAM,oBAAoB,iCAAiC,IAAI,IAAI,IAAI;;AAGzE,SAAgB,kBAAkB,MAAe,MAAwB;AACvE,KAAI,SAAS,UAAa,SAAS,KACjC,OAAM,oBAAoB,yCAAyC,IAAI;CAGzE,MAAM,UAAU,IAAI,QAAQ,KAAK,QAAQ;AACzC,SAAQ,IAAI,gBAAgB,mBAAmB;AAC/C,SAAQ,OAAO,iBAAiB;CAEhC,MAAM,iBAAiB,kBAAkB,KAAK;AAE9C,QAAO,IAAI,QAAQ,KAAK,KAAK;EAC3B,QAAQ;EACR;EACA,MAAM;EACN,QAAQ,KAAK;EACd,CAAC;;;;;;;;;AAUJ,SAAgB,sBACd,MACA,MACA,YACA,MACS;AACT,KAAI,CAAC,KAAK,WAAW,IAAI,IAAI,KAAK,WAAW,KAAK,CAChD,OAAM,oBAAoB,0CAA0C,IAAI;CAG1E,MAAM,cAAc,IAAI,IAAI,MAAM,6BAA6B;AAC/D,KAAI,YAAY,WAAW,6BACzB,OAAM,oBAAoB,0CAA0C,IAAI;CAG1E,MAAM,YAAY,IAAI,IAAI,KAAK,IAAI;AACnC,WAAU,WAAW,GAAG,UAAU,SAAS,QAAQ,OAAO,GAAG,GAAG,YAAY;AAC5E,WAAU,SAAS,YAAY;CAE/B,MAAM,SAAS,WAAW,aAAa;CACvC,MAAM,UAAU,IAAI,QAAQ,KAAK,QAAQ;AACzC,SAAQ,OAAO,iBAAiB;CAChC,MAAM,UAAU,WAAW,SAAS,WAAW,UAAU,QAAQ;AAEjE,QAAO,IAAI,QAAQ,WAAW;EAC5B;EACA;EACA,GAAI,UAAU,EAAE,MAAM,kBAAkB,KAAK,EAAE,GAAG,EAAE;EACpD,QAAQ,KAAK;EACd,CAAC;;AAGJ,SAAgB,oBAAoB,SAAiB,QAA0B;AAC7E,QAAO,IAAI,SACT,KAAK,UAAU;EACb,OAAO;EACP;EACD,CAAC,EACF;EACE;EACA,SAAS,EACP,gBAAgB,oBACjB;EACF,CACF;;AAGH,SAAS,eAAe,QAA4C;AAClE,KAAI,CAAC,OACH,OAAM,oBAAoB,wBAAwB,IAAI;AAGxD,KAAK,aAAmC,SAAS,OAAO,CACtD,QAAO;AAGT,OAAM,oBAAoB,uBAAuB,OAAO,IAAI,IAAI;;AAGlE,SAAS,kBAAkB,MAAyB;AAClD,KAAI,OAAO,SAAS,SAClB,QAAO;AAGT,KACE,gBAAgB,QAChB,gBAAgB,eAChB,gBAAgB,WAIhB,QAAO;AAGT,KAAI,gBAAgB,YAAY,gBAAgB,gBAC9C,QAAO;AAGT,QAAO,KAAK,UAAU,KAAK"}
|
|
@@ -7,7 +7,9 @@ const METHOD_NAMES = [
|
|
|
7
7
|
"agent/stop",
|
|
8
8
|
"info",
|
|
9
9
|
"inspector/metadata",
|
|
10
|
-
"
|
|
10
|
+
"inspector/learning",
|
|
11
|
+
"transcribe",
|
|
12
|
+
"resource/request"
|
|
11
13
|
];
|
|
12
14
|
/**
|
|
13
15
|
* Detect a single-route JSON envelope on a request the multi-route router
|
|
@@ -72,6 +74,31 @@ function createJsonRequest(base, body) {
|
|
|
72
74
|
signal: base.signal
|
|
73
75
|
});
|
|
74
76
|
}
|
|
77
|
+
/**
|
|
78
|
+
* Rebuild a resource request carried inside the single-route JSON envelope.
|
|
79
|
+
*
|
|
80
|
+
* The resource path must stay relative to the mounted Runtime. This prevents
|
|
81
|
+
* the envelope from becoming an open HTTP proxy while preserving the method,
|
|
82
|
+
* query string, headers, and cancellation signal used by the REST handler.
|
|
83
|
+
*/
|
|
84
|
+
function createResourceRequest(base, path, httpMethod, body) {
|
|
85
|
+
if (!path.startsWith("/") || path.startsWith("//")) throw createResponseError("Resource path must be Runtime-relative", 400);
|
|
86
|
+
const resourceUrl = new URL(path, "http://copilotkit.resource");
|
|
87
|
+
if (resourceUrl.origin !== "http://copilotkit.resource") throw createResponseError("Resource path must be Runtime-relative", 400);
|
|
88
|
+
const targetUrl = new URL(base.url);
|
|
89
|
+
targetUrl.pathname = `${targetUrl.pathname.replace(/\/$/, "")}${resourceUrl.pathname}`;
|
|
90
|
+
targetUrl.search = resourceUrl.search;
|
|
91
|
+
const method = httpMethod.toUpperCase();
|
|
92
|
+
const headers = new Headers(base.headers);
|
|
93
|
+
headers.delete("content-length");
|
|
94
|
+
const hasBody = method !== "GET" && method !== "HEAD" && body != null;
|
|
95
|
+
return new Request(targetUrl, {
|
|
96
|
+
method,
|
|
97
|
+
headers,
|
|
98
|
+
...hasBody ? { body: serializeJsonBody(body) } : {},
|
|
99
|
+
signal: base.signal
|
|
100
|
+
});
|
|
101
|
+
}
|
|
75
102
|
function createResponseError(message, status) {
|
|
76
103
|
return new Response(JSON.stringify({
|
|
77
104
|
error: "invalid_request",
|
|
@@ -94,5 +121,5 @@ function serializeJsonBody(body) {
|
|
|
94
121
|
}
|
|
95
122
|
|
|
96
123
|
//#endregion
|
|
97
|
-
export { createJsonRequest, detectSingleRouteEnvelope, expectString, parseMethodCall };
|
|
124
|
+
export { createJsonRequest, createResourceRequest, detectSingleRouteEnvelope, expectString, parseMethodCall };
|
|
98
125
|
//# sourceMappingURL=single-route-helpers.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"single-route-helpers.mjs","names":[],"sources":["../../../../src/v2/runtime/endpoints/single-route-helpers.ts"],"sourcesContent":["const METHOD_NAMES = [\n \"agent/run\",\n \"agent/suggest\",\n \"agent/connect\",\n \"agent/stop\",\n \"info\",\n \"inspector/metadata\",\n \"transcribe\",\n] as const;\n\nexport type EndpointMethod = (typeof METHOD_NAMES)[number];\n\ninterface JsonEnvelope {\n method?: string;\n params?: Record<string, unknown>;\n body?: unknown;\n}\n\nexport interface MethodCall {\n method: EndpointMethod;\n params?: Record<string, unknown>;\n body?: unknown;\n}\n\n/**\n * Detect a single-route JSON envelope on a request the multi-route router\n * could not match.\n *\n * A single-endpoint client (`useSingleEndpoint` on the frontend provider)\n * POSTs `{ method, params, body }` at the base path. A multi-route runtime\n * matches no route for that path and would otherwise answer a bare 404, giving\n * the developer nothing to go on. Recognising the envelope here lets the\n * handler name the actual cause instead.\n *\n * Deliberately conservative: it reports a method only for a POST carrying a\n * JSON body whose `method` is one the single-route endpoint actually accepts.\n * Anything else is a genuine 404 and must stay one.\n *\n * @returns The envelope's method name, or `null` if this is not an envelope.\n */\nexport async function detectSingleRouteEnvelope(\n request: Request,\n): Promise<EndpointMethod | null> {\n if (request.method !== \"POST\") return null;\n\n const contentType = request.headers.get(\"content-type\") || \"\";\n if (!contentType.includes(\"application/json\")) return null;\n\n let envelope: unknown;\n try {\n envelope = await request.clone().json();\n } catch {\n return null;\n }\n\n if (typeof envelope !== \"object\" || envelope === null) return null;\n\n const method = (envelope as JsonEnvelope).method;\n if (typeof method !== \"string\") return null;\n if (!(METHOD_NAMES as readonly string[]).includes(method)) return null;\n\n return method as EndpointMethod;\n}\n\nexport async function parseMethodCall(request: Request): Promise<MethodCall> {\n const contentType = request.headers.get(\"content-type\") || \"\";\n\n if (!contentType.includes(\"application/json\")) {\n throw createResponseError(\n \"Single-route endpoint expects JSON payloads\",\n 415,\n );\n }\n\n let jsonEnvelope: JsonEnvelope;\n try {\n jsonEnvelope = (await request.clone().json()) as JsonEnvelope;\n } catch {\n throw createResponseError(\"Invalid JSON payload\", 400);\n }\n\n const method = validateMethod(jsonEnvelope.method);\n\n return {\n method,\n params: jsonEnvelope.params,\n body: jsonEnvelope.body,\n };\n}\n\nexport function expectString(\n params: Record<string, unknown> | undefined,\n key: string,\n): string {\n const value = params?.[key];\n if (typeof value === \"string\" && value.trim().length > 0) {\n return value;\n }\n\n throw createResponseError(`Missing or invalid parameter '${key}'`, 400);\n}\n\nexport function createJsonRequest(base: Request, body: unknown): Request {\n if (body === undefined || body === null) {\n throw createResponseError(\"Missing request body for JSON handler\", 400);\n }\n\n const headers = new Headers(base.headers);\n headers.set(\"content-type\", \"application/json\");\n headers.delete(\"content-length\");\n\n const serializedBody = serializeJsonBody(body);\n\n return new Request(base.url, {\n method: \"POST\",\n headers,\n body: serializedBody,\n signal: base.signal,\n });\n}\n\nexport function createResponseError(message: string, status: number): Response {\n return new Response(\n JSON.stringify({\n error: \"invalid_request\",\n message,\n }),\n {\n status,\n headers: {\n \"Content-Type\": \"application/json\",\n },\n },\n );\n}\n\nfunction validateMethod(method: string | undefined): EndpointMethod {\n if (!method) {\n throw createResponseError(\"Missing method field\", 400);\n }\n\n if ((METHOD_NAMES as readonly string[]).includes(method)) {\n return method as EndpointMethod;\n }\n\n throw createResponseError(`Unsupported method '${method}'`, 400);\n}\n\nfunction serializeJsonBody(body: unknown): BodyInit {\n if (typeof body === \"string\") {\n return body;\n }\n\n if (\n body instanceof Blob ||\n body instanceof ArrayBuffer ||\n body instanceof Uint8Array\n ) {\n // Uint8Array<ArrayBufferLike> is a valid fetch body at runtime, but the\n // DOM lib's BodyInit only admits ArrayBuffer-backed views.\n return body as BodyInit;\n }\n\n if (body instanceof FormData || body instanceof URLSearchParams) {\n return body;\n }\n\n return JSON.stringify(body);\n}\n"],"mappings":";;AAAA,MAAM,eAAe;CACnB;CACA;CACA;CACA;CACA;CACA;CACA;CACD;;;;;;;;;;;;;;;;;AAgCD,eAAsB,0BACpB,SACgC;AAChC,KAAI,QAAQ,WAAW,OAAQ,QAAO;AAGtC,KAAI,EADgB,QAAQ,QAAQ,IAAI,eAAe,IAAI,IAC1C,SAAS,mBAAmB,CAAE,QAAO;CAEtD,IAAI;AACJ,KAAI;AACF,aAAW,MAAM,QAAQ,OAAO,CAAC,MAAM;SACjC;AACN,SAAO;;AAGT,KAAI,OAAO,aAAa,YAAY,aAAa,KAAM,QAAO;CAE9D,MAAM,SAAU,SAA0B;AAC1C,KAAI,OAAO,WAAW,SAAU,QAAO;AACvC,KAAI,CAAE,aAAmC,SAAS,OAAO,CAAE,QAAO;AAElE,QAAO;;AAGT,eAAsB,gBAAgB,SAAuC;AAG3E,KAAI,EAFgB,QAAQ,QAAQ,IAAI,eAAe,IAAI,IAE1C,SAAS,mBAAmB,CAC3C,OAAM,oBACJ,+CACA,IACD;CAGH,IAAI;AACJ,KAAI;AACF,iBAAgB,MAAM,QAAQ,OAAO,CAAC,MAAM;SACtC;AACN,QAAM,oBAAoB,wBAAwB,IAAI;;AAKxD,QAAO;EACL,QAHa,eAAe,aAAa,OAAO;EAIhD,QAAQ,aAAa;EACrB,MAAM,aAAa;EACpB;;AAGH,SAAgB,aACd,QACA,KACQ;CACR,MAAM,QAAQ,SAAS;AACvB,KAAI,OAAO,UAAU,YAAY,MAAM,MAAM,CAAC,SAAS,EACrD,QAAO;AAGT,OAAM,oBAAoB,iCAAiC,IAAI,IAAI,IAAI;;AAGzE,SAAgB,kBAAkB,MAAe,MAAwB;AACvE,KAAI,SAAS,UAAa,SAAS,KACjC,OAAM,oBAAoB,yCAAyC,IAAI;CAGzE,MAAM,UAAU,IAAI,QAAQ,KAAK,QAAQ;AACzC,SAAQ,IAAI,gBAAgB,mBAAmB;AAC/C,SAAQ,OAAO,iBAAiB;CAEhC,MAAM,iBAAiB,kBAAkB,KAAK;AAE9C,QAAO,IAAI,QAAQ,KAAK,KAAK;EAC3B,QAAQ;EACR;EACA,MAAM;EACN,QAAQ,KAAK;EACd,CAAC;;AAGJ,SAAgB,oBAAoB,SAAiB,QAA0B;AAC7E,QAAO,IAAI,SACT,KAAK,UAAU;EACb,OAAO;EACP;EACD,CAAC,EACF;EACE;EACA,SAAS,EACP,gBAAgB,oBACjB;EACF,CACF;;AAGH,SAAS,eAAe,QAA4C;AAClE,KAAI,CAAC,OACH,OAAM,oBAAoB,wBAAwB,IAAI;AAGxD,KAAK,aAAmC,SAAS,OAAO,CACtD,QAAO;AAGT,OAAM,oBAAoB,uBAAuB,OAAO,IAAI,IAAI;;AAGlE,SAAS,kBAAkB,MAAyB;AAClD,KAAI,OAAO,SAAS,SAClB,QAAO;AAGT,KACE,gBAAgB,QAChB,gBAAgB,eAChB,gBAAgB,WAIhB,QAAO;AAGT,KAAI,gBAAgB,YAAY,gBAAgB,gBAC9C,QAAO;AAGT,QAAO,KAAK,UAAU,KAAK"}
|
|
1
|
+
{"version":3,"file":"single-route-helpers.mjs","names":[],"sources":["../../../../src/v2/runtime/endpoints/single-route-helpers.ts"],"sourcesContent":["const METHOD_NAMES = [\n \"agent/run\",\n \"agent/suggest\",\n \"agent/connect\",\n \"agent/stop\",\n \"info\",\n \"inspector/metadata\",\n \"inspector/learning\",\n \"transcribe\",\n \"resource/request\",\n] as const;\n\nexport type EndpointMethod = (typeof METHOD_NAMES)[number];\n\ninterface JsonEnvelope {\n method?: string;\n params?: Record<string, unknown>;\n body?: unknown;\n}\n\nexport interface MethodCall {\n method: EndpointMethod;\n params?: Record<string, unknown>;\n body?: unknown;\n}\n\n/**\n * Detect a single-route JSON envelope on a request the multi-route router\n * could not match.\n *\n * A single-endpoint client (`useSingleEndpoint` on the frontend provider)\n * POSTs `{ method, params, body }` at the base path. A multi-route runtime\n * matches no route for that path and would otherwise answer a bare 404, giving\n * the developer nothing to go on. Recognising the envelope here lets the\n * handler name the actual cause instead.\n *\n * Deliberately conservative: it reports a method only for a POST carrying a\n * JSON body whose `method` is one the single-route endpoint actually accepts.\n * Anything else is a genuine 404 and must stay one.\n *\n * @returns The envelope's method name, or `null` if this is not an envelope.\n */\nexport async function detectSingleRouteEnvelope(\n request: Request,\n): Promise<EndpointMethod | null> {\n if (request.method !== \"POST\") return null;\n\n const contentType = request.headers.get(\"content-type\") || \"\";\n if (!contentType.includes(\"application/json\")) return null;\n\n let envelope: unknown;\n try {\n envelope = await request.clone().json();\n } catch {\n return null;\n }\n\n if (typeof envelope !== \"object\" || envelope === null) return null;\n\n const method = (envelope as JsonEnvelope).method;\n if (typeof method !== \"string\") return null;\n if (!(METHOD_NAMES as readonly string[]).includes(method)) return null;\n\n return method as EndpointMethod;\n}\n\nexport async function parseMethodCall(request: Request): Promise<MethodCall> {\n const contentType = request.headers.get(\"content-type\") || \"\";\n\n if (!contentType.includes(\"application/json\")) {\n throw createResponseError(\n \"Single-route endpoint expects JSON payloads\",\n 415,\n );\n }\n\n let jsonEnvelope: JsonEnvelope;\n try {\n jsonEnvelope = (await request.clone().json()) as JsonEnvelope;\n } catch {\n throw createResponseError(\"Invalid JSON payload\", 400);\n }\n\n const method = validateMethod(jsonEnvelope.method);\n\n return {\n method,\n params: jsonEnvelope.params,\n body: jsonEnvelope.body,\n };\n}\n\nexport function expectString(\n params: Record<string, unknown> | undefined,\n key: string,\n): string {\n const value = params?.[key];\n if (typeof value === \"string\" && value.trim().length > 0) {\n return value;\n }\n\n throw createResponseError(`Missing or invalid parameter '${key}'`, 400);\n}\n\nexport function createJsonRequest(base: Request, body: unknown): Request {\n if (body === undefined || body === null) {\n throw createResponseError(\"Missing request body for JSON handler\", 400);\n }\n\n const headers = new Headers(base.headers);\n headers.set(\"content-type\", \"application/json\");\n headers.delete(\"content-length\");\n\n const serializedBody = serializeJsonBody(body);\n\n return new Request(base.url, {\n method: \"POST\",\n headers,\n body: serializedBody,\n signal: base.signal,\n });\n}\n\n/**\n * Rebuild a resource request carried inside the single-route JSON envelope.\n *\n * The resource path must stay relative to the mounted Runtime. This prevents\n * the envelope from becoming an open HTTP proxy while preserving the method,\n * query string, headers, and cancellation signal used by the REST handler.\n */\nexport function createResourceRequest(\n base: Request,\n path: string,\n httpMethod: string,\n body: unknown,\n): Request {\n if (!path.startsWith(\"/\") || path.startsWith(\"//\")) {\n throw createResponseError(\"Resource path must be Runtime-relative\", 400);\n }\n\n const resourceUrl = new URL(path, \"http://copilotkit.resource\");\n if (resourceUrl.origin !== \"http://copilotkit.resource\") {\n throw createResponseError(\"Resource path must be Runtime-relative\", 400);\n }\n\n const targetUrl = new URL(base.url);\n targetUrl.pathname = `${targetUrl.pathname.replace(/\\/$/, \"\")}${resourceUrl.pathname}`;\n targetUrl.search = resourceUrl.search;\n\n const method = httpMethod.toUpperCase();\n const headers = new Headers(base.headers);\n headers.delete(\"content-length\");\n const hasBody = method !== \"GET\" && method !== \"HEAD\" && body != null;\n\n return new Request(targetUrl, {\n method,\n headers,\n ...(hasBody ? { body: serializeJsonBody(body) } : {}),\n signal: base.signal,\n });\n}\n\nexport function createResponseError(message: string, status: number): Response {\n return new Response(\n JSON.stringify({\n error: \"invalid_request\",\n message,\n }),\n {\n status,\n headers: {\n \"Content-Type\": \"application/json\",\n },\n },\n );\n}\n\nfunction validateMethod(method: string | undefined): EndpointMethod {\n if (!method) {\n throw createResponseError(\"Missing method field\", 400);\n }\n\n if ((METHOD_NAMES as readonly string[]).includes(method)) {\n return method as EndpointMethod;\n }\n\n throw createResponseError(`Unsupported method '${method}'`, 400);\n}\n\nfunction serializeJsonBody(body: unknown): BodyInit {\n if (typeof body === \"string\") {\n return body;\n }\n\n if (\n body instanceof Blob ||\n body instanceof ArrayBuffer ||\n body instanceof Uint8Array\n ) {\n // Uint8Array<ArrayBufferLike> is a valid fetch body at runtime, but the\n // DOM lib's BodyInit only admits ArrayBuffer-backed views.\n return body as BodyInit;\n }\n\n if (body instanceof FormData || body instanceof URLSearchParams) {\n return body;\n }\n\n return JSON.stringify(body);\n}\n"],"mappings":";;AAAA,MAAM,eAAe;CACnB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;;;;;;;;;;;;;;;;;AAgCD,eAAsB,0BACpB,SACgC;AAChC,KAAI,QAAQ,WAAW,OAAQ,QAAO;AAGtC,KAAI,EADgB,QAAQ,QAAQ,IAAI,eAAe,IAAI,IAC1C,SAAS,mBAAmB,CAAE,QAAO;CAEtD,IAAI;AACJ,KAAI;AACF,aAAW,MAAM,QAAQ,OAAO,CAAC,MAAM;SACjC;AACN,SAAO;;AAGT,KAAI,OAAO,aAAa,YAAY,aAAa,KAAM,QAAO;CAE9D,MAAM,SAAU,SAA0B;AAC1C,KAAI,OAAO,WAAW,SAAU,QAAO;AACvC,KAAI,CAAE,aAAmC,SAAS,OAAO,CAAE,QAAO;AAElE,QAAO;;AAGT,eAAsB,gBAAgB,SAAuC;AAG3E,KAAI,EAFgB,QAAQ,QAAQ,IAAI,eAAe,IAAI,IAE1C,SAAS,mBAAmB,CAC3C,OAAM,oBACJ,+CACA,IACD;CAGH,IAAI;AACJ,KAAI;AACF,iBAAgB,MAAM,QAAQ,OAAO,CAAC,MAAM;SACtC;AACN,QAAM,oBAAoB,wBAAwB,IAAI;;AAKxD,QAAO;EACL,QAHa,eAAe,aAAa,OAAO;EAIhD,QAAQ,aAAa;EACrB,MAAM,aAAa;EACpB;;AAGH,SAAgB,aACd,QACA,KACQ;CACR,MAAM,QAAQ,SAAS;AACvB,KAAI,OAAO,UAAU,YAAY,MAAM,MAAM,CAAC,SAAS,EACrD,QAAO;AAGT,OAAM,oBAAoB,iCAAiC,IAAI,IAAI,IAAI;;AAGzE,SAAgB,kBAAkB,MAAe,MAAwB;AACvE,KAAI,SAAS,UAAa,SAAS,KACjC,OAAM,oBAAoB,yCAAyC,IAAI;CAGzE,MAAM,UAAU,IAAI,QAAQ,KAAK,QAAQ;AACzC,SAAQ,IAAI,gBAAgB,mBAAmB;AAC/C,SAAQ,OAAO,iBAAiB;CAEhC,MAAM,iBAAiB,kBAAkB,KAAK;AAE9C,QAAO,IAAI,QAAQ,KAAK,KAAK;EAC3B,QAAQ;EACR;EACA,MAAM;EACN,QAAQ,KAAK;EACd,CAAC;;;;;;;;;AAUJ,SAAgB,sBACd,MACA,MACA,YACA,MACS;AACT,KAAI,CAAC,KAAK,WAAW,IAAI,IAAI,KAAK,WAAW,KAAK,CAChD,OAAM,oBAAoB,0CAA0C,IAAI;CAG1E,MAAM,cAAc,IAAI,IAAI,MAAM,6BAA6B;AAC/D,KAAI,YAAY,WAAW,6BACzB,OAAM,oBAAoB,0CAA0C,IAAI;CAG1E,MAAM,YAAY,IAAI,IAAI,KAAK,IAAI;AACnC,WAAU,WAAW,GAAG,UAAU,SAAS,QAAQ,OAAO,GAAG,GAAG,YAAY;AAC5E,WAAU,SAAS,YAAY;CAE/B,MAAM,SAAS,WAAW,aAAa;CACvC,MAAM,UAAU,IAAI,QAAQ,KAAK,QAAQ;AACzC,SAAQ,OAAO,iBAAiB;CAChC,MAAM,UAAU,WAAW,SAAS,WAAW,UAAU,QAAQ;AAEjE,QAAO,IAAI,QAAQ,WAAW;EAC5B;EACA;EACA,GAAI,UAAU,EAAE,MAAM,kBAAkB,KAAK,EAAE,GAAG,EAAE;EACpD,QAAQ,KAAK;EACd,CAAC;;AAGJ,SAAgB,oBAAoB,SAAiB,QAA0B;AAC7E,QAAO,IAAI,SACT,KAAK,UAAU;EACb,OAAO;EACP;EACD,CAAC,EACF;EACE;EACA,SAAS,EACP,gBAAgB,oBACjB;EACF,CACF;;AAGH,SAAS,eAAe,QAA4C;AAClE,KAAI,CAAC,OACH,OAAM,oBAAoB,wBAAwB,IAAI;AAGxD,KAAK,aAAmC,SAAS,OAAO,CACtD,QAAO;AAGT,OAAM,oBAAoB,uBAAuB,OAAO,IAAI,IAAI;;AAGlE,SAAS,kBAAkB,MAAyB;AAClD,KAAI,OAAO,SAAS,SAClB,QAAO;AAGT,KACE,gBAAgB,QAChB,gBAAgB,eAChB,gBAAgB,WAIhB,QAAO;AAGT,KAAI,gBAAgB,YAAY,gBAAgB,gBAC9C,QAAO;AAGT,QAAO,KAAK,UAAU,KAAK"}
|