openmerit 0.4.1 → 0.4.2
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 +239 -58
- package/data/catalogue.json +6778 -0
- package/dist/catalogue/catalogue.d.ts +41 -0
- package/dist/catalogue/catalogue.js +33 -0
- package/dist/cli/prompt.d.ts +26 -0
- package/dist/cli/prompt.js +114 -0
- package/dist/cli/render.d.ts +12 -0
- package/dist/cli/render.js +104 -0
- package/dist/cli.js +245 -158
- package/dist/connect.d.ts +34 -0
- package/dist/connect.js +158 -0
- package/dist/connectors/langfuse/index.d.ts +37 -110
- package/dist/connectors/langfuse/index.js +95 -246
- package/dist/daemon/daemon.d.ts +81 -0
- package/dist/daemon/daemon.js +408 -0
- package/dist/daemon/registry.d.ts +111 -0
- package/dist/daemon/registry.js +109 -0
- package/dist/eval/proxy.d.ts +54 -0
- package/dist/eval/proxy.js +174 -0
- package/dist/eval/runner.d.ts +29 -0
- package/dist/eval/runner.js +80 -0
- package/dist/harness/claude-bridge.d.ts +21 -0
- package/dist/harness/claude-bridge.js +65 -0
- package/dist/harness/harness.d.ts +60 -0
- package/dist/harness/harness.js +221 -0
- package/dist/index.d.ts +9 -10
- package/dist/index.js +9 -10
- package/dist/local.d.ts +12 -0
- package/dist/local.js +40 -0
- package/dist/mcp.d.ts +1 -0
- package/dist/mcp.js +155 -0
- package/dist/scout/pool.d.ts +17 -0
- package/dist/scout/pool.js +56 -0
- package/dist/scout/scan.d.ts +42 -0
- package/dist/scout/scan.js +169 -0
- package/dist/scout/search.d.ts +25 -98
- package/dist/scout/search.js +56 -156
- package/dist/scout/workflow.d.ts +221 -0
- package/dist/scout/workflow.js +941 -0
- package/dist/setup.d.ts +44 -0
- package/dist/setup.js +211 -0
- package/dist/state/config.d.ts +116 -0
- package/dist/state/config.js +60 -0
- package/dist/state/db.d.ts +159 -0
- package/dist/state/db.js +260 -0
- package/dist/state/paths.d.ts +12 -0
- package/dist/state/paths.js +23 -0
- package/dist/update.d.ts +22 -0
- package/dist/update.js +58 -0
- package/package.json +12 -17
- package/dist/connectors/langfuse/otlp.d.ts +0 -60
- package/dist/connectors/langfuse/otlp.js +0 -40
- package/dist/pi/extension.d.ts +0 -13
- package/dist/pi/extension.js +0 -148
- package/dist/pi/harness.d.ts +0 -20
- package/dist/pi/harness.js +0 -49
- package/dist/pi/instructions.d.ts +0 -2
- package/dist/pi/instructions.js +0 -12
- package/dist/scout/evaluators/module.d.ts +0 -24
- package/dist/scout/evaluators/module.js +0 -19
- package/dist/scout/evaluators/pi.d.ts +0 -53
- package/dist/scout/evaluators/pi.js +0 -117
- package/dist/scout/pipeline.d.ts +0 -111
- package/dist/scout/pipeline.js +0 -157
- package/dist/scout/report.d.ts +0 -3
- package/dist/scout/report.js +0 -42
- package/dist/scout/service.d.ts +0 -148
- package/dist/scout/service.js +0 -143
- package/examples/health-declaration-codes/dataset.jsonl +0 -14
- package/examples/sahra-enrollment/evaluator.mts +0 -152
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
import { type Catalogue, type CatalogueModel } from "../catalogue/catalogue.js";
|
|
2
|
+
import { type TaskEvidence } from "../connectors/langfuse/index.js";
|
|
3
|
+
import type { Harness, HarnessUsage } from "../harness/harness.js";
|
|
4
|
+
import { type Endpoint, type EvalSpec } from "../state/config.js";
|
|
5
|
+
import type { RunStatus, Spend, State } from "../state/db.js";
|
|
6
|
+
import type { Repo } from "../state/paths.js";
|
|
7
|
+
import { type PoolModel } from "./pool.js";
|
|
8
|
+
import { type ScanResult } from "./scan.js";
|
|
9
|
+
import { type Stage } from "./search.js";
|
|
10
|
+
export type Answer = string | string[] | boolean | number;
|
|
11
|
+
export type Answers = Record<string, Answer>;
|
|
12
|
+
export interface Question {
|
|
13
|
+
id: string;
|
|
14
|
+
kind: "choice" | "multi" | "confirm" | "text";
|
|
15
|
+
prompt: string;
|
|
16
|
+
detail?: string;
|
|
17
|
+
options?: {
|
|
18
|
+
value: string;
|
|
19
|
+
label: string;
|
|
20
|
+
detail?: string;
|
|
21
|
+
}[];
|
|
22
|
+
default?: Answer;
|
|
23
|
+
/** What to type, for answers beyond the options, such as a mapping correction. */
|
|
24
|
+
hint?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface Task {
|
|
27
|
+
name: string;
|
|
28
|
+
description: string;
|
|
29
|
+
usageIds: string[];
|
|
30
|
+
usesTools: boolean;
|
|
31
|
+
needsVision: boolean;
|
|
32
|
+
structuredOutput: boolean;
|
|
33
|
+
}
|
|
34
|
+
/** A candidate in a task's pool: ECI-ranked, allowed, cheaper than the current model. */
|
|
35
|
+
export interface PoolEntry {
|
|
36
|
+
key: string;
|
|
37
|
+
model: string;
|
|
38
|
+
endpoint: string;
|
|
39
|
+
endpointModel: string;
|
|
40
|
+
eci: number;
|
|
41
|
+
eciSource: string | null;
|
|
42
|
+
price: number | null;
|
|
43
|
+
}
|
|
44
|
+
interface PlannedEval extends EvalSpec {
|
|
45
|
+
source: "saved" | "harness" | "user";
|
|
46
|
+
helperFiles?: {
|
|
47
|
+
path: string;
|
|
48
|
+
content: string;
|
|
49
|
+
purpose: string;
|
|
50
|
+
}[];
|
|
51
|
+
explanation?: string;
|
|
52
|
+
}
|
|
53
|
+
/** One eval run's result as recorded in SQLite: pass/fail per item, nothing else from the item. */
|
|
54
|
+
export interface UnitResult {
|
|
55
|
+
items: Record<string, boolean>;
|
|
56
|
+
passes: number;
|
|
57
|
+
total: number;
|
|
58
|
+
source: "langfuse" | "eval";
|
|
59
|
+
experiment: string;
|
|
60
|
+
requests: number;
|
|
61
|
+
durationMs: number;
|
|
62
|
+
}
|
|
63
|
+
export interface SearchSummary {
|
|
64
|
+
status: "running" | "selected" | "no_passing_model" | "stopped";
|
|
65
|
+
/** ECI-ranked candidates searched, and eligible ones left out for lack of an ECI. */
|
|
66
|
+
pool: number;
|
|
67
|
+
unranked: number;
|
|
68
|
+
sampleIds: string[];
|
|
69
|
+
pick: string | null;
|
|
70
|
+
trials: {
|
|
71
|
+
stage: Stage;
|
|
72
|
+
model: string;
|
|
73
|
+
eci: number;
|
|
74
|
+
passes: number;
|
|
75
|
+
total: number;
|
|
76
|
+
accepted: boolean;
|
|
77
|
+
}[];
|
|
78
|
+
skipped: {
|
|
79
|
+
model: string;
|
|
80
|
+
stage: string;
|
|
81
|
+
reason: string;
|
|
82
|
+
}[];
|
|
83
|
+
finalists: string[];
|
|
84
|
+
challengers: string[];
|
|
85
|
+
shortfall?: string;
|
|
86
|
+
}
|
|
87
|
+
export interface ModelResult {
|
|
88
|
+
model: string;
|
|
89
|
+
endpoint: string;
|
|
90
|
+
endpointModel: string;
|
|
91
|
+
role: "baseline" | "candidate";
|
|
92
|
+
eci: number | null;
|
|
93
|
+
status: "measured" | "failed" | "unavailable" | "incomplete" | "budget_paused" | "not_run";
|
|
94
|
+
/** Passes over every item run (items × repeats). */
|
|
95
|
+
passes: number;
|
|
96
|
+
total: number;
|
|
97
|
+
runs: number;
|
|
98
|
+
/** Pass rate, passes / total. */
|
|
99
|
+
score: number | null;
|
|
100
|
+
/** Where per-item results came from: the Langfuse experiment the eval recorded, or the eval's own report. */
|
|
101
|
+
source: "langfuse" | "eval" | null;
|
|
102
|
+
/** Measured eval cost per item run, from the metering proxy. */
|
|
103
|
+
costPerItemUsd: number | null;
|
|
104
|
+
costIsEstimate: boolean;
|
|
105
|
+
meanLatencyMs: number | null;
|
|
106
|
+
requests: number;
|
|
107
|
+
qualified: boolean;
|
|
108
|
+
note: string;
|
|
109
|
+
/** Eval units in SQLite this result rests on, and the Langfuse experiments they read. */
|
|
110
|
+
evidence: string[];
|
|
111
|
+
experiments: string[];
|
|
112
|
+
}
|
|
113
|
+
export interface TaskComparison {
|
|
114
|
+
task: string;
|
|
115
|
+
eval: {
|
|
116
|
+
command: string;
|
|
117
|
+
source: string;
|
|
118
|
+
threshold: number | null;
|
|
119
|
+
langfuse: string | null;
|
|
120
|
+
};
|
|
121
|
+
baseline: ModelResult | null;
|
|
122
|
+
candidates: ModelResult[];
|
|
123
|
+
/** Up to three qualified candidates, cheapest measured cost first. */
|
|
124
|
+
top: ModelResult[];
|
|
125
|
+
status: "ranked" | "no_qualified" | "no_passing_model" | "stopped" | "baseline_failed" | "no_eval" | "non_discriminating" | "incomplete";
|
|
126
|
+
note: string;
|
|
127
|
+
search?: SearchSummary;
|
|
128
|
+
langfuse?: TaskEvidence | {
|
|
129
|
+
error: string;
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
interface ConfigureState {
|
|
133
|
+
decision?: "yes" | "no";
|
|
134
|
+
edits?: {
|
|
135
|
+
file: string;
|
|
136
|
+
line: number;
|
|
137
|
+
before: string;
|
|
138
|
+
after: string;
|
|
139
|
+
hash: string;
|
|
140
|
+
from: string;
|
|
141
|
+
to: string;
|
|
142
|
+
}[];
|
|
143
|
+
manual?: string[];
|
|
144
|
+
applied?: boolean;
|
|
145
|
+
}
|
|
146
|
+
export interface RunState {
|
|
147
|
+
scan?: ScanResult;
|
|
148
|
+
tasks?: Task[];
|
|
149
|
+
model?: string;
|
|
150
|
+
corrected?: boolean;
|
|
151
|
+
selected?: string[];
|
|
152
|
+
pool?: Record<string, PoolEntry[]>;
|
|
153
|
+
unranked?: Record<string, number>;
|
|
154
|
+
evals?: Record<string, PlannedEval | {
|
|
155
|
+
skipped: string;
|
|
156
|
+
}>;
|
|
157
|
+
evalApproved?: boolean;
|
|
158
|
+
repeats?: number;
|
|
159
|
+
datasetItems?: Record<string, string[]>;
|
|
160
|
+
samples?: Record<string, string[]>;
|
|
161
|
+
search?: Record<string, SearchSummary>;
|
|
162
|
+
stopped?: Record<string, string>;
|
|
163
|
+
retryDeclined?: string[];
|
|
164
|
+
compare?: Record<string, TaskComparison>;
|
|
165
|
+
accepted?: Record<string, "accept" | "stop">;
|
|
166
|
+
configure?: Record<string, ConfigureState>;
|
|
167
|
+
harnessUsage?: HarnessUsage;
|
|
168
|
+
[key: string]: unknown;
|
|
169
|
+
}
|
|
170
|
+
export interface Context {
|
|
171
|
+
state: State;
|
|
172
|
+
repo: Repo;
|
|
173
|
+
catalogue: Catalogue;
|
|
174
|
+
env: Record<string, string | undefined>;
|
|
175
|
+
harness: () => Promise<Harness>;
|
|
176
|
+
log: (line: string) => void;
|
|
177
|
+
fetch?: typeof fetch;
|
|
178
|
+
signal?: AbortSignal;
|
|
179
|
+
/** How long to wait for Langfuse to ingest an eval run's experiment. */
|
|
180
|
+
langfusePoll?: {
|
|
181
|
+
intervalMs: number;
|
|
182
|
+
timeoutMs: number;
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
export interface Step {
|
|
186
|
+
runId: string;
|
|
187
|
+
status: RunStatus;
|
|
188
|
+
phase: string;
|
|
189
|
+
questions: Question[];
|
|
190
|
+
notices: string[];
|
|
191
|
+
spend: Spend;
|
|
192
|
+
budgetUsd: number;
|
|
193
|
+
harnessUsage: HarnessUsage | null;
|
|
194
|
+
result?: ScoutResult;
|
|
195
|
+
error?: string;
|
|
196
|
+
}
|
|
197
|
+
export interface ScoutResult {
|
|
198
|
+
model: string | null;
|
|
199
|
+
tasks: TaskComparison[];
|
|
200
|
+
configuration: Record<string, ConfigureState>;
|
|
201
|
+
}
|
|
202
|
+
export declare const TOP = 3;
|
|
203
|
+
export declare const TASK_QUESTION = "Select which Agents/Tasks do you want OpenMerit to review?";
|
|
204
|
+
export declare const CONFIGURE_QUESTION = "Should OpenMerit configure this? Yes / No.";
|
|
205
|
+
export declare function newRunId(): string;
|
|
206
|
+
/** Advances a run as far as it can go. Answers are keyed by question ID. */
|
|
207
|
+
export declare function advance(ctx: Context, runId: string, answers?: Answers): Promise<Step>;
|
|
208
|
+
export declare function step(ctx: Context, runId: string, questions: Question[], notices: string[]): Step;
|
|
209
|
+
/** Upper estimate of eval runs: baseline and finals on every item, screens on the sample. */
|
|
210
|
+
export declare function estimate(poolSize: number, repeats: number): {
|
|
211
|
+
probes: number;
|
|
212
|
+
screens: number;
|
|
213
|
+
fullRuns: number;
|
|
214
|
+
};
|
|
215
|
+
/**
|
|
216
|
+
* Allowed-pool models a task could switch to: priced, cheaper than the current model, and able to do
|
|
217
|
+
* what the task needs (tools, images, structured output). The binary search ranks them by ECI.
|
|
218
|
+
*/
|
|
219
|
+
export declare function eligibleCandidates(catalogue: Catalogue, configured: readonly Endpoint[], baseline: CatalogueModel, task: Pick<Task, "usesTools" | "needsVision" | "structuredOutput">): PoolModel[];
|
|
220
|
+
export declare const DEFAULT_BUDGET = 10;
|
|
221
|
+
export {};
|