@librechat/agents 1.5.1 → 1.5.3

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.
@@ -15,12 +15,7 @@ class ModelEndHandler {
15
15
  console.warn(`Graph or metadata not found in ${event} event`);
16
16
  return;
17
17
  }
18
- // const messageType = (data?.output as BaseMessage | undefined)?._getType();
19
- // console.log('messageType', messageType);
20
18
  const usage = data?.output?.usage_metadata;
21
- // const stepKey = graph.getStepKey(metadata);
22
- // const stepId = graph.getStepIdByKey(stepKey);
23
- // const step = graph.getRunStep(stepId);
24
19
  console.log(`====== ${event.toUpperCase()} ======`);
25
20
  console.dir({
26
21
  usage,
@@ -44,7 +39,7 @@ class TestLLMStreamHandler {
44
39
  handle(event, data) {
45
40
  const chunk = data?.chunk;
46
41
  const isMessageChunk = !!(chunk && 'message' in chunk);
47
- const msg = isMessageChunk && chunk?.message;
42
+ const msg = isMessageChunk && chunk.message;
48
43
  if (msg && msg.tool_call_chunks && msg.tool_call_chunks.length > 0) {
49
44
  console.log(msg.tool_call_chunks);
50
45
  }
@@ -59,7 +54,7 @@ class TestChatStreamHandler {
59
54
  handle(event, data) {
60
55
  const chunk = data?.chunk;
61
56
  const isContentChunk = !!(chunk && 'content' in chunk);
62
- const content = isContentChunk && chunk?.content;
57
+ const content = isContentChunk && chunk.content;
63
58
  if (!content || !isContentChunk) {
64
59
  return;
65
60
  }
@@ -78,7 +73,7 @@ class LLMStreamHandler {
78
73
  handle(event, data, metadata) {
79
74
  const chunk = data?.chunk;
80
75
  const isMessageChunk = !!(chunk && 'message' in chunk);
81
- const msg = isMessageChunk && chunk?.message;
76
+ const msg = isMessageChunk && chunk.message;
82
77
  if (metadata) {
83
78
  console.log(metadata);
84
79
  }
@@ -1 +1 @@
1
- {"version":3,"file":"events.cjs","sources":["../../src/events.ts"],"sourcesContent":["/* eslint-disable no-console */\n// src/events.ts\nimport type { AIMessage } from '@langchain/core/messages';\nimport type { Graph } from '@/graphs';\nimport type * as t from '@/types';\n\nexport class HandlerRegistry {\n private handlers: Map<string, t.EventHandler> = new Map();\n\n register(eventType: string, handler: t.EventHandler): void {\n this.handlers.set(eventType, handler);\n }\n\n getHandler(eventType: string): t.EventHandler | undefined {\n return this.handlers.get(eventType);\n }\n}\n\nexport class ModelEndHandler implements t.EventHandler {\n handle(event: string, data: t.StreamEventData, metadata?: Record<string, unknown>, graph?: Graph): void {\n if (!graph || !metadata) {\n console.warn(`Graph or metadata not found in ${event} event`);\n return;\n }\n\n // const messageType = (data?.output as BaseMessage | undefined)?._getType();\n // console.log('messageType', messageType);\n const usage = (data?.output as AIMessage)?.usage_metadata;\n\n // const stepKey = graph.getStepKey(metadata);\n // const stepId = graph.getStepIdByKey(stepKey);\n // const step = graph.getRunStep(stepId);\n\n console.log(`====== ${event.toUpperCase()} ======`);\n console.dir({\n usage,\n }, { depth: null });\n }\n}\n\nexport class ToolEndHandler implements t.EventHandler {\n handle(event: string, data: t.StreamEventData, metadata?: Record<string, unknown>, graph?: Graph): void {\n if (!graph || !metadata) {\n console.warn(`Graph or metadata not found in ${event} event`);\n return;\n }\n\n if (!data?.output) {\n console.warn('No output found in tool_end event');\n return;\n }\n\n graph.handleToolCallCompleted({ input: data.input, output: data.output } as t.ToolEndData);\n }\n}\n\nexport class TestLLMStreamHandler implements t.EventHandler {\n handle(event: string, data: t.StreamEventData): void {\n const chunk = data?.chunk;\n const isMessageChunk = !!(chunk && 'message' in chunk);\n const msg = isMessageChunk && chunk?.message;\n if (msg && msg.tool_call_chunks && msg.tool_call_chunks.length > 0) {\n console.log(msg.tool_call_chunks);\n } else if (msg && msg.content) {\n if (typeof msg.content === 'string') {\n process.stdout.write(msg.content);\n }\n }\n }\n}\n\nexport class TestChatStreamHandler implements t.EventHandler {\n handle(event: string, data: t.StreamEventData): void {\n const chunk = data?.chunk;\n const isContentChunk = !!(chunk && 'content' in chunk);\n const content = isContentChunk && chunk?.content;\n\n if (!content || !isContentChunk) {\n return;\n }\n\n if (chunk.tool_call_chunks && chunk.tool_call_chunks.length > 0) {\n console.dir(chunk.tool_call_chunks, { depth: null });\n }\n\n if (typeof content === 'string') {\n process.stdout.write(content);\n } else {\n console.dir(content, { depth: null });\n }\n }\n}\n\nexport class LLMStreamHandler implements t.EventHandler {\n handle(event: string, data: t.StreamEventData, metadata?: Record<string, unknown>): void {\n const chunk = data?.chunk;\n const isMessageChunk = !!(chunk && 'message' in chunk);\n const msg = isMessageChunk && chunk?.message;\n if (metadata) { console.log(metadata); }\n if (msg && msg.tool_call_chunks && msg.tool_call_chunks.length > 0) {\n console.log(msg.tool_call_chunks);\n } else if (msg && msg.content) {\n if (typeof msg.content === 'string') {\n // const text_delta = msg.content;\n // dispatchCustomEvent(GraphEvents.CHAT_MODEL_STREAM, { chunk }, config);\n process.stdout.write(msg.content);\n }\n }\n }\n}\n\nexport const createMetadataAggregator = (_collected?: Record<string, unknown>[]): t.MetadataAggregatorResult => {\n const collected = _collected || [];\n\n const handleLLMEnd: t.HandleLLMEnd = (output) => {\n const { generations } = output;\n const lastMessageOutput = (generations[generations.length - 1] as (t.StreamGeneration | undefined)[] | undefined)?.[0];\n if (!lastMessageOutput) {\n return;\n }\n const { message } = lastMessageOutput;\n if (message?.response_metadata) {\n collected.push(message.response_metadata);\n }\n };\n\n return { handleLLMEnd, collected };\n};"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"events.cjs","sources":["../../src/events.ts"],"sourcesContent":["/* eslint-disable no-console */\n// src/events.ts\nimport type { Graph } from '@/graphs';\nimport type * as t from '@/types';\n\nexport class HandlerRegistry {\n private handlers: Map<string, t.EventHandler> = new Map();\n\n register(eventType: string, handler: t.EventHandler): void {\n this.handlers.set(eventType, handler);\n }\n\n getHandler(eventType: string): t.EventHandler | undefined {\n return this.handlers.get(eventType);\n }\n}\n\nexport class ModelEndHandler implements t.EventHandler {\n handle(event: string, data: t.ModelEndData, metadata?: Record<string, unknown>, graph?: Graph): void {\n if (!graph || !metadata) {\n console.warn(`Graph or metadata not found in ${event} event`);\n return;\n }\n\n const usage = data?.output?.usage_metadata;\n\n console.log(`====== ${event.toUpperCase()} ======`);\n console.dir({\n usage,\n }, { depth: null });\n }\n}\n\nexport class ToolEndHandler implements t.EventHandler {\n handle(event: string, data: t.StreamEventData | undefined, metadata?: Record<string, unknown>, graph?: Graph): void {\n if (!graph || !metadata) {\n console.warn(`Graph or metadata not found in ${event} event`);\n return;\n }\n\n if (!data?.output) {\n console.warn('No output found in tool_end event');\n return;\n }\n\n graph.handleToolCallCompleted({ input: data.input, output: data.output } as t.ToolEndData);\n }\n}\n\nexport class TestLLMStreamHandler implements t.EventHandler {\n handle(event: string, data: t.StreamEventData | undefined): void {\n const chunk = data?.chunk;\n const isMessageChunk = !!(chunk && 'message' in chunk);\n const msg = isMessageChunk && chunk.message;\n if (msg && msg.tool_call_chunks && msg.tool_call_chunks.length > 0) {\n console.log(msg.tool_call_chunks);\n } else if (msg && msg.content) {\n if (typeof msg.content === 'string') {\n process.stdout.write(msg.content);\n }\n }\n }\n}\n\nexport class TestChatStreamHandler implements t.EventHandler {\n handle(event: string, data: t.StreamEventData | undefined): void {\n const chunk = data?.chunk;\n const isContentChunk = !!(chunk && 'content' in chunk);\n const content = isContentChunk && chunk.content;\n\n if (!content || !isContentChunk) {\n return;\n }\n\n if (chunk.tool_call_chunks && chunk.tool_call_chunks.length > 0) {\n console.dir(chunk.tool_call_chunks, { depth: null });\n }\n\n if (typeof content === 'string') {\n process.stdout.write(content);\n } else {\n console.dir(content, { depth: null });\n }\n }\n}\n\nexport class LLMStreamHandler implements t.EventHandler {\n handle(event: string, data: t.StreamEventData | undefined, metadata?: Record<string, unknown>): void {\n const chunk = data?.chunk;\n const isMessageChunk = !!(chunk && 'message' in chunk);\n const msg = isMessageChunk && chunk.message;\n if (metadata) { console.log(metadata); }\n if (msg && msg.tool_call_chunks && msg.tool_call_chunks.length > 0) {\n console.log(msg.tool_call_chunks);\n } else if (msg && msg.content) {\n if (typeof msg.content === 'string') {\n // const text_delta = msg.content;\n // dispatchCustomEvent(GraphEvents.CHAT_MODEL_STREAM, { chunk }, config);\n process.stdout.write(msg.content);\n }\n }\n }\n}\n\nexport const createMetadataAggregator = (_collected?: Record<string, unknown>[]): t.MetadataAggregatorResult => {\n const collected = _collected || [];\n\n const handleLLMEnd: t.HandleLLMEnd = (output) => {\n const { generations } = output;\n const lastMessageOutput = (generations[generations.length - 1] as (t.StreamGeneration | undefined)[] | undefined)?.[0];\n if (!lastMessageOutput) {\n return;\n }\n const { message } = lastMessageOutput;\n if (message?.response_metadata) {\n collected.push(message.response_metadata);\n }\n };\n\n return { handleLLMEnd, collected };\n};"],"names":[],"mappings":";;MAKa,eAAe,CAAA;AAClB,IAAA,QAAQ,GAAgC,IAAI,GAAG,EAAE,CAAC;IAE1D,QAAQ,CAAC,SAAiB,EAAE,OAAuB,EAAA;QACjD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;KACvC;AAED,IAAA,UAAU,CAAC,SAAiB,EAAA;QAC1B,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;KACrC;AACF,CAAA;MAEY,eAAe,CAAA;AAC1B,IAAA,MAAM,CAAC,KAAa,EAAE,IAAoB,EAAE,QAAkC,EAAE,KAAa,EAAA;AAC3F,QAAA,IAAI,CAAC,KAAK,IAAI,CAAC,QAAQ,EAAE;AACvB,YAAA,OAAO,CAAC,IAAI,CAAC,kCAAkC,KAAK,CAAA,MAAA,CAAQ,CAAC,CAAC;YAC9D,OAAO;SACR;AAED,QAAA,MAAM,KAAK,GAAG,IAAI,EAAE,MAAM,EAAE,cAAc,CAAC;QAE3C,OAAO,CAAC,GAAG,CAAC,CAAU,OAAA,EAAA,KAAK,CAAC,WAAW,EAAE,CAAS,OAAA,CAAA,CAAC,CAAC;QACpD,OAAO,CAAC,GAAG,CAAC;YACV,KAAK;AACN,SAAA,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;KACrB;AACF,CAAA;MAEY,cAAc,CAAA;AACzB,IAAA,MAAM,CAAC,KAAa,EAAE,IAAmC,EAAE,QAAkC,EAAE,KAAa,EAAA;AAC1G,QAAA,IAAI,CAAC,KAAK,IAAI,CAAC,QAAQ,EAAE;AACvB,YAAA,OAAO,CAAC,IAAI,CAAC,kCAAkC,KAAK,CAAA,MAAA,CAAQ,CAAC,CAAC;YAC9D,OAAO;SACR;AAED,QAAA,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE;AACjB,YAAA,OAAO,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;YAClD,OAAO;SACR;AAED,QAAA,KAAK,CAAC,uBAAuB,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAmB,CAAC,CAAC;KAC5F;AACF,CAAA;MAEY,oBAAoB,CAAA;IAC/B,MAAM,CAAC,KAAa,EAAE,IAAmC,EAAA;AACvD,QAAA,MAAM,KAAK,GAAG,IAAI,EAAE,KAAK,CAAC;QAC1B,MAAO,cAAc,GAAG,CAAC,EAAE,KAAK,IAAI,SAAS,IAAI,KAAK,CAAC,CAAC;AACxD,QAAA,MAAM,GAAG,GAAG,cAAc,IAAI,KAAK,CAAC,OAAO,CAAC;AAC5C,QAAA,IAAI,GAAG,IAAI,GAAG,CAAC,gBAAgB,IAAI,GAAG,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE;AAClE,YAAA,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;SACnC;AAAM,aAAA,IAAI,GAAG,IAAI,GAAG,CAAC,OAAO,EAAE;AAC7B,YAAA,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,EAAE;gBACnC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;aACnC;SACF;KACF;AACF,CAAA;MAEY,qBAAqB,CAAA;IAChC,MAAM,CAAC,KAAa,EAAE,IAAmC,EAAA;AACvD,QAAA,MAAM,KAAK,GAAG,IAAI,EAAE,KAAK,CAAC;QAC1B,MAAM,cAAc,GAAG,CAAC,EAAE,KAAK,IAAI,SAAS,IAAI,KAAK,CAAC,CAAC;AACvD,QAAA,MAAM,OAAO,GAAG,cAAc,IAAI,KAAK,CAAC,OAAO,CAAC;AAEhD,QAAA,IAAI,CAAC,OAAO,IAAI,CAAC,cAAc,EAAE;YAC/B,OAAO;SACR;AAED,QAAA,IAAI,KAAK,CAAC,gBAAgB,IAAI,KAAK,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE;AAC/D,YAAA,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,gBAAgB,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;SACtD;AAED,QAAA,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE;AAC/B,YAAA,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;SAC/B;aAAM;YACL,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;SACvC;KACF;AACF,CAAA;MAEY,gBAAgB,CAAA;AAC3B,IAAA,MAAM,CAAC,KAAa,EAAE,IAAmC,EAAE,QAAkC,EAAA;AAC3F,QAAA,MAAM,KAAK,GAAG,IAAI,EAAE,KAAK,CAAC;QAC1B,MAAO,cAAc,GAAG,CAAC,EAAE,KAAK,IAAI,SAAS,IAAI,KAAK,CAAC,CAAC;AACxD,QAAA,MAAM,GAAG,GAAG,cAAc,IAAI,KAAK,CAAC,OAAO,CAAC;QAC5C,IAAI,QAAQ,EAAE;AAAE,YAAA,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;SAAE;AACxC,QAAA,IAAI,GAAG,IAAI,GAAG,CAAC,gBAAgB,IAAI,GAAG,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE;AAClE,YAAA,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;SACnC;AAAM,aAAA,IAAI,GAAG,IAAI,GAAG,CAAC,OAAO,EAAE;AAC7B,YAAA,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,EAAE;;;gBAGnC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;aACnC;SACF;KACF;AACF,CAAA;AAEY,MAAA,wBAAwB,GAAG,CAAC,UAAsC,KAAgC;AAC7G,IAAA,MAAM,SAAS,GAAG,UAAU,IAAI,EAAE,CAAC;AAEnC,IAAA,MAAM,YAAY,GAAmB,CAAC,MAAM,KAAI;AAC9C,QAAA,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,CAAC;AAC/B,QAAA,MAAM,iBAAiB,GAAI,WAAW,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAoD,GAAG,CAAC,CAAC,CAAC;QACvH,IAAI,CAAC,iBAAiB,EAAE;YACtB,OAAO;SACR;AACD,QAAA,MAAM,EAAE,OAAO,EAAE,GAAG,iBAAiB,CAAC;AACtC,QAAA,IAAI,OAAO,EAAE,iBAAiB,EAAE;AAC9B,YAAA,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;SAC3C;AACH,KAAC,CAAC;AAEF,IAAA,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC;AACrC;;;;;;;;;;"}
@@ -13,12 +13,7 @@ class ModelEndHandler {
13
13
  console.warn(`Graph or metadata not found in ${event} event`);
14
14
  return;
15
15
  }
16
- // const messageType = (data?.output as BaseMessage | undefined)?._getType();
17
- // console.log('messageType', messageType);
18
16
  const usage = data?.output?.usage_metadata;
19
- // const stepKey = graph.getStepKey(metadata);
20
- // const stepId = graph.getStepIdByKey(stepKey);
21
- // const step = graph.getRunStep(stepId);
22
17
  console.log(`====== ${event.toUpperCase()} ======`);
23
18
  console.dir({
24
19
  usage,
@@ -42,7 +37,7 @@ class TestLLMStreamHandler {
42
37
  handle(event, data) {
43
38
  const chunk = data?.chunk;
44
39
  const isMessageChunk = !!(chunk && 'message' in chunk);
45
- const msg = isMessageChunk && chunk?.message;
40
+ const msg = isMessageChunk && chunk.message;
46
41
  if (msg && msg.tool_call_chunks && msg.tool_call_chunks.length > 0) {
47
42
  console.log(msg.tool_call_chunks);
48
43
  }
@@ -57,7 +52,7 @@ class TestChatStreamHandler {
57
52
  handle(event, data) {
58
53
  const chunk = data?.chunk;
59
54
  const isContentChunk = !!(chunk && 'content' in chunk);
60
- const content = isContentChunk && chunk?.content;
55
+ const content = isContentChunk && chunk.content;
61
56
  if (!content || !isContentChunk) {
62
57
  return;
63
58
  }
@@ -76,7 +71,7 @@ class LLMStreamHandler {
76
71
  handle(event, data, metadata) {
77
72
  const chunk = data?.chunk;
78
73
  const isMessageChunk = !!(chunk && 'message' in chunk);
79
- const msg = isMessageChunk && chunk?.message;
74
+ const msg = isMessageChunk && chunk.message;
80
75
  if (metadata) {
81
76
  console.log(metadata);
82
77
  }
@@ -1 +1 @@
1
- {"version":3,"file":"events.mjs","sources":["../../src/events.ts"],"sourcesContent":["/* eslint-disable no-console */\n// src/events.ts\nimport type { AIMessage } from '@langchain/core/messages';\nimport type { Graph } from '@/graphs';\nimport type * as t from '@/types';\n\nexport class HandlerRegistry {\n private handlers: Map<string, t.EventHandler> = new Map();\n\n register(eventType: string, handler: t.EventHandler): void {\n this.handlers.set(eventType, handler);\n }\n\n getHandler(eventType: string): t.EventHandler | undefined {\n return this.handlers.get(eventType);\n }\n}\n\nexport class ModelEndHandler implements t.EventHandler {\n handle(event: string, data: t.StreamEventData, metadata?: Record<string, unknown>, graph?: Graph): void {\n if (!graph || !metadata) {\n console.warn(`Graph or metadata not found in ${event} event`);\n return;\n }\n\n // const messageType = (data?.output as BaseMessage | undefined)?._getType();\n // console.log('messageType', messageType);\n const usage = (data?.output as AIMessage)?.usage_metadata;\n\n // const stepKey = graph.getStepKey(metadata);\n // const stepId = graph.getStepIdByKey(stepKey);\n // const step = graph.getRunStep(stepId);\n\n console.log(`====== ${event.toUpperCase()} ======`);\n console.dir({\n usage,\n }, { depth: null });\n }\n}\n\nexport class ToolEndHandler implements t.EventHandler {\n handle(event: string, data: t.StreamEventData, metadata?: Record<string, unknown>, graph?: Graph): void {\n if (!graph || !metadata) {\n console.warn(`Graph or metadata not found in ${event} event`);\n return;\n }\n\n if (!data?.output) {\n console.warn('No output found in tool_end event');\n return;\n }\n\n graph.handleToolCallCompleted({ input: data.input, output: data.output } as t.ToolEndData);\n }\n}\n\nexport class TestLLMStreamHandler implements t.EventHandler {\n handle(event: string, data: t.StreamEventData): void {\n const chunk = data?.chunk;\n const isMessageChunk = !!(chunk && 'message' in chunk);\n const msg = isMessageChunk && chunk?.message;\n if (msg && msg.tool_call_chunks && msg.tool_call_chunks.length > 0) {\n console.log(msg.tool_call_chunks);\n } else if (msg && msg.content) {\n if (typeof msg.content === 'string') {\n process.stdout.write(msg.content);\n }\n }\n }\n}\n\nexport class TestChatStreamHandler implements t.EventHandler {\n handle(event: string, data: t.StreamEventData): void {\n const chunk = data?.chunk;\n const isContentChunk = !!(chunk && 'content' in chunk);\n const content = isContentChunk && chunk?.content;\n\n if (!content || !isContentChunk) {\n return;\n }\n\n if (chunk.tool_call_chunks && chunk.tool_call_chunks.length > 0) {\n console.dir(chunk.tool_call_chunks, { depth: null });\n }\n\n if (typeof content === 'string') {\n process.stdout.write(content);\n } else {\n console.dir(content, { depth: null });\n }\n }\n}\n\nexport class LLMStreamHandler implements t.EventHandler {\n handle(event: string, data: t.StreamEventData, metadata?: Record<string, unknown>): void {\n const chunk = data?.chunk;\n const isMessageChunk = !!(chunk && 'message' in chunk);\n const msg = isMessageChunk && chunk?.message;\n if (metadata) { console.log(metadata); }\n if (msg && msg.tool_call_chunks && msg.tool_call_chunks.length > 0) {\n console.log(msg.tool_call_chunks);\n } else if (msg && msg.content) {\n if (typeof msg.content === 'string') {\n // const text_delta = msg.content;\n // dispatchCustomEvent(GraphEvents.CHAT_MODEL_STREAM, { chunk }, config);\n process.stdout.write(msg.content);\n }\n }\n }\n}\n\nexport const createMetadataAggregator = (_collected?: Record<string, unknown>[]): t.MetadataAggregatorResult => {\n const collected = _collected || [];\n\n const handleLLMEnd: t.HandleLLMEnd = (output) => {\n const { generations } = output;\n const lastMessageOutput = (generations[generations.length - 1] as (t.StreamGeneration | undefined)[] | undefined)?.[0];\n if (!lastMessageOutput) {\n return;\n }\n const { message } = lastMessageOutput;\n if (message?.response_metadata) {\n collected.push(message.response_metadata);\n }\n };\n\n return { handleLLMEnd, collected };\n};"],"names":[],"mappings":"MAMa,eAAe,CAAA;AAClB,IAAA,QAAQ,GAAgC,IAAI,GAAG,EAAE,CAAC;IAE1D,QAAQ,CAAC,SAAiB,EAAE,OAAuB,EAAA;QACjD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;KACvC;AAED,IAAA,UAAU,CAAC,SAAiB,EAAA;QAC1B,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;KACrC;AACF,CAAA;MAEY,eAAe,CAAA;AAC1B,IAAA,MAAM,CAAC,KAAa,EAAE,IAAuB,EAAE,QAAkC,EAAE,KAAa,EAAA;AAC9F,QAAA,IAAI,CAAC,KAAK,IAAI,CAAC,QAAQ,EAAE;AACvB,YAAA,OAAO,CAAC,IAAI,CAAC,kCAAkC,KAAK,CAAA,MAAA,CAAQ,CAAC,CAAC;YAC9D,OAAO;SACR;;;AAID,QAAA,MAAM,KAAK,GAAI,IAAI,EAAE,MAAoB,EAAE,cAAc,CAAC;;;;QAM1D,OAAO,CAAC,GAAG,CAAC,CAAU,OAAA,EAAA,KAAK,CAAC,WAAW,EAAE,CAAS,OAAA,CAAA,CAAC,CAAC;QACpD,OAAO,CAAC,GAAG,CAAC;YACV,KAAK;AACN,SAAA,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;KACrB;AACF,CAAA;MAEY,cAAc,CAAA;AACzB,IAAA,MAAM,CAAC,KAAa,EAAE,IAAuB,EAAE,QAAkC,EAAE,KAAa,EAAA;AAC9F,QAAA,IAAI,CAAC,KAAK,IAAI,CAAC,QAAQ,EAAE;AACvB,YAAA,OAAO,CAAC,IAAI,CAAC,kCAAkC,KAAK,CAAA,MAAA,CAAQ,CAAC,CAAC;YAC9D,OAAO;SACR;AAED,QAAA,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE;AACjB,YAAA,OAAO,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;YAClD,OAAO;SACR;AAED,QAAA,KAAK,CAAC,uBAAuB,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAmB,CAAC,CAAC;KAC5F;AACF,CAAA;MAEY,oBAAoB,CAAA;IAC/B,MAAM,CAAC,KAAa,EAAE,IAAuB,EAAA;AAC3C,QAAA,MAAM,KAAK,GAAG,IAAI,EAAE,KAAK,CAAC;QAC1B,MAAO,cAAc,GAAG,CAAC,EAAE,KAAK,IAAI,SAAS,IAAI,KAAK,CAAC,CAAC;AACxD,QAAA,MAAM,GAAG,GAAG,cAAc,IAAI,KAAK,EAAE,OAAO,CAAC;AAC7C,QAAA,IAAI,GAAG,IAAI,GAAG,CAAC,gBAAgB,IAAI,GAAG,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE;AAClE,YAAA,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;SACnC;AAAM,aAAA,IAAI,GAAG,IAAI,GAAG,CAAC,OAAO,EAAE;AAC7B,YAAA,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,EAAE;gBACnC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;aACnC;SACF;KACF;AACF,CAAA;MAEY,qBAAqB,CAAA;IAChC,MAAM,CAAC,KAAa,EAAE,IAAuB,EAAA;AAC3C,QAAA,MAAM,KAAK,GAAG,IAAI,EAAE,KAAK,CAAC;QAC1B,MAAM,cAAc,GAAG,CAAC,EAAE,KAAK,IAAI,SAAS,IAAI,KAAK,CAAC,CAAC;AACvD,QAAA,MAAM,OAAO,GAAG,cAAc,IAAI,KAAK,EAAE,OAAO,CAAC;AAEjD,QAAA,IAAI,CAAC,OAAO,IAAI,CAAC,cAAc,EAAE;YAC/B,OAAO;SACR;AAED,QAAA,IAAI,KAAK,CAAC,gBAAgB,IAAI,KAAK,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE;AAC/D,YAAA,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,gBAAgB,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;SACtD;AAED,QAAA,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE;AAC/B,YAAA,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;SAC/B;aAAM;YACL,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;SACvC;KACF;AACF,CAAA;MAEY,gBAAgB,CAAA;AAC3B,IAAA,MAAM,CAAC,KAAa,EAAE,IAAuB,EAAE,QAAkC,EAAA;AAC/E,QAAA,MAAM,KAAK,GAAG,IAAI,EAAE,KAAK,CAAC;QAC1B,MAAO,cAAc,GAAG,CAAC,EAAE,KAAK,IAAI,SAAS,IAAI,KAAK,CAAC,CAAC;AACxD,QAAA,MAAM,GAAG,GAAG,cAAc,IAAI,KAAK,EAAE,OAAO,CAAC;QAC7C,IAAI,QAAQ,EAAE;AAAE,YAAA,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;SAAE;AACxC,QAAA,IAAI,GAAG,IAAI,GAAG,CAAC,gBAAgB,IAAI,GAAG,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE;AAClE,YAAA,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;SACnC;AAAM,aAAA,IAAI,GAAG,IAAI,GAAG,CAAC,OAAO,EAAE;AAC7B,YAAA,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,EAAE;;;gBAGnC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;aACnC;SACF;KACF;AACF,CAAA;AAEY,MAAA,wBAAwB,GAAG,CAAC,UAAsC,KAAgC;AAC7G,IAAA,MAAM,SAAS,GAAG,UAAU,IAAI,EAAE,CAAC;AAEnC,IAAA,MAAM,YAAY,GAAmB,CAAC,MAAM,KAAI;AAC9C,QAAA,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,CAAC;AAC/B,QAAA,MAAM,iBAAiB,GAAI,WAAW,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAoD,GAAG,CAAC,CAAC,CAAC;QACvH,IAAI,CAAC,iBAAiB,EAAE;YACtB,OAAO;SACR;AACD,QAAA,MAAM,EAAE,OAAO,EAAE,GAAG,iBAAiB,CAAC;AACtC,QAAA,IAAI,OAAO,EAAE,iBAAiB,EAAE;AAC9B,YAAA,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;SAC3C;AACH,KAAC,CAAC;AAEF,IAAA,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC;AACrC;;;;"}
1
+ {"version":3,"file":"events.mjs","sources":["../../src/events.ts"],"sourcesContent":["/* eslint-disable no-console */\n// src/events.ts\nimport type { Graph } from '@/graphs';\nimport type * as t from '@/types';\n\nexport class HandlerRegistry {\n private handlers: Map<string, t.EventHandler> = new Map();\n\n register(eventType: string, handler: t.EventHandler): void {\n this.handlers.set(eventType, handler);\n }\n\n getHandler(eventType: string): t.EventHandler | undefined {\n return this.handlers.get(eventType);\n }\n}\n\nexport class ModelEndHandler implements t.EventHandler {\n handle(event: string, data: t.ModelEndData, metadata?: Record<string, unknown>, graph?: Graph): void {\n if (!graph || !metadata) {\n console.warn(`Graph or metadata not found in ${event} event`);\n return;\n }\n\n const usage = data?.output?.usage_metadata;\n\n console.log(`====== ${event.toUpperCase()} ======`);\n console.dir({\n usage,\n }, { depth: null });\n }\n}\n\nexport class ToolEndHandler implements t.EventHandler {\n handle(event: string, data: t.StreamEventData | undefined, metadata?: Record<string, unknown>, graph?: Graph): void {\n if (!graph || !metadata) {\n console.warn(`Graph or metadata not found in ${event} event`);\n return;\n }\n\n if (!data?.output) {\n console.warn('No output found in tool_end event');\n return;\n }\n\n graph.handleToolCallCompleted({ input: data.input, output: data.output } as t.ToolEndData);\n }\n}\n\nexport class TestLLMStreamHandler implements t.EventHandler {\n handle(event: string, data: t.StreamEventData | undefined): void {\n const chunk = data?.chunk;\n const isMessageChunk = !!(chunk && 'message' in chunk);\n const msg = isMessageChunk && chunk.message;\n if (msg && msg.tool_call_chunks && msg.tool_call_chunks.length > 0) {\n console.log(msg.tool_call_chunks);\n } else if (msg && msg.content) {\n if (typeof msg.content === 'string') {\n process.stdout.write(msg.content);\n }\n }\n }\n}\n\nexport class TestChatStreamHandler implements t.EventHandler {\n handle(event: string, data: t.StreamEventData | undefined): void {\n const chunk = data?.chunk;\n const isContentChunk = !!(chunk && 'content' in chunk);\n const content = isContentChunk && chunk.content;\n\n if (!content || !isContentChunk) {\n return;\n }\n\n if (chunk.tool_call_chunks && chunk.tool_call_chunks.length > 0) {\n console.dir(chunk.tool_call_chunks, { depth: null });\n }\n\n if (typeof content === 'string') {\n process.stdout.write(content);\n } else {\n console.dir(content, { depth: null });\n }\n }\n}\n\nexport class LLMStreamHandler implements t.EventHandler {\n handle(event: string, data: t.StreamEventData | undefined, metadata?: Record<string, unknown>): void {\n const chunk = data?.chunk;\n const isMessageChunk = !!(chunk && 'message' in chunk);\n const msg = isMessageChunk && chunk.message;\n if (metadata) { console.log(metadata); }\n if (msg && msg.tool_call_chunks && msg.tool_call_chunks.length > 0) {\n console.log(msg.tool_call_chunks);\n } else if (msg && msg.content) {\n if (typeof msg.content === 'string') {\n // const text_delta = msg.content;\n // dispatchCustomEvent(GraphEvents.CHAT_MODEL_STREAM, { chunk }, config);\n process.stdout.write(msg.content);\n }\n }\n }\n}\n\nexport const createMetadataAggregator = (_collected?: Record<string, unknown>[]): t.MetadataAggregatorResult => {\n const collected = _collected || [];\n\n const handleLLMEnd: t.HandleLLMEnd = (output) => {\n const { generations } = output;\n const lastMessageOutput = (generations[generations.length - 1] as (t.StreamGeneration | undefined)[] | undefined)?.[0];\n if (!lastMessageOutput) {\n return;\n }\n const { message } = lastMessageOutput;\n if (message?.response_metadata) {\n collected.push(message.response_metadata);\n }\n };\n\n return { handleLLMEnd, collected };\n};"],"names":[],"mappings":"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"}
@@ -6,18 +6,18 @@ export declare class HandlerRegistry {
6
6
  getHandler(eventType: string): t.EventHandler | undefined;
7
7
  }
8
8
  export declare class ModelEndHandler implements t.EventHandler {
9
- handle(event: string, data: t.StreamEventData, metadata?: Record<string, unknown>, graph?: Graph): void;
9
+ handle(event: string, data: t.ModelEndData, metadata?: Record<string, unknown>, graph?: Graph): void;
10
10
  }
11
11
  export declare class ToolEndHandler implements t.EventHandler {
12
- handle(event: string, data: t.StreamEventData, metadata?: Record<string, unknown>, graph?: Graph): void;
12
+ handle(event: string, data: t.StreamEventData | undefined, metadata?: Record<string, unknown>, graph?: Graph): void;
13
13
  }
14
14
  export declare class TestLLMStreamHandler implements t.EventHandler {
15
- handle(event: string, data: t.StreamEventData): void;
15
+ handle(event: string, data: t.StreamEventData | undefined): void;
16
16
  }
17
17
  export declare class TestChatStreamHandler implements t.EventHandler {
18
- handle(event: string, data: t.StreamEventData): void;
18
+ handle(event: string, data: t.StreamEventData | undefined): void;
19
19
  }
20
20
  export declare class LLMStreamHandler implements t.EventHandler {
21
- handle(event: string, data: t.StreamEventData, metadata?: Record<string, unknown>): void;
21
+ handle(event: string, data: t.StreamEventData | undefined, metadata?: Record<string, unknown>): void;
22
22
  }
23
23
  export declare const createMetadataAggregator: (_collected?: Record<string, unknown>[]) => t.MetadataAggregatorResult;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,33 @@
1
+ import { z } from 'zod';
2
+ import { DynamicStructuredTool } from '@langchain/core/tools';
3
+ export type CodeExecutionToolParams = {
4
+ session_id?: string;
5
+ user_id?: string;
6
+ };
7
+ export type FileRef = {
8
+ id: string;
9
+ name: string;
10
+ path?: string;
11
+ };
12
+ export type FileRefs = FileRef[];
13
+ export type ExecuteResult = {
14
+ session_id: string;
15
+ stdout: string;
16
+ stderr: string;
17
+ files?: FileRefs;
18
+ };
19
+ declare const CodeExecutionToolSchema: z.ZodObject<{
20
+ lang: z.ZodEnum<["py", "js", "ts", "c", "cpp", "java", "php", "rs", "go", "bash", "d", "f90"]>;
21
+ code: z.ZodString;
22
+ args: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
23
+ }, "strip", z.ZodTypeAny, {
24
+ code: string;
25
+ lang: "py" | "js" | "ts" | "c" | "cpp" | "java" | "php" | "rs" | "go" | "bash" | "d" | "f90";
26
+ args?: string[] | undefined;
27
+ }, {
28
+ code: string;
29
+ lang: "py" | "js" | "ts" | "c" | "cpp" | "java" | "php" | "rs" | "go" | "bash" | "d" | "f90";
30
+ args?: string[] | undefined;
31
+ }>;
32
+ declare function createCodeExecutionTool(params?: CodeExecutionToolParams): DynamicStructuredTool<typeof CodeExecutionToolSchema>;
33
+ export { createCodeExecutionTool };
@@ -8,7 +8,7 @@ export type BaseGraphState = {
8
8
  };
9
9
  export type IState = BaseGraphState;
10
10
  export interface EventHandler {
11
- handle(event: string, data: StreamEventData, metadata?: Record<string, unknown>, graph?: Graph): void;
11
+ handle(event: string, data: StreamEventData | ModelEndData, metadata?: Record<string, unknown>, graph?: Graph): void;
12
12
  }
13
13
  export type GraphStateChannels<T extends BaseGraphState> = StateGraphArgs<T>['channels'];
14
14
  export type Workflow<T extends BaseGraphState = BaseGraphState, U extends Partial<T> = Partial<T>, N extends string = string> = StateGraph<T, U, N>;
@@ -113,3 +113,6 @@ export type PartMetadata = {
113
113
  action?: boolean;
114
114
  output?: string;
115
115
  };
116
+ export type ModelEndData = StreamEventData & {
117
+ output: AIMessageChunk | undefined;
118
+ } | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@librechat/agents",
3
- "version": "1.5.1",
3
+ "version": "1.5.3",
4
4
  "main": "./dist/cjs/main.cjs",
5
5
  "module": "./dist/esm/main.mjs",
6
6
  "types": "./dist/types/index.d.ts",
@@ -42,7 +42,8 @@
42
42
  "start:cli": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/cli.ts --provider 'anthropic' --name 'Jo' --location 'New York, NY'",
43
43
  "content": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/content.ts --provider 'anthropic' --name 'Jo' --location 'New York, NY'",
44
44
  "stream": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/stream.ts --provider 'anthropic' --name 'Jo' --location 'New York, NY'",
45
- "simple": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/simple.ts --provider 'openAI' --name 'Jo' --location 'New York, NY'",
45
+ "code_exec": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/code_exec.ts --provider 'openAI' --name 'Jo' --location 'New York, NY'",
46
+ "simple": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/simple.ts --provider 'bedrock' --name 'Jo' --location 'New York, NY'",
46
47
  "tool-test": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/tools.ts --provider 'anthropic' --name 'Jo' --location 'New York, NY'",
47
48
  "abort": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/abort.ts --provider 'anthropic' --name 'Jo' --location 'New York, NY'",
48
49
  "start:cli2": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/cli2.ts --provider 'anthropic' --name 'Jo' --location 'New York, NY'",
package/src/events.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  /* eslint-disable no-console */
2
2
  // src/events.ts
3
- import type { AIMessage } from '@langchain/core/messages';
4
3
  import type { Graph } from '@/graphs';
5
4
  import type * as t from '@/types';
6
5
 
@@ -17,19 +16,13 @@ export class HandlerRegistry {
17
16
  }
18
17
 
19
18
  export class ModelEndHandler implements t.EventHandler {
20
- handle(event: string, data: t.StreamEventData, metadata?: Record<string, unknown>, graph?: Graph): void {
19
+ handle(event: string, data: t.ModelEndData, metadata?: Record<string, unknown>, graph?: Graph): void {
21
20
  if (!graph || !metadata) {
22
21
  console.warn(`Graph or metadata not found in ${event} event`);
23
22
  return;
24
23
  }
25
24
 
26
- // const messageType = (data?.output as BaseMessage | undefined)?._getType();
27
- // console.log('messageType', messageType);
28
- const usage = (data?.output as AIMessage)?.usage_metadata;
29
-
30
- // const stepKey = graph.getStepKey(metadata);
31
- // const stepId = graph.getStepIdByKey(stepKey);
32
- // const step = graph.getRunStep(stepId);
25
+ const usage = data?.output?.usage_metadata;
33
26
 
34
27
  console.log(`====== ${event.toUpperCase()} ======`);
35
28
  console.dir({
@@ -39,7 +32,7 @@ export class ModelEndHandler implements t.EventHandler {
39
32
  }
40
33
 
41
34
  export class ToolEndHandler implements t.EventHandler {
42
- handle(event: string, data: t.StreamEventData, metadata?: Record<string, unknown>, graph?: Graph): void {
35
+ handle(event: string, data: t.StreamEventData | undefined, metadata?: Record<string, unknown>, graph?: Graph): void {
43
36
  if (!graph || !metadata) {
44
37
  console.warn(`Graph or metadata not found in ${event} event`);
45
38
  return;
@@ -55,10 +48,10 @@ export class ToolEndHandler implements t.EventHandler {
55
48
  }
56
49
 
57
50
  export class TestLLMStreamHandler implements t.EventHandler {
58
- handle(event: string, data: t.StreamEventData): void {
51
+ handle(event: string, data: t.StreamEventData | undefined): void {
59
52
  const chunk = data?.chunk;
60
53
  const isMessageChunk = !!(chunk && 'message' in chunk);
61
- const msg = isMessageChunk && chunk?.message;
54
+ const msg = isMessageChunk && chunk.message;
62
55
  if (msg && msg.tool_call_chunks && msg.tool_call_chunks.length > 0) {
63
56
  console.log(msg.tool_call_chunks);
64
57
  } else if (msg && msg.content) {
@@ -70,10 +63,10 @@ export class TestLLMStreamHandler implements t.EventHandler {
70
63
  }
71
64
 
72
65
  export class TestChatStreamHandler implements t.EventHandler {
73
- handle(event: string, data: t.StreamEventData): void {
66
+ handle(event: string, data: t.StreamEventData | undefined): void {
74
67
  const chunk = data?.chunk;
75
68
  const isContentChunk = !!(chunk && 'content' in chunk);
76
- const content = isContentChunk && chunk?.content;
69
+ const content = isContentChunk && chunk.content;
77
70
 
78
71
  if (!content || !isContentChunk) {
79
72
  return;
@@ -92,10 +85,10 @@ export class TestChatStreamHandler implements t.EventHandler {
92
85
  }
93
86
 
94
87
  export class LLMStreamHandler implements t.EventHandler {
95
- handle(event: string, data: t.StreamEventData, metadata?: Record<string, unknown>): void {
88
+ handle(event: string, data: t.StreamEventData | undefined, metadata?: Record<string, unknown>): void {
96
89
  const chunk = data?.chunk;
97
90
  const isMessageChunk = !!(chunk && 'message' in chunk);
98
- const msg = isMessageChunk && chunk?.message;
91
+ const msg = isMessageChunk && chunk.message;
99
92
  if (metadata) { console.log(metadata); }
100
93
  if (msg && msg.tool_call_chunks && msg.tool_call_chunks.length > 0) {
101
94
  console.log(msg.tool_call_chunks);
@@ -0,0 +1,176 @@
1
+ // src/scripts/cli.ts
2
+ import { config } from 'dotenv';
3
+ config();
4
+ import { HumanMessage, AIMessage, BaseMessage } from '@langchain/core/messages';
5
+ import { TavilySearchResults } from '@langchain/community/tools/tavily_search';
6
+ import type * as t from '@/types';
7
+ import { ChatModelStreamHandler, createContentAggregator } from '@/stream';
8
+ import { ToolEndHandler, ModelEndHandler, createMetadataAggregator } from '@/events';
9
+ import { getLLMConfig } from '@/utils/llmConfig';
10
+ import { getArgs } from '@/scripts/args';
11
+ import { GraphEvents } from '@/common';
12
+ import { Run } from '@/run';
13
+ import { createCodeExecutionTool } from '@/tools/CodeExecutor';
14
+
15
+ const conversationHistory: BaseMessage[] = [];
16
+
17
+ async function testCodeExecution(): Promise<void> {
18
+ const { userName, location, provider, currentDate } = await getArgs();
19
+ const { contentParts, aggregateContent } = createContentAggregator();
20
+ const customHandlers = {
21
+ [GraphEvents.TOOL_END]: new ToolEndHandler(),
22
+ [GraphEvents.CHAT_MODEL_END]: new ModelEndHandler(),
23
+ [GraphEvents.CHAT_MODEL_STREAM]: new ChatModelStreamHandler(),
24
+ [GraphEvents.ON_RUN_STEP_COMPLETED]: {
25
+ handle: (event: GraphEvents.ON_RUN_STEP_COMPLETED, data: t.StreamEventData): void => {
26
+ console.log('====== ON_RUN_STEP_COMPLETED ======');
27
+ console.dir(data, { depth: null });
28
+ aggregateContent({ event, data: data as unknown as { result: t.ToolEndEvent } });
29
+ }
30
+ },
31
+ [GraphEvents.ON_RUN_STEP]: {
32
+ handle: (event: GraphEvents.ON_RUN_STEP, data: t.StreamEventData): void => {
33
+ console.log('====== ON_RUN_STEP ======');
34
+ console.dir(data, { depth: null });
35
+ aggregateContent({ event, data: data as t.RunStep });
36
+ }
37
+ },
38
+ [GraphEvents.ON_RUN_STEP_DELTA]: {
39
+ handle: (event: GraphEvents.ON_RUN_STEP_DELTA, data: t.StreamEventData): void => {
40
+ console.log('====== ON_RUN_STEP_DELTA ======');
41
+ console.dir(data, { depth: null });
42
+ aggregateContent({ event, data: data as t.RunStepDeltaEvent });
43
+ }
44
+ },
45
+ [GraphEvents.ON_MESSAGE_DELTA]: {
46
+ handle: (event: GraphEvents.ON_MESSAGE_DELTA, data: t.StreamEventData): void => {
47
+ console.log('====== ON_MESSAGE_DELTA ======');
48
+ console.dir(data, { depth: null });
49
+ aggregateContent({ event, data: data as t.MessageDeltaEvent });
50
+ }
51
+ },
52
+ [GraphEvents.TOOL_START]: {
53
+ handle: (_event: string, data: t.StreamEventData, metadata?: Record<string, unknown>): void => {
54
+ console.log('====== TOOL_START ======');
55
+ console.dir(data, { depth: null });
56
+ }
57
+ },
58
+ };
59
+
60
+ const llmConfig = getLLMConfig(provider);
61
+
62
+ const run = await Run.create<t.IState>({
63
+ graphConfig: {
64
+ type: 'standard',
65
+ llmConfig,
66
+ tools: [new TavilySearchResults(), createCodeExecutionTool()],
67
+ instructions: 'You are a friendly AI assistant with coding capabilities. Always address the user by their name.',
68
+ additional_instructions: `The user's name is ${userName} and they are located in ${location}.`,
69
+ },
70
+ returnContent: true,
71
+ customHandlers,
72
+ });
73
+
74
+ const config = {
75
+ configurable: {
76
+ provider,
77
+ thread_id: 'conversation-num-1',
78
+ },
79
+ streamMode: 'values',
80
+ version: 'v2' as const,
81
+ };
82
+
83
+ console.log('Test 1: Sorting Algorithm Comparison');
84
+
85
+ const userMessage1 = `
86
+ Hi ${userName} here. I need a Python script that compares different sorting algorithms. Can you write a script that:
87
+ 1. Implements three sorting algorithms: Bubble Sort, Insertion Sort, and Merge Sort
88
+ 2. Generates three random lists of integers:
89
+ - A small list (20 elements)
90
+ - A medium list (100 elements)
91
+ - A large list (1000 elements)
92
+ 3. Applies each sorting algorithm to each list and measures the execution time
93
+ 4. Prints a comparison table showing the time taken by each algorithm for each list size
94
+ 5. Determines and announces the fastest algorithm for each list size
95
+ Please write the script and then execute it to show the results.
96
+ `;
97
+
98
+ conversationHistory.push(new HumanMessage(userMessage1));
99
+
100
+ let inputs = {
101
+ messages: conversationHistory,
102
+ };
103
+ const finalContentParts1 = await run.processStream(inputs, config);
104
+ const finalMessages1 = run.getRunMessages();
105
+ if (finalMessages1) {
106
+ conversationHistory.push(...finalMessages1);
107
+ }
108
+ console.log('\n\n====================\n\n');
109
+ console.dir(contentParts, { depth: null });
110
+
111
+ console.log('Test 2: Text File Analysis and Processing');
112
+
113
+ const userMessage2 = `
114
+ Great job on the sorting algorithms! Now, let's solve a popular LeetCode problem using the Merge Sort algorithm we implemented. The problem is "Merge Intervals". Here's what I need:
115
+
116
+ 1. Implement a solution to the Merge Intervals problem:
117
+ - Given an array of intervals where intervals[i] = [starti, endi], merge all overlapping intervals.
118
+ - Return an array of the non-overlapping intervals that cover all the intervals in the input.
119
+
120
+ 2. Use the Merge Sort algorithm as part of the solution to sort the intervals based on their start times.
121
+
122
+ 3. Implement a function to generate a random list of intervals for testing.
123
+
124
+ 4. Create test cases:
125
+ - A small case with 5 intervals
126
+ - A medium case with 20 intervals
127
+ - A large case with 100 intervals
128
+
129
+ 5. Apply your solution to each test case and print:
130
+ - The original intervals
131
+ - The merged intervals
132
+ - The time taken to solve each case
133
+
134
+ Please write the script and execute it to demonstrate the results for all three test cases.
135
+ `;
136
+
137
+ conversationHistory.push(new HumanMessage(userMessage2));
138
+
139
+ inputs = {
140
+ messages: conversationHistory,
141
+ };
142
+ const finalContentParts2 = await run.processStream(inputs, config);
143
+ const finalMessages2 = run.getRunMessages();
144
+ if (finalMessages2) {
145
+ conversationHistory.push(...finalMessages2);
146
+ }
147
+ console.log('\n\n====================\n\n');
148
+ console.dir(contentParts, { depth: null });
149
+
150
+ const { handleLLMEnd, collected } = createMetadataAggregator();
151
+ const titleResult = await run.generateTitle({
152
+ inputText: userMessage2,
153
+ contentParts,
154
+ chainOptions: {
155
+ callbacks: [{
156
+ handleLLMEnd,
157
+ }],
158
+ },
159
+ });
160
+ console.log('Generated Title:', titleResult);
161
+ console.log('Collected metadata:', collected);
162
+ }
163
+
164
+ process.on('unhandledRejection', (reason, promise) => {
165
+ console.error('Unhandled Rejection at:', promise, 'reason:', reason);
166
+ console.log('Conversation history:');
167
+ console.dir(conversationHistory, { depth: null });
168
+ process.exit(1);
169
+ });
170
+
171
+ testCodeExecution().catch((err) => {
172
+ console.error(err);
173
+ console.log('Conversation history:');
174
+ console.dir(conversationHistory, { depth: null });
175
+ process.exit(1);
176
+ });
@@ -5,7 +5,7 @@ import { HumanMessage, BaseMessage } from '@langchain/core/messages';
5
5
  import { TavilySearchResults } from '@langchain/community/tools/tavily_search';
6
6
  import type * as t from '@/types';
7
7
  import { ChatModelStreamHandler, createContentAggregator } from '@/stream';
8
- import { ToolEndHandler, createMetadataAggregator } from '@/events';
8
+ import { ToolEndHandler, ModelEndHandler, createMetadataAggregator } from '@/events';
9
9
  import { getLLMConfig } from '@/utils/llmConfig';
10
10
  import { getArgs } from '@/scripts/args';
11
11
  import { GraphEvents } from '@/common';
@@ -18,7 +18,7 @@ async function testStandardStreaming(): Promise<void> {
18
18
  const { contentParts, aggregateContent } = createContentAggregator();
19
19
  const customHandlers = {
20
20
  [GraphEvents.TOOL_END]: new ToolEndHandler(),
21
- // [GraphEvents.CHAT_MODEL_END]: new ModelEndHandler(),
21
+ [GraphEvents.CHAT_MODEL_END]: new ModelEndHandler(),
22
22
  [GraphEvents.CHAT_MODEL_STREAM]: new ChatModelStreamHandler(),
23
23
  [GraphEvents.ON_RUN_STEP_COMPLETED]: {
24
24
  handle: (event: GraphEvents.ON_RUN_STEP_COMPLETED, data: t.StreamEventData): void => {
@@ -0,0 +1,105 @@
1
+ import { z } from 'zod';
2
+ import { config } from 'dotenv';
3
+ import { tool, DynamicStructuredTool } from '@langchain/core/tools';
4
+
5
+ config();
6
+
7
+ const EXEC_ENDPOINT = 'https://api.librechat.ai/exec';
8
+
9
+ export type CodeExecutionToolParams = {
10
+ session_id?: string;
11
+ user_id?: string;
12
+ }
13
+
14
+ export type FileRef = {
15
+ id: string;
16
+ name: string;
17
+ path?: string;
18
+ };
19
+
20
+ export type FileRefs = FileRef[];
21
+
22
+ export type ExecuteResult = {
23
+ session_id: string;
24
+ stdout: string;
25
+ stderr: string;
26
+ files?: FileRefs;
27
+ };
28
+
29
+ const CodeExecutionToolSchema = z.object({
30
+ lang: z.enum([
31
+ 'py',
32
+ 'js',
33
+ 'ts',
34
+ 'c',
35
+ 'cpp',
36
+ 'java',
37
+ 'php',
38
+ 'rs',
39
+ 'go',
40
+ 'bash',
41
+ 'd',
42
+ 'f90',
43
+ ])
44
+ .describe('The programming language or runtime to execute the code in.'),
45
+ code: z.string()
46
+ .describe('The complete, self-contained code to execute, without any truncation or minimization.'),
47
+ args: z.array(z.string()).optional()
48
+ .describe('Additional arguments to execute the code with.'),
49
+ });
50
+
51
+ function createCodeExecutionTool(params: CodeExecutionToolParams = {}): DynamicStructuredTool<typeof CodeExecutionToolSchema> {
52
+ return tool<typeof CodeExecutionToolSchema>(
53
+ async ({ lang, code, ...rest }) => {
54
+ const postData = {
55
+ lang,
56
+ code,
57
+ ...rest,
58
+ ...params,
59
+ };
60
+
61
+ try {
62
+ const response = await fetch(EXEC_ENDPOINT, {
63
+ method: 'POST',
64
+ headers: {
65
+ 'Content-Type': 'application/json',
66
+ 'User-Agent': 'LibreChat/1.0',
67
+ },
68
+ body: JSON.stringify(postData),
69
+ });
70
+
71
+ if (!response.ok) {
72
+ throw new Error(`HTTP error! status: ${response.status}`);
73
+ }
74
+
75
+ const result: ExecuteResult = await response.json();
76
+ let formattedOutput = '';
77
+ if (result.stdout) formattedOutput += `stdout:\n${result.stdout}\n`;
78
+ if (result.stderr) formattedOutput += `stderr:\n${result.stderr}\n`;
79
+ if (result.files && result.files.length > 0) {
80
+ formattedOutput += 'Generated files:\n';
81
+ result.files.forEach((file: FileRef) => {
82
+ formattedOutput += `${file.name}`;
83
+ });
84
+ return [formattedOutput.trim(), result.files];
85
+ }
86
+
87
+ return [formattedOutput.trim(), undefined];
88
+ } catch (error) {
89
+ return `Calling tool with arguments:\n\n${JSON.stringify({
90
+ lang,
91
+ code,
92
+ ...rest,
93
+ })}\n\nraised the following error:\n\n${(error as Error | undefined)?.message}`;
94
+ }
95
+ },
96
+ {
97
+ name: 'execute_code',
98
+ description: 'Executes code in various programming languages, returning stdout/stderr output.',
99
+ schema: CodeExecutionToolSchema,
100
+ responseFormat: 'content_and_artifact',
101
+ }
102
+ );
103
+ }
104
+
105
+ export { createCodeExecutionTool };
@@ -19,7 +19,7 @@ export type IState = BaseGraphState;
19
19
  // }
20
20
 
21
21
  export interface EventHandler {
22
- handle(event: string, data: StreamEventData, metadata?: Record<string, unknown>, graph?: Graph): void;
22
+ handle(event: string, data: StreamEventData | ModelEndData, metadata?: Record<string, unknown>, graph?: Graph): void;
23
23
  }
24
24
 
25
25
  export type GraphStateChannels<T extends BaseGraphState> = StateGraphArgs<T>['channels'];
@@ -70,6 +70,7 @@ export type StreamEventData = {
70
70
  */
71
71
  result?: unknown;
72
72
  };
73
+
73
74
  /**
74
75
  * A streaming event.
75
76
  *
@@ -131,4 +132,6 @@ export type PartMetadata = {
131
132
  status?: string;
132
133
  action?: boolean;
133
134
  output?: string;
134
- };
135
+ };
136
+
137
+ export type ModelEndData = StreamEventData & { output: AIMessageChunk | undefined } | undefined;