@copilotkit/runtime 1.3.2 → 1.3.3
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 +8 -0
- package/dist/{chunk-VQY3UTNK.mjs → chunk-3RSGBABY.mjs} +2 -2
- package/dist/{chunk-CP4IV75Q.mjs → chunk-4QVREBXP.mjs} +2 -2
- package/dist/{chunk-IYJBUTRQ.mjs → chunk-AOSWZOH5.mjs} +2 -2
- package/dist/{chunk-J3URDBS7.mjs → chunk-LQSJAQSM.mjs} +157 -72
- package/dist/chunk-LQSJAQSM.mjs.map +1 -0
- package/dist/{chunk-GJHAWL7E.mjs → chunk-TU4DA2BH.mjs} +2 -2
- package/dist/index.js +159 -74
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +5 -5
- package/dist/lib/index.js +159 -74
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/index.mjs +5 -5
- package/dist/lib/integrations/index.js +4 -2
- package/dist/lib/integrations/index.js.map +1 -1
- package/dist/lib/integrations/index.mjs +4 -4
- package/dist/lib/integrations/nest/index.js +4 -2
- package/dist/lib/integrations/nest/index.js.map +1 -1
- package/dist/lib/integrations/nest/index.mjs +2 -2
- package/dist/lib/integrations/node-express/index.js +4 -2
- package/dist/lib/integrations/node-express/index.js.map +1 -1
- package/dist/lib/integrations/node-express/index.mjs +2 -2
- package/dist/lib/integrations/node-http/index.js +4 -2
- package/dist/lib/integrations/node-http/index.js.map +1 -1
- package/dist/lib/integrations/node-http/index.mjs +1 -1
- package/package.json +7 -5
- package/src/agents/langgraph/event-source.ts +97 -24
- package/src/agents/langgraph/events.ts +10 -1
- package/src/lib/runtime/remote-actions.ts +52 -31
- package/dist/chunk-J3URDBS7.mjs.map +0 -1
- /package/dist/{chunk-VQY3UTNK.mjs.map → chunk-3RSGBABY.mjs.map} +0 -0
- /package/dist/{chunk-CP4IV75Q.mjs.map → chunk-4QVREBXP.mjs.map} +0 -0
- /package/dist/{chunk-IYJBUTRQ.mjs.map → chunk-AOSWZOH5.mjs.map} +0 -0
- /package/dist/{chunk-GJHAWL7E.mjs.map → chunk-TU4DA2BH.mjs.map} +0 -0
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import { ReplaySubject, scan, mergeMap } from "rxjs";
|
|
1
|
+
import { ReplaySubject, scan, mergeMap, catchError } from "rxjs";
|
|
2
2
|
import { LangGraphEvent, LangGraphEventTypes } from "./events";
|
|
3
3
|
import { RuntimeEvent, RuntimeEventTypes } from "../../service-adapters/events";
|
|
4
|
+
import { randomId } from "@copilotkit/shared";
|
|
4
5
|
|
|
5
6
|
interface LangGraphEventWithState {
|
|
6
7
|
event: LangGraphEvent | null;
|
|
7
8
|
toolCallName: string | null;
|
|
8
9
|
toolCallId: string | null;
|
|
9
|
-
|
|
10
|
+
toolCallMessageId: string | null;
|
|
11
|
+
prevToolCallMessageId: string | null;
|
|
10
12
|
messageId: string | null;
|
|
11
13
|
prevMessageId: string | null;
|
|
12
14
|
}
|
|
@@ -48,51 +50,77 @@ export class RemoteLangGraphEventSource {
|
|
|
48
50
|
});
|
|
49
51
|
}
|
|
50
52
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
+
try {
|
|
54
|
+
while (true) {
|
|
55
|
+
const { done, value } = await reader.read();
|
|
53
56
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
+
if (!done) {
|
|
58
|
+
buffer.push(decoder.decode(value, { stream: true }));
|
|
59
|
+
}
|
|
57
60
|
|
|
58
|
-
|
|
61
|
+
flushBuffer();
|
|
59
62
|
|
|
60
|
-
|
|
61
|
-
|
|
63
|
+
if (done) {
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
62
66
|
}
|
|
67
|
+
} catch (error) {
|
|
68
|
+
console.error("Error in stream", error);
|
|
69
|
+
eventStream$.error(error);
|
|
70
|
+
return;
|
|
63
71
|
}
|
|
64
72
|
eventStream$.complete();
|
|
65
73
|
}
|
|
66
74
|
|
|
75
|
+
private shouldEmitToolCall(
|
|
76
|
+
shouldEmitToolCalls: string | string[] | boolean,
|
|
77
|
+
toolCallName: string,
|
|
78
|
+
) {
|
|
79
|
+
if (typeof shouldEmitToolCalls === "boolean") {
|
|
80
|
+
return shouldEmitToolCalls;
|
|
81
|
+
}
|
|
82
|
+
if (Array.isArray(shouldEmitToolCalls)) {
|
|
83
|
+
return shouldEmitToolCalls.includes(toolCallName);
|
|
84
|
+
}
|
|
85
|
+
return shouldEmitToolCalls === toolCallName;
|
|
86
|
+
}
|
|
87
|
+
|
|
67
88
|
processLangGraphEvents() {
|
|
89
|
+
let lastEventWithState: LangGraphEventWithState | null = null;
|
|
90
|
+
|
|
68
91
|
return this.eventStream$.pipe(
|
|
69
92
|
scan(
|
|
70
93
|
(acc, event) => {
|
|
71
94
|
if (event.event === LangGraphEventTypes.OnChatModelStream) {
|
|
72
95
|
if (event.data?.chunk?.kwargs?.tool_call_chunks) {
|
|
73
|
-
acc.
|
|
74
|
-
acc.
|
|
96
|
+
acc.prevToolCallMessageId = acc.toolCallMessageId;
|
|
97
|
+
acc.toolCallMessageId = event.data.chunk.kwargs?.id;
|
|
75
98
|
if (event.data.chunk.kwargs.tool_call_chunks[0]?.name) {
|
|
76
99
|
acc.toolCallName = event.data.chunk.kwargs.tool_call_chunks[0].name;
|
|
77
100
|
}
|
|
101
|
+
if (event.data.chunk.kwargs.tool_call_chunks[0]?.id) {
|
|
102
|
+
acc.toolCallId = event.data.chunk.kwargs.tool_call_chunks[0].id;
|
|
103
|
+
}
|
|
78
104
|
}
|
|
79
105
|
acc.prevMessageId = acc.messageId;
|
|
80
106
|
acc.messageId = event.data?.chunk?.kwargs?.id;
|
|
81
107
|
} else {
|
|
82
|
-
acc.
|
|
83
|
-
acc.
|
|
108
|
+
acc.prevToolCallMessageId = acc.toolCallMessageId;
|
|
109
|
+
acc.toolCallMessageId = null;
|
|
84
110
|
acc.prevMessageId = acc.messageId;
|
|
85
111
|
acc.messageId = null;
|
|
86
112
|
acc.toolCallName = null;
|
|
87
113
|
}
|
|
88
114
|
|
|
89
115
|
acc.event = event;
|
|
116
|
+
lastEventWithState = acc; // Capture the state
|
|
90
117
|
return acc;
|
|
91
118
|
},
|
|
92
119
|
{
|
|
93
120
|
event: null,
|
|
94
121
|
toolCallId: null,
|
|
95
|
-
|
|
122
|
+
toolCallMessageId: null,
|
|
123
|
+
prevToolCallMessageId: null,
|
|
96
124
|
messageId: null,
|
|
97
125
|
toolCallName: null,
|
|
98
126
|
prevMessageId: null,
|
|
@@ -102,7 +130,7 @@ export class RemoteLangGraphEventSource {
|
|
|
102
130
|
const events: RuntimeEvent[] = [];
|
|
103
131
|
|
|
104
132
|
let shouldEmitMessages = true;
|
|
105
|
-
let shouldEmitToolCalls = false;
|
|
133
|
+
let shouldEmitToolCalls: string | string[] | boolean = false;
|
|
106
134
|
|
|
107
135
|
if (eventWithState.event.event == LangGraphEventTypes.OnChatModelStream) {
|
|
108
136
|
if ("copilotkit:emit-tool-calls" in (eventWithState.event.metadata || {})) {
|
|
@@ -115,9 +143,9 @@ export class RemoteLangGraphEventSource {
|
|
|
115
143
|
|
|
116
144
|
// Tool call ended: emit ActionExecutionEnd
|
|
117
145
|
if (
|
|
118
|
-
eventWithState.
|
|
119
|
-
eventWithState.
|
|
120
|
-
shouldEmitToolCalls
|
|
146
|
+
eventWithState.prevToolCallMessageId !== null &&
|
|
147
|
+
eventWithState.prevToolCallMessageId !== eventWithState.toolCallMessageId &&
|
|
148
|
+
this.shouldEmitToolCall(shouldEmitToolCalls, eventWithState.toolCallName)
|
|
121
149
|
) {
|
|
122
150
|
events.push({
|
|
123
151
|
type: RuntimeEventTypes.ActionExecutionEnd,
|
|
@@ -149,6 +177,20 @@ export class RemoteLangGraphEventSource {
|
|
|
149
177
|
type: RuntimeEventTypes.TextMessageEnd,
|
|
150
178
|
});
|
|
151
179
|
break;
|
|
180
|
+
case LangGraphEventTypes.OnCopilotKitEmitToolCall:
|
|
181
|
+
events.push({
|
|
182
|
+
type: RuntimeEventTypes.ActionExecutionStart,
|
|
183
|
+
actionExecutionId: eventWithState.event.id,
|
|
184
|
+
actionName: eventWithState.event.name,
|
|
185
|
+
});
|
|
186
|
+
events.push({
|
|
187
|
+
type: RuntimeEventTypes.ActionExecutionArgs,
|
|
188
|
+
args: JSON.stringify(eventWithState.event.args),
|
|
189
|
+
});
|
|
190
|
+
events.push({
|
|
191
|
+
type: RuntimeEventTypes.ActionExecutionEnd,
|
|
192
|
+
});
|
|
193
|
+
break;
|
|
152
194
|
case LangGraphEventTypes.OnCopilotKitStateSync:
|
|
153
195
|
events.push({
|
|
154
196
|
type: RuntimeEventTypes.AgentStateMessage,
|
|
@@ -180,13 +222,13 @@ export class RemoteLangGraphEventSource {
|
|
|
180
222
|
break;
|
|
181
223
|
case LangGraphEventTypes.OnChatModelStream:
|
|
182
224
|
if (
|
|
183
|
-
eventWithState.
|
|
184
|
-
eventWithState.
|
|
225
|
+
eventWithState.toolCallMessageId !== null &&
|
|
226
|
+
eventWithState.prevToolCallMessageId !== eventWithState.toolCallMessageId
|
|
185
227
|
) {
|
|
186
|
-
if (shouldEmitToolCalls) {
|
|
228
|
+
if (this.shouldEmitToolCall(shouldEmitToolCalls, eventWithState.toolCallName)) {
|
|
187
229
|
events.push({
|
|
188
230
|
type: RuntimeEventTypes.ActionExecutionStart,
|
|
189
|
-
actionExecutionId: eventWithState.
|
|
231
|
+
actionExecutionId: eventWithState.toolCallMessageId,
|
|
190
232
|
actionName: eventWithState.toolCallName,
|
|
191
233
|
scope: "client",
|
|
192
234
|
});
|
|
@@ -210,7 +252,7 @@ export class RemoteLangGraphEventSource {
|
|
|
210
252
|
|
|
211
253
|
// Tool call args: emit ActionExecutionArgs
|
|
212
254
|
if (args) {
|
|
213
|
-
if (shouldEmitToolCalls) {
|
|
255
|
+
if (this.shouldEmitToolCall(shouldEmitToolCalls, eventWithState.toolCallName)) {
|
|
214
256
|
events.push({
|
|
215
257
|
type: RuntimeEventTypes.ActionExecutionArgs,
|
|
216
258
|
args,
|
|
@@ -230,6 +272,37 @@ export class RemoteLangGraphEventSource {
|
|
|
230
272
|
}
|
|
231
273
|
return events;
|
|
232
274
|
}),
|
|
275
|
+
catchError((error) => {
|
|
276
|
+
console.error(error);
|
|
277
|
+
const events: RuntimeEvent[] = [];
|
|
278
|
+
|
|
279
|
+
if (lastEventWithState?.messageId) {
|
|
280
|
+
events.push({
|
|
281
|
+
type: RuntimeEventTypes.TextMessageEnd,
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
if (lastEventWithState?.toolCallMessageId) {
|
|
285
|
+
events.push({
|
|
286
|
+
type: RuntimeEventTypes.ActionExecutionEnd,
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
const messageId = randomId();
|
|
291
|
+
|
|
292
|
+
events.push({
|
|
293
|
+
type: RuntimeEventTypes.TextMessageStart,
|
|
294
|
+
messageId: messageId,
|
|
295
|
+
});
|
|
296
|
+
events.push({
|
|
297
|
+
type: RuntimeEventTypes.TextMessageContent,
|
|
298
|
+
content: "❌ An error occurred. Please try again.",
|
|
299
|
+
});
|
|
300
|
+
events.push({
|
|
301
|
+
type: RuntimeEventTypes.TextMessageEnd,
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
return events;
|
|
305
|
+
}),
|
|
233
306
|
);
|
|
234
307
|
}
|
|
235
308
|
}
|
|
@@ -9,6 +9,7 @@ export enum LangGraphEventTypes {
|
|
|
9
9
|
OnToolEnd = "on_tool_end",
|
|
10
10
|
OnCopilotKitStateSync = "on_copilotkit_state_sync",
|
|
11
11
|
OnCopilotKitEmitMessage = "on_copilotkit_emit_message",
|
|
12
|
+
OnCopilotKitEmitToolCall = "on_copilotkit_emit_tool_call",
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
type LangGraphOnCopilotKitStateSyncEvent = {
|
|
@@ -29,6 +30,13 @@ type LangGraphOnCopilotKitManualMessageEvent = {
|
|
|
29
30
|
message_id: string;
|
|
30
31
|
};
|
|
31
32
|
|
|
33
|
+
type LangGraphOnCopilotKitEmitToolCallEvent = {
|
|
34
|
+
event: LangGraphEventTypes.OnCopilotKitEmitToolCall;
|
|
35
|
+
name: string;
|
|
36
|
+
args: any;
|
|
37
|
+
id: string;
|
|
38
|
+
};
|
|
39
|
+
|
|
32
40
|
type LangGraphOnChainStartEvent = {
|
|
33
41
|
event: LangGraphEventTypes.OnChainStart;
|
|
34
42
|
run_id: string;
|
|
@@ -314,4 +322,5 @@ export type LangGraphEvent =
|
|
|
314
322
|
| LangGraphOnToolStartEvent
|
|
315
323
|
| LangGraphOnToolEndEvent
|
|
316
324
|
| LangGraphOnCopilotKitStateSyncEvent
|
|
317
|
-
| LangGraphOnCopilotKitManualMessageEvent
|
|
325
|
+
| LangGraphOnCopilotKitManualMessageEvent
|
|
326
|
+
| LangGraphOnCopilotKitEmitToolCallEvent;
|
|
@@ -16,6 +16,11 @@ export type RemoteActionDefinition = {
|
|
|
16
16
|
};
|
|
17
17
|
};
|
|
18
18
|
|
|
19
|
+
export type RemoteActionInfoResponse = {
|
|
20
|
+
actions: any[];
|
|
21
|
+
agents: any[];
|
|
22
|
+
};
|
|
23
|
+
|
|
19
24
|
export type LangGraphAgentHandlerParams = {
|
|
20
25
|
name: string;
|
|
21
26
|
actionInputsWithoutAgents: ActionInput[];
|
|
@@ -64,27 +69,35 @@ async function fetchRemoteInfo({
|
|
|
64
69
|
graphqlContext: GraphQLContext;
|
|
65
70
|
logger: Logger;
|
|
66
71
|
frontendUrl?: string;
|
|
67
|
-
}): Promise<
|
|
72
|
+
}): Promise<RemoteActionInfoResponse> {
|
|
68
73
|
logger.debug({ url }, "Fetching actions from url");
|
|
69
74
|
const headers = createHeaders(onBeforeRequest, graphqlContext);
|
|
70
75
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
+
try {
|
|
77
|
+
const response = await fetch(`${url}/info`, {
|
|
78
|
+
method: "POST",
|
|
79
|
+
headers,
|
|
80
|
+
body: JSON.stringify({ properties: graphqlContext.properties, frontendUrl }),
|
|
81
|
+
});
|
|
76
82
|
|
|
77
|
-
|
|
83
|
+
if (!response.ok) {
|
|
84
|
+
logger.error(
|
|
85
|
+
{ url, status: response.status, body: await response.text() },
|
|
86
|
+
"Failed to fetch actions from url",
|
|
87
|
+
);
|
|
88
|
+
return { actions: [], agents: [] };
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const json = await response.json();
|
|
92
|
+
logger.debug({ json }, "Fetched actions from url");
|
|
93
|
+
return json;
|
|
94
|
+
} catch (error) {
|
|
78
95
|
logger.error(
|
|
79
|
-
{
|
|
96
|
+
{ error: error.message ? error.message : error + "" },
|
|
80
97
|
"Failed to fetch actions from url",
|
|
81
98
|
);
|
|
82
|
-
return [];
|
|
99
|
+
return { actions: [], agents: [] };
|
|
83
100
|
}
|
|
84
|
-
|
|
85
|
-
const json = await response.json();
|
|
86
|
-
logger.debug({ json }, "Fetched actions from url");
|
|
87
|
-
return json;
|
|
88
101
|
}
|
|
89
102
|
|
|
90
103
|
function constructRemoteActions({
|
|
@@ -96,7 +109,7 @@ function constructRemoteActions({
|
|
|
96
109
|
messages,
|
|
97
110
|
agentStates,
|
|
98
111
|
}: {
|
|
99
|
-
json:
|
|
112
|
+
json: RemoteActionInfoResponse;
|
|
100
113
|
url: string;
|
|
101
114
|
onBeforeRequest?: RemoteActionDefinition["onBeforeRequest"];
|
|
102
115
|
graphqlContext: GraphQLContext;
|
|
@@ -114,29 +127,37 @@ function constructRemoteActions({
|
|
|
114
127
|
const headers = createHeaders(onBeforeRequest, graphqlContext);
|
|
115
128
|
telemetry.capture("oss.runtime.remote_action_executed", {});
|
|
116
129
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
130
|
+
try {
|
|
131
|
+
const response = await fetch(`${url}/actions/execute`, {
|
|
132
|
+
method: "POST",
|
|
133
|
+
headers,
|
|
134
|
+
body: JSON.stringify({
|
|
135
|
+
name: action.name,
|
|
136
|
+
arguments: args,
|
|
137
|
+
properties: graphqlContext.properties,
|
|
138
|
+
}),
|
|
139
|
+
});
|
|
126
140
|
|
|
127
|
-
|
|
141
|
+
if (!response.ok) {
|
|
142
|
+
logger.error(
|
|
143
|
+
{ url, status: response.status, body: await response.text() },
|
|
144
|
+
"Failed to execute remote action",
|
|
145
|
+
);
|
|
146
|
+
return "Failed to execute remote action";
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const requestResult = await response.json();
|
|
150
|
+
|
|
151
|
+
const result = requestResult["result"];
|
|
152
|
+
logger.debug({ actionName: action.name, result }, "Executed remote action");
|
|
153
|
+
return result;
|
|
154
|
+
} catch (error) {
|
|
128
155
|
logger.error(
|
|
129
|
-
{
|
|
156
|
+
{ error: error.message ? error.message : error + "" },
|
|
130
157
|
"Failed to execute remote action",
|
|
131
158
|
);
|
|
132
159
|
return "Failed to execute remote action";
|
|
133
160
|
}
|
|
134
|
-
|
|
135
|
-
const requestResult = await response.json();
|
|
136
|
-
|
|
137
|
-
const result = requestResult["result"];
|
|
138
|
-
logger.debug({ actionName: action.name, result }, "Executed remote action");
|
|
139
|
-
return result;
|
|
140
161
|
},
|
|
141
162
|
}));
|
|
142
163
|
|