UNPKG

@traceprompt/node

Version:

Client-side encrypted, audit-ready logging for LLM applications

67 lines (55 loc) 2.14 kB
import { performance } from "node:perf_hooks"; import { initTracePrompt as initCfgAsync, ConfigManager } from "./config"; import { encryptBuffer } from "./crypto/encryptor"; import { computeLeaf } from "./crypto/hasher"; import { countTokens } from "./utils/tokenCounter"; import { PersistentBatcher as Batcher } from "./queue/persistentBatcher"; const stringify = require("json-stable-stringify") as (v: any) => string; import type { TracePromptInit, WrapOpts } from "./types"; import { registry } from "./metrics"; import { Histogram } from "prom-client"; const wrapperLatencyHist = new Histogram({ name: "traceprompt_llm_wrapper_latency_ms", help: "End‑to‑end latency from prompt send to response receive in the SDK wrapper (ms)", buckets: [50, 100, 250, 500, 1000, 2000, 5000], registers: [registry], }); export async function initTracePrompt( cfg?: Partial<TracePromptInit> ): Promise<void> { await initCfgAsync(cfg); } export function wrapLLM<P extends Record<string, any>, R>( originalFn: (prompt: string, params?: P) => Promise<R>, meta: WrapOpts ): (prompt: string, params?: P) => Promise<R> { const staticMeta = ConfigManager.cfg.staticMeta; return async function wrapped(prompt: string, params?: P): Promise<R> { const t0 = performance.now(); const result = await originalFn(prompt, params); const t1 = performance.now(); wrapperLatencyHist.observe(t1 - t0); const plaintextJson = JSON.stringify({ prompt, response: result, }); const enc = await encryptBuffer(Buffer.from(plaintextJson, "utf8")); const payload = { ...staticMeta, orgId: ConfigManager.cfg.orgId, modelVendor: meta.modelVendor, modelName: meta.modelName, userId: meta.userId, ts_client: new Date().toISOString(), latency_ms: +(t1 - t0).toFixed(2), prompt_tokens: countTokens(prompt), response_tokens: countTokens( typeof result === "string" ? result : JSON.stringify(result) ), enc, }; const leafHash = computeLeaf(stringify(payload)); Batcher.enqueue({ payload, leafHash }); return result; }; }