@copilotkit/runtime 1.4.6 → 1.4.8-coagents-v0-3.1

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 (73) hide show
  1. package/CHANGELOG.md +69 -5
  2. package/__snapshots__/schema/schema.graphql +7 -9
  3. package/dist/{chunk-OKQVDDJ2.mjs → chunk-2PK2SFRB.mjs} +220 -57
  4. package/dist/chunk-2PK2SFRB.mjs.map +1 -0
  5. package/dist/{chunk-37LZS4PV.mjs → chunk-BACNNHHI.mjs} +2 -2
  6. package/dist/{chunk-55FONM7Y.mjs → chunk-FVYNRYIB.mjs} +420 -296
  7. package/dist/chunk-FVYNRYIB.mjs.map +1 -0
  8. package/dist/{chunk-6KZNQI7Z.mjs → chunk-MQJNZYAH.mjs} +2 -2
  9. package/dist/{chunk-B74M7FXG.mjs → chunk-RFF5IIZJ.mjs} +3 -2
  10. package/dist/chunk-RFF5IIZJ.mjs.map +1 -0
  11. package/dist/{chunk-XA3KCJ6P.mjs → chunk-YFG3Q3YH.mjs} +2 -2
  12. package/dist/{copilot-runtime-12e7ac40.d.ts → copilot-runtime-b15b683d.d.ts} +2 -2
  13. package/dist/graphql/types/converted/index.d.ts +1 -1
  14. package/dist/graphql/types/converted/index.js +2 -1
  15. package/dist/graphql/types/converted/index.js.map +1 -1
  16. package/dist/graphql/types/converted/index.mjs +1 -1
  17. package/dist/{groq-adapter-24abe931.d.ts → groq-adapter-50aa9621.d.ts} +1 -1
  18. package/dist/{index-10b1c870.d.ts → index-ff3fbc33.d.ts} +7 -8
  19. package/dist/index.d.ts +4 -4
  20. package/dist/index.js +725 -437
  21. package/dist/index.js.map +1 -1
  22. package/dist/index.mjs +6 -6
  23. package/dist/{langserve-f021ab9c.d.ts → langserve-8ec29cba.d.ts} +51 -12
  24. package/dist/lib/index.d.ts +4 -4
  25. package/dist/lib/index.js +703 -431
  26. package/dist/lib/index.js.map +1 -1
  27. package/dist/lib/index.mjs +6 -6
  28. package/dist/lib/integrations/index.d.ts +4 -4
  29. package/dist/lib/integrations/index.js +71 -30
  30. package/dist/lib/integrations/index.js.map +1 -1
  31. package/dist/lib/integrations/index.mjs +6 -6
  32. package/dist/lib/integrations/nest/index.d.ts +3 -3
  33. package/dist/lib/integrations/nest/index.js +71 -30
  34. package/dist/lib/integrations/nest/index.js.map +1 -1
  35. package/dist/lib/integrations/nest/index.mjs +4 -4
  36. package/dist/lib/integrations/node-express/index.d.ts +3 -3
  37. package/dist/lib/integrations/node-express/index.js +71 -30
  38. package/dist/lib/integrations/node-express/index.js.map +1 -1
  39. package/dist/lib/integrations/node-express/index.mjs +4 -4
  40. package/dist/lib/integrations/node-http/index.d.ts +3 -3
  41. package/dist/lib/integrations/node-http/index.js +71 -30
  42. package/dist/lib/integrations/node-http/index.js.map +1 -1
  43. package/dist/lib/integrations/node-http/index.mjs +3 -3
  44. package/dist/service-adapters/index.d.ts +4 -4
  45. package/dist/service-adapters/index.js +219 -56
  46. package/dist/service-adapters/index.js.map +1 -1
  47. package/dist/service-adapters/index.mjs +1 -1
  48. package/package.json +2 -2
  49. package/src/agents/langgraph/event-source.ts +140 -148
  50. package/src/agents/langgraph/events.ts +1 -1
  51. package/src/graphql/inputs/message.input.ts +15 -3
  52. package/src/graphql/resolvers/copilot.resolver.ts +32 -6
  53. package/src/graphql/types/converted/index.ts +4 -3
  54. package/src/graphql/types/copilot-response.type.ts +12 -3
  55. package/src/graphql/types/enums.ts +0 -11
  56. package/src/lib/runtime/remote-action-constructors.ts +4 -2
  57. package/src/lib/runtime/remote-actions.ts +1 -0
  58. package/src/lib/runtime/remote-lg-action.ts +161 -140
  59. package/src/service-adapters/anthropic/anthropic-adapter.ts +16 -6
  60. package/src/service-adapters/conversion.ts +2 -1
  61. package/src/service-adapters/events.ts +111 -52
  62. package/src/service-adapters/experimental/ollama/ollama-adapter.ts +7 -3
  63. package/src/service-adapters/groq/groq-adapter.ts +23 -8
  64. package/src/service-adapters/langchain/utils.ts +49 -31
  65. package/src/service-adapters/openai/openai-adapter.ts +22 -9
  66. package/src/service-adapters/openai/openai-assistant-adapter.ts +22 -8
  67. package/src/service-adapters/unify/unify-adapter.ts +28 -11
  68. package/dist/chunk-55FONM7Y.mjs.map +0 -1
  69. package/dist/chunk-B74M7FXG.mjs.map +0 -1
  70. package/dist/chunk-OKQVDDJ2.mjs.map +0 -1
  71. /package/dist/{chunk-37LZS4PV.mjs.map → chunk-BACNNHHI.mjs.map} +0 -0
  72. /package/dist/{chunk-6KZNQI7Z.mjs.map → chunk-MQJNZYAH.mjs.map} +0 -0
  73. /package/dist/{chunk-XA3KCJ6P.mjs.map → chunk-YFG3Q3YH.mjs.map} +0 -0
@@ -15,6 +15,8 @@ import { GuardrailsResult } from "../graphql/types/guardrails-result.type";
15
15
  import telemetry from "../lib/telemetry-client";
16
16
  import { isLangGraphAgentAction } from "../lib/runtime/remote-actions";
17
17
  import { ActionInput } from "../graphql/inputs/action.input";
18
+ import { ActionExecutionMessage, ResultMessage } from "../graphql/types/converted";
19
+ import { plainToInstance } from "class-transformer";
18
20
 
19
21
  export enum RuntimeEventTypes {
20
22
  TextMessageStart = "TextMessageStart",
@@ -27,23 +29,22 @@ export enum RuntimeEventTypes {
27
29
  AgentStateMessage = "AgentStateMessage",
28
30
  }
29
31
 
30
- type FunctionCallScope = "client" | "server" | "passThrough";
31
-
32
32
  export type RuntimeEvent =
33
- | { type: RuntimeEventTypes.TextMessageStart; messageId: string }
33
+ | { type: RuntimeEventTypes.TextMessageStart; messageId: string; parentMessageId?: string }
34
34
  | {
35
35
  type: RuntimeEventTypes.TextMessageContent;
36
+ messageId: string;
36
37
  content: string;
37
38
  }
38
- | { type: RuntimeEventTypes.TextMessageEnd }
39
+ | { type: RuntimeEventTypes.TextMessageEnd; messageId: string }
39
40
  | {
40
41
  type: RuntimeEventTypes.ActionExecutionStart;
41
42
  actionExecutionId: string;
42
43
  actionName: string;
43
- scope?: FunctionCallScope;
44
+ parentMessageId?: string;
44
45
  }
45
- | { type: RuntimeEventTypes.ActionExecutionArgs; args: string }
46
- | { type: RuntimeEventTypes.ActionExecutionEnd }
46
+ | { type: RuntimeEventTypes.ActionExecutionArgs; actionExecutionId: string; args: string }
47
+ | { type: RuntimeEventTypes.ActionExecutionEnd; actionExecutionId: string }
47
48
  | {
48
49
  type: RuntimeEventTypes.ActionExecutionResult;
49
50
  actionName: string;
@@ -77,47 +78,86 @@ export class RuntimeEventSubject extends ReplaySubject<RuntimeEvent> {
77
78
  super();
78
79
  }
79
80
 
80
- sendTextMessageStart(messageId: string) {
81
- this.next({ type: RuntimeEventTypes.TextMessageStart, messageId });
81
+ sendTextMessageStart({
82
+ messageId,
83
+ parentMessageId,
84
+ }: {
85
+ messageId: string;
86
+ parentMessageId?: string;
87
+ }) {
88
+ this.next({ type: RuntimeEventTypes.TextMessageStart, messageId, parentMessageId });
82
89
  }
83
90
 
84
- sendTextMessageContent(content: string) {
85
- this.next({ type: RuntimeEventTypes.TextMessageContent, content });
91
+ sendTextMessageContent({ messageId, content }: { messageId: string; content: string }) {
92
+ this.next({ type: RuntimeEventTypes.TextMessageContent, content, messageId });
86
93
  }
87
94
 
88
- sendTextMessageEnd() {
89
- this.next({ type: RuntimeEventTypes.TextMessageEnd });
95
+ sendTextMessageEnd({ messageId }: { messageId: string }) {
96
+ this.next({ type: RuntimeEventTypes.TextMessageEnd, messageId });
90
97
  }
91
98
 
92
99
  sendTextMessage(messageId: string, content: string) {
93
- this.sendTextMessageStart(messageId);
94
- this.sendTextMessageContent(content);
95
- this.sendTextMessageEnd();
100
+ this.sendTextMessageStart({ messageId });
101
+ this.sendTextMessageContent({ messageId, content });
102
+ this.sendTextMessageEnd({ messageId });
96
103
  }
97
104
 
98
- sendActionExecutionStart(actionExecutionId: string, actionName: string) {
105
+ sendActionExecutionStart({
106
+ actionExecutionId,
107
+ actionName,
108
+ parentMessageId,
109
+ }: {
110
+ actionExecutionId: string;
111
+ actionName: string;
112
+ parentMessageId?: string;
113
+ }) {
99
114
  this.next({
100
115
  type: RuntimeEventTypes.ActionExecutionStart,
101
116
  actionExecutionId,
102
117
  actionName,
118
+ parentMessageId,
103
119
  });
104
120
  }
105
121
 
106
- sendActionExecutionArgs(args: string) {
107
- this.next({ type: RuntimeEventTypes.ActionExecutionArgs, args });
122
+ sendActionExecutionArgs({
123
+ actionExecutionId,
124
+ args,
125
+ }: {
126
+ actionExecutionId: string;
127
+ args: string;
128
+ }) {
129
+ this.next({ type: RuntimeEventTypes.ActionExecutionArgs, args, actionExecutionId });
108
130
  }
109
131
 
110
- sendActionExecutionEnd() {
111
- this.next({ type: RuntimeEventTypes.ActionExecutionEnd });
132
+ sendActionExecutionEnd({ actionExecutionId }: { actionExecutionId: string }) {
133
+ this.next({ type: RuntimeEventTypes.ActionExecutionEnd, actionExecutionId });
112
134
  }
113
135
 
114
- sendActionExecution(actionExecutionId: string, toolName: string, args: string) {
115
- this.sendActionExecutionStart(actionExecutionId, toolName);
116
- this.sendActionExecutionArgs(args);
117
- this.sendActionExecutionEnd();
136
+ sendActionExecution({
137
+ actionExecutionId,
138
+ actionName,
139
+ args,
140
+ parentMessageId,
141
+ }: {
142
+ actionExecutionId: string;
143
+ actionName: string;
144
+ args: string;
145
+ parentMessageId?: string;
146
+ }) {
147
+ this.sendActionExecutionStart({ actionExecutionId, actionName, parentMessageId });
148
+ this.sendActionExecutionArgs({ actionExecutionId, args });
149
+ this.sendActionExecutionEnd({ actionExecutionId });
118
150
  }
119
151
 
120
- sendActionExecutionResult(actionExecutionId: string, actionName: string, result: string) {
152
+ sendActionExecutionResult({
153
+ actionExecutionId,
154
+ actionName,
155
+ result,
156
+ }: {
157
+ actionExecutionId: string;
158
+ actionName: string;
159
+ result: string;
160
+ }) {
121
161
  this.next({
122
162
  type: RuntimeEventTypes.ActionExecutionResult,
123
163
  actionName,
@@ -126,16 +166,25 @@ export class RuntimeEventSubject extends ReplaySubject<RuntimeEvent> {
126
166
  });
127
167
  }
128
168
 
129
- sendAgentStateMessage(
130
- threadId: string,
131
- agentName: string,
132
- nodeName: string,
133
- runId: string,
134
- active: boolean,
135
- role: string,
136
- state: string,
137
- running: boolean,
138
- ) {
169
+ sendAgentStateMessage({
170
+ threadId,
171
+ agentName,
172
+ nodeName,
173
+ runId,
174
+ active,
175
+ role,
176
+ state,
177
+ running,
178
+ }: {
179
+ threadId: string;
180
+ agentName: string;
181
+ nodeName: string;
182
+ runId: string;
183
+ active: boolean;
184
+ role: string;
185
+ state: string;
186
+ running: boolean;
187
+ }) {
139
188
  this.next({
140
189
  type: RuntimeEventTypes.AgentStateMessage,
141
190
  threadId,
@@ -183,17 +232,6 @@ export class RuntimeEventSource {
183
232
  this.sendErrorMessageToChat();
184
233
  });
185
234
  return this.eventStream$.pipe(
186
- // mark tools for server side execution
187
- map((event) => {
188
- if (event.type === RuntimeEventTypes.ActionExecutionStart) {
189
- if (event.scope !== "passThrough") {
190
- event.scope = serverSideActions.find((action) => action.name === event.actionName)
191
- ? "server"
192
- : "client";
193
- }
194
- }
195
- return event;
196
- }),
197
235
  // track state
198
236
  scan(
199
237
  (acc, event) => {
@@ -203,7 +241,8 @@ export class RuntimeEventSource {
203
241
  acc = { ...acc };
204
242
 
205
243
  if (event.type === RuntimeEventTypes.ActionExecutionStart) {
206
- acc.callActionServerSide = event.scope === "server";
244
+ acc.callActionServerSide =
245
+ serverSideActions.find((action) => action.name === event.actionName) !== undefined;
207
246
  acc.args = "";
208
247
  acc.actionExecutionId = event.actionExecutionId;
209
248
  if (acc.callActionServerSide) {
@@ -281,14 +320,34 @@ async function executeAction(
281
320
 
282
321
  // handle LangGraph agents
283
322
  if (isLangGraphAgentAction(action)) {
284
- eventStream$.sendActionExecutionResult(
323
+ const result = `${action.name} agent started`;
324
+
325
+ const agentExecution = plainToInstance(ActionExecutionMessage, {
326
+ id: actionExecutionId,
327
+ createdAt: new Date(),
328
+ name: action.name,
329
+ arguments: JSON.parse(actionArguments),
330
+ parentMessageId: actionExecutionId,
331
+ });
332
+
333
+ const agentExecutionResult = plainToInstance(ResultMessage, {
334
+ id: "result-" + actionExecutionId,
335
+ createdAt: new Date(),
285
336
  actionExecutionId,
286
- action.name,
287
- `${action.name} agent started`,
288
- );
337
+ actionName: action.name,
338
+ result,
339
+ });
340
+
341
+ eventStream$.sendActionExecutionResult({
342
+ actionExecutionId,
343
+ actionName: action.name,
344
+ result,
345
+ });
346
+
289
347
  const stream = await action.langGraphAgentHandler({
290
348
  name: action.name,
291
349
  actionInputsWithoutAgents,
350
+ additionalMessages: [agentExecution, agentExecutionResult],
292
351
  });
293
352
 
294
353
  // forward to eventStream$
@@ -58,11 +58,15 @@ export class ExperimentalOllamaAdapter implements CopilotServiceAdapter {
58
58
  const _stream = await ollama.stream(contents); // [TODO] role info is dropped...
59
59
 
60
60
  eventSource.stream(async (eventStream$) => {
61
- eventStream$.sendTextMessageStart(randomId());
61
+ const currentMessageId = randomId();
62
+ eventStream$.sendTextMessageStart({ messageId: currentMessageId });
62
63
  for await (const chunkText of _stream) {
63
- eventStream$.sendTextMessageContent(chunkText);
64
+ eventStream$.sendTextMessageContent({
65
+ messageId: currentMessageId,
66
+ content: chunkText,
67
+ });
64
68
  }
65
- eventStream$.sendTextMessageEnd();
69
+ eventStream$.sendTextMessageEnd({ messageId: currentMessageId });
66
70
  // we may need to add this later.. [nc]
67
71
  // let calls = (await result.response).functionCalls();
68
72
 
@@ -106,6 +106,9 @@ export class GroqAdapter implements CopilotServiceAdapter {
106
106
 
107
107
  eventSource.stream(async (eventStream$) => {
108
108
  let mode: "function" | "message" | null = null;
109
+ let currentMessageId: string;
110
+ let currentToolCallId: string;
111
+
109
112
  for await (const chunk of stream) {
110
113
  const toolCall = chunk.choices[0].delta.tool_calls?.[0];
111
114
  const content = chunk.choices[0].delta.content;
@@ -115,36 +118,48 @@ export class GroqAdapter implements CopilotServiceAdapter {
115
118
  // If toolCall?.id is defined, it means a new tool call starts.
116
119
  if (mode === "message" && toolCall?.id) {
117
120
  mode = null;
118
- eventStream$.sendTextMessageEnd();
121
+ eventStream$.sendTextMessageEnd({ messageId: currentMessageId });
119
122
  } else if (mode === "function" && (toolCall === undefined || toolCall?.id)) {
120
123
  mode = null;
121
- eventStream$.sendActionExecutionEnd();
124
+ eventStream$.sendActionExecutionEnd({ actionExecutionId: currentToolCallId });
122
125
  }
123
126
 
124
127
  // If we send a new message type, send the appropriate start event.
125
128
  if (mode === null) {
126
129
  if (toolCall?.id) {
127
130
  mode = "function";
128
- eventStream$.sendActionExecutionStart(toolCall!.id, toolCall!.function!.name);
131
+ currentToolCallId = toolCall!.id;
132
+ eventStream$.sendActionExecutionStart({
133
+ actionExecutionId: currentToolCallId,
134
+ actionName: toolCall!.function!.name,
135
+ parentMessageId: chunk.id,
136
+ });
129
137
  } else if (content) {
130
138
  mode = "message";
131
- eventStream$.sendTextMessageStart(chunk.id);
139
+ currentMessageId = chunk.id;
140
+ eventStream$.sendTextMessageStart({ messageId: currentMessageId });
132
141
  }
133
142
  }
134
143
 
135
144
  // send the content events
136
145
  if (mode === "message" && content) {
137
- eventStream$.sendTextMessageContent(content);
146
+ eventStream$.sendTextMessageContent({
147
+ messageId: currentMessageId,
148
+ content,
149
+ });
138
150
  } else if (mode === "function" && toolCall?.function?.arguments) {
139
- eventStream$.sendActionExecutionArgs(toolCall.function.arguments);
151
+ eventStream$.sendActionExecutionArgs({
152
+ actionExecutionId: currentToolCallId,
153
+ args: toolCall.function.arguments,
154
+ });
140
155
  }
141
156
  }
142
157
 
143
158
  // send the end events
144
159
  if (mode === "message") {
145
- eventStream$.sendTextMessageEnd();
160
+ eventStream$.sendTextMessageEnd({ messageId: currentMessageId });
146
161
  } else if (mode === "function") {
147
- eventStream$.sendActionExecutionEnd();
162
+ eventStream$.sendActionExecutionEnd({ actionExecutionId: currentToolCallId });
148
163
  }
149
164
 
150
165
  eventStream$.complete();
@@ -97,11 +97,11 @@ function maybeSendActionExecutionResultIsMessage(
97
97
  // language models need a result after the function call
98
98
  // we simply let them know that we are sending a message
99
99
  if (actionExecution) {
100
- eventStream$.sendActionExecutionResult(
101
- actionExecution.id,
102
- actionExecution.name,
103
- "Sending a message",
104
- );
100
+ eventStream$.sendActionExecutionResult({
101
+ actionExecutionId: actionExecution.id,
102
+ actionName: actionExecution.name,
103
+ result: "Sending a message",
104
+ });
105
105
  }
106
106
  }
107
107
 
@@ -120,7 +120,11 @@ export async function streamLangChainResponse({
120
120
  eventStream$.sendTextMessage(randomId(), result);
121
121
  } else {
122
122
  // Send as a result
123
- eventStream$.sendActionExecutionResult(actionExecution.id, actionExecution.name, result);
123
+ eventStream$.sendActionExecutionResult({
124
+ actionExecutionId: actionExecution.id,
125
+ actionName: actionExecution.name,
126
+ result: result,
127
+ });
124
128
  }
125
129
  }
126
130
 
@@ -133,11 +137,11 @@ export async function streamLangChainResponse({
133
137
  eventStream$.sendTextMessage(randomId(), result.content as string);
134
138
  }
135
139
  for (const toolCall of result.tool_calls) {
136
- eventStream$.sendActionExecution(
137
- toolCall.id || randomId(),
138
- toolCall.name,
139
- JSON.stringify(toolCall.args),
140
- );
140
+ eventStream$.sendActionExecution({
141
+ actionExecutionId: toolCall.id || randomId(),
142
+ actionName: toolCall.name,
143
+ args: JSON.stringify(toolCall.args),
144
+ });
141
145
  }
142
146
  }
143
147
 
@@ -151,11 +155,11 @@ export async function streamLangChainResponse({
151
155
  }
152
156
  if (result.lc_kwargs?.tool_calls) {
153
157
  for (const toolCall of result.lc_kwargs?.tool_calls) {
154
- eventStream$.sendActionExecution(
155
- toolCall.id || randomId(),
156
- toolCall.name,
157
- JSON.stringify(toolCall.args),
158
- );
158
+ eventStream$.sendActionExecution({
159
+ actionExecutionId: toolCall.id || randomId(),
160
+ actionName: toolCall.name,
161
+ args: JSON.stringify(toolCall.args),
162
+ });
159
163
  }
160
164
  }
161
165
  }
@@ -168,6 +172,7 @@ export async function streamLangChainResponse({
168
172
  let reader = result.getReader();
169
173
 
170
174
  let mode: "function" | "message" | null = null;
175
+ let currentMessageId: string;
171
176
 
172
177
  const toolCallDetails = {
173
178
  name: null,
@@ -216,10 +221,10 @@ export async function streamLangChainResponse({
216
221
  // If toolCallName is defined, it means a new tool call starts.
217
222
  if (mode === "message" && (toolCallId || done)) {
218
223
  mode = null;
219
- eventStream$.sendTextMessageEnd();
224
+ eventStream$.sendTextMessageEnd({ messageId: currentMessageId });
220
225
  } else if (mode === "function" && (!hasToolCall || done)) {
221
226
  mode = null;
222
- eventStream$.sendActionExecutionEnd();
227
+ eventStream$.sendActionExecutionEnd({ actionExecutionId: toolCallId });
223
228
  }
224
229
 
225
230
  if (done) {
@@ -230,26 +235,39 @@ export async function streamLangChainResponse({
230
235
  if (mode === null) {
231
236
  if (hasToolCall && toolCallId && toolCallName) {
232
237
  mode = "function";
233
- eventStream$.sendActionExecutionStart(toolCallId, toolCallName);
238
+ eventStream$.sendActionExecutionStart({
239
+ actionExecutionId: toolCallId,
240
+ actionName: toolCallName,
241
+ parentMessageId: value.lc_kwargs?.id,
242
+ });
234
243
  } else if (content) {
235
244
  mode = "message";
236
- eventStream$.sendTextMessageStart(randomId());
245
+ currentMessageId = value.lc_kwargs?.id || randomId();
246
+ eventStream$.sendTextMessageStart({ messageId: currentMessageId });
237
247
  }
238
248
  }
239
249
 
240
250
  // send the content events
241
251
  if (mode === "message" && content) {
242
- eventStream$.sendTextMessageContent(
243
- Array.isArray(content) ? (content[0]?.text ?? "") : content,
244
- );
252
+ eventStream$.sendTextMessageContent({
253
+ messageId: currentMessageId,
254
+ content: Array.isArray(content) ? (content[0]?.text ?? "") : content,
255
+ });
245
256
  } else if (mode === "function" && toolCallArgs) {
246
257
  // For calls of the same tool with different index, we seal last tool call and register a new one
247
258
  if (toolCallDetails.index !== toolCallDetails.prevIndex) {
248
- eventStream$.sendActionExecutionEnd();
249
- eventStream$.sendActionExecutionStart(toolCallId, toolCallName);
259
+ eventStream$.sendActionExecutionEnd({ actionExecutionId: toolCallId });
260
+ eventStream$.sendActionExecutionStart({
261
+ actionExecutionId: toolCallId,
262
+ actionName: toolCallName,
263
+ parentMessageId: value.lc_kwargs?.id,
264
+ });
250
265
  toolCallDetails.prevIndex = toolCallDetails.index;
251
266
  }
252
- eventStream$.sendActionExecutionArgs(toolCallArgs);
267
+ eventStream$.sendActionExecutionArgs({
268
+ actionExecutionId: toolCallId,
269
+ args: toolCallArgs,
270
+ });
253
271
  }
254
272
  } catch (error) {
255
273
  console.error("Error reading from stream", error);
@@ -257,11 +275,11 @@ export async function streamLangChainResponse({
257
275
  }
258
276
  }
259
277
  } else if (actionExecution) {
260
- eventStream$.sendActionExecutionResult(
261
- actionExecution.id,
262
- actionExecution.name,
263
- encodeResult(result),
264
- );
278
+ eventStream$.sendActionExecutionResult({
279
+ actionExecutionId: actionExecution.id,
280
+ actionName: actionExecution.name,
281
+ result: encodeResult(result),
282
+ });
265
283
  }
266
284
 
267
285
  // unsupported type
@@ -140,7 +140,8 @@ export class OpenAIAdapter implements CopilotServiceAdapter {
140
140
 
141
141
  eventSource.stream(async (eventStream$) => {
142
142
  let mode: "function" | "message" | null = null;
143
-
143
+ let currentMessageId: string;
144
+ let currentToolCallId: string;
144
145
  for await (const chunk of stream) {
145
146
  if (chunk.choices.length === 0) {
146
147
  continue;
@@ -154,36 +155,48 @@ export class OpenAIAdapter implements CopilotServiceAdapter {
154
155
  // If toolCall?.id is defined, it means a new tool call starts.
155
156
  if (mode === "message" && toolCall?.id) {
156
157
  mode = null;
157
- eventStream$.sendTextMessageEnd();
158
+ eventStream$.sendTextMessageEnd({ messageId: currentMessageId });
158
159
  } else if (mode === "function" && (toolCall === undefined || toolCall?.id)) {
159
160
  mode = null;
160
- eventStream$.sendActionExecutionEnd();
161
+ eventStream$.sendActionExecutionEnd({ actionExecutionId: currentToolCallId });
161
162
  }
162
163
 
163
164
  // If we send a new message type, send the appropriate start event.
164
165
  if (mode === null) {
165
166
  if (toolCall?.id) {
166
167
  mode = "function";
167
- eventStream$.sendActionExecutionStart(toolCall!.id, toolCall!.function!.name);
168
+ currentToolCallId = toolCall!.id;
169
+ eventStream$.sendActionExecutionStart({
170
+ actionExecutionId: currentToolCallId,
171
+ parentMessageId: chunk.id,
172
+ actionName: toolCall!.function!.name,
173
+ });
168
174
  } else if (content) {
169
175
  mode = "message";
170
- eventStream$.sendTextMessageStart(chunk.id);
176
+ currentMessageId = chunk.id;
177
+ eventStream$.sendTextMessageStart({ messageId: currentMessageId });
171
178
  }
172
179
  }
173
180
 
174
181
  // send the content events
175
182
  if (mode === "message" && content) {
176
- eventStream$.sendTextMessageContent(content);
183
+ eventStream$.sendTextMessageContent({
184
+ messageId: currentMessageId,
185
+ content: content,
186
+ });
177
187
  } else if (mode === "function" && toolCall?.function?.arguments) {
178
- eventStream$.sendActionExecutionArgs(toolCall.function.arguments);
188
+ eventStream$.sendActionExecutionArgs({
189
+ actionExecutionId: currentToolCallId,
190
+ args: toolCall.function.arguments,
191
+ });
179
192
  }
180
193
  }
181
194
 
182
195
  // send the end events
183
196
  if (mode === "message") {
184
- eventStream$.sendTextMessageEnd();
197
+ eventStream$.sendTextMessageEnd({ messageId: currentMessageId });
185
198
  } else if (mode === "function") {
186
- eventStream$.sendActionExecutionEnd();
199
+ eventStream$.sendActionExecutionEnd({ actionExecutionId: currentToolCallId });
187
200
  }
188
201
 
189
202
  eventStream$.complete();
@@ -226,22 +226,28 @@ export class OpenAIAssistantAdapter implements CopilotServiceAdapter {
226
226
  private async streamResponse(stream: AssistantStream, eventSource: RuntimeEventSource) {
227
227
  eventSource.stream(async (eventStream$) => {
228
228
  let inFunctionCall = false;
229
+ let currentMessageId: string;
230
+ let currentToolCallId: string;
229
231
 
230
232
  for await (const chunk of stream) {
231
233
  switch (chunk.event) {
232
234
  case "thread.message.created":
233
235
  if (inFunctionCall) {
234
- eventStream$.sendActionExecutionEnd();
236
+ eventStream$.sendActionExecutionEnd({ actionExecutionId: currentToolCallId });
235
237
  }
236
- eventStream$.sendTextMessageStart(chunk.data.id);
238
+ currentMessageId = chunk.data.id;
239
+ eventStream$.sendTextMessageStart({ messageId: currentMessageId });
237
240
  break;
238
241
  case "thread.message.delta":
239
242
  if (chunk.data.delta.content?.[0].type === "text") {
240
- eventStream$.sendTextMessageContent(chunk.data.delta.content?.[0].text.value);
243
+ eventStream$.sendTextMessageContent({
244
+ messageId: currentMessageId,
245
+ content: chunk.data.delta.content?.[0].text.value,
246
+ });
241
247
  }
242
248
  break;
243
249
  case "thread.message.completed":
244
- eventStream$.sendTextMessageEnd();
250
+ eventStream$.sendTextMessageEnd({ messageId: currentMessageId });
245
251
  break;
246
252
  case "thread.run.step.delta":
247
253
  let toolCallId: string | undefined;
@@ -258,18 +264,26 @@ export class OpenAIAssistantAdapter implements CopilotServiceAdapter {
258
264
 
259
265
  if (toolCallName && toolCallId) {
260
266
  if (inFunctionCall) {
261
- eventStream$.sendActionExecutionEnd();
267
+ eventStream$.sendActionExecutionEnd({ actionExecutionId: currentToolCallId });
262
268
  }
263
269
  inFunctionCall = true;
264
- eventStream$.sendActionExecutionStart(toolCallId, toolCallName);
270
+ currentToolCallId = toolCallId;
271
+ eventStream$.sendActionExecutionStart({
272
+ actionExecutionId: currentToolCallId,
273
+ parentMessageId: chunk.data.id,
274
+ actionName: toolCallName,
275
+ });
265
276
  } else if (toolCallArgs) {
266
- eventStream$.sendActionExecutionArgs(toolCallArgs);
277
+ eventStream$.sendActionExecutionArgs({
278
+ actionExecutionId: currentToolCallId,
279
+ args: toolCallArgs,
280
+ });
267
281
  }
268
282
  break;
269
283
  }
270
284
  }
271
285
  if (inFunctionCall) {
272
- eventStream$.sendActionExecutionEnd();
286
+ eventStream$.sendActionExecutionEnd({ actionExecutionId: currentToolCallId });
273
287
  }
274
288
  eventStream$.complete();
275
289
  });