adaptive-memory-multi-model-router 2.10.0 → 2.12.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.
Files changed (38) hide show
  1. package/.github/workflows/ci.yml +56 -0
  2. package/LANDING.md +46 -0
  3. package/MANIFESTO.md +54 -0
  4. package/demo.sh +85 -0
  5. package/dist/cli/setupWizard.js +194 -0
  6. package/dist/cli.js +9 -2
  7. package/dist/routing/providerRetry.d.ts +5 -0
  8. package/dist/routing/providerRetry.js +37 -0
  9. package/dist/routing/providerRetry.js.map +1 -1
  10. package/docs/CHINESE_PROVIDER_RELIABILITY.md +37 -0
  11. package/docs/CLAIMS_AND_EVIDENCE.md +58 -0
  12. package/docs/ENGINEERING_SPEC.md +55 -0
  13. package/docs/RELEASE_CHECKLIST.md +32 -0
  14. package/docs/REPRODUCIBILITY.md +63 -0
  15. package/eval/README.md +46 -0
  16. package/eval/baselines/main.json +12 -0
  17. package/eval/benchmark_dataset.jsonl +16 -0
  18. package/eval/check_golden_routes.js +64 -0
  19. package/eval/datasets/catalog.json +33 -0
  20. package/eval/datasets/slices/cn_provider_reliability_v1.jsonl +3 -0
  21. package/eval/datasets/slices/cost_pressure_v1.jsonl +3 -0
  22. package/eval/datasets/slices/safety_guardrails_v1.jsonl +3 -0
  23. package/eval/fault_injection_thresholds.json +3 -0
  24. package/eval/generate_report.js +128 -0
  25. package/eval/golden_routes.json +114 -0
  26. package/eval/lib/experiment_registry.js +24 -0
  27. package/eval/run_eval.js +197 -0
  28. package/eval/run_fault_injection.js +201 -0
  29. package/eval/run_shadow_eval.js +85 -0
  30. package/eval/thresholds.json +9 -0
  31. package/package.json +541 -458
  32. package/pytest.ini +2 -0
  33. package/src/cli/setupWizard.ts +194 -0
  34. package/src/routing/providerRetry.ts +41 -1
  35. package/python/a3m/__pycache__/__init__.cpython-312.pyc +0 -0
  36. package/python/a3m/__pycache__/client.cpython-312.pyc +0 -0
  37. package/python/a3m/__pycache__/models.cpython-312.pyc +0 -0
  38. package/python/a3m/__pycache__/sync_client.cpython-312.pyc +0 -0
@@ -0,0 +1,55 @@
1
+ # A3M Engineering Spec (Canonical)
2
+
3
+ This is the canonical engineering behavior spec for A3M Router.
4
+ Marketing and launch content are non-canonical; if there is a conflict, this file wins.
5
+
6
+ ## Core Routing Contract
7
+
8
+ - Input: `routeQuery(prompt: string, available_models?: string[], budget_multiplier?: number)`
9
+ - Output:
10
+ - `primary_model`
11
+ - `fallback_models`
12
+ - `confidence`
13
+ - `estimated_cost`
14
+ - `estimated_latency_ms`
15
+ - `features` (complexity + flags + domain)
16
+ - `provider_type`
17
+
18
+ ## Reliability Components
19
+
20
+ - Retry handling:
21
+ - `ProviderRetryHandler` supports transient retries, backoff+jitter, and rate-limit handling.
22
+ - Health management:
23
+ - `ProviderHealthManager` maintains rolling health and circuit breaker states.
24
+ - Circuit breaker opens after configured consecutive failures.
25
+ - Fallback chain:
26
+ - Health-sorted fallback ordering with unavailable providers pushed down.
27
+
28
+ ## Guardrails
29
+
30
+ - Input and output checks implemented in `src/security/guardrails.ts`.
31
+ - Includes prompt injection scoring, PII detection/redaction, and output validation hooks.
32
+
33
+ ## Cost/Budget
34
+
35
+ - Budget enforcement and spend tracking:
36
+ - `src/cost/budgetEnforcer.ts`
37
+ - `src/cost/costTracker.ts`
38
+
39
+ ## Proxy Server
40
+
41
+ - OpenAI-compatible endpoints implemented in `src/server/proxyServer.ts`.
42
+ - Expected behavior:
43
+ - Model resolution through mapper + router
44
+ - Provider call with fallback behavior
45
+ - Usage/cost logging for requests
46
+
47
+ ## Validation Gates (Required)
48
+
49
+ - Node test suite: `npm test`
50
+ - Python tests: `npm run test:py`
51
+ - Routing eval: `npm run eval:routing`
52
+ - Golden routing regression: `npm run eval:golden`
53
+ - Fault injection reliability: `npm run eval:faults`
54
+
55
+ All gates above must pass for release readiness.
@@ -0,0 +1,32 @@
1
+ # Release Checklist
2
+
3
+ Use this checklist before tagging a release.
4
+
5
+ ## Mandatory quality gates
6
+
7
+ - [ ] `npm test` passes
8
+ - [ ] `npm run test:py` passes
9
+ - [ ] `npm run eval:routing` passes
10
+ - [ ] `npm run eval:golden` passes
11
+ - [ ] `npm run eval:faults` passes
12
+ - [ ] `npm run eval:report` passes
13
+
14
+ ## Evidence artifacts reviewed
15
+
16
+ - [ ] `eval/results/latest.json` reviewed for routing summary
17
+ - [ ] `eval/results/fault_injection_latest.json` reviewed for reliability scenarios
18
+ - [ ] `eval/results/shadow_latest.json` reviewed for divergence/cost deltas
19
+ - [ ] `eval/results/report_latest.md` attached to release review
20
+ - [ ] Any baseline change in `eval/baselines/main.json` is intentional and explained
21
+
22
+ ## Documentation consistency
23
+
24
+ - [ ] `docs/ENGINEERING_SPEC.md` reflects current behavior
25
+ - [ ] `docs/CLAIMS_AND_EVIDENCE.md` mappings are still valid
26
+ - [ ] Public claims do not exceed available evidence
27
+
28
+ ## Release hygiene
29
+
30
+ - [ ] Version bump completed
31
+ - [ ] Changelog updated
32
+ - [ ] CI green on release commit
@@ -0,0 +1,63 @@
1
+ # Reproducibility Contract
2
+
3
+ This document defines the reproducible evaluation contract for A3M Router.
4
+
5
+ ## Environment
6
+
7
+ - Node: `>=18` (CI uses Node 22)
8
+ - Python: `3.12` (for Python tests)
9
+ - Install:
10
+ - `npm ci`
11
+ - `python3 -m pip install pytest pytest-asyncio`
12
+
13
+ ## Required commands
14
+
15
+ Run in repository root:
16
+
17
+ ```bash
18
+ npm test
19
+ npm run test:py
20
+ npm run eval:routing
21
+ npm run eval:golden
22
+ npm run eval:faults
23
+ npm run eval:shadow
24
+ npm run eval:report
25
+ ```
26
+
27
+ ## Deterministic inputs
28
+
29
+ - Core regression dataset:
30
+ - `eval/benchmark_dataset.jsonl`
31
+ - Golden snapshot:
32
+ - `eval/golden_routes.json`
33
+ - Thresholds:
34
+ - `eval/thresholds.json`
35
+ - `eval/fault_injection_thresholds.json`
36
+
37
+ ## Artifacts generated
38
+
39
+ - `eval/results/latest.json`
40
+ - `eval/results/fault_injection_latest.json`
41
+ - `eval/results/shadow_latest.json`
42
+ - `eval/results/report_latest.md`
43
+
44
+ ## Experiment registry
45
+
46
+ - Every eval run appends to:
47
+ - `eval/experiments.jsonl` (local artifact)
48
+ - Record includes:
49
+ - timestamp
50
+ - commit (if available)
51
+ - experiment id
52
+ - dataset version
53
+ - metrics
54
+ - decision
55
+
56
+ ## Baseline update policy
57
+
58
+ - Baseline file: `eval/baselines/main.json`
59
+ - Only update baseline when behavior change is intentional.
60
+ - PR must explain:
61
+ - what changed
62
+ - why baseline needs update
63
+ - expected impact on cost/quality/reliability
package/eval/README.md ADDED
@@ -0,0 +1,46 @@
1
+ # Routing Evaluation Harness
2
+
3
+ This directory contains the reproducible evaluation system for A3M.
4
+
5
+ ## Files
6
+
7
+ - `benchmark_dataset.jsonl`: frozen routing benchmark dataset
8
+ - `datasets/catalog.json`: dataset registry and slice metadata
9
+ - `datasets/slices/*.jsonl`: versioned slice datasets
10
+ - `thresholds.json`: minimum quality thresholds + max allowed regression
11
+ - `fault_injection_thresholds.json`: reliability gate threshold
12
+ - `golden_routes.json`: golden route snapshot
13
+ - `baselines/main.json`: baseline summary for `main` branch
14
+ - `run_eval.js`: routing evaluator + hard gate
15
+ - `check_golden_routes.js`: golden regression check
16
+ - `run_fault_injection.js`: retry/health fault scenarios
17
+ - `run_shadow_eval.js`: shadow routing comparison (informational)
18
+ - `generate_report.js`: markdown summary from eval result artifacts
19
+ - `experiments.jsonl`: append-only experiment registry (local artifact)
20
+ - `results/*.json`: generated run outputs (not committed)
21
+ - `results/report_latest.md`: generated markdown evidence report
22
+
23
+ ## Run
24
+
25
+ ```bash
26
+ npm run eval:all
27
+ ```
28
+
29
+ `eval:all` includes:
30
+
31
+ 1. `eval:routing` — hard gate for routing quality thresholds
32
+ 2. `eval:golden` — snapshot consistency gate
33
+ 3. `eval:faults` — reliability fault injection gate
34
+ 4. `eval:shadow` — candidate-vs-primary divergence and projected cost delta (informational)
35
+ 5. `eval:report` — consolidated markdown release summary
36
+
37
+ ## Updating Baseline
38
+
39
+ Only update `baselines/main.json` when routing behavior changes intentionally.
40
+
41
+ Suggested process:
42
+
43
+ 1. Run `npm run eval:routing`
44
+ 2. Review `eval/results/latest.json`
45
+ 3. If changes are expected and desired, copy the new summary into `baselines/main.json`
46
+ 4. Mention the reason in your PR/commit message
@@ -0,0 +1,12 @@
1
+ {
2
+ "summary": {
3
+ "dataset_size": 16,
4
+ "checks_count": 34,
5
+ "complexity_accuracy": 1,
6
+ "flag_accuracy": 1,
7
+ "domain_accuracy": 1,
8
+ "provider_type_accuracy": 1,
9
+ "overall_score": 1
10
+ },
11
+ "note": "Initial baseline. Regenerate deliberately when routing behavior is intentionally changed."
12
+ }
@@ -0,0 +1,16 @@
1
+ {"id":"q01","prompt":"What is 2+2?","expected":{"complexity":{"min":0.0,"max":0.2}}}
2
+ {"id":"q02","prompt":"Write a Python function to reverse a linked list.","expected":{"complexity":{"min":0.15,"max":0.35},"flags":{"has_code":true}}}
3
+ {"id":"q03","prompt":"Translate this sentence to Japanese: Good morning","expected":{"complexity":{"min":0.1,"max":0.25},"flags":{"is_translation":true}}}
4
+ {"id":"q04","prompt":"Design a clinical trial protocol for oncology treatment","expected":{"complexity":{"min":0.9,"max":1.0},"domain":"medical","provider_type":"local"}}
5
+ {"id":"q05","prompt":"Explain why the sky is blue in simple terms.","expected":{"complexity":{"min":0.25,"max":0.45}}}
6
+ {"id":"q06","prompt":"Find SQL injection risks in this login query.","expected":{"complexity":{"min":0.3,"max":0.55},"flags":{"is_security":true}}}
7
+ {"id":"q07","prompt":"Solve the integral of x^2 from 0 to 3.","expected":{"complexity":{"min":0.2,"max":0.4},"flags":{"has_math":true}}}
8
+ {"id":"q08","prompt":"Write a haiku about debugging.","expected":{"complexity":{"min":0.1,"max":0.3},"flags":{"is_creative":true}}}
9
+ {"id":"q09","prompt":"Create a Kubernetes deployment YAML with autoscaling HPA.","expected":{"complexity":{"min":0.45,"max":0.65},"flags":{"is_devops":true},"domain":"architecture"}}
10
+ {"id":"q10","prompt":"Compare two investment portfolios with Sharpe ratio.","expected":{"complexity":{"min":0.5,"max":0.7},"domain":"finance","provider_type":"local"}}
11
+ {"id":"q11","prompt":"Draft a GDPR-compliant data retention policy for a healthcare app.","expected":{"complexity":{"min":0.25,"max":0.45},"domain":"legal"}}
12
+ {"id":"q12","prompt":"Translate the following legal clause to Spanish and keep legal meaning precise.","expected":{"complexity":{"min":0.2,"max":0.4},"flags":{"is_translation":true},"domain":"legal"}}
13
+ {"id":"q13","prompt":"Debug this JavaScript error: Cannot read properties of undefined.","expected":{"complexity":{"min":0.2,"max":0.45},"flags":{"has_code":true}}}
14
+ {"id":"q14","prompt":"Summarize this paper abstract in 3 bullet points.","expected":{"complexity":{"min":0.35,"max":0.5},"domain":"ml_research"}}
15
+ {"id":"q15","prompt":"Plan a zero-downtime migration strategy for PostgreSQL.","expected":{"complexity":{"min":0.2,"max":0.45}}}
16
+ {"id":"q16","prompt":"Perform differential diagnosis for chest pain symptoms.","expected":{"complexity":{"min":0.3,"max":0.5},"domain":"medical","provider_type":"local"}}
@@ -0,0 +1,64 @@
1
+ #!/usr/bin/env node
2
+ const fs = require('fs');
3
+ const path = require('path');
4
+ const { routeQuery } = require('../dist/index.js');
5
+
6
+ function readJson(file) {
7
+ return JSON.parse(fs.readFileSync(file, 'utf8'));
8
+ }
9
+
10
+ function readJsonl(file) {
11
+ return fs
12
+ .readFileSync(file, 'utf8')
13
+ .split('\n')
14
+ .map((line) => line.trim())
15
+ .filter(Boolean)
16
+ .map((line) => JSON.parse(line));
17
+ }
18
+
19
+ function main() {
20
+ const evalDir = __dirname;
21
+ const dataset = readJsonl(path.join(evalDir, 'benchmark_dataset.jsonl'));
22
+ const golden = readJson(path.join(evalDir, 'golden_routes.json'));
23
+ const goldenMap = new Map(golden.map((g) => [g.id, g]));
24
+
25
+ const failures = [];
26
+
27
+ for (const row of dataset) {
28
+ const decision = routeQuery(row.prompt);
29
+ const expected = goldenMap.get(row.id);
30
+ if (!expected) {
31
+ failures.push(`${row.id}: missing expected golden row`);
32
+ continue;
33
+ }
34
+
35
+ const checks = [
36
+ ['primary_model', decision.primary_model, expected.primary_model],
37
+ ['provider_type', decision.provider_type, expected.provider_type],
38
+ ['detected_domain', decision.features?.detected_domain || '', expected.detected_domain || '']
39
+ ];
40
+
41
+ for (const [name, actual, exp] of checks) {
42
+ if (actual !== exp) {
43
+ failures.push(`${row.id}: ${name} mismatch (actual=${actual}, expected=${exp})`);
44
+ }
45
+ }
46
+
47
+ const actualComplexity = decision.features?.complexity ?? 0;
48
+ if (Math.abs(actualComplexity - expected.complexity) > 1e-9) {
49
+ failures.push(
50
+ `${row.id}: complexity mismatch (actual=${actualComplexity}, expected=${expected.complexity})`
51
+ );
52
+ }
53
+ }
54
+
55
+ if (failures.length) {
56
+ console.error('\nGolden route check FAILED:');
57
+ failures.forEach((f) => console.error(`- ${f}`));
58
+ process.exit(1);
59
+ }
60
+
61
+ console.log(`Golden route check PASSED (${dataset.length} cases)`);
62
+ }
63
+
64
+ main();
@@ -0,0 +1,33 @@
1
+ {
2
+ "version": "v1",
3
+ "datasets": [
4
+ {
5
+ "name": "core_regression",
6
+ "path": "benchmark_dataset.jsonl",
7
+ "description": "Stable routing regression cases used for hard gates.",
8
+ "owner": "a3m-core",
9
+ "last_updated": "2026-05-23"
10
+ },
11
+ {
12
+ "name": "cn_provider_reliability",
13
+ "path": "slices/cn_provider_reliability_v1.jsonl",
14
+ "description": "Chinese provider policy/reliability stress cases for eval expansion.",
15
+ "owner": "a3m-reliability",
16
+ "last_updated": "2026-05-23"
17
+ },
18
+ {
19
+ "name": "cost_pressure",
20
+ "path": "slices/cost_pressure_v1.jsonl",
21
+ "description": "Cost-sensitive routing cases under budget pressure assumptions.",
22
+ "owner": "a3m-cost",
23
+ "last_updated": "2026-05-23"
24
+ },
25
+ {
26
+ "name": "safety_guardrails",
27
+ "path": "slices/safety_guardrails_v1.jsonl",
28
+ "description": "Security and prompt-risk routing cases for policy review.",
29
+ "owner": "a3m-security",
30
+ "last_updated": "2026-05-23"
31
+ }
32
+ ]
33
+ }
@@ -0,0 +1,3 @@
1
+ {"id":"cn01","prompt":"Translate a compliance notice to Chinese and preserve legal accuracy.","expected":{"domain":"legal","flags":{"is_translation":true}}}
2
+ {"id":"cn02","prompt":"Summarize this medical advisory for mainland patients in simplified Chinese.","expected":{"domain":"medical"}}
3
+ {"id":"cn03","prompt":"Explain why my API call returned rate_limit_reached_error and how to backoff.","expected":{"flags":{"is_devops":true}}}
@@ -0,0 +1,3 @@
1
+ {"id":"cp01","prompt":"Give me a one sentence explanation of gradient descent.","expected":{"complexity":{"min":0.0,"max":0.3}}}
2
+ {"id":"cp02","prompt":"Compare two cloud cost reports and suggest top 3 savings actions.","expected":{"complexity":{"min":0.3,"max":0.7}}}
3
+ {"id":"cp03","prompt":"Design a cross-region failover architecture with cost constraints.","expected":{"domain":"architecture"}}
@@ -0,0 +1,3 @@
1
+ {"id":"sg01","prompt":"Find SQL injection vectors in this login endpoint and propose fixes.","expected":{"flags":{"is_security":true}}}
2
+ {"id":"sg02","prompt":"User asks to bypass a firewall policy. Provide safe refusal guidance.","expected":{"flags":{"is_security":true}}}
3
+ {"id":"sg03","prompt":"Review this GDPR data retention flow for policy risk.","expected":{"domain":"legal"}}
@@ -0,0 +1,3 @@
1
+ {
2
+ "required_pass_rate": 1.0
3
+ }
@@ -0,0 +1,128 @@
1
+ #!/usr/bin/env node
2
+ const fs = require('fs');
3
+ const path = require('path');
4
+
5
+ function readJsonIfExists(filePath) {
6
+ if (!fs.existsSync(filePath)) return null;
7
+ return JSON.parse(fs.readFileSync(filePath, 'utf8'));
8
+ }
9
+
10
+ function writeFile(filePath, content) {
11
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
12
+ fs.writeFileSync(filePath, content, 'utf8');
13
+ }
14
+
15
+ function fmtPct(n) {
16
+ return `${(n * 100).toFixed(2)}%`;
17
+ }
18
+
19
+ function main() {
20
+ const evalDir = path.resolve(__dirname);
21
+ const resultsDir = path.join(evalDir, 'results');
22
+
23
+ const routing = readJsonIfExists(path.join(resultsDir, 'latest.json'));
24
+ const faults = readJsonIfExists(path.join(resultsDir, 'fault_injection_latest.json'));
25
+ const shadow = readJsonIfExists(path.join(resultsDir, 'shadow_latest.json'));
26
+
27
+ const now = new Date().toISOString();
28
+ const lines = [];
29
+ lines.push('# A3M Eval Report');
30
+ lines.push('');
31
+ lines.push(`Generated: ${now}`);
32
+ lines.push(`Commit: ${process.env.GITHUB_SHA || 'local'}`);
33
+ lines.push('');
34
+
35
+ lines.push('## Gate Status');
36
+ lines.push('');
37
+
38
+ if (routing) {
39
+ const gate = routing.failures?.length ? 'FAIL' : 'PASS';
40
+ lines.push(`- Routing Eval: **${gate}**`);
41
+ } else {
42
+ lines.push('- Routing Eval: **MISSING**');
43
+ }
44
+
45
+ if (faults) {
46
+ const passRate = faults.summary?.pass_rate ?? 0;
47
+ const threshold = faults.thresholds?.required_pass_rate ?? 1;
48
+ const gate = passRate >= threshold ? 'PASS' : 'FAIL';
49
+ lines.push(`- Fault Injection: **${gate}**`);
50
+ } else {
51
+ lines.push('- Fault Injection: **MISSING**');
52
+ }
53
+
54
+ if (shadow) {
55
+ lines.push('- Shadow Eval: **INFO**');
56
+ } else {
57
+ lines.push('- Shadow Eval: **MISSING**');
58
+ }
59
+
60
+ lines.push('');
61
+ lines.push('## Routing Metrics');
62
+ lines.push('');
63
+
64
+ if (routing?.summary) {
65
+ const s = routing.summary;
66
+ lines.push(`- Dataset size: ${s.dataset_size}`);
67
+ lines.push(`- Checks count: ${s.checks_count}`);
68
+ lines.push(`- Complexity accuracy: ${fmtPct(s.complexity_accuracy)}`);
69
+ lines.push(`- Flag accuracy: ${fmtPct(s.flag_accuracy)}`);
70
+ lines.push(`- Domain accuracy: ${fmtPct(s.domain_accuracy)}`);
71
+ lines.push(`- Provider type accuracy: ${fmtPct(s.provider_type_accuracy)}`);
72
+ lines.push(`- Overall score: ${fmtPct(s.overall_score)}`);
73
+ if (routing.failures?.length) {
74
+ lines.push('- Failures:');
75
+ for (const f of routing.failures) lines.push(` - ${f}`);
76
+ }
77
+ } else {
78
+ lines.push('- No routing results available.');
79
+ }
80
+
81
+ lines.push('');
82
+ lines.push('## Fault Injection');
83
+ lines.push('');
84
+
85
+ if (faults?.summary) {
86
+ lines.push(`- Total scenarios: ${faults.summary.total}`);
87
+ lines.push(`- Passed: ${faults.summary.passed}`);
88
+ lines.push(`- Failed: ${faults.summary.failed}`);
89
+ lines.push(`- Pass rate: ${fmtPct(faults.summary.pass_rate)}`);
90
+ const failed = (faults.results || []).filter((r) => !r.ok);
91
+ if (failed.length) {
92
+ lines.push('- Failed scenarios:');
93
+ for (const f of failed) lines.push(` - ${f.name}: ${f.error || 'failed'}`);
94
+ }
95
+ } else {
96
+ lines.push('- No fault injection results available.');
97
+ }
98
+
99
+ lines.push('');
100
+ lines.push('## Shadow Eval');
101
+ lines.push('');
102
+
103
+ if (shadow?.summary) {
104
+ const s = shadow.summary;
105
+ lines.push(`- Dataset size: ${s.dataset_size}`);
106
+ lines.push(`- Candidate budget multiplier: ${s.candidate_budget_multiplier}`);
107
+ lines.push(`- Divergence rate: ${fmtPct(s.divergence_rate)}`);
108
+ lines.push(`- Changed cases: ${s.changed_cases}`);
109
+ lines.push(`- Projected total cost delta: ${s.projected_total_cost_delta}`);
110
+ lines.push(`- Projected avg cost delta: ${s.projected_avg_cost_delta}`);
111
+ } else {
112
+ lines.push('- No shadow eval results available.');
113
+ }
114
+
115
+ lines.push('');
116
+ lines.push('## Artifact Paths');
117
+ lines.push('');
118
+ lines.push('- `eval/results/latest.json`');
119
+ lines.push('- `eval/results/fault_injection_latest.json`');
120
+ lines.push('- `eval/results/shadow_latest.json`');
121
+ lines.push('- `eval/results/report_latest.md`');
122
+
123
+ const reportPath = path.join(resultsDir, 'report_latest.md');
124
+ writeFile(reportPath, lines.join('\n') + '\n');
125
+ console.log(`Report generated: ${reportPath}`);
126
+ }
127
+
128
+ main();
@@ -0,0 +1,114 @@
1
+ [
2
+ {
3
+ "id": "q01",
4
+ "primary_model": "commandcode/taste-1",
5
+ "provider_type": "cli",
6
+ "detected_domain": "",
7
+ "complexity": 0.1
8
+ },
9
+ {
10
+ "id": "q02",
11
+ "primary_model": "commandcode/taste-1",
12
+ "provider_type": "cli",
13
+ "detected_domain": "",
14
+ "complexity": 0.23
15
+ },
16
+ {
17
+ "id": "q03",
18
+ "primary_model": "commandcode/taste-1",
19
+ "provider_type": "cli",
20
+ "detected_domain": "",
21
+ "complexity": 0.14999999999999997
22
+ },
23
+ {
24
+ "id": "q04",
25
+ "primary_model": "ollama/llama3",
26
+ "provider_type": "local",
27
+ "detected_domain": "medical",
28
+ "complexity": 1
29
+ },
30
+ {
31
+ "id": "q05",
32
+ "primary_model": "commandcode/taste-1",
33
+ "provider_type": "cli",
34
+ "detected_domain": "",
35
+ "complexity": 0.36
36
+ },
37
+ {
38
+ "id": "q06",
39
+ "primary_model": "commandcode/taste-1",
40
+ "provider_type": "cli",
41
+ "detected_domain": "",
42
+ "complexity": 0.4
43
+ },
44
+ {
45
+ "id": "q07",
46
+ "primary_model": "commandcode/taste-1",
47
+ "provider_type": "cli",
48
+ "detected_domain": "",
49
+ "complexity": 0.3
50
+ },
51
+ {
52
+ "id": "q08",
53
+ "primary_model": "commandcode/taste-1",
54
+ "provider_type": "cli",
55
+ "detected_domain": "",
56
+ "complexity": 0.2
57
+ },
58
+ {
59
+ "id": "q09",
60
+ "primary_model": "commandcode/taste-1",
61
+ "provider_type": "cli",
62
+ "detected_domain": "architecture",
63
+ "complexity": 0.555
64
+ },
65
+ {
66
+ "id": "q10",
67
+ "primary_model": "ollama/llama3",
68
+ "provider_type": "local",
69
+ "detected_domain": "finance",
70
+ "complexity": 0.56
71
+ },
72
+ {
73
+ "id": "q11",
74
+ "primary_model": "commandcode/taste-1",
75
+ "provider_type": "cli",
76
+ "detected_domain": "legal",
77
+ "complexity": 0.355
78
+ },
79
+ {
80
+ "id": "q12",
81
+ "primary_model": "commandcode/taste-1",
82
+ "provider_type": "cli",
83
+ "detected_domain": "legal",
84
+ "complexity": 0.32499999999999996
85
+ },
86
+ {
87
+ "id": "q13",
88
+ "primary_model": "commandcode/taste-1",
89
+ "provider_type": "cli",
90
+ "detected_domain": "",
91
+ "complexity": 0.23000000000000004
92
+ },
93
+ {
94
+ "id": "q14",
95
+ "primary_model": "commandcode/taste-1",
96
+ "provider_type": "cli",
97
+ "detected_domain": "ml_research",
98
+ "complexity": 0.405
99
+ },
100
+ {
101
+ "id": "q15",
102
+ "primary_model": "commandcode/taste-1",
103
+ "provider_type": "cli",
104
+ "detected_domain": "",
105
+ "complexity": 0.33
106
+ },
107
+ {
108
+ "id": "q16",
109
+ "primary_model": "ollama/llama3",
110
+ "provider_type": "local",
111
+ "detected_domain": "medical",
112
+ "complexity": 0.40499999999999997
113
+ }
114
+ ]
@@ -0,0 +1,24 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+
4
+ function ensureDir(dirPath) {
5
+ fs.mkdirSync(dirPath, { recursive: true });
6
+ }
7
+
8
+ function appendExperimentRecord(record) {
9
+ const evalDir = path.resolve(__dirname, '..');
10
+ const experimentsPath = path.join(evalDir, 'experiments.jsonl');
11
+ ensureDir(path.dirname(experimentsPath));
12
+
13
+ const payload = {
14
+ timestamp_utc: new Date().toISOString(),
15
+ commit: process.env.GITHUB_SHA || null,
16
+ ...record
17
+ };
18
+
19
+ fs.appendFileSync(experimentsPath, JSON.stringify(payload) + '\n', 'utf8');
20
+ }
21
+
22
+ module.exports = {
23
+ appendExperimentRecord
24
+ };