@copilotkit/runtime 1.57.3 → 1.58.0-canary.thread-id-propagation
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/observability.d.cts +1 -1
- package/dist/lib/observability.d.cts.map +1 -1
- package/dist/lib/observability.d.mts +1 -1
- package/dist/lib/observability.d.mts.map +1 -1
- package/dist/lib/runtime/copilot-runtime.cjs +2 -0
- package/dist/lib/runtime/copilot-runtime.cjs.map +1 -1
- package/dist/lib/runtime/copilot-runtime.d.cts.map +1 -1
- package/dist/lib/runtime/copilot-runtime.d.mts.map +1 -1
- package/dist/lib/runtime/copilot-runtime.mjs +2 -0
- package/dist/lib/runtime/copilot-runtime.mjs.map +1 -1
- package/dist/package.cjs +5 -8
- package/dist/package.mjs +5 -8
- package/dist/v2/runtime/core/runtime.cjs +4 -1
- package/dist/v2/runtime/core/runtime.cjs.map +1 -1
- package/dist/v2/runtime/core/runtime.d.cts.map +1 -1
- package/dist/v2/runtime/core/runtime.d.mts.map +1 -1
- package/dist/v2/runtime/core/runtime.mjs +4 -1
- package/dist/v2/runtime/core/runtime.mjs.map +1 -1
- package/dist/v2/runtime/handlers/get-runtime-info.cjs +1 -1
- package/dist/v2/runtime/handlers/get-runtime-info.mjs +1 -1
- package/dist/v2/runtime/handlers/handle-connect.cjs +1 -1
- package/dist/v2/runtime/handlers/handle-connect.mjs +1 -1
- package/dist/v2/runtime/handlers/handle-run.cjs +1 -1
- package/dist/v2/runtime/handlers/handle-run.mjs +1 -1
- package/dist/v2/runtime/handlers/shared/agent-utils.cjs +1 -1
- package/dist/v2/runtime/handlers/shared/agent-utils.cjs.map +1 -1
- package/dist/v2/runtime/handlers/shared/agent-utils.mjs +1 -1
- package/dist/v2/runtime/handlers/shared/agent-utils.mjs.map +1 -1
- package/dist/v2/runtime/telemetry/telemetry-client.cjs +22 -6
- package/dist/v2/runtime/telemetry/telemetry-client.cjs.map +1 -1
- package/dist/v2/runtime/telemetry/telemetry-client.mjs +27 -11
- package/dist/v2/runtime/telemetry/telemetry-client.mjs.map +1 -1
- package/package.json +9 -19
- package/skills/runtime/SKILL.md +98 -0
- package/skills/runtime/references/agent-runners-custom.md +161 -0
- package/skills/runtime/references/agent-runners-in-memory.md +64 -0
- package/skills/runtime/references/agent-runners-sqlite.md +90 -0
- package/skills/runtime/references/agent-runners.md +304 -0
- package/skills/runtime/references/built-in-agent-factory-modes.md +232 -0
- package/skills/runtime/references/built-in-agent-helper-utilities.md +123 -0
- package/skills/runtime/references/built-in-agent-model-identifiers.md +59 -0
- package/skills/runtime/references/built-in-agent.md +523 -0
- package/skills/runtime/references/intelligence-mode.md +336 -0
- package/skills/runtime/references/middleware.md +376 -0
- package/skills/runtime/references/server-side-tools.md +414 -0
- package/skills/runtime/references/setup-endpoint.md +503 -0
- package/skills/runtime/references/transcription.md +287 -0
- package/skills/runtime/references/wiring-a2a.md +40 -0
- package/skills/runtime/references/wiring-adk.md +45 -0
- package/skills/runtime/references/wiring-ag2.md +41 -0
- package/skills/runtime/references/wiring-agno.md +39 -0
- package/skills/runtime/references/wiring-aws-strands.md +59 -0
- package/skills/runtime/references/wiring-crewai-crews.md +51 -0
- package/skills/runtime/references/wiring-crewai-flows.md +45 -0
- package/skills/runtime/references/wiring-external-agents.md +348 -0
- package/skills/runtime/references/wiring-langgraph.md +50 -0
- package/skills/runtime/references/wiring-llamaindex.md +39 -0
- package/skills/runtime/references/wiring-mastra.md +70 -0
- package/skills/runtime/references/wiring-mcp-apps-middleware.md +68 -0
- package/skills/runtime/references/wiring-ms-agent-framework.md +41 -0
- package/skills/runtime/references/wiring-pydantic-ai.md +45 -0
- package/CHANGELOG.md +0 -3624
- package/__snapshots__/schema/schema.graphql +0 -371
- package/dist/v2/runtime/telemetry/scarf-client.cjs +0 -32
- package/dist/v2/runtime/telemetry/scarf-client.cjs.map +0 -1
- package/dist/v2/runtime/telemetry/scarf-client.mjs +0 -32
- package/dist/v2/runtime/telemetry/scarf-client.mjs.map +0 -1
- package/scripts/generate-gql-schema.ts +0 -16
- package/src/agent/__tests__/agent-test-helpers.ts +0 -476
- package/src/agent/__tests__/agent.test.ts +0 -593
- package/src/agent/__tests__/ai-sdk-v6-compat.test.ts +0 -116
- package/src/agent/__tests__/basic-agent.test.ts +0 -1698
- package/src/agent/__tests__/capabilities.test.ts +0 -81
- package/src/agent/__tests__/config-tools-execution.test.ts +0 -516
- package/src/agent/__tests__/converter-aisdk.test.ts +0 -692
- package/src/agent/__tests__/converter-custom.test.ts +0 -319
- package/src/agent/__tests__/converter-tanstack-input.test.ts +0 -211
- package/src/agent/__tests__/converter-tanstack.test.ts +0 -594
- package/src/agent/__tests__/mcp-clients.test.ts +0 -246
- package/src/agent/__tests__/mcp-servers-integration.test.ts +0 -373
- package/src/agent/__tests__/multimodal-tanstack.test.ts +0 -284
- package/src/agent/__tests__/multimodal.test.ts +0 -176
- package/src/agent/__tests__/property-overrides.test.ts +0 -598
- package/src/agent/__tests__/provider-id-collision.test.ts +0 -195
- package/src/agent/__tests__/standard-schema-tools.test.ts +0 -313
- package/src/agent/__tests__/standard-schema-types.test.ts +0 -158
- package/src/agent/__tests__/state-tools.test.ts +0 -436
- package/src/agent/__tests__/test-helpers.ts +0 -197
- package/src/agent/__tests__/utils.test.ts +0 -536
- package/src/agent/__tests__/zod-regression.test.ts +0 -350
- package/src/agent/converters/aisdk.ts +0 -326
- package/src/agent/converters/index.ts +0 -7
- package/src/agent/converters/tanstack.ts +0 -451
- package/src/agent/index.ts +0 -1743
- package/src/agents/langgraph/__tests__/event-source.test.ts +0 -256
- package/src/agents/langgraph/event-source.ts +0 -365
- package/src/agents/langgraph/events.ts +0 -394
- package/src/graphql/inputs/action.input.ts +0 -16
- package/src/graphql/inputs/agent-session.input.ts +0 -13
- package/src/graphql/inputs/agent-state.input.ts +0 -13
- package/src/graphql/inputs/cloud-guardrails.input.ts +0 -16
- package/src/graphql/inputs/cloud.input.ts +0 -8
- package/src/graphql/inputs/context-property.input.ts +0 -10
- package/src/graphql/inputs/copilot-context.input.ts +0 -10
- package/src/graphql/inputs/custom-property.input.ts +0 -15
- package/src/graphql/inputs/extensions.input.ts +0 -21
- package/src/graphql/inputs/forwarded-parameters.input.ts +0 -22
- package/src/graphql/inputs/frontend.input.ts +0 -14
- package/src/graphql/inputs/generate-copilot-response.input.ts +0 -59
- package/src/graphql/inputs/load-agent-state.input.ts +0 -10
- package/src/graphql/inputs/message.input.ts +0 -110
- package/src/graphql/inputs/meta-event.input.ts +0 -18
- package/src/graphql/message-conversion/agui-to-gql.test.ts +0 -1384
- package/src/graphql/message-conversion/agui-to-gql.ts +0 -384
- package/src/graphql/message-conversion/gql-to-agui.test.ts +0 -1653
- package/src/graphql/message-conversion/gql-to-agui.ts +0 -297
- package/src/graphql/message-conversion/index.ts +0 -2
- package/src/graphql/message-conversion/roundtrip-conversion.test.ts +0 -561
- package/src/graphql/resolvers/__tests__/resolve-message-id.test.ts +0 -25
- package/src/graphql/resolvers/copilot.resolver.ts +0 -785
- package/src/graphql/resolvers/resolve-message-id.ts +0 -14
- package/src/graphql/resolvers/state.resolver.ts +0 -30
- package/src/graphql/types/agents-response.type.ts +0 -19
- package/src/graphql/types/base/index.ts +0 -10
- package/src/graphql/types/converted/index.ts +0 -183
- package/src/graphql/types/copilot-response.type.ts +0 -141
- package/src/graphql/types/enums.ts +0 -38
- package/src/graphql/types/extensions-response.type.ts +0 -23
- package/src/graphql/types/guardrails-result.type.ts +0 -20
- package/src/graphql/types/load-agent-state-response.type.ts +0 -17
- package/src/graphql/types/message-status.type.ts +0 -48
- package/src/graphql/types/meta-events.type.ts +0 -78
- package/src/graphql/types/response-status.type.ts +0 -77
- package/src/index.ts +0 -3
- package/src/langgraph.ts +0 -1
- package/src/lib/__tests__/telemetry-disclosure.test.ts +0 -55
- package/src/lib/cloud/index.ts +0 -4
- package/src/lib/error-messages.ts +0 -211
- package/src/lib/index.ts +0 -52
- package/src/lib/integrations/index.ts +0 -6
- package/src/lib/integrations/nest/index.ts +0 -21
- package/src/lib/integrations/nextjs/app-router.ts +0 -47
- package/src/lib/integrations/nextjs/pages-router.ts +0 -45
- package/src/lib/integrations/node-express/index.ts +0 -21
- package/src/lib/integrations/node-http/__tests__/request-duck-type.test.ts +0 -66
- package/src/lib/integrations/node-http/index.ts +0 -187
- package/src/lib/integrations/node-http/request-handler.ts +0 -128
- package/src/lib/integrations/shared.ts +0 -112
- package/src/lib/logger.ts +0 -31
- package/src/lib/observability.ts +0 -167
- package/src/lib/runtime/__tests__/copilot-runtime-error.test.ts +0 -183
- package/src/lib/runtime/__tests__/handle-service-adapter.test.ts +0 -108
- package/src/lib/runtime/__tests__/mcp-tools-utils.test.ts +0 -499
- package/src/lib/runtime/__tests__/on-after-request.test.ts +0 -122
- package/src/lib/runtime/__tests__/retry-utils.test.ts +0 -137
- package/src/lib/runtime/__tests__/v1-agent-factory.test.ts +0 -109
- package/src/lib/runtime/agent-integrations/langgraph/__tests__/dispatch-event-filtering.test.ts +0 -345
- package/src/lib/runtime/agent-integrations/langgraph/__tests__/run-message-filtering.test.ts +0 -156
- package/src/lib/runtime/agent-integrations/langgraph/agent.ts +0 -263
- package/src/lib/runtime/agent-integrations/langgraph/consts.ts +0 -37
- package/src/lib/runtime/agent-integrations/langgraph/index.ts +0 -2
- package/src/lib/runtime/copilot-runtime.ts +0 -863
- package/src/lib/runtime/mcp-tools-utils.ts +0 -313
- package/src/lib/runtime/retry-utils.ts +0 -141
- package/src/lib/runtime/telemetry-agent-runner.ts +0 -151
- package/src/lib/runtime/types.ts +0 -48
- package/src/lib/runtime/utils.ts +0 -93
- package/src/lib/streaming.ts +0 -220
- package/src/lib/telemetry-client.ts +0 -66
- package/src/lib/telemetry-disclosure.ts +0 -53
- package/src/service-adapters/anthropic/anthropic-adapter.ts +0 -532
- package/src/service-adapters/anthropic/utils.ts +0 -219
- package/src/service-adapters/bedrock/bedrock-adapter.ts +0 -73
- package/src/service-adapters/conversion.test.ts +0 -56
- package/src/service-adapters/conversion.ts +0 -69
- package/src/service-adapters/empty/empty-adapter.ts +0 -38
- package/src/service-adapters/events.ts +0 -337
- package/src/service-adapters/experimental/ollama/ollama-adapter.ts +0 -84
- package/src/service-adapters/google/google-genai-adapter.test.ts +0 -151
- package/src/service-adapters/google/google-genai-adapter.ts +0 -95
- package/src/service-adapters/groq/groq-adapter.ts +0 -229
- package/src/service-adapters/index.ts +0 -18
- package/src/service-adapters/langchain/langchain-adapter.ts +0 -113
- package/src/service-adapters/langchain/langserve.ts +0 -88
- package/src/service-adapters/langchain/types.ts +0 -20
- package/src/service-adapters/langchain/utils.ts +0 -330
- package/src/service-adapters/openai/__tests__/openai-v5-compat.test.ts +0 -177
- package/src/service-adapters/openai/openai-adapter.ts +0 -324
- package/src/service-adapters/openai/openai-assistant-adapter.ts +0 -385
- package/src/service-adapters/openai/utils.ts +0 -305
- package/src/service-adapters/service-adapter.ts +0 -50
- package/src/service-adapters/shared/error-utils.ts +0 -64
- package/src/service-adapters/shared/index.ts +0 -2
- package/src/service-adapters/shared/sdk-client-utils.ts +0 -19
- package/src/service-adapters/unify/unify-adapter.ts +0 -165
- package/src/utils/failed-response-status-reasons.ts +0 -70
- package/src/utils/index.ts +0 -1
- package/src/v2/express.ts +0 -1
- package/src/v2/hono.ts +0 -1
- package/src/v2/index.ts +0 -5
- package/src/v2/node.ts +0 -1
- package/src/v2/runtime/__tests__/agents-factory.test.ts +0 -136
- package/src/v2/runtime/__tests__/backward-compat.test.ts +0 -261
- package/src/v2/runtime/__tests__/code-review-fixes.test.ts +0 -500
- package/src/v2/runtime/__tests__/cors-credentials.test.ts +0 -320
- package/src/v2/runtime/__tests__/debug-sse-response.test.ts +0 -302
- package/src/v2/runtime/__tests__/express-adapter.test.ts +0 -188
- package/src/v2/runtime/__tests__/express-body-order.test.ts +0 -76
- package/src/v2/runtime/__tests__/express-fetch-bridge.test.ts +0 -344
- package/src/v2/runtime/__tests__/express-single-sse.test.ts +0 -122
- package/src/v2/runtime/__tests__/express-single-telemetry.integration.test.ts +0 -65
- package/src/v2/runtime/__tests__/express-telemetry.integration.test.ts +0 -101
- package/src/v2/runtime/__tests__/fetch-cors.test.ts +0 -205
- package/src/v2/runtime/__tests__/fetch-handler-validation.test.ts +0 -440
- package/src/v2/runtime/__tests__/fetch-handler.test.ts +0 -456
- package/src/v2/runtime/__tests__/fetch-router.test.ts +0 -276
- package/src/v2/runtime/__tests__/get-runtime-info.test.ts +0 -335
- package/src/v2/runtime/__tests__/handle-connect.test.ts +0 -585
- package/src/v2/runtime/__tests__/handle-run.test.ts +0 -1388
- package/src/v2/runtime/__tests__/handle-threads.test.ts +0 -930
- package/src/v2/runtime/__tests__/handle-transcribe.test.ts +0 -301
- package/src/v2/runtime/__tests__/header-utils.test.ts +0 -88
- package/src/v2/runtime/__tests__/hono-adapter.test.ts +0 -150
- package/src/v2/runtime/__tests__/hono-single-telemetry.integration.test.ts +0 -46
- package/src/v2/runtime/__tests__/hono-telemetry.integration.test.ts +0 -99
- package/src/v2/runtime/__tests__/hooks-edge-cases.test.ts +0 -457
- package/src/v2/runtime/__tests__/hooks.test.ts +0 -557
- package/src/v2/runtime/__tests__/in-process-agent-runner-messages.test.ts +0 -230
- package/src/v2/runtime/__tests__/in-process-agent-runner.test.ts +0 -1030
- package/src/v2/runtime/__tests__/integration/bun/bun-servers.integration.test.ts +0 -27
- package/src/v2/runtime/__tests__/integration/bun/elysia-multi.ts +0 -32
- package/src/v2/runtime/__tests__/integration/bun/elysia-single.ts +0 -33
- package/src/v2/runtime/__tests__/integration/bun/hono-bun-multi.ts +0 -25
- package/src/v2/runtime/__tests__/integration/bun/hono-bun-single.ts +0 -32
- package/src/v2/runtime/__tests__/integration/helpers/create-test-runtime.ts +0 -15
- package/src/v2/runtime/__tests__/integration/helpers/sse-reader.ts +0 -45
- package/src/v2/runtime/__tests__/integration/helpers/test-agent.ts +0 -58
- package/src/v2/runtime/__tests__/integration/node-servers.integration.test.ts +0 -58
- package/src/v2/runtime/__tests__/integration/servers/express-multi.ts +0 -35
- package/src/v2/runtime/__tests__/integration/servers/express-single.ts +0 -36
- package/src/v2/runtime/__tests__/integration/servers/fetch-direct.ts +0 -39
- package/src/v2/runtime/__tests__/integration/servers/hono-multi.ts +0 -30
- package/src/v2/runtime/__tests__/integration/servers/hono-single.ts +0 -37
- package/src/v2/runtime/__tests__/integration/servers/node-multi.ts +0 -45
- package/src/v2/runtime/__tests__/integration/servers/node-single.ts +0 -46
- package/src/v2/runtime/__tests__/integration/servers/types.ts +0 -18
- package/src/v2/runtime/__tests__/integration/suites/debug-events.suite.ts +0 -253
- package/src/v2/runtime/__tests__/integration/suites/multi-endpoint.suite.ts +0 -358
- package/src/v2/runtime/__tests__/integration/suites/single-endpoint.suite.ts +0 -363
- package/src/v2/runtime/__tests__/intelligence-run-telemetry.test.ts +0 -194
- package/src/v2/runtime/__tests__/mcp-apps-middleware-integration.test.ts +0 -275
- package/src/v2/runtime/__tests__/middleware-express.test.ts +0 -208
- package/src/v2/runtime/__tests__/middleware-single-express.test.ts +0 -213
- package/src/v2/runtime/__tests__/middleware-single.test.ts +0 -225
- package/src/v2/runtime/__tests__/middleware-sse-parser.test.ts +0 -237
- package/src/v2/runtime/__tests__/middleware.test.ts +0 -250
- package/src/v2/runtime/__tests__/node-fetch-handler.test.ts +0 -157
- package/src/v2/runtime/__tests__/open-generative-ui-middleware.e2e.test.ts +0 -728
- package/src/v2/runtime/__tests__/router-edge-cases.test.ts +0 -217
- package/src/v2/runtime/__tests__/routing-express.test.ts +0 -174
- package/src/v2/runtime/__tests__/routing-single-express.test.ts +0 -168
- package/src/v2/runtime/__tests__/routing-single.test.ts +0 -193
- package/src/v2/runtime/__tests__/routing.test.ts +0 -257
- package/src/v2/runtime/__tests__/runtime.test.ts +0 -234
- package/src/v2/runtime/__tests__/sse-response-telemetry.test.ts +0 -108
- package/src/v2/runtime/__tests__/telemetry.test.ts +0 -167
- package/src/v2/runtime/__tests__/thread-names.test.ts +0 -188
- package/src/v2/runtime/core/__tests__/debug-event-bus.test.ts +0 -156
- package/src/v2/runtime/core/debug-event-bus.ts +0 -45
- package/src/v2/runtime/core/fetch-cors.ts +0 -136
- package/src/v2/runtime/core/fetch-handler.ts +0 -492
- package/src/v2/runtime/core/fetch-router.ts +0 -203
- package/src/v2/runtime/core/hooks.ts +0 -160
- package/src/v2/runtime/core/middleware-sse-parser.ts +0 -210
- package/src/v2/runtime/core/middleware.ts +0 -115
- package/src/v2/runtime/core/runtime.ts +0 -432
- package/src/v2/runtime/endpoints/express-fetch-bridge.ts +0 -137
- package/src/v2/runtime/endpoints/express-single.ts +0 -54
- package/src/v2/runtime/endpoints/express.ts +0 -179
- package/src/v2/runtime/endpoints/hono-single.ts +0 -60
- package/src/v2/runtime/endpoints/hono.ts +0 -89
- package/src/v2/runtime/endpoints/index.ts +0 -4
- package/src/v2/runtime/endpoints/node-fetch-handler.ts +0 -48
- package/src/v2/runtime/endpoints/node.ts +0 -28
- package/src/v2/runtime/endpoints/single-route-helpers.ts +0 -125
- package/src/v2/runtime/express.ts +0 -2
- package/src/v2/runtime/handlers/__tests__/handle-debug-events.test.ts +0 -176
- package/src/v2/runtime/handlers/get-runtime-info.ts +0 -101
- package/src/v2/runtime/handlers/handle-connect.ts +0 -80
- package/src/v2/runtime/handlers/handle-debug-events.ts +0 -52
- package/src/v2/runtime/handlers/handle-run.ts +0 -111
- package/src/v2/runtime/handlers/handle-stop.ts +0 -77
- package/src/v2/runtime/handlers/handle-threads.ts +0 -11
- package/src/v2/runtime/handlers/handle-transcribe.ts +0 -269
- package/src/v2/runtime/handlers/header-utils.ts +0 -24
- package/src/v2/runtime/handlers/intelligence/connect.ts +0 -102
- package/src/v2/runtime/handlers/intelligence/run.ts +0 -351
- package/src/v2/runtime/handlers/intelligence/thread-names.ts +0 -246
- package/src/v2/runtime/handlers/intelligence/threads.ts +0 -420
- package/src/v2/runtime/handlers/shared/agent-utils.ts +0 -154
- package/src/v2/runtime/handlers/shared/intelligence-utils.ts +0 -41
- package/src/v2/runtime/handlers/shared/json-response.ts +0 -9
- package/src/v2/runtime/handlers/shared/resolve-intelligence-user.ts +0 -28
- package/src/v2/runtime/handlers/shared/sse-response.ts +0 -215
- package/src/v2/runtime/handlers/sse/__tests__/sse-connect-agent-id.test.ts +0 -71
- package/src/v2/runtime/handlers/sse/connect.ts +0 -30
- package/src/v2/runtime/handlers/sse/run.ts +0 -40
- package/src/v2/runtime/hono.ts +0 -2
- package/src/v2/runtime/index.ts +0 -51
- package/src/v2/runtime/intelligence-platform/__tests__/client.test.ts +0 -601
- package/src/v2/runtime/intelligence-platform/__tests__/intelligence-mcp-helper.test.ts +0 -246
- package/src/v2/runtime/intelligence-platform/client.ts +0 -818
- package/src/v2/runtime/intelligence-platform/index.ts +0 -10
- package/src/v2/runtime/node.ts +0 -6
- package/src/v2/runtime/open-generative-ui-middleware.ts +0 -373
- package/src/v2/runtime/runner/__tests__/finalize-events.test.ts +0 -109
- package/src/v2/runtime/runner/__tests__/in-memory-runner.e2e.test.ts +0 -775
- package/src/v2/runtime/runner/__tests__/in-memory-runner.test.ts +0 -777
- package/src/v2/runtime/runner/__tests__/intelligence-runner.test.ts +0 -1039
- package/src/v2/runtime/runner/agent-runner.ts +0 -35
- package/src/v2/runtime/runner/in-memory.ts +0 -467
- package/src/v2/runtime/runner/index.ts +0 -4
- package/src/v2/runtime/runner/intelligence.ts +0 -498
- package/src/v2/runtime/telemetry/__tests__/instance-created.test.ts +0 -96
- package/src/v2/runtime/telemetry/events.ts +0 -35
- package/src/v2/runtime/telemetry/index.ts +0 -7
- package/src/v2/runtime/telemetry/instance-created.ts +0 -44
- package/src/v2/runtime/telemetry/scarf-client.ts +0 -39
- package/src/v2/runtime/telemetry/telemetry-client.ts +0 -70
- package/src/v2/runtime/transcription-service/transcription-service.ts +0 -11
- package/tests/global.d.ts +0 -1
- package/tests/service-adapters/anthropic/allowlist-approach.test.ts +0 -259
- package/tests/service-adapters/anthropic/anthropic-adapter-language-model.test.ts +0 -101
- package/tests/service-adapters/anthropic/anthropic-adapter.test.ts +0 -645
- package/tests/service-adapters/anthropic/utils-token-trimming.test.ts +0 -301
- package/tests/service-adapters/groq/groq-adapter-language-model.test.ts +0 -102
- package/tests/service-adapters/openai/allowlist-approach.test.ts +0 -294
- package/tests/service-adapters/openai/openai-adapter-language-model.test.ts +0 -122
- package/tests/service-adapters/openai/openai-adapter.test.ts +0 -291
- package/tests/service-adapters/shared/sdk-client-utils.test.ts +0 -36
- package/tests/setup.vitest.ts +0 -8
- package/tests/tsconfig.json +0 -10
- package/tsconfig.json +0 -20
- package/tsdown.config.ts +0 -45
- package/typedoc.json +0 -4
- package/vitest.config.mjs +0 -13
|
@@ -1,930 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it, vi } from "vitest";
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
handleArchiveThread,
|
|
5
|
-
handleClearThreads,
|
|
6
|
-
handleDeleteThread,
|
|
7
|
-
handleGetThreadEvents,
|
|
8
|
-
handleGetThreadMessages,
|
|
9
|
-
handleGetThreadState,
|
|
10
|
-
handleListThreads,
|
|
11
|
-
handleSubscribeToThreads,
|
|
12
|
-
handleUpdateThread,
|
|
13
|
-
} from "../handlers/handle-threads";
|
|
14
|
-
import { CopilotRuntime } from "../core/runtime";
|
|
15
|
-
import { InMemoryAgentRunner } from "../runner/in-memory";
|
|
16
|
-
|
|
17
|
-
describe("thread handlers", () => {
|
|
18
|
-
const createIdentifyUser = () =>
|
|
19
|
-
vi.fn().mockResolvedValue({ id: "user-1", name: "User One" });
|
|
20
|
-
|
|
21
|
-
const createIntelligenceRuntime = (options?: {
|
|
22
|
-
identifyUser?: (
|
|
23
|
-
request: Request,
|
|
24
|
-
) => { id: string; name: string } | Promise<{ id: string; name: string }>;
|
|
25
|
-
intelligence?: Record<string, unknown>;
|
|
26
|
-
}) =>
|
|
27
|
-
({
|
|
28
|
-
agents: Promise.resolve({}),
|
|
29
|
-
transcriptionService: undefined,
|
|
30
|
-
beforeRequestMiddleware: undefined,
|
|
31
|
-
afterRequestMiddleware: undefined,
|
|
32
|
-
runner: {
|
|
33
|
-
run: vi.fn(),
|
|
34
|
-
connect: vi.fn(),
|
|
35
|
-
isRunning: vi.fn(),
|
|
36
|
-
stop: vi.fn(),
|
|
37
|
-
},
|
|
38
|
-
mode: "intelligence",
|
|
39
|
-
generateThreadNames: false,
|
|
40
|
-
identifyUser: options?.identifyUser ?? createIdentifyUser(),
|
|
41
|
-
intelligence: options?.intelligence,
|
|
42
|
-
}) as unknown as CopilotRuntime;
|
|
43
|
-
|
|
44
|
-
const createMutationRequest = (
|
|
45
|
-
path: string,
|
|
46
|
-
method: "PATCH" | "POST" | "DELETE",
|
|
47
|
-
body: Record<string, unknown>,
|
|
48
|
-
) =>
|
|
49
|
-
new Request(`https://example.com${path}`, {
|
|
50
|
-
method,
|
|
51
|
-
headers: { "Content-Type": "application/json" },
|
|
52
|
-
body: JSON.stringify(body),
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it("returns empty thread list when intelligence is not configured for listThreads", async () => {
|
|
56
|
-
const runtime = new CopilotRuntime({ agents: {} });
|
|
57
|
-
|
|
58
|
-
const response = await handleListThreads({
|
|
59
|
-
runtime,
|
|
60
|
-
request: new Request("https://example.com/threads?agentId=agent-1"),
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
expect(response.status).toBe(200);
|
|
64
|
-
await expect(response.json()).resolves.toEqual({
|
|
65
|
-
threads: [],
|
|
66
|
-
nextCursor: null,
|
|
67
|
-
});
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
it("lists threads using identifyUser and the request agentId", async () => {
|
|
71
|
-
const intelligence = {
|
|
72
|
-
listThreads: vi.fn().mockResolvedValue({
|
|
73
|
-
threads: [{ id: "thread-1", name: "Hello" }],
|
|
74
|
-
joinCode: "jc-1",
|
|
75
|
-
}),
|
|
76
|
-
};
|
|
77
|
-
const identifyUser = createIdentifyUser();
|
|
78
|
-
const runtime = createIntelligenceRuntime({ intelligence, identifyUser });
|
|
79
|
-
const request = new Request("https://example.com/threads?agentId=agent-1");
|
|
80
|
-
|
|
81
|
-
const response = await handleListThreads({
|
|
82
|
-
runtime,
|
|
83
|
-
request,
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
expect(response.status).toBe(200);
|
|
87
|
-
expect(identifyUser).toHaveBeenCalledTimes(1);
|
|
88
|
-
expect(identifyUser).toHaveBeenCalledWith(request);
|
|
89
|
-
expect(intelligence.listThreads).toHaveBeenCalledWith({
|
|
90
|
-
userId: "user-1",
|
|
91
|
-
agentId: "agent-1",
|
|
92
|
-
});
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
it("returns 400 when identifyUser returns an invalid id for thread list", async () => {
|
|
96
|
-
const intelligence = {
|
|
97
|
-
listThreads: vi.fn(),
|
|
98
|
-
};
|
|
99
|
-
const runtime = createIntelligenceRuntime({
|
|
100
|
-
intelligence,
|
|
101
|
-
identifyUser: vi.fn().mockResolvedValue({ id: "", name: "User" }),
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
const response = await handleListThreads({
|
|
105
|
-
runtime,
|
|
106
|
-
request: new Request("https://example.com/threads?agentId=agent-1"),
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
expect(response.status).toBe(400);
|
|
110
|
-
expect(intelligence.listThreads).not.toHaveBeenCalled();
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
it("returns 400 when identifyUser returns an invalid name for thread list", async () => {
|
|
114
|
-
const intelligence = {
|
|
115
|
-
listThreads: vi.fn(),
|
|
116
|
-
};
|
|
117
|
-
const runtime = createIntelligenceRuntime({
|
|
118
|
-
intelligence,
|
|
119
|
-
identifyUser: vi.fn().mockResolvedValue({ id: "user-1", name: "" }),
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
const response = await handleListThreads({
|
|
123
|
-
runtime,
|
|
124
|
-
request: new Request("https://example.com/threads?agentId=agent-1"),
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
expect(response.status).toBe(400);
|
|
128
|
-
expect(intelligence.listThreads).not.toHaveBeenCalled();
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
it("returns 500 when identifyUser throws for thread subscription", async () => {
|
|
132
|
-
const intelligence = {
|
|
133
|
-
ɵsubscribeToThreads: vi.fn(),
|
|
134
|
-
};
|
|
135
|
-
const runtime = createIntelligenceRuntime({
|
|
136
|
-
intelligence,
|
|
137
|
-
identifyUser: vi.fn().mockRejectedValue(new Error("auth failed")),
|
|
138
|
-
});
|
|
139
|
-
const errorSpy = vi.spyOn(console, "error").mockImplementation(() => {});
|
|
140
|
-
|
|
141
|
-
try {
|
|
142
|
-
const response = await handleSubscribeToThreads({
|
|
143
|
-
runtime,
|
|
144
|
-
request: new Request("https://example.com/threads/subscribe", {
|
|
145
|
-
method: "POST",
|
|
146
|
-
}),
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
expect(response.status).toBe(500);
|
|
150
|
-
expect(intelligence.ɵsubscribeToThreads).not.toHaveBeenCalled();
|
|
151
|
-
// The handler must log the auth failure so an operator looking at
|
|
152
|
-
// the runtime logs sees why the request 500ed. Asserting the
|
|
153
|
-
// operation name ("identifying intelligence user") catches a
|
|
154
|
-
// regression that swaps the diagnostic for a generic placeholder.
|
|
155
|
-
// The throw originates inside `resolveIntelligenceUser`, which
|
|
156
|
-
// logs and returns 500 before `subscribeToThreads` is reached.
|
|
157
|
-
expect(errorSpy).toHaveBeenCalledWith(
|
|
158
|
-
expect.stringContaining("Error identifying intelligence user"),
|
|
159
|
-
expect.any(Error),
|
|
160
|
-
);
|
|
161
|
-
} finally {
|
|
162
|
-
errorSpy.mockRestore();
|
|
163
|
-
}
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
it("updates, archives, and deletes threads using identifyUser and ignoring request userId", async () => {
|
|
167
|
-
const intelligence = {
|
|
168
|
-
updateThread: vi
|
|
169
|
-
.fn()
|
|
170
|
-
.mockResolvedValue({ id: "thread-1", name: "Renamed" }),
|
|
171
|
-
archiveThread: vi.fn().mockResolvedValue(undefined),
|
|
172
|
-
deleteThread: vi.fn().mockResolvedValue(undefined),
|
|
173
|
-
};
|
|
174
|
-
const identifyUser = createIdentifyUser();
|
|
175
|
-
const runtime = createIntelligenceRuntime({ intelligence, identifyUser });
|
|
176
|
-
const mutationBody = {
|
|
177
|
-
userId: "ignored-user",
|
|
178
|
-
agentId: "agent-1",
|
|
179
|
-
name: "Renamed",
|
|
180
|
-
};
|
|
181
|
-
|
|
182
|
-
const updateRequest = createMutationRequest(
|
|
183
|
-
"/threads/thread-1",
|
|
184
|
-
"PATCH",
|
|
185
|
-
mutationBody,
|
|
186
|
-
);
|
|
187
|
-
const updateResponse = await handleUpdateThread({
|
|
188
|
-
runtime,
|
|
189
|
-
request: updateRequest,
|
|
190
|
-
threadId: "thread-1",
|
|
191
|
-
});
|
|
192
|
-
expect(updateResponse.status).toBe(200);
|
|
193
|
-
expect(identifyUser).toHaveBeenCalledWith(updateRequest);
|
|
194
|
-
expect(intelligence.updateThread).toHaveBeenCalledWith({
|
|
195
|
-
threadId: "thread-1",
|
|
196
|
-
userId: "user-1",
|
|
197
|
-
agentId: "agent-1",
|
|
198
|
-
updates: { name: "Renamed" },
|
|
199
|
-
});
|
|
200
|
-
|
|
201
|
-
const archiveRequest = createMutationRequest(
|
|
202
|
-
"/threads/thread-1/archive",
|
|
203
|
-
"POST",
|
|
204
|
-
mutationBody,
|
|
205
|
-
);
|
|
206
|
-
const archiveResponse = await handleArchiveThread({
|
|
207
|
-
runtime,
|
|
208
|
-
request: archiveRequest,
|
|
209
|
-
threadId: "thread-1",
|
|
210
|
-
});
|
|
211
|
-
expect(archiveResponse.status).toBe(200);
|
|
212
|
-
expect(identifyUser).toHaveBeenCalledWith(archiveRequest);
|
|
213
|
-
expect(intelligence.archiveThread).toHaveBeenCalledWith({
|
|
214
|
-
threadId: "thread-1",
|
|
215
|
-
userId: "user-1",
|
|
216
|
-
agentId: "agent-1",
|
|
217
|
-
});
|
|
218
|
-
|
|
219
|
-
const deleteRequest = createMutationRequest(
|
|
220
|
-
"/threads/thread-1",
|
|
221
|
-
"DELETE",
|
|
222
|
-
mutationBody,
|
|
223
|
-
);
|
|
224
|
-
const deleteResponse = await handleDeleteThread({
|
|
225
|
-
runtime,
|
|
226
|
-
request: deleteRequest,
|
|
227
|
-
threadId: "thread-1",
|
|
228
|
-
});
|
|
229
|
-
expect(deleteResponse.status).toBe(200);
|
|
230
|
-
expect(identifyUser).toHaveBeenCalledWith(deleteRequest);
|
|
231
|
-
expect(identifyUser).toHaveBeenCalledTimes(3);
|
|
232
|
-
expect(intelligence.deleteThread).toHaveBeenCalledWith({
|
|
233
|
-
threadId: "thread-1",
|
|
234
|
-
userId: "user-1",
|
|
235
|
-
agentId: "agent-1",
|
|
236
|
-
});
|
|
237
|
-
});
|
|
238
|
-
|
|
239
|
-
it("subscribes to threads using identifyUser", async () => {
|
|
240
|
-
const intelligence = {
|
|
241
|
-
ɵsubscribeToThreads: vi
|
|
242
|
-
.fn()
|
|
243
|
-
.mockResolvedValue({ joinToken: "join-token-1" }),
|
|
244
|
-
};
|
|
245
|
-
const identifyUser = createIdentifyUser();
|
|
246
|
-
const runtime = createIntelligenceRuntime({ intelligence, identifyUser });
|
|
247
|
-
const request = new Request("https://example.com/threads/subscribe", {
|
|
248
|
-
method: "POST",
|
|
249
|
-
});
|
|
250
|
-
|
|
251
|
-
const response = await handleSubscribeToThreads({
|
|
252
|
-
runtime,
|
|
253
|
-
request,
|
|
254
|
-
});
|
|
255
|
-
|
|
256
|
-
expect(response.status).toBe(200);
|
|
257
|
-
expect(identifyUser).toHaveBeenCalledTimes(1);
|
|
258
|
-
expect(identifyUser).toHaveBeenCalledWith(request);
|
|
259
|
-
await expect(response.json()).resolves.toEqual({
|
|
260
|
-
joinToken: "join-token-1",
|
|
261
|
-
});
|
|
262
|
-
expect(intelligence.ɵsubscribeToThreads).toHaveBeenCalledWith({
|
|
263
|
-
userId: "user-1",
|
|
264
|
-
});
|
|
265
|
-
});
|
|
266
|
-
|
|
267
|
-
it("returns 400 when agentId is invalid for thread mutations", async () => {
|
|
268
|
-
const intelligence = {
|
|
269
|
-
updateThread: vi.fn(),
|
|
270
|
-
};
|
|
271
|
-
const runtime = createIntelligenceRuntime({ intelligence });
|
|
272
|
-
|
|
273
|
-
const response = await handleUpdateThread({
|
|
274
|
-
runtime,
|
|
275
|
-
request: new Request("https://example.com/threads/thread-1", {
|
|
276
|
-
method: "PATCH",
|
|
277
|
-
headers: { "Content-Type": "application/json" },
|
|
278
|
-
body: JSON.stringify({ agentId: "" }),
|
|
279
|
-
}),
|
|
280
|
-
threadId: "thread-1",
|
|
281
|
-
});
|
|
282
|
-
|
|
283
|
-
expect(response.status).toBe(400);
|
|
284
|
-
expect(intelligence.updateThread).not.toHaveBeenCalled();
|
|
285
|
-
});
|
|
286
|
-
|
|
287
|
-
it("returns 400 when identifyUser returns an invalid id for thread mutations", async () => {
|
|
288
|
-
const intelligence = {
|
|
289
|
-
updateThread: vi.fn(),
|
|
290
|
-
archiveThread: vi.fn(),
|
|
291
|
-
deleteThread: vi.fn(),
|
|
292
|
-
};
|
|
293
|
-
const runtime = createIntelligenceRuntime({
|
|
294
|
-
intelligence,
|
|
295
|
-
identifyUser: vi.fn().mockResolvedValue({ id: "", name: "User" }),
|
|
296
|
-
});
|
|
297
|
-
|
|
298
|
-
const updateResponse = await handleUpdateThread({
|
|
299
|
-
runtime,
|
|
300
|
-
request: createMutationRequest("/threads/thread-1", "PATCH", {
|
|
301
|
-
agentId: "agent-1",
|
|
302
|
-
}),
|
|
303
|
-
threadId: "thread-1",
|
|
304
|
-
});
|
|
305
|
-
expect(updateResponse.status).toBe(400);
|
|
306
|
-
|
|
307
|
-
const archiveResponse = await handleArchiveThread({
|
|
308
|
-
runtime,
|
|
309
|
-
request: createMutationRequest("/threads/thread-1/archive", "POST", {
|
|
310
|
-
agentId: "agent-1",
|
|
311
|
-
}),
|
|
312
|
-
threadId: "thread-1",
|
|
313
|
-
});
|
|
314
|
-
expect(archiveResponse.status).toBe(400);
|
|
315
|
-
|
|
316
|
-
const deleteResponse = await handleDeleteThread({
|
|
317
|
-
runtime,
|
|
318
|
-
request: createMutationRequest("/threads/thread-1", "DELETE", {
|
|
319
|
-
agentId: "agent-1",
|
|
320
|
-
}),
|
|
321
|
-
threadId: "thread-1",
|
|
322
|
-
});
|
|
323
|
-
expect(deleteResponse.status).toBe(400);
|
|
324
|
-
|
|
325
|
-
expect(intelligence.updateThread).not.toHaveBeenCalled();
|
|
326
|
-
expect(intelligence.archiveThread).not.toHaveBeenCalled();
|
|
327
|
-
expect(intelligence.deleteThread).not.toHaveBeenCalled();
|
|
328
|
-
});
|
|
329
|
-
|
|
330
|
-
it("returns 400 when identifyUser returns an invalid name for thread mutations", async () => {
|
|
331
|
-
const intelligence = {
|
|
332
|
-
updateThread: vi.fn(),
|
|
333
|
-
archiveThread: vi.fn(),
|
|
334
|
-
deleteThread: vi.fn(),
|
|
335
|
-
};
|
|
336
|
-
const runtime = createIntelligenceRuntime({
|
|
337
|
-
intelligence,
|
|
338
|
-
identifyUser: vi.fn().mockResolvedValue({ id: "user-1", name: "" }),
|
|
339
|
-
});
|
|
340
|
-
|
|
341
|
-
const updateResponse = await handleUpdateThread({
|
|
342
|
-
runtime,
|
|
343
|
-
request: createMutationRequest("/threads/thread-1", "PATCH", {
|
|
344
|
-
agentId: "agent-1",
|
|
345
|
-
}),
|
|
346
|
-
threadId: "thread-1",
|
|
347
|
-
});
|
|
348
|
-
expect(updateResponse.status).toBe(400);
|
|
349
|
-
|
|
350
|
-
const archiveResponse = await handleArchiveThread({
|
|
351
|
-
runtime,
|
|
352
|
-
request: createMutationRequest("/threads/thread-1/archive", "POST", {
|
|
353
|
-
agentId: "agent-1",
|
|
354
|
-
}),
|
|
355
|
-
threadId: "thread-1",
|
|
356
|
-
});
|
|
357
|
-
expect(archiveResponse.status).toBe(400);
|
|
358
|
-
|
|
359
|
-
const deleteResponse = await handleDeleteThread({
|
|
360
|
-
runtime,
|
|
361
|
-
request: createMutationRequest("/threads/thread-1", "DELETE", {
|
|
362
|
-
agentId: "agent-1",
|
|
363
|
-
}),
|
|
364
|
-
threadId: "thread-1",
|
|
365
|
-
});
|
|
366
|
-
expect(deleteResponse.status).toBe(400);
|
|
367
|
-
|
|
368
|
-
expect(intelligence.updateThread).not.toHaveBeenCalled();
|
|
369
|
-
expect(intelligence.archiveThread).not.toHaveBeenCalled();
|
|
370
|
-
expect(intelligence.deleteThread).not.toHaveBeenCalled();
|
|
371
|
-
});
|
|
372
|
-
|
|
373
|
-
it("returns 422 when intelligence is not configured for thread mutations", async () => {
|
|
374
|
-
const runtime = new CopilotRuntime({ agents: {} });
|
|
375
|
-
const buildRequest = (method: "PATCH" | "POST" | "DELETE") =>
|
|
376
|
-
new Request("https://example.com/threads/thread-1", {
|
|
377
|
-
method,
|
|
378
|
-
headers: { "Content-Type": "application/json" },
|
|
379
|
-
body: JSON.stringify({ userId: "user-1", agentId: "agent-1" }),
|
|
380
|
-
});
|
|
381
|
-
|
|
382
|
-
const updateResponse = await handleUpdateThread({
|
|
383
|
-
runtime,
|
|
384
|
-
request: buildRequest("PATCH"),
|
|
385
|
-
threadId: "thread-1",
|
|
386
|
-
});
|
|
387
|
-
expect(updateResponse.status).toBe(422);
|
|
388
|
-
|
|
389
|
-
const archiveResponse = await handleArchiveThread({
|
|
390
|
-
runtime,
|
|
391
|
-
request: buildRequest("POST"),
|
|
392
|
-
threadId: "thread-1",
|
|
393
|
-
});
|
|
394
|
-
expect(archiveResponse.status).toBe(422);
|
|
395
|
-
|
|
396
|
-
// Use the real DELETE method here — Request.clone() preserves the
|
|
397
|
-
// method of the original, so re-using a POST clone for the delete
|
|
398
|
-
// path silently exercises the wrong verb.
|
|
399
|
-
const deleteResponse = await handleDeleteThread({
|
|
400
|
-
runtime,
|
|
401
|
-
request: buildRequest("DELETE"),
|
|
402
|
-
threadId: "thread-1",
|
|
403
|
-
});
|
|
404
|
-
expect(deleteResponse.status).toBe(422);
|
|
405
|
-
});
|
|
406
|
-
|
|
407
|
-
describe("handleClearThreads", () => {
|
|
408
|
-
// handleClearThreads is intentionally synchronous — it has no I/O on
|
|
409
|
-
// either branch (in-memory map mutation or platform no-op), so it
|
|
410
|
-
// returns a plain Response rather than a Promise. The other handlers
|
|
411
|
-
// in this suite are awaited because they either parse JSON or hit
|
|
412
|
-
// the Intelligence platform; this one does neither.
|
|
413
|
-
it("clears in-memory threads and returns 204 for InMemoryAgentRunner", () => {
|
|
414
|
-
const runner = new InMemoryAgentRunner();
|
|
415
|
-
const clearThreadsSpy = vi.spyOn(runner, "clearThreads");
|
|
416
|
-
const runtime = new CopilotRuntime({ agents: {}, runner });
|
|
417
|
-
|
|
418
|
-
const response = handleClearThreads({
|
|
419
|
-
runtime,
|
|
420
|
-
request: new Request("https://example.com/threads"),
|
|
421
|
-
});
|
|
422
|
-
|
|
423
|
-
// Lock the synchronous contract: a regression that starts awaiting
|
|
424
|
-
// I/O inside this handler must update the call sites that rely on
|
|
425
|
-
// the synchronous return shape. Asserting `not.toBeInstanceOf(Promise)`
|
|
426
|
-
// catches that drift at runtime.
|
|
427
|
-
expect(response).not.toBeInstanceOf(Promise);
|
|
428
|
-
expect(response.status).toBe(204);
|
|
429
|
-
expect(clearThreadsSpy).toHaveBeenCalledTimes(1);
|
|
430
|
-
});
|
|
431
|
-
|
|
432
|
-
it("returns 204 without touching state when intelligence runtime is configured", () => {
|
|
433
|
-
const intelligence = { listThreads: vi.fn() };
|
|
434
|
-
const runtime = createIntelligenceRuntime({ intelligence });
|
|
435
|
-
|
|
436
|
-
const response = handleClearThreads({
|
|
437
|
-
runtime,
|
|
438
|
-
request: new Request("https://example.com/threads"),
|
|
439
|
-
});
|
|
440
|
-
|
|
441
|
-
// Same synchronous-contract guard as the in-memory branch above.
|
|
442
|
-
expect(response).not.toBeInstanceOf(Promise);
|
|
443
|
-
expect(response.status).toBe(204);
|
|
444
|
-
expect(intelligence.listThreads).not.toHaveBeenCalled();
|
|
445
|
-
});
|
|
446
|
-
});
|
|
447
|
-
|
|
448
|
-
describe("handleGetThreadMessages", () => {
|
|
449
|
-
it("returns messages from the in-memory runner for a known thread", async () => {
|
|
450
|
-
const runner = new InMemoryAgentRunner();
|
|
451
|
-
vi.spyOn(runner, "getThreadMessages").mockReturnValue([
|
|
452
|
-
{ id: "m1", role: "user", content: "hello" } as never,
|
|
453
|
-
{ id: "m2", role: "assistant", content: "hi there" } as never,
|
|
454
|
-
]);
|
|
455
|
-
const runtime = new CopilotRuntime({ agents: {}, runner });
|
|
456
|
-
|
|
457
|
-
const response = await handleGetThreadMessages({
|
|
458
|
-
runtime,
|
|
459
|
-
request: new Request("https://example.com/threads/thread-1/messages"),
|
|
460
|
-
threadId: "thread-1",
|
|
461
|
-
});
|
|
462
|
-
|
|
463
|
-
expect(response.status).toBe(200);
|
|
464
|
-
const body = await response.json();
|
|
465
|
-
expect(body.messages).toHaveLength(2);
|
|
466
|
-
expect(body.messages[0]).toMatchObject({
|
|
467
|
-
id: "m1",
|
|
468
|
-
role: "user",
|
|
469
|
-
content: "hello",
|
|
470
|
-
});
|
|
471
|
-
expect(body.messages[1]).toMatchObject({
|
|
472
|
-
id: "m2",
|
|
473
|
-
role: "assistant",
|
|
474
|
-
content: "hi there",
|
|
475
|
-
});
|
|
476
|
-
});
|
|
477
|
-
|
|
478
|
-
it("returns empty messages for an unknown threadId", async () => {
|
|
479
|
-
const runtime = new CopilotRuntime({ agents: {} });
|
|
480
|
-
|
|
481
|
-
const response = await handleGetThreadMessages({
|
|
482
|
-
runtime,
|
|
483
|
-
request: new Request(
|
|
484
|
-
"https://example.com/threads/nonexistent/messages",
|
|
485
|
-
),
|
|
486
|
-
threadId: "nonexistent",
|
|
487
|
-
});
|
|
488
|
-
|
|
489
|
-
expect(response.status).toBe(200);
|
|
490
|
-
const body = await response.json();
|
|
491
|
-
expect(body.messages).toEqual([]);
|
|
492
|
-
});
|
|
493
|
-
|
|
494
|
-
it("delegates to intelligence.getThreadMessages when intelligence is configured", async () => {
|
|
495
|
-
const intelligence = {
|
|
496
|
-
getThreadMessages: vi
|
|
497
|
-
.fn()
|
|
498
|
-
.mockResolvedValue({ messages: [{ id: "m1" }] }),
|
|
499
|
-
};
|
|
500
|
-
const identifyUser = createIdentifyUser();
|
|
501
|
-
const runtime = createIntelligenceRuntime({ intelligence, identifyUser });
|
|
502
|
-
|
|
503
|
-
const response = await handleGetThreadMessages({
|
|
504
|
-
runtime,
|
|
505
|
-
request: new Request("https://example.com/threads/thread-1/messages"),
|
|
506
|
-
threadId: "thread-1",
|
|
507
|
-
});
|
|
508
|
-
|
|
509
|
-
expect(response.status).toBe(200);
|
|
510
|
-
// The handler must propagate the platform's response body verbatim —
|
|
511
|
-
// assert it explicitly so a regression that swaps in a stubbed body
|
|
512
|
-
// (e.g. `{ messages: [] }`) is caught.
|
|
513
|
-
const body = await response.json();
|
|
514
|
-
expect(body.messages).toEqual([{ id: "m1" }]);
|
|
515
|
-
expect(intelligence.getThreadMessages).toHaveBeenCalledWith({
|
|
516
|
-
threadId: "thread-1",
|
|
517
|
-
});
|
|
518
|
-
expect(identifyUser).toHaveBeenCalledTimes(1);
|
|
519
|
-
expect(identifyUser).toHaveBeenCalledWith(
|
|
520
|
-
expect.objectContaining({ url: expect.stringContaining("thread-1") }),
|
|
521
|
-
);
|
|
522
|
-
});
|
|
523
|
-
|
|
524
|
-
it("returns 500 when identifyUser throws for getThreadMessages", async () => {
|
|
525
|
-
const intelligence = {
|
|
526
|
-
getThreadMessages: vi.fn(),
|
|
527
|
-
};
|
|
528
|
-
const runtime = createIntelligenceRuntime({
|
|
529
|
-
intelligence,
|
|
530
|
-
identifyUser: vi.fn().mockRejectedValue(new Error("auth failed")),
|
|
531
|
-
});
|
|
532
|
-
// resolveIntelligenceUser logs via console.error on rejection — silence
|
|
533
|
-
// it for the duration of this test so the suite output stays clean,
|
|
534
|
-
// matching the pattern used in the subscribe-throw test above.
|
|
535
|
-
const errorSpy = vi.spyOn(console, "error").mockImplementation(() => {});
|
|
536
|
-
|
|
537
|
-
try {
|
|
538
|
-
const response = await handleGetThreadMessages({
|
|
539
|
-
runtime,
|
|
540
|
-
request: new Request("https://example.com/threads/thread-1/messages"),
|
|
541
|
-
threadId: "thread-1",
|
|
542
|
-
});
|
|
543
|
-
|
|
544
|
-
expect(response.status).toBe(500);
|
|
545
|
-
expect(intelligence.getThreadMessages).not.toHaveBeenCalled();
|
|
546
|
-
} finally {
|
|
547
|
-
errorSpy.mockRestore();
|
|
548
|
-
}
|
|
549
|
-
});
|
|
550
|
-
|
|
551
|
-
it("returns 422 when neither in-memory nor intelligence is configured", async () => {
|
|
552
|
-
// A CopilotRuntime with no runner defaults to InMemoryAgentRunner,
|
|
553
|
-
// so simulate a non-InMemory, non-intelligence setup via a custom runner stub.
|
|
554
|
-
// Use the intelligence path but omit intelligence config.
|
|
555
|
-
const runtime = createIntelligenceRuntime({ intelligence: undefined });
|
|
556
|
-
|
|
557
|
-
const response = await handleGetThreadMessages({
|
|
558
|
-
runtime,
|
|
559
|
-
request: new Request("https://example.com/threads/thread-1/messages"),
|
|
560
|
-
threadId: "thread-1",
|
|
561
|
-
});
|
|
562
|
-
|
|
563
|
-
expect(response.status).toBe(422);
|
|
564
|
-
});
|
|
565
|
-
|
|
566
|
-
it("maps tool-call and tool-result messages from the in-memory runner without as-never casts", async () => {
|
|
567
|
-
const runner = new InMemoryAgentRunner();
|
|
568
|
-
const messages = [
|
|
569
|
-
{
|
|
570
|
-
id: "m1",
|
|
571
|
-
role: "assistant" as const,
|
|
572
|
-
toolCalls: [
|
|
573
|
-
{
|
|
574
|
-
id: "tc-1",
|
|
575
|
-
type: "function" as const,
|
|
576
|
-
function: { name: "get_weather", arguments: '{"city":"Paris"}' },
|
|
577
|
-
},
|
|
578
|
-
],
|
|
579
|
-
},
|
|
580
|
-
{
|
|
581
|
-
id: "m2",
|
|
582
|
-
role: "tool" as const,
|
|
583
|
-
toolCallId: "tc-1",
|
|
584
|
-
content: '{"temp":18}',
|
|
585
|
-
},
|
|
586
|
-
];
|
|
587
|
-
vi.spyOn(runner, "getThreadMessages").mockReturnValue(messages);
|
|
588
|
-
const runtime = new CopilotRuntime({ agents: {}, runner });
|
|
589
|
-
|
|
590
|
-
const response = await handleGetThreadMessages({
|
|
591
|
-
runtime,
|
|
592
|
-
request: new Request("https://example.com/threads/thread-1/messages"),
|
|
593
|
-
threadId: "thread-1",
|
|
594
|
-
});
|
|
595
|
-
|
|
596
|
-
expect(response.status).toBe(200);
|
|
597
|
-
const body = await response.json();
|
|
598
|
-
expect(body.messages).toHaveLength(2);
|
|
599
|
-
|
|
600
|
-
const assistantMsg = body.messages[0];
|
|
601
|
-
expect(assistantMsg.role).toBe("assistant");
|
|
602
|
-
expect(assistantMsg.toolCalls).toHaveLength(1);
|
|
603
|
-
expect(assistantMsg.toolCalls[0]).toMatchObject({
|
|
604
|
-
id: "tc-1",
|
|
605
|
-
name: "get_weather",
|
|
606
|
-
args: '{"city":"Paris"}',
|
|
607
|
-
});
|
|
608
|
-
|
|
609
|
-
const toolResultMsg = body.messages[1];
|
|
610
|
-
expect(toolResultMsg.role).toBe("tool");
|
|
611
|
-
expect(toolResultMsg.toolCallId).toBe("tc-1");
|
|
612
|
-
expect(toolResultMsg.content).toBe('{"temp":18}');
|
|
613
|
-
});
|
|
614
|
-
});
|
|
615
|
-
|
|
616
|
-
it("returns 422 when intelligence is not configured for thread subscription", async () => {
|
|
617
|
-
const runtime = new CopilotRuntime({ agents: {} });
|
|
618
|
-
|
|
619
|
-
const response = await handleSubscribeToThreads({
|
|
620
|
-
runtime,
|
|
621
|
-
request: new Request("https://example.com/threads/subscribe", {
|
|
622
|
-
method: "POST",
|
|
623
|
-
}),
|
|
624
|
-
});
|
|
625
|
-
|
|
626
|
-
expect(response.status).toBe(422);
|
|
627
|
-
});
|
|
628
|
-
|
|
629
|
-
it("forwards includeArchived, limit, and cursor query params to listThreads", async () => {
|
|
630
|
-
const intelligence = {
|
|
631
|
-
listThreads: vi.fn().mockResolvedValue({
|
|
632
|
-
threads: [{ id: "thread-1", name: "Hello" }],
|
|
633
|
-
joinCode: "jc-1",
|
|
634
|
-
nextCursor: "cursor-xyz",
|
|
635
|
-
}),
|
|
636
|
-
};
|
|
637
|
-
const identifyUser = createIdentifyUser();
|
|
638
|
-
const runtime = createIntelligenceRuntime({ intelligence, identifyUser });
|
|
639
|
-
const request = new Request(
|
|
640
|
-
"https://example.com/threads?agentId=agent-1&includeArchived=true&limit=10&cursor=prev-cursor",
|
|
641
|
-
);
|
|
642
|
-
|
|
643
|
-
const response = await handleListThreads({ runtime, request });
|
|
644
|
-
|
|
645
|
-
expect(response.status).toBe(200);
|
|
646
|
-
expect(intelligence.listThreads).toHaveBeenCalledWith({
|
|
647
|
-
userId: "user-1",
|
|
648
|
-
agentId: "agent-1",
|
|
649
|
-
includeArchived: true,
|
|
650
|
-
limit: 10,
|
|
651
|
-
cursor: "prev-cursor",
|
|
652
|
-
});
|
|
653
|
-
const body = await response.json();
|
|
654
|
-
expect(body.nextCursor).toBe("cursor-xyz");
|
|
655
|
-
});
|
|
656
|
-
|
|
657
|
-
it("omits includeArchived, limit, and cursor when not provided", async () => {
|
|
658
|
-
const intelligence = {
|
|
659
|
-
listThreads: vi.fn().mockResolvedValue({
|
|
660
|
-
threads: [],
|
|
661
|
-
joinCode: "jc-1",
|
|
662
|
-
}),
|
|
663
|
-
};
|
|
664
|
-
const identifyUser = createIdentifyUser();
|
|
665
|
-
const runtime = createIntelligenceRuntime({ intelligence, identifyUser });
|
|
666
|
-
const request = new Request("https://example.com/threads?agentId=agent-1");
|
|
667
|
-
|
|
668
|
-
await handleListThreads({ runtime, request });
|
|
669
|
-
|
|
670
|
-
expect(intelligence.listThreads).toHaveBeenCalledWith({
|
|
671
|
-
userId: "user-1",
|
|
672
|
-
agentId: "agent-1",
|
|
673
|
-
});
|
|
674
|
-
});
|
|
675
|
-
|
|
676
|
-
describe("handleGetThreadEvents", () => {
|
|
677
|
-
it("returns events from the in-memory runner for a known thread", async () => {
|
|
678
|
-
const runner = new InMemoryAgentRunner();
|
|
679
|
-
const fakeEvents = [
|
|
680
|
-
{ type: "RUN_STARTED", runId: "r1", threadId: "thread-1" },
|
|
681
|
-
{
|
|
682
|
-
type: "TEXT_MESSAGE_START",
|
|
683
|
-
messageId: "m1",
|
|
684
|
-
role: "assistant",
|
|
685
|
-
},
|
|
686
|
-
];
|
|
687
|
-
vi.spyOn(runner, "getThreadEvents").mockReturnValue(fakeEvents as never);
|
|
688
|
-
const runtime = new CopilotRuntime({ agents: {}, runner });
|
|
689
|
-
|
|
690
|
-
const response = await handleGetThreadEvents({
|
|
691
|
-
runtime,
|
|
692
|
-
request: new Request("https://example.com/threads/thread-1/events"),
|
|
693
|
-
threadId: "thread-1",
|
|
694
|
-
});
|
|
695
|
-
|
|
696
|
-
expect(response.status).toBe(200);
|
|
697
|
-
const body = await response.json();
|
|
698
|
-
expect(body.events).toHaveLength(2);
|
|
699
|
-
expect(body.events[0]).toMatchObject({ type: "RUN_STARTED" });
|
|
700
|
-
});
|
|
701
|
-
|
|
702
|
-
it("returns empty events for an unknown threadId via the in-memory runner", async () => {
|
|
703
|
-
const runtime = new CopilotRuntime({ agents: {} });
|
|
704
|
-
|
|
705
|
-
const response = await handleGetThreadEvents({
|
|
706
|
-
runtime,
|
|
707
|
-
request: new Request("https://example.com/threads/nonexistent/events"),
|
|
708
|
-
threadId: "nonexistent",
|
|
709
|
-
});
|
|
710
|
-
|
|
711
|
-
expect(response.status).toBe(200);
|
|
712
|
-
const body = await response.json();
|
|
713
|
-
expect(body.events).toEqual([]);
|
|
714
|
-
});
|
|
715
|
-
|
|
716
|
-
it("delegates to intelligence.getThreadEvents when intelligence is configured", async () => {
|
|
717
|
-
// Mirrors the platform's `_inspect/threads/:id/events` response shape
|
|
718
|
-
// (Intelligence PR #144). The handler strips the platform-internal
|
|
719
|
-
// `decodeErrorRowIds` and `truncated` fields before returning, so the
|
|
720
|
-
// wire shape stays `{ events }` to match the in-memory branch.
|
|
721
|
-
const platformEvents = [
|
|
722
|
-
{ type: "RUN_STARTED", threadId: "thread-1", runId: "run-a" },
|
|
723
|
-
{ type: "TEXT_MESSAGE_CONTENT", messageId: "m1", delta: "hello" },
|
|
724
|
-
];
|
|
725
|
-
const intelligence = {
|
|
726
|
-
getThreadEvents: vi.fn().mockResolvedValue({
|
|
727
|
-
events: platformEvents,
|
|
728
|
-
decodeErrorRowIds: [],
|
|
729
|
-
truncated: false,
|
|
730
|
-
}),
|
|
731
|
-
};
|
|
732
|
-
const identifyUser = createIdentifyUser();
|
|
733
|
-
const runtime = createIntelligenceRuntime({ intelligence, identifyUser });
|
|
734
|
-
|
|
735
|
-
const response = await handleGetThreadEvents({
|
|
736
|
-
runtime,
|
|
737
|
-
request: new Request("https://example.com/threads/thread-1/events"),
|
|
738
|
-
threadId: "thread-1",
|
|
739
|
-
});
|
|
740
|
-
|
|
741
|
-
expect(response.status).toBe(200);
|
|
742
|
-
expect(intelligence.getThreadEvents).toHaveBeenCalledWith({
|
|
743
|
-
threadId: "thread-1",
|
|
744
|
-
});
|
|
745
|
-
expect(identifyUser).toHaveBeenCalledTimes(1);
|
|
746
|
-
const body = await response.json();
|
|
747
|
-
expect(body).toEqual({ events: platformEvents });
|
|
748
|
-
});
|
|
749
|
-
|
|
750
|
-
it("returns 500 when intelligence.getThreadEvents throws", async () => {
|
|
751
|
-
const intelligence = {
|
|
752
|
-
getThreadEvents: vi
|
|
753
|
-
.fn()
|
|
754
|
-
.mockRejectedValue(new Error("platform unavailable")),
|
|
755
|
-
};
|
|
756
|
-
const runtime = createIntelligenceRuntime({ intelligence });
|
|
757
|
-
|
|
758
|
-
const errorSpy = vi.spyOn(console, "error").mockImplementation(() => {});
|
|
759
|
-
try {
|
|
760
|
-
const response = await handleGetThreadEvents({
|
|
761
|
-
runtime,
|
|
762
|
-
request: new Request("https://example.com/threads/thread-1/events"),
|
|
763
|
-
threadId: "thread-1",
|
|
764
|
-
});
|
|
765
|
-
|
|
766
|
-
expect(response.status).toBe(500);
|
|
767
|
-
expect(intelligence.getThreadEvents).toHaveBeenCalledTimes(1);
|
|
768
|
-
} finally {
|
|
769
|
-
errorSpy.mockRestore();
|
|
770
|
-
}
|
|
771
|
-
});
|
|
772
|
-
|
|
773
|
-
it("returns 500 when the runner throws", async () => {
|
|
774
|
-
const runner = new InMemoryAgentRunner();
|
|
775
|
-
vi.spyOn(runner, "getThreadEvents").mockImplementation(() => {
|
|
776
|
-
throw new Error("boom");
|
|
777
|
-
});
|
|
778
|
-
const runtime = new CopilotRuntime({ agents: {}, runner });
|
|
779
|
-
|
|
780
|
-
const response = await handleGetThreadEvents({
|
|
781
|
-
runtime,
|
|
782
|
-
request: new Request("https://example.com/threads/thread-1/events"),
|
|
783
|
-
threadId: "thread-1",
|
|
784
|
-
});
|
|
785
|
-
|
|
786
|
-
expect(response.status).toBe(500);
|
|
787
|
-
});
|
|
788
|
-
});
|
|
789
|
-
|
|
790
|
-
describe("handleGetThreadState", () => {
|
|
791
|
-
it("returns the state from the in-memory runner", async () => {
|
|
792
|
-
const runner = new InMemoryAgentRunner();
|
|
793
|
-
const snapshot = { counter: 3, label: "alpha" };
|
|
794
|
-
vi.spyOn(runner, "getThreadState").mockReturnValue(snapshot as never);
|
|
795
|
-
const runtime = new CopilotRuntime({ agents: {}, runner });
|
|
796
|
-
|
|
797
|
-
const response = await handleGetThreadState({
|
|
798
|
-
runtime,
|
|
799
|
-
request: new Request("https://example.com/threads/thread-1/state"),
|
|
800
|
-
threadId: "thread-1",
|
|
801
|
-
});
|
|
802
|
-
|
|
803
|
-
expect(response.status).toBe(200);
|
|
804
|
-
const body = await response.json();
|
|
805
|
-
expect(body.state).toEqual(snapshot);
|
|
806
|
-
});
|
|
807
|
-
|
|
808
|
-
it("returns state:null when the runner has no snapshot for the thread", async () => {
|
|
809
|
-
const runtime = new CopilotRuntime({ agents: {} });
|
|
810
|
-
|
|
811
|
-
const response = await handleGetThreadState({
|
|
812
|
-
runtime,
|
|
813
|
-
request: new Request("https://example.com/threads/nonexistent/state"),
|
|
814
|
-
threadId: "nonexistent",
|
|
815
|
-
});
|
|
816
|
-
|
|
817
|
-
expect(response.status).toBe(200);
|
|
818
|
-
const body = await response.json();
|
|
819
|
-
expect(body.state).toBeNull();
|
|
820
|
-
});
|
|
821
|
-
|
|
822
|
-
it("delegates to intelligence.getThreadState and returns the snapshot when intelligence is configured", async () => {
|
|
823
|
-
// Platform returns a discriminated `ThreadStateResult` (Intelligence
|
|
824
|
-
// PR #144). The `snapshot` arm carries the folded current state; the
|
|
825
|
-
// handler flattens it to `{ state }` so the inspector consumes the
|
|
826
|
-
// same shape as the in-memory branch.
|
|
827
|
-
const snapshot = { counter: 7, label: "intel" };
|
|
828
|
-
const intelligence = {
|
|
829
|
-
getThreadState: vi.fn().mockResolvedValue({
|
|
830
|
-
kind: "snapshot",
|
|
831
|
-
state: snapshot,
|
|
832
|
-
skippedDeltas: 0,
|
|
833
|
-
}),
|
|
834
|
-
};
|
|
835
|
-
const identifyUser = createIdentifyUser();
|
|
836
|
-
const runtime = createIntelligenceRuntime({ intelligence, identifyUser });
|
|
837
|
-
|
|
838
|
-
const response = await handleGetThreadState({
|
|
839
|
-
runtime,
|
|
840
|
-
request: new Request("https://example.com/threads/thread-1/state"),
|
|
841
|
-
threadId: "thread-1",
|
|
842
|
-
});
|
|
843
|
-
|
|
844
|
-
expect(response.status).toBe(200);
|
|
845
|
-
expect(intelligence.getThreadState).toHaveBeenCalledWith({
|
|
846
|
-
threadId: "thread-1",
|
|
847
|
-
});
|
|
848
|
-
expect(identifyUser).toHaveBeenCalledTimes(1);
|
|
849
|
-
const body = await response.json();
|
|
850
|
-
expect(body.state).toEqual(snapshot);
|
|
851
|
-
});
|
|
852
|
-
|
|
853
|
-
it("returns state:null for the no-snapshot kind from intelligence", async () => {
|
|
854
|
-
const intelligence = {
|
|
855
|
-
getThreadState: vi.fn().mockResolvedValue({ kind: "no-snapshot" }),
|
|
856
|
-
};
|
|
857
|
-
const runtime = createIntelligenceRuntime({ intelligence });
|
|
858
|
-
|
|
859
|
-
const response = await handleGetThreadState({
|
|
860
|
-
runtime,
|
|
861
|
-
request: new Request("https://example.com/threads/thread-1/state"),
|
|
862
|
-
threadId: "thread-1",
|
|
863
|
-
});
|
|
864
|
-
|
|
865
|
-
expect(response.status).toBe(200);
|
|
866
|
-
const body = await response.json();
|
|
867
|
-
expect(body.state).toBeNull();
|
|
868
|
-
});
|
|
869
|
-
|
|
870
|
-
it("returns state:null for the snapshot-decode-error kind from intelligence", async () => {
|
|
871
|
-
// The platform logs the underlying decode failure server-side; from
|
|
872
|
-
// the inspector's perspective, "no readable state" is the same UX as
|
|
873
|
-
// "no snapshot yet."
|
|
874
|
-
const intelligence = {
|
|
875
|
-
getThreadState: vi
|
|
876
|
-
.fn()
|
|
877
|
-
.mockResolvedValue({ kind: "snapshot-decode-error" }),
|
|
878
|
-
};
|
|
879
|
-
const runtime = createIntelligenceRuntime({ intelligence });
|
|
880
|
-
|
|
881
|
-
const response = await handleGetThreadState({
|
|
882
|
-
runtime,
|
|
883
|
-
request: new Request("https://example.com/threads/thread-1/state"),
|
|
884
|
-
threadId: "thread-1",
|
|
885
|
-
});
|
|
886
|
-
|
|
887
|
-
expect(response.status).toBe(200);
|
|
888
|
-
const body = await response.json();
|
|
889
|
-
expect(body.state).toBeNull();
|
|
890
|
-
});
|
|
891
|
-
|
|
892
|
-
it("returns 500 when intelligence.getThreadState throws", async () => {
|
|
893
|
-
const intelligence = {
|
|
894
|
-
getThreadState: vi
|
|
895
|
-
.fn()
|
|
896
|
-
.mockRejectedValue(new Error("platform unavailable")),
|
|
897
|
-
};
|
|
898
|
-
const runtime = createIntelligenceRuntime({ intelligence });
|
|
899
|
-
|
|
900
|
-
const errorSpy = vi.spyOn(console, "error").mockImplementation(() => {});
|
|
901
|
-
try {
|
|
902
|
-
const response = await handleGetThreadState({
|
|
903
|
-
runtime,
|
|
904
|
-
request: new Request("https://example.com/threads/thread-1/state"),
|
|
905
|
-
threadId: "thread-1",
|
|
906
|
-
});
|
|
907
|
-
|
|
908
|
-
expect(response.status).toBe(500);
|
|
909
|
-
} finally {
|
|
910
|
-
errorSpy.mockRestore();
|
|
911
|
-
}
|
|
912
|
-
});
|
|
913
|
-
|
|
914
|
-
it("returns 500 when the runner throws", async () => {
|
|
915
|
-
const runner = new InMemoryAgentRunner();
|
|
916
|
-
vi.spyOn(runner, "getThreadState").mockImplementation(() => {
|
|
917
|
-
throw new Error("boom");
|
|
918
|
-
});
|
|
919
|
-
const runtime = new CopilotRuntime({ agents: {}, runner });
|
|
920
|
-
|
|
921
|
-
const response = await handleGetThreadState({
|
|
922
|
-
runtime,
|
|
923
|
-
request: new Request("https://example.com/threads/thread-1/state"),
|
|
924
|
-
threadId: "thread-1",
|
|
925
|
-
});
|
|
926
|
-
|
|
927
|
-
expect(response.status).toBe(500);
|
|
928
|
-
});
|
|
929
|
-
});
|
|
930
|
-
});
|