@copilotkit/runtime 1.10.6 → 1.50.0-beta.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 (133) hide show
  1. package/dist/index.d.ts +1655 -27
  2. package/dist/index.js +2172 -5049
  3. package/dist/index.js.map +1 -1
  4. package/dist/index.mjs +5441 -99
  5. package/dist/index.mjs.map +1 -1
  6. package/dist/v2/index.d.ts +1 -0
  7. package/dist/v2/index.js +15 -0
  8. package/dist/v2/index.js.map +1 -0
  9. package/dist/v2/index.mjs +4 -0
  10. package/dist/v2/index.mjs.map +1 -0
  11. package/package.json +33 -21
  12. package/src/graphql/message-conversion/agui-to-gql.test.ts +1263 -0
  13. package/src/graphql/message-conversion/agui-to-gql.ts +333 -0
  14. package/src/graphql/message-conversion/gql-to-agui.test.ts +1578 -0
  15. package/src/graphql/message-conversion/gql-to-agui.ts +278 -0
  16. package/src/graphql/message-conversion/index.ts +2 -0
  17. package/src/graphql/message-conversion/roundtrip-conversion.test.ts +526 -0
  18. package/src/graphql/resolvers/copilot.resolver.ts +3 -48
  19. package/src/graphql/resolvers/state.resolver.ts +3 -2
  20. package/src/graphql/types/converted/index.ts +32 -6
  21. package/src/graphql/types/enums.ts +2 -2
  22. package/src/graphql/types/message-status.type.ts +3 -1
  23. package/src/lib/index.ts +1 -1
  24. package/src/lib/integrations/nextjs/app-router.ts +10 -11
  25. package/src/lib/integrations/nextjs/pages-router.ts +4 -11
  26. package/src/lib/integrations/node-http/index.ts +64 -5
  27. package/src/lib/integrations/shared.ts +1 -1
  28. package/src/lib/observability.ts +87 -0
  29. package/src/lib/runtime/{langgraph/langgraph-agent.ts → agent-integrations/langgraph.agent.ts} +5 -0
  30. package/src/lib/runtime/copilot-runtime.ts +346 -1333
  31. package/src/lib/runtime/types.ts +49 -0
  32. package/src/lib/runtime/utils.ts +87 -0
  33. package/src/lib/telemetry-client.ts +6 -5
  34. package/src/service-adapters/anthropic/anthropic-adapter.ts +5 -1
  35. package/src/service-adapters/bedrock/bedrock-adapter.ts +6 -1
  36. package/src/service-adapters/empty/empty-adapter.ts +3 -0
  37. package/src/service-adapters/events.ts +0 -254
  38. package/src/service-adapters/experimental/ollama/ollama-adapter.ts +5 -1
  39. package/src/service-adapters/google/google-genai-adapter.ts +7 -1
  40. package/src/service-adapters/groq/groq-adapter.ts +5 -1
  41. package/src/service-adapters/langchain/langchain-adapter.ts +3 -0
  42. package/src/service-adapters/openai/openai-adapter.ts +5 -1
  43. package/src/service-adapters/openai/openai-assistant-adapter.ts +4 -0
  44. package/src/service-adapters/service-adapter.ts +3 -0
  45. package/src/service-adapters/unify/unify-adapter.ts +6 -1
  46. package/src/v2/index.ts +2 -0
  47. package/tsup.config.ts +2 -1
  48. package/dist/chunk-27JKTS6P.mjs +0 -1704
  49. package/dist/chunk-27JKTS6P.mjs.map +0 -1
  50. package/dist/chunk-2OZAGFV3.mjs +0 -43
  51. package/dist/chunk-2OZAGFV3.mjs.map +0 -1
  52. package/dist/chunk-AMUJQ6IR.mjs +0 -50
  53. package/dist/chunk-AMUJQ6IR.mjs.map +0 -1
  54. package/dist/chunk-CEOMFPJU.mjs +0 -6020
  55. package/dist/chunk-CEOMFPJU.mjs.map +0 -1
  56. package/dist/chunk-DTPRUTNV.mjs +0 -25
  57. package/dist/chunk-DTPRUTNV.mjs.map +0 -1
  58. package/dist/chunk-FHD4JECV.mjs +0 -33
  59. package/dist/chunk-FHD4JECV.mjs.map +0 -1
  60. package/dist/chunk-I27F2UPA.mjs +0 -175
  61. package/dist/chunk-I27F2UPA.mjs.map +0 -1
  62. package/dist/chunk-LPEPX6NH.mjs +0 -25
  63. package/dist/chunk-LPEPX6NH.mjs.map +0 -1
  64. package/dist/chunk-PTYRVXXP.mjs +0 -80
  65. package/dist/chunk-PTYRVXXP.mjs.map +0 -1
  66. package/dist/chunk-SHBDMA63.mjs +0 -141
  67. package/dist/chunk-SHBDMA63.mjs.map +0 -1
  68. package/dist/chunk-XWBDEXDA.mjs +0 -153
  69. package/dist/chunk-XWBDEXDA.mjs.map +0 -1
  70. package/dist/graphql/types/base/index.d.ts +0 -6
  71. package/dist/graphql/types/base/index.js +0 -63
  72. package/dist/graphql/types/base/index.js.map +0 -1
  73. package/dist/graphql/types/base/index.mjs +0 -8
  74. package/dist/graphql/types/base/index.mjs.map +0 -1
  75. package/dist/graphql/types/converted/index.d.ts +0 -2
  76. package/dist/graphql/types/converted/index.js +0 -200
  77. package/dist/graphql/types/converted/index.js.map +0 -1
  78. package/dist/graphql/types/converted/index.mjs +0 -19
  79. package/dist/graphql/types/converted/index.mjs.map +0 -1
  80. package/dist/groq-adapter-c8aec5c5.d.ts +0 -321
  81. package/dist/index-96b330da.d.ts +0 -119
  82. package/dist/langserve-0c6100e3.d.ts +0 -257
  83. package/dist/lib/cloud/index.d.ts +0 -6
  84. package/dist/lib/cloud/index.js +0 -18
  85. package/dist/lib/cloud/index.js.map +0 -1
  86. package/dist/lib/cloud/index.mjs +0 -1
  87. package/dist/lib/cloud/index.mjs.map +0 -1
  88. package/dist/lib/index.d.ts +0 -212
  89. package/dist/lib/index.js +0 -7843
  90. package/dist/lib/index.js.map +0 -1
  91. package/dist/lib/index.mjs +0 -76
  92. package/dist/lib/index.mjs.map +0 -1
  93. package/dist/lib/integrations/index.d.ts +0 -34
  94. package/dist/lib/integrations/index.js +0 -3052
  95. package/dist/lib/integrations/index.js.map +0 -1
  96. package/dist/lib/integrations/index.mjs +0 -37
  97. package/dist/lib/integrations/index.mjs.map +0 -1
  98. package/dist/lib/integrations/nest/index.d.ts +0 -15
  99. package/dist/lib/integrations/nest/index.js +0 -2959
  100. package/dist/lib/integrations/nest/index.js.map +0 -1
  101. package/dist/lib/integrations/nest/index.mjs +0 -14
  102. package/dist/lib/integrations/nest/index.mjs.map +0 -1
  103. package/dist/lib/integrations/node-express/index.d.ts +0 -15
  104. package/dist/lib/integrations/node-express/index.js +0 -2959
  105. package/dist/lib/integrations/node-express/index.js.map +0 -1
  106. package/dist/lib/integrations/node-express/index.mjs +0 -14
  107. package/dist/lib/integrations/node-express/index.mjs.map +0 -1
  108. package/dist/lib/integrations/node-http/index.d.ts +0 -15
  109. package/dist/lib/integrations/node-http/index.js +0 -2945
  110. package/dist/lib/integrations/node-http/index.js.map +0 -1
  111. package/dist/lib/integrations/node-http/index.mjs +0 -13
  112. package/dist/lib/integrations/node-http/index.mjs.map +0 -1
  113. package/dist/service-adapters/index.d.ts +0 -162
  114. package/dist/service-adapters/index.js +0 -1787
  115. package/dist/service-adapters/index.js.map +0 -1
  116. package/dist/service-adapters/index.mjs +0 -34
  117. package/dist/service-adapters/index.mjs.map +0 -1
  118. package/dist/service-adapters/shared/index.d.ts +0 -9
  119. package/dist/service-adapters/shared/index.js +0 -72
  120. package/dist/service-adapters/shared/index.js.map +0 -1
  121. package/dist/service-adapters/shared/index.mjs +0 -8
  122. package/dist/service-adapters/shared/index.mjs.map +0 -1
  123. package/dist/shared-0a7346ce.d.ts +0 -466
  124. package/dist/utils/index.d.ts +0 -65
  125. package/dist/utils/index.js +0 -175
  126. package/dist/utils/index.js.map +0 -1
  127. package/dist/utils/index.mjs +0 -12
  128. package/dist/utils/index.mjs.map +0 -1
  129. package/src/lib/runtime/__tests__/remote-action-constructors.test.ts +0 -246
  130. package/src/lib/runtime/agui-action.ts +0 -180
  131. package/src/lib/runtime/remote-action-constructors.ts +0 -331
  132. package/src/lib/runtime/remote-actions.ts +0 -217
  133. 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
+ }