@diogonzafe/tokenwatch 0.2.1 → 0.5.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.
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/langchain/index.ts
21
+ var langchain_exports = {};
22
+ __export(langchain_exports, {
23
+ TokenwatchCallbackHandler: () => TokenwatchCallbackHandler
24
+ });
25
+ module.exports = __toCommonJS(langchain_exports);
26
+
27
+ // src/langchain/handler.ts
28
+ var BaseCallbackHandlerStub = class {
29
+ };
30
+ var TokenwatchCallbackHandler = class extends BaseCallbackHandlerStub {
31
+ constructor(tracker, options = {}) {
32
+ super();
33
+ this.tracker = tracker;
34
+ this.options = options;
35
+ }
36
+ tracker;
37
+ options;
38
+ name = "TokenwatchCallbackHandler";
39
+ async handleLLMEnd(output) {
40
+ const tokenUsage = output.llmOutput?.tokenUsage ?? output.llmOutput?.estimatedTokenUsage;
41
+ const inputTokens = tokenUsage?.promptTokens ?? 0;
42
+ const outputTokens = tokenUsage?.completionTokens ?? 0;
43
+ const firstGenerations = output.generations[0];
44
+ const firstGen = firstGenerations?.[0];
45
+ const modelFromResponse = firstGen?.message?.response_metadata?.model_name;
46
+ const model = modelFromResponse ?? this.options.defaultModel ?? "unknown";
47
+ const { sessionId, userId, feature } = this.options;
48
+ this.tracker.track({
49
+ model,
50
+ inputTokens,
51
+ outputTokens,
52
+ ...sessionId !== void 0 && { sessionId },
53
+ ...userId !== void 0 && { userId },
54
+ ...feature !== void 0 && { feature }
55
+ });
56
+ }
57
+ };
58
+ // Annotate the CommonJS export names for ESM import in node:
59
+ 0 && (module.exports = {
60
+ TokenwatchCallbackHandler
61
+ });
62
+ //# sourceMappingURL=langchain.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/langchain/index.ts","../src/langchain/handler.ts"],"sourcesContent":["export { TokenwatchCallbackHandler } from './handler.js'\nexport type { TokenwatchCallbackHandlerOptions } from './handler.js'\n","import type { Tracker } from '../types/index.js'\n\n// ─── Local type stubs ─────────────────────────────────────────────────────────\n// These mirror the minimal shape of @langchain/core types so this file compiles\n// without a hard compile-time dependency on @langchain/core.\n\ninterface TokenUsage {\n promptTokens?: number\n completionTokens?: number\n}\n\ninterface Generation {\n message?: {\n response_metadata?: {\n model_name?: string\n }\n }\n}\n\ninterface LLMResult {\n llmOutput?: {\n tokenUsage?: TokenUsage\n estimatedTokenUsage?: TokenUsage\n } | null\n generations: Generation[][]\n}\n\n/**\n * Minimal stub that mirrors the shape of BaseCallbackHandler from @langchain/core.\n * Extend this so the class compiles without the peer dependency being installed.\n * LangChain's callback system is duck-typed and will call the methods that exist.\n */\nabstract class BaseCallbackHandlerStub {\n abstract name: string\n handleLLMStart?(...args: unknown[]): Promise<void> | void\n handleLLMEnd?(output: LLMResult, ...args: unknown[]): Promise<void> | void\n handleLLMError?(...args: unknown[]): Promise<void> | void\n handleChainStart?(...args: unknown[]): Promise<void> | void\n handleChainEnd?(...args: unknown[]): Promise<void> | void\n handleChainError?(...args: unknown[]): Promise<void> | void\n handleToolStart?(...args: unknown[]): Promise<void> | void\n handleToolEnd?(...args: unknown[]): Promise<void> | void\n handleToolError?(...args: unknown[]): Promise<void> | void\n handleAgentAction?(...args: unknown[]): Promise<void> | void\n handleAgentEnd?(...args: unknown[]): Promise<void> | void\n handleText?(...args: unknown[]): Promise<void> | void\n}\n\n// ─── Public types ─────────────────────────────────────────────────────────────\n\nexport interface TokenwatchCallbackHandlerOptions {\n /** Fallback model name when the response does not include it. Defaults to 'unknown'. */\n defaultModel?: string\n /** Tag all calls from this handler with a session ID */\n sessionId?: string\n /** Tag all calls from this handler with a user ID */\n userId?: string\n /** Tag all calls from this handler with a product feature name */\n feature?: string\n}\n\n// ─── Handler ──────────────────────────────────────────────────────────────────\n\n/**\n * LangChain callback handler that automatically tracks LLM cost via tokenwatch.\n *\n * @example\n * import { TokenwatchCallbackHandler } from '@diogonzafe/tokenwatch/langchain'\n *\n * const handler = new TokenwatchCallbackHandler(tracker, { defaultModel: 'gpt-4o' })\n * const llm = new ChatOpenAI({ model: 'gpt-4o', callbacks: [handler] })\n */\nexport class TokenwatchCallbackHandler extends BaseCallbackHandlerStub {\n name = 'TokenwatchCallbackHandler' as const\n\n constructor(\n private readonly tracker: Tracker,\n private readonly options: TokenwatchCallbackHandlerOptions = {},\n ) {\n super()\n }\n\n async handleLLMEnd(output: LLMResult): Promise<void> {\n // Prefer exact tokenUsage, fall back to estimatedTokenUsage (streaming)\n const tokenUsage = output.llmOutput?.tokenUsage ?? output.llmOutput?.estimatedTokenUsage\n\n const inputTokens = tokenUsage?.promptTokens ?? 0\n const outputTokens = tokenUsage?.completionTokens ?? 0\n\n // noUncheckedIndexedAccess: generations[0] is Generation[] | undefined\n const firstGenerations = output.generations[0]\n const firstGen = firstGenerations?.[0]\n const modelFromResponse = firstGen?.message?.response_metadata?.model_name\n const model = modelFromResponse ?? this.options.defaultModel ?? 'unknown'\n\n const { sessionId, userId, feature } = this.options\n\n this.tracker.track({\n model,\n inputTokens,\n outputTokens,\n ...(sessionId !== undefined && { sessionId }),\n ...(userId !== undefined && { userId }),\n ...(feature !== undefined && { feature }),\n })\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACgCA,IAAe,0BAAf,MAAuC;AAcvC;AA0BO,IAAM,4BAAN,cAAwC,wBAAwB;AAAA,EAGrE,YACmB,SACA,UAA4C,CAAC,GAC9D;AACA,UAAM;AAHW;AACA;AAAA,EAGnB;AAAA,EAJmB;AAAA,EACA;AAAA,EAJnB,OAAO;AAAA,EASP,MAAM,aAAa,QAAkC;AAEnD,UAAM,aAAa,OAAO,WAAW,cAAc,OAAO,WAAW;AAErE,UAAM,cAAc,YAAY,gBAAgB;AAChD,UAAM,eAAe,YAAY,oBAAoB;AAGrD,UAAM,mBAAmB,OAAO,YAAY,CAAC;AAC7C,UAAM,WAAW,mBAAmB,CAAC;AACrC,UAAM,oBAAoB,UAAU,SAAS,mBAAmB;AAChE,UAAM,QAAQ,qBAAqB,KAAK,QAAQ,gBAAgB;AAEhE,UAAM,EAAE,WAAW,QAAQ,QAAQ,IAAI,KAAK;AAE5C,SAAK,QAAQ,MAAM;AAAA,MACjB;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAI,cAAc,UAAa,EAAE,UAAU;AAAA,MAC3C,GAAI,WAAW,UAAa,EAAE,OAAO;AAAA,MACrC,GAAI,YAAY,UAAa,EAAE,QAAQ;AAAA,IACzC,CAAC;AAAA,EACH;AACF;","names":[]}
@@ -0,0 +1,68 @@
1
+ import { a as Tracker } from './index-CJKk1hHw.cjs';
2
+
3
+ interface TokenUsage {
4
+ promptTokens?: number;
5
+ completionTokens?: number;
6
+ }
7
+ interface Generation {
8
+ message?: {
9
+ response_metadata?: {
10
+ model_name?: string;
11
+ };
12
+ };
13
+ }
14
+ interface LLMResult {
15
+ llmOutput?: {
16
+ tokenUsage?: TokenUsage;
17
+ estimatedTokenUsage?: TokenUsage;
18
+ } | null;
19
+ generations: Generation[][];
20
+ }
21
+ /**
22
+ * Minimal stub that mirrors the shape of BaseCallbackHandler from @langchain/core.
23
+ * Extend this so the class compiles without the peer dependency being installed.
24
+ * LangChain's callback system is duck-typed and will call the methods that exist.
25
+ */
26
+ declare abstract class BaseCallbackHandlerStub {
27
+ abstract name: string;
28
+ handleLLMStart?(...args: unknown[]): Promise<void> | void;
29
+ handleLLMEnd?(output: LLMResult, ...args: unknown[]): Promise<void> | void;
30
+ handleLLMError?(...args: unknown[]): Promise<void> | void;
31
+ handleChainStart?(...args: unknown[]): Promise<void> | void;
32
+ handleChainEnd?(...args: unknown[]): Promise<void> | void;
33
+ handleChainError?(...args: unknown[]): Promise<void> | void;
34
+ handleToolStart?(...args: unknown[]): Promise<void> | void;
35
+ handleToolEnd?(...args: unknown[]): Promise<void> | void;
36
+ handleToolError?(...args: unknown[]): Promise<void> | void;
37
+ handleAgentAction?(...args: unknown[]): Promise<void> | void;
38
+ handleAgentEnd?(...args: unknown[]): Promise<void> | void;
39
+ handleText?(...args: unknown[]): Promise<void> | void;
40
+ }
41
+ interface TokenwatchCallbackHandlerOptions {
42
+ /** Fallback model name when the response does not include it. Defaults to 'unknown'. */
43
+ defaultModel?: string;
44
+ /** Tag all calls from this handler with a session ID */
45
+ sessionId?: string;
46
+ /** Tag all calls from this handler with a user ID */
47
+ userId?: string;
48
+ /** Tag all calls from this handler with a product feature name */
49
+ feature?: string;
50
+ }
51
+ /**
52
+ * LangChain callback handler that automatically tracks LLM cost via tokenwatch.
53
+ *
54
+ * @example
55
+ * import { TokenwatchCallbackHandler } from '@diogonzafe/tokenwatch/langchain'
56
+ *
57
+ * const handler = new TokenwatchCallbackHandler(tracker, { defaultModel: 'gpt-4o' })
58
+ * const llm = new ChatOpenAI({ model: 'gpt-4o', callbacks: [handler] })
59
+ */
60
+ declare class TokenwatchCallbackHandler extends BaseCallbackHandlerStub {
61
+ private readonly tracker;
62
+ private readonly options;
63
+ name: "TokenwatchCallbackHandler";
64
+ constructor(tracker: Tracker, options?: TokenwatchCallbackHandlerOptions);
65
+ handleLLMEnd(output: LLMResult): Promise<void>;
66
+ }
67
+
68
+ export { TokenwatchCallbackHandler, type TokenwatchCallbackHandlerOptions };
@@ -0,0 +1,68 @@
1
+ import { a as Tracker } from './index-CJKk1hHw.js';
2
+
3
+ interface TokenUsage {
4
+ promptTokens?: number;
5
+ completionTokens?: number;
6
+ }
7
+ interface Generation {
8
+ message?: {
9
+ response_metadata?: {
10
+ model_name?: string;
11
+ };
12
+ };
13
+ }
14
+ interface LLMResult {
15
+ llmOutput?: {
16
+ tokenUsage?: TokenUsage;
17
+ estimatedTokenUsage?: TokenUsage;
18
+ } | null;
19
+ generations: Generation[][];
20
+ }
21
+ /**
22
+ * Minimal stub that mirrors the shape of BaseCallbackHandler from @langchain/core.
23
+ * Extend this so the class compiles without the peer dependency being installed.
24
+ * LangChain's callback system is duck-typed and will call the methods that exist.
25
+ */
26
+ declare abstract class BaseCallbackHandlerStub {
27
+ abstract name: string;
28
+ handleLLMStart?(...args: unknown[]): Promise<void> | void;
29
+ handleLLMEnd?(output: LLMResult, ...args: unknown[]): Promise<void> | void;
30
+ handleLLMError?(...args: unknown[]): Promise<void> | void;
31
+ handleChainStart?(...args: unknown[]): Promise<void> | void;
32
+ handleChainEnd?(...args: unknown[]): Promise<void> | void;
33
+ handleChainError?(...args: unknown[]): Promise<void> | void;
34
+ handleToolStart?(...args: unknown[]): Promise<void> | void;
35
+ handleToolEnd?(...args: unknown[]): Promise<void> | void;
36
+ handleToolError?(...args: unknown[]): Promise<void> | void;
37
+ handleAgentAction?(...args: unknown[]): Promise<void> | void;
38
+ handleAgentEnd?(...args: unknown[]): Promise<void> | void;
39
+ handleText?(...args: unknown[]): Promise<void> | void;
40
+ }
41
+ interface TokenwatchCallbackHandlerOptions {
42
+ /** Fallback model name when the response does not include it. Defaults to 'unknown'. */
43
+ defaultModel?: string;
44
+ /** Tag all calls from this handler with a session ID */
45
+ sessionId?: string;
46
+ /** Tag all calls from this handler with a user ID */
47
+ userId?: string;
48
+ /** Tag all calls from this handler with a product feature name */
49
+ feature?: string;
50
+ }
51
+ /**
52
+ * LangChain callback handler that automatically tracks LLM cost via tokenwatch.
53
+ *
54
+ * @example
55
+ * import { TokenwatchCallbackHandler } from '@diogonzafe/tokenwatch/langchain'
56
+ *
57
+ * const handler = new TokenwatchCallbackHandler(tracker, { defaultModel: 'gpt-4o' })
58
+ * const llm = new ChatOpenAI({ model: 'gpt-4o', callbacks: [handler] })
59
+ */
60
+ declare class TokenwatchCallbackHandler extends BaseCallbackHandlerStub {
61
+ private readonly tracker;
62
+ private readonly options;
63
+ name: "TokenwatchCallbackHandler";
64
+ constructor(tracker: Tracker, options?: TokenwatchCallbackHandlerOptions);
65
+ handleLLMEnd(output: LLMResult): Promise<void>;
66
+ }
67
+
68
+ export { TokenwatchCallbackHandler, type TokenwatchCallbackHandlerOptions };
@@ -0,0 +1,35 @@
1
+ // src/langchain/handler.ts
2
+ var BaseCallbackHandlerStub = class {
3
+ };
4
+ var TokenwatchCallbackHandler = class extends BaseCallbackHandlerStub {
5
+ constructor(tracker, options = {}) {
6
+ super();
7
+ this.tracker = tracker;
8
+ this.options = options;
9
+ }
10
+ tracker;
11
+ options;
12
+ name = "TokenwatchCallbackHandler";
13
+ async handleLLMEnd(output) {
14
+ const tokenUsage = output.llmOutput?.tokenUsage ?? output.llmOutput?.estimatedTokenUsage;
15
+ const inputTokens = tokenUsage?.promptTokens ?? 0;
16
+ const outputTokens = tokenUsage?.completionTokens ?? 0;
17
+ const firstGenerations = output.generations[0];
18
+ const firstGen = firstGenerations?.[0];
19
+ const modelFromResponse = firstGen?.message?.response_metadata?.model_name;
20
+ const model = modelFromResponse ?? this.options.defaultModel ?? "unknown";
21
+ const { sessionId, userId, feature } = this.options;
22
+ this.tracker.track({
23
+ model,
24
+ inputTokens,
25
+ outputTokens,
26
+ ...sessionId !== void 0 && { sessionId },
27
+ ...userId !== void 0 && { userId },
28
+ ...feature !== void 0 && { feature }
29
+ });
30
+ }
31
+ };
32
+ export {
33
+ TokenwatchCallbackHandler
34
+ };
35
+ //# sourceMappingURL=langchain.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/langchain/handler.ts"],"sourcesContent":["import type { Tracker } from '../types/index.js'\n\n// ─── Local type stubs ─────────────────────────────────────────────────────────\n// These mirror the minimal shape of @langchain/core types so this file compiles\n// without a hard compile-time dependency on @langchain/core.\n\ninterface TokenUsage {\n promptTokens?: number\n completionTokens?: number\n}\n\ninterface Generation {\n message?: {\n response_metadata?: {\n model_name?: string\n }\n }\n}\n\ninterface LLMResult {\n llmOutput?: {\n tokenUsage?: TokenUsage\n estimatedTokenUsage?: TokenUsage\n } | null\n generations: Generation[][]\n}\n\n/**\n * Minimal stub that mirrors the shape of BaseCallbackHandler from @langchain/core.\n * Extend this so the class compiles without the peer dependency being installed.\n * LangChain's callback system is duck-typed and will call the methods that exist.\n */\nabstract class BaseCallbackHandlerStub {\n abstract name: string\n handleLLMStart?(...args: unknown[]): Promise<void> | void\n handleLLMEnd?(output: LLMResult, ...args: unknown[]): Promise<void> | void\n handleLLMError?(...args: unknown[]): Promise<void> | void\n handleChainStart?(...args: unknown[]): Promise<void> | void\n handleChainEnd?(...args: unknown[]): Promise<void> | void\n handleChainError?(...args: unknown[]): Promise<void> | void\n handleToolStart?(...args: unknown[]): Promise<void> | void\n handleToolEnd?(...args: unknown[]): Promise<void> | void\n handleToolError?(...args: unknown[]): Promise<void> | void\n handleAgentAction?(...args: unknown[]): Promise<void> | void\n handleAgentEnd?(...args: unknown[]): Promise<void> | void\n handleText?(...args: unknown[]): Promise<void> | void\n}\n\n// ─── Public types ─────────────────────────────────────────────────────────────\n\nexport interface TokenwatchCallbackHandlerOptions {\n /** Fallback model name when the response does not include it. Defaults to 'unknown'. */\n defaultModel?: string\n /** Tag all calls from this handler with a session ID */\n sessionId?: string\n /** Tag all calls from this handler with a user ID */\n userId?: string\n /** Tag all calls from this handler with a product feature name */\n feature?: string\n}\n\n// ─── Handler ──────────────────────────────────────────────────────────────────\n\n/**\n * LangChain callback handler that automatically tracks LLM cost via tokenwatch.\n *\n * @example\n * import { TokenwatchCallbackHandler } from '@diogonzafe/tokenwatch/langchain'\n *\n * const handler = new TokenwatchCallbackHandler(tracker, { defaultModel: 'gpt-4o' })\n * const llm = new ChatOpenAI({ model: 'gpt-4o', callbacks: [handler] })\n */\nexport class TokenwatchCallbackHandler extends BaseCallbackHandlerStub {\n name = 'TokenwatchCallbackHandler' as const\n\n constructor(\n private readonly tracker: Tracker,\n private readonly options: TokenwatchCallbackHandlerOptions = {},\n ) {\n super()\n }\n\n async handleLLMEnd(output: LLMResult): Promise<void> {\n // Prefer exact tokenUsage, fall back to estimatedTokenUsage (streaming)\n const tokenUsage = output.llmOutput?.tokenUsage ?? output.llmOutput?.estimatedTokenUsage\n\n const inputTokens = tokenUsage?.promptTokens ?? 0\n const outputTokens = tokenUsage?.completionTokens ?? 0\n\n // noUncheckedIndexedAccess: generations[0] is Generation[] | undefined\n const firstGenerations = output.generations[0]\n const firstGen = firstGenerations?.[0]\n const modelFromResponse = firstGen?.message?.response_metadata?.model_name\n const model = modelFromResponse ?? this.options.defaultModel ?? 'unknown'\n\n const { sessionId, userId, feature } = this.options\n\n this.tracker.track({\n model,\n inputTokens,\n outputTokens,\n ...(sessionId !== undefined && { sessionId }),\n ...(userId !== undefined && { userId }),\n ...(feature !== undefined && { feature }),\n })\n }\n}\n"],"mappings":";AAgCA,IAAe,0BAAf,MAAuC;AAcvC;AA0BO,IAAM,4BAAN,cAAwC,wBAAwB;AAAA,EAGrE,YACmB,SACA,UAA4C,CAAC,GAC9D;AACA,UAAM;AAHW;AACA;AAAA,EAGnB;AAAA,EAJmB;AAAA,EACA;AAAA,EAJnB,OAAO;AAAA,EASP,MAAM,aAAa,QAAkC;AAEnD,UAAM,aAAa,OAAO,WAAW,cAAc,OAAO,WAAW;AAErE,UAAM,cAAc,YAAY,gBAAgB;AAChD,UAAM,eAAe,YAAY,oBAAoB;AAGrD,UAAM,mBAAmB,OAAO,YAAY,CAAC;AAC7C,UAAM,WAAW,mBAAmB,CAAC;AACrC,UAAM,oBAAoB,UAAU,SAAS,mBAAmB;AAChE,UAAM,QAAQ,qBAAqB,KAAK,QAAQ,gBAAgB;AAEhE,UAAM,EAAE,WAAW,QAAQ,QAAQ,IAAI,KAAK;AAE5C,SAAK,QAAQ,MAAM;AAAA,MACjB;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAI,cAAc,UAAa,EAAE,UAAU;AAAA,MAC3C,GAAI,WAAW,UAAa,EAAE,OAAO;AAAA,MACrC,GAAI,YAAY,UAAa,EAAE,QAAQ;AAAA,IACzC,CAAC;AAAA,EACH;AACF;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@diogonzafe/tokenwatch",
3
- "version": "0.2.1",
3
+ "version": "0.5.0",
4
4
  "description": "Transparent wrapper to track LLM API costs in real-time by session, user and model",
5
5
  "author": "diogonzafe",
6
6
  "license": "MIT",
@@ -18,6 +18,11 @@
18
18
  "types": "./dist/adapters.d.ts",
19
19
  "import": "./dist/adapters.js",
20
20
  "require": "./dist/adapters.cjs"
21
+ },
22
+ "./langchain": {
23
+ "types": "./dist/langchain.d.ts",
24
+ "import": "./dist/langchain.js",
25
+ "require": "./dist/langchain.cjs"
21
26
  }
22
27
  },
23
28
  "bin": {
@@ -52,7 +57,8 @@
52
57
  "mongodb": ">=6.0.0",
53
58
  "mysql2": ">=3.0.0",
54
59
  "openai": ">=4.68.0",
55
- "pg": ">=8.0.0"
60
+ "pg": ">=8.0.0",
61
+ "@langchain/core": ">=0.1.0"
56
62
  },
57
63
  "peerDependenciesMeta": {
58
64
  "openai": {
@@ -75,6 +81,9 @@
75
81
  },
76
82
  "mongodb": {
77
83
  "optional": true
84
+ },
85
+ "@langchain/core": {
86
+ "optional": true
78
87
  }
79
88
  },
80
89
  "keywords": [