@velum-labs/routekit-eval-setup 1.0.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 +201 -0
- package/README.md +23 -0
- package/dist/effect-api.d.ts +12 -0
- package/dist/effect-api.js +9 -0
- package/dist/errors.d.ts +91 -0
- package/dist/errors.js +46 -0
- package/dist/host-metadata.d.ts +32 -0
- package/dist/host-metadata.js +46 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.js +13 -0
- package/dist/inspection.d.ts +24 -0
- package/dist/inspection.js +261 -0
- package/dist/model-selection.d.ts +6 -0
- package/dist/model-selection.js +37 -0
- package/dist/ori-authoring.d.ts +16 -0
- package/dist/ori-authoring.js +17 -0
- package/dist/ori-result.d.ts +45 -0
- package/dist/ori-result.js +1 -0
- package/dist/project-artifacts.d.ts +31 -0
- package/dist/project-artifacts.js +353 -0
- package/dist/project-authoring.d.ts +68 -0
- package/dist/project-authoring.js +431 -0
- package/dist/project-contracts.d.ts +1197 -0
- package/dist/project-contracts.js +396 -0
- package/dist/project-store.d.ts +13 -0
- package/dist/project-store.js +53 -0
- package/dist/project-workflow.d.ts +33 -0
- package/dist/project-workflow.js +904 -0
- package/dist/questions.d.ts +7 -0
- package/dist/questions.js +67 -0
- package/dist/runner.d.ts +8 -0
- package/dist/runner.js +16 -0
- package/dist/service.d.ts +24 -0
- package/dist/service.js +279 -0
- package/dist/state-store.d.ts +21 -0
- package/dist/state-store.js +86 -0
- package/dist/test/inspection.test.d.ts +1 -0
- package/dist/test/inspection.test.js +68 -0
- package/dist/test/model-selection.test.d.ts +1 -0
- package/dist/test/model-selection.test.js +15 -0
- package/dist/test/project-authoring.test.d.ts +1 -0
- package/dist/test/project-authoring.test.js +67 -0
- package/dist/test/project-workflow.test.d.ts +1 -0
- package/dist/test/project-workflow.test.js +516 -0
- package/dist/test/questions.test.d.ts +1 -0
- package/dist/test/questions.test.js +48 -0
- package/dist/test/skill.test.d.ts +1 -0
- package/dist/test/skill.test.js +31 -0
- package/dist/test/state-store.test.d.ts +1 -0
- package/dist/test/state-store.test.js +30 -0
- package/dist/test/workflow.test.d.ts +1 -0
- package/dist/test/workflow.test.js +167 -0
- package/dist/types.d.ts +77 -0
- package/dist/types.js +1 -0
- package/package.json +52 -0
- package/skills/setup-eval-routing/SKILL.md +149 -0
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
import { Context, Effect, FileSystem, Layer, Option, Path } from "effect";
|
|
2
|
+
import { EvalSetupInspectionError } from "./errors.js";
|
|
3
|
+
export class EvalRepositoryInspector extends Context.Service()("@velum-labs/routekit-eval-setup/EvalRepositoryInspector") {
|
|
4
|
+
}
|
|
5
|
+
const IGNORED_SEGMENTS = new Set([
|
|
6
|
+
".cache",
|
|
7
|
+
".git",
|
|
8
|
+
".next",
|
|
9
|
+
".pnpm-store",
|
|
10
|
+
".routekit",
|
|
11
|
+
".turbo",
|
|
12
|
+
".venv",
|
|
13
|
+
"build",
|
|
14
|
+
"coverage",
|
|
15
|
+
"dist",
|
|
16
|
+
"generated",
|
|
17
|
+
"node_modules",
|
|
18
|
+
"out",
|
|
19
|
+
"target",
|
|
20
|
+
"vendor"
|
|
21
|
+
]);
|
|
22
|
+
const MAX_INSPECTION_FILES = 2_000;
|
|
23
|
+
const MAX_INSPECTION_ENTRIES = 10_000;
|
|
24
|
+
const MAX_INSPECTION_DEPTH = 24;
|
|
25
|
+
const MAX_INSPECTION_DIRECTORIES = 1_000;
|
|
26
|
+
const MAX_FILE_BYTES = 256 * 1024;
|
|
27
|
+
const MAX_TOTAL_BYTES = 8 * 1024 * 1024;
|
|
28
|
+
const TEXT_EXTENSIONS = new Set([
|
|
29
|
+
".cjs",
|
|
30
|
+
".go",
|
|
31
|
+
".js",
|
|
32
|
+
".json",
|
|
33
|
+
".jsx",
|
|
34
|
+
".md",
|
|
35
|
+
".mdx",
|
|
36
|
+
".mjs",
|
|
37
|
+
".py",
|
|
38
|
+
".rs",
|
|
39
|
+
".ts",
|
|
40
|
+
".tsx",
|
|
41
|
+
".yaml",
|
|
42
|
+
".yml"
|
|
43
|
+
]);
|
|
44
|
+
const MODEL_CALL = /(?:chat\.completions|responses\.create|messages\.create|generateContent|model\s*[:=])/u;
|
|
45
|
+
const MODEL_ID = /\b(?:openai|anthropic|google|meta-llama|mistralai|cohere|x-ai)\/[A-Za-z0-9._~:-]+\b/u;
|
|
46
|
+
const PROMPT_NAME = /(?:^|[-_.])(prompt|system|instructions?)(?:[-_.]|$)/iu;
|
|
47
|
+
const DATASET_NAME = /(?:dataset|cases?|examples?|samples?|traffic)/iu;
|
|
48
|
+
const FIXTURE_NAME = /(?:fixture|gold|expected)/iu;
|
|
49
|
+
const TEST_NAME = /(?:^|[-_.])(test|spec)(?:[-_.]|$)/iu;
|
|
50
|
+
const SCHEMA_NAME = /(?:schema|output)/iu;
|
|
51
|
+
const inspectionFailure = (path, cause) => new EvalSetupInspectionError({
|
|
52
|
+
path,
|
|
53
|
+
detail: cause instanceof Error ? cause.message : String(cause),
|
|
54
|
+
cause
|
|
55
|
+
});
|
|
56
|
+
const skippedPath = (relativePath) => relativePath.split(/[\\/]/u).some((segment) => IGNORED_SEGMENTS.has(segment));
|
|
57
|
+
const pathIsWithin = (paths, root, candidate) => {
|
|
58
|
+
const relative = paths.relative(root, candidate);
|
|
59
|
+
return (relative === "" ||
|
|
60
|
+
(relative !== ".." && !relative.startsWith(`..${paths.sep}`) && !paths.isAbsolute(relative)));
|
|
61
|
+
};
|
|
62
|
+
const posixPath = (relativePath) => relativePath.split(/[\\/]/u).join("/");
|
|
63
|
+
const isTopLevelReadme = (relativePath) => /^README\.mdx?$/iu.test(posixPath(relativePath));
|
|
64
|
+
const isReadme = (relativePath) => /(^|\/)README\.mdx?$/iu.test(posixPath(relativePath));
|
|
65
|
+
const isDocPath = (relativePath) => {
|
|
66
|
+
const posix = posixPath(relativePath);
|
|
67
|
+
if (isReadme(posix))
|
|
68
|
+
return true;
|
|
69
|
+
const segments = posix.split("/");
|
|
70
|
+
const docsIndex = segments.findIndex((segment) => segment.toLowerCase() === "docs");
|
|
71
|
+
if (docsIndex < 0 || docsIndex >= segments.length - 1)
|
|
72
|
+
return false;
|
|
73
|
+
const ext = segments[segments.length - 1]?.toLowerCase();
|
|
74
|
+
return ext !== undefined && (ext.endsWith(".md") || ext.endsWith(".mdx"));
|
|
75
|
+
};
|
|
76
|
+
const skipSurfacePath = (relativePath) => {
|
|
77
|
+
const posix = posixPath(relativePath);
|
|
78
|
+
const segments = posix.split("/");
|
|
79
|
+
if (segments.some((segment) => ["vendor", "generated", "test", "tests", "__tests__"].includes(segment.toLowerCase()))) {
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
const base = segments[segments.length - 1] ?? "";
|
|
83
|
+
return /\.(?:test|spec)\.[cm]?[jt]sx?$/iu.test(base);
|
|
84
|
+
};
|
|
85
|
+
const materialKind = (relativePath) => {
|
|
86
|
+
if (isDocPath(relativePath))
|
|
87
|
+
return "doc";
|
|
88
|
+
const lower = relativePath.toLowerCase();
|
|
89
|
+
if (TEST_NAME.test(lower))
|
|
90
|
+
return "test";
|
|
91
|
+
if (FIXTURE_NAME.test(lower))
|
|
92
|
+
return "fixture";
|
|
93
|
+
if (DATASET_NAME.test(lower))
|
|
94
|
+
return "dataset";
|
|
95
|
+
if (PROMPT_NAME.test(lower))
|
|
96
|
+
return "prompt";
|
|
97
|
+
if (SCHEMA_NAME.test(lower))
|
|
98
|
+
return "schema";
|
|
99
|
+
return undefined;
|
|
100
|
+
};
|
|
101
|
+
const materialRank = (material) => {
|
|
102
|
+
if (isTopLevelReadme(material.path))
|
|
103
|
+
return 0;
|
|
104
|
+
if (material.kind === "doc" && isReadme(material.path))
|
|
105
|
+
return 1;
|
|
106
|
+
if (material.kind === "doc")
|
|
107
|
+
return 2;
|
|
108
|
+
if (material.kind === "prompt")
|
|
109
|
+
return 3;
|
|
110
|
+
if (material.kind === "fixture")
|
|
111
|
+
return 4;
|
|
112
|
+
if (material.kind === "dataset")
|
|
113
|
+
return 5;
|
|
114
|
+
if (material.kind === "schema")
|
|
115
|
+
return 6;
|
|
116
|
+
return 7;
|
|
117
|
+
};
|
|
118
|
+
const surfaceRank = (surface) => {
|
|
119
|
+
const posix = posixPath(surface.path);
|
|
120
|
+
if (isTopLevelReadme(posix))
|
|
121
|
+
return 0;
|
|
122
|
+
if (posix.startsWith("docs/") || posix.includes("/docs/"))
|
|
123
|
+
return 1;
|
|
124
|
+
return 2;
|
|
125
|
+
};
|
|
126
|
+
const compareByPath = (left, right) => posixPath(left).localeCompare(posixPath(right));
|
|
127
|
+
export const inspectRepository = Effect.fn("EvalSetup.inspectRepository")(function* (repositoryRoot) {
|
|
128
|
+
const fs = yield* FileSystem.FileSystem;
|
|
129
|
+
const paths = yield* Path.Path;
|
|
130
|
+
const root = yield* fs
|
|
131
|
+
.realPath(repositoryRoot)
|
|
132
|
+
.pipe(Effect.mapError((cause) => inspectionFailure(repositoryRoot, cause)));
|
|
133
|
+
const surfaces = [];
|
|
134
|
+
const materials = [];
|
|
135
|
+
const pendingDirectories = [{ absolutePath: root, relativePath: "", depth: 0 }];
|
|
136
|
+
const visitedDirectories = new Set([root]);
|
|
137
|
+
let entriesVisited = 0;
|
|
138
|
+
let textFilesConsidered = 0;
|
|
139
|
+
let filesRead = 0;
|
|
140
|
+
let bytesRead = 0;
|
|
141
|
+
let skippedOversizedFiles = 0;
|
|
142
|
+
let truncated = false;
|
|
143
|
+
while (pendingDirectories.length > 0 && !truncated) {
|
|
144
|
+
const directory = pendingDirectories.shift();
|
|
145
|
+
if (directory === undefined)
|
|
146
|
+
break;
|
|
147
|
+
const names = directory.depth === 0
|
|
148
|
+
? yield* fs
|
|
149
|
+
.readDirectory(directory.absolutePath)
|
|
150
|
+
.pipe(Effect.mapError((cause) => inspectionFailure(directory.absolutePath, cause)))
|
|
151
|
+
: yield* fs.readDirectory(directory.absolutePath).pipe(Effect.orElseSucceed(() => []));
|
|
152
|
+
names.sort((left, right) => left.localeCompare(right));
|
|
153
|
+
for (const name of names) {
|
|
154
|
+
if (entriesVisited >= MAX_INSPECTION_ENTRIES) {
|
|
155
|
+
truncated = true;
|
|
156
|
+
break;
|
|
157
|
+
}
|
|
158
|
+
entriesVisited += 1;
|
|
159
|
+
const relativePath = directory.relativePath.length === 0 ? name : paths.join(directory.relativePath, name);
|
|
160
|
+
if (skippedPath(relativePath))
|
|
161
|
+
continue;
|
|
162
|
+
const unresolvedPath = paths.join(directory.absolutePath, name);
|
|
163
|
+
const canonicalOption = yield* fs.realPath(unresolvedPath).pipe(Effect.option);
|
|
164
|
+
if (Option.isNone(canonicalOption))
|
|
165
|
+
continue;
|
|
166
|
+
const canonicalPath = canonicalOption.value;
|
|
167
|
+
if (!pathIsWithin(paths, root, canonicalPath))
|
|
168
|
+
continue;
|
|
169
|
+
const infoOption = yield* fs.stat(canonicalPath).pipe(Effect.option);
|
|
170
|
+
if (Option.isNone(infoOption))
|
|
171
|
+
continue;
|
|
172
|
+
const info = infoOption.value;
|
|
173
|
+
if (info.type === "Directory") {
|
|
174
|
+
if (directory.depth >= MAX_INSPECTION_DEPTH) {
|
|
175
|
+
truncated = true;
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
if (visitedDirectories.has(canonicalPath))
|
|
179
|
+
continue;
|
|
180
|
+
if (visitedDirectories.size >= MAX_INSPECTION_DIRECTORIES) {
|
|
181
|
+
truncated = true;
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
visitedDirectories.add(canonicalPath);
|
|
185
|
+
pendingDirectories.push({
|
|
186
|
+
absolutePath: canonicalPath,
|
|
187
|
+
relativePath,
|
|
188
|
+
depth: directory.depth + 1
|
|
189
|
+
});
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
if (info.type !== "File")
|
|
193
|
+
continue;
|
|
194
|
+
if (!TEXT_EXTENSIONS.has(paths.extname(relativePath).toLowerCase()))
|
|
195
|
+
continue;
|
|
196
|
+
if (textFilesConsidered >= MAX_INSPECTION_FILES) {
|
|
197
|
+
truncated = true;
|
|
198
|
+
break;
|
|
199
|
+
}
|
|
200
|
+
textFilesConsidered += 1;
|
|
201
|
+
const kind = materialKind(relativePath);
|
|
202
|
+
if (kind !== undefined)
|
|
203
|
+
materials.push({ kind, path: relativePath });
|
|
204
|
+
const fileBytes = Number(info.size);
|
|
205
|
+
if (fileBytes > MAX_FILE_BYTES) {
|
|
206
|
+
skippedOversizedFiles += 1;
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
if (bytesRead + fileBytes > MAX_TOTAL_BYTES) {
|
|
210
|
+
skippedOversizedFiles += 1;
|
|
211
|
+
truncated = true;
|
|
212
|
+
break;
|
|
213
|
+
}
|
|
214
|
+
const contentOption = yield* fs.readFileString(canonicalPath).pipe(Effect.option);
|
|
215
|
+
if (Option.isNone(contentOption))
|
|
216
|
+
continue;
|
|
217
|
+
filesRead += 1;
|
|
218
|
+
bytesRead += fileBytes;
|
|
219
|
+
const content = contentOption.value;
|
|
220
|
+
if (skipSurfacePath(relativePath) || !MODEL_CALL.test(content))
|
|
221
|
+
continue;
|
|
222
|
+
const model = MODEL_ID.exec(content)?.[0];
|
|
223
|
+
surfaces.push({
|
|
224
|
+
name: relativePath.replace(/\.[^.]+$/u, ""),
|
|
225
|
+
path: relativePath,
|
|
226
|
+
...(model === undefined ? {} : { model })
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
materials.sort((left, right) => {
|
|
231
|
+
const rank = materialRank(left) - materialRank(right);
|
|
232
|
+
return rank !== 0 ? rank : compareByPath(left.path, right.path);
|
|
233
|
+
});
|
|
234
|
+
surfaces.sort((left, right) => {
|
|
235
|
+
const rank = surfaceRank(left) - surfaceRank(right);
|
|
236
|
+
return rank !== 0 ? rank : compareByPath(left.path, right.path);
|
|
237
|
+
});
|
|
238
|
+
if (surfaces.length === 0 && materials.some((material) => isTopLevelReadme(material.path))) {
|
|
239
|
+
surfaces.push({ name: "repository-docs", path: "README.md" });
|
|
240
|
+
}
|
|
241
|
+
return {
|
|
242
|
+
repositoryRoot: root,
|
|
243
|
+
surfaces,
|
|
244
|
+
materials,
|
|
245
|
+
summary: {
|
|
246
|
+
entriesVisited,
|
|
247
|
+
textFilesConsidered,
|
|
248
|
+
filesRead,
|
|
249
|
+
bytesRead,
|
|
250
|
+
skippedOversizedFiles,
|
|
251
|
+
truncated
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
});
|
|
255
|
+
export const EvalRepositoryInspectorLive = Layer.effect(EvalRepositoryInspector, Effect.gen(function* () {
|
|
256
|
+
const fs = yield* FileSystem.FileSystem;
|
|
257
|
+
const paths = yield* Path.Path;
|
|
258
|
+
return EvalRepositoryInspector.of({
|
|
259
|
+
inspect: (repositoryRoot) => inspectRepository(repositoryRoot).pipe(Effect.provideService(FileSystem.FileSystem, fs), Effect.provideService(Path.Path, paths))
|
|
260
|
+
});
|
|
261
|
+
}));
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export type EvalModelSelection = {
|
|
2
|
+
readonly candidates: readonly [string, string];
|
|
3
|
+
readonly judgeModel: string;
|
|
4
|
+
};
|
|
5
|
+
export declare const assertEvalModelSelection: (candidates: readonly string[], judgeModel: string) => EvalModelSelection;
|
|
6
|
+
export declare const modelSelectionFromAnswer: (answer: string) => EvalModelSelection;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { assertExplicitEvalModel } from "@velum-labs/routekit-eval-contracts";
|
|
2
|
+
const EXPLICIT_MODEL_ID = /\b[A-Za-z0-9][A-Za-z0-9._-]*\/[A-Za-z0-9][A-Za-z0-9._~:-]*\b/gu;
|
|
3
|
+
const FORBIDDEN_ALIAS_SEGMENTS = new Set(["auto", "default", "router"]);
|
|
4
|
+
const assertNotAlias = (model) => {
|
|
5
|
+
const segments = model.toLowerCase().split("/");
|
|
6
|
+
if (segments.some((segment) => FORBIDDEN_ALIAS_SEGMENTS.has(segment))) {
|
|
7
|
+
throw new Error(`eval model must be a concrete provider/model id, not alias ${JSON.stringify(model)}`);
|
|
8
|
+
}
|
|
9
|
+
};
|
|
10
|
+
export const assertEvalModelSelection = (candidates, judgeModel) => {
|
|
11
|
+
if (candidates.length !== 2) {
|
|
12
|
+
throw new Error("provide exactly two candidate model ids");
|
|
13
|
+
}
|
|
14
|
+
const first = candidates[0];
|
|
15
|
+
const second = candidates[1];
|
|
16
|
+
if (first === undefined || second === undefined) {
|
|
17
|
+
throw new Error("provide exactly two candidate model ids");
|
|
18
|
+
}
|
|
19
|
+
assertExplicitEvalModel(first, "candidate");
|
|
20
|
+
assertExplicitEvalModel(second, "candidate");
|
|
21
|
+
assertExplicitEvalModel(judgeModel, "judge");
|
|
22
|
+
assertNotAlias(first);
|
|
23
|
+
assertNotAlias(second);
|
|
24
|
+
assertNotAlias(judgeModel);
|
|
25
|
+
const unique = new Set([first, second, judgeModel].map((model) => model.toLowerCase()));
|
|
26
|
+
if (unique.size !== 3) {
|
|
27
|
+
throw new Error("candidate and judge roles require three unique model ids; the judge must differ from both candidates");
|
|
28
|
+
}
|
|
29
|
+
return { candidates: [first, second], judgeModel };
|
|
30
|
+
};
|
|
31
|
+
export const modelSelectionFromAnswer = (answer) => {
|
|
32
|
+
const modelIds = answer.match(EXPLICIT_MODEL_ID) ?? [];
|
|
33
|
+
if (modelIds.length !== 3) {
|
|
34
|
+
throw new Error("provide exactly three explicit provider/model ids: two candidates followed by one distinct judge");
|
|
35
|
+
}
|
|
36
|
+
return assertEvalModelSelection(modelIds.slice(0, 2), modelIds[2] ?? "");
|
|
37
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Context, Effect, Layer } from "effect";
|
|
2
|
+
import { EvalSetupRunnerError } from "./errors.js";
|
|
3
|
+
import type { OriEvalAuthoringApi } from "./ori-result.js";
|
|
4
|
+
export type OriAuthoringInput = {
|
|
5
|
+
readonly profileId: string;
|
|
6
|
+
readonly repositoryRoot: string;
|
|
7
|
+
};
|
|
8
|
+
export type OriEvalAuthoringShape = {
|
|
9
|
+
readonly withAuthoring: <A>(input: OriAuthoringInput, use: (api: OriEvalAuthoringApi) => Promise<A>) => Effect.Effect<A, EvalSetupRunnerError>;
|
|
10
|
+
};
|
|
11
|
+
declare const OriEvalAuthoring_base: Context.ServiceClass<OriEvalAuthoring, "@velum-labs/routekit-eval-setup/OriEvalAuthoring", OriEvalAuthoringShape>;
|
|
12
|
+
export declare class OriEvalAuthoring extends OriEvalAuthoring_base {
|
|
13
|
+
static layer(service: OriEvalAuthoringShape): Layer.Layer<OriEvalAuthoring, never, never>;
|
|
14
|
+
}
|
|
15
|
+
export declare const oriAuthoringFromApi: (api: OriEvalAuthoringApi) => OriEvalAuthoringShape;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Context, Effect, Layer } from "effect";
|
|
2
|
+
import { EvalSetupRunnerError } from "./errors.js";
|
|
3
|
+
export class OriEvalAuthoring extends Context.Service()("@velum-labs/routekit-eval-setup/OriEvalAuthoring") {
|
|
4
|
+
static layer(service) {
|
|
5
|
+
return Layer.succeed(OriEvalAuthoring, OriEvalAuthoring.of(service));
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
export const oriAuthoringFromApi = (api) => ({
|
|
9
|
+
withAuthoring: (_input, use) => Effect.tryPromise({
|
|
10
|
+
try: () => use(api),
|
|
11
|
+
catch: (cause) => new EvalSetupRunnerError({
|
|
12
|
+
operation: "call Ori authoring",
|
|
13
|
+
detail: cause instanceof Error ? cause.message : String(cause),
|
|
14
|
+
cause
|
|
15
|
+
})
|
|
16
|
+
})
|
|
17
|
+
});
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structural Ori library result. RouteKit setup persists and relays this JSON
|
|
3
|
+
* without importing the eval-engine authoring module.
|
|
4
|
+
*/
|
|
5
|
+
export type OriEvalResult = {
|
|
6
|
+
readonly ok: boolean;
|
|
7
|
+
readonly status?: string;
|
|
8
|
+
readonly runDirectory?: string;
|
|
9
|
+
readonly scratchWorkspace?: string;
|
|
10
|
+
readonly tag?: string;
|
|
11
|
+
readonly prompt?: string;
|
|
12
|
+
readonly question?: string;
|
|
13
|
+
readonly context?: string;
|
|
14
|
+
readonly options?: unknown;
|
|
15
|
+
readonly accepted?: boolean;
|
|
16
|
+
readonly state?: unknown;
|
|
17
|
+
readonly evalRuns?: unknown;
|
|
18
|
+
readonly evalRunTotals?: unknown;
|
|
19
|
+
readonly attemptTotals?: unknown;
|
|
20
|
+
readonly error?: string;
|
|
21
|
+
readonly [key: string]: unknown;
|
|
22
|
+
};
|
|
23
|
+
export type OriEvalAuthoringApi = {
|
|
24
|
+
readonly prepare: (input: {
|
|
25
|
+
readonly repository: string;
|
|
26
|
+
readonly request?: string;
|
|
27
|
+
readonly harness?: "pi" | "claude" | "codex";
|
|
28
|
+
readonly model?: string;
|
|
29
|
+
readonly judgeModel?: string;
|
|
30
|
+
readonly existing?: "resume" | "archive" | "stop";
|
|
31
|
+
}) => Promise<OriEvalResult>;
|
|
32
|
+
readonly run: (input: {
|
|
33
|
+
readonly repository?: string;
|
|
34
|
+
readonly runDirectory?: string;
|
|
35
|
+
}) => Promise<OriEvalResult>;
|
|
36
|
+
readonly answer: (input: {
|
|
37
|
+
readonly answer: string;
|
|
38
|
+
readonly repository?: string;
|
|
39
|
+
readonly runDirectory?: string;
|
|
40
|
+
}) => Promise<OriEvalResult>;
|
|
41
|
+
readonly status: (input: {
|
|
42
|
+
readonly repository?: string;
|
|
43
|
+
readonly runDirectory?: string;
|
|
44
|
+
}) => Promise<OriEvalResult>;
|
|
45
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type RoutingBasis } from "@velum-labs/routekit-eval-contracts";
|
|
2
|
+
import { Context, Effect, FileSystem, Layer, Path } from "effect";
|
|
3
|
+
import { EvalProjectArtifactError } from "./errors.js";
|
|
4
|
+
import { type EvalArtifactApproval, type EvalEvaluationProposal, type EvalExecutionPlan, type EvalRunReport } from "./project-contracts.js";
|
|
5
|
+
export declare function routingBasisDigest(dimensions: RoutingBasis["dimensions"]): string;
|
|
6
|
+
export declare function evaluationProposalDigest(proposal: Omit<EvalEvaluationProposal, "evaluationDigest">): string;
|
|
7
|
+
export type EvalProjectArtifactsShape = {
|
|
8
|
+
readonly loadBasisProposal: (repositoryRoot: string) => Effect.Effect<RoutingBasis | undefined, EvalProjectArtifactError, never>;
|
|
9
|
+
readonly saveBasisProposal: (repositoryRoot: string, basis: RoutingBasis) => Effect.Effect<void, EvalProjectArtifactError, never>;
|
|
10
|
+
readonly loadBasisApproval: (repositoryRoot: string) => Effect.Effect<EvalArtifactApproval | undefined, EvalProjectArtifactError, never>;
|
|
11
|
+
readonly saveBasisApproval: (repositoryRoot: string, approval: EvalArtifactApproval) => Effect.Effect<void, EvalProjectArtifactError, never>;
|
|
12
|
+
readonly loadEvaluationProposal: (repositoryRoot: string) => Effect.Effect<EvalEvaluationProposal | undefined, EvalProjectArtifactError, never>;
|
|
13
|
+
readonly saveEvaluationProposal: (repositoryRoot: string, proposal: EvalEvaluationProposal) => Effect.Effect<void, EvalProjectArtifactError, never>;
|
|
14
|
+
readonly loadEvaluationsApproval: (repositoryRoot: string) => Effect.Effect<EvalArtifactApproval | undefined, EvalProjectArtifactError, never>;
|
|
15
|
+
readonly saveEvaluationsApproval: (repositoryRoot: string, approval: EvalArtifactApproval) => Effect.Effect<void, EvalProjectArtifactError, never>;
|
|
16
|
+
readonly savePlan: (repositoryRoot: string, plan: EvalExecutionPlan) => Effect.Effect<void, EvalProjectArtifactError, never>;
|
|
17
|
+
readonly materializePlanSuites: (repositoryRoot: string, plan: EvalExecutionPlan, proposal: EvalEvaluationProposal) => Effect.Effect<void, EvalProjectArtifactError, never>;
|
|
18
|
+
readonly planSuitePath: (repositoryRoot: string, planId: string, dimensionId: string) => Effect.Effect<string, EvalProjectArtifactError, never>;
|
|
19
|
+
readonly compositionSuitePath: (repositoryRoot: string, planId: string) => Effect.Effect<string, EvalProjectArtifactError, never>;
|
|
20
|
+
readonly loadPlan: (repositoryRoot: string, planId: string) => Effect.Effect<EvalExecutionPlan | undefined, EvalProjectArtifactError, never>;
|
|
21
|
+
readonly listPlans: (repositoryRoot: string) => Effect.Effect<readonly string[], EvalProjectArtifactError, never>;
|
|
22
|
+
readonly saveRunReport: (repositoryRoot: string, report: EvalRunReport) => Effect.Effect<string, EvalProjectArtifactError, never>;
|
|
23
|
+
readonly loadRunReport: (repositoryRoot: string, runId: string) => Effect.Effect<EvalRunReport | undefined, EvalProjectArtifactError, never>;
|
|
24
|
+
readonly listRunReports: (repositoryRoot: string) => Effect.Effect<readonly string[], EvalProjectArtifactError, never>;
|
|
25
|
+
};
|
|
26
|
+
declare const EvalProjectArtifacts_base: Context.ServiceClass<EvalProjectArtifacts, "@velum-labs/routekit-eval-setup/EvalProjectArtifacts", EvalProjectArtifactsShape>;
|
|
27
|
+
export declare class EvalProjectArtifacts extends EvalProjectArtifacts_base {
|
|
28
|
+
}
|
|
29
|
+
export declare const makeFileEvalProjectArtifacts: Effect.Effect<EvalProjectArtifactsShape, never, Path.Path | FileSystem.FileSystem>;
|
|
30
|
+
export declare const EvalProjectArtifactsLive: Layer.Layer<EvalProjectArtifacts, never, Path.Path | FileSystem.FileSystem>;
|
|
31
|
+
export {};
|