@copilotkit/runtime 1.7.0-next.0 → 1.7.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 (44) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.md +75 -0
  3. package/dist/{chunk-34Y5DNNJ.mjs → chunk-66YYMUU2.mjs} +120 -5
  4. package/dist/chunk-66YYMUU2.mjs.map +1 -0
  5. package/dist/{chunk-PH24IU7T.mjs → chunk-7X5R75DH.mjs} +2 -2
  6. package/dist/{chunk-2BN7NZNC.mjs → chunk-BYQ7M4HT.mjs} +2 -2
  7. package/dist/{chunk-ZYFN76KV.mjs → chunk-KFTZCVAE.mjs} +2 -2
  8. package/dist/chunk-PTC5JN3P.mjs +1 -0
  9. package/dist/{copilot-runtime-15bfc4f4.d.ts → copilot-runtime-5103c7e7.d.ts} +66 -1
  10. package/dist/index.d.ts +1 -1
  11. package/dist/index.js +120 -4
  12. package/dist/index.js.map +1 -1
  13. package/dist/index.mjs +7 -5
  14. package/dist/index.mjs.map +1 -1
  15. package/dist/lib/index.d.ts +1 -1
  16. package/dist/lib/index.js +120 -4
  17. package/dist/lib/index.js.map +1 -1
  18. package/dist/lib/index.mjs +7 -5
  19. package/dist/lib/integrations/index.d.ts +2 -2
  20. package/dist/lib/integrations/index.js +1 -1
  21. package/dist/lib/integrations/index.js.map +1 -1
  22. package/dist/lib/integrations/index.mjs +4 -4
  23. package/dist/lib/integrations/nest/index.d.ts +1 -1
  24. package/dist/lib/integrations/nest/index.js +1 -1
  25. package/dist/lib/integrations/nest/index.js.map +1 -1
  26. package/dist/lib/integrations/nest/index.mjs +2 -2
  27. package/dist/lib/integrations/node-express/index.d.ts +1 -1
  28. package/dist/lib/integrations/node-express/index.js +1 -1
  29. package/dist/lib/integrations/node-express/index.js.map +1 -1
  30. package/dist/lib/integrations/node-express/index.mjs +2 -2
  31. package/dist/lib/integrations/node-http/index.d.ts +1 -1
  32. package/dist/lib/integrations/node-http/index.js +1 -1
  33. package/dist/lib/integrations/node-http/index.js.map +1 -1
  34. package/dist/lib/integrations/node-http/index.mjs +1 -1
  35. package/package.json +2 -2
  36. package/src/lib/index.ts +1 -0
  37. package/src/lib/logger.ts +48 -0
  38. package/src/lib/runtime/copilot-runtime.ts +162 -2
  39. package/dist/chunk-34Y5DNNJ.mjs.map +0 -1
  40. package/dist/chunk-DFOKBSIS.mjs +0 -1
  41. /package/dist/{chunk-PH24IU7T.mjs.map → chunk-7X5R75DH.mjs.map} +0 -0
  42. /package/dist/{chunk-2BN7NZNC.mjs.map → chunk-BYQ7M4HT.mjs.map} +0 -0
  43. /package/dist/{chunk-ZYFN76KV.mjs.map → chunk-KFTZCVAE.mjs.map} +0 -0
  44. /package/dist/{chunk-DFOKBSIS.mjs.map → chunk-PTC5JN3P.mjs.map} +0 -0
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  copilotRuntimeNodeHttpEndpoint
3
- } from "../../../chunk-34Y5DNNJ.mjs";
3
+ } from "../../../chunk-66YYMUU2.mjs";
4
4
  import "../../../chunk-FZJAYGIR.mjs";
5
5
  import "../../../chunk-5BIEM2UU.mjs";
6
6
  import "../../../chunk-RTFJTJMA.mjs";
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  "publishConfig": {
10
10
  "access": "public"
11
11
  },
12
- "version": "1.7.0-next.0",
12
+ "version": "1.7.0",
13
13
  "sideEffects": false,
14
14
  "main": "./dist/index.js",
15
15
  "module": "./dist/index.mjs",
@@ -59,7 +59,7 @@
59
59
  "rxjs": "^7.8.1",
60
60
  "type-graphql": "2.0.0-rc.1",
61
61
  "zod": "^3.23.3",
62
- "@copilotkit/shared": "1.7.0-next.0"
62
+ "@copilotkit/shared": "1.7.0"
63
63
  },
64
64
  "keywords": [
65
65
  "copilotkit",
package/src/lib/index.ts CHANGED
@@ -6,3 +6,4 @@ export * from "../service-adapters/openai/openai-assistant-adapter";
6
6
  export * from "../service-adapters/unify/unify-adapter";
7
7
  export * from "../service-adapters/groq/groq-adapter";
8
8
  export * from "./integrations";
9
+ export * from "./logger";
package/src/lib/logger.ts CHANGED
@@ -26,3 +26,51 @@ export function createLogger(options?: { level?: LogLevel; component?: string })
26
26
  return logger;
27
27
  }
28
28
  }
29
+
30
+ // LangFuse Logging Integration
31
+ export interface LogLLMRequestData {
32
+ threadId?: string;
33
+ runId?: string;
34
+ model?: string;
35
+ messages: any[];
36
+ actions?: any[];
37
+ forwardedParameters?: any;
38
+ timestamp: number;
39
+ provider?: string;
40
+ [key: string]: any;
41
+ }
42
+
43
+ export interface LogLLMResponseData {
44
+ threadId: string;
45
+ runId?: string;
46
+ model?: string;
47
+ output: any;
48
+ latency: number;
49
+ timestamp: number;
50
+ provider?: string;
51
+ isProgressiveChunk?: boolean;
52
+ isFinalResponse?: boolean;
53
+ [key: string]: any;
54
+ }
55
+
56
+ export interface LogLLMErrorData {
57
+ threadId?: string;
58
+ runId?: string;
59
+ model?: string;
60
+ error: Error | string;
61
+ timestamp: number;
62
+ provider?: string;
63
+ [key: string]: any;
64
+ }
65
+
66
+ export interface CopilotLoggerHooks {
67
+ logRequest: (data: LogLLMRequestData) => void | Promise<void>;
68
+ logResponse: (data: LogLLMResponseData) => void | Promise<void>;
69
+ logError: (data: LogLLMErrorData) => void | Promise<void>;
70
+ }
71
+
72
+ export interface CopilotLoggingConfig {
73
+ enabled: boolean;
74
+ progressive: boolean;
75
+ logger: CopilotLoggerHooks;
76
+ }
@@ -33,7 +33,7 @@ import {
33
33
 
34
34
  import { MessageInput } from "../../graphql/inputs/message.input";
35
35
  import { ActionInput } from "../../graphql/inputs/action.input";
36
- import { RuntimeEventSource } from "../../service-adapters/events";
36
+ import { RuntimeEventSource, RuntimeEventTypes } from "../../service-adapters/events";
37
37
  import { convertGqlInputToMessages } from "../../service-adapters/conversion";
38
38
  import { Message } from "../../graphql/types/converted";
39
39
  import { ForwardedParametersInput } from "../../graphql/inputs/forwarded-parameters.input";
@@ -61,6 +61,12 @@ import { LoadAgentStateResponse } from "../../graphql/types/load-agent-state-res
61
61
  import { Client as LangGraphClient } from "@langchain/langgraph-sdk";
62
62
  import { langchainMessagesToCopilotKit } from "./remote-lg-action";
63
63
  import { MetaEventInput } from "../../graphql/inputs/meta-event.input";
64
+ import {
65
+ CopilotLoggingConfig,
66
+ LogLLMRequestData,
67
+ LogLLMResponseData,
68
+ LogLLMErrorData,
69
+ } from "../logger";
64
70
 
65
71
  interface CopilotRuntimeRequest {
66
72
  serviceAdapter: CopilotServiceAdapter;
@@ -179,6 +185,23 @@ export interface CopilotRuntimeConstructorParams<T extends Parameter[] | [] = []
179
185
  * Instead, all processing will be handled by the service adapter.
180
186
  */
181
187
  delegateAgentProcessingToServiceAdapter?: boolean;
188
+
189
+ /**
190
+ * Configuration for LLM request/response logging
191
+ *
192
+ * ```ts
193
+ * logging: {
194
+ * enabled: true, // Enable or disable logging
195
+ * progressive: true, // Set to false for buffered logging
196
+ * logger: {
197
+ * logRequest: (data) => langfuse.trace({ name: "LLM Request", input: data }),
198
+ * logResponse: (data) => langfuse.trace({ name: "LLM Response", output: data }),
199
+ * logError: (errorData) => langfuse.trace({ name: "LLM Error", metadata: errorData }),
200
+ * },
201
+ * }
202
+ * ```
203
+ */
204
+ logging?: CopilotLoggingConfig;
182
205
  }
183
206
 
184
207
  export class CopilotRuntime<const T extends Parameter[] | [] = []> {
@@ -188,6 +211,7 @@ export class CopilotRuntime<const T extends Parameter[] | [] = []> {
188
211
  private onBeforeRequest?: OnBeforeRequestHandler;
189
212
  private onAfterRequest?: OnAfterRequestHandler;
190
213
  private delegateAgentProcessingToServiceAdapter: boolean;
214
+ private logging?: CopilotLoggingConfig;
191
215
 
192
216
  constructor(params?: CopilotRuntimeConstructorParams<T>) {
193
217
  // Do not register actions if endpoints are set
@@ -209,6 +233,7 @@ export class CopilotRuntime<const T extends Parameter[] | [] = []> {
209
233
  this.onAfterRequest = params?.middleware?.onAfterRequest;
210
234
  this.delegateAgentProcessingToServiceAdapter =
211
235
  params?.delegateAgentProcessingToServiceAdapter || false;
236
+ this.logging = params?.logging;
212
237
  }
213
238
 
214
239
  async processRuntimeRequest(request: CopilotRuntimeRequest): Promise<CopilotRuntimeResponse> {
@@ -228,6 +253,10 @@ export class CopilotRuntime<const T extends Parameter[] | [] = []> {
228
253
  } = request;
229
254
 
230
255
  const eventSource = new RuntimeEventSource();
256
+ // Track request start time for logging
257
+ const requestStartTime = Date.now();
258
+ // For storing streamed chunks if progressive logging is enabled
259
+ const streamedChunks: any[] = [];
231
260
 
232
261
  try {
233
262
  if (agentSession && !this.delegateAgentProcessingToServiceAdapter) {
@@ -245,6 +274,26 @@ please use an LLM adapter instead.`,
245
274
  const inputMessages = convertGqlInputToMessages(messages);
246
275
  const serverSideActions = await this.getServerSideActions(request);
247
276
 
277
+ // Log LLM request if logging is enabled
278
+ if (this.logging?.enabled) {
279
+ try {
280
+ const requestData: LogLLMRequestData = {
281
+ threadId,
282
+ runId,
283
+ model: forwardedParameters?.model,
284
+ messages: inputMessages,
285
+ actions: clientSideActionsInput,
286
+ forwardedParameters,
287
+ timestamp: requestStartTime,
288
+ provider: this.detectProvider(serviceAdapter),
289
+ };
290
+
291
+ await this.logging.logger.logRequest(requestData);
292
+ } catch (error) {
293
+ console.error("Error logging LLM request:", error);
294
+ }
295
+ }
296
+
248
297
  const serverSideActionsInput: ActionInput[] = serverSideActions.map((action) => ({
249
298
  name: action.name,
250
299
  description: action.description,
@@ -296,6 +345,88 @@ please use an LLM adapter instead.`,
296
345
  })
297
346
  .catch((_error) => {});
298
347
 
348
+ // After getting the response, log it if logging is enabled
349
+ if (this.logging?.enabled) {
350
+ try {
351
+ outputMessagesPromise
352
+ .then((outputMessages) => {
353
+ const responseData: LogLLMResponseData = {
354
+ threadId: result.threadId,
355
+ runId: result.runId,
356
+ model: forwardedParameters?.model,
357
+ // Use collected chunks for progressive mode or outputMessages for regular mode
358
+ output: this.logging.progressive ? streamedChunks : outputMessages,
359
+ latency: Date.now() - requestStartTime,
360
+ timestamp: Date.now(),
361
+ provider: this.detectProvider(serviceAdapter),
362
+ // Indicate this is the final response
363
+ isFinalResponse: true,
364
+ };
365
+
366
+ try {
367
+ this.logging?.logger.logResponse(responseData);
368
+ } catch (logError) {
369
+ console.error("Error logging LLM response:", logError);
370
+ }
371
+ })
372
+ .catch((error) => {
373
+ console.error("Failed to get output messages for logging:", error);
374
+ });
375
+ } catch (error) {
376
+ console.error("Error setting up logging for LLM response:", error);
377
+ }
378
+ }
379
+
380
+ // Add progressive logging if enabled
381
+ if (this.logging?.enabled && this.logging.progressive) {
382
+ // Keep reference to original stream function
383
+ const originalStream = eventSource.stream.bind(eventSource);
384
+
385
+ // Wrap the stream function to intercept events
386
+ eventSource.stream = async (callback) => {
387
+ await originalStream(async (eventStream$) => {
388
+ // Create subscription to capture streaming events
389
+ eventStream$.subscribe({
390
+ next: (event) => {
391
+ // Only log content chunks
392
+ if (event.type === RuntimeEventTypes.TextMessageContent) {
393
+ // Store the chunk
394
+ streamedChunks.push(event.content);
395
+
396
+ // Log each chunk separately for progressive mode
397
+ try {
398
+ const progressiveData: LogLLMResponseData = {
399
+ threadId: threadId || "",
400
+ runId,
401
+ model: forwardedParameters?.model,
402
+ output: event.content,
403
+ latency: Date.now() - requestStartTime,
404
+ timestamp: Date.now(),
405
+ provider: this.detectProvider(serviceAdapter),
406
+ isProgressiveChunk: true,
407
+ };
408
+
409
+ // Use Promise to handle async logger without awaiting
410
+ Promise.resolve()
411
+ .then(() => {
412
+ this.logging?.logger.logResponse(progressiveData);
413
+ })
414
+ .catch((error) => {
415
+ console.error("Error in progressive logging:", error);
416
+ });
417
+ } catch (error) {
418
+ console.error("Error preparing progressive log data:", error);
419
+ }
420
+ }
421
+ },
422
+ });
423
+
424
+ // Call the original callback with the event stream
425
+ await callback(eventStream$);
426
+ });
427
+ };
428
+ }
429
+
299
430
  return {
300
431
  threadId: nonEmptyThreadId,
301
432
  runId: result.runId,
@@ -312,6 +443,25 @@ please use an LLM adapter instead.`,
312
443
  extensions: result.extensions,
313
444
  };
314
445
  } catch (error) {
446
+ // Log error if logging is enabled
447
+ if (this.logging?.enabled) {
448
+ try {
449
+ const errorData: LogLLMErrorData = {
450
+ threadId,
451
+ runId,
452
+ model: forwardedParameters?.model,
453
+ error: error instanceof Error ? error : String(error),
454
+ timestamp: Date.now(),
455
+ latency: Date.now() - requestStartTime,
456
+ provider: this.detectProvider(serviceAdapter),
457
+ };
458
+
459
+ await this.logging.logger.logError(errorData);
460
+ } catch (logError) {
461
+ console.error("Error logging LLM error:", logError);
462
+ }
463
+ }
464
+
315
465
  if (error instanceof CopilotKitError) {
316
466
  throw error;
317
467
  }
@@ -405,7 +555,6 @@ please use an LLM adapter instead.`,
405
555
  if (!agentWithEndpoint) {
406
556
  throw new Error("Agent not found");
407
557
  }
408
- const headers = createHeaders(null, graphqlContext);
409
558
 
410
559
  if (agentWithEndpoint.endpoint.type === EndpointType.LangGraphPlatform) {
411
560
  const propertyHeaders = graphqlContext.properties.authorization
@@ -624,6 +773,17 @@ please use an LLM adapter instead.`,
624
773
 
625
774
  return [...configuredActions, ...langserveFunctions, ...remoteActions];
626
775
  }
776
+
777
+ // Add helper method to detect provider
778
+ private detectProvider(serviceAdapter: CopilotServiceAdapter): string | undefined {
779
+ const adapterName = serviceAdapter.constructor.name;
780
+ if (adapterName.includes("OpenAI")) return "openai";
781
+ if (adapterName.includes("Anthropic")) return "anthropic";
782
+ if (adapterName.includes("Google")) return "google";
783
+ if (adapterName.includes("Groq")) return "groq";
784
+ if (adapterName.includes("LangChain")) return "langchain";
785
+ return undefined;
786
+ }
627
787
  }
628
788
 
629
789
  export function flattenToolCallsNoDuplicates(toolsByPriority: ActionInput[]): ActionInput[] {