@seanhogg/builderforce-memory 2026.7.12 → 2026.9.27
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 +55 -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/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 +21 -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
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VertexAIBridge — TransformerBridge for Google Cloud Vertex AI.
|
|
3
|
+
*
|
|
4
|
+
* GCP is where a large share of enterprise AI actually runs, usually because the
|
|
5
|
+
* customer's data already lives in BigQuery and Cloud Storage and moving it is a
|
|
6
|
+
* procurement problem, not a technical one. This bridge lets Evermind serve those
|
|
7
|
+
* deployments without changing anything above the port.
|
|
8
|
+
*
|
|
9
|
+
* Two deliberate choices:
|
|
10
|
+
*
|
|
11
|
+
* • **Auth is injected, never owned.** `getAccessToken` is supplied by the
|
|
12
|
+
* caller, which is what lets the same code run under Application Default
|
|
13
|
+
* Credentials locally, a Workload Identity service account on GKE, and an
|
|
14
|
+
* impersonated token in CI — and keeps this package free of the Google auth
|
|
15
|
+
* library (and of any credential lifecycle it has no business managing).
|
|
16
|
+
* • **Raw HTTP, like every other bridge here.** The package is zero-dependency
|
|
17
|
+
* and runs in a browser, a Worker and Node; adding a Node-only vendor SDK to
|
|
18
|
+
* one bridge would cost that portability for the whole package.
|
|
19
|
+
*
|
|
20
|
+
* Usage is reported from `usageMetadata`, so cost accounting on Vertex is measured
|
|
21
|
+
* rather than estimated — with the caveat that Vertex is partner-billed at rates
|
|
22
|
+
* that differ from the first-party API, so supply a matching `PriceBook`.
|
|
23
|
+
*/
|
|
24
|
+
import type { TransformerBridge, BridgeGenerateOptions, BridgeCallInfo } from './TransformerBridge.js';
|
|
25
|
+
export interface VertexAIBridgeOptions {
|
|
26
|
+
/** GCP project id. */
|
|
27
|
+
projectId: string;
|
|
28
|
+
/** Region, or `'global'`. Default `'us-central1'`. */
|
|
29
|
+
location?: string;
|
|
30
|
+
/**
|
|
31
|
+
* Publisher model id, e.g. `'gemini-2.5-pro'`, or a Claude model served through
|
|
32
|
+
* Vertex. Default `'gemini-2.5-flash'`.
|
|
33
|
+
*/
|
|
34
|
+
model?: string;
|
|
35
|
+
/** Publisher owning the model. Default `'google'`; use `'anthropic'` for Claude. */
|
|
36
|
+
publisher?: string;
|
|
37
|
+
/**
|
|
38
|
+
* Returns a current OAuth access token. Called per request, so the caller's
|
|
39
|
+
* token source owns caching and refresh.
|
|
40
|
+
*/
|
|
41
|
+
getAccessToken: () => Promise<string> | string;
|
|
42
|
+
systemPrompt?: string;
|
|
43
|
+
maxTokens?: number;
|
|
44
|
+
/** Override the API host — for a private endpoint or a test double. */
|
|
45
|
+
baseUrl?: string;
|
|
46
|
+
fetchImpl?: typeof fetch;
|
|
47
|
+
}
|
|
48
|
+
export declare class VertexAIBridge implements TransformerBridge {
|
|
49
|
+
readonly supportsStreaming: true;
|
|
50
|
+
private readonly _projectId;
|
|
51
|
+
private readonly _location;
|
|
52
|
+
private readonly _model;
|
|
53
|
+
private readonly _publisher;
|
|
54
|
+
private readonly _getToken;
|
|
55
|
+
private readonly _systemPrompt;
|
|
56
|
+
private readonly _maxTokens;
|
|
57
|
+
private readonly _baseUrl;
|
|
58
|
+
private readonly _fetch;
|
|
59
|
+
private _lastCall;
|
|
60
|
+
constructor(opts: VertexAIBridgeOptions);
|
|
61
|
+
get lastCall(): BridgeCallInfo | undefined;
|
|
62
|
+
generate(prompt: string, opts?: BridgeGenerateOptions): Promise<string>;
|
|
63
|
+
stream(prompt: string, opts?: BridgeGenerateOptions): AsyncIterable<string>;
|
|
64
|
+
private _send;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Vertex AI text embeddings — the `:predict` surface on a publisher model.
|
|
68
|
+
*
|
|
69
|
+
* Exposed as a {@link BatchEmbedder}-shaped function so it drops straight into the
|
|
70
|
+
* ingestion pipeline: on GCP the embedder, the vector index and the generator can
|
|
71
|
+
* all be Vertex, and nothing above the ports changes.
|
|
72
|
+
*/
|
|
73
|
+
export interface VertexAIEmbedderOptions {
|
|
74
|
+
projectId: string;
|
|
75
|
+
location?: string;
|
|
76
|
+
/** Embedding model. Default `'text-embedding-005'`. */
|
|
77
|
+
model?: string;
|
|
78
|
+
getAccessToken: () => Promise<string> | string;
|
|
79
|
+
/**
|
|
80
|
+
* Task type hint. `RETRIEVAL_DOCUMENT` when indexing, `RETRIEVAL_QUERY` when
|
|
81
|
+
* searching — using the same hint for both measurably degrades recall, because
|
|
82
|
+
* the model embeds questions and passages into deliberately different regions.
|
|
83
|
+
*/
|
|
84
|
+
taskType?: 'RETRIEVAL_DOCUMENT' | 'RETRIEVAL_QUERY' | 'SEMANTIC_SIMILARITY' | 'CLASSIFICATION';
|
|
85
|
+
baseUrl?: string;
|
|
86
|
+
fetchImpl?: typeof fetch;
|
|
87
|
+
}
|
|
88
|
+
export declare class VertexAIEmbedder {
|
|
89
|
+
private readonly _projectId;
|
|
90
|
+
private readonly _location;
|
|
91
|
+
private readonly _model;
|
|
92
|
+
private readonly _getToken;
|
|
93
|
+
private readonly _taskType;
|
|
94
|
+
private readonly _baseUrl;
|
|
95
|
+
private readonly _fetch;
|
|
96
|
+
constructor(opts: VertexAIEmbedderOptions);
|
|
97
|
+
/** Embeds a batch. Shape matches `BatchEmbedder`, for the ingestion pipeline. */
|
|
98
|
+
embedBatch: (texts: string[]) => Promise<Float32Array[]>;
|
|
99
|
+
/** Single-text convenience, for the retriever's query embedding. */
|
|
100
|
+
embed: (text: string) => Promise<Float32Array>;
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=VertexAIBridge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VertexAIBridge.d.ts","sourceRoot":"","sources":["../../src/bridges/VertexAIBridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAIH,OAAO,KAAK,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAEvG,MAAM,WAAW,qBAAqB;IAClC,sBAAsB;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,sDAAsD;IACtD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oFAAoF;IACpF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,cAAc,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;IAC/C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uEAAuE;IACvE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC5B;AAED,qBAAa,cAAe,YAAW,iBAAiB;IACpD,QAAQ,CAAC,iBAAiB,EAAG,IAAI,CAAU;IAE3C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAiC;IAC3D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IAEtC,OAAO,CAAC,SAAS,CAA6B;gBAElC,IAAI,EAAE,qBAAqB;IAYvC,IAAI,QAAQ,IAAI,cAAc,GAAG,SAAS,CAEzC;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;YAiBxE,KAAK;CAqCtB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,uBAAuB;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uDAAuD;IACvD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;IAC/C;;;;OAIG;IACH,QAAQ,CAAC,EAAE,oBAAoB,GAAG,iBAAiB,GAAG,qBAAqB,GAAG,gBAAgB,CAAC;IAC/F,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC5B;AAED,qBAAa,gBAAgB;IACzB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAiC;IAC3D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAqB;IAC/C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;gBAE1B,IAAI,EAAE,uBAAuB;IAUzC,iFAAiF;IACjF,UAAU,GAAU,OAAO,MAAM,EAAE,KAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAmC3D;IAEF,oEAAoE;IACpE,KAAK,GAAU,MAAM,MAAM,KAAG,OAAO,CAAC,YAAY,CAAC,CAGjD;CACL"}
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VertexAIBridge — TransformerBridge for Google Cloud Vertex AI.
|
|
3
|
+
*
|
|
4
|
+
* GCP is where a large share of enterprise AI actually runs, usually because the
|
|
5
|
+
* customer's data already lives in BigQuery and Cloud Storage and moving it is a
|
|
6
|
+
* procurement problem, not a technical one. This bridge lets Evermind serve those
|
|
7
|
+
* deployments without changing anything above the port.
|
|
8
|
+
*
|
|
9
|
+
* Two deliberate choices:
|
|
10
|
+
*
|
|
11
|
+
* • **Auth is injected, never owned.** `getAccessToken` is supplied by the
|
|
12
|
+
* caller, which is what lets the same code run under Application Default
|
|
13
|
+
* Credentials locally, a Workload Identity service account on GKE, and an
|
|
14
|
+
* impersonated token in CI — and keeps this package free of the Google auth
|
|
15
|
+
* library (and of any credential lifecycle it has no business managing).
|
|
16
|
+
* • **Raw HTTP, like every other bridge here.** The package is zero-dependency
|
|
17
|
+
* and runs in a browser, a Worker and Node; adding a Node-only vendor SDK to
|
|
18
|
+
* one bridge would cost that portability for the whole package.
|
|
19
|
+
*
|
|
20
|
+
* Usage is reported from `usageMetadata`, so cost accounting on Vertex is measured
|
|
21
|
+
* rather than estimated — with the caveat that Vertex is partner-billed at rates
|
|
22
|
+
* that differ from the first-party API, so supply a matching `PriceBook`.
|
|
23
|
+
*/
|
|
24
|
+
import { SSMError } from '../errors/SSMError.js';
|
|
25
|
+
export class VertexAIBridge {
|
|
26
|
+
supportsStreaming = true;
|
|
27
|
+
_projectId;
|
|
28
|
+
_location;
|
|
29
|
+
_model;
|
|
30
|
+
_publisher;
|
|
31
|
+
_getToken;
|
|
32
|
+
_systemPrompt;
|
|
33
|
+
_maxTokens;
|
|
34
|
+
_baseUrl;
|
|
35
|
+
_fetch;
|
|
36
|
+
_lastCall;
|
|
37
|
+
constructor(opts) {
|
|
38
|
+
this._projectId = opts.projectId;
|
|
39
|
+
this._location = opts.location ?? 'us-central1';
|
|
40
|
+
this._model = opts.model ?? 'gemini-2.5-flash';
|
|
41
|
+
this._publisher = opts.publisher ?? 'google';
|
|
42
|
+
this._getToken = opts.getAccessToken;
|
|
43
|
+
this._systemPrompt = opts.systemPrompt ?? '';
|
|
44
|
+
this._maxTokens = opts.maxTokens ?? 1024;
|
|
45
|
+
this._baseUrl = opts.baseUrl ?? defaultHost(this._location);
|
|
46
|
+
this._fetch = opts.fetchImpl ?? ((...args) => fetch(...args));
|
|
47
|
+
}
|
|
48
|
+
get lastCall() {
|
|
49
|
+
return this._lastCall;
|
|
50
|
+
}
|
|
51
|
+
async generate(prompt, opts = {}) {
|
|
52
|
+
const res = await this._send(prompt, opts, false);
|
|
53
|
+
const json = await res.json();
|
|
54
|
+
const text = readCandidateText(json);
|
|
55
|
+
if (text === undefined) {
|
|
56
|
+
throw new SSMError('BRIDGE_RESPONSE_INVALID', 'Unexpected Vertex AI response shape.');
|
|
57
|
+
}
|
|
58
|
+
this._lastCall = { usage: readVertexUsage(json['usageMetadata'], opts.model ?? this._model) };
|
|
59
|
+
return text;
|
|
60
|
+
}
|
|
61
|
+
async *stream(prompt, opts = {}) {
|
|
62
|
+
const res = await this._send(prompt, opts, true);
|
|
63
|
+
if (!res.body) {
|
|
64
|
+
throw new SSMError('BRIDGE_RESPONSE_INVALID', 'Vertex AI streaming response has no body.');
|
|
65
|
+
}
|
|
66
|
+
let usage;
|
|
67
|
+
for await (const event of parseSseJson(res.body)) {
|
|
68
|
+
const text = readCandidateText(event);
|
|
69
|
+
if (text)
|
|
70
|
+
yield text;
|
|
71
|
+
// Vertex repeats cumulative usage on each chunk; the last one wins.
|
|
72
|
+
const reported = readVertexUsage(event['usageMetadata'], opts.model ?? this._model);
|
|
73
|
+
if (reported)
|
|
74
|
+
usage = reported;
|
|
75
|
+
}
|
|
76
|
+
this._lastCall = usage ? { usage } : {};
|
|
77
|
+
}
|
|
78
|
+
async _send(prompt, opts, stream) {
|
|
79
|
+
const model = opts.model ?? this._model;
|
|
80
|
+
const method = stream ? 'streamGenerateContent?alt=sse' : 'generateContent';
|
|
81
|
+
const url = `${this._baseUrl}/v1/projects/${this._projectId}/locations/${this._location}` +
|
|
82
|
+
`/publishers/${this._publisher}/models/${model}:${method}`;
|
|
83
|
+
const system = opts.systemPrompt ?? this._systemPrompt;
|
|
84
|
+
const body = {
|
|
85
|
+
contents: [{ role: 'user', parts: [{ text: prompt }] }],
|
|
86
|
+
generationConfig: {
|
|
87
|
+
maxOutputTokens: opts.maxTokens ?? this._maxTokens,
|
|
88
|
+
temperature: opts.temperature ?? 0.7,
|
|
89
|
+
topP: opts.topP ?? 0.9,
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
if (system)
|
|
93
|
+
body['systemInstruction'] = { parts: [{ text: system }] };
|
|
94
|
+
const token = await this._getToken();
|
|
95
|
+
const res = await this._fetch(url, {
|
|
96
|
+
method: 'POST',
|
|
97
|
+
headers: {
|
|
98
|
+
'Content-Type': 'application/json',
|
|
99
|
+
'Authorization': `Bearer ${token}`,
|
|
100
|
+
},
|
|
101
|
+
body: JSON.stringify(body),
|
|
102
|
+
});
|
|
103
|
+
if (!res.ok) {
|
|
104
|
+
const detail = await res.text().catch(() => '');
|
|
105
|
+
throw new SSMError('BRIDGE_REQUEST_FAILED', `Vertex AI returned ${res.status}: ${detail}`);
|
|
106
|
+
}
|
|
107
|
+
return res;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
export class VertexAIEmbedder {
|
|
111
|
+
_projectId;
|
|
112
|
+
_location;
|
|
113
|
+
_model;
|
|
114
|
+
_getToken;
|
|
115
|
+
_taskType;
|
|
116
|
+
_baseUrl;
|
|
117
|
+
_fetch;
|
|
118
|
+
constructor(opts) {
|
|
119
|
+
this._projectId = opts.projectId;
|
|
120
|
+
this._location = opts.location ?? 'us-central1';
|
|
121
|
+
this._model = opts.model ?? 'text-embedding-005';
|
|
122
|
+
this._getToken = opts.getAccessToken;
|
|
123
|
+
this._taskType = opts.taskType;
|
|
124
|
+
this._baseUrl = opts.baseUrl ?? defaultHost(this._location);
|
|
125
|
+
this._fetch = opts.fetchImpl ?? ((...args) => fetch(...args));
|
|
126
|
+
}
|
|
127
|
+
/** Embeds a batch. Shape matches `BatchEmbedder`, for the ingestion pipeline. */
|
|
128
|
+
embedBatch = async (texts) => {
|
|
129
|
+
if (texts.length === 0)
|
|
130
|
+
return [];
|
|
131
|
+
const url = `${this._baseUrl}/v1/projects/${this._projectId}/locations/${this._location}` +
|
|
132
|
+
`/publishers/google/models/${this._model}:predict`;
|
|
133
|
+
const token = await this._getToken();
|
|
134
|
+
const res = await this._fetch(url, {
|
|
135
|
+
method: 'POST',
|
|
136
|
+
headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` },
|
|
137
|
+
body: JSON.stringify({
|
|
138
|
+
instances: texts.map((content) => ({
|
|
139
|
+
content,
|
|
140
|
+
...(this._taskType ? { task_type: this._taskType } : {}),
|
|
141
|
+
})),
|
|
142
|
+
}),
|
|
143
|
+
});
|
|
144
|
+
if (!res.ok) {
|
|
145
|
+
const detail = await res.text().catch(() => '');
|
|
146
|
+
throw new SSMError('BRIDGE_REQUEST_FAILED', `Vertex AI embeddings returned ${res.status}: ${detail}`);
|
|
147
|
+
}
|
|
148
|
+
const json = await res.json();
|
|
149
|
+
const predictions = json.predictions ?? [];
|
|
150
|
+
if (predictions.length !== texts.length) {
|
|
151
|
+
// A short batch would silently misalign vectors with their chunks — the
|
|
152
|
+
// worst kind of RAG bug, because retrieval still "works" and is wrong.
|
|
153
|
+
throw new SSMError('BRIDGE_RESPONSE_INVALID', `Vertex AI returned ${predictions.length} embeddings for ${texts.length} inputs.`);
|
|
154
|
+
}
|
|
155
|
+
return predictions.map((p) => Float32Array.from(p.embeddings?.values ?? []));
|
|
156
|
+
};
|
|
157
|
+
/** Single-text convenience, for the retriever's query embedding. */
|
|
158
|
+
embed = async (text) => {
|
|
159
|
+
const [vector] = await this.embedBatch([text]);
|
|
160
|
+
return vector ?? new Float32Array();
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
function defaultHost(location) {
|
|
164
|
+
return location === 'global'
|
|
165
|
+
? 'https://aiplatform.googleapis.com'
|
|
166
|
+
: `https://${location}-aiplatform.googleapis.com`;
|
|
167
|
+
}
|
|
168
|
+
function readCandidateText(json) {
|
|
169
|
+
const candidates = json['candidates'];
|
|
170
|
+
if (!Array.isArray(candidates) || candidates.length === 0)
|
|
171
|
+
return undefined;
|
|
172
|
+
const parts = candidates[0].content?.parts;
|
|
173
|
+
if (!Array.isArray(parts))
|
|
174
|
+
return undefined;
|
|
175
|
+
// Multi-part responses are concatenated; taking only parts[0] silently truncates.
|
|
176
|
+
return parts.map((p) => p.text ?? '').join('');
|
|
177
|
+
}
|
|
178
|
+
function readVertexUsage(usage, model) {
|
|
179
|
+
if (!usage || typeof usage !== 'object')
|
|
180
|
+
return undefined;
|
|
181
|
+
const u = usage;
|
|
182
|
+
const cached = Number(u['cachedContentTokenCount']) || 0;
|
|
183
|
+
const prompt = Number(u['promptTokenCount']) || 0;
|
|
184
|
+
return {
|
|
185
|
+
model,
|
|
186
|
+
inputTokens: Math.max(0, prompt - cached),
|
|
187
|
+
outputTokens: Number(u['candidatesTokenCount']) || 0,
|
|
188
|
+
cachedInputTokens: cached,
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
/** Parses an `alt=sse` stream into JSON events. */
|
|
192
|
+
async function* parseSseJson(body) {
|
|
193
|
+
const reader = body.getReader();
|
|
194
|
+
const decoder = new TextDecoder();
|
|
195
|
+
let buffer = '';
|
|
196
|
+
try {
|
|
197
|
+
while (true) {
|
|
198
|
+
const { done, value } = await reader.read();
|
|
199
|
+
if (done)
|
|
200
|
+
break;
|
|
201
|
+
buffer += decoder.decode(value, { stream: true });
|
|
202
|
+
const lines = buffer.split('\n');
|
|
203
|
+
buffer = lines.pop();
|
|
204
|
+
for (const line of lines) {
|
|
205
|
+
const trimmed = line.trim();
|
|
206
|
+
if (!trimmed.startsWith('data:'))
|
|
207
|
+
continue;
|
|
208
|
+
const payload = trimmed.slice(5).trim();
|
|
209
|
+
if (!payload || payload === '[DONE]')
|
|
210
|
+
continue;
|
|
211
|
+
try {
|
|
212
|
+
yield JSON.parse(payload);
|
|
213
|
+
}
|
|
214
|
+
catch {
|
|
215
|
+
// Skip malformed SSE frames rather than failing the stream.
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
finally {
|
|
221
|
+
reader.releaseLock();
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
//# sourceMappingURL=VertexAIBridge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VertexAIBridge.js","sourceRoot":"","sources":["../../src/bridges/VertexAIBridge.ts"],"names":[],"mappings":"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"}
|
package/dist/bridges/index.d.ts
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
export type { TransformerBridge, BridgeGenerateOptions } from './TransformerBridge.js';
|
|
1
|
+
export type { TransformerBridge, BridgeGenerateOptions, BridgeCallInfo } from './TransformerBridge.js';
|
|
2
2
|
export { OpenAIBridge } from './OpenAIBridge.js';
|
|
3
3
|
export { AnthropicBridge } from './AnthropicBridge.js';
|
|
4
4
|
export { FetchBridge } from './FetchBridge.js';
|
|
5
5
|
export { CachingBridge } from './CachingBridge.js';
|
|
6
6
|
export { SemanticCachingBridge } from './SemanticCachingBridge.js';
|
|
7
|
+
export { VertexAIBridge, VertexAIEmbedder } from './VertexAIBridge.js';
|
|
7
8
|
export { ResponseCache, buildCacheKey } from './ResponseCache.js';
|
|
8
9
|
export type { OpenAIBridgeOptions } from './OpenAIBridge.js';
|
|
9
10
|
export type { AnthropicBridgeOptions } from './AnthropicBridge.js';
|
|
10
11
|
export type { FetchBridgeOptions } from './FetchBridge.js';
|
|
11
12
|
export type { CachingBridgeOptions } from './CachingBridge.js';
|
|
12
13
|
export type { SemanticCachingBridgeOptions } from './SemanticCachingBridge.js';
|
|
14
|
+
export type { VertexAIBridgeOptions, VertexAIEmbedderOptions } from './VertexAIBridge.js';
|
|
13
15
|
export type { ResponseCacheOptions } from './ResponseCache.js';
|
|
14
16
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/bridges/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/bridges/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACvG,OAAO,EAAE,YAAY,EAAE,MAAS,mBAAmB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAU,kBAAkB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAQ,oBAAoB,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAClE,YAAY,EAAE,mBAAmB,EAAE,MAAS,mBAAmB,CAAC;AAChE,YAAY,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AACnE,YAAY,EAAE,kBAAkB,EAAE,MAAU,kBAAkB,CAAC;AAC/D,YAAY,EAAE,oBAAoB,EAAE,MAAQ,oBAAoB,CAAC;AACjE,YAAY,EAAE,4BAA4B,EAAE,MAAM,4BAA4B,CAAC;AAC/E,YAAY,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAC1F,YAAY,EAAE,oBAAoB,EAAE,MAAQ,oBAAoB,CAAC"}
|
package/dist/bridges/index.js
CHANGED
|
@@ -3,5 +3,6 @@ export { AnthropicBridge } from './AnthropicBridge.js';
|
|
|
3
3
|
export { FetchBridge } from './FetchBridge.js';
|
|
4
4
|
export { CachingBridge } from './CachingBridge.js';
|
|
5
5
|
export { SemanticCachingBridge } from './SemanticCachingBridge.js';
|
|
6
|
+
export { VertexAIBridge, VertexAIEmbedder } from './VertexAIBridge.js';
|
|
6
7
|
export { ResponseCache, buildCacheKey } from './ResponseCache.js';
|
|
7
8
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/bridges/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAS,mBAAmB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAU,kBAAkB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAQ,oBAAoB,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/bridges/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAS,mBAAmB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAU,kBAAkB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAQ,oBAAoB,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* eval/EvalHarness.ts — run a dataset, grade it, and decide the gate.
|
|
3
|
+
*
|
|
4
|
+
* The harness measures cost and latency itself rather than trusting the target to
|
|
5
|
+
* report them, because the number that matters is the one the caller experiences.
|
|
6
|
+
* When a tracer is attached, per-case cost is read back from the SPANS that case
|
|
7
|
+
* produced — the same numbers the production dashboard shows, so an eval budget
|
|
8
|
+
* and a production bill are denominated identically.
|
|
9
|
+
*/
|
|
10
|
+
import type { Tracer } from '../telemetry/Tracer.js';
|
|
11
|
+
import type { EvalDataset, EvalGate, EvalReport, EvalTarget, GateVerdict, Grader } from './types.js';
|
|
12
|
+
export interface EvalHarnessOptions {
|
|
13
|
+
graders?: readonly Grader[];
|
|
14
|
+
gate?: EvalGate;
|
|
15
|
+
/** Cases evaluated concurrently. Default 4. */
|
|
16
|
+
concurrency?: number;
|
|
17
|
+
/**
|
|
18
|
+
* When supplied, per-case cost is summed from the spans of the case's trace.
|
|
19
|
+
* The target must return its `traceId` for this to attribute anything.
|
|
20
|
+
*/
|
|
21
|
+
tracer?: Tracer;
|
|
22
|
+
}
|
|
23
|
+
export declare class EvalHarness {
|
|
24
|
+
private readonly _graders;
|
|
25
|
+
private readonly _gate;
|
|
26
|
+
private readonly _concurrency;
|
|
27
|
+
private readonly _tracer;
|
|
28
|
+
constructor(opts?: EvalHarnessOptions);
|
|
29
|
+
run(dataset: EvalDataset, target: EvalTarget): Promise<EvalReport>;
|
|
30
|
+
private _traceCost;
|
|
31
|
+
private _report;
|
|
32
|
+
}
|
|
33
|
+
/** Applies a gate to a report. Pure, so a build can re-gate an archived report. */
|
|
34
|
+
export declare function evaluateGate(report: EvalReport, gate: EvalGate): GateVerdict;
|
|
35
|
+
/** One-screen summary for CI logs. */
|
|
36
|
+
export declare function formatReport(report: EvalReport): string;
|
|
37
|
+
//# sourceMappingURL=EvalHarness.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EvalHarness.d.ts","sourceRoot":"","sources":["../../src/eval/EvalHarness.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAErD,OAAO,KAAK,EAER,WAAW,EACX,QAAQ,EACR,UAAU,EACV,UAAU,EACV,WAAW,EAEX,MAAM,EACT,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,kBAAkB;IAC/B,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,+CAA+C;IAC/C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,WAAW;IACpB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAoB;IAC7C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAW;IACjC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;gBAEjC,IAAI,GAAE,kBAAuB;IAOnC,GAAG,CAAC,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IA+CxE,OAAO,CAAC,UAAU;IAMlB,OAAO,CAAC,OAAO;CAmClB;AAED,mFAAmF;AACnF,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,GAAG,WAAW,CA6B5E;AAED,sCAAsC;AACtC,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAoCvD"}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* eval/EvalHarness.ts — run a dataset, grade it, and decide the gate.
|
|
3
|
+
*
|
|
4
|
+
* The harness measures cost and latency itself rather than trusting the target to
|
|
5
|
+
* report them, because the number that matters is the one the caller experiences.
|
|
6
|
+
* When a tracer is attached, per-case cost is read back from the SPANS that case
|
|
7
|
+
* produced — the same numbers the production dashboard shows, so an eval budget
|
|
8
|
+
* and a production bill are denominated identically.
|
|
9
|
+
*/
|
|
10
|
+
import { mapWithConcurrency } from '../ingest/IngestionPipeline.js';
|
|
11
|
+
import { percentile } from '../telemetry/MetricsRegistry.js';
|
|
12
|
+
import { DEFAULT_RAG_GRADERS } from './graders.js';
|
|
13
|
+
export class EvalHarness {
|
|
14
|
+
_graders;
|
|
15
|
+
_gate;
|
|
16
|
+
_concurrency;
|
|
17
|
+
_tracer;
|
|
18
|
+
constructor(opts = {}) {
|
|
19
|
+
this._graders = opts.graders ?? DEFAULT_RAG_GRADERS;
|
|
20
|
+
this._gate = opts.gate ?? {};
|
|
21
|
+
this._concurrency = Math.max(1, opts.concurrency ?? 4);
|
|
22
|
+
this._tracer = opts.tracer;
|
|
23
|
+
}
|
|
24
|
+
async run(dataset, target) {
|
|
25
|
+
const started = Date.now();
|
|
26
|
+
const results = new Array(dataset.cases.length);
|
|
27
|
+
await mapWithConcurrency(dataset.cases, this._concurrency, async (evalCase, index) => {
|
|
28
|
+
const caseStarted = Date.now();
|
|
29
|
+
let output;
|
|
30
|
+
try {
|
|
31
|
+
output = await target(evalCase);
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
// A thrown target is a data point, not a crashed suite — the run
|
|
35
|
+
// must still produce a report covering every other case.
|
|
36
|
+
output = { answer: '', error: err instanceof Error ? err.message : String(err) };
|
|
37
|
+
}
|
|
38
|
+
if (output.latencyMs === undefined)
|
|
39
|
+
output.latencyMs = Date.now() - caseStarted;
|
|
40
|
+
if (output.costUsd === undefined && this._tracer && output.traceId) {
|
|
41
|
+
output.costUsd = this._traceCost(output.traceId);
|
|
42
|
+
}
|
|
43
|
+
const grades = [];
|
|
44
|
+
for (const grader of this._graders) {
|
|
45
|
+
try {
|
|
46
|
+
grades.push(await grader({ evalCase, output }));
|
|
47
|
+
}
|
|
48
|
+
catch (err) {
|
|
49
|
+
grades.push({
|
|
50
|
+
grader: 'grader-error',
|
|
51
|
+
score: 0,
|
|
52
|
+
passed: false,
|
|
53
|
+
detail: err instanceof Error ? err.message : String(err),
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
const score = grades.length ? grades.reduce((s, g) => s + g.score, 0) / grades.length : 0;
|
|
58
|
+
results[index] = {
|
|
59
|
+
caseId: evalCase.id,
|
|
60
|
+
output,
|
|
61
|
+
grades,
|
|
62
|
+
score,
|
|
63
|
+
passed: grades.length > 0 && grades.every((g) => g.passed),
|
|
64
|
+
};
|
|
65
|
+
});
|
|
66
|
+
return this._report(dataset.name, results, Date.now() - started);
|
|
67
|
+
}
|
|
68
|
+
_traceCost(traceId) {
|
|
69
|
+
return this._tracer
|
|
70
|
+
.trace(traceId)
|
|
71
|
+
.reduce((sum, span) => sum + (span.costUsd ?? 0), 0);
|
|
72
|
+
}
|
|
73
|
+
_report(dataset, cases, durationMs) {
|
|
74
|
+
const n = cases.length || 1;
|
|
75
|
+
const latencies = cases.map((c) => c.output.latencyMs ?? 0);
|
|
76
|
+
const costs = cases.map((c) => c.output.costUsd ?? 0);
|
|
77
|
+
const graderTotals = new Map();
|
|
78
|
+
for (const result of cases) {
|
|
79
|
+
for (const g of result.grades) {
|
|
80
|
+
const acc = graderTotals.get(g.grader) ?? { sum: 0, count: 0 };
|
|
81
|
+
acc.sum += g.score;
|
|
82
|
+
acc.count += 1;
|
|
83
|
+
graderTotals.set(g.grader, acc);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
const graderScores = {};
|
|
87
|
+
for (const [name, acc] of graderTotals)
|
|
88
|
+
graderScores[name] = acc.sum / acc.count;
|
|
89
|
+
const report = {
|
|
90
|
+
dataset,
|
|
91
|
+
cases,
|
|
92
|
+
passRate: cases.filter((c) => c.passed).length / n,
|
|
93
|
+
meanScore: cases.reduce((s, c) => s + c.score, 0) / n,
|
|
94
|
+
graderScores,
|
|
95
|
+
errorRate: cases.filter((c) => c.output.error).length / n,
|
|
96
|
+
meanCostUsd: costs.reduce((s, c) => s + c, 0) / n,
|
|
97
|
+
totalCostUsd: costs.reduce((s, c) => s + c, 0),
|
|
98
|
+
p50LatencyMs: percentile(latencies, 0.5),
|
|
99
|
+
p95LatencyMs: percentile(latencies, 0.95),
|
|
100
|
+
durationMs,
|
|
101
|
+
gate: { passed: true, failures: [], vacuous: true },
|
|
102
|
+
};
|
|
103
|
+
report.gate = evaluateGate(report, this._gate);
|
|
104
|
+
return report;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/** Applies a gate to a report. Pure, so a build can re-gate an archived report. */
|
|
108
|
+
export function evaluateGate(report, gate) {
|
|
109
|
+
const failures = [];
|
|
110
|
+
const thresholds = Object.entries(gate).filter(([, v]) => v !== undefined);
|
|
111
|
+
if (gate.minPassRate !== undefined && report.passRate < gate.minPassRate) {
|
|
112
|
+
failures.push(`pass rate ${pct(report.passRate)} < required ${pct(gate.minPassRate)}`);
|
|
113
|
+
}
|
|
114
|
+
if (gate.minMeanScore !== undefined && report.meanScore < gate.minMeanScore) {
|
|
115
|
+
failures.push(`mean score ${report.meanScore.toFixed(3)} < required ${gate.minMeanScore}`);
|
|
116
|
+
}
|
|
117
|
+
if (gate.maxErrorRate !== undefined && report.errorRate > gate.maxErrorRate) {
|
|
118
|
+
failures.push(`error rate ${pct(report.errorRate)} > allowed ${pct(gate.maxErrorRate)}`);
|
|
119
|
+
}
|
|
120
|
+
if (gate.maxMeanCostUsd !== undefined && report.meanCostUsd > gate.maxMeanCostUsd) {
|
|
121
|
+
failures.push(`mean cost $${report.meanCostUsd.toFixed(6)} > allowed $${gate.maxMeanCostUsd}`);
|
|
122
|
+
}
|
|
123
|
+
if (gate.maxP95LatencyMs !== undefined && report.p95LatencyMs > gate.maxP95LatencyMs) {
|
|
124
|
+
failures.push(`p95 latency ${Math.round(report.p95LatencyMs)}ms > allowed ${gate.maxP95LatencyMs}ms`);
|
|
125
|
+
}
|
|
126
|
+
for (const [grader, minimum] of Object.entries(gate.minGraderScore ?? {})) {
|
|
127
|
+
const actual = report.graderScores[grader];
|
|
128
|
+
if (actual === undefined) {
|
|
129
|
+
failures.push(`gate names grader "${grader}", which did not run`);
|
|
130
|
+
}
|
|
131
|
+
else if (actual < minimum) {
|
|
132
|
+
failures.push(`grader "${grader}" scored ${actual.toFixed(3)} < required ${minimum}`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return { passed: failures.length === 0, failures, vacuous: thresholds.length === 0 };
|
|
136
|
+
}
|
|
137
|
+
/** One-screen summary for CI logs. */
|
|
138
|
+
export function formatReport(report) {
|
|
139
|
+
const lines = [
|
|
140
|
+
`Eval: ${report.dataset} — ${report.cases.length} cases in ${Math.round(report.durationMs)}ms`,
|
|
141
|
+
` pass rate ${pct(report.passRate)}`,
|
|
142
|
+
` mean score ${report.meanScore.toFixed(3)}`,
|
|
143
|
+
` error rate ${pct(report.errorRate)}`,
|
|
144
|
+
` cost $${report.totalCostUsd.toFixed(6)} total, $${report.meanCostUsd.toFixed(6)}/case`,
|
|
145
|
+
` latency p50 ${Math.round(report.p50LatencyMs)}ms · p95 ${Math.round(report.p95LatencyMs)}ms`,
|
|
146
|
+
];
|
|
147
|
+
for (const [grader, score] of Object.entries(report.graderScores)) {
|
|
148
|
+
lines.push(` ${grader.padEnd(20)} ${score.toFixed(3)}`);
|
|
149
|
+
}
|
|
150
|
+
if (report.gate.vacuous) {
|
|
151
|
+
lines.push(' GATE: no thresholds configured — this suite proves nothing yet.');
|
|
152
|
+
}
|
|
153
|
+
else if (report.gate.passed) {
|
|
154
|
+
lines.push(' GATE: PASS');
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
lines.push(' GATE: FAIL');
|
|
158
|
+
for (const failure of report.gate.failures)
|
|
159
|
+
lines.push(` - ${failure}`);
|
|
160
|
+
}
|
|
161
|
+
const failed = report.cases.filter((c) => !c.passed);
|
|
162
|
+
if (failed.length > 0) {
|
|
163
|
+
lines.push(` Failing cases (${failed.length}):`);
|
|
164
|
+
for (const result of failed.slice(0, 10)) {
|
|
165
|
+
const why = result.grades.filter((g) => !g.passed)
|
|
166
|
+
.map((g) => `${g.grader}${g.detail ? ` (${g.detail})` : ''}`)
|
|
167
|
+
.join(', ');
|
|
168
|
+
lines.push(` - ${result.caseId}: ${why}`);
|
|
169
|
+
}
|
|
170
|
+
if (failed.length > 10)
|
|
171
|
+
lines.push(` … and ${failed.length - 10} more`);
|
|
172
|
+
}
|
|
173
|
+
return lines.join('\n');
|
|
174
|
+
}
|
|
175
|
+
function pct(value) {
|
|
176
|
+
return `${(value * 100).toFixed(1)}%`;
|
|
177
|
+
}
|
|
178
|
+
//# sourceMappingURL=EvalHarness.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EvalHarness.js","sourceRoot":"","sources":["../../src/eval/EvalHarness.ts"],"names":[],"mappings":"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"}
|