@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,203 @@
1
+ /**
2
+ * Copilot Runtime adapter for Groq.
3
+ *
4
+ * ## Example
5
+ *
6
+ * ```ts
7
+ * import { CopilotRuntime, GroqAdapter } from "@copilotkit/runtime";
8
+ * import { Groq } from "groq-sdk";
9
+ *
10
+ * const groq = new Groq({ apiKey: process.env["GROQ_API_KEY"] });
11
+ *
12
+ * const copilotKit = new CopilotRuntime();
13
+ *
14
+ * return new GroqAdapter({ groq, model: "<model-name>" });
15
+ * ```
16
+ */
17
+ import type { Groq } from "groq-sdk";
18
+ import type { ChatCompletionMessageParam } from "groq-sdk/resources/chat";
19
+ import {
20
+ CopilotServiceAdapter,
21
+ CopilotRuntimeChatCompletionRequest,
22
+ CopilotRuntimeChatCompletionResponse,
23
+ } from "../service-adapter";
24
+ import {
25
+ convertActionInputToOpenAITool,
26
+ convertMessageToOpenAIMessage,
27
+ limitMessagesToTokenCount,
28
+ } from "../openai/utils";
29
+ import { randomUUID } from "@copilotkit/shared";
30
+ import { convertServiceAdapterError } from "../shared";
31
+
32
+ const DEFAULT_MODEL = "llama-3.3-70b-versatile";
33
+
34
+ export interface GroqAdapterParams {
35
+ /**
36
+ * An optional Groq instance to use.
37
+ */
38
+ groq?: Groq;
39
+
40
+ /**
41
+ * The model to use.
42
+ */
43
+ model?: string;
44
+
45
+ /**
46
+ * Whether to disable parallel tool calls.
47
+ * You can disable parallel tool calls to force the model to execute tool calls sequentially.
48
+ * This is useful if you want to execute tool calls in a specific order so that the state changes
49
+ * introduced by one tool call are visible to the next tool call. (i.e. new actions or readables)
50
+ *
51
+ * @default false
52
+ */
53
+ disableParallelToolCalls?: boolean;
54
+ }
55
+
56
+ export class GroqAdapter implements CopilotServiceAdapter {
57
+ public model: string = DEFAULT_MODEL;
58
+ public provider = "groq";
59
+
60
+ private disableParallelToolCalls: boolean = false;
61
+ private _groq: Groq;
62
+ public get groq(): Groq {
63
+ return this._groq;
64
+ }
65
+ public get name() {
66
+ return "GroqAdapter";
67
+ }
68
+
69
+ constructor(params?: GroqAdapterParams) {
70
+ if (params?.groq) {
71
+ this._groq = params.groq;
72
+ }
73
+ // If no instance provided, we'll lazy-load in ensureGroq()
74
+ if (params?.model) {
75
+ this.model = params.model;
76
+ }
77
+ this.disableParallelToolCalls = params?.disableParallelToolCalls || false;
78
+ }
79
+
80
+ private ensureGroq(): Groq {
81
+ if (!this._groq) {
82
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
83
+ const { Groq } = require("groq-sdk");
84
+ this._groq = new Groq({});
85
+ }
86
+ return this._groq;
87
+ }
88
+
89
+ async process(
90
+ request: CopilotRuntimeChatCompletionRequest,
91
+ ): Promise<CopilotRuntimeChatCompletionResponse> {
92
+ const {
93
+ threadId,
94
+ model = this.model,
95
+ messages,
96
+ actions,
97
+ eventSource,
98
+ forwardedParameters,
99
+ } = request;
100
+ const tools = actions.map(convertActionInputToOpenAITool);
101
+
102
+ let openaiMessages = messages.map((m) =>
103
+ convertMessageToOpenAIMessage(m, { keepSystemRole: true }),
104
+ );
105
+ openaiMessages = limitMessagesToTokenCount(openaiMessages, tools, model);
106
+
107
+ let toolChoice: any = forwardedParameters?.toolChoice;
108
+ if (forwardedParameters?.toolChoice === "function") {
109
+ toolChoice = {
110
+ type: "function",
111
+ function: { name: forwardedParameters.toolChoiceFunctionName },
112
+ };
113
+ }
114
+ let stream;
115
+ try {
116
+ const groq = this.ensureGroq();
117
+ stream = await groq.chat.completions.create({
118
+ model: model,
119
+ stream: true,
120
+ messages: openaiMessages as unknown as ChatCompletionMessageParam[],
121
+ ...(tools.length > 0 && { tools }),
122
+ ...(forwardedParameters?.maxTokens && {
123
+ max_tokens: forwardedParameters.maxTokens,
124
+ }),
125
+ ...(forwardedParameters?.stop && { stop: forwardedParameters.stop }),
126
+ ...(toolChoice && { tool_choice: toolChoice }),
127
+ ...(this.disableParallelToolCalls && { parallel_tool_calls: false }),
128
+ ...(forwardedParameters?.temperature && { temperature: forwardedParameters.temperature }),
129
+ });
130
+ } catch (error) {
131
+ throw convertServiceAdapterError(error, "Groq");
132
+ }
133
+
134
+ eventSource.stream(async (eventStream$) => {
135
+ let mode: "function" | "message" | null = null;
136
+ let currentMessageId: string;
137
+ let currentToolCallId: string;
138
+
139
+ try {
140
+ for await (const chunk of stream) {
141
+ const toolCall = chunk.choices[0].delta.tool_calls?.[0];
142
+ const content = chunk.choices[0].delta.content;
143
+
144
+ // When switching from message to function or vice versa,
145
+ // send the respective end event.
146
+ // If toolCall?.id is defined, it means a new tool call starts.
147
+ if (mode === "message" && toolCall?.id) {
148
+ mode = null;
149
+ eventStream$.sendTextMessageEnd({ messageId: currentMessageId });
150
+ } else if (mode === "function" && (toolCall === undefined || toolCall?.id)) {
151
+ mode = null;
152
+ eventStream$.sendActionExecutionEnd({ actionExecutionId: currentToolCallId });
153
+ }
154
+
155
+ // If we send a new message type, send the appropriate start event.
156
+ if (mode === null) {
157
+ if (toolCall?.id) {
158
+ mode = "function";
159
+ currentToolCallId = toolCall!.id;
160
+ eventStream$.sendActionExecutionStart({
161
+ actionExecutionId: currentToolCallId,
162
+ actionName: toolCall!.function!.name,
163
+ parentMessageId: chunk.id,
164
+ });
165
+ } else if (content) {
166
+ mode = "message";
167
+ currentMessageId = chunk.id;
168
+ eventStream$.sendTextMessageStart({ messageId: currentMessageId });
169
+ }
170
+ }
171
+
172
+ // send the content events
173
+ if (mode === "message" && content) {
174
+ eventStream$.sendTextMessageContent({
175
+ messageId: currentMessageId,
176
+ content,
177
+ });
178
+ } else if (mode === "function" && toolCall?.function?.arguments) {
179
+ eventStream$.sendActionExecutionArgs({
180
+ actionExecutionId: currentToolCallId,
181
+ args: toolCall.function.arguments,
182
+ });
183
+ }
184
+ }
185
+
186
+ // send the end events
187
+ if (mode === "message") {
188
+ eventStream$.sendTextMessageEnd({ messageId: currentMessageId });
189
+ } else if (mode === "function") {
190
+ eventStream$.sendActionExecutionEnd({ actionExecutionId: currentToolCallId });
191
+ }
192
+ } catch (error) {
193
+ throw convertServiceAdapterError(error, "Groq");
194
+ }
195
+
196
+ eventStream$.complete();
197
+ });
198
+
199
+ return {
200
+ threadId: request.threadId || randomUUID(),
201
+ };
202
+ }
203
+ }
@@ -0,0 +1,18 @@
1
+ export type {
2
+ CopilotRuntimeChatCompletionRequest,
3
+ CopilotRuntimeChatCompletionResponse,
4
+ CopilotServiceAdapter,
5
+ } from "./service-adapter";
6
+ export type { RemoteChainParameters } from "./langchain/langserve";
7
+ export { RemoteChain } from "./langchain/langserve";
8
+ export * from "./shared";
9
+ export * from "./openai/openai-adapter";
10
+ export * from "./langchain/langchain-adapter";
11
+ export * from "./google/google-genai-adapter";
12
+ export * from "./openai/openai-assistant-adapter";
13
+ export * from "./unify/unify-adapter";
14
+ export * from "./groq/groq-adapter";
15
+ export * from "./anthropic/anthropic-adapter";
16
+ export * from "./experimental/ollama/ollama-adapter";
17
+ export * from "./bedrock/bedrock-adapter";
18
+ export * from "./empty/empty-adapter";
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Copilot Runtime adapter for LangChain.
3
+ *
4
+ * ## Example
5
+ *
6
+ * ```ts
7
+ * import { CopilotRuntime, LangChainAdapter } from "@copilotkit/runtime";
8
+ * import { ChatOpenAI } from "@langchain/openai";
9
+ *
10
+ * const copilotKit = new CopilotRuntime();
11
+ *
12
+ * const model = new ChatOpenAI({
13
+ * model: "gpt-4o",
14
+ * apiKey: "<your-api-key>",
15
+ * });
16
+ *
17
+ * return new LangChainAdapter({
18
+ * chainFn: async ({ messages, tools }) => {
19
+ * return model.bindTools(tools).stream(messages);
20
+ * // or optionally enable strict mode
21
+ * // return model.bindTools(tools, { strict: true }).stream(messages);
22
+ * }
23
+ * });
24
+ * ```
25
+ *
26
+ * The asynchronous handler function (`chainFn`) can return any of the following:
27
+ *
28
+ * - A simple `string` response
29
+ * - A LangChain stream (`IterableReadableStream`)
30
+ * - A LangChain `BaseMessageChunk` object
31
+ * - A LangChain `AIMessage` object
32
+ */
33
+
34
+ import type { BaseMessage } from "@langchain/core/messages";
35
+ import { CopilotServiceAdapter } from "../service-adapter";
36
+ import {
37
+ CopilotRuntimeChatCompletionRequest,
38
+ CopilotRuntimeChatCompletionResponse,
39
+ } from "../service-adapter";
40
+ import {
41
+ convertActionInputToLangChainTool,
42
+ convertMessageToLangChainMessage,
43
+ streamLangChainResponse,
44
+ } from "./utils";
45
+ import type { DynamicStructuredTool } from "@langchain/core/tools";
46
+ import { LangChainReturnType } from "./types";
47
+ import { randomUUID } from "@copilotkit/shared";
48
+
49
+ interface ChainFnParameters {
50
+ model: string;
51
+ messages: BaseMessage[];
52
+ tools: DynamicStructuredTool[];
53
+ threadId?: string;
54
+ runId?: string;
55
+ }
56
+
57
+ interface LangChainAdapterOptions {
58
+ /**
59
+ * A function that uses the LangChain API to generate a response.
60
+ */
61
+ chainFn: (parameters: ChainFnParameters) => Promise<LangChainReturnType>;
62
+ }
63
+
64
+ export class LangChainAdapter implements CopilotServiceAdapter {
65
+ /**
66
+ * To use LangChain as a backend, provide a handler function to the adapter with your custom LangChain logic.
67
+ */
68
+ public get name() {
69
+ return "LangChainAdapter";
70
+ }
71
+ constructor(private options: LangChainAdapterOptions) {}
72
+
73
+ async process(
74
+ request: CopilotRuntimeChatCompletionRequest,
75
+ ): Promise<CopilotRuntimeChatCompletionResponse> {
76
+ try {
77
+ const {
78
+ eventSource,
79
+ model,
80
+ actions,
81
+ messages,
82
+ runId,
83
+ threadId: threadIdFromRequest,
84
+ } = request;
85
+ const threadId = threadIdFromRequest ?? randomUUID();
86
+ const result = await this.options.chainFn({
87
+ messages: messages.map(convertMessageToLangChainMessage),
88
+ tools: actions.map(convertActionInputToLangChainTool),
89
+ model,
90
+ threadId,
91
+ runId,
92
+ });
93
+
94
+ eventSource.stream(async (eventStream$) => {
95
+ await streamLangChainResponse({
96
+ result,
97
+ eventStream$,
98
+ });
99
+ });
100
+
101
+ return {
102
+ threadId,
103
+ };
104
+ } finally {
105
+ // Lazy require for optional peer dependency
106
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
107
+ const { awaitAllCallbacks } = require("@langchain/core/callbacks/promises");
108
+ await awaitAllCallbacks();
109
+ }
110
+ }
111
+ }
@@ -0,0 +1,88 @@
1
+ import { Parameter, Action } from "@copilotkit/shared";
2
+
3
+ export interface RemoteChainParameters {
4
+ name: string;
5
+ description: string;
6
+ chainUrl: string;
7
+ parameters?: Parameter[];
8
+ parameterType?: "single" | "multi";
9
+ }
10
+
11
+ export class RemoteChain {
12
+ name: string;
13
+ description: string;
14
+ chainUrl: string;
15
+ parameters?: Parameter[];
16
+ parameterType: "single" | "multi";
17
+
18
+ constructor(options: RemoteChainParameters) {
19
+ this.name = options.name;
20
+ this.description = options.description;
21
+ this.chainUrl = options.chainUrl;
22
+ this.parameters = options.parameters;
23
+ this.parameterType = options.parameterType || "multi";
24
+ }
25
+
26
+ async toAction(): Promise<Action<any>> {
27
+ if (!this.parameters) {
28
+ await this.inferLangServeParameters();
29
+ }
30
+
31
+ return {
32
+ name: this.name,
33
+ description: this.description,
34
+ parameters: this.parameters!,
35
+ handler: async (args: any) => {
36
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
37
+ const { RemoteRunnable } = require("langchain/runnables/remote");
38
+ const runnable = new RemoteRunnable({ url: this.chainUrl });
39
+ let input: any;
40
+ if (this.parameterType === "single") {
41
+ input = args[Object.keys(args)[0]];
42
+ } else {
43
+ input = args;
44
+ }
45
+ return await runnable.invoke(input);
46
+ },
47
+ };
48
+ }
49
+
50
+ async inferLangServeParameters() {
51
+ const supportedTypes = ["string", "number", "boolean"];
52
+
53
+ let schemaUrl = this.chainUrl.replace(/\/+$/, "") + "/input_schema";
54
+ let schema = await fetch(schemaUrl)
55
+ .then((res) => res.json())
56
+ .catch(() => {
57
+ throw new Error("Failed to fetch langserve schema at " + schemaUrl);
58
+ });
59
+ // for now, don't use json schema, just do a simple conversion
60
+
61
+ if (supportedTypes.includes(schema.type)) {
62
+ this.parameterType = "single";
63
+ this.parameters = [
64
+ {
65
+ name: "input",
66
+ type: schema.type,
67
+ description: "The input to the chain",
68
+ },
69
+ ];
70
+ } else if (schema.type === "object") {
71
+ this.parameterType = "multi";
72
+ this.parameters = Object.keys(schema.properties).map((key) => {
73
+ let property = schema.properties[key];
74
+ if (!supportedTypes.includes(property.type)) {
75
+ throw new Error("Unsupported schema type");
76
+ }
77
+ return {
78
+ name: key,
79
+ type: property.type,
80
+ description: property.description || "",
81
+ required: schema.required?.includes(key) || false,
82
+ };
83
+ });
84
+ } else {
85
+ throw new Error("Unsupported schema type");
86
+ }
87
+ }
88
+ }
@@ -0,0 +1,14 @@
1
+ import { AIMessage, AIMessageChunk, BaseMessageChunk } from "@langchain/core/messages";
2
+ import {
3
+ IterableReadableStream,
4
+ IterableReadableStreamInterface,
5
+ } from "@langchain/core/utils/stream";
6
+
7
+ export type LangChainBaseMessageChunkStream = IterableReadableStream<BaseMessageChunk>;
8
+ export type LangChainAIMessageChunkStream = IterableReadableStreamInterface<AIMessageChunk>;
9
+ export type LangChainReturnType =
10
+ | LangChainBaseMessageChunkStream
11
+ | LangChainAIMessageChunkStream
12
+ | BaseMessageChunk
13
+ | string
14
+ | AIMessage;