@infersec/conduit 1.46.0 → 1.46.1
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.js +87 -21
- package/dist/modelManagement/ModelManager.d.ts +6 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -112782,6 +112782,7 @@ class ModelManager extends EventEmitter {
|
|
|
112782
112782
|
contextLength;
|
|
112783
112783
|
logger;
|
|
112784
112784
|
engineProcess = null;
|
|
112785
|
+
healthPollInterval = null;
|
|
112785
112786
|
lifecycleState = "stopped";
|
|
112786
112787
|
stopRequested = false;
|
|
112787
112788
|
modelsDirectory;
|
|
@@ -112919,6 +112920,9 @@ class ModelManager extends EventEmitter {
|
|
|
112919
112920
|
}
|
|
112920
112921
|
this.lifecycleState = "errored";
|
|
112921
112922
|
this.emit("engineError", err);
|
|
112923
|
+
if (this.engineProcess) {
|
|
112924
|
+
this.startHealthPoll();
|
|
112925
|
+
}
|
|
112922
112926
|
throw err;
|
|
112923
112927
|
}
|
|
112924
112928
|
this.lifecycleState = "running";
|
|
@@ -112930,16 +112934,18 @@ class ModelManager extends EventEmitter {
|
|
|
112930
112934
|
message: "Cannot stop LLM engine: already stopping"
|
|
112931
112935
|
});
|
|
112932
112936
|
}
|
|
112933
|
-
if (this.lifecycleState !== "running" &&
|
|
112937
|
+
if (this.lifecycleState !== "running" &&
|
|
112938
|
+
this.lifecycleState !== "starting" &&
|
|
112939
|
+
this.lifecycleState !== "errored") {
|
|
112934
112940
|
throw new UnknownError({
|
|
112935
112941
|
message: `Cannot stop LLM engine: Invalid state: ${this.lifecycleState}`
|
|
112936
112942
|
});
|
|
112937
112943
|
}
|
|
112944
|
+
this.clearHealthPoll();
|
|
112938
112945
|
const processManager = this.engineProcess;
|
|
112939
112946
|
if (!processManager) {
|
|
112940
|
-
|
|
112941
|
-
|
|
112942
|
-
});
|
|
112947
|
+
this.lifecycleState = "stopped";
|
|
112948
|
+
return;
|
|
112943
112949
|
}
|
|
112944
112950
|
this.lifecycleState = "stopping";
|
|
112945
112951
|
this.stopRequested = true;
|
|
@@ -112949,32 +112955,63 @@ class ModelManager extends EventEmitter {
|
|
|
112949
112955
|
return this.lifecycleState === "stopped";
|
|
112950
112956
|
}
|
|
112951
112957
|
get canStop() {
|
|
112952
|
-
return this.lifecycleState === "running" ||
|
|
112958
|
+
return (this.lifecycleState === "running" ||
|
|
112959
|
+
this.lifecycleState === "starting" ||
|
|
112960
|
+
this.lifecycleState === "errored");
|
|
112953
112961
|
}
|
|
112954
112962
|
get state() {
|
|
112955
112963
|
return this.lifecycleState;
|
|
112956
112964
|
}
|
|
112957
|
-
async
|
|
112965
|
+
async checkEngineReadiness() {
|
|
112958
112966
|
switch (this.engine) {
|
|
112959
|
-
case "llama.cpp":
|
|
112967
|
+
case "llama.cpp": {
|
|
112968
|
+
return this.checkLlamacppReadiness();
|
|
112969
|
+
}
|
|
112960
112970
|
case "vllm": {
|
|
112961
|
-
|
|
112962
|
-
const response = await this.fetchOpenAI("/v1/models", {
|
|
112963
|
-
method: "GET",
|
|
112964
|
-
signal: AbortSignal.timeout(5000)
|
|
112965
|
-
});
|
|
112966
|
-
return response.ok;
|
|
112967
|
-
}
|
|
112968
|
-
catch (_error) {
|
|
112969
|
-
return false;
|
|
112970
|
-
}
|
|
112971
|
+
return this.checkVLLMReadiness();
|
|
112971
112972
|
}
|
|
112972
112973
|
default:
|
|
112973
|
-
return
|
|
112974
|
+
return "ready";
|
|
112975
|
+
}
|
|
112976
|
+
}
|
|
112977
|
+
async checkLlamacppReadiness() {
|
|
112978
|
+
try {
|
|
112979
|
+
const response = await undiciExports.fetch(joinURL(`http://localhost:${this.enginePort}`, "/health"), {
|
|
112980
|
+
method: "GET",
|
|
112981
|
+
signal: AbortSignal.timeout(5000)
|
|
112982
|
+
});
|
|
112983
|
+
if (response.status === 503) {
|
|
112984
|
+
return "loading";
|
|
112985
|
+
}
|
|
112986
|
+
if (response.ok) {
|
|
112987
|
+
return "ready";
|
|
112988
|
+
}
|
|
112989
|
+
return "loading";
|
|
112990
|
+
}
|
|
112991
|
+
catch (_error) {
|
|
112992
|
+
return "unreachable";
|
|
112993
|
+
}
|
|
112994
|
+
}
|
|
112995
|
+
async checkVLLMReadiness() {
|
|
112996
|
+
try {
|
|
112997
|
+
const response = await undiciExports.fetch(joinURL(`http://localhost:${this.enginePort}`, "/v1/models"), {
|
|
112998
|
+
method: "GET",
|
|
112999
|
+
signal: AbortSignal.timeout(5000)
|
|
113000
|
+
});
|
|
113001
|
+
if (response.status === 503) {
|
|
113002
|
+
return "loading";
|
|
113003
|
+
}
|
|
113004
|
+
if (response.ok) {
|
|
113005
|
+
return "ready";
|
|
113006
|
+
}
|
|
113007
|
+
return "loading";
|
|
113008
|
+
}
|
|
113009
|
+
catch (_error) {
|
|
113010
|
+
return "unreachable";
|
|
112974
113011
|
}
|
|
112975
113012
|
}
|
|
112976
113013
|
async waitForEngineReady() {
|
|
112977
|
-
const maxWaitMs =
|
|
113014
|
+
const maxWaitMs = 15 * 60 * 1000;
|
|
112978
113015
|
const pollIntervalMs = 2000;
|
|
112979
113016
|
const start = Date.now();
|
|
112980
113017
|
while (Date.now() - start < maxWaitMs) {
|
|
@@ -112984,14 +113021,41 @@ class ModelManager extends EventEmitter {
|
|
|
112984
113021
|
if (!this.engineProcess) {
|
|
112985
113022
|
throw new Error("LLM engine process exited before readiness checks completed");
|
|
112986
113023
|
}
|
|
112987
|
-
const
|
|
112988
|
-
if (ready) {
|
|
113024
|
+
const readiness = await this.checkEngineReadiness();
|
|
113025
|
+
if (readiness === "ready") {
|
|
112989
113026
|
return;
|
|
112990
113027
|
}
|
|
112991
113028
|
await new Promise(resolve => setTimeout(resolve, pollIntervalMs));
|
|
112992
113029
|
}
|
|
112993
113030
|
throw new Error("LLM engine failed readiness checks within timeout");
|
|
112994
113031
|
}
|
|
113032
|
+
clearHealthPoll() {
|
|
113033
|
+
if (this.healthPollInterval) {
|
|
113034
|
+
clearInterval(this.healthPollInterval);
|
|
113035
|
+
this.healthPollInterval = null;
|
|
113036
|
+
}
|
|
113037
|
+
}
|
|
113038
|
+
startHealthPoll() {
|
|
113039
|
+
this.clearHealthPoll();
|
|
113040
|
+
this.logger.info("Starting background health poll for errored engine");
|
|
113041
|
+
this.healthPollInterval = setInterval(() => {
|
|
113042
|
+
if (!this.engineProcess) {
|
|
113043
|
+
this.clearHealthPoll();
|
|
113044
|
+
return;
|
|
113045
|
+
}
|
|
113046
|
+
this.checkEngineReadiness()
|
|
113047
|
+
.then(readiness => {
|
|
113048
|
+
if (readiness === "ready") {
|
|
113049
|
+
this.clearHealthPoll();
|
|
113050
|
+
this.lifecycleState = "running";
|
|
113051
|
+
this.emit("engineReady");
|
|
113052
|
+
}
|
|
113053
|
+
})
|
|
113054
|
+
.catch(() => {
|
|
113055
|
+
// keep polling
|
|
113056
|
+
});
|
|
113057
|
+
}, 15_000);
|
|
113058
|
+
}
|
|
112995
113059
|
bindEngineProcessEvents(processManager) {
|
|
112996
113060
|
let hasTerminated = false;
|
|
112997
113061
|
processManager.on("stderr", line => {
|
|
@@ -113005,6 +113069,7 @@ class ModelManager extends EventEmitter {
|
|
|
113005
113069
|
return;
|
|
113006
113070
|
}
|
|
113007
113071
|
hasTerminated = true;
|
|
113072
|
+
this.clearHealthPoll();
|
|
113008
113073
|
if (this.stopRequested) {
|
|
113009
113074
|
this.engineProcess = null;
|
|
113010
113075
|
this.lifecycleState = "stopped";
|
|
@@ -113026,6 +113091,7 @@ class ModelManager extends EventEmitter {
|
|
|
113026
113091
|
return;
|
|
113027
113092
|
}
|
|
113028
113093
|
hasTerminated = true;
|
|
113094
|
+
this.clearHealthPoll();
|
|
113029
113095
|
this.engineProcess = null;
|
|
113030
113096
|
if (this.stopRequested) {
|
|
113031
113097
|
this.lifecycleState = "stopped";
|
|
@@ -18,6 +18,7 @@ export declare class ModelManager extends EventEmitter<ModelManagerEvents> {
|
|
|
18
18
|
readonly contextLength: number | null;
|
|
19
19
|
protected readonly logger: Logger;
|
|
20
20
|
private engineProcess;
|
|
21
|
+
private healthPollInterval;
|
|
21
22
|
private lifecycleState;
|
|
22
23
|
private stopRequested;
|
|
23
24
|
protected readonly modelsDirectory: string;
|
|
@@ -39,8 +40,12 @@ export declare class ModelManager extends EventEmitter<ModelManagerEvents> {
|
|
|
39
40
|
get canStart(): boolean;
|
|
40
41
|
get canStop(): boolean;
|
|
41
42
|
get state(): EngineLifecycleState;
|
|
42
|
-
private
|
|
43
|
+
private checkEngineReadiness;
|
|
44
|
+
private checkLlamacppReadiness;
|
|
45
|
+
private checkVLLMReadiness;
|
|
43
46
|
private waitForEngineReady;
|
|
47
|
+
private clearHealthPoll;
|
|
48
|
+
private startHealthPoll;
|
|
44
49
|
private bindEngineProcessEvents;
|
|
45
50
|
private startEngineProcess;
|
|
46
51
|
}
|