@cendor/core 0.3.2 → 0.4.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.
- package/LICENSE +201 -201
- package/NOTICE +7 -0
- package/README.md +2 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/langchain.d.ts +60 -0
- package/dist/langchain.d.ts.map +1 -0
- package/dist/langchain.js +345 -0
- package/dist/langchain.js.map +1 -0
- package/package.json +19 -2
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Optional LangChain.js / LangGraph integration — the SDK-aligned way to observe a framework.
|
|
3
|
+
*
|
|
4
|
+
* The SDK-aligned integration point for a framework is its **callback system**, not client
|
|
5
|
+
* monkeypatching: `@langchain/openai` consumes usage through its own response path and streams via
|
|
6
|
+
* async iterators, so `instrument()` on the raw client can miss usage — observing through callbacks
|
|
7
|
+
* sidesteps that. {@link CendorCallbackHandler} reads LangChain's own `usage_metadata` (which carries
|
|
8
|
+
* **reasoning** and **cached** token breakdowns), prices the call offline, correlates multi-node /
|
|
9
|
+
* multi-agent runs via `traceId`, and emits normalized {@link LLMCall} / {@link ToolCall} events on
|
|
10
|
+
* the bus — so `tokenguard`, `acttrace`, and any other subscriber see LangChain activity with no
|
|
11
|
+
* client touch.
|
|
12
|
+
*
|
|
13
|
+
* **Recording-only.** This path is post-call: it *observes*, it never enforces. `tokenguard`'s caps
|
|
14
|
+
* and `acttrace`'s `guard()` act on the `instrument()` seam, which the callback path does not touch —
|
|
15
|
+
* so pre-flight enforcement (budget blocking, redact-before-send) is a **no-op** here. Use the direct
|
|
16
|
+
* provider SDK with `instrument()` when you need enforcement.
|
|
17
|
+
*
|
|
18
|
+
* Requires the optional peer dependency, keeping `@cendor/core` dependency-light (like
|
|
19
|
+
* `@opentelemetry/api`). Importing this subpath without `@langchain/core` installed throws a clear
|
|
20
|
+
* error.
|
|
21
|
+
*
|
|
22
|
+
* npm install @langchain/core
|
|
23
|
+
*
|
|
24
|
+
* Usage:
|
|
25
|
+
*
|
|
26
|
+
* ```ts
|
|
27
|
+
* import { CendorCallbackHandler } from '@cendor/core/langchain';
|
|
28
|
+
* const handler = new CendorCallbackHandler();
|
|
29
|
+
*
|
|
30
|
+
* const llm = new ChatOpenAI({ model: 'gpt-4o', callbacks: [handler] }); // every call recorded
|
|
31
|
+
* await llm.invoke('hi');
|
|
32
|
+
*
|
|
33
|
+
* // or per-call / per-agent — propagates to all LangGraph nodes, correlated by root run:
|
|
34
|
+
* await agent.invoke({ messages: [...] }, { callbacks: [handler] });
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
import { createRequire } from 'node:module';
|
|
38
|
+
import * as bus from './bus.js';
|
|
39
|
+
import * as prices from './prices.js';
|
|
40
|
+
import { LLMCall, ToolCall, Usage } from './types.js';
|
|
41
|
+
/**
|
|
42
|
+
* Load LangChain's `BaseCallbackHandler` synchronously so this class can extend it, mirroring the
|
|
43
|
+
* Python handler's import-time `ImportError` when the optional dependency is absent. LangChain
|
|
44
|
+
* accepts handlers by duck-typing (`copy`/`name`/`awaitHandlers`), so the CJS build resolved here
|
|
45
|
+
* interoperates with an ESM-imported `@langchain/core` in the host app.
|
|
46
|
+
*/
|
|
47
|
+
function loadBaseCallbackHandler() {
|
|
48
|
+
try {
|
|
49
|
+
const req = createRequire(import.meta.url);
|
|
50
|
+
const mod = req('@langchain/core/callbacks/base');
|
|
51
|
+
return mod.BaseCallbackHandler;
|
|
52
|
+
}
|
|
53
|
+
catch (cause) {
|
|
54
|
+
throw new Error('@cendor/core/langchain requires @langchain/core. Install it with: npm install @langchain/core', { cause });
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
const BaseCallbackHandler = loadBaseCallbackHandler();
|
|
58
|
+
/**
|
|
59
|
+
* A LangChain / LangGraph callback handler that records usage, reasoning, tool calls, and run
|
|
60
|
+
* correlation onto cendor's bus. **Recording-only** — never enforces (see the module docstring).
|
|
61
|
+
*
|
|
62
|
+
* Attach it globally (`new ChatOpenAI({ callbacks: [new CendorCallbackHandler()] })`), per call
|
|
63
|
+
* (`{ callbacks: [handler] }`), or on an agent (`agent.invoke(..., { callbacks: [handler] })`) — for
|
|
64
|
+
* LangGraph it propagates to every node and its tools.
|
|
65
|
+
*
|
|
66
|
+
* **Correlation.** Every emitted event carries a `traceId` that is the **root run id** of the
|
|
67
|
+
* invocation — resolved by tracking the callback run tree (each run's `parentRunId`) and walking to
|
|
68
|
+
* the top. So all model/tool calls of one `agent.invoke` (across its nodes and the react loop) share
|
|
69
|
+
* one `traceId`, while separate invocations get distinct ones. A standalone `llm.invoke` uses its own
|
|
70
|
+
* run id. This is a correlation *hook*, not an orchestrator: cendor groups by the framework's own run
|
|
71
|
+
* tree; it invents no run graph.
|
|
72
|
+
*
|
|
73
|
+
* Every handler body is exception-safe (a recorder must never break the app); `raiseError` is left
|
|
74
|
+
* `false` (the base default) so LangChain also swallows any escape.
|
|
75
|
+
*/
|
|
76
|
+
export class CendorCallbackHandler extends BaseCallbackHandler {
|
|
77
|
+
name = 'CendorCallbackHandler';
|
|
78
|
+
// runId -> parentRunId (or null for a root), built from the *Start callbacks so each event can be
|
|
79
|
+
// resolved to the root run it belongs to. Bounded: entries are removed on run end/error.
|
|
80
|
+
parents = new Map();
|
|
81
|
+
// tool runId -> pending { name, input }, bridged from handleToolStart to handleToolEnd.
|
|
82
|
+
toolRuns = new Map();
|
|
83
|
+
// Node is single-threaded, so — unlike the Python handler — there is no lock guarding the maps.
|
|
84
|
+
/**
|
|
85
|
+
* Share one handler instance across merged callback managers instead of copying. A stateful
|
|
86
|
+
* correlation handler must observe the *whole* run tree; the base `copy()` returns a fresh clone
|
|
87
|
+
* with empty maps, which would break trace-id resolution. Sharing is safe here: every handler body
|
|
88
|
+
* is exception-safe and the map operations are idempotent, and returning the same identity also
|
|
89
|
+
* lets LangChain's identity-based handler de-duplication work.
|
|
90
|
+
*/
|
|
91
|
+
copy() {
|
|
92
|
+
return this;
|
|
93
|
+
}
|
|
94
|
+
// ------------------------------------------------------------------ run-tree bookkeeping
|
|
95
|
+
register(runId, parentRunId) {
|
|
96
|
+
if (!runId)
|
|
97
|
+
return;
|
|
98
|
+
this.parents.set(runId, parentRunId ?? null);
|
|
99
|
+
}
|
|
100
|
+
forget(runId) {
|
|
101
|
+
if (!runId)
|
|
102
|
+
return;
|
|
103
|
+
this.parents.delete(runId);
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* The root run id for this event: walk `parent` links up to the top. Falls back to
|
|
107
|
+
* `parentRunId`/`runId` when the run tree wasn't observed (e.g. a bare model call).
|
|
108
|
+
*/
|
|
109
|
+
traceId(runId, parentRunId) {
|
|
110
|
+
let rid = runId ?? '';
|
|
111
|
+
if (!rid)
|
|
112
|
+
return parentRunId ?? '';
|
|
113
|
+
const seen = new Set();
|
|
114
|
+
while (this.parents.has(rid) && this.parents.get(rid) && !seen.has(rid)) {
|
|
115
|
+
seen.add(rid);
|
|
116
|
+
rid = this.parents.get(rid); // guarded truthy above
|
|
117
|
+
}
|
|
118
|
+
return rid;
|
|
119
|
+
}
|
|
120
|
+
handleChainStart(_chain, _inputs, runId, _runType, _tags, _metadata, _runName, parentRunId) {
|
|
121
|
+
this.register(runId, parentRunId);
|
|
122
|
+
}
|
|
123
|
+
handleChainEnd(_outputs, runId) {
|
|
124
|
+
this.forget(runId);
|
|
125
|
+
}
|
|
126
|
+
handleChainError(_err, runId) {
|
|
127
|
+
this.forget(runId);
|
|
128
|
+
}
|
|
129
|
+
handleChatModelStart(_llm, _messages, runId, parentRunId) {
|
|
130
|
+
this.register(runId, parentRunId);
|
|
131
|
+
}
|
|
132
|
+
handleLLMStart(_llm, _prompts, runId, parentRunId) {
|
|
133
|
+
this.register(runId, parentRunId);
|
|
134
|
+
}
|
|
135
|
+
// ------------------------------------------------------------------ LLM calls
|
|
136
|
+
/** Emit an {@link LLMCall} with usage/reasoning/cost and a run-correlated `traceId`. */
|
|
137
|
+
handleLLMEnd(output, runId, parentRunId) {
|
|
138
|
+
try {
|
|
139
|
+
const usage = usageFromResult(output);
|
|
140
|
+
const call = new LLMCall({
|
|
141
|
+
id: uuidHex(),
|
|
142
|
+
provider: 'langchain', // observed via the framework; the real model rides call.model
|
|
143
|
+
model: modelFromResult(output),
|
|
144
|
+
messages: [], // the callback path is usage-focused; prompts aren't recorded here
|
|
145
|
+
usage,
|
|
146
|
+
traceId: this.traceId(runId, parentRunId),
|
|
147
|
+
});
|
|
148
|
+
call.metadata.source = 'langchain';
|
|
149
|
+
setCost(call, usage);
|
|
150
|
+
bus.emit(call);
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
// recording must never break the app
|
|
154
|
+
}
|
|
155
|
+
finally {
|
|
156
|
+
this.forget(runId);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
/** Record a failed model call (no usage) with the error on metadata — never re-raised. */
|
|
160
|
+
handleLLMError(err, runId, parentRunId) {
|
|
161
|
+
try {
|
|
162
|
+
const call = new LLMCall({
|
|
163
|
+
id: uuidHex(),
|
|
164
|
+
provider: 'langchain',
|
|
165
|
+
model: '',
|
|
166
|
+
messages: [],
|
|
167
|
+
traceId: this.traceId(runId, parentRunId),
|
|
168
|
+
});
|
|
169
|
+
call.metadata.source = 'langchain';
|
|
170
|
+
call.metadata.error = errorMessage(err);
|
|
171
|
+
bus.emit(call);
|
|
172
|
+
}
|
|
173
|
+
catch {
|
|
174
|
+
// recording must never break the app
|
|
175
|
+
}
|
|
176
|
+
finally {
|
|
177
|
+
this.forget(runId);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
// ------------------------------------------------------------------ tool calls
|
|
181
|
+
/** Record the tool's parent (for correlation) and stash its name/args until it ends. */
|
|
182
|
+
handleToolStart(tool, input, runId, parentRunId) {
|
|
183
|
+
this.register(runId, parentRunId);
|
|
184
|
+
try {
|
|
185
|
+
this.toolRuns.set(runId, { name: serializedName(tool) ?? 'tool', input });
|
|
186
|
+
}
|
|
187
|
+
catch {
|
|
188
|
+
// recording must never break the app
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
/** Emit a {@link ToolCall} (name, args, result) correlated to its run's root. */
|
|
192
|
+
handleToolEnd(output, runId, parentRunId) {
|
|
193
|
+
try {
|
|
194
|
+
const pending = this.toolRuns.get(runId);
|
|
195
|
+
this.toolRuns.delete(runId);
|
|
196
|
+
const tc = new ToolCall({
|
|
197
|
+
id: uuidHex(),
|
|
198
|
+
name: pending?.name ?? 'tool',
|
|
199
|
+
arguments: { input: pending?.input },
|
|
200
|
+
result: output,
|
|
201
|
+
traceId: this.traceId(runId, parentRunId),
|
|
202
|
+
});
|
|
203
|
+
tc.metadata.source = 'langchain';
|
|
204
|
+
bus.emit(tc);
|
|
205
|
+
}
|
|
206
|
+
catch {
|
|
207
|
+
// recording must never break the app
|
|
208
|
+
}
|
|
209
|
+
finally {
|
|
210
|
+
this.forget(runId);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
/** Emit a {@link ToolCall} marking the failure; drop the pending entry. Never re-raised. */
|
|
214
|
+
handleToolError(err, runId, parentRunId) {
|
|
215
|
+
try {
|
|
216
|
+
const pending = this.toolRuns.get(runId);
|
|
217
|
+
this.toolRuns.delete(runId);
|
|
218
|
+
const tc = new ToolCall({
|
|
219
|
+
id: uuidHex(),
|
|
220
|
+
name: pending?.name ?? 'tool',
|
|
221
|
+
arguments: { input: pending?.input },
|
|
222
|
+
traceId: this.traceId(runId, parentRunId),
|
|
223
|
+
});
|
|
224
|
+
tc.metadata.source = 'langchain';
|
|
225
|
+
tc.metadata.error = errorMessage(err);
|
|
226
|
+
bus.emit(tc);
|
|
227
|
+
}
|
|
228
|
+
catch {
|
|
229
|
+
// recording must never break the app
|
|
230
|
+
}
|
|
231
|
+
finally {
|
|
232
|
+
this.forget(runId);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
// --------------------------------------------------------------------------- extraction helpers
|
|
237
|
+
/** A hex UUID (no dashes), mirroring the ids `instrument()` stamps. */
|
|
238
|
+
function uuidHex() {
|
|
239
|
+
return globalThis.crypto.randomUUID().replace(/-/g, '');
|
|
240
|
+
}
|
|
241
|
+
function num(value) {
|
|
242
|
+
if (typeof value === 'number')
|
|
243
|
+
return Number.isFinite(value) ? value : 0;
|
|
244
|
+
if (typeof value === 'string') {
|
|
245
|
+
const n = Number.parseInt(value, 10);
|
|
246
|
+
return Number.isNaN(n) ? 0 : n;
|
|
247
|
+
}
|
|
248
|
+
return 0;
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Recover usage from an `LLMResult`: prefer a generation message's `usage_metadata` (it carries
|
|
252
|
+
* reasoning + cache breakdowns), falling back to `llmOutput`'s token usage.
|
|
253
|
+
*/
|
|
254
|
+
function usageFromResult(result) {
|
|
255
|
+
for (const gens of result.generations ?? []) {
|
|
256
|
+
for (const gen of gens) {
|
|
257
|
+
const meta = gen.message?.usage_metadata;
|
|
258
|
+
if (meta)
|
|
259
|
+
return usageFromMetadata(meta);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
const llmOutput = (result.llmOutput ?? {});
|
|
263
|
+
const tokenUsage = (llmOutput.tokenUsage ?? llmOutput.token_usage ?? llmOutput.usage);
|
|
264
|
+
if (tokenUsage) {
|
|
265
|
+
const inp = num(tokenUsage.promptTokens ?? tokenUsage.prompt_tokens ?? tokenUsage.input_tokens);
|
|
266
|
+
const out = num(tokenUsage.completionTokens ?? tokenUsage.completion_tokens ?? tokenUsage.output_tokens);
|
|
267
|
+
const cdetails = (tokenUsage.completion_tokens_details ??
|
|
268
|
+
tokenUsage.completionTokensDetails ??
|
|
269
|
+
{});
|
|
270
|
+
const reasoning = num(cdetails.reasoning_tokens ?? cdetails.reasoningTokens);
|
|
271
|
+
const pdetails = (tokenUsage.prompt_tokens_details ??
|
|
272
|
+
tokenUsage.promptTokensDetails ??
|
|
273
|
+
{});
|
|
274
|
+
const cached = num(pdetails.cached_tokens ?? pdetails.cachedTokens);
|
|
275
|
+
return new Usage({
|
|
276
|
+
inputTokens: inp,
|
|
277
|
+
outputTokens: out,
|
|
278
|
+
cachedTokens: cached,
|
|
279
|
+
reasoningTokens: reasoning,
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
return null;
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Map LangChain's `usage_metadata` to {@link Usage}. LangChain already reports `input_tokens`
|
|
286
|
+
* *including* the cached read (`cached ⊆ input`, the same convention cendor normalizes to), so no
|
|
287
|
+
* folding is needed. Reasoning is under `output_token_details.reasoning`; cache read/creation under
|
|
288
|
+
* `input_token_details`.
|
|
289
|
+
*/
|
|
290
|
+
function usageFromMetadata(meta) {
|
|
291
|
+
return new Usage({
|
|
292
|
+
inputTokens: num(meta.input_tokens),
|
|
293
|
+
outputTokens: num(meta.output_tokens),
|
|
294
|
+
cachedTokens: num(meta.input_token_details?.cache_read),
|
|
295
|
+
reasoningTokens: num(meta.output_token_details?.reasoning),
|
|
296
|
+
cacheWrite: num(meta.input_token_details?.cache_creation),
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
/** Read the model id from `llmOutput` or a generation message's `response_metadata`. */
|
|
300
|
+
function modelFromResult(result) {
|
|
301
|
+
const llmOutput = (result.llmOutput ?? {});
|
|
302
|
+
const direct = llmOutput.model_name ?? llmOutput.modelName ?? llmOutput.model;
|
|
303
|
+
if (direct)
|
|
304
|
+
return String(direct);
|
|
305
|
+
for (const gens of result.generations ?? []) {
|
|
306
|
+
for (const gen of gens) {
|
|
307
|
+
const meta = gen.message?.response_metadata ?? {};
|
|
308
|
+
const m = meta.model_name ?? meta.model;
|
|
309
|
+
if (m)
|
|
310
|
+
return String(m);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
return '';
|
|
314
|
+
}
|
|
315
|
+
/** Price the call offline from the bundled snapshot; unknown model ⇒ `cost` stays `null`. */
|
|
316
|
+
function setCost(call, usage) {
|
|
317
|
+
if (usage === null)
|
|
318
|
+
return;
|
|
319
|
+
try {
|
|
320
|
+
call.cost = prices.estimate(call.model, usage.inputTokens, {
|
|
321
|
+
outputTokens: usage.outputTokens,
|
|
322
|
+
cachedTokens: usage.cachedTokens,
|
|
323
|
+
cacheWriteTokens: usage.cacheWrite,
|
|
324
|
+
});
|
|
325
|
+
call.metadata.cost_estimated = true;
|
|
326
|
+
}
|
|
327
|
+
catch (err) {
|
|
328
|
+
if (err instanceof prices.UnknownModelError) {
|
|
329
|
+
call.cost = null;
|
|
330
|
+
}
|
|
331
|
+
else {
|
|
332
|
+
throw err;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
/** LangChain's serialized tool descriptor carries a `name`; default when absent. */
|
|
337
|
+
function serializedName(tool) {
|
|
338
|
+
const name = tool?.name;
|
|
339
|
+
return typeof name === 'string' ? name : undefined;
|
|
340
|
+
}
|
|
341
|
+
/** The message of an error, mirroring Python's `str(exc)`. */
|
|
342
|
+
function errorMessage(err) {
|
|
343
|
+
return err instanceof Error ? err.message : String(err);
|
|
344
|
+
}
|
|
345
|
+
//# sourceMappingURL=langchain.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"langchain.js","sourceRoot":"","sources":["../src/langchain.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cendor/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Wrap your LLM client once and capture exact token counts and cost on every call — the shared foundation the other Cendor tools build on.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -10,11 +10,17 @@
|
|
|
10
10
|
".": {
|
|
11
11
|
"types": "./dist/index.d.ts",
|
|
12
12
|
"default": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./langchain": {
|
|
15
|
+
"types": "./dist/langchain.d.ts",
|
|
16
|
+
"default": "./dist/langchain.js"
|
|
13
17
|
}
|
|
14
18
|
},
|
|
15
19
|
"files": [
|
|
16
20
|
"dist",
|
|
17
|
-
"README.md"
|
|
21
|
+
"README.md",
|
|
22
|
+
"LICENSE",
|
|
23
|
+
"NOTICE"
|
|
18
24
|
],
|
|
19
25
|
"sideEffects": false,
|
|
20
26
|
"engines": {
|
|
@@ -25,9 +31,13 @@
|
|
|
25
31
|
"js-tiktoken": "^1.0.15"
|
|
26
32
|
},
|
|
27
33
|
"peerDependencies": {
|
|
34
|
+
"@langchain/core": ">=0.3",
|
|
28
35
|
"@opentelemetry/api": ">=1"
|
|
29
36
|
},
|
|
30
37
|
"peerDependenciesMeta": {
|
|
38
|
+
"@langchain/core": {
|
|
39
|
+
"optional": true
|
|
40
|
+
},
|
|
31
41
|
"@opentelemetry/api": {
|
|
32
42
|
"optional": true
|
|
33
43
|
}
|
|
@@ -46,7 +56,14 @@
|
|
|
46
56
|
"url": "git+https://github.com/cendorhq/cendor-libs-js.git",
|
|
47
57
|
"directory": "packages/core"
|
|
48
58
|
},
|
|
59
|
+
"homepage": "https://cendor.ai/docs/core",
|
|
60
|
+
"bugs": {
|
|
61
|
+
"url": "https://github.com/cendorhq/cendor-libs-js/issues"
|
|
62
|
+
},
|
|
49
63
|
"publishConfig": {
|
|
50
64
|
"access": "public"
|
|
65
|
+
},
|
|
66
|
+
"devDependencies": {
|
|
67
|
+
"@langchain/core": "^1.2.1"
|
|
51
68
|
}
|
|
52
69
|
}
|