@amenophis1er/foreman 0.1.1 → 0.1.2
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@amenophis1er/foreman",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Autonomous mission runner on the Claude Agent SDK: a director plans, delegates to workers, verifies, and reports — from one dashboard, your phone, or the CLI.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"author": "Amen AMOUZOU",
|
|
25
25
|
"type": "module",
|
|
26
26
|
"bin": {
|
|
27
|
-
"foreman": "
|
|
27
|
+
"foreman": "bin/foreman.mjs"
|
|
28
28
|
},
|
|
29
29
|
"files": [
|
|
30
30
|
"bin",
|
package/src/server.ts
CHANGED
|
@@ -1131,20 +1131,39 @@ async function startRun(
|
|
|
1131
1131
|
await driveRun(projectId, meta);
|
|
1132
1132
|
}
|
|
1133
1133
|
|
|
1134
|
-
/**
|
|
1135
|
-
|
|
1134
|
+
/**
|
|
1135
|
+
* Resumes an interrupted run by restoring the director's session. `pick`
|
|
1136
|
+
* carries models chosen for this resume (the header's "Resume on…"); a role
|
|
1137
|
+
* it names wins over Settings for that role.
|
|
1138
|
+
*/
|
|
1139
|
+
async function resumeRun(projectId: string, meta: RunMeta, pick: {
|
|
1140
|
+
directorModel?: string; directorProviderId?: string; workerModel?: string; workerProviderId?: string;
|
|
1141
|
+
} = {}): Promise<void> {
|
|
1136
1142
|
const sessionId = meta.directorSessionId;
|
|
1137
1143
|
// Resume re-reads Settings, so changing models or tool policy after a
|
|
1138
1144
|
// failure takes effect on the retry. A director session cannot switch
|
|
1139
1145
|
// model mid-session, so a changed director model restarts the session
|
|
1140
1146
|
// fresh (the mission doc carries the state forward).
|
|
1141
|
-
const
|
|
1147
|
+
const base = await effectiveSettings(projectId);
|
|
1148
|
+
const settings = {
|
|
1149
|
+
...base,
|
|
1150
|
+
...(pick.directorModel ? { directorModel: modelChoice(pick.directorModel), directorProviderId: pick.directorProviderId } : {}),
|
|
1151
|
+
...(pick.workerModel ? { workerModel: modelChoice(pick.workerModel), workerProviderId: pick.workerProviderId } : {}),
|
|
1152
|
+
};
|
|
1153
|
+
// A model is picked together with the provider that serves it, so a
|
|
1154
|
+
// change of either moves the role. Without the provider following the
|
|
1155
|
+
// model, "resume on Sonnet" after a Codex usage limit went back through
|
|
1156
|
+
// the Codex gateway — which remapped the unknown id to its own default and
|
|
1157
|
+
// hit the same 429. The provider id is left undefined when Settings does
|
|
1158
|
+
// not pin one, which means the project's own provider, as at start.
|
|
1142
1159
|
const directorChanged =
|
|
1143
|
-
settings.directorModel !== undefined && settings.directorModel !== meta.directorModel
|
|
1160
|
+
(settings.directorModel !== undefined && settings.directorModel !== meta.directorModel)
|
|
1161
|
+
|| (settings.directorModel !== undefined && settings.directorProviderId !== meta.directorProviderId);
|
|
1144
1162
|
const workerChanged =
|
|
1145
|
-
settings.workerModel !== undefined && settings.workerModel !== meta.workerModel
|
|
1146
|
-
|
|
1147
|
-
if (
|
|
1163
|
+
(settings.workerModel !== undefined && settings.workerModel !== meta.workerModel)
|
|
1164
|
+
|| (settings.workerModel !== undefined && settings.workerProviderId !== meta.workerProviderId);
|
|
1165
|
+
if (directorChanged) { meta.directorModel = settings.directorModel; meta.directorProviderId = settings.directorProviderId; }
|
|
1166
|
+
if (workerChanged) { meta.workerModel = settings.workerModel; meta.workerProviderId = settings.workerProviderId; }
|
|
1148
1167
|
meta.toolPolicy = settings.toolPolicy;
|
|
1149
1168
|
meta.autoAllowReadOnly = settings.autoAllowReadOnly;
|
|
1150
1169
|
meta.status = 'running';
|
|
@@ -1863,7 +1882,14 @@ const server = http.createServer(async (req, res) => {
|
|
|
1863
1882
|
if (!reserveProject(meta.projectId)) {
|
|
1864
1883
|
return json(res, 409, { error: 'this project already has an active mission' });
|
|
1865
1884
|
}
|
|
1866
|
-
|
|
1885
|
+
// "Resume on…": models picked for this resume, ahead of Settings. A
|
|
1886
|
+
// model without a provider id means the project's own provider.
|
|
1887
|
+
const str = (v: unknown) => (typeof v === 'string' && v.trim() ? v.trim() : undefined);
|
|
1888
|
+
const overrides = {
|
|
1889
|
+
directorModel: str(resumeBody.directorModel), directorProviderId: str(resumeBody.directorProviderId),
|
|
1890
|
+
workerModel: str(resumeBody.workerModel), workerProviderId: str(resumeBody.workerProviderId),
|
|
1891
|
+
};
|
|
1892
|
+
void resumeRun(meta.projectId, meta, overrides);
|
|
1867
1893
|
json(res, 200, { ok: true });
|
|
1868
1894
|
|
|
1869
1895
|
} else if (req.method === 'GET' && runEventsMatch) {
|