@copilotkit/runtime 1.5.0-tyler-reset-chat.0 → 1.5.1-custom-tag-pre.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.
Files changed (78) hide show
  1. package/CHANGELOG.md +150 -3
  2. package/__snapshots__/schema/schema.graphql +8 -9
  3. package/dist/{chunk-K67A6XOJ.mjs → chunk-3ECBC2K2.mjs} +462 -328
  4. package/dist/chunk-3ECBC2K2.mjs.map +1 -0
  5. package/dist/{chunk-QNQ6UT3D.mjs → chunk-5E6LOP76.mjs} +2 -2
  6. package/dist/{chunk-OKQVDDJ2.mjs → chunk-CLGKEUOA.mjs} +298 -63
  7. package/dist/chunk-CLGKEUOA.mjs.map +1 -0
  8. package/dist/{chunk-ZBG4KJW5.mjs → chunk-MKDG5ZHT.mjs} +2 -2
  9. package/dist/{chunk-AGSBOD2T.mjs → chunk-MYZB2EKG.mjs} +2 -2
  10. package/dist/{chunk-B74M7FXG.mjs → chunk-RFF5IIZJ.mjs} +3 -2
  11. package/dist/chunk-RFF5IIZJ.mjs.map +1 -0
  12. package/dist/{copilot-runtime-12e7ac40.d.ts → copilot-runtime-6285d897.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-15d41154.d.ts} +1 -1
  18. package/dist/{index-10b1c870.d.ts → index-ff3fbc33.d.ts} +7 -8
  19. package/dist/index.d.ts +5 -5
  20. package/dist/index.js +852 -480
  21. package/dist/index.js.map +1 -1
  22. package/dist/index.mjs +10 -6
  23. package/dist/index.mjs.map +1 -1
  24. package/dist/{langserve-f021ab9c.d.ts → langserve-48e976ac.d.ts} +54 -14
  25. package/dist/lib/index.d.ts +4 -4
  26. package/dist/lib/index.js +754 -459
  27. package/dist/lib/index.js.map +1 -1
  28. package/dist/lib/index.mjs +6 -6
  29. package/dist/lib/integrations/index.d.ts +4 -4
  30. package/dist/lib/integrations/index.js +78 -30
  31. package/dist/lib/integrations/index.js.map +1 -1
  32. package/dist/lib/integrations/index.mjs +6 -6
  33. package/dist/lib/integrations/nest/index.d.ts +3 -3
  34. package/dist/lib/integrations/nest/index.js +78 -30
  35. package/dist/lib/integrations/nest/index.js.map +1 -1
  36. package/dist/lib/integrations/nest/index.mjs +4 -4
  37. package/dist/lib/integrations/node-express/index.d.ts +3 -3
  38. package/dist/lib/integrations/node-express/index.js +78 -30
  39. package/dist/lib/integrations/node-express/index.js.map +1 -1
  40. package/dist/lib/integrations/node-express/index.mjs +4 -4
  41. package/dist/lib/integrations/node-http/index.d.ts +3 -3
  42. package/dist/lib/integrations/node-http/index.js +78 -30
  43. package/dist/lib/integrations/node-http/index.js.map +1 -1
  44. package/dist/lib/integrations/node-http/index.mjs +3 -3
  45. package/dist/service-adapters/index.d.ts +36 -5
  46. package/dist/service-adapters/index.js +298 -61
  47. package/dist/service-adapters/index.js.map +1 -1
  48. package/dist/service-adapters/index.mjs +5 -1
  49. package/package.json +4 -4
  50. package/src/agents/langgraph/event-source.ts +140 -148
  51. package/src/agents/langgraph/events.ts +1 -1
  52. package/src/graphql/inputs/forwarded-parameters.input.ts +3 -0
  53. package/src/graphql/inputs/message.input.ts +15 -3
  54. package/src/graphql/resolvers/copilot.resolver.ts +32 -6
  55. package/src/graphql/types/converted/index.ts +4 -3
  56. package/src/graphql/types/copilot-response.type.ts +12 -3
  57. package/src/graphql/types/enums.ts +0 -11
  58. package/src/lib/runtime/copilot-runtime.ts +1 -7
  59. package/src/lib/runtime/remote-action-constructors.ts +64 -58
  60. package/src/lib/runtime/remote-actions.ts +1 -0
  61. package/src/lib/runtime/remote-lg-action.ts +184 -154
  62. package/src/service-adapters/anthropic/anthropic-adapter.ts +17 -6
  63. package/src/service-adapters/conversion.ts +2 -1
  64. package/src/service-adapters/events.ts +118 -54
  65. package/src/service-adapters/experimental/empty/empty-adapter.ts +33 -0
  66. package/src/service-adapters/experimental/ollama/ollama-adapter.ts +7 -3
  67. package/src/service-adapters/groq/groq-adapter.ts +24 -8
  68. package/src/service-adapters/index.ts +7 -1
  69. package/src/service-adapters/langchain/utils.ts +55 -32
  70. package/src/service-adapters/openai/openai-adapter.ts +23 -9
  71. package/src/service-adapters/openai/openai-assistant-adapter.ts +22 -8
  72. package/src/service-adapters/unify/unify-adapter.ts +30 -11
  73. package/dist/chunk-B74M7FXG.mjs.map +0 -1
  74. package/dist/chunk-K67A6XOJ.mjs.map +0 -1
  75. package/dist/chunk-OKQVDDJ2.mjs.map +0 -1
  76. /package/dist/{chunk-QNQ6UT3D.mjs.map → chunk-5E6LOP76.mjs.map} +0 -0
  77. /package/dist/{chunk-ZBG4KJW5.mjs.map → chunk-MKDG5ZHT.mjs.map} +0 -0
  78. /package/dist/{chunk-AGSBOD2T.mjs.map → chunk-MYZB2EKG.mjs.map} +0 -0
@@ -98,6 +98,7 @@ export class AnthropicAdapter implements CopilotServiceAdapter {
98
98
  model: this.model,
99
99
  messages: anthropicMessages,
100
100
  max_tokens: forwardedParameters?.maxTokens || 1024,
101
+ ...(forwardedParameters?.temperature ? { temperature: forwardedParameters.temperature } : {}),
101
102
  ...(tools.length > 0 && { tools }),
102
103
  ...(toolChoice && { tool_choice: toolChoice }),
103
104
  stream: true,
@@ -120,7 +121,11 @@ export class AnthropicAdapter implements CopilotServiceAdapter {
120
121
  mode = "message";
121
122
  } else if (chunk.content_block.type === "tool_use") {
122
123
  currentToolCallId = chunk.content_block.id;
123
- eventStream$.sendActionExecutionStart(currentToolCallId, chunk.content_block.name);
124
+ eventStream$.sendActionExecutionStart({
125
+ actionExecutionId: currentToolCallId,
126
+ actionName: chunk.content_block.name,
127
+ parentMessageId: currentMessageId,
128
+ });
124
129
  mode = "function";
125
130
  }
126
131
  } else if (chunk.type === "content_block_delta") {
@@ -128,21 +133,27 @@ export class AnthropicAdapter implements CopilotServiceAdapter {
128
133
  const text = filterThinkingTextBuffer.onTextChunk(chunk.delta.text);
129
134
  if (text.length > 0) {
130
135
  if (!didOutputText) {
131
- eventStream$.sendTextMessageStart(currentMessageId);
136
+ eventStream$.sendTextMessageStart({ messageId: currentMessageId });
132
137
  didOutputText = true;
133
138
  }
134
- eventStream$.sendTextMessageContent(text);
139
+ eventStream$.sendTextMessageContent({
140
+ messageId: currentMessageId,
141
+ content: text,
142
+ });
135
143
  }
136
144
  } else if (chunk.delta.type === "input_json_delta") {
137
- eventStream$.sendActionExecutionArgs(chunk.delta.partial_json);
145
+ eventStream$.sendActionExecutionArgs({
146
+ actionExecutionId: currentToolCallId,
147
+ args: chunk.delta.partial_json,
148
+ });
138
149
  }
139
150
  } else if (chunk.type === "content_block_stop") {
140
151
  if (mode === "message") {
141
152
  if (didOutputText) {
142
- eventStream$.sendTextMessageEnd();
153
+ eventStream$.sendTextMessageEnd({ messageId: currentMessageId });
143
154
  }
144
155
  } else if (mode === "function") {
145
- eventStream$.sendActionExecutionEnd();
156
+ eventStream$.sendActionExecutionEnd({ actionExecutionId: currentToolCallId });
146
157
  }
147
158
  }
148
159
  }
@@ -19,6 +19,7 @@ export function convertGqlInputToMessages(inputMessages: MessageInput[]): Messag
19
19
  createdAt: message.createdAt,
20
20
  role: message.textMessage.role,
21
21
  content: message.textMessage.content,
22
+ parentMessageId: message.textMessage.parentMessageId,
22
23
  }),
23
24
  );
24
25
  } else if (message.actionExecutionMessage) {
@@ -28,7 +29,7 @@ export function convertGqlInputToMessages(inputMessages: MessageInput[]): Messag
28
29
  createdAt: message.createdAt,
29
30
  name: message.actionExecutionMessage.name,
30
31
  arguments: JSON.parse(message.actionExecutionMessage.arguments),
31
- scope: message.actionExecutionMessage.scope,
32
+ parentMessageId: message.actionExecutionMessage.parentMessageId,
32
33
  }),
33
34
  );
34
35
  } else if (message.resultMessage) {
@@ -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;
@@ -68,6 +69,7 @@ interface RuntimeEventWithState {
68
69
  action: Action<any> | null;
69
70
  actionExecutionId: string | null;
70
71
  args: string;
72
+ actionExecutionParentMessageId: string | null;
71
73
  }
72
74
 
73
75
  type EventSourceCallback = (eventStream$: RuntimeEventSubject) => Promise<void>;
@@ -77,47 +79,86 @@ export class RuntimeEventSubject extends ReplaySubject<RuntimeEvent> {
77
79
  super();
78
80
  }
79
81
 
80
- sendTextMessageStart(messageId: string) {
81
- this.next({ type: RuntimeEventTypes.TextMessageStart, messageId });
82
+ sendTextMessageStart({
83
+ messageId,
84
+ parentMessageId,
85
+ }: {
86
+ messageId: string;
87
+ parentMessageId?: string;
88
+ }) {
89
+ this.next({ type: RuntimeEventTypes.TextMessageStart, messageId, parentMessageId });
82
90
  }
83
91
 
84
- sendTextMessageContent(content: string) {
85
- this.next({ type: RuntimeEventTypes.TextMessageContent, content });
92
+ sendTextMessageContent({ messageId, content }: { messageId: string; content: string }) {
93
+ this.next({ type: RuntimeEventTypes.TextMessageContent, content, messageId });
86
94
  }
87
95
 
88
- sendTextMessageEnd() {
89
- this.next({ type: RuntimeEventTypes.TextMessageEnd });
96
+ sendTextMessageEnd({ messageId }: { messageId: string }) {
97
+ this.next({ type: RuntimeEventTypes.TextMessageEnd, messageId });
90
98
  }
91
99
 
92
100
  sendTextMessage(messageId: string, content: string) {
93
- this.sendTextMessageStart(messageId);
94
- this.sendTextMessageContent(content);
95
- this.sendTextMessageEnd();
101
+ this.sendTextMessageStart({ messageId });
102
+ this.sendTextMessageContent({ messageId, content });
103
+ this.sendTextMessageEnd({ messageId });
96
104
  }
97
105
 
98
- sendActionExecutionStart(actionExecutionId: string, actionName: string) {
106
+ sendActionExecutionStart({
107
+ actionExecutionId,
108
+ actionName,
109
+ parentMessageId,
110
+ }: {
111
+ actionExecutionId: string;
112
+ actionName: string;
113
+ parentMessageId?: string;
114
+ }) {
99
115
  this.next({
100
116
  type: RuntimeEventTypes.ActionExecutionStart,
101
117
  actionExecutionId,
102
118
  actionName,
119
+ parentMessageId,
103
120
  });
104
121
  }
105
122
 
106
- sendActionExecutionArgs(args: string) {
107
- this.next({ type: RuntimeEventTypes.ActionExecutionArgs, args });
123
+ sendActionExecutionArgs({
124
+ actionExecutionId,
125
+ args,
126
+ }: {
127
+ actionExecutionId: string;
128
+ args: string;
129
+ }) {
130
+ this.next({ type: RuntimeEventTypes.ActionExecutionArgs, args, actionExecutionId });
108
131
  }
109
132
 
110
- sendActionExecutionEnd() {
111
- this.next({ type: RuntimeEventTypes.ActionExecutionEnd });
133
+ sendActionExecutionEnd({ actionExecutionId }: { actionExecutionId: string }) {
134
+ this.next({ type: RuntimeEventTypes.ActionExecutionEnd, actionExecutionId });
112
135
  }
113
136
 
114
- sendActionExecution(actionExecutionId: string, toolName: string, args: string) {
115
- this.sendActionExecutionStart(actionExecutionId, toolName);
116
- this.sendActionExecutionArgs(args);
117
- this.sendActionExecutionEnd();
137
+ sendActionExecution({
138
+ actionExecutionId,
139
+ actionName,
140
+ args,
141
+ parentMessageId,
142
+ }: {
143
+ actionExecutionId: string;
144
+ actionName: string;
145
+ args: string;
146
+ parentMessageId?: string;
147
+ }) {
148
+ this.sendActionExecutionStart({ actionExecutionId, actionName, parentMessageId });
149
+ this.sendActionExecutionArgs({ actionExecutionId, args });
150
+ this.sendActionExecutionEnd({ actionExecutionId });
118
151
  }
119
152
 
120
- sendActionExecutionResult(actionExecutionId: string, actionName: string, result: string) {
153
+ sendActionExecutionResult({
154
+ actionExecutionId,
155
+ actionName,
156
+ result,
157
+ }: {
158
+ actionExecutionId: string;
159
+ actionName: string;
160
+ result: string;
161
+ }) {
121
162
  this.next({
122
163
  type: RuntimeEventTypes.ActionExecutionResult,
123
164
  actionName,
@@ -126,16 +167,25 @@ export class RuntimeEventSubject extends ReplaySubject<RuntimeEvent> {
126
167
  });
127
168
  }
128
169
 
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
- ) {
170
+ sendAgentStateMessage({
171
+ threadId,
172
+ agentName,
173
+ nodeName,
174
+ runId,
175
+ active,
176
+ role,
177
+ state,
178
+ running,
179
+ }: {
180
+ threadId: string;
181
+ agentName: string;
182
+ nodeName: string;
183
+ runId: string;
184
+ active: boolean;
185
+ role: string;
186
+ state: string;
187
+ running: boolean;
188
+ }) {
139
189
  this.next({
140
190
  type: RuntimeEventTypes.AgentStateMessage,
141
191
  threadId,
@@ -158,8 +208,8 @@ export class RuntimeEventSource {
158
208
  this.callback = callback;
159
209
  }
160
210
 
161
- sendErrorMessageToChat() {
162
- const errorMessage = "❌ An error occurred. Please try again.";
211
+ sendErrorMessageToChat(message = "An error occurred. Please try again.") {
212
+ const errorMessage = `❌ ${message}`;
163
213
  if (!this.callback) {
164
214
  this.stream(async (eventStream$) => {
165
215
  eventStream$.sendTextMessage(randomId(), errorMessage);
@@ -183,17 +233,6 @@ export class RuntimeEventSource {
183
233
  this.sendErrorMessageToChat();
184
234
  });
185
235
  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
236
  // track state
198
237
  scan(
199
238
  (acc, event) => {
@@ -203,12 +242,14 @@ export class RuntimeEventSource {
203
242
  acc = { ...acc };
204
243
 
205
244
  if (event.type === RuntimeEventTypes.ActionExecutionStart) {
206
- acc.callActionServerSide = event.scope === "server";
245
+ acc.callActionServerSide =
246
+ serverSideActions.find((action) => action.name === event.actionName) !== undefined;
207
247
  acc.args = "";
208
248
  acc.actionExecutionId = event.actionExecutionId;
209
249
  if (acc.callActionServerSide) {
210
250
  acc.action = serverSideActions.find((action) => action.name === event.actionName);
211
251
  }
252
+ acc.actionExecutionParentMessageId = event.parentMessageId;
212
253
  } else if (event.type === RuntimeEventTypes.ActionExecutionArgs) {
213
254
  acc.args += event.args;
214
255
  }
@@ -223,6 +264,7 @@ export class RuntimeEventSource {
223
264
  args: "",
224
265
  actionExecutionId: null,
225
266
  action: null,
267
+ actionExecutionParentMessageId: null,
226
268
  } as RuntimeEventWithState,
227
269
  ),
228
270
  concatMap((eventWithState) => {
@@ -236,6 +278,7 @@ export class RuntimeEventSource {
236
278
  guardrailsResult$ ? guardrailsResult$ : null,
237
279
  eventWithState.action!,
238
280
  eventWithState.args,
281
+ eventWithState.actionExecutionParentMessageId,
239
282
  eventWithState.actionExecutionId,
240
283
  actionInputsWithoutAgents,
241
284
  ).catch((error) => {
@@ -257,6 +300,7 @@ async function executeAction(
257
300
  guardrailsResult$: Subject<GuardrailsResult> | null,
258
301
  action: Action<any>,
259
302
  actionArguments: string,
303
+ actionExecutionParentMessageId: string | null,
260
304
  actionExecutionId: string,
261
305
  actionInputsWithoutAgents: ActionInput[],
262
306
  ) {
@@ -281,14 +325,34 @@ async function executeAction(
281
325
 
282
326
  // handle LangGraph agents
283
327
  if (isLangGraphAgentAction(action)) {
284
- eventStream$.sendActionExecutionResult(
328
+ const result = `${action.name} agent started`;
329
+
330
+ const agentExecution = plainToInstance(ActionExecutionMessage, {
331
+ id: actionExecutionId,
332
+ createdAt: new Date(),
333
+ name: action.name,
334
+ arguments: JSON.parse(actionArguments),
335
+ parentMessageId: actionExecutionParentMessageId ?? actionExecutionId,
336
+ });
337
+
338
+ const agentExecutionResult = plainToInstance(ResultMessage, {
339
+ id: "result-" + actionExecutionId,
340
+ createdAt: new Date(),
285
341
  actionExecutionId,
286
- action.name,
287
- `${action.name} agent started`,
288
- );
342
+ actionName: action.name,
343
+ result,
344
+ });
345
+
346
+ eventStream$.sendActionExecutionResult({
347
+ actionExecutionId,
348
+ actionName: action.name,
349
+ result,
350
+ });
351
+
289
352
  const stream = await action.langGraphAgentHandler({
290
353
  name: action.name,
291
354
  actionInputsWithoutAgents,
355
+ additionalMessages: [agentExecution, agentExecutionResult],
292
356
  });
293
357
 
294
358
  // forward to eventStream$
@@ -0,0 +1,33 @@
1
+ /**
2
+ * CopilotKit Empty Adapter
3
+ *
4
+ * This adapter is meant to preserve adherence to runtime requirements, while doing nothing
5
+ * Ideal if you don't want to connect an LLM the to the runtime, and only use your LangGraph agent.
6
+ * Be aware that Copilot Suggestions will not work if you use this adapter
7
+ *
8
+ * ## Example
9
+ *
10
+ * ```ts
11
+ * import { CopilotRuntime, ExperimentalEmptyAdapter } from "@copilotkit/runtime";
12
+ *
13
+ * const copilotKit = new CopilotRuntime();
14
+ *
15
+ * return new ExperimentalEmptyAdapter();
16
+ * ```
17
+ */
18
+ import {
19
+ CopilotServiceAdapter,
20
+ CopilotRuntimeChatCompletionRequest,
21
+ CopilotRuntimeChatCompletionResponse,
22
+ } from "../../service-adapter";
23
+ import { randomId } from "@copilotkit/shared";
24
+
25
+ export class ExperimentalEmptyAdapter implements CopilotServiceAdapter {
26
+ async process(
27
+ request: CopilotRuntimeChatCompletionRequest,
28
+ ): Promise<CopilotRuntimeChatCompletionResponse> {
29
+ return {
30
+ threadId: request.threadId || randomId(),
31
+ };
32
+ }
33
+ }
@@ -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
 
@@ -102,10 +102,14 @@ export class GroqAdapter implements CopilotServiceAdapter {
102
102
  ...(forwardedParameters?.stop && { stop: forwardedParameters.stop }),
103
103
  ...(toolChoice && { tool_choice: toolChoice }),
104
104
  ...(this.disableParallelToolCalls && { parallel_tool_calls: false }),
105
+ ...(forwardedParameters?.temperature && { temperature: forwardedParameters.temperature }),
105
106
  });
106
107
 
107
108
  eventSource.stream(async (eventStream$) => {
108
109
  let mode: "function" | "message" | null = null;
110
+ let currentMessageId: string;
111
+ let currentToolCallId: string;
112
+
109
113
  for await (const chunk of stream) {
110
114
  const toolCall = chunk.choices[0].delta.tool_calls?.[0];
111
115
  const content = chunk.choices[0].delta.content;
@@ -115,36 +119,48 @@ export class GroqAdapter implements CopilotServiceAdapter {
115
119
  // If toolCall?.id is defined, it means a new tool call starts.
116
120
  if (mode === "message" && toolCall?.id) {
117
121
  mode = null;
118
- eventStream$.sendTextMessageEnd();
122
+ eventStream$.sendTextMessageEnd({ messageId: currentMessageId });
119
123
  } else if (mode === "function" && (toolCall === undefined || toolCall?.id)) {
120
124
  mode = null;
121
- eventStream$.sendActionExecutionEnd();
125
+ eventStream$.sendActionExecutionEnd({ actionExecutionId: currentToolCallId });
122
126
  }
123
127
 
124
128
  // If we send a new message type, send the appropriate start event.
125
129
  if (mode === null) {
126
130
  if (toolCall?.id) {
127
131
  mode = "function";
128
- eventStream$.sendActionExecutionStart(toolCall!.id, toolCall!.function!.name);
132
+ currentToolCallId = toolCall!.id;
133
+ eventStream$.sendActionExecutionStart({
134
+ actionExecutionId: currentToolCallId,
135
+ actionName: toolCall!.function!.name,
136
+ parentMessageId: chunk.id,
137
+ });
129
138
  } else if (content) {
130
139
  mode = "message";
131
- eventStream$.sendTextMessageStart(chunk.id);
140
+ currentMessageId = chunk.id;
141
+ eventStream$.sendTextMessageStart({ messageId: currentMessageId });
132
142
  }
133
143
  }
134
144
 
135
145
  // send the content events
136
146
  if (mode === "message" && content) {
137
- eventStream$.sendTextMessageContent(content);
147
+ eventStream$.sendTextMessageContent({
148
+ messageId: currentMessageId,
149
+ content,
150
+ });
138
151
  } else if (mode === "function" && toolCall?.function?.arguments) {
139
- eventStream$.sendActionExecutionArgs(toolCall.function.arguments);
152
+ eventStream$.sendActionExecutionArgs({
153
+ actionExecutionId: currentToolCallId,
154
+ args: toolCall.function.arguments,
155
+ });
140
156
  }
141
157
  }
142
158
 
143
159
  // send the end events
144
160
  if (mode === "message") {
145
- eventStream$.sendTextMessageEnd();
161
+ eventStream$.sendTextMessageEnd({ messageId: currentMessageId });
146
162
  } else if (mode === "function") {
147
- eventStream$.sendActionExecutionEnd();
163
+ eventStream$.sendActionExecutionEnd({ actionExecutionId: currentToolCallId });
148
164
  }
149
165
 
150
166
  eventStream$.complete();
@@ -1,4 +1,8 @@
1
- export type { CopilotServiceAdapter } from "./service-adapter";
1
+ export type {
2
+ CopilotRuntimeChatCompletionRequest,
3
+ CopilotRuntimeChatCompletionResponse,
4
+ CopilotServiceAdapter,
5
+ } from "./service-adapter";
2
6
  export type { RemoteChainParameters } from "./langchain/langserve";
3
7
  export { RemoteChain } from "./langchain/langserve";
4
8
  export * from "./openai/openai-adapter";
@@ -8,3 +12,5 @@ export * from "./openai/openai-assistant-adapter";
8
12
  export * from "./unify/unify-adapter";
9
13
  export * from "./groq/groq-adapter";
10
14
  export * from "./anthropic/anthropic-adapter";
15
+ export * from "./experimental/ollama/ollama-adapter";
16
+ export * from "./experimental/empty/empty-adapter";
@@ -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,
@@ -184,7 +189,12 @@ export async function streamLangChainResponse({
184
189
  let toolCallId: string | undefined = undefined;
185
190
  let toolCallArgs: string | undefined = undefined;
186
191
  let hasToolCall: boolean = false;
187
- let content = value?.content as string;
192
+ let content = "";
193
+ if (value && value.content) {
194
+ content = Array.isArray(value.content)
195
+ ? (((value.content[0] as any)?.text ?? "") as string)
196
+ : value.content;
197
+ }
188
198
 
189
199
  if (isAIMessageChunk(value)) {
190
200
  let chunk = value.tool_call_chunks?.[0];
@@ -216,10 +226,10 @@ export async function streamLangChainResponse({
216
226
  // If toolCallName is defined, it means a new tool call starts.
217
227
  if (mode === "message" && (toolCallId || done)) {
218
228
  mode = null;
219
- eventStream$.sendTextMessageEnd();
229
+ eventStream$.sendTextMessageEnd({ messageId: currentMessageId });
220
230
  } else if (mode === "function" && (!hasToolCall || done)) {
221
231
  mode = null;
222
- eventStream$.sendActionExecutionEnd();
232
+ eventStream$.sendActionExecutionEnd({ actionExecutionId: toolCallId });
223
233
  }
224
234
 
225
235
  if (done) {
@@ -230,26 +240,39 @@ export async function streamLangChainResponse({
230
240
  if (mode === null) {
231
241
  if (hasToolCall && toolCallId && toolCallName) {
232
242
  mode = "function";
233
- eventStream$.sendActionExecutionStart(toolCallId, toolCallName);
243
+ eventStream$.sendActionExecutionStart({
244
+ actionExecutionId: toolCallId,
245
+ actionName: toolCallName,
246
+ parentMessageId: value.lc_kwargs?.id,
247
+ });
234
248
  } else if (content) {
235
249
  mode = "message";
236
- eventStream$.sendTextMessageStart(randomId());
250
+ currentMessageId = value.lc_kwargs?.id || randomId();
251
+ eventStream$.sendTextMessageStart({ messageId: currentMessageId });
237
252
  }
238
253
  }
239
254
 
240
255
  // send the content events
241
256
  if (mode === "message" && content) {
242
- eventStream$.sendTextMessageContent(
243
- Array.isArray(content) ? (content[0]?.text ?? "") : content,
244
- );
257
+ eventStream$.sendTextMessageContent({
258
+ messageId: currentMessageId,
259
+ content,
260
+ });
245
261
  } else if (mode === "function" && toolCallArgs) {
246
262
  // For calls of the same tool with different index, we seal last tool call and register a new one
247
263
  if (toolCallDetails.index !== toolCallDetails.prevIndex) {
248
- eventStream$.sendActionExecutionEnd();
249
- eventStream$.sendActionExecutionStart(toolCallId, toolCallName);
264
+ eventStream$.sendActionExecutionEnd({ actionExecutionId: toolCallId });
265
+ eventStream$.sendActionExecutionStart({
266
+ actionExecutionId: toolCallId,
267
+ actionName: toolCallName,
268
+ parentMessageId: value.lc_kwargs?.id,
269
+ });
250
270
  toolCallDetails.prevIndex = toolCallDetails.index;
251
271
  }
252
- eventStream$.sendActionExecutionArgs(toolCallArgs);
272
+ eventStream$.sendActionExecutionArgs({
273
+ actionExecutionId: toolCallId,
274
+ args: toolCallArgs,
275
+ });
253
276
  }
254
277
  } catch (error) {
255
278
  console.error("Error reading from stream", error);
@@ -257,11 +280,11 @@ export async function streamLangChainResponse({
257
280
  }
258
281
  }
259
282
  } else if (actionExecution) {
260
- eventStream$.sendActionExecutionResult(
261
- actionExecution.id,
262
- actionExecution.name,
263
- encodeResult(result),
264
- );
283
+ eventStream$.sendActionExecutionResult({
284
+ actionExecutionId: actionExecution.id,
285
+ actionName: actionExecution.name,
286
+ result: encodeResult(result),
287
+ });
265
288
  }
266
289
 
267
290
  // unsupported type