@copilotkit/runtime 1.56.2 → 1.56.4
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/graphql/resolvers/copilot.resolver.cjs +2 -1
- package/dist/graphql/resolvers/copilot.resolver.cjs.map +1 -1
- package/dist/graphql/resolvers/copilot.resolver.mjs +2 -1
- package/dist/graphql/resolvers/copilot.resolver.mjs.map +1 -1
- package/dist/graphql/resolvers/resolve-message-id.cjs +19 -0
- package/dist/graphql/resolvers/resolve-message-id.cjs.map +1 -0
- package/dist/graphql/resolvers/resolve-message-id.mjs +18 -0
- package/dist/graphql/resolvers/resolve-message-id.mjs.map +1 -0
- package/dist/lib/runtime/copilot-runtime.cjs +4 -2
- 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 +4 -2
- package/dist/lib/runtime/copilot-runtime.mjs.map +1 -1
- package/dist/package.cjs +2 -2
- package/dist/package.mjs +2 -2
- package/dist/v2/index.d.cts +2 -2
- package/dist/v2/index.d.mts +2 -2
- package/dist/v2/runtime/core/debug-event-bus.cjs +36 -0
- package/dist/v2/runtime/core/debug-event-bus.cjs.map +1 -0
- package/dist/v2/runtime/core/debug-event-bus.d.cts +19 -0
- package/dist/v2/runtime/core/debug-event-bus.d.cts.map +1 -0
- package/dist/v2/runtime/core/debug-event-bus.d.mts +19 -0
- package/dist/v2/runtime/core/debug-event-bus.d.mts.map +1 -0
- package/dist/v2/runtime/core/debug-event-bus.mjs +35 -0
- package/dist/v2/runtime/core/debug-event-bus.mjs.map +1 -0
- package/dist/v2/runtime/core/fetch-handler.cjs +8 -0
- package/dist/v2/runtime/core/fetch-handler.cjs.map +1 -1
- package/dist/v2/runtime/core/fetch-handler.d.cts.map +1 -1
- package/dist/v2/runtime/core/fetch-handler.d.mts.map +1 -1
- package/dist/v2/runtime/core/fetch-handler.mjs +8 -0
- package/dist/v2/runtime/core/fetch-handler.mjs.map +1 -1
- package/dist/v2/runtime/core/fetch-router.cjs +1 -0
- package/dist/v2/runtime/core/fetch-router.cjs.map +1 -1
- package/dist/v2/runtime/core/fetch-router.mjs +1 -0
- package/dist/v2/runtime/core/fetch-router.mjs.map +1 -1
- package/dist/v2/runtime/core/hooks.cjs.map +1 -1
- package/dist/v2/runtime/core/hooks.d.cts +2 -0
- package/dist/v2/runtime/core/hooks.d.cts.map +1 -1
- package/dist/v2/runtime/core/hooks.d.mts +2 -0
- package/dist/v2/runtime/core/hooks.d.mts.map +1 -1
- package/dist/v2/runtime/core/hooks.mjs.map +1 -1
- package/dist/v2/runtime/core/runtime.cjs +5 -0
- package/dist/v2/runtime/core/runtime.cjs.map +1 -1
- package/dist/v2/runtime/core/runtime.d.cts +5 -0
- package/dist/v2/runtime/core/runtime.d.cts.map +1 -1
- package/dist/v2/runtime/core/runtime.d.mts +5 -1
- package/dist/v2/runtime/core/runtime.d.mts.map +1 -1
- package/dist/v2/runtime/core/runtime.mjs +5 -0
- package/dist/v2/runtime/core/runtime.mjs.map +1 -1
- package/dist/v2/runtime/handlers/handle-connect.cjs +3 -2
- package/dist/v2/runtime/handlers/handle-connect.cjs.map +1 -1
- package/dist/v2/runtime/handlers/handle-connect.mjs +3 -2
- package/dist/v2/runtime/handlers/handle-connect.mjs.map +1 -1
- package/dist/v2/runtime/handlers/handle-debug-events.cjs +33 -0
- package/dist/v2/runtime/handlers/handle-debug-events.cjs.map +1 -0
- package/dist/v2/runtime/handlers/handle-debug-events.mjs +32 -0
- package/dist/v2/runtime/handlers/handle-debug-events.mjs.map +1 -0
- package/dist/v2/runtime/handlers/handle-run.cjs +1 -0
- package/dist/v2/runtime/handlers/handle-run.cjs.map +1 -1
- package/dist/v2/runtime/handlers/handle-run.mjs +1 -0
- package/dist/v2/runtime/handlers/handle-run.mjs.map +1 -1
- package/dist/v2/runtime/handlers/intelligence/connect.cjs +24 -4
- package/dist/v2/runtime/handlers/intelligence/connect.cjs.map +1 -1
- package/dist/v2/runtime/handlers/intelligence/connect.mjs +25 -5
- package/dist/v2/runtime/handlers/intelligence/connect.mjs.map +1 -1
- package/dist/v2/runtime/handlers/intelligence/run.cjs +111 -26
- package/dist/v2/runtime/handlers/intelligence/run.cjs.map +1 -1
- package/dist/v2/runtime/handlers/intelligence/run.mjs +111 -26
- package/dist/v2/runtime/handlers/intelligence/run.mjs.map +1 -1
- package/dist/v2/runtime/handlers/shared/intelligence-utils.cjs +7 -3
- package/dist/v2/runtime/handlers/shared/intelligence-utils.cjs.map +1 -1
- package/dist/v2/runtime/handlers/shared/intelligence-utils.mjs +7 -3
- package/dist/v2/runtime/handlers/shared/intelligence-utils.mjs.map +1 -1
- package/dist/v2/runtime/handlers/shared/resolve-intelligence-user.cjs +5 -1
- package/dist/v2/runtime/handlers/shared/resolve-intelligence-user.cjs.map +1 -1
- package/dist/v2/runtime/handlers/shared/resolve-intelligence-user.mjs +5 -1
- package/dist/v2/runtime/handlers/shared/resolve-intelligence-user.mjs.map +1 -1
- package/dist/v2/runtime/handlers/shared/sse-response.cjs +21 -1
- package/dist/v2/runtime/handlers/shared/sse-response.cjs.map +1 -1
- package/dist/v2/runtime/handlers/shared/sse-response.mjs +21 -1
- package/dist/v2/runtime/handlers/shared/sse-response.mjs.map +1 -1
- package/dist/v2/runtime/handlers/sse/connect.cjs +3 -1
- package/dist/v2/runtime/handlers/sse/connect.cjs.map +1 -1
- package/dist/v2/runtime/handlers/sse/connect.mjs +3 -1
- package/dist/v2/runtime/handlers/sse/connect.mjs.map +1 -1
- package/dist/v2/runtime/handlers/sse/run.cjs +3 -1
- package/dist/v2/runtime/handlers/sse/run.cjs.map +1 -1
- package/dist/v2/runtime/handlers/sse/run.mjs +3 -1
- package/dist/v2/runtime/handlers/sse/run.mjs.map +1 -1
- package/dist/v2/runtime/index.d.cts +1 -1
- package/dist/v2/runtime/index.d.mts +1 -2
- package/dist/v2/runtime/index.d.mts.map +1 -1
- package/dist/v2/runtime/intelligence-platform/client.cjs +6 -8
- package/dist/v2/runtime/intelligence-platform/client.cjs.map +1 -1
- package/dist/v2/runtime/intelligence-platform/client.d.cts +16 -21
- package/dist/v2/runtime/intelligence-platform/client.d.cts.map +1 -1
- package/dist/v2/runtime/intelligence-platform/client.d.mts +16 -21
- package/dist/v2/runtime/intelligence-platform/client.d.mts.map +1 -1
- package/dist/v2/runtime/intelligence-platform/client.mjs +6 -8
- package/dist/v2/runtime/intelligence-platform/client.mjs.map +1 -1
- package/dist/v2/runtime/runner/agent-runner.cjs.map +1 -1
- package/dist/v2/runtime/runner/agent-runner.d.cts +0 -1
- package/dist/v2/runtime/runner/agent-runner.d.cts.map +1 -1
- package/dist/v2/runtime/runner/agent-runner.d.mts +0 -1
- package/dist/v2/runtime/runner/agent-runner.d.mts.map +1 -1
- package/dist/v2/runtime/runner/agent-runner.mjs.map +1 -1
- package/dist/v2/runtime/runner/index.d.cts +1 -1
- package/dist/v2/runtime/runner/index.d.mts +1 -1
- package/dist/v2/runtime/runner/intelligence.cjs +47 -10
- package/dist/v2/runtime/runner/intelligence.cjs.map +1 -1
- package/dist/v2/runtime/runner/intelligence.d.cts +8 -1
- package/dist/v2/runtime/runner/intelligence.d.cts.map +1 -1
- package/dist/v2/runtime/runner/intelligence.d.mts +8 -1
- package/dist/v2/runtime/runner/intelligence.d.mts.map +1 -1
- package/dist/v2/runtime/runner/intelligence.mjs +47 -10
- package/dist/v2/runtime/runner/intelligence.mjs.map +1 -1
- package/dist/v2/runtime/telemetry/instance-created.cjs +33 -0
- package/dist/v2/runtime/telemetry/instance-created.cjs.map +1 -0
- package/dist/v2/runtime/telemetry/instance-created.mjs +33 -0
- package/dist/v2/runtime/telemetry/instance-created.mjs.map +1 -0
- package/dist/v2/runtime/telemetry/telemetry-client.cjs +1 -38
- package/dist/v2/runtime/telemetry/telemetry-client.cjs.map +1 -1
- package/dist/v2/runtime/telemetry/telemetry-client.mjs +1 -37
- package/dist/v2/runtime/telemetry/telemetry-client.mjs.map +1 -1
- package/package.json +3 -3
- package/src/agents/langgraph/__tests__/event-source.test.ts +256 -0
- package/src/graphql/resolvers/__tests__/resolve-message-id.test.ts +25 -0
- package/src/graphql/resolvers/copilot.resolver.ts +2 -1
- package/src/graphql/resolvers/resolve-message-id.ts +14 -0
- package/src/lib/runtime/__tests__/handle-service-adapter.test.ts +108 -0
- package/src/lib/runtime/__tests__/retry-utils.test.ts +137 -0
- package/src/lib/runtime/agent-integrations/langgraph/__tests__/dispatch-event-filtering.test.ts +190 -0
- package/src/lib/runtime/copilot-runtime.ts +20 -4
- package/src/lib/runtime/retry-utils.ts +41 -1
- package/src/v2/runtime/__tests__/express-single-telemetry.integration.test.ts +65 -0
- package/src/v2/runtime/__tests__/express-telemetry.integration.test.ts +101 -0
- package/src/v2/runtime/__tests__/fetch-router.test.ts +22 -0
- package/src/v2/runtime/__tests__/handle-connect.test.ts +183 -23
- package/src/v2/runtime/__tests__/handle-run.test.ts +411 -33
- package/src/v2/runtime/__tests__/handle-threads.test.ts +66 -4
- package/src/v2/runtime/__tests__/hono-single-telemetry.integration.test.ts +46 -0
- package/src/v2/runtime/__tests__/hono-telemetry.integration.test.ts +99 -0
- package/src/v2/runtime/__tests__/integration/node-servers.integration.test.ts +19 -0
- package/src/v2/runtime/__tests__/integration/suites/debug-events.suite.ts +253 -0
- package/src/v2/runtime/__tests__/intelligence-run-telemetry.test.ts +194 -0
- package/src/v2/runtime/__tests__/runtime.test.ts +3 -1
- package/src/v2/runtime/__tests__/sse-response-telemetry.test.ts +108 -0
- package/src/v2/runtime/__tests__/telemetry.test.ts +0 -61
- package/src/v2/runtime/core/__tests__/debug-event-bus.test.ts +156 -0
- package/src/v2/runtime/core/debug-event-bus.ts +45 -0
- package/src/v2/runtime/core/fetch-handler.ts +7 -0
- package/src/v2/runtime/core/fetch-router.ts +11 -0
- package/src/v2/runtime/core/hooks.ts +2 -1
- package/src/v2/runtime/core/runtime.ts +12 -0
- package/src/v2/runtime/handlers/__tests__/handle-debug-events.test.ts +176 -0
- package/src/v2/runtime/handlers/handle-connect.ts +2 -1
- package/src/v2/runtime/handlers/handle-debug-events.ts +52 -0
- package/src/v2/runtime/handlers/handle-run.ts +1 -0
- package/src/v2/runtime/handlers/intelligence/connect.ts +48 -11
- package/src/v2/runtime/handlers/intelligence/run.ts +162 -21
- package/src/v2/runtime/handlers/shared/intelligence-utils.ts +21 -1
- package/src/v2/runtime/handlers/shared/resolve-intelligence-user.ts +4 -1
- package/src/v2/runtime/handlers/shared/sse-response.ts +46 -0
- package/src/v2/runtime/handlers/sse/__tests__/sse-connect-agent-id.test.ts +71 -0
- package/src/v2/runtime/handlers/sse/connect.ts +6 -0
- package/src/v2/runtime/handlers/sse/run.ts +4 -0
- package/src/v2/runtime/intelligence-platform/__tests__/client.test.ts +33 -37
- package/src/v2/runtime/intelligence-platform/client.ts +37 -40
- package/src/v2/runtime/runner/__tests__/intelligence-runner.test.ts +66 -8
- package/src/v2/runtime/runner/agent-runner.ts +0 -1
- package/src/v2/runtime/runner/intelligence.ts +74 -15
- package/src/v2/runtime/telemetry/__tests__/instance-created.test.ts +96 -0
- package/src/v2/runtime/telemetry/instance-created.ts +44 -0
- package/src/v2/runtime/telemetry/telemetry-client.ts +1 -57
- package/dist/v2/runtime/intelligence-platform/index.d.mts +0 -2
- package/dist/v2/runtime/telemetry/utils.cjs +0 -15
- package/dist/v2/runtime/telemetry/utils.cjs.map +0 -1
- package/dist/v2/runtime/telemetry/utils.mjs +0 -14
- package/dist/v2/runtime/telemetry/utils.mjs.map +0 -1
- package/src/v2/runtime/telemetry/utils.ts +0 -15
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Observable } from "rxjs";
|
|
2
2
|
import { describe, it, expect, vi } from "vitest";
|
|
3
|
-
import { AbstractAgent, HttpAgent } from "@ag-ui/client";
|
|
3
|
+
import { AbstractAgent, BaseEvent, EventType, HttpAgent } from "@ag-ui/client";
|
|
4
4
|
import { A2UIMiddleware } from "@ag-ui/a2ui-middleware";
|
|
5
5
|
import { handleRunAgent } from "../handlers/handle-run";
|
|
6
6
|
import { CopilotRuntime } from "../core/runtime";
|
|
@@ -285,7 +285,7 @@ describe("handleRunAgent", () => {
|
|
|
285
285
|
expect(useSpy).not.toHaveBeenCalled();
|
|
286
286
|
});
|
|
287
287
|
|
|
288
|
-
describe("IntelligenceAgentRunner
|
|
288
|
+
describe("IntelligenceAgentRunner realtime credentials path", () => {
|
|
289
289
|
/** Loose mock type for CopilotKitIntelligence — avoids `as any` while the class has private fields. */
|
|
290
290
|
interface MockIntelligencePlatform {
|
|
291
291
|
[key: string]: ((...args: any[]) => any) | undefined;
|
|
@@ -296,9 +296,13 @@ describe("handleRunAgent", () => {
|
|
|
296
296
|
platform?: MockIntelligencePlatform,
|
|
297
297
|
options?: {
|
|
298
298
|
generateThreadNames?: boolean;
|
|
299
|
+
lockHeartbeatIntervalSeconds?: number;
|
|
300
|
+
lockTtlSeconds?: number;
|
|
299
301
|
identifyUser?: (
|
|
300
302
|
request: Request,
|
|
301
|
-
) =>
|
|
303
|
+
) =>
|
|
304
|
+
| { id: string; name: string }
|
|
305
|
+
| Promise<{ id: string; name: string }>;
|
|
302
306
|
},
|
|
303
307
|
) => {
|
|
304
308
|
const runner = Object.create(IntelligenceAgentRunner.prototype);
|
|
@@ -316,9 +320,16 @@ describe("handleRunAgent", () => {
|
|
|
316
320
|
runner,
|
|
317
321
|
mode: "intelligence",
|
|
318
322
|
generateThreadNames: options?.generateThreadNames ?? false,
|
|
319
|
-
|
|
323
|
+
lockHeartbeatIntervalSeconds:
|
|
324
|
+
options?.lockHeartbeatIntervalSeconds ?? 15,
|
|
325
|
+
lockTtlSeconds: options?.lockTtlSeconds ?? 20,
|
|
326
|
+
intelligence: {
|
|
327
|
+
ɵgetClientWsUrl: vi.fn(() => "wss://runtime.example/client"),
|
|
328
|
+
...platform,
|
|
329
|
+
},
|
|
320
330
|
identifyUser:
|
|
321
|
-
options?.identifyUser ??
|
|
331
|
+
options?.identifyUser ??
|
|
332
|
+
vi.fn().mockResolvedValue({ id: "user-1", name: "User One" }),
|
|
322
333
|
} as unknown as CopilotRuntime;
|
|
323
334
|
};
|
|
324
335
|
|
|
@@ -328,6 +339,7 @@ describe("handleRunAgent", () => {
|
|
|
328
339
|
clone: vi.fn(() => createClone()),
|
|
329
340
|
setMessages: vi.fn(),
|
|
330
341
|
setState: vi.fn(),
|
|
342
|
+
abortRun: vi.fn(),
|
|
331
343
|
threadId: undefined,
|
|
332
344
|
headers: {},
|
|
333
345
|
runAgent: vi.fn().mockResolvedValue(undefined),
|
|
@@ -337,6 +349,7 @@ describe("handleRunAgent", () => {
|
|
|
337
349
|
clone: vi.fn(() => createClone()),
|
|
338
350
|
setMessages: vi.fn(),
|
|
339
351
|
setState: vi.fn(),
|
|
352
|
+
abortRun: vi.fn(),
|
|
340
353
|
threadId: undefined,
|
|
341
354
|
headers: {},
|
|
342
355
|
runAgent: vi.fn().mockResolvedValue(undefined),
|
|
@@ -352,9 +365,12 @@ describe("handleRunAgent", () => {
|
|
|
352
365
|
created: false,
|
|
353
366
|
}),
|
|
354
367
|
getThreadMessages: vi.fn().mockResolvedValue({ messages: [] }),
|
|
355
|
-
ɵacquireThreadLock: vi
|
|
356
|
-
|
|
357
|
-
|
|
368
|
+
ɵacquireThreadLock: vi.fn().mockResolvedValue({
|
|
369
|
+
threadId: "thread-1",
|
|
370
|
+
runId: "run-1",
|
|
371
|
+
joinToken: "jt-123",
|
|
372
|
+
}),
|
|
373
|
+
ɵcleanupThreadLock: vi.fn().mockResolvedValue(undefined),
|
|
358
374
|
};
|
|
359
375
|
const runtime = createIntelligenceRuntime(agent, platform);
|
|
360
376
|
|
|
@@ -367,7 +383,15 @@ describe("handleRunAgent", () => {
|
|
|
367
383
|
expect(response.status).toBe(200);
|
|
368
384
|
expect(response.headers.get("Content-Type")).toBe("application/json");
|
|
369
385
|
const body = await response.json();
|
|
370
|
-
expect(body).toEqual({
|
|
386
|
+
expect(body).toEqual({
|
|
387
|
+
threadId: "thread-1",
|
|
388
|
+
runId: "run-1",
|
|
389
|
+
joinToken: "jt-123",
|
|
390
|
+
realtime: {
|
|
391
|
+
clientUrl: "wss://runtime.example/client",
|
|
392
|
+
topic: "thread:thread-1",
|
|
393
|
+
},
|
|
394
|
+
});
|
|
371
395
|
expect(platform.getOrCreateThread).toHaveBeenCalledWith({
|
|
372
396
|
threadId: "thread-1",
|
|
373
397
|
userId: "user-1",
|
|
@@ -377,6 +401,8 @@ describe("handleRunAgent", () => {
|
|
|
377
401
|
threadId: "thread-1",
|
|
378
402
|
runId: "run-1",
|
|
379
403
|
userId: "user-1",
|
|
404
|
+
agentId: "my-agent",
|
|
405
|
+
ttlSeconds: 20,
|
|
380
406
|
});
|
|
381
407
|
expect(platform.getThreadMessages).toHaveBeenCalledWith({
|
|
382
408
|
threadId: "thread-1",
|
|
@@ -391,11 +417,16 @@ describe("handleRunAgent", () => {
|
|
|
391
417
|
created: false,
|
|
392
418
|
}),
|
|
393
419
|
getThreadMessages: vi.fn().mockResolvedValue({ messages: [] }),
|
|
394
|
-
ɵacquireThreadLock: vi
|
|
395
|
-
|
|
396
|
-
|
|
420
|
+
ɵacquireThreadLock: vi.fn().mockResolvedValue({
|
|
421
|
+
threadId: "thread-1",
|
|
422
|
+
runId: "run-1",
|
|
423
|
+
joinToken: "jt-123",
|
|
424
|
+
}),
|
|
425
|
+
ɵcleanupThreadLock: vi.fn().mockResolvedValue(undefined),
|
|
397
426
|
};
|
|
398
|
-
const identifyUser = vi
|
|
427
|
+
const identifyUser = vi
|
|
428
|
+
.fn()
|
|
429
|
+
.mockResolvedValue({ id: "resolved-user", name: "Resolved User" });
|
|
399
430
|
const runtime = createIntelligenceRuntime(agent, platform, {
|
|
400
431
|
identifyUser,
|
|
401
432
|
});
|
|
@@ -419,10 +450,12 @@ describe("handleRunAgent", () => {
|
|
|
419
450
|
threadId: "thread-1",
|
|
420
451
|
runId: "run-1",
|
|
421
452
|
userId: "resolved-user",
|
|
453
|
+
agentId: "my-agent",
|
|
454
|
+
ttlSeconds: 20,
|
|
422
455
|
});
|
|
423
456
|
});
|
|
424
457
|
|
|
425
|
-
it("
|
|
458
|
+
it("starts the runner with canonical threadId and runId from the lock response", async () => {
|
|
426
459
|
const agent = createAgentForIntelligence();
|
|
427
460
|
const platform = {
|
|
428
461
|
getOrCreateThread: vi.fn().mockResolvedValue({
|
|
@@ -430,9 +463,11 @@ describe("handleRunAgent", () => {
|
|
|
430
463
|
created: false,
|
|
431
464
|
}),
|
|
432
465
|
getThreadMessages: vi.fn().mockResolvedValue({ messages: [] }),
|
|
433
|
-
ɵacquireThreadLock: vi
|
|
434
|
-
|
|
435
|
-
|
|
466
|
+
ɵacquireThreadLock: vi.fn().mockResolvedValue({
|
|
467
|
+
threadId: "canonical-thread",
|
|
468
|
+
runId: "canonical-run",
|
|
469
|
+
joinToken: "jt-456",
|
|
470
|
+
}),
|
|
436
471
|
};
|
|
437
472
|
const runtime = createIntelligenceRuntime(agent, platform);
|
|
438
473
|
|
|
@@ -443,11 +478,17 @@ describe("handleRunAgent", () => {
|
|
|
443
478
|
});
|
|
444
479
|
|
|
445
480
|
expect(runtime.runner.run).toHaveBeenCalledWith(
|
|
446
|
-
expect.objectContaining({
|
|
481
|
+
expect.objectContaining({
|
|
482
|
+
threadId: "canonical-thread",
|
|
483
|
+
input: expect.objectContaining({
|
|
484
|
+
threadId: "canonical-thread",
|
|
485
|
+
runId: "canonical-run",
|
|
486
|
+
}),
|
|
487
|
+
}),
|
|
447
488
|
);
|
|
448
489
|
});
|
|
449
490
|
|
|
450
|
-
it("returns 502 when joinToken is missing", async () => {
|
|
491
|
+
it("cleans up the lock and returns 502 when joinToken is missing", async () => {
|
|
451
492
|
const agent = createAgentForIntelligence();
|
|
452
493
|
const platform = {
|
|
453
494
|
getOrCreateThread: vi.fn().mockResolvedValue({
|
|
@@ -455,7 +496,11 @@ describe("handleRunAgent", () => {
|
|
|
455
496
|
created: false,
|
|
456
497
|
}),
|
|
457
498
|
getThreadMessages: vi.fn().mockResolvedValue({ messages: [] }),
|
|
458
|
-
ɵacquireThreadLock: vi.fn().mockResolvedValue({
|
|
499
|
+
ɵacquireThreadLock: vi.fn().mockResolvedValue({
|
|
500
|
+
threadId: "thread-1",
|
|
501
|
+
runId: "run-1",
|
|
502
|
+
}),
|
|
503
|
+
ɵcleanupThreadLock: vi.fn().mockResolvedValue(undefined),
|
|
459
504
|
};
|
|
460
505
|
const runtime = createIntelligenceRuntime(agent, platform);
|
|
461
506
|
|
|
@@ -467,7 +512,40 @@ describe("handleRunAgent", () => {
|
|
|
467
512
|
|
|
468
513
|
expect(response.status).toBe(502);
|
|
469
514
|
const body = await response.json();
|
|
470
|
-
expect(body.error).toBe("
|
|
515
|
+
expect(body.error).toBe("Run connection credentials not available");
|
|
516
|
+
expect(platform.ɵcleanupThreadLock).toHaveBeenCalledWith({
|
|
517
|
+
threadId: "thread-1",
|
|
518
|
+
runId: "run-1",
|
|
519
|
+
});
|
|
520
|
+
expect(runtime.runner.run).not.toHaveBeenCalled();
|
|
521
|
+
});
|
|
522
|
+
|
|
523
|
+
it("uses the requested lock owner when malformed credentials omit canonical IDs", async () => {
|
|
524
|
+
const agent = createAgentForIntelligence();
|
|
525
|
+
const platform = {
|
|
526
|
+
getOrCreateThread: vi.fn().mockResolvedValue({
|
|
527
|
+
thread: { id: "thread-1", name: null },
|
|
528
|
+
created: false,
|
|
529
|
+
}),
|
|
530
|
+
getThreadMessages: vi.fn().mockResolvedValue({ messages: [] }),
|
|
531
|
+
ɵacquireThreadLock: vi.fn().mockResolvedValue({
|
|
532
|
+
joinToken: "jt-123",
|
|
533
|
+
}),
|
|
534
|
+
ɵcleanupThreadLock: vi.fn().mockResolvedValue(undefined),
|
|
535
|
+
};
|
|
536
|
+
const runtime = createIntelligenceRuntime(agent, platform);
|
|
537
|
+
|
|
538
|
+
const response = await handleRunAgent({
|
|
539
|
+
runtime,
|
|
540
|
+
request: createRunRequest(),
|
|
541
|
+
agentId: "my-agent",
|
|
542
|
+
});
|
|
543
|
+
|
|
544
|
+
expect(response.status).toBe(502);
|
|
545
|
+
expect(platform.ɵcleanupThreadLock).toHaveBeenCalledWith({
|
|
546
|
+
threadId: "thread-1",
|
|
547
|
+
runId: "run-1",
|
|
548
|
+
});
|
|
471
549
|
expect(runtime.runner.run).not.toHaveBeenCalled();
|
|
472
550
|
});
|
|
473
551
|
|
|
@@ -496,6 +574,206 @@ describe("handleRunAgent", () => {
|
|
|
496
574
|
expect(body.error).toBe("Thread lock denied");
|
|
497
575
|
});
|
|
498
576
|
|
|
577
|
+
it("cleans up the canonical lock and returns 502 when runner start fails immediately", async () => {
|
|
578
|
+
const agent = createAgentForIntelligence();
|
|
579
|
+
const platform = {
|
|
580
|
+
getOrCreateThread: vi.fn().mockResolvedValue({
|
|
581
|
+
thread: { id: "thread-1", name: null },
|
|
582
|
+
created: false,
|
|
583
|
+
}),
|
|
584
|
+
getThreadMessages: vi.fn().mockResolvedValue({ messages: [] }),
|
|
585
|
+
ɵacquireThreadLock: vi.fn().mockResolvedValue({
|
|
586
|
+
threadId: "canonical-thread",
|
|
587
|
+
runId: "canonical-run",
|
|
588
|
+
joinToken: "jt-123",
|
|
589
|
+
}),
|
|
590
|
+
ɵcleanupThreadLock: vi.fn().mockResolvedValue(undefined),
|
|
591
|
+
};
|
|
592
|
+
const runtime = createIntelligenceRuntime(agent, platform);
|
|
593
|
+
runtime.runner.run = vi.fn(
|
|
594
|
+
() =>
|
|
595
|
+
new Observable<BaseEvent>((subscriber) => {
|
|
596
|
+
subscriber.next({
|
|
597
|
+
type: EventType.RUN_ERROR,
|
|
598
|
+
message: "join failed",
|
|
599
|
+
} as BaseEvent);
|
|
600
|
+
subscriber.complete();
|
|
601
|
+
}),
|
|
602
|
+
);
|
|
603
|
+
|
|
604
|
+
const response = await handleRunAgent({
|
|
605
|
+
runtime,
|
|
606
|
+
request: createRunRequest(),
|
|
607
|
+
agentId: "my-agent",
|
|
608
|
+
});
|
|
609
|
+
|
|
610
|
+
expect(response.status).toBe(502);
|
|
611
|
+
const body = await response.json();
|
|
612
|
+
expect(body).toEqual({
|
|
613
|
+
error: "Failed to start runner",
|
|
614
|
+
message: "join failed",
|
|
615
|
+
});
|
|
616
|
+
expect(platform.ɵcleanupThreadLock).toHaveBeenCalledWith({
|
|
617
|
+
threadId: "canonical-thread",
|
|
618
|
+
runId: "canonical-run",
|
|
619
|
+
});
|
|
620
|
+
expect(platform.ɵcleanupThreadLock).toHaveBeenCalledTimes(1);
|
|
621
|
+
});
|
|
622
|
+
|
|
623
|
+
it("delays the run success response until the runner startup boundary resolves", async () => {
|
|
624
|
+
const agent = createAgentForIntelligence();
|
|
625
|
+
let resolveStartup: (() => void) | undefined;
|
|
626
|
+
const startup = new Promise<void>((resolve) => {
|
|
627
|
+
resolveStartup = resolve;
|
|
628
|
+
});
|
|
629
|
+
const platform = {
|
|
630
|
+
getOrCreateThread: vi.fn().mockResolvedValue({
|
|
631
|
+
thread: { id: "thread-1", name: null },
|
|
632
|
+
created: false,
|
|
633
|
+
}),
|
|
634
|
+
getThreadMessages: vi.fn().mockResolvedValue({ messages: [] }),
|
|
635
|
+
ɵacquireThreadLock: vi.fn().mockResolvedValue({
|
|
636
|
+
threadId: "canonical-thread",
|
|
637
|
+
runId: "canonical-run",
|
|
638
|
+
joinToken: "jt-123",
|
|
639
|
+
}),
|
|
640
|
+
ɵcleanupThreadLock: vi.fn().mockResolvedValue(undefined),
|
|
641
|
+
};
|
|
642
|
+
const runtime = createIntelligenceRuntime(agent, platform);
|
|
643
|
+
runtime.runner.runWithStartupBoundary = vi.fn(() => ({
|
|
644
|
+
events: new Observable<BaseEvent>(() => {}),
|
|
645
|
+
startup,
|
|
646
|
+
}));
|
|
647
|
+
let settled = false;
|
|
648
|
+
|
|
649
|
+
const responsePromise = handleRunAgent({
|
|
650
|
+
runtime,
|
|
651
|
+
request: createRunRequest(),
|
|
652
|
+
agentId: "my-agent",
|
|
653
|
+
}).then((response) => {
|
|
654
|
+
settled = true;
|
|
655
|
+
return response;
|
|
656
|
+
});
|
|
657
|
+
|
|
658
|
+
await Promise.resolve();
|
|
659
|
+
|
|
660
|
+
expect(settled).toBe(false);
|
|
661
|
+
|
|
662
|
+
resolveStartup?.();
|
|
663
|
+
const response = await responsePromise;
|
|
664
|
+
|
|
665
|
+
expect(response.status).toBe(200);
|
|
666
|
+
expect(runtime.runner.runWithStartupBoundary).toHaveBeenCalledWith(
|
|
667
|
+
expect.objectContaining({
|
|
668
|
+
threadId: "canonical-thread",
|
|
669
|
+
input: expect.objectContaining({
|
|
670
|
+
threadId: "canonical-thread",
|
|
671
|
+
runId: "canonical-run",
|
|
672
|
+
}),
|
|
673
|
+
}),
|
|
674
|
+
);
|
|
675
|
+
});
|
|
676
|
+
|
|
677
|
+
it("cleans up the lock and returns 502 when the runner startup boundary rejects", async () => {
|
|
678
|
+
const agent = createAgentForIntelligence();
|
|
679
|
+
const platform = {
|
|
680
|
+
getOrCreateThread: vi.fn().mockResolvedValue({
|
|
681
|
+
thread: { id: "thread-1", name: null },
|
|
682
|
+
created: false,
|
|
683
|
+
}),
|
|
684
|
+
getThreadMessages: vi.fn().mockResolvedValue({ messages: [] }),
|
|
685
|
+
ɵacquireThreadLock: vi.fn().mockResolvedValue({
|
|
686
|
+
threadId: "canonical-thread",
|
|
687
|
+
runId: "canonical-run",
|
|
688
|
+
joinToken: "jt-123",
|
|
689
|
+
}),
|
|
690
|
+
ɵcleanupThreadLock: vi.fn().mockResolvedValue(undefined),
|
|
691
|
+
};
|
|
692
|
+
const runtime = createIntelligenceRuntime(agent, platform);
|
|
693
|
+
runtime.runner.runWithStartupBoundary = vi.fn(() => ({
|
|
694
|
+
events: new Observable<BaseEvent>(() => {}),
|
|
695
|
+
startup: Promise.reject(new Error("Failed to join channel: denied")),
|
|
696
|
+
}));
|
|
697
|
+
|
|
698
|
+
const response = await handleRunAgent({
|
|
699
|
+
runtime,
|
|
700
|
+
request: createRunRequest(),
|
|
701
|
+
agentId: "my-agent",
|
|
702
|
+
});
|
|
703
|
+
|
|
704
|
+
expect(response.status).toBe(502);
|
|
705
|
+
const body = await response.json();
|
|
706
|
+
expect(body).toEqual({
|
|
707
|
+
error: "Failed to start runner",
|
|
708
|
+
message: "Failed to join channel: denied",
|
|
709
|
+
});
|
|
710
|
+
expect(platform.ɵcleanupThreadLock).toHaveBeenCalledWith({
|
|
711
|
+
threadId: "canonical-thread",
|
|
712
|
+
runId: "canonical-run",
|
|
713
|
+
});
|
|
714
|
+
expect(platform.ɵcleanupThreadLock).toHaveBeenCalledTimes(1);
|
|
715
|
+
});
|
|
716
|
+
|
|
717
|
+
it("aborts the agent when lock renewal fails", async () => {
|
|
718
|
+
vi.useFakeTimers();
|
|
719
|
+
const runningAgent = {
|
|
720
|
+
clone: vi.fn(),
|
|
721
|
+
setMessages: vi.fn(),
|
|
722
|
+
setState: vi.fn(),
|
|
723
|
+
abortRun: vi.fn(),
|
|
724
|
+
threadId: undefined,
|
|
725
|
+
headers: {},
|
|
726
|
+
runAgent: vi.fn().mockResolvedValue(undefined),
|
|
727
|
+
} as unknown as AbstractAgent;
|
|
728
|
+
const baseAgent = {
|
|
729
|
+
clone: vi.fn(() => runningAgent),
|
|
730
|
+
setMessages: vi.fn(),
|
|
731
|
+
setState: vi.fn(),
|
|
732
|
+
abortRun: vi.fn(),
|
|
733
|
+
threadId: undefined,
|
|
734
|
+
headers: {},
|
|
735
|
+
runAgent: vi.fn().mockResolvedValue(undefined),
|
|
736
|
+
} as unknown as AbstractAgent;
|
|
737
|
+
const platform = {
|
|
738
|
+
getOrCreateThread: vi.fn().mockResolvedValue({
|
|
739
|
+
thread: { id: "thread-1", name: null },
|
|
740
|
+
created: false,
|
|
741
|
+
}),
|
|
742
|
+
getThreadMessages: vi.fn().mockResolvedValue({ messages: [] }),
|
|
743
|
+
ɵacquireThreadLock: vi.fn().mockResolvedValue({
|
|
744
|
+
threadId: "canonical-thread",
|
|
745
|
+
runId: "canonical-run",
|
|
746
|
+
joinToken: "jt-123",
|
|
747
|
+
}),
|
|
748
|
+
ɵrenewThreadLock: vi.fn().mockRejectedValue(new Error("lost lock")),
|
|
749
|
+
};
|
|
750
|
+
const runtime = createIntelligenceRuntime(baseAgent, platform, {
|
|
751
|
+
lockHeartbeatIntervalSeconds: 1,
|
|
752
|
+
lockTtlSeconds: 5,
|
|
753
|
+
});
|
|
754
|
+
runtime.runner.run = vi.fn(() => new Observable<BaseEvent>(() => {}));
|
|
755
|
+
|
|
756
|
+
try {
|
|
757
|
+
const response = await handleRunAgent({
|
|
758
|
+
runtime,
|
|
759
|
+
request: createRunRequest(),
|
|
760
|
+
agentId: "my-agent",
|
|
761
|
+
});
|
|
762
|
+
expect(response.status).toBe(200);
|
|
763
|
+
|
|
764
|
+
await vi.advanceTimersByTimeAsync(1_000);
|
|
765
|
+
|
|
766
|
+
expect(platform.ɵrenewThreadLock).toHaveBeenCalledWith({
|
|
767
|
+
threadId: "canonical-thread",
|
|
768
|
+
runId: "canonical-run",
|
|
769
|
+
ttlSeconds: 5,
|
|
770
|
+
});
|
|
771
|
+
expect(runningAgent.abortRun).toHaveBeenCalledTimes(1);
|
|
772
|
+
} finally {
|
|
773
|
+
vi.useRealTimers();
|
|
774
|
+
}
|
|
775
|
+
});
|
|
776
|
+
|
|
499
777
|
it("passes only unseen input messages to the runner for durable persistence", async () => {
|
|
500
778
|
const agent = createAgentForIntelligence();
|
|
501
779
|
const platform = {
|
|
@@ -512,9 +790,11 @@ describe("handleRunAgent", () => {
|
|
|
512
790
|
},
|
|
513
791
|
],
|
|
514
792
|
}),
|
|
515
|
-
ɵacquireThreadLock: vi
|
|
516
|
-
|
|
517
|
-
|
|
793
|
+
ɵacquireThreadLock: vi.fn().mockResolvedValue({
|
|
794
|
+
threadId: "thread-1",
|
|
795
|
+
runId: "run-1",
|
|
796
|
+
joinToken: "jt-123",
|
|
797
|
+
}),
|
|
518
798
|
};
|
|
519
799
|
const runtime = createIntelligenceRuntime(agent, platform);
|
|
520
800
|
const response = await handleRunAgent({
|
|
@@ -572,9 +852,12 @@ describe("handleRunAgent", () => {
|
|
|
572
852
|
getThreadMessages: vi
|
|
573
853
|
.fn()
|
|
574
854
|
.mockRejectedValue(new Error("history unavailable")),
|
|
575
|
-
ɵacquireThreadLock: vi
|
|
576
|
-
|
|
577
|
-
|
|
855
|
+
ɵacquireThreadLock: vi.fn().mockResolvedValue({
|
|
856
|
+
threadId: "thread-1",
|
|
857
|
+
runId: "run-1",
|
|
858
|
+
joinToken: "jt-123",
|
|
859
|
+
}),
|
|
860
|
+
ɵcleanupThreadLock: vi.fn().mockResolvedValue(undefined),
|
|
578
861
|
};
|
|
579
862
|
const runtime = createIntelligenceRuntime(agent, platform);
|
|
580
863
|
|
|
@@ -587,6 +870,10 @@ describe("handleRunAgent", () => {
|
|
|
587
870
|
expect(response.status).toBe(502);
|
|
588
871
|
const body = await response.json();
|
|
589
872
|
expect(body.error).toBe("Thread history lookup failed");
|
|
873
|
+
expect(platform.ɵcleanupThreadLock).toHaveBeenCalledWith({
|
|
874
|
+
threadId: "thread-1",
|
|
875
|
+
runId: "run-1",
|
|
876
|
+
});
|
|
590
877
|
expect(runtime.runner.run).not.toHaveBeenCalled();
|
|
591
878
|
});
|
|
592
879
|
|
|
@@ -599,8 +886,9 @@ describe("handleRunAgent", () => {
|
|
|
599
886
|
}),
|
|
600
887
|
getThreadMessages: vi.fn().mockResolvedValue({ messages: [] }),
|
|
601
888
|
ɵacquireThreadLock: vi.fn().mockResolvedValue({
|
|
889
|
+
threadId: "thread-1",
|
|
890
|
+
runId: "run-1",
|
|
602
891
|
joinToken: "jt-created",
|
|
603
|
-
joinCode: "jc-created",
|
|
604
892
|
}),
|
|
605
893
|
};
|
|
606
894
|
const runtime = createIntelligenceRuntime(agent, platform);
|
|
@@ -621,6 +909,8 @@ describe("handleRunAgent", () => {
|
|
|
621
909
|
threadId: "thread-1",
|
|
622
910
|
runId: "run-1",
|
|
623
911
|
userId: "user-1",
|
|
912
|
+
agentId: "my-agent",
|
|
913
|
+
ttlSeconds: 20,
|
|
624
914
|
});
|
|
625
915
|
});
|
|
626
916
|
|
|
@@ -670,8 +960,9 @@ describe("handleRunAgent", () => {
|
|
|
670
960
|
}),
|
|
671
961
|
getThreadMessages: vi.fn().mockResolvedValue({ messages: [] }),
|
|
672
962
|
ɵacquireThreadLock: vi.fn().mockResolvedValue({
|
|
963
|
+
threadId: "thread-1",
|
|
964
|
+
runId: "run-1",
|
|
673
965
|
joinToken: "jt-created",
|
|
674
|
-
joinCode: "jc-created",
|
|
675
966
|
}),
|
|
676
967
|
};
|
|
677
968
|
const runtime = createIntelligenceRuntime(baseAgent, platform, {
|
|
@@ -725,8 +1016,9 @@ describe("handleRunAgent", () => {
|
|
|
725
1016
|
updateThread: vi.fn(),
|
|
726
1017
|
getThreadMessages: vi.fn().mockResolvedValue({ messages: [] }),
|
|
727
1018
|
ɵacquireThreadLock: vi.fn().mockResolvedValue({
|
|
1019
|
+
threadId: "thread-1",
|
|
1020
|
+
runId: "run-1",
|
|
728
1021
|
joinToken: "jt-created",
|
|
729
|
-
joinCode: "jc-created",
|
|
730
1022
|
}),
|
|
731
1023
|
};
|
|
732
1024
|
const runtime = createIntelligenceRuntime(agent, platform, {
|
|
@@ -754,8 +1046,9 @@ describe("handleRunAgent", () => {
|
|
|
754
1046
|
updateThread: vi.fn(),
|
|
755
1047
|
getThreadMessages: vi.fn().mockResolvedValue({ messages: [] }),
|
|
756
1048
|
ɵacquireThreadLock: vi.fn().mockResolvedValue({
|
|
1049
|
+
threadId: "thread-1",
|
|
1050
|
+
runId: "run-1",
|
|
757
1051
|
joinToken: "jt-created",
|
|
758
|
-
joinCode: "jc-created",
|
|
759
1052
|
}),
|
|
760
1053
|
};
|
|
761
1054
|
const runtime = createIntelligenceRuntime(agent, platform, {
|
|
@@ -810,8 +1103,9 @@ describe("handleRunAgent", () => {
|
|
|
810
1103
|
updateThread: vi.fn(),
|
|
811
1104
|
getThreadMessages: vi.fn().mockResolvedValue({ messages: [] }),
|
|
812
1105
|
ɵacquireThreadLock: vi.fn().mockResolvedValue({
|
|
1106
|
+
threadId: "thread-1",
|
|
1107
|
+
runId: "run-1",
|
|
813
1108
|
joinToken: "jt-created",
|
|
814
|
-
joinCode: "jc-created",
|
|
815
1109
|
}),
|
|
816
1110
|
};
|
|
817
1111
|
const runtime = createIntelligenceRuntime(baseAgent, platform, {
|
|
@@ -870,7 +1164,29 @@ describe("handleRunAgent", () => {
|
|
|
870
1164
|
ɵacquireThreadLock: vi.fn(),
|
|
871
1165
|
};
|
|
872
1166
|
const runtime = createIntelligenceRuntime(agent, platform, {
|
|
873
|
-
identifyUser: vi.fn().mockResolvedValue({ id: "" }),
|
|
1167
|
+
identifyUser: vi.fn().mockResolvedValue({ id: "", name: "User" }),
|
|
1168
|
+
});
|
|
1169
|
+
|
|
1170
|
+
const response = await handleRunAgent({
|
|
1171
|
+
runtime,
|
|
1172
|
+
request: createRunRequest(),
|
|
1173
|
+
agentId: "my-agent",
|
|
1174
|
+
});
|
|
1175
|
+
|
|
1176
|
+
expect(response.status).toBe(400);
|
|
1177
|
+
expect(platform.getOrCreateThread).not.toHaveBeenCalled();
|
|
1178
|
+
expect(platform.ɵacquireThreadLock).not.toHaveBeenCalled();
|
|
1179
|
+
});
|
|
1180
|
+
|
|
1181
|
+
it("returns 400 when identifyUser returns an invalid name", async () => {
|
|
1182
|
+
const agent = createAgentForIntelligence();
|
|
1183
|
+
const platform = {
|
|
1184
|
+
getOrCreateThread: vi.fn(),
|
|
1185
|
+
getThreadMessages: vi.fn(),
|
|
1186
|
+
ɵacquireThreadLock: vi.fn(),
|
|
1187
|
+
};
|
|
1188
|
+
const runtime = createIntelligenceRuntime(agent, platform, {
|
|
1189
|
+
identifyUser: vi.fn().mockResolvedValue({ id: "user-1", name: "" }),
|
|
874
1190
|
});
|
|
875
1191
|
|
|
876
1192
|
const response = await handleRunAgent({
|
|
@@ -911,4 +1227,66 @@ describe("handleRunAgent", () => {
|
|
|
911
1227
|
}
|
|
912
1228
|
});
|
|
913
1229
|
});
|
|
1230
|
+
|
|
1231
|
+
describe("telemetry", () => {
|
|
1232
|
+
it("captures oss.runtime.copilot_request_created on every invocation", async () => {
|
|
1233
|
+
// Dynamic import so we spy on the module singleton the handler uses.
|
|
1234
|
+
const { telemetry } = await import("../telemetry");
|
|
1235
|
+
const captureSpy = vi
|
|
1236
|
+
.spyOn(telemetry, "capture")
|
|
1237
|
+
.mockResolvedValue(undefined);
|
|
1238
|
+
|
|
1239
|
+
try {
|
|
1240
|
+
const runtime = createMockRuntime({});
|
|
1241
|
+
await handleRunAgent({
|
|
1242
|
+
runtime,
|
|
1243
|
+
request: createMockRequest(),
|
|
1244
|
+
agentId: "nonexistent-agent",
|
|
1245
|
+
});
|
|
1246
|
+
|
|
1247
|
+
expect(captureSpy).toHaveBeenCalledWith(
|
|
1248
|
+
"oss.runtime.copilot_request_created",
|
|
1249
|
+
expect.objectContaining({
|
|
1250
|
+
requestType: "run",
|
|
1251
|
+
"cloud.api_key_provided": false,
|
|
1252
|
+
}),
|
|
1253
|
+
);
|
|
1254
|
+
} finally {
|
|
1255
|
+
captureSpy.mockRestore();
|
|
1256
|
+
}
|
|
1257
|
+
});
|
|
1258
|
+
|
|
1259
|
+
it("includes cloud.public_api_key when x-copilotcloud-public-api-key header is set", async () => {
|
|
1260
|
+
const { telemetry } = await import("../telemetry");
|
|
1261
|
+
const captureSpy = vi
|
|
1262
|
+
.spyOn(telemetry, "capture")
|
|
1263
|
+
.mockResolvedValue(undefined);
|
|
1264
|
+
|
|
1265
|
+
try {
|
|
1266
|
+
const runtime = createMockRuntime({});
|
|
1267
|
+
const request = new Request("https://example.com/agent/test/run", {
|
|
1268
|
+
method: "POST",
|
|
1269
|
+
headers: {
|
|
1270
|
+
"x-copilotcloud-public-api-key": "ck_pub_run_test",
|
|
1271
|
+
},
|
|
1272
|
+
});
|
|
1273
|
+
|
|
1274
|
+
await handleRunAgent({
|
|
1275
|
+
runtime,
|
|
1276
|
+
request,
|
|
1277
|
+
agentId: "nonexistent-agent",
|
|
1278
|
+
});
|
|
1279
|
+
|
|
1280
|
+
expect(captureSpy).toHaveBeenCalledWith(
|
|
1281
|
+
"oss.runtime.copilot_request_created",
|
|
1282
|
+
expect.objectContaining({
|
|
1283
|
+
"cloud.api_key_provided": true,
|
|
1284
|
+
"cloud.public_api_key": "ck_pub_run_test",
|
|
1285
|
+
}),
|
|
1286
|
+
);
|
|
1287
|
+
} finally {
|
|
1288
|
+
captureSpy.mockRestore();
|
|
1289
|
+
}
|
|
1290
|
+
});
|
|
1291
|
+
});
|
|
914
1292
|
});
|