UNPKG

langchain

Version:
1 lines 5.53 kB
{"version":3,"file":"utils.cjs","names":["AIMessage","ToolMessage"],"sources":["../../../src/agents/middleware/utils.ts"],"sourcesContent":["import {\n AIMessage,\n ToolMessage,\n type BaseMessage,\n} from \"@langchain/core/messages\";\nimport { isLangChainTool } from \"@langchain/core/tools\";\nimport { convertToOpenAITool } from \"@langchain/core/utils/function_calling\";\nimport {\n AfterModelHook,\n AfterAgentHook,\n BeforeAgentHook,\n BeforeModelHook,\n} from \"./types.js\";\nimport { JumpToTarget } from \"../constants.js\";\n\n/**\n * Default token counter that approximates based on character count.\n *\n * If tools are provided, the token count also includes stringified tool schemas.\n *\n * @param messages Messages to count tokens for\n * @param tools Optional list of tools to include in the token count. Each tool\n * can be either a LangChain tool instance or a dict representing a tool schema.\n * LangChain tool instances are converted to OpenAI tool format before counting.\n * @returns Approximate token count\n */\nexport function countTokensApproximately(\n messages: BaseMessage[],\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n tools?: Array<Record<string, any>> | null\n): number {\n const charsPerToken = 4;\n let totalChars = 0;\n\n // Count tokens for tools if provided\n if (tools && tools.length > 0) {\n let toolsChars = 0;\n for (const tool of tools) {\n const toolDict = isLangChainTool(tool) ? convertToOpenAITool(tool) : tool;\n toolsChars += JSON.stringify(toolDict).length;\n }\n totalChars += toolsChars;\n }\n\n for (const msg of messages) {\n let textContent: string;\n if (typeof msg.content === \"string\") {\n textContent = msg.content;\n } else if (Array.isArray(msg.content)) {\n textContent = msg.content\n .map((item) => {\n if (typeof item === \"string\") return item;\n if (item.type === \"text\" && \"text\" in item) return item.text;\n return \"\";\n })\n .join(\"\");\n } else {\n textContent = \"\";\n }\n\n if (\n AIMessage.isInstance(msg) &&\n Array.isArray(msg.tool_calls) &&\n msg.tool_calls.length > 0\n ) {\n textContent += JSON.stringify(msg.tool_calls);\n }\n\n if (ToolMessage.isInstance(msg)) {\n textContent += msg.tool_call_id ?? \"\";\n }\n\n totalChars += textContent.length;\n }\n // Approximate 1 token = 4 characters\n return Math.ceil(totalChars / charsPerToken);\n}\n\nexport function getHookConstraint(\n hook:\n | BeforeAgentHook\n | BeforeModelHook\n | AfterAgentHook\n | AfterModelHook\n | undefined\n): JumpToTarget[] | undefined {\n if (!hook || typeof hook === \"function\") {\n return undefined;\n }\n return hook.canJumpTo;\n}\n\nexport function getHookFunction(\n arg: BeforeAgentHook | BeforeModelHook | AfterAgentHook | AfterModelHook\n) {\n if (typeof arg === \"function\") {\n return arg;\n }\n return arg.hook;\n}\n\n/**\n * Sleep for the specified number of milliseconds.\n */\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Calculate delay for a retry attempt with exponential backoff and jitter.\n *\n * @param retryNumber - The retry attempt number (0-indexed)\n * @param config - Configuration for backoff calculation\n * @returns Delay in milliseconds before next retry\n *\n * @internal Exported for testing purposes\n */\nexport function calculateRetryDelay(\n config: {\n backoffFactor: number;\n initialDelayMs: number;\n maxDelayMs: number;\n jitter: boolean;\n },\n retryNumber: number\n): number {\n const { backoffFactor, initialDelayMs, maxDelayMs, jitter } = config;\n\n let delay: number;\n if (backoffFactor === 0.0) {\n delay = initialDelayMs;\n } else {\n delay = initialDelayMs * backoffFactor ** retryNumber;\n }\n\n // Cap at maxDelayMs\n delay = Math.min(delay, maxDelayMs);\n\n if (jitter && delay > 0) {\n const jitterAmount = delay * 0.25;\n delay = delay + (Math.random() * 2 - 1) * jitterAmount;\n // Ensure delay is not negative after jitter\n delay = Math.max(0, delay);\n }\n\n return delay;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AA0BA,SAAgB,yBACd,UAEA,OACQ;CACR,MAAM,gBAAgB;CACtB,IAAI,aAAa;AAGjB,KAAI,SAAS,MAAM,SAAS,GAAG;EAC7B,IAAI,aAAa;AACjB,OAAK,MAAM,QAAQ,OAAO;GACxB,MAAM,YAAA,GAAA,sBAAA,iBAA2B,KAAK,IAAA,GAAA,uCAAA,qBAAuB,KAAK,GAAG;AACrE,iBAAc,KAAK,UAAU,SAAS,CAAC;;AAEzC,gBAAc;;AAGhB,MAAK,MAAM,OAAO,UAAU;EAC1B,IAAI;AACJ,MAAI,OAAO,IAAI,YAAY,SACzB,eAAc,IAAI;WACT,MAAM,QAAQ,IAAI,QAAQ,CACnC,eAAc,IAAI,QACf,KAAK,SAAS;AACb,OAAI,OAAO,SAAS,SAAU,QAAO;AACrC,OAAI,KAAK,SAAS,UAAU,UAAU,KAAM,QAAO,KAAK;AACxD,UAAO;IACP,CACD,KAAK,GAAG;MAEX,eAAc;AAGhB,MACEA,yBAAAA,UAAU,WAAW,IAAI,IACzB,MAAM,QAAQ,IAAI,WAAW,IAC7B,IAAI,WAAW,SAAS,EAExB,gBAAe,KAAK,UAAU,IAAI,WAAW;AAG/C,MAAIC,yBAAAA,YAAY,WAAW,IAAI,CAC7B,gBAAe,IAAI,gBAAgB;AAGrC,gBAAc,YAAY;;AAG5B,QAAO,KAAK,KAAK,aAAa,cAAc;;AAG9C,SAAgB,kBACd,MAM4B;AAC5B,KAAI,CAAC,QAAQ,OAAO,SAAS,WAC3B;AAEF,QAAO,KAAK;;AAGd,SAAgB,gBACd,KACA;AACA,KAAI,OAAO,QAAQ,WACjB,QAAO;AAET,QAAO,IAAI;;;;;AAMb,SAAgB,MAAM,IAA2B;AAC/C,QAAO,IAAI,SAAS,YAAY,WAAW,SAAS,GAAG,CAAC;;;;;;;;;;;AAY1D,SAAgB,oBACd,QAMA,aACQ;CACR,MAAM,EAAE,eAAe,gBAAgB,YAAY,WAAW;CAE9D,IAAI;AACJ,KAAI,kBAAkB,EACpB,SAAQ;KAER,SAAQ,iBAAiB,iBAAiB;AAI5C,SAAQ,KAAK,IAAI,OAAO,WAAW;AAEnC,KAAI,UAAU,QAAQ,GAAG;EACvB,MAAM,eAAe,QAAQ;AAC7B,UAAQ,SAAS,KAAK,QAAQ,GAAG,IAAI,KAAK;AAE1C,UAAQ,KAAK,IAAI,GAAG,MAAM;;AAG5B,QAAO"}