poe-code 4.0.6 → 4.0.7
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/gaslight.js +3 -18
- package/dist/cli/commands/gaslight.js.map +1 -1
- package/dist/index.js +36 -19
- package/dist/index.js.map +2 -2
- package/dist/metafile.json +1 -1
- package/package.json +1 -1
- package/packages/agent-gaslight/dist/config.js +15 -2
- package/packages/agent-gaslight/dist/run.js +20 -2
- package/packages/agent-gaslight/dist/types.d.ts +4 -0
package/package.json
CHANGED
|
@@ -2,12 +2,14 @@ import { promises as nodeFs } from "node:fs";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { parse } from "yaml";
|
|
4
4
|
export const GASLIGHT_CONFIG_EXAMPLE = [
|
|
5
|
+
"setup: Prepare the workspace",
|
|
5
6
|
"prompt: Implement",
|
|
6
7
|
"archive: false",
|
|
7
8
|
"followups:",
|
|
8
9
|
" - Is this best you can do?",
|
|
9
10
|
" - Did you test it well? Like real end to end test?",
|
|
10
|
-
" - Did you forget something?"
|
|
11
|
+
" - Did you forget something?",
|
|
12
|
+
"teardown: Clean up the workspace"
|
|
11
13
|
].join("\n");
|
|
12
14
|
function isMissingFile(error) {
|
|
13
15
|
return (typeof error === "object" &&
|
|
@@ -35,7 +37,11 @@ function validateConfig(value, configPath, options) {
|
|
|
35
37
|
}
|
|
36
38
|
const config = value;
|
|
37
39
|
if (options.rejectExtraKeys) {
|
|
38
|
-
const extraKey = objectKeys(config).find((key) => key !== "
|
|
40
|
+
const extraKey = objectKeys(config).find((key) => key !== "setup" &&
|
|
41
|
+
key !== "prompt" &&
|
|
42
|
+
key !== "followups" &&
|
|
43
|
+
key !== "teardown" &&
|
|
44
|
+
key !== "archive");
|
|
39
45
|
if (extraKey) {
|
|
40
46
|
throw new Error(`Invalid gaslight config at ${configPath}: unexpected key "${extraKey}".`);
|
|
41
47
|
}
|
|
@@ -51,9 +57,16 @@ function validateConfig(value, configPath, options) {
|
|
|
51
57
|
if (config.archive !== undefined && typeof config.archive !== "boolean") {
|
|
52
58
|
throw new Error(`Invalid gaslight config at ${configPath}: archive must be a boolean.`);
|
|
53
59
|
}
|
|
60
|
+
for (const key of ["setup", "teardown"]) {
|
|
61
|
+
if (config[key] !== undefined && (typeof config[key] !== "string" || !config[key].trim())) {
|
|
62
|
+
throw new Error(`Invalid gaslight config at ${configPath}: ${key} must be a non-empty string.`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
54
65
|
return {
|
|
66
|
+
...(typeof config.setup === "string" ? { setup: config.setup.trim() } : {}),
|
|
55
67
|
prompt: config.prompt.trim(),
|
|
56
68
|
followups: config.followups.map((followup) => followup.trim()),
|
|
69
|
+
...(typeof config.teardown === "string" ? { teardown: config.teardown.trim() } : {}),
|
|
57
70
|
...(config.archive !== undefined ? { archive: config.archive } : {})
|
|
58
71
|
};
|
|
59
72
|
}
|
|
@@ -82,6 +82,12 @@ function resolveModel(value) {
|
|
|
82
82
|
}
|
|
83
83
|
return trimmed;
|
|
84
84
|
}
|
|
85
|
+
function resolveOptionalPrompt(value, label) {
|
|
86
|
+
if (value === undefined) {
|
|
87
|
+
return undefined;
|
|
88
|
+
}
|
|
89
|
+
return requireNonEmptyString(value, label);
|
|
90
|
+
}
|
|
85
91
|
function resolvePlanPaths(options, cwd, homeDir) {
|
|
86
92
|
if (options.planPaths.length === 0) {
|
|
87
93
|
throw new Error("Provide at least one plan path.");
|
|
@@ -110,20 +116,32 @@ export async function runGaslight(options) {
|
|
|
110
116
|
const spawn = options.spawn ?? defaultSpawn;
|
|
111
117
|
const agent = requireNonEmptyString(options.agent, "agent");
|
|
112
118
|
const model = resolveModel(options.model);
|
|
119
|
+
const inlineSetup = resolveOptionalPrompt(options.setup, "setup");
|
|
120
|
+
const inlineTeardown = resolveOptionalPrompt(options.teardown, "teardown");
|
|
113
121
|
validateInlineConfig(options.prompt, options.followups);
|
|
114
122
|
const planPaths = resolvePlanPaths(options, cwd, homeDir);
|
|
115
123
|
for (const planPath of planPaths) {
|
|
116
124
|
await requirePlan(fs, resolvePlanPath(cwd, homeDir, planPath), planPath);
|
|
117
125
|
}
|
|
118
126
|
const config = options.prompt !== undefined && options.followups !== undefined
|
|
119
|
-
? {
|
|
127
|
+
? {
|
|
128
|
+
...(inlineSetup ? { setup: inlineSetup } : {}),
|
|
129
|
+
prompt: options.prompt.trim(),
|
|
130
|
+
followups: options.followups.map((value) => value.trim()),
|
|
131
|
+
...(inlineTeardown ? { teardown: inlineTeardown } : {})
|
|
132
|
+
}
|
|
120
133
|
: await loadGaslightConfig(cwd, homeDir, fs, options.configPath);
|
|
121
134
|
const shouldArchive = options.archive ?? config.archive ?? false;
|
|
122
135
|
const rounds = [];
|
|
123
136
|
const plans = [];
|
|
124
137
|
let usage;
|
|
125
138
|
for (const [planIndex, planPath] of planPaths.entries()) {
|
|
126
|
-
const prompts = [
|
|
139
|
+
const prompts = [
|
|
140
|
+
...(config.setup ? [config.setup] : []),
|
|
141
|
+
`${config.prompt} ${planPath}`,
|
|
142
|
+
...config.followups,
|
|
143
|
+
...(config.teardown ? [config.teardown] : [])
|
|
144
|
+
];
|
|
127
145
|
const planRounds = [];
|
|
128
146
|
let planUsage;
|
|
129
147
|
let resumeThreadId;
|
|
@@ -51,16 +51,20 @@ export interface GaslightOptions {
|
|
|
51
51
|
cwd?: string;
|
|
52
52
|
homeDir?: string;
|
|
53
53
|
configPath?: string;
|
|
54
|
+
setup?: string;
|
|
54
55
|
prompt?: string;
|
|
55
56
|
followups?: string[];
|
|
57
|
+
teardown?: string;
|
|
56
58
|
onEvent?: (event: GaslightEvent) => void;
|
|
57
59
|
signal?: AbortSignal;
|
|
58
60
|
fs?: GaslightFileSystem;
|
|
59
61
|
spawn?: GaslightSpawn;
|
|
60
62
|
}
|
|
61
63
|
export interface GaslightConfig {
|
|
64
|
+
setup?: string;
|
|
62
65
|
prompt: string;
|
|
63
66
|
followups: string[];
|
|
67
|
+
teardown?: string;
|
|
64
68
|
archive?: boolean;
|
|
65
69
|
path: string;
|
|
66
70
|
}
|