@copilotkit/runtime 1.56.0 → 1.56.2-canary.pin-to-send
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/index.cjs +2 -2
- package/dist/agent/index.cjs.map +1 -1
- package/dist/agent/index.d.cts.map +1 -1
- package/dist/agent/index.d.mts.map +1 -1
- package/dist/agent/index.mjs +2 -2
- package/dist/agent/index.mjs.map +1 -1
- 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/integrations/node-http/index.cjs +4 -1
- package/dist/lib/integrations/node-http/index.cjs.map +1 -1
- package/dist/lib/integrations/node-http/index.d.cts.map +1 -1
- package/dist/lib/integrations/node-http/index.d.mts.map +1 -1
- package/dist/lib/integrations/node-http/index.mjs +4 -1
- package/dist/lib/integrations/node-http/index.mjs.map +1 -1
- package/dist/lib/runtime/copilot-runtime.cjs +15 -3
- 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 +15 -3
- package/dist/lib/runtime/copilot-runtime.mjs.map +1 -1
- package/dist/lib/runtime/mcp-tools-utils.cjs +21 -4
- package/dist/lib/runtime/mcp-tools-utils.cjs.map +1 -1
- package/dist/lib/runtime/mcp-tools-utils.d.cts.map +1 -1
- package/dist/lib/runtime/mcp-tools-utils.d.mts.map +1 -1
- package/dist/lib/runtime/mcp-tools-utils.mjs +21 -4
- package/dist/lib/runtime/mcp-tools-utils.mjs.map +1 -1
- package/dist/package.cjs +2 -2
- package/dist/package.mjs +2 -2
- package/dist/service-adapters/anthropic/anthropic-adapter.cjs +11 -3
- package/dist/service-adapters/anthropic/anthropic-adapter.cjs.map +1 -1
- package/dist/service-adapters/anthropic/anthropic-adapter.d.cts +6 -0
- package/dist/service-adapters/anthropic/anthropic-adapter.d.cts.map +1 -1
- package/dist/service-adapters/anthropic/anthropic-adapter.d.mts +6 -0
- package/dist/service-adapters/anthropic/anthropic-adapter.d.mts.map +1 -1
- package/dist/service-adapters/anthropic/anthropic-adapter.mjs +11 -3
- package/dist/service-adapters/anthropic/anthropic-adapter.mjs.map +1 -1
- package/dist/service-adapters/anthropic/utils.cjs +27 -1
- package/dist/service-adapters/anthropic/utils.cjs.map +1 -1
- package/dist/service-adapters/anthropic/utils.mjs +27 -1
- package/dist/service-adapters/anthropic/utils.mjs.map +1 -1
- package/dist/service-adapters/langchain/utils.cjs +1 -1
- package/dist/service-adapters/langchain/utils.cjs.map +1 -1
- package/dist/service-adapters/langchain/utils.mjs +1 -1
- package/dist/service-adapters/langchain/utils.mjs.map +1 -1
- package/dist/service-adapters/openai/openai-adapter.cjs +2 -1
- package/dist/service-adapters/openai/openai-adapter.cjs.map +1 -1
- package/dist/service-adapters/openai/openai-adapter.d.cts +6 -0
- package/dist/service-adapters/openai/openai-adapter.d.cts.map +1 -1
- package/dist/service-adapters/openai/openai-adapter.d.mts +6 -0
- package/dist/service-adapters/openai/openai-adapter.d.mts.map +1 -1
- package/dist/service-adapters/openai/openai-adapter.mjs +2 -1
- package/dist/service-adapters/openai/openai-adapter.mjs.map +1 -1
- 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 +6 -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 +6 -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/middleware-sse-parser.cjs +5 -2
- package/dist/v2/runtime/core/middleware-sse-parser.cjs.map +1 -1
- package/dist/v2/runtime/core/middleware-sse-parser.mjs +5 -2
- package/dist/v2/runtime/core/middleware-sse-parser.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 -0
- 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 +2 -0
- package/dist/v2/runtime/handlers/handle-connect.cjs.map +1 -1
- package/dist/v2/runtime/handlers/handle-connect.mjs +2 -0
- 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 +32 -2
- package/dist/v2/runtime/handlers/intelligence/connect.cjs.map +1 -1
- package/dist/v2/runtime/handlers/intelligence/connect.mjs +31 -2
- package/dist/v2/runtime/handlers/intelligence/connect.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/intelligence-platform/client.cjs +2 -7
- package/dist/v2/runtime/intelligence-platform/client.cjs.map +1 -1
- package/dist/v2/runtime/intelligence-platform/client.d.cts +1 -4
- package/dist/v2/runtime/intelligence-platform/client.d.cts.map +1 -1
- package/dist/v2/runtime/intelligence-platform/client.d.mts +1 -4
- package/dist/v2/runtime/intelligence-platform/client.d.mts.map +1 -1
- package/dist/v2/runtime/intelligence-platform/client.mjs +2 -7
- package/dist/v2/runtime/intelligence-platform/client.mjs.map +1 -1
- package/dist/v2/runtime/runner/intelligence.cjs +17 -5
- package/dist/v2/runtime/runner/intelligence.cjs.map +1 -1
- package/dist/v2/runtime/runner/intelligence.d.cts +1 -0
- package/dist/v2/runtime/runner/intelligence.d.cts.map +1 -1
- package/dist/v2/runtime/runner/intelligence.d.mts +1 -0
- package/dist/v2/runtime/runner/intelligence.d.mts.map +1 -1
- package/dist/v2/runtime/runner/intelligence.mjs +17 -5
- package/dist/v2/runtime/runner/intelligence.mjs.map +1 -1
- package/package.json +3 -3
- package/src/agent/__tests__/provider-id-collision.test.ts +195 -0
- package/src/agent/index.ts +19 -11
- 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/integrations/node-http/__tests__/request-duck-type.test.ts +66 -0
- package/src/lib/integrations/node-http/index.ts +15 -1
- package/src/lib/runtime/__tests__/handle-service-adapter.test.ts +108 -0
- package/src/lib/runtime/__tests__/mcp-tools-utils.test.ts +30 -1
- package/src/lib/runtime/__tests__/on-after-request.test.ts +122 -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 +36 -7
- package/src/lib/runtime/mcp-tools-utils.ts +41 -6
- package/src/lib/runtime/retry-utils.ts +41 -1
- package/src/service-adapters/anthropic/anthropic-adapter.ts +22 -2
- package/src/service-adapters/anthropic/utils.ts +60 -1
- package/src/service-adapters/langchain/utils.ts +1 -1
- package/src/service-adapters/openai/openai-adapter.ts +14 -1
- package/src/v2/runtime/__tests__/fetch-router.test.ts +22 -0
- package/src/v2/runtime/__tests__/handle-connect.test.ts +58 -5
- package/src/v2/runtime/__tests__/handle-run.test.ts +31 -4
- package/src/v2/runtime/__tests__/handle-threads.test.ts +66 -4
- 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__/middleware-sse-parser.test.ts +50 -0
- package/src/v2/runtime/__tests__/runtime.test.ts +3 -1
- 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 +4 -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/middleware-sse-parser.ts +12 -2
- 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 -0
- 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 +58 -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 +13 -11
- package/src/v2/runtime/intelligence-platform/client.ts +3 -11
- package/src/v2/runtime/runner/__tests__/intelligence-runner.test.ts +51 -1
- package/src/v2/runtime/runner/intelligence.ts +27 -9
- package/tests/service-adapters/anthropic/anthropic-adapter.test.ts +268 -0
- package/tests/service-adapters/anthropic/utils-token-trimming.test.ts +301 -0
|
@@ -42,7 +42,6 @@ export class PlatformRequestError extends Error {
|
|
|
42
42
|
* apiUrl: "https://api.copilotkit.ai",
|
|
43
43
|
* wsUrl: "wss://api.copilotkit.ai",
|
|
44
44
|
* apiKey: process.env.COPILOTKIT_API_KEY!,
|
|
45
|
-
* organizationId: process.env.COPILOTKIT_ORGANIZATION_ID!,
|
|
46
45
|
* });
|
|
47
46
|
*
|
|
48
47
|
* const runtime = new CopilotRuntime({
|
|
@@ -66,8 +65,6 @@ export interface CopilotKitIntelligenceConfig {
|
|
|
66
65
|
wsUrl: string;
|
|
67
66
|
/** API key for authenticating with the intelligence platform */
|
|
68
67
|
apiKey: string;
|
|
69
|
-
/** Organization identifier used for self-hosted Intelligence instances */
|
|
70
|
-
organizationId: string;
|
|
71
68
|
/**
|
|
72
69
|
* Initial listener invoked after a thread is created.
|
|
73
70
|
* Prefer {@link CopilotKitIntelligence.onThreadCreated} for multiple listeners.
|
|
@@ -248,7 +245,6 @@ export class CopilotKitIntelligence {
|
|
|
248
245
|
#runnerWsUrl: string;
|
|
249
246
|
#clientWsUrl: string;
|
|
250
247
|
#apiKey: string;
|
|
251
|
-
#organizationId: string;
|
|
252
248
|
#threadCreatedListeners = new Set<(thread: ThreadSummary) => void>();
|
|
253
249
|
#threadUpdatedListeners = new Set<(thread: ThreadSummary) => void>();
|
|
254
250
|
#threadDeletedListeners = new Set<(params: ThreadDeletedPayload) => void>();
|
|
@@ -260,7 +256,6 @@ export class CopilotKitIntelligence {
|
|
|
260
256
|
this.#runnerWsUrl = deriveRunnerWsUrl(intelligenceWsUrl);
|
|
261
257
|
this.#clientWsUrl = deriveClientWsUrl(intelligenceWsUrl);
|
|
262
258
|
this.#apiKey = config.apiKey;
|
|
263
|
-
this.#organizationId = config.organizationId;
|
|
264
259
|
|
|
265
260
|
if (config.onThreadCreated) {
|
|
266
261
|
this.onThreadCreated(config.onThreadCreated);
|
|
@@ -345,10 +340,6 @@ export class CopilotKitIntelligence {
|
|
|
345
340
|
return this.#clientWsUrl;
|
|
346
341
|
}
|
|
347
342
|
|
|
348
|
-
ɵgetOrganizationId(): string {
|
|
349
|
-
return this.#organizationId;
|
|
350
|
-
}
|
|
351
|
-
|
|
352
343
|
ɵgetRunnerAuthToken(): string {
|
|
353
344
|
return this.#apiKey;
|
|
354
345
|
}
|
|
@@ -359,7 +350,6 @@ export class CopilotKitIntelligence {
|
|
|
359
350
|
const headers: Record<string, string> = {
|
|
360
351
|
Authorization: `Bearer ${this.#apiKey}`,
|
|
361
352
|
"Content-Type": "application/json",
|
|
362
|
-
"X-Organization-Id": this.#organizationId,
|
|
363
353
|
};
|
|
364
354
|
|
|
365
355
|
const response = await fetch(url, {
|
|
@@ -400,7 +390,7 @@ export class CopilotKitIntelligence {
|
|
|
400
390
|
|
|
401
391
|
for (const callback of listeners) {
|
|
402
392
|
try {
|
|
403
|
-
|
|
393
|
+
(callback as (p: typeof payload) => void)(payload);
|
|
404
394
|
} catch (error) {
|
|
405
395
|
logger.error(
|
|
406
396
|
{ err: error, callbackName, payload },
|
|
@@ -663,12 +653,14 @@ export class CopilotKitIntelligence {
|
|
|
663
653
|
async ɵconnectThread(params: {
|
|
664
654
|
threadId: string;
|
|
665
655
|
userId: string;
|
|
656
|
+
runId?: string;
|
|
666
657
|
lastSeenEventId?: string | null;
|
|
667
658
|
}): Promise<ConnectThreadResponse> {
|
|
668
659
|
const result = await this.#request<
|
|
669
660
|
ConnectThreadBootstrapResponse | ConnectThreadLiveResponse
|
|
670
661
|
>("POST", `/api/threads/${encodeURIComponent(params.threadId)}/connect`, {
|
|
671
662
|
userId: params.userId,
|
|
663
|
+
...(params.runId !== undefined ? { runId: params.runId } : {}),
|
|
672
664
|
...(params.lastSeenEventId !== undefined
|
|
673
665
|
? { lastSeenEventId: params.lastSeenEventId }
|
|
674
666
|
: {}),
|
|
@@ -286,6 +286,49 @@ describe("IntelligenceAgentRunner", () => {
|
|
|
286
286
|
expect(ch.pushLog[2].payload.metadata.cpki_event_seq).toBe(3);
|
|
287
287
|
});
|
|
288
288
|
|
|
289
|
+
it("overrides conflicting event thread and run ownership before pushing to the channel", async () => {
|
|
290
|
+
const threadId = "t-canonical";
|
|
291
|
+
const input = createRunInput({ threadId, runId: "r-canonical" });
|
|
292
|
+
|
|
293
|
+
const agent = new MockAgent([
|
|
294
|
+
{
|
|
295
|
+
type: EventType.RUN_STARTED,
|
|
296
|
+
threadId: "backend-thread",
|
|
297
|
+
runId: "backend-run",
|
|
298
|
+
} as RunStartedEvent,
|
|
299
|
+
{
|
|
300
|
+
type: EventType.RUN_FINISHED,
|
|
301
|
+
threadId: "backend-thread",
|
|
302
|
+
runId: "backend-run",
|
|
303
|
+
} as RunFinishedEvent,
|
|
304
|
+
]);
|
|
305
|
+
|
|
306
|
+
const eventsPromise = collectEvents(
|
|
307
|
+
runner.run({ threadId, agent, input }),
|
|
308
|
+
);
|
|
309
|
+
const ch = mockChannels[0];
|
|
310
|
+
ch.triggerJoin("ok");
|
|
311
|
+
|
|
312
|
+
await eventsPromise;
|
|
313
|
+
|
|
314
|
+
expect(ch.pushLog.map((entry) => entry.payload)).toEqual([
|
|
315
|
+
expect.objectContaining({
|
|
316
|
+
type: EventType.RUN_STARTED,
|
|
317
|
+
threadId,
|
|
318
|
+
runId: input.runId,
|
|
319
|
+
thread_id: threadId,
|
|
320
|
+
run_id: input.runId,
|
|
321
|
+
}),
|
|
322
|
+
expect.objectContaining({
|
|
323
|
+
type: EventType.RUN_FINISHED,
|
|
324
|
+
threadId,
|
|
325
|
+
runId: input.runId,
|
|
326
|
+
thread_id: threadId,
|
|
327
|
+
run_id: input.runId,
|
|
328
|
+
}),
|
|
329
|
+
]);
|
|
330
|
+
});
|
|
331
|
+
|
|
289
332
|
it("rewrites RUN_STARTED input.messages to the unseen persisted subset", async () => {
|
|
290
333
|
const threadId = "t-persisted-input";
|
|
291
334
|
const input = createRunInput({
|
|
@@ -442,7 +485,14 @@ describe("IntelligenceAgentRunner", () => {
|
|
|
442
485
|
(p) => p.payload?.type === EventType.RUN_ERROR,
|
|
443
486
|
);
|
|
444
487
|
expect(errorPush).toBeDefined();
|
|
445
|
-
expect(errorPush!.payload
|
|
488
|
+
expect(errorPush!.payload).toMatchObject({
|
|
489
|
+
type: EventType.RUN_ERROR,
|
|
490
|
+
message: "Something went wrong",
|
|
491
|
+
threadId,
|
|
492
|
+
runId: input.runId,
|
|
493
|
+
thread_id: threadId,
|
|
494
|
+
run_id: input.runId,
|
|
495
|
+
});
|
|
446
496
|
});
|
|
447
497
|
|
|
448
498
|
it("finalizes open message streams before completing", async () => {
|
|
@@ -95,22 +95,33 @@ export class IntelligenceAgentRunner extends AgentRunner {
|
|
|
95
95
|
request: AgentRunnerRunRequest,
|
|
96
96
|
state: ThreadState,
|
|
97
97
|
): Record<string, unknown> {
|
|
98
|
-
const canonicalEvent = this.stampRunnerMetadata(
|
|
98
|
+
const canonicalEvent = this.stampRunnerMetadata(
|
|
99
|
+
this.stampCanonicalRunOwnership(event, request),
|
|
100
|
+
state,
|
|
101
|
+
);
|
|
99
102
|
const payload = {
|
|
100
103
|
...(canonicalEvent as Record<string, unknown>),
|
|
101
104
|
};
|
|
102
105
|
|
|
103
|
-
payload.
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
if (runId) {
|
|
108
|
-
payload.run_id = runId;
|
|
109
|
-
}
|
|
106
|
+
payload.threadId = request.threadId;
|
|
107
|
+
payload.runId = request.input.runId;
|
|
108
|
+
payload.thread_id = request.threadId;
|
|
109
|
+
payload.run_id = request.input.runId;
|
|
110
110
|
|
|
111
111
|
return payload;
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
+
private stampCanonicalRunOwnership(
|
|
115
|
+
event: BaseEvent,
|
|
116
|
+
request: AgentRunnerRunRequest,
|
|
117
|
+
): BaseEvent {
|
|
118
|
+
return {
|
|
119
|
+
...(event as BaseEvent & Record<string, unknown>),
|
|
120
|
+
threadId: request.threadId,
|
|
121
|
+
runId: request.input.runId,
|
|
122
|
+
} as BaseEvent;
|
|
123
|
+
}
|
|
124
|
+
|
|
114
125
|
private stampRunnerMetadata(event: BaseEvent, state: ThreadState): BaseEvent {
|
|
115
126
|
const eventRecord = event as BaseEvent & {
|
|
116
127
|
metadata?: Record<string, unknown>;
|
|
@@ -327,7 +338,10 @@ export class IntelligenceAgentRunner extends AgentRunner {
|
|
|
327
338
|
): Observable<void> {
|
|
328
339
|
const { currentEvents, channel } = state;
|
|
329
340
|
const pushCanonicalEvent = (event: BaseEvent): void => {
|
|
330
|
-
const canonicalEvent = this.stampRunnerMetadata(
|
|
341
|
+
const canonicalEvent = this.stampRunnerMetadata(
|
|
342
|
+
this.stampCanonicalRunOwnership(event, request),
|
|
343
|
+
state,
|
|
344
|
+
);
|
|
331
345
|
currentEvents.push(canonicalEvent);
|
|
332
346
|
|
|
333
347
|
if (canonicalEvent.type === EventType.RUN_STARTED) {
|
|
@@ -355,8 +369,12 @@ export class IntelligenceAgentRunner extends AgentRunner {
|
|
|
355
369
|
threadId: request.threadId,
|
|
356
370
|
runId: request.input.runId,
|
|
357
371
|
}),
|
|
372
|
+
threadId: request.threadId,
|
|
373
|
+
runId: request.input.runId,
|
|
358
374
|
input: {
|
|
359
375
|
...baseInput,
|
|
376
|
+
threadId: request.threadId,
|
|
377
|
+
runId: request.input.runId,
|
|
360
378
|
...(persistedInputMessages !== undefined
|
|
361
379
|
? { messages: persistedInputMessages }
|
|
362
380
|
: {}),
|
|
@@ -374,4 +374,272 @@ describe("AnthropicAdapter", () => {
|
|
|
374
374
|
});
|
|
375
375
|
});
|
|
376
376
|
});
|
|
377
|
+
|
|
378
|
+
describe("Unknown Tool Use Handling", () => {
|
|
379
|
+
it("should skip unknown tool_use blocks without crashing", async () => {
|
|
380
|
+
const systemMessage = new TextMessage("system", "System message");
|
|
381
|
+
const userMessage = new TextMessage("user", "Do something");
|
|
382
|
+
|
|
383
|
+
// Mock Anthropic to return a stream with an unknown tool_use block
|
|
384
|
+
mockAnthropicCreate.mockResolvedValue({
|
|
385
|
+
[Symbol.asyncIterator]: async function* () {
|
|
386
|
+
yield { type: "message_start", message: { id: "msg-1" } };
|
|
387
|
+
// Unknown tool_use block — tool name not in the actions list
|
|
388
|
+
yield {
|
|
389
|
+
type: "content_block_start",
|
|
390
|
+
content_block: {
|
|
391
|
+
type: "tool_use",
|
|
392
|
+
id: "tool-unknown",
|
|
393
|
+
name: "nonexistent_tool",
|
|
394
|
+
},
|
|
395
|
+
};
|
|
396
|
+
yield {
|
|
397
|
+
type: "content_block_delta",
|
|
398
|
+
delta: { type: "input_json_delta", partial_json: '{"query":' },
|
|
399
|
+
};
|
|
400
|
+
yield {
|
|
401
|
+
type: "content_block_delta",
|
|
402
|
+
delta: { type: "input_json_delta", partial_json: '"test"}' },
|
|
403
|
+
};
|
|
404
|
+
yield { type: "content_block_stop" };
|
|
405
|
+
// Then a normal text block
|
|
406
|
+
yield {
|
|
407
|
+
type: "content_block_start",
|
|
408
|
+
content_block: { type: "text" },
|
|
409
|
+
};
|
|
410
|
+
yield {
|
|
411
|
+
type: "content_block_delta",
|
|
412
|
+
delta: { type: "text_delta", text: "Here is the result." },
|
|
413
|
+
};
|
|
414
|
+
yield { type: "content_block_stop" };
|
|
415
|
+
},
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
const mockStream = {
|
|
419
|
+
sendTextMessageStart: vi.fn(),
|
|
420
|
+
sendTextMessageContent: vi.fn(),
|
|
421
|
+
sendTextMessageEnd: vi.fn(),
|
|
422
|
+
sendActionExecutionStart: vi.fn(),
|
|
423
|
+
sendActionExecutionArgs: vi.fn(),
|
|
424
|
+
sendActionExecutionEnd: vi.fn(),
|
|
425
|
+
complete: vi.fn(),
|
|
426
|
+
};
|
|
427
|
+
|
|
428
|
+
let streamCallbackDone: Promise<void>;
|
|
429
|
+
mockEventSource.stream.mockImplementation((callback: any) => {
|
|
430
|
+
streamCallbackDone = callback(mockStream);
|
|
431
|
+
});
|
|
432
|
+
|
|
433
|
+
await adapter.process({
|
|
434
|
+
threadId: "test-thread",
|
|
435
|
+
messages: [systemMessage, userMessage],
|
|
436
|
+
actions: [
|
|
437
|
+
{
|
|
438
|
+
name: "known_tool",
|
|
439
|
+
description: "A known tool",
|
|
440
|
+
parameters: [],
|
|
441
|
+
jsonSchema: '{"type":"object","properties":{}}',
|
|
442
|
+
},
|
|
443
|
+
],
|
|
444
|
+
eventSource: mockEventSource,
|
|
445
|
+
forwardedParameters: {},
|
|
446
|
+
});
|
|
447
|
+
|
|
448
|
+
// Wait for async stream processing to complete
|
|
449
|
+
await streamCallbackDone!;
|
|
450
|
+
|
|
451
|
+
// Should NOT have sent action execution events for the unknown tool
|
|
452
|
+
expect(mockStream.sendActionExecutionStart).not.toHaveBeenCalled();
|
|
453
|
+
expect(mockStream.sendActionExecutionArgs).not.toHaveBeenCalled();
|
|
454
|
+
expect(mockStream.sendActionExecutionEnd).not.toHaveBeenCalled();
|
|
455
|
+
|
|
456
|
+
// Should still process the text block normally
|
|
457
|
+
expect(mockStream.sendTextMessageStart).toHaveBeenCalled();
|
|
458
|
+
expect(mockStream.sendTextMessageContent).toHaveBeenCalledWith({
|
|
459
|
+
messageId: "msg-1",
|
|
460
|
+
content: "Here is the result.",
|
|
461
|
+
});
|
|
462
|
+
expect(mockStream.sendTextMessageEnd).toHaveBeenCalled();
|
|
463
|
+
expect(mockStream.complete).toHaveBeenCalled();
|
|
464
|
+
});
|
|
465
|
+
|
|
466
|
+
it("should trigger fallback when only unknown tool_use blocks are returned", async () => {
|
|
467
|
+
const systemMessage = new TextMessage("system", "System message");
|
|
468
|
+
const userMessage = new TextMessage("user", "Do something");
|
|
469
|
+
|
|
470
|
+
const toolExecution = new ActionExecutionMessage({
|
|
471
|
+
id: "tool-prev",
|
|
472
|
+
name: "someAction",
|
|
473
|
+
arguments: "{}",
|
|
474
|
+
});
|
|
475
|
+
|
|
476
|
+
const toolResult = new ResultMessage({
|
|
477
|
+
actionExecutionId: "tool-prev",
|
|
478
|
+
result: "Previous result",
|
|
479
|
+
});
|
|
480
|
+
|
|
481
|
+
// Mock Anthropic to return ONLY an unknown tool_use block
|
|
482
|
+
mockAnthropicCreate.mockResolvedValue({
|
|
483
|
+
[Symbol.asyncIterator]: async function* () {
|
|
484
|
+
yield { type: "message_start", message: { id: "msg-1" } };
|
|
485
|
+
yield {
|
|
486
|
+
type: "content_block_start",
|
|
487
|
+
content_block: {
|
|
488
|
+
type: "tool_use",
|
|
489
|
+
id: "tool-unknown",
|
|
490
|
+
name: "nonexistent_tool",
|
|
491
|
+
},
|
|
492
|
+
};
|
|
493
|
+
yield {
|
|
494
|
+
type: "content_block_delta",
|
|
495
|
+
delta: { type: "input_json_delta", partial_json: "{}" },
|
|
496
|
+
};
|
|
497
|
+
yield { type: "content_block_stop" };
|
|
498
|
+
},
|
|
499
|
+
});
|
|
500
|
+
|
|
501
|
+
const mockStream = {
|
|
502
|
+
sendTextMessageStart: vi.fn(),
|
|
503
|
+
sendTextMessageContent: vi.fn(),
|
|
504
|
+
sendTextMessageEnd: vi.fn(),
|
|
505
|
+
sendActionExecutionStart: vi.fn(),
|
|
506
|
+
sendActionExecutionArgs: vi.fn(),
|
|
507
|
+
sendActionExecutionEnd: vi.fn(),
|
|
508
|
+
complete: vi.fn(),
|
|
509
|
+
};
|
|
510
|
+
|
|
511
|
+
let streamCallbackDone: Promise<void>;
|
|
512
|
+
mockEventSource.stream.mockImplementation((callback: any) => {
|
|
513
|
+
streamCallbackDone = callback(mockStream);
|
|
514
|
+
});
|
|
515
|
+
|
|
516
|
+
await adapter.process({
|
|
517
|
+
threadId: "test-thread",
|
|
518
|
+
messages: [systemMessage, userMessage, toolExecution, toolResult],
|
|
519
|
+
actions: [
|
|
520
|
+
{
|
|
521
|
+
name: "known_tool",
|
|
522
|
+
description: "A known tool",
|
|
523
|
+
parameters: [],
|
|
524
|
+
jsonSchema: '{"type":"object","properties":{}}',
|
|
525
|
+
},
|
|
526
|
+
],
|
|
527
|
+
eventSource: mockEventSource,
|
|
528
|
+
forwardedParameters: {},
|
|
529
|
+
});
|
|
530
|
+
|
|
531
|
+
// Wait for async stream processing to complete
|
|
532
|
+
await streamCallbackDone!;
|
|
533
|
+
|
|
534
|
+
// Should NOT have sent action execution events
|
|
535
|
+
expect(mockStream.sendActionExecutionStart).not.toHaveBeenCalled();
|
|
536
|
+
|
|
537
|
+
// Should trigger fallback since hasReceivedContent should be false
|
|
538
|
+
expect(mockStream.sendTextMessageStart).toHaveBeenCalled();
|
|
539
|
+
expect(mockStream.sendTextMessageContent).toHaveBeenCalledWith({
|
|
540
|
+
messageId: expect.any(String),
|
|
541
|
+
content: "Previous result",
|
|
542
|
+
});
|
|
543
|
+
expect(mockStream.sendTextMessageEnd).toHaveBeenCalled();
|
|
544
|
+
});
|
|
545
|
+
});
|
|
546
|
+
});
|
|
547
|
+
|
|
548
|
+
describe("AnthropicAdapter max_tokens default", () => {
|
|
549
|
+
let mockAnthropicCreate: any;
|
|
550
|
+
let mockEventSource: any;
|
|
551
|
+
|
|
552
|
+
beforeEach(() => {
|
|
553
|
+
vi.clearAllMocks();
|
|
554
|
+
});
|
|
555
|
+
|
|
556
|
+
it("should default max_tokens to 4096 when not specified", async () => {
|
|
557
|
+
const mockAnthropic = {
|
|
558
|
+
messages: {
|
|
559
|
+
create: vi.fn(),
|
|
560
|
+
},
|
|
561
|
+
};
|
|
562
|
+
|
|
563
|
+
const adapter = new AnthropicAdapter({ anthropic: mockAnthropic as any });
|
|
564
|
+
mockAnthropicCreate = mockAnthropic.messages.create;
|
|
565
|
+
|
|
566
|
+
mockAnthropicCreate.mockResolvedValue({
|
|
567
|
+
[Symbol.asyncIterator]: async function* () {},
|
|
568
|
+
});
|
|
569
|
+
|
|
570
|
+
mockEventSource = {
|
|
571
|
+
stream: vi.fn((callback) => {
|
|
572
|
+
const mockStream = {
|
|
573
|
+
sendTextMessageStart: vi.fn(),
|
|
574
|
+
sendTextMessageContent: vi.fn(),
|
|
575
|
+
sendTextMessageEnd: vi.fn(),
|
|
576
|
+
sendActionExecutionStart: vi.fn(),
|
|
577
|
+
sendActionExecutionArgs: vi.fn(),
|
|
578
|
+
sendActionExecutionEnd: vi.fn(),
|
|
579
|
+
complete: vi.fn(),
|
|
580
|
+
};
|
|
581
|
+
callback(mockStream);
|
|
582
|
+
return Promise.resolve();
|
|
583
|
+
}),
|
|
584
|
+
};
|
|
585
|
+
|
|
586
|
+
const systemMessage = new TextMessage("system", "System message");
|
|
587
|
+
const userMessage = new TextMessage("user", "Hello");
|
|
588
|
+
|
|
589
|
+
await adapter.process({
|
|
590
|
+
threadId: "test-thread",
|
|
591
|
+
messages: [systemMessage, userMessage],
|
|
592
|
+
actions: [],
|
|
593
|
+
eventSource: mockEventSource,
|
|
594
|
+
forwardedParameters: {},
|
|
595
|
+
});
|
|
596
|
+
|
|
597
|
+
const createCallArgs = mockAnthropicCreate.mock.calls[0][0];
|
|
598
|
+
expect(createCallArgs.max_tokens).toBe(4096);
|
|
599
|
+
});
|
|
600
|
+
|
|
601
|
+
it("should use provided maxTokens when specified", async () => {
|
|
602
|
+
const mockAnthropic = {
|
|
603
|
+
messages: {
|
|
604
|
+
create: vi.fn(),
|
|
605
|
+
},
|
|
606
|
+
};
|
|
607
|
+
|
|
608
|
+
const adapter = new AnthropicAdapter({ anthropic: mockAnthropic as any });
|
|
609
|
+
mockAnthropicCreate = mockAnthropic.messages.create;
|
|
610
|
+
|
|
611
|
+
mockAnthropicCreate.mockResolvedValue({
|
|
612
|
+
[Symbol.asyncIterator]: async function* () {},
|
|
613
|
+
});
|
|
614
|
+
|
|
615
|
+
mockEventSource = {
|
|
616
|
+
stream: vi.fn((callback) => {
|
|
617
|
+
const mockStream = {
|
|
618
|
+
sendTextMessageStart: vi.fn(),
|
|
619
|
+
sendTextMessageContent: vi.fn(),
|
|
620
|
+
sendTextMessageEnd: vi.fn(),
|
|
621
|
+
sendActionExecutionStart: vi.fn(),
|
|
622
|
+
sendActionExecutionArgs: vi.fn(),
|
|
623
|
+
sendActionExecutionEnd: vi.fn(),
|
|
624
|
+
complete: vi.fn(),
|
|
625
|
+
};
|
|
626
|
+
callback(mockStream);
|
|
627
|
+
return Promise.resolve();
|
|
628
|
+
}),
|
|
629
|
+
};
|
|
630
|
+
|
|
631
|
+
const systemMessage = new TextMessage("system", "System message");
|
|
632
|
+
const userMessage = new TextMessage("user", "Hello");
|
|
633
|
+
|
|
634
|
+
await adapter.process({
|
|
635
|
+
threadId: "test-thread",
|
|
636
|
+
messages: [systemMessage, userMessage],
|
|
637
|
+
actions: [],
|
|
638
|
+
eventSource: mockEventSource,
|
|
639
|
+
forwardedParameters: { maxTokens: 8192 },
|
|
640
|
+
});
|
|
641
|
+
|
|
642
|
+
const createCallArgs = mockAnthropicCreate.mock.calls[0][0];
|
|
643
|
+
expect(createCallArgs.max_tokens).toBe(8192);
|
|
644
|
+
});
|
|
377
645
|
});
|