nexgenr 1.0.3 → 1.1.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.
Files changed (2) hide show
  1. package/dist/main.mjs +222 -9
  2. package/package.json +1 -1
package/dist/main.mjs CHANGED
@@ -188855,6 +188855,112 @@ var init_capability$6 = __esmMin((() => {
188855
188855
  dynamically_loaded_tools: false
188856
188856
  }, UNKNOWN_CAPABILITY_MARKER$1, { value: true }));
188857
188857
  }));
188858
+ // ../../packages/agent-core-v2/src/human/llm/repair/inline-tool-call.ts
188859
+ function parseParameterValue(raw) {
188860
+ const trimmed = raw.trim();
188861
+ if (trimmed === "") return "";
188862
+ const first = trimmed[0];
188863
+ if (first === "{" || first === "[" || first === "\"" || trimmed === "true" || trimmed === "false") try {
188864
+ return JSON.parse(trimmed);
188865
+ } catch {
188866
+ return trimmed;
188867
+ }
188868
+ if (/^-?\d+(\.\d+)?$/.test(trimmed)) return Number(trimmed);
188869
+ return trimmed;
188870
+ }
188871
+ function parseBlockBody(body) {
188872
+ const trimmed = body.trim();
188873
+ if (trimmed.startsWith("{")) try {
188874
+ const decoded = JSON.parse(trimmed);
188875
+ if (typeof decoded.name === "string" && decoded.name !== "") {
188876
+ const args = decoded.arguments ?? decoded.parameters ?? {};
188877
+ return {
188878
+ name: decoded.name,
188879
+ arguments: JSON.stringify(args)
188880
+ };
188881
+ }
188882
+ } catch {
188883
+ return;
188884
+ }
188885
+ const functionMatch = FUNCTION_PATTERN.exec(trimmed);
188886
+ if (functionMatch === null) return void 0;
188887
+ const name = functionMatch[1];
188888
+ if (name === void 0 || name === "") return void 0;
188889
+ const args = {};
188890
+ for (const match of trimmed.matchAll(PARAMETER_PATTERN)) {
188891
+ const key = match[1];
188892
+ if (key === void 0 || key === "") continue;
188893
+ args[key] = parseParameterValue(match[2] ?? "");
188894
+ }
188895
+ return {
188896
+ name,
188897
+ arguments: JSON.stringify(args)
188898
+ };
188899
+ }
188900
+ function extractInlineToolCalls(content) {
188901
+ if (!content.includes("<tool_call>")) return {
188902
+ text: content,
188903
+ calls: []
188904
+ };
188905
+ const calls = [];
188906
+ let consumed = false;
188907
+ const text = content.replace(BLOCK_PATTERN, (block, body) => {
188908
+ const call = parseBlockBody(body);
188909
+ if (call === void 0) return block;
188910
+ calls.push(call);
188911
+ consumed = true;
188912
+ return "";
188913
+ });
188914
+ return consumed ? {
188915
+ text: text.replace(/\n{3,}/g, "\n\n").trim(),
188916
+ calls
188917
+ } : {
188918
+ text: content,
188919
+ calls: []
188920
+ };
188921
+ }
188922
+ function sameCall(left, call) {
188923
+ return left.name === call.name && left.arguments === call.arguments;
188924
+ }
188925
+ function repairAssistantMessage(message) {
188926
+ const recovered = [];
188927
+ const kept = [];
188928
+ for (const part of message.content) {
188929
+ if (part.type !== "text") {
188930
+ kept.push(part);
188931
+ continue;
188932
+ }
188933
+ const scan = extractInlineToolCalls(part.text);
188934
+ if (scan.calls.length === 0) {
188935
+ kept.push(part);
188936
+ continue;
188937
+ }
188938
+ recovered.push(...scan.calls);
188939
+ const rest = scan.text.trim();
188940
+ if (rest !== "") kept.push({
188941
+ ...part,
188942
+ text: rest
188943
+ });
188944
+ }
188945
+ if (recovered.length === 0) return;
188946
+ message.content.length = 0;
188947
+ message.content.push(...kept);
188948
+ for (const call of recovered) {
188949
+ if (message.toolCalls.some((existing) => sameCall(existing, call))) continue;
188950
+ message.toolCalls.push({
188951
+ type: "function",
188952
+ id: crypto.randomUUID(),
188953
+ name: call.name,
188954
+ arguments: call.arguments
188955
+ });
188956
+ }
188957
+ }
188958
+ var BLOCK_PATTERN, FUNCTION_PATTERN, PARAMETER_PATTERN;
188959
+ var init_inline_tool_call = __esmMin((() => {
188960
+ BLOCK_PATTERN = /<tool_call>([\s\S]*?)<\/tool_call>/g;
188961
+ FUNCTION_PATTERN = /<function=([^>\s]+)>/;
188962
+ PARAMETER_PATTERN = /<parameter=([^>\s]+)>([\s\S]*?)<\/parameter>/g;
188963
+ }));
188858
188964
  // ../../packages/agent-core-v2/src/human/llm/message.ts
188859
188965
  function isContentPart(part) {
188860
188966
  const t = part.type;
@@ -188984,11 +189090,14 @@ function createMessageAccumulator() {
188984
189090
  },
188985
189091
  finish() {
188986
189092
  flush();
189093
+ repairAssistantMessage(message);
188987
189094
  return message;
188988
189095
  }
188989
189096
  };
188990
189097
  }
188991
- var init_message$2 = __esmMin((() => {}));
189098
+ var init_message$2 = __esmMin((() => {
189099
+ init_inline_tool_call();
189100
+ }));
188992
189101
  // ../../packages/agent-core-v2/src/llm-adapter/contract/message.ts
188993
189102
  function createUserMessage(content) {
188994
189103
  return {
@@ -197085,7 +197194,9 @@ function extractReasoningStrings(source) {
197085
197194
  value
197086
197195
  });
197087
197196
  }
197088
- return found;
197197
+ const [first] = found;
197198
+ if (first === void 0 || found.length === 1) return found;
197199
+ return found.every((entry) => entry.value === first.value) ? [first] : found;
197089
197200
  }
197090
197201
  function extractReasoning(source, explicitKey) {
197091
197202
  if (explicitKey !== void 0) {
@@ -200163,12 +200274,24 @@ function createEmptyResponseError(model, finish, thinkOnly) {
200163
200274
  rawFinishReason: finish.rawFinishReason
200164
200275
  };
200165
200276
  }
200277
+ function createUnrecoveredToolCallError(model, finish) {
200278
+ return {
200279
+ kind: "empty_response",
200280
+ message: `The model wrote a tool call as text instead of calling a tool, and it could not be recovered from the response.${formatFinishReasonHint(finish)} Provider: ${model.provider}, model: ${model.model}`,
200281
+ finishReason: finish.finishReason,
200282
+ rawFinishReason: finish.rawFinishReason
200283
+ };
200284
+ }
200285
+ function hasUnrecoveredToolCallText(message) {
200286
+ return message.content.some((part) => part.type === "text" && part.text.includes("<tool_call"));
200287
+ }
200166
200288
  function emptyResponseError(message, model, finish) {
200167
200289
  const hasToolCalls = message.toolCalls.length > 0;
200168
200290
  if (message.content.length === 0 && !hasToolCalls) return createEmptyResponseError(model, finish, false);
200169
200291
  const hasThink = message.content.some((part) => part.type === "think");
200170
200292
  const hasText = message.content.some((part) => part.type === "text" && part.text.trim().length > 0);
200171
200293
  if (hasThink && !hasText && !hasToolCalls) return createEmptyResponseError(model, finish, true);
200294
+ if (!hasToolCalls && hasUnrecoveredToolCallText(message)) return createUnrecoveredToolCallError(model, finish);
200172
200295
  return null;
200173
200296
  }
200174
200297
  var init_empty_response = __esmMin((() => {}));
@@ -223949,7 +224072,7 @@ function createAgentMachine({ abortTimeoutMs, maxStepsPerTurn }) {
223949
224072
  event: [...event.output.produced.map((message) => messageAppended({ message })), turnEnded({
223950
224073
  turnId: context.activeTurnId ?? context.turnId,
223951
224074
  outcome: event.output.type,
223952
- errorMessage: event.output.type === "failed" ? String(event.output.error) : void 0
224075
+ errorMessage: event.output.type === "failed" ? toErrorMessage(event.output.error) : void 0
223953
224076
  })]
223954
224077
  }))
223955
224078
  ]
@@ -223967,7 +224090,7 @@ function createAgentMachine({ abortTimeoutMs, maxStepsPerTurn }) {
223967
224090
  event: turnEnded({
223968
224091
  turnId: context.activeTurnId ?? context.turnId,
223969
224092
  outcome: "failed",
223970
- errorMessage: String(event.error)
224093
+ errorMessage: toErrorMessage(event.error)
223971
224094
  })
223972
224095
  }))]
223973
224096
  },
@@ -224093,6 +224216,7 @@ function createAgentMachine({ abortTimeoutMs, maxStepsPerTurn }) {
224093
224216
  }
224094
224217
  var init_machine$2 = __esmMin((() => {
224095
224218
  init_xstate2();
224219
+ init_errorMessage();
224096
224220
  init_message$2();
224097
224221
  init_machine$3();
224098
224222
  init_wait_for$1();
@@ -270915,7 +271039,7 @@ function preflightToolCall(toolRegistry, toolCall, guard, describeUnavailableToo
270915
271039
  toolCall,
270916
271040
  toolName,
270917
271041
  args: parsedArgs.data,
270918
- output: describeMissingTool?.(toolName) ?? `Tool "${toolName}" not found`
271042
+ output: describeMissingTool?.(toolName) ?? missingToolMessage(toolRegistry, toolName)
270919
271043
  };
270920
271044
  const source = toolRegistry.list().find((entry) => entry.name === toolName)?.source ?? "builtin";
270921
271045
  const denied = guard?.({
@@ -270953,6 +271077,19 @@ function preflightToolCall(toolRegistry, toolCall, guard, describeUnavailableToo
270953
271077
  args: parsedArgs.data
270954
271078
  };
270955
271079
  }
271080
+ function missingToolMessage(toolRegistry, toolName) {
271081
+ const base = `Tool "${toolName}" not found`;
271082
+ const wanted = toolName.toLowerCase();
271083
+ const suggestions = [];
271084
+ for (const entry of toolRegistry.list()) {
271085
+ if (!entry.name.startsWith("mcp__")) continue;
271086
+ if (!entry.name.toLowerCase().includes(wanted)) continue;
271087
+ suggestions.push(entry.name);
271088
+ if (suggestions.length === 5) break;
271089
+ }
271090
+ if (suggestions.length === 0) return base;
271091
+ return `${base}. Registered MCP tools with a similar name: ${suggestions.join(", ")}. Use the exact name.`;
271092
+ }
270956
271093
  function validateExecutableToolArgs(tool, args) {
270957
271094
  const schema = tool.parameters;
270958
271095
  let cached = validators.get(tool);
@@ -279532,6 +279669,7 @@ var init_toolRegistryService = __esmMin((() => {
279532
279669
  init_scopes();
279533
279670
  init_scope();
279534
279671
  init_toolRegistry();
279672
+ init_tool_naming();
279535
279673
  init_builtinToolAssemblyService();
279536
279674
  AgentToolRegistryService = class {
279537
279675
  tools = /* @__PURE__ */ new Map();
@@ -279564,7 +279702,22 @@ var init_toolRegistryService = __esmMin((() => {
279564
279702
  })).toSorted((a, b) => a.name.localeCompare(b.name));
279565
279703
  }
279566
279704
  resolve(name) {
279567
- return this.tools.get(name)?.tool;
279705
+ const direct = this.tools.get(name)?.tool;
279706
+ if (direct !== void 0) return direct;
279707
+ return this.resolveMcpAlias(name);
279708
+ }
279709
+ resolveMcpAlias(name) {
279710
+ if (name.startsWith("mcp__")) return void 0;
279711
+ const wanted = sanitizeMcpNamePart(name);
279712
+ const matches = [];
279713
+ for (const [qualified, entry] of this.tools) {
279714
+ if (!qualified.startsWith("mcp__")) continue;
279715
+ const rest = qualified.slice(5);
279716
+ const separator = rest.indexOf("__");
279717
+ if (separator < 0) continue;
279718
+ if (rest.slice(separator + 2) === wanted) matches.push(entry);
279719
+ }
279720
+ return matches.length === 1 ? matches[0]?.tool : void 0;
279568
279721
  }
279569
279722
  unregisterTool(name) {
279570
279723
  const entry = this.tools.get(name);
@@ -279863,6 +280016,7 @@ var init_src$10 = __esmMin((() => {
279863
280016
  init_capability$6();
279864
280017
  init_errors$38();
279865
280018
  init_message$1();
280019
+ init_message$2();
279866
280020
  init_request_trace();
279867
280021
  init_sessionIndex();
279868
280022
  init_sessionIndexService();
@@ -323257,6 +323411,51 @@ async function callRedteamTool(input) {
323257
323411
  text: text.slice(0, 2e3)
323258
323412
  };
323259
323413
  }
323414
+ async function listRedteamToolNames(input) {
323415
+ const doFetch = input.fetchImpl ?? fetch;
323416
+ const timeoutMs = input.timeoutMs ?? PROBE_TIMEOUT_MS$1;
323417
+ const origin = input.origin ?? "https://redteam.nexgen.systems";
323418
+ const headers = {
323419
+ ...mcpHeaders(input.apiKey),
323420
+ "content-type": "application/json",
323421
+ accept: "application/json, text/event-stream"
323422
+ };
323423
+ const initResponse = await timedFetch(doFetch, `${origin}/mcp`, {
323424
+ method: "POST",
323425
+ headers,
323426
+ body: JSON.stringify({
323427
+ jsonrpc: "2.0",
323428
+ id: 1,
323429
+ method: "initialize",
323430
+ params: {
323431
+ protocolVersion: "2025-06-18",
323432
+ capabilities: {},
323433
+ clientInfo: {
323434
+ name: "nexgenr-doctor",
323435
+ version: "1"
323436
+ }
323437
+ }
323438
+ })
323439
+ }, timeoutMs);
323440
+ if (!initResponse.ok) return [];
323441
+ const sessionId = initResponse.headers.get("mcp-session-id") ?? "";
323442
+ await readJsonRpc(initResponse, 1);
323443
+ const listResponse = await timedFetch(doFetch, `${origin}/mcp`, {
323444
+ method: "POST",
323445
+ headers: sessionId === "" ? headers : {
323446
+ ...headers,
323447
+ "mcp-session-id": sessionId
323448
+ },
323449
+ body: JSON.stringify({
323450
+ jsonrpc: "2.0",
323451
+ id: 2,
323452
+ method: "tools/list",
323453
+ params: {}
323454
+ })
323455
+ }, timeoutMs);
323456
+ if (!listResponse.ok) return [];
323457
+ return (((await readJsonRpc(listResponse, 2))?.["result"])?.tools ?? []).flatMap((tool) => typeof tool.name === "string" ? [tool.name] : []);
323458
+ }
323260
323459
  async function probeRedteam(input = {}) {
323261
323460
  const doFetch = input.fetchImpl ?? fetch;
323262
323461
  const timeoutMs = input.timeoutMs ?? PROBE_TIMEOUT_MS$1;
@@ -323316,6 +323515,19 @@ async function handleDoctorRedteam(deps) {
323316
323515
  }
323317
323516
  const verdict = verdictOf$1(rows);
323318
323517
  deps.stdout.write(deps.json === true ? formatJson$1(rows, verdict) : formatTable$1(rows, verdict));
323518
+ if (deps.listTools === true) {
323519
+ const names = await listRedteamToolNames({
323520
+ apiKey: process.env["NEXGENR_REDTEAM_MCP_KEY"] ?? apiKey,
323521
+ fetchImpl: deps.fetchImpl
323522
+ });
323523
+ deps.stdout.write([
323524
+ `Gateway tools (${names.length}):`,
323525
+ ...names.map((name) => ` ${name}`),
323526
+ "",
323527
+ "The model sees them as mcp__<server>__<name>. A bare gateway name resolves only when it is unambiguous.",
323528
+ ""
323529
+ ].join("\n"));
323530
+ }
323319
323531
  deps.exit(EXIT_CODES$1[verdict]);
323320
323532
  }
323321
323533
  function formatJson$1(rows, verdict) {
@@ -323707,7 +323919,7 @@ function registerDoctorCommand(parent, deps) {
323707
323919
  json: options.json === true
323708
323920
  });
323709
323921
  });
323710
- doctor.command("redteam").description("Probe the red-team surface: contract, inference catalog and MCP gateway.").option("--json", "Emit a machine-readable report instead of the table.").option("--call <tool>", "Call one MCP tool after the probes (this spends service credits).").option("--args <json>", "JSON arguments for --call.").action(async (options) => {
323922
+ doctor.command("redteam").description("Probe the red-team surface: contract, inference catalog and MCP gateway.").option("--json", "Emit a machine-readable report instead of the table.").option("--tools", "List the gateway tool names after the probes.").option("--call <tool>", "Call one MCP tool after the probes (this spends service credits).").option("--args <json>", "JSON arguments for --call.").action(async (options) => {
323711
323923
  const resolved = resolveDeps$1(deps);
323712
323924
  let args;
323713
323925
  if (options.args !== void 0) try {
@@ -323721,6 +323933,7 @@ function registerDoctorCommand(parent, deps) {
323721
323933
  stderr: resolved.stderr,
323722
323934
  exit: resolved.exit,
323723
323935
  json: options.json === true,
323936
+ listTools: options.tools === true,
323724
323937
  call: options.call === void 0 ? void 0 : {
323725
323938
  tool: options.call,
323726
323939
  args
@@ -497579,7 +497792,7 @@ function sameStringArrays(a, b) {
497579
497792
  return a.length === b.length && a.every((value, index) => value === b[index]);
497580
497793
  }
497581
497794
  function createInitialAppState(input) {
497582
- const startupPermission = input.cliOptions.auto ? "auto" : input.cliOptions.yolo ? "yolo" : "manual";
497795
+ const startupPermission = input.cliOptions.yolo ? "yolo" : "auto";
497583
497796
  return {
497584
497797
  model: "",
497585
497798
  workDir: input.workDir,
@@ -499251,7 +499464,7 @@ var NexgenTUI = class {
499251
499464
  const { startup } = this.options;
499252
499465
  const config = await this.harness.getConfig({ reload: true });
499253
499466
  const patch = includeModel ? lazyModelSelection(config, startup.model ?? config.defaultModel) : {};
499254
- if (!startup.auto && !startup.yolo) patch.permissionMode = config.defaultPermissionMode ?? "manual";
499467
+ if (!startup.auto && !startup.yolo) patch.permissionMode = config.defaultPermissionMode ?? "auto";
499255
499468
  patch.configDefaultPlanMode = config.defaultPlanMode === true;
499256
499469
  if (!startup.plan) patch.planMode = config.defaultPlanMode === true;
499257
499470
  if (startup.agentProfile !== void 0 || startup.agentFiles !== void 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nexgenr",
3
- "version": "1.0.3",
3
+ "version": "1.1.0",
4
4
  "description": "NexgenR — terminal AI coding agent",
5
5
  "license": "MIT",
6
6
  "author": "NexgenR",