@copilotkit/runtime 1.55.3 → 1.56.0
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/converters/tanstack.cjs.map +1 -1
- package/dist/agent/converters/tanstack.d.cts +6 -19
- package/dist/agent/converters/tanstack.d.cts.map +1 -1
- package/dist/agent/converters/tanstack.d.mts +6 -19
- package/dist/agent/converters/tanstack.d.mts.map +1 -1
- package/dist/agent/converters/tanstack.mjs.map +1 -1
- package/dist/agent/index.cjs +14 -0
- package/dist/agent/index.cjs.map +1 -1
- package/dist/agent/index.d.cts +12 -1
- package/dist/agent/index.d.cts.map +1 -1
- package/dist/agent/index.d.mts +12 -1
- package/dist/agent/index.d.mts.map +1 -1
- package/dist/agent/index.mjs +14 -0
- package/dist/agent/index.mjs.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +3 -2
- package/dist/index.d.mts +3 -2
- package/dist/index.mjs +1 -1
- package/dist/lib/index.cjs +1 -1
- package/dist/lib/index.d.cts +2 -1
- package/dist/lib/index.d.cts.map +1 -1
- package/dist/lib/index.d.mts +2 -1
- package/dist/lib/index.d.mts.map +1 -1
- package/dist/lib/index.mjs +1 -1
- package/dist/lib/integrations/shared.cjs +1 -1
- package/dist/lib/integrations/shared.d.cts +1 -1
- package/dist/lib/integrations/shared.d.mts +1 -1
- package/dist/lib/integrations/shared.mjs +1 -1
- package/dist/lib/runtime/copilot-runtime.cjs +14 -4
- package/dist/lib/runtime/copilot-runtime.cjs.map +1 -1
- package/dist/lib/runtime/copilot-runtime.d.cts +15 -3
- package/dist/lib/runtime/copilot-runtime.d.cts.map +1 -1
- package/dist/lib/runtime/copilot-runtime.d.mts +15 -3
- package/dist/lib/runtime/copilot-runtime.d.mts.map +1 -1
- package/dist/lib/runtime/copilot-runtime.mjs +14 -4
- package/dist/lib/runtime/copilot-runtime.mjs.map +1 -1
- package/dist/package.cjs +6 -5
- package/dist/package.mjs +6 -5
- package/dist/service-adapters/openai/openai-adapter.cjs +1 -1
- package/dist/service-adapters/openai/openai-adapter.cjs.map +1 -1
- package/dist/service-adapters/openai/openai-adapter.d.cts.map +1 -1
- package/dist/service-adapters/openai/openai-adapter.d.mts.map +1 -1
- package/dist/service-adapters/openai/openai-adapter.mjs +2 -2
- package/dist/service-adapters/openai/openai-adapter.mjs.map +1 -1
- package/dist/service-adapters/openai/openai-assistant-adapter.cjs +8 -9
- package/dist/service-adapters/openai/openai-assistant-adapter.cjs.map +1 -1
- package/dist/service-adapters/openai/openai-assistant-adapter.d.cts.map +1 -1
- package/dist/service-adapters/openai/openai-assistant-adapter.d.mts.map +1 -1
- package/dist/service-adapters/openai/openai-assistant-adapter.mjs +9 -10
- package/dist/service-adapters/openai/openai-assistant-adapter.mjs.map +1 -1
- package/dist/service-adapters/openai/utils.cjs +53 -0
- package/dist/service-adapters/openai/utils.cjs.map +1 -1
- package/dist/service-adapters/openai/utils.mjs +51 -1
- package/dist/service-adapters/openai/utils.mjs.map +1 -1
- package/dist/v2/index.cjs +1 -0
- package/dist/v2/index.d.cts +3 -3
- package/dist/v2/index.d.mts +3 -3
- package/dist/v2/index.mjs +2 -2
- package/dist/v2/runtime/core/runtime.cjs +25 -0
- package/dist/v2/runtime/core/runtime.cjs.map +1 -1
- package/dist/v2/runtime/core/runtime.d.cts +53 -4
- package/dist/v2/runtime/core/runtime.d.cts.map +1 -1
- package/dist/v2/runtime/core/runtime.d.mts +53 -4
- package/dist/v2/runtime/core/runtime.d.mts.map +1 -1
- package/dist/v2/runtime/core/runtime.mjs +26 -2
- package/dist/v2/runtime/core/runtime.mjs.map +1 -1
- package/dist/v2/runtime/handlers/get-runtime-info.cjs +18 -10
- package/dist/v2/runtime/handlers/get-runtime-info.cjs.map +1 -1
- package/dist/v2/runtime/handlers/get-runtime-info.mjs +19 -11
- package/dist/v2/runtime/handlers/get-runtime-info.mjs.map +1 -1
- package/dist/v2/runtime/handlers/handle-connect.cjs +1 -1
- package/dist/v2/runtime/handlers/handle-connect.cjs.map +1 -1
- package/dist/v2/runtime/handlers/handle-connect.mjs +1 -1
- package/dist/v2/runtime/handlers/handle-connect.mjs.map +1 -1
- package/dist/v2/runtime/handlers/handle-run.cjs +8 -2
- package/dist/v2/runtime/handlers/handle-run.cjs.map +1 -1
- package/dist/v2/runtime/handlers/handle-run.mjs +8 -2
- package/dist/v2/runtime/handlers/handle-run.mjs.map +1 -1
- package/dist/v2/runtime/handlers/handle-stop.cjs +2 -1
- package/dist/v2/runtime/handlers/handle-stop.cjs.map +1 -1
- package/dist/v2/runtime/handlers/handle-stop.mjs +2 -1
- package/dist/v2/runtime/handlers/handle-stop.mjs.map +1 -1
- package/dist/v2/runtime/handlers/intelligence/thread-names.cjs +1 -1
- package/dist/v2/runtime/handlers/intelligence/thread-names.cjs.map +1 -1
- package/dist/v2/runtime/handlers/intelligence/thread-names.mjs +1 -1
- package/dist/v2/runtime/handlers/intelligence/thread-names.mjs.map +1 -1
- package/dist/v2/runtime/handlers/shared/agent-utils.cjs +3 -2
- package/dist/v2/runtime/handlers/shared/agent-utils.cjs.map +1 -1
- package/dist/v2/runtime/handlers/shared/agent-utils.mjs +3 -2
- package/dist/v2/runtime/handlers/shared/agent-utils.mjs.map +1 -1
- package/dist/v2/runtime/handlers/shared/sse-response.cjs +40 -1
- package/dist/v2/runtime/handlers/shared/sse-response.cjs.map +1 -1
- package/dist/v2/runtime/handlers/shared/sse-response.mjs +40 -1
- package/dist/v2/runtime/handlers/shared/sse-response.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 -1
- package/package.json +7 -6
- package/src/agent/__tests__/capabilities.test.ts +81 -0
- package/src/agent/converters/tanstack.ts +15 -7
- package/src/agent/index.ts +33 -0
- package/src/lib/runtime/__tests__/v1-agent-factory.test.ts +109 -0
- package/src/lib/runtime/copilot-runtime.ts +38 -2
- package/src/service-adapters/openai/__tests__/openai-v5-compat.test.ts +177 -0
- package/src/service-adapters/openai/openai-adapter.ts +3 -1
- package/src/service-adapters/openai/openai-assistant-adapter.ts +7 -9
- package/src/service-adapters/openai/utils.ts +100 -0
- package/src/v2/runtime/__tests__/agents-factory.test.ts +136 -0
- package/src/v2/runtime/__tests__/debug-sse-response.test.ts +302 -0
- package/src/v2/runtime/__tests__/get-runtime-info.test.ts +134 -1
- package/src/v2/runtime/core/runtime.ts +90 -2
- package/src/v2/runtime/handlers/get-runtime-info.ts +33 -8
- package/src/v2/runtime/handlers/handle-connect.ts +1 -1
- package/src/v2/runtime/handlers/handle-run.ts +16 -2
- package/src/v2/runtime/handlers/handle-stop.ts +2 -1
- package/src/v2/runtime/handlers/intelligence/thread-names.ts +1 -1
- package/src/v2/runtime/handlers/shared/agent-utils.ts +3 -2
- package/src/v2/runtime/handlers/shared/sse-response.ts +69 -0
- package/src/v2/runtime/handlers/sse/run.ts +9 -0
|
@@ -9,6 +9,11 @@ import {
|
|
|
9
9
|
createLicenseChecker,
|
|
10
10
|
type LicenseChecker,
|
|
11
11
|
} from "@copilotkit/license-verifier";
|
|
12
|
+
import {
|
|
13
|
+
type ResolvedDebugConfig,
|
|
14
|
+
resolveDebugConfig,
|
|
15
|
+
type DebugConfig,
|
|
16
|
+
} from "@copilotkit/shared";
|
|
12
17
|
import { AbstractAgent } from "@ag-ui/client";
|
|
13
18
|
import type { MCPClientConfig } from "@ag-ui/mcp-apps-middleware";
|
|
14
19
|
import { A2UIMiddlewareConfig } from "@ag-ui/a2ui-middleware";
|
|
@@ -17,6 +22,7 @@ import type {
|
|
|
17
22
|
BeforeRequestMiddleware,
|
|
18
23
|
AfterRequestMiddleware,
|
|
19
24
|
} from "./middleware";
|
|
25
|
+
import { createLogger, type CopilotRuntimeLogger } from "../../../lib/logger";
|
|
20
26
|
import { TranscriptionService } from "../transcription-service/transcription-service";
|
|
21
27
|
import { AgentRunner } from "../runner/agent-runner";
|
|
22
28
|
import { InMemoryAgentRunner } from "../runner/in-memory";
|
|
@@ -56,9 +62,70 @@ interface CopilotRuntimeMiddlewares {
|
|
|
56
62
|
openGenerativeUI?: OpenGenerativeUIConfig;
|
|
57
63
|
}
|
|
58
64
|
|
|
65
|
+
/**
|
|
66
|
+
* Context passed to agent factory functions for per-request agent resolution.
|
|
67
|
+
*/
|
|
68
|
+
export interface AgentFactoryContext {
|
|
69
|
+
/** The incoming HTTP request. */
|
|
70
|
+
request: Request;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* A function that dynamically creates agents on a per-request basis.
|
|
75
|
+
* Useful for multi-tenant scenarios or request-scoped agent configuration.
|
|
76
|
+
*/
|
|
77
|
+
export type AgentsFactory = (
|
|
78
|
+
ctx: AgentFactoryContext,
|
|
79
|
+
) => MaybePromise<NonEmptyRecord<Record<string, AbstractAgent>>>;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Agents can be provided as:
|
|
83
|
+
* - A static record of agents
|
|
84
|
+
* - A Promise that resolves to a record of agents
|
|
85
|
+
* - A factory function that receives request context and returns agents (or a Promise of agents)
|
|
86
|
+
*/
|
|
87
|
+
export type AgentsConfig =
|
|
88
|
+
| MaybePromise<NonEmptyRecord<Record<string, AbstractAgent>>>
|
|
89
|
+
| AgentsFactory;
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Resolve an AgentsConfig value to a concrete record of agents.
|
|
93
|
+
* If the config is a factory function, it is called with the given request context.
|
|
94
|
+
* Otherwise it is awaited directly (static record or Promise).
|
|
95
|
+
*/
|
|
96
|
+
export async function resolveAgents(
|
|
97
|
+
agents: AgentsConfig,
|
|
98
|
+
request?: Request,
|
|
99
|
+
): Promise<Record<string, AbstractAgent>> {
|
|
100
|
+
if (typeof agents === "function") {
|
|
101
|
+
if (!request) {
|
|
102
|
+
throw new Error(
|
|
103
|
+
"Agent factory function requires a request context, but none was provided.",
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
return agents({ request });
|
|
107
|
+
}
|
|
108
|
+
return agents;
|
|
109
|
+
}
|
|
110
|
+
|
|
59
111
|
interface BaseCopilotRuntimeOptions extends CopilotRuntimeMiddlewares {
|
|
60
|
-
/**
|
|
61
|
-
|
|
112
|
+
/**
|
|
113
|
+
* Map of available agents, or a factory function for per-request agent resolution.
|
|
114
|
+
*
|
|
115
|
+
* Static record:
|
|
116
|
+
* ```ts
|
|
117
|
+
* agents: { support: new SupportAgent(), technical: new TechnicalAgent() }
|
|
118
|
+
* ```
|
|
119
|
+
*
|
|
120
|
+
* Factory function (called per-request):
|
|
121
|
+
* ```ts
|
|
122
|
+
* agents: ({ request }) => {
|
|
123
|
+
* const tenantId = request.headers.get("x-tenant-id");
|
|
124
|
+
* return { default: createAgentForTenant(tenantId) };
|
|
125
|
+
* }
|
|
126
|
+
* ```
|
|
127
|
+
*/
|
|
128
|
+
agents: AgentsConfig;
|
|
62
129
|
/** Optional transcription service for audio processing. */
|
|
63
130
|
transcriptionService?: TranscriptionService;
|
|
64
131
|
/** Optional *before* middleware – callback function or webhook URL. */
|
|
@@ -67,6 +134,8 @@ interface BaseCopilotRuntimeOptions extends CopilotRuntimeMiddlewares {
|
|
|
67
134
|
afterRequestMiddleware?: AfterRequestMiddleware;
|
|
68
135
|
/** Signed license token for server-side feature verification. Falls back to COPILOTKIT_LICENSE_TOKEN env var. */
|
|
69
136
|
licenseToken?: string;
|
|
137
|
+
/** Enable debug logging for the event pipeline. */
|
|
138
|
+
debug?: DebugConfig;
|
|
70
139
|
}
|
|
71
140
|
|
|
72
141
|
export interface CopilotRuntimeUser {
|
|
@@ -120,6 +189,8 @@ export interface CopilotRuntimeLike {
|
|
|
120
189
|
identifyUser?: IdentifyUserCallback;
|
|
121
190
|
mode: RuntimeMode;
|
|
122
191
|
licenseChecker?: LicenseChecker;
|
|
192
|
+
debug: ResolvedDebugConfig;
|
|
193
|
+
debugLogger?: CopilotRuntimeLogger;
|
|
123
194
|
}
|
|
124
195
|
|
|
125
196
|
export interface CopilotSseRuntimeLike extends CopilotRuntimeLike {
|
|
@@ -147,6 +218,8 @@ abstract class BaseCopilotRuntime implements CopilotRuntimeLike {
|
|
|
147
218
|
public mcpApps: CopilotRuntimeOptions["mcpApps"];
|
|
148
219
|
public openGenerativeUI: CopilotRuntimeOptions["openGenerativeUI"];
|
|
149
220
|
public licenseChecker?: LicenseChecker;
|
|
221
|
+
public debug: ResolvedDebugConfig;
|
|
222
|
+
public debugLogger?: CopilotRuntimeLogger;
|
|
150
223
|
|
|
151
224
|
abstract readonly intelligence?: CopilotKitIntelligence;
|
|
152
225
|
abstract readonly mode: RuntimeMode;
|
|
@@ -170,6 +243,13 @@ abstract class BaseCopilotRuntime implements CopilotRuntimeLike {
|
|
|
170
243
|
this.mcpApps = mcpApps;
|
|
171
244
|
this.openGenerativeUI = openGenerativeUI;
|
|
172
245
|
this.runner = runner;
|
|
246
|
+
this.debug = resolveDebugConfig(options.debug);
|
|
247
|
+
if (this.debug.enabled) {
|
|
248
|
+
this.debugLogger = createLogger({
|
|
249
|
+
level: "debug",
|
|
250
|
+
component: "copilotkit-debug",
|
|
251
|
+
});
|
|
252
|
+
}
|
|
173
253
|
}
|
|
174
254
|
}
|
|
175
255
|
|
|
@@ -326,4 +406,12 @@ export class CopilotRuntime implements CopilotRuntimeLike {
|
|
|
326
406
|
get licenseChecker() {
|
|
327
407
|
return this.delegate.licenseChecker;
|
|
328
408
|
}
|
|
409
|
+
|
|
410
|
+
get debug(): ResolvedDebugConfig {
|
|
411
|
+
return this.delegate.debug;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
get debugLogger(): CopilotRuntimeLogger | undefined {
|
|
415
|
+
return this.delegate.debugLogger;
|
|
416
|
+
}
|
|
329
417
|
}
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { AgentCapabilities } from "@ag-ui/core";
|
|
2
|
+
import {
|
|
3
|
+
CopilotRuntimeLike,
|
|
4
|
+
isIntelligenceRuntime,
|
|
5
|
+
resolveAgents,
|
|
6
|
+
} from "../core/runtime";
|
|
2
7
|
import {
|
|
3
8
|
AgentDescription,
|
|
4
9
|
RuntimeInfo,
|
|
@@ -26,22 +31,42 @@ interface HandleGetRuntimeInfoParameters {
|
|
|
26
31
|
|
|
27
32
|
export async function handleGetRuntimeInfo({
|
|
28
33
|
runtime,
|
|
34
|
+
request,
|
|
29
35
|
}: HandleGetRuntimeInfoParameters) {
|
|
30
36
|
try {
|
|
31
|
-
const agents = await runtime.agents;
|
|
37
|
+
const agents = await resolveAgents(runtime.agents, request);
|
|
38
|
+
|
|
39
|
+
const agentEntries = await Promise.all(
|
|
40
|
+
Object.entries(agents).map(async ([name, agent]) => {
|
|
41
|
+
let capabilities: AgentCapabilities | undefined;
|
|
42
|
+
try {
|
|
43
|
+
capabilities = agent.getCapabilities
|
|
44
|
+
? await agent.getCapabilities()
|
|
45
|
+
: undefined;
|
|
46
|
+
} catch (error) {
|
|
47
|
+
// Per-agent isolation: a single agent failing to report capabilities
|
|
48
|
+
// must not take down the entire /info endpoint.
|
|
49
|
+
console.warn(
|
|
50
|
+
`Failed to fetch capabilities for agent "${name}":`,
|
|
51
|
+
error instanceof Error ? error.message : error,
|
|
52
|
+
);
|
|
53
|
+
capabilities = undefined;
|
|
54
|
+
}
|
|
32
55
|
|
|
33
|
-
|
|
34
|
-
(acc, [name, agent]) => {
|
|
35
|
-
acc[name] = {
|
|
56
|
+
const description: AgentDescription = {
|
|
36
57
|
name,
|
|
37
58
|
description: agent.description,
|
|
38
59
|
className: agent.constructor.name,
|
|
60
|
+
...(capabilities ? { capabilities } : {}),
|
|
39
61
|
};
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
62
|
+
|
|
63
|
+
return [name, description] as const;
|
|
64
|
+
}),
|
|
43
65
|
);
|
|
44
66
|
|
|
67
|
+
const agentsDict: Record<string, AgentDescription> =
|
|
68
|
+
Object.fromEntries(agentEntries);
|
|
69
|
+
|
|
45
70
|
const runtimeInfo: RuntimeInfo = {
|
|
46
71
|
version: VERSION,
|
|
47
72
|
agents: agentsDict,
|
|
@@ -30,7 +30,7 @@ export async function handleRunAgent({
|
|
|
30
30
|
});
|
|
31
31
|
|
|
32
32
|
try {
|
|
33
|
-
const agent = await cloneAgentForRequest(runtime, agentId);
|
|
33
|
+
const agent = await cloneAgentForRequest(runtime, agentId, request);
|
|
34
34
|
if (agent instanceof Response) {
|
|
35
35
|
return agent;
|
|
36
36
|
}
|
|
@@ -55,6 +55,13 @@ export async function handleRunAgent({
|
|
|
55
55
|
agent.setState(input.state);
|
|
56
56
|
agent.threadId = input.threadId;
|
|
57
57
|
|
|
58
|
+
if (runtime.debug?.lifecycle && runtime.debugLogger) {
|
|
59
|
+
runtime.debugLogger.debug(
|
|
60
|
+
{ agentName: agentId, threadId: input.threadId },
|
|
61
|
+
"Agent run started",
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
58
65
|
if (isIntelligenceRuntime(runtime)) {
|
|
59
66
|
return handleIntelligenceRun({
|
|
60
67
|
runtime,
|
|
@@ -65,7 +72,14 @@ export async function handleRunAgent({
|
|
|
65
72
|
});
|
|
66
73
|
}
|
|
67
74
|
|
|
68
|
-
return handleSseRun({
|
|
75
|
+
return handleSseRun({
|
|
76
|
+
runtime,
|
|
77
|
+
request,
|
|
78
|
+
agent,
|
|
79
|
+
input,
|
|
80
|
+
debug: runtime.debug,
|
|
81
|
+
logger: runtime.debugLogger,
|
|
82
|
+
});
|
|
69
83
|
} catch (error) {
|
|
70
84
|
console.error("Error running agent:", error);
|
|
71
85
|
console.error(
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { CopilotRuntimeLike } from "../core/runtime";
|
|
2
|
+
import { resolveAgents } from "../core/runtime";
|
|
2
3
|
import { EventType } from "@ag-ui/client";
|
|
3
4
|
|
|
4
5
|
interface StopAgentParameters {
|
|
@@ -15,7 +16,7 @@ export async function handleStopAgent({
|
|
|
15
16
|
threadId,
|
|
16
17
|
}: StopAgentParameters) {
|
|
17
18
|
try {
|
|
18
|
-
const agents = await runtime.agents;
|
|
19
|
+
const agents = await resolveAgents(runtime.agents, request);
|
|
19
20
|
|
|
20
21
|
if (!agents[agentId]) {
|
|
21
22
|
return new Response(
|
|
@@ -99,7 +99,7 @@ async function runTitleGenerationAttempt(params: {
|
|
|
99
99
|
prompt: string;
|
|
100
100
|
}): Promise<string | null> {
|
|
101
101
|
const { runtime, request, agentId, threadId, prompt } = params;
|
|
102
|
-
const agent = await cloneAgentForRequest(runtime, agentId);
|
|
102
|
+
const agent = await cloneAgentForRequest(runtime, agentId, request);
|
|
103
103
|
if (isHandlerResponse(agent)) {
|
|
104
104
|
logger.warn(
|
|
105
105
|
{ agentId, threadId },
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
} from "@ag-ui/client";
|
|
6
6
|
import { A2UIMiddleware } from "@ag-ui/a2ui-middleware";
|
|
7
7
|
import { MCPAppsMiddleware } from "@ag-ui/mcp-apps-middleware";
|
|
8
|
-
import { CopilotRuntimeLike } from "../../core/runtime";
|
|
8
|
+
import { CopilotRuntimeLike, resolveAgents } from "../../core/runtime";
|
|
9
9
|
import { OpenGenerativeUIMiddleware } from "../../open-generative-ui-middleware";
|
|
10
10
|
import { extractForwardableHeaders } from "../header-utils";
|
|
11
11
|
import { logger } from "@copilotkit/shared";
|
|
@@ -28,8 +28,9 @@ export interface ConnectRequestBody extends RunAgentInput {
|
|
|
28
28
|
export async function cloneAgentForRequest(
|
|
29
29
|
runtime: CopilotRuntimeLike,
|
|
30
30
|
agentId: string,
|
|
31
|
+
request?: Request,
|
|
31
32
|
): Promise<AbstractAgent | Response> {
|
|
32
|
-
const agents = await runtime.agents;
|
|
33
|
+
const agents = await resolveAgents(runtime.agents, request);
|
|
33
34
|
|
|
34
35
|
if (!agents[agentId]) {
|
|
35
36
|
return new Response(
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { BaseEvent } from "@ag-ui/client";
|
|
2
2
|
import { EventEncoder } from "@ag-ui/encoder";
|
|
3
3
|
import { Observable, Subscription } from "rxjs";
|
|
4
|
+
import { ResolvedDebugConfig } from "@copilotkit/shared";
|
|
5
|
+
import {
|
|
6
|
+
createLogger,
|
|
7
|
+
type CopilotRuntimeLogger,
|
|
8
|
+
} from "../../../../lib/logger";
|
|
4
9
|
import { telemetry } from "../../telemetry";
|
|
5
10
|
|
|
6
11
|
interface CreateSseEventResponseParams {
|
|
@@ -8,17 +13,27 @@ interface CreateSseEventResponseParams {
|
|
|
8
13
|
observableFactory: () =>
|
|
9
14
|
| Promise<Observable<BaseEvent>>
|
|
10
15
|
| Observable<BaseEvent>;
|
|
16
|
+
debug?: ResolvedDebugConfig;
|
|
17
|
+
/** Pre-created logger instance to avoid creating a new pino logger per request. */
|
|
18
|
+
logger?: CopilotRuntimeLogger;
|
|
11
19
|
}
|
|
12
20
|
|
|
13
21
|
export function createSseEventResponse({
|
|
14
22
|
request,
|
|
15
23
|
observableFactory,
|
|
24
|
+
debug,
|
|
25
|
+
logger,
|
|
16
26
|
}: CreateSseEventResponseParams): Response {
|
|
17
27
|
const stream = new TransformStream();
|
|
18
28
|
const writer = stream.writable.getWriter();
|
|
19
29
|
const encoder = new EventEncoder();
|
|
20
30
|
let streamClosed = false;
|
|
21
31
|
|
|
32
|
+
const debugLogger = debug?.enabled
|
|
33
|
+
? (logger ??
|
|
34
|
+
createLogger({ level: "debug", component: "copilotkit-debug" }))
|
|
35
|
+
: undefined;
|
|
36
|
+
|
|
22
37
|
const closeStream = async () => {
|
|
23
38
|
if (!streamClosed) {
|
|
24
39
|
try {
|
|
@@ -50,10 +65,29 @@ export function createSseEventResponse({
|
|
|
50
65
|
|
|
51
66
|
telemetry.capture("oss.runtime.agent_execution_stream_started", {});
|
|
52
67
|
|
|
68
|
+
if (debug?.lifecycle) {
|
|
69
|
+
debugLogger!.debug("SSE stream opened");
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
let eventCount = 0;
|
|
73
|
+
let loggedEventCount = 0;
|
|
74
|
+
|
|
53
75
|
subscription = observable.subscribe({
|
|
54
76
|
next: async (event) => {
|
|
55
77
|
if (!request.signal.aborted && !streamClosed) {
|
|
56
78
|
try {
|
|
79
|
+
eventCount++;
|
|
80
|
+
if (debug?.events) {
|
|
81
|
+
loggedEventCount++;
|
|
82
|
+
if (debug.verbose) {
|
|
83
|
+
debugLogger!.debug({ event }, "Event emitted");
|
|
84
|
+
} else {
|
|
85
|
+
debugLogger!.debug(
|
|
86
|
+
{ type: event.type, ...summarizeEvent(event) },
|
|
87
|
+
"Event emitted",
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
57
91
|
await writer.write(encoder.encode(event));
|
|
58
92
|
} catch (error) {
|
|
59
93
|
if (error instanceof Error && error.name === "AbortError") {
|
|
@@ -66,11 +100,23 @@ export function createSseEventResponse({
|
|
|
66
100
|
telemetry.capture("oss.runtime.agent_execution_stream_errored", {
|
|
67
101
|
error: error instanceof Error ? error.message : String(error),
|
|
68
102
|
});
|
|
103
|
+
if (debug?.lifecycle) {
|
|
104
|
+
debugLogger!.debug(
|
|
105
|
+
{ error: error instanceof Error ? error.message : String(error) },
|
|
106
|
+
"SSE stream errored",
|
|
107
|
+
);
|
|
108
|
+
}
|
|
69
109
|
logError(error);
|
|
70
110
|
await closeStream();
|
|
71
111
|
},
|
|
72
112
|
complete: async () => {
|
|
73
113
|
telemetry.capture("oss.runtime.agent_execution_stream_ended", {});
|
|
114
|
+
if (debug?.lifecycle) {
|
|
115
|
+
debugLogger!.debug(
|
|
116
|
+
{ eventCount, loggedEventCount },
|
|
117
|
+
"SSE stream completed",
|
|
118
|
+
);
|
|
119
|
+
}
|
|
74
120
|
await closeStream();
|
|
75
121
|
},
|
|
76
122
|
});
|
|
@@ -98,3 +144,26 @@ export function createSseEventResponse({
|
|
|
98
144
|
},
|
|
99
145
|
});
|
|
100
146
|
}
|
|
147
|
+
|
|
148
|
+
function summarizeEvent(event: BaseEvent): Record<string, unknown> {
|
|
149
|
+
const e = event as any;
|
|
150
|
+
const summary: Record<string, unknown> = {};
|
|
151
|
+
|
|
152
|
+
if (e.messageId) summary.messageId = e.messageId;
|
|
153
|
+
if (e.toolCallId) summary.toolCallId = e.toolCallId;
|
|
154
|
+
if (e.toolCallName) summary.toolCallName = e.toolCallName;
|
|
155
|
+
if (e.role) summary.role = e.role;
|
|
156
|
+
if (e.delta != null && typeof e.delta === "string")
|
|
157
|
+
summary.deltaLength = e.delta.length;
|
|
158
|
+
if (e.snapshot && typeof e.snapshot === "object")
|
|
159
|
+
summary.snapshotKeys = Object.keys(e.snapshot);
|
|
160
|
+
if (e.delta && Array.isArray(e.delta))
|
|
161
|
+
summary.operationCount = e.delta.length;
|
|
162
|
+
if (e.threadId) summary.threadId = e.threadId;
|
|
163
|
+
if (e.runId) summary.runId = e.runId;
|
|
164
|
+
if (e.message) summary.message = e.message;
|
|
165
|
+
if (e.code) summary.code = e.code;
|
|
166
|
+
if (e.stepName) summary.stepName = e.stepName;
|
|
167
|
+
|
|
168
|
+
return summary;
|
|
169
|
+
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { AbstractAgent, RunAgentInput } from "@ag-ui/client";
|
|
2
|
+
import { ResolvedDebugConfig } from "@copilotkit/shared";
|
|
3
|
+
import { type CopilotRuntimeLogger } from "../../../../lib/logger";
|
|
2
4
|
import { CopilotRuntimeLike } from "../../core/runtime";
|
|
3
5
|
import { createSseEventResponse } from "../shared/sse-response";
|
|
4
6
|
|
|
@@ -7,6 +9,9 @@ interface HandleSseRunParams {
|
|
|
7
9
|
request: Request;
|
|
8
10
|
agent: AbstractAgent;
|
|
9
11
|
input: RunAgentInput;
|
|
12
|
+
debug?: ResolvedDebugConfig;
|
|
13
|
+
/** Pre-created logger instance to avoid creating a new pino logger per request. */
|
|
14
|
+
logger?: CopilotRuntimeLogger;
|
|
10
15
|
}
|
|
11
16
|
|
|
12
17
|
export function handleSseRun({
|
|
@@ -14,9 +19,13 @@ export function handleSseRun({
|
|
|
14
19
|
request,
|
|
15
20
|
agent,
|
|
16
21
|
input,
|
|
22
|
+
debug,
|
|
23
|
+
logger,
|
|
17
24
|
}: HandleSseRunParams): Response {
|
|
18
25
|
return createSseEventResponse({
|
|
19
26
|
request,
|
|
27
|
+
debug,
|
|
28
|
+
logger,
|
|
20
29
|
observableFactory: () =>
|
|
21
30
|
runtime.runner.run({
|
|
22
31
|
threadId: input.threadId,
|