@plune-ai/cairn 0.2.1
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 +674 -0
- package/README.md +181 -0
- package/dist/agent/graph.d.ts +538 -0
- package/dist/agent/graph.d.ts.map +1 -0
- package/dist/agent/graph.js +0 -0
- package/dist/agent/graph.js.map +1 -0
- package/dist/agent/index.d.ts +83 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/agent/index.js +407 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/analyze/index.d.ts +22 -0
- package/dist/analyze/index.d.ts.map +1 -0
- package/dist/analyze/index.js +39 -0
- package/dist/analyze/index.js.map +1 -0
- package/dist/artifacts/index.d.ts +29 -0
- package/dist/artifacts/index.d.ts.map +1 -0
- package/dist/artifacts/index.js +68 -0
- package/dist/artifacts/index.js.map +1 -0
- package/dist/artifacts/report.d.ts +21 -0
- package/dist/artifacts/report.d.ts.map +1 -0
- package/dist/artifacts/report.js +56 -0
- package/dist/artifacts/report.js.map +1 -0
- package/dist/artifacts/testcase-md.d.ts +37 -0
- package/dist/artifacts/testcase-md.d.ts.map +1 -0
- package/dist/artifacts/testcase-md.js +91 -0
- package/dist/artifacts/testcase-md.js.map +1 -0
- package/dist/browser/backends/playwright-cli.d.ts +23 -0
- package/dist/browser/backends/playwright-cli.d.ts.map +1 -0
- package/dist/browser/backends/playwright-cli.js +85 -0
- package/dist/browser/backends/playwright-cli.js.map +1 -0
- package/dist/browser/backends/playwright-lib.d.ts +32 -0
- package/dist/browser/backends/playwright-lib.d.ts.map +1 -0
- package/dist/browser/backends/playwright-lib.js +157 -0
- package/dist/browser/backends/playwright-lib.js.map +1 -0
- package/dist/browser/gateway.d.ts +33 -0
- package/dist/browser/gateway.d.ts.map +1 -0
- package/dist/browser/gateway.js +2 -0
- package/dist/browser/gateway.js.map +1 -0
- package/dist/browser/index.d.ts +15 -0
- package/dist/browser/index.d.ts.map +1 -0
- package/dist/browser/index.js +59 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/browser/types.d.ts +99 -0
- package/dist/browser/types.d.ts.map +1 -0
- package/dist/browser/types.js +6 -0
- package/dist/browser/types.js.map +1 -0
- package/dist/checklist/index.d.ts +24 -0
- package/dist/checklist/index.d.ts.map +1 -0
- package/dist/checklist/index.js +65 -0
- package/dist/checklist/index.js.map +1 -0
- package/dist/cli/branding.d.ts +14 -0
- package/dist/cli/branding.d.ts.map +1 -0
- package/dist/cli/branding.js +14 -0
- package/dist/cli/branding.js.map +1 -0
- package/dist/cli/index.d.ts +12 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +322 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/lex-bot.d.ts +3 -0
- package/dist/cli/lex-bot.d.ts.map +1 -0
- package/dist/cli/lex-bot.js +11 -0
- package/dist/cli/lex-bot.js.map +1 -0
- package/dist/codegen/index.d.ts +36 -0
- package/dist/codegen/index.d.ts.map +1 -0
- package/dist/codegen/index.js +63 -0
- package/dist/codegen/index.js.map +1 -0
- package/dist/codegen/schema.d.ts +14 -0
- package/dist/codegen/schema.d.ts.map +1 -0
- package/dist/codegen/schema.js +9 -0
- package/dist/codegen/schema.js.map +1 -0
- package/dist/config/env.d.ts +18 -0
- package/dist/config/env.d.ts.map +1 -0
- package/dist/config/env.js +42 -0
- package/dist/config/env.js.map +1 -0
- package/dist/config/index.d.ts +11 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +74 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/profiles.d.ts +7 -0
- package/dist/config/profiles.d.ts.map +1 -0
- package/dist/config/profiles.js +28 -0
- package/dist/config/profiles.js.map +1 -0
- package/dist/config/schema.d.ts +91 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +20 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/design/index.d.ts +36 -0
- package/dist/design/index.d.ts.map +1 -0
- package/dist/design/index.js +35 -0
- package/dist/design/index.js.map +1 -0
- package/dist/design/schema.d.ts +109 -0
- package/dist/design/schema.d.ts.map +1 -0
- package/dist/design/schema.js +35 -0
- package/dist/design/schema.js.map +1 -0
- package/dist/eval/collect.d.ts +18 -0
- package/dist/eval/collect.d.ts.map +1 -0
- package/dist/eval/collect.js +53 -0
- package/dist/eval/collect.js.map +1 -0
- package/dist/eval/experiment.d.ts +49 -0
- package/dist/eval/experiment.d.ts.map +1 -0
- package/dist/eval/experiment.js +66 -0
- package/dist/eval/experiment.js.map +1 -0
- package/dist/eval/judge.d.ts +30 -0
- package/dist/eval/judge.d.ts.map +1 -0
- package/dist/eval/judge.js +47 -0
- package/dist/eval/judge.js.map +1 -0
- package/dist/eval/pilot.d.ts +21 -0
- package/dist/eval/pilot.d.ts.map +1 -0
- package/dist/eval/pilot.js +24 -0
- package/dist/eval/pilot.js.map +1 -0
- package/dist/eval/scorers.d.ts +23 -0
- package/dist/eval/scorers.d.ts.map +1 -0
- package/dist/eval/scorers.js +38 -0
- package/dist/eval/scorers.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/knowledge/index.d.ts +7 -0
- package/dist/knowledge/index.d.ts.map +1 -0
- package/dist/knowledge/index.js +39 -0
- package/dist/knowledge/index.js.map +1 -0
- package/dist/llm/factory.d.ts +31 -0
- package/dist/llm/factory.d.ts.map +1 -0
- package/dist/llm/factory.js +48 -0
- package/dist/llm/factory.js.map +1 -0
- package/dist/llm/index.d.ts +5 -0
- package/dist/llm/index.d.ts.map +1 -0
- package/dist/llm/index.js +3 -0
- package/dist/llm/index.js.map +1 -0
- package/dist/llm/structured.d.ts +30 -0
- package/dist/llm/structured.d.ts.map +1 -0
- package/dist/llm/structured.js +58 -0
- package/dist/llm/structured.js.map +1 -0
- package/dist/llm/vision.d.ts +16 -0
- package/dist/llm/vision.d.ts.map +1 -0
- package/dist/llm/vision.js +4 -0
- package/dist/llm/vision.js.map +1 -0
- package/dist/observe/index.d.ts +21 -0
- package/dist/observe/index.d.ts.map +1 -0
- package/dist/observe/index.js +18 -0
- package/dist/observe/index.js.map +1 -0
- package/dist/observe/parse-aria.d.ts +8 -0
- package/dist/observe/parse-aria.d.ts.map +1 -0
- package/dist/observe/parse-aria.js +71 -0
- package/dist/observe/parse-aria.js.map +1 -0
- package/dist/probe/index.d.ts +19 -0
- package/dist/probe/index.d.ts.map +1 -0
- package/dist/probe/index.js +38 -0
- package/dist/probe/index.js.map +1 -0
- package/dist/promote/index.d.ts +6 -0
- package/dist/promote/index.d.ts.map +1 -0
- package/dist/promote/index.js +4 -0
- package/dist/promote/index.js.map +1 -0
- package/dist/promote/promote-case.d.ts +12 -0
- package/dist/promote/promote-case.d.ts.map +1 -0
- package/dist/promote/promote-case.js +103 -0
- package/dist/promote/promote-case.js.map +1 -0
- package/dist/promote/selectors.d.ts +29 -0
- package/dist/promote/selectors.d.ts.map +1 -0
- package/dist/promote/selectors.js +58 -0
- package/dist/promote/selectors.js.map +1 -0
- package/dist/prompts/index.d.ts +32 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/index.js +55 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/prompts/local/identify-elements.d.ts +6 -0
- package/dist/prompts/local/identify-elements.d.ts.map +1 -0
- package/dist/prompts/local/identify-elements.js +21 -0
- package/dist/prompts/local/identify-elements.js.map +1 -0
- package/dist/prompts/local/index.d.ts +3 -0
- package/dist/prompts/local/index.d.ts.map +1 -0
- package/dist/prompts/local/index.js +18 -0
- package/dist/prompts/local/index.js.map +1 -0
- package/dist/prompts/local/judge-checklist-coverage.d.ts +3 -0
- package/dist/prompts/local/judge-checklist-coverage.d.ts.map +1 -0
- package/dist/prompts/local/judge-checklist-coverage.js +11 -0
- package/dist/prompts/local/judge-checklist-coverage.js.map +1 -0
- package/dist/prompts/local/judge-test-cases.d.ts +3 -0
- package/dist/prompts/local/judge-test-cases.d.ts.map +1 -0
- package/dist/prompts/local/judge-test-cases.js +11 -0
- package/dist/prompts/local/judge-test-cases.js.map +1 -0
- package/dist/prompts/local/pilot-review.d.ts +3 -0
- package/dist/prompts/local/pilot-review.d.ts.map +1 -0
- package/dist/prompts/local/pilot-review.js +13 -0
- package/dist/prompts/local/pilot-review.js.map +1 -0
- package/dist/prompts/local/qa-manual-test-designer.d.ts +7 -0
- package/dist/prompts/local/qa-manual-test-designer.d.ts.map +1 -0
- package/dist/prompts/local/qa-manual-test-designer.js +13 -0
- package/dist/prompts/local/qa-manual-test-designer.js.map +1 -0
- package/dist/prompts/local/qa-playwright-ts-writer.d.ts +6 -0
- package/dist/prompts/local/qa-playwright-ts-writer.d.ts.map +1 -0
- package/dist/prompts/local/qa-playwright-ts-writer.js +40 -0
- package/dist/prompts/local/qa-playwright-ts-writer.js.map +1 -0
- package/dist/prompts/local/qa-testcase-from-ui.d.ts +6 -0
- package/dist/prompts/local/qa-testcase-from-ui.d.ts.map +1 -0
- package/dist/prompts/local/qa-testcase-from-ui.js +52 -0
- package/dist/prompts/local/qa-testcase-from-ui.js.map +1 -0
- package/dist/session/index.d.ts +27 -0
- package/dist/session/index.d.ts.map +1 -0
- package/dist/session/index.js +74 -0
- package/dist/session/index.js.map +1 -0
- package/dist/telemetry/index.d.ts +21 -0
- package/dist/telemetry/index.d.ts.map +1 -0
- package/dist/telemetry/index.js +26 -0
- package/dist/telemetry/index.js.map +1 -0
- package/dist/tui/App.d.ts +6 -0
- package/dist/tui/App.d.ts.map +1 -0
- package/dist/tui/App.js +61 -0
- package/dist/tui/App.js.map +1 -0
- package/dist/tui/components/error-boundary.d.ts +17 -0
- package/dist/tui/components/error-boundary.d.ts.map +1 -0
- package/dist/tui/components/error-boundary.js +20 -0
- package/dist/tui/components/error-boundary.js.map +1 -0
- package/dist/tui/components/field.d.ts +10 -0
- package/dist/tui/components/field.d.ts.map +1 -0
- package/dist/tui/components/field.js +8 -0
- package/dist/tui/components/field.js.map +1 -0
- package/dist/tui/components/help.d.ts +5 -0
- package/dist/tui/components/help.d.ts.map +1 -0
- package/dist/tui/components/help.js +7 -0
- package/dist/tui/components/help.js.map +1 -0
- package/dist/tui/components/log-pane.d.ts +6 -0
- package/dist/tui/components/log-pane.d.ts.map +1 -0
- package/dist/tui/components/log-pane.js +10 -0
- package/dist/tui/components/log-pane.js.map +1 -0
- package/dist/tui/components/node-checklist.d.ts +6 -0
- package/dist/tui/components/node-checklist.d.ts.map +1 -0
- package/dist/tui/components/node-checklist.js +9 -0
- package/dist/tui/components/node-checklist.js.map +1 -0
- package/dist/tui/components/pilot-badge.d.ts +6 -0
- package/dist/tui/components/pilot-badge.d.ts.map +1 -0
- package/dist/tui/components/pilot-badge.js +12 -0
- package/dist/tui/components/pilot-badge.js.map +1 -0
- package/dist/tui/components/scores-table.d.ts +6 -0
- package/dist/tui/components/scores-table.d.ts.map +1 -0
- package/dist/tui/components/scores-table.js +9 -0
- package/dist/tui/components/scores-table.js.map +1 -0
- package/dist/tui/components/scrollable-text.d.ts +6 -0
- package/dist/tui/components/scrollable-text.d.ts.map +1 -0
- package/dist/tui/components/scrollable-text.js +22 -0
- package/dist/tui/components/scrollable-text.js.map +1 -0
- package/dist/tui/components/session-picker.d.ts +5 -0
- package/dist/tui/components/session-picker.d.ts.map +1 -0
- package/dist/tui/components/session-picker.js +16 -0
- package/dist/tui/components/session-picker.js.map +1 -0
- package/dist/tui/components/test-case-list.d.ts +7 -0
- package/dist/tui/components/test-case-list.d.ts.map +1 -0
- package/dist/tui/components/test-case-list.js +10 -0
- package/dist/tui/components/test-case-list.js.map +1 -0
- package/dist/tui/hooks/use-run-artifacts.d.ts +14 -0
- package/dist/tui/hooks/use-run-artifacts.d.ts.map +1 -0
- package/dist/tui/hooks/use-run-artifacts.js +37 -0
- package/dist/tui/hooks/use-run-artifacts.js.map +1 -0
- package/dist/tui/hooks/use-runner.d.ts +25 -0
- package/dist/tui/hooks/use-runner.d.ts.map +1 -0
- package/dist/tui/hooks/use-runner.js +116 -0
- package/dist/tui/hooks/use-runner.js.map +1 -0
- package/dist/tui/hooks/use-runs.d.ts +14 -0
- package/dist/tui/hooks/use-runs.d.ts.map +1 -0
- package/dist/tui/hooks/use-runs.js +57 -0
- package/dist/tui/hooks/use-runs.js.map +1 -0
- package/dist/tui/hooks/use-sessions.d.ts +10 -0
- package/dist/tui/hooks/use-sessions.d.ts.map +1 -0
- package/dist/tui/hooks/use-sessions.js +32 -0
- package/dist/tui/hooks/use-sessions.js.map +1 -0
- package/dist/tui/hooks/use-stdout-dimensions.d.ts +3 -0
- package/dist/tui/hooks/use-stdout-dimensions.d.ts.map +1 -0
- package/dist/tui/hooks/use-stdout-dimensions.js +18 -0
- package/dist/tui/hooks/use-stdout-dimensions.js.map +1 -0
- package/dist/tui/index.d.ts +7 -0
- package/dist/tui/index.d.ts.map +1 -0
- package/dist/tui/index.js +13 -0
- package/dist/tui/index.js.map +1 -0
- package/dist/tui/router-context.d.ts +12 -0
- package/dist/tui/router-context.d.ts.map +1 -0
- package/dist/tui/router-context.js +14 -0
- package/dist/tui/router-context.js.map +1 -0
- package/dist/tui/router.d.ts +44 -0
- package/dist/tui/router.d.ts.map +1 -0
- package/dist/tui/router.js +22 -0
- package/dist/tui/router.js.map +1 -0
- package/dist/tui/screens/form-screen.d.ts +7 -0
- package/dist/tui/screens/form-screen.d.ts.map +1 -0
- package/dist/tui/screens/form-screen.js +104 -0
- package/dist/tui/screens/form-screen.js.map +1 -0
- package/dist/tui/screens/launcher-screen.d.ts +2 -0
- package/dist/tui/screens/launcher-screen.d.ts.map +1 -0
- package/dist/tui/screens/launcher-screen.js +28 -0
- package/dist/tui/screens/launcher-screen.js.map +1 -0
- package/dist/tui/screens/run-dashboard-screen.d.ts +7 -0
- package/dist/tui/screens/run-dashboard-screen.d.ts.map +1 -0
- package/dist/tui/screens/run-dashboard-screen.js +32 -0
- package/dist/tui/screens/run-dashboard-screen.js.map +1 -0
- package/dist/tui/screens/run-detail-screen.d.ts +5 -0
- package/dist/tui/screens/run-detail-screen.d.ts.map +1 -0
- package/dist/tui/screens/run-detail-screen.js +67 -0
- package/dist/tui/screens/run-detail-screen.js.map +1 -0
- package/dist/tui/screens/runs-list-screen.d.ts +2 -0
- package/dist/tui/screens/runs-list-screen.d.ts.map +1 -0
- package/dist/tui/screens/runs-list-screen.js +22 -0
- package/dist/tui/screens/runs-list-screen.js.map +1 -0
- package/dist/tui/screens/summary-screen.d.ts +6 -0
- package/dist/tui/screens/summary-screen.d.ts.map +1 -0
- package/dist/tui/screens/summary-screen.js +53 -0
- package/dist/tui/screens/summary-screen.js.map +1 -0
- package/dist/tui/theme.d.ts +31 -0
- package/dist/tui/theme.d.ts.map +1 -0
- package/dist/tui/theme.js +70 -0
- package/dist/tui/theme.js.map +1 -0
- package/dist/tui/types.d.ts +38 -0
- package/dist/tui/types.d.ts.map +1 -0
- package/dist/tui/types.js +2 -0
- package/dist/tui/types.js.map +1 -0
- package/dist/validate/index.d.ts +30 -0
- package/dist/validate/index.d.ts.map +1 -0
- package/dist/validate/index.js +39 -0
- package/dist/validate/index.js.map +1 -0
- package/dist/validate/runner.d.ts +15 -0
- package/dist/validate/runner.d.ts.map +1 -0
- package/dist/validate/runner.js +74 -0
- package/dist/validate/runner.js.map +1 -0
- package/package.json +97 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { BrowserBackendSchema, LlmProfileSchema, ModelsConfigSchema, } from "./schema.js";
|
|
2
|
+
import { PROFILES } from "./profiles.js";
|
|
3
|
+
import { createEnvReader } from "./env.js";
|
|
4
|
+
/**
|
|
5
|
+
* Read and validate configuration from env. Pure function (env is injected for tests).
|
|
6
|
+
* Throws a clear error on an invalid profile/backend or a missing key for a required provider.
|
|
7
|
+
*/
|
|
8
|
+
export function loadConfig(env = process.env, opts = {}) {
|
|
9
|
+
// Resolve every var via CAIRN_ → LEXBOT_/LEX_ (deprecated) → bare name (C0-06).
|
|
10
|
+
const read = createEnvReader(env, opts.warn);
|
|
11
|
+
const llmProfileRaw = read("LLM_PROFILE");
|
|
12
|
+
const profileResult = LlmProfileSchema.safeParse(llmProfileRaw ?? "anthropic");
|
|
13
|
+
if (!profileResult.success) {
|
|
14
|
+
throw new Error(`Invalid LLM_PROFILE='${llmProfileRaw}'. Allowed: anthropic | openrouter | mixed.`);
|
|
15
|
+
}
|
|
16
|
+
const llmProfile = profileResult.data;
|
|
17
|
+
const models = ModelsConfigSchema.parse(PROFILES[llmProfile]);
|
|
18
|
+
// Which providers does this profile actually need?
|
|
19
|
+
const tiers = [models.reasoning, models.bulk, models.judge];
|
|
20
|
+
if (models.vision)
|
|
21
|
+
tiers.push(models.vision);
|
|
22
|
+
const providers = new Set(tiers.map((t) => t.provider));
|
|
23
|
+
const anthropicApiKey = read("ANTHROPIC_API_KEY");
|
|
24
|
+
const openrouterApiKey = read("OPENROUTER_API_KEY");
|
|
25
|
+
if (providers.has("anthropic") && !anthropicApiKey) {
|
|
26
|
+
throw new Error(`Profile '${llmProfile}' uses Anthropic, but ANTHROPIC_API_KEY is not set.`);
|
|
27
|
+
}
|
|
28
|
+
if (providers.has("openrouter") && !openrouterApiKey) {
|
|
29
|
+
throw new Error(`Profile '${llmProfile}' uses OpenRouter, but OPENROUTER_API_KEY is not set.`);
|
|
30
|
+
}
|
|
31
|
+
const browserBackendRaw = read("BROWSER_BACKEND");
|
|
32
|
+
const backendResult = BrowserBackendSchema.safeParse(browserBackendRaw ?? "lib");
|
|
33
|
+
if (!backendResult.success) {
|
|
34
|
+
throw new Error(`Invalid BROWSER_BACKEND='${browserBackendRaw}'. Allowed: lib | cli.`);
|
|
35
|
+
}
|
|
36
|
+
const langfuseBaseUrl = read("LANGFUSE_BASE_URL");
|
|
37
|
+
const langfusePublicKey = read("LANGFUSE_PUBLIC_KEY");
|
|
38
|
+
const langfuseSecretKey = read("LANGFUSE_SECRET_KEY");
|
|
39
|
+
const langfuseEnabled = Boolean(langfuseBaseUrl && langfusePublicKey && langfuseSecretKey);
|
|
40
|
+
const maxRepairRaw = read("MAX_REPAIR");
|
|
41
|
+
const maxRepair = maxRepairRaw === undefined ? 2 : Number(maxRepairRaw);
|
|
42
|
+
if (!Number.isInteger(maxRepair) || maxRepair < 0) {
|
|
43
|
+
throw new Error(`Invalid MAX_REPAIR='${maxRepairRaw}'. Must be a non-negative integer.`);
|
|
44
|
+
}
|
|
45
|
+
// Test-case language: default English; env override accepts a name or a code (en/uk/ua).
|
|
46
|
+
const langRaw = (read("QA_TESTCASE_LANG") ?? "English").trim();
|
|
47
|
+
const LANG_ALIASES = {
|
|
48
|
+
en: "English",
|
|
49
|
+
eng: "English",
|
|
50
|
+
english: "English",
|
|
51
|
+
uk: "Ukrainian",
|
|
52
|
+
ua: "Ukrainian",
|
|
53
|
+
ukr: "Ukrainian",
|
|
54
|
+
ukrainian: "Ukrainian",
|
|
55
|
+
українська: "Ukrainian",
|
|
56
|
+
};
|
|
57
|
+
const testCaseLanguage = LANG_ALIASES[langRaw.toLowerCase()] ?? langRaw;
|
|
58
|
+
return {
|
|
59
|
+
llmProfile,
|
|
60
|
+
models,
|
|
61
|
+
anthropicApiKey,
|
|
62
|
+
openrouterApiKey,
|
|
63
|
+
langfuse: {
|
|
64
|
+
enabled: langfuseEnabled,
|
|
65
|
+
baseUrl: langfuseBaseUrl,
|
|
66
|
+
publicKey: langfusePublicKey,
|
|
67
|
+
secretKey: langfuseSecretKey,
|
|
68
|
+
},
|
|
69
|
+
browser: { backend: backendResult.data, channel: read("BROWSER_CHANNEL") },
|
|
70
|
+
maxRepair,
|
|
71
|
+
testCaseLanguage,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { LlmProfile, ModelsConfig } from "./schema.js";
|
|
2
|
+
/**
|
|
3
|
+
* Default model profiles (ADR-0002). Exact OpenRouter model-ids are confirmed by Spike S6;
|
|
4
|
+
* everything is overridable via custom configuration.
|
|
5
|
+
*/
|
|
6
|
+
export declare const PROFILES: Record<LlmProfile, ModelsConfig>;
|
|
7
|
+
//# sourceMappingURL=profiles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profiles.d.ts","sourceRoot":"","sources":["../../src/config/profiles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE5D;;;GAGG;AACH,eAAO,MAAM,QAAQ,EAAE,MAAM,CAAC,UAAU,EAAE,YAAY,CAsBrD,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default model profiles (ADR-0002). Exact OpenRouter model-ids are confirmed by Spike S6;
|
|
3
|
+
* everything is overridable via custom configuration.
|
|
4
|
+
*/
|
|
5
|
+
export const PROFILES = {
|
|
6
|
+
// Quality, more expensive.
|
|
7
|
+
anthropic: {
|
|
8
|
+
reasoning: { provider: "anthropic", model: "claude-opus-4-8", supportsVision: true },
|
|
9
|
+
bulk: { provider: "anthropic", model: "claude-sonnet-4-6", supportsVision: false },
|
|
10
|
+
judge: { provider: "anthropic", model: "claude-haiku-4-5", supportsVision: false },
|
|
11
|
+
vision: { provider: "anthropic", model: "claude-haiku-4-5", supportsVision: true },
|
|
12
|
+
},
|
|
13
|
+
// Economical: DeepSeek/Qwen. reasoning has no vision → the vision-tier provides Qwen-VL.
|
|
14
|
+
openrouter: {
|
|
15
|
+
reasoning: { provider: "openrouter", model: "deepseek/deepseek-r1", supportsVision: false },
|
|
16
|
+
bulk: { provider: "openrouter", model: "deepseek/deepseek-chat", supportsVision: false },
|
|
17
|
+
judge: { provider: "openrouter", model: "qwen/qwen-2.5-72b-instruct", supportsVision: false },
|
|
18
|
+
vision: { provider: "openrouter", model: "qwen/qwen-2-vl-72b-instruct", supportsVision: true },
|
|
19
|
+
},
|
|
20
|
+
// Balanced: high-quality reasoning+vision on Anthropic, cheap bulk+judge on OpenRouter.
|
|
21
|
+
mixed: {
|
|
22
|
+
reasoning: { provider: "anthropic", model: "claude-opus-4-8", supportsVision: true },
|
|
23
|
+
bulk: { provider: "openrouter", model: "deepseek/deepseek-chat", supportsVision: false },
|
|
24
|
+
judge: { provider: "openrouter", model: "qwen/qwen-2.5-72b-instruct", supportsVision: false },
|
|
25
|
+
vision: { provider: "anthropic", model: "claude-haiku-4-5", supportsVision: true },
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=profiles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profiles.js","sourceRoot":"","sources":["../../src/config/profiles.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAqC;IACxD,2BAA2B;IAC3B,SAAS,EAAE;QACT,SAAS,EAAE,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,IAAI,EAAE;QACpF,IAAI,EAAE,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,mBAAmB,EAAE,cAAc,EAAE,KAAK,EAAE;QAClF,KAAK,EAAE,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,KAAK,EAAE;QAClF,MAAM,EAAE,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,IAAI,EAAE;KACnF;IACD,yFAAyF;IACzF,UAAU,EAAE;QACV,SAAS,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE,KAAK,EAAE,sBAAsB,EAAE,cAAc,EAAE,KAAK,EAAE;QAC3F,IAAI,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE,KAAK,EAAE,wBAAwB,EAAE,cAAc,EAAE,KAAK,EAAE;QACxF,KAAK,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE,KAAK,EAAE,4BAA4B,EAAE,cAAc,EAAE,KAAK,EAAE;QAC7F,MAAM,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE,KAAK,EAAE,6BAA6B,EAAE,cAAc,EAAE,IAAI,EAAE;KAC/F;IACD,wFAAwF;IACxF,KAAK,EAAE;QACL,SAAS,EAAE,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,IAAI,EAAE;QACpF,IAAI,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE,KAAK,EAAE,wBAAwB,EAAE,cAAc,EAAE,KAAK,EAAE;QACxF,KAAK,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE,KAAK,EAAE,4BAA4B,EAAE,cAAc,EAAE,KAAK,EAAE;QAC7F,MAAM,EAAE,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,IAAI,EAAE;KACnF;CACF,CAAC"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/** LLM provider (ADR-0002). */
|
|
3
|
+
export declare const ProviderSchema: z.ZodEnum<{
|
|
4
|
+
anthropic: "anthropic";
|
|
5
|
+
openrouter: "openrouter";
|
|
6
|
+
}>;
|
|
7
|
+
export type Provider = z.infer<typeof ProviderSchema>;
|
|
8
|
+
/** Model settings for a single tier. */
|
|
9
|
+
export declare const ModelTierSchema: z.ZodObject<{
|
|
10
|
+
provider: z.ZodEnum<{
|
|
11
|
+
anthropic: "anthropic";
|
|
12
|
+
openrouter: "openrouter";
|
|
13
|
+
}>;
|
|
14
|
+
model: z.ZodString;
|
|
15
|
+
supportsVision: z.ZodDefault<z.ZodBoolean>;
|
|
16
|
+
temperature: z.ZodOptional<z.ZodNumber>;
|
|
17
|
+
}, z.core.$strip>;
|
|
18
|
+
export type ModelTier = z.infer<typeof ModelTierSchema>;
|
|
19
|
+
/** Mapping tier → model (ADR-0002, see docs/architecture/data-contracts.md). */
|
|
20
|
+
export declare const ModelsConfigSchema: z.ZodObject<{
|
|
21
|
+
reasoning: z.ZodObject<{
|
|
22
|
+
provider: z.ZodEnum<{
|
|
23
|
+
anthropic: "anthropic";
|
|
24
|
+
openrouter: "openrouter";
|
|
25
|
+
}>;
|
|
26
|
+
model: z.ZodString;
|
|
27
|
+
supportsVision: z.ZodDefault<z.ZodBoolean>;
|
|
28
|
+
temperature: z.ZodOptional<z.ZodNumber>;
|
|
29
|
+
}, z.core.$strip>;
|
|
30
|
+
bulk: z.ZodObject<{
|
|
31
|
+
provider: z.ZodEnum<{
|
|
32
|
+
anthropic: "anthropic";
|
|
33
|
+
openrouter: "openrouter";
|
|
34
|
+
}>;
|
|
35
|
+
model: z.ZodString;
|
|
36
|
+
supportsVision: z.ZodDefault<z.ZodBoolean>;
|
|
37
|
+
temperature: z.ZodOptional<z.ZodNumber>;
|
|
38
|
+
}, z.core.$strip>;
|
|
39
|
+
judge: z.ZodObject<{
|
|
40
|
+
provider: z.ZodEnum<{
|
|
41
|
+
anthropic: "anthropic";
|
|
42
|
+
openrouter: "openrouter";
|
|
43
|
+
}>;
|
|
44
|
+
model: z.ZodString;
|
|
45
|
+
supportsVision: z.ZodDefault<z.ZodBoolean>;
|
|
46
|
+
temperature: z.ZodOptional<z.ZodNumber>;
|
|
47
|
+
}, z.core.$strip>;
|
|
48
|
+
vision: z.ZodOptional<z.ZodObject<{
|
|
49
|
+
provider: z.ZodEnum<{
|
|
50
|
+
anthropic: "anthropic";
|
|
51
|
+
openrouter: "openrouter";
|
|
52
|
+
}>;
|
|
53
|
+
model: z.ZodString;
|
|
54
|
+
supportsVision: z.ZodDefault<z.ZodBoolean>;
|
|
55
|
+
temperature: z.ZodOptional<z.ZodNumber>;
|
|
56
|
+
}, z.core.$strip>>;
|
|
57
|
+
}, z.core.$strip>;
|
|
58
|
+
export type ModelsConfig = z.infer<typeof ModelsConfigSchema>;
|
|
59
|
+
export declare const LlmProfileSchema: z.ZodEnum<{
|
|
60
|
+
anthropic: "anthropic";
|
|
61
|
+
openrouter: "openrouter";
|
|
62
|
+
mixed: "mixed";
|
|
63
|
+
}>;
|
|
64
|
+
export type LlmProfile = z.infer<typeof LlmProfileSchema>;
|
|
65
|
+
export declare const BrowserBackendSchema: z.ZodEnum<{
|
|
66
|
+
lib: "lib";
|
|
67
|
+
cli: "cli";
|
|
68
|
+
}>;
|
|
69
|
+
export type BrowserBackend = z.infer<typeof BrowserBackendSchema>;
|
|
70
|
+
export interface LangfuseConfig {
|
|
71
|
+
enabled: boolean;
|
|
72
|
+
baseUrl?: string;
|
|
73
|
+
publicKey?: string;
|
|
74
|
+
secretKey?: string;
|
|
75
|
+
}
|
|
76
|
+
/** Full typed bot configuration. */
|
|
77
|
+
export interface AppConfig {
|
|
78
|
+
llmProfile: LlmProfile;
|
|
79
|
+
models: ModelsConfig;
|
|
80
|
+
anthropicApiKey?: string;
|
|
81
|
+
openrouterApiKey?: string;
|
|
82
|
+
langfuse: LangfuseConfig;
|
|
83
|
+
browser: {
|
|
84
|
+
backend: BrowserBackend;
|
|
85
|
+
channel?: string;
|
|
86
|
+
};
|
|
87
|
+
maxRepair: number;
|
|
88
|
+
/** Language of generated test cases (env QA_TESTCASE_LANG; default "English"). */
|
|
89
|
+
testCaseLanguage: string;
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,+BAA+B;AAC/B,eAAO,MAAM,cAAc;;;EAAsC,CAAC;AAClE,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAEtD,wCAAwC;AACxC,eAAO,MAAM,eAAe;;;;;;;;iBAK1B,CAAC;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAExD,gFAAgF;AAChF,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAK7B,CAAC;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D,eAAO,MAAM,gBAAgB;;;;EAA+C,CAAC;AAC7E,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,eAAO,MAAM,oBAAoB;;;EAAyB,CAAC;AAC3D,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,oCAAoC;AACpC,MAAM,WAAW,SAAS;IACxB,UAAU,EAAE,UAAU,CAAC;IACvB,MAAM,EAAE,YAAY,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,cAAc,CAAC;IACzB,OAAO,EAAE;QAAE,OAAO,EAAE,cAAc,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACvD,SAAS,EAAE,MAAM,CAAC;IAClB,kFAAkF;IAClF,gBAAgB,EAAE,MAAM,CAAC;CAC1B"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/** LLM provider (ADR-0002). */
|
|
3
|
+
export const ProviderSchema = z.enum(["anthropic", "openrouter"]);
|
|
4
|
+
/** Model settings for a single tier. */
|
|
5
|
+
export const ModelTierSchema = z.object({
|
|
6
|
+
provider: ProviderSchema,
|
|
7
|
+
model: z.string().min(1),
|
|
8
|
+
supportsVision: z.boolean().default(false),
|
|
9
|
+
temperature: z.number().optional(),
|
|
10
|
+
});
|
|
11
|
+
/** Mapping tier → model (ADR-0002, see docs/architecture/data-contracts.md). */
|
|
12
|
+
export const ModelsConfigSchema = z.object({
|
|
13
|
+
reasoning: ModelTierSchema, // designTestCases (+ identifyElements if vision)
|
|
14
|
+
bulk: ModelTierSchema, // generateCode
|
|
15
|
+
judge: ModelTierSchema, // LLM-as-judge (SDK-side)
|
|
16
|
+
vision: ModelTierSchema.optional(), // if reasoning has no vision → aria-only fallback
|
|
17
|
+
});
|
|
18
|
+
export const LlmProfileSchema = z.enum(["anthropic", "openrouter", "mixed"]);
|
|
19
|
+
export const BrowserBackendSchema = z.enum(["lib", "cli"]);
|
|
20
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,+BAA+B;AAC/B,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC,CAAC;AAGlE,wCAAwC;AACxC,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC;IACtC,QAAQ,EAAE,cAAc;IACxB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACxB,cAAc,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;IAC1C,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACnC,CAAC,CAAC;AAGH,gFAAgF;AAChF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,SAAS,EAAE,eAAe,EAAE,iDAAiD;IAC7E,IAAI,EAAE,eAAe,EAAE,eAAe;IACtC,KAAK,EAAE,eAAe,EAAE,0BAA0B;IAClD,MAAM,EAAE,eAAe,CAAC,QAAQ,EAAE,EAAE,kDAAkD;CACvF,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC;AAG7E,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { StructuredInvoke } from "../llm/structured.js";
|
|
2
|
+
import type { PromptRegistry } from "../prompts/index.js";
|
|
3
|
+
import type { PageStudy } from "../observe/index.js";
|
|
4
|
+
import type { VerifiedElement } from "../browser/types.js";
|
|
5
|
+
import { type Transition } from "../probe/index.js";
|
|
6
|
+
import { type TestCase } from "./schema.js";
|
|
7
|
+
export type { TestCase, DesignedCase } from "./schema.js";
|
|
8
|
+
export { DesignedCaseSchema, DesignResultSchema, TestTechniqueSchema, TestPrioritySchema, } from "./schema.js";
|
|
9
|
+
export interface DesignInput {
|
|
10
|
+
study: PageStudy;
|
|
11
|
+
pageSemantics: string;
|
|
12
|
+
/** Checklist text (Sprint 4); currently empty. */
|
|
13
|
+
checklistText?: string;
|
|
14
|
+
/** Discovered elements (count≥1) from verify; fallback — study.elements. */
|
|
15
|
+
elements?: VerifiedElement[];
|
|
16
|
+
/** Observed state transitions (act→observe, Stage B). */
|
|
17
|
+
transitions?: Transition[];
|
|
18
|
+
/** Domain knowledge (credentials, validation rules) — URL-matched knowledge files. */
|
|
19
|
+
knowledge?: string;
|
|
20
|
+
/** Few-shot from experience: previously stable cases (experience-tracker). */
|
|
21
|
+
experience?: string;
|
|
22
|
+
/** Planning style for the run (happy/negative/coverage). */
|
|
23
|
+
style?: string;
|
|
24
|
+
/** Case language (default "English"). */
|
|
25
|
+
language?: string;
|
|
26
|
+
}
|
|
27
|
+
export interface DesignDeps {
|
|
28
|
+
invoke: StructuredInvoke;
|
|
29
|
+
prompts: PromptRegistry;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Generate test cases from the page using the ISO 29119-4 methodology.
|
|
33
|
+
* Grounding: elementRefs are filtered down to those actually present in study (anti-hallucination).
|
|
34
|
+
*/
|
|
35
|
+
export declare function designTestCases(input: DesignInput, deps: DesignDeps): Promise<TestCase[]>;
|
|
36
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/design/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAqB,KAAK,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAAsB,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEhE,YAAY,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAErB,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,SAAS,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,kDAAkD;IAClD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,eAAe,EAAE,CAAC;IAC7B,yDAAyD;IACzD,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;IAC3B,sFAAsF;IACtF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8EAA8E;IAC9E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4DAA4D;IAC5D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yCAAyC;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,gBAAgB,CAAC;IACzB,OAAO,EAAE,cAAc,CAAC;CACzB;AAED;;;GAGG;AACH,wBAAsB,eAAe,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CAgC/F"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { HumanMessage } from "@langchain/core/messages";
|
|
2
|
+
import { formatTransitions } from "../probe/index.js";
|
|
3
|
+
import { DesignResultSchema } from "./schema.js";
|
|
4
|
+
export { DesignedCaseSchema, DesignResultSchema, TestTechniqueSchema, TestPrioritySchema, } from "./schema.js";
|
|
5
|
+
/**
|
|
6
|
+
* Generate test cases from the page using the ISO 29119-4 methodology.
|
|
7
|
+
* Grounding: elementRefs are filtered down to those actually present in study (anti-hallucination).
|
|
8
|
+
*/
|
|
9
|
+
export async function designTestCases(input, deps) {
|
|
10
|
+
const methodology = (await deps.prompts.getPrompt("qa-manual-test-designer")).text;
|
|
11
|
+
const els = input.elements ?? input.study.elements.map((e) => ({ ...e, count: 1, verified: true }));
|
|
12
|
+
const elements = els
|
|
13
|
+
.filter((e) => e.interactive)
|
|
14
|
+
.map((e) => `${e.ref} · ${e.role}${e.name ? ` "${e.name}"` : ""}${e.count > 1 ? ` (×${e.count} — repeated, .first())` : ""}${e.viaSwitcher ? ` [behind tab "${e.viaSwitcher.name ?? ""}"]` : ""}`)
|
|
15
|
+
.join("\n");
|
|
16
|
+
const prompt = await deps.prompts.getPrompt("qa-testcase-from-ui", {
|
|
17
|
+
pageSemantics: input.pageSemantics,
|
|
18
|
+
elements,
|
|
19
|
+
methodology,
|
|
20
|
+
checklist: input.checklistText ?? "",
|
|
21
|
+
transitions: formatTransitions(input.transitions ?? []),
|
|
22
|
+
language: input.language ?? "English",
|
|
23
|
+
knowledge: input.knowledge ?? "",
|
|
24
|
+
experience: input.experience ?? "",
|
|
25
|
+
style: input.style ?? "",
|
|
26
|
+
});
|
|
27
|
+
const result = await deps.invoke(DesignResultSchema, [new HumanMessage(prompt.text)]);
|
|
28
|
+
const known = new Set(els.map((e) => e.ref));
|
|
29
|
+
return result.testCases.map((c, i) => ({
|
|
30
|
+
...c,
|
|
31
|
+
id: `tc-${i + 1}`,
|
|
32
|
+
elementRefs: c.elementRefs.filter((r) => known.has(r)),
|
|
33
|
+
}));
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/design/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAKxD,OAAO,EAAE,iBAAiB,EAAmB,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAAE,kBAAkB,EAAiB,MAAM,aAAa,CAAC;AAGhE,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,aAAa,CAAC;AA0BrB;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,KAAkB,EAAE,IAAgB;IACxE,MAAM,WAAW,GAAG,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,yBAAyB,CAAC,CAAC,CAAC,IAAI,CAAC;IACnF,MAAM,GAAG,GACP,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAC1F,MAAM,QAAQ,GAAG,GAAG;SACjB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC;SAC5B,GAAG,CACF,CAAC,CAAC,EAAE,EAAE,CACJ,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,wBAAwB,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,WAAW,CAAC,IAAI,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CACxL;SACA,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,qBAAqB,EAAE;QACjE,aAAa,EAAE,KAAK,CAAC,aAAa;QAClC,QAAQ;QACR,WAAW;QACX,SAAS,EAAE,KAAK,CAAC,aAAa,IAAI,EAAE;QACpC,WAAW,EAAE,iBAAiB,CAAC,KAAK,CAAC,WAAW,IAAI,EAAE,CAAC;QACvD,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,SAAS;QACrC,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,EAAE;QAChC,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,EAAE;QAClC,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,EAAE;KACzB,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,kBAAkB,EAAE,CAAC,IAAI,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAEtF,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7C,OAAO,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QACrC,GAAG,CAAC;QACJ,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE;QACjB,WAAW,EAAE,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;KACvD,CAAC,CAAC,CAAC;AACN,CAAC"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/** ISO/IEC/IEEE 29119-4 techniques. */
|
|
3
|
+
export declare const TestTechniqueSchema: z.ZodEnum<{
|
|
4
|
+
"equivalence-partitioning": "equivalence-partitioning";
|
|
5
|
+
"boundary-value": "boundary-value";
|
|
6
|
+
"decision-table": "decision-table";
|
|
7
|
+
"state-transition": "state-transition";
|
|
8
|
+
exploratory: "exploratory";
|
|
9
|
+
"error-guessing": "error-guessing";
|
|
10
|
+
}>;
|
|
11
|
+
export declare const TestPrioritySchema: z.ZodEnum<{
|
|
12
|
+
low: "low";
|
|
13
|
+
medium: "medium";
|
|
14
|
+
high: "high";
|
|
15
|
+
critical: "critical";
|
|
16
|
+
}>;
|
|
17
|
+
/** Case kind: static = read-only check (visibility/state); active = with actions (click/fill/navigation). */
|
|
18
|
+
export declare const TestKindSchema: z.ZodEnum<{
|
|
19
|
+
static: "static";
|
|
20
|
+
active: "active";
|
|
21
|
+
}>;
|
|
22
|
+
/** Scenario nature: Positive (valid path) | Negative (invalid/erroneous). */
|
|
23
|
+
export declare const TestTypeSchema: z.ZodEnum<{
|
|
24
|
+
Positive: "Positive";
|
|
25
|
+
Negative: "Negative";
|
|
26
|
+
}>;
|
|
27
|
+
/**
|
|
28
|
+
* Execution: auto = the bot can reliably automate (read-only, verified locators) → ATC;
|
|
29
|
+
* manual = manual (full generation/submit, security/XSS, UI-UX/visual, irreversible actions) → MTC, NOT automated.
|
|
30
|
+
*/
|
|
31
|
+
export declare const TestExecutionSchema: z.ZodEnum<{
|
|
32
|
+
auto: "auto";
|
|
33
|
+
manual: "manual";
|
|
34
|
+
}>;
|
|
35
|
+
/** A case as returned by the LLM (without id — we assign the id ourselves). */
|
|
36
|
+
export declare const DesignedCaseSchema: z.ZodObject<{
|
|
37
|
+
title: z.ZodString;
|
|
38
|
+
technique: z.ZodEnum<{
|
|
39
|
+
"equivalence-partitioning": "equivalence-partitioning";
|
|
40
|
+
"boundary-value": "boundary-value";
|
|
41
|
+
"decision-table": "decision-table";
|
|
42
|
+
"state-transition": "state-transition";
|
|
43
|
+
exploratory: "exploratory";
|
|
44
|
+
"error-guessing": "error-guessing";
|
|
45
|
+
}>;
|
|
46
|
+
kind: z.ZodDefault<z.ZodEnum<{
|
|
47
|
+
static: "static";
|
|
48
|
+
active: "active";
|
|
49
|
+
}>>;
|
|
50
|
+
type: z.ZodDefault<z.ZodEnum<{
|
|
51
|
+
Positive: "Positive";
|
|
52
|
+
Negative: "Negative";
|
|
53
|
+
}>>;
|
|
54
|
+
execution: z.ZodDefault<z.ZodEnum<{
|
|
55
|
+
auto: "auto";
|
|
56
|
+
manual: "manual";
|
|
57
|
+
}>>;
|
|
58
|
+
preconditions: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
59
|
+
steps: z.ZodArray<z.ZodString>;
|
|
60
|
+
expected: z.ZodString;
|
|
61
|
+
priority: z.ZodEnum<{
|
|
62
|
+
low: "low";
|
|
63
|
+
medium: "medium";
|
|
64
|
+
high: "high";
|
|
65
|
+
critical: "critical";
|
|
66
|
+
}>;
|
|
67
|
+
elementRefs: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
68
|
+
}, z.core.$strip>;
|
|
69
|
+
export type DesignedCase = z.infer<typeof DesignedCaseSchema>;
|
|
70
|
+
export declare const DesignResultSchema: z.ZodObject<{
|
|
71
|
+
testCases: z.ZodArray<z.ZodObject<{
|
|
72
|
+
title: z.ZodString;
|
|
73
|
+
technique: z.ZodEnum<{
|
|
74
|
+
"equivalence-partitioning": "equivalence-partitioning";
|
|
75
|
+
"boundary-value": "boundary-value";
|
|
76
|
+
"decision-table": "decision-table";
|
|
77
|
+
"state-transition": "state-transition";
|
|
78
|
+
exploratory: "exploratory";
|
|
79
|
+
"error-guessing": "error-guessing";
|
|
80
|
+
}>;
|
|
81
|
+
kind: z.ZodDefault<z.ZodEnum<{
|
|
82
|
+
static: "static";
|
|
83
|
+
active: "active";
|
|
84
|
+
}>>;
|
|
85
|
+
type: z.ZodDefault<z.ZodEnum<{
|
|
86
|
+
Positive: "Positive";
|
|
87
|
+
Negative: "Negative";
|
|
88
|
+
}>>;
|
|
89
|
+
execution: z.ZodDefault<z.ZodEnum<{
|
|
90
|
+
auto: "auto";
|
|
91
|
+
manual: "manual";
|
|
92
|
+
}>>;
|
|
93
|
+
preconditions: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
94
|
+
steps: z.ZodArray<z.ZodString>;
|
|
95
|
+
expected: z.ZodString;
|
|
96
|
+
priority: z.ZodEnum<{
|
|
97
|
+
low: "low";
|
|
98
|
+
medium: "medium";
|
|
99
|
+
high: "high";
|
|
100
|
+
critical: "critical";
|
|
101
|
+
}>;
|
|
102
|
+
elementRefs: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
103
|
+
}, z.core.$strip>>;
|
|
104
|
+
}, z.core.$strip>;
|
|
105
|
+
/** Final test case with an assigned id. */
|
|
106
|
+
export interface TestCase extends DesignedCase {
|
|
107
|
+
id: string;
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/design/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,uCAAuC;AACvC,eAAO,MAAM,mBAAmB;;;;;;;EAO9B,CAAC;AAEH,eAAO,MAAM,kBAAkB;;;;;EAAgD,CAAC;AAEhF,6GAA6G;AAC7G,eAAO,MAAM,cAAc;;;EAA+B,CAAC;AAE3D,6EAA6E;AAC7E,eAAO,MAAM,cAAc;;;EAAmC,CAAC;AAE/D;;;GAGG;AACH,eAAO,MAAM,mBAAmB;;;EAA6B,CAAC;AAE9D,+EAA+E;AAC/E,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAW7B,CAAC;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAuD,CAAC;AAEvF,2CAA2C;AAC3C,MAAM,WAAW,QAAS,SAAQ,YAAY;IAC5C,EAAE,EAAE,MAAM,CAAC;CACZ"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/** ISO/IEC/IEEE 29119-4 techniques. */
|
|
3
|
+
export const TestTechniqueSchema = z.enum([
|
|
4
|
+
"equivalence-partitioning",
|
|
5
|
+
"boundary-value",
|
|
6
|
+
"decision-table",
|
|
7
|
+
"state-transition",
|
|
8
|
+
"exploratory",
|
|
9
|
+
"error-guessing",
|
|
10
|
+
]);
|
|
11
|
+
export const TestPrioritySchema = z.enum(["low", "medium", "high", "critical"]);
|
|
12
|
+
/** Case kind: static = read-only check (visibility/state); active = with actions (click/fill/navigation). */
|
|
13
|
+
export const TestKindSchema = z.enum(["static", "active"]);
|
|
14
|
+
/** Scenario nature: Positive (valid path) | Negative (invalid/erroneous). */
|
|
15
|
+
export const TestTypeSchema = z.enum(["Positive", "Negative"]);
|
|
16
|
+
/**
|
|
17
|
+
* Execution: auto = the bot can reliably automate (read-only, verified locators) → ATC;
|
|
18
|
+
* manual = manual (full generation/submit, security/XSS, UI-UX/visual, irreversible actions) → MTC, NOT automated.
|
|
19
|
+
*/
|
|
20
|
+
export const TestExecutionSchema = z.enum(["auto", "manual"]);
|
|
21
|
+
/** A case as returned by the LLM (without id — we assign the id ourselves). */
|
|
22
|
+
export const DesignedCaseSchema = z.object({
|
|
23
|
+
title: z.string(),
|
|
24
|
+
technique: TestTechniqueSchema,
|
|
25
|
+
kind: TestKindSchema.default("static"),
|
|
26
|
+
type: TestTypeSchema.default("Positive"),
|
|
27
|
+
execution: TestExecutionSchema.default("auto"),
|
|
28
|
+
preconditions: z.array(z.string()).default([]),
|
|
29
|
+
steps: z.array(z.string()),
|
|
30
|
+
expected: z.string(),
|
|
31
|
+
priority: TestPrioritySchema,
|
|
32
|
+
elementRefs: z.array(z.string()).default([]),
|
|
33
|
+
});
|
|
34
|
+
export const DesignResultSchema = z.object({ testCases: z.array(DesignedCaseSchema) });
|
|
35
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/design/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,uCAAuC;AACvC,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,IAAI,CAAC;IACxC,0BAA0B;IAC1B,gBAAgB;IAChB,gBAAgB;IAChB,kBAAkB;IAClB,aAAa;IACb,gBAAgB;CACjB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;AAEhF,6GAA6G;AAC7G,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;AAE3D,6EAA6E;AAC7E,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC;AAE/D;;;GAGG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;AAE9D,+EAA+E;AAC/E,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,SAAS,EAAE,mBAAmB;IAC9B,IAAI,EAAE,cAAc,CAAC,OAAO,CAAC,QAAQ,CAAC;IACtC,IAAI,EAAE,cAAc,CAAC,OAAO,CAAC,UAAU,CAAC;IACxC,SAAS,EAAE,mBAAmB,CAAC,OAAO,CAAC,MAAM,CAAC;IAC9C,aAAa,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IAC9C,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IAC1B,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;IACpB,QAAQ,EAAE,kBAAkB;IAC5B,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CAC7C,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** Summary of a prior run (from runs/<id>/report.json). */
|
|
2
|
+
export interface PriorRun {
|
|
3
|
+
runId: string;
|
|
4
|
+
url: string;
|
|
5
|
+
greenRatio: number;
|
|
6
|
+
passedTests: string[];
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Collect prior runs of the same URL from local artifacts (runs/<id>/report.json),
|
|
10
|
+
* sorted by greenRatio (best first). A source of self-improvement at the RESULTS level.
|
|
11
|
+
* (The production path is querying traces/scores from Langfuse by URL metadata; here it's a local trail.)
|
|
12
|
+
*/
|
|
13
|
+
export declare function collectPriorRuns(runsBaseDir: string, url: string): Promise<PriorRun[]>;
|
|
14
|
+
/** All tests that EVER passed for the URL (union of the best across runs). */
|
|
15
|
+
export declare function unionPassedTitles(runs: PriorRun[]): string[];
|
|
16
|
+
/** Few-shot from experience: a "previously stable cases" block for the design prompt (experience-tracker). Empty → "". */
|
|
17
|
+
export declare function formatExperience(titles: string[]): string;
|
|
18
|
+
//# sourceMappingURL=collect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collect.d.ts","sourceRoot":"","sources":["../../src/eval/collect.ts"],"names":[],"mappings":"AAGA,2DAA2D;AAC3D,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAOD;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CA2B5F;AAED,8EAA8E;AAC9E,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,MAAM,EAAE,CAI5D;AAED,0HAA0H;AAC1H,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAMzD"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { readdir, readFile } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
/**
|
|
4
|
+
* Collect prior runs of the same URL from local artifacts (runs/<id>/report.json),
|
|
5
|
+
* sorted by greenRatio (best first). A source of self-improvement at the RESULTS level.
|
|
6
|
+
* (The production path is querying traces/scores from Langfuse by URL metadata; here it's a local trail.)
|
|
7
|
+
*/
|
|
8
|
+
export async function collectPriorRuns(runsBaseDir, url) {
|
|
9
|
+
let dirs = [];
|
|
10
|
+
try {
|
|
11
|
+
dirs = await readdir(runsBaseDir);
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return [];
|
|
15
|
+
}
|
|
16
|
+
const out = [];
|
|
17
|
+
for (const dir of dirs) {
|
|
18
|
+
try {
|
|
19
|
+
const raw = await readFile(join(runsBaseDir, dir, "report.json"), "utf8");
|
|
20
|
+
const rep = JSON.parse(raw);
|
|
21
|
+
if (rep.url !== url)
|
|
22
|
+
continue;
|
|
23
|
+
out.push({
|
|
24
|
+
runId: dir,
|
|
25
|
+
url,
|
|
26
|
+
greenRatio: rep.validation?.greenRatio ?? 0,
|
|
27
|
+
passedTests: (rep.validation?.results ?? [])
|
|
28
|
+
.filter((r) => r.status === "passed")
|
|
29
|
+
.map((r) => r.test),
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
// not a run / unreadable — skip
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return out.sort((a, b) => b.greenRatio - a.greenRatio);
|
|
37
|
+
}
|
|
38
|
+
/** All tests that EVER passed for the URL (union of the best across runs). */
|
|
39
|
+
export function unionPassedTitles(runs) {
|
|
40
|
+
const set = new Set();
|
|
41
|
+
for (const r of runs)
|
|
42
|
+
for (const t of r.passedTests)
|
|
43
|
+
set.add(t);
|
|
44
|
+
return [...set];
|
|
45
|
+
}
|
|
46
|
+
/** Few-shot from experience: a "previously stable cases" block for the design prompt (experience-tracker). Empty → "". */
|
|
47
|
+
export function formatExperience(titles) {
|
|
48
|
+
if (titles.length === 0)
|
|
49
|
+
return "";
|
|
50
|
+
return ("Previously STABLE cases for this URL (past runs) — reuse/extend, do NOT duplicate:\n" +
|
|
51
|
+
titles.map((t) => `- ${t}`).join("\n"));
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=collect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collect.js","sourceRoot":"","sources":["../../src/eval/collect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAejC;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,WAAmB,EAAE,GAAW;IACrE,IAAI,IAAI,GAAa,EAAE,CAAC;IACxB,IAAI,CAAC;QACH,IAAI,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC;IACpC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,GAAG,GAAe,EAAE,CAAC;IAC3B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,EAAE,aAAa,CAAC,EAAE,MAAM,CAAC,CAAC;YAC1E,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAgB,CAAC;YAC3C,IAAI,GAAG,CAAC,GAAG,KAAK,GAAG;gBAAE,SAAS;YAC9B,GAAG,CAAC,IAAI,CAAC;gBACP,KAAK,EAAE,GAAG;gBACV,GAAG;gBACH,UAAU,EAAE,GAAG,CAAC,UAAU,EAAE,UAAU,IAAI,CAAC;gBAC3C,WAAW,EAAE,CAAC,GAAG,CAAC,UAAU,EAAE,OAAO,IAAI,EAAE,CAAC;qBACzC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC;qBACpC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;aACtB,CAAC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACP,gCAAgC;QAClC,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC;AACzD,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,iBAAiB,CAAC,IAAgB;IAChD,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,KAAK,MAAM,CAAC,IAAI,IAAI;QAAE,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,WAAW;YAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAChE,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC;AAClB,CAAC;AAED,0HAA0H;AAC1H,MAAM,UAAU,gBAAgB,CAAC,MAAgB;IAC/C,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACnC,OAAO,CACL,sFAAsF;QACtF,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CACvC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { PageStudy } from "../observe/index.js";
|
|
2
|
+
import type { StructuredInvoke } from "../llm/structured.js";
|
|
3
|
+
import type { PromptRegistry } from "../prompts/index.js";
|
|
4
|
+
import type { VerifiedElement } from "../browser/types.js";
|
|
5
|
+
/** A dataset item for an experiment (a pre-captured observation). */
|
|
6
|
+
export interface DatasetItem {
|
|
7
|
+
id: string;
|
|
8
|
+
study: PageStudy;
|
|
9
|
+
pageSemantics: string;
|
|
10
|
+
verified?: VerifiedElement[];
|
|
11
|
+
}
|
|
12
|
+
/** A prompt version to compare (same invoke, different PromptRegistry). */
|
|
13
|
+
export interface Variant {
|
|
14
|
+
label: string;
|
|
15
|
+
prompts: PromptRegistry;
|
|
16
|
+
}
|
|
17
|
+
export interface ExperimentDeps {
|
|
18
|
+
designInvoke: StructuredInvoke;
|
|
19
|
+
judgeInvoke?: StructuredInvoke;
|
|
20
|
+
}
|
|
21
|
+
export interface VariantResult {
|
|
22
|
+
label: string;
|
|
23
|
+
meanScores: Record<string, number>;
|
|
24
|
+
itemCount: number;
|
|
25
|
+
}
|
|
26
|
+
export interface ExperimentVerdict {
|
|
27
|
+
target: string;
|
|
28
|
+
baseline: string;
|
|
29
|
+
candidate: string;
|
|
30
|
+
delta: number;
|
|
31
|
+
improved: boolean;
|
|
32
|
+
guardrailRegressions: string[];
|
|
33
|
+
}
|
|
34
|
+
export interface ExperimentResult {
|
|
35
|
+
perVariant: VariantResult[];
|
|
36
|
+
verdict?: ExperimentVerdict;
|
|
37
|
+
}
|
|
38
|
+
export interface ExperimentOptions {
|
|
39
|
+
target?: string;
|
|
40
|
+
threshold?: number;
|
|
41
|
+
tolerance?: number;
|
|
42
|
+
guardrails?: string[];
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Run dataset × prompt versions through the design stage, average the metrics, and produce a verdict
|
|
46
|
+
* (B2 self-improvement). A verdict is produced only for two variants: baseline (first) vs candidate (second).
|
|
47
|
+
*/
|
|
48
|
+
export declare function runExperiment(items: DatasetItem[], variants: Variant[], deps: ExperimentDeps, opts?: ExperimentOptions): Promise<ExperimentResult>;
|
|
49
|
+
//# sourceMappingURL=experiment.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"experiment.d.ts","sourceRoot":"","sources":["../../src/eval/experiment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAK3D,qEAAqE;AACrE,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,SAAS,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,eAAe,EAAE,CAAC;CAC9B;AAED,2EAA2E;AAC3E,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,cAAc,CAAC;CACzB;AAED,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,gBAAgB,CAAC;IAC/B,WAAW,CAAC,EAAE,gBAAgB,CAAC;CAChC;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,OAAO,CAAC;IAClB,oBAAoB,EAAE,MAAM,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,aAAa,EAAE,CAAC;IAC5B,OAAO,CAAC,EAAE,iBAAiB,CAAC;CAC7B;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED;;;GAGG;AACH,wBAAsB,aAAa,CACjC,KAAK,EAAE,WAAW,EAAE,EACpB,QAAQ,EAAE,OAAO,EAAE,EACnB,IAAI,EAAE,cAAc,EACpB,IAAI,GAAE,iBAAsB,GAC3B,OAAO,CAAC,gBAAgB,CAAC,CAgE3B"}
|