@seanhogg/builderforce-memory 2026.7.14 → 2026.9.28
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/README.md +10 -0
- package/dist/bridges/AnthropicBridge.d.ts +9 -1
- package/dist/bridges/AnthropicBridge.d.ts.map +1 -1
- package/dist/bridges/AnthropicBridge.js +58 -2
- package/dist/bridges/AnthropicBridge.js.map +1 -1
- package/dist/bridges/CachingBridge.d.ts +9 -1
- package/dist/bridges/CachingBridge.d.ts.map +1 -1
- package/dist/bridges/CachingBridge.js +24 -1
- package/dist/bridges/CachingBridge.js.map +1 -1
- package/dist/bridges/OpenAIBridge.d.ts +4 -1
- package/dist/bridges/OpenAIBridge.d.ts.map +1 -1
- package/dist/bridges/OpenAIBridge.js +40 -2
- package/dist/bridges/OpenAIBridge.js.map +1 -1
- package/dist/bridges/SemanticCachingBridge.d.ts +8 -1
- package/dist/bridges/SemanticCachingBridge.d.ts.map +1 -1
- package/dist/bridges/SemanticCachingBridge.js +26 -1
- package/dist/bridges/SemanticCachingBridge.js.map +1 -1
- package/dist/bridges/TransformerBridge.d.ts +13 -0
- package/dist/bridges/TransformerBridge.d.ts.map +1 -1
- package/dist/bridges/VertexAIBridge.d.ts +102 -0
- package/dist/bridges/VertexAIBridge.d.ts.map +1 -0
- package/dist/bridges/VertexAIBridge.js +224 -0
- package/dist/bridges/VertexAIBridge.js.map +1 -0
- package/dist/bridges/index.d.ts +3 -1
- package/dist/bridges/index.d.ts.map +1 -1
- package/dist/bridges/index.js +1 -0
- package/dist/bridges/index.js.map +1 -1
- package/dist/eval/EvalHarness.d.ts +37 -0
- package/dist/eval/EvalHarness.d.ts.map +1 -0
- package/dist/eval/EvalHarness.js +178 -0
- package/dist/eval/EvalHarness.js.map +1 -0
- package/dist/eval/graders.d.ts +76 -0
- package/dist/eval/graders.d.ts.map +1 -0
- package/dist/eval/graders.js +168 -0
- package/dist/eval/graders.js.map +1 -0
- package/dist/eval/index.d.ts +26 -0
- package/dist/eval/index.d.ts.map +1 -0
- package/dist/eval/index.js +26 -0
- package/dist/eval/index.js.map +1 -0
- package/dist/eval/types.d.ts +97 -0
- package/dist/eval/types.d.ts.map +1 -0
- package/dist/eval/types.js +5 -0
- package/dist/eval/types.js.map +1 -0
- package/dist/evermind/contract.d.ts +40 -0
- package/dist/evermind/contract.d.ts.map +1 -0
- package/dist/evermind/contract.js +13 -0
- package/dist/evermind/contract.js.map +1 -0
- package/dist/evermind/index.d.ts +15 -0
- package/dist/evermind/index.d.ts.map +1 -0
- package/dist/evermind/index.js +4 -0
- package/dist/evermind/index.js.map +1 -0
- package/dist/evermind/memoryBlock.d.ts +7 -0
- package/dist/evermind/memoryBlock.d.ts.map +1 -0
- package/dist/evermind/memoryBlock.js +37 -0
- package/dist/evermind/memoryBlock.js.map +1 -0
- package/dist/evermind/recall.d.ts +48 -0
- package/dist/evermind/recall.d.ts.map +1 -0
- package/dist/evermind/recall.js +105 -0
- package/dist/evermind/recall.js.map +1 -0
- package/dist/index.d.ts +18 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -1
- package/dist/index.js.map +1 -1
- package/dist/ingest/IngestionPipeline.d.ts +95 -0
- package/dist/ingest/IngestionPipeline.d.ts.map +1 -0
- package/dist/ingest/IngestionPipeline.js +295 -0
- package/dist/ingest/IngestionPipeline.js.map +1 -0
- package/dist/ingest/index.d.ts +10 -0
- package/dist/ingest/index.d.ts.map +1 -0
- package/dist/ingest/index.js +8 -0
- package/dist/ingest/index.js.map +1 -0
- package/dist/ingest/parsers.d.ts +53 -0
- package/dist/ingest/parsers.d.ts.map +1 -0
- package/dist/ingest/parsers.js +306 -0
- package/dist/ingest/parsers.js.map +1 -0
- package/dist/ingest/types.d.ts +114 -0
- package/dist/ingest/types.d.ts.map +1 -0
- package/dist/ingest/types.js +19 -0
- package/dist/ingest/types.js.map +1 -0
- package/dist/memory/MemoryStore.d.ts +33 -0
- package/dist/memory/MemoryStore.d.ts.map +1 -1
- package/dist/memory/MemoryStore.js +29 -3
- package/dist/memory/MemoryStore.js.map +1 -1
- package/dist/memory/index.d.ts +1 -1
- package/dist/memory/index.d.ts.map +1 -1
- package/dist/orchestration/AgentGraph.d.ts +104 -0
- package/dist/orchestration/AgentGraph.d.ts.map +1 -0
- package/dist/orchestration/AgentGraph.js +364 -0
- package/dist/orchestration/AgentGraph.js.map +1 -0
- package/dist/orchestration/checkpoint.d.ts +58 -0
- package/dist/orchestration/checkpoint.d.ts.map +1 -0
- package/dist/orchestration/checkpoint.js +92 -0
- package/dist/orchestration/checkpoint.js.map +1 -0
- package/dist/orchestration/index.d.ts +14 -0
- package/dist/orchestration/index.d.ts.map +1 -0
- package/dist/orchestration/index.js +10 -0
- package/dist/orchestration/index.js.map +1 -0
- package/dist/orchestration/patterns.d.ts +159 -0
- package/dist/orchestration/patterns.d.ts.map +1 -0
- package/dist/orchestration/patterns.js +371 -0
- package/dist/orchestration/patterns.js.map +1 -0
- package/dist/orchestration/types.d.ts +146 -0
- package/dist/orchestration/types.d.ts.map +1 -0
- package/dist/orchestration/types.js +20 -0
- package/dist/orchestration/types.js.map +1 -0
- package/dist/rag/EnterpriseRetriever.d.ts +114 -0
- package/dist/rag/EnterpriseRetriever.d.ts.map +1 -0
- package/dist/rag/EnterpriseRetriever.js +240 -0
- package/dist/rag/EnterpriseRetriever.js.map +1 -0
- package/dist/rag/index.d.ts +6 -0
- package/dist/rag/index.d.ts.map +1 -0
- package/dist/rag/index.js +5 -0
- package/dist/rag/index.js.map +1 -0
- package/dist/retrieval/bm25.d.ts +48 -1
- package/dist/retrieval/bm25.d.ts.map +1 -1
- package/dist/retrieval/bm25.js +59 -13
- package/dist/retrieval/bm25.js.map +1 -1
- package/dist/retrieval/index.d.ts +2 -2
- package/dist/retrieval/index.d.ts.map +1 -1
- package/dist/retrieval/index.js +1 -1
- package/dist/retrieval/index.js.map +1 -1
- package/dist/runtime/SSMRuntime.d.ts +1 -1
- package/dist/runtime/SSMRuntime.d.ts.map +1 -1
- package/dist/telemetry/InstrumentedBridge.d.ts +62 -0
- package/dist/telemetry/InstrumentedBridge.d.ts.map +1 -0
- package/dist/telemetry/InstrumentedBridge.js +120 -0
- package/dist/telemetry/InstrumentedBridge.js.map +1 -0
- package/dist/telemetry/MetricsRegistry.d.ts +88 -0
- package/dist/telemetry/MetricsRegistry.d.ts.map +1 -0
- package/dist/telemetry/MetricsRegistry.js +167 -0
- package/dist/telemetry/MetricsRegistry.js.map +1 -0
- package/dist/telemetry/Tracer.d.ts +137 -0
- package/dist/telemetry/Tracer.d.ts.map +1 -0
- package/dist/telemetry/Tracer.js +244 -0
- package/dist/telemetry/Tracer.js.map +1 -0
- package/dist/telemetry/exporters.d.ts +68 -0
- package/dist/telemetry/exporters.d.ts.map +1 -0
- package/dist/telemetry/exporters.js +145 -0
- package/dist/telemetry/exporters.js.map +1 -0
- package/dist/telemetry/index.d.ts +19 -0
- package/dist/telemetry/index.d.ts.map +1 -0
- package/dist/telemetry/index.js +12 -0
- package/dist/telemetry/index.js.map +1 -0
- package/dist/telemetry/pricing.d.ts +74 -0
- package/dist/telemetry/pricing.d.ts.map +1 -0
- package/dist/telemetry/pricing.js +98 -0
- package/dist/telemetry/pricing.js.map +1 -0
- package/dist/telemetry/traceparent.d.ts +50 -0
- package/dist/telemetry/traceparent.d.ts.map +1 -0
- package/dist/telemetry/traceparent.js +77 -0
- package/dist/telemetry/traceparent.js.map +1 -0
- package/dist/telemetry/types.d.ts +90 -0
- package/dist/telemetry/types.d.ts.map +1 -0
- package/dist/telemetry/types.js +17 -0
- package/dist/telemetry/types.js.map +1 -0
- package/dist/vectorstore/MemoryVectorStore.d.ts +72 -0
- package/dist/vectorstore/MemoryVectorStore.d.ts.map +1 -0
- package/dist/vectorstore/MemoryVectorStore.js +205 -0
- package/dist/vectorstore/MemoryVectorStore.js.map +1 -0
- package/dist/vectorstore/RestVectorStore.d.ts +79 -0
- package/dist/vectorstore/RestVectorStore.d.ts.map +1 -0
- package/dist/vectorstore/RestVectorStore.js +170 -0
- package/dist/vectorstore/RestVectorStore.js.map +1 -0
- package/dist/vectorstore/dialects.d.ts +101 -0
- package/dist/vectorstore/dialects.d.ts.map +1 -0
- package/dist/vectorstore/dialects.js +618 -0
- package/dist/vectorstore/dialects.js.map +1 -0
- package/dist/vectorstore/filter.d.ts +42 -0
- package/dist/vectorstore/filter.d.ts.map +1 -0
- package/dist/vectorstore/filter.js +132 -0
- package/dist/vectorstore/filter.js.map +1 -0
- package/dist/vectorstore/index.d.ts +15 -0
- package/dist/vectorstore/index.d.ts.map +1 -0
- package/dist/vectorstore/index.js +11 -0
- package/dist/vectorstore/index.js.map +1 -0
- package/dist/vectorstore/types.d.ts +151 -0
- package/dist/vectorstore/types.d.ts.map +1 -0
- package/dist/vectorstore/types.js +30 -0
- package/dist/vectorstore/types.js.map +1 -0
- package/package.json +39 -5
- package/src/bridges/AnthropicBridge.ts +68 -3
- package/src/bridges/CachingBridge.ts +28 -2
- package/src/bridges/OpenAIBridge.ts +48 -3
- package/src/bridges/SemanticCachingBridge.ts +29 -2
- package/src/bridges/TransformerBridge.ts +16 -0
- package/src/bridges/VertexAIBridge.ts +297 -0
- package/src/bridges/index.ts +3 -1
- package/src/eval/EvalHarness.ts +214 -0
- package/src/eval/graders.ts +218 -0
- package/src/eval/index.ts +26 -0
- package/src/eval/types.ts +107 -0
- package/src/evermind/contract.ts +39 -0
- package/src/evermind/index.ts +18 -0
- package/src/evermind/memoryBlock.ts +38 -0
- package/src/evermind/recall.ts +122 -0
- package/src/index.ts +232 -0
- package/src/ingest/IngestionPipeline.ts +378 -0
- package/src/ingest/index.ts +46 -0
- package/src/ingest/parsers.ts +318 -0
- package/src/ingest/types.ts +116 -0
- package/src/memory/MemoryStore.ts +55 -3
- package/src/memory/index.ts +1 -1
- package/src/orchestration/AgentGraph.ts +462 -0
- package/src/orchestration/checkpoint.ts +129 -0
- package/src/orchestration/index.ts +63 -0
- package/src/orchestration/patterns.ts +532 -0
- package/src/orchestration/types.ts +128 -0
- package/src/rag/EnterpriseRetriever.ts +348 -0
- package/src/rag/index.ts +18 -0
- package/src/retrieval/bm25.ts +71 -13
- package/src/retrieval/index.ts +2 -2
- package/src/telemetry/InstrumentedBridge.ts +152 -0
- package/src/telemetry/MetricsRegistry.ts +263 -0
- package/src/telemetry/Tracer.ts +310 -0
- package/src/telemetry/exporters.ts +187 -0
- package/src/telemetry/index.ts +56 -0
- package/src/telemetry/pricing.ts +129 -0
- package/src/telemetry/traceparent.ts +89 -0
- package/src/telemetry/types.ts +105 -0
- package/src/vectorstore/MemoryVectorStore.ts +250 -0
- package/src/vectorstore/RestVectorStore.ts +236 -0
- package/src/vectorstore/dialects.ts +702 -0
- package/src/vectorstore/filter.ts +148 -0
- package/src/vectorstore/index.ts +53 -0
- package/src/vectorstore/types.ts +149 -0
|
@@ -156,7 +156,7 @@ export declare class SSMRuntime {
|
|
|
156
156
|
* Escape hatch to the underlying MambaSession internals.
|
|
157
157
|
* Use sparingly — the SSMRuntime API covers the common cases.
|
|
158
158
|
*/
|
|
159
|
-
get internals(): import("../
|
|
159
|
+
get internals(): import("../index.js").SessionInternals;
|
|
160
160
|
/**
|
|
161
161
|
* Destroys the underlying MambaSession and releases all GPU resources.
|
|
162
162
|
* After calling this, all methods throw SSMError('RUNTIME_DESTROYED').
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SSMRuntime.d.ts","sourceRoot":"","sources":["../../src/runtime/SSMRuntime.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"SSMRuntime.d.ts","sourceRoot":"","sources":["../../src/runtime/SSMRuntime.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* telemetry/InstrumentedBridge.ts — one decorator that makes ANY bridge observable.
|
|
3
|
+
*
|
|
4
|
+
* The alternative — instrumenting Anthropic, OpenAI, Vertex, Fetch, Caching and
|
|
5
|
+
* SemanticCaching bridges each in their own way — guarantees six subtly different
|
|
6
|
+
* definitions of "a call". This is a single decorator over the
|
|
7
|
+
* {@link TransformerBridge} port, so a bridge added tomorrow is observable the
|
|
8
|
+
* moment it satisfies the interface, and the caching bridges are measured at the
|
|
9
|
+
* same seam as the provider bridges (which is how the cache-hit rate becomes a
|
|
10
|
+
* real number rather than an anecdote).
|
|
11
|
+
*
|
|
12
|
+
* Token counts come from the provider when the inner bridge reports them via
|
|
13
|
+
* `lastCall`, and are estimated from characters otherwise — with `estimated: true`
|
|
14
|
+
* carried through to the metric snapshot so a dashboard never mixes measured and
|
|
15
|
+
* inferred spend without saying so.
|
|
16
|
+
*/
|
|
17
|
+
import type { TransformerBridge, BridgeGenerateOptions } from '../bridges/TransformerBridge.js';
|
|
18
|
+
import { Tracer, type Span } from './Tracer.js';
|
|
19
|
+
import type { LlmUsage } from './types.js';
|
|
20
|
+
export interface InstrumentedBridgeOptions {
|
|
21
|
+
/** Tracer that receives the spans. */
|
|
22
|
+
tracer: Tracer;
|
|
23
|
+
/** Model label used when the inner bridge reports none. Default `'unknown'`. */
|
|
24
|
+
model?: string;
|
|
25
|
+
/** Span name. Default `'llm.generate'`. */
|
|
26
|
+
spanName?: string;
|
|
27
|
+
/**
|
|
28
|
+
* Parent span, so a model call nests under the agent/graph node that made it.
|
|
29
|
+
* A function is accepted for the common case where the parent changes per call.
|
|
30
|
+
*/
|
|
31
|
+
parent?: Span | (() => Span | undefined);
|
|
32
|
+
/** Static attributes stamped on every span (tenant, environment, route). */
|
|
33
|
+
attributes?: Record<string, string | number | boolean>;
|
|
34
|
+
/**
|
|
35
|
+
* Token counter, when an exact one is available (e.g. the provider's
|
|
36
|
+
* count_tokens endpoint). Default: ~4 chars per token.
|
|
37
|
+
*/
|
|
38
|
+
countTokens?: (text: string) => number;
|
|
39
|
+
}
|
|
40
|
+
export declare class InstrumentedBridge implements TransformerBridge {
|
|
41
|
+
readonly supportsStreaming: boolean;
|
|
42
|
+
private readonly _inner;
|
|
43
|
+
private readonly _tracer;
|
|
44
|
+
private readonly _model;
|
|
45
|
+
private readonly _spanName;
|
|
46
|
+
private readonly _parent?;
|
|
47
|
+
private readonly _attributes;
|
|
48
|
+
private readonly _count;
|
|
49
|
+
private _lastCall;
|
|
50
|
+
constructor(inner: TransformerBridge, opts: InstrumentedBridgeOptions);
|
|
51
|
+
/** Usage/cache info for the most recent call — makes the decorator chainable. */
|
|
52
|
+
get lastCall(): {
|
|
53
|
+
usage?: LlmUsage;
|
|
54
|
+
cacheHit?: boolean;
|
|
55
|
+
cacheTier?: string;
|
|
56
|
+
} | undefined;
|
|
57
|
+
generate(prompt: string, opts?: BridgeGenerateOptions): Promise<string>;
|
|
58
|
+
stream(prompt: string, opts?: BridgeGenerateOptions): AsyncIterable<string>;
|
|
59
|
+
private _startSpan;
|
|
60
|
+
private _finish;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=InstrumentedBridge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InstrumentedBridge.d.ts","sourceRoot":"","sources":["../../src/telemetry/InstrumentedBridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AAEhG,OAAO,EAAE,MAAM,EAAE,KAAK,IAAI,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,MAAM,WAAW,yBAAyB;IACtC,sCAAsC;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,gFAAgF;IAChF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,MAAM,CAAC,EAAE,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,SAAS,CAAC,CAAC;IACzC,4EAA4E;IAC5E,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;IACvD;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;CAC1C;AAED,qBAAa,kBAAmB,YAAW,iBAAiB;IACxD,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAC;IAEpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoB;IAC3C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAkC;IAC3D,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA4C;IACxE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA2B;IAElD,OAAO,CAAC,SAAS,CAA2E;gBAEhF,KAAK,EAAE,iBAAiB,EAAE,IAAI,EAAE,yBAAyB;IAWrE,iFAAiF;IACjF,IAAI,QAAQ,IAAI;QAAE,KAAK,CAAC,EAAE,QAAQ,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAEvF;IAEK,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,qBAA0B,GAAG,OAAO,CAAC,MAAM,CAAC;IAa1E,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,qBAA0B,GAAG,aAAa,CAAC,MAAM,CAAC;IAwBtF,OAAO,CAAC,UAAU;IAiBlB,OAAO,CAAC,OAAO;CAyBlB"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* telemetry/InstrumentedBridge.ts — one decorator that makes ANY bridge observable.
|
|
3
|
+
*
|
|
4
|
+
* The alternative — instrumenting Anthropic, OpenAI, Vertex, Fetch, Caching and
|
|
5
|
+
* SemanticCaching bridges each in their own way — guarantees six subtly different
|
|
6
|
+
* definitions of "a call". This is a single decorator over the
|
|
7
|
+
* {@link TransformerBridge} port, so a bridge added tomorrow is observable the
|
|
8
|
+
* moment it satisfies the interface, and the caching bridges are measured at the
|
|
9
|
+
* same seam as the provider bridges (which is how the cache-hit rate becomes a
|
|
10
|
+
* real number rather than an anecdote).
|
|
11
|
+
*
|
|
12
|
+
* Token counts come from the provider when the inner bridge reports them via
|
|
13
|
+
* `lastCall`, and are estimated from characters otherwise — with `estimated: true`
|
|
14
|
+
* carried through to the metric snapshot so a dashboard never mixes measured and
|
|
15
|
+
* inferred spend without saying so.
|
|
16
|
+
*/
|
|
17
|
+
import { estimateTokens } from './pricing.js';
|
|
18
|
+
export class InstrumentedBridge {
|
|
19
|
+
supportsStreaming;
|
|
20
|
+
_inner;
|
|
21
|
+
_tracer;
|
|
22
|
+
_model;
|
|
23
|
+
_spanName;
|
|
24
|
+
_parent;
|
|
25
|
+
_attributes;
|
|
26
|
+
_count;
|
|
27
|
+
_lastCall;
|
|
28
|
+
constructor(inner, opts) {
|
|
29
|
+
this._inner = inner;
|
|
30
|
+
this._tracer = opts.tracer;
|
|
31
|
+
this._model = opts.model ?? 'unknown';
|
|
32
|
+
this._spanName = opts.spanName ?? 'llm.generate';
|
|
33
|
+
if (opts.parent)
|
|
34
|
+
this._parent = opts.parent;
|
|
35
|
+
this._attributes = opts.attributes ?? {};
|
|
36
|
+
this._count = opts.countTokens ?? estimateTokens;
|
|
37
|
+
this.supportsStreaming = inner.supportsStreaming;
|
|
38
|
+
}
|
|
39
|
+
/** Usage/cache info for the most recent call — makes the decorator chainable. */
|
|
40
|
+
get lastCall() {
|
|
41
|
+
return this._lastCall;
|
|
42
|
+
}
|
|
43
|
+
async generate(prompt, opts = {}) {
|
|
44
|
+
const span = this._startSpan(prompt, opts, false);
|
|
45
|
+
try {
|
|
46
|
+
const reply = await this._inner.generate(prompt, opts);
|
|
47
|
+
this._finish(span, prompt, reply, opts);
|
|
48
|
+
span.end('ok');
|
|
49
|
+
return reply;
|
|
50
|
+
}
|
|
51
|
+
catch (err) {
|
|
52
|
+
span.fail(err);
|
|
53
|
+
throw err;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
async *stream(prompt, opts = {}) {
|
|
57
|
+
if (!this._inner.stream) {
|
|
58
|
+
throw new Error('InstrumentedBridge: the wrapped bridge does not support streaming.');
|
|
59
|
+
}
|
|
60
|
+
const span = this._startSpan(prompt, opts, true);
|
|
61
|
+
let reply = '';
|
|
62
|
+
let first = true;
|
|
63
|
+
try {
|
|
64
|
+
for await (const chunk of this._inner.stream(prompt, opts)) {
|
|
65
|
+
if (first) {
|
|
66
|
+
span.recordFirstToken();
|
|
67
|
+
first = false;
|
|
68
|
+
}
|
|
69
|
+
reply += chunk;
|
|
70
|
+
yield chunk;
|
|
71
|
+
}
|
|
72
|
+
this._finish(span, prompt, reply, opts);
|
|
73
|
+
span.end('ok');
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
span.fail(err);
|
|
77
|
+
throw err;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
_startSpan(prompt, opts, streaming) {
|
|
81
|
+
const parent = typeof this._parent === 'function' ? this._parent() : this._parent;
|
|
82
|
+
const span = this._tracer.startSpan(this._spanName, {
|
|
83
|
+
kind: 'llm',
|
|
84
|
+
...(parent ? { parent } : {}),
|
|
85
|
+
});
|
|
86
|
+
span.setAttributes({
|
|
87
|
+
...this._attributes,
|
|
88
|
+
'llm.model': opts.model ?? this._model,
|
|
89
|
+
'llm.streaming': streaming,
|
|
90
|
+
'llm.prompt_chars': prompt.length,
|
|
91
|
+
'llm.max_tokens': opts.maxTokens,
|
|
92
|
+
'llm.temperature': opts.temperature,
|
|
93
|
+
});
|
|
94
|
+
return span;
|
|
95
|
+
}
|
|
96
|
+
_finish(span, prompt, reply, opts) {
|
|
97
|
+
const reported = this._inner.lastCall;
|
|
98
|
+
const model = reported?.usage?.model ?? opts.model ?? this._model;
|
|
99
|
+
const usage = reported?.usage ?? {
|
|
100
|
+
model,
|
|
101
|
+
inputTokens: this._count(prompt),
|
|
102
|
+
outputTokens: this._count(reply),
|
|
103
|
+
estimated: true,
|
|
104
|
+
};
|
|
105
|
+
if (reported?.cacheHit)
|
|
106
|
+
usage.localCacheHit = true;
|
|
107
|
+
span.recordUsage(usage);
|
|
108
|
+
span.setAttributes({
|
|
109
|
+
'llm.response_chars': reply.length,
|
|
110
|
+
'llm.cache_hit': reported?.cacheHit ?? false,
|
|
111
|
+
'llm.cache_tier': reported?.cacheTier,
|
|
112
|
+
});
|
|
113
|
+
this._lastCall = {
|
|
114
|
+
usage,
|
|
115
|
+
...(reported?.cacheHit !== undefined ? { cacheHit: reported.cacheHit } : {}),
|
|
116
|
+
...(reported?.cacheTier !== undefined ? { cacheTier: reported.cacheTier } : {}),
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=InstrumentedBridge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InstrumentedBridge.js","sourceRoot":"","sources":["../../src/telemetry/InstrumentedBridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAyB9C,MAAM,OAAO,kBAAkB;IAClB,iBAAiB,CAAU;IAEnB,MAAM,CAAoB;IAC1B,OAAO,CAAS;IAChB,MAAM,CAAS;IACf,SAAS,CAAS;IAClB,OAAO,CAAmC;IAC1C,WAAW,CAA4C;IACvD,MAAM,CAA2B;IAE1C,SAAS,CAA2E;IAE5F,YAAY,KAAwB,EAAE,IAA+B;QACjE,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC;QAC3B,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,IAAI,SAAS,CAAC;QACtC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,QAAQ,IAAI,cAAc,CAAC;QACjD,IAAI,IAAI,CAAC,MAAM;YAAE,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC;QAC5C,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,UAAU,IAAI,EAAE,CAAC;QACzC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,WAAW,IAAI,cAAc,CAAC;QACjD,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC,iBAAiB,CAAC;IACrD,CAAC;IAED,iFAAiF;IACjF,IAAI,QAAQ;QACR,OAAO,IAAI,CAAC,SAAS,CAAC;IAC1B,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,MAAc,EAAE,OAA8B,EAAE;QAC3D,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;QAClD,IAAI,CAAC;YACD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;YACvD,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;YACxC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACf,OAAO,KAAK,CAAC;QACjB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACf,MAAM,GAAG,CAAC;QACd,CAAC;IACL,CAAC;IAED,KAAK,CAAC,CAAC,MAAM,CAAC,MAAc,EAAE,OAA8B,EAAE;QAC1D,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,oEAAoE,CAAC,CAAC;QAC1F,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QACjD,IAAI,KAAK,GAAG,EAAE,CAAC;QACf,IAAI,KAAK,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC;YACD,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC;gBACzD,IAAI,KAAK,EAAE,CAAC;oBACR,IAAI,CAAC,gBAAgB,EAAE,CAAC;oBACxB,KAAK,GAAG,KAAK,CAAC;gBAClB,CAAC;gBACD,KAAK,IAAI,KAAK,CAAC;gBACf,MAAM,KAAK,CAAC;YAChB,CAAC;YACD,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;YACxC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACnB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACf,MAAM,GAAG,CAAC;QACd,CAAC;IACL,CAAC;IAEO,UAAU,CAAC,MAAc,EAAE,IAA2B,EAAE,SAAkB;QAC9E,MAAM,MAAM,GAAG,OAAO,IAAI,CAAC,OAAO,KAAK,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC;QAClF,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,EAAE;YAChD,IAAI,EAAE,KAAK;YACX,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAChC,CAAC,CAAC;QACH,IAAI,CAAC,aAAa,CAAC;YACf,GAAG,IAAI,CAAC,WAAW;YACnB,WAAW,EAAE,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM;YACtC,eAAe,EAAE,SAAS;YAC1B,kBAAkB,EAAE,MAAM,CAAC,MAAM;YACjC,gBAAgB,EAAE,IAAI,CAAC,SAAS;YAChC,iBAAiB,EAAE,IAAI,CAAC,WAAW;SACtC,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IAChB,CAAC;IAEO,OAAO,CAAC,IAAU,EAAE,MAAc,EAAE,KAAa,EAAE,IAA2B;QAClF,MAAM,QAAQ,GAAI,IAAI,CAAC,MAAsF,CAAC,QAAQ,CAAC;QACvH,MAAM,KAAK,GAAG,QAAQ,EAAE,KAAK,EAAE,KAAK,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC;QAElE,MAAM,KAAK,GAAa,QAAQ,EAAE,KAAK,IAAI;YACvC,KAAK;YACL,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;YAChC,YAAY,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;YAChC,SAAS,EAAE,IAAI;SAClB,CAAC;QACF,IAAI,QAAQ,EAAE,QAAQ;YAAE,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC;QAEnD,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QACxB,IAAI,CAAC,aAAa,CAAC;YACf,oBAAoB,EAAE,KAAK,CAAC,MAAM;YAClC,eAAe,EAAE,QAAQ,EAAE,QAAQ,IAAI,KAAK;YAC5C,gBAAgB,EAAE,QAAQ,EAAE,SAAS;SACxC,CAAC,CAAC;QAEH,IAAI,CAAC,SAAS,GAAG;YACb,KAAK;YACL,GAAG,CAAC,QAAQ,EAAE,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC5E,GAAG,CAAC,QAAQ,EAAE,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAClF,CAAC;IACN,CAAC;CACJ"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* telemetry/MetricsRegistry.ts — LLM-native metrics, aggregated from spans.
|
|
3
|
+
*
|
|
4
|
+
* The registry is itself a {@link SpanExporter}. That is the DRY move: every
|
|
5
|
+
* subsystem already emits spans for tracing, so metrics are a *projection* of the
|
|
6
|
+
* trace stream rather than a second instrumentation path that can drift out of
|
|
7
|
+
* agreement with it. Attach it to a tracer and tokens/sec, cost-per-request, TTFT
|
|
8
|
+
* and cache-hit rate fall out of the traffic that is already being traced.
|
|
9
|
+
*
|
|
10
|
+
* Metrics that matter for an LLM system, and why the usual web ones do not:
|
|
11
|
+
* • tokens/sec — throughput the user actually feels, not requests/sec.
|
|
12
|
+
* • cost per request — the only unit that ties spend to a product decision.
|
|
13
|
+
* • TTFT — perceived latency for streamed answers; p95 latency
|
|
14
|
+
* hides it entirely.
|
|
15
|
+
* • cache-hit rate — the lever that moves cost, split local vs provider.
|
|
16
|
+
* • unpriced calls — honesty: a model missing from the rate card is counted,
|
|
17
|
+
* never billed at a silent zero.
|
|
18
|
+
*/
|
|
19
|
+
import type { SpanData, SpanExporter, SpanKind } from './types.js';
|
|
20
|
+
export interface LlmMetricSnapshot {
|
|
21
|
+
/** Model id, or `'*'` for the all-models roll-up. */
|
|
22
|
+
model: string;
|
|
23
|
+
calls: number;
|
|
24
|
+
errors: number;
|
|
25
|
+
errorRate: number;
|
|
26
|
+
inputTokens: number;
|
|
27
|
+
outputTokens: number;
|
|
28
|
+
cachedInputTokens: number;
|
|
29
|
+
cacheWriteTokens: number;
|
|
30
|
+
totalTokens: number;
|
|
31
|
+
/** Sum of priced calls, USD. Calls on unpriced models contribute 0 here. */
|
|
32
|
+
costUsd: number;
|
|
33
|
+
avgCostPerRequestUsd: number;
|
|
34
|
+
/** Calls whose model was absent from the price book — excluded from `costUsd`. */
|
|
35
|
+
unpricedCalls: number;
|
|
36
|
+
/** Calls whose token counts were estimated rather than provider-reported. */
|
|
37
|
+
estimatedCalls: number;
|
|
38
|
+
totalDurationMs: number;
|
|
39
|
+
avgLatencyMs: number;
|
|
40
|
+
p50LatencyMs: number;
|
|
41
|
+
p95LatencyMs: number;
|
|
42
|
+
/** Output tokens per second of wall-clock spent generating them. */
|
|
43
|
+
tokensPerSecond: number;
|
|
44
|
+
/** Mean time-to-first-token over streamed calls; 0 when none streamed. */
|
|
45
|
+
avgTimeToFirstTokenMs: number;
|
|
46
|
+
streamedCalls: number;
|
|
47
|
+
/** Share of calls served without reaching a provider (exact/semantic cache). */
|
|
48
|
+
localCacheHitRate: number;
|
|
49
|
+
/** Share of input tokens served from the provider's prompt cache. */
|
|
50
|
+
providerCacheHitRate: number;
|
|
51
|
+
}
|
|
52
|
+
export interface KindMetricSnapshot {
|
|
53
|
+
kind: SpanKind;
|
|
54
|
+
count: number;
|
|
55
|
+
errors: number;
|
|
56
|
+
totalDurationMs: number;
|
|
57
|
+
avgLatencyMs: number;
|
|
58
|
+
p95LatencyMs: number;
|
|
59
|
+
}
|
|
60
|
+
export interface MetricsRegistryOptions {
|
|
61
|
+
/**
|
|
62
|
+
* Max latency samples retained per series for percentiles. Default 2048 —
|
|
63
|
+
* bounded so a long-lived process cannot grow the registry without limit.
|
|
64
|
+
*/
|
|
65
|
+
maxSamples?: number;
|
|
66
|
+
}
|
|
67
|
+
export declare class MetricsRegistry implements SpanExporter {
|
|
68
|
+
private readonly _maxSamples;
|
|
69
|
+
private readonly _byModel;
|
|
70
|
+
private readonly _byKind;
|
|
71
|
+
constructor(opts?: MetricsRegistryOptions);
|
|
72
|
+
/** {@link SpanExporter} — attach this registry directly to a {@link Tracer}. */
|
|
73
|
+
export(spans: readonly SpanData[]): void;
|
|
74
|
+
/** Folds one finished span into the aggregates. */
|
|
75
|
+
record(span: SpanData): void;
|
|
76
|
+
/** Snapshot for one model, or the `'*'` roll-up when omitted. */
|
|
77
|
+
llm(model?: string): LlmMetricSnapshot;
|
|
78
|
+
/** Snapshots for every model seen, excluding the `'*'` roll-up. */
|
|
79
|
+
models(): LlmMetricSnapshot[];
|
|
80
|
+
/** Latency/error snapshots per span kind — retrieval, ingest, graph, tool. */
|
|
81
|
+
kinds(): KindMetricSnapshot[];
|
|
82
|
+
reset(): void;
|
|
83
|
+
private _model;
|
|
84
|
+
private _kind;
|
|
85
|
+
}
|
|
86
|
+
/** Nearest-rank percentile over an unsorted sample array. */
|
|
87
|
+
export declare function percentile(samples: readonly number[], q: number): number;
|
|
88
|
+
//# sourceMappingURL=MetricsRegistry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MetricsRegistry.d.ts","sourceRoot":"","sources":["../../src/telemetry/MetricsRegistry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEnE,MAAM,WAAW,iBAAiB;IAC9B,qDAAqD;IACrD,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAElB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IAEpB,4EAA4E;IAC5E,OAAO,EAAE,MAAM,CAAC;IAChB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,kFAAkF;IAClF,aAAa,EAAE,MAAM,CAAC;IACtB,6EAA6E;IAC7E,cAAc,EAAE,MAAM,CAAC;IAEvB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IAErB,oEAAoE;IACpE,eAAe,EAAE,MAAM,CAAC;IACxB,0EAA0E;IAC1E,qBAAqB,EAAE,MAAM,CAAC;IAC9B,aAAa,EAAE,MAAM,CAAC;IAEtB,gFAAgF;IAChF,iBAAiB,EAAE,MAAM,CAAC;IAC1B,qEAAqE;IACrE,oBAAoB,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,kBAAkB;IAC/B,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,sBAAsB;IACnC;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AA0BD,qBAAa,eAAgB,YAAW,YAAY;IAChD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqC;IAC9D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAwC;gBAEpD,IAAI,GAAE,sBAA2B;IAI7C,gFAAgF;IAChF,MAAM,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,GAAG,IAAI;IAIxC,mDAAmD;IACnD,MAAM,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI;IAuC5B,iEAAiE;IACjE,GAAG,CAAC,KAAK,SAAM,GAAG,iBAAiB;IAInC,mEAAmE;IACnE,MAAM,IAAI,iBAAiB,EAAE;IAO7B,8EAA8E;IAC9E,KAAK,IAAI,kBAAkB,EAAE;IAa7B,KAAK,IAAI,IAAI;IAKb,OAAO,CAAC,MAAM;IASd,OAAO,CAAC,KAAK;CAQhB;AAoDD,6DAA6D;AAC7D,wBAAgB,UAAU,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAMxE"}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* telemetry/MetricsRegistry.ts — LLM-native metrics, aggregated from spans.
|
|
3
|
+
*
|
|
4
|
+
* The registry is itself a {@link SpanExporter}. That is the DRY move: every
|
|
5
|
+
* subsystem already emits spans for tracing, so metrics are a *projection* of the
|
|
6
|
+
* trace stream rather than a second instrumentation path that can drift out of
|
|
7
|
+
* agreement with it. Attach it to a tracer and tokens/sec, cost-per-request, TTFT
|
|
8
|
+
* and cache-hit rate fall out of the traffic that is already being traced.
|
|
9
|
+
*
|
|
10
|
+
* Metrics that matter for an LLM system, and why the usual web ones do not:
|
|
11
|
+
* • tokens/sec — throughput the user actually feels, not requests/sec.
|
|
12
|
+
* • cost per request — the only unit that ties spend to a product decision.
|
|
13
|
+
* • TTFT — perceived latency for streamed answers; p95 latency
|
|
14
|
+
* hides it entirely.
|
|
15
|
+
* • cache-hit rate — the lever that moves cost, split local vs provider.
|
|
16
|
+
* • unpriced calls — honesty: a model missing from the rate card is counted,
|
|
17
|
+
* never billed at a silent zero.
|
|
18
|
+
*/
|
|
19
|
+
export class MetricsRegistry {
|
|
20
|
+
_maxSamples;
|
|
21
|
+
_byModel = new Map();
|
|
22
|
+
_byKind = new Map();
|
|
23
|
+
constructor(opts = {}) {
|
|
24
|
+
this._maxSamples = Math.max(1, opts.maxSamples ?? 2048);
|
|
25
|
+
}
|
|
26
|
+
/** {@link SpanExporter} — attach this registry directly to a {@link Tracer}. */
|
|
27
|
+
export(spans) {
|
|
28
|
+
for (const span of spans)
|
|
29
|
+
this.record(span);
|
|
30
|
+
}
|
|
31
|
+
/** Folds one finished span into the aggregates. */
|
|
32
|
+
record(span) {
|
|
33
|
+
const duration = span.durationMs ?? 0;
|
|
34
|
+
const failed = span.status === 'error';
|
|
35
|
+
const kindAcc = this._kind(span.kind);
|
|
36
|
+
kindAcc.count += 1;
|
|
37
|
+
if (failed)
|
|
38
|
+
kindAcc.errors += 1;
|
|
39
|
+
kindAcc.totalDurationMs += duration;
|
|
40
|
+
push(kindAcc.latencies, duration, this._maxSamples);
|
|
41
|
+
if (span.kind !== 'llm' && span.kind !== 'embedding')
|
|
42
|
+
return;
|
|
43
|
+
const model = span.usage?.model ?? String(span.attributes['llm.model'] ?? 'unknown');
|
|
44
|
+
for (const acc of [this._model(model), this._model('*')]) {
|
|
45
|
+
acc.calls += 1;
|
|
46
|
+
if (failed)
|
|
47
|
+
acc.errors += 1;
|
|
48
|
+
acc.totalDurationMs += duration;
|
|
49
|
+
push(acc.latencies, duration, this._maxSamples);
|
|
50
|
+
if (span.timeToFirstTokenMs !== undefined) {
|
|
51
|
+
acc.streamedCalls += 1;
|
|
52
|
+
acc.ttftTotalMs += span.timeToFirstTokenMs;
|
|
53
|
+
}
|
|
54
|
+
const usage = span.usage;
|
|
55
|
+
if (!usage)
|
|
56
|
+
continue;
|
|
57
|
+
acc.inputTokens += usage.inputTokens;
|
|
58
|
+
acc.outputTokens += usage.outputTokens;
|
|
59
|
+
acc.cachedInputTokens += usage.cachedInputTokens ?? 0;
|
|
60
|
+
acc.cacheWriteTokens += usage.cacheWriteTokens ?? 0;
|
|
61
|
+
if (usage.estimated)
|
|
62
|
+
acc.estimatedCalls += 1;
|
|
63
|
+
if (usage.localCacheHit)
|
|
64
|
+
acc.localCacheHits += 1;
|
|
65
|
+
if (span.costUsd === undefined)
|
|
66
|
+
acc.unpricedCalls += 1;
|
|
67
|
+
else
|
|
68
|
+
acc.costUsd += span.costUsd;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/** Snapshot for one model, or the `'*'` roll-up when omitted. */
|
|
72
|
+
llm(model = '*') {
|
|
73
|
+
return summarize(model, this._byModel.get(model) ?? emptyLlm());
|
|
74
|
+
}
|
|
75
|
+
/** Snapshots for every model seen, excluding the `'*'` roll-up. */
|
|
76
|
+
models() {
|
|
77
|
+
return [...this._byModel.entries()]
|
|
78
|
+
.filter(([model]) => model !== '*')
|
|
79
|
+
.map(([model, acc]) => summarize(model, acc))
|
|
80
|
+
.sort((a, b) => b.costUsd - a.costUsd || b.calls - a.calls);
|
|
81
|
+
}
|
|
82
|
+
/** Latency/error snapshots per span kind — retrieval, ingest, graph, tool. */
|
|
83
|
+
kinds() {
|
|
84
|
+
return [...this._byKind.entries()]
|
|
85
|
+
.map(([kind, acc]) => ({
|
|
86
|
+
kind,
|
|
87
|
+
count: acc.count,
|
|
88
|
+
errors: acc.errors,
|
|
89
|
+
totalDurationMs: acc.totalDurationMs,
|
|
90
|
+
avgLatencyMs: acc.count ? acc.totalDurationMs / acc.count : 0,
|
|
91
|
+
p95LatencyMs: percentile(acc.latencies, 0.95),
|
|
92
|
+
}))
|
|
93
|
+
.sort((a, b) => b.count - a.count);
|
|
94
|
+
}
|
|
95
|
+
reset() {
|
|
96
|
+
this._byModel.clear();
|
|
97
|
+
this._byKind.clear();
|
|
98
|
+
}
|
|
99
|
+
_model(model) {
|
|
100
|
+
let acc = this._byModel.get(model);
|
|
101
|
+
if (!acc) {
|
|
102
|
+
acc = emptyLlm();
|
|
103
|
+
this._byModel.set(model, acc);
|
|
104
|
+
}
|
|
105
|
+
return acc;
|
|
106
|
+
}
|
|
107
|
+
_kind(kind) {
|
|
108
|
+
let acc = this._byKind.get(kind);
|
|
109
|
+
if (!acc) {
|
|
110
|
+
acc = { count: 0, errors: 0, totalDurationMs: 0, latencies: [] };
|
|
111
|
+
this._byKind.set(kind, acc);
|
|
112
|
+
}
|
|
113
|
+
return acc;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
function emptyLlm() {
|
|
117
|
+
return {
|
|
118
|
+
calls: 0, errors: 0,
|
|
119
|
+
inputTokens: 0, outputTokens: 0, cachedInputTokens: 0, cacheWriteTokens: 0,
|
|
120
|
+
costUsd: 0, unpricedCalls: 0, estimatedCalls: 0, localCacheHits: 0,
|
|
121
|
+
totalDurationMs: 0, ttftTotalMs: 0, streamedCalls: 0, latencies: [],
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
function summarize(model, acc) {
|
|
125
|
+
const totalTokens = acc.inputTokens + acc.outputTokens + acc.cachedInputTokens + acc.cacheWriteTokens;
|
|
126
|
+
const seconds = acc.totalDurationMs / 1000;
|
|
127
|
+
const billableInput = acc.inputTokens + acc.cachedInputTokens;
|
|
128
|
+
return {
|
|
129
|
+
model,
|
|
130
|
+
calls: acc.calls,
|
|
131
|
+
errors: acc.errors,
|
|
132
|
+
errorRate: acc.calls ? acc.errors / acc.calls : 0,
|
|
133
|
+
inputTokens: acc.inputTokens,
|
|
134
|
+
outputTokens: acc.outputTokens,
|
|
135
|
+
cachedInputTokens: acc.cachedInputTokens,
|
|
136
|
+
cacheWriteTokens: acc.cacheWriteTokens,
|
|
137
|
+
totalTokens,
|
|
138
|
+
costUsd: acc.costUsd,
|
|
139
|
+
avgCostPerRequestUsd: acc.calls ? acc.costUsd / acc.calls : 0,
|
|
140
|
+
unpricedCalls: acc.unpricedCalls,
|
|
141
|
+
estimatedCalls: acc.estimatedCalls,
|
|
142
|
+
totalDurationMs: acc.totalDurationMs,
|
|
143
|
+
avgLatencyMs: acc.calls ? acc.totalDurationMs / acc.calls : 0,
|
|
144
|
+
p50LatencyMs: percentile(acc.latencies, 0.5),
|
|
145
|
+
p95LatencyMs: percentile(acc.latencies, 0.95),
|
|
146
|
+
tokensPerSecond: seconds > 0 ? acc.outputTokens / seconds : 0,
|
|
147
|
+
avgTimeToFirstTokenMs: acc.streamedCalls ? acc.ttftTotalMs / acc.streamedCalls : 0,
|
|
148
|
+
streamedCalls: acc.streamedCalls,
|
|
149
|
+
localCacheHitRate: acc.calls ? acc.localCacheHits / acc.calls : 0,
|
|
150
|
+
providerCacheHitRate: billableInput ? acc.cachedInputTokens / billableInput : 0,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
function push(samples, value, cap) {
|
|
154
|
+
samples.push(value);
|
|
155
|
+
if (samples.length > cap)
|
|
156
|
+
samples.shift();
|
|
157
|
+
}
|
|
158
|
+
/** Nearest-rank percentile over an unsorted sample array. */
|
|
159
|
+
export function percentile(samples, q) {
|
|
160
|
+
if (samples.length === 0)
|
|
161
|
+
return 0;
|
|
162
|
+
const sorted = [...samples].sort((a, b) => a - b);
|
|
163
|
+
const rank = Math.ceil(q * sorted.length);
|
|
164
|
+
const idx = Math.min(sorted.length - 1, Math.max(0, rank - 1));
|
|
165
|
+
return sorted[idx];
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=MetricsRegistry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MetricsRegistry.js","sourceRoot":"","sources":["../../src/telemetry/MetricsRegistry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* telemetry/Tracer.ts — granular tracing for agent runs.
|
|
3
|
+
*
|
|
4
|
+
* A production agent failure is almost never "the LLM was wrong"; it is "the
|
|
5
|
+
* retrieval returned nothing, so the LLM was asked to answer from an empty
|
|
6
|
+
* context". You can only see that with a span tree covering the WHOLE request —
|
|
7
|
+
* ingest, retrieval, each graph node, each model call — under one trace id.
|
|
8
|
+
*
|
|
9
|
+
* `now` and `newId` are injected so traces are deterministic under test; the
|
|
10
|
+
* defaults use wall-clock and a random hex id.
|
|
11
|
+
*/
|
|
12
|
+
import { type PriceBook } from './pricing.js';
|
|
13
|
+
import { type TraceContext } from './traceparent.js';
|
|
14
|
+
import type { AttributeValue, LlmUsage, SpanData, SpanExporter, SpanKind, SpanStatus } from './types.js';
|
|
15
|
+
export interface SpanOptions {
|
|
16
|
+
kind?: SpanKind;
|
|
17
|
+
attributes?: Record<string, AttributeValue>;
|
|
18
|
+
/** Parent span. Omit for a root span (starts a new trace). */
|
|
19
|
+
parent?: Span;
|
|
20
|
+
/** Force a trace id (e.g. to continue a trace propagated from an HTTP header). */
|
|
21
|
+
traceId?: string;
|
|
22
|
+
/**
|
|
23
|
+
* A parent span in ANOTHER process, decoded from a `traceparent` header. Adopts
|
|
24
|
+
* its trace id, links to it as parent, and — crucially — obeys its sampling
|
|
25
|
+
* flag, so the four hops of a cloud run are one tree or none, never a tree with
|
|
26
|
+
* a hole where a hop re-rolled the dice. Ignored when `parent` is given (an
|
|
27
|
+
* in-process parent is always the more specific answer).
|
|
28
|
+
*/
|
|
29
|
+
remoteParent?: TraceContext;
|
|
30
|
+
}
|
|
31
|
+
export interface TracerOptions {
|
|
32
|
+
/** Where finished spans go. Omit to buffer only (readable via `finished()`). */
|
|
33
|
+
exporter?: SpanExporter;
|
|
34
|
+
/** Rates used to price `llm` spans. Default {@link DEFAULT_PRICE_BOOK}. */
|
|
35
|
+
pricing?: PriceBook;
|
|
36
|
+
/** Clock, injected for determinism. Default `Date.now`. */
|
|
37
|
+
now?: () => number;
|
|
38
|
+
/** Id factory, injected for determinism. Default random hex. */
|
|
39
|
+
newId?: (bytes: number) => string;
|
|
40
|
+
/**
|
|
41
|
+
* Export once this many spans have finished. Default 64. Set 1 to export
|
|
42
|
+
* eagerly, when a downstream collector wants a live stream.
|
|
43
|
+
*/
|
|
44
|
+
maxBatchSize?: number;
|
|
45
|
+
/**
|
|
46
|
+
* Fraction of ROOT traces recorded, 0..1. Default 1. Sampling is decided once
|
|
47
|
+
* per trace and inherited by children, so a sampled trace is never a tree with
|
|
48
|
+
* holes in it.
|
|
49
|
+
*/
|
|
50
|
+
sampleRate?: number;
|
|
51
|
+
/** Sampling dice, injected for test. Default `Math.random`. */
|
|
52
|
+
random?: () => number;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* A live span. Mutating methods are no-ops once `end()`/`fail()` has run, so a
|
|
56
|
+
* late callback (a stream resolving after a timeout) cannot corrupt a span that
|
|
57
|
+
* has already been exported.
|
|
58
|
+
*/
|
|
59
|
+
export declare class Span {
|
|
60
|
+
private readonly _tracer;
|
|
61
|
+
private readonly _data;
|
|
62
|
+
private _closed;
|
|
63
|
+
private readonly _recorded;
|
|
64
|
+
/** @internal — construct via {@link Tracer.startSpan}. */
|
|
65
|
+
constructor(tracer: Tracer, data: SpanData, recorded: boolean);
|
|
66
|
+
get traceId(): string;
|
|
67
|
+
get spanId(): string;
|
|
68
|
+
get name(): string;
|
|
69
|
+
get closed(): boolean;
|
|
70
|
+
/** False when this trace was dropped by sampling — nothing will be exported. */
|
|
71
|
+
get recorded(): boolean;
|
|
72
|
+
/** A snapshot copy; mutating it does not affect the span. */
|
|
73
|
+
get data(): SpanData;
|
|
74
|
+
setAttribute(key: string, value: AttributeValue): this;
|
|
75
|
+
setAttributes(attrs: Record<string, AttributeValue | undefined>): this;
|
|
76
|
+
addEvent(name: string, attributes?: Record<string, AttributeValue>): this;
|
|
77
|
+
/** Records token usage and prices it with the tracer's price book. */
|
|
78
|
+
recordUsage(usage: LlmUsage): this;
|
|
79
|
+
/** Marks time-to-first-token; call when a stream yields its first chunk. */
|
|
80
|
+
recordFirstToken(): this;
|
|
81
|
+
/** Opens a child span inside this one (same trace, this span as parent). */
|
|
82
|
+
child(name: string, opts?: Omit<SpanOptions, 'parent' | 'traceId' | 'remoteParent'>): Span;
|
|
83
|
+
/**
|
|
84
|
+
* This span's position, for handing to another process. The sampling flag is the
|
|
85
|
+
* span's OWN `recorded` verdict, so the next hop inherits the decision already
|
|
86
|
+
* taken rather than making a second, possibly contradictory one.
|
|
87
|
+
*/
|
|
88
|
+
context(): TraceContext;
|
|
89
|
+
/**
|
|
90
|
+
* The `traceparent` header value to send on an outbound request made inside this
|
|
91
|
+
* span. Set it and the callee's root span becomes this span's child.
|
|
92
|
+
*/
|
|
93
|
+
traceparent(): string;
|
|
94
|
+
end(status?: SpanStatus): SpanData;
|
|
95
|
+
/** Ends the span as failed, recording the error message. */
|
|
96
|
+
fail(error: unknown): SpanData;
|
|
97
|
+
private _close;
|
|
98
|
+
}
|
|
99
|
+
export declare class Tracer {
|
|
100
|
+
readonly pricing: PriceBook;
|
|
101
|
+
private readonly _exporter?;
|
|
102
|
+
private readonly _now;
|
|
103
|
+
private readonly _newId;
|
|
104
|
+
private readonly _maxBatch;
|
|
105
|
+
private readonly _sampleRate;
|
|
106
|
+
private readonly _random;
|
|
107
|
+
private _buffer;
|
|
108
|
+
private readonly _finished;
|
|
109
|
+
/** traceId -> sampling decision, so children inherit the root's verdict. */
|
|
110
|
+
private readonly _sampled;
|
|
111
|
+
constructor(opts?: TracerOptions);
|
|
112
|
+
now(): number;
|
|
113
|
+
startSpan(name: string, opts?: SpanOptions): Span;
|
|
114
|
+
/**
|
|
115
|
+
* Runs `fn` inside a span, ending it `ok` on resolve and `error` on throw.
|
|
116
|
+
* Every subsystem uses this rather than hand-pairing start/end, so a thrown
|
|
117
|
+
* error can never leak an un-ended span into the trace tree.
|
|
118
|
+
*/
|
|
119
|
+
withSpan<T>(name: string, opts: SpanOptions, fn: (span: Span) => Promise<T> | T): Promise<T>;
|
|
120
|
+
/** All spans finished since construction (recorded ones only). */
|
|
121
|
+
finished(): readonly SpanData[];
|
|
122
|
+
/** Spans of one trace, in completion order. */
|
|
123
|
+
trace(traceId: string): readonly SpanData[];
|
|
124
|
+
/** Pushes any buffered spans to the exporter. */
|
|
125
|
+
flush(): Promise<void>;
|
|
126
|
+
shutdown(): Promise<void>;
|
|
127
|
+
/** @internal */
|
|
128
|
+
_finish(data: SpanData, recorded: boolean): void;
|
|
129
|
+
/**
|
|
130
|
+
* Take the upstream hop's sampling verdict verbatim and record it against the
|
|
131
|
+
* trace, so every later span in this process inherits it too. Head-based
|
|
132
|
+
* sampling only works if it is decided ONCE, at the head.
|
|
133
|
+
*/
|
|
134
|
+
private _adoptSampling;
|
|
135
|
+
private _decideSampling;
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=Tracer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Tracer.d.ts","sourceRoot":"","sources":["../../src/telemetry/Tracer.ts"],"names":[],"mappings":"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"}
|