@copilotkit/runtime 1.5.0-tyler-reset-chat.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +141 -3
- package/__snapshots__/schema/schema.graphql +7 -9
- package/dist/{chunk-K67A6XOJ.mjs → chunk-25G6SHWM.mjs} +458 -331
- package/dist/chunk-25G6SHWM.mjs.map +1 -0
- package/dist/{chunk-OKQVDDJ2.mjs → chunk-4AYRDPWK.mjs} +285 -63
- package/dist/chunk-4AYRDPWK.mjs.map +1 -0
- package/dist/{chunk-ZBG4KJW5.mjs → chunk-AFKLCW76.mjs} +2 -2
- package/dist/{chunk-AGSBOD2T.mjs → chunk-D6J2N5ZQ.mjs} +2 -2
- package/dist/{chunk-QNQ6UT3D.mjs → chunk-PIUHAIBR.mjs} +2 -2
- package/dist/{chunk-B74M7FXG.mjs → chunk-RFF5IIZJ.mjs} +3 -2
- package/dist/chunk-RFF5IIZJ.mjs.map +1 -0
- package/dist/{copilot-runtime-12e7ac40.d.ts → copilot-runtime-2e46a7b6.d.ts} +2 -2
- package/dist/graphql/types/converted/index.d.ts +1 -1
- package/dist/graphql/types/converted/index.js +2 -1
- package/dist/graphql/types/converted/index.js.map +1 -1
- package/dist/graphql/types/converted/index.mjs +1 -1
- package/dist/{groq-adapter-24abe931.d.ts → groq-adapter-7bf6824b.d.ts} +1 -1
- package/dist/{index-10b1c870.d.ts → index-ff3fbc33.d.ts} +7 -8
- package/dist/index.d.ts +5 -5
- package/dist/index.js +832 -480
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +15 -11
- package/dist/index.mjs.map +1 -1
- package/dist/{langserve-f021ab9c.d.ts → langserve-f318db89.d.ts} +53 -14
- package/dist/lib/index.d.ts +4 -4
- package/dist/lib/index.js +737 -459
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/index.mjs +7 -7
- package/dist/lib/integrations/index.d.ts +4 -4
- package/dist/lib/integrations/index.js +71 -30
- package/dist/lib/integrations/index.js.map +1 -1
- package/dist/lib/integrations/index.mjs +6 -6
- package/dist/lib/integrations/nest/index.d.ts +3 -3
- package/dist/lib/integrations/nest/index.js +71 -30
- package/dist/lib/integrations/nest/index.js.map +1 -1
- package/dist/lib/integrations/nest/index.mjs +4 -4
- package/dist/lib/integrations/node-express/index.d.ts +3 -3
- package/dist/lib/integrations/node-express/index.js +71 -30
- package/dist/lib/integrations/node-express/index.js.map +1 -1
- package/dist/lib/integrations/node-express/index.mjs +4 -4
- package/dist/lib/integrations/node-http/index.d.ts +3 -3
- package/dist/lib/integrations/node-http/index.js +71 -30
- package/dist/lib/integrations/node-http/index.js.map +1 -1
- package/dist/lib/integrations/node-http/index.mjs +3 -3
- package/dist/service-adapters/index.d.ts +36 -5
- package/dist/service-adapters/index.js +285 -61
- package/dist/service-adapters/index.js.map +1 -1
- package/dist/service-adapters/index.mjs +5 -1
- package/package.json +4 -4
- package/src/agents/langgraph/event-source.ts +140 -148
- package/src/agents/langgraph/events.ts +1 -1
- package/src/graphql/inputs/message.input.ts +15 -3
- package/src/graphql/resolvers/copilot.resolver.ts +32 -6
- package/src/graphql/types/converted/index.ts +4 -3
- package/src/graphql/types/copilot-response.type.ts +12 -3
- package/src/graphql/types/enums.ts +0 -11
- package/src/lib/runtime/copilot-runtime.ts +1 -7
- package/src/lib/runtime/remote-action-constructors.ts +64 -58
- package/src/lib/runtime/remote-actions.ts +1 -0
- package/src/lib/runtime/remote-lg-action.ts +184 -154
- package/src/service-adapters/anthropic/anthropic-adapter.ts +16 -6
- package/src/service-adapters/conversion.ts +2 -1
- package/src/service-adapters/events.ts +118 -54
- package/src/service-adapters/experimental/empty/empty-adapter.ts +33 -0
- package/src/service-adapters/experimental/ollama/ollama-adapter.ts +7 -3
- package/src/service-adapters/groq/groq-adapter.ts +23 -8
- package/src/service-adapters/index.ts +7 -1
- package/src/service-adapters/langchain/utils.ts +55 -32
- package/src/service-adapters/openai/openai-adapter.ts +22 -9
- package/src/service-adapters/openai/openai-assistant-adapter.ts +22 -8
- package/src/service-adapters/unify/unify-adapter.ts +28 -11
- package/dist/chunk-B74M7FXG.mjs.map +0 -1
- package/dist/chunk-K67A6XOJ.mjs.map +0 -1
- package/dist/chunk-OKQVDDJ2.mjs.map +0 -1
- /package/dist/{chunk-ZBG4KJW5.mjs.map → chunk-AFKLCW76.mjs.map} +0 -0
- /package/dist/{chunk-AGSBOD2T.mjs.map → chunk-D6J2N5ZQ.mjs.map} +0 -0
- /package/dist/{chunk-QNQ6UT3D.mjs.map → chunk-PIUHAIBR.mjs.map} +0 -0
|
@@ -40,6 +40,7 @@ export function constructLGCRemoteAction({
|
|
|
40
40
|
actionInputsWithoutAgents,
|
|
41
41
|
threadId,
|
|
42
42
|
nodeName,
|
|
43
|
+
additionalMessages = [],
|
|
43
44
|
}: LangGraphAgentHandlerParams): Promise<Observable<RuntimeEvent>> => {
|
|
44
45
|
logger.debug({ actionName: agent.name }, "Executing LangGraph Platform agent");
|
|
45
46
|
|
|
@@ -66,7 +67,7 @@ export function constructLGCRemoteAction({
|
|
|
66
67
|
agent,
|
|
67
68
|
threadId,
|
|
68
69
|
nodeName,
|
|
69
|
-
messages,
|
|
70
|
+
messages: [...messages, ...additionalMessages],
|
|
70
71
|
state,
|
|
71
72
|
properties: graphqlContext.properties,
|
|
72
73
|
actions: actionInputsWithoutAgents.map((action) => ({
|
|
@@ -109,6 +110,8 @@ export function constructRemoteActions({
|
|
|
109
110
|
messages: Message[];
|
|
110
111
|
agentStates?: AgentStateInput[];
|
|
111
112
|
}): Action<any>[] {
|
|
113
|
+
const totalAgents = Array.isArray(json["agents"]) ? json["agents"].length : 0;
|
|
114
|
+
|
|
112
115
|
const actions = json["actions"].map((action) => ({
|
|
113
116
|
name: action.name,
|
|
114
117
|
description: action.description,
|
|
@@ -120,7 +123,7 @@ export function constructRemoteActions({
|
|
|
120
123
|
telemetry.capture("oss.runtime.remote_action_executed", {
|
|
121
124
|
agentExecution: false,
|
|
122
125
|
type: "self-hosted",
|
|
123
|
-
agentsAmount:
|
|
126
|
+
agentsAmount: totalAgents,
|
|
124
127
|
});
|
|
125
128
|
|
|
126
129
|
try {
|
|
@@ -157,66 +160,69 @@ export function constructRemoteActions({
|
|
|
157
160
|
},
|
|
158
161
|
}));
|
|
159
162
|
|
|
160
|
-
const agents =
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
langGraphAgentHandler: async ({
|
|
167
|
-
name,
|
|
168
|
-
actionInputsWithoutAgents,
|
|
169
|
-
threadId,
|
|
170
|
-
nodeName,
|
|
171
|
-
}: LangGraphAgentHandlerParams): Promise<Observable<RuntimeEvent>> => {
|
|
172
|
-
logger.debug({ actionName: agent.name }, "Executing remote agent");
|
|
173
|
-
|
|
174
|
-
const headers = createHeaders(onBeforeRequest, graphqlContext);
|
|
175
|
-
telemetry.capture("oss.runtime.remote_action_executed", {
|
|
176
|
-
agentExecution: true,
|
|
177
|
-
type: "self-hosted",
|
|
178
|
-
agentsAmount: json["agents"].length,
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
let state = {};
|
|
182
|
-
if (agentStates) {
|
|
183
|
-
const jsonState = agentStates.find((state) => state.agentName === name)?.state;
|
|
184
|
-
if (jsonState) {
|
|
185
|
-
state = JSON.parse(jsonState);
|
|
186
|
-
}
|
|
187
|
-
}
|
|
163
|
+
const agents = totalAgents
|
|
164
|
+
? json["agents"].map((agent) => ({
|
|
165
|
+
name: agent.name,
|
|
166
|
+
description: agent.description,
|
|
167
|
+
parameters: [],
|
|
168
|
+
handler: async (_args: any) => {},
|
|
188
169
|
|
|
189
|
-
|
|
190
|
-
method: "POST",
|
|
191
|
-
headers,
|
|
192
|
-
body: JSON.stringify({
|
|
170
|
+
langGraphAgentHandler: async ({
|
|
193
171
|
name,
|
|
172
|
+
actionInputsWithoutAgents,
|
|
194
173
|
threadId,
|
|
195
174
|
nodeName,
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
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
|
+
: [];
|
|
220
226
|
|
|
221
227
|
return [...actions, ...agents];
|
|
222
228
|
}
|
|
@@ -5,7 +5,7 @@ import { Logger } from "pino";
|
|
|
5
5
|
import { ActionInput } from "../../graphql/inputs/action.input";
|
|
6
6
|
import { LangGraphPlatformAgent, LangGraphPlatformEndpoint } from "./remote-actions";
|
|
7
7
|
import { CopilotRequestContextProperties } from "../integrations";
|
|
8
|
-
import { Message, MessageType } from "../../graphql/types/converted";
|
|
8
|
+
import { ActionExecutionMessage, Message, MessageType } from "../../graphql/types/converted";
|
|
9
9
|
import { MessageRole } from "../../graphql/types/enums";
|
|
10
10
|
import { CustomEventNames, LangGraphEventTypes } from "../../agents/langgraph/events";
|
|
11
11
|
import telemetry from "../telemetry-client";
|
|
@@ -96,8 +96,6 @@ async function streamEvents(controller: ReadableStreamDefaultController, args: E
|
|
|
96
96
|
initialThreadId = initialThreadId.substring(3);
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
-
const assistants = await client.assistants.search();
|
|
100
|
-
const retrievedAssistant = assistants.find((a) => a.name === name);
|
|
101
99
|
const threadId = initialThreadId ?? randomUUID();
|
|
102
100
|
if (initialThreadId === threadId) {
|
|
103
101
|
await client.threads.get(threadId);
|
|
@@ -114,7 +112,7 @@ async function streamEvents(controller: ReadableStreamDefaultController, args: E
|
|
|
114
112
|
const mode = wasInitiatedWithExistingThread && nodeName != "__end__" ? "continue" : "start";
|
|
115
113
|
let formattedMessages = [];
|
|
116
114
|
try {
|
|
117
|
-
formattedMessages =
|
|
115
|
+
formattedMessages = copilotkitMessagesToLangChain(messages);
|
|
118
116
|
} catch (e) {
|
|
119
117
|
logger.error(e, `Error event thrown: ${e.message}`);
|
|
120
118
|
}
|
|
@@ -124,8 +122,24 @@ async function streamEvents(controller: ReadableStreamDefaultController, args: E
|
|
|
124
122
|
await client.threads.updateState(threadId, { values: state, asNode: nodeName });
|
|
125
123
|
}
|
|
126
124
|
|
|
127
|
-
|
|
128
|
-
|
|
125
|
+
let streamInfo: {
|
|
126
|
+
provider?: string;
|
|
127
|
+
langGraphHost?: string;
|
|
128
|
+
langGraphVersion?: string;
|
|
129
|
+
hashedLgcKey: string;
|
|
130
|
+
} = {
|
|
131
|
+
hashedLgcKey: createHash("sha256").update(langsmithApiKey).digest("hex"),
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
const assistants = await client.assistants.search();
|
|
135
|
+
const retrievedAssistant = assistants.find(
|
|
136
|
+
(a) => a.name === name || a.assistant_id === initialAssistantId,
|
|
137
|
+
);
|
|
138
|
+
if (!retrievedAssistant) {
|
|
139
|
+
telemetry.capture("oss.runtime.agent_execution_stream_errored", {
|
|
140
|
+
...streamInfo,
|
|
141
|
+
error: `Found no assistants for given information, while ${assistants.length} assistants exists`,
|
|
142
|
+
});
|
|
129
143
|
console.error(`
|
|
130
144
|
No agent found for the agent name specified in CopilotKit provider
|
|
131
145
|
Please check your available agents or provide an agent ID in the LangGraph Platform endpoint definition.\n
|
|
@@ -134,6 +148,8 @@ async function streamEvents(controller: ReadableStreamDefaultController, args: E
|
|
|
134
148
|
`);
|
|
135
149
|
throw new Error("No agent id found");
|
|
136
150
|
}
|
|
151
|
+
const assistantId = retrievedAssistant.assistant_id;
|
|
152
|
+
|
|
137
153
|
const graphInfo = await client.assistants.getGraph(assistantId);
|
|
138
154
|
const streamInput = mode === "start" ? state : null;
|
|
139
155
|
|
|
@@ -155,14 +171,6 @@ async function streamEvents(controller: ReadableStreamDefaultController, args: E
|
|
|
155
171
|
// If a manual emittance happens, it is the ultimate source of truth of state, unless a node has exited.
|
|
156
172
|
// Therefore, this value should either hold null, or the only edition of state that should be used.
|
|
157
173
|
let manuallyEmittedState = null;
|
|
158
|
-
let streamInfo: {
|
|
159
|
-
provider?: string;
|
|
160
|
-
langGraphHost?: string;
|
|
161
|
-
langGraphVersion?: string;
|
|
162
|
-
hashedLgcKey: string;
|
|
163
|
-
} = {
|
|
164
|
-
hashedLgcKey: createHash("sha256").update(langsmithApiKey).digest("hex"),
|
|
165
|
-
};
|
|
166
174
|
|
|
167
175
|
try {
|
|
168
176
|
telemetry.capture("oss.runtime.agent_execution_stream_started", {
|
|
@@ -172,7 +180,6 @@ async function streamEvents(controller: ReadableStreamDefaultController, args: E
|
|
|
172
180
|
if (!["events", "values", "error"].includes(chunk.event)) continue;
|
|
173
181
|
|
|
174
182
|
if (chunk.event === "error") {
|
|
175
|
-
logger.error(chunk, `Error event thrown: ${chunk.data.message}`);
|
|
176
183
|
throw new Error(`Error event thrown: ${chunk.data.message}`);
|
|
177
184
|
}
|
|
178
185
|
|
|
@@ -312,12 +319,17 @@ async function streamEvents(controller: ReadableStreamDefaultController, args: E
|
|
|
312
319
|
state: state.values,
|
|
313
320
|
running: !shouldExit,
|
|
314
321
|
active: false,
|
|
322
|
+
includeMessages: true,
|
|
315
323
|
}),
|
|
316
324
|
);
|
|
317
325
|
|
|
318
326
|
return Promise.resolve();
|
|
319
327
|
} catch (e) {
|
|
320
|
-
|
|
328
|
+
logger.error(e);
|
|
329
|
+
telemetry.capture("oss.runtime.agent_execution_stream_errored", {
|
|
330
|
+
...streamInfo,
|
|
331
|
+
error: e.message,
|
|
332
|
+
});
|
|
321
333
|
return Promise.resolve();
|
|
322
334
|
}
|
|
323
335
|
}
|
|
@@ -330,6 +342,7 @@ function getStateSyncEvent({
|
|
|
330
342
|
state,
|
|
331
343
|
running,
|
|
332
344
|
active,
|
|
345
|
+
includeMessages = false,
|
|
333
346
|
}: {
|
|
334
347
|
threadId: string;
|
|
335
348
|
runId: string;
|
|
@@ -338,13 +351,21 @@ function getStateSyncEvent({
|
|
|
338
351
|
state: State;
|
|
339
352
|
running: boolean;
|
|
340
353
|
active: boolean;
|
|
354
|
+
includeMessages?: boolean;
|
|
341
355
|
}): string {
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
356
|
+
if (!includeMessages) {
|
|
357
|
+
state = Object.keys(state).reduce((acc, key) => {
|
|
358
|
+
if (key !== "messages") {
|
|
359
|
+
acc[key] = state[key];
|
|
360
|
+
}
|
|
361
|
+
return acc;
|
|
362
|
+
}, {} as State);
|
|
363
|
+
} else {
|
|
364
|
+
state = {
|
|
365
|
+
...state,
|
|
366
|
+
messages: langchainMessagesToCopilotKit(state.messages || []),
|
|
367
|
+
};
|
|
368
|
+
}
|
|
348
369
|
|
|
349
370
|
return (
|
|
350
371
|
JSON.stringify({
|
|
@@ -354,7 +375,7 @@ function getStateSyncEvent({
|
|
|
354
375
|
agent_name: agentName,
|
|
355
376
|
node_name: nodeName,
|
|
356
377
|
active: active,
|
|
357
|
-
state:
|
|
378
|
+
state: state,
|
|
358
379
|
running: running,
|
|
359
380
|
role: "assistant",
|
|
360
381
|
}) + "\n"
|
|
@@ -449,179 +470,188 @@ function langGraphDefaultMergeState(
|
|
|
449
470
|
}
|
|
450
471
|
|
|
451
472
|
// merge with existing messages
|
|
452
|
-
const
|
|
453
|
-
const existingMessageIds = new Set(
|
|
454
|
-
const
|
|
473
|
+
const existingMessages: LangGraphPlatformMessage[] = state.messages || [];
|
|
474
|
+
const existingMessageIds = new Set(existingMessages.map((message) => message.id));
|
|
475
|
+
const newMessages = messages.filter((message) => !existingMessageIds.has(message.id));
|
|
476
|
+
|
|
477
|
+
return {
|
|
478
|
+
...state,
|
|
479
|
+
messages: newMessages,
|
|
480
|
+
copilotkit: {
|
|
481
|
+
actions,
|
|
482
|
+
},
|
|
483
|
+
};
|
|
484
|
+
}
|
|
455
485
|
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
486
|
+
function langchainMessagesToCopilotKit(messages: any[]): any[] {
|
|
487
|
+
const result: any[] = [];
|
|
488
|
+
const tool_call_names: Record<string, string> = {};
|
|
489
|
+
|
|
490
|
+
// First pass: gather all tool call names from AI messages
|
|
491
|
+
for (const message of messages) {
|
|
492
|
+
if (message.type === "ai") {
|
|
493
|
+
for (const tool_call of message.tool_calls) {
|
|
494
|
+
tool_call_names[tool_call.id] = tool_call.name;
|
|
495
|
+
}
|
|
459
496
|
}
|
|
460
497
|
}
|
|
461
498
|
|
|
462
499
|
for (const message of messages) {
|
|
463
|
-
|
|
464
|
-
if (
|
|
465
|
-
|
|
466
|
-
message.tool_calls.length > 0 &&
|
|
467
|
-
message.tool_calls[0].name === agentName
|
|
468
|
-
) {
|
|
469
|
-
continue;
|
|
500
|
+
let content: any = message.content;
|
|
501
|
+
if (content instanceof Array) {
|
|
502
|
+
content = content[0];
|
|
470
503
|
}
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
if ("name" in message && message.name === agentName) {
|
|
474
|
-
continue;
|
|
504
|
+
if (content instanceof Object) {
|
|
505
|
+
content = content.text;
|
|
475
506
|
}
|
|
476
507
|
|
|
477
|
-
if (
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
508
|
+
if (message.type === "human") {
|
|
509
|
+
result.push({
|
|
510
|
+
role: "user",
|
|
511
|
+
content: content,
|
|
512
|
+
id: message.id,
|
|
513
|
+
});
|
|
514
|
+
} else if (message.type === "system") {
|
|
515
|
+
result.push({
|
|
516
|
+
role: "system",
|
|
517
|
+
content: content,
|
|
518
|
+
id: message.id,
|
|
519
|
+
});
|
|
520
|
+
} else if (message.type === "ai") {
|
|
521
|
+
if (message.tool_calls && message.tool_calls.length > 0) {
|
|
522
|
+
for (const tool_call of message.tool_calls) {
|
|
523
|
+
result.push({
|
|
524
|
+
id: tool_call.id,
|
|
525
|
+
name: tool_call.name,
|
|
526
|
+
arguments: tool_call.args,
|
|
527
|
+
parentMessageId: message.id,
|
|
528
|
+
});
|
|
498
529
|
}
|
|
530
|
+
} else {
|
|
531
|
+
result.push({
|
|
532
|
+
role: "assistant",
|
|
533
|
+
content: content,
|
|
534
|
+
id: message.id,
|
|
535
|
+
parentMessageId: message.id,
|
|
536
|
+
});
|
|
499
537
|
}
|
|
538
|
+
} else if (message.type === "tool") {
|
|
539
|
+
const actionName = tool_call_names[message.tool_call_id] || message.name || "";
|
|
540
|
+
result.push({
|
|
541
|
+
actionExecutionId: message.tool_call_id,
|
|
542
|
+
actionName: actionName,
|
|
543
|
+
result: content,
|
|
544
|
+
id: message.id,
|
|
545
|
+
});
|
|
500
546
|
}
|
|
501
547
|
}
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
const nextMessage = mergedMessages[i + 1];
|
|
507
|
-
|
|
508
|
-
if (
|
|
509
|
-
"tool_calls" in currentMessage &&
|
|
510
|
-
currentMessage.tool_calls.length > 0 &&
|
|
511
|
-
"tool_call_id" in nextMessage
|
|
512
|
-
) {
|
|
513
|
-
nextMessage.tool_call_id = currentMessage.tool_calls[0].id;
|
|
548
|
+
const resultsDict: Record<string, any> = {};
|
|
549
|
+
for (const msg of result) {
|
|
550
|
+
if (msg.actionExecutionId) {
|
|
551
|
+
resultsDict[msg.actionExecutionId] = msg;
|
|
514
552
|
}
|
|
515
553
|
}
|
|
516
554
|
|
|
517
|
-
|
|
518
|
-
const correctedMessages: LangGraphPlatformMessage[] = [];
|
|
555
|
+
const reorderedResult: Message[] = [];
|
|
519
556
|
|
|
520
|
-
for (
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
557
|
+
for (const msg of result) {
|
|
558
|
+
// If it's not a tool result, just append it
|
|
559
|
+
if (!("actionExecutionId" in msg)) {
|
|
560
|
+
reorderedResult.push(msg);
|
|
561
|
+
}
|
|
524
562
|
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
);
|
|
531
|
-
continue;
|
|
563
|
+
// If the message has arguments (i.e., is a tool call invocation),
|
|
564
|
+
// append the corresponding result right after it
|
|
565
|
+
if ("arguments" in msg) {
|
|
566
|
+
const msgId = msg.id;
|
|
567
|
+
if (msgId in resultsDict) {
|
|
568
|
+
reorderedResult.push(resultsDict[msgId]);
|
|
532
569
|
}
|
|
570
|
+
}
|
|
571
|
+
}
|
|
533
572
|
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
nextMessage.tool_call_id !== currentMessage.tool_calls[0].id
|
|
537
|
-
) {
|
|
538
|
-
const toolMessage = mergedMessages.find(
|
|
539
|
-
(m) => "tool_call_id" in m && m.tool_call_id === currentMessage.tool_calls[0].id,
|
|
540
|
-
);
|
|
573
|
+
return reorderedResult;
|
|
574
|
+
}
|
|
541
575
|
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
currentMessage.tool_calls[0].id,
|
|
546
|
-
);
|
|
547
|
-
correctedMessages.push(currentMessage, toolMessage);
|
|
548
|
-
continue;
|
|
549
|
-
} else {
|
|
550
|
-
console.warn(
|
|
551
|
-
"No corresponding tool call result found for tool call, skipping:",
|
|
552
|
-
currentMessage.tool_calls[0].id,
|
|
553
|
-
);
|
|
554
|
-
continue;
|
|
555
|
-
}
|
|
556
|
-
}
|
|
576
|
+
function copilotkitMessagesToLangChain(messages: Message[]): LangGraphPlatformMessage[] {
|
|
577
|
+
const result: LangGraphPlatformMessage[] = [];
|
|
578
|
+
const processedActionExecutions = new Set<string>();
|
|
557
579
|
|
|
558
|
-
|
|
580
|
+
for (const message of messages) {
|
|
581
|
+
// Handle TextMessage
|
|
582
|
+
if (message.isTextMessage()) {
|
|
583
|
+
if (message.role === "user") {
|
|
584
|
+
// Human message
|
|
585
|
+
result.push({
|
|
586
|
+
...message,
|
|
587
|
+
role: MessageRole.user,
|
|
588
|
+
});
|
|
589
|
+
} else if (message.role === "system") {
|
|
590
|
+
// System message
|
|
591
|
+
result.push({
|
|
592
|
+
...message,
|
|
593
|
+
role: MessageRole.system,
|
|
594
|
+
});
|
|
595
|
+
} else if (message.role === "assistant") {
|
|
596
|
+
// Assistant message
|
|
597
|
+
result.push({
|
|
598
|
+
...message,
|
|
599
|
+
role: MessageRole.assistant,
|
|
600
|
+
});
|
|
601
|
+
}
|
|
559
602
|
continue;
|
|
560
603
|
}
|
|
561
604
|
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
continue;
|
|
566
|
-
}
|
|
605
|
+
// Handle ActionExecutionMessage (multiple tool calls per parentMessageId)
|
|
606
|
+
if (message.isActionExecutionMessage()) {
|
|
607
|
+
const messageId = message.parentMessageId ?? message.id;
|
|
567
608
|
|
|
568
|
-
|
|
569
|
-
|
|
609
|
+
// If we've already processed this action execution group, skip
|
|
610
|
+
if (processedActionExecutions.has(messageId)) {
|
|
570
611
|
continue;
|
|
571
612
|
}
|
|
572
613
|
|
|
573
|
-
|
|
574
|
-
continue;
|
|
575
|
-
}
|
|
614
|
+
processedActionExecutions.add(messageId);
|
|
576
615
|
|
|
577
|
-
|
|
578
|
-
|
|
616
|
+
// Gather all tool calls related to this messageId
|
|
617
|
+
const relatedActionExecutions = messages.filter(
|
|
618
|
+
(m) =>
|
|
619
|
+
m.isActionExecutionMessage() &&
|
|
620
|
+
((m.parentMessageId && m.parentMessageId === messageId) || m.id === messageId),
|
|
621
|
+
) as ActionExecutionMessage[];
|
|
579
622
|
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
},
|
|
586
|
-
};
|
|
587
|
-
}
|
|
623
|
+
const tool_calls: ToolCall[] = relatedActionExecutions.map((m) => ({
|
|
624
|
+
name: m.name,
|
|
625
|
+
args: m.arguments,
|
|
626
|
+
id: m.id,
|
|
627
|
+
}));
|
|
588
628
|
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
return message;
|
|
593
|
-
}
|
|
594
|
-
if (message.isTextMessage() && message.role === "system") {
|
|
595
|
-
return message;
|
|
596
|
-
}
|
|
597
|
-
if (message.isTextMessage() && message.role === "user") {
|
|
598
|
-
return message;
|
|
599
|
-
}
|
|
600
|
-
if (message.isActionExecutionMessage()) {
|
|
601
|
-
const toolCall: ToolCall = {
|
|
602
|
-
name: message.name,
|
|
603
|
-
args: message.arguments,
|
|
604
|
-
id: message.id,
|
|
605
|
-
};
|
|
606
|
-
return {
|
|
607
|
-
type: message.type,
|
|
629
|
+
result.push({
|
|
630
|
+
id: messageId,
|
|
631
|
+
type: "ActionExecutionMessage",
|
|
608
632
|
content: "",
|
|
609
|
-
tool_calls:
|
|
633
|
+
tool_calls: tool_calls,
|
|
610
634
|
role: MessageRole.assistant,
|
|
611
|
-
|
|
612
|
-
|
|
635
|
+
} satisfies LangGraphPlatformActionExecutionMessage);
|
|
636
|
+
|
|
637
|
+
continue;
|
|
613
638
|
}
|
|
639
|
+
|
|
640
|
+
// Handle ResultMessage
|
|
614
641
|
if (message.isResultMessage()) {
|
|
615
|
-
|
|
642
|
+
result.push({
|
|
616
643
|
type: message.type,
|
|
617
644
|
content: message.result,
|
|
618
645
|
id: message.id,
|
|
619
646
|
tool_call_id: message.actionExecutionId,
|
|
620
647
|
name: message.actionName,
|
|
621
648
|
role: MessageRole.tool,
|
|
622
|
-
} satisfies LangGraphPlatformResultMessage;
|
|
649
|
+
} satisfies LangGraphPlatformResultMessage);
|
|
650
|
+
continue;
|
|
623
651
|
}
|
|
624
652
|
|
|
625
653
|
throw new Error(`Unknown message type ${message.type}`);
|
|
626
|
-
}
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
return result;
|
|
627
657
|
}
|