@copilotkit/runtime 0.37.0 → 0.38.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 (96) hide show
  1. package/.turbo/turbo-build.log +69 -54
  2. package/CHANGELOG.md +11 -0
  3. package/__snapshots__/schema/schema.graphql +15 -4
  4. package/dist/{chunk-2CCVVJDU.mjs → chunk-2PJG3NAC.mjs} +13 -15
  5. package/dist/chunk-2PJG3NAC.mjs.map +1 -0
  6. package/dist/{chunk-NFCPM5AM.mjs → chunk-6NZ4UMOD.mjs} +4 -4
  7. package/dist/chunk-6NZ4UMOD.mjs.map +1 -0
  8. package/dist/{chunk-XPAUPJMW.mjs → chunk-6YGDE3YI.mjs} +432 -220
  9. package/dist/chunk-6YGDE3YI.mjs.map +1 -0
  10. package/dist/chunk-BYB2LNMK.mjs +152 -0
  11. package/dist/chunk-BYB2LNMK.mjs.map +1 -0
  12. package/dist/{chunk-7IFP53C6.mjs → chunk-FRK6BXXV.mjs} +49 -11
  13. package/dist/chunk-FRK6BXXV.mjs.map +1 -0
  14. package/dist/{chunk-5HGYI6EG.mjs → chunk-JBDOA7MK.mjs} +34 -15
  15. package/dist/chunk-JBDOA7MK.mjs.map +1 -0
  16. package/dist/{chunk-4UA4RB4C.mjs → chunk-JIKPSUGQ.mjs} +45 -76
  17. package/dist/chunk-JIKPSUGQ.mjs.map +1 -0
  18. package/dist/{chunk-BLTAUVRP.mjs → chunk-OZMCHYYR.mjs} +5 -3
  19. package/dist/{chunk-BLTAUVRP.mjs.map → chunk-OZMCHYYR.mjs.map} +1 -1
  20. package/dist/chunk-RHQLCJGG.mjs +7 -0
  21. package/dist/chunk-RHQLCJGG.mjs.map +1 -0
  22. package/dist/failed-response-status-reasons-0ab19e06.d.ts +49 -0
  23. package/dist/graphql/types/base/index.mjs +2 -1
  24. package/dist/graphql/types/converted/index.mjs +3 -2
  25. package/dist/{index-f0875df3.d.ts → index-0e75acd2.d.ts} +86 -59
  26. package/dist/index.d.ts +7 -4
  27. package/dist/index.js +536 -169
  28. package/dist/index.js.map +1 -1
  29. package/dist/index.mjs +16 -13
  30. package/dist/index.mjs.map +1 -1
  31. package/dist/{langchain-adapter-9ce103f3.d.ts → langchain-adapter-a02d1d38.d.ts} +4 -4
  32. package/dist/{langserve-fd5066ee.d.ts → langserve-75ebbc38.d.ts} +25 -9
  33. package/dist/lib/cloud/index.d.ts +6 -0
  34. package/dist/lib/cloud/index.js +18 -0
  35. package/dist/lib/cloud/index.js.map +1 -0
  36. package/dist/lib/cloud/index.mjs +1 -0
  37. package/dist/lib/cloud/index.mjs.map +1 -0
  38. package/dist/lib/index.d.ts +6 -4
  39. package/dist/lib/index.js +530 -169
  40. package/dist/lib/index.js.map +1 -1
  41. package/dist/lib/index.mjs +9 -13
  42. package/dist/lib/integrations/index.d.ts +5 -3
  43. package/dist/lib/integrations/index.js +426 -64
  44. package/dist/lib/integrations/index.js.map +1 -1
  45. package/dist/lib/integrations/index.mjs +7 -5
  46. package/dist/lib/integrations/node-http/index.d.ts +4 -2
  47. package/dist/lib/integrations/node-http/index.js +416 -52
  48. package/dist/lib/integrations/node-http/index.js.map +1 -1
  49. package/dist/lib/integrations/node-http/index.mjs +6 -4
  50. package/dist/pages-router-e81920d5.d.ts +21 -0
  51. package/dist/service-adapters/index.d.ts +2 -2
  52. package/dist/service-adapters/index.js +82 -25
  53. package/dist/service-adapters/index.js.map +1 -1
  54. package/dist/service-adapters/index.mjs +5 -4
  55. package/dist/utils/index.d.ts +1 -0
  56. package/dist/utils/index.js +174 -0
  57. package/dist/utils/index.js.map +1 -0
  58. package/dist/utils/index.mjs +12 -0
  59. package/dist/utils/index.mjs.map +1 -0
  60. package/package.json +6 -4
  61. package/src/graphql/inputs/cloud-guardrails.input.ts +2 -5
  62. package/src/graphql/inputs/cloud.input.ts +2 -2
  63. package/src/graphql/resolvers/copilot.resolver.ts +340 -30
  64. package/src/graphql/types/response-status.type.ts +16 -2
  65. package/src/index.ts +1 -0
  66. package/src/lib/cloud/index.ts +4 -0
  67. package/src/lib/copilot-runtime.ts +116 -70
  68. package/src/lib/index.ts +0 -1
  69. package/src/lib/integrations/nextjs/app-router.ts +9 -17
  70. package/src/lib/integrations/nextjs/pages-router.ts +9 -15
  71. package/src/lib/integrations/node-http/index.ts +6 -14
  72. package/src/lib/integrations/shared.ts +38 -18
  73. package/src/lib/logger.ts +28 -0
  74. package/src/service-adapters/events.ts +20 -2
  75. package/src/service-adapters/experimental/groq/groq-adapter.ts +3 -1
  76. package/src/service-adapters/experimental/ollama/ollama-adapter.ts +3 -1
  77. package/src/service-adapters/google/google-genai-adapter.ts +6 -1
  78. package/src/service-adapters/google/utils.ts +1 -1
  79. package/src/service-adapters/index.ts +1 -1
  80. package/src/service-adapters/langchain/langchain-adapter.ts +8 -9
  81. package/src/service-adapters/langchain/langserve.ts +10 -4
  82. package/src/service-adapters/langchain/utils.ts +58 -9
  83. package/src/service-adapters/openai/openai-adapter.ts +8 -7
  84. package/src/service-adapters/openai/openai-assistant-adapter.ts +6 -8
  85. package/src/service-adapters/service-adapter.ts +1 -2
  86. package/src/utils/failed-response-status-reasons.ts +48 -0
  87. package/src/utils/index.ts +1 -0
  88. package/dist/chunk-2CCVVJDU.mjs.map +0 -1
  89. package/dist/chunk-4UA4RB4C.mjs.map +0 -1
  90. package/dist/chunk-5HGYI6EG.mjs.map +0 -1
  91. package/dist/chunk-7IFP53C6.mjs.map +0 -1
  92. package/dist/chunk-NFCPM5AM.mjs.map +0 -1
  93. package/dist/chunk-XPAUPJMW.mjs.map +0 -1
  94. package/dist/pages-router-b6bc6c60.d.ts +0 -30
  95. package/src/lib/copilot-cloud.ts +0 -63
  96. package/src/lib/guardrails.ts +0 -3
@@ -99,48 +99,107 @@
99
99
  */
100
100
 
101
101
  import { Action, actionParametersToJsonSchema, Parameter } from "@copilotkit/shared";
102
- import { RemoteChain, CopilotServiceAdapter } from "../service-adapters";
103
- import { CopilotCloud, RemoteCopilotCloud } from "./copilot-cloud";
102
+ import { RemoteChain, RemoteChainParameters, CopilotServiceAdapter } from "../service-adapters";
104
103
  import { MessageInput } from "../graphql/inputs/message.input";
105
104
  import { ActionInput } from "../graphql/inputs/action.input";
106
105
  import { RuntimeEventSource } from "../service-adapters/events";
107
106
  import { convertGqlInputToMessages } from "../service-adapters/conversion";
107
+ import { Message } from "../graphql/types/converted";
108
108
 
109
109
  interface CopilotRuntimeRequest {
110
110
  serviceAdapter: CopilotServiceAdapter;
111
111
  messages: MessageInput[];
112
112
  actions: ActionInput[];
113
+ outputMessagesPromise: Promise<Message[]>;
114
+ properties: any;
113
115
  threadId?: string;
114
116
  runId?: string;
115
117
  publicApiKey?: string;
116
118
  }
117
119
 
118
120
  interface CopilotRuntimeResponse {
119
- threadId?: string;
121
+ threadId: string;
120
122
  runId?: string;
121
123
  eventSource: RuntimeEventSource;
124
+ actions: Action<any>[];
125
+ }
126
+
127
+ type ActionsConfiguration<T extends Parameter[] | [] = []> =
128
+ | Action<T>[]
129
+ | ((ctx: { properties: any }) => Action<T>[]);
130
+
131
+ interface OnBeforeRequestOptions {
132
+ threadId?: string;
133
+ runId?: string;
134
+ inputMessages: Message[];
135
+ properties: any;
136
+ }
137
+
138
+ type OnBeforeRequestHandler = (options: OnBeforeRequestOptions) => void | Promise<void>;
139
+
140
+ interface OnAfterRequestOptions {
141
+ threadId: string;
142
+ runId?: string;
143
+ inputMessages: Message[];
144
+ outputMessages: Message[];
145
+ properties: any;
146
+ }
147
+
148
+ type OnAfterRequestHandler = (options: OnAfterRequestOptions) => void | Promise<void>;
149
+
150
+ interface Middleware {
151
+ /**
152
+ * A function that is called before the request is processed.
153
+ */
154
+ onBeforeRequest?: OnBeforeRequestHandler;
155
+
156
+ /**
157
+ * A function that is called after the request is processed.
158
+ */
159
+ onAfterRequest?: OnAfterRequestHandler;
122
160
  }
123
161
 
124
162
  export interface CopilotRuntimeConstructorParams<T extends Parameter[] | [] = []> {
163
+ /**
164
+ * Middleware to be used by the runtime.
165
+ *
166
+ * ```ts
167
+ * onBeforeRequest: (options: {
168
+ * threadId?: string;
169
+ * runId?: string;
170
+ * inputMessages: Message[];
171
+ * properties: any;
172
+ * }) => void | Promise<void>;
173
+ * ```
174
+ *
175
+ * ```ts
176
+ * onAfterRequest: (options: {
177
+ * threadId?: string;
178
+ * runId?: string;
179
+ * inputMessages: Message[];
180
+ * outputMessages: Message[];
181
+ * properties: any;
182
+ * }) => void | Promise<void>;
183
+ * ```
184
+ */
185
+ middleware?: Middleware;
186
+
125
187
  /*
126
188
  * A list of server side actions that can be executed.
127
189
  */
128
- actions?: Action<T>[];
190
+ actions?: ActionsConfiguration<T>;
129
191
 
130
192
  /*
131
193
  * An array of LangServer URLs.
132
194
  */
133
- langserve?: RemoteChain[];
134
-
135
- debug?: boolean;
136
- copilotCloud?: CopilotCloud;
195
+ langserve?: RemoteChainParameters[];
137
196
  }
138
197
 
139
198
  export class CopilotRuntime<const T extends Parameter[] | [] = []> {
140
- public actions: Action<any>[] = [];
199
+ public actions: ActionsConfiguration<T>;
141
200
  private langserve: Promise<Action<any>>[] = [];
142
- private debug: boolean = false;
143
- private copilotCloud: CopilotCloud;
201
+ private onBeforeRequest?: OnBeforeRequestHandler;
202
+ private onAfterRequest?: OnAfterRequestHandler;
144
203
 
145
204
  constructor(params?: CopilotRuntimeConstructorParams<T>) {
146
205
  this.actions = params?.actions || [];
@@ -149,30 +208,21 @@ export class CopilotRuntime<const T extends Parameter[] | [] = []> {
149
208
  const remoteChain = new RemoteChain(chain);
150
209
  this.langserve.push(remoteChain.toAction());
151
210
  }
152
- this.debug = params?.debug || false;
153
- this.copilotCloud = params?.copilotCloud || new RemoteCopilotCloud();
154
- }
155
-
156
- addAction<const T extends Parameter[] | [] = []>(action: Action<T>): void {
157
- this.removeAction(action.name);
158
- this.actions.push(action);
159
- }
160
211
 
161
- removeAction(actionName: string): void {
162
- this.actions = this.actions.filter((f) => f.name !== actionName);
212
+ this.onBeforeRequest = params?.middleware?.onBeforeRequest;
213
+ this.onAfterRequest = params?.middleware?.onAfterRequest;
163
214
  }
164
215
 
165
- async process({
166
- serviceAdapter,
167
- messages,
168
- actions: clientSideActionsInput,
169
- threadId,
170
- runId,
171
- publicApiKey,
172
- }: CopilotRuntimeRequest): Promise<CopilotRuntimeResponse> {
173
- // TODO-PROTOCOL: cloud configuration
174
- // const cloud: CopilotCloudConfig = forwardedProps.cloud;
175
-
216
+ async process(request: CopilotRuntimeRequest): Promise<CopilotRuntimeResponse> {
217
+ const {
218
+ serviceAdapter,
219
+ messages,
220
+ actions: clientSideActionsInput,
221
+ threadId,
222
+ runId,
223
+ properties,
224
+ outputMessagesPromise,
225
+ } = request;
176
226
  const langserveFunctions: Action<any>[] = [];
177
227
 
178
228
  for (const chainPromise of this.langserve) {
@@ -184,57 +234,58 @@ export class CopilotRuntime<const T extends Parameter[] | [] = []> {
184
234
  }
185
235
  }
186
236
 
187
- const serverSideActionsInput: ActionInput[] = [...this.actions, ...langserveFunctions].map(
188
- (action) => ({
189
- name: action.name,
190
- description: action.description,
191
- jsonSchema: JSON.stringify(actionParametersToJsonSchema(action.parameters)),
192
- }),
193
- );
237
+ const configuredActions =
238
+ typeof this.actions === "function" ? this.actions({ properties }) : this.actions;
194
239
 
195
- const actions = flattenToolCallsNoDuplicates([
240
+ const actions = [...configuredActions, ...langserveFunctions];
241
+
242
+ const serverSideActionsInput: ActionInput[] = actions.map((action) => ({
243
+ name: action.name,
244
+ description: action.description,
245
+ jsonSchema: JSON.stringify(actionParametersToJsonSchema(action.parameters)),
246
+ }));
247
+
248
+ const actionInputs = flattenToolCallsNoDuplicates([
196
249
  ...serverSideActionsInput,
197
250
  ...clientSideActionsInput,
198
251
  ]);
252
+ const inputMessages = convertGqlInputToMessages(messages);
253
+
254
+ await this.onBeforeRequest?.({
255
+ threadId,
256
+ runId,
257
+ inputMessages,
258
+ properties,
259
+ });
199
260
 
200
261
  try {
201
262
  const eventSource = new RuntimeEventSource();
202
- // TODO-PROTOCOL: type this and support function calls
263
+
203
264
  const result = await serviceAdapter.process({
204
- messages: convertGqlInputToMessages(messages),
205
- actions,
265
+ messages: inputMessages,
266
+ actions: actionInputs,
206
267
  threadId,
207
268
  runId,
208
269
  eventSource,
209
270
  });
210
271
 
211
- // TODO-PROTOCOL add guardrails
212
- //
213
- // if (publicApiKey !== undefined) {
214
- // // wait for the cloud log chat to finish before streaming back the response
215
- // try {
216
- // const checkGuardrailsInputResult = await this.copilotCloud.checkGuardrailsInput({
217
- // cloud,
218
- // publicApiKey,
219
- // messages: forwardedProps.messages || [],
220
- // });
272
+ outputMessagesPromise
273
+ .then((outputMessages) => {
274
+ this.onAfterRequest?.({
275
+ threadId: result.threadId,
276
+ runId: result.runId,
277
+ inputMessages,
278
+ outputMessages,
279
+ properties,
280
+ });
281
+ })
282
+ .catch((_error) => {});
221
283
 
222
- // if (checkGuardrailsInputResult.status === "denied") {
223
- // // the chat was denied. instead of streaming back the response,
224
- // // we let the client know...
225
- // return {
226
- // stream: new SingleChunkReadableStream(checkGuardrailsInputResult.reason),
227
- // // headers: result.headers,
228
- // };
229
- // }
230
- // } catch (error) {
231
- // console.error("Error checking guardrails:", error);
232
- // }
233
- // }
234
284
  return {
235
285
  threadId: result.threadId,
236
286
  runId: result.runId,
237
287
  eventSource,
288
+ actions: actions,
238
289
  };
239
290
  } catch (error) {
240
291
  console.error("Error getting response:", error);
@@ -254,8 +305,3 @@ export function flattenToolCallsNoDuplicates(toolsByPriority: ActionInput[]): Ac
254
305
  }
255
306
  return allTools;
256
307
  }
257
-
258
- /**
259
- * @deprecated use CopilotRuntime instead
260
- */
261
- export class CopilotBackend extends CopilotRuntime {}
package/src/lib/index.ts CHANGED
@@ -3,5 +3,4 @@ export * from "../service-adapters/openai/openai-adapter";
3
3
  export * from "../service-adapters/langchain/langchain-adapter";
4
4
  export * from "../service-adapters/google/google-genai-adapter";
5
5
  export * from "../service-adapters/openai/openai-assistant-adapter";
6
- export * from "./copilot-cloud";
7
6
  export * from "./integrations";
@@ -1,29 +1,21 @@
1
1
  import { createYoga } from "graphql-yoga";
2
- import { getCommonConfig } from "../shared";
3
- import { CopilotRuntime } from "../../copilot-runtime";
4
- import { CopilotServiceAdapter } from "../../../service-adapters";
2
+ import { CreateCopilotRuntimeServerOptions, getCommonConfig } from "../shared";
5
3
 
6
- export function copilotRuntimeNextJSAppRouterEndpoint({
7
- runtime,
8
- endpoint,
9
- serviceAdapter,
10
- }: {
11
- runtime: CopilotRuntime;
12
- serviceAdapter: CopilotServiceAdapter;
13
- endpoint: string;
14
- }) {
15
- const commonConfig = getCommonConfig({ runtime, serviceAdapter });
4
+ export function copilotRuntimeNextJSAppRouterEndpoint(options: CreateCopilotRuntimeServerOptions) {
5
+ const commonConfig = getCommonConfig(options);
6
+ const logger = commonConfig.logging;
7
+ logger.debug("Creating NextJS App Router endpoint");
16
8
 
17
9
  const yoga = createYoga({
18
10
  ...commonConfig,
19
- graphqlEndpoint: endpoint,
11
+ graphqlEndpoint: options.endpoint,
20
12
  fetchAPI: { Response: globalThis.Response },
21
13
  });
22
14
 
23
15
  return {
24
16
  handleRequest: yoga,
25
- GET: yoga,
26
- POST: yoga,
27
- OPTIONS: yoga,
17
+ GET: yoga as any,
18
+ POST: yoga as any,
19
+ OPTIONS: yoga as any,
28
20
  };
29
21
  }
@@ -1,7 +1,5 @@
1
1
  import { YogaServerInstance, createYoga } from "graphql-yoga";
2
- import { GraphQLContext, getCommonConfig } from "../shared";
3
- import { CopilotRuntime } from "../../copilot-runtime";
4
- import { CopilotServiceAdapter } from "../../../service-adapters";
2
+ import { CreateCopilotRuntimeServerOptions, GraphQLContext, getCommonConfig } from "../shared";
5
3
 
6
4
  export const config = {
7
5
  api: {
@@ -11,25 +9,21 @@ export const config = {
11
9
 
12
10
  export type CopilotRuntimeServerInstance<T> = YogaServerInstance<T, Partial<GraphQLContext>>;
13
11
 
14
- // Theis import is needed to fix the type error
12
+ // This import is needed to fix the type error
15
13
  // Fix is currently in TypeScript 5.5 beta, waiting for stable version
16
14
  // https://github.com/microsoft/TypeScript/issues/42873#issuecomment-2066874644
17
15
  export type {} from "@whatwg-node/server";
18
16
 
19
- export function copilotRuntimeNextJSPagesRouterEndpoint({
20
- runtime,
21
- endpoint,
22
- serviceAdapter,
23
- }: {
24
- runtime: CopilotRuntime;
25
- serviceAdapter: CopilotServiceAdapter;
26
- endpoint: string;
27
- }): CopilotRuntimeServerInstance<GraphQLContext> {
28
- const commonConfig = getCommonConfig({ runtime, serviceAdapter });
17
+ export function copilotRuntimeNextJSPagesRouterEndpoint(
18
+ options: CreateCopilotRuntimeServerOptions,
19
+ ): CopilotRuntimeServerInstance<GraphQLContext> {
20
+ const commonConfig = getCommonConfig(options);
21
+ const logger = commonConfig.logging;
22
+ logger.debug("Creating NextJS Pages Router endpoint");
29
23
 
30
24
  const yoga = createYoga({
31
25
  ...commonConfig,
32
- graphqlEndpoint: endpoint,
26
+ graphqlEndpoint: options.endpoint,
33
27
  });
34
28
 
35
29
  return yoga;
@@ -1,22 +1,14 @@
1
1
  import { createYoga } from "graphql-yoga";
2
- import { getCommonConfig } from "../shared";
3
- import { CopilotRuntime } from "../../copilot-runtime";
4
- import { CopilotServiceAdapter } from "../../../service-adapters";
2
+ import { CreateCopilotRuntimeServerOptions, getCommonConfig } from "../shared";
5
3
 
6
- export function copilotRuntimeNodeHttpEndpoint({
7
- runtime,
8
- endpoint,
9
- serviceAdapter,
10
- }: {
11
- runtime: CopilotRuntime;
12
- serviceAdapter: CopilotServiceAdapter;
13
- endpoint: string;
14
- }) {
15
- const commonConfig = getCommonConfig({ runtime, serviceAdapter });
4
+ export function copilotRuntimeNodeHttpEndpoint(options: CreateCopilotRuntimeServerOptions) {
5
+ const commonConfig = getCommonConfig(options);
6
+ const logger = commonConfig.logging;
7
+ logger.debug("Creating Node HTTP endpoint");
16
8
 
17
9
  const yoga = createYoga({
18
10
  ...commonConfig,
19
- graphqlEndpoint: endpoint,
11
+ graphqlEndpoint: options.endpoint,
20
12
  });
21
13
 
22
14
  return yoga;
@@ -1,10 +1,14 @@
1
1
  import { YogaInitialContext } from "graphql-yoga";
2
- import { GuardrailsOptions } from "../guardrails";
3
2
  import { buildSchemaSync } from "type-graphql";
4
3
  import { CopilotResolver } from "../../graphql/resolvers/copilot.resolver";
5
4
  import { useDeferStream } from "@graphql-yoga/plugin-defer-stream";
6
5
  import { CopilotRuntime } from "../copilot-runtime";
7
6
  import { CopilotServiceAdapter } from "../../service-adapters";
7
+ import { CopilotCloudOptions } from "../cloud";
8
+ import { LogLevel, createLogger } from "../../lib/logger";
9
+ import { createYoga } from "graphql-yoga";
10
+
11
+ const logger = createLogger();
8
12
 
9
13
  type AnyPrimitive = string | boolean | number | null;
10
14
  export type CopilotRequestContextProperties = Record<
@@ -12,33 +16,37 @@ export type CopilotRequestContextProperties = Record<
12
16
  AnyPrimitive | Record<string, AnyPrimitive>
13
17
  >;
14
18
 
15
- type CopilotKitContext = {
16
- runtime: CopilotRuntime;
17
- serviceAdapter: CopilotServiceAdapter;
18
- properties: CopilotRequestContextProperties;
19
- };
20
-
21
19
  export type GraphQLContext = YogaInitialContext & {
22
- _copilotkit: CopilotKitContext;
20
+ _copilotkit: CreateCopilotRuntimeServerOptions;
21
+ properties: CopilotRequestContextProperties;
22
+ logger: typeof logger;
23
23
  };
24
24
 
25
25
  export interface CreateCopilotRuntimeServerOptions {
26
- runtime: CopilotRuntime;
26
+ runtime: CopilotRuntime<any>;
27
27
  serviceAdapter: CopilotServiceAdapter;
28
- guardrails?: GuardrailsOptions;
28
+ endpoint: string;
29
+ baseUrl?: string;
30
+ cloud?: CopilotCloudOptions;
31
+ properties?: CopilotRequestContextProperties;
32
+ logLevel?: LogLevel;
29
33
  }
30
34
 
31
35
  export async function createContext(
32
36
  initialContext: YogaInitialContext,
33
- copilotKitContext: CopilotKitContext,
37
+ copilotKitContext: CreateCopilotRuntimeServerOptions,
38
+ contextLogger: typeof logger,
39
+ properties: CopilotRequestContextProperties = {},
34
40
  ): Promise<Partial<GraphQLContext>> {
41
+ logger.debug({ copilotKitContext }, "Creating GraphQL context");
35
42
  const ctx: GraphQLContext = {
36
43
  ...initialContext,
37
44
  _copilotkit: {
38
45
  ...copilotKitContext,
39
46
  },
47
+ properties: { ...properties },
48
+ logger: contextLogger,
40
49
  };
41
-
42
50
  return ctx;
43
51
  }
44
52
 
@@ -47,22 +55,34 @@ export function buildSchema(
47
55
  emitSchemaFile?: string;
48
56
  } = {},
49
57
  ) {
58
+ logger.debug("Building GraphQL schema...");
50
59
  const schema = buildSchemaSync({
51
60
  resolvers: [CopilotResolver],
52
61
  emitSchemaFile: options.emitSchemaFile,
53
62
  });
63
+ logger.debug("GraphQL schema built successfully");
54
64
  return schema;
55
65
  }
56
66
 
57
- export function getCommonConfig(options?: CreateCopilotRuntimeServerOptions) {
67
+ export type CommonConfig = {
68
+ logging: typeof logger;
69
+ schema: ReturnType<typeof buildSchema>;
70
+ plugins: Parameters<typeof createYoga>[0]["plugins"];
71
+ context: (ctx: YogaInitialContext) => Promise<Partial<GraphQLContext>>;
72
+ };
73
+
74
+ export function getCommonConfig(options: CreateCopilotRuntimeServerOptions): CommonConfig {
75
+ const logLevel = (process.env.LOG_LEVEL as LogLevel) || (options.logLevel as LogLevel) || "error";
76
+ const logger = createLogger({ level: logLevel, component: "getCommonConfig" });
77
+ logger.debug("Getting common config");
78
+
79
+ const contextLogger = createLogger({ level: logLevel });
80
+
58
81
  return {
82
+ logging: createLogger({ component: "Yoga GraphQL", level: logLevel }),
59
83
  schema: buildSchema(),
60
84
  plugins: [useDeferStream()],
61
85
  context: (ctx: YogaInitialContext): Promise<Partial<GraphQLContext>> =>
62
- createContext(ctx, {
63
- runtime: options.runtime,
64
- serviceAdapter: options.serviceAdapter,
65
- properties: {},
66
- }),
86
+ createContext(ctx, options, contextLogger, options.properties),
67
87
  };
68
88
  }
@@ -0,0 +1,28 @@
1
+ import createPinoLogger from "pino";
2
+ import pretty from "pino-pretty";
3
+
4
+ export type LogLevel = "debug" | "info" | "warn" | "error";
5
+
6
+ export type CopilotRuntimeLogger = ReturnType<typeof createLogger>;
7
+
8
+ export function createLogger(options?: { level?: LogLevel; component?: string }) {
9
+ const { level, component } = options || {};
10
+ const stream = pretty({ colorize: true });
11
+
12
+ const logger = createPinoLogger(
13
+ {
14
+ level: process.env.LOG_LEVEL || level || "error",
15
+ redact: {
16
+ paths: ["pid", "hostname"],
17
+ remove: true,
18
+ },
19
+ },
20
+ stream,
21
+ );
22
+
23
+ if (component) {
24
+ return logger.child({ component });
25
+ } else {
26
+ return logger;
27
+ }
28
+ }
@@ -1,6 +1,7 @@
1
1
  import { Action } from "@copilotkit/shared";
2
- import { of, concat, map, scan, concatMap, ReplaySubject } from "rxjs";
2
+ import { of, concat, map, scan, concatMap, ReplaySubject, Subject, firstValueFrom } from "rxjs";
3
3
  import { streamLangChainResponse } from "./langchain/utils";
4
+ import { GuardrailsResult } from "../graphql/types/guardrails-result.type";
4
5
 
5
6
  export enum RuntimeEventTypes {
6
7
  TextMessageStart = "TextMessageStart",
@@ -109,7 +110,13 @@ export class RuntimeEventSource {
109
110
  this.callback = callback;
110
111
  }
111
112
 
112
- process(serversideActions: Action<any>[]) {
113
+ process({
114
+ serversideActions,
115
+ guardrailsResult$,
116
+ }: {
117
+ serversideActions: Action<any>[];
118
+ guardrailsResult$?: Subject<GuardrailsResult>;
119
+ }) {
113
120
  this.callback(this.eventStream$).catch((error) => {
114
121
  console.error("Error in event source callback", error);
115
122
  });
@@ -156,6 +163,7 @@ export class RuntimeEventSource {
156
163
  const toolCallEventStream$ = new RuntimeEventSubject();
157
164
  executeAction(
158
165
  toolCallEventStream$,
166
+ guardrailsResult$ ? guardrailsResult$ : null,
159
167
  eventWithState.action!,
160
168
  eventWithState.args,
161
169
  eventWithState.actionExecutionId,
@@ -173,10 +181,20 @@ export class RuntimeEventSource {
173
181
 
174
182
  async function executeAction(
175
183
  eventStream$: RuntimeEventSubject,
184
+ guardrailsResult$: Subject<GuardrailsResult> | null,
176
185
  action: Action<any>,
177
186
  actionArguments: string,
178
187
  actionExecutionId: string,
179
188
  ) {
189
+ if (guardrailsResult$) {
190
+ const { status } = await firstValueFrom(guardrailsResult$);
191
+
192
+ if (status === "denied") {
193
+ eventStream$.complete();
194
+ return;
195
+ }
196
+ }
197
+
180
198
  // Prepare arguments for function calling
181
199
  let args: Record<string, any>[] = [];
182
200
  if (actionArguments) {
@@ -107,7 +107,9 @@ export class ExperimentalGroqAdapter implements CopilotServiceAdapter {
107
107
 
108
108
  eventStream$.complete();
109
109
  });
110
- return {};
110
+ return {
111
+ threadId: request.threadId || nanoid(),
112
+ };
111
113
  }
112
114
  }
113
115
 
@@ -70,6 +70,8 @@ export class ExperimentalOllamaAdapter implements CopilotServiceAdapter {
70
70
 
71
71
  eventStream$.complete();
72
72
  });
73
- return {};
73
+ return {
74
+ threadId: request.threadId || nanoid(),
75
+ };
74
76
  }
75
77
  }
@@ -104,6 +104,9 @@ export class GoogleGenerativeAIAdapter implements CopilotServiceAdapter {
104
104
  let isTextMessage = false;
105
105
  for await (const chunk of result.stream) {
106
106
  const chunkText = chunk.text();
107
+ if (chunkText === "") {
108
+ continue;
109
+ }
107
110
  if (!isTextMessage) {
108
111
  isTextMessage = true;
109
112
  eventStream$.sendTextMessageStart(nanoid());
@@ -127,7 +130,9 @@ export class GoogleGenerativeAIAdapter implements CopilotServiceAdapter {
127
130
  eventStream$.complete();
128
131
  });
129
132
 
130
- return {};
133
+ return {
134
+ threadId: request.threadId || nanoid(),
135
+ };
131
136
  }
132
137
  }
133
138
 
@@ -38,7 +38,7 @@ export function convertMessageToGoogleGenAIMessage(message: Message) {
38
38
  };
39
39
  } else if (message instanceof ResultMessage) {
40
40
  return {
41
- role: "model",
41
+ role: "function",
42
42
  parts: [
43
43
  {
44
44
  functionResponse: {
@@ -3,4 +3,4 @@ export { OpenAIAdapter } from "./openai/openai-adapter";
3
3
  export { OpenAIAssistantAdapter } from "./openai/openai-assistant-adapter";
4
4
  export { GoogleGenerativeAIAdapter } from "./google/google-genai-adapter";
5
5
  export { LangChainAdapter } from "./langchain/langchain-adapter";
6
- export { RemoteChain } from "./langchain/langserve";
6
+ export { RemoteChain, type RemoteChainParameters } from "./langchain/langserve";
@@ -35,6 +35,7 @@ import {
35
35
  } from "./utils";
36
36
  import { DynamicStructuredTool } from "@langchain/core/tools";
37
37
  import { LangChainReturnType } from "./types";
38
+ import { nanoid } from "nanoid";
38
39
 
39
40
  interface ChainFnParameters {
40
41
  model: string;
@@ -54,14 +55,10 @@ export class LangChainAdapter implements CopilotServiceAdapter {
54
55
  */
55
56
  constructor(private options: LangChainAdapterOptions) {}
56
57
 
57
- async process({
58
- eventSource,
59
- model,
60
- actions,
61
- messages,
62
- threadId,
63
- runId,
64
- }: CopilotRuntimeChatCompletionRequest): Promise<CopilotRuntimeChatCompletionResponse> {
58
+ async process(
59
+ request: CopilotRuntimeChatCompletionRequest,
60
+ ): Promise<CopilotRuntimeChatCompletionResponse> {
61
+ const { eventSource, model, actions, messages, threadId, runId } = request;
65
62
  const result = await this.options.chainFn({
66
63
  messages: messages.map(convertMessageToLangChainMessage),
67
64
  tools: actions.map(convertActionInputToLangChainTool),
@@ -77,6 +74,8 @@ export class LangChainAdapter implements CopilotServiceAdapter {
77
74
  });
78
75
  });
79
76
 
80
- return {};
77
+ return {
78
+ threadId: threadId || nanoid(),
79
+ };
81
80
  }
82
81
  }