@copilotkit/runtime 1.5.12-next.5 → 1.5.12-next.7
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 +17 -0
- package/__snapshots__/schema/schema.graphql +33 -0
- package/dist/{chunk-MFDRA3BJ.mjs → chunk-34276UUU.mjs} +652 -285
- package/dist/chunk-34276UUU.mjs.map +1 -0
- package/dist/{chunk-XRW7ZSWJ.mjs → chunk-DLESGNLO.mjs} +2 -2
- package/dist/{chunk-TPTCSIAR.mjs → chunk-S3KKBII4.mjs} +42 -30
- package/dist/chunk-S3KKBII4.mjs.map +1 -0
- package/dist/{chunk-QDMAQO2C.mjs → chunk-UBYSQI43.mjs} +2 -2
- package/dist/{chunk-NORCONUM.mjs → chunk-WTUPF3W3.mjs} +2 -2
- package/dist/{copilot-runtime-1a224a0f.d.ts → copilot-runtime-8c442d65.d.ts} +16 -3
- package/dist/graphql/types/converted/index.d.ts +1 -1
- package/dist/{groq-adapter-c35c5374.d.ts → groq-adapter-7a82cd22.d.ts} +21 -1
- package/dist/{index-24315d90.d.ts → index-a7f37670.d.ts} +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +727 -348
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +5 -5
- package/dist/{langserve-a16ef8f4.d.ts → langserve-e308c437.d.ts} +32 -3
- package/dist/lib/index.d.ts +4 -4
- package/dist/lib/index.js +725 -346
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/index.mjs +5 -5
- package/dist/lib/integrations/index.d.ts +4 -4
- package/dist/lib/integrations/index.js +504 -244
- package/dist/lib/integrations/index.js.map +1 -1
- package/dist/lib/integrations/index.mjs +5 -5
- package/dist/lib/integrations/nest/index.d.ts +3 -3
- package/dist/lib/integrations/nest/index.js +504 -244
- package/dist/lib/integrations/nest/index.js.map +1 -1
- package/dist/lib/integrations/nest/index.mjs +3 -3
- package/dist/lib/integrations/node-express/index.d.ts +3 -3
- package/dist/lib/integrations/node-express/index.js +504 -244
- package/dist/lib/integrations/node-express/index.js.map +1 -1
- package/dist/lib/integrations/node-express/index.mjs +3 -3
- package/dist/lib/integrations/node-http/index.d.ts +3 -3
- package/dist/lib/integrations/node-http/index.js +504 -244
- package/dist/lib/integrations/node-http/index.js.map +1 -1
- package/dist/lib/integrations/node-http/index.mjs +2 -2
- package/dist/service-adapters/index.d.ts +4 -4
- package/dist/service-adapters/index.js +23 -11
- package/dist/service-adapters/index.js.map +1 -1
- package/dist/service-adapters/index.mjs +1 -1
- package/package.json +2 -2
- package/src/graphql/inputs/extensions.input.ts +21 -0
- package/src/graphql/inputs/generate-copilot-response.input.ts +4 -0
- package/src/graphql/inputs/load-agent-state.input.ts +10 -0
- package/src/graphql/resolvers/copilot.resolver.ts +8 -3
- package/src/graphql/resolvers/state.resolver.ts +23 -0
- package/src/graphql/types/agents-response.type.ts +1 -4
- package/src/graphql/types/copilot-response.type.ts +5 -1
- package/src/graphql/types/extensions-response.type.ts +23 -0
- package/src/graphql/types/load-agent-state-response.type.ts +17 -0
- package/src/lib/integrations/shared.ts +2 -1
- package/src/lib/runtime/copilot-runtime.ts +155 -31
- package/src/lib/runtime/remote-action-constructors.ts +42 -33
- package/src/lib/runtime/remote-actions.ts +12 -7
- package/src/lib/runtime/remote-lg-action.ts +24 -12
- package/src/service-adapters/anthropic/anthropic-adapter.ts +2 -3
- package/src/service-adapters/empty/empty-adapter.ts +2 -2
- package/src/service-adapters/events.ts +5 -0
- package/src/service-adapters/experimental/ollama/ollama-adapter.ts +2 -2
- package/src/service-adapters/groq/groq-adapter.ts +2 -2
- package/src/service-adapters/langchain/langchain-adapter.ts +10 -3
- package/src/service-adapters/openai/openai-adapter.ts +4 -3
- package/src/service-adapters/openai/openai-assistant-adapter.ts +15 -4
- package/src/service-adapters/service-adapter.ts +4 -0
- package/src/service-adapters/unify/unify-adapter.ts +2 -3
- package/dist/chunk-MFDRA3BJ.mjs.map +0 -1
- package/dist/chunk-TPTCSIAR.mjs.map +0 -1
- /package/dist/{chunk-XRW7ZSWJ.mjs.map → chunk-DLESGNLO.mjs.map} +0 -0
- /package/dist/{chunk-QDMAQO2C.mjs.map → chunk-UBYSQI43.mjs.map} +0 -0
- /package/dist/{chunk-NORCONUM.mjs.map → chunk-WTUPF3W3.mjs.map} +0 -0
|
@@ -42,7 +42,6 @@ import {
|
|
|
42
42
|
} from "../types/converted";
|
|
43
43
|
import telemetry from "../../lib/telemetry-client";
|
|
44
44
|
import { randomId } from "@copilotkit/shared";
|
|
45
|
-
import { EndpointType, LangGraphPlatformAgent } from "../../lib/runtime/remote-actions";
|
|
46
45
|
import { AgentsResponse } from "../types/agents-response.type";
|
|
47
46
|
|
|
48
47
|
const invokeGuardrails = async ({
|
|
@@ -113,12 +112,14 @@ export class CopilotResolver {
|
|
|
113
112
|
let logger = ctx.logger.child({ component: "CopilotResolver.availableAgents" });
|
|
114
113
|
|
|
115
114
|
logger.debug("Processing");
|
|
116
|
-
const
|
|
115
|
+
const agentsWithEndpoints = await ctx._copilotkit.runtime.discoverAgentsFromEndpoints(ctx);
|
|
117
116
|
|
|
118
117
|
logger.debug("Event source created, creating response");
|
|
119
118
|
|
|
120
119
|
return {
|
|
121
|
-
agents
|
|
120
|
+
agents: agentsWithEndpoints.map(
|
|
121
|
+
({ endpoint, ...agentWithoutEndpoint }) => agentWithoutEndpoint,
|
|
122
|
+
),
|
|
122
123
|
};
|
|
123
124
|
}
|
|
124
125
|
|
|
@@ -192,6 +193,7 @@ export class CopilotResolver {
|
|
|
192
193
|
runId,
|
|
193
194
|
serverSideActions,
|
|
194
195
|
actionInputsWithoutAgents,
|
|
196
|
+
extensions,
|
|
195
197
|
} = await copilotRuntime.processRuntimeRequest({
|
|
196
198
|
serviceAdapter,
|
|
197
199
|
messages: data.messages,
|
|
@@ -207,6 +209,7 @@ export class CopilotResolver {
|
|
|
207
209
|
agentSession: data.agentSession,
|
|
208
210
|
agentStates: data.agentStates,
|
|
209
211
|
url: data.frontend.url,
|
|
212
|
+
extensions: data.extensions,
|
|
210
213
|
});
|
|
211
214
|
|
|
212
215
|
logger.debug("Event source created, creating response");
|
|
@@ -215,6 +218,7 @@ export class CopilotResolver {
|
|
|
215
218
|
threadId,
|
|
216
219
|
runId,
|
|
217
220
|
status: firstValueFrom(responseStatus$),
|
|
221
|
+
extensions,
|
|
218
222
|
messages: new Repeater(async (pushMessage, stopStreamingMessages) => {
|
|
219
223
|
logger.debug("Messages repeater created");
|
|
220
224
|
|
|
@@ -281,6 +285,7 @@ export class CopilotResolver {
|
|
|
281
285
|
(action) =>
|
|
282
286
|
!serverSideActions.find((serverSideAction) => serverSideAction.name == action.name),
|
|
283
287
|
),
|
|
288
|
+
threadId,
|
|
284
289
|
})
|
|
285
290
|
.pipe(
|
|
286
291
|
// shareReplay() ensures that later subscribers will see the whole stream instead of
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Arg, Resolver } from "type-graphql";
|
|
2
|
+
import { Ctx } from "type-graphql";
|
|
3
|
+
import { Query } from "type-graphql";
|
|
4
|
+
import { LoadAgentStateResponse } from "../types/load-agent-state-response.type";
|
|
5
|
+
import type { GraphQLContext } from "../../lib/integrations";
|
|
6
|
+
import { LoadAgentStateInput } from "../inputs/load-agent-state.input";
|
|
7
|
+
|
|
8
|
+
@Resolver(() => LoadAgentStateResponse)
|
|
9
|
+
export class StateResolver {
|
|
10
|
+
@Query(() => LoadAgentStateResponse)
|
|
11
|
+
async loadAgentState(@Ctx() ctx: GraphQLContext, @Arg("data") data: LoadAgentStateInput) {
|
|
12
|
+
const agents = await ctx._copilotkit.runtime.discoverAgentsFromEndpoints(ctx);
|
|
13
|
+
const agent = agents.find((agent) => agent.name === data.agentName);
|
|
14
|
+
|
|
15
|
+
if (!agent) {
|
|
16
|
+
throw new Error("Agent not found");
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const state = await ctx._copilotkit.runtime.loadAgentState(ctx, data.threadId, data.agentName);
|
|
20
|
+
|
|
21
|
+
return state;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import { Field,
|
|
2
|
-
import { MessageRole } from "./enums";
|
|
3
|
-
import { MessageStatusUnion } from "./message-status.type";
|
|
4
|
-
import { ResponseStatusUnion } from "./response-status.type";
|
|
1
|
+
import { Field, ObjectType } from "type-graphql";
|
|
5
2
|
|
|
6
3
|
@ObjectType()
|
|
7
4
|
export class Agent {
|
|
@@ -2,6 +2,7 @@ import { Field, InterfaceType, ObjectType } from "type-graphql";
|
|
|
2
2
|
import { MessageRole } from "./enums";
|
|
3
3
|
import { MessageStatusUnion } from "./message-status.type";
|
|
4
4
|
import { ResponseStatusUnion } from "./response-status.type";
|
|
5
|
+
import { ExtensionsResponse } from "./extensions-response.type";
|
|
5
6
|
|
|
6
7
|
@InterfaceType({
|
|
7
8
|
resolveType(value) {
|
|
@@ -17,7 +18,7 @@ import { ResponseStatusUnion } from "./response-status.type";
|
|
|
17
18
|
return undefined;
|
|
18
19
|
},
|
|
19
20
|
})
|
|
20
|
-
abstract class BaseMessageOutput {
|
|
21
|
+
export abstract class BaseMessageOutput {
|
|
21
22
|
@Field(() => String)
|
|
22
23
|
id: string;
|
|
23
24
|
|
|
@@ -110,4 +111,7 @@ export class CopilotResponse {
|
|
|
110
111
|
|
|
111
112
|
@Field(() => [BaseMessageOutput])
|
|
112
113
|
messages: (typeof BaseMessageOutput)[];
|
|
114
|
+
|
|
115
|
+
@Field(() => ExtensionsResponse, { nullable: true })
|
|
116
|
+
extensions?: ExtensionsResponse;
|
|
113
117
|
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Field, ObjectType } from "type-graphql";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The extensions response is used to receive additional information from the copilot runtime, specific to a
|
|
5
|
+
* service adapter or agent framework.
|
|
6
|
+
*
|
|
7
|
+
* Next time a request to the runtime is made, the extensions response will be included in the request as input.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
@ObjectType()
|
|
11
|
+
export class ExtensionsResponse {
|
|
12
|
+
@Field(() => OpenAIApiAssistantAPIResponse, { nullable: true })
|
|
13
|
+
openaiAssistantAPI?: OpenAIApiAssistantAPIResponse;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
@ObjectType()
|
|
17
|
+
export class OpenAIApiAssistantAPIResponse {
|
|
18
|
+
@Field(() => String, { nullable: true })
|
|
19
|
+
runId?: string;
|
|
20
|
+
|
|
21
|
+
@Field(() => String, { nullable: true })
|
|
22
|
+
threadId?: string;
|
|
23
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Field, ObjectType } from "type-graphql";
|
|
2
|
+
import { BaseMessageOutput } from "./copilot-response.type";
|
|
3
|
+
|
|
4
|
+
@ObjectType()
|
|
5
|
+
export class LoadAgentStateResponse {
|
|
6
|
+
@Field(() => String)
|
|
7
|
+
threadId: string;
|
|
8
|
+
|
|
9
|
+
@Field(() => Boolean)
|
|
10
|
+
threadExists: boolean;
|
|
11
|
+
|
|
12
|
+
@Field(() => String)
|
|
13
|
+
state: string;
|
|
14
|
+
|
|
15
|
+
@Field(() => String)
|
|
16
|
+
messages: string;
|
|
17
|
+
}
|
|
@@ -8,6 +8,7 @@ import { CopilotCloudOptions } from "../cloud";
|
|
|
8
8
|
import { LogLevel, createLogger } from "../../lib/logger";
|
|
9
9
|
import { createYoga } from "graphql-yoga";
|
|
10
10
|
import telemetry from "../telemetry-client";
|
|
11
|
+
import { StateResolver } from "../../graphql/resolvers/state.resolver";
|
|
11
12
|
|
|
12
13
|
const logger = createLogger();
|
|
13
14
|
|
|
@@ -58,7 +59,7 @@ export function buildSchema(
|
|
|
58
59
|
) {
|
|
59
60
|
logger.debug("Building GraphQL schema...");
|
|
60
61
|
const schema = buildSchemaSync({
|
|
61
|
-
resolvers: [CopilotResolver],
|
|
62
|
+
resolvers: [CopilotResolver, StateResolver],
|
|
62
63
|
emitSchemaFile: options.emitSchemaFile,
|
|
63
64
|
});
|
|
64
65
|
logger.debug("GraphQL schema built successfully");
|
|
@@ -12,7 +12,18 @@
|
|
|
12
12
|
* ```
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
Action,
|
|
17
|
+
actionParametersToJsonSchema,
|
|
18
|
+
Parameter,
|
|
19
|
+
ResolvedCopilotKitError,
|
|
20
|
+
CopilotKitApiDiscoveryError,
|
|
21
|
+
randomId,
|
|
22
|
+
CopilotKitError,
|
|
23
|
+
CopilotKitLowLevelError,
|
|
24
|
+
CopilotKitAgentDiscoveryError,
|
|
25
|
+
CopilotKitMisuseError,
|
|
26
|
+
} from "@copilotkit/shared";
|
|
16
27
|
import {
|
|
17
28
|
CopilotServiceAdapter,
|
|
18
29
|
EmptyAdapter,
|
|
@@ -41,6 +52,11 @@ import { AgentStateInput } from "../../graphql/inputs/agent-state.input";
|
|
|
41
52
|
import { ActionInputAvailability } from "../../graphql/types/enums";
|
|
42
53
|
import { createHeaders } from "./remote-action-constructors";
|
|
43
54
|
import { Agent } from "../../graphql/types/agents-response.type";
|
|
55
|
+
import { ExtensionsInput } from "../../graphql/inputs/extensions.input";
|
|
56
|
+
import { ExtensionsResponse } from "../../graphql/types/extensions-response.type";
|
|
57
|
+
import { LoadAgentStateResponse } from "../../graphql/types/load-agent-state-response.type";
|
|
58
|
+
import { Client as LangGraphClient } from "@langchain/langgraph-sdk";
|
|
59
|
+
import { langchainMessagesToCopilotKit } from "./remote-lg-action";
|
|
44
60
|
|
|
45
61
|
interface CopilotRuntimeRequest {
|
|
46
62
|
serviceAdapter: CopilotServiceAdapter;
|
|
@@ -55,6 +71,7 @@ interface CopilotRuntimeRequest {
|
|
|
55
71
|
graphqlContext: GraphQLContext;
|
|
56
72
|
forwardedParameters?: ForwardedParametersInput;
|
|
57
73
|
url?: string;
|
|
74
|
+
extensions?: ExtensionsInput;
|
|
58
75
|
}
|
|
59
76
|
|
|
60
77
|
interface CopilotRuntimeResponse {
|
|
@@ -63,6 +80,7 @@ interface CopilotRuntimeResponse {
|
|
|
63
80
|
eventSource: RuntimeEventSource;
|
|
64
81
|
serverSideActions: Action<any>[];
|
|
65
82
|
actionInputsWithoutAgents: ActionInput[];
|
|
83
|
+
extensions?: ExtensionsResponse;
|
|
66
84
|
}
|
|
67
85
|
|
|
68
86
|
type ActionsConfiguration<T extends Parameter[] | [] = []> =
|
|
@@ -102,6 +120,8 @@ interface Middleware {
|
|
|
102
120
|
onAfterRequest?: OnAfterRequestHandler;
|
|
103
121
|
}
|
|
104
122
|
|
|
123
|
+
type AgentWithEndpoint = Agent & { endpoint: EndpointDefinition };
|
|
124
|
+
|
|
105
125
|
export interface CopilotRuntimeConstructorParams<T extends Parameter[] | [] = []> {
|
|
106
126
|
/**
|
|
107
127
|
* Middleware to be used by the runtime.
|
|
@@ -181,6 +201,7 @@ export class CopilotRuntime<const T extends Parameter[] | [] = []> {
|
|
|
181
201
|
forwardedParameters,
|
|
182
202
|
agentSession,
|
|
183
203
|
url,
|
|
204
|
+
extensions,
|
|
184
205
|
} = request;
|
|
185
206
|
|
|
186
207
|
const eventSource = new RuntimeEventSource();
|
|
@@ -190,10 +211,11 @@ export class CopilotRuntime<const T extends Parameter[] | [] = []> {
|
|
|
190
211
|
return await this.processAgentRequest(request);
|
|
191
212
|
}
|
|
192
213
|
if (serviceAdapter instanceof EmptyAdapter) {
|
|
193
|
-
|
|
194
|
-
|
|
214
|
+
throw new CopilotKitMisuseError({
|
|
215
|
+
message: `Invalid adapter configuration: EmptyAdapter is only meant to be used with agent lock mode.
|
|
195
216
|
For non-agent components like useCopilotChatSuggestions, CopilotTextarea, or CopilotTask,
|
|
196
|
-
please use an LLM adapter instead
|
|
217
|
+
please use an LLM adapter instead.`,
|
|
218
|
+
});
|
|
197
219
|
}
|
|
198
220
|
|
|
199
221
|
const messages = rawMessages.filter((message) => !message.agentStateMessage);
|
|
@@ -230,12 +252,17 @@ please use an LLM adapter instead.`);
|
|
|
230
252
|
runId,
|
|
231
253
|
eventSource,
|
|
232
254
|
forwardedParameters,
|
|
255
|
+
extensions,
|
|
233
256
|
});
|
|
234
257
|
|
|
258
|
+
// for backwards compatibility, we deal with the case that no threadId is provided
|
|
259
|
+
// by the frontend, by using the threadId from the response
|
|
260
|
+
const nonEmptyThreadId = threadId ?? result.threadId;
|
|
261
|
+
|
|
235
262
|
outputMessagesPromise
|
|
236
263
|
.then((outputMessages) => {
|
|
237
264
|
this.onAfterRequest?.({
|
|
238
|
-
threadId:
|
|
265
|
+
threadId: nonEmptyThreadId,
|
|
239
266
|
runId: result.runId,
|
|
240
267
|
inputMessages,
|
|
241
268
|
outputMessages,
|
|
@@ -246,7 +273,7 @@ please use an LLM adapter instead.`);
|
|
|
246
273
|
.catch((_error) => {});
|
|
247
274
|
|
|
248
275
|
return {
|
|
249
|
-
threadId:
|
|
276
|
+
threadId: nonEmptyThreadId,
|
|
250
277
|
runId: result.runId,
|
|
251
278
|
eventSource,
|
|
252
279
|
serverSideActions,
|
|
@@ -258,32 +285,37 @@ please use an LLM adapter instead.`);
|
|
|
258
285
|
// serverSideActions.find((serverSideAction) => serverSideAction.name == action.name),
|
|
259
286
|
// ),
|
|
260
287
|
),
|
|
288
|
+
extensions: result.extensions,
|
|
261
289
|
};
|
|
262
290
|
} catch (error) {
|
|
291
|
+
if (error instanceof CopilotKitError) {
|
|
292
|
+
throw error;
|
|
293
|
+
}
|
|
263
294
|
console.error("Error getting response:", error);
|
|
264
295
|
eventSource.sendErrorMessageToChat();
|
|
265
296
|
throw error;
|
|
266
297
|
}
|
|
267
298
|
}
|
|
268
299
|
|
|
269
|
-
async discoverAgentsFromEndpoints(graphqlContext: GraphQLContext): Promise<
|
|
300
|
+
async discoverAgentsFromEndpoints(graphqlContext: GraphQLContext): Promise<AgentWithEndpoint[]> {
|
|
270
301
|
const headers = createHeaders(null, graphqlContext);
|
|
271
302
|
const agents = this.remoteEndpointDefinitions.reduce(
|
|
272
303
|
async (acc: Promise<Agent[]>, endpoint) => {
|
|
273
304
|
const agents = await acc;
|
|
274
305
|
if (endpoint.type === EndpointType.LangGraphPlatform) {
|
|
275
|
-
const
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
const data: Array<{ assistant_id: string; graph_id: string }> = await response.json();
|
|
306
|
+
const client = new LangGraphClient({
|
|
307
|
+
apiUrl: endpoint.deploymentUrl,
|
|
308
|
+
apiKey: endpoint.langsmithApiKey,
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
const data: Array<{ assistant_id: string; graph_id: string }> =
|
|
312
|
+
await client.assistants.search();
|
|
313
|
+
|
|
284
314
|
const endpointAgents = (data ?? []).map((entry) => ({
|
|
285
315
|
name: entry.graph_id,
|
|
286
316
|
id: entry.assistant_id,
|
|
317
|
+
description: "",
|
|
318
|
+
endpoint,
|
|
287
319
|
}));
|
|
288
320
|
return [...agents, ...endpointAgents];
|
|
289
321
|
}
|
|
@@ -295,18 +327,34 @@ please use an LLM adapter instead.`);
|
|
|
295
327
|
}>;
|
|
296
328
|
}
|
|
297
329
|
|
|
298
|
-
const
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
330
|
+
const fetchUrl = `${(endpoint as CopilotKitEndpoint).url}/info`;
|
|
331
|
+
try {
|
|
332
|
+
const response = await fetch(fetchUrl, {
|
|
333
|
+
method: "POST",
|
|
334
|
+
headers,
|
|
335
|
+
body: JSON.stringify({ properties: graphqlContext.properties }),
|
|
336
|
+
});
|
|
337
|
+
if (!response.ok) {
|
|
338
|
+
if (response.status === 404) {
|
|
339
|
+
throw new CopilotKitApiDiscoveryError();
|
|
340
|
+
}
|
|
341
|
+
throw new ResolvedCopilotKitError({ status: response.status, isRemoteEndpoint: true });
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
const data: InfoResponse = await response.json();
|
|
345
|
+
const endpointAgents = (data?.agents ?? []).map((agent) => ({
|
|
346
|
+
name: agent.name,
|
|
347
|
+
description: agent.description ?? "" ?? "",
|
|
348
|
+
id: randomId(), // Required by Agent type
|
|
349
|
+
endpoint,
|
|
350
|
+
}));
|
|
351
|
+
return [...agents, ...endpointAgents];
|
|
352
|
+
} catch (error) {
|
|
353
|
+
if (error instanceof CopilotKitError) {
|
|
354
|
+
throw error;
|
|
355
|
+
}
|
|
356
|
+
throw new CopilotKitLowLevelError({ error: error as Error, url: fetchUrl });
|
|
357
|
+
}
|
|
310
358
|
},
|
|
311
359
|
Promise.resolve([]),
|
|
312
360
|
);
|
|
@@ -314,11 +362,87 @@ please use an LLM adapter instead.`);
|
|
|
314
362
|
return agents;
|
|
315
363
|
}
|
|
316
364
|
|
|
365
|
+
async loadAgentState(
|
|
366
|
+
graphqlContext: GraphQLContext,
|
|
367
|
+
threadId: string,
|
|
368
|
+
agentName: string,
|
|
369
|
+
): Promise<LoadAgentStateResponse> {
|
|
370
|
+
const agentsWithEndpoints = await this.discoverAgentsFromEndpoints(graphqlContext);
|
|
371
|
+
|
|
372
|
+
const agentWithEndpoint = agentsWithEndpoints.find((agent) => agent.name === agentName);
|
|
373
|
+
if (!agentWithEndpoint) {
|
|
374
|
+
throw new Error("Agent not found");
|
|
375
|
+
}
|
|
376
|
+
const headers = createHeaders(null, graphqlContext);
|
|
377
|
+
|
|
378
|
+
if (agentWithEndpoint.endpoint.type === EndpointType.LangGraphPlatform) {
|
|
379
|
+
const client = new LangGraphClient({
|
|
380
|
+
apiUrl: agentWithEndpoint.endpoint.deploymentUrl,
|
|
381
|
+
apiKey: agentWithEndpoint.endpoint.langsmithApiKey,
|
|
382
|
+
});
|
|
383
|
+
const state = (await client.threads.getState(threadId)).values as any;
|
|
384
|
+
|
|
385
|
+
if (Object.keys(state).length === 0) {
|
|
386
|
+
return {
|
|
387
|
+
threadId,
|
|
388
|
+
threadExists: false,
|
|
389
|
+
state: JSON.stringify({}),
|
|
390
|
+
messages: JSON.stringify([]),
|
|
391
|
+
};
|
|
392
|
+
} else {
|
|
393
|
+
console.log(state);
|
|
394
|
+
const { messages, ...stateWithoutMessages } = state;
|
|
395
|
+
const copilotkitMessages = langchainMessagesToCopilotKit(messages);
|
|
396
|
+
return {
|
|
397
|
+
threadId,
|
|
398
|
+
threadExists: true,
|
|
399
|
+
state: JSON.stringify(stateWithoutMessages),
|
|
400
|
+
messages: JSON.stringify(copilotkitMessages),
|
|
401
|
+
};
|
|
402
|
+
}
|
|
403
|
+
} else if (
|
|
404
|
+
agentWithEndpoint.endpoint.type === EndpointType.CopilotKit ||
|
|
405
|
+
!("type" in agentWithEndpoint.endpoint)
|
|
406
|
+
) {
|
|
407
|
+
const response = await fetch(
|
|
408
|
+
`${(agentWithEndpoint.endpoint as CopilotKitEndpoint).url}/agents/state`,
|
|
409
|
+
{
|
|
410
|
+
method: "POST",
|
|
411
|
+
headers,
|
|
412
|
+
body: JSON.stringify({
|
|
413
|
+
properties: graphqlContext.properties,
|
|
414
|
+
threadId,
|
|
415
|
+
name: agentName,
|
|
416
|
+
}),
|
|
417
|
+
},
|
|
418
|
+
);
|
|
419
|
+
const data: LoadAgentStateResponse = await response.json();
|
|
420
|
+
|
|
421
|
+
return {
|
|
422
|
+
...data,
|
|
423
|
+
state: JSON.stringify(data.state),
|
|
424
|
+
messages: JSON.stringify(data.messages),
|
|
425
|
+
};
|
|
426
|
+
} else {
|
|
427
|
+
throw new Error(`Unknown endpoint type: ${(agentWithEndpoint.endpoint as any).type}`);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
|
|
317
431
|
private async processAgentRequest(
|
|
318
432
|
request: CopilotRuntimeRequest,
|
|
319
433
|
): Promise<CopilotRuntimeResponse> {
|
|
320
|
-
const {
|
|
321
|
-
|
|
434
|
+
const {
|
|
435
|
+
messages: rawMessages,
|
|
436
|
+
outputMessagesPromise,
|
|
437
|
+
graphqlContext,
|
|
438
|
+
agentSession,
|
|
439
|
+
threadId: threadIdFromRequest,
|
|
440
|
+
} = request;
|
|
441
|
+
const { agentName, nodeName } = agentSession;
|
|
442
|
+
|
|
443
|
+
// for backwards compatibility, deal with the case when no threadId is provided
|
|
444
|
+
const threadId = threadIdFromRequest ?? agentSession.threadId;
|
|
445
|
+
|
|
322
446
|
const serverSideActions = await this.getServerSideActions(request);
|
|
323
447
|
|
|
324
448
|
const messages = convertGqlInputToMessages(rawMessages);
|
|
@@ -328,7 +452,7 @@ please use an LLM adapter instead.`);
|
|
|
328
452
|
) as LangGraphAgentAction;
|
|
329
453
|
|
|
330
454
|
if (!agent) {
|
|
331
|
-
throw new
|
|
455
|
+
throw new CopilotKitAgentDiscoveryError({ agentName });
|
|
332
456
|
}
|
|
333
457
|
|
|
334
458
|
const serverSideActionsInput: ActionInput[] = serverSideActions
|
|
@@ -16,6 +16,7 @@ import { RemoteLangGraphEventSource } from "../../agents/langgraph/event-source"
|
|
|
16
16
|
import { Action } from "@copilotkit/shared";
|
|
17
17
|
import { LangGraphEvent } from "../../agents/langgraph/events";
|
|
18
18
|
import { execute } from "./remote-lg-action";
|
|
19
|
+
import { CopilotKitError, CopilotKitLowLevelError } from "@copilotkit/shared";
|
|
19
20
|
|
|
20
21
|
export function constructLGCRemoteAction({
|
|
21
22
|
endpoint,
|
|
@@ -126,8 +127,9 @@ export function constructRemoteActions({
|
|
|
126
127
|
agentsAmount: totalAgents,
|
|
127
128
|
});
|
|
128
129
|
|
|
130
|
+
const fetchUrl = `${url}/actions/execute`;
|
|
129
131
|
try {
|
|
130
|
-
const response = await fetch(
|
|
132
|
+
const response = await fetch(fetchUrl, {
|
|
131
133
|
method: "POST",
|
|
132
134
|
headers,
|
|
133
135
|
body: JSON.stringify({
|
|
@@ -151,11 +153,10 @@ export function constructRemoteActions({
|
|
|
151
153
|
logger.debug({ actionName: action.name, result }, "Executed remote action");
|
|
152
154
|
return result;
|
|
153
155
|
} catch (error) {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
);
|
|
158
|
-
return "Failed to execute remote action";
|
|
156
|
+
if (error instanceof CopilotKitError) {
|
|
157
|
+
throw error;
|
|
158
|
+
}
|
|
159
|
+
throw new CopilotKitLowLevelError({ error, url: fetchUrl });
|
|
159
160
|
}
|
|
160
161
|
},
|
|
161
162
|
}));
|
|
@@ -191,35 +192,43 @@ export function constructRemoteActions({
|
|
|
191
192
|
}
|
|
192
193
|
}
|
|
193
194
|
|
|
194
|
-
const
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
195
|
+
const fetchUrl = `${url}/agents/execute`;
|
|
196
|
+
try {
|
|
197
|
+
const response = await fetch(fetchUrl, {
|
|
198
|
+
method: "POST",
|
|
199
|
+
headers,
|
|
200
|
+
body: JSON.stringify({
|
|
201
|
+
name,
|
|
202
|
+
threadId,
|
|
203
|
+
nodeName,
|
|
204
|
+
messages: [...messages, ...additionalMessages],
|
|
205
|
+
state,
|
|
206
|
+
properties: graphqlContext.properties,
|
|
207
|
+
actions: actionInputsWithoutAgents.map((action) => ({
|
|
208
|
+
name: action.name,
|
|
209
|
+
description: action.description,
|
|
210
|
+
parameters: JSON.parse(action.jsonSchema),
|
|
211
|
+
})),
|
|
212
|
+
}),
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
if (!response.ok) {
|
|
216
|
+
logger.error(
|
|
217
|
+
{ url, status: response.status, body: await response.text() },
|
|
218
|
+
"Failed to execute remote agent",
|
|
219
|
+
);
|
|
220
|
+
throw new Error("Failed to execute remote agent");
|
|
221
|
+
}
|
|
211
222
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
)
|
|
217
|
-
|
|
223
|
+
const eventSource = new RemoteLangGraphEventSource();
|
|
224
|
+
streamResponse(response.body!, eventSource.eventStream$);
|
|
225
|
+
return eventSource.processLangGraphEvents();
|
|
226
|
+
} catch (error) {
|
|
227
|
+
if (error instanceof CopilotKitError) {
|
|
228
|
+
throw error;
|
|
229
|
+
}
|
|
230
|
+
throw new CopilotKitLowLevelError({ error, url: fetchUrl });
|
|
218
231
|
}
|
|
219
|
-
|
|
220
|
-
const eventSource = new RemoteLangGraphEventSource();
|
|
221
|
-
streamResponse(response.body!, eventSource.eventStream$);
|
|
222
|
-
return eventSource.processLangGraphEvents();
|
|
223
232
|
},
|
|
224
233
|
}))
|
|
225
234
|
: [];
|
|
@@ -11,6 +11,11 @@ import {
|
|
|
11
11
|
constructRemoteActions,
|
|
12
12
|
createHeaders,
|
|
13
13
|
} from "./remote-action-constructors";
|
|
14
|
+
import {
|
|
15
|
+
CopilotKitLowLevelError,
|
|
16
|
+
ResolvedCopilotKitError,
|
|
17
|
+
CopilotKitError,
|
|
18
|
+
} from "@copilotkit/shared";
|
|
14
19
|
|
|
15
20
|
export type EndpointDefinition = CopilotKitEndpoint | LangGraphPlatformEndpoint;
|
|
16
21
|
|
|
@@ -83,8 +88,9 @@ async function fetchRemoteInfo({
|
|
|
83
88
|
logger.debug({ url }, "Fetching actions from url");
|
|
84
89
|
const headers = createHeaders(onBeforeRequest, graphqlContext);
|
|
85
90
|
|
|
91
|
+
const fetchUrl = `${url}/info`;
|
|
86
92
|
try {
|
|
87
|
-
const response = await fetch(
|
|
93
|
+
const response = await fetch(fetchUrl, {
|
|
88
94
|
method: "POST",
|
|
89
95
|
headers,
|
|
90
96
|
body: JSON.stringify({ properties: graphqlContext.properties, frontendUrl }),
|
|
@@ -95,18 +101,17 @@ async function fetchRemoteInfo({
|
|
|
95
101
|
{ url, status: response.status, body: await response.text() },
|
|
96
102
|
"Failed to fetch actions from url",
|
|
97
103
|
);
|
|
98
|
-
|
|
104
|
+
throw new ResolvedCopilotKitError({ status: response.status, isRemoteEndpoint: true });
|
|
99
105
|
}
|
|
100
106
|
|
|
101
107
|
const json = await response.json();
|
|
102
108
|
logger.debug({ json }, "Fetched actions from url");
|
|
103
109
|
return json;
|
|
104
110
|
} catch (error) {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
);
|
|
109
|
-
return { actions: [], agents: [] };
|
|
111
|
+
if (error instanceof CopilotKitError) {
|
|
112
|
+
throw error;
|
|
113
|
+
}
|
|
114
|
+
throw new CopilotKitLowLevelError({ error, url: fetchUrl });
|
|
110
115
|
}
|
|
111
116
|
}
|
|
112
117
|
|