| |
| |
| |
| |
| |
| |
| |
| |
| |
| import { createHash } from "node:crypto"; |
| import type { Logger } from "pino"; |
| import { newId } from "../../ids.ts"; |
| import type { KnowledgeKind } from "./types.ts"; |
|
|
| export interface TelemetryRecord { |
| adapter: KnowledgeKind; |
| capabilityId: string | null; |
| latencyMs: number; |
| hitCount: number; |
| cacheHit: "hit" | "miss" | null; |
| error: string | null; |
| paramsFingerprint: string | null; |
| } |
|
|
| type TestHook = (rec: TelemetryRecord) => void; |
| let _testHook: TestHook | null = null; |
|
|
| |
| export function _setTelemetryTestHook(hook: TestHook | null): void { |
| _testHook = hook; |
| } |
|
|
| export function fingerprintParams(params: Record<string, unknown>): string { |
| |
| const sortedKeys = Object.keys(params).sort(); |
| const stable = sortedKeys.reduce<Record<string, unknown>>((acc, k) => { |
| acc[k] = params[k]; |
| return acc; |
| }, {}); |
| return createHash("sha1").update(JSON.stringify(stable)).digest("hex"); |
| } |
|
|
| export async function recordCall(rec: TelemetryRecord): Promise<void> { |
| if (_testHook) { |
| try { |
| _testHook(rec); |
| } catch { |
| |
| } |
| return; |
| } |
| |
| let db: typeof import("@workspace/db").db | undefined; |
| let capabilityExternalKnowledgeCalls: |
| | typeof import("@workspace/db").capabilityExternalKnowledgeCalls |
| | undefined; |
| let logger: Logger | undefined; |
| try { |
| const dbMod = await import("@workspace/db"); |
| db = dbMod.db; |
| capabilityExternalKnowledgeCalls = dbMod.capabilityExternalKnowledgeCalls; |
| } catch { |
| |
| } |
| try { |
| const loggerMod = await import("../../logger.ts"); |
| logger = loggerMod.logger; |
| } catch { |
| |
| } |
| if (db && capabilityExternalKnowledgeCalls) { |
| try { |
| await db.insert(capabilityExternalKnowledgeCalls).values({ |
| id: newId("cek"), |
| adapter: rec.adapter, |
| capabilityId: rec.capabilityId, |
| latencyMs: rec.latencyMs, |
| hitCount: rec.hitCount, |
| cacheHit: rec.cacheHit, |
| error: rec.error, |
| paramsFingerprint: rec.paramsFingerprint, |
| }); |
| return; |
| } catch (err) { |
| logger?.debug?.( |
| { err, rec }, |
| "capability_external_knowledge_calls insert failed (non-blocking)", |
| ); |
| } |
| } |
| |
| logger?.info?.({ rec }, "[external-knowledge] call (no-db fallback log)"); |
| } |
|
|