@infersec/conduit 1.24.2 → 1.24.3

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
@@ -6,7 +6,7 @@ const __dirname = __pathDirname(__filename);
6
6
 
7
7
  import { parseArgs } from 'node:util';
8
8
  import 'node:crypto';
9
- import { a as asError, s as startInferenceAgent } from './start-CpPE5_K5.js';
9
+ import { a as asError, s as startInferenceAgent } from './start-DiikacLf.js';
10
10
  import 'argon2';
11
11
  import 'node:child_process';
12
12
  import 'node:stream';
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@ const __filename = __fileURLToPath(import.meta.url);
5
5
  const __dirname = __pathDirname(__filename);
6
6
 
7
7
  import 'node:crypto';
8
- import { s as startInferenceAgent, a as asError } from './start-CpPE5_K5.js';
8
+ import { s as startInferenceAgent, a as asError } from './start-DiikacLf.js';
9
9
  import 'argon2';
10
10
  import 'node:child_process';
11
11
  import 'node:stream';
@@ -14917,6 +14917,12 @@ const API_SERVICE_CONDUIT_API_REFERENCE = {
14917
14917
  }
14918
14918
  };
14919
14919
 
14920
+ /**
14921
+ * Coerce non-string values to JSON strings. Some LLM backends (e.g. llama.cpp)
14922
+ * return tool_calls arguments as parsed objects instead of JSON strings, which
14923
+ * violates the OpenAI spec. This schema field normalises them on parse.
14924
+ */
14925
+ const jsonStringCoerced = preprocess(val => (typeof val === "string" ? val : JSON.stringify(val)), string$1());
14920
14926
  // ==================== CHAT COMPLETION ROLES ====================
14921
14927
  _enum([
14922
14928
  "system",
@@ -14963,13 +14969,13 @@ const ChatCompletionAssistantMessageParamSchema = object({
14963
14969
  type: literal("function"),
14964
14970
  function: object({
14965
14971
  name: string$1(),
14966
- arguments: string$1()
14972
+ arguments: jsonStringCoerced
14967
14973
  })
14968
14974
  }))
14969
14975
  .optional(),
14970
14976
  function_call: object({
14971
14977
  name: string$1(),
14972
- arguments: string$1()
14978
+ arguments: jsonStringCoerced
14973
14979
  })
14974
14980
  .optional(),
14975
14981
  refusal: string$1().nullable().optional()
@@ -15006,13 +15012,13 @@ const ChatCompletionMessageSchema = object({
15006
15012
  type: literal("function"),
15007
15013
  function: object({
15008
15014
  name: string$1(),
15009
- arguments: string$1()
15015
+ arguments: jsonStringCoerced
15010
15016
  })
15011
15017
  }))
15012
15018
  .optional(),
15013
15019
  function_call: object({
15014
15020
  name: string$1(),
15015
- arguments: string$1()
15021
+ arguments: jsonStringCoerced
15016
15022
  })
15017
15023
  .optional(),
15018
15024
  refusal: string$1().nullable()
@@ -117945,6 +117951,42 @@ async function collectMachineMetadata() {
117945
117951
  return machineMetadata;
117946
117952
  }
117947
117953
 
117954
+ /**
117955
+ * Coerce non-string tool_calls function.arguments to JSON strings.
117956
+ * Some LLM backends return arguments as parsed objects instead of
117957
+ * JSON strings, violating the OpenAI spec. This mutates in place
117958
+ * and returns true if any coercion was performed.
117959
+ */
117960
+ function coerceToolCallArguments(parsed) {
117961
+ const choices = parsed.choices;
117962
+ if (!Array.isArray(choices))
117963
+ return false;
117964
+ let modified = false;
117965
+ for (const choice of choices) {
117966
+ if (!choice || typeof choice !== "object")
117967
+ continue;
117968
+ const choiceRecord = choice;
117969
+ const msg = choiceRecord.delta ?? choiceRecord.message;
117970
+ if (!msg || typeof msg !== "object")
117971
+ continue;
117972
+ const toolCalls = msg.tool_calls;
117973
+ if (!Array.isArray(toolCalls))
117974
+ continue;
117975
+ for (const tc of toolCalls) {
117976
+ if (!tc || typeof tc !== "object")
117977
+ continue;
117978
+ const fn = tc.function;
117979
+ if (!fn || typeof fn !== "object")
117980
+ continue;
117981
+ const fnRecord = fn;
117982
+ if (fnRecord.arguments !== undefined && typeof fnRecord.arguments !== "string") {
117983
+ fnRecord.arguments = JSON.stringify(fnRecord.arguments);
117984
+ modified = true;
117985
+ }
117986
+ }
117987
+ }
117988
+ return modified;
117989
+ }
117948
117990
  function isEngineUsageChunk(value) {
117949
117991
  if (!value || typeof value !== "object") {
117950
117992
  return false;
@@ -117980,6 +118022,10 @@ function monitorEngineResponseStream({ agentEngineType, body, contextLength, eng
117980
118022
  }
117981
118023
  try {
117982
118024
  const parsed = JSON.parse(payload);
118025
+ let modified = false;
118026
+ if (coerceToolCallArguments(parsed)) {
118027
+ modified = true;
118028
+ }
117983
118029
  if (parsed.usage) {
117984
118030
  const usageChunk = parsed.usage;
117985
118031
  const effectiveContext = getEffectiveContextLength({
@@ -117991,10 +118037,13 @@ function monitorEngineResponseStream({ agentEngineType, body, contextLength, eng
117991
118037
  usageChunk.prompt_tokens !== undefined &&
117992
118038
  effectiveContext !== null) {
117993
118039
  usageChunk.context_usage = usageChunk.prompt_tokens / effectiveContext;
117994
- modifiedLines.push("data: " + JSON.stringify(parsed));
117995
- continue;
118040
+ modified = true;
117996
118041
  }
117997
118042
  }
118043
+ if (modified) {
118044
+ modifiedLines.push("data: " + JSON.stringify(parsed));
118045
+ continue;
118046
+ }
117998
118047
  }
117999
118048
  catch (_error) {
118000
118049
  // Ignore malformed chunks
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@infersec/conduit",
3
3
  "description": "End user conduit agent for connecting local LLMs to the cloud.",
4
- "version": "1.24.2",
4
+ "version": "1.24.3",
5
5
  "bin": {
6
6
  "infersec-conduit": "./dist/cli.js"
7
7
  },