poe-code 3.0.129 → 3.0.130
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/commands/experiment.js +68 -5
- package/dist/cli/commands/experiment.js.map +1 -1
- package/dist/index.js +222 -318
- package/dist/index.js.map +3 -3
- package/dist/sdk/experiment.d.ts +5 -1
- package/dist/sdk/experiment.js +7 -0
- package/dist/sdk/experiment.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -8154,7 +8154,7 @@ function interpolate(template, values) {
|
|
|
8154
8154
|
}
|
|
8155
8155
|
return output;
|
|
8156
8156
|
}
|
|
8157
|
-
async function resolveFileIncludes(template, cwd,
|
|
8157
|
+
async function resolveFileIncludes(template, cwd, readFile15) {
|
|
8158
8158
|
const matches = [...template.matchAll(FILE_INCLUDE_PATTERN)];
|
|
8159
8159
|
if (matches.length === 0) {
|
|
8160
8160
|
return template;
|
|
@@ -8162,7 +8162,7 @@ async function resolveFileIncludes(template, cwd, readFile14) {
|
|
|
8162
8162
|
let result = template;
|
|
8163
8163
|
for (const match of matches) {
|
|
8164
8164
|
const absolutePath = path14.resolve(cwd, match[1]);
|
|
8165
|
-
const content = await
|
|
8165
|
+
const content = await readFile15(absolutePath, "utf8");
|
|
8166
8166
|
result = result.replace(match[0], content);
|
|
8167
8167
|
}
|
|
8168
8168
|
return result;
|
|
@@ -8288,10 +8288,10 @@ function createDefaultFs3() {
|
|
|
8288
8288
|
function isAbortError(error2) {
|
|
8289
8289
|
return error2 instanceof Error && error2.name === "AbortError";
|
|
8290
8290
|
}
|
|
8291
|
-
async function resolveVars(vars, cwd,
|
|
8291
|
+
async function resolveVars(vars, cwd, readFile15) {
|
|
8292
8292
|
const resolved = {};
|
|
8293
8293
|
for (const [key, value] of Object.entries(vars)) {
|
|
8294
|
-
resolved[key] = await resolveFileIncludes(value, cwd,
|
|
8294
|
+
resolved[key] = await resolveFileIncludes(value, cwd, readFile15);
|
|
8295
8295
|
}
|
|
8296
8296
|
return resolved;
|
|
8297
8297
|
}
|
|
@@ -10640,12 +10640,6 @@ function parseExperimentFrontmatter(content) {
|
|
|
10640
10640
|
body: parsed.content
|
|
10641
10641
|
};
|
|
10642
10642
|
}
|
|
10643
|
-
async function writeExperimentFrontmatter(docPath, frontmatter, body, fs3) {
|
|
10644
|
-
await fs3.mkdir(dirname(docPath), { recursive: true });
|
|
10645
|
-
const serialized = matter.stringify(body, serializeFrontmatter(frontmatter));
|
|
10646
|
-
const content = body.endsWith("\n") || !serialized.endsWith("\n") ? serialized : serialized.slice(0, -1);
|
|
10647
|
-
await fs3.writeFile(docPath, content);
|
|
10648
|
-
}
|
|
10649
10643
|
function parseFrontmatterData2(value) {
|
|
10650
10644
|
const parsed = isRecord5(value) ? value : void 0;
|
|
10651
10645
|
const agent2 = parseAgent2(parsed?.agent);
|
|
@@ -10657,22 +10651,7 @@ function parseFrontmatterData2(value) {
|
|
|
10657
10651
|
...metric !== void 0 ? { metric } : {},
|
|
10658
10652
|
baseline: parseBaseline(parsed?.baseline),
|
|
10659
10653
|
...maxExperiments !== void 0 ? { maxExperiments } : {},
|
|
10660
|
-
...metricTimeout !== void 0 ? { metricTimeout } : {}
|
|
10661
|
-
status: parseStatus(parsed?.status)
|
|
10662
|
-
};
|
|
10663
|
-
}
|
|
10664
|
-
function serializeFrontmatter(frontmatter) {
|
|
10665
|
-
return {
|
|
10666
|
-
...frontmatter.agent !== void 0 ? { agent: frontmatter.agent } : {},
|
|
10667
|
-
...frontmatter.metric !== void 0 ? { metric: frontmatter.metric } : {},
|
|
10668
|
-
baseline: frontmatter.baseline,
|
|
10669
|
-
...frontmatter.maxExperiments !== void 0 ? { maxExperiments: frontmatter.maxExperiments } : {},
|
|
10670
|
-
...frontmatter.metricTimeout !== void 0 ? { metricTimeout: frontmatter.metricTimeout } : {},
|
|
10671
|
-
status: {
|
|
10672
|
-
state: frontmatter.status.state,
|
|
10673
|
-
experiment: frontmatter.status.experiment,
|
|
10674
|
-
kept: frontmatter.status.kept
|
|
10675
|
-
}
|
|
10654
|
+
...metricTimeout !== void 0 ? { metricTimeout } : {}
|
|
10676
10655
|
};
|
|
10677
10656
|
}
|
|
10678
10657
|
function parseMetric(value) {
|
|
@@ -10716,14 +10695,6 @@ function parseBaseline(value) {
|
|
|
10716
10695
|
}).filter((entry) => entry !== void 0);
|
|
10717
10696
|
return baselineEntries.length === Object.keys(value).length ? Object.fromEntries(baselineEntries) : null;
|
|
10718
10697
|
}
|
|
10719
|
-
function parseStatus(value) {
|
|
10720
|
-
const parsed = isRecord5(value) ? value : void 0;
|
|
10721
|
-
return {
|
|
10722
|
-
state: parseString(parsed?.state) ?? DEFAULT_STATUS2.state,
|
|
10723
|
-
experiment: parseNonNegativeInteger2(parsed?.experiment) ?? DEFAULT_STATUS2.experiment,
|
|
10724
|
-
kept: parseNonNegativeInteger2(parsed?.kept) ?? DEFAULT_STATUS2.kept
|
|
10725
|
-
};
|
|
10726
|
-
}
|
|
10727
10698
|
function parseAgent2(value) {
|
|
10728
10699
|
if (typeof value === "string") {
|
|
10729
10700
|
return parseString(value);
|
|
@@ -10754,20 +10725,23 @@ function parseNonNegativeInteger2(value) {
|
|
|
10754
10725
|
function isRecord5(value) {
|
|
10755
10726
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
10756
10727
|
}
|
|
10757
|
-
var DEFAULT_STATUS2;
|
|
10758
10728
|
var init_frontmatter2 = __esm({
|
|
10759
10729
|
"packages/experiment-loop/src/frontmatter/frontmatter.ts"() {
|
|
10760
10730
|
"use strict";
|
|
10761
|
-
DEFAULT_STATUS2 = {
|
|
10762
|
-
state: "open",
|
|
10763
|
-
experiment: 0,
|
|
10764
|
-
kept: 0
|
|
10765
|
-
};
|
|
10766
10731
|
}
|
|
10767
10732
|
});
|
|
10768
10733
|
|
|
10769
10734
|
// packages/experiment-loop/src/journal/journal.ts
|
|
10770
10735
|
import { dirname as dirname2 } from "node:path";
|
|
10736
|
+
function baselineFromEntry(metrics, entry) {
|
|
10737
|
+
if (entry.scores) {
|
|
10738
|
+
return entry.scores;
|
|
10739
|
+
}
|
|
10740
|
+
if (entry.score !== null && metrics.length === 1) {
|
|
10741
|
+
return { [metrics[0].name]: entry.score };
|
|
10742
|
+
}
|
|
10743
|
+
return null;
|
|
10744
|
+
}
|
|
10771
10745
|
function parseLine(line) {
|
|
10772
10746
|
try {
|
|
10773
10747
|
return [JSON.parse(line)];
|
|
@@ -10833,6 +10807,20 @@ var init_journal = __esm({
|
|
|
10833
10807
|
}
|
|
10834
10808
|
return content.split("\n").filter((line) => line.length > 0).flatMap((line) => parseLine(line));
|
|
10835
10809
|
}
|
|
10810
|
+
async updateLast(updates) {
|
|
10811
|
+
const entries = await this.readAll();
|
|
10812
|
+
if (entries.length === 0) {
|
|
10813
|
+
return null;
|
|
10814
|
+
}
|
|
10815
|
+
const last = entries[entries.length - 1];
|
|
10816
|
+
const updated = { ...last, ...updates };
|
|
10817
|
+
entries[entries.length - 1] = updated;
|
|
10818
|
+
await this.fs.writeFile(
|
|
10819
|
+
this.journalPath,
|
|
10820
|
+
entries.map((e) => JSON.stringify(e)).join("\n") + "\n"
|
|
10821
|
+
);
|
|
10822
|
+
return updated;
|
|
10823
|
+
}
|
|
10836
10824
|
async format() {
|
|
10837
10825
|
const entries = await this.readAll();
|
|
10838
10826
|
return [
|
|
@@ -10919,20 +10907,6 @@ async function readCurrentHash(exec3, cwd) {
|
|
|
10919
10907
|
}
|
|
10920
10908
|
function createDefaultGit(exec3) {
|
|
10921
10909
|
return {
|
|
10922
|
-
async commitAll(message2, cwd) {
|
|
10923
|
-
await runOrThrow(exec3, `git add -A -- . ':!${EXPERIMENT_DOCS_PATH}'`, cwd);
|
|
10924
|
-
const diffResult = await exec3("git diff --cached --quiet", { cwd });
|
|
10925
|
-
if (diffResult.exitCode === 0) {
|
|
10926
|
-
return readCurrentHash(exec3, cwd);
|
|
10927
|
-
}
|
|
10928
|
-
if (diffResult.exitCode !== 1) {
|
|
10929
|
-
throw new Error(
|
|
10930
|
-
diffResult.stderr || diffResult.stdout || "Failed to detect staged git changes"
|
|
10931
|
-
);
|
|
10932
|
-
}
|
|
10933
|
-
await runOrThrow(exec3, `git commit -m ${shellEscape(message2)}`, cwd);
|
|
10934
|
-
return readCurrentHash(exec3, cwd);
|
|
10935
|
-
},
|
|
10936
10910
|
async reset(commitHash, cwd) {
|
|
10937
10911
|
const stashResult = await exec3(
|
|
10938
10912
|
`git stash push -q --include-untracked -- ${EXPERIMENT_DOCS_PATH}`,
|
|
@@ -10959,6 +10933,8 @@ var init_git = __esm({
|
|
|
10959
10933
|
|
|
10960
10934
|
// packages/experiment-loop/src/config/loader.ts
|
|
10961
10935
|
import path23 from "node:path";
|
|
10936
|
+
import { readFile as readFile5 } from "node:fs/promises";
|
|
10937
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
10962
10938
|
import { parse as parse7 } from "yaml";
|
|
10963
10939
|
function isRecord6(value) {
|
|
10964
10940
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -10996,8 +10972,20 @@ function parseRunConfigDocument(filePath, content) {
|
|
|
10996
10972
|
}
|
|
10997
10973
|
return { prompt };
|
|
10998
10974
|
}
|
|
10999
|
-
function
|
|
11000
|
-
|
|
10975
|
+
async function readBundledFile(name) {
|
|
10976
|
+
const filePath = fileURLToPath2(new URL(`./${name}`, import.meta.url));
|
|
10977
|
+
return readFile5(filePath, "utf8");
|
|
10978
|
+
}
|
|
10979
|
+
async function readDefaultRunConfig() {
|
|
10980
|
+
const content = await readBundledFile("default-run.yaml");
|
|
10981
|
+
const config = parseRunConfigDocument("default-run.yaml", content);
|
|
10982
|
+
if (!config) {
|
|
10983
|
+
throw new Error("default-run.yaml is empty or invalid.");
|
|
10984
|
+
}
|
|
10985
|
+
return config;
|
|
10986
|
+
}
|
|
10987
|
+
async function loadInstructions() {
|
|
10988
|
+
return readBundledFile("default-instructions.md");
|
|
11001
10989
|
}
|
|
11002
10990
|
async function loadRunConfig(options) {
|
|
11003
10991
|
const projectPath = path23.join(options.cwd, ".poe-code", "experiments", "run.yaml");
|
|
@@ -11016,26 +11004,11 @@ async function loadRunConfig(options) {
|
|
|
11016
11004
|
return config;
|
|
11017
11005
|
}
|
|
11018
11006
|
}
|
|
11019
|
-
return
|
|
11007
|
+
return readDefaultRunConfig();
|
|
11020
11008
|
}
|
|
11021
|
-
var DEFAULT_PROMPT;
|
|
11022
11009
|
var init_loader2 = __esm({
|
|
11023
11010
|
"packages/experiment-loop/src/config/loader.ts"() {
|
|
11024
11011
|
"use strict";
|
|
11025
|
-
DEFAULT_PROMPT = `{{body}}
|
|
11026
|
-
|
|
11027
|
-
## Metrics
|
|
11028
|
-
|
|
11029
|
-
{{metrics}}
|
|
11030
|
-
|
|
11031
|
-
## Journal
|
|
11032
|
-
|
|
11033
|
-
{{journal}}
|
|
11034
|
-
|
|
11035
|
-
{{crash_output}}
|
|
11036
|
-
|
|
11037
|
-
You are autonomous, do not stop or ask for input.
|
|
11038
|
-
Do not write to the journal file or commit changes. Both are managed automatically after your run completes.`;
|
|
11039
11012
|
}
|
|
11040
11013
|
});
|
|
11041
11014
|
|
|
@@ -11135,9 +11108,6 @@ function createAbortError5() {
|
|
|
11135
11108
|
function isAbortError3(error2) {
|
|
11136
11109
|
return error2 instanceof Error && error2.name === "AbortError";
|
|
11137
11110
|
}
|
|
11138
|
-
function combineOutput(stdout, stderr) {
|
|
11139
|
-
return `${stdout}${stderr}`;
|
|
11140
|
-
}
|
|
11141
11111
|
function interpolate2(template, values) {
|
|
11142
11112
|
let output = template;
|
|
11143
11113
|
for (const [key, value] of Object.entries(values)) {
|
|
@@ -11160,41 +11130,25 @@ function formatMetrics(metrics, baseline) {
|
|
|
11160
11130
|
}).join("\n");
|
|
11161
11131
|
}
|
|
11162
11132
|
function buildPrompt(options) {
|
|
11163
|
-
|
|
11133
|
+
const vars = {
|
|
11164
11134
|
body: options.body.trim(),
|
|
11165
11135
|
journal: options.journal,
|
|
11166
11136
|
metrics: formatMetrics(options.metrics, options.baseline),
|
|
11167
|
-
crash_output: options.lastCrashOutput ? `## Last crash output
|
|
11168
|
-
|
|
11169
|
-
${options.lastCrashOutput.trim()}` : "",
|
|
11170
11137
|
experiment_index: String(options.experimentIndex),
|
|
11171
|
-
baseline: options.baseline ? JSON.stringify(options.baseline) : ""
|
|
11172
|
-
|
|
11138
|
+
baseline: options.baseline ? JSON.stringify(options.baseline) : "",
|
|
11139
|
+
doc_path: options.docPath,
|
|
11140
|
+
doc_name: options.docName
|
|
11141
|
+
};
|
|
11142
|
+
const context = interpolate2(options.runConfig.prompt, vars).trim();
|
|
11143
|
+
const instructions = interpolate2(options.instructions, vars).trim();
|
|
11144
|
+
return `${context}
|
|
11145
|
+
|
|
11146
|
+
${instructions}`;
|
|
11173
11147
|
}
|
|
11174
11148
|
function allMetricsPassed(metrics, results) {
|
|
11175
11149
|
return results.length === metrics.length && results.every((result) => result.passed);
|
|
11176
11150
|
}
|
|
11177
|
-
function
|
|
11178
|
-
return metrics.every((metric, index) => {
|
|
11179
|
-
const score = results[index]?.score;
|
|
11180
|
-
if (score === null || score === void 0) {
|
|
11181
|
-
return false;
|
|
11182
|
-
}
|
|
11183
|
-
const baselineScore = baseline?.[metric.name];
|
|
11184
|
-
if (baselineScore === void 0) {
|
|
11185
|
-
return true;
|
|
11186
|
-
}
|
|
11187
|
-
const delta = metric.delta;
|
|
11188
|
-
if (metric.direction === "stable") {
|
|
11189
|
-
return delta !== void 0 ? Math.abs(score - baselineScore) <= delta : score === baselineScore;
|
|
11190
|
-
}
|
|
11191
|
-
if (metric.direction === "maximize") {
|
|
11192
|
-
return delta !== void 0 ? score >= baselineScore - delta : score > baselineScore;
|
|
11193
|
-
}
|
|
11194
|
-
return delta !== void 0 ? score <= baselineScore + delta : score < baselineScore;
|
|
11195
|
-
});
|
|
11196
|
-
}
|
|
11197
|
-
function updateBaseline(metrics, results) {
|
|
11151
|
+
function baselineFromResults(metrics, results) {
|
|
11198
11152
|
return Object.fromEntries(
|
|
11199
11153
|
metrics.map((metric, index) => {
|
|
11200
11154
|
const score = results[index]?.score;
|
|
@@ -11205,53 +11159,16 @@ function updateBaseline(metrics, results) {
|
|
|
11205
11159
|
})
|
|
11206
11160
|
);
|
|
11207
11161
|
}
|
|
11208
|
-
function
|
|
11209
|
-
|
|
11210
|
-
|
|
11211
|
-
if (!result) {
|
|
11212
|
-
return `${metric.name}: not_run`;
|
|
11213
|
-
}
|
|
11214
|
-
return [
|
|
11215
|
-
`${metric.name}: score=${result.score === null ? "null" : result.score}, passed=${String(result.passed)}`,
|
|
11216
|
-
result.output.trim()
|
|
11217
|
-
].filter((entry) => entry.length > 0).join("\n");
|
|
11218
|
-
}).join("\n\n");
|
|
11219
|
-
}
|
|
11220
|
-
function selectJournalScore(metrics, results) {
|
|
11221
|
-
if (metrics.length !== 1) {
|
|
11222
|
-
return null;
|
|
11223
|
-
}
|
|
11224
|
-
return results[0]?.score ?? null;
|
|
11225
|
-
}
|
|
11226
|
-
function createEntry(options) {
|
|
11162
|
+
function deriveStateFromJournal(entries, metrics) {
|
|
11163
|
+
const keepEntries = entries.filter((e) => e.status === "keep");
|
|
11164
|
+
const lastKeep = keepEntries[keepEntries.length - 1];
|
|
11227
11165
|
return {
|
|
11228
|
-
|
|
11229
|
-
|
|
11230
|
-
|
|
11231
|
-
|
|
11232
|
-
agentOutput: options.agentOutput,
|
|
11233
|
-
durationMs: options.durationMs,
|
|
11234
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
11166
|
+
experimentsCompleted: entries.length,
|
|
11167
|
+
experimentsKept: keepEntries.length,
|
|
11168
|
+
baseline: lastKeep ? baselineFromEntry(metrics, lastKeep) : null,
|
|
11169
|
+
baselineHash: lastKeep?.commit
|
|
11235
11170
|
};
|
|
11236
11171
|
}
|
|
11237
|
-
async function persistDoc(options) {
|
|
11238
|
-
const rawContent = await options.fs.readFile(options.docPath, "utf8");
|
|
11239
|
-
const { frontmatter, body } = parseExperimentFrontmatter(rawContent);
|
|
11240
|
-
await writeExperimentFrontmatter(
|
|
11241
|
-
options.docPath,
|
|
11242
|
-
{
|
|
11243
|
-
...frontmatter,
|
|
11244
|
-
baseline: options.baseline,
|
|
11245
|
-
status: {
|
|
11246
|
-
...frontmatter.status,
|
|
11247
|
-
experiment: options.experimentsCompleted,
|
|
11248
|
-
kept: options.experimentsKept
|
|
11249
|
-
}
|
|
11250
|
-
},
|
|
11251
|
-
body,
|
|
11252
|
-
options.fs
|
|
11253
|
-
);
|
|
11254
|
-
}
|
|
11255
11172
|
async function runExperimentLoop(options) {
|
|
11256
11173
|
const fs3 = options.fs ?? createDefaultFs6();
|
|
11257
11174
|
const exec3 = options.exec ?? createDefaultExec();
|
|
@@ -11263,35 +11180,35 @@ async function runExperimentLoop(options) {
|
|
|
11263
11180
|
const absoluteDocPath = resolveAbsoluteDocPath2(options.docPath, options.cwd, options.homeDir);
|
|
11264
11181
|
const journal = new ExperimentJournal(resolveJournalPath(absoluteDocPath), fs3);
|
|
11265
11182
|
await journal.init();
|
|
11266
|
-
const runConfig = await
|
|
11183
|
+
const [runConfig, instructions] = await Promise.all([
|
|
11184
|
+
loadRunConfig({ cwd: options.cwd, homeDir: options.homeDir, fs: fs3 }),
|
|
11185
|
+
loadInstructions()
|
|
11186
|
+
]);
|
|
11267
11187
|
const startTime = Date.now();
|
|
11268
11188
|
async function readDoc() {
|
|
11269
11189
|
const rawContent = await fs3.readFile(absoluteDocPath, "utf8");
|
|
11270
11190
|
return parseExperimentFrontmatter(rawContent);
|
|
11271
11191
|
}
|
|
11272
|
-
|
|
11273
|
-
|
|
11274
|
-
|
|
11275
|
-
|
|
11276
|
-
let
|
|
11277
|
-
|
|
11278
|
-
|
|
11279
|
-
|
|
11280
|
-
|
|
11281
|
-
|
|
11282
|
-
|
|
11192
|
+
const { frontmatter: initialFrontmatter } = await readDoc();
|
|
11193
|
+
const initialMetrics = normalizeMetrics(initialFrontmatter.metric);
|
|
11194
|
+
const journalEntries = await journal.readAll();
|
|
11195
|
+
const journalState = deriveStateFromJournal(journalEntries, initialMetrics);
|
|
11196
|
+
let experimentsCompleted = journalState.experimentsCompleted;
|
|
11197
|
+
let experimentsKept = journalState.experimentsKept;
|
|
11198
|
+
let baselineHash = journalState.baselineHash;
|
|
11199
|
+
let baseline = journalState.baseline ?? initialFrontmatter.baseline;
|
|
11200
|
+
if (baseline === null) {
|
|
11201
|
+
const metricTimeoutMs = initialFrontmatter.metricTimeout ? initialFrontmatter.metricTimeout * 1e3 : void 0;
|
|
11202
|
+
const baselineResults = await evaluateChain(
|
|
11203
|
+
initialMetrics,
|
|
11204
|
+
options.cwd,
|
|
11205
|
+
exec3,
|
|
11206
|
+
options.onMetricResult,
|
|
11207
|
+
metricTimeoutMs
|
|
11208
|
+
);
|
|
11209
|
+
if (allMetricsPassed(initialMetrics, baselineResults)) {
|
|
11210
|
+
baseline = baselineFromResults(initialMetrics, baselineResults);
|
|
11283
11211
|
options.onBaselineCollected?.(baseline);
|
|
11284
|
-
frontmatter = {
|
|
11285
|
-
...frontmatter,
|
|
11286
|
-
baseline
|
|
11287
|
-
};
|
|
11288
|
-
await persistDoc({
|
|
11289
|
-
fs: fs3,
|
|
11290
|
-
docPath: absoluteDocPath,
|
|
11291
|
-
baseline: frontmatter.baseline,
|
|
11292
|
-
experimentsCompleted,
|
|
11293
|
-
experimentsKept
|
|
11294
|
-
});
|
|
11295
11212
|
}
|
|
11296
11213
|
}
|
|
11297
11214
|
async function finalize(stopReason) {
|
|
@@ -11307,8 +11224,7 @@ async function runExperimentLoop(options) {
|
|
|
11307
11224
|
while (true) {
|
|
11308
11225
|
assertNotAborted3(options.signal);
|
|
11309
11226
|
const doc = await readDoc();
|
|
11310
|
-
body = doc
|
|
11311
|
-
frontmatter = doc.frontmatter;
|
|
11227
|
+
const { body, frontmatter } = doc;
|
|
11312
11228
|
const maxExperiments = validateMaxExperiments(
|
|
11313
11229
|
options.maxExperiments ?? frontmatter.maxExperiments
|
|
11314
11230
|
);
|
|
@@ -11317,20 +11233,21 @@ async function runExperimentLoop(options) {
|
|
|
11317
11233
|
}
|
|
11318
11234
|
const metrics = normalizeMetrics(frontmatter.metric);
|
|
11319
11235
|
const agents = normalizeAgents2(options.agent ?? frontmatter.agent);
|
|
11320
|
-
const metricTimeoutMs = frontmatter.metricTimeout ? frontmatter.metricTimeout * 1e3 : void 0;
|
|
11321
11236
|
const experimentIndex = experimentsCompleted + 1;
|
|
11237
|
+
baselineHash ??= await git.currentHash(options.cwd);
|
|
11238
|
+
const preExperimentHash = baselineHash;
|
|
11239
|
+
const journalLengthBefore = (await journal.readAll()).length;
|
|
11322
11240
|
const prompt = buildPrompt({
|
|
11323
11241
|
runConfig,
|
|
11242
|
+
instructions,
|
|
11324
11243
|
body,
|
|
11325
11244
|
journal: await journal.format(),
|
|
11326
11245
|
metrics,
|
|
11327
11246
|
experimentIndex,
|
|
11328
|
-
baseline
|
|
11329
|
-
|
|
11247
|
+
baseline,
|
|
11248
|
+
docPath: options.docPath,
|
|
11249
|
+
docName: path24.basename(absoluteDocPath, path24.extname(absoluteDocPath))
|
|
11330
11250
|
});
|
|
11331
|
-
baselineHash ??= await git.currentHash(options.cwd);
|
|
11332
|
-
const preExperimentHash = baselineHash;
|
|
11333
|
-
const experimentStart = Date.now();
|
|
11334
11251
|
const currentSpecifier = agents[(experimentIndex - 1) % agents.length];
|
|
11335
11252
|
const model = currentSpecifier.model;
|
|
11336
11253
|
options.onExperimentStart?.(experimentIndex, currentSpecifier.agent);
|
|
@@ -11349,108 +11266,39 @@ async function runExperimentLoop(options) {
|
|
|
11349
11266
|
}
|
|
11350
11267
|
throw error2;
|
|
11351
11268
|
}
|
|
11352
|
-
const
|
|
11353
|
-
|
|
11354
|
-
|
|
11355
|
-
|
|
11356
|
-
|
|
11357
|
-
|
|
11358
|
-
|
|
11359
|
-
|
|
11360
|
-
|
|
11361
|
-
|
|
11362
|
-
|
|
11363
|
-
|
|
11364
|
-
|
|
11365
|
-
|
|
11366
|
-
|
|
11367
|
-
|
|
11368
|
-
|
|
11369
|
-
|
|
11370
|
-
|
|
11371
|
-
|
|
11372
|
-
|
|
11373
|
-
|
|
11374
|
-
|
|
11375
|
-
|
|
11376
|
-
|
|
11377
|
-
const commitMessage = `experiment-loop: ${path24.basename(absoluteDocPath, path24.extname(absoluteDocPath))} #${experimentIndex}`;
|
|
11378
|
-
let commitHash;
|
|
11379
|
-
try {
|
|
11380
|
-
commitHash = await git.commitAll(commitMessage, options.cwd);
|
|
11381
|
-
} catch (commitError) {
|
|
11382
|
-
const errorMessage = commitError instanceof Error ? commitError.message : String(commitError);
|
|
11383
|
-
options.onRecoveryAttempt?.(errorMessage);
|
|
11384
|
-
const recoveryResult = await runAgent({
|
|
11385
|
-
agent: currentSpecifier.agent,
|
|
11386
|
-
prompt: `A git command failed. Fix the issue so the commit can succeed.
|
|
11387
|
-
|
|
11388
|
-
Error:
|
|
11389
|
-
${errorMessage}`,
|
|
11390
|
-
cwd: options.cwd,
|
|
11391
|
-
...model ? { model } : {},
|
|
11392
|
-
...options.signal ? { signal: options.signal } : {}
|
|
11393
|
-
});
|
|
11394
|
-
if (recoveryResult.exitCode !== 0) {
|
|
11395
|
-
const entry2 = createEntry({
|
|
11396
|
-
commit: preExperimentHash,
|
|
11397
|
-
status: "crash",
|
|
11398
|
-
score: null,
|
|
11399
|
-
output: errorMessage,
|
|
11400
|
-
agentOutput,
|
|
11401
|
-
durationMs: Date.now() - experimentStart
|
|
11402
|
-
});
|
|
11403
|
-
experimentsCompleted += 1;
|
|
11404
|
-
lastCrashOutput = entry2.output;
|
|
11405
|
-
await journal.log(entry2);
|
|
11269
|
+
const journalAfter = await journal.readAll();
|
|
11270
|
+
let newEntry = journalAfter.length > journalLengthBefore ? journalAfter[journalAfter.length - 1] : null;
|
|
11271
|
+
experimentsCompleted += 1;
|
|
11272
|
+
if (newEntry && newEntry.score === null && !newEntry.scores && metrics.length > 0) {
|
|
11273
|
+
const metricTimeoutMs = frontmatter.metricTimeout ? frontmatter.metricTimeout * 1e3 : void 0;
|
|
11274
|
+
const results = await evaluateChain(
|
|
11275
|
+
metrics,
|
|
11276
|
+
options.cwd,
|
|
11277
|
+
exec3,
|
|
11278
|
+
options.onMetricResult,
|
|
11279
|
+
metricTimeoutMs
|
|
11280
|
+
);
|
|
11281
|
+
if (allMetricsPassed(metrics, results)) {
|
|
11282
|
+
const scores = baselineFromResults(metrics, results);
|
|
11283
|
+
const score = metrics.length === 1 ? results[0].score : null;
|
|
11284
|
+
newEntry = await journal.updateLast({ score, scores }) ?? newEntry;
|
|
11285
|
+
}
|
|
11286
|
+
}
|
|
11287
|
+
if (newEntry) {
|
|
11288
|
+
if (newEntry.status === "keep") {
|
|
11289
|
+
experimentsKept += 1;
|
|
11290
|
+
baselineHash = newEntry.commit;
|
|
11291
|
+
baseline = baselineFromEntry(metrics, newEntry) ?? baseline;
|
|
11292
|
+
options.onCommit?.(newEntry.commit);
|
|
11293
|
+
} else {
|
|
11406
11294
|
await git.reset(preExperimentHash, options.cwd);
|
|
11407
11295
|
options.onReset?.(preExperimentHash);
|
|
11408
|
-
options.onExperimentComplete?.(experimentIndex, entry2);
|
|
11409
|
-
await persistDoc({
|
|
11410
|
-
fs: fs3,
|
|
11411
|
-
docPath: absoluteDocPath,
|
|
11412
|
-
baseline: frontmatter.baseline,
|
|
11413
|
-
experimentsCompleted,
|
|
11414
|
-
experimentsKept
|
|
11415
|
-
});
|
|
11416
|
-
continue;
|
|
11417
11296
|
}
|
|
11418
|
-
|
|
11419
|
-
}
|
|
11420
|
-
options.onCommit?.(commitHash);
|
|
11421
|
-
const evaluationResults = await evaluateChain(metrics, options.cwd, exec3, options.onMetricResult, metricTimeoutMs);
|
|
11422
|
-
const keep = allMetricsPassed(metrics, evaluationResults) && allScoresImproved(metrics, evaluationResults, frontmatter.baseline);
|
|
11423
|
-
const entry = createEntry({
|
|
11424
|
-
commit: commitHash,
|
|
11425
|
-
status: keep ? "keep" : "discard",
|
|
11426
|
-
score: selectJournalScore(metrics, evaluationResults),
|
|
11427
|
-
output: formatEvaluationOutput(metrics, evaluationResults),
|
|
11428
|
-
agentOutput,
|
|
11429
|
-
durationMs: Date.now() - experimentStart
|
|
11430
|
-
});
|
|
11431
|
-
experimentsCompleted += 1;
|
|
11432
|
-
await journal.log(entry);
|
|
11433
|
-
if (keep) {
|
|
11434
|
-
experimentsKept += 1;
|
|
11435
|
-
frontmatter = {
|
|
11436
|
-
...frontmatter,
|
|
11437
|
-
baseline: updateBaseline(metrics, evaluationResults)
|
|
11438
|
-
};
|
|
11439
|
-
baselineHash = commitHash;
|
|
11440
|
-
lastCrashOutput = void 0;
|
|
11297
|
+
options.onExperimentComplete?.(experimentIndex, newEntry);
|
|
11441
11298
|
} else {
|
|
11442
11299
|
await git.reset(preExperimentHash, options.cwd);
|
|
11443
11300
|
options.onReset?.(preExperimentHash);
|
|
11444
|
-
lastCrashOutput = void 0;
|
|
11445
11301
|
}
|
|
11446
|
-
options.onExperimentComplete?.(experimentIndex, entry);
|
|
11447
|
-
await persistDoc({
|
|
11448
|
-
fs: fs3,
|
|
11449
|
-
docPath: absoluteDocPath,
|
|
11450
|
-
baseline: frontmatter.baseline,
|
|
11451
|
-
experimentsCompleted,
|
|
11452
|
-
experimentsKept
|
|
11453
|
-
});
|
|
11454
11302
|
}
|
|
11455
11303
|
} catch (error2) {
|
|
11456
11304
|
if (isAbortError3(error2)) {
|
|
@@ -11545,6 +11393,13 @@ async function readExperimentJournal(options) {
|
|
|
11545
11393
|
const journal = new ExperimentJournal(resolveJournalPath2(absoluteDocPath), fs3);
|
|
11546
11394
|
return await journal.readAll();
|
|
11547
11395
|
}
|
|
11396
|
+
async function appendExperimentJournalEntry(options) {
|
|
11397
|
+
const fs3 = options.fs ?? createDefaultFs7();
|
|
11398
|
+
const absoluteDocPath = resolveAbsoluteDocPath3(options.docPath, options.cwd, options.homeDir);
|
|
11399
|
+
const journal = new ExperimentJournal(resolveJournalPath2(absoluteDocPath), fs3);
|
|
11400
|
+
await journal.init();
|
|
11401
|
+
await journal.log(options.entry);
|
|
11402
|
+
}
|
|
11548
11403
|
var init_experiment = __esm({
|
|
11549
11404
|
async "src/sdk/experiment.ts"() {
|
|
11550
11405
|
"use strict";
|
|
@@ -11804,7 +11659,7 @@ var init_frontmatter3 = __esm({
|
|
|
11804
11659
|
});
|
|
11805
11660
|
|
|
11806
11661
|
// packages/github-workflows/src/discover.ts
|
|
11807
|
-
import { readdir as readdir9, readFile as
|
|
11662
|
+
import { readdir as readdir9, readFile as readFile8 } from "node:fs/promises";
|
|
11808
11663
|
import { join } from "node:path";
|
|
11809
11664
|
async function discoverAutomations(builtInDir, projectDir) {
|
|
11810
11665
|
const automationsByName = /* @__PURE__ */ new Map();
|
|
@@ -11845,7 +11700,7 @@ async function listMarkdownFiles(dir) {
|
|
|
11845
11700
|
}
|
|
11846
11701
|
}
|
|
11847
11702
|
async function readAutomation(dir, fileName) {
|
|
11848
|
-
const content = await
|
|
11703
|
+
const content = await readFile8(join(dir, fileName), "utf8");
|
|
11849
11704
|
const { frontmatter, body } = parseFrontmatter2(content);
|
|
11850
11705
|
const name = fileName.slice(0, -3);
|
|
11851
11706
|
return {
|
|
@@ -12042,7 +11897,7 @@ var init_src13 = __esm({
|
|
|
12042
11897
|
});
|
|
12043
11898
|
|
|
12044
11899
|
// packages/cmdkit/src/index.ts
|
|
12045
|
-
import { fileURLToPath as
|
|
11900
|
+
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
12046
11901
|
function cloneScope(scope) {
|
|
12047
11902
|
return scope === void 0 ? void 0 : [...scope];
|
|
12048
11903
|
}
|
|
@@ -12074,7 +11929,7 @@ function cloneRequires(requires) {
|
|
|
12074
11929
|
function parseStackPath(candidate) {
|
|
12075
11930
|
if (candidate.startsWith("file://")) {
|
|
12076
11931
|
try {
|
|
12077
|
-
return
|
|
11932
|
+
return fileURLToPath3(candidate);
|
|
12078
11933
|
} catch {
|
|
12079
11934
|
return void 0;
|
|
12080
11935
|
}
|
|
@@ -12470,9 +12325,9 @@ var init_require_comment_prefix = __esm({
|
|
|
12470
12325
|
});
|
|
12471
12326
|
|
|
12472
12327
|
// packages/github-workflows/src/commands.ts
|
|
12473
|
-
import { access, mkdir as mkdir8, readFile as
|
|
12328
|
+
import { access, mkdir as mkdir8, readFile as readFile9, unlink as unlink2, writeFile as writeFile6 } from "node:fs/promises";
|
|
12474
12329
|
import path26 from "node:path";
|
|
12475
|
-
import { fileURLToPath as
|
|
12330
|
+
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
12476
12331
|
import Mustache3 from "mustache";
|
|
12477
12332
|
function formatLabel(name) {
|
|
12478
12333
|
const capitalize = (s) => s.charAt(0).toUpperCase() + s.slice(1);
|
|
@@ -12490,7 +12345,7 @@ async function loadNamedAutomation(name, cwd) {
|
|
|
12490
12345
|
}
|
|
12491
12346
|
async function readBuiltInPromptFile(name) {
|
|
12492
12347
|
try {
|
|
12493
|
-
return await
|
|
12348
|
+
return await readFile9(path26.join(await resolveBuiltInPromptsDir(), `${name}.md`), "utf8");
|
|
12494
12349
|
} catch (error2) {
|
|
12495
12350
|
if (isMissingPathError2(error2)) {
|
|
12496
12351
|
throw new UserError(`Automation "${name}" was not found.`);
|
|
@@ -12501,7 +12356,7 @@ async function readBuiltInPromptFile(name) {
|
|
|
12501
12356
|
async function readBuiltInWorkflowTemplate(name, variant) {
|
|
12502
12357
|
const templatePath = path26.join(await resolveBuiltInWorkflowTemplatesDir(), `${name}.${variant}.yml`);
|
|
12503
12358
|
try {
|
|
12504
|
-
const content = await
|
|
12359
|
+
const content = await readFile9(templatePath, "utf8");
|
|
12505
12360
|
const header = variant === "ejected" ? `# Auto-generated by: poe-code github-workflows install ${name}
|
|
12506
12361
|
# Edit .poe-code/github-workflows/poe-code-${name}.md to customize the prompt.
|
|
12507
12362
|
` : `# Auto-generated by: poe-code github-workflows install ${name}
|
|
@@ -12718,12 +12573,12 @@ var init_commands = __esm({
|
|
|
12718
12573
|
init_require_comment_prefix();
|
|
12719
12574
|
UPSTREAM_REPO = "poe-platform/poe-code";
|
|
12720
12575
|
builtInPromptsDirCandidates = [
|
|
12721
|
-
|
|
12722
|
-
|
|
12576
|
+
fileURLToPath4(new URL("./prompts", import.meta.url)),
|
|
12577
|
+
fileURLToPath4(new URL("../src/prompts", import.meta.url))
|
|
12723
12578
|
];
|
|
12724
12579
|
builtInWorkflowTemplatesDirCandidates = [
|
|
12725
|
-
|
|
12726
|
-
|
|
12580
|
+
fileURLToPath4(new URL("./workflow-templates", import.meta.url)),
|
|
12581
|
+
fileURLToPath4(new URL("../src/workflow-templates", import.meta.url))
|
|
12727
12582
|
];
|
|
12728
12583
|
originalMustacheEscape = Mustache3.escape;
|
|
12729
12584
|
installableAutomations = [
|
|
@@ -13001,7 +12856,7 @@ var init_src15 = __esm({
|
|
|
13001
12856
|
|
|
13002
12857
|
// src/utils/execution-context.ts
|
|
13003
12858
|
import { basename as basename2, dirname as dirname3 } from "node:path";
|
|
13004
|
-
import { fileURLToPath as
|
|
12859
|
+
import { fileURLToPath as fileURLToPath5 } from "node:url";
|
|
13005
12860
|
function detectExecutionContext(input) {
|
|
13006
12861
|
const { argv, env, moduleUrl } = input;
|
|
13007
12862
|
if (isDevelopmentMode(argv, env)) {
|
|
@@ -13060,7 +12915,7 @@ function detectNpxVersion(env) {
|
|
|
13060
12915
|
return "default";
|
|
13061
12916
|
}
|
|
13062
12917
|
function createDevelopmentContext(moduleUrl) {
|
|
13063
|
-
const modulePath =
|
|
12918
|
+
const modulePath = fileURLToPath5(moduleUrl);
|
|
13064
12919
|
const srcIndex = modulePath.lastIndexOf("/src/");
|
|
13065
12920
|
const projectRoot = srcIndex !== -1 ? modulePath.substring(0, srcIndex) : dirname3(dirname3(modulePath));
|
|
13066
12921
|
return {
|
|
@@ -15920,8 +15775,8 @@ var init_poe_agent_plugin_shell = __esm({
|
|
|
15920
15775
|
|
|
15921
15776
|
// packages/poe-agent/src/system-prompt.ts
|
|
15922
15777
|
import { readFileSync } from "node:fs";
|
|
15923
|
-
import { readFile as
|
|
15924
|
-
import { fileURLToPath as
|
|
15778
|
+
import { readFile as readFile10 } from "node:fs/promises";
|
|
15779
|
+
import { fileURLToPath as fileURLToPath6 } from "node:url";
|
|
15925
15780
|
function loadSystemPromptSync() {
|
|
15926
15781
|
return readFileSync(SYSTEM_PROMPT_PATH, "utf8");
|
|
15927
15782
|
}
|
|
@@ -15929,7 +15784,7 @@ var SYSTEM_PROMPT_PATH;
|
|
|
15929
15784
|
var init_system_prompt = __esm({
|
|
15930
15785
|
"packages/poe-agent/src/system-prompt.ts"() {
|
|
15931
15786
|
"use strict";
|
|
15932
|
-
SYSTEM_PROMPT_PATH =
|
|
15787
|
+
SYSTEM_PROMPT_PATH = fileURLToPath6(new URL("./SYSTEM_PROMPT.md", import.meta.url));
|
|
15933
15788
|
}
|
|
15934
15789
|
});
|
|
15935
15790
|
|
|
@@ -19241,7 +19096,7 @@ var init_renderer2 = __esm({
|
|
|
19241
19096
|
});
|
|
19242
19097
|
|
|
19243
19098
|
// packages/cmdkit/src/cli.ts
|
|
19244
|
-
import { access as access2, readFile as
|
|
19099
|
+
import { access as access2, readFile as readFile11, writeFile as writeFile7 } from "node:fs/promises";
|
|
19245
19100
|
import path32 from "node:path";
|
|
19246
19101
|
import { Command as CommanderCommand, CommanderError, InvalidArgumentError, Option } from "commander";
|
|
19247
19102
|
function unwrapOptional(schema) {
|
|
@@ -19817,7 +19672,7 @@ async function withOutputFormat2(output, fn) {
|
|
|
19817
19672
|
}
|
|
19818
19673
|
function createFs() {
|
|
19819
19674
|
return {
|
|
19820
|
-
readFile: async (path42, encoding = "utf8") =>
|
|
19675
|
+
readFile: async (path42, encoding = "utf8") => readFile11(path42, { encoding }),
|
|
19821
19676
|
writeFile: async (path42, contents) => {
|
|
19822
19677
|
await writeFile7(path42, contents);
|
|
19823
19678
|
},
|
|
@@ -19909,7 +19764,7 @@ function validatePresetFieldValue(value, field, presetPath) {
|
|
|
19909
19764
|
async function loadPresetValues(fields, presetPath) {
|
|
19910
19765
|
let rawPreset;
|
|
19911
19766
|
try {
|
|
19912
|
-
rawPreset = await
|
|
19767
|
+
rawPreset = await readFile11(presetPath, {
|
|
19913
19768
|
encoding: "utf8"
|
|
19914
19769
|
});
|
|
19915
19770
|
} catch (error2) {
|
|
@@ -20158,7 +20013,7 @@ async function loadFixtureScenario(command, selector) {
|
|
|
20158
20013
|
const fixturePath = resolveFixturePath(commandPath);
|
|
20159
20014
|
let rawFixture;
|
|
20160
20015
|
try {
|
|
20161
|
-
rawFixture = await
|
|
20016
|
+
rawFixture = await readFile11(fixturePath, {
|
|
20162
20017
|
encoding: "utf8"
|
|
20163
20018
|
});
|
|
20164
20019
|
} catch {
|
|
@@ -24564,7 +24419,7 @@ var init_configs3 = __esm({
|
|
|
24564
24419
|
});
|
|
24565
24420
|
|
|
24566
24421
|
// packages/agent-skill-config/src/templates.ts
|
|
24567
|
-
import { readFile as
|
|
24422
|
+
import { readFile as readFile12 } from "node:fs/promises";
|
|
24568
24423
|
async function getTemplates() {
|
|
24569
24424
|
if (templatesCache) {
|
|
24570
24425
|
return templatesCache;
|
|
@@ -24573,7 +24428,7 @@ async function getTemplates() {
|
|
|
24573
24428
|
"./templates/poe-generate.md",
|
|
24574
24429
|
import.meta.url
|
|
24575
24430
|
);
|
|
24576
|
-
const poeGenerateTemplate = await
|
|
24431
|
+
const poeGenerateTemplate = await readFile12(poeGenerateTemplateUrl, "utf8");
|
|
24577
24432
|
templatesCache = {
|
|
24578
24433
|
"poe-generate.md": poeGenerateTemplate
|
|
24579
24434
|
};
|
|
@@ -25615,8 +25470,8 @@ var init_models2 = __esm({
|
|
|
25615
25470
|
|
|
25616
25471
|
// src/cli/commands/pipeline.ts
|
|
25617
25472
|
import path39 from "node:path";
|
|
25618
|
-
import { readFile as
|
|
25619
|
-
import { fileURLToPath as
|
|
25473
|
+
import { readFile as readFile13, stat as stat9 } from "node:fs/promises";
|
|
25474
|
+
import { fileURLToPath as fileURLToPath7 } from "node:url";
|
|
25620
25475
|
async function resolvePipelinePlanDirectory(container) {
|
|
25621
25476
|
const configDoc = await readMergedDocument(
|
|
25622
25477
|
container.fs,
|
|
@@ -25675,7 +25530,7 @@ async function loadPipelineTemplates() {
|
|
|
25675
25530
|
if (pipelineTemplatesCache) {
|
|
25676
25531
|
return pipelineTemplatesCache;
|
|
25677
25532
|
}
|
|
25678
|
-
const packageRoot = await findPackageRoot(
|
|
25533
|
+
const packageRoot = await findPackageRoot(fileURLToPath7(import.meta.url));
|
|
25679
25534
|
const templateRoots = [
|
|
25680
25535
|
path39.join(packageRoot, "src", "templates", "pipeline"),
|
|
25681
25536
|
path39.join(packageRoot, "dist", "templates", "pipeline")
|
|
@@ -25685,8 +25540,8 @@ async function loadPipelineTemplates() {
|
|
|
25685
25540
|
continue;
|
|
25686
25541
|
}
|
|
25687
25542
|
const [skillPlan, steps] = await Promise.all([
|
|
25688
|
-
|
|
25689
|
-
|
|
25543
|
+
readFile13(path39.join(templateRoot, "SKILL_plan.md"), "utf8"),
|
|
25544
|
+
readFile13(path39.join(templateRoot, "steps.yaml.hbs"), "utf8")
|
|
25690
25545
|
]);
|
|
25691
25546
|
pipelineTemplatesCache = { skillPlan, steps };
|
|
25692
25547
|
return pipelineTemplatesCache;
|
|
@@ -25897,16 +25752,16 @@ function registerPipelineCommand(program, container) {
|
|
|
25897
25752
|
resources.logger.success("Plan is valid.");
|
|
25898
25753
|
const opts = this.opts();
|
|
25899
25754
|
if (opts.preview) {
|
|
25900
|
-
const
|
|
25755
|
+
const readFile15 = container.fs.readFile.bind(container.fs);
|
|
25901
25756
|
const resolvedVars = {};
|
|
25902
25757
|
for (const [key, value] of Object.entries(plan.vars ?? {})) {
|
|
25903
|
-
resolvedVars[key] = await resolveFileIncludes(value, container.env.cwd,
|
|
25758
|
+
resolvedVars[key] = await resolveFileIncludes(value, container.env.cwd, readFile15);
|
|
25904
25759
|
}
|
|
25905
25760
|
const resolvedSetup = plan.setup === null ? void 0 : plan.setup ?? steps.setup;
|
|
25906
25761
|
const resolvedTeardown = plan.teardown === null ? void 0 : plan.teardown ?? steps.teardown;
|
|
25907
25762
|
if (resolvedSetup) {
|
|
25908
25763
|
const raw = Object.keys(resolvedVars).length > 0 ? interpolate(resolvedSetup.prompt, resolvedVars) : resolvedSetup.prompt;
|
|
25909
|
-
const expanded = await resolveFileIncludes(raw, container.env.cwd,
|
|
25764
|
+
const expanded = await resolveFileIncludes(raw, container.env.cwd, readFile15);
|
|
25910
25765
|
resources.logger.resolved("setup", expanded);
|
|
25911
25766
|
}
|
|
25912
25767
|
for (const task of plan.tasks) {
|
|
@@ -25914,7 +25769,7 @@ function registerPipelineCommand(program, container) {
|
|
|
25914
25769
|
const expanded = await resolveFileIncludes(
|
|
25915
25770
|
buildExecutionPrompt({ selection: { kind: "run", task }, steps: steps.steps, planPath: file, vars: resolvedVars }),
|
|
25916
25771
|
container.env.cwd,
|
|
25917
|
-
|
|
25772
|
+
readFile15
|
|
25918
25773
|
);
|
|
25919
25774
|
resources.logger.resolved(`task: ${task.id} \u2014 ${task.title}`, expanded);
|
|
25920
25775
|
} else {
|
|
@@ -25922,7 +25777,7 @@ function registerPipelineCommand(program, container) {
|
|
|
25922
25777
|
const expanded = await resolveFileIncludes(
|
|
25923
25778
|
buildExecutionPrompt({ selection: { kind: "run", task, stepName }, steps: steps.steps, planPath: file, vars: resolvedVars }),
|
|
25924
25779
|
container.env.cwd,
|
|
25925
|
-
|
|
25780
|
+
readFile15
|
|
25926
25781
|
);
|
|
25927
25782
|
resources.logger.resolved(`task: ${task.id} / ${stepName}`, expanded);
|
|
25928
25783
|
}
|
|
@@ -25930,7 +25785,7 @@ function registerPipelineCommand(program, container) {
|
|
|
25930
25785
|
}
|
|
25931
25786
|
if (resolvedTeardown) {
|
|
25932
25787
|
const raw = Object.keys(resolvedVars).length > 0 ? interpolate(resolvedTeardown.prompt, resolvedVars) : resolvedTeardown.prompt;
|
|
25933
|
-
const expanded = await resolveFileIncludes(raw, container.env.cwd,
|
|
25788
|
+
const expanded = await resolveFileIncludes(raw, container.env.cwd, readFile15);
|
|
25934
25789
|
resources.logger.resolved("teardown", expanded);
|
|
25935
25790
|
}
|
|
25936
25791
|
}
|
|
@@ -26498,8 +26353,8 @@ var init_ralph3 = __esm({
|
|
|
26498
26353
|
|
|
26499
26354
|
// src/cli/commands/experiment.ts
|
|
26500
26355
|
import path41 from "node:path";
|
|
26501
|
-
import { readFile as
|
|
26502
|
-
import { fileURLToPath as
|
|
26356
|
+
import { readFile as readFile14, stat as stat10 } from "node:fs/promises";
|
|
26357
|
+
import { fileURLToPath as fileURLToPath8 } from "node:url";
|
|
26503
26358
|
function resolveExperimentPaths(scope, cwd, homeDir) {
|
|
26504
26359
|
const rootPath = scope === "global" ? path41.join(homeDir, ".poe-code", "experiments") : path41.join(cwd, ".poe-code", "experiments");
|
|
26505
26360
|
const displayRoot = scope === "global" ? "~/.poe-code/experiments" : ".poe-code/experiments";
|
|
@@ -26536,7 +26391,7 @@ async function loadExperimentTemplates() {
|
|
|
26536
26391
|
if (experimentTemplatesCache) {
|
|
26537
26392
|
return experimentTemplatesCache;
|
|
26538
26393
|
}
|
|
26539
|
-
const packageRoot = await findPackageRoot2(
|
|
26394
|
+
const packageRoot = await findPackageRoot2(fileURLToPath8(import.meta.url));
|
|
26540
26395
|
const templateRoots = [
|
|
26541
26396
|
path41.join(packageRoot, "src", "templates", "experiment"),
|
|
26542
26397
|
path41.join(packageRoot, "dist", "templates", "experiment")
|
|
@@ -26546,8 +26401,8 @@ async function loadExperimentTemplates() {
|
|
|
26546
26401
|
continue;
|
|
26547
26402
|
}
|
|
26548
26403
|
const [skillPlan, runYaml] = await Promise.all([
|
|
26549
|
-
|
|
26550
|
-
|
|
26404
|
+
readFile14(path41.join(templateRoot, "SKILL_experiment.md"), "utf8"),
|
|
26405
|
+
readFile14(path41.join(templateRoot, "run.yaml.hbs"), "utf8")
|
|
26551
26406
|
]);
|
|
26552
26407
|
experimentTemplatesCache = { skillPlan, runYaml };
|
|
26553
26408
|
return experimentTemplatesCache;
|
|
@@ -26588,11 +26443,6 @@ function validateExperimentDoc(frontmatter) {
|
|
|
26588
26443
|
}
|
|
26589
26444
|
}
|
|
26590
26445
|
}
|
|
26591
|
-
if (frontmatter.status.kept > frontmatter.status.experiment) {
|
|
26592
|
-
errors.push(
|
|
26593
|
-
`Status inconsistency: kept (${frontmatter.status.kept}) exceeds experiment count (${frontmatter.status.experiment})`
|
|
26594
|
-
);
|
|
26595
|
-
}
|
|
26596
26446
|
return errors;
|
|
26597
26447
|
}
|
|
26598
26448
|
function formatDuration3(ms) {
|
|
@@ -26821,7 +26671,7 @@ function registerExperimentCommand(program, container) {
|
|
|
26821
26671
|
resources.context.finalize();
|
|
26822
26672
|
}
|
|
26823
26673
|
});
|
|
26824
|
-
experiment.command("journal").description("Display the experiment journal as a table.").argument("[doc]", "Experiment doc path").action(async function(docArg) {
|
|
26674
|
+
const journalCommand = experiment.command("journal").description("Display the experiment journal as a table.").argument("[doc]", "Experiment doc path").action(async function(docArg) {
|
|
26825
26675
|
const flags = resolveCommandFlags(program);
|
|
26826
26676
|
const resources = createExecutionResources(container, flags, "experiment:journal");
|
|
26827
26677
|
resources.logger.intro("experiment journal");
|
|
@@ -26872,6 +26722,60 @@ function registerExperimentCommand(program, container) {
|
|
|
26872
26722
|
resources.context.finalize();
|
|
26873
26723
|
}
|
|
26874
26724
|
});
|
|
26725
|
+
journalCommand.command("log").description("Append an entry to the experiment journal.").argument("[doc]", "Experiment doc path").requiredOption("--status <status>", "Entry status: keep or discard").requiredOption("--commit <hash>", "Git commit hash").option("--score <number>", "Metric score (for single-metric display)").option("--scores <json>", `Multi-metric scores as JSON object, e.g. '{"tests":2}'`).option("--output <text>", "Metric output text", "").option("--duration-ms <number>", "Duration in milliseconds", "0").action(async function(docArg) {
|
|
26726
|
+
const flags = resolveCommandFlags(program);
|
|
26727
|
+
const resources = createExecutionResources(container, flags, "experiment:journal:log");
|
|
26728
|
+
const opts = this.opts();
|
|
26729
|
+
try {
|
|
26730
|
+
const docPath = await resolveDocPath2({
|
|
26731
|
+
container,
|
|
26732
|
+
program,
|
|
26733
|
+
providedDoc: docArg,
|
|
26734
|
+
selectMessage: "Select the experiment doc to log to:",
|
|
26735
|
+
cancelMessage: "Journal log cancelled."
|
|
26736
|
+
});
|
|
26737
|
+
if (!docPath) {
|
|
26738
|
+
return;
|
|
26739
|
+
}
|
|
26740
|
+
const status = opts.status;
|
|
26741
|
+
if (status !== "keep" && status !== "discard") {
|
|
26742
|
+
throw new ValidationError(`Invalid status "${opts.status}". Must be keep or discard.`);
|
|
26743
|
+
}
|
|
26744
|
+
const score = opts.score !== void 0 ? Number.parseFloat(opts.score) : null;
|
|
26745
|
+
let scores;
|
|
26746
|
+
if (opts.scores) {
|
|
26747
|
+
try {
|
|
26748
|
+
scores = JSON.parse(opts.scores);
|
|
26749
|
+
} catch {
|
|
26750
|
+
throw new ValidationError(`Invalid --scores JSON: ${opts.scores}`);
|
|
26751
|
+
}
|
|
26752
|
+
}
|
|
26753
|
+
const entry = {
|
|
26754
|
+
commit: opts.commit,
|
|
26755
|
+
status,
|
|
26756
|
+
score: score !== null && Number.isFinite(score) ? score : null,
|
|
26757
|
+
...scores ? { scores } : {},
|
|
26758
|
+
output: opts.output,
|
|
26759
|
+
agentOutput: "",
|
|
26760
|
+
durationMs: Number.parseInt(opts.durationMs, 10) || 0,
|
|
26761
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
26762
|
+
};
|
|
26763
|
+
if (!flags.dryRun) {
|
|
26764
|
+
await appendExperimentJournalEntry({
|
|
26765
|
+
cwd: container.env.cwd,
|
|
26766
|
+
homeDir: container.env.homeDir,
|
|
26767
|
+
docPath,
|
|
26768
|
+
entry
|
|
26769
|
+
});
|
|
26770
|
+
}
|
|
26771
|
+
resources.context.complete({
|
|
26772
|
+
success: `Logged ${status} entry (commit: ${opts.commit})`,
|
|
26773
|
+
dry: `Would log ${status} entry (commit: ${opts.commit})`
|
|
26774
|
+
});
|
|
26775
|
+
} finally {
|
|
26776
|
+
resources.context.finalize();
|
|
26777
|
+
}
|
|
26778
|
+
});
|
|
26875
26779
|
experiment.command("validate").description("Validate an experiment doc without running it.").argument("[doc]", "Experiment doc path").action(async function(docArg) {
|
|
26876
26780
|
const flags = resolveCommandFlags(program);
|
|
26877
26781
|
const resources = createExecutionResources(
|
|
@@ -27475,7 +27379,7 @@ var init_package = __esm({
|
|
|
27475
27379
|
"package.json"() {
|
|
27476
27380
|
package_default = {
|
|
27477
27381
|
name: "poe-code",
|
|
27478
|
-
version: "3.0.
|
|
27382
|
+
version: "3.0.130",
|
|
27479
27383
|
description: "CLI tool to configure Poe API for developer workflows.",
|
|
27480
27384
|
type: "module",
|
|
27481
27385
|
main: "./dist/index.js",
|