11import type { BaseChatModel } from "@langchain/core/language_models/chat_models" ;
22import {
3- logger ,
43 type CompletionAdapter ,
54} from "adminforth" ;
65import { BaseCallbackHandler } from "@langchain/core/callbacks/base" ;
@@ -35,19 +34,8 @@ type AgentChatModelSpec = {
3534 middleware : AgentMiddleware [ ] ;
3635} ;
3736
38- type LlmOutputTokenUsage = {
39- promptTokens ?: unknown ;
40- completionTokens ?: unknown ;
41- } ;
42-
43- type MessageUsageMetadata = {
44- input_tokens ?: unknown ;
45- output_tokens ?: unknown ;
46- } ;
47-
4837type PendingLlmRun = {
4938 startedAt : number ;
50- firstTokenAt ?: number ;
5139} ;
5240
5341function isLangChainAgentCompletionAdapter (
@@ -73,61 +61,6 @@ async function getAgentChatModelSpec(params: {
7361 } ;
7462}
7563
76- function getFiniteNumber ( value : unknown ) {
77- return typeof value === "number" && Number . isFinite ( value )
78- ? value
79- : undefined ;
80- }
81-
82- function extractTokenUsage ( output : LLMResult ) {
83- const llmOutputTokenUsage = (
84- output . llmOutput as { tokenUsage ?: LlmOutputTokenUsage } | undefined
85- ) ?. tokenUsage ;
86-
87- const promptTokens = getFiniteNumber ( llmOutputTokenUsage ?. promptTokens ) ;
88- const completionTokens = getFiniteNumber (
89- llmOutputTokenUsage ?. completionTokens ,
90- ) ;
91-
92- if ( promptTokens !== undefined || completionTokens !== undefined ) {
93- return {
94- InputTokens : promptTokens ?? 0 ,
95- outputTokens : completionTokens ?? 0 ,
96- } ;
97- }
98-
99- let InputTokens = 0 ;
100- let outputTokens = 0 ;
101-
102- for ( const generationBatch of output . generations ) {
103- for ( const generation of generationBatch ) {
104- if ( ! ( "message" in generation ) || ! generation . message ) {
105- continue ;
106- }
107-
108- const message = generation . message as {
109- usage_metadata ?: MessageUsageMetadata ;
110- response_metadata ?: {
111- tokenUsage ?: LlmOutputTokenUsage ;
112- } ;
113- } ;
114-
115- InputTokens +=
116- getFiniteNumber ( message . usage_metadata ?. input_tokens ) ??
117- getFiniteNumber ( message . response_metadata ?. tokenUsage ?. promptTokens ) ??
118- 0 ;
119- outputTokens +=
120- getFiniteNumber ( message . usage_metadata ?. output_tokens ) ??
121- getFiniteNumber (
122- message . response_metadata ?. tokenUsage ?. completionTokens ,
123- ) ??
124- 0 ;
125- }
126- }
127-
128- return { InputTokens, outputTokens } ;
129- }
130-
13164class AgentLlmMetricsLogger extends BaseCallbackHandler {
13265 name = "AgentLlmMetricsLogger" ;
13366 lc_prefer_streaming = true ;
@@ -138,41 +71,8 @@ class AgentLlmMetricsLogger extends BaseCallbackHandler {
13871 this . pendingRuns . set ( runId , { startedAt : Date . now ( ) } ) ;
13972 }
14073
141- async handleLLMNewToken (
142- _token : string ,
143- _chunk : unknown ,
144- runId : string ,
145- ) {
146- const pendingRun = this . pendingRuns . get ( runId ) ;
147-
148- if ( ! pendingRun || pendingRun . firstTokenAt !== undefined ) {
149- return ;
150- }
151-
152- pendingRun . firstTokenAt = Date . now ( ) ;
153- }
154-
155- async handleLLMEnd ( output : LLMResult , runId : string ) {
156- const pendingRun = this . pendingRuns . get ( runId ) ;
157-
158- if ( ! pendingRun ) {
159- return ;
160- }
161-
74+ async handleLLMEnd ( _output : LLMResult , runId : string ) {
16275 this . pendingRuns . delete ( runId ) ;
163-
164- const finishedAt = Date . now ( ) ;
165- const rtt = finishedAt - pendingRun . startedAt ;
166- const ttft =
167- pendingRun . firstTokenAt === undefined
168- ? rtt
169- : pendingRun . firstTokenAt - pendingRun . startedAt ;
170- const { InputTokens, outputTokens } = extractTokenUsage ( output ) ;
171-
172- logger . info (
173- { InputTokens, outputTokens, ttft, rtt } ,
174- "LLM call finished" ,
175- ) ;
17676 }
17777
17878 async handleLLMError ( _error : unknown , runId : string ) {
0 commit comments