@evalguard/langchain 1.0.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/dist/index.js ADDED
@@ -0,0 +1,592 @@
1
+ /**
2
+ * EvalGuard instrumentation for LangChain + LangGraph.
3
+ *
4
+ * LangChain's instrumentation surface is `@langchain/core/callbacks`. The
5
+ * recommended integration shape is a class that extends `BaseCallbackHandler`
6
+ * and overrides `handleLLMStart` / `handleLLMEnd` (and friends). The same
7
+ * handler works across LangChain.js + LangGraph because LangGraph reuses
8
+ * LangChain's callback dispatching for node-level events.
9
+ *
10
+ * Two usage patterns:
11
+ *
12
+ * // 1. Pass directly to a chain/runnable
13
+ * import { ChatOpenAI } from "@langchain/openai";
14
+ * import { EvalGuardCallbackHandler } from "@evalguard/langchain";
15
+ *
16
+ * const handler = new EvalGuardCallbackHandler({
17
+ * apiKey: process.env.EVALGUARD_API_KEY!,
18
+ * projectId: "proj-123",
19
+ * });
20
+ * const model = new ChatOpenAI({ model: "gpt-4o", callbacks: [handler] });
21
+ *
22
+ * // 2. Or globally via env (auto-installed when present)
23
+ * import { autoInstall } from "@evalguard/langchain";
24
+ * autoInstall(); // reads EVALGUARD_API_KEY + EVALGUARD_PROJECT_ID
25
+ *
26
+ * Implementation notes:
27
+ * - We do NOT depend on `@langchain/core` at install time. The handler
28
+ * extends a duck-typed `BaseCallbackHandler` shape so the package
29
+ * compiles + tests without LangChain present. Customers get full types
30
+ * from their own `@langchain/core` install via TypeScript's module
31
+ * resolution.
32
+ * - Fail-CLOSED semantics match openai-wrapper / anthropic-wrapper /
33
+ * llamaindex-wrapper (changed 2026-05-28): when `blockOnViolation` is
34
+ * on (the default), an UNREACHABLE guardrail blocks the run rather
35
+ * than waving it through. Set `blockOnViolation: false` for
36
+ * monitor-only/availability-first deployments.
37
+ * - `blockOnViolation` raises `EvalguardBlockedError` from `handleLLMStart`,
38
+ * which aborts the run ONLY because this handler sets
39
+ * `raiseError = true` and `awaitHandlers = true` (see the class body).
40
+ * LangChain swallows handler throws by default. The customer catches
41
+ * via `try { await chain.invoke(...) } catch {}`. Verified end-to-end
42
+ * against @langchain/core@1.1.48 through `model.invoke`, `model.stream`
43
+ * and a `RunnableSequence` in
44
+ * `src/__tests__/blocking-enforcement.test.ts` — NOT by inspection.
45
+ * - Because `raiseError = true` makes every throw from this class abort
46
+ * the customer's run, the split is strict: the guardrail path is the
47
+ * ONLY thing allowed to throw. Prompt-extraction failure fails CLOSED
48
+ * (an unscannable prompt is rejected, never silently skipped); model-name
49
+ * resolution degrades to "unknown"; every logging hook is wrapped in
50
+ * `safeLog` so a trace-log failure can never bubble into the chain.
51
+ * - Options that cannot be honoured are rejected in the constructor
52
+ * (`EvalguardConfigError`) rather than accepted and ignored.
53
+ * - **OpenInference compatibility**: every trace emits a `openinference`
54
+ * sidecar with the standard `openinference.span.kind`, `llm.input_messages`,
55
+ * `llm.output_messages`, `llm.model_name`, `llm.token_count.*` attributes.
56
+ * This frees rendering in Phoenix / Arize / any OpenInference-aware viewer.
57
+ * - LangGraph: the same handler emits `chain` + `tool` + `agent` events
58
+ * so node-level activity in a graph shows up as nested spans, mirroring
59
+ * LangSmith's per-node evaluator surface.
60
+ */
61
+ import { GuardrailClient } from "./guardrail-client.js";
62
+ import { collapseMessageText } from "@evalguard/wrapper-core";
63
+ import { estimateCostDetailed } from "./cost.js";
64
+ export class EvalguardBlockedError extends Error {
65
+ violations;
66
+ constructor(message, violations) {
67
+ super(message);
68
+ this.name = "EvalguardBlockedError";
69
+ this.violations = violations;
70
+ }
71
+ }
72
+ /**
73
+ * Thrown from the constructor when the supplied options cannot all be
74
+ * honoured. A security option that the handler is structurally unable to
75
+ * enforce must fail loudly at wiring time — silently accepting it is how
76
+ * a customer ends up believing they are protected when they are not.
77
+ */
78
+ export class EvalguardConfigError extends Error {
79
+ constructor(message) {
80
+ super(message);
81
+ this.name = "EvalguardConfigError";
82
+ }
83
+ }
84
+ /**
85
+ * The handler keeps state per runId so async overlapping calls are tracked
86
+ * correctly. LangChain assigns each LLM/chain/tool invocation a unique runId
87
+ * (UUID) which is passed to every handle* method.
88
+ */
89
+ export class EvalGuardCallbackHandler {
90
+ // BaseCallbackHandler's required `name` property (LangChain uses this to
91
+ // disambiguate handlers in stack traces). Set explicitly so callers
92
+ // adding multiple handlers can debug ordering.
93
+ name = "evalguard-handler";
94
+ // 2026-07-29 (audit A277): `blockOnViolation` was a COMPLETE no-op
95
+ // against real LangChain. `CallbackManager.handleLLMStart` /
96
+ // `handleChatModelStart` invoke each handler inside
97
+ // consumeCallback(async () => { try { await handler.handleLLMStart(...) }
98
+ // catch (err) { (handler.raiseError ? console.error : console.warn)(...);
99
+ // if (handler.raiseError) throw err; } }, handler.awaitHandlers)
100
+ // (@langchain/core@1.1.48 dist/callbacks/manager.js:294-301, :312-323).
101
+ //
102
+ // Because this class is duck-typed rather than extending
103
+ // BaseCallbackHandler, `raiseError` and `awaitHandlers` were both
104
+ // `undefined`, so:
105
+ // 1. awaitHandlers falsy → consumeCallback queued the guardrail check
106
+ // in the background and the LLM call proceeded WITHOUT waiting;
107
+ // 2. raiseError falsy → EvalguardBlockedError was console.warn'd
108
+ // and swallowed, so `chain.invoke()` resolved normally.
109
+ // A blocked prompt reached the model every time.
110
+ //
111
+ // Both flags are read off the handler instance by LangChain, so setting
112
+ // them here is the whole fix. They are declared unconditionally (not
113
+ // `blockOnViolation ? true : false`) because trace correctness also
114
+ // requires the start hook to complete before the LLM call — a
115
+ // background-queued handleLLMStart can lose the race with handleLLMEnd
116
+ // and drop the span.
117
+ awaitHandlers = true;
118
+ raiseError = true;
119
+ client;
120
+ config;
121
+ inflight = new Map();
122
+ blockOnViolation;
123
+ enableLogging;
124
+ enableGuardrails;
125
+ constructor(config) {
126
+ // `disableGuardrails` removes the only code path that can produce a
127
+ // block, so an EXPLICIT `blockOnViolation: true` alongside it can never
128
+ // be honoured. Accepting the pair silently is the same failure mode as
129
+ // the callback no-op this class was fixed for: the customer configures
130
+ // enforcement and gets none. Only the explicit combination is rejected —
131
+ // `disableGuardrails: true` on its own is a valid tracing-only setup.
132
+ if (config.disableGuardrails === true && config.blockOnViolation === true) {
133
+ throw new EvalguardConfigError("EvalGuard: `blockOnViolation: true` cannot be honoured together with " +
134
+ "`disableGuardrails: true` — with the firewall disabled there is nothing " +
135
+ "to block on. Drop one of the two options.");
136
+ }
137
+ this.config = config;
138
+ // wrapper-core's GuardrailClient takes a config object (not positional
139
+ // apiKey/baseUrl) — #40 convergence.
140
+ this.client = new GuardrailClient({ apiKey: config.apiKey, baseUrl: config.baseUrl });
141
+ this.blockOnViolation = config.blockOnViolation ?? true;
142
+ this.enableLogging = !config.disableLogging;
143
+ this.enableGuardrails = !config.disableGuardrails;
144
+ }
145
+ /**
146
+ * Called when an LLM (completion-style) starts. LangChain emits both
147
+ * `handleLLMStart` and `handleChatModelStart` — we cover both so the
148
+ * same handler works across `LLM` and `BaseChatModel` subclasses.
149
+ */
150
+ async handleLLMStart(llm, prompts, runId, _parentRunId, extraParams) {
151
+ const model = this.safeResolveModel(llm, extraParams);
152
+ let prompt;
153
+ try {
154
+ prompt = prompts.join("\n");
155
+ }
156
+ catch (err) {
157
+ return this.onUnreadablePrompt(runId, model, err);
158
+ }
159
+ await this.startRun(runId, prompt, model);
160
+ }
161
+ /**
162
+ * Called when a chat-style LLM (e.g. ChatOpenAI, ChatAnthropic) starts.
163
+ * `messages` is `BaseMessage[][]` — one inner array per parallel
164
+ * generation. We collapse EVERY role into a single prompt for the
165
+ * guardrail check (A287: user-only collapse hid tool results and
166
+ * retrieved documents from the firewall).
167
+ */
168
+ async handleChatModelStart(llm, messages, runId, _parentRunId, extraParams) {
169
+ const model = this.safeResolveModel(llm, extraParams);
170
+ let prompt;
171
+ try {
172
+ prompt = collapseMessages(messages.flat());
173
+ }
174
+ catch (err) {
175
+ return this.onUnreadablePrompt(runId, model, err);
176
+ }
177
+ await this.startRun(runId, prompt, model);
178
+ }
179
+ /**
180
+ * Called when the LLM finishes (success). Emits a trace with latency,
181
+ * token usage, cost, and OpenInference-compliant span attributes.
182
+ */
183
+ async handleLLMEnd(output, runId) {
184
+ const run = this.inflight.get(runId);
185
+ if (!run)
186
+ return;
187
+ this.inflight.delete(runId);
188
+ if (!this.enableLogging)
189
+ return;
190
+ this.safeLog(() => {
191
+ const latencyMs = Math.round(performance.now() - run.startedAt);
192
+ const usage = output.llmOutput?.tokenUsage ?? {};
193
+ const inputTokens = usage.promptTokens ?? 0;
194
+ const outputTokens = usage.completionTokens ?? 0;
195
+ const completion = extractCompletion(output);
196
+ const model = output.llmOutput?.modelName ??
197
+ output.llmOutput?.model_name ??
198
+ output.llmOutput?.model ??
199
+ run.model;
200
+ const { costUsd: cost, pricingSource: costPricingSource } = estimateCostDetailed(model, inputTokens, outputTokens);
201
+ return {
202
+ model,
203
+ provider: "langchain",
204
+ input: run.prompt,
205
+ output: completion,
206
+ latencyMs,
207
+ tokenUsage: { input: inputTokens, output: outputTokens },
208
+ cost,
209
+ costPricingSource,
210
+ projectId: this.config.projectId,
211
+ metadata: this.config.metadata,
212
+ guardrailResult: run.guardrailResult,
213
+ openinference: buildOpenInferenceAttrs({
214
+ kind: "llm",
215
+ model,
216
+ input: run.prompt,
217
+ output: completion,
218
+ promptTokens: inputTokens,
219
+ completionTokens: outputTokens,
220
+ latencyMs,
221
+ }),
222
+ };
223
+ });
224
+ }
225
+ /**
226
+ * Called when the LLM call errors. We still emit a trace so customers
227
+ * can see failed calls in the dashboard (latency + error type + model).
228
+ */
229
+ async handleLLMError(err, runId) {
230
+ const run = this.inflight.get(runId);
231
+ if (!run)
232
+ return;
233
+ this.inflight.delete(runId);
234
+ if (!this.enableLogging)
235
+ return;
236
+ this.safeLog(() => {
237
+ const latencyMs = Math.round(performance.now() - run.startedAt);
238
+ const errorMessage = err instanceof Error ? err.message : String(err ?? "unknown error");
239
+ return {
240
+ model: run.model,
241
+ provider: "langchain",
242
+ input: run.prompt,
243
+ output: null,
244
+ latencyMs,
245
+ tokenUsage: { input: 0, output: 0 },
246
+ cost: 0,
247
+ projectId: this.config.projectId,
248
+ metadata: {
249
+ ...this.config.metadata,
250
+ error: errorMessage,
251
+ errorKind: err instanceof Error ? err.name : "Unknown",
252
+ },
253
+ guardrailResult: run.guardrailResult,
254
+ openinference: buildOpenInferenceAttrs({
255
+ kind: "llm",
256
+ model: run.model,
257
+ input: run.prompt,
258
+ output: null,
259
+ promptTokens: 0,
260
+ completionTokens: 0,
261
+ latencyMs,
262
+ statusCode: "ERROR",
263
+ statusMessage: errorMessage,
264
+ }),
265
+ };
266
+ });
267
+ }
268
+ /**
269
+ * Chain start — covers LangChain Runnables + LangGraph node entry.
270
+ * We log these as nested spans via OpenInference `chain` kind so the
271
+ * trace tree mirrors the customer's actual graph topology.
272
+ */
273
+ async handleChainStart(chain, inputs, runId) {
274
+ if (!this.enableLogging)
275
+ return;
276
+ this.safeLog(() => ({
277
+ model: chain.name ?? "chain",
278
+ provider: "langchain",
279
+ input: inputs,
280
+ output: null,
281
+ latencyMs: 0,
282
+ tokenUsage: { input: 0, output: 0 },
283
+ cost: 0,
284
+ projectId: this.config.projectId,
285
+ metadata: {
286
+ ...this.config.metadata,
287
+ runId,
288
+ spanKind: "chain.start",
289
+ },
290
+ openinference: buildOpenInferenceAttrs({
291
+ kind: "chain",
292
+ model: chain.name ?? "chain",
293
+ input: inputs,
294
+ }),
295
+ }));
296
+ }
297
+ /**
298
+ * Tool execution start (LangGraph node calling a tool). Treated as its
299
+ * own span so trajectory-style assertions can recover the tool-call
300
+ * sequence from the trace.
301
+ */
302
+ async handleToolStart(tool, input, runId) {
303
+ if (!this.enableLogging)
304
+ return;
305
+ this.safeLog(() => ({
306
+ model: tool.name ?? "tool",
307
+ provider: "langchain",
308
+ input,
309
+ output: null,
310
+ latencyMs: 0,
311
+ tokenUsage: { input: 0, output: 0 },
312
+ cost: 0,
313
+ projectId: this.config.projectId,
314
+ metadata: {
315
+ ...this.config.metadata,
316
+ runId,
317
+ spanKind: "tool.start",
318
+ toolName: tool.name,
319
+ },
320
+ openinference: buildOpenInferenceAttrs({
321
+ kind: "tool",
322
+ model: tool.name ?? "tool",
323
+ input,
324
+ }),
325
+ }));
326
+ }
327
+ /**
328
+ * Agent action (LangChain agents + LangGraph). Captures the decided
329
+ * action so trajectory-grading metrics can score whether the action
330
+ * was the right next step.
331
+ */
332
+ async handleAgentAction(action, runId) {
333
+ if (!this.enableLogging)
334
+ return;
335
+ this.safeLog(() => ({
336
+ model: action.tool,
337
+ provider: "langchain",
338
+ input: action.toolInput,
339
+ output: action.log ?? null,
340
+ latencyMs: 0,
341
+ tokenUsage: { input: 0, output: 0 },
342
+ cost: 0,
343
+ projectId: this.config.projectId,
344
+ metadata: {
345
+ ...this.config.metadata,
346
+ runId,
347
+ spanKind: "agent.action",
348
+ decidedTool: action.tool,
349
+ },
350
+ openinference: buildOpenInferenceAttrs({
351
+ kind: "agent",
352
+ model: action.tool,
353
+ input: action.toolInput,
354
+ output: action.log ?? null,
355
+ }),
356
+ }));
357
+ }
358
+ /** Shared startup path for both `handleLLMStart` and `handleChatModelStart`. */
359
+ async startRun(runId, prompt, model) {
360
+ const startedAt = performance.now();
361
+ const run = { startedAt, prompt, model };
362
+ if (this.enableGuardrails && prompt) {
363
+ try {
364
+ const result = await this.client.checkInput(prompt, {
365
+ provider: "langchain",
366
+ model,
367
+ ...this.config.metadata,
368
+ });
369
+ run.guardrailResult = result;
370
+ if (!result.allowed && this.blockOnViolation) {
371
+ // Throwing here aborts the LangChain run. Customers catch via
372
+ // `try { await chain.invoke(...) } catch (err) { ... }`.
373
+ throw new EvalguardBlockedError(`Request blocked by EvalGuard guardrails: ${result.violations
374
+ .map((v) => v.type)
375
+ .join(", ")}`, result.violations);
376
+ }
377
+ }
378
+ catch (err) {
379
+ if (err instanceof EvalguardBlockedError)
380
+ throw err;
381
+ // 2026-05-28: previously silently fell through ("fail-open") on
382
+ // any guardrail outage — defeats blockOnViolation:true callers
383
+ // who expect fail-CLOSED. Per check.txt audit P1 fix, an
384
+ // unreachable guardrail now blocks the run when blockOnViolation
385
+ // is on; otherwise fall through to keep availability.
386
+ if (this.blockOnViolation) {
387
+ throw new EvalguardBlockedError(`Request blocked: guardrail unavailable (${err instanceof Error ? err.message : "unknown"})`, [{
388
+ type: "guardrail_unavailable",
389
+ severity: "high",
390
+ message: err instanceof Error ? err.message : "guardrail check failed",
391
+ }]);
392
+ }
393
+ }
394
+ }
395
+ this.inflight.set(runId, run);
396
+ }
397
+ /**
398
+ * Model name is trace METADATA, not a security input. A failure to
399
+ * resolve it must never abort the customer's run and must never skip the
400
+ * firewall — degrade to "unknown" and carry on to the scan.
401
+ */
402
+ safeResolveModel(llm, extraParams) {
403
+ try {
404
+ return this.resolveModel(llm, extraParams);
405
+ }
406
+ catch {
407
+ return "unknown";
408
+ }
409
+ }
410
+ /**
411
+ * The prompt could not be read, so the firewall cannot see the bytes that
412
+ * are about to reach the model. Silently returning here (what this handler
413
+ * did until 2026-07-30) skipped the scan entirely and let the call through
414
+ * unguarded — a total bypass for any customer using a message class whose
415
+ * `_getType()`/content accessor throws.
416
+ *
417
+ * Fail CLOSED instead, with an explicit `prompt_unreadable` marker so the
418
+ * trace records that nothing was scanned. Note this is a REJECTION, not a
419
+ * shortened/partial scan: never hand the scanner less than the real input.
420
+ */
421
+ async onUnreadablePrompt(runId, model, err) {
422
+ const detail = err instanceof Error ? err.message : String(err ?? "unknown error");
423
+ const violations = [
424
+ {
425
+ type: "prompt_unreadable",
426
+ severity: "high",
427
+ message: `EvalGuard could not extract the prompt for scanning: ${detail}`,
428
+ },
429
+ ];
430
+ if (this.enableGuardrails && this.blockOnViolation) {
431
+ throw new EvalguardBlockedError(`Request blocked: EvalGuard could not read the prompt to scan it (${detail})`, violations);
432
+ }
433
+ // Monitor-only / guardrails-off: the call proceeds, but the trace must
434
+ // still say the input was never scanned.
435
+ this.inflight.set(runId, {
436
+ startedAt: performance.now(),
437
+ prompt: "",
438
+ model,
439
+ guardrailResult: { allowed: true, violations },
440
+ });
441
+ }
442
+ /**
443
+ * Fire-and-forget trace logging that can NEVER throw into the customer's
444
+ * chain. This class sets `raiseError = true` so LangChain propagates our
445
+ * throws — that is required for a guardrail block to actually block, but
446
+ * it also means an incidental failure in a logging-only hook would abort a
447
+ * perfectly good LLM call. The published contract (README, "Outage
448
+ * semantics") is that a trace-log failure never bubbles into your chain;
449
+ * this is where that contract is enforced.
450
+ *
451
+ * `GuardrailClient.logTrace` already resolves to null on transport failure
452
+ * (wrapper-core `withRetry`), so this guards the synchronous payload
453
+ * construction and any future rejection path.
454
+ */
455
+ safeLog(build) {
456
+ try {
457
+ void this.client.logTrace(build()).catch(() => {
458
+ /* trace logging never affects the customer's run */
459
+ });
460
+ }
461
+ catch {
462
+ /* trace logging never affects the customer's run */
463
+ }
464
+ }
465
+ resolveModel(llm, extraParams) {
466
+ // Best-effort model resolution across LangChain's varying serialized
467
+ // shapes. Order matters: kwargs.model is the most specific (set by
468
+ // ChatOpenAI/ChatAnthropic constructor), then extraParams.invocation_
469
+ // params.model (set on call), then the serialized id chain.
470
+ const kwModel = llm.kwargs?.["model"];
471
+ if (kwModel)
472
+ return kwModel;
473
+ const kwModelName = llm.kwargs?.["modelName"];
474
+ if (kwModelName)
475
+ return kwModelName;
476
+ const invParams = extraParams?.["invocation_params"];
477
+ const invModel = invParams?.["model"];
478
+ if (invModel)
479
+ return invModel;
480
+ if (llm.id && llm.id.length > 0)
481
+ return llm.id[llm.id.length - 1] ?? "unknown";
482
+ return llm.name ?? "unknown";
483
+ }
484
+ }
485
+ /**
486
+ * Auto-install path for the lazy customer. Reads EVALGUARD_API_KEY from env.
487
+ * Returns the handler instance if installed; null if EVALGUARD_API_KEY is
488
+ * not set (no-op safe to call at module load).
489
+ *
490
+ * Usage:
491
+ *
492
+ * import { autoInstall } from "@evalguard/langchain";
493
+ * autoInstall();
494
+ *
495
+ * Then pass the returned handler to a Runnable's `callbacks` array, OR set
496
+ * the global LangChain callbacks via `setGlobalCallbacks([handler])` from
497
+ * `@langchain/core/callbacks/manager`.
498
+ */
499
+ export function autoInstall() {
500
+ const apiKey = process.env["EVALGUARD_API_KEY"];
501
+ if (!apiKey)
502
+ return null;
503
+ return new EvalGuardCallbackHandler({
504
+ apiKey,
505
+ projectId: process.env["EVALGUARD_PROJECT_ID"],
506
+ baseUrl: process.env["EVALGUARD_BASE_URL"],
507
+ });
508
+ }
509
+ // ── Helpers ─────────────────────────────────────────────────────────────────
510
+ /**
511
+ * 2026-07-29 (audit A287): this used to `.filter(type === "human"|"user")`
512
+ * before handing text to the firewall, so `ToolMessage` results and
513
+ * retrieved RAG documents (which arrive as `tool`/`function`/`system`
514
+ * messages) were never scanned — the exact channels an agent-app attacker
515
+ * controls. It now delegates to wrapper-core's canonical
516
+ * `collapseMessageText`, which scans every role and is shared with the
517
+ * llamaindex and vercel-ai wrappers so the three copies cannot drift again.
518
+ *
519
+ * LangChain BaseMessages expose their role via `_getType()` rather than a
520
+ * `role` field, so normalize that here before delegating.
521
+ */
522
+ function collapseMessages(messages) {
523
+ if (!messages || messages.length === 0)
524
+ return "";
525
+ const normalized = messages.map((m) => ({
526
+ role: typeof m._getType === "function" ? m._getType() : m.type,
527
+ content: m.content,
528
+ }));
529
+ return collapseMessageText(normalized);
530
+ }
531
+ function extractCompletion(output) {
532
+ const firstGeneration = output.generations[0]?.[0];
533
+ if (!firstGeneration)
534
+ return "";
535
+ if (firstGeneration.message?.content)
536
+ return firstGeneration.message.content;
537
+ return firstGeneration.text ?? "";
538
+ }
539
+ /**
540
+ * Build OpenInference-compliant span attributes. OpenInference is the
541
+ * tracing semantic convention authored by Arize and adopted across the
542
+ * industry (Phoenix, Arize AX, OpenLLMetry). Emitting these attributes
543
+ * lets EvalGuard traces render natively in any OpenInference-aware
544
+ * viewer without conversion.
545
+ *
546
+ * Spec: https://github.com/Arize-ai/openinference/tree/main/spec
547
+ */
548
+ function buildOpenInferenceAttrs(args) {
549
+ const attrs = {
550
+ "openinference.span.kind": args.kind.toUpperCase(),
551
+ "llm.model_name": args.model,
552
+ "input.value": stringifyForAttr(args.input),
553
+ };
554
+ if (args.output !== undefined) {
555
+ attrs["output.value"] = stringifyForAttr(args.output);
556
+ }
557
+ if (args.promptTokens != null) {
558
+ attrs["llm.token_count.prompt"] = args.promptTokens;
559
+ }
560
+ if (args.completionTokens != null) {
561
+ attrs["llm.token_count.completion"] = args.completionTokens;
562
+ }
563
+ if (args.promptTokens != null && args.completionTokens != null) {
564
+ attrs["llm.token_count.total"] = args.promptTokens + args.completionTokens;
565
+ }
566
+ if (args.statusCode)
567
+ attrs["status.code"] = args.statusCode;
568
+ if (args.statusMessage)
569
+ attrs["status.message"] = args.statusMessage;
570
+ return attrs;
571
+ }
572
+ function stringifyForAttr(value) {
573
+ if (value == null)
574
+ return "";
575
+ if (typeof value === "string")
576
+ return value;
577
+ try {
578
+ return JSON.stringify(value);
579
+ }
580
+ catch {
581
+ return String(value);
582
+ }
583
+ }
584
+ // ── Cost estimation (public surface) ────────────────────────────────────────
585
+ // The README's "Cost estimates" section tells the customer to
586
+ // `import { estimateCostDetailed, isModelPriced } from "@evalguard/langchain"`.
587
+ // Until 2026-08-01 these lived only in `./cost.ts`, which is NOT an `exports`
588
+ // subpath, so that documented import resolved to nothing from the published
589
+ // tarball. The three SDK-shaped wrappers (openai / anthropic / gemini) already
590
+ // re-exported them; the three framework-shaped ones did not.
591
+ export { estimateCost, estimateCostDetailed, isModelPriced } from "./cost.js";
592
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}