amsd-pipeline-shared 0.4.2 → 0.4.4
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.
|
@@ -122,7 +122,9 @@ function seed({ install, project, ticket, runsRoots }) {
|
|
|
122
122
|
* list, less the templates it installs as they are (copyVerbatim, and multi-body templates), present in the cached set.
|
|
123
123
|
* An entry is <cache>/<id>.json, or <id>.<variant>.json for a variant run (brownfield).
|
|
124
124
|
*/
|
|
125
|
-
|
|
125
|
+
// maxRebuild: how many generated prompts without an entry the launch accepts rebuilding (operator, 2026-10-19: a short,
|
|
126
|
+
// NAMED list is acceptable). The launch states it (--max-rebuild); unstated it is 0 — every prompt must be reusable.
|
|
127
|
+
function cache({ install, project, codeline, variant = process.env.EPAM_BROWNFIELD === '1' ? 'brownfield' : '', maxRebuild = 0 }) {
|
|
126
128
|
const O = orchOf(install);
|
|
127
129
|
const C = path.join(O, 'projects', project, '.prompt-cache', codeline);
|
|
128
130
|
const b = require(path.join(scriptsOf(install), 'lib', 'project-prompt-builder.js'));
|
|
@@ -139,9 +141,10 @@ function cache({ install, project, codeline, variant = process.env.EPAM_BROWNFIE
|
|
|
139
141
|
const required = list.filter((i) => prompts.includes(i) && !multi(i));
|
|
140
142
|
const has = (i) => fs.existsSync(path.join(C, `${i}.json`)) || (variant && fs.existsSync(path.join(C, `${i}.${variant}.json`)));
|
|
141
143
|
const missing = required.filter((i) => !has(i));
|
|
142
|
-
if (missing.length) problems.push(`${missing.length} of ${required.length} generated prompt(s) have no per-prompt entry
|
|
143
|
-
|
|
144
|
-
|
|
144
|
+
if (missing.length > Number(maxRebuild || 0)) problems.push(`${missing.length} of ${required.length} generated prompt(s) have no per-prompt entry and would be rebuilt (paid), above the launch's limit of ${Number(maxRebuild || 0)}: ${missing.join(', ')}`);
|
|
145
|
+
const rebuild = missing.length ? `; ${missing.length} without an entry will be rebuilt (within the launch's limit of ${maxRebuild}): ${missing.join(', ')}` : '';
|
|
146
|
+
return res('cache', !problems.length, problems.length ? problems.join('; ') : `${codeline}: ${prompts.length} cached prompt(s), ${b.MINTED_FILES.length} minted file(s), ${required.length - missing.length} of ${required.length} per-prompt entries, marker present${rebuild}`,
|
|
147
|
+
{ required: required.length, missing, willRebuild: problems.length ? [] : missing });
|
|
145
148
|
}
|
|
146
149
|
|
|
147
150
|
// ── 4. cost ──────────────────────────────────────────────────────────────────────────────────────────────────────────
|
|
@@ -192,6 +195,13 @@ const cmdline = (pid, procDir = '/proc') => { try { return fs.readFileSync(`${pr
|
|
|
192
195
|
function alone({ install, selfPid = process.pid, procDir = '/proc' }) {
|
|
193
196
|
const mine = ancestors(selfPid, procDir);
|
|
194
197
|
const inst = path.resolve(install);
|
|
198
|
+
// THE INSTALL'S OWN SERVICES are not another run: the services its installer registers, one pid file each
|
|
199
|
+
// (orchestrations/dashboards/.<name>.pid — snapshot-watch, cassette-watch), read from the install, never listed here.
|
|
200
|
+
// The pre-flight requires them running; a process running one of their scripts is that service (the pid recorded may be
|
|
201
|
+
// stale after a restart, so the script, not the pid, identifies it).
|
|
202
|
+
let services = [];
|
|
203
|
+
try { services = fs.readdirSync(path.join(orchOf(install), 'dashboards')).map((n) => (n.match(/^\.(.+)\.pid$/) || [])[1]).filter(Boolean).sort(); } catch { services = []; }
|
|
204
|
+
const isService = (s) => services.some((n) => s.includes(`${n}.js`));
|
|
195
205
|
const others = [];
|
|
196
206
|
let pids = []; try { pids = fs.readdirSync(procDir).filter((n) => /^\d+$/.test(n)); } catch { pids = []; }
|
|
197
207
|
for (const p of pids) {
|
|
@@ -200,9 +210,9 @@ function alone({ install, selfPid = process.pid, procDir = '/proc' }) {
|
|
|
200
210
|
const s = a.join(' ');
|
|
201
211
|
let cwd = ''; try { cwd = fs.readlinkSync(`${procDir}/${p}/cwd`); } catch { cwd = ''; }
|
|
202
212
|
// a pipeline process of THIS install: anything running its scripts or a run against it; my own shell is excluded above
|
|
203
|
-
if ((s.includes(inst) || cwd.startsWith(inst)) && /\b(node|bash|sh|python3?|claude)\b/.test(a[0] + ' ' + (a[1] || ''))) others.push(`${p} ${s.slice(0, 140)}`);
|
|
213
|
+
if ((s.includes(inst) || cwd.startsWith(inst)) && /\b(node|bash|sh|python3?|claude)\b/.test(a[0] + ' ' + (a[1] || '')) && !isService(s)) others.push(`${p} ${s.slice(0, 140)}`);
|
|
204
214
|
}
|
|
205
|
-
return res('alone', !others.length, others.length ? `${others.length} other process(es) are working against ${inst}: ${others.slice(0, 3).join(' | ')}` : `nothing else is working against ${inst}`, { others });
|
|
215
|
+
return res('alone', !others.length, others.length ? `${others.length} other process(es) are working against ${inst}: ${others.slice(0, 3).join(' | ')}` : `nothing else is working against ${inst}${services.length ? ` (its own services not counted: ${services.join(', ')})` : ''}`, { others, services });
|
|
206
216
|
}
|
|
207
217
|
|
|
208
218
|
// ── 6. memory ────────────────────────────────────────────────────────────────────────────────────────────────────────
|
|
@@ -257,7 +267,7 @@ function prelaunch(o) {
|
|
|
257
267
|
results.push(langfuse({ install: o.install, env: o.env, runId: o.runId, outDir: o.outDir }));
|
|
258
268
|
if (o.ticket) results.push(seed({ install: o.install, project: o.project, ticket: o.ticket, runsRoots: o.runsRoots || [] }));
|
|
259
269
|
// the variant (brownfield) is the run's, from the env the launch hands over — not this process's own environment
|
|
260
|
-
if (o.codeline) results.push(cache({ install: o.install, project: o.project, codeline: o.codeline, variant: (o.env || {}).EPAM_BROWNFIELD === '1' ? 'brownfield' : '' }));
|
|
270
|
+
if (o.codeline) results.push(cache({ install: o.install, project: o.project, codeline: o.codeline, variant: (o.env || {}).EPAM_BROWNFIELD === '1' ? 'brownfield' : '', maxRebuild: o.maxRebuild || 0 }));
|
|
261
271
|
results.push(cost({ install: o.install, set: o.set || o.env.EPAM_PROVIDER_SET || 'claude', tmpDir: o.outDir }));
|
|
262
272
|
results.push(alone({ install: o.install }));
|
|
263
273
|
results.push(memory({ needMb: Number(o.needMb || 4096) }));
|
|
@@ -276,7 +286,7 @@ module.exports = { prelaunch, prelaunchCli, preflight, langfuse, langfuseEnv, se
|
|
|
276
286
|
* THE COMMAND, for every pipeline:
|
|
277
287
|
* prelaunch.js --install <i> --project <p> --run-id <id> --out <dir> [--ticket <KEY> --runs <runs dir>[,…]]
|
|
278
288
|
* [--codeline <cl>] [--set <provider set>] [--need-mb <n>] [--leg-timeout-secs <s>] [--runner <launcher>]
|
|
279
|
-
* [--prd <file>] [--preflight no]
|
|
289
|
+
* [--prd <file>] [--preflight no] [--max-rebuild <n prompts the launch accepts rebuilding>]
|
|
280
290
|
* Prints each check and the verdict; writes <out>/prelaunch.json; exit 0 all green, 1 any red, 64 usage.
|
|
281
291
|
*/
|
|
282
292
|
function prelaunchCli(argv, env = process.env) {
|
|
@@ -284,7 +294,7 @@ function prelaunchCli(argv, env = process.env) {
|
|
|
284
294
|
for (const k of ['install', 'project', 'run-id', 'out']) if (!a[k]) { process.stderr.write(`prelaunch: --${k} is required\n`); return 64; }
|
|
285
295
|
const r = prelaunch({ install: path.resolve(a.install), project: a.project, runId: a['run-id'], outDir: path.resolve(a.out), env,
|
|
286
296
|
ticket: a.ticket, runsRoots: a.runs ? a.runs.split(',').map((d) => path.resolve(d)) : [], codeline: a.codeline,
|
|
287
|
-
set: a.set, needMb: a['need-mb'], legTimeoutSecs: a['leg-timeout-secs'], runner: a.runner, prd: a.prd, preflight: a.preflight !== 'no' });
|
|
297
|
+
set: a.set, needMb: a['need-mb'], maxRebuild: Number(a['max-rebuild'] || 0), legTimeoutSecs: a['leg-timeout-secs'], runner: a.runner, prd: a.prd, preflight: a.preflight !== 'no' });
|
|
288
298
|
process.stdout.write('── Pre-launch (amsd-pipeline-shared) ─────────────────────────────────────────\n');
|
|
289
299
|
for (const c of r.results) process.stdout.write(` ${c.ok ? '✓' : '✗'} ${c.name}: ${c.detail}\n`);
|
|
290
300
|
const cl = r.results.find((c) => c.name === 'checklist');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "amsd-pipeline-shared",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.4",
|
|
4
4
|
"description": "The AMSD pipeline's shared components, one source for the bash pipeline and its Claude workflows: the model-call gateway (llm-handler.sh — retry, ladder, self-heal, cost) and the libraries it runs.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"bin": {
|