@jaggerxtrm/specialists 3.3.3 → 3.3.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.
- package/dist/index.js +95 -66
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -17888,7 +17888,17 @@ class PiAgentSession {
|
|
|
17888
17888
|
if (this._killed)
|
|
17889
17889
|
return;
|
|
17890
17890
|
this.proc?.stdin?.end();
|
|
17891
|
-
|
|
17891
|
+
if (this.proc) {
|
|
17892
|
+
await new Promise((resolve) => {
|
|
17893
|
+
this.proc.on("close", () => resolve());
|
|
17894
|
+
setTimeout(() => {
|
|
17895
|
+
if (this.proc && !this._killed) {
|
|
17896
|
+
this.proc.kill();
|
|
17897
|
+
}
|
|
17898
|
+
resolve();
|
|
17899
|
+
}, 2000);
|
|
17900
|
+
});
|
|
17901
|
+
}
|
|
17892
17902
|
}
|
|
17893
17903
|
kill() {
|
|
17894
17904
|
if (this._killed)
|
|
@@ -18267,6 +18277,7 @@ ${preScripts.map((s) => ` • ${s.run}${s.inject_output ? " → $pre_script_o
|
|
|
18267
18277
|
let sessionBackend = model;
|
|
18268
18278
|
let session;
|
|
18269
18279
|
let keepAliveActive = false;
|
|
18280
|
+
let sessionClosed = false;
|
|
18270
18281
|
try {
|
|
18271
18282
|
session = await this.sessionFactory({
|
|
18272
18283
|
model,
|
|
@@ -18305,6 +18316,7 @@ ${preScripts.map((s) => ` • ${s.run}${s.inject_output ? " → $pre_script_o
|
|
|
18305
18316
|
onResumeReady(resumeFn, closeFn);
|
|
18306
18317
|
} else {
|
|
18307
18318
|
await session.close();
|
|
18319
|
+
sessionClosed = true;
|
|
18308
18320
|
}
|
|
18309
18321
|
const postScripts = spec.specialist.skills?.scripts?.filter((s) => s.phase === "post") ?? [];
|
|
18310
18322
|
for (const script of postScripts)
|
|
@@ -18329,7 +18341,7 @@ ${preScripts.map((s) => ` • ${s.run}${s.inject_output ? " → $pre_script_o
|
|
|
18329
18341
|
});
|
|
18330
18342
|
throw err;
|
|
18331
18343
|
} finally {
|
|
18332
|
-
if (!keepAliveActive) {
|
|
18344
|
+
if (!keepAliveActive && !sessionClosed) {
|
|
18333
18345
|
session?.kill();
|
|
18334
18346
|
}
|
|
18335
18347
|
}
|
|
@@ -18725,10 +18737,13 @@ class Supervisor {
|
|
|
18725
18737
|
};
|
|
18726
18738
|
appendTimelineEvent(createRunStartEvent(runOptions.name));
|
|
18727
18739
|
const fifoPath = join3(dir, "steer.pipe");
|
|
18728
|
-
|
|
18729
|
-
|
|
18730
|
-
|
|
18731
|
-
|
|
18740
|
+
const needsFifo = runOptions.keepAlive;
|
|
18741
|
+
if (needsFifo) {
|
|
18742
|
+
try {
|
|
18743
|
+
execFileSync("mkfifo", [fifoPath]);
|
|
18744
|
+
this.updateStatus(id, { fifo_path: fifoPath });
|
|
18745
|
+
} catch {}
|
|
18746
|
+
}
|
|
18732
18747
|
let textLogged = false;
|
|
18733
18748
|
let currentTool = "";
|
|
18734
18749
|
let currentToolCallId = "";
|
|
@@ -18736,6 +18751,8 @@ class Supervisor {
|
|
|
18736
18751
|
let steerFn;
|
|
18737
18752
|
let resumeFn;
|
|
18738
18753
|
let closeFn;
|
|
18754
|
+
let fifoReadStream;
|
|
18755
|
+
let fifoReadline;
|
|
18739
18756
|
const sigtermHandler = () => killFn?.();
|
|
18740
18757
|
process.once("SIGTERM", sigtermHandler);
|
|
18741
18758
|
try {
|
|
@@ -18745,6 +18762,7 @@ class Supervisor {
|
|
|
18745
18762
|
currentTool = toolMatch[1];
|
|
18746
18763
|
this.updateStatus(id, { current_tool: currentTool });
|
|
18747
18764
|
}
|
|
18765
|
+
this.opts.onProgress?.(delta);
|
|
18748
18766
|
}, (eventType) => {
|
|
18749
18767
|
const now = Date.now();
|
|
18750
18768
|
this.updateStatus(id, {
|
|
@@ -18766,41 +18784,43 @@ class Supervisor {
|
|
|
18766
18784
|
}, (meta) => {
|
|
18767
18785
|
this.updateStatus(id, { model: meta.model, backend: meta.backend });
|
|
18768
18786
|
appendTimelineEvent(createMetaEvent(meta.model, meta.backend));
|
|
18787
|
+
this.opts.onMeta?.(meta);
|
|
18769
18788
|
}, (fn) => {
|
|
18770
18789
|
killFn = fn;
|
|
18771
18790
|
}, (beadId) => {
|
|
18772
18791
|
this.updateStatus(id, { bead_id: beadId });
|
|
18773
18792
|
}, (fn) => {
|
|
18774
18793
|
steerFn = fn;
|
|
18775
|
-
if (existsSync4(fifoPath))
|
|
18776
|
-
|
|
18777
|
-
|
|
18778
|
-
|
|
18779
|
-
|
|
18780
|
-
|
|
18781
|
-
|
|
18782
|
-
|
|
18783
|
-
|
|
18784
|
-
|
|
18785
|
-
|
|
18786
|
-
|
|
18787
|
-
|
|
18788
|
-
|
|
18789
|
-
|
|
18790
|
-
|
|
18791
|
-
|
|
18792
|
-
|
|
18793
|
-
|
|
18794
|
-
this.updateStatus(id, { status: "error", error: err?.message ?? String(err) });
|
|
18794
|
+
if (!needsFifo || !existsSync4(fifoPath))
|
|
18795
|
+
return;
|
|
18796
|
+
fifoReadStream = createReadStream(fifoPath, { flags: "r+" });
|
|
18797
|
+
fifoReadline = createInterface({ input: fifoReadStream });
|
|
18798
|
+
fifoReadline.on("line", (line) => {
|
|
18799
|
+
try {
|
|
18800
|
+
const parsed = JSON.parse(line);
|
|
18801
|
+
if (parsed?.type === "steer" && typeof parsed.message === "string") {
|
|
18802
|
+
steerFn?.(parsed.message).catch(() => {});
|
|
18803
|
+
} else if (parsed?.type === "prompt" && typeof parsed.message === "string") {
|
|
18804
|
+
if (resumeFn) {
|
|
18805
|
+
this.updateStatus(id, { status: "running", current_event: "starting" });
|
|
18806
|
+
resumeFn(parsed.message).then((output) => {
|
|
18807
|
+
writeFileSync(this.resultPath(id), output, "utf-8");
|
|
18808
|
+
this.updateStatus(id, {
|
|
18809
|
+
status: "waiting",
|
|
18810
|
+
current_event: "waiting",
|
|
18811
|
+
elapsed_s: Math.round((Date.now() - startedAtMs) / 1000),
|
|
18812
|
+
last_event_at_ms: Date.now()
|
|
18795
18813
|
});
|
|
18796
|
-
}
|
|
18797
|
-
|
|
18798
|
-
|
|
18814
|
+
}).catch((err) => {
|
|
18815
|
+
this.updateStatus(id, { status: "error", error: err?.message ?? String(err) });
|
|
18816
|
+
});
|
|
18799
18817
|
}
|
|
18800
|
-
}
|
|
18801
|
-
|
|
18802
|
-
|
|
18803
|
-
|
|
18818
|
+
} else if (parsed?.type === "close") {
|
|
18819
|
+
closeFn?.().catch(() => {});
|
|
18820
|
+
}
|
|
18821
|
+
} catch {}
|
|
18822
|
+
});
|
|
18823
|
+
fifoReadline.on("error", () => {});
|
|
18804
18824
|
}, (rFn, cFn) => {
|
|
18805
18825
|
resumeFn = rFn;
|
|
18806
18826
|
closeFn = cFn;
|
|
@@ -18840,6 +18860,12 @@ class Supervisor {
|
|
|
18840
18860
|
throw err;
|
|
18841
18861
|
} finally {
|
|
18842
18862
|
process.removeListener("SIGTERM", sigtermHandler);
|
|
18863
|
+
try {
|
|
18864
|
+
fifoReadline?.close();
|
|
18865
|
+
} catch {}
|
|
18866
|
+
try {
|
|
18867
|
+
fifoReadStream?.destroy();
|
|
18868
|
+
} catch {}
|
|
18843
18869
|
try {
|
|
18844
18870
|
fsyncSync(eventsFd);
|
|
18845
18871
|
} catch {}
|
|
@@ -19601,50 +19627,52 @@ async function run7() {
|
|
|
19601
19627
|
circuitBreaker,
|
|
19602
19628
|
beadsClient
|
|
19603
19629
|
});
|
|
19604
|
-
process.
|
|
19605
|
-
|
|
19606
|
-
|
|
19607
|
-
|
|
19608
|
-
|
|
19609
|
-
|
|
19610
|
-
|
|
19611
|
-
|
|
19612
|
-
|
|
19613
|
-
|
|
19614
|
-
|
|
19615
|
-
|
|
19630
|
+
const jobsDir = join10(process.cwd(), ".specialists", "jobs");
|
|
19631
|
+
const supervisor = new Supervisor({
|
|
19632
|
+
runner,
|
|
19633
|
+
runOptions: {
|
|
19634
|
+
name: args.name,
|
|
19635
|
+
prompt,
|
|
19636
|
+
variables,
|
|
19637
|
+
backendOverride: args.model,
|
|
19638
|
+
inputBeadId: args.beadId,
|
|
19639
|
+
keepAlive: args.keepAlive
|
|
19640
|
+
},
|
|
19641
|
+
jobsDir,
|
|
19642
|
+
beadsClient,
|
|
19643
|
+
onProgress: (delta) => process.stdout.write(delta),
|
|
19644
|
+
onMeta: (meta) => process.stderr.write(dim5(`
|
|
19616
19645
|
[${meta.backend} / ${meta.model}]
|
|
19617
19646
|
|
|
19618
|
-
`))
|
|
19619
|
-
|
|
19620
|
-
|
|
19647
|
+
`))
|
|
19648
|
+
});
|
|
19649
|
+
process.stderr.write(`
|
|
19650
|
+
${bold5(`Running ${cyan3(args.name)}`)}
|
|
19621
19651
|
|
|
19622
|
-
Interrupted.
|
|
19623
19652
|
`);
|
|
19624
|
-
|
|
19625
|
-
|
|
19626
|
-
|
|
19627
|
-
}
|
|
19628
|
-
|
|
19629
|
-
process.stderr.write(dim5(`
|
|
19630
|
-
[bead: ${beadId}]
|
|
19631
|
-
`));
|
|
19632
|
-
});
|
|
19633
|
-
if (result.output && !result.output.endsWith(`
|
|
19634
|
-
`))
|
|
19635
|
-
process.stdout.write(`
|
|
19653
|
+
let jobId;
|
|
19654
|
+
try {
|
|
19655
|
+
jobId = await supervisor.run();
|
|
19656
|
+
} catch (err) {
|
|
19657
|
+
process.stderr.write(`Error: ${err?.message ?? err}
|
|
19636
19658
|
`);
|
|
19637
|
-
|
|
19638
|
-
|
|
19659
|
+
process.exit(1);
|
|
19660
|
+
}
|
|
19661
|
+
const status = supervisor.readStatus(jobId);
|
|
19662
|
+
const secs = ((status?.last_event_at_ms ?? Date.now()) - (status?.started_at_ms ?? Date.now())) / 1000;
|
|
19639
19663
|
const footer = [
|
|
19640
|
-
|
|
19641
|
-
|
|
19642
|
-
|
|
19664
|
+
`job ${jobId}`,
|
|
19665
|
+
status?.bead_id ? `bead ${status.bead_id}` : "",
|
|
19666
|
+
`${secs.toFixed(1)}s`,
|
|
19667
|
+
status?.model ? dim5(`${status.backend}/${status.model}`) : ""
|
|
19643
19668
|
].filter(Boolean).join(" ");
|
|
19644
19669
|
process.stderr.write(`
|
|
19645
19670
|
${green5("✓")} ${footer}
|
|
19646
19671
|
|
|
19647
19672
|
`);
|
|
19673
|
+
process.stderr.write(dim5(`Poll: specialists poll ${jobId} --json
|
|
19674
|
+
|
|
19675
|
+
`));
|
|
19648
19676
|
}
|
|
19649
19677
|
var bold5 = (s) => `\x1B[1m${s}\x1B[0m`, dim5 = (s) => `\x1B[2m${s}\x1B[0m`, green5 = (s) => `\x1B[32m${s}\x1B[0m`, cyan3 = (s) => `\x1B[36m${s}\x1B[0m`;
|
|
19650
19678
|
var init_run = __esm(() => {
|
|
@@ -19652,6 +19680,7 @@ var init_run = __esm(() => {
|
|
|
19652
19680
|
init_runner();
|
|
19653
19681
|
init_hooks();
|
|
19654
19682
|
init_beads();
|
|
19683
|
+
init_supervisor();
|
|
19655
19684
|
});
|
|
19656
19685
|
|
|
19657
19686
|
// src/cli/format-helpers.ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jaggerxtrm/specialists",
|
|
3
|
-
"version": "3.3.
|
|
3
|
+
"version": "3.3.4",
|
|
4
4
|
"description": "OmniSpecialist — 7-tool MCP orchestration layer powered by the Specialist System. Discover and execute .specialist.yaml files across project/user/system scopes via pi.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|