/** * LangSmith's run export, read as a usage log. * * The fifth converter in the pattern `from-claude-code` started: a pure * function turns one tool's export into Trazum's usage-log records, and every * door prices it from there. LangSmith is the tracing product most LangChain * teams already run, so the export exists before Trazum does. * * **The format is derived, not guessed.** Every field below is `RunBase` and * `Run` in `python/langsmith/schemas.py` in langchain-ai/langsmith-sdk. A * converter written from memory of an API is a converter that silently * mis-reads somebody's bill. * * ## A run is not a call, and that is the whole difficulty * * LangSmith records a **run**, and a trace is a tree of them: chains, tools and * retrievers alongside the model calls. Only `run_type: "llm"` carries token * counts, and summing the tree would count the same tokens once per level. So * everything else is skipped and **counted out loud** — a converter that * quietly dropped two thirds of a file would look like one that read it. * * ## The model, and why it is refused rather than inferred * * There is no model column. The name lives in `extra.metadata.ls_model_name`, * or in the invocation parameters the SDK records beside it, and a run whose * metadata carries neither cannot be priced. The obvious guess is the run's * own `name` — LangChain names them after the class, `ChatOpenAI`, which is a * client and not a model. Pricing a call by the class that made it would be a * figure attributed to something it does not describe, which is the fault this * repository keeps finding in itself. Such a run is counted in `unnamedModel` * and dropped. * * ## What deliberately does not cross * * `inputs` and `outputs` are the prompt and the completion, on every single * run. **Neither is read.** `extra.metadata` is read for two named keys and * nothing else, because it is a free-form bag the operator fills and the next * thing they put in it might be a credential. The converter names the fields * it takes and takes nothing else, and a fixture plants a marker in each and * greps the whole output. * * ## What it refuses to invent * * There is no cache-token split. `prompt_cost_details` looks like one and is * not: it is LangSmith's own priced breakdown in dollars, computed from * LangSmith's price table. It never enters a record, and neither does * `total_cost` — `reportedCostUsd` returns it on its own, the way * `from-litellm` keeps the gateway's arithmetic apart from Trazum's. Two price * tables, two figures; merging them is how a report becomes quietly wrong. */ /** One converted record, shaped exactly as `parseUsageLine` reads it. */ export interface LangsmithRecord { model: string; ts?: string; label?: string; session?: string; usage: { input_tokens: number; output_tokens: number; }; } export interface LangsmithConversion { records: LangsmithRecord[]; /** Runs that were model calls and converted. */ rows: number; /** * Runs that were not model calls: chains, tools, retrievers, prompts. * * Counted rather than ignored. They are most of a LangSmith export, and a * reader who converted a thousand runs into three hundred records is owed * the reason. */ notModelCalls: number; /** Model calls whose metadata named no model: counted, never guessed. */ unnamedModel: number; /** Model calls carrying no token counts at all. */ noTokens: number; /** * LangSmith's own cost total, in dollars, or null when no run reported one. * * Kept apart from anything Trazum computes and never merged into a record. * Null is an absence, not a total of nothing. */ reportedCostUsd: number | null; /** Lines or documents that did not parse as JSON at all. */ unparseable: number; } /** * Convert a LangSmith run export. * * Accepts a JSON array of runs, a single run, `{ runs: [...] }` as the list * endpoint returns it, or newline-delimited runs. Pure over its input. */ export declare function langsmithRecords(text: string): LangsmithConversion; /** * Whether a file looks like a LangSmith run export, by shape. * * Deliberately narrow: `run_type` beside one of the trace fields only * LangSmith writes. A looser test would claim a Helicone export or a LiteLLM * spend log — both carry `prompt_tokens` — and refuse it in this file's words * instead of letting the code that can read it try. */ export declare function looksLikeLangsmith(text: string, prefixBytes?: number): boolean; //# sourceMappingURL=langsmith.d.ts.map