@castlemilk/omega 0.6.9 → 0.6.11
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/dist/cli.js +690 -2
- package/dist/server/dist/routes/tasks.d.ts.map +1 -1
- package/dist/server/dist/routes/tasks.js +26 -0
- package/dist/server/dist/routes/tasks.js.map +1 -1
- package/dist/server/node_modules/@omega/agent/dist/executor.d.ts.map +1 -1
- package/dist/server/node_modules/@omega/agent/dist/executor.js +79 -18
- package/dist/server/node_modules/@omega/agent/dist/executor.js.map +1 -1
- package/dist/server/node_modules/@omega/agent/dist/planner.d.ts +1 -1
- package/dist/server/node_modules/@omega/agent/dist/planner.d.ts.map +1 -1
- package/dist/server/node_modules/@omega/agent/dist/planner.js +3 -2
- package/dist/server/node_modules/@omega/agent/dist/planner.js.map +1 -1
- package/dist/server/node_modules/@omega/agent/dist/prompt-context.d.ts +10 -0
- package/dist/server/node_modules/@omega/agent/dist/prompt-context.d.ts.map +1 -0
- package/dist/server/node_modules/@omega/agent/dist/prompt-context.js +138 -0
- package/dist/server/node_modules/@omega/agent/dist/prompt-context.js.map +1 -0
- package/dist/server/node_modules/@omega/agent/dist/prompts.d.ts +2 -0
- package/dist/server/node_modules/@omega/agent/dist/prompts.d.ts.map +1 -1
- package/dist/server/node_modules/@omega/agent/dist/prompts.js +10 -0
- package/dist/server/node_modules/@omega/agent/dist/prompts.js.map +1 -1
- package/dist/server/node_modules/@omega/agent/dist/tracer.d.ts +39 -0
- package/dist/server/node_modules/@omega/agent/dist/tracer.d.ts.map +1 -0
- package/dist/server/node_modules/@omega/agent/dist/tracer.js +90 -0
- package/dist/server/node_modules/@omega/agent/dist/tracer.js.map +1 -0
- package/dist/server/node_modules/@omega/db/generated/client/edge.js +18 -3
- package/dist/server/node_modules/@omega/db/generated/client/index-browser.js +15 -0
- package/dist/server/node_modules/@omega/db/generated/client/index.d.ts +1924 -169
- package/dist/server/node_modules/@omega/db/generated/client/index.js +18 -3
- package/dist/server/node_modules/@omega/db/generated/client/package.json +1 -1
- package/dist/server/node_modules/@omega/db/generated/client/schema.prisma +19 -0
- package/dist/server/node_modules/@omega/db/generated/client/wasm.js +18 -3
- package/dist/server/node_modules/@omega/db/prisma/migrations/20260703000000_add_trace_spans/migration.sql +25 -0
- package/dist/server/pglite-data/base/5/1247 +0 -0
- package/dist/server/pglite-data/base/5/1249 +0 -0
- package/dist/server/pglite-data/base/5/1249_fsm +0 -0
- package/dist/server/pglite-data/base/5/1259 +0 -0
- package/dist/server/pglite-data/base/5/1259_fsm +0 -0
- package/dist/server/pglite-data/base/5/1259_vm +0 -0
- package/dist/server/pglite-data/base/5/16384 +0 -0
- package/dist/server/pglite-data/base/5/16392 +0 -0
- package/dist/server/pglite-data/base/5/16394 +0 -0
- package/dist/server/pglite-data/base/5/16404 +0 -0
- package/dist/server/pglite-data/base/5/16406 +0 -0
- package/dist/server/pglite-data/base/5/16421 +0 -0
- package/dist/server/pglite-data/base/5/16510 +0 -0
- package/dist/server/pglite-data/base/5/24576 +0 -0
- package/dist/server/pglite-data/base/5/24587 +0 -0
- package/dist/server/pglite-data/base/5/24588 +0 -0
- package/dist/server/pglite-data/base/5/24589 +0 -0
- package/dist/server/pglite-data/base/5/24591 +0 -0
- package/dist/server/pglite-data/base/5/24592 +0 -0
- package/dist/server/pglite-data/base/5/2579 +0 -0
- package/dist/server/pglite-data/base/5/2604 +0 -0
- package/dist/server/pglite-data/base/5/2604_fsm +0 -0
- package/dist/server/pglite-data/base/5/2606 +0 -0
- package/dist/server/pglite-data/base/5/2608 +0 -0
- package/dist/server/pglite-data/base/5/2608_fsm +0 -0
- package/dist/server/pglite-data/base/5/2610 +0 -0
- package/dist/server/pglite-data/base/5/2620 +0 -0
- package/dist/server/pglite-data/base/5/2656 +0 -0
- package/dist/server/pglite-data/base/5/2657 +0 -0
- package/dist/server/pglite-data/base/5/2658 +0 -0
- package/dist/server/pglite-data/base/5/2659 +0 -0
- package/dist/server/pglite-data/base/5/2662 +0 -0
- package/dist/server/pglite-data/base/5/2663 +0 -0
- package/dist/server/pglite-data/base/5/2664 +0 -0
- package/dist/server/pglite-data/base/5/2665 +0 -0
- package/dist/server/pglite-data/base/5/2666 +0 -0
- package/dist/server/pglite-data/base/5/2667 +0 -0
- package/dist/server/pglite-data/base/5/2673 +0 -0
- package/dist/server/pglite-data/base/5/2674 +0 -0
- package/dist/server/pglite-data/base/5/2678 +0 -0
- package/dist/server/pglite-data/base/5/2679 +0 -0
- package/dist/server/pglite-data/base/5/2699 +0 -0
- package/dist/server/pglite-data/base/5/2701 +0 -0
- package/dist/server/pglite-data/base/5/2702 +0 -0
- package/dist/server/pglite-data/base/5/2703 +0 -0
- package/dist/server/pglite-data/base/5/2704 +0 -0
- package/dist/server/pglite-data/base/5/3455 +0 -0
- package/dist/server/pglite-data/base/5/pg_internal.init +0 -0
- package/dist/server/pglite-data/global/pg_control +0 -0
- package/dist/server/pglite-data/global/pg_internal.init +0 -0
- package/dist/server/pglite-data/pg_wal/000000010000000000000001 +0 -0
- package/dist/server/pglite-data/pg_xact/0000 +0 -0
- package/dist/server/pglite-data/postmaster.pid +1 -1
- package/dist/server/src/routes/tasks.ts +30 -0
- package/dist/web/dist/assets/index-B2af4AQD.js +40 -0
- package/dist/web/dist/assets/index-iY2pDoq8.css +1 -0
- package/dist/web/dist/index.html +2 -2
- package/package.json +3 -3
package/dist/cli.js
CHANGED
|
@@ -330,8 +330,8 @@ function getApiUrl() {
|
|
|
330
330
|
const opts = program.opts();
|
|
331
331
|
return opts.api ?? "http://localhost:4000";
|
|
332
332
|
}
|
|
333
|
-
async function apiFetch(
|
|
334
|
-
const url = `${getApiUrl()}${
|
|
333
|
+
async function apiFetch(path10, init) {
|
|
334
|
+
const url = `${getApiUrl()}${path10}`;
|
|
335
335
|
const res = await fetch(url, init);
|
|
336
336
|
const data = await res.json().catch(() => ({}));
|
|
337
337
|
if (!res.ok) {
|
|
@@ -817,6 +817,693 @@ agentCmd.command("diffs").description("Show diffs for a task").argument("<id>",
|
|
|
817
817
|
console.log(JSON.stringify(diffs, null, 2));
|
|
818
818
|
});
|
|
819
819
|
|
|
820
|
+
// ../../apps/cli/src/commands/bench.ts
|
|
821
|
+
import { Command as Command8 } from "commander";
|
|
822
|
+
import path9 from "node:path";
|
|
823
|
+
|
|
824
|
+
// ../bench/dist/api-client.js
|
|
825
|
+
var ApiError = class extends Error {
|
|
826
|
+
status;
|
|
827
|
+
constructor(status, message) {
|
|
828
|
+
super(message);
|
|
829
|
+
this.status = status;
|
|
830
|
+
}
|
|
831
|
+
};
|
|
832
|
+
async function apiFetch2(url, init) {
|
|
833
|
+
const res = await fetch(url, init);
|
|
834
|
+
if (!res.ok) {
|
|
835
|
+
throw new ApiError(res.status, `${init?.method ?? "GET"} ${url} -> ${String(res.status)}`);
|
|
836
|
+
}
|
|
837
|
+
return res.json();
|
|
838
|
+
}
|
|
839
|
+
async function ensureProject2(apiUrl, name, path10) {
|
|
840
|
+
const res = await fetch(`${apiUrl}/projects`, {
|
|
841
|
+
method: "POST",
|
|
842
|
+
headers: { "Content-Type": "application/json" },
|
|
843
|
+
body: JSON.stringify({ name, path: path10 })
|
|
844
|
+
});
|
|
845
|
+
if (res.status === 409) {
|
|
846
|
+
const projects = await fetch(`${apiUrl}/projects?path=${encodeURIComponent(path10)}`).then((r) => r.json());
|
|
847
|
+
const existing = projects.find((p) => p.path === path10);
|
|
848
|
+
if (existing)
|
|
849
|
+
return existing;
|
|
850
|
+
}
|
|
851
|
+
if (!res.ok)
|
|
852
|
+
throw new ApiError(res.status, `create project failed: ${String(res.status)}`);
|
|
853
|
+
return res.json();
|
|
854
|
+
}
|
|
855
|
+
async function createTask(apiUrl, projectId, title, options = {}) {
|
|
856
|
+
return apiFetch2(`${apiUrl}/tasks`, {
|
|
857
|
+
method: "POST",
|
|
858
|
+
headers: { "Content-Type": "application/json" },
|
|
859
|
+
body: JSON.stringify({
|
|
860
|
+
projectId,
|
|
861
|
+
title,
|
|
862
|
+
description: options.description,
|
|
863
|
+
complexity: options.complexity ?? "simple",
|
|
864
|
+
tags: options.tags ?? ["benchmark"]
|
|
865
|
+
})
|
|
866
|
+
});
|
|
867
|
+
}
|
|
868
|
+
async function runTask(apiUrl, taskId) {
|
|
869
|
+
await apiFetch2(`${apiUrl}/tasks/${taskId}/run`, { method: "POST" });
|
|
870
|
+
}
|
|
871
|
+
async function getTask(apiUrl, taskId) {
|
|
872
|
+
return apiFetch2(`${apiUrl}/tasks/${taskId}`);
|
|
873
|
+
}
|
|
874
|
+
async function waitForTask(apiUrl, taskId, timeoutMs = 12e4) {
|
|
875
|
+
const deadline = Date.now() + timeoutMs;
|
|
876
|
+
while (Date.now() < deadline) {
|
|
877
|
+
const task = await getTask(apiUrl, taskId);
|
|
878
|
+
if (task.status === "done" || task.status === "failed")
|
|
879
|
+
return task;
|
|
880
|
+
await new Promise((r) => setTimeout(r, 300));
|
|
881
|
+
}
|
|
882
|
+
return { status: "timeout", error: "Task did not finish in time" };
|
|
883
|
+
}
|
|
884
|
+
async function getAgentRun(apiUrl, taskId) {
|
|
885
|
+
try {
|
|
886
|
+
return await apiFetch2(`${apiUrl}/tasks/${taskId}/agent-run`);
|
|
887
|
+
} catch {
|
|
888
|
+
return void 0;
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
async function getDiffs(apiUrl, taskId) {
|
|
892
|
+
try {
|
|
893
|
+
return await apiFetch2(`${apiUrl}/tasks/${taskId}/diffs`);
|
|
894
|
+
} catch {
|
|
895
|
+
return [];
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
async function getTraceFlow(apiUrl, taskId) {
|
|
899
|
+
try {
|
|
900
|
+
return await apiFetch2(`${apiUrl}/tasks/${taskId}/trace-flow`);
|
|
901
|
+
} catch {
|
|
902
|
+
return void 0;
|
|
903
|
+
}
|
|
904
|
+
}
|
|
905
|
+
function countSpans(node) {
|
|
906
|
+
let count = 1;
|
|
907
|
+
if (Array.isArray(node.children)) {
|
|
908
|
+
for (const child of node.children) {
|
|
909
|
+
count += countSpans(child);
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
return count;
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
// ../bench/dist/runner.js
|
|
916
|
+
import fs from "node:fs/promises";
|
|
917
|
+
import path4 from "node:path";
|
|
918
|
+
import { execSync } from "node:child_process";
|
|
919
|
+
function countAllSpans(traceFlow) {
|
|
920
|
+
if (!traceFlow)
|
|
921
|
+
return 0;
|
|
922
|
+
return traceFlow.spans.reduce((acc, span) => acc + countSpans(span), 0);
|
|
923
|
+
}
|
|
924
|
+
function ensureGitRepo(repoPath) {
|
|
925
|
+
try {
|
|
926
|
+
execSync("git rev-parse --git-dir", { cwd: repoPath, stdio: "ignore" });
|
|
927
|
+
return;
|
|
928
|
+
} catch {
|
|
929
|
+
}
|
|
930
|
+
execSync("git init", { cwd: repoPath, stdio: "ignore" });
|
|
931
|
+
execSync('git config user.email "bench@omega.local"', { cwd: repoPath, stdio: "ignore" });
|
|
932
|
+
execSync('git config user.name "Omega Bench"', { cwd: repoPath, stdio: "ignore" });
|
|
933
|
+
execSync("git add .", { cwd: repoPath, stdio: "ignore" });
|
|
934
|
+
execSync('git commit -m "bench init"', { cwd: repoPath, stdio: "ignore" });
|
|
935
|
+
}
|
|
936
|
+
async function runBenchmark(tasks, options) {
|
|
937
|
+
const { apiUrl, suiteName, timeoutMs = 12e4, projectPrefix = "bench" } = options;
|
|
938
|
+
const report = {
|
|
939
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
940
|
+
suite: suiteName,
|
|
941
|
+
total: tasks.length,
|
|
942
|
+
passed: 0,
|
|
943
|
+
failed: 0,
|
|
944
|
+
timeouts: 0,
|
|
945
|
+
totalDurationMs: 0,
|
|
946
|
+
results: []
|
|
947
|
+
};
|
|
948
|
+
const baseDir = path4.join("/tmp", `omega-bench-${String(Date.now())}`);
|
|
949
|
+
await fs.mkdir(baseDir, { recursive: true });
|
|
950
|
+
for (const task of tasks) {
|
|
951
|
+
const start = Date.now();
|
|
952
|
+
let harnessTaskId = "";
|
|
953
|
+
let status = "failed";
|
|
954
|
+
let agentRun;
|
|
955
|
+
let diffs = [];
|
|
956
|
+
let traceFlow;
|
|
957
|
+
let evaluation = { passed: false, message: "Task did not complete" };
|
|
958
|
+
let projectId = "";
|
|
959
|
+
let projectPath = "";
|
|
960
|
+
try {
|
|
961
|
+
projectPath = path4.join(baseDir, task.id);
|
|
962
|
+
await fs.mkdir(projectPath, { recursive: true });
|
|
963
|
+
if (task.setup) {
|
|
964
|
+
await task.setup(projectPath);
|
|
965
|
+
}
|
|
966
|
+
ensureGitRepo(projectPath);
|
|
967
|
+
const project = await ensureProject2(apiUrl, `${projectPrefix}-${task.id}`, projectPath);
|
|
968
|
+
projectId = project.id;
|
|
969
|
+
const harnessTask = await createTask(apiUrl, project.id, task.title, {
|
|
970
|
+
description: task.description,
|
|
971
|
+
complexity: task.complexity ?? "simple",
|
|
972
|
+
tags: ["benchmark", "agent"]
|
|
973
|
+
});
|
|
974
|
+
harnessTaskId = harnessTask.id;
|
|
975
|
+
await runTask(apiUrl, harnessTask.id);
|
|
976
|
+
const finished = await waitForTask(apiUrl, harnessTask.id, timeoutMs);
|
|
977
|
+
status = finished.status === "timeout" ? "timeout" : finished.status;
|
|
978
|
+
[agentRun, diffs, traceFlow] = await Promise.all([
|
|
979
|
+
getAgentRun(apiUrl, harnessTask.id),
|
|
980
|
+
getDiffs(apiUrl, harnessTask.id),
|
|
981
|
+
getTraceFlow(apiUrl, harnessTask.id)
|
|
982
|
+
]);
|
|
983
|
+
evaluation = await task.evaluate({
|
|
984
|
+
apiUrl,
|
|
985
|
+
taskId: harnessTask.id,
|
|
986
|
+
projectPath,
|
|
987
|
+
projectId,
|
|
988
|
+
agentRun,
|
|
989
|
+
diffs,
|
|
990
|
+
traceFlow
|
|
991
|
+
});
|
|
992
|
+
} catch (err) {
|
|
993
|
+
evaluation = {
|
|
994
|
+
passed: false,
|
|
995
|
+
message: err instanceof Error ? err.message : String(err)
|
|
996
|
+
};
|
|
997
|
+
}
|
|
998
|
+
const durationMs = Date.now() - start;
|
|
999
|
+
const result = {
|
|
1000
|
+
task,
|
|
1001
|
+
harnessTaskId,
|
|
1002
|
+
durationMs,
|
|
1003
|
+
status,
|
|
1004
|
+
evaluation,
|
|
1005
|
+
agentRun,
|
|
1006
|
+
spanCount: countAllSpans(traceFlow)
|
|
1007
|
+
};
|
|
1008
|
+
if (status === "timeout")
|
|
1009
|
+
report.timeouts++;
|
|
1010
|
+
else if (evaluation.passed)
|
|
1011
|
+
report.passed++;
|
|
1012
|
+
else
|
|
1013
|
+
report.failed++;
|
|
1014
|
+
report.totalDurationMs += durationMs;
|
|
1015
|
+
report.results.push(result);
|
|
1016
|
+
options.onProgress?.(result);
|
|
1017
|
+
}
|
|
1018
|
+
return report;
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
// ../bench/dist/report.js
|
|
1022
|
+
import fs2 from "node:fs/promises";
|
|
1023
|
+
import path5 from "node:path";
|
|
1024
|
+
function nowIso() {
|
|
1025
|
+
return (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
1026
|
+
}
|
|
1027
|
+
function formatDuration(ms) {
|
|
1028
|
+
if (ms < 1e3)
|
|
1029
|
+
return `${String(Math.round(ms))}ms`;
|
|
1030
|
+
return `${(ms / 1e3).toFixed(1)}s`;
|
|
1031
|
+
}
|
|
1032
|
+
function resultLine(r, idx) {
|
|
1033
|
+
const symbol = r.evaluation.passed ? "\u2713" : "\u2717";
|
|
1034
|
+
const status = r.status === "timeout" ? "timeout" : r.status;
|
|
1035
|
+
const score = r.evaluation.score !== void 0 ? ` (score ${String(r.evaluation.score)})` : "";
|
|
1036
|
+
const msg = r.evaluation.message ? ` \u2014 ${r.evaluation.message}` : "";
|
|
1037
|
+
return `${String(idx + 1)}. ${symbol} ${r.task.name} [${status}] ${formatDuration(r.durationMs)}${score}${msg}`;
|
|
1038
|
+
}
|
|
1039
|
+
async function writeReport(report, outputDir = ".omega/reports") {
|
|
1040
|
+
await fs2.mkdir(outputDir, { recursive: true });
|
|
1041
|
+
const ts = nowIso();
|
|
1042
|
+
const jsonFile = path5.join(outputDir, `benchmark-${ts}.json`);
|
|
1043
|
+
const mdFile = path5.join(outputDir, `benchmark-${ts}.md`);
|
|
1044
|
+
await fs2.writeFile(jsonFile, JSON.stringify(report, null, 2), "utf-8");
|
|
1045
|
+
const passRate = report.total > 0 ? Math.round(report.passed / report.total * 100) : 0;
|
|
1046
|
+
const md = [
|
|
1047
|
+
"# Omega Benchmark Report",
|
|
1048
|
+
"",
|
|
1049
|
+
`- Suite: ${report.suite}`,
|
|
1050
|
+
`- Timestamp: ${report.timestamp}`,
|
|
1051
|
+
`- Total: ${String(report.total)}`,
|
|
1052
|
+
`- Passed: ${String(report.passed)}`,
|
|
1053
|
+
`- Failed: ${String(report.failed)}`,
|
|
1054
|
+
`- Timeouts: ${String(report.timeouts)}`,
|
|
1055
|
+
`- Pass rate: ${String(passRate)}%`,
|
|
1056
|
+
`- Total duration: ${formatDuration(report.totalDurationMs)}`,
|
|
1057
|
+
"",
|
|
1058
|
+
"## Results",
|
|
1059
|
+
"",
|
|
1060
|
+
...report.results.map((r, i) => resultLine(r, i)),
|
|
1061
|
+
"",
|
|
1062
|
+
"## Details",
|
|
1063
|
+
"",
|
|
1064
|
+
"```json",
|
|
1065
|
+
JSON.stringify(report, null, 2),
|
|
1066
|
+
"```",
|
|
1067
|
+
""
|
|
1068
|
+
].join("\n");
|
|
1069
|
+
await fs2.writeFile(mdFile, md, "utf-8");
|
|
1070
|
+
return jsonFile;
|
|
1071
|
+
}
|
|
1072
|
+
function printSummary(report) {
|
|
1073
|
+
const passRate = report.total > 0 ? Math.round(report.passed / report.total * 100) : 0;
|
|
1074
|
+
console.log(`
|
|
1075
|
+
Benchmark: ${report.suite}`);
|
|
1076
|
+
console.log(`Total: ${String(report.total)} | Passed: ${String(report.passed)} | Failed: ${String(report.failed)} | Timeouts: ${String(report.timeouts)}`);
|
|
1077
|
+
console.log(`Pass rate: ${String(passRate)}%`);
|
|
1078
|
+
console.log(`Duration: ${formatDuration(report.totalDurationMs)}`);
|
|
1079
|
+
for (const r of report.results) {
|
|
1080
|
+
console.log(resultLine(r, report.results.indexOf(r)));
|
|
1081
|
+
}
|
|
1082
|
+
}
|
|
1083
|
+
|
|
1084
|
+
// ../bench/dist/suites/synthetic.js
|
|
1085
|
+
import fs3 from "node:fs/promises";
|
|
1086
|
+
import path6 from "node:path";
|
|
1087
|
+
async function writeJson(projectPath, file, data) {
|
|
1088
|
+
await fs3.writeFile(path6.join(projectPath, file), JSON.stringify(data, null, 2), "utf-8");
|
|
1089
|
+
}
|
|
1090
|
+
async function writeFile2(projectPath, file, content) {
|
|
1091
|
+
await fs3.mkdir(path6.dirname(path6.join(projectPath, file)), { recursive: true });
|
|
1092
|
+
await fs3.writeFile(path6.join(projectPath, file), content, "utf-8");
|
|
1093
|
+
}
|
|
1094
|
+
function parseValidation(ctx) {
|
|
1095
|
+
if (!ctx.agentRun?.validationSummary)
|
|
1096
|
+
return { allPassed: false };
|
|
1097
|
+
try {
|
|
1098
|
+
const summary = JSON.parse(ctx.agentRun.validationSummary);
|
|
1099
|
+
return { allPassed: Boolean(summary.allPassed), summary };
|
|
1100
|
+
} catch {
|
|
1101
|
+
return { allPassed: false };
|
|
1102
|
+
}
|
|
1103
|
+
}
|
|
1104
|
+
function validate(ctx) {
|
|
1105
|
+
const v = parseValidation(ctx);
|
|
1106
|
+
return {
|
|
1107
|
+
passed: v.allPassed,
|
|
1108
|
+
message: v.allPassed ? "Validation passed" : "Validation failed"
|
|
1109
|
+
};
|
|
1110
|
+
}
|
|
1111
|
+
function basePackage() {
|
|
1112
|
+
return {
|
|
1113
|
+
name: "synthetic-bench-project",
|
|
1114
|
+
version: "1.0.0",
|
|
1115
|
+
type: "module",
|
|
1116
|
+
scripts: {
|
|
1117
|
+
lint: "node lint.js",
|
|
1118
|
+
test: "node test.js",
|
|
1119
|
+
build: "node build.js"
|
|
1120
|
+
}
|
|
1121
|
+
};
|
|
1122
|
+
}
|
|
1123
|
+
var TASKS = [
|
|
1124
|
+
{
|
|
1125
|
+
id: "greet-function",
|
|
1126
|
+
name: "Add a greet function",
|
|
1127
|
+
title: "Add greet.js with a greet function",
|
|
1128
|
+
description: "Create a `greet.js` file that exports a function `greet(name)` returning `Hello, <name>!`. The existing test expects this function.",
|
|
1129
|
+
complexity: "simple",
|
|
1130
|
+
setup: async (projectPath) => {
|
|
1131
|
+
await writeJson(projectPath, "package.json", basePackage());
|
|
1132
|
+
await writeFile2(projectPath, "test.js", `import { greet } from './greet.js';
|
|
1133
|
+
import assert from 'node:assert';
|
|
1134
|
+
assert.strictEqual(greet('World'), 'Hello, World!');
|
|
1135
|
+
console.log('greet test passed');
|
|
1136
|
+
`);
|
|
1137
|
+
await writeFile2(projectPath, "lint.js", `console.log('lint ok');
|
|
1138
|
+
`);
|
|
1139
|
+
await writeFile2(projectPath, "build.js", `console.log('build ok');
|
|
1140
|
+
`);
|
|
1141
|
+
},
|
|
1142
|
+
evaluate: (ctx) => Promise.resolve(validate(ctx))
|
|
1143
|
+
},
|
|
1144
|
+
{
|
|
1145
|
+
id: "fix-lint-warning",
|
|
1146
|
+
name: "Fix a lint warning",
|
|
1147
|
+
title: "Remove unused variable flagged by linter",
|
|
1148
|
+
description: "The custom linter flags any use of `var`. Update `src/index.js` so the lint script passes while keeping the greeting behavior.",
|
|
1149
|
+
complexity: "simple",
|
|
1150
|
+
setup: async (projectPath) => {
|
|
1151
|
+
await writeJson(projectPath, "package.json", basePackage());
|
|
1152
|
+
await writeFile2(projectPath, "src/index.js", `var greeting = 'Hello';
|
|
1153
|
+
export function hi(name) { return greeting + ', ' + name + '!'; }
|
|
1154
|
+
`);
|
|
1155
|
+
await writeFile2(projectPath, "test.js", `import { hi } from './src/index.js';
|
|
1156
|
+
import assert from 'node:assert';
|
|
1157
|
+
assert.strictEqual(hi('Omega'), 'Hello, Omega!');
|
|
1158
|
+
console.log('hi test passed');
|
|
1159
|
+
`);
|
|
1160
|
+
await writeFile2(projectPath, "lint.js", `import fs from 'node:fs/promises';
|
|
1161
|
+
const code = await fs.readFile('./src/index.js', 'utf-8');
|
|
1162
|
+
if (code.includes('var ')) { console.error('lint failed: var keyword found'); process.exit(1); }
|
|
1163
|
+
console.log('lint ok');
|
|
1164
|
+
`);
|
|
1165
|
+
await writeFile2(projectPath, "build.js", `console.log('build ok');
|
|
1166
|
+
`);
|
|
1167
|
+
},
|
|
1168
|
+
evaluate: (ctx) => Promise.resolve(validate(ctx))
|
|
1169
|
+
},
|
|
1170
|
+
{
|
|
1171
|
+
id: "update-config",
|
|
1172
|
+
name: "Update a config value",
|
|
1173
|
+
title: "Update timeout value in config.json",
|
|
1174
|
+
description: "Change `config.json` so that `timeout` is `5000` instead of `1000`. The test will read the file and assert the value.",
|
|
1175
|
+
complexity: "simple",
|
|
1176
|
+
setup: async (projectPath) => {
|
|
1177
|
+
await writeJson(projectPath, "package.json", basePackage());
|
|
1178
|
+
await writeJson(projectPath, "config.json", { timeout: 1e3, retries: 3 });
|
|
1179
|
+
await writeFile2(projectPath, "test.js", `import { readFile } from 'node:fs/promises';
|
|
1180
|
+
const cfg = JSON.parse(await readFile('./config.json', 'utf-8'));
|
|
1181
|
+
if (cfg.timeout !== 5000) { console.error('timeout is ' + cfg.timeout); process.exit(1); }
|
|
1182
|
+
console.log('config test passed');
|
|
1183
|
+
`);
|
|
1184
|
+
await writeFile2(projectPath, "lint.js", `console.log('lint ok');
|
|
1185
|
+
`);
|
|
1186
|
+
await writeFile2(projectPath, "build.js", `console.log('build ok');
|
|
1187
|
+
`);
|
|
1188
|
+
},
|
|
1189
|
+
evaluate: (ctx) => Promise.resolve(validate(ctx))
|
|
1190
|
+
},
|
|
1191
|
+
{
|
|
1192
|
+
id: "extract-constant",
|
|
1193
|
+
name: "Extract a magic constant",
|
|
1194
|
+
title: "Extract MAX_RETRIES constant",
|
|
1195
|
+
description: "Refactor `src/retry.js` so the magic number `3` is replaced by a top-level constant named `MAX_RETRIES`. The test checks for the constant.",
|
|
1196
|
+
complexity: "medium",
|
|
1197
|
+
setup: async (projectPath) => {
|
|
1198
|
+
await writeJson(projectPath, "package.json", basePackage());
|
|
1199
|
+
await writeFile2(projectPath, "src/retry.js", `export function attempts() { return 3; }
|
|
1200
|
+
`);
|
|
1201
|
+
await writeFile2(projectPath, "test.js", `import fs from 'node:fs/promises';
|
|
1202
|
+
import { attempts } from './src/retry.js';
|
|
1203
|
+
const code = await fs.readFile('./src/retry.js', 'utf-8');
|
|
1204
|
+
if (!code.includes('const MAX_RETRIES')) { console.error('MAX_RETRIES constant not found'); process.exit(1); }
|
|
1205
|
+
if (attempts() !== 3) { console.error('attempts() changed'); process.exit(1); }
|
|
1206
|
+
console.log('constant test passed');
|
|
1207
|
+
`);
|
|
1208
|
+
await writeFile2(projectPath, "lint.js", `console.log('lint ok');
|
|
1209
|
+
`);
|
|
1210
|
+
await writeFile2(projectPath, "build.js", `console.log('build ok');
|
|
1211
|
+
`);
|
|
1212
|
+
},
|
|
1213
|
+
evaluate: (ctx) => Promise.resolve(validate(ctx))
|
|
1214
|
+
},
|
|
1215
|
+
{
|
|
1216
|
+
id: "noop-validation",
|
|
1217
|
+
name: "Run validation on a clean project",
|
|
1218
|
+
title: "Confirm the project already passes validation",
|
|
1219
|
+
description: "This project already passes lint, test and build. Use the publish tool to confirm validation passes and finish.",
|
|
1220
|
+
complexity: "simple",
|
|
1221
|
+
setup: async (projectPath) => {
|
|
1222
|
+
await writeJson(projectPath, "package.json", basePackage());
|
|
1223
|
+
await writeFile2(projectPath, "test.js", `console.log('test ok');
|
|
1224
|
+
`);
|
|
1225
|
+
await writeFile2(projectPath, "lint.js", `console.log('lint ok');
|
|
1226
|
+
`);
|
|
1227
|
+
await writeFile2(projectPath, "build.js", `console.log('build ok');
|
|
1228
|
+
`);
|
|
1229
|
+
},
|
|
1230
|
+
evaluate: (ctx) => Promise.resolve(validate(ctx))
|
|
1231
|
+
}
|
|
1232
|
+
];
|
|
1233
|
+
function syntheticSuite() {
|
|
1234
|
+
return TASKS;
|
|
1235
|
+
}
|
|
1236
|
+
|
|
1237
|
+
// ../bench/dist/adapters/deepswe.js
|
|
1238
|
+
import fs4 from "node:fs/promises";
|
|
1239
|
+
import path7 from "node:path";
|
|
1240
|
+
import { execFile } from "node:child_process";
|
|
1241
|
+
import { promisify } from "node:util";
|
|
1242
|
+
var execFileAsync = promisify(execFile);
|
|
1243
|
+
function parseToml(raw) {
|
|
1244
|
+
const result = { task: {}, metadata: {} };
|
|
1245
|
+
let section;
|
|
1246
|
+
for (const line of raw.split("\n")) {
|
|
1247
|
+
const trimmed = line.trim();
|
|
1248
|
+
if (trimmed.startsWith("[")) {
|
|
1249
|
+
const name = trimmed.slice(1, -1).split(".")[0];
|
|
1250
|
+
if (name === "task" || name === "metadata")
|
|
1251
|
+
section = name;
|
|
1252
|
+
continue;
|
|
1253
|
+
}
|
|
1254
|
+
if (!section || trimmed.startsWith("#") || !trimmed.includes("="))
|
|
1255
|
+
continue;
|
|
1256
|
+
const eq = trimmed.indexOf("=");
|
|
1257
|
+
const key = trimmed.slice(0, eq).trim();
|
|
1258
|
+
let value = trimmed.slice(eq + 1).trim();
|
|
1259
|
+
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
1260
|
+
value = value.slice(1, -1);
|
|
1261
|
+
}
|
|
1262
|
+
if (section === "task") {
|
|
1263
|
+
result.task ??= {};
|
|
1264
|
+
result.task[key] = value;
|
|
1265
|
+
} else {
|
|
1266
|
+
result.metadata ??= {};
|
|
1267
|
+
result.metadata[key] = value;
|
|
1268
|
+
}
|
|
1269
|
+
}
|
|
1270
|
+
return result;
|
|
1271
|
+
}
|
|
1272
|
+
function mulberry32(seed) {
|
|
1273
|
+
return () => {
|
|
1274
|
+
let t = seed += 1831565813;
|
|
1275
|
+
t = Math.imul(t ^ t >>> 15, t | 1);
|
|
1276
|
+
t ^= t + Math.imul(t ^ t >>> 7, t | 61);
|
|
1277
|
+
return ((t ^ t >>> 14) >>> 0) / 4294967296;
|
|
1278
|
+
};
|
|
1279
|
+
}
|
|
1280
|
+
async function readTask(taskDir) {
|
|
1281
|
+
const tomlRaw = await fs4.readFile(path7.join(taskDir, "task.toml"), "utf-8");
|
|
1282
|
+
const instructionRaw = await fs4.readFile(path7.join(taskDir, "instruction.md"), "utf-8");
|
|
1283
|
+
return { toml: parseToml(tomlRaw), instruction: instructionRaw };
|
|
1284
|
+
}
|
|
1285
|
+
async function cloneRepo(repoUrl, commit, targetPath) {
|
|
1286
|
+
await fs4.mkdir(path7.dirname(targetPath), { recursive: true });
|
|
1287
|
+
await execFileAsync("git", ["clone", repoUrl, targetPath], { timeout: 12e4 });
|
|
1288
|
+
await execFileAsync("git", ["-C", targetPath, "checkout", commit], { timeout: 6e4 });
|
|
1289
|
+
}
|
|
1290
|
+
async function loadDeepSWESuite(options) {
|
|
1291
|
+
const entries = await fs4.readdir(options.tasksDir, { withFileTypes: true });
|
|
1292
|
+
const taskDirs = entries.filter((e) => e.isDirectory()).map((e) => path7.join(options.tasksDir, e.name));
|
|
1293
|
+
let loaded = [];
|
|
1294
|
+
for (const dir of taskDirs) {
|
|
1295
|
+
try {
|
|
1296
|
+
const data = await readTask(dir);
|
|
1297
|
+
loaded.push({ dir, ...data });
|
|
1298
|
+
} catch {
|
|
1299
|
+
}
|
|
1300
|
+
}
|
|
1301
|
+
if (options.taskIds && options.taskIds.length > 0) {
|
|
1302
|
+
loaded = loaded.filter((t) => {
|
|
1303
|
+
const id = t.toml.metadata?.task_id ?? path7.basename(t.dir);
|
|
1304
|
+
return options.taskIds?.includes(id);
|
|
1305
|
+
});
|
|
1306
|
+
}
|
|
1307
|
+
if (options.nTasks && options.nTasks > 0 && options.nTasks < loaded.length) {
|
|
1308
|
+
const seed = options.sampleSeed ?? 0;
|
|
1309
|
+
const rnd = mulberry32(seed);
|
|
1310
|
+
loaded = loaded.map((t) => ({ t, sort: rnd() })).sort((a, b) => a.sort - b.sort).slice(0, options.nTasks).map((x) => x.t);
|
|
1311
|
+
}
|
|
1312
|
+
const tasks = [];
|
|
1313
|
+
for (const { dir, toml, instruction } of loaded) {
|
|
1314
|
+
const id = toml.metadata?.task_id ?? path7.basename(dir);
|
|
1315
|
+
const title = toml.metadata?.display_title ?? toml.metadata?.original_title ?? id;
|
|
1316
|
+
const repo = toml.metadata?.repository_url;
|
|
1317
|
+
const commit = toml.metadata?.base_commit_hash;
|
|
1318
|
+
tasks.push({
|
|
1319
|
+
id: `deepswe-${id}`,
|
|
1320
|
+
name: id,
|
|
1321
|
+
title,
|
|
1322
|
+
description: instruction,
|
|
1323
|
+
complexity: "complex",
|
|
1324
|
+
setup: async (projectPath) => {
|
|
1325
|
+
if (!repo || !commit) {
|
|
1326
|
+
throw new Error(`DeepSWE task ${id} is missing repository_url or base_commit_hash`);
|
|
1327
|
+
}
|
|
1328
|
+
await cloneRepo(repo, commit, projectPath);
|
|
1329
|
+
},
|
|
1330
|
+
evaluate: (ctx) => {
|
|
1331
|
+
const hasDiff = ctx.diffs.length > 0 && ctx.diffs.some((d) => d.patch.trim().length > 0);
|
|
1332
|
+
const done = ctx.agentRun?.resultStatus === "done";
|
|
1333
|
+
const passed = done && hasDiff;
|
|
1334
|
+
return Promise.resolve({
|
|
1335
|
+
passed,
|
|
1336
|
+
message: passed ? `Agent finished and produced a diff (${String(ctx.diffs[0]?.patch.length ?? 0)} chars)` : `Agent status=${ctx.agentRun?.resultStatus ?? "unknown"}, diff=${hasDiff ? "yes" : "no"}`
|
|
1337
|
+
});
|
|
1338
|
+
}
|
|
1339
|
+
});
|
|
1340
|
+
}
|
|
1341
|
+
return tasks;
|
|
1342
|
+
}
|
|
1343
|
+
|
|
1344
|
+
// ../bench/dist/optimise.js
|
|
1345
|
+
import fs5 from "node:fs/promises";
|
|
1346
|
+
import path8 from "node:path";
|
|
1347
|
+
async function findLatestReport(outputDir) {
|
|
1348
|
+
const entries = await fs5.readdir(outputDir).catch(() => []);
|
|
1349
|
+
const files = entries.filter((f) => f.startsWith("benchmark-") && f.endsWith(".json")).sort().reverse();
|
|
1350
|
+
if (files.length === 0)
|
|
1351
|
+
return void 0;
|
|
1352
|
+
const raw = await fs5.readFile(path8.join(outputDir, files[0]), "utf-8");
|
|
1353
|
+
return JSON.parse(raw);
|
|
1354
|
+
}
|
|
1355
|
+
function summariseTraceFlow(report, maxLines = 60) {
|
|
1356
|
+
const lines = report.split("\n");
|
|
1357
|
+
if (lines.length <= maxLines)
|
|
1358
|
+
return report;
|
|
1359
|
+
return lines.slice(0, maxLines).join("\n") + "\n... (truncated)";
|
|
1360
|
+
}
|
|
1361
|
+
function buildOptimisePrompt(report, failedResult, traceFlowText) {
|
|
1362
|
+
const passRate = report.total > 0 ? Math.round(report.passed / report.total * 100) : 0;
|
|
1363
|
+
const failed = report.results.filter((r) => !r.evaluation.passed);
|
|
1364
|
+
const lines = [];
|
|
1365
|
+
lines.push("# Prompt optimisation task");
|
|
1366
|
+
lines.push("");
|
|
1367
|
+
lines.push(`The latest benchmark run achieved ${String(passRate)}% pass rate (${String(report.passed)}/${String(report.total)}).`);
|
|
1368
|
+
lines.push("");
|
|
1369
|
+
lines.push("## Failed tasks");
|
|
1370
|
+
for (const r of failed.slice(0, 5)) {
|
|
1371
|
+
lines.push(`- ${r.task.name}: ${r.evaluation.message ?? "no message"}`);
|
|
1372
|
+
}
|
|
1373
|
+
lines.push("");
|
|
1374
|
+
if (failedResult) {
|
|
1375
|
+
lines.push(`## Focus task: ${failedResult.task.name}`);
|
|
1376
|
+
lines.push(`Status: ${failedResult.status}`);
|
|
1377
|
+
lines.push(`Evaluation: ${failedResult.evaluation.message ?? "none"}`);
|
|
1378
|
+
lines.push("");
|
|
1379
|
+
}
|
|
1380
|
+
if (traceFlowText) {
|
|
1381
|
+
lines.push("## Trace flow snapshot");
|
|
1382
|
+
lines.push("```json");
|
|
1383
|
+
lines.push(summariseTraceFlow(traceFlowText));
|
|
1384
|
+
lines.push("```");
|
|
1385
|
+
lines.push("");
|
|
1386
|
+
}
|
|
1387
|
+
lines.push("## Instructions");
|
|
1388
|
+
lines.push("Analyse the failures above and edit `packages/agent/src/prompts.ts` (and optionally `packages/agent/src/planner.ts`) to improve the Omega agent.");
|
|
1389
|
+
lines.push("Rules:");
|
|
1390
|
+
lines.push("- Keep changes minimal and targeted.");
|
|
1391
|
+
lines.push("- Do not break existing tool signatures or system behaviour.");
|
|
1392
|
+
lines.push("- Run `pnpm lint` and `pnpm test` after edits.");
|
|
1393
|
+
lines.push("- Finish with a summary of what changed and why it should help.");
|
|
1394
|
+
return lines.join("\n");
|
|
1395
|
+
}
|
|
1396
|
+
async function loadOptimisationContext(apiUrl, outputDir) {
|
|
1397
|
+
const report = await findLatestReport(outputDir);
|
|
1398
|
+
if (!report)
|
|
1399
|
+
return void 0;
|
|
1400
|
+
const failedResult = report.results.find((r) => !r.evaluation.passed);
|
|
1401
|
+
let traceFlowText;
|
|
1402
|
+
if (failedResult?.harnessTaskId) {
|
|
1403
|
+
const traceFlow = await getTraceFlow(apiUrl, failedResult.harnessTaskId);
|
|
1404
|
+
if (traceFlow) {
|
|
1405
|
+
traceFlowText = JSON.stringify(traceFlow, null, 2);
|
|
1406
|
+
}
|
|
1407
|
+
}
|
|
1408
|
+
return { report, failedResult, traceFlowText };
|
|
1409
|
+
}
|
|
1410
|
+
async function submitOptimiseTask(apiUrl, projectId, prompt) {
|
|
1411
|
+
const title = "Optimise agent prompts from benchmark trace analysis";
|
|
1412
|
+
const res = await fetch(`${apiUrl}/tasks`, {
|
|
1413
|
+
method: "POST",
|
|
1414
|
+
headers: { "Content-Type": "application/json" },
|
|
1415
|
+
body: JSON.stringify({
|
|
1416
|
+
projectId,
|
|
1417
|
+
title,
|
|
1418
|
+
description: prompt,
|
|
1419
|
+
complexity: "complex",
|
|
1420
|
+
tags: ["self-improve", "benchmark"]
|
|
1421
|
+
})
|
|
1422
|
+
});
|
|
1423
|
+
if (!res.ok)
|
|
1424
|
+
throw new Error(`submit optimise task failed: ${String(res.status)}`);
|
|
1425
|
+
return res.json();
|
|
1426
|
+
}
|
|
1427
|
+
|
|
1428
|
+
// ../../apps/cli/src/commands/bench.ts
|
|
1429
|
+
async function waitForApi2(apiUrl, maxMs = 1e4) {
|
|
1430
|
+
const deadline = Date.now() + maxMs;
|
|
1431
|
+
while (Date.now() < deadline) {
|
|
1432
|
+
try {
|
|
1433
|
+
const res = await fetch(`${apiUrl}/projects`);
|
|
1434
|
+
if (res.ok) return;
|
|
1435
|
+
} catch {
|
|
1436
|
+
}
|
|
1437
|
+
await new Promise((r) => setTimeout(r, 300));
|
|
1438
|
+
}
|
|
1439
|
+
throw new Error(`Harness API is not ready at ${apiUrl}. Run \`omega ui\` or \`omega console\` first.`);
|
|
1440
|
+
}
|
|
1441
|
+
function currentProject(apiUrl) {
|
|
1442
|
+
const cwd = process.cwd();
|
|
1443
|
+
const name = path9.basename(cwd);
|
|
1444
|
+
return ensureProject2(apiUrl, `bench-${name}`, cwd);
|
|
1445
|
+
}
|
|
1446
|
+
var runCmd = new Command8("run").description("Run a benchmark suite").option("--suite <name>", "suite name: synthetic | deep-swe", "synthetic").option("--path <dir>", "path to DeepSWE tasks directory (for deep-swe suite)").option("--n-tasks <n>", "limit number of tasks (for deep-swe)", parseInt).option("--sample-seed <n>", "seed for deterministic sampling (for deep-swe)", parseInt).option("--timeout <ms>", "per-task timeout in ms", "120000").option("--output-dir <dir>", "report output directory", ".omega/reports").action(async (opts) => {
|
|
1447
|
+
const apiUrl = getApiUrl();
|
|
1448
|
+
await waitForApi2(apiUrl);
|
|
1449
|
+
const timeoutMs = Number(opts.timeout);
|
|
1450
|
+
let tasks;
|
|
1451
|
+
let suiteName;
|
|
1452
|
+
if (opts.suite === "deep-swe") {
|
|
1453
|
+
if (!opts.path) {
|
|
1454
|
+
throw new Error("--path is required for the deep-swe suite");
|
|
1455
|
+
}
|
|
1456
|
+
tasks = await loadDeepSWESuite({
|
|
1457
|
+
tasksDir: opts.path,
|
|
1458
|
+
nTasks: opts.nTasks,
|
|
1459
|
+
sampleSeed: opts.sampleSeed
|
|
1460
|
+
});
|
|
1461
|
+
suiteName = "deep-swe";
|
|
1462
|
+
} else if (opts.suite === "synthetic") {
|
|
1463
|
+
tasks = syntheticSuite();
|
|
1464
|
+
suiteName = "synthetic";
|
|
1465
|
+
} else {
|
|
1466
|
+
throw new Error(`Unknown suite: ${opts.suite}`);
|
|
1467
|
+
}
|
|
1468
|
+
if (tasks.length === 0) {
|
|
1469
|
+
console.log("No benchmark tasks to run.");
|
|
1470
|
+
return;
|
|
1471
|
+
}
|
|
1472
|
+
console.log(`Running ${String(tasks.length)} benchmark tasks against ${apiUrl}`);
|
|
1473
|
+
const report = await runBenchmark(tasks, {
|
|
1474
|
+
apiUrl,
|
|
1475
|
+
suiteName,
|
|
1476
|
+
timeoutMs,
|
|
1477
|
+
onProgress: (result) => {
|
|
1478
|
+
const symbol = result.evaluation.passed ? "\u2713" : "\u2717";
|
|
1479
|
+
console.log(`${symbol} ${result.task.name} [${result.status}] ${String(result.durationMs)}ms`);
|
|
1480
|
+
}
|
|
1481
|
+
});
|
|
1482
|
+
const reportFile = await writeReport(report, opts.outputDir);
|
|
1483
|
+
printSummary(report);
|
|
1484
|
+
console.log(`
|
|
1485
|
+
Report written to ${reportFile}`);
|
|
1486
|
+
});
|
|
1487
|
+
var optimiseCmd = new Command8("optimise").description("Create a self-improve task from the latest benchmark report").option("--output-dir <dir>", "report output directory", ".omega/reports").action(async (opts) => {
|
|
1488
|
+
const apiUrl = getApiUrl();
|
|
1489
|
+
await waitForApi2(apiUrl);
|
|
1490
|
+
const context = await loadOptimisationContext(apiUrl, opts.outputDir);
|
|
1491
|
+
if (!context) {
|
|
1492
|
+
console.log("No benchmark report found. Run `omega bench run` first.");
|
|
1493
|
+
return;
|
|
1494
|
+
}
|
|
1495
|
+
const project = await currentProject(apiUrl);
|
|
1496
|
+
const prompt = buildOptimisePrompt(
|
|
1497
|
+
context.report,
|
|
1498
|
+
context.failedResult,
|
|
1499
|
+
context.traceFlowText
|
|
1500
|
+
);
|
|
1501
|
+
const task = await submitOptimiseTask(apiUrl, project.id, prompt);
|
|
1502
|
+
console.log(`Created self-improve task ${task.id}`);
|
|
1503
|
+
console.log(`Run \`omega task run ${task.id}\` to execute it.`);
|
|
1504
|
+
});
|
|
1505
|
+
var benchCmd = new Command8("bench").description("Run benchmarks and optimise prompts").addCommand(runCmd).addCommand(optimiseCmd);
|
|
1506
|
+
|
|
820
1507
|
// ../../apps/cli/src/index.ts
|
|
821
1508
|
program2.name("harness").description("Omega harness CLI").version("0.1.0").option("--api <url>", "API base URL", "http://localhost:4000");
|
|
822
1509
|
program2.addCommand(projectCmd);
|
|
@@ -825,4 +1512,5 @@ program2.addCommand(uiCmd);
|
|
|
825
1512
|
program2.addCommand(consoleCmd);
|
|
826
1513
|
program2.addCommand(skillCmd);
|
|
827
1514
|
program2.addCommand(agentCmd);
|
|
1515
|
+
program2.addCommand(benchCmd);
|
|
828
1516
|
program2.parse();
|