@copilotkit/runtime 0.0.0-0.0.0-max-changeset-10101010101010-20260109191632

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 (122) hide show
  1. package/.eslintrc.js +7 -0
  2. package/CHANGELOG.md +2905 -0
  3. package/LICENSE +21 -0
  4. package/README.md +76 -0
  5. package/__snapshots__/schema/schema.graphql +371 -0
  6. package/dist/index.d.ts +1495 -0
  7. package/dist/index.js +5644 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/index.mjs +5601 -0
  10. package/dist/index.mjs.map +1 -0
  11. package/dist/langgraph.d.ts +284 -0
  12. package/dist/langgraph.js +211 -0
  13. package/dist/langgraph.js.map +1 -0
  14. package/dist/langgraph.mjs +206 -0
  15. package/dist/langgraph.mjs.map +1 -0
  16. package/dist/v2/index.d.ts +2 -0
  17. package/dist/v2/index.js +22 -0
  18. package/dist/v2/index.js.map +1 -0
  19. package/dist/v2/index.mjs +5 -0
  20. package/dist/v2/index.mjs.map +1 -0
  21. package/jest.config.js +10 -0
  22. package/package.json +143 -0
  23. package/scripts/generate-gql-schema.ts +13 -0
  24. package/src/agents/langgraph/event-source.ts +329 -0
  25. package/src/agents/langgraph/events.ts +377 -0
  26. package/src/graphql/inputs/action.input.ts +16 -0
  27. package/src/graphql/inputs/agent-session.input.ts +13 -0
  28. package/src/graphql/inputs/agent-state.input.ts +13 -0
  29. package/src/graphql/inputs/cloud-guardrails.input.ts +16 -0
  30. package/src/graphql/inputs/cloud.input.ts +8 -0
  31. package/src/graphql/inputs/context-property.input.ts +10 -0
  32. package/src/graphql/inputs/copilot-context.input.ts +10 -0
  33. package/src/graphql/inputs/custom-property.input.ts +15 -0
  34. package/src/graphql/inputs/extensions.input.ts +21 -0
  35. package/src/graphql/inputs/forwarded-parameters.input.ts +22 -0
  36. package/src/graphql/inputs/frontend.input.ts +14 -0
  37. package/src/graphql/inputs/generate-copilot-response.input.ts +59 -0
  38. package/src/graphql/inputs/load-agent-state.input.ts +10 -0
  39. package/src/graphql/inputs/message.input.ts +110 -0
  40. package/src/graphql/inputs/meta-event.input.ts +18 -0
  41. package/src/graphql/message-conversion/agui-to-gql.test.ts +1263 -0
  42. package/src/graphql/message-conversion/agui-to-gql.ts +333 -0
  43. package/src/graphql/message-conversion/gql-to-agui.test.ts +1580 -0
  44. package/src/graphql/message-conversion/gql-to-agui.ts +278 -0
  45. package/src/graphql/message-conversion/index.ts +2 -0
  46. package/src/graphql/message-conversion/roundtrip-conversion.test.ts +526 -0
  47. package/src/graphql/resolvers/copilot.resolver.ts +708 -0
  48. package/src/graphql/resolvers/state.resolver.ts +27 -0
  49. package/src/graphql/types/agents-response.type.ts +19 -0
  50. package/src/graphql/types/base/index.ts +10 -0
  51. package/src/graphql/types/converted/index.ts +176 -0
  52. package/src/graphql/types/copilot-response.type.ts +138 -0
  53. package/src/graphql/types/enums.ts +38 -0
  54. package/src/graphql/types/extensions-response.type.ts +23 -0
  55. package/src/graphql/types/guardrails-result.type.ts +20 -0
  56. package/src/graphql/types/load-agent-state-response.type.ts +17 -0
  57. package/src/graphql/types/message-status.type.ts +42 -0
  58. package/src/graphql/types/meta-events.type.ts +71 -0
  59. package/src/graphql/types/response-status.type.ts +66 -0
  60. package/src/index.ts +4 -0
  61. package/src/langgraph.ts +1 -0
  62. package/src/lib/cloud/index.ts +4 -0
  63. package/src/lib/error-messages.ts +200 -0
  64. package/src/lib/index.ts +52 -0
  65. package/src/lib/integrations/index.ts +6 -0
  66. package/src/lib/integrations/nest/index.ts +14 -0
  67. package/src/lib/integrations/nextjs/app-router.ts +38 -0
  68. package/src/lib/integrations/nextjs/pages-router.ts +39 -0
  69. package/src/lib/integrations/node-express/index.ts +14 -0
  70. package/src/lib/integrations/node-http/index.ts +143 -0
  71. package/src/lib/integrations/node-http/request-handler.ts +111 -0
  72. package/src/lib/integrations/shared.ts +161 -0
  73. package/src/lib/logger.ts +28 -0
  74. package/src/lib/observability.ts +160 -0
  75. package/src/lib/runtime/__tests__/copilot-runtime-error.test.ts +169 -0
  76. package/src/lib/runtime/__tests__/mcp-tools-utils.test.ts +464 -0
  77. package/src/lib/runtime/agent-integrations/langgraph/agent.ts +209 -0
  78. package/src/lib/runtime/agent-integrations/langgraph/consts.ts +34 -0
  79. package/src/lib/runtime/agent-integrations/langgraph/index.ts +2 -0
  80. package/src/lib/runtime/copilot-runtime.ts +710 -0
  81. package/src/lib/runtime/mcp-tools-utils.ts +254 -0
  82. package/src/lib/runtime/retry-utils.ts +96 -0
  83. package/src/lib/runtime/telemetry-agent-runner.ts +139 -0
  84. package/src/lib/runtime/types.ts +49 -0
  85. package/src/lib/runtime/utils.ts +87 -0
  86. package/src/lib/streaming.ts +202 -0
  87. package/src/lib/telemetry-client.ts +64 -0
  88. package/src/service-adapters/anthropic/anthropic-adapter.ts +452 -0
  89. package/src/service-adapters/anthropic/utils.ts +152 -0
  90. package/src/service-adapters/bedrock/bedrock-adapter.ts +73 -0
  91. package/src/service-adapters/conversion.ts +67 -0
  92. package/src/service-adapters/empty/empty-adapter.ts +38 -0
  93. package/src/service-adapters/events.ts +294 -0
  94. package/src/service-adapters/experimental/ollama/ollama-adapter.ts +84 -0
  95. package/src/service-adapters/google/google-genai-adapter.test.ts +104 -0
  96. package/src/service-adapters/google/google-genai-adapter.ts +88 -0
  97. package/src/service-adapters/groq/groq-adapter.ts +203 -0
  98. package/src/service-adapters/index.ts +18 -0
  99. package/src/service-adapters/langchain/langchain-adapter.ts +111 -0
  100. package/src/service-adapters/langchain/langserve.ts +88 -0
  101. package/src/service-adapters/langchain/types.ts +14 -0
  102. package/src/service-adapters/langchain/utils.ts +313 -0
  103. package/src/service-adapters/openai/openai-adapter.ts +283 -0
  104. package/src/service-adapters/openai/openai-assistant-adapter.ts +344 -0
  105. package/src/service-adapters/openai/utils.ts +199 -0
  106. package/src/service-adapters/service-adapter.ts +41 -0
  107. package/src/service-adapters/shared/error-utils.ts +61 -0
  108. package/src/service-adapters/shared/index.ts +1 -0
  109. package/src/service-adapters/unify/unify-adapter.ts +151 -0
  110. package/src/utils/failed-response-status-reasons.ts +70 -0
  111. package/src/utils/index.ts +1 -0
  112. package/src/v2/index.ts +3 -0
  113. package/tests/global.d.ts +13 -0
  114. package/tests/service-adapters/anthropic/allowlist-approach.test.ts +226 -0
  115. package/tests/service-adapters/anthropic/anthropic-adapter.test.ts +389 -0
  116. package/tests/service-adapters/openai/allowlist-approach.test.ts +238 -0
  117. package/tests/service-adapters/openai/openai-adapter.test.ts +301 -0
  118. package/tests/setup.jest.ts +21 -0
  119. package/tests/tsconfig.json +10 -0
  120. package/tsconfig.json +13 -0
  121. package/tsup.config.ts +20 -0
  122. package/typedoc.json +4 -0
@@ -0,0 +1,301 @@
1
+ // Mock the modules first
2
+ jest.mock("openai", () => {
3
+ function MockOpenAI() {}
4
+ return { default: MockOpenAI };
5
+ });
6
+
7
+ // Mock the OpenAIAdapter class to avoid the "new OpenAI()" issue
8
+ jest.mock("../../../src/service-adapters/openai/openai-adapter", () => {
9
+ class MockOpenAIAdapter {
10
+ _openai: any;
11
+ model: string = "gpt-4o";
12
+ keepSystemRole: boolean = false;
13
+ disableParallelToolCalls: boolean = false;
14
+
15
+ constructor() {
16
+ this._openai = {
17
+ beta: {
18
+ chat: {
19
+ completions: {
20
+ stream: jest.fn(),
21
+ },
22
+ },
23
+ },
24
+ };
25
+ }
26
+
27
+ get openai() {
28
+ return this._openai;
29
+ }
30
+
31
+ async process(request: any) {
32
+ // Mock implementation that calls our event source but doesn't do the actual processing
33
+ request.eventSource.stream(async (stream: any) => {
34
+ stream.complete();
35
+ return Promise.resolve();
36
+ });
37
+
38
+ return { threadId: request.threadId || "mock-thread-id" };
39
+ }
40
+ }
41
+
42
+ return { OpenAIAdapter: MockOpenAIAdapter };
43
+ });
44
+
45
+ // Now import the modules
46
+ import { OpenAIAdapter } from "../../../src/service-adapters/openai/openai-adapter";
47
+
48
+ // Mock the Message classes since they use TypeGraphQL decorators
49
+ jest.mock("../../../src/graphql/types/converted", () => {
50
+ // Create minimal implementations of the message classes
51
+ class MockTextMessage {
52
+ content: string;
53
+ role: string;
54
+ id: string;
55
+
56
+ constructor(role: string, content: string) {
57
+ this.role = role;
58
+ this.content = content;
59
+ this.id = "mock-text-" + Math.random().toString(36).substring(7);
60
+ }
61
+
62
+ isTextMessage() {
63
+ return true;
64
+ }
65
+ isImageMessage() {
66
+ return false;
67
+ }
68
+ isActionExecutionMessage() {
69
+ return false;
70
+ }
71
+ isResultMessage() {
72
+ return false;
73
+ }
74
+ }
75
+
76
+ class MockActionExecutionMessage {
77
+ id: string;
78
+ name: string;
79
+ arguments: string;
80
+
81
+ constructor(params: { id: string; name: string; arguments: string }) {
82
+ this.id = params.id;
83
+ this.name = params.name;
84
+ this.arguments = params.arguments;
85
+ }
86
+
87
+ isTextMessage() {
88
+ return false;
89
+ }
90
+ isImageMessage() {
91
+ return false;
92
+ }
93
+ isActionExecutionMessage() {
94
+ return true;
95
+ }
96
+ isResultMessage() {
97
+ return false;
98
+ }
99
+ }
100
+
101
+ class MockResultMessage {
102
+ actionExecutionId: string;
103
+ result: string;
104
+ id: string;
105
+
106
+ constructor(params: { actionExecutionId: string; result: string }) {
107
+ this.actionExecutionId = params.actionExecutionId;
108
+ this.result = params.result;
109
+ this.id = "mock-result-" + Math.random().toString(36).substring(7);
110
+ }
111
+
112
+ isTextMessage() {
113
+ return false;
114
+ }
115
+ isImageMessage() {
116
+ return false;
117
+ }
118
+ isActionExecutionMessage() {
119
+ return false;
120
+ }
121
+ isResultMessage() {
122
+ return true;
123
+ }
124
+ }
125
+
126
+ return {
127
+ TextMessage: MockTextMessage,
128
+ ActionExecutionMessage: MockActionExecutionMessage,
129
+ ResultMessage: MockResultMessage,
130
+ };
131
+ });
132
+
133
+ describe("OpenAIAdapter", () => {
134
+ let adapter: OpenAIAdapter;
135
+ let mockEventSource: any;
136
+
137
+ beforeEach(() => {
138
+ jest.clearAllMocks();
139
+ adapter = new OpenAIAdapter();
140
+ mockEventSource = {
141
+ stream: jest.fn((callback) => {
142
+ const mockStream = {
143
+ sendTextMessageStart: jest.fn(),
144
+ sendTextMessageContent: jest.fn(),
145
+ sendTextMessageEnd: jest.fn(),
146
+ sendActionExecutionStart: jest.fn(),
147
+ sendActionExecutionArgs: jest.fn(),
148
+ sendActionExecutionEnd: jest.fn(),
149
+ complete: jest.fn(),
150
+ };
151
+ callback(mockStream);
152
+ }),
153
+ };
154
+ });
155
+
156
+ describe("Tool ID handling", () => {
157
+ it("should filter out tool_result messages that don't have corresponding tool_call IDs", async () => {
158
+ // Import dynamically after mocking
159
+ const {
160
+ TextMessage,
161
+ ActionExecutionMessage,
162
+ ResultMessage,
163
+ } = require("../../../src/graphql/types/converted");
164
+
165
+ // Create messages including one valid pair and one invalid tool_result
166
+ const systemMessage = new TextMessage("system", "System message");
167
+ const userMessage = new TextMessage("user", "User message");
168
+
169
+ // Valid tool execution message
170
+ const validToolExecution = new ActionExecutionMessage({
171
+ id: "valid-tool-id",
172
+ name: "validTool",
173
+ arguments: '{"arg":"value"}',
174
+ });
175
+
176
+ // Valid result for the above tool
177
+ const validToolResult = new ResultMessage({
178
+ actionExecutionId: "valid-tool-id",
179
+ result: '{"result":"success"}',
180
+ });
181
+
182
+ // Invalid tool result with no corresponding tool execution
183
+ const invalidToolResult = new ResultMessage({
184
+ actionExecutionId: "invalid-tool-id",
185
+ result: '{"result":"failure"}',
186
+ });
187
+
188
+ // Spy on the process method to test it's called properly
189
+ const processSpy = jest.spyOn(adapter, "process");
190
+
191
+ await adapter.process({
192
+ threadId: "test-thread",
193
+ model: "gpt-4o",
194
+ messages: [
195
+ systemMessage,
196
+ userMessage,
197
+ validToolExecution,
198
+ validToolResult,
199
+ invalidToolResult,
200
+ ],
201
+ actions: [],
202
+ eventSource: mockEventSource,
203
+ forwardedParameters: {},
204
+ });
205
+
206
+ // Verify the process method was called
207
+ expect(processSpy).toHaveBeenCalledTimes(1);
208
+
209
+ // Verify the stream function was called
210
+ expect(mockEventSource.stream).toHaveBeenCalled();
211
+ });
212
+
213
+ it("should handle duplicate tool IDs by only using each once", async () => {
214
+ // Import dynamically after mocking
215
+ const {
216
+ TextMessage,
217
+ ActionExecutionMessage,
218
+ ResultMessage,
219
+ } = require("../../../src/graphql/types/converted");
220
+
221
+ // Create messages including duplicate tool results for the same ID
222
+ const systemMessage = new TextMessage("system", "System message");
223
+
224
+ // Valid tool execution message
225
+ const toolExecution = new ActionExecutionMessage({
226
+ id: "tool-id-1",
227
+ name: "someTool",
228
+ arguments: '{"arg":"value"}',
229
+ });
230
+
231
+ // Two results for the same tool ID
232
+ const firstToolResult = new ResultMessage({
233
+ actionExecutionId: "tool-id-1",
234
+ result: '{"result":"first"}',
235
+ });
236
+
237
+ const duplicateToolResult = new ResultMessage({
238
+ actionExecutionId: "tool-id-1",
239
+ result: '{"result":"duplicate"}',
240
+ });
241
+
242
+ // Spy on the process method to test it's called properly
243
+ const processSpy = jest.spyOn(adapter, "process");
244
+
245
+ await adapter.process({
246
+ threadId: "test-thread",
247
+ model: "gpt-4o",
248
+ messages: [systemMessage, toolExecution, firstToolResult, duplicateToolResult],
249
+ actions: [],
250
+ eventSource: mockEventSource,
251
+ forwardedParameters: {},
252
+ });
253
+
254
+ // Verify the process method was called
255
+ expect(processSpy).toHaveBeenCalledTimes(1);
256
+
257
+ // Verify the stream function was called
258
+ expect(mockEventSource.stream).toHaveBeenCalled();
259
+ });
260
+
261
+ it("should call the stream method on eventSource", async () => {
262
+ // Import dynamically after mocking
263
+ const { TextMessage } = require("../../../src/graphql/types/converted");
264
+
265
+ // Create messages
266
+ const systemMessage = new TextMessage("system", "System message");
267
+ const userMessage = new TextMessage("user", "User message");
268
+
269
+ await adapter.process({
270
+ threadId: "test-thread",
271
+ model: "gpt-4o",
272
+ messages: [systemMessage, userMessage],
273
+ actions: [],
274
+ eventSource: mockEventSource,
275
+ forwardedParameters: {},
276
+ });
277
+
278
+ // Verify the stream function was called
279
+ expect(mockEventSource.stream).toHaveBeenCalled();
280
+ });
281
+
282
+ it("should return the provided threadId", async () => {
283
+ // Import dynamically after mocking
284
+ const { TextMessage } = require("../../../src/graphql/types/converted");
285
+
286
+ // Create a message
287
+ const systemMessage = new TextMessage("system", "System message");
288
+
289
+ const result = await adapter.process({
290
+ threadId: "test-thread",
291
+ model: "gpt-4o",
292
+ messages: [systemMessage],
293
+ actions: [],
294
+ eventSource: mockEventSource,
295
+ forwardedParameters: {},
296
+ });
297
+
298
+ expect(result.threadId).toBe("test-thread");
299
+ });
300
+ });
301
+ });
@@ -0,0 +1,21 @@
1
+ // Import reflect-metadata to support TypeGraphQL
2
+ import "reflect-metadata";
3
+
4
+ // Import Jest types and functions
5
+ import {
6
+ jest,
7
+ describe,
8
+ expect,
9
+ it,
10
+ test,
11
+ beforeEach,
12
+ afterEach,
13
+ beforeAll,
14
+ afterAll,
15
+ } from "@jest/globals";
16
+
17
+ // Suppress console output during tests
18
+ jest.spyOn(console, "log").mockImplementation(() => {});
19
+ jest.spyOn(console, "error").mockImplementation(() => {});
20
+
21
+ // The global types are already declared in global.d.ts, so we don't need to set globals here
@@ -0,0 +1,10 @@
1
+ {
2
+ "extends": "../tsconfig.json",
3
+ "compilerOptions": {
4
+ "types": ["node", "jest"],
5
+ "esModuleInterop": true,
6
+ "noEmit": true,
7
+ "allowJs": true
8
+ },
9
+ "include": ["./**/*.ts"]
10
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,13 @@
1
+ {
2
+ "extends": "../../utilities/tsconfig/base.json",
3
+ "compilerOptions": {
4
+ "types": ["node", "jest"],
5
+ "lib": ["es2017", "dom"],
6
+ "emitDecoratorMetadata": true,
7
+ "experimentalDecorators": true,
8
+ "strict": false,
9
+ "resolveJsonModule": true
10
+ },
11
+ "include": ["./src/**/*.ts", "./src/**/*.test.ts", "./src/**/__tests__/*", "./tests/**/*.ts"],
12
+ "exclude": ["dist", "build", "node_modules"]
13
+ }
package/tsup.config.ts ADDED
@@ -0,0 +1,20 @@
1
+ import { defineConfig, Options } from "tsup";
2
+
3
+ export default defineConfig((options: Options) => ({
4
+ ...options,
5
+ entry: ["src/index.ts", "src/v2/index.ts", "src/langgraph.ts"],
6
+ format: ["esm", "cjs"],
7
+ dts: true,
8
+ minify: false,
9
+ external: ["@ag-ui/langgraph"],
10
+ sourcemap: true,
11
+ exclude: [
12
+ "**/*.test.ts", // Exclude TypeScript test files
13
+ "**/*.test.tsx", // Exclude TypeScript React test files
14
+ "**/__tests__/*", // Exclude any files inside a __tests__ directory
15
+ ],
16
+ treeshake: true,
17
+ // Disable code splitting so each entry point is fully independent
18
+ // This prevents @ag-ui/langgraph from being pulled into index.mjs via shared chunks
19
+ splitting: false,
20
+ }));
package/typedoc.json ADDED
@@ -0,0 +1,4 @@
1
+ {
2
+ "extends": ["../../typedoc.base.json"],
3
+ "entryPoints": ["src/index.ts"]
4
+ }