@copilotkit/runtime 1.10.7-next.0 → 1.50.0-beta.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 (134) hide show
  1. package/CHANGELOG.md +0 -6
  2. package/dist/index.d.ts +1655 -27
  3. package/dist/index.js +2172 -5049
  4. package/dist/index.js.map +1 -1
  5. package/dist/index.mjs +5441 -99
  6. package/dist/index.mjs.map +1 -1
  7. package/dist/v2/index.d.ts +1 -0
  8. package/dist/v2/index.js +15 -0
  9. package/dist/v2/index.js.map +1 -0
  10. package/dist/v2/index.mjs +4 -0
  11. package/dist/v2/index.mjs.map +1 -0
  12. package/package.json +17 -5
  13. package/src/graphql/message-conversion/agui-to-gql.test.ts +1263 -0
  14. package/src/graphql/message-conversion/agui-to-gql.ts +333 -0
  15. package/src/graphql/message-conversion/gql-to-agui.test.ts +1578 -0
  16. package/src/graphql/message-conversion/gql-to-agui.ts +278 -0
  17. package/src/graphql/message-conversion/index.ts +2 -0
  18. package/src/graphql/message-conversion/roundtrip-conversion.test.ts +526 -0
  19. package/src/graphql/resolvers/copilot.resolver.ts +3 -48
  20. package/src/graphql/resolvers/state.resolver.ts +3 -2
  21. package/src/graphql/types/converted/index.ts +32 -6
  22. package/src/graphql/types/enums.ts +2 -2
  23. package/src/graphql/types/message-status.type.ts +3 -1
  24. package/src/lib/index.ts +1 -1
  25. package/src/lib/integrations/nextjs/app-router.ts +10 -11
  26. package/src/lib/integrations/nextjs/pages-router.ts +4 -11
  27. package/src/lib/integrations/node-http/index.ts +64 -5
  28. package/src/lib/integrations/shared.ts +1 -1
  29. package/src/lib/observability.ts +87 -0
  30. package/src/lib/runtime/{langgraph/langgraph-agent.ts → agent-integrations/langgraph.agent.ts} +5 -0
  31. package/src/lib/runtime/copilot-runtime.ts +346 -1333
  32. package/src/lib/runtime/types.ts +49 -0
  33. package/src/lib/runtime/utils.ts +87 -0
  34. package/src/lib/telemetry-client.ts +6 -5
  35. package/src/service-adapters/anthropic/anthropic-adapter.ts +5 -1
  36. package/src/service-adapters/bedrock/bedrock-adapter.ts +6 -1
  37. package/src/service-adapters/empty/empty-adapter.ts +3 -0
  38. package/src/service-adapters/events.ts +0 -254
  39. package/src/service-adapters/experimental/ollama/ollama-adapter.ts +5 -1
  40. package/src/service-adapters/google/google-genai-adapter.ts +7 -1
  41. package/src/service-adapters/groq/groq-adapter.ts +5 -1
  42. package/src/service-adapters/langchain/langchain-adapter.ts +3 -0
  43. package/src/service-adapters/openai/openai-adapter.ts +5 -1
  44. package/src/service-adapters/openai/openai-assistant-adapter.ts +4 -0
  45. package/src/service-adapters/service-adapter.ts +3 -0
  46. package/src/service-adapters/unify/unify-adapter.ts +6 -1
  47. package/src/v2/index.ts +2 -0
  48. package/tsup.config.ts +2 -1
  49. package/dist/chunk-27JKTS6P.mjs +0 -1704
  50. package/dist/chunk-27JKTS6P.mjs.map +0 -1
  51. package/dist/chunk-2OZAGFV3.mjs +0 -43
  52. package/dist/chunk-2OZAGFV3.mjs.map +0 -1
  53. package/dist/chunk-5BW5IBTZ.mjs +0 -80
  54. package/dist/chunk-5BW5IBTZ.mjs.map +0 -1
  55. package/dist/chunk-AMUJQ6IR.mjs +0 -50
  56. package/dist/chunk-AMUJQ6IR.mjs.map +0 -1
  57. package/dist/chunk-BMIYSM5W.mjs +0 -25
  58. package/dist/chunk-BMIYSM5W.mjs.map +0 -1
  59. package/dist/chunk-FDTCG47E.mjs +0 -25
  60. package/dist/chunk-FDTCG47E.mjs.map +0 -1
  61. package/dist/chunk-FHD4JECV.mjs +0 -33
  62. package/dist/chunk-FHD4JECV.mjs.map +0 -1
  63. package/dist/chunk-LRCKLBMO.mjs +0 -6020
  64. package/dist/chunk-LRCKLBMO.mjs.map +0 -1
  65. package/dist/chunk-R7RMYEPZ.mjs +0 -175
  66. package/dist/chunk-R7RMYEPZ.mjs.map +0 -1
  67. package/dist/chunk-SHBDMA63.mjs +0 -141
  68. package/dist/chunk-SHBDMA63.mjs.map +0 -1
  69. package/dist/chunk-XWBDEXDA.mjs +0 -153
  70. package/dist/chunk-XWBDEXDA.mjs.map +0 -1
  71. package/dist/graphql/types/base/index.d.ts +0 -6
  72. package/dist/graphql/types/base/index.js +0 -63
  73. package/dist/graphql/types/base/index.js.map +0 -1
  74. package/dist/graphql/types/base/index.mjs +0 -8
  75. package/dist/graphql/types/base/index.mjs.map +0 -1
  76. package/dist/graphql/types/converted/index.d.ts +0 -2
  77. package/dist/graphql/types/converted/index.js +0 -200
  78. package/dist/graphql/types/converted/index.js.map +0 -1
  79. package/dist/graphql/types/converted/index.mjs +0 -19
  80. package/dist/graphql/types/converted/index.mjs.map +0 -1
  81. package/dist/groq-adapter-c8aec5c5.d.ts +0 -321
  82. package/dist/index-96b330da.d.ts +0 -119
  83. package/dist/langserve-0c6100e3.d.ts +0 -257
  84. package/dist/lib/cloud/index.d.ts +0 -6
  85. package/dist/lib/cloud/index.js +0 -18
  86. package/dist/lib/cloud/index.js.map +0 -1
  87. package/dist/lib/cloud/index.mjs +0 -1
  88. package/dist/lib/cloud/index.mjs.map +0 -1
  89. package/dist/lib/index.d.ts +0 -212
  90. package/dist/lib/index.js +0 -7843
  91. package/dist/lib/index.js.map +0 -1
  92. package/dist/lib/index.mjs +0 -76
  93. package/dist/lib/index.mjs.map +0 -1
  94. package/dist/lib/integrations/index.d.ts +0 -34
  95. package/dist/lib/integrations/index.js +0 -3052
  96. package/dist/lib/integrations/index.js.map +0 -1
  97. package/dist/lib/integrations/index.mjs +0 -37
  98. package/dist/lib/integrations/index.mjs.map +0 -1
  99. package/dist/lib/integrations/nest/index.d.ts +0 -15
  100. package/dist/lib/integrations/nest/index.js +0 -2959
  101. package/dist/lib/integrations/nest/index.js.map +0 -1
  102. package/dist/lib/integrations/nest/index.mjs +0 -14
  103. package/dist/lib/integrations/nest/index.mjs.map +0 -1
  104. package/dist/lib/integrations/node-express/index.d.ts +0 -15
  105. package/dist/lib/integrations/node-express/index.js +0 -2959
  106. package/dist/lib/integrations/node-express/index.js.map +0 -1
  107. package/dist/lib/integrations/node-express/index.mjs +0 -14
  108. package/dist/lib/integrations/node-express/index.mjs.map +0 -1
  109. package/dist/lib/integrations/node-http/index.d.ts +0 -15
  110. package/dist/lib/integrations/node-http/index.js +0 -2945
  111. package/dist/lib/integrations/node-http/index.js.map +0 -1
  112. package/dist/lib/integrations/node-http/index.mjs +0 -13
  113. package/dist/lib/integrations/node-http/index.mjs.map +0 -1
  114. package/dist/service-adapters/index.d.ts +0 -162
  115. package/dist/service-adapters/index.js +0 -1787
  116. package/dist/service-adapters/index.js.map +0 -1
  117. package/dist/service-adapters/index.mjs +0 -34
  118. package/dist/service-adapters/index.mjs.map +0 -1
  119. package/dist/service-adapters/shared/index.d.ts +0 -9
  120. package/dist/service-adapters/shared/index.js +0 -72
  121. package/dist/service-adapters/shared/index.js.map +0 -1
  122. package/dist/service-adapters/shared/index.mjs +0 -8
  123. package/dist/service-adapters/shared/index.mjs.map +0 -1
  124. package/dist/shared-0a7346ce.d.ts +0 -466
  125. package/dist/utils/index.d.ts +0 -65
  126. package/dist/utils/index.js +0 -175
  127. package/dist/utils/index.js.map +0 -1
  128. package/dist/utils/index.mjs +0 -12
  129. package/dist/utils/index.mjs.map +0 -1
  130. package/src/lib/runtime/__tests__/remote-action-constructors.test.ts +0 -246
  131. package/src/lib/runtime/agui-action.ts +0 -180
  132. package/src/lib/runtime/remote-action-constructors.ts +0 -331
  133. package/src/lib/runtime/remote-actions.ts +0 -217
  134. package/src/lib/runtime/remote-lg-action.ts +0 -1006
@@ -0,0 +1,333 @@
1
+ import * as gql from "../types/converted/index";
2
+ import { MessageRole } from "../types/enums";
3
+ import agui from "@copilotkit/shared"; // named agui for clarity, but this only includes agui message types
4
+
5
+ // Helper function to extract agent name from message
6
+ function extractAgentName(message: agui.Message): string {
7
+ if (message.role !== "assistant") {
8
+ throw new Error(`Cannot extract agent name from message with role ${message.role}`);
9
+ }
10
+
11
+ return message.agentName || "unknown";
12
+ }
13
+
14
+ // Type guard for agent state message
15
+ function isAgentStateMessage(message: agui.Message): boolean {
16
+ return message.role === "assistant" && "agentName" in message && "state" in message;
17
+ }
18
+
19
+ // Type guard for messages with image property
20
+ function hasImageProperty(message: agui.Message): boolean {
21
+ const canContainImage = message.role === "assistant" || message.role === "user";
22
+ if (!canContainImage || message.image === undefined) {
23
+ return false;
24
+ }
25
+
26
+ const isMalformed = message.image.format === undefined || message.image.bytes === undefined;
27
+ if (isMalformed) {
28
+ return false;
29
+ }
30
+
31
+ return true;
32
+ }
33
+
34
+ function normalizeMessageContent(content: agui.Message["content"]): string {
35
+ if (typeof content === "string" || typeof content === "undefined") {
36
+ return content || "";
37
+ }
38
+
39
+ if (Array.isArray(content)) {
40
+ return content
41
+ .map((part) => {
42
+ if (part?.type === "text") {
43
+ return part.text;
44
+ }
45
+ if (part?.type === "binary") {
46
+ return part.data || part.url || part.filename || `[binary:${part.mimeType}]`;
47
+ }
48
+ return "";
49
+ })
50
+ .filter(Boolean)
51
+ .join("\n");
52
+ }
53
+
54
+ if (content && typeof content === "object") {
55
+ try {
56
+ return JSON.stringify(content);
57
+ } catch (error) {
58
+ console.warn("Failed to serialize message content", error);
59
+ }
60
+ }
61
+
62
+ return String(content ?? "");
63
+ }
64
+
65
+ /*
66
+ ----------------------------
67
+ AGUI Message -> GQL Message
68
+ ----------------------------
69
+ */
70
+ export function aguiToGQL(
71
+ messages: agui.Message[] | agui.Message,
72
+ actions?: Record<string, any>,
73
+ coAgentStateRenders?: Record<string, any>,
74
+ ): gql.Message[] {
75
+ const gqlMessages: gql.Message[] = [];
76
+ messages = Array.isArray(messages) ? messages : [messages];
77
+
78
+ // Track tool call names by their IDs for use in result messages
79
+ const toolCallNames: Record<string, string> = {};
80
+
81
+ for (const message of messages) {
82
+ // Agent state message support
83
+ if (isAgentStateMessage(message)) {
84
+ const agentName = extractAgentName(message);
85
+ const state = "state" in message && message.state ? message.state : {};
86
+ gqlMessages.push(
87
+ new gql.AgentStateMessage({
88
+ id: message.id,
89
+ agentName,
90
+ state,
91
+ role: gql.Role.assistant,
92
+ }),
93
+ );
94
+ // Optionally preserve render function
95
+ if ("generativeUI" in message && message.generativeUI && coAgentStateRenders) {
96
+ coAgentStateRenders[agentName] = {
97
+ name: agentName,
98
+ render: message.generativeUI,
99
+ };
100
+ }
101
+ continue;
102
+ }
103
+
104
+ if (hasImageProperty(message)) {
105
+ gqlMessages.push(aguiMessageWithImageToGQLMessage(message));
106
+ continue;
107
+ }
108
+
109
+ // Action execution message support
110
+ if (message.role === "assistant" && message.toolCalls) {
111
+ gqlMessages.push(aguiTextMessageToGQLMessage(message));
112
+ for (const toolCall of message.toolCalls) {
113
+ // Track the tool call name by its ID
114
+ toolCallNames[toolCall.id] = toolCall.function.name;
115
+
116
+ const actionExecMsg = aguiToolCallToGQLActionExecution(toolCall, message.id);
117
+ // Preserve render function in actions context
118
+ if ("generativeUI" in message && message.generativeUI && actions) {
119
+ const actionName = toolCall.function.name;
120
+ // Check for specific action first, then wild card action
121
+ const specificAction = Object.values(actions).find(
122
+ (action: any) => action.name === actionName,
123
+ );
124
+ const wildcardAction = Object.values(actions).find((action: any) => action.name === "*");
125
+
126
+ // Assign render function to the matching action (specific takes priority)
127
+ if (specificAction) {
128
+ specificAction.render = message.generativeUI;
129
+ } else if (wildcardAction) {
130
+ wildcardAction.render = message.generativeUI;
131
+ }
132
+ }
133
+ gqlMessages.push(actionExecMsg);
134
+ }
135
+ continue;
136
+ }
137
+ // Regular text messages
138
+ if (
139
+ message.role === "developer" ||
140
+ message.role === "system" ||
141
+ message.role === "assistant" ||
142
+ message.role === "user"
143
+ ) {
144
+ gqlMessages.push(aguiTextMessageToGQLMessage(message));
145
+ continue;
146
+ }
147
+ // Tool result message
148
+ if (message.role === "tool") {
149
+ gqlMessages.push(aguiToolMessageToGQLResultMessage(message, toolCallNames));
150
+ continue;
151
+ }
152
+ throw new Error(
153
+ `Unknown message role: "${(message as any).role}" in message with id: ${(message as any).id}`,
154
+ );
155
+ }
156
+
157
+ return gqlMessages;
158
+ }
159
+
160
+ export function aguiTextMessageToGQLMessage(message: agui.Message): gql.TextMessage {
161
+ if (
162
+ message.role !== "developer" &&
163
+ message.role !== "system" &&
164
+ message.role !== "assistant" &&
165
+ message.role !== "user"
166
+ ) {
167
+ throw new Error(`Cannot convert message with role ${message.role} to TextMessage`);
168
+ }
169
+
170
+ let roleValue: MessageRole;
171
+
172
+ if (message.role === "developer") {
173
+ roleValue = gql.Role.developer;
174
+ } else if (message.role === "system") {
175
+ roleValue = gql.Role.system;
176
+ } else if (message.role === "assistant") {
177
+ roleValue = gql.Role.assistant;
178
+ } else {
179
+ roleValue = gql.Role.user;
180
+ }
181
+
182
+ return new gql.TextMessage({
183
+ id: message.id,
184
+ content: normalizeMessageContent(message.content),
185
+ role: roleValue,
186
+ });
187
+ }
188
+
189
+ export function aguiToolCallToGQLActionExecution(
190
+ toolCall: agui.ToolCall,
191
+ parentMessageId: string,
192
+ ): gql.ActionExecutionMessage {
193
+ if (toolCall.type !== "function") {
194
+ throw new Error(`Unsupported tool call type: ${toolCall.type}`);
195
+ }
196
+
197
+ // Handle arguments - they should be a JSON string in AGUI format,
198
+ // but we need to convert them to an object for GQL format
199
+ let argumentsObj: any;
200
+
201
+ if (typeof toolCall.function.arguments === "string") {
202
+ // Expected case: arguments is a JSON string
203
+ try {
204
+ argumentsObj = JSON.parse(toolCall.function.arguments);
205
+ } catch (error) {
206
+ console.warn(`Failed to parse tool call arguments for ${toolCall.function.name}:`, error);
207
+ // Provide fallback empty object to prevent application crash
208
+ argumentsObj = {};
209
+ }
210
+ } else if (
211
+ typeof toolCall.function.arguments === "object" &&
212
+ toolCall.function.arguments !== null
213
+ ) {
214
+ // Backward compatibility: arguments is already an object
215
+ argumentsObj = toolCall.function.arguments;
216
+ } else {
217
+ // Fallback for undefined, null, or other types
218
+ console.warn(
219
+ `Invalid tool call arguments type for ${toolCall.function.name}:`,
220
+ typeof toolCall.function.arguments,
221
+ );
222
+ argumentsObj = {};
223
+ }
224
+
225
+ // Always include name and arguments
226
+ return new gql.ActionExecutionMessage({
227
+ id: toolCall.id,
228
+ name: toolCall.function.name,
229
+ arguments: argumentsObj,
230
+ parentMessageId: parentMessageId,
231
+ });
232
+ }
233
+
234
+ export function aguiToolMessageToGQLResultMessage(
235
+ message: agui.Message,
236
+ toolCallNames: Record<string, string>,
237
+ ): gql.ResultMessage {
238
+ if (message.role !== "tool") {
239
+ throw new Error(`Cannot convert message with role ${message.role} to ResultMessage`);
240
+ }
241
+
242
+ if (!message.toolCallId) {
243
+ throw new Error("Tool message must have a toolCallId");
244
+ }
245
+
246
+ const actionName = toolCallNames[message.toolCallId] || "unknown";
247
+
248
+ // Handle result content - it could be a string or an object that needs serialization
249
+ let resultContent: string;
250
+ const messageContent = message.content || "";
251
+
252
+ if (typeof messageContent === "string") {
253
+ // Expected case: content is already a string
254
+ resultContent = messageContent;
255
+ } else if (typeof messageContent === "object" && messageContent !== null) {
256
+ // Handle case where content is an object that needs to be serialized
257
+ try {
258
+ resultContent = JSON.stringify(messageContent);
259
+ } catch (error) {
260
+ console.warn(`Failed to stringify tool result for ${actionName}:`, error);
261
+ resultContent = String(messageContent);
262
+ }
263
+ } else {
264
+ // Handle other types (number, boolean, etc.)
265
+ resultContent = String(messageContent);
266
+ }
267
+
268
+ return new gql.ResultMessage({
269
+ id: message.id,
270
+ result: resultContent,
271
+ actionExecutionId: message.toolCallId,
272
+ actionName: message.toolName || actionName,
273
+ });
274
+ }
275
+
276
+ // New function to handle AGUI messages with render functions
277
+ export function aguiMessageWithRenderToGQL(
278
+ message: agui.Message,
279
+ actions?: Record<string, any>,
280
+ coAgentStateRenders?: Record<string, any>,
281
+ ): gql.Message[] {
282
+ // Handle the special case: assistant messages with render function but no tool calls
283
+ if (
284
+ message.role === "assistant" &&
285
+ "generativeUI" in message &&
286
+ message.generativeUI &&
287
+ !message.toolCalls
288
+ ) {
289
+ const gqlMessages: gql.Message[] = [];
290
+ gqlMessages.push(
291
+ new gql.AgentStateMessage({
292
+ id: message.id,
293
+ agentName: "unknown",
294
+ state: {},
295
+ role: gql.Role.assistant,
296
+ }),
297
+ );
298
+ if (coAgentStateRenders) {
299
+ coAgentStateRenders.unknown = {
300
+ name: "unknown",
301
+ render: message.generativeUI,
302
+ };
303
+ }
304
+ return gqlMessages;
305
+ }
306
+
307
+ // For all other cases, delegate to aguiToGQL
308
+ return aguiToGQL([message], actions, coAgentStateRenders);
309
+ }
310
+
311
+ export function aguiMessageWithImageToGQLMessage(message: agui.Message): gql.ImageMessage {
312
+ if (!hasImageProperty(message)) {
313
+ throw new Error(`Cannot convert message to ImageMessage: missing format or bytes`);
314
+ }
315
+
316
+ let roleValue: MessageRole;
317
+ if (message.role === "assistant") {
318
+ roleValue = gql.Role.assistant;
319
+ } else {
320
+ roleValue = gql.Role.user;
321
+ }
322
+
323
+ if (message.role !== "assistant" && message.role !== "user") {
324
+ throw new Error(`Cannot convert message with role ${message.role} to ImageMessage`);
325
+ }
326
+
327
+ return new gql.ImageMessage({
328
+ id: message.id,
329
+ format: message.image!.format,
330
+ bytes: message.image!.bytes,
331
+ role: roleValue,
332
+ });
333
+ }