@copilotkit/runtime 1.9.2-next.8 → 1.9.2
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/CHANGELOG.md +177 -0
- package/dist/{chunk-4TLMVLU4.mjs → chunk-56ZNYBXV.mjs} +2 -2
- package/dist/chunk-AMUJQ6IR.mjs +50 -0
- package/dist/chunk-AMUJQ6IR.mjs.map +1 -0
- package/dist/{chunk-5SG4WWXH.mjs → chunk-GB4M7WUE.mjs} +2 -2
- package/dist/{chunk-JWPSIGSA.mjs → chunk-HJYWUUFY.mjs} +2 -2
- package/dist/{chunk-KYCDL2KX.mjs → chunk-M35WOOEP.mjs} +2 -2
- package/dist/{chunk-IIXJVVTV.mjs → chunk-QLLV2QVK.mjs} +132 -78
- package/dist/chunk-QLLV2QVK.mjs.map +1 -0
- package/dist/{chunk-WIXS6EG7.mjs → chunk-TE5QWP4H.mjs} +2401 -2055
- package/dist/chunk-TE5QWP4H.mjs.map +1 -0
- package/dist/{chunk-5BIEM2UU.mjs → chunk-XWBDEXDA.mjs} +4 -3
- package/dist/{chunk-5BIEM2UU.mjs.map → chunk-XWBDEXDA.mjs.map} +1 -1
- package/dist/{groq-adapter-25a2bd35.d.ts → groq-adapter-742818f2.d.ts} +5 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.js +3747 -3303
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +12 -8
- package/dist/index.mjs.map +1 -1
- package/dist/{langserve-4a5c9217.d.ts → langserve-3e8d0e06.d.ts} +13 -7
- package/dist/lib/index.d.ts +155 -5
- package/dist/lib/index.js +2808 -2407
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/index.mjs +9 -8
- package/dist/lib/integrations/index.d.ts +3 -3
- package/dist/lib/integrations/index.js +151 -96
- package/dist/lib/integrations/index.js.map +1 -1
- package/dist/lib/integrations/index.mjs +7 -6
- package/dist/lib/integrations/nest/index.d.ts +2 -2
- package/dist/lib/integrations/nest/index.js +151 -96
- package/dist/lib/integrations/nest/index.js.map +1 -1
- package/dist/lib/integrations/nest/index.mjs +5 -4
- package/dist/lib/integrations/node-express/index.d.ts +2 -2
- package/dist/lib/integrations/node-express/index.js +151 -96
- package/dist/lib/integrations/node-express/index.js.map +1 -1
- package/dist/lib/integrations/node-express/index.mjs +5 -4
- package/dist/lib/integrations/node-http/index.d.ts +2 -2
- package/dist/lib/integrations/node-http/index.js +151 -96
- package/dist/lib/integrations/node-http/index.js.map +1 -1
- package/dist/lib/integrations/node-http/index.mjs +4 -3
- package/dist/service-adapters/index.d.ts +6 -4
- package/dist/service-adapters/index.js +202 -107
- package/dist/service-adapters/index.js.map +1 -1
- package/dist/service-adapters/index.mjs +6 -2
- package/dist/service-adapters/shared/index.d.ts +9 -0
- package/dist/service-adapters/shared/index.js +72 -0
- package/dist/service-adapters/shared/index.js.map +1 -0
- package/dist/service-adapters/shared/index.mjs +8 -0
- package/dist/service-adapters/shared/index.mjs.map +1 -0
- package/dist/{shared-941d59dc.d.ts → shared-96b46379.d.ts} +23 -21
- package/dist/utils/index.d.ts +17 -1
- package/dist/utils/index.js +3 -2
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/index.mjs +1 -1
- package/package.json +11 -11
- package/src/agents/langgraph/event-source.ts +36 -38
- package/src/agents/langgraph/events.ts +19 -1
- package/src/graphql/resolvers/copilot.resolver.ts +85 -42
- package/src/lib/error-messages.ts +200 -0
- package/src/lib/integrations/shared.ts +43 -0
- package/src/lib/runtime/__tests__/{copilot-runtime-trace.test.ts → copilot-runtime-error.test.ts} +27 -27
- package/src/lib/runtime/__tests__/mcp-tools-utils.test.ts +464 -0
- package/src/lib/runtime/agui-action.ts +9 -3
- package/src/lib/runtime/copilot-runtime.ts +156 -160
- package/src/lib/runtime/mcp-tools-utils.ts +84 -18
- package/src/lib/runtime/remote-action-constructors.ts +28 -3
- package/src/lib/runtime/remote-actions.ts +6 -0
- package/src/lib/runtime/remote-lg-action.ts +85 -3
- package/src/lib/streaming.ts +125 -36
- package/src/service-adapters/anthropic/anthropic-adapter.ts +67 -8
- package/src/service-adapters/anthropic/utils.ts +3 -8
- package/src/service-adapters/events.ts +75 -80
- package/src/service-adapters/google/google-genai-adapter.ts +5 -0
- package/src/service-adapters/groq/groq-adapter.ts +66 -56
- package/src/service-adapters/index.ts +1 -0
- package/src/service-adapters/openai/openai-adapter.ts +4 -3
- package/src/service-adapters/shared/error-utils.ts +61 -0
- package/src/service-adapters/shared/index.ts +1 -0
- package/src/utils/failed-response-status-reasons.ts +23 -1
- package/tests/service-adapters/anthropic/anthropic-adapter.test.ts +172 -387
- package/dist/chunk-IIXJVVTV.mjs.map +0 -1
- package/dist/chunk-WIXS6EG7.mjs.map +0 -1
- /package/dist/{chunk-4TLMVLU4.mjs.map → chunk-56ZNYBXV.mjs.map} +0 -0
- /package/dist/{chunk-5SG4WWXH.mjs.map → chunk-GB4M7WUE.mjs.map} +0 -0
- /package/dist/{chunk-JWPSIGSA.mjs.map → chunk-HJYWUUFY.mjs.map} +0 -0
- /package/dist/{chunk-KYCDL2KX.mjs.map → chunk-M35WOOEP.mjs.map} +0 -0
|
@@ -20,14 +20,14 @@ import {
|
|
|
20
20
|
CopilotKitApiDiscoveryError,
|
|
21
21
|
randomId,
|
|
22
22
|
CopilotKitError,
|
|
23
|
-
CopilotKitRemoteEndpointDiscoveryError,
|
|
24
23
|
CopilotKitAgentDiscoveryError,
|
|
25
24
|
CopilotKitMisuseError,
|
|
26
25
|
CopilotKitErrorCode,
|
|
27
26
|
CopilotKitLowLevelError,
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
CopilotErrorHandler,
|
|
28
|
+
CopilotErrorEvent,
|
|
30
29
|
CopilotRequestContext,
|
|
30
|
+
ensureStructuredError,
|
|
31
31
|
} from "@copilotkit/shared";
|
|
32
32
|
import {
|
|
33
33
|
CopilotServiceAdapter,
|
|
@@ -89,6 +89,8 @@ import { LangGraphAgent } from "./langgraph/langgraph-agent";
|
|
|
89
89
|
type CreateMCPClientFunction = (config: MCPEndpointConfig) => Promise<MCPClient>;
|
|
90
90
|
// --- MCP Imports ---
|
|
91
91
|
|
|
92
|
+
import { generateHelpfulErrorMessage } from "../streaming";
|
|
93
|
+
|
|
92
94
|
export interface CopilotRuntimeRequest {
|
|
93
95
|
serviceAdapter: CopilotServiceAdapter;
|
|
94
96
|
messages: MessageInput[];
|
|
@@ -280,23 +282,23 @@ export interface CopilotRuntimeConstructorParams<T extends Parameter[] | [] = []
|
|
|
280
282
|
createMCPClient?: CreateMCPClientFunction;
|
|
281
283
|
|
|
282
284
|
/**
|
|
283
|
-
* Optional
|
|
285
|
+
* Optional error handler for comprehensive debugging and observability.
|
|
284
286
|
*
|
|
285
|
-
* **Requires publicApiKey**:
|
|
287
|
+
* **Requires publicApiKey**: Error handling only works when requests include a valid publicApiKey.
|
|
286
288
|
* This is a premium CopilotKit Cloud feature.
|
|
287
289
|
*
|
|
288
|
-
* @param
|
|
290
|
+
* @param errorEvent - Structured error event with rich debugging context
|
|
289
291
|
*
|
|
290
292
|
* @example
|
|
291
293
|
* ```typescript
|
|
292
294
|
* const runtime = new CopilotRuntime({
|
|
293
|
-
*
|
|
294
|
-
* debugDashboard.capture(
|
|
295
|
+
* onError: (errorEvent) => {
|
|
296
|
+
* debugDashboard.capture(errorEvent);
|
|
295
297
|
* }
|
|
296
298
|
* });
|
|
297
299
|
* ```
|
|
298
300
|
*/
|
|
299
|
-
|
|
301
|
+
onError?: CopilotErrorHandler;
|
|
300
302
|
}
|
|
301
303
|
|
|
302
304
|
export class CopilotRuntime<const T extends Parameter[] | [] = []> {
|
|
@@ -309,8 +311,8 @@ export class CopilotRuntime<const T extends Parameter[] | [] = []> {
|
|
|
309
311
|
private delegateAgentProcessingToServiceAdapter: boolean;
|
|
310
312
|
private observability?: CopilotObservabilityConfig;
|
|
311
313
|
private availableAgents: Pick<AgentWithEndpoint, "name" | "id">[];
|
|
312
|
-
private
|
|
313
|
-
private
|
|
314
|
+
private onError?: CopilotErrorHandler;
|
|
315
|
+
private hasWarnedAboutError = false;
|
|
314
316
|
|
|
315
317
|
// +++ MCP Properties +++
|
|
316
318
|
private readonly mcpServersConfig?: MCPEndpointConfig[];
|
|
@@ -359,7 +361,7 @@ export class CopilotRuntime<const T extends Parameter[] | [] = []> {
|
|
|
359
361
|
params?.delegateAgentProcessingToServiceAdapter || false;
|
|
360
362
|
this.observability = params?.observability_c;
|
|
361
363
|
this.agents = params?.agents ?? {};
|
|
362
|
-
this.
|
|
364
|
+
this.onError = params?.onError;
|
|
363
365
|
// +++ MCP Initialization +++
|
|
364
366
|
this.mcpServersConfig = params?.mcpServers;
|
|
365
367
|
this.createMCPClientImpl = params?.createMCPClient;
|
|
@@ -437,9 +439,7 @@ export class CopilotRuntime<const T extends Parameter[] | [] = []> {
|
|
|
437
439
|
}
|
|
438
440
|
|
|
439
441
|
const instructions =
|
|
440
|
-
|
|
441
|
-
mcpToolInstructions +
|
|
442
|
-
"\nUse them when appropriate to fulfill the user's request.";
|
|
442
|
+
mcpToolInstructions + "\nUse them when appropriate to fulfill the user's request.";
|
|
443
443
|
|
|
444
444
|
const systemMessageIndex = messages.findIndex((msg) => msg.textMessage?.role === "system");
|
|
445
445
|
|
|
@@ -486,16 +486,11 @@ export class CopilotRuntime<const T extends Parameter[] | [] = []> {
|
|
|
486
486
|
publicApiKey,
|
|
487
487
|
} = request;
|
|
488
488
|
|
|
489
|
-
const eventSource = new RuntimeEventSource(
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
// Trace request start
|
|
496
|
-
await this.trace(
|
|
497
|
-
"request",
|
|
498
|
-
{
|
|
489
|
+
const eventSource = new RuntimeEventSource({
|
|
490
|
+
errorHandler: async (error, context) => {
|
|
491
|
+
await this.error("error", context, error, publicApiKey);
|
|
492
|
+
},
|
|
493
|
+
errorContext: {
|
|
499
494
|
threadId,
|
|
500
495
|
runId,
|
|
501
496
|
source: "runtime",
|
|
@@ -503,20 +498,18 @@ export class CopilotRuntime<const T extends Parameter[] | [] = []> {
|
|
|
503
498
|
operation: "processRuntimeRequest",
|
|
504
499
|
method: "POST",
|
|
505
500
|
url: url,
|
|
506
|
-
startTime:
|
|
501
|
+
startTime: Date.now(),
|
|
507
502
|
},
|
|
508
503
|
agent: agentSession ? { name: agentSession.agentName } : undefined,
|
|
509
|
-
messages: {
|
|
510
|
-
input: rawMessages,
|
|
511
|
-
messageCount: rawMessages.length,
|
|
512
|
-
},
|
|
513
504
|
technical: {
|
|
514
505
|
environment: process.env.NODE_ENV,
|
|
515
506
|
},
|
|
516
507
|
},
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
);
|
|
508
|
+
});
|
|
509
|
+
// Track request start time for logging
|
|
510
|
+
const requestStartTime = Date.now();
|
|
511
|
+
// For storing streamed chunks if progressive logging is enabled
|
|
512
|
+
const streamedChunks: any[] = [];
|
|
520
513
|
|
|
521
514
|
try {
|
|
522
515
|
if (
|
|
@@ -746,13 +739,14 @@ please use an LLM adapter instead.`,
|
|
|
746
739
|
if (error instanceof CopilotKitError) {
|
|
747
740
|
structuredError = error;
|
|
748
741
|
} else {
|
|
749
|
-
// Convert non-CopilotKitErrors to structured errors
|
|
750
|
-
|
|
751
|
-
|
|
742
|
+
// Convert non-CopilotKitErrors to structured errors, but preserve already structured ones
|
|
743
|
+
structuredError = ensureStructuredError(error, (err) =>
|
|
744
|
+
this.convertStreamingErrorToStructured(err),
|
|
745
|
+
);
|
|
752
746
|
}
|
|
753
747
|
|
|
754
|
-
//
|
|
755
|
-
await this.
|
|
748
|
+
// Track the error
|
|
749
|
+
await this.error(
|
|
756
750
|
"error",
|
|
757
751
|
{
|
|
758
752
|
threadId,
|
|
@@ -783,10 +777,8 @@ please use an LLM adapter instead.`,
|
|
|
783
777
|
}
|
|
784
778
|
|
|
785
779
|
async getAllAgents(graphqlContext: GraphQLContext): Promise<(AgentWithEndpoint | Agent)[]> {
|
|
786
|
-
const
|
|
787
|
-
|
|
788
|
-
this.discoverAgentsFromAgui(),
|
|
789
|
-
]);
|
|
780
|
+
const agentsWithEndpoints = await this.discoverAgentsFromEndpoints(graphqlContext);
|
|
781
|
+
const aguiAgents = this.discoverAgentsFromAgui();
|
|
790
782
|
|
|
791
783
|
this.availableAgents = [...agentsWithEndpoints, ...aguiAgents].map((a) => ({
|
|
792
784
|
name: a.name,
|
|
@@ -881,39 +873,12 @@ please use an LLM adapter instead.`,
|
|
|
881
873
|
return agents;
|
|
882
874
|
}
|
|
883
875
|
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
let data: Array<{ assistant_id: string; graph_id: string }> | { detail: string } = [];
|
|
891
|
-
try {
|
|
892
|
-
data = await client.assistants.search();
|
|
893
|
-
|
|
894
|
-
if (data && "detail" in data && (data.detail as string).toLowerCase() === "not found") {
|
|
895
|
-
throw new CopilotKitAgentDiscoveryError({ availableAgents: this.availableAgents });
|
|
896
|
-
}
|
|
897
|
-
} catch (e) {
|
|
898
|
-
throw new CopilotKitMisuseError({
|
|
899
|
-
message: `
|
|
900
|
-
Failed to find or contact agent ${agent.graphId}.
|
|
901
|
-
Make sure the LangGraph API is running and the agent is defined in langgraph.json
|
|
902
|
-
|
|
903
|
-
See more: https://docs.copilotkit.ai/troubleshooting/common-issues`,
|
|
904
|
-
});
|
|
905
|
-
}
|
|
906
|
-
const endpointAgents = data.map((entry) => ({
|
|
907
|
-
name: entry.graph_id,
|
|
908
|
-
id: entry.assistant_id,
|
|
909
|
-
description: "",
|
|
910
|
-
}));
|
|
911
|
-
return [...agents, ...endpointAgents];
|
|
912
|
-
},
|
|
913
|
-
Promise.resolve([]),
|
|
914
|
-
);
|
|
915
|
-
|
|
916
|
-
return agents;
|
|
876
|
+
discoverAgentsFromAgui(): Agent[] {
|
|
877
|
+
return Object.entries(this.agents ?? []).map(([key, agent]: [string, AbstractAgent]) => ({
|
|
878
|
+
name: (agent as any).agentName ?? key,
|
|
879
|
+
id: agent.agentId ?? key,
|
|
880
|
+
description: agent.description ?? "",
|
|
881
|
+
}));
|
|
917
882
|
}
|
|
918
883
|
|
|
919
884
|
async loadAgentState(
|
|
@@ -948,10 +913,24 @@ please use an LLM adapter instead.`,
|
|
|
948
913
|
if (response.status === 404) {
|
|
949
914
|
throw new CopilotKitApiDiscoveryError({ url: fetchUrl });
|
|
950
915
|
}
|
|
916
|
+
|
|
917
|
+
// Extract semantic error information from response body
|
|
918
|
+
let errorMessage = `HTTP ${response.status} error`;
|
|
919
|
+
try {
|
|
920
|
+
const errorBody = await response.text();
|
|
921
|
+
const parsedError = JSON.parse(errorBody);
|
|
922
|
+
if (parsedError.error && typeof parsedError.error === "string") {
|
|
923
|
+
errorMessage = parsedError.error;
|
|
924
|
+
}
|
|
925
|
+
} catch {
|
|
926
|
+
// If parsing fails, fall back to generic message
|
|
927
|
+
}
|
|
928
|
+
|
|
951
929
|
throw new ResolvedCopilotKitError({
|
|
952
930
|
status: response.status,
|
|
953
931
|
url: fetchUrl,
|
|
954
932
|
isRemoteEndpoint: true,
|
|
933
|
+
message: errorMessage,
|
|
955
934
|
});
|
|
956
935
|
}
|
|
957
936
|
|
|
@@ -974,25 +953,44 @@ please use an LLM adapter instead.`,
|
|
|
974
953
|
? { authorization: `Bearer ${graphqlContext.properties.authorization}` }
|
|
975
954
|
: null;
|
|
976
955
|
|
|
977
|
-
let client: LangGraphClient;
|
|
978
|
-
if ("endpoint" in agent && agent.endpoint.type === EndpointType.LangGraphPlatform) {
|
|
979
|
-
client = new LangGraphClient({
|
|
980
|
-
apiUrl: agent.endpoint.deploymentUrl,
|
|
981
|
-
apiKey: agent.endpoint.langsmithApiKey,
|
|
982
|
-
defaultHeaders: { ...propertyHeaders },
|
|
983
|
-
});
|
|
984
|
-
} else {
|
|
985
|
-
const aguiAgent = graphqlContext._copilotkit.runtime.agents[agent.name] as LangGraphAgent;
|
|
986
|
-
if (!aguiAgent) {
|
|
987
|
-
throw new Error(`Agent: ${agent.name} could not be resolved`);
|
|
988
|
-
}
|
|
989
|
-
// @ts-expect-error -- both clients are the same
|
|
990
|
-
client = aguiAgent.client;
|
|
991
|
-
}
|
|
992
956
|
let state: any = {};
|
|
993
957
|
try {
|
|
994
|
-
|
|
995
|
-
|
|
958
|
+
let client: LangGraphClient | null;
|
|
959
|
+
if ("endpoint" in agent && agent.endpoint.type === EndpointType.LangGraphPlatform) {
|
|
960
|
+
client = new LangGraphClient({
|
|
961
|
+
apiUrl: agent.endpoint.deploymentUrl,
|
|
962
|
+
apiKey: agent.endpoint.langsmithApiKey,
|
|
963
|
+
defaultHeaders: { ...propertyHeaders },
|
|
964
|
+
});
|
|
965
|
+
} else {
|
|
966
|
+
const aguiAgent = graphqlContext._copilotkit.runtime.agents[agent.name] as LangGraphAgent;
|
|
967
|
+
if (!aguiAgent) {
|
|
968
|
+
throw new Error(`Agent: ${agent.name} could not be resolved`);
|
|
969
|
+
}
|
|
970
|
+
// @ts-expect-error -- both clients are the same
|
|
971
|
+
client = aguiAgent.client ?? null;
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
state = client ? ((await client.threads.getState(threadId)).values as any) : {};
|
|
975
|
+
} catch (error) {
|
|
976
|
+
// All errors from agent state loading are user configuration issues
|
|
977
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
978
|
+
const errorStatus = error?.response?.status || error?.status;
|
|
979
|
+
|
|
980
|
+
if (errorStatus === 404) {
|
|
981
|
+
state = {};
|
|
982
|
+
} else {
|
|
983
|
+
// Log user configuration errors at debug level to reduce noise
|
|
984
|
+
console.debug(`Agent '${agentName}' configuration issue: ${errorMessage}`);
|
|
985
|
+
|
|
986
|
+
// Throw a configuration error - all agent state loading failures are user setup issues
|
|
987
|
+
throw new ResolvedCopilotKitError({
|
|
988
|
+
status: 400,
|
|
989
|
+
message: `Agent '${agentName}' failed to execute: ${errorMessage}`,
|
|
990
|
+
code: CopilotKitErrorCode.CONFIGURATION_ERROR,
|
|
991
|
+
});
|
|
992
|
+
}
|
|
993
|
+
}
|
|
996
994
|
|
|
997
995
|
if (Object.keys(state).length === 0) {
|
|
998
996
|
return {
|
|
@@ -1038,8 +1036,8 @@ please use an LLM adapter instead.`,
|
|
|
1038
1036
|
// for backwards compatibility, deal with the case when no threadId is provided
|
|
1039
1037
|
const threadId = threadIdFromRequest ?? agentSession.threadId;
|
|
1040
1038
|
|
|
1041
|
-
//
|
|
1042
|
-
await this.
|
|
1039
|
+
// Track agent request start
|
|
1040
|
+
await this.error(
|
|
1043
1041
|
"agent_state",
|
|
1044
1042
|
{
|
|
1045
1043
|
threadId,
|
|
@@ -1129,7 +1127,27 @@ please use an LLM adapter instead.`,
|
|
|
1129
1127
|
});
|
|
1130
1128
|
|
|
1131
1129
|
try {
|
|
1132
|
-
const eventSource = new RuntimeEventSource(
|
|
1130
|
+
const eventSource = new RuntimeEventSource({
|
|
1131
|
+
errorHandler: async (error, context) => {
|
|
1132
|
+
await this.error("error", context, error, publicApiKey);
|
|
1133
|
+
},
|
|
1134
|
+
errorContext: {
|
|
1135
|
+
threadId,
|
|
1136
|
+
source: "agent",
|
|
1137
|
+
request: {
|
|
1138
|
+
operation: "processAgentRequest",
|
|
1139
|
+
method: "POST",
|
|
1140
|
+
startTime: requestStartTime,
|
|
1141
|
+
},
|
|
1142
|
+
agent: {
|
|
1143
|
+
name: agentName,
|
|
1144
|
+
nodeName: nodeName,
|
|
1145
|
+
},
|
|
1146
|
+
technical: {
|
|
1147
|
+
environment: process.env.NODE_ENV,
|
|
1148
|
+
},
|
|
1149
|
+
},
|
|
1150
|
+
});
|
|
1133
1151
|
const stream = await currentAgent.remoteAgentHandler({
|
|
1134
1152
|
name: agentName,
|
|
1135
1153
|
threadId,
|
|
@@ -1193,8 +1211,6 @@ please use an LLM adapter instead.`,
|
|
|
1193
1211
|
from(stream).subscribe({
|
|
1194
1212
|
next: (event) => eventStream$.next(event),
|
|
1195
1213
|
error: async (err) => {
|
|
1196
|
-
console.error("Error in stream", err);
|
|
1197
|
-
|
|
1198
1214
|
// Log error with observability if enabled
|
|
1199
1215
|
if (this.observability?.enabled && publicApiKey) {
|
|
1200
1216
|
try {
|
|
@@ -1216,11 +1232,13 @@ please use an LLM adapter instead.`,
|
|
|
1216
1232
|
}
|
|
1217
1233
|
}
|
|
1218
1234
|
|
|
1219
|
-
//
|
|
1220
|
-
const structuredError =
|
|
1235
|
+
// Preserve structured CopilotKit errors, only convert unstructured errors
|
|
1236
|
+
const structuredError = ensureStructuredError(err, (error) =>
|
|
1237
|
+
this.convertStreamingErrorToStructured(error),
|
|
1238
|
+
);
|
|
1221
1239
|
|
|
1222
|
-
//
|
|
1223
|
-
await this.
|
|
1240
|
+
// Track streaming errors
|
|
1241
|
+
await this.error(
|
|
1224
1242
|
"error",
|
|
1225
1243
|
{
|
|
1226
1244
|
threadId,
|
|
@@ -1325,15 +1343,12 @@ please use an LLM adapter instead.`,
|
|
|
1325
1343
|
}
|
|
1326
1344
|
|
|
1327
1345
|
// Ensure error is structured
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
} else {
|
|
1332
|
-
structuredError = this.convertStreamingErrorToStructured(error);
|
|
1333
|
-
}
|
|
1346
|
+
const structuredError = ensureStructuredError(error, (err) =>
|
|
1347
|
+
this.convertStreamingErrorToStructured(err),
|
|
1348
|
+
);
|
|
1334
1349
|
|
|
1335
|
-
//
|
|
1336
|
-
await this.
|
|
1350
|
+
// Track the agent error
|
|
1351
|
+
await this.error(
|
|
1337
1352
|
"error",
|
|
1338
1353
|
{
|
|
1339
1354
|
threadId,
|
|
@@ -1392,6 +1407,7 @@ please use an LLM adapter instead.`,
|
|
|
1392
1407
|
frontendUrl: url,
|
|
1393
1408
|
agents: this.agents,
|
|
1394
1409
|
metaEvents: request.metaEvents,
|
|
1410
|
+
nodeName: request.agentSession?.nodeName,
|
|
1395
1411
|
});
|
|
1396
1412
|
|
|
1397
1413
|
const configuredActions =
|
|
@@ -1477,93 +1493,73 @@ please use an LLM adapter instead.`,
|
|
|
1477
1493
|
}
|
|
1478
1494
|
|
|
1479
1495
|
private convertStreamingErrorToStructured(error: any): CopilotKitError {
|
|
1480
|
-
//
|
|
1481
|
-
|
|
1482
|
-
error?.message?.includes("terminated") ||
|
|
1483
|
-
error?.cause?.code === "UND_ERR_SOCKET" ||
|
|
1484
|
-
error?.message?.includes("other side closed") ||
|
|
1485
|
-
error?.code === "UND_ERR_SOCKET"
|
|
1486
|
-
) {
|
|
1487
|
-
return new CopilotKitError({
|
|
1488
|
-
message:
|
|
1489
|
-
"Connection to agent was unexpectedly terminated. This may be due to the agent service being restarted or network issues. Please try again.",
|
|
1490
|
-
code: CopilotKitErrorCode.NETWORK_ERROR,
|
|
1491
|
-
});
|
|
1492
|
-
}
|
|
1496
|
+
// Determine a more helpful error message based on context
|
|
1497
|
+
let helpfulMessage = generateHelpfulErrorMessage(error, "agent streaming connection");
|
|
1493
1498
|
|
|
1494
|
-
//
|
|
1499
|
+
// For network-related errors, use CopilotKitLowLevelError to preserve the original error
|
|
1495
1500
|
if (
|
|
1496
1501
|
error?.message?.includes("fetch failed") ||
|
|
1497
1502
|
error?.message?.includes("ECONNREFUSED") ||
|
|
1498
1503
|
error?.message?.includes("ENOTFOUND") ||
|
|
1499
|
-
error?.message?.includes("ETIMEDOUT")
|
|
1504
|
+
error?.message?.includes("ETIMEDOUT") ||
|
|
1505
|
+
error?.message?.includes("terminated") ||
|
|
1506
|
+
error?.cause?.code === "UND_ERR_SOCKET" ||
|
|
1507
|
+
error?.message?.includes("other side closed") ||
|
|
1508
|
+
error?.code === "UND_ERR_SOCKET"
|
|
1500
1509
|
) {
|
|
1501
1510
|
return new CopilotKitLowLevelError({
|
|
1502
1511
|
error: error instanceof Error ? error : new Error(String(error)),
|
|
1503
1512
|
url: "agent streaming connection",
|
|
1504
|
-
message:
|
|
1505
|
-
"Network error occurred during agent streaming. Please check your connection and try again.",
|
|
1506
|
-
});
|
|
1507
|
-
}
|
|
1508
|
-
|
|
1509
|
-
// Handle abort/cancellation errors (these are usually normal)
|
|
1510
|
-
if (
|
|
1511
|
-
error?.message?.includes("aborted") ||
|
|
1512
|
-
error?.message?.includes("canceled") ||
|
|
1513
|
-
error?.message?.includes("signal is aborted")
|
|
1514
|
-
) {
|
|
1515
|
-
return new CopilotKitError({
|
|
1516
|
-
message: "Agent request was cancelled",
|
|
1517
|
-
code: CopilotKitErrorCode.UNKNOWN,
|
|
1513
|
+
message: helpfulMessage,
|
|
1518
1514
|
});
|
|
1519
1515
|
}
|
|
1520
1516
|
|
|
1521
|
-
//
|
|
1517
|
+
// For all other errors, preserve the raw error in a basic CopilotKitError
|
|
1522
1518
|
return new CopilotKitError({
|
|
1523
|
-
message:
|
|
1519
|
+
message: helpfulMessage,
|
|
1524
1520
|
code: CopilotKitErrorCode.UNKNOWN,
|
|
1525
1521
|
});
|
|
1526
1522
|
}
|
|
1527
1523
|
|
|
1528
|
-
private async
|
|
1529
|
-
type:
|
|
1524
|
+
private async error(
|
|
1525
|
+
type: CopilotErrorEvent["type"],
|
|
1530
1526
|
context: CopilotRequestContext,
|
|
1531
1527
|
error?: any,
|
|
1532
1528
|
publicApiKey?: string,
|
|
1533
1529
|
): Promise<void> {
|
|
1534
|
-
if (!this.
|
|
1530
|
+
if (!this.onError) return;
|
|
1535
1531
|
|
|
1532
|
+
// Just check if publicApiKey is defined (regardless of validity)
|
|
1536
1533
|
if (!publicApiKey) {
|
|
1537
|
-
if (!this.
|
|
1534
|
+
if (!this.hasWarnedAboutError) {
|
|
1538
1535
|
console.warn(
|
|
1539
|
-
"CopilotKit:
|
|
1540
|
-
"This is a CopilotKit Cloud feature. See: https://docs.copilotkit.ai/cloud",
|
|
1536
|
+
"CopilotKit: onError handler provided but requires publicApiKey to be defined for error handling to work.",
|
|
1541
1537
|
);
|
|
1542
|
-
this.
|
|
1538
|
+
this.hasWarnedAboutError = true;
|
|
1543
1539
|
}
|
|
1544
1540
|
return;
|
|
1545
1541
|
}
|
|
1546
1542
|
|
|
1547
1543
|
try {
|
|
1548
|
-
const
|
|
1544
|
+
const errorEvent: CopilotErrorEvent = {
|
|
1549
1545
|
type,
|
|
1550
1546
|
timestamp: Date.now(),
|
|
1551
1547
|
context,
|
|
1552
1548
|
...(error && { error }),
|
|
1553
1549
|
};
|
|
1554
1550
|
|
|
1555
|
-
await this.
|
|
1556
|
-
} catch (
|
|
1557
|
-
// Don't let
|
|
1558
|
-
console.error("Error in
|
|
1551
|
+
await this.onError(errorEvent);
|
|
1552
|
+
} catch (errorHandlerError) {
|
|
1553
|
+
// Don't let error handler errors break the main flow
|
|
1554
|
+
console.error("Error in onError handler:", errorHandlerError);
|
|
1559
1555
|
}
|
|
1560
1556
|
}
|
|
1561
1557
|
|
|
1562
1558
|
/**
|
|
1563
|
-
* Public method to
|
|
1564
|
-
* This allows the GraphQL resolver to send validation errors through the
|
|
1559
|
+
* Public method to handle GraphQL validation errors
|
|
1560
|
+
* This allows the GraphQL resolver to send validation errors through the error system
|
|
1565
1561
|
*/
|
|
1566
|
-
public async
|
|
1562
|
+
public async errorGraphQLError(
|
|
1567
1563
|
error: { message: string; code: string; type: string },
|
|
1568
1564
|
context: {
|
|
1569
1565
|
operation: string;
|
|
@@ -1571,10 +1567,10 @@ please use an LLM adapter instead.`,
|
|
|
1571
1567
|
guardrailsEnabled: boolean;
|
|
1572
1568
|
},
|
|
1573
1569
|
): Promise<void> {
|
|
1574
|
-
if (!this.
|
|
1570
|
+
if (!this.onError) return;
|
|
1575
1571
|
|
|
1576
1572
|
try {
|
|
1577
|
-
await this.
|
|
1573
|
+
await this.onError({
|
|
1578
1574
|
type: "error",
|
|
1579
1575
|
timestamp: Date.now(),
|
|
1580
1576
|
context: {
|
|
@@ -1594,9 +1590,9 @@ please use an LLM adapter instead.`,
|
|
|
1594
1590
|
},
|
|
1595
1591
|
error,
|
|
1596
1592
|
});
|
|
1597
|
-
} catch (
|
|
1598
|
-
// Don't let
|
|
1599
|
-
console.error("Error in
|
|
1593
|
+
} catch (errorHandlerError) {
|
|
1594
|
+
// Don't let error handler errors break the main flow
|
|
1595
|
+
console.error("Error in onError handler:", errorHandlerError);
|
|
1600
1596
|
}
|
|
1601
1597
|
}
|
|
1602
1598
|
}
|