@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.
- package/.eslintrc.js +7 -0
- package/CHANGELOG.md +913 -0
- package/README.md +46 -0
- package/__snapshots__/schema/schema.graphql +273 -0
- package/dist/chunk-44O2JGUY.mjs +12 -0
- package/dist/chunk-44O2JGUY.mjs.map +1 -0
- package/dist/chunk-BETLEV37.mjs +25 -0
- package/dist/chunk-BETLEV37.mjs.map +1 -0
- package/dist/chunk-CLGKEUOA.mjs +1408 -0
- package/dist/chunk-CLGKEUOA.mjs.map +1 -0
- package/dist/chunk-D2WLFQS6.mjs +43 -0
- package/dist/chunk-D2WLFQS6.mjs.map +1 -0
- package/dist/chunk-DFOKBSIS.mjs +1 -0
- package/dist/chunk-DFOKBSIS.mjs.map +1 -0
- package/dist/chunk-FA5DJ2TZ.mjs +3437 -0
- package/dist/chunk-FA5DJ2TZ.mjs.map +1 -0
- package/dist/chunk-HNUNXFTW.mjs +129 -0
- package/dist/chunk-HNUNXFTW.mjs.map +1 -0
- package/dist/chunk-SFLMY3ES.mjs +80 -0
- package/dist/chunk-SFLMY3ES.mjs.map +1 -0
- package/dist/chunk-U3V2BCGI.mjs +152 -0
- package/dist/chunk-U3V2BCGI.mjs.map +1 -0
- package/dist/chunk-ZCU6UPCY.mjs +25 -0
- package/dist/chunk-ZCU6UPCY.mjs.map +1 -0
- package/dist/copilot-runtime-1a224a0f.d.ts +196 -0
- package/dist/graphql/types/base/index.d.ts +6 -0
- package/dist/graphql/types/base/index.js +63 -0
- package/dist/graphql/types/base/index.js.map +1 -0
- package/dist/graphql/types/base/index.mjs +8 -0
- package/dist/graphql/types/base/index.mjs.map +1 -0
- package/dist/graphql/types/converted/index.d.ts +2 -0
- package/dist/graphql/types/converted/index.js +187 -0
- package/dist/graphql/types/converted/index.js.map +1 -0
- package/dist/graphql/types/converted/index.mjs +17 -0
- package/dist/graphql/types/converted/index.mjs.map +1 -0
- package/dist/groq-adapter-c35c5374.d.ts +281 -0
- package/dist/index-24315d90.d.ts +103 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.js +5258 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +76 -0
- package/dist/index.mjs.map +1 -0
- package/dist/langserve-a16ef8f4.d.ts +180 -0
- package/dist/lib/cloud/index.d.ts +6 -0
- package/dist/lib/cloud/index.js +18 -0
- package/dist/lib/cloud/index.js.map +1 -0
- package/dist/lib/cloud/index.mjs +1 -0
- package/dist/lib/cloud/index.mjs.map +1 -0
- package/dist/lib/index.d.ts +20 -0
- package/dist/lib/index.js +4906 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/lib/index.mjs +58 -0
- package/dist/lib/index.mjs.map +1 -0
- package/dist/lib/integrations/index.d.ts +33 -0
- package/dist/lib/integrations/index.js +2229 -0
- package/dist/lib/integrations/index.js.map +1 -0
- package/dist/lib/integrations/index.mjs +34 -0
- package/dist/lib/integrations/index.mjs.map +1 -0
- package/dist/lib/integrations/nest/index.d.ts +14 -0
- package/dist/lib/integrations/nest/index.js +2138 -0
- package/dist/lib/integrations/nest/index.js.map +1 -0
- package/dist/lib/integrations/nest/index.mjs +13 -0
- package/dist/lib/integrations/nest/index.mjs.map +1 -0
- package/dist/lib/integrations/node-express/index.d.ts +14 -0
- package/dist/lib/integrations/node-express/index.js +2138 -0
- package/dist/lib/integrations/node-express/index.js.map +1 -0
- package/dist/lib/integrations/node-express/index.mjs +13 -0
- package/dist/lib/integrations/node-express/index.mjs.map +1 -0
- package/dist/lib/integrations/node-http/index.d.ts +14 -0
- package/dist/lib/integrations/node-http/index.js +2124 -0
- package/dist/lib/integrations/node-http/index.js.map +1 -0
- package/dist/lib/integrations/node-http/index.mjs +12 -0
- package/dist/lib/integrations/node-http/index.mjs.map +1 -0
- package/dist/service-adapters/index.d.ts +84 -0
- package/dist/service-adapters/index.js +1448 -0
- package/dist/service-adapters/index.js.map +1 -0
- package/dist/service-adapters/index.mjs +26 -0
- package/dist/service-adapters/index.mjs.map +1 -0
- package/dist/utils/index.d.ts +49 -0
- package/dist/utils/index.js +174 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/index.mjs +12 -0
- package/dist/utils/index.mjs.map +1 -0
- package/jest.config.js +5 -0
- package/package.json +85 -0
- package/scripts/generate-gql-schema.ts +13 -0
- package/src/agents/langgraph/event-source.ts +287 -0
- package/src/agents/langgraph/events.ts +338 -0
- package/src/graphql/inputs/action.input.ts +16 -0
- package/src/graphql/inputs/agent-session.input.ts +13 -0
- package/src/graphql/inputs/agent-state.input.ts +10 -0
- package/src/graphql/inputs/cloud-guardrails.input.ts +16 -0
- package/src/graphql/inputs/cloud.input.ts +8 -0
- package/src/graphql/inputs/context-property.input.ts +10 -0
- package/src/graphql/inputs/custom-property.input.ts +15 -0
- package/src/graphql/inputs/forwarded-parameters.input.ts +22 -0
- package/src/graphql/inputs/frontend.input.ts +14 -0
- package/src/graphql/inputs/generate-copilot-response.input.ts +47 -0
- package/src/graphql/inputs/message.input.ts +92 -0
- package/src/graphql/resolvers/copilot.resolver.ts +556 -0
- package/src/graphql/types/agents-response.type.ts +22 -0
- package/src/graphql/types/base/index.ts +10 -0
- package/src/graphql/types/converted/index.ts +136 -0
- package/src/graphql/types/copilot-response.type.ts +113 -0
- package/src/graphql/types/enums.ts +37 -0
- package/src/graphql/types/guardrails-result.type.ts +20 -0
- package/src/graphql/types/message-status.type.ts +40 -0
- package/src/graphql/types/response-status.type.ts +66 -0
- package/src/index.ts +4 -0
- package/src/lib/cloud/index.ts +4 -0
- package/src/lib/index.ts +8 -0
- package/src/lib/integrations/index.ts +6 -0
- package/src/lib/integrations/nest/index.ts +17 -0
- package/src/lib/integrations/nextjs/app-router.ts +40 -0
- package/src/lib/integrations/nextjs/pages-router.ts +49 -0
- package/src/lib/integrations/node-express/index.ts +17 -0
- package/src/lib/integrations/node-http/index.ts +34 -0
- package/src/lib/integrations/shared.ts +109 -0
- package/src/lib/logger.ts +28 -0
- package/src/lib/runtime/copilot-runtime.ts +466 -0
- package/src/lib/runtime/remote-action-constructors.ts +304 -0
- package/src/lib/runtime/remote-actions.ts +174 -0
- package/src/lib/runtime/remote-lg-action.ts +657 -0
- package/src/lib/telemetry-client.ts +52 -0
- package/src/service-adapters/anthropic/anthropic-adapter.ts +205 -0
- package/src/service-adapters/anthropic/utils.ts +144 -0
- package/src/service-adapters/conversion.ts +64 -0
- package/src/service-adapters/events.ts +419 -0
- package/src/service-adapters/experimental/empty/empty-adapter.ts +33 -0
- package/src/service-adapters/experimental/ollama/ollama-adapter.ts +79 -0
- package/src/service-adapters/google/google-genai-adapter.ts +39 -0
- package/src/service-adapters/groq/groq-adapter.ts +173 -0
- package/src/service-adapters/index.ts +16 -0
- package/src/service-adapters/langchain/langchain-adapter.ts +99 -0
- package/src/service-adapters/langchain/langserve.ts +87 -0
- package/src/service-adapters/langchain/types.ts +14 -0
- package/src/service-adapters/langchain/utils.ts +306 -0
- package/src/service-adapters/openai/openai-adapter.ts +210 -0
- package/src/service-adapters/openai/openai-assistant-adapter.ts +304 -0
- package/src/service-adapters/openai/utils.ts +161 -0
- package/src/service-adapters/service-adapter.ts +30 -0
- package/src/service-adapters/unify/unify-adapter.ts +145 -0
- package/src/utils/failed-response-status-reasons.ts +48 -0
- package/src/utils/index.ts +1 -0
- package/tsconfig.json +11 -0
- package/tsup.config.ts +16 -0
- package/typedoc.json +4 -0
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import {
|
|
3
|
+
CopilotKitEndpoint,
|
|
4
|
+
LangGraphAgentHandlerParams,
|
|
5
|
+
RemoteActionInfoResponse,
|
|
6
|
+
LangGraphPlatformEndpoint,
|
|
7
|
+
} from "./remote-actions";
|
|
8
|
+
import { GraphQLContext } from "../integrations";
|
|
9
|
+
import { Logger } from "pino";
|
|
10
|
+
import { Message } from "../../graphql/types/converted";
|
|
11
|
+
import { AgentStateInput } from "../../graphql/inputs/agent-state.input";
|
|
12
|
+
import { Observable, ReplaySubject } from "rxjs";
|
|
13
|
+
import { RuntimeEvent } from "../../service-adapters/events";
|
|
14
|
+
import telemetry from "../telemetry-client";
|
|
15
|
+
import { RemoteLangGraphEventSource } from "../../agents/langgraph/event-source";
|
|
16
|
+
import { Action } from "@copilotkit/shared";
|
|
17
|
+
import { LangGraphEvent } from "../../agents/langgraph/events";
|
|
18
|
+
import { execute } from "./remote-lg-action";
|
|
19
|
+
|
|
20
|
+
export function constructLGCRemoteAction({
|
|
21
|
+
endpoint,
|
|
22
|
+
graphqlContext,
|
|
23
|
+
logger,
|
|
24
|
+
messages,
|
|
25
|
+
agentStates,
|
|
26
|
+
}: {
|
|
27
|
+
endpoint: LangGraphPlatformEndpoint;
|
|
28
|
+
graphqlContext: GraphQLContext;
|
|
29
|
+
logger: Logger;
|
|
30
|
+
messages: Message[];
|
|
31
|
+
agentStates?: AgentStateInput[];
|
|
32
|
+
}) {
|
|
33
|
+
const agents = endpoint.agents.map((agent) => ({
|
|
34
|
+
name: agent.name,
|
|
35
|
+
description: agent.description,
|
|
36
|
+
parameters: [],
|
|
37
|
+
handler: async (_args: any) => {},
|
|
38
|
+
langGraphAgentHandler: async ({
|
|
39
|
+
name,
|
|
40
|
+
actionInputsWithoutAgents,
|
|
41
|
+
threadId,
|
|
42
|
+
nodeName,
|
|
43
|
+
additionalMessages = [],
|
|
44
|
+
}: LangGraphAgentHandlerParams): Promise<Observable<RuntimeEvent>> => {
|
|
45
|
+
logger.debug({ actionName: agent.name }, "Executing LangGraph Platform agent");
|
|
46
|
+
|
|
47
|
+
telemetry.capture("oss.runtime.remote_action_executed", {
|
|
48
|
+
agentExecution: true,
|
|
49
|
+
type: "langgraph-platform",
|
|
50
|
+
agentsAmount: endpoint.agents.length,
|
|
51
|
+
hashedLgcKey: createHash("sha256").update(endpoint.langsmithApiKey).digest("hex"),
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
let state = {};
|
|
55
|
+
if (agentStates) {
|
|
56
|
+
const jsonState = agentStates.find((state) => state.agentName === name)?.state;
|
|
57
|
+
if (jsonState) {
|
|
58
|
+
state = JSON.parse(jsonState);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
try {
|
|
63
|
+
const response = await execute({
|
|
64
|
+
logger,
|
|
65
|
+
deploymentUrl: endpoint.deploymentUrl,
|
|
66
|
+
langsmithApiKey: endpoint.langsmithApiKey,
|
|
67
|
+
agent,
|
|
68
|
+
threadId,
|
|
69
|
+
nodeName,
|
|
70
|
+
messages: [...messages, ...additionalMessages],
|
|
71
|
+
state,
|
|
72
|
+
properties: graphqlContext.properties,
|
|
73
|
+
actions: actionInputsWithoutAgents.map((action) => ({
|
|
74
|
+
name: action.name,
|
|
75
|
+
description: action.description,
|
|
76
|
+
parameters: JSON.parse(action.jsonSchema) as string,
|
|
77
|
+
})),
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
const eventSource = new RemoteLangGraphEventSource();
|
|
81
|
+
streamResponse(response, eventSource.eventStream$);
|
|
82
|
+
return eventSource.processLangGraphEvents();
|
|
83
|
+
} catch (error) {
|
|
84
|
+
logger.error(
|
|
85
|
+
{ url: endpoint.deploymentUrl, status: 500, body: error.message },
|
|
86
|
+
"Failed to execute LangGraph Platform agent",
|
|
87
|
+
);
|
|
88
|
+
throw new Error("Failed to execute LangGraph Platform agent");
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
}));
|
|
92
|
+
|
|
93
|
+
return [...agents];
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export function constructRemoteActions({
|
|
97
|
+
json,
|
|
98
|
+
url,
|
|
99
|
+
onBeforeRequest,
|
|
100
|
+
graphqlContext,
|
|
101
|
+
logger,
|
|
102
|
+
messages,
|
|
103
|
+
agentStates,
|
|
104
|
+
}: {
|
|
105
|
+
json: RemoteActionInfoResponse;
|
|
106
|
+
url: string;
|
|
107
|
+
onBeforeRequest?: CopilotKitEndpoint["onBeforeRequest"];
|
|
108
|
+
graphqlContext: GraphQLContext;
|
|
109
|
+
logger: Logger;
|
|
110
|
+
messages: Message[];
|
|
111
|
+
agentStates?: AgentStateInput[];
|
|
112
|
+
}): Action<any>[] {
|
|
113
|
+
const totalAgents = Array.isArray(json["agents"]) ? json["agents"].length : 0;
|
|
114
|
+
|
|
115
|
+
const actions = json["actions"].map((action) => ({
|
|
116
|
+
name: action.name,
|
|
117
|
+
description: action.description,
|
|
118
|
+
parameters: action.parameters,
|
|
119
|
+
handler: async (args: any) => {
|
|
120
|
+
logger.debug({ actionName: action.name, args }, "Executing remote action");
|
|
121
|
+
|
|
122
|
+
const headers = createHeaders(onBeforeRequest, graphqlContext);
|
|
123
|
+
telemetry.capture("oss.runtime.remote_action_executed", {
|
|
124
|
+
agentExecution: false,
|
|
125
|
+
type: "self-hosted",
|
|
126
|
+
agentsAmount: totalAgents,
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
try {
|
|
130
|
+
const response = await fetch(`${url}/actions/execute`, {
|
|
131
|
+
method: "POST",
|
|
132
|
+
headers,
|
|
133
|
+
body: JSON.stringify({
|
|
134
|
+
name: action.name,
|
|
135
|
+
arguments: args,
|
|
136
|
+
properties: graphqlContext.properties,
|
|
137
|
+
}),
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
if (!response.ok) {
|
|
141
|
+
logger.error(
|
|
142
|
+
{ url, status: response.status, body: await response.text() },
|
|
143
|
+
"Failed to execute remote action",
|
|
144
|
+
);
|
|
145
|
+
return "Failed to execute remote action";
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const requestResult = await response.json();
|
|
149
|
+
|
|
150
|
+
const result = requestResult["result"];
|
|
151
|
+
logger.debug({ actionName: action.name, result }, "Executed remote action");
|
|
152
|
+
return result;
|
|
153
|
+
} catch (error) {
|
|
154
|
+
logger.error(
|
|
155
|
+
{ error: error.message ? error.message : error + "" },
|
|
156
|
+
"Failed to execute remote action",
|
|
157
|
+
);
|
|
158
|
+
return "Failed to execute remote action";
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
}));
|
|
162
|
+
|
|
163
|
+
const agents = totalAgents
|
|
164
|
+
? json["agents"].map((agent) => ({
|
|
165
|
+
name: agent.name,
|
|
166
|
+
description: agent.description,
|
|
167
|
+
parameters: [],
|
|
168
|
+
handler: async (_args: any) => {},
|
|
169
|
+
|
|
170
|
+
langGraphAgentHandler: async ({
|
|
171
|
+
name,
|
|
172
|
+
actionInputsWithoutAgents,
|
|
173
|
+
threadId,
|
|
174
|
+
nodeName,
|
|
175
|
+
additionalMessages = [],
|
|
176
|
+
}: LangGraphAgentHandlerParams): Promise<Observable<RuntimeEvent>> => {
|
|
177
|
+
logger.debug({ actionName: agent.name }, "Executing remote agent");
|
|
178
|
+
|
|
179
|
+
const headers = createHeaders(onBeforeRequest, graphqlContext);
|
|
180
|
+
telemetry.capture("oss.runtime.remote_action_executed", {
|
|
181
|
+
agentExecution: true,
|
|
182
|
+
type: "self-hosted",
|
|
183
|
+
agentsAmount: json["agents"].length,
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
let state = {};
|
|
187
|
+
if (agentStates) {
|
|
188
|
+
const jsonState = agentStates.find((state) => state.agentName === name)?.state;
|
|
189
|
+
if (jsonState) {
|
|
190
|
+
state = JSON.parse(jsonState);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
const response = await fetch(`${url}/agents/execute`, {
|
|
195
|
+
method: "POST",
|
|
196
|
+
headers,
|
|
197
|
+
body: JSON.stringify({
|
|
198
|
+
name,
|
|
199
|
+
threadId,
|
|
200
|
+
nodeName,
|
|
201
|
+
messages: [...messages, ...additionalMessages],
|
|
202
|
+
state,
|
|
203
|
+
properties: graphqlContext.properties,
|
|
204
|
+
actions: actionInputsWithoutAgents.map((action) => ({
|
|
205
|
+
name: action.name,
|
|
206
|
+
description: action.description,
|
|
207
|
+
parameters: JSON.parse(action.jsonSchema),
|
|
208
|
+
})),
|
|
209
|
+
}),
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
if (!response.ok) {
|
|
213
|
+
logger.error(
|
|
214
|
+
{ url, status: response.status, body: await response.text() },
|
|
215
|
+
"Failed to execute remote agent",
|
|
216
|
+
);
|
|
217
|
+
throw new Error("Failed to execute remote agent");
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
const eventSource = new RemoteLangGraphEventSource();
|
|
221
|
+
streamResponse(response.body!, eventSource.eventStream$);
|
|
222
|
+
return eventSource.processLangGraphEvents();
|
|
223
|
+
},
|
|
224
|
+
}))
|
|
225
|
+
: [];
|
|
226
|
+
|
|
227
|
+
return [...actions, ...agents];
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
async function streamResponse(
|
|
231
|
+
response: ReadableStream<Uint8Array>,
|
|
232
|
+
eventStream$: ReplaySubject<LangGraphEvent>,
|
|
233
|
+
) {
|
|
234
|
+
const reader = response.getReader();
|
|
235
|
+
const decoder = new TextDecoder();
|
|
236
|
+
let buffer = [];
|
|
237
|
+
|
|
238
|
+
function flushBuffer() {
|
|
239
|
+
const currentBuffer = buffer.join("");
|
|
240
|
+
if (currentBuffer.trim().length === 0) {
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
const parts = currentBuffer.split("\n");
|
|
244
|
+
if (parts.length === 0) {
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
const lastPartIsComplete = currentBuffer.endsWith("\n");
|
|
249
|
+
|
|
250
|
+
// truncate buffer
|
|
251
|
+
buffer = [];
|
|
252
|
+
|
|
253
|
+
if (!lastPartIsComplete) {
|
|
254
|
+
// put back the last part
|
|
255
|
+
buffer.push(parts.pop());
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
parts
|
|
259
|
+
.map((part) => part.trim())
|
|
260
|
+
.filter((part) => part != "")
|
|
261
|
+
.forEach((part) => {
|
|
262
|
+
eventStream$.next(JSON.parse(part));
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
try {
|
|
267
|
+
while (true) {
|
|
268
|
+
const { done, value } = await reader.read();
|
|
269
|
+
|
|
270
|
+
if (!done) {
|
|
271
|
+
buffer.push(decoder.decode(value, { stream: true }));
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
flushBuffer();
|
|
275
|
+
|
|
276
|
+
if (done) {
|
|
277
|
+
break;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
} catch (error) {
|
|
281
|
+
console.error("Error in stream", error);
|
|
282
|
+
eventStream$.error(error);
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
eventStream$.complete();
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
export function createHeaders(
|
|
289
|
+
onBeforeRequest: CopilotKitEndpoint["onBeforeRequest"],
|
|
290
|
+
graphqlContext: GraphQLContext,
|
|
291
|
+
) {
|
|
292
|
+
const headers = {
|
|
293
|
+
"Content-Type": "application/json",
|
|
294
|
+
};
|
|
295
|
+
|
|
296
|
+
if (onBeforeRequest) {
|
|
297
|
+
const { headers: additionalHeaders } = onBeforeRequest({ ctx: graphqlContext });
|
|
298
|
+
if (additionalHeaders) {
|
|
299
|
+
Object.assign(headers, additionalHeaders);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
return headers;
|
|
304
|
+
}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { Action } from "@copilotkit/shared";
|
|
2
|
+
import { GraphQLContext } from "../integrations/shared";
|
|
3
|
+
import { Logger } from "pino";
|
|
4
|
+
import { Message } from "../../graphql/types/converted";
|
|
5
|
+
import { RuntimeEvent } from "../../service-adapters/events";
|
|
6
|
+
import { Observable } from "rxjs";
|
|
7
|
+
import { ActionInput } from "../../graphql/inputs/action.input";
|
|
8
|
+
import { AgentStateInput } from "../../graphql/inputs/agent-state.input";
|
|
9
|
+
import {
|
|
10
|
+
constructLGCRemoteAction,
|
|
11
|
+
constructRemoteActions,
|
|
12
|
+
createHeaders,
|
|
13
|
+
} from "./remote-action-constructors";
|
|
14
|
+
|
|
15
|
+
export type EndpointDefinition = CopilotKitEndpoint | LangGraphPlatformEndpoint;
|
|
16
|
+
|
|
17
|
+
export enum EndpointType {
|
|
18
|
+
CopilotKit = "copilotKit",
|
|
19
|
+
LangGraphPlatform = "langgraph-platform",
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface BaseEndpointDefinition<TActionType extends EndpointType> {
|
|
23
|
+
type?: TActionType;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface CopilotKitEndpoint extends BaseEndpointDefinition<EndpointType.CopilotKit> {
|
|
27
|
+
url: string;
|
|
28
|
+
onBeforeRequest?: ({ ctx }: { ctx: GraphQLContext }) => {
|
|
29
|
+
headers?: Record<string, string> | undefined;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface LangGraphPlatformAgent {
|
|
34
|
+
name: string;
|
|
35
|
+
description: string;
|
|
36
|
+
assistantId?: string;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface LangGraphPlatformEndpoint
|
|
40
|
+
extends BaseEndpointDefinition<EndpointType.LangGraphPlatform> {
|
|
41
|
+
deploymentUrl: string;
|
|
42
|
+
langsmithApiKey: string;
|
|
43
|
+
agents: LangGraphPlatformAgent[];
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export type RemoteActionInfoResponse = {
|
|
47
|
+
actions: any[];
|
|
48
|
+
agents: any[];
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export type LangGraphAgentHandlerParams = {
|
|
52
|
+
name: string;
|
|
53
|
+
actionInputsWithoutAgents: ActionInput[];
|
|
54
|
+
threadId?: string;
|
|
55
|
+
nodeName?: string;
|
|
56
|
+
additionalMessages?: Message[];
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export type LangGraphAgentAction = Action<any> & {
|
|
60
|
+
langGraphAgentHandler: (params: LangGraphAgentHandlerParams) => Promise<Observable<RuntimeEvent>>;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export function isLangGraphAgentAction(action: Action<any>): action is LangGraphAgentAction {
|
|
64
|
+
if (!action) {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
return typeof (action as LangGraphAgentAction).langGraphAgentHandler === "function";
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
async function fetchRemoteInfo({
|
|
71
|
+
url,
|
|
72
|
+
onBeforeRequest,
|
|
73
|
+
graphqlContext,
|
|
74
|
+
logger,
|
|
75
|
+
frontendUrl,
|
|
76
|
+
}: {
|
|
77
|
+
url: string;
|
|
78
|
+
onBeforeRequest?: CopilotKitEndpoint["onBeforeRequest"];
|
|
79
|
+
graphqlContext: GraphQLContext;
|
|
80
|
+
logger: Logger;
|
|
81
|
+
frontendUrl?: string;
|
|
82
|
+
}): Promise<RemoteActionInfoResponse> {
|
|
83
|
+
logger.debug({ url }, "Fetching actions from url");
|
|
84
|
+
const headers = createHeaders(onBeforeRequest, graphqlContext);
|
|
85
|
+
|
|
86
|
+
try {
|
|
87
|
+
const response = await fetch(`${url}/info`, {
|
|
88
|
+
method: "POST",
|
|
89
|
+
headers,
|
|
90
|
+
body: JSON.stringify({ properties: graphqlContext.properties, frontendUrl }),
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
if (!response.ok) {
|
|
94
|
+
logger.error(
|
|
95
|
+
{ url, status: response.status, body: await response.text() },
|
|
96
|
+
"Failed to fetch actions from url",
|
|
97
|
+
);
|
|
98
|
+
return { actions: [], agents: [] };
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const json = await response.json();
|
|
102
|
+
logger.debug({ json }, "Fetched actions from url");
|
|
103
|
+
return json;
|
|
104
|
+
} catch (error) {
|
|
105
|
+
logger.error(
|
|
106
|
+
{ error: error.message ? error.message : error + "" },
|
|
107
|
+
"Failed to fetch actions from url",
|
|
108
|
+
);
|
|
109
|
+
return { actions: [], agents: [] };
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export async function setupRemoteActions({
|
|
114
|
+
remoteEndpointDefinitions,
|
|
115
|
+
graphqlContext,
|
|
116
|
+
messages,
|
|
117
|
+
agentStates,
|
|
118
|
+
frontendUrl,
|
|
119
|
+
}: {
|
|
120
|
+
remoteEndpointDefinitions: EndpointDefinition[];
|
|
121
|
+
graphqlContext: GraphQLContext;
|
|
122
|
+
messages: Message[];
|
|
123
|
+
agentStates?: AgentStateInput[];
|
|
124
|
+
frontendUrl?: string;
|
|
125
|
+
}): Promise<Action[]> {
|
|
126
|
+
const logger = graphqlContext.logger.child({ component: "remote-actions.fetchRemoteActions" });
|
|
127
|
+
logger.debug({ remoteEndpointDefinitions }, "Fetching from remote endpoints");
|
|
128
|
+
|
|
129
|
+
// Remove duplicates of remoteEndpointDefinitions.url
|
|
130
|
+
const filtered = remoteEndpointDefinitions.filter((value, index, self) => {
|
|
131
|
+
if (value.type === EndpointType.LangGraphPlatform) {
|
|
132
|
+
return value;
|
|
133
|
+
}
|
|
134
|
+
return index === self.findIndex((t: CopilotKitEndpoint) => t.url === value.url);
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
const result = await Promise.all(
|
|
138
|
+
filtered.map(async (endpoint) => {
|
|
139
|
+
// Check for properties that can distinguish LG platform from other actions
|
|
140
|
+
if (endpoint.type === EndpointType.LangGraphPlatform) {
|
|
141
|
+
return constructLGCRemoteAction({
|
|
142
|
+
endpoint,
|
|
143
|
+
messages,
|
|
144
|
+
graphqlContext,
|
|
145
|
+
logger: logger.child({
|
|
146
|
+
component: "remote-actions.constructLGCRemoteAction",
|
|
147
|
+
endpoint,
|
|
148
|
+
}),
|
|
149
|
+
agentStates,
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const json = await fetchRemoteInfo({
|
|
154
|
+
url: endpoint.url,
|
|
155
|
+
onBeforeRequest: endpoint.onBeforeRequest,
|
|
156
|
+
graphqlContext,
|
|
157
|
+
logger: logger.child({ component: "remote-actions.fetchActionsFromUrl", endpoint }),
|
|
158
|
+
frontendUrl,
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
return constructRemoteActions({
|
|
162
|
+
json,
|
|
163
|
+
messages,
|
|
164
|
+
url: endpoint.url,
|
|
165
|
+
onBeforeRequest: endpoint.onBeforeRequest,
|
|
166
|
+
graphqlContext,
|
|
167
|
+
logger: logger.child({ component: "remote-actions.constructActions", endpoint }),
|
|
168
|
+
agentStates,
|
|
169
|
+
});
|
|
170
|
+
}),
|
|
171
|
+
);
|
|
172
|
+
|
|
173
|
+
return result.flat();
|
|
174
|
+
}
|