@copilotkit/runtime 0.0.0-feat-dynamic-copilotcloud-qa-20250117190454

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.
Files changed (147) hide show
  1. package/.eslintrc.js +7 -0
  2. package/CHANGELOG.md +913 -0
  3. package/README.md +46 -0
  4. package/__snapshots__/schema/schema.graphql +273 -0
  5. package/dist/chunk-44O2JGUY.mjs +12 -0
  6. package/dist/chunk-44O2JGUY.mjs.map +1 -0
  7. package/dist/chunk-BETLEV37.mjs +25 -0
  8. package/dist/chunk-BETLEV37.mjs.map +1 -0
  9. package/dist/chunk-CLGKEUOA.mjs +1408 -0
  10. package/dist/chunk-CLGKEUOA.mjs.map +1 -0
  11. package/dist/chunk-D2WLFQS6.mjs +43 -0
  12. package/dist/chunk-D2WLFQS6.mjs.map +1 -0
  13. package/dist/chunk-DFOKBSIS.mjs +1 -0
  14. package/dist/chunk-DFOKBSIS.mjs.map +1 -0
  15. package/dist/chunk-FA5DJ2TZ.mjs +3437 -0
  16. package/dist/chunk-FA5DJ2TZ.mjs.map +1 -0
  17. package/dist/chunk-HNUNXFTW.mjs +129 -0
  18. package/dist/chunk-HNUNXFTW.mjs.map +1 -0
  19. package/dist/chunk-SFLMY3ES.mjs +80 -0
  20. package/dist/chunk-SFLMY3ES.mjs.map +1 -0
  21. package/dist/chunk-U3V2BCGI.mjs +152 -0
  22. package/dist/chunk-U3V2BCGI.mjs.map +1 -0
  23. package/dist/chunk-ZCU6UPCY.mjs +25 -0
  24. package/dist/chunk-ZCU6UPCY.mjs.map +1 -0
  25. package/dist/copilot-runtime-1a224a0f.d.ts +196 -0
  26. package/dist/graphql/types/base/index.d.ts +6 -0
  27. package/dist/graphql/types/base/index.js +63 -0
  28. package/dist/graphql/types/base/index.js.map +1 -0
  29. package/dist/graphql/types/base/index.mjs +8 -0
  30. package/dist/graphql/types/base/index.mjs.map +1 -0
  31. package/dist/graphql/types/converted/index.d.ts +2 -0
  32. package/dist/graphql/types/converted/index.js +187 -0
  33. package/dist/graphql/types/converted/index.js.map +1 -0
  34. package/dist/graphql/types/converted/index.mjs +17 -0
  35. package/dist/graphql/types/converted/index.mjs.map +1 -0
  36. package/dist/groq-adapter-c35c5374.d.ts +281 -0
  37. package/dist/index-24315d90.d.ts +103 -0
  38. package/dist/index.d.ts +23 -0
  39. package/dist/index.js +5258 -0
  40. package/dist/index.js.map +1 -0
  41. package/dist/index.mjs +76 -0
  42. package/dist/index.mjs.map +1 -0
  43. package/dist/langserve-a16ef8f4.d.ts +180 -0
  44. package/dist/lib/cloud/index.d.ts +6 -0
  45. package/dist/lib/cloud/index.js +18 -0
  46. package/dist/lib/cloud/index.js.map +1 -0
  47. package/dist/lib/cloud/index.mjs +1 -0
  48. package/dist/lib/cloud/index.mjs.map +1 -0
  49. package/dist/lib/index.d.ts +20 -0
  50. package/dist/lib/index.js +4906 -0
  51. package/dist/lib/index.js.map +1 -0
  52. package/dist/lib/index.mjs +58 -0
  53. package/dist/lib/index.mjs.map +1 -0
  54. package/dist/lib/integrations/index.d.ts +33 -0
  55. package/dist/lib/integrations/index.js +2229 -0
  56. package/dist/lib/integrations/index.js.map +1 -0
  57. package/dist/lib/integrations/index.mjs +34 -0
  58. package/dist/lib/integrations/index.mjs.map +1 -0
  59. package/dist/lib/integrations/nest/index.d.ts +14 -0
  60. package/dist/lib/integrations/nest/index.js +2138 -0
  61. package/dist/lib/integrations/nest/index.js.map +1 -0
  62. package/dist/lib/integrations/nest/index.mjs +13 -0
  63. package/dist/lib/integrations/nest/index.mjs.map +1 -0
  64. package/dist/lib/integrations/node-express/index.d.ts +14 -0
  65. package/dist/lib/integrations/node-express/index.js +2138 -0
  66. package/dist/lib/integrations/node-express/index.js.map +1 -0
  67. package/dist/lib/integrations/node-express/index.mjs +13 -0
  68. package/dist/lib/integrations/node-express/index.mjs.map +1 -0
  69. package/dist/lib/integrations/node-http/index.d.ts +14 -0
  70. package/dist/lib/integrations/node-http/index.js +2124 -0
  71. package/dist/lib/integrations/node-http/index.js.map +1 -0
  72. package/dist/lib/integrations/node-http/index.mjs +12 -0
  73. package/dist/lib/integrations/node-http/index.mjs.map +1 -0
  74. package/dist/service-adapters/index.d.ts +84 -0
  75. package/dist/service-adapters/index.js +1448 -0
  76. package/dist/service-adapters/index.js.map +1 -0
  77. package/dist/service-adapters/index.mjs +26 -0
  78. package/dist/service-adapters/index.mjs.map +1 -0
  79. package/dist/utils/index.d.ts +49 -0
  80. package/dist/utils/index.js +174 -0
  81. package/dist/utils/index.js.map +1 -0
  82. package/dist/utils/index.mjs +12 -0
  83. package/dist/utils/index.mjs.map +1 -0
  84. package/jest.config.js +5 -0
  85. package/package.json +85 -0
  86. package/scripts/generate-gql-schema.ts +13 -0
  87. package/src/agents/langgraph/event-source.ts +287 -0
  88. package/src/agents/langgraph/events.ts +338 -0
  89. package/src/graphql/inputs/action.input.ts +16 -0
  90. package/src/graphql/inputs/agent-session.input.ts +13 -0
  91. package/src/graphql/inputs/agent-state.input.ts +10 -0
  92. package/src/graphql/inputs/cloud-guardrails.input.ts +16 -0
  93. package/src/graphql/inputs/cloud.input.ts +8 -0
  94. package/src/graphql/inputs/context-property.input.ts +10 -0
  95. package/src/graphql/inputs/custom-property.input.ts +15 -0
  96. package/src/graphql/inputs/forwarded-parameters.input.ts +22 -0
  97. package/src/graphql/inputs/frontend.input.ts +14 -0
  98. package/src/graphql/inputs/generate-copilot-response.input.ts +47 -0
  99. package/src/graphql/inputs/message.input.ts +92 -0
  100. package/src/graphql/resolvers/copilot.resolver.ts +556 -0
  101. package/src/graphql/types/agents-response.type.ts +22 -0
  102. package/src/graphql/types/base/index.ts +10 -0
  103. package/src/graphql/types/converted/index.ts +136 -0
  104. package/src/graphql/types/copilot-response.type.ts +113 -0
  105. package/src/graphql/types/enums.ts +37 -0
  106. package/src/graphql/types/guardrails-result.type.ts +20 -0
  107. package/src/graphql/types/message-status.type.ts +40 -0
  108. package/src/graphql/types/response-status.type.ts +66 -0
  109. package/src/index.ts +4 -0
  110. package/src/lib/cloud/index.ts +4 -0
  111. package/src/lib/index.ts +8 -0
  112. package/src/lib/integrations/index.ts +6 -0
  113. package/src/lib/integrations/nest/index.ts +17 -0
  114. package/src/lib/integrations/nextjs/app-router.ts +40 -0
  115. package/src/lib/integrations/nextjs/pages-router.ts +49 -0
  116. package/src/lib/integrations/node-express/index.ts +17 -0
  117. package/src/lib/integrations/node-http/index.ts +34 -0
  118. package/src/lib/integrations/shared.ts +109 -0
  119. package/src/lib/logger.ts +28 -0
  120. package/src/lib/runtime/copilot-runtime.ts +466 -0
  121. package/src/lib/runtime/remote-action-constructors.ts +304 -0
  122. package/src/lib/runtime/remote-actions.ts +174 -0
  123. package/src/lib/runtime/remote-lg-action.ts +657 -0
  124. package/src/lib/telemetry-client.ts +52 -0
  125. package/src/service-adapters/anthropic/anthropic-adapter.ts +205 -0
  126. package/src/service-adapters/anthropic/utils.ts +144 -0
  127. package/src/service-adapters/conversion.ts +64 -0
  128. package/src/service-adapters/events.ts +419 -0
  129. package/src/service-adapters/experimental/empty/empty-adapter.ts +33 -0
  130. package/src/service-adapters/experimental/ollama/ollama-adapter.ts +79 -0
  131. package/src/service-adapters/google/google-genai-adapter.ts +39 -0
  132. package/src/service-adapters/groq/groq-adapter.ts +173 -0
  133. package/src/service-adapters/index.ts +16 -0
  134. package/src/service-adapters/langchain/langchain-adapter.ts +99 -0
  135. package/src/service-adapters/langchain/langserve.ts +87 -0
  136. package/src/service-adapters/langchain/types.ts +14 -0
  137. package/src/service-adapters/langchain/utils.ts +306 -0
  138. package/src/service-adapters/openai/openai-adapter.ts +210 -0
  139. package/src/service-adapters/openai/openai-assistant-adapter.ts +304 -0
  140. package/src/service-adapters/openai/utils.ts +161 -0
  141. package/src/service-adapters/service-adapter.ts +30 -0
  142. package/src/service-adapters/unify/unify-adapter.ts +145 -0
  143. package/src/utils/failed-response-status-reasons.ts +48 -0
  144. package/src/utils/index.ts +1 -0
  145. package/tsconfig.json +11 -0
  146. package/tsup.config.ts +16 -0
  147. package/typedoc.json +4 -0
@@ -0,0 +1,109 @@
1
+ import { YogaInitialContext } from "graphql-yoga";
2
+ import { buildSchemaSync } from "type-graphql";
3
+ import { CopilotResolver } from "../../graphql/resolvers/copilot.resolver";
4
+ import { useDeferStream } from "@graphql-yoga/plugin-defer-stream";
5
+ import { CopilotRuntime } from "../runtime/copilot-runtime";
6
+ import { CopilotServiceAdapter } from "../../service-adapters";
7
+ import { CopilotCloudOptions } from "../cloud";
8
+ import { LogLevel, createLogger } from "../../lib/logger";
9
+ import { createYoga } from "graphql-yoga";
10
+ import telemetry from "../telemetry-client";
11
+
12
+ const logger = createLogger();
13
+
14
+ type AnyPrimitive = string | boolean | number | null;
15
+ export type CopilotRequestContextProperties = Record<
16
+ string,
17
+ AnyPrimitive | Record<string, AnyPrimitive>
18
+ >;
19
+
20
+ export type GraphQLContext = YogaInitialContext & {
21
+ _copilotkit: CreateCopilotRuntimeServerOptions;
22
+ properties: CopilotRequestContextProperties;
23
+ logger: typeof logger;
24
+ };
25
+
26
+ export interface CreateCopilotRuntimeServerOptions {
27
+ runtime: CopilotRuntime<any>;
28
+ serviceAdapter: CopilotServiceAdapter;
29
+ endpoint: string;
30
+ baseUrl?: string;
31
+ cloud?: CopilotCloudOptions;
32
+ properties?: CopilotRequestContextProperties;
33
+ logLevel?: LogLevel;
34
+ }
35
+
36
+ export async function createContext(
37
+ initialContext: YogaInitialContext,
38
+ copilotKitContext: CreateCopilotRuntimeServerOptions,
39
+ contextLogger: typeof logger,
40
+ properties: CopilotRequestContextProperties = {},
41
+ ): Promise<Partial<GraphQLContext>> {
42
+ logger.debug({ copilotKitContext }, "Creating GraphQL context");
43
+ const ctx: GraphQLContext = {
44
+ ...initialContext,
45
+ _copilotkit: {
46
+ ...copilotKitContext,
47
+ },
48
+ properties: { ...properties },
49
+ logger: contextLogger,
50
+ };
51
+ return ctx;
52
+ }
53
+
54
+ export function buildSchema(
55
+ options: {
56
+ emitSchemaFile?: string;
57
+ } = {},
58
+ ) {
59
+ logger.debug("Building GraphQL schema...");
60
+ const schema = buildSchemaSync({
61
+ resolvers: [CopilotResolver],
62
+ emitSchemaFile: options.emitSchemaFile,
63
+ });
64
+ logger.debug("GraphQL schema built successfully");
65
+ return schema;
66
+ }
67
+
68
+ export type CommonConfig = {
69
+ logging: typeof logger;
70
+ schema: ReturnType<typeof buildSchema>;
71
+ plugins: Parameters<typeof createYoga>[0]["plugins"];
72
+ context: (ctx: YogaInitialContext) => Promise<Partial<GraphQLContext>>;
73
+ };
74
+
75
+ export function getCommonConfig(options: CreateCopilotRuntimeServerOptions): CommonConfig {
76
+ const logLevel = (process.env.LOG_LEVEL as LogLevel) || (options.logLevel as LogLevel) || "error";
77
+ const logger = createLogger({ level: logLevel, component: "getCommonConfig" });
78
+
79
+ const contextLogger = createLogger({ level: logLevel });
80
+
81
+ if (options.cloud) {
82
+ telemetry.setCloudConfiguration({
83
+ publicApiKey: options.cloud.publicApiKey,
84
+ baseUrl: options.cloud.baseUrl,
85
+ });
86
+ }
87
+
88
+ if (options.properties?._copilotkit) {
89
+ telemetry.setGlobalProperties({
90
+ _copilotkit: {
91
+ ...(options.properties._copilotkit as Record<string, any>),
92
+ },
93
+ });
94
+ }
95
+
96
+ telemetry.setGlobalProperties({
97
+ runtime: {
98
+ serviceAdapter: options.serviceAdapter.constructor.name,
99
+ },
100
+ });
101
+
102
+ return {
103
+ logging: createLogger({ component: "Yoga GraphQL", level: logLevel }),
104
+ schema: buildSchema(),
105
+ plugins: [useDeferStream()],
106
+ context: (ctx: YogaInitialContext): Promise<Partial<GraphQLContext>> =>
107
+ createContext(ctx, options, contextLogger, options.properties),
108
+ };
109
+ }
@@ -0,0 +1,28 @@
1
+ import createPinoLogger from "pino";
2
+ import pretty from "pino-pretty";
3
+
4
+ export type LogLevel = "debug" | "info" | "warn" | "error";
5
+
6
+ export type CopilotRuntimeLogger = ReturnType<typeof createLogger>;
7
+
8
+ export function createLogger(options?: { level?: LogLevel; component?: string }) {
9
+ const { level, component } = options || {};
10
+ const stream = pretty({ colorize: true });
11
+
12
+ const logger = createPinoLogger(
13
+ {
14
+ level: process.env.LOG_LEVEL || level || "error",
15
+ redact: {
16
+ paths: ["pid", "hostname"],
17
+ remove: true,
18
+ },
19
+ },
20
+ stream,
21
+ );
22
+
23
+ if (component) {
24
+ return logger.child({ component });
25
+ } else {
26
+ return logger;
27
+ }
28
+ }
@@ -0,0 +1,466 @@
1
+ /**
2
+ * <Callout type="info">
3
+ * This is the reference for the `CopilotRuntime` class. For more information and example code snippets, please see [Concept: Copilot Runtime](/concepts/copilot-runtime).
4
+ * </Callout>
5
+ *
6
+ * ## Usage
7
+ *
8
+ * ```tsx
9
+ * import { CopilotRuntime } from "@copilotkit/runtime";
10
+ *
11
+ * const copilotKit = new CopilotRuntime();
12
+ * ```
13
+ */
14
+
15
+ import { Action, actionParametersToJsonSchema, Parameter, randomId } from "@copilotkit/shared";
16
+ import { CopilotServiceAdapter, RemoteChain, RemoteChainParameters } from "../../service-adapters";
17
+ import { MessageInput } from "../../graphql/inputs/message.input";
18
+ import { ActionInput } from "../../graphql/inputs/action.input";
19
+ import { RuntimeEventSource } from "../../service-adapters/events";
20
+ import { convertGqlInputToMessages } from "../../service-adapters/conversion";
21
+ import { Message } from "../../graphql/types/converted";
22
+ import { ForwardedParametersInput } from "../../graphql/inputs/forwarded-parameters.input";
23
+ import {
24
+ isLangGraphAgentAction,
25
+ LangGraphAgentAction,
26
+ EndpointType,
27
+ setupRemoteActions,
28
+ EndpointDefinition,
29
+ CopilotKitEndpoint,
30
+ LangGraphPlatformEndpoint,
31
+ } from "./remote-actions";
32
+ import { GraphQLContext } from "../integrations/shared";
33
+ import { AgentSessionInput } from "../../graphql/inputs/agent-session.input";
34
+ import { from } from "rxjs";
35
+ import { AgentStateInput } from "../../graphql/inputs/agent-state.input";
36
+ import { ActionInputAvailability } from "../../graphql/types/enums";
37
+ import { createHeaders } from "./remote-action-constructors";
38
+ import { Agent } from "../../graphql/types/agents-response.type";
39
+
40
+ interface CopilotRuntimeRequest {
41
+ serviceAdapter: CopilotServiceAdapter;
42
+ messages: MessageInput[];
43
+ actions: ActionInput[];
44
+ agentSession?: AgentSessionInput;
45
+ agentStates?: AgentStateInput[];
46
+ outputMessagesPromise: Promise<Message[]>;
47
+ threadId?: string;
48
+ runId?: string;
49
+ publicApiKey?: string;
50
+ graphqlContext: GraphQLContext;
51
+ forwardedParameters?: ForwardedParametersInput;
52
+ url?: string;
53
+ }
54
+
55
+ interface CopilotRuntimeResponse {
56
+ threadId: string;
57
+ runId?: string;
58
+ eventSource: RuntimeEventSource;
59
+ serverSideActions: Action<any>[];
60
+ actionInputsWithoutAgents: ActionInput[];
61
+ }
62
+
63
+ type ActionsConfiguration<T extends Parameter[] | [] = []> =
64
+ | Action<T>[]
65
+ | ((ctx: { properties: any; url?: string }) => Action<T>[]);
66
+
67
+ interface OnBeforeRequestOptions {
68
+ threadId?: string;
69
+ runId?: string;
70
+ inputMessages: Message[];
71
+ properties: any;
72
+ url?: string;
73
+ }
74
+
75
+ type OnBeforeRequestHandler = (options: OnBeforeRequestOptions) => void | Promise<void>;
76
+
77
+ interface OnAfterRequestOptions {
78
+ threadId: string;
79
+ runId?: string;
80
+ inputMessages: Message[];
81
+ outputMessages: Message[];
82
+ properties: any;
83
+ url?: string;
84
+ }
85
+
86
+ type OnAfterRequestHandler = (options: OnAfterRequestOptions) => void | Promise<void>;
87
+
88
+ interface Middleware {
89
+ /**
90
+ * A function that is called before the request is processed.
91
+ */
92
+ onBeforeRequest?: OnBeforeRequestHandler;
93
+
94
+ /**
95
+ * A function that is called after the request is processed.
96
+ */
97
+ onAfterRequest?: OnAfterRequestHandler;
98
+ }
99
+
100
+ export interface CopilotRuntimeConstructorParams<T extends Parameter[] | [] = []> {
101
+ /**
102
+ * Middleware to be used by the runtime.
103
+ *
104
+ * ```ts
105
+ * onBeforeRequest: (options: {
106
+ * threadId?: string;
107
+ * runId?: string;
108
+ * inputMessages: Message[];
109
+ * properties: any;
110
+ * }) => void | Promise<void>;
111
+ * ```
112
+ *
113
+ * ```ts
114
+ * onAfterRequest: (options: {
115
+ * threadId?: string;
116
+ * runId?: string;
117
+ * inputMessages: Message[];
118
+ * outputMessages: Message[];
119
+ * properties: any;
120
+ * }) => void | Promise<void>;
121
+ * ```
122
+ */
123
+ middleware?: Middleware;
124
+
125
+ /*
126
+ * A list of server side actions that can be executed.
127
+ */
128
+ actions?: ActionsConfiguration<T>;
129
+
130
+ /*
131
+ * Deprecated: Use `remoteEndpoints`.
132
+ */
133
+ remoteActions?: CopilotKitEndpoint[];
134
+
135
+ /*
136
+ * A list of remote actions that can be executed.
137
+ */
138
+ remoteEndpoints?: EndpointDefinition[];
139
+
140
+ /*
141
+ * An array of LangServer URLs.
142
+ */
143
+ langserve?: RemoteChainParameters[];
144
+ }
145
+
146
+ export class CopilotRuntime<const T extends Parameter[] | [] = []> {
147
+ public actions: ActionsConfiguration<T>;
148
+ public remoteEndpointDefinitions: EndpointDefinition[];
149
+ private langserve: Promise<Action<any>>[] = [];
150
+ private onBeforeRequest?: OnBeforeRequestHandler;
151
+ private onAfterRequest?: OnAfterRequestHandler;
152
+
153
+ constructor(params?: CopilotRuntimeConstructorParams<T>) {
154
+ this.actions = params?.actions || [];
155
+
156
+ for (const chain of params?.langserve || []) {
157
+ const remoteChain = new RemoteChain(chain);
158
+ this.langserve.push(remoteChain.toAction());
159
+ }
160
+
161
+ this.remoteEndpointDefinitions = params?.remoteEndpoints ?? params?.remoteActions ?? [];
162
+
163
+ this.onBeforeRequest = params?.middleware?.onBeforeRequest;
164
+ this.onAfterRequest = params?.middleware?.onAfterRequest;
165
+ }
166
+
167
+ async processRuntimeRequest(request: CopilotRuntimeRequest): Promise<CopilotRuntimeResponse> {
168
+ const {
169
+ serviceAdapter,
170
+ messages: rawMessages,
171
+ actions: clientSideActionsInput,
172
+ threadId,
173
+ runId,
174
+ outputMessagesPromise,
175
+ graphqlContext,
176
+ forwardedParameters,
177
+ agentSession,
178
+ url,
179
+ } = request;
180
+
181
+ const eventSource = new RuntimeEventSource();
182
+
183
+ try {
184
+ if (agentSession) {
185
+ return await this.processAgentRequest(request);
186
+ }
187
+
188
+ const messages = rawMessages.filter((message) => !message.agentStateMessage);
189
+
190
+ const inputMessages = convertGqlInputToMessages(messages);
191
+ const serverSideActions = await this.getServerSideActions(request);
192
+
193
+ const serverSideActionsInput: ActionInput[] = serverSideActions.map((action) => ({
194
+ name: action.name,
195
+ description: action.description,
196
+ jsonSchema: JSON.stringify(actionParametersToJsonSchema(action.parameters)),
197
+ }));
198
+
199
+ const actionInputs = flattenToolCallsNoDuplicates([
200
+ ...serverSideActionsInput,
201
+ ...clientSideActionsInput.filter(
202
+ // Filter remote actions from CopilotKit core loop
203
+ (action) => action.available !== ActionInputAvailability.remote,
204
+ ),
205
+ ]);
206
+
207
+ await this.onBeforeRequest?.({
208
+ threadId,
209
+ runId,
210
+ inputMessages,
211
+ properties: graphqlContext.properties,
212
+ url,
213
+ });
214
+
215
+ const result = await serviceAdapter.process({
216
+ messages: inputMessages,
217
+ actions: actionInputs,
218
+ threadId,
219
+ runId,
220
+ eventSource,
221
+ forwardedParameters,
222
+ });
223
+
224
+ outputMessagesPromise
225
+ .then((outputMessages) => {
226
+ this.onAfterRequest?.({
227
+ threadId: result.threadId,
228
+ runId: result.runId,
229
+ inputMessages,
230
+ outputMessages,
231
+ properties: graphqlContext.properties,
232
+ url,
233
+ });
234
+ })
235
+ .catch((_error) => {});
236
+
237
+ return {
238
+ threadId: result.threadId,
239
+ runId: result.runId,
240
+ eventSource,
241
+ serverSideActions,
242
+ actionInputsWithoutAgents: actionInputs.filter(
243
+ (action) =>
244
+ // TODO-AGENTS: do not exclude ALL server side actions
245
+ !serverSideActions.find((serverSideAction) => serverSideAction.name == action.name),
246
+ // !isLangGraphAgentAction(
247
+ // serverSideActions.find((serverSideAction) => serverSideAction.name == action.name),
248
+ // ),
249
+ ),
250
+ };
251
+ } catch (error) {
252
+ console.error("Error getting response:", error);
253
+ eventSource.sendErrorMessageToChat();
254
+ throw error;
255
+ }
256
+ }
257
+
258
+ async discoverAgentsFromEndpoints(graphqlContext: GraphQLContext): Promise<Agent[]> {
259
+ const headers = createHeaders(null, graphqlContext);
260
+ const agents = this.remoteEndpointDefinitions.reduce(
261
+ async (acc: Promise<Agent[]>, endpoint) => {
262
+ const agents = await acc;
263
+ if (endpoint.type === EndpointType.LangGraphPlatform) {
264
+ const response = await fetch(
265
+ `${(endpoint as LangGraphPlatformEndpoint).deploymentUrl}/assistants/search`,
266
+ {
267
+ method: "POST",
268
+ headers,
269
+ },
270
+ );
271
+
272
+ const data: Array<{ assistant_id: string; graph_id: string }> = await response.json();
273
+ const endpointAgents = (data ?? []).map((entry) => ({
274
+ name: entry.graph_id,
275
+ id: entry.assistant_id,
276
+ }));
277
+ return [...agents, ...endpointAgents];
278
+ }
279
+
280
+ interface InfoResponse {
281
+ agents?: Array<{
282
+ name: string;
283
+ description: string;
284
+ }>;
285
+ }
286
+
287
+ const response = await fetch(`${(endpoint as CopilotKitEndpoint).url}/info`, {
288
+ method: "POST",
289
+ headers,
290
+ body: JSON.stringify({ properties: graphqlContext.properties }),
291
+ });
292
+ const data: InfoResponse = await response.json();
293
+ const endpointAgents = (data?.agents ?? []).map((agent) => ({
294
+ name: agent.name,
295
+ description: agent.description,
296
+ id: randomId(), // Required by Agent type
297
+ }));
298
+ return [...agents, ...endpointAgents];
299
+ },
300
+ Promise.resolve([]),
301
+ );
302
+
303
+ return agents;
304
+ }
305
+
306
+ private async processAgentRequest(
307
+ request: CopilotRuntimeRequest,
308
+ ): Promise<CopilotRuntimeResponse> {
309
+ const { messages: rawMessages, outputMessagesPromise, graphqlContext, agentSession } = request;
310
+ const { threadId, agentName, nodeName } = agentSession;
311
+ const serverSideActions = await this.getServerSideActions(request);
312
+
313
+ const messages = convertGqlInputToMessages(rawMessages);
314
+
315
+ const agent = serverSideActions.find(
316
+ (action) => action.name === agentName && isLangGraphAgentAction(action),
317
+ ) as LangGraphAgentAction;
318
+
319
+ if (!agent) {
320
+ throw new Error(`Agent ${agentName} not found`);
321
+ }
322
+
323
+ const serverSideActionsInput: ActionInput[] = serverSideActions
324
+ .filter((action) => !isLangGraphAgentAction(action))
325
+ .map((action) => ({
326
+ name: action.name,
327
+ description: action.description,
328
+ jsonSchema: JSON.stringify(actionParametersToJsonSchema(action.parameters)),
329
+ }));
330
+
331
+ const actionInputsWithoutAgents = flattenToolCallsNoDuplicates([
332
+ ...serverSideActionsInput,
333
+ ...request.actions,
334
+ ]);
335
+
336
+ await this.onBeforeRequest?.({
337
+ threadId,
338
+ runId: undefined,
339
+ inputMessages: messages,
340
+ properties: graphqlContext.properties,
341
+ });
342
+ try {
343
+ const eventSource = new RuntimeEventSource();
344
+ const stream = await agent.langGraphAgentHandler({
345
+ name: agentName,
346
+ threadId,
347
+ nodeName,
348
+ actionInputsWithoutAgents,
349
+ });
350
+
351
+ eventSource.stream(async (eventStream$) => {
352
+ from(stream).subscribe({
353
+ next: (event) => eventStream$.next(event),
354
+ error: (err) => {
355
+ console.error("Error in stream", err);
356
+ eventStream$.error(err);
357
+ eventStream$.complete();
358
+ },
359
+ complete: () => eventStream$.complete(),
360
+ });
361
+ });
362
+
363
+ outputMessagesPromise
364
+ .then((outputMessages) => {
365
+ this.onAfterRequest?.({
366
+ threadId,
367
+ runId: undefined,
368
+ inputMessages: messages,
369
+ outputMessages,
370
+ properties: graphqlContext.properties,
371
+ });
372
+ })
373
+ .catch((_error) => {});
374
+
375
+ return {
376
+ threadId,
377
+ runId: undefined,
378
+ eventSource,
379
+ serverSideActions: [],
380
+ actionInputsWithoutAgents,
381
+ };
382
+ } catch (error) {
383
+ console.error("Error getting response:", error);
384
+ throw error;
385
+ }
386
+ }
387
+
388
+ private async getServerSideActions(request: CopilotRuntimeRequest): Promise<Action<any>[]> {
389
+ const { messages: rawMessages, graphqlContext, agentStates, url } = request;
390
+ const inputMessages = convertGqlInputToMessages(rawMessages);
391
+ const langserveFunctions: Action<any>[] = [];
392
+
393
+ for (const chainPromise of this.langserve) {
394
+ try {
395
+ const chain = await chainPromise;
396
+ langserveFunctions.push(chain);
397
+ } catch (error) {
398
+ console.error("Error loading langserve chain:", error);
399
+ }
400
+ }
401
+
402
+ const remoteEndpointDefinitions = this.remoteEndpointDefinitions.map(
403
+ (endpoint) =>
404
+ ({
405
+ ...endpoint,
406
+ type: resolveEndpointType(endpoint),
407
+ }) as EndpointDefinition,
408
+ );
409
+
410
+ const remoteActions = await setupRemoteActions({
411
+ remoteEndpointDefinitions,
412
+ graphqlContext,
413
+ messages: inputMessages,
414
+ agentStates,
415
+ frontendUrl: url,
416
+ });
417
+
418
+ const configuredActions =
419
+ typeof this.actions === "function"
420
+ ? this.actions({ properties: graphqlContext.properties, url })
421
+ : this.actions;
422
+
423
+ return [...configuredActions, ...langserveFunctions, ...remoteActions];
424
+ }
425
+ }
426
+
427
+ export function flattenToolCallsNoDuplicates(toolsByPriority: ActionInput[]): ActionInput[] {
428
+ let allTools: ActionInput[] = [];
429
+ const allToolNames: string[] = [];
430
+ for (const tool of toolsByPriority) {
431
+ if (!allToolNames.includes(tool.name)) {
432
+ allTools.push(tool);
433
+ allToolNames.push(tool.name);
434
+ }
435
+ }
436
+ return allTools;
437
+ }
438
+
439
+ // The two functions below are "factory functions", meant to create the action objects that adhere to the expected interfaces
440
+ export function copilotKitEndpoint(config: Omit<CopilotKitEndpoint, "type">): CopilotKitEndpoint {
441
+ return {
442
+ ...config,
443
+ type: EndpointType.CopilotKit,
444
+ };
445
+ }
446
+
447
+ export function langGraphPlatformEndpoint(
448
+ config: Omit<LangGraphPlatformEndpoint, "type">,
449
+ ): LangGraphPlatformEndpoint {
450
+ return {
451
+ ...config,
452
+ type: EndpointType.LangGraphPlatform,
453
+ };
454
+ }
455
+
456
+ export function resolveEndpointType(endpoint: EndpointDefinition) {
457
+ if (!endpoint.type) {
458
+ if ("langsmithApiKey" in endpoint && "deploymentUrl" in endpoint && "agents" in endpoint) {
459
+ return EndpointType.LangGraphPlatform;
460
+ } else {
461
+ return EndpointType.CopilotKit;
462
+ }
463
+ }
464
+
465
+ return endpoint.type;
466
+ }