@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,123 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from "vitest";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
CopilotIntelligenceRuntime,
|
|
5
|
+
CopilotRuntime,
|
|
6
|
+
CopilotSseRuntime,
|
|
7
|
+
} from "../runtime";
|
|
8
|
+
import type { CopilotKitIntelligence } from "../intelligence-platform";
|
|
9
|
+
import { InMemoryAgentRunner } from "../runner/in-memory";
|
|
10
|
+
import { IntelligenceAgentRunner } from "../runner/intelligence";
|
|
11
|
+
|
|
12
|
+
describe("runtime construction", () => {
|
|
13
|
+
const agents = {};
|
|
14
|
+
const identifyUser = vi.fn().mockResolvedValue({ id: "user-1" });
|
|
15
|
+
const createMockIntelligence = (): CopilotKitIntelligence =>
|
|
16
|
+
({
|
|
17
|
+
ɵgetRunnerWsUrl: vi.fn().mockReturnValue("ws://runner.example"),
|
|
18
|
+
ɵgetRunnerAuthToken: vi.fn().mockReturnValue("token-123"),
|
|
19
|
+
ɵgetClientWsUrl: vi.fn().mockReturnValue("ws://client.example"),
|
|
20
|
+
}) as unknown as CopilotKitIntelligence;
|
|
21
|
+
|
|
22
|
+
it("builds an SSE runtime by default", () => {
|
|
23
|
+
const runtime = new CopilotSseRuntime({ agents });
|
|
24
|
+
|
|
25
|
+
expect(runtime.mode).toBe("sse");
|
|
26
|
+
|
|
27
|
+
expect(runtime.runner).toBeInstanceOf(InMemoryAgentRunner);
|
|
28
|
+
expect(runtime.intelligence).toBeUndefined();
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it("builds an Intelligence runtime with an Intelligence runner", () => {
|
|
32
|
+
const sdk = createMockIntelligence();
|
|
33
|
+
|
|
34
|
+
const runtime = new CopilotIntelligenceRuntime({
|
|
35
|
+
agents,
|
|
36
|
+
intelligence: sdk,
|
|
37
|
+
identifyUser,
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
expect(runtime.mode).toBe("intelligence");
|
|
41
|
+
|
|
42
|
+
expect(runtime.intelligence).toBe(sdk);
|
|
43
|
+
expect(runtime.runner).toBeInstanceOf(IntelligenceAgentRunner);
|
|
44
|
+
expect(runtime.generateThreadNames).toBe(true);
|
|
45
|
+
expect(runtime.identifyUser).toBe(identifyUser);
|
|
46
|
+
expect(sdk.ɵgetRunnerWsUrl).toHaveBeenCalledTimes(1);
|
|
47
|
+
expect(sdk.ɵgetRunnerAuthToken).toHaveBeenCalledTimes(1);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it("preserves an explicit generateThreadNames=false option in Intelligence mode", () => {
|
|
51
|
+
const sdk = createMockIntelligence();
|
|
52
|
+
|
|
53
|
+
const runtime = new CopilotIntelligenceRuntime({
|
|
54
|
+
agents,
|
|
55
|
+
intelligence: sdk,
|
|
56
|
+
identifyUser,
|
|
57
|
+
generateThreadNames: false,
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
expect(runtime.generateThreadNames).toBe(false);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it("keeps CopilotRuntime as an SSE shim when no CopilotKitIntelligence is provided", () => {
|
|
64
|
+
const runtime = new CopilotRuntime({ agents });
|
|
65
|
+
|
|
66
|
+
expect(runtime.mode).toBe("sse");
|
|
67
|
+
|
|
68
|
+
expect(runtime.runner).toBeInstanceOf(InMemoryAgentRunner);
|
|
69
|
+
expect(runtime.intelligence).toBeUndefined();
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it("keeps CopilotRuntime as an Intelligence shim when CopilotKitIntelligence is provided", () => {
|
|
73
|
+
const sdk = createMockIntelligence();
|
|
74
|
+
|
|
75
|
+
const runtime = new CopilotRuntime({
|
|
76
|
+
agents,
|
|
77
|
+
intelligence: sdk,
|
|
78
|
+
identifyUser,
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
expect(runtime.mode).toBe("intelligence");
|
|
82
|
+
|
|
83
|
+
expect(runtime.intelligence).toBe(sdk);
|
|
84
|
+
expect(runtime.runner).toBeInstanceOf(IntelligenceAgentRunner);
|
|
85
|
+
expect(
|
|
86
|
+
(runtime as CopilotRuntime & { generateThreadNames?: boolean })
|
|
87
|
+
.generateThreadNames,
|
|
88
|
+
).toBe(true);
|
|
89
|
+
expect(
|
|
90
|
+
(
|
|
91
|
+
runtime as CopilotRuntime & {
|
|
92
|
+
identifyUser?: typeof identifyUser;
|
|
93
|
+
}
|
|
94
|
+
).identifyUser,
|
|
95
|
+
).toBe(identifyUser);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it("forwards generateThreadNames=false through the CopilotRuntime intelligence shim", () => {
|
|
99
|
+
const sdk = createMockIntelligence();
|
|
100
|
+
|
|
101
|
+
const runtime = new CopilotRuntime({
|
|
102
|
+
agents,
|
|
103
|
+
intelligence: sdk,
|
|
104
|
+
identifyUser,
|
|
105
|
+
generateThreadNames: false,
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
expect(runtime.mode).toBe("intelligence");
|
|
109
|
+
expect(
|
|
110
|
+
(runtime as CopilotRuntime & { generateThreadNames?: boolean })
|
|
111
|
+
.generateThreadNames,
|
|
112
|
+
).toBe(false);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it("exposes identifyUser as undefined for SSE runtimes", () => {
|
|
116
|
+
const runtime = new CopilotRuntime({ agents });
|
|
117
|
+
|
|
118
|
+
expect(
|
|
119
|
+
(runtime as CopilotRuntime & { identifyUser?: typeof identifyUser })
|
|
120
|
+
.identifyUser,
|
|
121
|
+
).toBeUndefined();
|
|
122
|
+
});
|
|
123
|
+
});
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
|
2
|
+
import { TelemetryClient } from "../telemetry/telemetry-client";
|
|
3
|
+
import scarfClient from "../telemetry/scarf-client";
|
|
4
|
+
|
|
5
|
+
describe("TelemetryClient", () => {
|
|
6
|
+
let scarfSpy: ReturnType<typeof vi.spyOn>;
|
|
7
|
+
|
|
8
|
+
beforeEach(() => {
|
|
9
|
+
scarfSpy = vi.spyOn(scarfClient, "logEvent").mockResolvedValue(undefined);
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
afterEach(() => {
|
|
13
|
+
vi.restoreAllMocks();
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it("sends event to scarf when sampled in", async () => {
|
|
17
|
+
vi.spyOn(Math, "random").mockReturnValue(0);
|
|
18
|
+
const client = new TelemetryClient({
|
|
19
|
+
telemetryDisabled: false,
|
|
20
|
+
sampleRate: 1,
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
await client.capture("oss.runtime.instance_created", {
|
|
24
|
+
actionsAmount: 0,
|
|
25
|
+
endpointTypes: [],
|
|
26
|
+
endpointsAmount: 0,
|
|
27
|
+
"cloud.api_key_provided": false,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
expect(scarfSpy).toHaveBeenCalledWith({
|
|
31
|
+
event: "oss.runtime.instance_created",
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it("only sends event name to scarf, not properties", async () => {
|
|
36
|
+
const client = new TelemetryClient({
|
|
37
|
+
telemetryDisabled: false,
|
|
38
|
+
sampleRate: 1,
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
await client.capture("oss.runtime.copilot_request_created", {
|
|
42
|
+
"cloud.guardrails.enabled": true,
|
|
43
|
+
requestType: "run",
|
|
44
|
+
"cloud.api_key_provided": true,
|
|
45
|
+
"cloud.public_api_key": "pk_test_123",
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
expect(scarfSpy).toHaveBeenCalledWith({
|
|
49
|
+
event: "oss.runtime.copilot_request_created",
|
|
50
|
+
});
|
|
51
|
+
// Properties should NOT be forwarded to scarf
|
|
52
|
+
const callArg = scarfSpy.mock.calls[0][0];
|
|
53
|
+
expect(Object.keys(callArg)).toEqual(["event"]);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it("does not send events when telemetryDisabled is true", async () => {
|
|
57
|
+
const client = new TelemetryClient({
|
|
58
|
+
telemetryDisabled: true,
|
|
59
|
+
sampleRate: 1,
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
await client.capture("oss.runtime.instance_created", {
|
|
63
|
+
actionsAmount: 0,
|
|
64
|
+
endpointTypes: [],
|
|
65
|
+
endpointsAmount: 0,
|
|
66
|
+
"cloud.api_key_provided": false,
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
expect(scarfSpy).not.toHaveBeenCalled();
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it("does not send events when sampled out", async () => {
|
|
73
|
+
vi.spyOn(Math, "random").mockReturnValue(0.99);
|
|
74
|
+
const client = new TelemetryClient({
|
|
75
|
+
telemetryDisabled: false,
|
|
76
|
+
sampleRate: 0.05,
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
await client.capture("oss.runtime.instance_created", {
|
|
80
|
+
actionsAmount: 0,
|
|
81
|
+
endpointTypes: [],
|
|
82
|
+
endpointsAmount: 0,
|
|
83
|
+
"cloud.api_key_provided": false,
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
expect(scarfSpy).not.toHaveBeenCalled();
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it("respects sample rate boundary", async () => {
|
|
90
|
+
vi.spyOn(Math, "random").mockReturnValue(0.04);
|
|
91
|
+
const client = new TelemetryClient({
|
|
92
|
+
telemetryDisabled: false,
|
|
93
|
+
sampleRate: 0.05,
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
await client.capture("oss.runtime.agent_execution_stream_started", {});
|
|
97
|
+
|
|
98
|
+
expect(scarfSpy).toHaveBeenCalled();
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it("throws when sample rate is out of range", () => {
|
|
102
|
+
expect(() => new TelemetryClient({ sampleRate: 1.5 })).toThrow(
|
|
103
|
+
"Sample rate must be between 0 and 1",
|
|
104
|
+
);
|
|
105
|
+
expect(() => new TelemetryClient({ sampleRate: -0.1 })).toThrow(
|
|
106
|
+
"Sample rate must be between 0 and 1",
|
|
107
|
+
);
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
describe("ScarfClient", () => {
|
|
112
|
+
let originalFetch: typeof fetch;
|
|
113
|
+
let fetchMock: ReturnType<typeof vi.fn>;
|
|
114
|
+
|
|
115
|
+
beforeEach(() => {
|
|
116
|
+
originalFetch = global.fetch;
|
|
117
|
+
fetchMock = vi.fn().mockResolvedValue(new Response("", { status: 200 }));
|
|
118
|
+
global.fetch = fetchMock as unknown as typeof fetch;
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
afterEach(() => {
|
|
122
|
+
global.fetch = originalFetch;
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it("sends GET request to scarf gateway with event as query param", async () => {
|
|
126
|
+
await scarfClient.logEvent({ event: "oss.runtime.instance_created" });
|
|
127
|
+
|
|
128
|
+
expect(fetchMock).toHaveBeenCalledTimes(1);
|
|
129
|
+
const [url, options] = fetchMock.mock.calls[0];
|
|
130
|
+
expect(url).toContain("https://copilotkit.gateway.scarf.sh/");
|
|
131
|
+
expect(url).toContain("event=oss.runtime.instance_created");
|
|
132
|
+
expect(options.method).toBe("GET");
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it("silently fails on network error", async () => {
|
|
136
|
+
fetchMock.mockRejectedValue(new Error("Network error"));
|
|
137
|
+
|
|
138
|
+
// Should not throw
|
|
139
|
+
await expect(
|
|
140
|
+
scarfClient.logEvent({ event: "oss.runtime.instance_created" }),
|
|
141
|
+
).resolves.toBeUndefined();
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
it("silently fails on non-ok response", async () => {
|
|
145
|
+
fetchMock.mockResolvedValue(new Response("", { status: 500 }));
|
|
146
|
+
|
|
147
|
+
// Should not throw
|
|
148
|
+
await expect(
|
|
149
|
+
scarfClient.logEvent({ event: "oss.runtime.instance_created" }),
|
|
150
|
+
).resolves.toBeUndefined();
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
it("skips null and undefined values in query params", async () => {
|
|
154
|
+
await scarfClient.logEvent({
|
|
155
|
+
event: "oss.runtime.instance_created",
|
|
156
|
+
nullVal: null,
|
|
157
|
+
undefinedVal: undefined,
|
|
158
|
+
validVal: "test",
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
const url = fetchMock.mock.calls[0][0] as string;
|
|
162
|
+
expect(url).toContain("event=oss.runtime.instance_created");
|
|
163
|
+
expect(url).toContain("validVal=test");
|
|
164
|
+
expect(url).not.toContain("nullVal");
|
|
165
|
+
expect(url).not.toContain("undefinedVal");
|
|
166
|
+
});
|
|
167
|
+
});
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import type { Message } from "@ag-ui/client";
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
ɵnormalizeGeneratedTitle as normalizeGeneratedTitle,
|
|
6
|
+
ɵbuildThreadTitlePrompt as buildThreadTitlePrompt,
|
|
7
|
+
ɵhasThreadName as hasThreadName,
|
|
8
|
+
} from "../handlers/intelligence/thread-names";
|
|
9
|
+
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
// normalizeGeneratedTitle
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
|
|
14
|
+
describe("normalizeGeneratedTitle", () => {
|
|
15
|
+
it("extracts title from valid JSON response", () => {
|
|
16
|
+
expect(normalizeGeneratedTitle('{"title":"Budget Review"}')).toBe(
|
|
17
|
+
"Budget Review",
|
|
18
|
+
);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it("extracts title from JSON wrapped in code fences", () => {
|
|
22
|
+
expect(
|
|
23
|
+
normalizeGeneratedTitle('```json\n{"title":"Budget Review"}\n```'),
|
|
24
|
+
).toBe("Budget Review");
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it("strips surrounding quotes from plain text", () => {
|
|
28
|
+
expect(normalizeGeneratedTitle('"Budget Review"')).toBe("Budget Review");
|
|
29
|
+
expect(normalizeGeneratedTitle("'Budget Review'")).toBe("Budget Review");
|
|
30
|
+
expect(normalizeGeneratedTitle("`Budget Review`")).toBe("Budget Review");
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it("strips markdown characters", () => {
|
|
34
|
+
expect(normalizeGeneratedTitle("**Budget** _Review_")).toBe(
|
|
35
|
+
"Budget Review",
|
|
36
|
+
);
|
|
37
|
+
expect(normalizeGeneratedTitle("# Budget Review")).toBe("Budget Review");
|
|
38
|
+
expect(normalizeGeneratedTitle("[Budget](Review)")).toBe("BudgetReview");
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it("strips trailing punctuation", () => {
|
|
42
|
+
expect(normalizeGeneratedTitle("Budget Review.")).toBe("Budget Review");
|
|
43
|
+
expect(normalizeGeneratedTitle("Budget Review!")).toBe("Budget Review");
|
|
44
|
+
expect(normalizeGeneratedTitle("Budget Review?")).toBe("Budget Review");
|
|
45
|
+
expect(normalizeGeneratedTitle("Budget Review;")).toBe("Budget Review");
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it("collapses whitespace", () => {
|
|
49
|
+
expect(normalizeGeneratedTitle("Budget Review")).toBe("Budget Review");
|
|
50
|
+
expect(normalizeGeneratedTitle(" Budget Review ")).toBe("Budget Review");
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it("returns null for empty or whitespace-only input", () => {
|
|
54
|
+
expect(normalizeGeneratedTitle("")).toBeNull();
|
|
55
|
+
expect(normalizeGeneratedTitle(" ")).toBeNull();
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it("returns null when all content is stripped", () => {
|
|
59
|
+
expect(normalizeGeneratedTitle("***")).toBeNull();
|
|
60
|
+
expect(normalizeGeneratedTitle("[]()")).toBeNull();
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it("truncates titles longer than 80 characters", () => {
|
|
64
|
+
const long = "A".repeat(100);
|
|
65
|
+
const result = normalizeGeneratedTitle(long);
|
|
66
|
+
expect(result).not.toBeNull();
|
|
67
|
+
expect(result!.length).toBeLessThanOrEqual(80);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it("returns null when title has more than 8 words", () => {
|
|
71
|
+
expect(
|
|
72
|
+
normalizeGeneratedTitle("one two three four five six seven eight nine"),
|
|
73
|
+
).toBeNull();
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it("accepts title with exactly 8 words", () => {
|
|
77
|
+
expect(
|
|
78
|
+
normalizeGeneratedTitle("one two three four five six seven eight"),
|
|
79
|
+
).toBe("one two three four five six seven eight");
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it("handles JSON with non-string title gracefully", () => {
|
|
83
|
+
// Falls back to raw text path
|
|
84
|
+
expect(normalizeGeneratedTitle('{"title":42}')).toBe('{"title":42}');
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it("handles malformed JSON gracefully", () => {
|
|
88
|
+
expect(normalizeGeneratedTitle("{not json}")).toBe("{not json}");
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
// ---------------------------------------------------------------------------
|
|
93
|
+
// buildThreadTitlePrompt
|
|
94
|
+
// ---------------------------------------------------------------------------
|
|
95
|
+
|
|
96
|
+
describe("buildThreadTitlePrompt", () => {
|
|
97
|
+
const msg = (role: string, content: string): Message =>
|
|
98
|
+
({ id: `msg-${role}`, role, content }) as Message;
|
|
99
|
+
|
|
100
|
+
it("returns null for empty messages", () => {
|
|
101
|
+
expect(buildThreadTitlePrompt([])).toBeNull();
|
|
102
|
+
expect(
|
|
103
|
+
buildThreadTitlePrompt(undefined as unknown as Message[]),
|
|
104
|
+
).toBeNull();
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it("builds a prompt from user and assistant messages", () => {
|
|
108
|
+
const messages = [
|
|
109
|
+
msg("user", "What is the weather?"),
|
|
110
|
+
msg("assistant", "It is sunny today."),
|
|
111
|
+
];
|
|
112
|
+
|
|
113
|
+
const result = buildThreadTitlePrompt(messages);
|
|
114
|
+
expect(result).toContain("Generate a short title");
|
|
115
|
+
expect(result).toContain("user: What is the weather?");
|
|
116
|
+
expect(result).toContain("assistant: It is sunny today.");
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
it("filters out tool role messages", () => {
|
|
120
|
+
const messages = [
|
|
121
|
+
msg("user", "Search for cats"),
|
|
122
|
+
msg("tool", '{"results": []}'),
|
|
123
|
+
msg("assistant", "Found some cats."),
|
|
124
|
+
];
|
|
125
|
+
|
|
126
|
+
const result = buildThreadTitlePrompt(messages);
|
|
127
|
+
expect(result).not.toContain("tool:");
|
|
128
|
+
expect(result).toContain("user: Search for cats");
|
|
129
|
+
expect(result).toContain("assistant: Found some cats.");
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it("includes system and developer messages", () => {
|
|
133
|
+
const messages = [
|
|
134
|
+
msg("system", "You are helpful."),
|
|
135
|
+
msg("developer", "Be concise."),
|
|
136
|
+
msg("user", "Hello"),
|
|
137
|
+
];
|
|
138
|
+
|
|
139
|
+
const result = buildThreadTitlePrompt(messages);
|
|
140
|
+
expect(result).toContain("system: You are helpful.");
|
|
141
|
+
expect(result).toContain("developer: Be concise.");
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
it("takes only the last 8 messages", () => {
|
|
145
|
+
const messages = Array.from({ length: 12 }, (_, i) =>
|
|
146
|
+
msg("user", `Message ${i}`),
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
const result = buildThreadTitlePrompt(messages)!;
|
|
150
|
+
// Should contain messages 4-11 (last 8) but not 0-3
|
|
151
|
+
expect(result).not.toContain("Message 3");
|
|
152
|
+
expect(result).toContain("Message 4");
|
|
153
|
+
expect(result).toContain("Message 11");
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
it("skips messages with empty content", () => {
|
|
157
|
+
const messages = [msg("user", ""), msg("assistant", "Hello")];
|
|
158
|
+
|
|
159
|
+
const result = buildThreadTitlePrompt(messages);
|
|
160
|
+
expect(result).not.toContain("user:");
|
|
161
|
+
expect(result).toContain("assistant: Hello");
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
it("returns null when all messages have empty content", () => {
|
|
165
|
+
const messages = [msg("user", ""), msg("assistant", "")];
|
|
166
|
+
expect(buildThreadTitlePrompt(messages)).toBeNull();
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
// ---------------------------------------------------------------------------
|
|
171
|
+
// hasThreadName
|
|
172
|
+
// ---------------------------------------------------------------------------
|
|
173
|
+
|
|
174
|
+
describe("hasThreadName", () => {
|
|
175
|
+
it("returns true for non-empty strings", () => {
|
|
176
|
+
expect(hasThreadName("Budget Review")).toBe(true);
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
it("returns false for null and undefined", () => {
|
|
180
|
+
expect(hasThreadName(null)).toBe(false);
|
|
181
|
+
expect(hasThreadName(undefined)).toBe(false);
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
it("returns false for empty or whitespace-only strings", () => {
|
|
185
|
+
expect(hasThreadName("")).toBe(false);
|
|
186
|
+
expect(hasThreadName(" ")).toBe(false);
|
|
187
|
+
});
|
|
188
|
+
});
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import express from "express";
|
|
2
|
+
import type {
|
|
3
|
+
Request as ExpressRequest,
|
|
4
|
+
Response as ExpressResponse,
|
|
5
|
+
NextFunction,
|
|
6
|
+
Router,
|
|
7
|
+
} from "express";
|
|
8
|
+
import cors from "cors";
|
|
9
|
+
|
|
10
|
+
import { CopilotRuntimeLike } from "../runtime";
|
|
11
|
+
import { handleRunAgent } from "../handlers/handle-run";
|
|
12
|
+
import { handleConnectAgent } from "../handlers/handle-connect";
|
|
13
|
+
import { handleStopAgent } from "../handlers/handle-stop";
|
|
14
|
+
import { handleGetRuntimeInfo } from "../handlers/get-runtime-info";
|
|
15
|
+
import { handleTranscribe } from "../handlers/handle-transcribe";
|
|
16
|
+
import { logger } from "@copilotkit/shared";
|
|
17
|
+
import {
|
|
18
|
+
callBeforeRequestMiddleware,
|
|
19
|
+
callAfterRequestMiddleware,
|
|
20
|
+
} from "../middleware";
|
|
21
|
+
import {
|
|
22
|
+
createFetchRequestFromExpress,
|
|
23
|
+
sendFetchResponse,
|
|
24
|
+
} from "./express-utils";
|
|
25
|
+
import {
|
|
26
|
+
createJsonRequest,
|
|
27
|
+
expectString,
|
|
28
|
+
MethodCall,
|
|
29
|
+
parseMethodCall,
|
|
30
|
+
} from "./single-route-helpers";
|
|
31
|
+
|
|
32
|
+
interface CopilotSingleRouteExpressParams {
|
|
33
|
+
runtime: CopilotRuntimeLike;
|
|
34
|
+
basePath: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function createCopilotEndpointSingleRouteExpress({
|
|
38
|
+
runtime,
|
|
39
|
+
basePath,
|
|
40
|
+
}: CopilotSingleRouteExpressParams): Router {
|
|
41
|
+
const router = express.Router();
|
|
42
|
+
const routePath = normalizeSingleRoutePath(basePath);
|
|
43
|
+
|
|
44
|
+
router.use(
|
|
45
|
+
cors({
|
|
46
|
+
origin: "*",
|
|
47
|
+
methods: ["GET", "HEAD", "PUT", "POST", "DELETE", "PATCH", "OPTIONS"],
|
|
48
|
+
allowedHeaders: ["*"],
|
|
49
|
+
}),
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
router.post(routePath, createSingleRouteHandler(runtime));
|
|
53
|
+
|
|
54
|
+
router.use((req, res) => {
|
|
55
|
+
res.status(404).json({ error: "Not found" });
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
return router;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function createSingleRouteHandler(runtime: CopilotRuntimeLike) {
|
|
62
|
+
return async (
|
|
63
|
+
req: ExpressRequest,
|
|
64
|
+
res: ExpressResponse,
|
|
65
|
+
next: NextFunction,
|
|
66
|
+
) => {
|
|
67
|
+
const path = req.originalUrl ?? req.path;
|
|
68
|
+
let request = createFetchRequestFromExpress(req);
|
|
69
|
+
|
|
70
|
+
try {
|
|
71
|
+
const maybeModifiedRequest = await callBeforeRequestMiddleware({
|
|
72
|
+
runtime,
|
|
73
|
+
request,
|
|
74
|
+
path,
|
|
75
|
+
});
|
|
76
|
+
if (maybeModifiedRequest) {
|
|
77
|
+
request = maybeModifiedRequest;
|
|
78
|
+
}
|
|
79
|
+
} catch (error) {
|
|
80
|
+
logger.error(
|
|
81
|
+
{ err: error, url: request.url, path },
|
|
82
|
+
"Error running before request middleware",
|
|
83
|
+
);
|
|
84
|
+
if (error instanceof Response) {
|
|
85
|
+
try {
|
|
86
|
+
await sendFetchResponse(res, error);
|
|
87
|
+
} catch (streamError) {
|
|
88
|
+
next(streamError);
|
|
89
|
+
}
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
next(error);
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
let methodCall: MethodCall;
|
|
97
|
+
try {
|
|
98
|
+
methodCall = await parseMethodCall(request);
|
|
99
|
+
} catch (error) {
|
|
100
|
+
if (error instanceof Response) {
|
|
101
|
+
logger.warn({ url: request.url }, "Invalid single-route payload");
|
|
102
|
+
try {
|
|
103
|
+
await sendFetchResponse(res, error);
|
|
104
|
+
} catch (streamError) {
|
|
105
|
+
next(streamError);
|
|
106
|
+
}
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
logger.warn(
|
|
110
|
+
{ err: error, url: request.url },
|
|
111
|
+
"Invalid single-route payload",
|
|
112
|
+
);
|
|
113
|
+
res.status(400).json({
|
|
114
|
+
error: "invalid_request",
|
|
115
|
+
message:
|
|
116
|
+
error instanceof Error ? error.message : "Invalid request payload",
|
|
117
|
+
});
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
try {
|
|
122
|
+
let response: Response;
|
|
123
|
+
switch (methodCall.method) {
|
|
124
|
+
case "agent/run": {
|
|
125
|
+
const agentId = expectString(methodCall.params, "agentId");
|
|
126
|
+
const handlerRequest = createJsonRequest(request, methodCall.body);
|
|
127
|
+
response = await handleRunAgent({
|
|
128
|
+
runtime,
|
|
129
|
+
request: handlerRequest,
|
|
130
|
+
agentId,
|
|
131
|
+
});
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
case "agent/connect": {
|
|
135
|
+
const agentId = expectString(methodCall.params, "agentId");
|
|
136
|
+
const handlerRequest = createJsonRequest(request, methodCall.body);
|
|
137
|
+
response = await handleConnectAgent({
|
|
138
|
+
runtime,
|
|
139
|
+
request: handlerRequest,
|
|
140
|
+
agentId,
|
|
141
|
+
});
|
|
142
|
+
break;
|
|
143
|
+
}
|
|
144
|
+
case "agent/stop": {
|
|
145
|
+
const agentId = expectString(methodCall.params, "agentId");
|
|
146
|
+
const threadId = expectString(methodCall.params, "threadId");
|
|
147
|
+
response = await handleStopAgent({
|
|
148
|
+
runtime,
|
|
149
|
+
request,
|
|
150
|
+
agentId,
|
|
151
|
+
threadId,
|
|
152
|
+
});
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
case "info": {
|
|
156
|
+
response = await handleGetRuntimeInfo({ runtime, request });
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
case "transcribe": {
|
|
160
|
+
const handlerRequest = createJsonRequest(request, methodCall.body);
|
|
161
|
+
response = await handleTranscribe({
|
|
162
|
+
runtime,
|
|
163
|
+
request: handlerRequest,
|
|
164
|
+
});
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
default: {
|
|
168
|
+
const exhaustive: never = methodCall.method;
|
|
169
|
+
return exhaustive;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const responseForMiddleware = response.clone();
|
|
174
|
+
await sendFetchResponse(res, response);
|
|
175
|
+
callAfterRequestMiddleware({
|
|
176
|
+
runtime,
|
|
177
|
+
response: responseForMiddleware,
|
|
178
|
+
path,
|
|
179
|
+
}).catch((error) => {
|
|
180
|
+
logger.error(
|
|
181
|
+
{ err: error, url: req.originalUrl ?? req.url, path },
|
|
182
|
+
"Error running after request middleware",
|
|
183
|
+
);
|
|
184
|
+
});
|
|
185
|
+
} catch (error) {
|
|
186
|
+
if (error instanceof Response) {
|
|
187
|
+
const errorResponseForMiddleware = error.clone();
|
|
188
|
+
try {
|
|
189
|
+
await sendFetchResponse(res, error);
|
|
190
|
+
} catch (streamError) {
|
|
191
|
+
next(streamError);
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
callAfterRequestMiddleware({
|
|
195
|
+
runtime,
|
|
196
|
+
response: errorResponseForMiddleware,
|
|
197
|
+
path,
|
|
198
|
+
}).catch((mwError) => {
|
|
199
|
+
logger.error(
|
|
200
|
+
{ err: mwError, url: req.originalUrl ?? req.url, path },
|
|
201
|
+
"Error running after request middleware",
|
|
202
|
+
);
|
|
203
|
+
});
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
logger.error(
|
|
207
|
+
{ err: error, url: request.url, path },
|
|
208
|
+
"Error running single-route handler",
|
|
209
|
+
);
|
|
210
|
+
next(error);
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function normalizeSingleRoutePath(path: string): string {
|
|
216
|
+
if (!path) {
|
|
217
|
+
throw new Error(
|
|
218
|
+
"basePath must be provided for Express single-route endpoint",
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
if (!path.startsWith("/")) {
|
|
223
|
+
return `/${path}`;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
if (path.length > 1 && path.endsWith("/")) {
|
|
227
|
+
return path.slice(0, -1);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
return path;
|
|
231
|
+
}
|