@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.sea.cjs CHANGED
@@ -19900,6 +19900,7 @@ object$5({
19900
19900
  });
19901
19901
 
19902
19902
  const LLMEngineSchema = _enum$1([
19903
+ "custom",
19903
19904
  "exllamav3",
19904
19905
  "llama.cpp",
19905
19906
  "mlx-lm",
@@ -19908,8 +19909,25 @@ const LLMEngineSchema = _enum$1([
19908
19909
  "vllm"
19909
19910
  ]);
19910
19911
  const EngineConfigSchema = object$5({
19912
+ baseUrl: string$2().url().nullable().default(null),
19911
19913
  extraArgs: array$1(string$2()),
19912
19914
  type: LLMEngineSchema
19915
+ })
19916
+ .superRefine((config, ctx) => {
19917
+ if (config.type === "custom" && config.baseUrl === null) {
19918
+ ctx.addIssue({
19919
+ code: "custom",
19920
+ message: "Engine type 'custom' requires a base URL",
19921
+ path: ["baseUrl"]
19922
+ });
19923
+ }
19924
+ if (config.type !== "custom" && config.baseUrl !== null) {
19925
+ ctx.addIssue({
19926
+ code: "custom",
19927
+ message: "Base URL is only valid for engine type 'custom'",
19928
+ path: ["baseUrl"]
19929
+ });
19930
+ }
19913
19931
  });
19914
19932
  const LLMModelFormatSchema = _enum$1([
19915
19933
  // VLLM / SGLang / TensorRT-LLM
@@ -19968,14 +19986,18 @@ const LLMModelSchema = object$5({
19968
19986
  id: string$2().min(1),
19969
19987
  multimodalEnabled: boolean$1(),
19970
19988
  source: discriminatedUnion("type", [
19989
+ // Custom engines: no local model record, serving is external
19971
19990
  object$5({
19972
- irid: IRIDSchema,
19973
- type: literal("storage")
19991
+ type: literal("external")
19974
19992
  }),
19975
19993
  object$5({
19976
19994
  modelSecret: string$2().min(1).nullable(),
19977
19995
  slug: string$2().min(1),
19978
19996
  type: literal("huggingface")
19997
+ }),
19998
+ object$5({
19999
+ irid: IRIDSchema,
20000
+ type: literal("storage")
19979
20001
  })
19980
20002
  ]),
19981
20003
  taskType: LLMModelTaskTypeSchema,
@@ -21119,7 +21141,8 @@ const CreateModelResponseSchema = object$5({
21119
21141
  const CreateSourceBodySchema = object$5({
21120
21142
  contextLength: number$1().int().positive().max(1048576).optional(),
21121
21143
  engineId: ULIDSchema,
21122
- modelID: ULIDSchema,
21144
+ // Optional for custom engines, which serve externally managed models
21145
+ modelID: ULIDSchema.nullable().optional(),
21123
21146
  name: ResourceNameSchema,
21124
21147
  quantizationLabel: string$2().min(1).max(128).optional()
21125
21148
  });
@@ -21168,7 +21191,7 @@ const SourceDetailResponseSchema = object$5({
21168
21191
  const UpdateSourceBodySchema = object$5({
21169
21192
  contextLength: number$1().int().positive().nullable().optional(),
21170
21193
  engineId: ULIDSchema.nullable().optional(),
21171
- modelID: ULIDSchema.optional(),
21194
+ modelID: ULIDSchema.nullable().optional(),
21172
21195
  name: ResourceNameSchema.optional(),
21173
21196
  quantizationLabel: string$2().min(1).max(128).nullable().optional()
21174
21197
  });
@@ -21292,6 +21315,7 @@ const CreateEndpointResponseSchema = object$5({
21292
21315
  id: ULIDSchema
21293
21316
  });
21294
21317
  const EngineOutputSchema = object$5({
21318
+ baseUrl: string$2().nullable(),
21295
21319
  created: string$2(),
21296
21320
  extraArgs: array$1(string$2()),
21297
21321
  id: ULIDSchema,
@@ -21300,11 +21324,29 @@ const EngineOutputSchema = object$5({
21300
21324
  updated: string$2()
21301
21325
  });
21302
21326
  const CreateEngineBodySchema = object$5({
21327
+ baseUrl: string$2().url().nullable().optional(),
21303
21328
  extraArgs: array$1(string$2()).optional(),
21304
21329
  name: ResourceNameSchema,
21305
21330
  type: LLMEngineSchema
21331
+ })
21332
+ .superRefine((body, ctx) => {
21333
+ if (body.type === "custom" && !body.baseUrl) {
21334
+ ctx.addIssue({
21335
+ code: "custom",
21336
+ message: "Engine type 'custom' requires a base URL",
21337
+ path: ["baseUrl"]
21338
+ });
21339
+ }
21340
+ if (body.type !== "custom" && body.baseUrl) {
21341
+ ctx.addIssue({
21342
+ code: "custom",
21343
+ message: "Base URL is only valid for engine type 'custom'",
21344
+ path: ["baseUrl"]
21345
+ });
21346
+ }
21306
21347
  });
21307
21348
  const UpdateEngineBodySchema = object$5({
21349
+ baseUrl: string$2().url().nullable().optional(),
21308
21350
  extraArgs: array$1(string$2()).optional(),
21309
21351
  name: ResourceNameSchema.optional(),
21310
21352
  type: LLMEngineSchema.optional()
@@ -22110,6 +22152,11 @@ const RecommendedModelSchema = object$5({
22110
22152
  const recommendedModels = RecommendedModelSchema.array().parse(modelsData);
22111
22153
 
22112
22154
  const ENGINE_API_COMPATIBILITY = {
22155
+ custom: {
22156
+ nativeAnthropicMessages: false,
22157
+ supportsEmbeddings: true,
22158
+ supportsVision: true
22159
+ },
22113
22160
  exllamav3: {
22114
22161
  nativeAnthropicMessages: false,
22115
22162
  supportsEmbeddings: false,
@@ -111759,6 +111806,27 @@ function registerEndpointCommands({ program }) {
111759
111806
  }
111760
111807
 
111761
111808
  const ENGINE_TYPES = LLMEngineSchema.options;
111809
+ function isValidURL(value) {
111810
+ try {
111811
+ const url = new URL(value);
111812
+ return url.protocol === "http:" || url.protocol === "https:";
111813
+ }
111814
+ catch (_error) {
111815
+ return false;
111816
+ }
111817
+ }
111818
+ function validateEngineBaseURL({ baseUrl, type }) {
111819
+ if (type === "custom" && !baseUrl) {
111820
+ throw new Error("Engine type 'custom' requires --base-url");
111821
+ }
111822
+ if (baseUrl !== undefined && type !== "custom") {
111823
+ throw new Error("--base-url is only valid for engine type 'custom'");
111824
+ }
111825
+ if (baseUrl !== undefined && baseUrl !== "" && !isValidURL(baseUrl)) {
111826
+ throw new Error(`Invalid --base-url value: ${baseUrl}`);
111827
+ }
111828
+ return baseUrl === "" ? null : (baseUrl ?? null);
111829
+ }
111762
111830
  function buildEngineCreateBody(options) {
111763
111831
  if (!options.name) {
111764
111832
  throw new Error("--name is required");
@@ -111769,7 +111837,12 @@ function buildEngineCreateBody(options) {
111769
111837
  if (!ENGINE_TYPES.includes(options.type)) {
111770
111838
  throw new Error(`Invalid engine type: ${options.type} (expected one of: ${ENGINE_TYPES.join(", ")})`);
111771
111839
  }
111840
+ const baseUrl = validateEngineBaseURL({
111841
+ baseUrl: options.baseUrl,
111842
+ type: options.type
111843
+ });
111772
111844
  return {
111845
+ baseUrl,
111773
111846
  extraArgs: options.arg ?? [],
111774
111847
  name: options.name,
111775
111848
  type: options.type
@@ -111787,6 +111860,24 @@ function buildEngineUpdateBody(options) {
111787
111860
  }
111788
111861
  if (options.arg !== undefined)
111789
111862
  body.extraArgs = options.arg;
111863
+ if (options.baseUrl !== undefined) {
111864
+ const targetType = body.type;
111865
+ if (targetType !== undefined) {
111866
+ body.baseUrl = validateEngineBaseURL({
111867
+ baseUrl: options.baseUrl,
111868
+ type: targetType
111869
+ });
111870
+ }
111871
+ else if (options.baseUrl === "") {
111872
+ body.baseUrl = null;
111873
+ }
111874
+ else if (!isValidURL(options.baseUrl)) {
111875
+ throw new Error(`Invalid --base-url value: ${options.baseUrl}`);
111876
+ }
111877
+ else {
111878
+ body.baseUrl = options.baseUrl;
111879
+ }
111880
+ }
111790
111881
  return body;
111791
111882
  }
111792
111883
 
@@ -111800,10 +111891,11 @@ function registerEngineCommands({ program }) {
111800
111891
  .description("Create or update an inference engine resource")
111801
111892
  .option("--api-url <url>", "API base URL (required, no environment variable fallback)")
111802
111893
  .option("--arg <flag>", 'Raw engine CLI flag, repeatable (eg --arg "--flash-attn on")', collect, [])
111894
+ .option("--base-url <url>", "Base URL of an external OpenAI-compatible server (engine type 'custom' only)")
111803
111895
  .option("--id <ulid>", "Target an existing engine by ID (requires --update)")
111804
111896
  .option("--key <value>", "API key (required, no environment variable fallback)")
111805
111897
  .option("--name <name>", "Engine name (matched by --update)")
111806
- .option("--type <type>", "Engine type: llama.cpp|vllm|sglang|tensorrt-llm|mlx-lm|exllamav3")
111898
+ .option("--type <type>", "Engine type: llama.cpp|vllm|sglang|tensorrt-llm|mlx-lm|exllamav3|custom")
111807
111899
  .option("--update", "Update an existing engine matched by name (or --id) instead of erroring")
111808
111900
  .action(async (options) => {
111809
111901
  const { apiURL, apiKey } = resolveManagementConnection(options);
@@ -117803,6 +117895,9 @@ async function getChatTemplateEngineArgs({ engine, model, targetDirectory }) {
117803
117895
  return [];
117804
117896
  const flag = FLAG_BASED_ENGINE_ARGS[engine];
117805
117897
  if (!flag) {
117898
+ if (engine === "custom") {
117899
+ console.warn("[chatTemplate] Custom engines manage their own serving; ignoring chat template override");
117900
+ }
117806
117901
  if (engine === "tensorrt-llm") {
117807
117902
  console.warn("[chatTemplate] TensorRT-LLM does not support chat template overrides; ignoring");
117808
117903
  }
@@ -124700,7 +124795,7 @@ function matchesQuantizationVariant({ filePath, variant }) {
124700
124795
  return segments.slice(0, -1).some(segment => matcher.test(segment));
124701
124796
  }
124702
124797
  async function findQuantizedModelTarget({ model, path }) {
124703
- if (model.source.type === "storage") {
124798
+ if (model.source.type !== "huggingface") {
124704
124799
  throw new Error("Model storage not supported yet");
124705
124800
  }
124706
124801
  if (model.format !== "gguf") {
@@ -125615,7 +125710,11 @@ function sanitizeSegment(value) {
125615
125710
  .replace(new RegExp(`${SEPARATOR}{2,}`, "g"), SEPARATOR);
125616
125711
  }
125617
125712
  function createModelStorageKey(model) {
125618
- const identifier = model.source.type === "huggingface" ? model.source.slug : model.source.irid;
125713
+ const identifier = model.source.type === "huggingface"
125714
+ ? model.source.slug
125715
+ : model.source.type === "storage"
125716
+ ? model.source.irid
125717
+ : model.id;
125619
125718
  return `${model.source.type}${SEPARATOR}${sanitizeSegment(identifier)}`;
125620
125719
  }
125621
125720
 
@@ -125691,6 +125790,7 @@ class ModelManager extends EventEmitter {
125691
125790
  uniqueName;
125692
125791
  contextLength;
125693
125792
  logger;
125793
+ discoveredModelNames = [];
125694
125794
  engineProcess = null;
125695
125795
  healthPollInterval = null;
125696
125796
  lastEngineError = null;
@@ -125723,6 +125823,7 @@ class ModelManager extends EventEmitter {
125723
125823
  }
125724
125824
  async fetchOpenAI(path, opts) {
125725
125825
  switch (this.engine) {
125826
+ case "custom":
125726
125827
  case "exllamav3":
125727
125828
  case "llama.cpp":
125728
125829
  case "mlx-lm":
@@ -125730,6 +125831,9 @@ class ModelManager extends EventEmitter {
125730
125831
  case "tensorrt-llm":
125731
125832
  case "vllm": {
125732
125833
  this.logger.debug(`Fetching from engine: ${path}`);
125834
+ const baseURL = this.engine === "custom"
125835
+ ? this.requireCustomBaseURL()
125836
+ : `http://localhost:${this.enginePort}`;
125733
125837
  const callerSignal = opts?.signal;
125734
125838
  const controller = new AbortController();
125735
125839
  const timeout = setTimeout(() => {
@@ -125740,7 +125844,7 @@ class ModelManager extends EventEmitter {
125740
125844
  : controller.signal;
125741
125845
  try {
125742
125846
  const fetchStartedAt = Date.now();
125743
- const response = await undiciExports.fetch(joinURL(`http://localhost:${this.enginePort}`, path), {
125847
+ const response = await undiciExports.fetch(joinURL(baseURL, path), {
125744
125848
  ...opts,
125745
125849
  dispatcher: ENGINE_AGENT,
125746
125850
  headers: {
@@ -125775,6 +125879,11 @@ class ModelManager extends EventEmitter {
125775
125879
  modelID: this.model.id
125776
125880
  });
125777
125881
  switch (this.engine) {
125882
+ case "custom":
125883
+ if (this.model.chatTemplate) {
125884
+ this.logger.warn("Chat template overrides are ignored for custom engines: the remote server manages its own serving");
125885
+ }
125886
+ break;
125778
125887
  case "exllamav3":
125779
125888
  case "llama.cpp":
125780
125889
  case "mlx-lm":
@@ -125830,7 +125939,9 @@ class ModelManager extends EventEmitter {
125830
125939
  });
125831
125940
  try {
125832
125941
  this.engineProcess = await this.startEngineProcess();
125833
- this.bindEngineProcessEvents(this.engineProcess);
125942
+ if (this.engineProcess) {
125943
+ this.bindEngineProcessEvents(this.engineProcess);
125944
+ }
125834
125945
  this.logger.info("Started LLM engine", {
125835
125946
  agentEngineType: this.engine
125836
125947
  });
@@ -125849,7 +125960,7 @@ class ModelManager extends EventEmitter {
125849
125960
  if (!alreadyEmitted) {
125850
125961
  this.emit("engineError", err);
125851
125962
  }
125852
- if (this.engineProcess) {
125963
+ if (this.engineProcess || this.engine === "custom") {
125853
125964
  this.startHealthPoll();
125854
125965
  }
125855
125966
  throw err;
@@ -125857,6 +125968,9 @@ class ModelManager extends EventEmitter {
125857
125968
  this.lifecycleState = "running";
125858
125969
  this.reachedRunningState = true;
125859
125970
  this.emit("engineReady");
125971
+ if (this.engine === "custom") {
125972
+ this.startHealthPoll();
125973
+ }
125860
125974
  }
125861
125975
  async stop() {
125862
125976
  if (this.lifecycleState === "stopping") {
@@ -125877,6 +125991,8 @@ class ModelManager extends EventEmitter {
125877
125991
  this.clearHealthPoll();
125878
125992
  const processManager = this.engineProcess;
125879
125993
  if (!processManager) {
125994
+ this.stopRequested = true;
125995
+ this.reachedRunningState = false;
125880
125996
  this.lifecycleState = "stopped";
125881
125997
  return;
125882
125998
  }
@@ -125902,11 +126018,25 @@ class ModelManager extends EventEmitter {
125902
126018
  get state() {
125903
126019
  return this.lifecycleState;
125904
126020
  }
126021
+ get resolvedServedModelName() {
126022
+ if (this.engine !== "custom")
126023
+ return null;
126024
+ return this.discoveredModelNames[0] ?? null;
126025
+ }
125905
126026
  get wasRunning() {
125906
126027
  return this.reachedRunningState;
125907
126028
  }
126029
+ get customBaseURL() {
126030
+ if (this.engine !== "custom")
126031
+ return null;
126032
+ const baseUrl = this.engineConfig?.baseUrl;
126033
+ return typeof baseUrl === "string" && baseUrl.length > 0 ? baseUrl : null;
126034
+ }
125908
126035
  async checkEngineReadiness() {
125909
126036
  switch (this.engine) {
126037
+ case "custom": {
126038
+ return this.checkCustomReadiness();
126039
+ }
125910
126040
  case "llama.cpp": {
125911
126041
  return this.checkLlamacppReadiness();
125912
126042
  }
@@ -125923,6 +126053,51 @@ class ModelManager extends EventEmitter {
125923
126053
  return "ready";
125924
126054
  }
125925
126055
  }
126056
+ async checkCustomReadiness() {
126057
+ const baseURL = this.customBaseURL;
126058
+ if (!baseURL) {
126059
+ return "unreachable";
126060
+ }
126061
+ try {
126062
+ const response = await undiciExports.fetch(joinURL(baseURL, "/v1/models"), {
126063
+ method: "GET",
126064
+ signal: AbortSignal.timeout(5000)
126065
+ });
126066
+ if (response.status === 503) {
126067
+ return "loading";
126068
+ }
126069
+ if (!response.ok) {
126070
+ return "unreachable";
126071
+ }
126072
+ const payload = (await response.json());
126073
+ const models = Array.isArray(payload.data) ? payload.data : [];
126074
+ const modelIDs = models
126075
+ .map(model => {
126076
+ if (model === null || typeof model !== "object")
126077
+ return null;
126078
+ const id = model.id;
126079
+ return typeof id === "string" ? id : null;
126080
+ })
126081
+ .filter((id) => id !== null);
126082
+ if (modelIDs.length === 0) {
126083
+ this.logger.warn("Custom engine endpoint exposed no models via /v1/models", {
126084
+ engineBaseURL: baseURL
126085
+ });
126086
+ return "loading";
126087
+ }
126088
+ if (modelIDs.join("\n") !== this.discoveredModelNames.join("\n")) {
126089
+ this.logger.info("Discovered models on custom engine endpoint", {
126090
+ engineBaseURL: baseURL,
126091
+ models: modelIDs
126092
+ });
126093
+ this.discoveredModelNames = modelIDs;
126094
+ }
126095
+ return "ready";
126096
+ }
126097
+ catch (_error) {
126098
+ return "unreachable";
126099
+ }
126100
+ }
125926
126101
  async checkGenericHealthReadiness() {
125927
126102
  try {
125928
126103
  const response = await undiciExports.fetch(joinURL(`http://localhost:${this.enginePort}`, "/health"), {
@@ -125978,18 +126153,24 @@ class ModelManager extends EventEmitter {
125978
126153
  }
125979
126154
  }
125980
126155
  async waitForEngineReady() {
125981
- const maxWaitMs = 15 * 60 * 1000;
126156
+ const maxWaitMs = Number.parseInt(process.env.ENGINE_STARTUP_TIMEOUT_MS ?? "", 10) || 15 * 60 * 1000;
125982
126157
  const pollIntervalMs = 2000;
125983
126158
  const start = Date.now();
125984
126159
  while (Date.now() - start < maxWaitMs) {
125985
- if (this.lifecycleState === "stopping") {
126160
+ if (this.lifecycleState === "stopping" || this.stopRequested) {
125986
126161
  throw new Error("LLM engine startup interrupted by stop request");
125987
126162
  }
125988
- if (!this.engineProcess) {
126163
+ if (!this.engineProcess && this.engine !== "custom") {
125989
126164
  throw new Error("LLM engine process exited before readiness checks completed");
125990
126165
  }
125991
126166
  const readiness = await this.checkEngineReadiness();
125992
126167
  if (readiness === "ready") {
126168
+ // A stop() may have landed while the readiness request was
126169
+ // in flight; re-check before declaring ready.
126170
+ const lifecycleState = this.lifecycleState;
126171
+ if (lifecycleState === "stopping" || this.stopRequested) {
126172
+ throw new Error("LLM engine startup interrupted by stop request");
126173
+ }
125993
126174
  return;
125994
126175
  }
125995
126176
  await new Promise(resolve => setTimeout(resolve, pollIntervalMs));
@@ -126007,19 +126188,32 @@ class ModelManager extends EventEmitter {
126007
126188
  }
126008
126189
  startHealthPoll() {
126009
126190
  this.clearHealthPoll();
126010
- this.logger.info("Starting background health poll for errored engine");
126191
+ this.logger.info("Starting background engine health poll", {
126192
+ agentEngineType: this.engine
126193
+ });
126011
126194
  this.healthPollInterval = setInterval(() => {
126012
- if (!this.engineProcess) {
126195
+ if (!this.engineProcess && this.engine !== "custom") {
126013
126196
  this.clearHealthPoll();
126014
126197
  return;
126015
126198
  }
126016
126199
  this.checkEngineReadiness()
126017
126200
  .then(readiness => {
126018
126201
  if (readiness === "ready") {
126019
- this.clearHealthPoll();
126020
- this.lifecycleState = "running";
126021
- this.reachedRunningState = true;
126022
- this.emit("engineReady");
126202
+ if (this.lifecycleState === "errored" ||
126203
+ this.lifecycleState === "starting") {
126204
+ this.lifecycleState = "running";
126205
+ this.reachedRunningState = true;
126206
+ this.emit("engineReady");
126207
+ }
126208
+ if (this.engine !== "custom") {
126209
+ this.clearHealthPoll();
126210
+ }
126211
+ return;
126212
+ }
126213
+ if (this.engine === "custom" &&
126214
+ readiness === "unreachable" &&
126215
+ this.lifecycleState === "running") {
126216
+ this.recordEngineError(new Error(`Custom engine endpoint unreachable: ${this.customBaseURL}`));
126023
126217
  }
126024
126218
  })
126025
126219
  .catch(() => {
@@ -126044,6 +126238,15 @@ class ModelManager extends EventEmitter {
126044
126238
  this.lastEngineError = err;
126045
126239
  this.emit("engineError", err);
126046
126240
  }
126241
+ requireCustomBaseURL() {
126242
+ const baseURL = this.customBaseURL;
126243
+ if (!baseURL) {
126244
+ throw new ConfigurationInvalidError({
126245
+ message: "Custom engine requires a base URL"
126246
+ });
126247
+ }
126248
+ return baseURL;
126249
+ }
126047
126250
  async releaseDownloadLock() {
126048
126251
  const handle = this.downloadLockHandle;
126049
126252
  if (!handle)
@@ -126110,6 +126313,8 @@ class ModelManager extends EventEmitter {
126110
126313
  async startEngineProcess() {
126111
126314
  const targetDir = path$1.join(this.modelsDirectory, this.uniqueName);
126112
126315
  switch (this.engine) {
126316
+ case "custom":
126317
+ return null;
126113
126318
  case "exllamav3":
126114
126319
  return startExllamav3.call(this, {
126115
126320
  enginePort: this.enginePort,
@@ -126421,8 +126626,9 @@ function isEngineUsageChunk(value) {
126421
126626
  }
126422
126627
  return true;
126423
126628
  }
126424
- function monitorEngineResponseStream({ agentEngineType, body, contextLength, engineConfig, engineType, logger, onComplete, requestBodyBytes, requestPath, requestStartedAt }) {
126629
+ function monitorEngineResponseStream({ agentEngineType, body, contextLength, engineConfig, engineType, logger, onComplete, requestBodyBytes, requestPath, requestStartedAt, responseModelName }) {
126425
126630
  const startedAt = requestStartedAt ?? Date.now();
126631
+ const clientModelName = responseModelName ?? null;
126426
126632
  const passThrough = new require$$0$8.PassThrough();
126427
126633
  passThrough.on("error", (error) => {
126428
126634
  logger.error("Engine response stream error", {
@@ -126434,53 +126640,61 @@ function monitorEngineResponseStream({ agentEngineType, body, contextLength, eng
126434
126640
  let firstChunkAt = null;
126435
126641
  let usage = null;
126436
126642
  let buffer = "";
126643
+ let pendingFragment = "";
126437
126644
  let completed = false;
126438
- function modifyChunkWithUsage(chunk) {
126439
- const text = chunk.toString("utf8");
126440
- const lines = text.split("\n");
126441
- const modifiedLines = [];
126442
- for (const rawLine of lines) {
126443
- const line = rawLine.trim();
126444
- if (!line.startsWith("data:")) {
126445
- modifiedLines.push(rawLine);
126446
- continue;
126645
+ function rewriteDataLine(rawLine) {
126646
+ const line = rawLine.trim();
126647
+ if (!line.startsWith("data:")) {
126648
+ return rawLine;
126649
+ }
126650
+ const payload = line.slice(5).trim();
126651
+ if (!payload || payload === "[DONE]") {
126652
+ return rawLine;
126653
+ }
126654
+ try {
126655
+ const parsed = JSON.parse(payload);
126656
+ let modified = false;
126657
+ if (coerceToolCallArguments(parsed)) {
126658
+ modified = true;
126447
126659
  }
126448
- const payload = line.slice(5).trim();
126449
- if (!payload || payload === "[DONE]") {
126450
- modifiedLines.push(rawLine);
126451
- continue;
126660
+ if (clientModelName !== null &&
126661
+ typeof parsed.model === "string" &&
126662
+ parsed.model !== clientModelName) {
126663
+ parsed.model = clientModelName;
126664
+ modified = true;
126452
126665
  }
126453
- try {
126454
- const parsed = JSON.parse(payload);
126455
- let modified = false;
126456
- if (coerceToolCallArguments(parsed)) {
126666
+ if (parsed.usage) {
126667
+ const usageChunk = parsed.usage;
126668
+ const effectiveContext = getEffectiveContextLength({
126669
+ contextLength,
126670
+ engineConfig,
126671
+ engineType
126672
+ });
126673
+ if (usageChunk.context_usage === undefined &&
126674
+ usageChunk.prompt_tokens !== undefined &&
126675
+ effectiveContext !== null) {
126676
+ usageChunk.context_usage = usageChunk.prompt_tokens / effectiveContext;
126457
126677
  modified = true;
126458
126678
  }
126459
- if (parsed.usage) {
126460
- const usageChunk = parsed.usage;
126461
- const effectiveContext = getEffectiveContextLength({
126462
- contextLength,
126463
- engineConfig,
126464
- engineType
126465
- });
126466
- if (usageChunk.context_usage === undefined &&
126467
- usageChunk.prompt_tokens !== undefined &&
126468
- effectiveContext !== null) {
126469
- usageChunk.context_usage = usageChunk.prompt_tokens / effectiveContext;
126470
- modified = true;
126471
- }
126472
- }
126473
- if (modified) {
126474
- modifiedLines.push("data: " + JSON.stringify(parsed));
126475
- continue;
126476
- }
126477
126679
  }
126478
- catch (_error) {
126479
- // Ignore malformed chunks
126680
+ if (modified) {
126681
+ return "data: " + JSON.stringify(parsed);
126480
126682
  }
126481
- modifiedLines.push(rawLine);
126482
126683
  }
126483
- return Buffer.from(modifiedLines.join("\n"), "utf8");
126684
+ catch (_error) {
126685
+ // Ignore malformed chunks
126686
+ }
126687
+ return rawLine;
126688
+ }
126689
+ // SSE events can split across transport chunks: hold back the trailing
126690
+ // (newline-less) fragment and only rewrite complete data lines, so a
126691
+ // partial JSON event is never forwarded with its upstream model name.
126692
+ function modifyChunkWithUsage(chunk, flush = false) {
126693
+ const combined = pendingFragment + chunk.toString("utf8");
126694
+ const lines = combined.split("\n");
126695
+ pendingFragment = flush ? "" : (lines.pop() ?? "");
126696
+ const modifiedLines = lines.map(rewriteDataLine);
126697
+ return Buffer.from(modifiedLines.length > 0 ? modifiedLines.join("\n") + (flush ? "" : "\n") : "", "utf8");
126484
126698
  }
126485
126699
  function parseUsageFromBuffer() {
126486
126700
  const lines = buffer.split("\n");
@@ -126576,6 +126790,9 @@ function monitorEngineResponseStream({ agentEngineType, body, contextLength, eng
126576
126790
  if (buffer.length > 0) {
126577
126791
  parseUsageFromBuffer();
126578
126792
  }
126793
+ if (pendingFragment.length > 0) {
126794
+ passThrough.write(modifyChunkWithUsage(Buffer.from("", "utf8"), true));
126795
+ }
126579
126796
  logEngineMetrics({
126580
126797
  agentEngineType,
126581
126798
  level: "info",
@@ -126618,9 +126835,11 @@ function monitorEngineResponseStream({ agentEngineType, body, contextLength, eng
126618
126835
  stream: passThrough
126619
126836
  };
126620
126837
  }
126621
- function monitorEngineResponseSingle({ agentEngineType, body, contextLength, engineConfig, engineType, logger, onComplete, requestBodyBytes, requestPath, requestStartedAt }) {
126838
+ function monitorEngineResponseSingle({ agentEngineType, body, contextLength, engineConfig, engineType, logger, onComplete, requestBodyBytes, requestPath, requestStartedAt, responseModelName }) {
126622
126839
  const maxUsageCaptureBytes = 1024 * 1024;
126623
126840
  const startedAt = requestStartedAt ?? Date.now();
126841
+ const clientModelName = responseModelName ?? null;
126842
+ const rewriteBuffer = clientModelName !== null ? [] : null;
126624
126843
  const passThrough = new require$$0$8.PassThrough();
126625
126844
  passThrough.on("error", (error) => {
126626
126845
  logger.error("Engine response stream error", {
@@ -126676,7 +126895,12 @@ function monitorEngineResponseSingle({ agentEngineType, body, contextLength, eng
126676
126895
  usageChunks.length = 0;
126677
126896
  }
126678
126897
  }
126679
- passThrough.write(chunkBuffer);
126898
+ if (rewriteBuffer) {
126899
+ rewriteBuffer.push(chunkBuffer);
126900
+ }
126901
+ else {
126902
+ passThrough.write(chunkBuffer);
126903
+ }
126680
126904
  });
126681
126905
  body.once("error", err => {
126682
126906
  logEngineMetrics({
@@ -126736,6 +126960,24 @@ function monitorEngineResponseSingle({ agentEngineType, body, contextLength, eng
126736
126960
  responseBytes,
126737
126961
  usage
126738
126962
  });
126963
+ if (rewriteBuffer) {
126964
+ const original = Buffer.concat(rewriteBuffer);
126965
+ let output = original;
126966
+ try {
126967
+ const parsed = JSON.parse(original.toString("utf8"));
126968
+ if (parsed !== null &&
126969
+ typeof parsed === "object" &&
126970
+ typeof parsed.model === "string" &&
126971
+ parsed.model !== clientModelName) {
126972
+ parsed.model = clientModelName;
126973
+ output = Buffer.from(JSON.stringify(parsed), "utf8");
126974
+ }
126975
+ }
126976
+ catch (_error) {
126977
+ // Non-JSON body: pass through untouched
126978
+ }
126979
+ passThrough.write(output);
126980
+ }
126739
126981
  finalize(null);
126740
126982
  passThrough.end();
126741
126983
  });
@@ -126872,7 +127114,7 @@ function applyChatTemplateKwargs({ body, model }) {
126872
127114
  }
126873
127115
  return payload;
126874
127116
  }
126875
- function serializeRequestBody$1(body, { model, path } = {}) {
127117
+ function serializeRequestBody$1(body, { model, path, servedModelName } = {}) {
126876
127118
  if (!isPlainObject$a(body)) {
126877
127119
  const payload = typeof body === "string" ? body : JSON.stringify(body);
126878
127120
  return {
@@ -126881,6 +127123,9 @@ function serializeRequestBody$1(body, { model, path } = {}) {
126881
127123
  };
126882
127124
  }
126883
127125
  let requestPayload = { ...body };
127126
+ if (servedModelName) {
127127
+ requestPayload.model = servedModelName;
127128
+ }
126884
127129
  if (path === "/v1/chat/completions" && model) {
126885
127130
  requestPayload = applyChatTemplateKwargs({ body: requestPayload, model });
126886
127131
  }
@@ -126937,8 +127182,15 @@ async function proxyEmbeddingsRoute({ body, conduitConfiguration, endpointId, lo
126937
127182
  }
126938
127183
  const engineType = conduitConfiguration.engineConfig?.type ?? null;
126939
127184
  const engineConfig = conduitConfiguration.engineConfig ?? null;
127185
+ const servedModelName = modelManager.resolvedServedModelName;
127186
+ const clientModelName = isPlainObject$a(body) && typeof body.model === "string" ? body.model : null;
126940
127187
  const serializedBody = isPlainObject$a(body)
126941
- ? JSON.stringify(body)
127188
+ ? JSON.stringify(servedModelName
127189
+ ? {
127190
+ ...body,
127191
+ model: servedModelName
127192
+ }
127193
+ : body)
126942
127194
  : typeof body === "string"
126943
127195
  ? body
126944
127196
  : JSON.stringify(body);
@@ -127056,7 +127308,8 @@ async function proxyEmbeddingsRoute({ body, conduitConfiguration, endpointId, lo
127056
127308
  onComplete: onMonitoringComplete,
127057
127309
  requestBodyBytes,
127058
127310
  requestPath: "/v1/embeddings",
127059
- requestStartedAt
127311
+ requestStartedAt,
127312
+ responseModelName: servedModelName ? clientModelName : null
127060
127313
  });
127061
127314
  return {
127062
127315
  body: monitoredResponse.stream,
@@ -127081,8 +127334,10 @@ async function proxyOpenAIStreamingRoute({ body, conduitConfiguration, endpointI
127081
127334
  }
127082
127335
  const engineType = conduitConfiguration.engineConfig?.type ?? null;
127083
127336
  const engineConfig = conduitConfiguration.engineConfig ?? null;
127337
+ const servedModelName = modelManager.resolvedServedModelName;
127338
+ const clientModelName = isPlainObject$a(body) && typeof body.model === "string" ? body.model : null;
127084
127339
  const effectiveBody = modelManager.model.multimodalEnabled ? body : stripImagesFromBody(body);
127085
- const { bytes: requestBodyBytes, payload: serializedBody } = serializeRequestBody$1(effectiveBody, { model: modelManager.model, path });
127340
+ const { bytes: requestBodyBytes, payload: serializedBody } = serializeRequestBody$1(effectiveBody, { model: modelManager.model, path, servedModelName });
127086
127341
  const requestStartedAt = Date.now();
127087
127342
  const requestBody = JSON.parse(serializedBody);
127088
127343
  const streamRequested = requestBody.stream === true;
@@ -127222,7 +127477,8 @@ async function proxyOpenAIStreamingRoute({ body, conduitConfiguration, endpointI
127222
127477
  onComplete: onMonitoringComplete,
127223
127478
  requestBodyBytes,
127224
127479
  requestPath: path,
127225
- requestStartedAt
127480
+ requestStartedAt,
127481
+ responseModelName: servedModelName ? clientModelName : null
127226
127482
  })
127227
127483
  : monitorEngineResponseSingle({
127228
127484
  agentEngineType: engineType ?? "unknown",
@@ -127234,7 +127490,8 @@ async function proxyOpenAIStreamingRoute({ body, conduitConfiguration, endpointI
127234
127490
  onComplete: onMonitoringComplete,
127235
127491
  requestBodyBytes,
127236
127492
  requestPath: path,
127237
- requestStartedAt
127493
+ requestStartedAt,
127494
+ responseModelName: servedModelName ? clientModelName : null
127238
127495
  });
127239
127496
  return {
127240
127497
  body: monitoredResponse.stream,
@@ -158743,13 +159000,16 @@ async function detectDockerVersion() {
158743
159000
  * Flattens flat CLI extra-arg tokens into [arg, value] pairs, sorted by ARG NAME (ascending, ties by
158744
159001
  * value). `--flag=value` pairs split on the first `=`; a bare `--flag` consumes the following token
158745
159002
  * as its value when that token does not start with "-" (classic CLI convention); anything else
158746
- * (flags, non-strings) is dropped.
159003
+ * (flags, non-strings) is dropped. Secret-like option values are masked before pairing so they
159004
+ * never reach execution reports.
158747
159005
  */
158748
159006
  function pairExtraArgs(tokens) {
158749
159007
  if (!Array.isArray(tokens)) {
158750
159008
  return [];
158751
159009
  }
158752
- const list = tokens;
159010
+ // Non-string tokens become empty strings: they keep their position as a
159011
+ // non-consumable barrier while allowing secret masking over string tokens.
159012
+ const list = redactSecretArgs(tokens.map(token => (typeof token === "string" ? token : "")));
158753
159013
  const pairs = [];
158754
159014
  let index = 0;
158755
159015
  while (index < list.length) {
@@ -158885,9 +159145,9 @@ async function createApplication({ abortController, apiClient, configuration, lo
158885
159145
  }
158886
159146
  const reporter = new EngineExecutionReporter({
158887
159147
  buildContext: () => {
158888
- const engineType = (conduitConfiguration.engineConfig?.type ??
158889
- "llama.cpp");
159148
+ const engineType = conduitConfiguration.engineConfig?.type ?? "llama.cpp";
158890
159149
  const versions = {
159150
+ custom: null,
158891
159151
  exllamav3: machine?.exllamav3Version ?? null,
158892
159152
  "llama.cpp": machine?.llamaCppVersion ?? null,
158893
159153
  "mlx-lm": machine?.mlxlmVersion ?? null,
@@ -159374,7 +159634,11 @@ function createModelManagerFromConfig(conduitConfiguration, configuration, logge
159374
159634
  return new ModelManager({
159375
159635
  contextLength: conduitConfiguration.contextLength ?? null,
159376
159636
  engineConfig: engineConfig
159377
- ? { extraArgs: engineConfig.extraArgs, type: engineConfig.type }
159637
+ ? {
159638
+ baseUrl: engineConfig.baseUrl ?? null,
159639
+ extraArgs: engineConfig.extraArgs,
159640
+ type: engineConfig.type
159641
+ }
159378
159642
  : null,
159379
159643
  enginePort: configuration.enginePort,
159380
159644
  engineType: engineConfig?.type ?? "llama.cpp",
@@ -159385,7 +159649,11 @@ function createModelManagerFromConfig(conduitConfiguration, configuration, logge
159385
159649
  }
159386
159650
  function getConduitModelFileName(configuration) {
159387
159651
  const { source } = configuration.targetModel;
159388
- return source.type === "huggingface" ? source.slug : source.irid;
159652
+ if (source.type === "huggingface")
159653
+ return source.slug;
159654
+ if (source.type === "storage")
159655
+ return source.irid;
159656
+ return configuration.targetModel.id;
159389
159657
  }
159390
159658
  function getConduitModelName(configuration) {
159391
159659
  return configuration.targetModel.id;