ai.cjs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.AIMessageChunk = exports.isAIMessageChunk = exports.isAIMessage = exports.AIMessage = void 0;
  4. const json_js_1 = require("../utils/json.cjs");
  5. const base_js_1 = require("./base.cjs");
  6. const tool_js_1 = require("./tool.cjs");
  7. /**
  8. * Represents an AI message in a conversation.
  9. */
  10. class AIMessage extends base_js_1.BaseMessage {
  11. get lc_aliases() {
  12. // exclude snake case conversion to pascal case
  13. return {
  14. ...super.lc_aliases,
  15. tool_calls: "tool_calls",
  16. invalid_tool_calls: "invalid_tool_calls",
  17. };
  18. }
  19. constructor(fields,
  20. /** @deprecated */
  21. kwargs) {
  22. let initParams;
  23. if (typeof fields === "string") {
  24. initParams = {
  25. content: fields,
  26. tool_calls: [],
  27. invalid_tool_calls: [],
  28. additional_kwargs: kwargs ?? {},
  29. };
  30. }
  31. else {
  32. initParams = fields;
  33. const rawToolCalls = initParams.additional_kwargs?.tool_calls;
  34. const toolCalls = initParams.tool_calls;
  35. if (!(rawToolCalls == null) &&
  36. rawToolCalls.length > 0 &&
  37. (toolCalls === undefined || toolCalls.length === 0)) {
  38. console.warn([
  39. "New LangChain packages are available that more efficiently handle",
  40. "tool calling.\n\nPlease upgrade your packages to versions that set",
  41. "message tool calls. e.g., `yarn add @langchain/anthropic`,",
  42. "yarn add @langchain/openai`, etc.",
  43. ].join(" "));
  44. }
  45. try {
  46. if (!(rawToolCalls == null) && toolCalls === undefined) {
  47. const [toolCalls, invalidToolCalls] = (0, tool_js_1.defaultToolCallParser)(rawToolCalls);
  48. initParams.tool_calls = toolCalls ?? [];
  49. initParams.invalid_tool_calls = invalidToolCalls ?? [];
  50. }
  51. else {
  52. initParams.tool_calls = initParams.tool_calls ?? [];
  53. initParams.invalid_tool_calls = initParams.invalid_tool_calls ?? [];
  54. }
  55. }
  56. catch (e) {
  57. // Do nothing if parsing fails
  58. initParams.tool_calls = [];
  59. initParams.invalid_tool_calls = [];
  60. }
  61. }
  62. // Sadly, TypeScript only allows super() calls at root if the class has
  63. // properties with initializers, so we have to check types twice.
  64. super(initParams);
  65. // These are typed as optional to avoid breaking changes and allow for casting
  66. // from BaseMessage.
  67. Object.defineProperty(this, "tool_calls", {
  68. enumerable: true,
  69. configurable: true,
  70. writable: true,
  71. value: []
  72. });
  73. Object.defineProperty(this, "invalid_tool_calls", {
  74. enumerable: true,
  75. configurable: true,
  76. writable: true,
  77. value: []
  78. });
  79. /**
  80. * If provided, token usage information associated with the message.
  81. */
  82. Object.defineProperty(this, "usage_metadata", {
  83. enumerable: true,
  84. configurable: true,
  85. writable: true,
  86. value: void 0
  87. });
  88. if (typeof initParams !== "string") {
  89. this.tool_calls = initParams.tool_calls ?? this.tool_calls;
  90. this.invalid_tool_calls =
  91. initParams.invalid_tool_calls ?? this.invalid_tool_calls;
  92. }
  93. this.usage_metadata = initParams.usage_metadata;
  94. }
  95. static lc_name() {
  96. return "AIMessage";
  97. }
  98. _getType() {
  99. return "ai";
  100. }
  101. get _printableFields() {
  102. return {
  103. ...super._printableFields,
  104. tool_calls: this.tool_calls,
  105. invalid_tool_calls: this.invalid_tool_calls,
  106. usage_metadata: this.usage_metadata,
  107. };
  108. }
  109. }
  110. exports.AIMessage = AIMessage;
  111. function isAIMessage(x) {
  112. return x._getType() === "ai";
  113. }
  114. exports.isAIMessage = isAIMessage;
  115. function isAIMessageChunk(x) {
  116. return x._getType() === "ai";
  117. }
  118. exports.isAIMessageChunk = isAIMessageChunk;
  119. /**
  120. * Represents a chunk of an AI message, which can be concatenated with
  121. * other AI message chunks.
  122. */
  123. class AIMessageChunk extends base_js_1.BaseMessageChunk {
  124. constructor(fields) {
  125. let initParams;
  126. if (typeof fields === "string") {
  127. initParams = {
  128. content: fields,
  129. tool_calls: [],
  130. invalid_tool_calls: [],
  131. tool_call_chunks: [],
  132. };
  133. }
  134. else if (fields.tool_call_chunks === undefined) {
  135. initParams = {
  136. ...fields,
  137. tool_calls: fields.tool_calls ?? [],
  138. invalid_tool_calls: [],
  139. tool_call_chunks: [],
  140. usage_metadata: fields.usage_metadata !== undefined
  141. ? fields.usage_metadata
  142. : undefined,
  143. };
  144. }
  145. else {
  146. const toolCalls = [];
  147. const invalidToolCalls = [];
  148. for (const toolCallChunk of fields.tool_call_chunks) {
  149. let parsedArgs = {};
  150. try {
  151. parsedArgs = (0, json_js_1.parsePartialJson)(toolCallChunk.args || "{}");
  152. if (parsedArgs === null ||
  153. typeof parsedArgs !== "object" ||
  154. Array.isArray(parsedArgs)) {
  155. throw new Error("Malformed tool call chunk args.");
  156. }
  157. toolCalls.push({
  158. name: toolCallChunk.name ?? "",
  159. args: parsedArgs,
  160. id: toolCallChunk.id,
  161. type: "tool_call",
  162. });
  163. }
  164. catch (e) {
  165. invalidToolCalls.push({
  166. name: toolCallChunk.name,
  167. args: toolCallChunk.args,
  168. id: toolCallChunk.id,
  169. error: "Malformed args.",
  170. type: "invalid_tool_call",
  171. });
  172. }
  173. }
  174. initParams = {
  175. ...fields,
  176. tool_calls: toolCalls,
  177. invalid_tool_calls: invalidToolCalls,
  178. usage_metadata: fields.usage_metadata !== undefined
  179. ? fields.usage_metadata
  180. : undefined,
  181. };
  182. }
  183. // Sadly, TypeScript only allows super() calls at root if the class has
  184. // properties with initializers, so we have to check types twice.
  185. super(initParams);
  186. // Must redeclare tool call fields since there is no multiple inheritance in JS.
  187. // These are typed as optional to avoid breaking changes and allow for casting
  188. // from BaseMessage.
  189. Object.defineProperty(this, "tool_calls", {
  190. enumerable: true,
  191. configurable: true,
  192. writable: true,
  193. value: []
  194. });
  195. Object.defineProperty(this, "invalid_tool_calls", {
  196. enumerable: true,
  197. configurable: true,
  198. writable: true,
  199. value: []
  200. });
  201. Object.defineProperty(this, "tool_call_chunks", {
  202. enumerable: true,
  203. configurable: true,
  204. writable: true,
  205. value: []
  206. });
  207. /**
  208. * If provided, token usage information associated with the message.
  209. */
  210. Object.defineProperty(this, "usage_metadata", {
  211. enumerable: true,
  212. configurable: true,
  213. writable: true,
  214. value: void 0
  215. });
  216. this.tool_call_chunks =
  217. initParams.tool_call_chunks ?? this.tool_call_chunks;
  218. this.tool_calls = initParams.tool_calls ?? this.tool_calls;
  219. this.invalid_tool_calls =
  220. initParams.invalid_tool_calls ?? this.invalid_tool_calls;
  221. this.usage_metadata = initParams.usage_metadata;
  222. }
  223. get lc_aliases() {
  224. // exclude snake case conversion to pascal case
  225. return {
  226. ...super.lc_aliases,
  227. tool_calls: "tool_calls",
  228. invalid_tool_calls: "invalid_tool_calls",
  229. tool_call_chunks: "tool_call_chunks",
  230. };
  231. }
  232. static lc_name() {
  233. return "AIMessageChunk";
  234. }
  235. _getType() {
  236. return "ai";
  237. }
  238. get _printableFields() {
  239. return {
  240. ...super._printableFields,
  241. tool_calls: this.tool_calls,
  242. tool_call_chunks: this.tool_call_chunks,
  243. invalid_tool_calls: this.invalid_tool_calls,
  244. usage_metadata: this.usage_metadata,
  245. };
  246. }
  247. concat(chunk) {
  248. const combinedFields = {
  249. content: (0, base_js_1.mergeContent)(this.content, chunk.content),
  250. additional_kwargs: (0, base_js_1._mergeDicts)(this.additional_kwargs, chunk.additional_kwargs),
  251. response_metadata: (0, base_js_1._mergeDicts)(this.response_metadata, chunk.response_metadata),
  252. tool_call_chunks: [],
  253. id: this.id ?? chunk.id,
  254. };
  255. if (this.tool_call_chunks !== undefined ||
  256. chunk.tool_call_chunks !== undefined) {
  257. const rawToolCalls = (0, base_js_1._mergeLists)(this.tool_call_chunks, chunk.tool_call_chunks);
  258. if (rawToolCalls !== undefined && rawToolCalls.length > 0) {
  259. combinedFields.tool_call_chunks = rawToolCalls;
  260. }
  261. }
  262. if (this.usage_metadata !== undefined ||
  263. chunk.usage_metadata !== undefined) {
  264. const inputTokenDetails = {
  265. ...((this.usage_metadata?.input_token_details?.audio !== undefined ||
  266. chunk.usage_metadata?.input_token_details?.audio !== undefined) && {
  267. audio: (this.usage_metadata?.input_token_details?.audio ?? 0) +
  268. (chunk.usage_metadata?.input_token_details?.audio ?? 0),
  269. }),
  270. ...((this.usage_metadata?.input_token_details?.cache_read !==
  271. undefined ||
  272. chunk.usage_metadata?.input_token_details?.cache_read !==
  273. undefined) && {
  274. cache_read: (this.usage_metadata?.input_token_details?.cache_read ?? 0) +
  275. (chunk.usage_metadata?.input_token_details?.cache_read ?? 0),
  276. }),
  277. ...((this.usage_metadata?.input_token_details?.cache_creation !==
  278. undefined ||
  279. chunk.usage_metadata?.input_token_details?.cache_creation !==
  280. undefined) && {
  281. cache_creation: (this.usage_metadata?.input_token_details?.cache_creation ?? 0) +
  282. (chunk.usage_metadata?.input_token_details?.cache_creation ?? 0),
  283. }),
  284. };
  285. const outputTokenDetails = {
  286. ...((this.usage_metadata?.output_token_details?.audio !== undefined ||
  287. chunk.usage_metadata?.output_token_details?.audio !== undefined) && {
  288. audio: (this.usage_metadata?.output_token_details?.audio ?? 0) +
  289. (chunk.usage_metadata?.output_token_details?.audio ?? 0),
  290. }),
  291. ...((this.usage_metadata?.output_token_details?.reasoning !==
  292. undefined ||
  293. chunk.usage_metadata?.output_token_details?.reasoning !==
  294. undefined) && {
  295. reasoning: (this.usage_metadata?.output_token_details?.reasoning ?? 0) +
  296. (chunk.usage_metadata?.output_token_details?.reasoning ?? 0),
  297. }),
  298. };
  299. const left = this.usage_metadata ?? {
  300. input_tokens: 0,
  301. output_tokens: 0,
  302. total_tokens: 0,
  303. };
  304. const right = chunk.usage_metadata ?? {
  305. input_tokens: 0,
  306. output_tokens: 0,
  307. total_tokens: 0,
  308. };
  309. const usage_metadata = {
  310. input_tokens: left.input_tokens + right.input_tokens,
  311. output_tokens: left.output_tokens + right.output_tokens,
  312. total_tokens: left.total_tokens + right.total_tokens,
  313. // Do not include `input_token_details` / `output_token_details` keys in combined fields
  314. // unless their values are defined.
  315. ...(Object.keys(inputTokenDetails).length > 0 && {
  316. input_token_details: inputTokenDetails,
  317. }),
  318. ...(Object.keys(outputTokenDetails).length > 0 && {
  319. output_token_details: outputTokenDetails,
  320. }),
  321. };
  322. combinedFields.usage_metadata = usage_metadata;
  323. }
  324. return new AIMessageChunk(combinedFields);
  325. }
  326. }
  327. exports.AIMessageChunk = AIMessageChunk;