@copilotkit/runtime 1.54.1 → 1.55.0-next.8
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/.eslintrc.js +4 -4
- package/CHANGELOG.md +125 -113
- package/dist/_virtual/_rolldown/runtime.mjs +25 -1
- package/dist/agent/index.cjs +654 -0
- package/dist/agent/index.cjs.map +1 -0
- package/dist/agent/index.d.cts +263 -0
- package/dist/agent/index.d.cts.map +1 -0
- package/dist/agent/index.d.mts +263 -0
- package/dist/agent/index.d.mts.map +1 -0
- package/dist/agent/index.mjs +646 -0
- package/dist/agent/index.mjs.map +1 -0
- package/dist/graphql/message-conversion/agui-to-gql.cjs.map +1 -1
- package/dist/graphql/message-conversion/agui-to-gql.mjs.map +1 -1
- package/dist/lib/integrations/nextjs/app-router.cjs +2 -2
- package/dist/lib/integrations/nextjs/app-router.cjs.map +1 -1
- package/dist/lib/integrations/nextjs/app-router.mjs +1 -1
- package/dist/lib/integrations/nextjs/app-router.mjs.map +1 -1
- package/dist/lib/integrations/node-http/index.cjs +2 -3
- package/dist/lib/integrations/node-http/index.cjs.map +1 -1
- package/dist/lib/integrations/node-http/index.mjs +1 -1
- package/dist/lib/integrations/node-http/index.mjs.map +1 -1
- package/dist/lib/runtime/agent-integrations/langgraph/agent.cjs +1 -1
- package/dist/lib/runtime/agent-integrations/langgraph/agent.d.cts +2 -2
- package/dist/lib/runtime/agent-integrations/langgraph/agent.d.cts.map +1 -1
- package/dist/lib/runtime/agent-integrations/langgraph/agent.d.mts +3 -3
- package/dist/lib/runtime/agent-integrations/langgraph/agent.d.mts.map +1 -1
- package/dist/lib/runtime/agent-integrations/langgraph/agent.mjs +1 -1
- package/dist/lib/runtime/copilot-runtime.cjs +7 -5
- package/dist/lib/runtime/copilot-runtime.cjs.map +1 -1
- package/dist/lib/runtime/copilot-runtime.d.cts +10 -8
- package/dist/lib/runtime/copilot-runtime.d.cts.map +1 -1
- package/dist/lib/runtime/copilot-runtime.d.mts +10 -8
- package/dist/lib/runtime/copilot-runtime.d.mts.map +1 -1
- package/dist/lib/runtime/copilot-runtime.mjs +7 -5
- package/dist/lib/runtime/copilot-runtime.mjs.map +1 -1
- package/dist/lib/runtime/telemetry-agent-runner.cjs +2 -2
- package/dist/lib/runtime/telemetry-agent-runner.cjs.map +1 -1
- package/dist/lib/runtime/telemetry-agent-runner.d.cts +2 -1
- package/dist/lib/runtime/telemetry-agent-runner.d.cts.map +1 -1
- package/dist/lib/runtime/telemetry-agent-runner.d.mts +2 -1
- package/dist/lib/runtime/telemetry-agent-runner.d.mts.map +1 -1
- package/dist/lib/runtime/telemetry-agent-runner.mjs +1 -1
- package/dist/lib/runtime/telemetry-agent-runner.mjs.map +1 -1
- package/dist/lib/telemetry-client.cjs +1 -1
- package/dist/lib/telemetry-client.mjs +1 -1
- package/dist/package.cjs +21 -4
- package/dist/package.mjs +21 -4
- package/dist/service-adapters/anthropic/anthropic-adapter.d.mts +1 -1
- package/dist/v2/index.cjs +41 -15
- package/dist/v2/index.d.cts +14 -2
- package/dist/v2/index.d.mts +14 -2
- package/dist/v2/index.mjs +13 -4
- package/dist/v2/runtime/endpoints/express-single.cjs +190 -0
- package/dist/v2/runtime/endpoints/express-single.cjs.map +1 -0
- package/dist/v2/runtime/endpoints/express-single.d.cts +16 -0
- package/dist/v2/runtime/endpoints/express-single.d.cts.map +1 -0
- package/dist/v2/runtime/endpoints/express-single.d.mts +16 -0
- package/dist/v2/runtime/endpoints/express-single.d.mts.map +1 -0
- package/dist/v2/runtime/endpoints/express-single.mjs +187 -0
- package/dist/v2/runtime/endpoints/express-single.mjs.map +1 -0
- package/dist/v2/runtime/endpoints/express-utils.cjs +119 -0
- package/dist/v2/runtime/endpoints/express-utils.cjs.map +1 -0
- package/dist/v2/runtime/endpoints/express-utils.mjs +117 -0
- package/dist/v2/runtime/endpoints/express-utils.mjs.map +1 -0
- package/dist/v2/runtime/endpoints/express.cjs +217 -0
- package/dist/v2/runtime/endpoints/express.cjs.map +1 -0
- package/dist/v2/runtime/endpoints/express.d.cts +16 -0
- package/dist/v2/runtime/endpoints/express.d.cts.map +1 -0
- package/dist/v2/runtime/endpoints/express.d.mts +16 -0
- package/dist/v2/runtime/endpoints/express.d.mts.map +1 -0
- package/dist/v2/runtime/endpoints/express.mjs +214 -0
- package/dist/v2/runtime/endpoints/express.mjs.map +1 -0
- package/dist/v2/runtime/endpoints/hono-single.cjs +141 -0
- package/dist/v2/runtime/endpoints/hono-single.cjs.map +1 -0
- package/dist/v2/runtime/endpoints/hono-single.d.cts +41 -0
- package/dist/v2/runtime/endpoints/hono-single.d.cts.map +1 -0
- package/dist/v2/runtime/endpoints/hono-single.d.mts +41 -0
- package/dist/v2/runtime/endpoints/hono-single.d.mts.map +1 -0
- package/dist/v2/runtime/endpoints/hono-single.mjs +140 -0
- package/dist/v2/runtime/endpoints/hono-single.mjs.map +1 -0
- package/dist/v2/runtime/endpoints/hono.cjs +248 -0
- package/dist/v2/runtime/endpoints/hono.cjs.map +1 -0
- package/dist/v2/runtime/endpoints/hono.d.cts +164 -0
- package/dist/v2/runtime/endpoints/hono.d.cts.map +1 -0
- package/dist/v2/runtime/endpoints/hono.d.mts +164 -0
- package/dist/v2/runtime/endpoints/hono.d.mts.map +1 -0
- package/dist/v2/runtime/endpoints/hono.mjs +247 -0
- package/dist/v2/runtime/endpoints/hono.mjs.map +1 -0
- package/dist/v2/runtime/endpoints/index.d.cts +5 -0
- package/dist/v2/runtime/endpoints/index.d.mts +5 -0
- package/dist/v2/runtime/endpoints/single-route-helpers.cjs +68 -0
- package/dist/v2/runtime/endpoints/single-route-helpers.cjs.map +1 -0
- package/dist/v2/runtime/endpoints/single-route-helpers.mjs +65 -0
- package/dist/v2/runtime/endpoints/single-route-helpers.mjs.map +1 -0
- package/dist/v2/runtime/handlers/get-runtime-info.cjs +51 -0
- package/dist/v2/runtime/handlers/get-runtime-info.cjs.map +1 -0
- package/dist/v2/runtime/handlers/get-runtime-info.mjs +51 -0
- package/dist/v2/runtime/handlers/get-runtime-info.mjs.map +1 -0
- package/dist/v2/runtime/handlers/handle-connect.cjs +49 -0
- package/dist/v2/runtime/handlers/handle-connect.cjs.map +1 -0
- package/dist/v2/runtime/handlers/handle-connect.mjs +49 -0
- package/dist/v2/runtime/handlers/handle-connect.mjs.map +1 -0
- package/dist/v2/runtime/handlers/handle-run.cjs +61 -0
- package/dist/v2/runtime/handlers/handle-run.cjs.map +1 -0
- package/dist/v2/runtime/handlers/handle-run.mjs +61 -0
- package/dist/v2/runtime/handlers/handle-run.mjs.map +1 -0
- package/dist/v2/runtime/handlers/handle-stop.cjs +47 -0
- package/dist/v2/runtime/handlers/handle-stop.cjs.map +1 -0
- package/dist/v2/runtime/handlers/handle-stop.mjs +46 -0
- package/dist/v2/runtime/handlers/handle-stop.mjs.map +1 -0
- package/dist/v2/runtime/handlers/handle-transcribe.cjs +112 -0
- package/dist/v2/runtime/handlers/handle-transcribe.cjs.map +1 -0
- package/dist/v2/runtime/handlers/handle-transcribe.mjs +111 -0
- package/dist/v2/runtime/handlers/handle-transcribe.mjs.map +1 -0
- package/dist/v2/runtime/handlers/header-utils.cjs +26 -0
- package/dist/v2/runtime/handlers/header-utils.cjs.map +1 -0
- package/dist/v2/runtime/handlers/header-utils.mjs +25 -0
- package/dist/v2/runtime/handlers/header-utils.mjs.map +1 -0
- package/dist/v2/runtime/handlers/intelligence/connect.cjs +37 -0
- package/dist/v2/runtime/handlers/intelligence/connect.cjs.map +1 -0
- package/dist/v2/runtime/handlers/intelligence/connect.mjs +37 -0
- package/dist/v2/runtime/handlers/intelligence/connect.mjs.map +1 -0
- package/dist/v2/runtime/handlers/intelligence/run.cjs +89 -0
- package/dist/v2/runtime/handlers/intelligence/run.cjs.map +1 -0
- package/dist/v2/runtime/handlers/intelligence/run.mjs +88 -0
- package/dist/v2/runtime/handlers/intelligence/run.mjs.map +1 -0
- package/dist/v2/runtime/handlers/intelligence/thread-names.cjs +146 -0
- package/dist/v2/runtime/handlers/intelligence/thread-names.cjs.map +1 -0
- package/dist/v2/runtime/handlers/intelligence/thread-names.mjs +145 -0
- package/dist/v2/runtime/handlers/intelligence/thread-names.mjs.map +1 -0
- package/dist/v2/runtime/handlers/intelligence/threads.cjs +159 -0
- package/dist/v2/runtime/handlers/intelligence/threads.cjs.map +1 -0
- package/dist/v2/runtime/handlers/intelligence/threads.mjs +154 -0
- package/dist/v2/runtime/handlers/intelligence/threads.mjs.map +1 -0
- package/dist/v2/runtime/handlers/shared/agent-utils.cjs +74 -0
- package/dist/v2/runtime/handlers/shared/agent-utils.cjs.map +1 -0
- package/dist/v2/runtime/handlers/shared/agent-utils.mjs +70 -0
- package/dist/v2/runtime/handlers/shared/agent-utils.mjs.map +1 -0
- package/dist/v2/runtime/handlers/shared/intelligence-utils.cjs +21 -0
- package/dist/v2/runtime/handlers/shared/intelligence-utils.cjs.map +1 -0
- package/dist/v2/runtime/handlers/shared/intelligence-utils.mjs +20 -0
- package/dist/v2/runtime/handlers/shared/intelligence-utils.mjs.map +1 -0
- package/dist/v2/runtime/handlers/shared/json-response.cjs +12 -0
- package/dist/v2/runtime/handlers/shared/json-response.cjs.map +1 -0
- package/dist/v2/runtime/handlers/shared/json-response.mjs +10 -0
- package/dist/v2/runtime/handlers/shared/json-response.mjs.map +1 -0
- package/dist/v2/runtime/handlers/shared/resolve-intelligence-user.cjs +20 -0
- package/dist/v2/runtime/handlers/shared/resolve-intelligence-user.cjs.map +1 -0
- package/dist/v2/runtime/handlers/shared/resolve-intelligence-user.mjs +20 -0
- package/dist/v2/runtime/handlers/shared/resolve-intelligence-user.mjs.map +1 -0
- package/dist/v2/runtime/handlers/shared/sse-response.cjs +69 -0
- package/dist/v2/runtime/handlers/shared/sse-response.cjs.map +1 -0
- package/dist/v2/runtime/handlers/shared/sse-response.mjs +68 -0
- package/dist/v2/runtime/handlers/shared/sse-response.mjs.map +1 -0
- package/dist/v2/runtime/handlers/sse/connect.cjs +18 -0
- package/dist/v2/runtime/handlers/sse/connect.cjs.map +1 -0
- package/dist/v2/runtime/handlers/sse/connect.mjs +18 -0
- package/dist/v2/runtime/handlers/sse/connect.mjs.map +1 -0
- package/dist/v2/runtime/handlers/sse/run.cjs +18 -0
- package/dist/v2/runtime/handlers/sse/run.cjs.map +1 -0
- package/dist/v2/runtime/handlers/sse/run.mjs +18 -0
- package/dist/v2/runtime/handlers/sse/run.mjs.map +1 -0
- package/dist/v2/runtime/index.d.cts +13 -0
- package/dist/v2/runtime/index.d.mts +14 -0
- package/dist/v2/runtime/intelligence-platform/client.cjs +333 -0
- package/dist/v2/runtime/intelligence-platform/client.cjs.map +1 -0
- package/dist/v2/runtime/intelligence-platform/client.d.cts +336 -0
- package/dist/v2/runtime/intelligence-platform/client.d.cts.map +1 -0
- package/dist/v2/runtime/intelligence-platform/client.d.mts +336 -0
- package/dist/v2/runtime/intelligence-platform/client.d.mts.map +1 -0
- package/dist/v2/runtime/intelligence-platform/client.mjs +331 -0
- package/dist/v2/runtime/intelligence-platform/client.mjs.map +1 -0
- package/dist/v2/runtime/intelligence-platform/index.d.mts +2 -0
- package/dist/v2/runtime/middleware-sse-parser.cjs +138 -0
- package/dist/v2/runtime/middleware-sse-parser.cjs.map +1 -0
- package/dist/v2/runtime/middleware-sse-parser.d.cts +22 -0
- package/dist/v2/runtime/middleware-sse-parser.d.cts.map +1 -0
- package/dist/v2/runtime/middleware-sse-parser.d.mts +22 -0
- package/dist/v2/runtime/middleware-sse-parser.d.mts.map +1 -0
- package/dist/v2/runtime/middleware-sse-parser.mjs +137 -0
- package/dist/v2/runtime/middleware-sse-parser.mjs.map +1 -0
- package/dist/v2/runtime/middleware.cjs +35 -0
- package/dist/v2/runtime/middleware.cjs.map +1 -0
- package/dist/v2/runtime/middleware.d.cts +32 -0
- package/dist/v2/runtime/middleware.d.cts.map +1 -0
- package/dist/v2/runtime/middleware.d.mts +32 -0
- package/dist/v2/runtime/middleware.d.mts.map +1 -0
- package/dist/v2/runtime/middleware.mjs +33 -0
- package/dist/v2/runtime/middleware.mjs.map +1 -0
- package/dist/v2/runtime/runner/agent-runner.cjs +8 -0
- package/dist/v2/runtime/runner/agent-runner.cjs.map +1 -0
- package/dist/v2/runtime/runner/agent-runner.d.cts +32 -0
- package/dist/v2/runtime/runner/agent-runner.d.cts.map +1 -0
- package/dist/v2/runtime/runner/agent-runner.d.mts +32 -0
- package/dist/v2/runtime/runner/agent-runner.d.mts.map +1 -0
- package/dist/v2/runtime/runner/agent-runner.mjs +7 -0
- package/dist/v2/runtime/runner/agent-runner.mjs.map +1 -0
- package/dist/v2/runtime/runner/in-memory.cjs +223 -0
- package/dist/v2/runtime/runner/in-memory.cjs.map +1 -0
- package/dist/v2/runtime/runner/in-memory.d.cts +15 -0
- package/dist/v2/runtime/runner/in-memory.d.cts.map +1 -0
- package/dist/v2/runtime/runner/in-memory.d.mts +15 -0
- package/dist/v2/runtime/runner/in-memory.d.mts.map +1 -0
- package/dist/v2/runtime/runner/in-memory.mjs +222 -0
- package/dist/v2/runtime/runner/in-memory.mjs.map +1 -0
- package/dist/v2/runtime/runner/index.d.cts +6 -0
- package/dist/v2/runtime/runner/index.d.mts +6 -0
- package/dist/v2/runtime/runner/index.mjs +7 -0
- package/dist/v2/runtime/runner/intelligence.cjs +246 -0
- package/dist/v2/runtime/runner/intelligence.cjs.map +1 -0
- package/dist/v2/runtime/runner/intelligence.d.cts +57 -0
- package/dist/v2/runtime/runner/intelligence.d.cts.map +1 -0
- package/dist/v2/runtime/runner/intelligence.d.mts +57 -0
- package/dist/v2/runtime/runner/intelligence.d.mts.map +1 -0
- package/dist/v2/runtime/runner/intelligence.mjs +245 -0
- package/dist/v2/runtime/runner/intelligence.mjs.map +1 -0
- package/dist/v2/runtime/runtime.cjs +101 -0
- package/dist/v2/runtime/runtime.cjs.map +1 -0
- package/dist/v2/runtime/runtime.d.cts +132 -0
- package/dist/v2/runtime/runtime.d.cts.map +1 -0
- package/dist/v2/runtime/runtime.d.mts +133 -0
- package/dist/v2/runtime/runtime.d.mts.map +1 -0
- package/dist/v2/runtime/runtime.mjs +97 -0
- package/dist/v2/runtime/runtime.mjs.map +1 -0
- package/dist/v2/runtime/telemetry/scarf-client.cjs +32 -0
- package/dist/v2/runtime/telemetry/scarf-client.cjs.map +1 -0
- package/dist/v2/runtime/telemetry/scarf-client.mjs +32 -0
- package/dist/v2/runtime/telemetry/scarf-client.mjs.map +1 -0
- package/dist/v2/runtime/telemetry/telemetry-client.cjs +35 -0
- package/dist/v2/runtime/telemetry/telemetry-client.cjs.map +1 -0
- package/dist/v2/runtime/telemetry/telemetry-client.mjs +35 -0
- package/dist/v2/runtime/telemetry/telemetry-client.mjs.map +1 -0
- package/dist/v2/runtime/transcription-service/transcription-service.cjs +8 -0
- package/dist/v2/runtime/transcription-service/transcription-service.cjs.map +1 -0
- package/dist/v2/runtime/transcription-service/transcription-service.d.cts +15 -0
- package/dist/v2/runtime/transcription-service/transcription-service.d.cts.map +1 -0
- package/dist/v2/runtime/transcription-service/transcription-service.d.mts +15 -0
- package/dist/v2/runtime/transcription-service/transcription-service.d.mts.map +1 -0
- package/dist/v2/runtime/transcription-service/transcription-service.mjs +7 -0
- package/dist/v2/runtime/transcription-service/transcription-service.mjs.map +1 -0
- package/package.json +24 -7
- package/src/agent/__tests__/ai-sdk-v6-compat.test.ts +116 -0
- package/src/agent/__tests__/basic-agent.test.ts +1698 -0
- package/src/agent/__tests__/config-tools-execution.test.ts +516 -0
- package/src/agent/__tests__/mcp-clients.test.ts +260 -0
- package/src/agent/__tests__/property-overrides.test.ts +598 -0
- package/src/agent/__tests__/standard-schema-tools.test.ts +313 -0
- package/src/agent/__tests__/standard-schema-types.test.ts +158 -0
- package/src/agent/__tests__/state-tools.test.ts +436 -0
- package/src/agent/__tests__/test-helpers.ts +193 -0
- package/src/agent/__tests__/utils.test.ts +536 -0
- package/src/agent/__tests__/zod-regression.test.ts +350 -0
- package/src/agent/index.ts +1329 -0
- package/src/graphql/message-conversion/agui-to-gql.test.ts +1 -1
- package/src/graphql/message-conversion/agui-to-gql.ts +1 -1
- package/src/graphql/message-conversion/gql-to-agui.ts +1 -1
- package/src/graphql/message-conversion/roundtrip-conversion.test.ts +1 -1
- package/src/lib/integrations/nextjs/app-router.ts +2 -2
- package/src/lib/integrations/node-http/index.ts +2 -2
- package/src/lib/runtime/copilot-runtime.ts +3 -5
- package/src/lib/runtime/telemetry-agent-runner.ts +1 -1
- package/src/service-adapters/conversion.test.ts +1 -1
- package/src/service-adapters/conversion.ts +1 -28
- package/src/v2/index.ts +5 -2
- package/src/v2/runtime/__tests__/cors-credentials.test.ts +320 -0
- package/src/v2/runtime/__tests__/express-abort-signal.test.ts +25 -0
- package/src/v2/runtime/__tests__/express-body-order.test.ts +76 -0
- package/src/v2/runtime/__tests__/express-single-sse.test.ts +122 -0
- package/src/v2/runtime/__tests__/get-runtime-info.test.ts +141 -0
- package/src/v2/runtime/__tests__/handle-connect.test.ts +423 -0
- package/src/v2/runtime/__tests__/handle-run.test.ts +910 -0
- package/src/v2/runtime/__tests__/handle-threads.test.ts +388 -0
- package/src/v2/runtime/__tests__/handle-transcribe.test.ts +301 -0
- package/src/v2/runtime/__tests__/header-utils.test.ts +88 -0
- package/src/v2/runtime/__tests__/in-process-agent-runner-messages.test.ts +230 -0
- package/src/v2/runtime/__tests__/in-process-agent-runner.test.ts +1030 -0
- package/src/v2/runtime/__tests__/middleware-express.test.ts +206 -0
- package/src/v2/runtime/__tests__/middleware-single-express.test.ts +211 -0
- package/src/v2/runtime/__tests__/middleware-single.test.ts +225 -0
- package/src/v2/runtime/__tests__/middleware-sse-parser.test.ts +187 -0
- package/src/v2/runtime/__tests__/middleware.test.ts +251 -0
- package/src/v2/runtime/__tests__/routing-express.test.ts +174 -0
- package/src/v2/runtime/__tests__/routing-single-express.test.ts +168 -0
- package/src/v2/runtime/__tests__/routing-single.test.ts +193 -0
- package/src/v2/runtime/__tests__/routing.test.ts +257 -0
- package/src/v2/runtime/__tests__/runtime.test.ts +123 -0
- package/src/v2/runtime/__tests__/telemetry.test.ts +167 -0
- package/src/v2/runtime/__tests__/thread-names.test.ts +188 -0
- package/src/v2/runtime/endpoints/express-single.ts +231 -0
- package/src/v2/runtime/endpoints/express-utils.ts +182 -0
- package/src/v2/runtime/endpoints/express.ts +275 -0
- package/src/v2/runtime/endpoints/hono-single.ts +212 -0
- package/src/v2/runtime/endpoints/hono.ts +314 -0
- package/src/v2/runtime/endpoints/index.ts +4 -0
- package/src/v2/runtime/endpoints/single-route-helpers.ts +125 -0
- package/src/v2/runtime/express.ts +2 -0
- package/src/v2/runtime/handler.ts +3 -0
- package/src/v2/runtime/handlers/get-runtime-info.ts +79 -0
- package/src/v2/runtime/handlers/handle-connect.ts +76 -0
- package/src/v2/runtime/handlers/handle-run.ts +89 -0
- package/src/v2/runtime/handlers/handle-stop.ts +76 -0
- package/src/v2/runtime/handlers/handle-threads.ts +7 -0
- package/src/v2/runtime/handlers/handle-transcribe.ts +256 -0
- package/src/v2/runtime/handlers/header-utils.ts +24 -0
- package/src/v2/runtime/handlers/intelligence/connect.ts +65 -0
- package/src/v2/runtime/handlers/intelligence/run.ts +152 -0
- package/src/v2/runtime/handlers/intelligence/thread-names.ts +246 -0
- package/src/v2/runtime/handlers/intelligence/threads.ts +233 -0
- package/src/v2/runtime/handlers/shared/agent-utils.ts +136 -0
- package/src/v2/runtime/handlers/shared/intelligence-utils.ts +21 -0
- package/src/v2/runtime/handlers/shared/json-response.ts +6 -0
- package/src/v2/runtime/handlers/shared/resolve-intelligence-user.ts +25 -0
- package/src/v2/runtime/handlers/shared/sse-response.ts +100 -0
- package/src/v2/runtime/handlers/sse/connect.ts +24 -0
- package/src/v2/runtime/handlers/sse/run.ts +27 -0
- package/src/v2/runtime/index.ts +20 -0
- package/src/v2/runtime/intelligence-platform/__tests__/client.test.ts +605 -0
- package/src/v2/runtime/intelligence-platform/client.ts +659 -0
- package/src/v2/runtime/intelligence-platform/index.ts +10 -0
- package/src/v2/runtime/middleware-sse-parser.ts +200 -0
- package/src/v2/runtime/middleware.ts +115 -0
- package/src/v2/runtime/runner/__tests__/finalize-events.test.ts +109 -0
- package/src/v2/runtime/runner/__tests__/in-memory-runner.e2e.test.ts +775 -0
- package/src/v2/runtime/runner/__tests__/in-memory-runner.test.ts +363 -0
- package/src/v2/runtime/runner/__tests__/intelligence-runner.test.ts +981 -0
- package/src/v2/runtime/runner/agent-runner.ts +36 -0
- package/src/v2/runtime/runner/in-memory.ts +381 -0
- package/src/v2/runtime/runner/index.ts +4 -0
- package/src/v2/runtime/runner/intelligence.ts +429 -0
- package/src/v2/runtime/runtime.ts +260 -0
- package/src/v2/runtime/telemetry/events.ts +35 -0
- package/src/v2/runtime/telemetry/index.ts +7 -0
- package/src/v2/runtime/telemetry/scarf-client.ts +39 -0
- package/src/v2/runtime/telemetry/telemetry-client.ts +70 -0
- package/src/v2/runtime/transcription-service/transcription-service.ts +11 -0
- package/tsconfig.json +9 -2
- package/tsdown.config.ts +1 -0
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
require("reflect-metadata");
|
|
2
|
+
const require_runtime = require('../../../_virtual/_rolldown/runtime.cjs');
|
|
3
|
+
let _copilotkit_shared = require("@copilotkit/shared");
|
|
4
|
+
|
|
5
|
+
//#region src/v2/runtime/handlers/handle-transcribe.ts
|
|
6
|
+
/**
|
|
7
|
+
* HTTP status codes for transcription error codes
|
|
8
|
+
*/
|
|
9
|
+
const ERROR_STATUS_CODES = {
|
|
10
|
+
[_copilotkit_shared.TranscriptionErrorCode.SERVICE_NOT_CONFIGURED]: 503,
|
|
11
|
+
[_copilotkit_shared.TranscriptionErrorCode.INVALID_AUDIO_FORMAT]: 400,
|
|
12
|
+
[_copilotkit_shared.TranscriptionErrorCode.AUDIO_TOO_LONG]: 400,
|
|
13
|
+
[_copilotkit_shared.TranscriptionErrorCode.AUDIO_TOO_SHORT]: 400,
|
|
14
|
+
[_copilotkit_shared.TranscriptionErrorCode.RATE_LIMITED]: 429,
|
|
15
|
+
[_copilotkit_shared.TranscriptionErrorCode.AUTH_FAILED]: 401,
|
|
16
|
+
[_copilotkit_shared.TranscriptionErrorCode.PROVIDER_ERROR]: 500,
|
|
17
|
+
[_copilotkit_shared.TranscriptionErrorCode.NETWORK_ERROR]: 502,
|
|
18
|
+
[_copilotkit_shared.TranscriptionErrorCode.INVALID_REQUEST]: 400
|
|
19
|
+
};
|
|
20
|
+
const VALID_AUDIO_TYPES = [
|
|
21
|
+
"audio/mpeg",
|
|
22
|
+
"audio/mp3",
|
|
23
|
+
"audio/mp4",
|
|
24
|
+
"audio/wav",
|
|
25
|
+
"audio/webm",
|
|
26
|
+
"audio/ogg",
|
|
27
|
+
"audio/flac",
|
|
28
|
+
"audio/aac"
|
|
29
|
+
];
|
|
30
|
+
function isValidAudioType(type) {
|
|
31
|
+
const baseType = type.split(";")[0]?.trim() ?? "";
|
|
32
|
+
return VALID_AUDIO_TYPES.includes(baseType) || baseType === "" || baseType === "application/octet-stream";
|
|
33
|
+
}
|
|
34
|
+
function createErrorResponse(errorResponse) {
|
|
35
|
+
const status = ERROR_STATUS_CODES[errorResponse.error] ?? 500;
|
|
36
|
+
return new Response(JSON.stringify(errorResponse), {
|
|
37
|
+
status,
|
|
38
|
+
headers: { "Content-Type": "application/json" }
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
function base64ToFile(base64, mimeType, filename) {
|
|
42
|
+
const base64Data = base64.includes(",") ? base64.split(",")[1] ?? base64 : base64;
|
|
43
|
+
const binaryString = atob(base64Data);
|
|
44
|
+
const bytes = new Uint8Array(binaryString.length);
|
|
45
|
+
for (let i = 0; i < binaryString.length; i++) bytes[i] = binaryString.charCodeAt(i);
|
|
46
|
+
return new File([bytes], filename, { type: mimeType });
|
|
47
|
+
}
|
|
48
|
+
async function extractAudioFromFormData(request) {
|
|
49
|
+
const audioFile = (await request.formData()).get("audio");
|
|
50
|
+
if (!audioFile || !(audioFile instanceof File)) return { error: createErrorResponse(_copilotkit_shared.TranscriptionErrors.invalidRequest("No audio file found in form data. Please include an 'audio' field.")) };
|
|
51
|
+
if (!isValidAudioType(audioFile.type)) return { error: createErrorResponse(_copilotkit_shared.TranscriptionErrors.invalidAudioFormat(audioFile.type, VALID_AUDIO_TYPES)) };
|
|
52
|
+
return { file: audioFile };
|
|
53
|
+
}
|
|
54
|
+
async function extractAudioFromJson(request) {
|
|
55
|
+
let body;
|
|
56
|
+
try {
|
|
57
|
+
body = await request.json();
|
|
58
|
+
} catch {
|
|
59
|
+
return { error: createErrorResponse(_copilotkit_shared.TranscriptionErrors.invalidRequest("Request body must be valid JSON")) };
|
|
60
|
+
}
|
|
61
|
+
if (!body.audio || typeof body.audio !== "string") return { error: createErrorResponse(_copilotkit_shared.TranscriptionErrors.invalidRequest("Request must include 'audio' field with base64-encoded audio data")) };
|
|
62
|
+
if (!body.mimeType || typeof body.mimeType !== "string") return { error: createErrorResponse(_copilotkit_shared.TranscriptionErrors.invalidRequest("Request must include 'mimeType' field (e.g., 'audio/webm')")) };
|
|
63
|
+
if (!isValidAudioType(body.mimeType)) return { error: createErrorResponse(_copilotkit_shared.TranscriptionErrors.invalidAudioFormat(body.mimeType, VALID_AUDIO_TYPES)) };
|
|
64
|
+
try {
|
|
65
|
+
const filename = body.filename || "recording.webm";
|
|
66
|
+
return { file: base64ToFile(body.audio, body.mimeType, filename) };
|
|
67
|
+
} catch {
|
|
68
|
+
return { error: createErrorResponse(_copilotkit_shared.TranscriptionErrors.invalidRequest("Failed to decode base64 audio data")) };
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Categorize provider errors into appropriate transcription error responses.
|
|
73
|
+
*/
|
|
74
|
+
function categorizeProviderError(error) {
|
|
75
|
+
const message = error instanceof Error ? error.message : "Unknown error occurred";
|
|
76
|
+
const errorStr = String(error).toLowerCase();
|
|
77
|
+
if (errorStr.includes("rate") || errorStr.includes("429") || errorStr.includes("too many")) return _copilotkit_shared.TranscriptionErrors.rateLimited();
|
|
78
|
+
if (errorStr.includes("auth") || errorStr.includes("401") || errorStr.includes("api key") || errorStr.includes("unauthorized")) return _copilotkit_shared.TranscriptionErrors.authFailed();
|
|
79
|
+
if (errorStr.includes("too long") || errorStr.includes("duration") || errorStr.includes("length")) return _copilotkit_shared.TranscriptionErrors.audioTooLong();
|
|
80
|
+
return _copilotkit_shared.TranscriptionErrors.providerError(message);
|
|
81
|
+
}
|
|
82
|
+
async function handleTranscribe({ runtime, request }) {
|
|
83
|
+
try {
|
|
84
|
+
if (!runtime.transcriptionService) return createErrorResponse(_copilotkit_shared.TranscriptionErrors.serviceNotConfigured());
|
|
85
|
+
const contentType = request.headers.get("content-type") || "";
|
|
86
|
+
let extractResult;
|
|
87
|
+
if (contentType.includes("multipart/form-data")) extractResult = await extractAudioFromFormData(request);
|
|
88
|
+
else if (contentType.includes("application/json")) extractResult = await extractAudioFromJson(request);
|
|
89
|
+
else return createErrorResponse(_copilotkit_shared.TranscriptionErrors.invalidRequest("Request must be multipart/form-data or application/json with base64 audio"));
|
|
90
|
+
if ("error" in extractResult) return extractResult.error;
|
|
91
|
+
const audioFile = extractResult.file;
|
|
92
|
+
const transcription = await runtime.transcriptionService.transcribeFile({
|
|
93
|
+
audioFile,
|
|
94
|
+
mimeType: audioFile.type,
|
|
95
|
+
size: audioFile.size
|
|
96
|
+
});
|
|
97
|
+
return new Response(JSON.stringify({
|
|
98
|
+
text: transcription,
|
|
99
|
+
size: audioFile.size,
|
|
100
|
+
type: audioFile.type
|
|
101
|
+
}), {
|
|
102
|
+
status: 200,
|
|
103
|
+
headers: { "Content-Type": "application/json" }
|
|
104
|
+
});
|
|
105
|
+
} catch (error) {
|
|
106
|
+
return createErrorResponse(categorizeProviderError(error));
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
//#endregion
|
|
111
|
+
exports.handleTranscribe = handleTranscribe;
|
|
112
|
+
//# sourceMappingURL=handle-transcribe.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handle-transcribe.cjs","names":["TranscriptionErrorCode","TranscriptionErrors"],"sources":["../../../../src/v2/runtime/handlers/handle-transcribe.ts"],"sourcesContent":["import { CopilotRuntimeLike } from \"../runtime\";\nimport {\n TranscriptionErrorCode,\n TranscriptionErrors,\n type TranscriptionErrorResponse,\n} from \"@copilotkit/shared\";\n\n/**\n * HTTP status codes for transcription error codes\n */\nconst ERROR_STATUS_CODES: Record<TranscriptionErrorCode, number> = {\n [TranscriptionErrorCode.SERVICE_NOT_CONFIGURED]: 503,\n [TranscriptionErrorCode.INVALID_AUDIO_FORMAT]: 400,\n [TranscriptionErrorCode.AUDIO_TOO_LONG]: 400,\n [TranscriptionErrorCode.AUDIO_TOO_SHORT]: 400,\n [TranscriptionErrorCode.RATE_LIMITED]: 429,\n [TranscriptionErrorCode.AUTH_FAILED]: 401,\n [TranscriptionErrorCode.PROVIDER_ERROR]: 500,\n [TranscriptionErrorCode.NETWORK_ERROR]: 502,\n [TranscriptionErrorCode.INVALID_REQUEST]: 400,\n};\n\ninterface HandleTranscribeParameters {\n runtime: CopilotRuntimeLike;\n request: Request;\n}\n\ninterface Base64AudioInput {\n audio: string; // base64-encoded audio data\n mimeType: string;\n filename?: string;\n}\n\nconst VALID_AUDIO_TYPES = [\n \"audio/mpeg\",\n \"audio/mp3\",\n \"audio/mp4\",\n \"audio/wav\",\n \"audio/webm\",\n \"audio/ogg\",\n \"audio/flac\",\n \"audio/aac\",\n];\n\nfunction isValidAudioType(type: string): boolean {\n // Extract base MIME type (before semicolon) to handle types like \"audio/webm; codecs=opus\"\n const baseType = type.split(\";\")[0]?.trim() ?? \"\";\n return (\n VALID_AUDIO_TYPES.includes(baseType) ||\n baseType === \"\" ||\n baseType === \"application/octet-stream\"\n );\n}\n\nfunction createErrorResponse(\n errorResponse: TranscriptionErrorResponse,\n): Response {\n const status = ERROR_STATUS_CODES[errorResponse.error] ?? 500;\n return new Response(JSON.stringify(errorResponse), {\n status,\n headers: { \"Content-Type\": \"application/json\" },\n });\n}\n\nfunction base64ToFile(\n base64: string,\n mimeType: string,\n filename: string,\n): File {\n // Remove data URL prefix if present (e.g., \"data:audio/webm;base64,\")\n const base64Data = base64.includes(\",\")\n ? (base64.split(\",\")[1] ?? base64)\n : base64;\n\n // Decode base64 to binary\n const binaryString = atob(base64Data);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n\n // Create File object\n return new File([bytes], filename, { type: mimeType });\n}\n\nasync function extractAudioFromFormData(\n request: Request,\n): Promise<{ file: File } | { error: Response }> {\n const formData = await request.formData();\n const audioFile = formData.get(\"audio\") as File | null;\n\n if (!audioFile || !(audioFile instanceof File)) {\n const err = TranscriptionErrors.invalidRequest(\n \"No audio file found in form data. Please include an 'audio' field.\",\n );\n return { error: createErrorResponse(err) };\n }\n\n if (!isValidAudioType(audioFile.type)) {\n const err = TranscriptionErrors.invalidAudioFormat(\n audioFile.type,\n VALID_AUDIO_TYPES,\n );\n return { error: createErrorResponse(err) };\n }\n\n return { file: audioFile };\n}\n\nasync function extractAudioFromJson(\n request: Request,\n): Promise<{ file: File } | { error: Response }> {\n let body: Base64AudioInput;\n\n try {\n body = await request.json();\n } catch {\n const err = TranscriptionErrors.invalidRequest(\n \"Request body must be valid JSON\",\n );\n return { error: createErrorResponse(err) };\n }\n\n if (!body.audio || typeof body.audio !== \"string\") {\n const err = TranscriptionErrors.invalidRequest(\n \"Request must include 'audio' field with base64-encoded audio data\",\n );\n return { error: createErrorResponse(err) };\n }\n\n if (!body.mimeType || typeof body.mimeType !== \"string\") {\n const err = TranscriptionErrors.invalidRequest(\n \"Request must include 'mimeType' field (e.g., 'audio/webm')\",\n );\n return { error: createErrorResponse(err) };\n }\n\n if (!isValidAudioType(body.mimeType)) {\n const err = TranscriptionErrors.invalidAudioFormat(\n body.mimeType,\n VALID_AUDIO_TYPES,\n );\n return { error: createErrorResponse(err) };\n }\n\n try {\n const filename = body.filename || \"recording.webm\";\n const file = base64ToFile(body.audio, body.mimeType, filename);\n return { file };\n } catch {\n const err = TranscriptionErrors.invalidRequest(\n \"Failed to decode base64 audio data\",\n );\n return { error: createErrorResponse(err) };\n }\n}\n\n/**\n * Categorize provider errors into appropriate transcription error responses.\n */\nfunction categorizeProviderError(error: unknown): TranscriptionErrorResponse {\n const message =\n error instanceof Error ? error.message : \"Unknown error occurred\";\n const errorStr = String(error).toLowerCase();\n\n // Check for rate limiting\n if (\n errorStr.includes(\"rate\") ||\n errorStr.includes(\"429\") ||\n errorStr.includes(\"too many\")\n ) {\n return TranscriptionErrors.rateLimited();\n }\n\n // Check for auth errors\n if (\n errorStr.includes(\"auth\") ||\n errorStr.includes(\"401\") ||\n errorStr.includes(\"api key\") ||\n errorStr.includes(\"unauthorized\")\n ) {\n return TranscriptionErrors.authFailed();\n }\n\n // Check for audio too long\n if (\n errorStr.includes(\"too long\") ||\n errorStr.includes(\"duration\") ||\n errorStr.includes(\"length\")\n ) {\n return TranscriptionErrors.audioTooLong();\n }\n\n // Default to provider error\n return TranscriptionErrors.providerError(message);\n}\n\nexport async function handleTranscribe({\n runtime,\n request,\n}: HandleTranscribeParameters) {\n try {\n // Check if transcription service is configured\n if (!runtime.transcriptionService) {\n const err = TranscriptionErrors.serviceNotConfigured();\n return createErrorResponse(err);\n }\n\n // Determine input type based on content-type header\n const contentType = request.headers.get(\"content-type\") || \"\";\n\n let extractResult: { file: File } | { error: Response };\n\n if (contentType.includes(\"multipart/form-data\")) {\n // Handle multipart/form-data (REST mode)\n extractResult = await extractAudioFromFormData(request);\n } else if (contentType.includes(\"application/json\")) {\n // Handle JSON with base64 audio (single-endpoint mode)\n extractResult = await extractAudioFromJson(request);\n } else {\n const err = TranscriptionErrors.invalidRequest(\n \"Request must be multipart/form-data or application/json with base64 audio\",\n );\n return createErrorResponse(err);\n }\n\n // Check for extraction errors\n if (\"error\" in extractResult) {\n return extractResult.error;\n }\n\n const audioFile = extractResult.file;\n\n // Transcribe the audio file\n const transcription = await runtime.transcriptionService.transcribeFile({\n audioFile,\n mimeType: audioFile.type,\n size: audioFile.size,\n });\n\n return new Response(\n JSON.stringify({\n text: transcription,\n size: audioFile.size,\n type: audioFile.type,\n }),\n {\n status: 200,\n headers: { \"Content-Type\": \"application/json\" },\n },\n );\n } catch (error) {\n // Categorize the error for better client-side handling\n return createErrorResponse(categorizeProviderError(error));\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import "reflect-metadata";
|
|
2
|
+
import { TranscriptionErrorCode, TranscriptionErrors } from "@copilotkit/shared";
|
|
3
|
+
|
|
4
|
+
//#region src/v2/runtime/handlers/handle-transcribe.ts
|
|
5
|
+
/**
|
|
6
|
+
* HTTP status codes for transcription error codes
|
|
7
|
+
*/
|
|
8
|
+
const ERROR_STATUS_CODES = {
|
|
9
|
+
[TranscriptionErrorCode.SERVICE_NOT_CONFIGURED]: 503,
|
|
10
|
+
[TranscriptionErrorCode.INVALID_AUDIO_FORMAT]: 400,
|
|
11
|
+
[TranscriptionErrorCode.AUDIO_TOO_LONG]: 400,
|
|
12
|
+
[TranscriptionErrorCode.AUDIO_TOO_SHORT]: 400,
|
|
13
|
+
[TranscriptionErrorCode.RATE_LIMITED]: 429,
|
|
14
|
+
[TranscriptionErrorCode.AUTH_FAILED]: 401,
|
|
15
|
+
[TranscriptionErrorCode.PROVIDER_ERROR]: 500,
|
|
16
|
+
[TranscriptionErrorCode.NETWORK_ERROR]: 502,
|
|
17
|
+
[TranscriptionErrorCode.INVALID_REQUEST]: 400
|
|
18
|
+
};
|
|
19
|
+
const VALID_AUDIO_TYPES = [
|
|
20
|
+
"audio/mpeg",
|
|
21
|
+
"audio/mp3",
|
|
22
|
+
"audio/mp4",
|
|
23
|
+
"audio/wav",
|
|
24
|
+
"audio/webm",
|
|
25
|
+
"audio/ogg",
|
|
26
|
+
"audio/flac",
|
|
27
|
+
"audio/aac"
|
|
28
|
+
];
|
|
29
|
+
function isValidAudioType(type) {
|
|
30
|
+
const baseType = type.split(";")[0]?.trim() ?? "";
|
|
31
|
+
return VALID_AUDIO_TYPES.includes(baseType) || baseType === "" || baseType === "application/octet-stream";
|
|
32
|
+
}
|
|
33
|
+
function createErrorResponse(errorResponse) {
|
|
34
|
+
const status = ERROR_STATUS_CODES[errorResponse.error] ?? 500;
|
|
35
|
+
return new Response(JSON.stringify(errorResponse), {
|
|
36
|
+
status,
|
|
37
|
+
headers: { "Content-Type": "application/json" }
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
function base64ToFile(base64, mimeType, filename) {
|
|
41
|
+
const base64Data = base64.includes(",") ? base64.split(",")[1] ?? base64 : base64;
|
|
42
|
+
const binaryString = atob(base64Data);
|
|
43
|
+
const bytes = new Uint8Array(binaryString.length);
|
|
44
|
+
for (let i = 0; i < binaryString.length; i++) bytes[i] = binaryString.charCodeAt(i);
|
|
45
|
+
return new File([bytes], filename, { type: mimeType });
|
|
46
|
+
}
|
|
47
|
+
async function extractAudioFromFormData(request) {
|
|
48
|
+
const audioFile = (await request.formData()).get("audio");
|
|
49
|
+
if (!audioFile || !(audioFile instanceof File)) return { error: createErrorResponse(TranscriptionErrors.invalidRequest("No audio file found in form data. Please include an 'audio' field.")) };
|
|
50
|
+
if (!isValidAudioType(audioFile.type)) return { error: createErrorResponse(TranscriptionErrors.invalidAudioFormat(audioFile.type, VALID_AUDIO_TYPES)) };
|
|
51
|
+
return { file: audioFile };
|
|
52
|
+
}
|
|
53
|
+
async function extractAudioFromJson(request) {
|
|
54
|
+
let body;
|
|
55
|
+
try {
|
|
56
|
+
body = await request.json();
|
|
57
|
+
} catch {
|
|
58
|
+
return { error: createErrorResponse(TranscriptionErrors.invalidRequest("Request body must be valid JSON")) };
|
|
59
|
+
}
|
|
60
|
+
if (!body.audio || typeof body.audio !== "string") return { error: createErrorResponse(TranscriptionErrors.invalidRequest("Request must include 'audio' field with base64-encoded audio data")) };
|
|
61
|
+
if (!body.mimeType || typeof body.mimeType !== "string") return { error: createErrorResponse(TranscriptionErrors.invalidRequest("Request must include 'mimeType' field (e.g., 'audio/webm')")) };
|
|
62
|
+
if (!isValidAudioType(body.mimeType)) return { error: createErrorResponse(TranscriptionErrors.invalidAudioFormat(body.mimeType, VALID_AUDIO_TYPES)) };
|
|
63
|
+
try {
|
|
64
|
+
const filename = body.filename || "recording.webm";
|
|
65
|
+
return { file: base64ToFile(body.audio, body.mimeType, filename) };
|
|
66
|
+
} catch {
|
|
67
|
+
return { error: createErrorResponse(TranscriptionErrors.invalidRequest("Failed to decode base64 audio data")) };
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Categorize provider errors into appropriate transcription error responses.
|
|
72
|
+
*/
|
|
73
|
+
function categorizeProviderError(error) {
|
|
74
|
+
const message = error instanceof Error ? error.message : "Unknown error occurred";
|
|
75
|
+
const errorStr = String(error).toLowerCase();
|
|
76
|
+
if (errorStr.includes("rate") || errorStr.includes("429") || errorStr.includes("too many")) return TranscriptionErrors.rateLimited();
|
|
77
|
+
if (errorStr.includes("auth") || errorStr.includes("401") || errorStr.includes("api key") || errorStr.includes("unauthorized")) return TranscriptionErrors.authFailed();
|
|
78
|
+
if (errorStr.includes("too long") || errorStr.includes("duration") || errorStr.includes("length")) return TranscriptionErrors.audioTooLong();
|
|
79
|
+
return TranscriptionErrors.providerError(message);
|
|
80
|
+
}
|
|
81
|
+
async function handleTranscribe({ runtime, request }) {
|
|
82
|
+
try {
|
|
83
|
+
if (!runtime.transcriptionService) return createErrorResponse(TranscriptionErrors.serviceNotConfigured());
|
|
84
|
+
const contentType = request.headers.get("content-type") || "";
|
|
85
|
+
let extractResult;
|
|
86
|
+
if (contentType.includes("multipart/form-data")) extractResult = await extractAudioFromFormData(request);
|
|
87
|
+
else if (contentType.includes("application/json")) extractResult = await extractAudioFromJson(request);
|
|
88
|
+
else return createErrorResponse(TranscriptionErrors.invalidRequest("Request must be multipart/form-data or application/json with base64 audio"));
|
|
89
|
+
if ("error" in extractResult) return extractResult.error;
|
|
90
|
+
const audioFile = extractResult.file;
|
|
91
|
+
const transcription = await runtime.transcriptionService.transcribeFile({
|
|
92
|
+
audioFile,
|
|
93
|
+
mimeType: audioFile.type,
|
|
94
|
+
size: audioFile.size
|
|
95
|
+
});
|
|
96
|
+
return new Response(JSON.stringify({
|
|
97
|
+
text: transcription,
|
|
98
|
+
size: audioFile.size,
|
|
99
|
+
type: audioFile.type
|
|
100
|
+
}), {
|
|
101
|
+
status: 200,
|
|
102
|
+
headers: { "Content-Type": "application/json" }
|
|
103
|
+
});
|
|
104
|
+
} catch (error) {
|
|
105
|
+
return createErrorResponse(categorizeProviderError(error));
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
//#endregion
|
|
110
|
+
export { handleTranscribe };
|
|
111
|
+
//# sourceMappingURL=handle-transcribe.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handle-transcribe.mjs","names":[],"sources":["../../../../src/v2/runtime/handlers/handle-transcribe.ts"],"sourcesContent":["import { CopilotRuntimeLike } from \"../runtime\";\nimport {\n TranscriptionErrorCode,\n TranscriptionErrors,\n type TranscriptionErrorResponse,\n} from \"@copilotkit/shared\";\n\n/**\n * HTTP status codes for transcription error codes\n */\nconst ERROR_STATUS_CODES: Record<TranscriptionErrorCode, number> = {\n [TranscriptionErrorCode.SERVICE_NOT_CONFIGURED]: 503,\n [TranscriptionErrorCode.INVALID_AUDIO_FORMAT]: 400,\n [TranscriptionErrorCode.AUDIO_TOO_LONG]: 400,\n [TranscriptionErrorCode.AUDIO_TOO_SHORT]: 400,\n [TranscriptionErrorCode.RATE_LIMITED]: 429,\n [TranscriptionErrorCode.AUTH_FAILED]: 401,\n [TranscriptionErrorCode.PROVIDER_ERROR]: 500,\n [TranscriptionErrorCode.NETWORK_ERROR]: 502,\n [TranscriptionErrorCode.INVALID_REQUEST]: 400,\n};\n\ninterface HandleTranscribeParameters {\n runtime: CopilotRuntimeLike;\n request: Request;\n}\n\ninterface Base64AudioInput {\n audio: string; // base64-encoded audio data\n mimeType: string;\n filename?: string;\n}\n\nconst VALID_AUDIO_TYPES = [\n \"audio/mpeg\",\n \"audio/mp3\",\n \"audio/mp4\",\n \"audio/wav\",\n \"audio/webm\",\n \"audio/ogg\",\n \"audio/flac\",\n \"audio/aac\",\n];\n\nfunction isValidAudioType(type: string): boolean {\n // Extract base MIME type (before semicolon) to handle types like \"audio/webm; codecs=opus\"\n const baseType = type.split(\";\")[0]?.trim() ?? \"\";\n return (\n VALID_AUDIO_TYPES.includes(baseType) ||\n baseType === \"\" ||\n baseType === \"application/octet-stream\"\n );\n}\n\nfunction createErrorResponse(\n errorResponse: TranscriptionErrorResponse,\n): Response {\n const status = ERROR_STATUS_CODES[errorResponse.error] ?? 500;\n return new Response(JSON.stringify(errorResponse), {\n status,\n headers: { \"Content-Type\": \"application/json\" },\n });\n}\n\nfunction base64ToFile(\n base64: string,\n mimeType: string,\n filename: string,\n): File {\n // Remove data URL prefix if present (e.g., \"data:audio/webm;base64,\")\n const base64Data = base64.includes(\",\")\n ? (base64.split(\",\")[1] ?? base64)\n : base64;\n\n // Decode base64 to binary\n const binaryString = atob(base64Data);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n\n // Create File object\n return new File([bytes], filename, { type: mimeType });\n}\n\nasync function extractAudioFromFormData(\n request: Request,\n): Promise<{ file: File } | { error: Response }> {\n const formData = await request.formData();\n const audioFile = formData.get(\"audio\") as File | null;\n\n if (!audioFile || !(audioFile instanceof File)) {\n const err = TranscriptionErrors.invalidRequest(\n \"No audio file found in form data. Please include an 'audio' field.\",\n );\n return { error: createErrorResponse(err) };\n }\n\n if (!isValidAudioType(audioFile.type)) {\n const err = TranscriptionErrors.invalidAudioFormat(\n audioFile.type,\n VALID_AUDIO_TYPES,\n );\n return { error: createErrorResponse(err) };\n }\n\n return { file: audioFile };\n}\n\nasync function extractAudioFromJson(\n request: Request,\n): Promise<{ file: File } | { error: Response }> {\n let body: Base64AudioInput;\n\n try {\n body = await request.json();\n } catch {\n const err = TranscriptionErrors.invalidRequest(\n \"Request body must be valid JSON\",\n );\n return { error: createErrorResponse(err) };\n }\n\n if (!body.audio || typeof body.audio !== \"string\") {\n const err = TranscriptionErrors.invalidRequest(\n \"Request must include 'audio' field with base64-encoded audio data\",\n );\n return { error: createErrorResponse(err) };\n }\n\n if (!body.mimeType || typeof body.mimeType !== \"string\") {\n const err = TranscriptionErrors.invalidRequest(\n \"Request must include 'mimeType' field (e.g., 'audio/webm')\",\n );\n return { error: createErrorResponse(err) };\n }\n\n if (!isValidAudioType(body.mimeType)) {\n const err = TranscriptionErrors.invalidAudioFormat(\n body.mimeType,\n VALID_AUDIO_TYPES,\n );\n return { error: createErrorResponse(err) };\n }\n\n try {\n const filename = body.filename || \"recording.webm\";\n const file = base64ToFile(body.audio, body.mimeType, filename);\n return { file };\n } catch {\n const err = TranscriptionErrors.invalidRequest(\n \"Failed to decode base64 audio data\",\n );\n return { error: createErrorResponse(err) };\n }\n}\n\n/**\n * Categorize provider errors into appropriate transcription error responses.\n */\nfunction categorizeProviderError(error: unknown): TranscriptionErrorResponse {\n const message =\n error instanceof Error ? error.message : \"Unknown error occurred\";\n const errorStr = String(error).toLowerCase();\n\n // Check for rate limiting\n if (\n errorStr.includes(\"rate\") ||\n errorStr.includes(\"429\") ||\n errorStr.includes(\"too many\")\n ) {\n return TranscriptionErrors.rateLimited();\n }\n\n // Check for auth errors\n if (\n errorStr.includes(\"auth\") ||\n errorStr.includes(\"401\") ||\n errorStr.includes(\"api key\") ||\n errorStr.includes(\"unauthorized\")\n ) {\n return TranscriptionErrors.authFailed();\n }\n\n // Check for audio too long\n if (\n errorStr.includes(\"too long\") ||\n errorStr.includes(\"duration\") ||\n errorStr.includes(\"length\")\n ) {\n return TranscriptionErrors.audioTooLong();\n }\n\n // Default to provider error\n return TranscriptionErrors.providerError(message);\n}\n\nexport async function handleTranscribe({\n runtime,\n request,\n}: HandleTranscribeParameters) {\n try {\n // Check if transcription service is configured\n if (!runtime.transcriptionService) {\n const err = TranscriptionErrors.serviceNotConfigured();\n return createErrorResponse(err);\n }\n\n // Determine input type based on content-type header\n const contentType = request.headers.get(\"content-type\") || \"\";\n\n let extractResult: { file: File } | { error: Response };\n\n if (contentType.includes(\"multipart/form-data\")) {\n // Handle multipart/form-data (REST mode)\n extractResult = await extractAudioFromFormData(request);\n } else if (contentType.includes(\"application/json\")) {\n // Handle JSON with base64 audio (single-endpoint mode)\n extractResult = await extractAudioFromJson(request);\n } else {\n const err = TranscriptionErrors.invalidRequest(\n \"Request must be multipart/form-data or application/json with base64 audio\",\n );\n return createErrorResponse(err);\n }\n\n // Check for extraction errors\n if (\"error\" in extractResult) {\n return extractResult.error;\n }\n\n const audioFile = extractResult.file;\n\n // Transcribe the audio file\n const transcription = await runtime.transcriptionService.transcribeFile({\n audioFile,\n mimeType: audioFile.type,\n size: audioFile.size,\n });\n\n return new Response(\n JSON.stringify({\n text: transcription,\n size: audioFile.size,\n type: audioFile.type,\n }),\n {\n status: 200,\n headers: { \"Content-Type\": \"application/json\" },\n },\n );\n } catch (error) {\n // Categorize the error for better client-side handling\n return createErrorResponse(categorizeProviderError(error));\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
require("reflect-metadata");
|
|
2
|
+
|
|
3
|
+
//#region src/v2/runtime/handlers/header-utils.ts
|
|
4
|
+
/**
|
|
5
|
+
* Determines if a header should be forwarded based on the allowlist.
|
|
6
|
+
* Forwards: authorization header and all x-* custom headers.
|
|
7
|
+
*/
|
|
8
|
+
function shouldForwardHeader(headerName) {
|
|
9
|
+
const lower = headerName.toLowerCase();
|
|
10
|
+
return lower === "authorization" || lower.startsWith("x-");
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Extracts headers that should be forwarded from a Request object.
|
|
14
|
+
* Forwards only authorization and x-* headers.
|
|
15
|
+
*/
|
|
16
|
+
function extractForwardableHeaders(request) {
|
|
17
|
+
const forwardableHeaders = {};
|
|
18
|
+
request.headers.forEach((value, key) => {
|
|
19
|
+
if (shouldForwardHeader(key)) forwardableHeaders[key] = value;
|
|
20
|
+
});
|
|
21
|
+
return forwardableHeaders;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
//#endregion
|
|
25
|
+
exports.extractForwardableHeaders = extractForwardableHeaders;
|
|
26
|
+
//# sourceMappingURL=header-utils.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"header-utils.cjs","names":[],"sources":["../../../../src/v2/runtime/handlers/header-utils.ts"],"sourcesContent":["/**\n * Determines if a header should be forwarded based on the allowlist.\n * Forwards: authorization header and all x-* custom headers.\n */\nexport function shouldForwardHeader(headerName: string): boolean {\n const lower = headerName.toLowerCase();\n return lower === \"authorization\" || lower.startsWith(\"x-\");\n}\n\n/**\n * Extracts headers that should be forwarded from a Request object.\n * Forwards only authorization and x-* headers.\n */\nexport function extractForwardableHeaders(\n request: Request,\n): Record<string, string> {\n const forwardableHeaders: Record<string, string> = {};\n request.headers.forEach((value, key) => {\n if (shouldForwardHeader(key)) {\n forwardableHeaders[key] = value;\n }\n });\n return forwardableHeaders;\n}\n"],"mappings":";;;;;;;AAIA,SAAgB,oBAAoB,YAA6B;CAC/D,MAAM,QAAQ,WAAW,aAAa;AACtC,QAAO,UAAU,mBAAmB,MAAM,WAAW,KAAK;;;;;;AAO5D,SAAgB,0BACd,SACwB;CACxB,MAAM,qBAA6C,EAAE;AACrD,SAAQ,QAAQ,SAAS,OAAO,QAAQ;AACtC,MAAI,oBAAoB,IAAI,CAC1B,oBAAmB,OAAO;GAE5B;AACF,QAAO"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import "reflect-metadata";
|
|
2
|
+
//#region src/v2/runtime/handlers/header-utils.ts
|
|
3
|
+
/**
|
|
4
|
+
* Determines if a header should be forwarded based on the allowlist.
|
|
5
|
+
* Forwards: authorization header and all x-* custom headers.
|
|
6
|
+
*/
|
|
7
|
+
function shouldForwardHeader(headerName) {
|
|
8
|
+
const lower = headerName.toLowerCase();
|
|
9
|
+
return lower === "authorization" || lower.startsWith("x-");
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Extracts headers that should be forwarded from a Request object.
|
|
13
|
+
* Forwards only authorization and x-* headers.
|
|
14
|
+
*/
|
|
15
|
+
function extractForwardableHeaders(request) {
|
|
16
|
+
const forwardableHeaders = {};
|
|
17
|
+
request.headers.forEach((value, key) => {
|
|
18
|
+
if (shouldForwardHeader(key)) forwardableHeaders[key] = value;
|
|
19
|
+
});
|
|
20
|
+
return forwardableHeaders;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
//#endregion
|
|
24
|
+
export { extractForwardableHeaders };
|
|
25
|
+
//# sourceMappingURL=header-utils.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"header-utils.mjs","names":[],"sources":["../../../../src/v2/runtime/handlers/header-utils.ts"],"sourcesContent":["/**\n * Determines if a header should be forwarded based on the allowlist.\n * Forwards: authorization header and all x-* custom headers.\n */\nexport function shouldForwardHeader(headerName: string): boolean {\n const lower = headerName.toLowerCase();\n return lower === \"authorization\" || lower.startsWith(\"x-\");\n}\n\n/**\n * Extracts headers that should be forwarded from a Request object.\n * Forwards only authorization and x-* headers.\n */\nexport function extractForwardableHeaders(\n request: Request,\n): Record<string, string> {\n const forwardableHeaders: Record<string, string> = {};\n request.headers.forEach((value, key) => {\n if (shouldForwardHeader(key)) {\n forwardableHeaders[key] = value;\n }\n });\n return forwardableHeaders;\n}\n"],"mappings":";;;;;;AAIA,SAAgB,oBAAoB,YAA6B;CAC/D,MAAM,QAAQ,WAAW,aAAa;AACtC,QAAO,UAAU,mBAAmB,MAAM,WAAW,KAAK;;;;;;AAO5D,SAAgB,0BACd,SACwB;CACxB,MAAM,qBAA6C,EAAE;AACrD,SAAQ,QAAQ,SAAS,OAAO,QAAQ;AACtC,MAAI,oBAAoB,IAAI,CAC1B,oBAAmB,OAAO;GAE5B;AACF,QAAO"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
require("reflect-metadata");
|
|
2
|
+
const require_json_response = require('../shared/json-response.cjs');
|
|
3
|
+
const require_intelligence_utils = require('../shared/intelligence-utils.cjs');
|
|
4
|
+
const require_resolve_intelligence_user = require('../shared/resolve-intelligence-user.cjs');
|
|
5
|
+
|
|
6
|
+
//#region src/v2/runtime/handlers/intelligence/connect.ts
|
|
7
|
+
async function handleIntelligenceConnect({ runtime, request, threadId, lastSeenEventId }) {
|
|
8
|
+
if (!runtime.intelligence) return Response.json({
|
|
9
|
+
error: "Intelligence not configured",
|
|
10
|
+
message: "Intelligence mode requires a CopilotKitIntelligence"
|
|
11
|
+
}, { status: 500 });
|
|
12
|
+
try {
|
|
13
|
+
const user = await require_resolve_intelligence_user.resolveIntelligenceUser({
|
|
14
|
+
runtime,
|
|
15
|
+
request
|
|
16
|
+
});
|
|
17
|
+
if (require_json_response.isHandlerResponse(user)) return user;
|
|
18
|
+
const result = await runtime.intelligence.ɵconnectThread({
|
|
19
|
+
threadId,
|
|
20
|
+
userId: user.id,
|
|
21
|
+
lastSeenEventId
|
|
22
|
+
});
|
|
23
|
+
if (result === null) return new Response(null, { status: 204 });
|
|
24
|
+
return Response.json(result, { headers: {
|
|
25
|
+
"Cache-Control": "no-cache",
|
|
26
|
+
Connection: "keep-alive"
|
|
27
|
+
} });
|
|
28
|
+
} catch (error) {
|
|
29
|
+
if (require_intelligence_utils.isPlatformNotFoundError(error)) return new Response(null, { status: 204 });
|
|
30
|
+
console.error("Connect plan not available:", error);
|
|
31
|
+
return Response.json({ error: "Connect plan not available" }, { status: 404 });
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
//#endregion
|
|
36
|
+
exports.handleIntelligenceConnect = handleIntelligenceConnect;
|
|
37
|
+
//# sourceMappingURL=connect.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connect.cjs","names":["resolveIntelligenceUser","isHandlerResponse","isPlatformNotFoundError"],"sources":["../../../../../src/v2/runtime/handlers/intelligence/connect.ts"],"sourcesContent":["import { CopilotIntelligenceRuntimeLike } from \"../../runtime\";\nimport { isPlatformNotFoundError } from \"../shared/intelligence-utils\";\nimport { resolveIntelligenceUser } from \"../shared/resolve-intelligence-user\";\nimport { isHandlerResponse } from \"../shared/json-response\";\n\ninterface HandleIntelligenceConnectParams {\n runtime: CopilotIntelligenceRuntimeLike;\n request: Request;\n threadId: string;\n lastSeenEventId: string | null;\n}\n\nexport async function handleIntelligenceConnect({\n runtime,\n request,\n threadId,\n lastSeenEventId,\n}: HandleIntelligenceConnectParams): Promise<Response> {\n if (!runtime.intelligence) {\n return Response.json(\n {\n error: \"Intelligence not configured\",\n message: \"Intelligence mode requires a CopilotKitIntelligence\",\n },\n { status: 500 },\n );\n }\n\n try {\n const user = await resolveIntelligenceUser({ runtime, request });\n if (isHandlerResponse(user)) {\n return user;\n }\n\n const result = await runtime.intelligence.ɵconnectThread({\n threadId,\n userId: user.id,\n lastSeenEventId,\n });\n\n if (result === null) {\n return new Response(null, {\n status: 204,\n });\n }\n\n return Response.json(result, {\n headers: { \"Cache-Control\": \"no-cache\", Connection: \"keep-alive\" },\n });\n } catch (error) {\n if (isPlatformNotFoundError(error)) {\n return new Response(null, {\n status: 204,\n });\n }\n\n console.error(\"Connect plan not available:\", error);\n return Response.json(\n {\n error: \"Connect plan not available\",\n },\n { status: 404 },\n );\n }\n}\n"],"mappings":";;;;;;AAYA,eAAsB,0BAA0B,EAC9C,SACA,SACA,UACA,mBACqD;AACrD,KAAI,CAAC,QAAQ,aACX,QAAO,SAAS,KACd;EACE,OAAO;EACP,SAAS;EACV,EACD,EAAE,QAAQ,KAAK,CAChB;AAGH,KAAI;EACF,MAAM,OAAO,MAAMA,0DAAwB;GAAE;GAAS;GAAS,CAAC;AAChE,MAAIC,wCAAkB,KAAK,CACzB,QAAO;EAGT,MAAM,SAAS,MAAM,QAAQ,aAAa,eAAe;GACvD;GACA,QAAQ,KAAK;GACb;GACD,CAAC;AAEF,MAAI,WAAW,KACb,QAAO,IAAI,SAAS,MAAM,EACxB,QAAQ,KACT,CAAC;AAGJ,SAAO,SAAS,KAAK,QAAQ,EAC3B,SAAS;GAAE,iBAAiB;GAAY,YAAY;GAAc,EACnE,CAAC;UACK,OAAO;AACd,MAAIC,mDAAwB,MAAM,CAChC,QAAO,IAAI,SAAS,MAAM,EACxB,QAAQ,KACT,CAAC;AAGJ,UAAQ,MAAM,+BAA+B,MAAM;AACnD,SAAO,SAAS,KACd,EACE,OAAO,8BACR,EACD,EAAE,QAAQ,KAAK,CAChB"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import "reflect-metadata";
|
|
2
|
+
import { isHandlerResponse } from "../shared/json-response.mjs";
|
|
3
|
+
import { isPlatformNotFoundError } from "../shared/intelligence-utils.mjs";
|
|
4
|
+
import { resolveIntelligenceUser } from "../shared/resolve-intelligence-user.mjs";
|
|
5
|
+
|
|
6
|
+
//#region src/v2/runtime/handlers/intelligence/connect.ts
|
|
7
|
+
async function handleIntelligenceConnect({ runtime, request, threadId, lastSeenEventId }) {
|
|
8
|
+
if (!runtime.intelligence) return Response.json({
|
|
9
|
+
error: "Intelligence not configured",
|
|
10
|
+
message: "Intelligence mode requires a CopilotKitIntelligence"
|
|
11
|
+
}, { status: 500 });
|
|
12
|
+
try {
|
|
13
|
+
const user = await resolveIntelligenceUser({
|
|
14
|
+
runtime,
|
|
15
|
+
request
|
|
16
|
+
});
|
|
17
|
+
if (isHandlerResponse(user)) return user;
|
|
18
|
+
const result = await runtime.intelligence.ɵconnectThread({
|
|
19
|
+
threadId,
|
|
20
|
+
userId: user.id,
|
|
21
|
+
lastSeenEventId
|
|
22
|
+
});
|
|
23
|
+
if (result === null) return new Response(null, { status: 204 });
|
|
24
|
+
return Response.json(result, { headers: {
|
|
25
|
+
"Cache-Control": "no-cache",
|
|
26
|
+
Connection: "keep-alive"
|
|
27
|
+
} });
|
|
28
|
+
} catch (error) {
|
|
29
|
+
if (isPlatformNotFoundError(error)) return new Response(null, { status: 204 });
|
|
30
|
+
console.error("Connect plan not available:", error);
|
|
31
|
+
return Response.json({ error: "Connect plan not available" }, { status: 404 });
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
//#endregion
|
|
36
|
+
export { handleIntelligenceConnect };
|
|
37
|
+
//# sourceMappingURL=connect.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connect.mjs","names":[],"sources":["../../../../../src/v2/runtime/handlers/intelligence/connect.ts"],"sourcesContent":["import { CopilotIntelligenceRuntimeLike } from \"../../runtime\";\nimport { isPlatformNotFoundError } from \"../shared/intelligence-utils\";\nimport { resolveIntelligenceUser } from \"../shared/resolve-intelligence-user\";\nimport { isHandlerResponse } from \"../shared/json-response\";\n\ninterface HandleIntelligenceConnectParams {\n runtime: CopilotIntelligenceRuntimeLike;\n request: Request;\n threadId: string;\n lastSeenEventId: string | null;\n}\n\nexport async function handleIntelligenceConnect({\n runtime,\n request,\n threadId,\n lastSeenEventId,\n}: HandleIntelligenceConnectParams): Promise<Response> {\n if (!runtime.intelligence) {\n return Response.json(\n {\n error: \"Intelligence not configured\",\n message: \"Intelligence mode requires a CopilotKitIntelligence\",\n },\n { status: 500 },\n );\n }\n\n try {\n const user = await resolveIntelligenceUser({ runtime, request });\n if (isHandlerResponse(user)) {\n return user;\n }\n\n const result = await runtime.intelligence.ɵconnectThread({\n threadId,\n userId: user.id,\n lastSeenEventId,\n });\n\n if (result === null) {\n return new Response(null, {\n status: 204,\n });\n }\n\n return Response.json(result, {\n headers: { \"Cache-Control\": \"no-cache\", Connection: \"keep-alive\" },\n });\n } catch (error) {\n if (isPlatformNotFoundError(error)) {\n return new Response(null, {\n status: 204,\n });\n }\n\n console.error(\"Connect plan not available:\", error);\n return Response.json(\n {\n error: \"Connect plan not available\",\n },\n { status: 404 },\n );\n }\n}\n"],"mappings":";;;;;;AAYA,eAAsB,0BAA0B,EAC9C,SACA,SACA,UACA,mBACqD;AACrD,KAAI,CAAC,QAAQ,aACX,QAAO,SAAS,KACd;EACE,OAAO;EACP,SAAS;EACV,EACD,EAAE,QAAQ,KAAK,CAChB;AAGH,KAAI;EACF,MAAM,OAAO,MAAM,wBAAwB;GAAE;GAAS;GAAS,CAAC;AAChE,MAAI,kBAAkB,KAAK,CACzB,QAAO;EAGT,MAAM,SAAS,MAAM,QAAQ,aAAa,eAAe;GACvD;GACA,QAAQ,KAAK;GACb;GACD,CAAC;AAEF,MAAI,WAAW,KACb,QAAO,IAAI,SAAS,MAAM,EACxB,QAAQ,KACT,CAAC;AAGJ,SAAO,SAAS,KAAK,QAAQ,EAC3B,SAAS;GAAE,iBAAiB;GAAY,YAAY;GAAc,EACnE,CAAC;UACK,OAAO;AACd,MAAI,wBAAwB,MAAM,CAChC,QAAO,IAAI,SAAS,MAAM,EACxB,QAAQ,KACT,CAAC;AAGJ,UAAQ,MAAM,+BAA+B,MAAM;AACnD,SAAO,SAAS,KACd,EACE,OAAO,8BACR,EACD,EAAE,QAAQ,KAAK,CAChB"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
require("reflect-metadata");
|
|
2
|
+
const require_runtime = require('../../../../_virtual/_rolldown/runtime.cjs');
|
|
3
|
+
const require_telemetry_client = require('../../telemetry/telemetry-client.cjs');
|
|
4
|
+
const require_json_response = require('../shared/json-response.cjs');
|
|
5
|
+
const require_thread_names = require('./thread-names.cjs');
|
|
6
|
+
const require_resolve_intelligence_user = require('../shared/resolve-intelligence-user.cjs');
|
|
7
|
+
let _copilotkit_shared = require("@copilotkit/shared");
|
|
8
|
+
|
|
9
|
+
//#region src/v2/runtime/handlers/intelligence/run.ts
|
|
10
|
+
async function handleIntelligenceRun({ runtime, request, agentId, agent, input }) {
|
|
11
|
+
if (!runtime.intelligence) return Response.json({
|
|
12
|
+
error: "Intelligence not configured",
|
|
13
|
+
message: "Intelligence mode requires a CopilotKitIntelligence"
|
|
14
|
+
}, { status: 500 });
|
|
15
|
+
const user = await require_resolve_intelligence_user.resolveIntelligenceUser({
|
|
16
|
+
runtime,
|
|
17
|
+
request
|
|
18
|
+
});
|
|
19
|
+
if (require_json_response.isHandlerResponse(user)) return user;
|
|
20
|
+
const userId = user.id;
|
|
21
|
+
try {
|
|
22
|
+
const { thread, created } = await runtime.intelligence.getOrCreateThread({
|
|
23
|
+
threadId: input.threadId,
|
|
24
|
+
userId,
|
|
25
|
+
agentId
|
|
26
|
+
});
|
|
27
|
+
if (created && runtime.generateThreadNames && !thread.name?.trim()) require_thread_names.generateThreadNameForNewThread({
|
|
28
|
+
runtime,
|
|
29
|
+
request,
|
|
30
|
+
agentId,
|
|
31
|
+
sourceInput: input,
|
|
32
|
+
thread,
|
|
33
|
+
userId
|
|
34
|
+
}).catch((nameError) => {
|
|
35
|
+
_copilotkit_shared.logger.error("Failed to generate thread name:", nameError);
|
|
36
|
+
});
|
|
37
|
+
} catch (error) {
|
|
38
|
+
_copilotkit_shared.logger.error("Failed to get or create thread:", error);
|
|
39
|
+
return Response.json({ error: "Failed to initialize thread" }, { status: 502 });
|
|
40
|
+
}
|
|
41
|
+
let joinCode;
|
|
42
|
+
let joinToken;
|
|
43
|
+
try {
|
|
44
|
+
const lockResult = await runtime.intelligence.ɵacquireThreadLock({
|
|
45
|
+
threadId: input.threadId,
|
|
46
|
+
runId: input.runId,
|
|
47
|
+
userId
|
|
48
|
+
});
|
|
49
|
+
joinToken = lockResult.joinToken;
|
|
50
|
+
joinCode = lockResult.joinCode;
|
|
51
|
+
} catch (error) {
|
|
52
|
+
_copilotkit_shared.logger.error("Thread lock denied:", error);
|
|
53
|
+
return Response.json({ error: "Thread lock denied" }, { status: 409 });
|
|
54
|
+
}
|
|
55
|
+
if (!joinToken) return Response.json({
|
|
56
|
+
error: "Join token not available",
|
|
57
|
+
message: "Intelligence platform did not return a join token"
|
|
58
|
+
}, { status: 502 });
|
|
59
|
+
let persistedInputMessages;
|
|
60
|
+
if (Array.isArray(input.messages)) try {
|
|
61
|
+
const history = await runtime.intelligence.getThreadMessages({ threadId: input.threadId });
|
|
62
|
+
const historicMessageIds = new Set(history.messages.map((message) => message.id));
|
|
63
|
+
persistedInputMessages = input.messages.filter((message) => !historicMessageIds.has(message.id));
|
|
64
|
+
} catch (error) {
|
|
65
|
+
_copilotkit_shared.logger.error("Thread history lookup failed:", error);
|
|
66
|
+
return Response.json({ error: "Thread history lookup failed" }, { status: 502 });
|
|
67
|
+
}
|
|
68
|
+
require_telemetry_client.default.capture("oss.runtime.agent_execution_stream_started", {});
|
|
69
|
+
runtime.runner.run({
|
|
70
|
+
threadId: input.threadId,
|
|
71
|
+
agent,
|
|
72
|
+
input,
|
|
73
|
+
...persistedInputMessages !== void 0 ? { persistedInputMessages } : {},
|
|
74
|
+
...joinCode ? { joinCode } : {}
|
|
75
|
+
}).subscribe({
|
|
76
|
+
error: (error) => {
|
|
77
|
+
require_telemetry_client.default.capture("oss.runtime.agent_execution_stream_errored", { error: error instanceof Error ? error.message : String(error) });
|
|
78
|
+
_copilotkit_shared.logger.error("Error running agent:", error);
|
|
79
|
+
},
|
|
80
|
+
complete: () => {
|
|
81
|
+
require_telemetry_client.default.capture("oss.runtime.agent_execution_stream_ended", {});
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
return Response.json({ joinToken }, { headers: { "Cache-Control": "no-cache" } });
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
//#endregion
|
|
88
|
+
exports.handleIntelligenceRun = handleIntelligenceRun;
|
|
89
|
+
//# sourceMappingURL=run.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.cjs","names":["resolveIntelligenceUser","isHandlerResponse","generateThreadNameForNewThread"],"sources":["../../../../../src/v2/runtime/handlers/intelligence/run.ts"],"sourcesContent":["import { AbstractAgent, Message, RunAgentInput } from \"@ag-ui/client\";\nimport { CopilotIntelligenceRuntimeLike } from \"../../runtime\";\nimport { generateThreadNameForNewThread } from \"./thread-names\";\nimport { logger } from \"@copilotkit/shared\";\nimport { telemetry } from \"../../telemetry\";\nimport { resolveIntelligenceUser } from \"../shared/resolve-intelligence-user\";\nimport { isHandlerResponse } from \"../shared/json-response\";\n\ninterface HandleIntelligenceRunParams {\n runtime: CopilotIntelligenceRuntimeLike;\n request: Request;\n agentId: string;\n agent: AbstractAgent;\n input: RunAgentInput;\n}\n\nexport async function handleIntelligenceRun({\n runtime,\n request,\n agentId,\n agent,\n input,\n}: HandleIntelligenceRunParams): Promise<Response> {\n if (!runtime.intelligence) {\n return Response.json(\n {\n error: \"Intelligence not configured\",\n message: \"Intelligence mode requires a CopilotKitIntelligence\",\n },\n { status: 500 },\n );\n }\n\n const user = await resolveIntelligenceUser({ runtime, request });\n if (isHandlerResponse(user)) {\n return user;\n }\n const userId = user.id;\n\n try {\n const { thread, created } = await runtime.intelligence.getOrCreateThread({\n threadId: input.threadId,\n userId,\n agentId,\n });\n\n if (created && runtime.generateThreadNames && !thread.name?.trim()) {\n void generateThreadNameForNewThread({\n runtime,\n request,\n agentId,\n sourceInput: input,\n thread,\n userId,\n }).catch((nameError) => {\n logger.error(\"Failed to generate thread name:\", nameError);\n });\n }\n } catch (error) {\n logger.error(\"Failed to get or create thread:\", error);\n return Response.json(\n {\n error: \"Failed to initialize thread\",\n },\n { status: 502 },\n );\n }\n\n let joinCode: string | undefined;\n let joinToken: string | undefined;\n try {\n const lockResult = await runtime.intelligence.ɵacquireThreadLock({\n threadId: input.threadId,\n runId: input.runId,\n userId,\n });\n joinToken = lockResult.joinToken;\n joinCode = lockResult.joinCode;\n } catch (error) {\n logger.error(\"Thread lock denied:\", error);\n return Response.json(\n {\n error: \"Thread lock denied\",\n },\n { status: 409 },\n );\n }\n\n if (!joinToken) {\n return Response.json(\n {\n error: \"Join token not available\",\n message: \"Intelligence platform did not return a join token\",\n },\n { status: 502 },\n );\n }\n\n let persistedInputMessages: Message[] | undefined;\n if (Array.isArray(input.messages)) {\n try {\n const history = await runtime.intelligence.getThreadMessages({\n threadId: input.threadId,\n });\n const historicMessageIds = new Set(\n history.messages.map((message) => message.id),\n );\n persistedInputMessages = input.messages.filter(\n (message) => !historicMessageIds.has(message.id),\n );\n } catch (error) {\n logger.error(\"Thread history lookup failed:\", error);\n return Response.json(\n {\n error: \"Thread history lookup failed\",\n },\n { status: 502 },\n );\n }\n }\n\n telemetry.capture(\"oss.runtime.agent_execution_stream_started\", {});\n\n runtime.runner\n .run({\n threadId: input.threadId,\n agent,\n input,\n ...(persistedInputMessages !== undefined\n ? { persistedInputMessages }\n : {}),\n ...(joinCode ? { joinCode } : {}),\n })\n .subscribe({\n error: (error) => {\n telemetry.capture(\"oss.runtime.agent_execution_stream_errored\", {\n error: error instanceof Error ? error.message : String(error),\n });\n logger.error(\"Error running agent:\", error);\n },\n complete: () => {\n telemetry.capture(\"oss.runtime.agent_execution_stream_ended\", {});\n },\n });\n\n return Response.json(\n { joinToken },\n {\n headers: { \"Cache-Control\": \"no-cache\" },\n },\n );\n}\n"],"mappings":";;;;;;;;;AAgBA,eAAsB,sBAAsB,EAC1C,SACA,SACA,SACA,OACA,SACiD;AACjD,KAAI,CAAC,QAAQ,aACX,QAAO,SAAS,KACd;EACE,OAAO;EACP,SAAS;EACV,EACD,EAAE,QAAQ,KAAK,CAChB;CAGH,MAAM,OAAO,MAAMA,0DAAwB;EAAE;EAAS;EAAS,CAAC;AAChE,KAAIC,wCAAkB,KAAK,CACzB,QAAO;CAET,MAAM,SAAS,KAAK;AAEpB,KAAI;EACF,MAAM,EAAE,QAAQ,YAAY,MAAM,QAAQ,aAAa,kBAAkB;GACvE,UAAU,MAAM;GAChB;GACA;GACD,CAAC;AAEF,MAAI,WAAW,QAAQ,uBAAuB,CAAC,OAAO,MAAM,MAAM,CAChE,CAAKC,oDAA+B;GAClC;GACA;GACA;GACA,aAAa;GACb;GACA;GACD,CAAC,CAAC,OAAO,cAAc;AACtB,6BAAO,MAAM,mCAAmC,UAAU;IAC1D;UAEG,OAAO;AACd,4BAAO,MAAM,mCAAmC,MAAM;AACtD,SAAO,SAAS,KACd,EACE,OAAO,+BACR,EACD,EAAE,QAAQ,KAAK,CAChB;;CAGH,IAAI;CACJ,IAAI;AACJ,KAAI;EACF,MAAM,aAAa,MAAM,QAAQ,aAAa,mBAAmB;GAC/D,UAAU,MAAM;GAChB,OAAO,MAAM;GACb;GACD,CAAC;AACF,cAAY,WAAW;AACvB,aAAW,WAAW;UACf,OAAO;AACd,4BAAO,MAAM,uBAAuB,MAAM;AAC1C,SAAO,SAAS,KACd,EACE,OAAO,sBACR,EACD,EAAE,QAAQ,KAAK,CAChB;;AAGH,KAAI,CAAC,UACH,QAAO,SAAS,KACd;EACE,OAAO;EACP,SAAS;EACV,EACD,EAAE,QAAQ,KAAK,CAChB;CAGH,IAAI;AACJ,KAAI,MAAM,QAAQ,MAAM,SAAS,CAC/B,KAAI;EACF,MAAM,UAAU,MAAM,QAAQ,aAAa,kBAAkB,EAC3D,UAAU,MAAM,UACjB,CAAC;EACF,MAAM,qBAAqB,IAAI,IAC7B,QAAQ,SAAS,KAAK,YAAY,QAAQ,GAAG,CAC9C;AACD,2BAAyB,MAAM,SAAS,QACrC,YAAY,CAAC,mBAAmB,IAAI,QAAQ,GAAG,CACjD;UACM,OAAO;AACd,4BAAO,MAAM,iCAAiC,MAAM;AACpD,SAAO,SAAS,KACd,EACE,OAAO,gCACR,EACD,EAAE,QAAQ,KAAK,CAChB;;AAIL,kCAAU,QAAQ,8CAA8C,EAAE,CAAC;AAEnE,SAAQ,OACL,IAAI;EACH,UAAU,MAAM;EAChB;EACA;EACA,GAAI,2BAA2B,SAC3B,EAAE,wBAAwB,GAC1B,EAAE;EACN,GAAI,WAAW,EAAE,UAAU,GAAG,EAAE;EACjC,CAAC,CACD,UAAU;EACT,QAAQ,UAAU;AAChB,oCAAU,QAAQ,8CAA8C,EAC9D,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,EAC9D,CAAC;AACF,6BAAO,MAAM,wBAAwB,MAAM;;EAE7C,gBAAgB;AACd,oCAAU,QAAQ,4CAA4C,EAAE,CAAC;;EAEpE,CAAC;AAEJ,QAAO,SAAS,KACd,EAAE,WAAW,EACb,EACE,SAAS,EAAE,iBAAiB,YAAY,EACzC,CACF"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import "reflect-metadata";
|
|
2
|
+
import telemetry from "../../telemetry/telemetry-client.mjs";
|
|
3
|
+
import { isHandlerResponse } from "../shared/json-response.mjs";
|
|
4
|
+
import { generateThreadNameForNewThread } from "./thread-names.mjs";
|
|
5
|
+
import { resolveIntelligenceUser } from "../shared/resolve-intelligence-user.mjs";
|
|
6
|
+
import { logger } from "@copilotkit/shared";
|
|
7
|
+
|
|
8
|
+
//#region src/v2/runtime/handlers/intelligence/run.ts
|
|
9
|
+
async function handleIntelligenceRun({ runtime, request, agentId, agent, input }) {
|
|
10
|
+
if (!runtime.intelligence) return Response.json({
|
|
11
|
+
error: "Intelligence not configured",
|
|
12
|
+
message: "Intelligence mode requires a CopilotKitIntelligence"
|
|
13
|
+
}, { status: 500 });
|
|
14
|
+
const user = await resolveIntelligenceUser({
|
|
15
|
+
runtime,
|
|
16
|
+
request
|
|
17
|
+
});
|
|
18
|
+
if (isHandlerResponse(user)) return user;
|
|
19
|
+
const userId = user.id;
|
|
20
|
+
try {
|
|
21
|
+
const { thread, created } = await runtime.intelligence.getOrCreateThread({
|
|
22
|
+
threadId: input.threadId,
|
|
23
|
+
userId,
|
|
24
|
+
agentId
|
|
25
|
+
});
|
|
26
|
+
if (created && runtime.generateThreadNames && !thread.name?.trim()) generateThreadNameForNewThread({
|
|
27
|
+
runtime,
|
|
28
|
+
request,
|
|
29
|
+
agentId,
|
|
30
|
+
sourceInput: input,
|
|
31
|
+
thread,
|
|
32
|
+
userId
|
|
33
|
+
}).catch((nameError) => {
|
|
34
|
+
logger.error("Failed to generate thread name:", nameError);
|
|
35
|
+
});
|
|
36
|
+
} catch (error) {
|
|
37
|
+
logger.error("Failed to get or create thread:", error);
|
|
38
|
+
return Response.json({ error: "Failed to initialize thread" }, { status: 502 });
|
|
39
|
+
}
|
|
40
|
+
let joinCode;
|
|
41
|
+
let joinToken;
|
|
42
|
+
try {
|
|
43
|
+
const lockResult = await runtime.intelligence.ɵacquireThreadLock({
|
|
44
|
+
threadId: input.threadId,
|
|
45
|
+
runId: input.runId,
|
|
46
|
+
userId
|
|
47
|
+
});
|
|
48
|
+
joinToken = lockResult.joinToken;
|
|
49
|
+
joinCode = lockResult.joinCode;
|
|
50
|
+
} catch (error) {
|
|
51
|
+
logger.error("Thread lock denied:", error);
|
|
52
|
+
return Response.json({ error: "Thread lock denied" }, { status: 409 });
|
|
53
|
+
}
|
|
54
|
+
if (!joinToken) return Response.json({
|
|
55
|
+
error: "Join token not available",
|
|
56
|
+
message: "Intelligence platform did not return a join token"
|
|
57
|
+
}, { status: 502 });
|
|
58
|
+
let persistedInputMessages;
|
|
59
|
+
if (Array.isArray(input.messages)) try {
|
|
60
|
+
const history = await runtime.intelligence.getThreadMessages({ threadId: input.threadId });
|
|
61
|
+
const historicMessageIds = new Set(history.messages.map((message) => message.id));
|
|
62
|
+
persistedInputMessages = input.messages.filter((message) => !historicMessageIds.has(message.id));
|
|
63
|
+
} catch (error) {
|
|
64
|
+
logger.error("Thread history lookup failed:", error);
|
|
65
|
+
return Response.json({ error: "Thread history lookup failed" }, { status: 502 });
|
|
66
|
+
}
|
|
67
|
+
telemetry.capture("oss.runtime.agent_execution_stream_started", {});
|
|
68
|
+
runtime.runner.run({
|
|
69
|
+
threadId: input.threadId,
|
|
70
|
+
agent,
|
|
71
|
+
input,
|
|
72
|
+
...persistedInputMessages !== void 0 ? { persistedInputMessages } : {},
|
|
73
|
+
...joinCode ? { joinCode } : {}
|
|
74
|
+
}).subscribe({
|
|
75
|
+
error: (error) => {
|
|
76
|
+
telemetry.capture("oss.runtime.agent_execution_stream_errored", { error: error instanceof Error ? error.message : String(error) });
|
|
77
|
+
logger.error("Error running agent:", error);
|
|
78
|
+
},
|
|
79
|
+
complete: () => {
|
|
80
|
+
telemetry.capture("oss.runtime.agent_execution_stream_ended", {});
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
return Response.json({ joinToken }, { headers: { "Cache-Control": "no-cache" } });
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
//#endregion
|
|
87
|
+
export { handleIntelligenceRun };
|
|
88
|
+
//# sourceMappingURL=run.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.mjs","names":[],"sources":["../../../../../src/v2/runtime/handlers/intelligence/run.ts"],"sourcesContent":["import { AbstractAgent, Message, RunAgentInput } from \"@ag-ui/client\";\nimport { CopilotIntelligenceRuntimeLike } from \"../../runtime\";\nimport { generateThreadNameForNewThread } from \"./thread-names\";\nimport { logger } from \"@copilotkit/shared\";\nimport { telemetry } from \"../../telemetry\";\nimport { resolveIntelligenceUser } from \"../shared/resolve-intelligence-user\";\nimport { isHandlerResponse } from \"../shared/json-response\";\n\ninterface HandleIntelligenceRunParams {\n runtime: CopilotIntelligenceRuntimeLike;\n request: Request;\n agentId: string;\n agent: AbstractAgent;\n input: RunAgentInput;\n}\n\nexport async function handleIntelligenceRun({\n runtime,\n request,\n agentId,\n agent,\n input,\n}: HandleIntelligenceRunParams): Promise<Response> {\n if (!runtime.intelligence) {\n return Response.json(\n {\n error: \"Intelligence not configured\",\n message: \"Intelligence mode requires a CopilotKitIntelligence\",\n },\n { status: 500 },\n );\n }\n\n const user = await resolveIntelligenceUser({ runtime, request });\n if (isHandlerResponse(user)) {\n return user;\n }\n const userId = user.id;\n\n try {\n const { thread, created } = await runtime.intelligence.getOrCreateThread({\n threadId: input.threadId,\n userId,\n agentId,\n });\n\n if (created && runtime.generateThreadNames && !thread.name?.trim()) {\n void generateThreadNameForNewThread({\n runtime,\n request,\n agentId,\n sourceInput: input,\n thread,\n userId,\n }).catch((nameError) => {\n logger.error(\"Failed to generate thread name:\", nameError);\n });\n }\n } catch (error) {\n logger.error(\"Failed to get or create thread:\", error);\n return Response.json(\n {\n error: \"Failed to initialize thread\",\n },\n { status: 502 },\n );\n }\n\n let joinCode: string | undefined;\n let joinToken: string | undefined;\n try {\n const lockResult = await runtime.intelligence.ɵacquireThreadLock({\n threadId: input.threadId,\n runId: input.runId,\n userId,\n });\n joinToken = lockResult.joinToken;\n joinCode = lockResult.joinCode;\n } catch (error) {\n logger.error(\"Thread lock denied:\", error);\n return Response.json(\n {\n error: \"Thread lock denied\",\n },\n { status: 409 },\n );\n }\n\n if (!joinToken) {\n return Response.json(\n {\n error: \"Join token not available\",\n message: \"Intelligence platform did not return a join token\",\n },\n { status: 502 },\n );\n }\n\n let persistedInputMessages: Message[] | undefined;\n if (Array.isArray(input.messages)) {\n try {\n const history = await runtime.intelligence.getThreadMessages({\n threadId: input.threadId,\n });\n const historicMessageIds = new Set(\n history.messages.map((message) => message.id),\n );\n persistedInputMessages = input.messages.filter(\n (message) => !historicMessageIds.has(message.id),\n );\n } catch (error) {\n logger.error(\"Thread history lookup failed:\", error);\n return Response.json(\n {\n error: \"Thread history lookup failed\",\n },\n { status: 502 },\n );\n }\n }\n\n telemetry.capture(\"oss.runtime.agent_execution_stream_started\", {});\n\n runtime.runner\n .run({\n threadId: input.threadId,\n agent,\n input,\n ...(persistedInputMessages !== undefined\n ? { persistedInputMessages }\n : {}),\n ...(joinCode ? { joinCode } : {}),\n })\n .subscribe({\n error: (error) => {\n telemetry.capture(\"oss.runtime.agent_execution_stream_errored\", {\n error: error instanceof Error ? error.message : String(error),\n });\n logger.error(\"Error running agent:\", error);\n },\n complete: () => {\n telemetry.capture(\"oss.runtime.agent_execution_stream_ended\", {});\n },\n });\n\n return Response.json(\n { joinToken },\n {\n headers: { \"Cache-Control\": \"no-cache\" },\n },\n );\n}\n"],"mappings":";;;;;;;;AAgBA,eAAsB,sBAAsB,EAC1C,SACA,SACA,SACA,OACA,SACiD;AACjD,KAAI,CAAC,QAAQ,aACX,QAAO,SAAS,KACd;EACE,OAAO;EACP,SAAS;EACV,EACD,EAAE,QAAQ,KAAK,CAChB;CAGH,MAAM,OAAO,MAAM,wBAAwB;EAAE;EAAS;EAAS,CAAC;AAChE,KAAI,kBAAkB,KAAK,CACzB,QAAO;CAET,MAAM,SAAS,KAAK;AAEpB,KAAI;EACF,MAAM,EAAE,QAAQ,YAAY,MAAM,QAAQ,aAAa,kBAAkB;GACvE,UAAU,MAAM;GAChB;GACA;GACD,CAAC;AAEF,MAAI,WAAW,QAAQ,uBAAuB,CAAC,OAAO,MAAM,MAAM,CAChE,CAAK,+BAA+B;GAClC;GACA;GACA;GACA,aAAa;GACb;GACA;GACD,CAAC,CAAC,OAAO,cAAc;AACtB,UAAO,MAAM,mCAAmC,UAAU;IAC1D;UAEG,OAAO;AACd,SAAO,MAAM,mCAAmC,MAAM;AACtD,SAAO,SAAS,KACd,EACE,OAAO,+BACR,EACD,EAAE,QAAQ,KAAK,CAChB;;CAGH,IAAI;CACJ,IAAI;AACJ,KAAI;EACF,MAAM,aAAa,MAAM,QAAQ,aAAa,mBAAmB;GAC/D,UAAU,MAAM;GAChB,OAAO,MAAM;GACb;GACD,CAAC;AACF,cAAY,WAAW;AACvB,aAAW,WAAW;UACf,OAAO;AACd,SAAO,MAAM,uBAAuB,MAAM;AAC1C,SAAO,SAAS,KACd,EACE,OAAO,sBACR,EACD,EAAE,QAAQ,KAAK,CAChB;;AAGH,KAAI,CAAC,UACH,QAAO,SAAS,KACd;EACE,OAAO;EACP,SAAS;EACV,EACD,EAAE,QAAQ,KAAK,CAChB;CAGH,IAAI;AACJ,KAAI,MAAM,QAAQ,MAAM,SAAS,CAC/B,KAAI;EACF,MAAM,UAAU,MAAM,QAAQ,aAAa,kBAAkB,EAC3D,UAAU,MAAM,UACjB,CAAC;EACF,MAAM,qBAAqB,IAAI,IAC7B,QAAQ,SAAS,KAAK,YAAY,QAAQ,GAAG,CAC9C;AACD,2BAAyB,MAAM,SAAS,QACrC,YAAY,CAAC,mBAAmB,IAAI,QAAQ,GAAG,CACjD;UACM,OAAO;AACd,SAAO,MAAM,iCAAiC,MAAM;AACpD,SAAO,SAAS,KACd,EACE,OAAO,gCACR,EACD,EAAE,QAAQ,KAAK,CAChB;;AAIL,WAAU,QAAQ,8CAA8C,EAAE,CAAC;AAEnE,SAAQ,OACL,IAAI;EACH,UAAU,MAAM;EAChB;EACA;EACA,GAAI,2BAA2B,SAC3B,EAAE,wBAAwB,GAC1B,EAAE;EACN,GAAI,WAAW,EAAE,UAAU,GAAG,EAAE;EACjC,CAAC,CACD,UAAU;EACT,QAAQ,UAAU;AAChB,aAAU,QAAQ,8CAA8C,EAC9D,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,EAC9D,CAAC;AACF,UAAO,MAAM,wBAAwB,MAAM;;EAE7C,gBAAgB;AACd,aAAU,QAAQ,4CAA4C,EAAE,CAAC;;EAEpE,CAAC;AAEJ,QAAO,SAAS,KACd,EAAE,WAAW,EACb,EACE,SAAS,EAAE,iBAAiB,YAAY,EACzC,CACF"}
|