mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-10-28 00:02:42 +00:00
* feat: read-only ai sessions on protected workspaces with a use, plan and build picker Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: address local review findings on the use, plan and build picker Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: address CI review findings on use mode and protected sessions Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: hold test-run forms and pending protection lookups to use mode Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * refactor: fetch rules once per send and dedupe helpers and prompt text Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: send role-locked operators to an admin and cover it with an eval Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * feat: count the work mode each session message runs in Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * chore: regenerate the mcp session definitions after merging main Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * feat: rename build to use & build and let the chat ask to switch modes Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix: word a declined mode switch by the switch, not the mode Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * chore: update ee-repo-ref to 55445977dd05c25791388070182c77f4dbc20c0e This commit updates the EE repository reference after PR #915 was merged in windmill-ee-private. Previous ee-repo-ref: 7f7bf7003e356346ce74395af02c5bdf14f38781 New ee-repo-ref: 55445977dd05c25791388070182c77f4dbc20c0e Automated by sync-ee-ref workflow. --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
89 lines
2.4 KiB
TypeScript
89 lines
2.4 KiB
TypeScript
import { readFile } from "node:fs/promises";
|
|
import path from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
import { parse } from "yaml";
|
|
import type {
|
|
CliValidationSpec,
|
|
EvalCase,
|
|
EvalCaseRuntimeSpec,
|
|
EvalMode,
|
|
EvalValidationSpec,
|
|
} from "./types";
|
|
|
|
const REPO_ROOT = fileURLToPath(new URL("../../", import.meta.url));
|
|
const CASES_DIR = path.join(REPO_ROOT, "ai_evals", "cases");
|
|
|
|
interface RawEvalCase {
|
|
id: string;
|
|
prompt: string;
|
|
initial?: string;
|
|
expected?: string;
|
|
validate?: EvalValidationSpec;
|
|
toolExpect?: EvalCase["toolExpect"];
|
|
cliExpect?: CliValidationSpec;
|
|
assistantExpect?: EvalCase["assistantExpect"];
|
|
judgeChecklist?: string[];
|
|
skipJudge?: boolean;
|
|
judgeAssistantText?: boolean;
|
|
runtime?: EvalCaseRuntimeSpec;
|
|
}
|
|
export function getRepoRoot(): string {
|
|
return REPO_ROOT;
|
|
}
|
|
|
|
export function getAiEvalsRoot(): string {
|
|
return path.join(REPO_ROOT, "ai_evals");
|
|
}
|
|
|
|
export async function loadCases(mode: EvalMode): Promise<EvalCase[]> {
|
|
const filePath = path.join(CASES_DIR, `${mode}.yaml`);
|
|
const raw = await readFile(filePath, "utf8");
|
|
const parsed = parse(raw);
|
|
|
|
if (!Array.isArray(parsed)) {
|
|
throw new Error(`Expected ${filePath} to contain a YAML list of cases`);
|
|
}
|
|
|
|
return (parsed as RawEvalCase[]).map((entry) => ({
|
|
id: entry.id,
|
|
prompt: entry.prompt,
|
|
initialPath: resolveFixturePath(entry.initial),
|
|
expectedPath: resolveFixturePath(entry.expected),
|
|
validate: entry.validate,
|
|
toolExpect: entry.toolExpect,
|
|
cliExpect: entry.cliExpect,
|
|
assistantExpect: entry.assistantExpect,
|
|
judgeChecklist: entry.judgeChecklist,
|
|
skipJudge: entry.skipJudge,
|
|
judgeAssistantText: entry.judgeAssistantText,
|
|
runtime: entry.runtime,
|
|
}));
|
|
}
|
|
|
|
export async function loadSelectedCases(
|
|
mode: EvalMode,
|
|
selectedIds: string[]
|
|
): Promise<EvalCase[]> {
|
|
const allCases = await loadCases(mode);
|
|
if (selectedIds.length === 0) {
|
|
return allCases;
|
|
}
|
|
|
|
const caseMap = new Map(allCases.map((entry) => [entry.id, entry]));
|
|
const missing = selectedIds.filter((id) => !caseMap.has(id));
|
|
if (missing.length > 0) {
|
|
throw new Error(
|
|
`Unknown ${mode} case${missing.length === 1 ? "" : "s"}: ${missing.join(", ")}`
|
|
);
|
|
}
|
|
|
|
return selectedIds.map((id) => caseMap.get(id)!);
|
|
}
|
|
|
|
function resolveFixturePath(value: string | undefined): string | undefined {
|
|
if (!value) {
|
|
return undefined;
|
|
}
|
|
return path.isAbsolute(value) ? value : path.join(REPO_ROOT, value);
|
|
}
|