@infersec/conduit 1.113.0 → 1.114.0

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 CHANGED
@@ -19886,6 +19886,7 @@ object$5({
19886
19886
  });
19887
19887
 
19888
19888
  const LLMEngineSchema = _enum$1([
19889
+ "custom",
19889
19890
  "exllamav3",
19890
19891
  "llama.cpp",
19891
19892
  "mlx-lm",
@@ -19894,8 +19895,25 @@ const LLMEngineSchema = _enum$1([
19894
19895
  "vllm"
19895
19896
  ]);
19896
19897
  const EngineConfigSchema = object$5({
19898
+ baseUrl: string$2().url().nullable().default(null),
19897
19899
  extraArgs: array$1(string$2()),
19898
19900
  type: LLMEngineSchema
19901
+ })
19902
+ .superRefine((config, ctx) => {
19903
+ if (config.type === "custom" && config.baseUrl === null) {
19904
+ ctx.addIssue({
19905
+ code: "custom",
19906
+ message: "Engine type 'custom' requires a base URL",
19907
+ path: ["baseUrl"]
19908
+ });
19909
+ }
19910
+ if (config.type !== "custom" && config.baseUrl !== null) {
19911
+ ctx.addIssue({
19912
+ code: "custom",
19913
+ message: "Base URL is only valid for engine type 'custom'",
19914
+ path: ["baseUrl"]
19915
+ });
19916
+ }
19899
19917
  });
19900
19918
  const LLMModelFormatSchema = _enum$1([
19901
19919
  // VLLM / SGLang / TensorRT-LLM
@@ -19954,14 +19972,18 @@ const LLMModelSchema = object$5({
19954
19972
  id: string$2().min(1),
19955
19973
  multimodalEnabled: boolean$1(),
19956
19974
  source: discriminatedUnion("type", [
19975
+ // Custom engines: no local model record, serving is external
19957
19976
  object$5({
19958
- irid: IRIDSchema,
19959
- type: literal("storage")
19977
+ type: literal("external")
19960
19978
  }),
19961
19979
  object$5({
19962
19980
  modelSecret: string$2().min(1).nullable(),
19963
19981
  slug: string$2().min(1),
19964
19982
  type: literal("huggingface")
19983
+ }),
19984
+ object$5({
19985
+ irid: IRIDSchema,
19986
+ type: literal("storage")
19965
19987
  })
19966
19988
  ]),
19967
19989
  taskType: LLMModelTaskTypeSchema,
@@ -21105,7 +21127,8 @@ const CreateModelResponseSchema = object$5({
21105
21127
  const CreateSourceBodySchema = object$5({
21106
21128
  contextLength: number$1().int().positive().max(1048576).optional(),
21107
21129
  engineId: ULIDSchema,
21108
- modelID: ULIDSchema,
21130
+ // Optional for custom engines, which serve externally managed models
21131
+ modelID: ULIDSchema.nullable().optional(),
21109
21132
  name: ResourceNameSchema,
21110
21133
  quantizationLabel: string$2().min(1).max(128).optional()
21111
21134
  });
@@ -21154,7 +21177,7 @@ const SourceDetailResponseSchema = object$5({
21154
21177
  const UpdateSourceBodySchema = object$5({
21155
21178
  contextLength: number$1().int().positive().nullable().optional(),
21156
21179
  engineId: ULIDSchema.nullable().optional(),
21157
- modelID: ULIDSchema.optional(),
21180
+ modelID: ULIDSchema.nullable().optional(),
21158
21181
  name: ResourceNameSchema.optional(),
21159
21182
  quantizationLabel: string$2().min(1).max(128).nullable().optional()
21160
21183
  });
@@ -21278,6 +21301,7 @@ const CreateEndpointResponseSchema = object$5({
21278
21301
  id: ULIDSchema
21279
21302
  });
21280
21303
  const EngineOutputSchema = object$5({
21304
+ baseUrl: string$2().nullable(),
21281
21305
  created: string$2(),
21282
21306
  extraArgs: array$1(string$2()),
21283
21307
  id: ULIDSchema,
@@ -21286,11 +21310,29 @@ const EngineOutputSchema = object$5({
21286
21310
  updated: string$2()
21287
21311
  });
21288
21312
  const CreateEngineBodySchema = object$5({
21313
+ baseUrl: string$2().url().nullable().optional(),
21289
21314
  extraArgs: array$1(string$2()).optional(),
21290
21315
  name: ResourceNameSchema,
21291
21316
  type: LLMEngineSchema
21317
+ })
21318
+ .superRefine((body, ctx) => {
21319
+ if (body.type === "custom" && !body.baseUrl) {
21320
+ ctx.addIssue({
21321
+ code: "custom",
21322
+ message: "Engine type 'custom' requires a base URL",
21323
+ path: ["baseUrl"]
21324
+ });
21325
+ }
21326
+ if (body.type !== "custom" && body.baseUrl) {
21327
+ ctx.addIssue({
21328
+ code: "custom",
21329
+ message: "Base URL is only valid for engine type 'custom'",
21330
+ path: ["baseUrl"]
21331
+ });
21332
+ }
21292
21333
  });
21293
21334
  const UpdateEngineBodySchema = object$5({
21335
+ baseUrl: string$2().url().nullable().optional(),
21294
21336
  extraArgs: array$1(string$2()).optional(),
21295
21337
  name: ResourceNameSchema.optional(),
21296
21338
  type: LLMEngineSchema.optional()
@@ -22096,6 +22138,11 @@ const RecommendedModelSchema = object$5({
22096
22138
  const recommendedModels = RecommendedModelSchema.array().parse(modelsData);
22097
22139
 
22098
22140
  const ENGINE_API_COMPATIBILITY = {
22141
+ custom: {
22142
+ nativeAnthropicMessages: false,
22143
+ supportsEmbeddings: true,
22144
+ supportsVision: true
22145
+ },
22099
22146
  exllamav3: {
22100
22147
  nativeAnthropicMessages: false,
22101
22148
  supportsEmbeddings: false,
@@ -111745,6 +111792,27 @@ function registerEndpointCommands({ program }) {
111745
111792
  }
111746
111793
 
111747
111794
  const ENGINE_TYPES = LLMEngineSchema.options;
111795
+ function isValidURL(value) {
111796
+ try {
111797
+ const url = new URL(value);
111798
+ return url.protocol === "http:" || url.protocol === "https:";
111799
+ }
111800
+ catch (_error) {
111801
+ return false;
111802
+ }
111803
+ }
111804
+ function validateEngineBaseURL({ baseUrl, type }) {
111805
+ if (type === "custom" && !baseUrl) {
111806
+ throw new Error("Engine type 'custom' requires --base-url");
111807
+ }
111808
+ if (baseUrl !== undefined && type !== "custom") {
111809
+ throw new Error("--base-url is only valid for engine type 'custom'");
111810
+ }
111811
+ if (baseUrl !== undefined && baseUrl !== "" && !isValidURL(baseUrl)) {
111812
+ throw new Error(`Invalid --base-url value: ${baseUrl}`);
111813
+ }
111814
+ return baseUrl === "" ? null : (baseUrl ?? null);
111815
+ }
111748
111816
  function buildEngineCreateBody(options) {
111749
111817
  if (!options.name) {
111750
111818
  throw new Error("--name is required");
@@ -111755,7 +111823,12 @@ function buildEngineCreateBody(options) {
111755
111823
  if (!ENGINE_TYPES.includes(options.type)) {
111756
111824
  throw new Error(`Invalid engine type: ${options.type} (expected one of: ${ENGINE_TYPES.join(", ")})`);
111757
111825
  }
111826
+ const baseUrl = validateEngineBaseURL({
111827
+ baseUrl: options.baseUrl,
111828
+ type: options.type
111829
+ });
111758
111830
  return {
111831
+ baseUrl,
111759
111832
  extraArgs: options.arg ?? [],
111760
111833
  name: options.name,
111761
111834
  type: options.type
@@ -111773,6 +111846,24 @@ function buildEngineUpdateBody(options) {
111773
111846
  }
111774
111847
  if (options.arg !== undefined)
111775
111848
  body.extraArgs = options.arg;
111849
+ if (options.baseUrl !== undefined) {
111850
+ const targetType = body.type;
111851
+ if (targetType !== undefined) {
111852
+ body.baseUrl = validateEngineBaseURL({
111853
+ baseUrl: options.baseUrl,
111854
+ type: targetType
111855
+ });
111856
+ }
111857
+ else if (options.baseUrl === "") {
111858
+ body.baseUrl = null;
111859
+ }
111860
+ else if (!isValidURL(options.baseUrl)) {
111861
+ throw new Error(`Invalid --base-url value: ${options.baseUrl}`);
111862
+ }
111863
+ else {
111864
+ body.baseUrl = options.baseUrl;
111865
+ }
111866
+ }
111776
111867
  return body;
111777
111868
  }
111778
111869
 
@@ -111786,10 +111877,11 @@ function registerEngineCommands({ program }) {
111786
111877
  .description("Create or update an inference engine resource")
111787
111878
  .option("--api-url <url>", "API base URL (required, no environment variable fallback)")
111788
111879
  .option("--arg <flag>", 'Raw engine CLI flag, repeatable (eg --arg "--flash-attn on")', collect, [])
111880
+ .option("--base-url <url>", "Base URL of an external OpenAI-compatible server (engine type 'custom' only)")
111789
111881
  .option("--id <ulid>", "Target an existing engine by ID (requires --update)")
111790
111882
  .option("--key <value>", "API key (required, no environment variable fallback)")
111791
111883
  .option("--name <name>", "Engine name (matched by --update)")
111792
- .option("--type <type>", "Engine type: llama.cpp|vllm|sglang|tensorrt-llm|mlx-lm|exllamav3")
111884
+ .option("--type <type>", "Engine type: llama.cpp|vllm|sglang|tensorrt-llm|mlx-lm|exllamav3|custom")
111793
111885
  .option("--update", "Update an existing engine matched by name (or --id) instead of erroring")
111794
111886
  .action(async (options) => {
111795
111887
  const { apiURL, apiKey } = resolveManagementConnection(options);
@@ -117789,6 +117881,9 @@ async function getChatTemplateEngineArgs({ engine, model, targetDirectory }) {
117789
117881
  return [];
117790
117882
  const flag = FLAG_BASED_ENGINE_ARGS[engine];
117791
117883
  if (!flag) {
117884
+ if (engine === "custom") {
117885
+ console.warn("[chatTemplate] Custom engines manage their own serving; ignoring chat template override");
117886
+ }
117792
117887
  if (engine === "tensorrt-llm") {
117793
117888
  console.warn("[chatTemplate] TensorRT-LLM does not support chat template overrides; ignoring");
117794
117889
  }
@@ -124686,7 +124781,7 @@ function matchesQuantizationVariant({ filePath, variant }) {
124686
124781
  return segments.slice(0, -1).some(segment => matcher.test(segment));
124687
124782
  }
124688
124783
  async function findQuantizedModelTarget({ model, path }) {
124689
- if (model.source.type === "storage") {
124784
+ if (model.source.type !== "huggingface") {
124690
124785
  throw new Error("Model storage not supported yet");
124691
124786
  }
124692
124787
  if (model.format !== "gguf") {
@@ -125601,7 +125696,11 @@ function sanitizeSegment(value) {
125601
125696
  .replace(new RegExp(`${SEPARATOR}{2,}`, "g"), SEPARATOR);
125602
125697
  }
125603
125698
  function createModelStorageKey(model) {
125604
- const identifier = model.source.type === "huggingface" ? model.source.slug : model.source.irid;
125699
+ const identifier = model.source.type === "huggingface"
125700
+ ? model.source.slug
125701
+ : model.source.type === "storage"
125702
+ ? model.source.irid
125703
+ : model.id;
125605
125704
  return `${model.source.type}${SEPARATOR}${sanitizeSegment(identifier)}`;
125606
125705
  }
125607
125706
 
@@ -125677,6 +125776,7 @@ class ModelManager extends EventEmitter {
125677
125776
  uniqueName;
125678
125777
  contextLength;
125679
125778
  logger;
125779
+ discoveredModelNames = [];
125680
125780
  engineProcess = null;
125681
125781
  healthPollInterval = null;
125682
125782
  lastEngineError = null;
@@ -125709,6 +125809,7 @@ class ModelManager extends EventEmitter {
125709
125809
  }
125710
125810
  async fetchOpenAI(path, opts) {
125711
125811
  switch (this.engine) {
125812
+ case "custom":
125712
125813
  case "exllamav3":
125713
125814
  case "llama.cpp":
125714
125815
  case "mlx-lm":
@@ -125716,6 +125817,9 @@ class ModelManager extends EventEmitter {
125716
125817
  case "tensorrt-llm":
125717
125818
  case "vllm": {
125718
125819
  this.logger.debug(`Fetching from engine: ${path}`);
125820
+ const baseURL = this.engine === "custom"
125821
+ ? this.requireCustomBaseURL()
125822
+ : `http://localhost:${this.enginePort}`;
125719
125823
  const callerSignal = opts?.signal;
125720
125824
  const controller = new AbortController();
125721
125825
  const timeout = setTimeout(() => {
@@ -125726,7 +125830,7 @@ class ModelManager extends EventEmitter {
125726
125830
  : controller.signal;
125727
125831
  try {
125728
125832
  const fetchStartedAt = Date.now();
125729
- const response = await undiciExports.fetch(joinURL(`http://localhost:${this.enginePort}`, path), {
125833
+ const response = await undiciExports.fetch(joinURL(baseURL, path), {
125730
125834
  ...opts,
125731
125835
  dispatcher: ENGINE_AGENT,
125732
125836
  headers: {
@@ -125761,6 +125865,11 @@ class ModelManager extends EventEmitter {
125761
125865
  modelID: this.model.id
125762
125866
  });
125763
125867
  switch (this.engine) {
125868
+ case "custom":
125869
+ if (this.model.chatTemplate) {
125870
+ this.logger.warn("Chat template overrides are ignored for custom engines: the remote server manages its own serving");
125871
+ }
125872
+ break;
125764
125873
  case "exllamav3":
125765
125874
  case "llama.cpp":
125766
125875
  case "mlx-lm":
@@ -125816,7 +125925,9 @@ class ModelManager extends EventEmitter {
125816
125925
  });
125817
125926
  try {
125818
125927
  this.engineProcess = await this.startEngineProcess();
125819
- this.bindEngineProcessEvents(this.engineProcess);
125928
+ if (this.engineProcess) {
125929
+ this.bindEngineProcessEvents(this.engineProcess);
125930
+ }
125820
125931
  this.logger.info("Started LLM engine", {
125821
125932
  agentEngineType: this.engine
125822
125933
  });
@@ -125835,7 +125946,7 @@ class ModelManager extends EventEmitter {
125835
125946
  if (!alreadyEmitted) {
125836
125947
  this.emit("engineError", err);
125837
125948
  }
125838
- if (this.engineProcess) {
125949
+ if (this.engineProcess || this.engine === "custom") {
125839
125950
  this.startHealthPoll();
125840
125951
  }
125841
125952
  throw err;
@@ -125843,6 +125954,9 @@ class ModelManager extends EventEmitter {
125843
125954
  this.lifecycleState = "running";
125844
125955
  this.reachedRunningState = true;
125845
125956
  this.emit("engineReady");
125957
+ if (this.engine === "custom") {
125958
+ this.startHealthPoll();
125959
+ }
125846
125960
  }
125847
125961
  async stop() {
125848
125962
  if (this.lifecycleState === "stopping") {
@@ -125863,6 +125977,8 @@ class ModelManager extends EventEmitter {
125863
125977
  this.clearHealthPoll();
125864
125978
  const processManager = this.engineProcess;
125865
125979
  if (!processManager) {
125980
+ this.stopRequested = true;
125981
+ this.reachedRunningState = false;
125866
125982
  this.lifecycleState = "stopped";
125867
125983
  return;
125868
125984
  }
@@ -125888,11 +126004,25 @@ class ModelManager extends EventEmitter {
125888
126004
  get state() {
125889
126005
  return this.lifecycleState;
125890
126006
  }
126007
+ get resolvedServedModelName() {
126008
+ if (this.engine !== "custom")
126009
+ return null;
126010
+ return this.discoveredModelNames[0] ?? null;
126011
+ }
125891
126012
  get wasRunning() {
125892
126013
  return this.reachedRunningState;
125893
126014
  }
126015
+ get customBaseURL() {
126016
+ if (this.engine !== "custom")
126017
+ return null;
126018
+ const baseUrl = this.engineConfig?.baseUrl;
126019
+ return typeof baseUrl === "string" && baseUrl.length > 0 ? baseUrl : null;
126020
+ }
125894
126021
  async checkEngineReadiness() {
125895
126022
  switch (this.engine) {
126023
+ case "custom": {
126024
+ return this.checkCustomReadiness();
126025
+ }
125896
126026
  case "llama.cpp": {
125897
126027
  return this.checkLlamacppReadiness();
125898
126028
  }
@@ -125909,6 +126039,51 @@ class ModelManager extends EventEmitter {
125909
126039
  return "ready";
125910
126040
  }
125911
126041
  }
126042
+ async checkCustomReadiness() {
126043
+ const baseURL = this.customBaseURL;
126044
+ if (!baseURL) {
126045
+ return "unreachable";
126046
+ }
126047
+ try {
126048
+ const response = await undiciExports.fetch(joinURL(baseURL, "/v1/models"), {
126049
+ method: "GET",
126050
+ signal: AbortSignal.timeout(5000)
126051
+ });
126052
+ if (response.status === 503) {
126053
+ return "loading";
126054
+ }
126055
+ if (!response.ok) {
126056
+ return "unreachable";
126057
+ }
126058
+ const payload = (await response.json());
126059
+ const models = Array.isArray(payload.data) ? payload.data : [];
126060
+ const modelIDs = models
126061
+ .map(model => {
126062
+ if (model === null || typeof model !== "object")
126063
+ return null;
126064
+ const id = model.id;
126065
+ return typeof id === "string" ? id : null;
126066
+ })
126067
+ .filter((id) => id !== null);
126068
+ if (modelIDs.length === 0) {
126069
+ this.logger.warn("Custom engine endpoint exposed no models via /v1/models", {
126070
+ engineBaseURL: baseURL
126071
+ });
126072
+ return "loading";
126073
+ }
126074
+ if (modelIDs.join("\n") !== this.discoveredModelNames.join("\n")) {
126075
+ this.logger.info("Discovered models on custom engine endpoint", {
126076
+ engineBaseURL: baseURL,
126077
+ models: modelIDs
126078
+ });
126079
+ this.discoveredModelNames = modelIDs;
126080
+ }
126081
+ return "ready";
126082
+ }
126083
+ catch (_error) {
126084
+ return "unreachable";
126085
+ }
126086
+ }
125912
126087
  async checkGenericHealthReadiness() {
125913
126088
  try {
125914
126089
  const response = await undiciExports.fetch(joinURL(`http://localhost:${this.enginePort}`, "/health"), {
@@ -125964,18 +126139,24 @@ class ModelManager extends EventEmitter {
125964
126139
  }
125965
126140
  }
125966
126141
  async waitForEngineReady() {
125967
- const maxWaitMs = 15 * 60 * 1000;
126142
+ const maxWaitMs = Number.parseInt(process.env.ENGINE_STARTUP_TIMEOUT_MS ?? "", 10) || 15 * 60 * 1000;
125968
126143
  const pollIntervalMs = 2000;
125969
126144
  const start = Date.now();
125970
126145
  while (Date.now() - start < maxWaitMs) {
125971
- if (this.lifecycleState === "stopping") {
126146
+ if (this.lifecycleState === "stopping" || this.stopRequested) {
125972
126147
  throw new Error("LLM engine startup interrupted by stop request");
125973
126148
  }
125974
- if (!this.engineProcess) {
126149
+ if (!this.engineProcess && this.engine !== "custom") {
125975
126150
  throw new Error("LLM engine process exited before readiness checks completed");
125976
126151
  }
125977
126152
  const readiness = await this.checkEngineReadiness();
125978
126153
  if (readiness === "ready") {
126154
+ // A stop() may have landed while the readiness request was
126155
+ // in flight; re-check before declaring ready.
126156
+ const lifecycleState = this.lifecycleState;
126157
+ if (lifecycleState === "stopping" || this.stopRequested) {
126158
+ throw new Error("LLM engine startup interrupted by stop request");
126159
+ }
125979
126160
  return;
125980
126161
  }
125981
126162
  await new Promise(resolve => setTimeout(resolve, pollIntervalMs));
@@ -125993,19 +126174,32 @@ class ModelManager extends EventEmitter {
125993
126174
  }
125994
126175
  startHealthPoll() {
125995
126176
  this.clearHealthPoll();
125996
- this.logger.info("Starting background health poll for errored engine");
126177
+ this.logger.info("Starting background engine health poll", {
126178
+ agentEngineType: this.engine
126179
+ });
125997
126180
  this.healthPollInterval = setInterval(() => {
125998
- if (!this.engineProcess) {
126181
+ if (!this.engineProcess && this.engine !== "custom") {
125999
126182
  this.clearHealthPoll();
126000
126183
  return;
126001
126184
  }
126002
126185
  this.checkEngineReadiness()
126003
126186
  .then(readiness => {
126004
126187
  if (readiness === "ready") {
126005
- this.clearHealthPoll();
126006
- this.lifecycleState = "running";
126007
- this.reachedRunningState = true;
126008
- this.emit("engineReady");
126188
+ if (this.lifecycleState === "errored" ||
126189
+ this.lifecycleState === "starting") {
126190
+ this.lifecycleState = "running";
126191
+ this.reachedRunningState = true;
126192
+ this.emit("engineReady");
126193
+ }
126194
+ if (this.engine !== "custom") {
126195
+ this.clearHealthPoll();
126196
+ }
126197
+ return;
126198
+ }
126199
+ if (this.engine === "custom" &&
126200
+ readiness === "unreachable" &&
126201
+ this.lifecycleState === "running") {
126202
+ this.recordEngineError(new Error(`Custom engine endpoint unreachable: ${this.customBaseURL}`));
126009
126203
  }
126010
126204
  })
126011
126205
  .catch(() => {
@@ -126030,6 +126224,15 @@ class ModelManager extends EventEmitter {
126030
126224
  this.lastEngineError = err;
126031
126225
  this.emit("engineError", err);
126032
126226
  }
126227
+ requireCustomBaseURL() {
126228
+ const baseURL = this.customBaseURL;
126229
+ if (!baseURL) {
126230
+ throw new ConfigurationInvalidError({
126231
+ message: "Custom engine requires a base URL"
126232
+ });
126233
+ }
126234
+ return baseURL;
126235
+ }
126033
126236
  async releaseDownloadLock() {
126034
126237
  const handle = this.downloadLockHandle;
126035
126238
  if (!handle)
@@ -126096,6 +126299,8 @@ class ModelManager extends EventEmitter {
126096
126299
  async startEngineProcess() {
126097
126300
  const targetDir = join(this.modelsDirectory, this.uniqueName);
126098
126301
  switch (this.engine) {
126302
+ case "custom":
126303
+ return null;
126099
126304
  case "exllamav3":
126100
126305
  return startExllamav3.call(this, {
126101
126306
  enginePort: this.enginePort,
@@ -126407,8 +126612,9 @@ function isEngineUsageChunk(value) {
126407
126612
  }
126408
126613
  return true;
126409
126614
  }
126410
- function monitorEngineResponseStream({ agentEngineType, body, contextLength, engineConfig, engineType, logger, onComplete, requestBodyBytes, requestPath, requestStartedAt }) {
126615
+ function monitorEngineResponseStream({ agentEngineType, body, contextLength, engineConfig, engineType, logger, onComplete, requestBodyBytes, requestPath, requestStartedAt, responseModelName }) {
126411
126616
  const startedAt = requestStartedAt ?? Date.now();
126617
+ const clientModelName = responseModelName ?? null;
126412
126618
  const passThrough = new PassThrough();
126413
126619
  passThrough.on("error", (error) => {
126414
126620
  logger.error("Engine response stream error", {
@@ -126420,53 +126626,61 @@ function monitorEngineResponseStream({ agentEngineType, body, contextLength, eng
126420
126626
  let firstChunkAt = null;
126421
126627
  let usage = null;
126422
126628
  let buffer = "";
126629
+ let pendingFragment = "";
126423
126630
  let completed = false;
126424
- function modifyChunkWithUsage(chunk) {
126425
- const text = chunk.toString("utf8");
126426
- const lines = text.split("\n");
126427
- const modifiedLines = [];
126428
- for (const rawLine of lines) {
126429
- const line = rawLine.trim();
126430
- if (!line.startsWith("data:")) {
126431
- modifiedLines.push(rawLine);
126432
- continue;
126631
+ function rewriteDataLine(rawLine) {
126632
+ const line = rawLine.trim();
126633
+ if (!line.startsWith("data:")) {
126634
+ return rawLine;
126635
+ }
126636
+ const payload = line.slice(5).trim();
126637
+ if (!payload || payload === "[DONE]") {
126638
+ return rawLine;
126639
+ }
126640
+ try {
126641
+ const parsed = JSON.parse(payload);
126642
+ let modified = false;
126643
+ if (coerceToolCallArguments(parsed)) {
126644
+ modified = true;
126433
126645
  }
126434
- const payload = line.slice(5).trim();
126435
- if (!payload || payload === "[DONE]") {
126436
- modifiedLines.push(rawLine);
126437
- continue;
126646
+ if (clientModelName !== null &&
126647
+ typeof parsed.model === "string" &&
126648
+ parsed.model !== clientModelName) {
126649
+ parsed.model = clientModelName;
126650
+ modified = true;
126438
126651
  }
126439
- try {
126440
- const parsed = JSON.parse(payload);
126441
- let modified = false;
126442
- if (coerceToolCallArguments(parsed)) {
126652
+ if (parsed.usage) {
126653
+ const usageChunk = parsed.usage;
126654
+ const effectiveContext = getEffectiveContextLength({
126655
+ contextLength,
126656
+ engineConfig,
126657
+ engineType
126658
+ });
126659
+ if (usageChunk.context_usage === undefined &&
126660
+ usageChunk.prompt_tokens !== undefined &&
126661
+ effectiveContext !== null) {
126662
+ usageChunk.context_usage = usageChunk.prompt_tokens / effectiveContext;
126443
126663
  modified = true;
126444
126664
  }
126445
- if (parsed.usage) {
126446
- const usageChunk = parsed.usage;
126447
- const effectiveContext = getEffectiveContextLength({
126448
- contextLength,
126449
- engineConfig,
126450
- engineType
126451
- });
126452
- if (usageChunk.context_usage === undefined &&
126453
- usageChunk.prompt_tokens !== undefined &&
126454
- effectiveContext !== null) {
126455
- usageChunk.context_usage = usageChunk.prompt_tokens / effectiveContext;
126456
- modified = true;
126457
- }
126458
- }
126459
- if (modified) {
126460
- modifiedLines.push("data: " + JSON.stringify(parsed));
126461
- continue;
126462
- }
126463
126665
  }
126464
- catch (_error) {
126465
- // Ignore malformed chunks
126666
+ if (modified) {
126667
+ return "data: " + JSON.stringify(parsed);
126466
126668
  }
126467
- modifiedLines.push(rawLine);
126468
126669
  }
126469
- return Buffer.from(modifiedLines.join("\n"), "utf8");
126670
+ catch (_error) {
126671
+ // Ignore malformed chunks
126672
+ }
126673
+ return rawLine;
126674
+ }
126675
+ // SSE events can split across transport chunks: hold back the trailing
126676
+ // (newline-less) fragment and only rewrite complete data lines, so a
126677
+ // partial JSON event is never forwarded with its upstream model name.
126678
+ function modifyChunkWithUsage(chunk, flush = false) {
126679
+ const combined = pendingFragment + chunk.toString("utf8");
126680
+ const lines = combined.split("\n");
126681
+ pendingFragment = flush ? "" : (lines.pop() ?? "");
126682
+ const modifiedLines = lines.map(rewriteDataLine);
126683
+ return Buffer.from(modifiedLines.length > 0 ? modifiedLines.join("\n") + (flush ? "" : "\n") : "", "utf8");
126470
126684
  }
126471
126685
  function parseUsageFromBuffer() {
126472
126686
  const lines = buffer.split("\n");
@@ -126562,6 +126776,9 @@ function monitorEngineResponseStream({ agentEngineType, body, contextLength, eng
126562
126776
  if (buffer.length > 0) {
126563
126777
  parseUsageFromBuffer();
126564
126778
  }
126779
+ if (pendingFragment.length > 0) {
126780
+ passThrough.write(modifyChunkWithUsage(Buffer.from("", "utf8"), true));
126781
+ }
126565
126782
  logEngineMetrics({
126566
126783
  agentEngineType,
126567
126784
  level: "info",
@@ -126604,9 +126821,11 @@ function monitorEngineResponseStream({ agentEngineType, body, contextLength, eng
126604
126821
  stream: passThrough
126605
126822
  };
126606
126823
  }
126607
- function monitorEngineResponseSingle({ agentEngineType, body, contextLength, engineConfig, engineType, logger, onComplete, requestBodyBytes, requestPath, requestStartedAt }) {
126824
+ function monitorEngineResponseSingle({ agentEngineType, body, contextLength, engineConfig, engineType, logger, onComplete, requestBodyBytes, requestPath, requestStartedAt, responseModelName }) {
126608
126825
  const maxUsageCaptureBytes = 1024 * 1024;
126609
126826
  const startedAt = requestStartedAt ?? Date.now();
126827
+ const clientModelName = responseModelName ?? null;
126828
+ const rewriteBuffer = clientModelName !== null ? [] : null;
126610
126829
  const passThrough = new PassThrough();
126611
126830
  passThrough.on("error", (error) => {
126612
126831
  logger.error("Engine response stream error", {
@@ -126662,7 +126881,12 @@ function monitorEngineResponseSingle({ agentEngineType, body, contextLength, eng
126662
126881
  usageChunks.length = 0;
126663
126882
  }
126664
126883
  }
126665
- passThrough.write(chunkBuffer);
126884
+ if (rewriteBuffer) {
126885
+ rewriteBuffer.push(chunkBuffer);
126886
+ }
126887
+ else {
126888
+ passThrough.write(chunkBuffer);
126889
+ }
126666
126890
  });
126667
126891
  body.once("error", err => {
126668
126892
  logEngineMetrics({
@@ -126722,6 +126946,24 @@ function monitorEngineResponseSingle({ agentEngineType, body, contextLength, eng
126722
126946
  responseBytes,
126723
126947
  usage
126724
126948
  });
126949
+ if (rewriteBuffer) {
126950
+ const original = Buffer.concat(rewriteBuffer);
126951
+ let output = original;
126952
+ try {
126953
+ const parsed = JSON.parse(original.toString("utf8"));
126954
+ if (parsed !== null &&
126955
+ typeof parsed === "object" &&
126956
+ typeof parsed.model === "string" &&
126957
+ parsed.model !== clientModelName) {
126958
+ parsed.model = clientModelName;
126959
+ output = Buffer.from(JSON.stringify(parsed), "utf8");
126960
+ }
126961
+ }
126962
+ catch (_error) {
126963
+ // Non-JSON body: pass through untouched
126964
+ }
126965
+ passThrough.write(output);
126966
+ }
126725
126967
  finalize(null);
126726
126968
  passThrough.end();
126727
126969
  });
@@ -126858,7 +127100,7 @@ function applyChatTemplateKwargs({ body, model }) {
126858
127100
  }
126859
127101
  return payload;
126860
127102
  }
126861
- function serializeRequestBody$1(body, { model, path } = {}) {
127103
+ function serializeRequestBody$1(body, { model, path, servedModelName } = {}) {
126862
127104
  if (!isPlainObject$a(body)) {
126863
127105
  const payload = typeof body === "string" ? body : JSON.stringify(body);
126864
127106
  return {
@@ -126867,6 +127109,9 @@ function serializeRequestBody$1(body, { model, path } = {}) {
126867
127109
  };
126868
127110
  }
126869
127111
  let requestPayload = { ...body };
127112
+ if (servedModelName) {
127113
+ requestPayload.model = servedModelName;
127114
+ }
126870
127115
  if (path === "/v1/chat/completions" && model) {
126871
127116
  requestPayload = applyChatTemplateKwargs({ body: requestPayload, model });
126872
127117
  }
@@ -126923,8 +127168,15 @@ async function proxyEmbeddingsRoute({ body, conduitConfiguration, endpointId, lo
126923
127168
  }
126924
127169
  const engineType = conduitConfiguration.engineConfig?.type ?? null;
126925
127170
  const engineConfig = conduitConfiguration.engineConfig ?? null;
127171
+ const servedModelName = modelManager.resolvedServedModelName;
127172
+ const clientModelName = isPlainObject$a(body) && typeof body.model === "string" ? body.model : null;
126926
127173
  const serializedBody = isPlainObject$a(body)
126927
- ? JSON.stringify(body)
127174
+ ? JSON.stringify(servedModelName
127175
+ ? {
127176
+ ...body,
127177
+ model: servedModelName
127178
+ }
127179
+ : body)
126928
127180
  : typeof body === "string"
126929
127181
  ? body
126930
127182
  : JSON.stringify(body);
@@ -127042,7 +127294,8 @@ async function proxyEmbeddingsRoute({ body, conduitConfiguration, endpointId, lo
127042
127294
  onComplete: onMonitoringComplete,
127043
127295
  requestBodyBytes,
127044
127296
  requestPath: "/v1/embeddings",
127045
- requestStartedAt
127297
+ requestStartedAt,
127298
+ responseModelName: servedModelName ? clientModelName : null
127046
127299
  });
127047
127300
  return {
127048
127301
  body: monitoredResponse.stream,
@@ -127067,8 +127320,10 @@ async function proxyOpenAIStreamingRoute({ body, conduitConfiguration, endpointI
127067
127320
  }
127068
127321
  const engineType = conduitConfiguration.engineConfig?.type ?? null;
127069
127322
  const engineConfig = conduitConfiguration.engineConfig ?? null;
127323
+ const servedModelName = modelManager.resolvedServedModelName;
127324
+ const clientModelName = isPlainObject$a(body) && typeof body.model === "string" ? body.model : null;
127070
127325
  const effectiveBody = modelManager.model.multimodalEnabled ? body : stripImagesFromBody(body);
127071
- const { bytes: requestBodyBytes, payload: serializedBody } = serializeRequestBody$1(effectiveBody, { model: modelManager.model, path });
127326
+ const { bytes: requestBodyBytes, payload: serializedBody } = serializeRequestBody$1(effectiveBody, { model: modelManager.model, path, servedModelName });
127072
127327
  const requestStartedAt = Date.now();
127073
127328
  const requestBody = JSON.parse(serializedBody);
127074
127329
  const streamRequested = requestBody.stream === true;
@@ -127208,7 +127463,8 @@ async function proxyOpenAIStreamingRoute({ body, conduitConfiguration, endpointI
127208
127463
  onComplete: onMonitoringComplete,
127209
127464
  requestBodyBytes,
127210
127465
  requestPath: path,
127211
- requestStartedAt
127466
+ requestStartedAt,
127467
+ responseModelName: servedModelName ? clientModelName : null
127212
127468
  })
127213
127469
  : monitorEngineResponseSingle({
127214
127470
  agentEngineType: engineType ?? "unknown",
@@ -127220,7 +127476,8 @@ async function proxyOpenAIStreamingRoute({ body, conduitConfiguration, endpointI
127220
127476
  onComplete: onMonitoringComplete,
127221
127477
  requestBodyBytes,
127222
127478
  requestPath: path,
127223
- requestStartedAt
127479
+ requestStartedAt,
127480
+ responseModelName: servedModelName ? clientModelName : null
127224
127481
  });
127225
127482
  return {
127226
127483
  body: monitoredResponse.stream,
@@ -138514,13 +138771,16 @@ async function detectDockerVersion() {
138514
138771
  * Flattens flat CLI extra-arg tokens into [arg, value] pairs, sorted by ARG NAME (ascending, ties by
138515
138772
  * value). `--flag=value` pairs split on the first `=`; a bare `--flag` consumes the following token
138516
138773
  * as its value when that token does not start with "-" (classic CLI convention); anything else
138517
- * (flags, non-strings) is dropped.
138774
+ * (flags, non-strings) is dropped. Secret-like option values are masked before pairing so they
138775
+ * never reach execution reports.
138518
138776
  */
138519
138777
  function pairExtraArgs(tokens) {
138520
138778
  if (!Array.isArray(tokens)) {
138521
138779
  return [];
138522
138780
  }
138523
- const list = tokens;
138781
+ // Non-string tokens become empty strings: they keep their position as a
138782
+ // non-consumable barrier while allowing secret masking over string tokens.
138783
+ const list = redactSecretArgs(tokens.map(token => (typeof token === "string" ? token : "")));
138524
138784
  const pairs = [];
138525
138785
  let index = 0;
138526
138786
  while (index < list.length) {
@@ -138656,9 +138916,9 @@ async function createApplication({ abortController, apiClient, configuration, lo
138656
138916
  }
138657
138917
  const reporter = new EngineExecutionReporter({
138658
138918
  buildContext: () => {
138659
- const engineType = (conduitConfiguration.engineConfig?.type ??
138660
- "llama.cpp");
138919
+ const engineType = conduitConfiguration.engineConfig?.type ?? "llama.cpp";
138661
138920
  const versions = {
138921
+ custom: null,
138662
138922
  exllamav3: machine?.exllamav3Version ?? null,
138663
138923
  "llama.cpp": machine?.llamaCppVersion ?? null,
138664
138924
  "mlx-lm": machine?.mlxlmVersion ?? null,
@@ -139145,7 +139405,11 @@ function createModelManagerFromConfig(conduitConfiguration, configuration, logge
139145
139405
  return new ModelManager({
139146
139406
  contextLength: conduitConfiguration.contextLength ?? null,
139147
139407
  engineConfig: engineConfig
139148
- ? { extraArgs: engineConfig.extraArgs, type: engineConfig.type }
139408
+ ? {
139409
+ baseUrl: engineConfig.baseUrl ?? null,
139410
+ extraArgs: engineConfig.extraArgs,
139411
+ type: engineConfig.type
139412
+ }
139149
139413
  : null,
139150
139414
  enginePort: configuration.enginePort,
139151
139415
  engineType: engineConfig?.type ?? "llama.cpp",
@@ -139156,7 +139420,11 @@ function createModelManagerFromConfig(conduitConfiguration, configuration, logge
139156
139420
  }
139157
139421
  function getConduitModelFileName(configuration) {
139158
139422
  const { source } = configuration.targetModel;
139159
- return source.type === "huggingface" ? source.slug : source.irid;
139423
+ if (source.type === "huggingface")
139424
+ return source.slug;
139425
+ if (source.type === "storage")
139426
+ return source.irid;
139427
+ return configuration.targetModel.id;
139160
139428
  }
139161
139429
  function getConduitModelName(configuration) {
139162
139430
  return configuration.targetModel.id;