@agentproto/eval-reporters 0.2.0
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/LICENSE +21 -0
- package/README.md +45 -0
- package/dist/index.d.ts +110 -0
- package/dist/index.mjs +302 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +70 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Jeremy (agentik.net)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# `@agentproto/eval-reporters`
|
|
2
|
+
|
|
3
|
+
Adapter-kit family for eval reporter backends. It mirrors the tunnel-provider adapter family in `@agentproto/runtime`: each backend is identified by a slug, may require credentials stored in a 0600 creds file, and exposes a `Telemetry<EvalEvent>` sink.
|
|
4
|
+
|
|
5
|
+
## Backends
|
|
6
|
+
|
|
7
|
+
| slug | Needs creds | Description |
|
|
8
|
+
|---|---|---|
|
|
9
|
+
| `langfuse` | yes | Langfuse public ingestion API (`@agentproto/telemetry-langfuse`). |
|
|
10
|
+
| `stderr` | no | Human-readable events to `process.stderr`. |
|
|
11
|
+
| `array` | no | In-memory array for tests / inspection. |
|
|
12
|
+
|
|
13
|
+
## Setup flow
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { makeEvalReporterTools } from "@agentproto/eval-reporters"
|
|
17
|
+
|
|
18
|
+
const tools = makeEvalReporterTools()
|
|
19
|
+
|
|
20
|
+
// Configure Langfuse
|
|
21
|
+
await tools.setup_eval_reporter.handler({
|
|
22
|
+
slug: "langfuse",
|
|
23
|
+
publicKey: process.env.LANGFUSE_PUBLIC_KEY,
|
|
24
|
+
secretKey: process.env.LANGFUSE_SECRET_KEY,
|
|
25
|
+
baseUrl: "https://cloud.langfuse.com",
|
|
26
|
+
environment: "production",
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
// List backends — status is now `ready` for langfuse
|
|
30
|
+
const list = await tools.list_eval_reporters.handler()
|
|
31
|
+
console.log(JSON.parse(list.content[0].text))
|
|
32
|
+
|
|
33
|
+
// Resolve and sink
|
|
34
|
+
const { makeEvalReporterResolver, makeEvalReporterCredsStore } = await import("@agentproto/eval-reporters")
|
|
35
|
+
const resolver = makeEvalReporterResolver(makeEvalReporterCredsStore())
|
|
36
|
+
const handle = await resolver("langfuse")
|
|
37
|
+
const sink = handle!.sink()
|
|
38
|
+
|
|
39
|
+
runEval({ suite, sink })
|
|
40
|
+
await sink.flush?.()
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Security
|
|
44
|
+
|
|
45
|
+
Credentials live only in `~/.agentproto/eval-reporter-creds/<slug>.json` with mode `0600`. `list_eval_reporters` and `EvalReporterHandle.info()` expose only capability metadata — never a secret value.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { AdapterCatalog, CredsStore, AdapterHandle, AdapterResolver, SetupField } from '@agentproto/provider-kit';
|
|
2
|
+
import { Telemetry } from '@agentproto/telemetry';
|
|
3
|
+
import { EvalEvent } from '@agentproto/eval';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
|
|
6
|
+
/** Family key used for the eval-reporter creds store path. */
|
|
7
|
+
declare const EVAL_REPORTER_FAMILY: "eval-reporter";
|
|
8
|
+
/** Static catalog of eval reporter backends. */
|
|
9
|
+
declare const EVAL_REPORTER_CATALOG: AdapterCatalog;
|
|
10
|
+
|
|
11
|
+
/** Credentials required by the Langfuse eval reporter backend. */
|
|
12
|
+
interface LangfuseCreds {
|
|
13
|
+
readonly publicKey: string;
|
|
14
|
+
readonly secretKey: string;
|
|
15
|
+
readonly baseUrl: string;
|
|
16
|
+
readonly environment?: string;
|
|
17
|
+
}
|
|
18
|
+
/** Union of all eval-reporter credential shapes (per-slug). */
|
|
19
|
+
type EvalReporterCreds = LangfuseCreds;
|
|
20
|
+
/**
|
|
21
|
+
* Build the eval-reporter creds store (per-slug, 0600) at
|
|
22
|
+
* `~/.agentproto/eval-reporter-creds/`.
|
|
23
|
+
*/
|
|
24
|
+
declare function makeEvalReporterCredsStore(home?: string): CredsStore<EvalReporterCreds>;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Safe descriptor returned by {@link EvalReporterHandle.info}. NEVER carries
|
|
28
|
+
* a secret value — only capability metadata.
|
|
29
|
+
*/
|
|
30
|
+
interface EvalReporterInfo {
|
|
31
|
+
readonly slug: string;
|
|
32
|
+
readonly capabilities: {
|
|
33
|
+
readonly needsCreds: boolean;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/** Resolved eval reporter backend. */
|
|
37
|
+
interface EvalReporterHandle extends AdapterHandle {
|
|
38
|
+
/** Safe descriptor — NEVER a secret. */
|
|
39
|
+
info(): EvalReporterInfo;
|
|
40
|
+
/** Build the live sink. langfuse requires creds; stderr/array need none. */
|
|
41
|
+
sink(): Telemetry<EvalEvent> & {
|
|
42
|
+
flush?(): Promise<unknown>;
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
interface ResolveEvalReporterOptions {
|
|
46
|
+
/** Stored creds for the slug, or null when none have been configured. */
|
|
47
|
+
readonly creds: EvalReporterCreds | null;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Resolve a catalog slug to a concrete eval reporter handle.
|
|
51
|
+
*
|
|
52
|
+
* Throws for unknown slugs so the kit's resolver wraps the miss to `null`.
|
|
53
|
+
* Known slugs always resolve to a descriptor handle; `sink()` throws when
|
|
54
|
+
* creds are required but missing.
|
|
55
|
+
*/
|
|
56
|
+
declare function resolveEvalReporter(slug: string, options: ResolveEvalReporterOptions): EvalReporterHandle;
|
|
57
|
+
/**
|
|
58
|
+
* Build the eval-reporter resolver: reads stored creds and resolves a handle,
|
|
59
|
+
* returning `null` when the slug is unknown (via the kit's wrapper).
|
|
60
|
+
*/
|
|
61
|
+
declare function makeEvalReporterResolver(credsStore: CredsStore<EvalReporterCreds>): AdapterResolver<EvalReporterHandle>;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* MCP tool definitions for the eval-reporter adapter family.
|
|
65
|
+
*
|
|
66
|
+
* This module returns tool *specs* (name, description, schema, handler) rather
|
|
67
|
+
* than registering directly on an `McpServer`. That keeps the package
|
|
68
|
+
* daemon-free and unit-testable; a daemon package can register the returned
|
|
69
|
+
* specs on its server later.
|
|
70
|
+
*/
|
|
71
|
+
|
|
72
|
+
/** Fields collected by the `setup_eval_reporter` tool for Langfuse. */
|
|
73
|
+
declare const LANGFUSE_SETUP_FIELDS: readonly SetupField[];
|
|
74
|
+
interface MakeEvalReporterToolsOptions {
|
|
75
|
+
/** Home dir override (tests). Defaults to `AGENTPROTO_HOME ?? ~/.agentproto`. */
|
|
76
|
+
home?: string;
|
|
77
|
+
}
|
|
78
|
+
interface EvalReporterToolResult {
|
|
79
|
+
readonly content: readonly {
|
|
80
|
+
readonly type: "text";
|
|
81
|
+
readonly text: string;
|
|
82
|
+
}[];
|
|
83
|
+
readonly isError?: boolean;
|
|
84
|
+
}
|
|
85
|
+
interface EvalReporterListToolSpec {
|
|
86
|
+
readonly name: "list_eval_reporters";
|
|
87
|
+
readonly description: string;
|
|
88
|
+
readonly handler: () => Promise<EvalReporterToolResult>;
|
|
89
|
+
}
|
|
90
|
+
interface EvalReporterSetupToolSpec {
|
|
91
|
+
readonly name: "setup_eval_reporter";
|
|
92
|
+
readonly description: string;
|
|
93
|
+
readonly inputSchema: z.ZodObject<Record<string, z.ZodString>>;
|
|
94
|
+
readonly handler: (args: Record<string, string>) => Promise<EvalReporterToolResult>;
|
|
95
|
+
}
|
|
96
|
+
interface EvalReporterTools {
|
|
97
|
+
readonly list_eval_reporters: EvalReporterListToolSpec;
|
|
98
|
+
readonly setup_eval_reporter: EvalReporterSetupToolSpec;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Build the eval-reporter family's MCP tool specs.
|
|
102
|
+
*
|
|
103
|
+
* - `list_eval_reporters` — parameterless; returns status + capabilities,
|
|
104
|
+
* never creds.
|
|
105
|
+
* - `setup_eval_reporter` — multi-field form for configurable reporters
|
|
106
|
+
* (currently `langfuse`). Sensitive values are never echoed.
|
|
107
|
+
*/
|
|
108
|
+
declare function makeEvalReporterTools(deps?: MakeEvalReporterToolsOptions): EvalReporterTools;
|
|
109
|
+
|
|
110
|
+
export { EVAL_REPORTER_CATALOG, EVAL_REPORTER_FAMILY, type EvalReporterCreds, type EvalReporterHandle, type EvalReporterInfo, type EvalReporterListToolSpec, type EvalReporterSetupToolSpec, type EvalReporterToolResult, type EvalReporterTools, LANGFUSE_SETUP_FIELDS, type LangfuseCreds, type MakeEvalReporterToolsOptions, type ResolveEvalReporterOptions, makeEvalReporterCredsStore, makeEvalReporterResolver, makeEvalReporterTools, resolveEvalReporter };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
import { makeCredsStore, makeAdapterResolver, computeStatus } from '@agentproto/provider-kit';
|
|
2
|
+
import { arrayTelemetry, stderrTelemetry } from '@agentproto/telemetry';
|
|
3
|
+
import { langfuseTelemetry } from '@agentproto/telemetry-langfuse';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @agentproto/eval-reporters v0.1.0
|
|
8
|
+
* Adapter-kit family for eval reporter backends.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
// src/catalog.ts
|
|
12
|
+
var EVAL_REPORTER_FAMILY = "eval-reporter";
|
|
13
|
+
var EVAL_REPORTER_CATALOG = [
|
|
14
|
+
{
|
|
15
|
+
slug: "langfuse",
|
|
16
|
+
name: "Langfuse",
|
|
17
|
+
description: "Langfuse observability platform via the public ingestion API. Requires public key, secret key, and base URL.",
|
|
18
|
+
packageName: "@agentproto/telemetry-langfuse",
|
|
19
|
+
hint: "observability \xB7 scores"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
slug: "stderr",
|
|
23
|
+
name: "Standard Error",
|
|
24
|
+
description: "Human-readable eval events written to process stderr.",
|
|
25
|
+
packageName: "@agentproto/eval-reporters",
|
|
26
|
+
hint: "local \xB7 debug"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
slug: "array",
|
|
30
|
+
name: "In-Memory Array",
|
|
31
|
+
description: "Collects eval events in an in-memory array for tests and inspection.",
|
|
32
|
+
packageName: "@agentproto/eval-reporters",
|
|
33
|
+
hint: "local \xB7 test"
|
|
34
|
+
}
|
|
35
|
+
];
|
|
36
|
+
function makeEvalReporterCredsStore(home) {
|
|
37
|
+
return makeCredsStore({
|
|
38
|
+
family: EVAL_REPORTER_FAMILY,
|
|
39
|
+
...home ? { home } : {}
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
function resolveEvalReporter(slug, options) {
|
|
43
|
+
const catalogEntry = EVAL_REPORTER_CATALOG.find((entry) => entry.slug === slug);
|
|
44
|
+
if (catalogEntry === void 0) {
|
|
45
|
+
throw new Error(`unknown eval reporter slug: ${slug}`);
|
|
46
|
+
}
|
|
47
|
+
switch (slug) {
|
|
48
|
+
case "langfuse": {
|
|
49
|
+
const creds = options.creds;
|
|
50
|
+
return {
|
|
51
|
+
slug,
|
|
52
|
+
name: catalogEntry.name,
|
|
53
|
+
description: catalogEntry.description,
|
|
54
|
+
version: "0.1.0",
|
|
55
|
+
requiresSetup: true,
|
|
56
|
+
check: async () => true,
|
|
57
|
+
info() {
|
|
58
|
+
return { slug, capabilities: { needsCreds: true } };
|
|
59
|
+
},
|
|
60
|
+
sink() {
|
|
61
|
+
if (creds === null) {
|
|
62
|
+
throw new Error(
|
|
63
|
+
`eval reporter '${slug}' is not configured; run setup_eval_reporter first`
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
const langfuseCreds = creds;
|
|
67
|
+
return langfuseTelemetry({
|
|
68
|
+
publicKey: langfuseCreds.publicKey,
|
|
69
|
+
secretKey: langfuseCreds.secretKey,
|
|
70
|
+
baseUrl: langfuseCreds.baseUrl,
|
|
71
|
+
environment: langfuseCreds.environment
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
case "stderr": {
|
|
77
|
+
return {
|
|
78
|
+
slug,
|
|
79
|
+
name: catalogEntry.name,
|
|
80
|
+
description: catalogEntry.description,
|
|
81
|
+
version: "0.1.0",
|
|
82
|
+
requiresSetup: false,
|
|
83
|
+
check: async () => true,
|
|
84
|
+
info() {
|
|
85
|
+
return { slug, capabilities: { needsCreds: false } };
|
|
86
|
+
},
|
|
87
|
+
sink() {
|
|
88
|
+
return stderrTelemetry({
|
|
89
|
+
prefix: "eval: ",
|
|
90
|
+
format: formatEvalEvent
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
case "array": {
|
|
96
|
+
return {
|
|
97
|
+
slug,
|
|
98
|
+
name: catalogEntry.name,
|
|
99
|
+
description: catalogEntry.description,
|
|
100
|
+
version: "0.1.0",
|
|
101
|
+
requiresSetup: false,
|
|
102
|
+
check: async () => true,
|
|
103
|
+
info() {
|
|
104
|
+
return { slug, capabilities: { needsCreds: false } };
|
|
105
|
+
},
|
|
106
|
+
sink() {
|
|
107
|
+
return arrayTelemetry();
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
throw new Error(`unhandled eval reporter slug: ${slug}`);
|
|
113
|
+
}
|
|
114
|
+
function formatEvalEvent(event) {
|
|
115
|
+
switch (event.kind) {
|
|
116
|
+
case "eval.started":
|
|
117
|
+
return `${event.runId} started suite=${event.suiteId} cases=${event.caseCount} scorers=${event.scorerCount}`;
|
|
118
|
+
case "eval.case.started":
|
|
119
|
+
return `${event.runId} case.started case=${event.caseId}`;
|
|
120
|
+
case "eval.case.scored":
|
|
121
|
+
return `${event.runId} case.scored case=${event.caseId} scorer=${event.scorerId} value=${event.value} passed=${event.passed}`;
|
|
122
|
+
case "eval.case.finished":
|
|
123
|
+
return `${event.runId} case.finished case=${event.caseId} passed=${event.passed}`;
|
|
124
|
+
case "eval.finished":
|
|
125
|
+
return `${event.runId} finished suite=${event.suiteId} total=${event.total} passed=${event.passedCount} mean=${event.meanValue}ms=${event.durationMs}`;
|
|
126
|
+
default: {
|
|
127
|
+
const _exhaustive = event;
|
|
128
|
+
return JSON.stringify(_exhaustive);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
function makeEvalReporterResolver(credsStore) {
|
|
133
|
+
return makeAdapterResolver({
|
|
134
|
+
load: async (slug) => {
|
|
135
|
+
const creds = await credsStore.read(slug);
|
|
136
|
+
return resolveEvalReporter(slug, { creds });
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
var LANGFUSE_SETUP_FIELDS = [
|
|
141
|
+
{
|
|
142
|
+
name: "publicKey",
|
|
143
|
+
description: "Langfuse public key",
|
|
144
|
+
required: true,
|
|
145
|
+
sensitive: true
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
name: "secretKey",
|
|
149
|
+
description: "Langfuse secret key",
|
|
150
|
+
required: true,
|
|
151
|
+
sensitive: true
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
name: "baseUrl",
|
|
155
|
+
description: "Langfuse base URL, e.g. https://cloud.langfuse.com",
|
|
156
|
+
required: true,
|
|
157
|
+
sensitive: false
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
name: "environment",
|
|
161
|
+
description: "Optional environment label",
|
|
162
|
+
required: false,
|
|
163
|
+
sensitive: false
|
|
164
|
+
}
|
|
165
|
+
];
|
|
166
|
+
var DEFAULT_LANGFUSE_BASE_URL = "https://cloud.langfuse.com";
|
|
167
|
+
function makeEvalReporterTools(deps = {}) {
|
|
168
|
+
const credsStore = makeEvalReporterCredsStore(deps.home);
|
|
169
|
+
const resolver = makeEvalReporterResolver(credsStore);
|
|
170
|
+
const lister = async () => {
|
|
171
|
+
const out = [];
|
|
172
|
+
for (const entry of EVAL_REPORTER_CATALOG) {
|
|
173
|
+
const handle = await resolver(entry.slug);
|
|
174
|
+
if (handle === null) {
|
|
175
|
+
out.push({
|
|
176
|
+
slug: entry.slug,
|
|
177
|
+
name: entry.name,
|
|
178
|
+
description: entry.description,
|
|
179
|
+
packageName: entry.packageName,
|
|
180
|
+
...entry.hint !== void 0 ? { hint: entry.hint } : {},
|
|
181
|
+
status: "supported",
|
|
182
|
+
version: "not installed"
|
|
183
|
+
});
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
const credsExist = await credsStore.exists(entry.slug);
|
|
187
|
+
const status = computeStatus({
|
|
188
|
+
resolved: true,
|
|
189
|
+
requiresSetup: handle.requiresSetup,
|
|
190
|
+
ledgerExists: false,
|
|
191
|
+
credsExist
|
|
192
|
+
});
|
|
193
|
+
out.push({
|
|
194
|
+
slug: handle.slug,
|
|
195
|
+
name: handle.name,
|
|
196
|
+
description: handle.description,
|
|
197
|
+
packageName: entry.packageName,
|
|
198
|
+
...entry.hint !== void 0 ? { hint: entry.hint } : {},
|
|
199
|
+
status,
|
|
200
|
+
version: handle.version,
|
|
201
|
+
info: handle.info()
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
return out;
|
|
205
|
+
};
|
|
206
|
+
const listTool = {
|
|
207
|
+
name: "list_eval_reporters",
|
|
208
|
+
description: "List known eval reporter backends with their status (supported/available/ready) and declared capabilities. Credentials are never returned. Use `setup_eval_reporter` to configure a backend that needs credentials.",
|
|
209
|
+
handler: async () => {
|
|
210
|
+
const entries = await lister();
|
|
211
|
+
return {
|
|
212
|
+
content: [
|
|
213
|
+
{ type: "text", text: JSON.stringify(entries, null, 2) }
|
|
214
|
+
]
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
const shape = {
|
|
219
|
+
slug: z.string().describe("Eval reporter slug to configure")
|
|
220
|
+
};
|
|
221
|
+
for (const field of LANGFUSE_SETUP_FIELDS) {
|
|
222
|
+
const desc = field.sensitive ? `${field.description} SENSITIVE \u2014 never logged and never echoed back in tool results.` : field.description;
|
|
223
|
+
shape[field.name] = (field.required !== false ? z.string().min(1, `${field.name} is required`) : z.string()).describe(desc);
|
|
224
|
+
}
|
|
225
|
+
const inputSchema = z.object(shape);
|
|
226
|
+
const setupTool = {
|
|
227
|
+
name: "setup_eval_reporter",
|
|
228
|
+
description: "Configure an eval reporter backend that requires credentials (currently `langfuse`). Each field is SENSITIVE \u2014 stored with mode 0600 and never echoed back in tool results.",
|
|
229
|
+
inputSchema,
|
|
230
|
+
handler: async (args) => {
|
|
231
|
+
const slug = args.slug ?? "";
|
|
232
|
+
if (slug !== "langfuse") {
|
|
233
|
+
return {
|
|
234
|
+
content: [
|
|
235
|
+
{
|
|
236
|
+
type: "text",
|
|
237
|
+
text: `setup_eval_reporter: unknown slug '${slug}'. Valid: langfuse`
|
|
238
|
+
}
|
|
239
|
+
],
|
|
240
|
+
isError: true
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
const handle = resolveEvalReporter(slug, { creds: null });
|
|
244
|
+
if (!handle.requiresSetup) {
|
|
245
|
+
return {
|
|
246
|
+
content: [
|
|
247
|
+
{
|
|
248
|
+
type: "text",
|
|
249
|
+
text: `setup_eval_reporter: '${slug}' is not configurable`
|
|
250
|
+
}
|
|
251
|
+
],
|
|
252
|
+
isError: true
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
const missing = LANGFUSE_SETUP_FIELDS.filter(
|
|
256
|
+
(field) => field.required !== false
|
|
257
|
+
).map((field) => field.name).filter((name) => {
|
|
258
|
+
const value = args[name];
|
|
259
|
+
return value === void 0 || value.length === 0;
|
|
260
|
+
});
|
|
261
|
+
if (missing.length > 0) {
|
|
262
|
+
return {
|
|
263
|
+
content: [
|
|
264
|
+
{
|
|
265
|
+
type: "text",
|
|
266
|
+
text: `missing required field(s): ${missing.join(", ")}`
|
|
267
|
+
}
|
|
268
|
+
],
|
|
269
|
+
isError: true
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
const publicKey = args.publicKey ?? "";
|
|
273
|
+
const secretKey = args.secretKey ?? "";
|
|
274
|
+
const rawBaseUrl = args.baseUrl;
|
|
275
|
+
const baseUrl = rawBaseUrl !== void 0 && rawBaseUrl.length > 0 ? rawBaseUrl : DEFAULT_LANGFUSE_BASE_URL;
|
|
276
|
+
const environment = args.environment;
|
|
277
|
+
const creds = environment !== void 0 && environment.length > 0 ? { publicKey, secretKey, baseUrl, environment } : { publicKey, secretKey, baseUrl };
|
|
278
|
+
await credsStore.write(slug, creds);
|
|
279
|
+
return {
|
|
280
|
+
content: [
|
|
281
|
+
{
|
|
282
|
+
type: "text",
|
|
283
|
+
text: JSON.stringify(
|
|
284
|
+
{
|
|
285
|
+
ok: true,
|
|
286
|
+
slug,
|
|
287
|
+
hint: `${slug} configured \u2014 status is now ready`
|
|
288
|
+
},
|
|
289
|
+
null,
|
|
290
|
+
2
|
|
291
|
+
)
|
|
292
|
+
}
|
|
293
|
+
]
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
};
|
|
297
|
+
return { list_eval_reporters: listTool, setup_eval_reporter: setupTool };
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
export { EVAL_REPORTER_CATALOG, EVAL_REPORTER_FAMILY, LANGFUSE_SETUP_FIELDS, makeEvalReporterCredsStore, makeEvalReporterResolver, makeEvalReporterTools, resolveEvalReporter };
|
|
301
|
+
//# sourceMappingURL=index.mjs.map
|
|
302
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/catalog.ts","../src/creds.ts","../src/resolve.ts","../src/tools.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["import type { AdapterCatalog } from \"@agentproto/provider-kit\"\n\n/** Family key used for the eval-reporter creds store path. */\nexport const EVAL_REPORTER_FAMILY = \"eval-reporter\" as const\n\n/** Static catalog of eval reporter backends. */\nexport const EVAL_REPORTER_CATALOG: AdapterCatalog = [\n {\n slug: \"langfuse\",\n name: \"Langfuse\",\n description:\n \"Langfuse observability platform via the public ingestion API. \" +\n \"Requires public key, secret key, and base URL.\",\n packageName: \"@agentproto/telemetry-langfuse\",\n hint: \"observability · scores\",\n },\n {\n slug: \"stderr\",\n name: \"Standard Error\",\n description: \"Human-readable eval events written to process stderr.\",\n packageName: \"@agentproto/eval-reporters\",\n hint: \"local · debug\",\n },\n {\n slug: \"array\",\n name: \"In-Memory Array\",\n description: \"Collects eval events in an in-memory array for tests and inspection.\",\n packageName: \"@agentproto/eval-reporters\",\n hint: \"local · test\",\n },\n]\n","import { makeCredsStore, type CredsStore } from \"@agentproto/provider-kit\"\nimport { EVAL_REPORTER_FAMILY } from \"./catalog.js\"\n\n/** Credentials required by the Langfuse eval reporter backend. */\nexport interface LangfuseCreds {\n readonly publicKey: string\n readonly secretKey: string\n readonly baseUrl: string\n readonly environment?: string\n}\n\n/** Union of all eval-reporter credential shapes (per-slug). */\nexport type EvalReporterCreds = LangfuseCreds\n\n/**\n * Build the eval-reporter creds store (per-slug, 0600) at\n * `~/.agentproto/eval-reporter-creds/`.\n */\nexport function makeEvalReporterCredsStore(\n home?: string,\n): CredsStore<EvalReporterCreds> {\n return makeCredsStore<EvalReporterCreds>({\n family: EVAL_REPORTER_FAMILY,\n ...(home ? { home } : {}),\n })\n}\n","import { stderrTelemetry, arrayTelemetry, type Telemetry } from \"@agentproto/telemetry\"\nimport { langfuseTelemetry } from \"@agentproto/telemetry-langfuse\"\nimport type { EvalEvent } from \"@agentproto/eval\"\nimport {\n makeAdapterResolver,\n type AdapterHandle,\n type AdapterResolver,\n type CredsStore,\n} from \"@agentproto/provider-kit\"\nimport { EVAL_REPORTER_CATALOG } from \"./catalog.js\"\nimport type { EvalReporterCreds, LangfuseCreds } from \"./creds.js\"\n\n/**\n * Safe descriptor returned by {@link EvalReporterHandle.info}. NEVER carries\n * a secret value — only capability metadata.\n */\nexport interface EvalReporterInfo {\n readonly slug: string\n readonly capabilities: {\n readonly needsCreds: boolean\n }\n}\n\n/** Resolved eval reporter backend. */\nexport interface EvalReporterHandle extends AdapterHandle {\n /** Safe descriptor — NEVER a secret. */\n info(): EvalReporterInfo\n /** Build the live sink. langfuse requires creds; stderr/array need none. */\n sink(): Telemetry<EvalEvent> & { flush?(): Promise<unknown> }\n}\n\nexport interface ResolveEvalReporterOptions {\n /** Stored creds for the slug, or null when none have been configured. */\n readonly creds: EvalReporterCreds | null\n}\n\n/**\n * Resolve a catalog slug to a concrete eval reporter handle.\n *\n * Throws for unknown slugs so the kit's resolver wraps the miss to `null`.\n * Known slugs always resolve to a descriptor handle; `sink()` throws when\n * creds are required but missing.\n */\nexport function resolveEvalReporter(\n slug: string,\n options: ResolveEvalReporterOptions,\n): EvalReporterHandle {\n const catalogEntry = EVAL_REPORTER_CATALOG.find((entry) => entry.slug === slug)\n if (catalogEntry === undefined) {\n throw new Error(`unknown eval reporter slug: ${slug}`)\n }\n\n switch (slug) {\n case \"langfuse\": {\n const creds = options.creds\n return {\n slug,\n name: catalogEntry.name,\n description: catalogEntry.description,\n version: \"0.1.0\",\n requiresSetup: true,\n check: async () => true,\n info() {\n return { slug, capabilities: { needsCreds: true } }\n },\n sink() {\n if (creds === null) {\n throw new Error(\n `eval reporter '${slug}' is not configured; run setup_eval_reporter first`,\n )\n }\n const langfuseCreds: LangfuseCreds = creds\n return langfuseTelemetry({\n publicKey: langfuseCreds.publicKey,\n secretKey: langfuseCreds.secretKey,\n baseUrl: langfuseCreds.baseUrl,\n environment: langfuseCreds.environment,\n })\n },\n }\n }\n case \"stderr\": {\n return {\n slug,\n name: catalogEntry.name,\n description: catalogEntry.description,\n version: \"0.1.0\",\n requiresSetup: false,\n check: async () => true,\n info() {\n return { slug, capabilities: { needsCreds: false } }\n },\n sink() {\n return stderrTelemetry<EvalEvent>({\n prefix: \"eval: \",\n format: formatEvalEvent,\n })\n },\n }\n }\n case \"array\": {\n return {\n slug,\n name: catalogEntry.name,\n description: catalogEntry.description,\n version: \"0.1.0\",\n requiresSetup: false,\n check: async () => true,\n info() {\n return { slug, capabilities: { needsCreds: false } }\n },\n sink() {\n return arrayTelemetry<EvalEvent>()\n },\n }\n }\n }\n\n throw new Error(`unhandled eval reporter slug: ${slug}`)\n}\n\nfunction formatEvalEvent(event: EvalEvent): string {\n switch (event.kind) {\n case \"eval.started\":\n return `${event.runId} started suite=${event.suiteId} cases=${event.caseCount} scorers=${event.scorerCount}`\n case \"eval.case.started\":\n return `${event.runId} case.started case=${event.caseId}`\n case \"eval.case.scored\":\n return `${event.runId} case.scored case=${event.caseId} scorer=${event.scorerId} value=${event.value} passed=${event.passed}`\n case \"eval.case.finished\":\n return `${event.runId} case.finished case=${event.caseId} passed=${event.passed}`\n case \"eval.finished\":\n return `${event.runId} finished suite=${event.suiteId} total=${event.total} passed=${event.passedCount} mean=${event.meanValue}ms=${event.durationMs}`\n default: {\n const _exhaustive: never = event\n return JSON.stringify(_exhaustive)\n }\n }\n}\n\n/**\n * Build the eval-reporter resolver: reads stored creds and resolves a handle,\n * returning `null` when the slug is unknown (via the kit's wrapper).\n */\nexport function makeEvalReporterResolver(\n credsStore: CredsStore<EvalReporterCreds>,\n): AdapterResolver<EvalReporterHandle> {\n return makeAdapterResolver<EvalReporterHandle>({\n load: async (slug: string): Promise<EvalReporterHandle> => {\n const creds = await credsStore.read(slug)\n return resolveEvalReporter(slug, { creds })\n },\n })\n}\n","/**\n * MCP tool definitions for the eval-reporter adapter family.\n *\n * This module returns tool *specs* (name, description, schema, handler) rather\n * than registering directly on an `McpServer`. That keeps the package\n * daemon-free and unit-testable; a daemon package can register the returned\n * specs on its server later.\n */\n\nimport { z } from \"zod\"\nimport type { AdapterEntry, AdapterLister, SetupField } from \"@agentproto/provider-kit\"\nimport { computeStatus } from \"@agentproto/provider-kit\"\nimport type { EvalEvent } from \"@agentproto/eval\"\nimport { EVAL_REPORTER_CATALOG } from \"./catalog.js\"\nimport {\n makeEvalReporterCredsStore,\n type EvalReporterCreds,\n type LangfuseCreds,\n} from \"./creds.js\"\nimport type { EvalReporterHandle, EvalReporterInfo } from \"./resolve.js\"\nimport { makeEvalReporterResolver, resolveEvalReporter } from \"./resolve.js\"\n\n/** Fields collected by the `setup_eval_reporter` tool for Langfuse. */\nexport const LANGFUSE_SETUP_FIELDS: readonly SetupField[] = [\n {\n name: \"publicKey\",\n description: \"Langfuse public key\",\n required: true,\n sensitive: true,\n },\n {\n name: \"secretKey\",\n description: \"Langfuse secret key\",\n required: true,\n sensitive: true,\n },\n {\n name: \"baseUrl\",\n description: \"Langfuse base URL, e.g. https://cloud.langfuse.com\",\n required: true,\n sensitive: false,\n },\n {\n name: \"environment\",\n description: \"Optional environment label\",\n required: false,\n sensitive: false,\n },\n]\n\nconst DEFAULT_LANGFUSE_BASE_URL = \"https://cloud.langfuse.com\"\n\nexport interface MakeEvalReporterToolsOptions {\n /** Home dir override (tests). Defaults to `AGENTPROTO_HOME ?? ~/.agentproto`. */\n home?: string\n}\n\nexport interface EvalReporterToolResult {\n readonly content: readonly { readonly type: \"text\"; readonly text: string }[]\n readonly isError?: boolean\n}\n\nexport interface EvalReporterListToolSpec {\n readonly name: \"list_eval_reporters\"\n readonly description: string\n readonly handler: () => Promise<EvalReporterToolResult>\n}\n\nexport interface EvalReporterSetupToolSpec {\n readonly name: \"setup_eval_reporter\"\n readonly description: string\n readonly inputSchema: z.ZodObject<Record<string, z.ZodString>>\n readonly handler: (args: Record<string, string>) => Promise<EvalReporterToolResult>\n}\n\nexport interface EvalReporterTools {\n readonly list_eval_reporters: EvalReporterListToolSpec\n readonly setup_eval_reporter: EvalReporterSetupToolSpec\n}\n\n/**\n * Build the eval-reporter family's MCP tool specs.\n *\n * - `list_eval_reporters` — parameterless; returns status + capabilities,\n * never creds.\n * - `setup_eval_reporter` — multi-field form for configurable reporters\n * (currently `langfuse`). Sensitive values are never echoed.\n */\nexport function makeEvalReporterTools(\n deps: MakeEvalReporterToolsOptions = {},\n): EvalReporterTools {\n const credsStore = makeEvalReporterCredsStore(deps.home)\n const resolver = makeEvalReporterResolver(credsStore)\n\n const lister: AdapterLister<EvalReporterInfo> = async () => {\n const out: AdapterEntry<EvalReporterInfo>[] = []\n for (const entry of EVAL_REPORTER_CATALOG) {\n const handle = await resolver(entry.slug)\n if (handle === null) {\n out.push({\n slug: entry.slug,\n name: entry.name,\n description: entry.description,\n packageName: entry.packageName,\n ...(entry.hint !== undefined ? { hint: entry.hint } : {}),\n status: \"supported\",\n version: \"not installed\",\n })\n continue\n }\n\n const credsExist = await credsStore.exists(entry.slug)\n const status = computeStatus({\n resolved: true,\n requiresSetup: handle.requiresSetup,\n ledgerExists: false,\n credsExist,\n })\n\n out.push({\n slug: handle.slug,\n name: handle.name,\n description: handle.description,\n packageName: entry.packageName,\n ...(entry.hint !== undefined ? { hint: entry.hint } : {}),\n status,\n version: handle.version,\n info: handle.info(),\n })\n }\n return out\n }\n\n const listTool: EvalReporterListToolSpec = {\n name: \"list_eval_reporters\",\n description:\n \"List known eval reporter backends with their status (supported/\" +\n \"available/ready) and declared capabilities. Credentials are never \" +\n \"returned. Use `setup_eval_reporter` to configure a backend that \" +\n \"needs credentials.\",\n handler: async () => {\n const entries = await lister()\n return {\n content: [\n { type: \"text\" as const, text: JSON.stringify(entries, null, 2) },\n ],\n }\n },\n }\n\n const shape: Record<string, z.ZodString> = {\n slug: z.string().describe(\"Eval reporter slug to configure\"),\n }\n for (const field of LANGFUSE_SETUP_FIELDS) {\n const desc = field.sensitive\n ? `${field.description} SENSITIVE — never logged and never echoed back in tool results.`\n : field.description\n shape[field.name] = (\n field.required !== false\n ? z.string().min(1, `${field.name} is required`)\n : z.string()\n ).describe(desc)\n }\n const inputSchema = z.object(shape)\n\n const setupTool: EvalReporterSetupToolSpec = {\n name: \"setup_eval_reporter\",\n description:\n \"Configure an eval reporter backend that requires credentials \" +\n \"(currently `langfuse`). Each field is SENSITIVE — stored with mode \" +\n \"0600 and never echoed back in tool results.\",\n inputSchema,\n handler: async (args: Record<string, string>) => {\n const slug = args.slug ?? \"\"\n if (slug !== \"langfuse\") {\n return {\n content: [\n {\n type: \"text\" as const,\n text: `setup_eval_reporter: unknown slug '${slug}'. Valid: langfuse`,\n },\n ],\n isError: true,\n }\n }\n\n const handle = resolveEvalReporter(slug, { creds: null })\n if (!handle.requiresSetup) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: `setup_eval_reporter: '${slug}' is not configurable`,\n },\n ],\n isError: true,\n }\n }\n\n const missing = LANGFUSE_SETUP_FIELDS.filter(\n (field) => field.required !== false,\n )\n .map((field) => field.name)\n .filter((name) => {\n const value = args[name]\n return value === undefined || value.length === 0\n })\n if (missing.length > 0) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: `missing required field(s): ${missing.join(\", \")}`,\n },\n ],\n isError: true,\n }\n }\n\n const publicKey = args.publicKey ?? \"\"\n const secretKey = args.secretKey ?? \"\"\n const rawBaseUrl = args.baseUrl\n const baseUrl =\n rawBaseUrl !== undefined && rawBaseUrl.length > 0\n ? rawBaseUrl\n : DEFAULT_LANGFUSE_BASE_URL\n const environment = args.environment\n const creds: LangfuseCreds =\n environment !== undefined && environment.length > 0\n ? { publicKey, secretKey, baseUrl, environment }\n : { publicKey, secretKey, baseUrl }\n await credsStore.write(slug, creds)\n\n return {\n content: [\n {\n type: \"text\" as const,\n text: JSON.stringify(\n {\n ok: true,\n slug,\n hint: `${slug} configured — status is now ready`,\n },\n null,\n 2,\n ),\n },\n ],\n }\n },\n }\n\n return { list_eval_reporters: listTool, setup_eval_reporter: setupTool }\n}\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@agentproto/eval-reporters",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Adapter-kit family for eval reporters. Pluggable backends (Langfuse, stderr, in-memory array) configured by slug + credentials, mirroring the tunnel-provider adapter family.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"agentproto",
|
|
7
|
+
"eval",
|
|
8
|
+
"reporter",
|
|
9
|
+
"adapter",
|
|
10
|
+
"langfuse",
|
|
11
|
+
"telemetry",
|
|
12
|
+
"open-standard",
|
|
13
|
+
"agentic"
|
|
14
|
+
],
|
|
15
|
+
"homepage": "https://agentproto.sh",
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "https://github.com/agentproto/ts",
|
|
19
|
+
"directory": "packages/eval-reporters"
|
|
20
|
+
},
|
|
21
|
+
"bugs": {
|
|
22
|
+
"url": "https://github.com/agentproto/ts/issues"
|
|
23
|
+
},
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"type": "module",
|
|
26
|
+
"main": "dist/index.mjs",
|
|
27
|
+
"module": "dist/index.mjs",
|
|
28
|
+
"types": "dist/index.d.ts",
|
|
29
|
+
"exports": {
|
|
30
|
+
".": {
|
|
31
|
+
"types": "./dist/index.d.ts",
|
|
32
|
+
"import": "./dist/index.mjs",
|
|
33
|
+
"default": "./dist/index.mjs"
|
|
34
|
+
},
|
|
35
|
+
"./package.json": "./package.json"
|
|
36
|
+
},
|
|
37
|
+
"files": [
|
|
38
|
+
"dist",
|
|
39
|
+
"README.md",
|
|
40
|
+
"LICENSE"
|
|
41
|
+
],
|
|
42
|
+
"publishConfig": {
|
|
43
|
+
"access": "public"
|
|
44
|
+
},
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"zod": "^4.4.3",
|
|
47
|
+
"@agentproto/eval": "0.2.0",
|
|
48
|
+
"@agentproto/provider-kit": "0.2.0",
|
|
49
|
+
"@agentproto/telemetry": "0.2.0",
|
|
50
|
+
"@agentproto/telemetry-langfuse": "0.2.0"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@types/node": "^25.6.2",
|
|
54
|
+
"tsup": "^8.5.1",
|
|
55
|
+
"typescript": "^5.9.3",
|
|
56
|
+
"vitest": "^3.2.4",
|
|
57
|
+
"@agentproto/tooling": "0.1.0-alpha.0"
|
|
58
|
+
},
|
|
59
|
+
"engines": {
|
|
60
|
+
"node": ">=20.9.0"
|
|
61
|
+
},
|
|
62
|
+
"scripts": {
|
|
63
|
+
"dev": "tsup --watch",
|
|
64
|
+
"build": "tsup",
|
|
65
|
+
"clean": "rm -rf dist",
|
|
66
|
+
"check-types": "tsc --noEmit",
|
|
67
|
+
"test": "vitest run",
|
|
68
|
+
"test:watch": "vitest"
|
|
69
|
+
}
|
|
70
|
+
}
|