jinzd-ai-cli 0.4.56 → 0.4.57

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.
@@ -8,7 +8,7 @@ import { platform } from "os";
8
8
  import chalk from "chalk";
9
9
 
10
10
  // src/core/constants.ts
11
- var VERSION = "0.4.56";
11
+ var VERSION = "0.4.57";
12
12
  var APP_NAME = "ai-cli";
13
13
  var CONFIG_DIR_NAME = ".aicli";
14
14
  var CONFIG_FILE_NAME = "config.json";
@@ -7,7 +7,7 @@ import {
7
7
  ProviderNotFoundError,
8
8
  RateLimitError,
9
9
  schemaToJsonSchema
10
- } from "./chunk-FJSEFQ54.js";
10
+ } from "./chunk-G6K64M6X.js";
11
11
  import {
12
12
  APP_NAME,
13
13
  CONFIG_DIR_NAME,
@@ -20,7 +20,7 @@ import {
20
20
  MCP_TOOL_PREFIX,
21
21
  PLUGINS_DIR_NAME,
22
22
  VERSION
23
- } from "./chunk-7FOGK5TM.js";
23
+ } from "./chunk-C2MNNHJ6.js";
24
24
 
25
25
  // src/config/config-manager.ts
26
26
  import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
@@ -1220,7 +1220,29 @@ var OpenAICompatibleProvider = class extends BaseProvider {
1220
1220
  return { content: "", usage: void 0 };
1221
1221
  }
1222
1222
  const message = firstChoice.message;
1223
+ const finishReason = firstChoice.finish_reason;
1223
1224
  const usage = toUsage(response.usage);
1225
+ const contentStr = typeof message.content === "string" ? message.content : "";
1226
+ const hasToolCalls = !!(message.tool_calls && message.tool_calls.length > 0);
1227
+ if (!hasToolCalls && contentStr.trim() === "") {
1228
+ const providerId = this.info.id;
1229
+ if (finishReason === "length") {
1230
+ process.stderr.write(
1231
+ `[${providerId}] \u26A0 Empty response with finish_reason='length' \u2014 output/context limit reached. Try /compact, raise maxTokens, or switch to a larger-context model.
1232
+ `
1233
+ );
1234
+ } else if (finishReason === "content_filter") {
1235
+ process.stderr.write(
1236
+ `[${providerId}] \u26A0 Empty response with finish_reason='content_filter' \u2014 content was blocked.
1237
+ `
1238
+ );
1239
+ } else {
1240
+ process.stderr.write(
1241
+ `[${providerId}] \u26A0 Empty response (finish_reason=${finishReason ?? "unknown"}). Model produced no text and no tool calls. Context window may be exhausted.
1242
+ `
1243
+ );
1244
+ }
1245
+ }
1224
1246
  const reasoningContent = message.reasoning_content;
1225
1247
  if (message.tool_calls && message.tool_calls.length > 0) {
1226
1248
  const toolCalls = message.tool_calls.map((tc) => {
@@ -10,7 +10,7 @@ import {
10
10
  SUBAGENT_DEFAULT_MAX_ROUNDS,
11
11
  SUBAGENT_MAX_ROUNDS_LIMIT,
12
12
  runTestsTool
13
- } from "./chunk-7FOGK5TM.js";
13
+ } from "./chunk-C2MNNHJ6.js";
14
14
 
15
15
  // src/tools/builtin/bash.ts
16
16
  import { execSync } from "child_process";
@@ -6,7 +6,7 @@ import { platform } from "os";
6
6
  import chalk from "chalk";
7
7
 
8
8
  // src/core/constants.ts
9
- var VERSION = "0.4.56";
9
+ var VERSION = "0.4.57";
10
10
  var APP_NAME = "ai-cli";
11
11
  var CONFIG_DIR_NAME = ".aicli";
12
12
  var CONFIG_FILE_NAME = "config.json";
@@ -385,7 +385,7 @@ ${content}`);
385
385
  }
386
386
  }
387
387
  async function runTaskMode(config, providers, configManager, topic) {
388
- const { TaskOrchestrator } = await import("./task-orchestrator-6RGRKSTU.js");
388
+ const { TaskOrchestrator } = await import("./task-orchestrator-FRF6LTWK.js");
389
389
  const orchestrator = new TaskOrchestrator(config, providers, configManager);
390
390
  let interrupted = false;
391
391
  const onSigint = () => {
package/dist/index.js CHANGED
@@ -27,7 +27,7 @@ import {
27
27
  saveDevState,
28
28
  sessionHasMeaningfulContent,
29
29
  setupProxy
30
- } from "./chunk-2DC5ABAM.js";
30
+ } from "./chunk-G5REL4FK.js";
31
31
  import {
32
32
  ToolExecutor,
33
33
  ToolRegistry,
@@ -41,7 +41,7 @@ import {
41
41
  spawnAgentContext,
42
42
  theme,
43
43
  undoStack
44
- } from "./chunk-FJSEFQ54.js";
44
+ } from "./chunk-G6K64M6X.js";
45
45
  import {
46
46
  fileCheckpoints
47
47
  } from "./chunk-4BKXL7SM.js";
@@ -66,7 +66,7 @@ import {
66
66
  SKILLS_DIR_NAME,
67
67
  VERSION,
68
68
  buildUserIdentityPrompt
69
- } from "./chunk-7FOGK5TM.js";
69
+ } from "./chunk-C2MNNHJ6.js";
70
70
 
71
71
  // src/index.ts
72
72
  import { program } from "commander";
@@ -2161,7 +2161,7 @@ ${hint}` : "")
2161
2161
  usage: "/test [command|filter]",
2162
2162
  async execute(args, ctx) {
2163
2163
  try {
2164
- const { executeTests } = await import("./run-tests-GISOOQZC.js");
2164
+ const { executeTests } = await import("./run-tests-NVCAP42D.js");
2165
2165
  const argStr = args.join(" ").trim();
2166
2166
  let testArgs = {};
2167
2167
  if (argStr) {
@@ -4864,6 +4864,7 @@ You have a maximum of ${maxToolRounds} tool call rounds for this task. Plan effi
4864
4864
  let consecutiveFreeRounds = 0;
4865
4865
  let lastToolCallSignature = "";
4866
4866
  let repeatedToolCallCount = 0;
4867
+ let emptyResponseRetries = 0;
4867
4868
  const roundToolHistory = [];
4868
4869
  this.setupInterjectionListener();
4869
4870
  try {
@@ -4992,6 +4993,51 @@ You have a maximum of ${maxToolRounds} tool call rounds for this task. Plan effi
4992
4993
  spinner.start(`Retrying... (round ${round + 2}/${maxToolRounds})`);
4993
4994
  continue;
4994
4995
  }
4996
+ if (!result.content || result.content.trim() === "") {
4997
+ if (emptyResponseRetries === 0 && round < maxToolRounds - 1) {
4998
+ emptyResponseRetries++;
4999
+ spinner.stop();
5000
+ if (alreadyRendered) process.stdout.write("\n");
5001
+ process.stderr.write(
5002
+ theme.warning(
5003
+ `\u26A0 AI returned an empty response (no text, no tool calls). Nudging to continue...
5004
+ `
5005
+ )
5006
+ );
5007
+ extraMessages.push({
5008
+ role: "user",
5009
+ content: "Your previous response was empty \u2014 no text and no tool calls. This usually means the context window is nearly full. Please either: (1) continue the task by calling the next tool you need, or (2) give a concise final text summary of what has been accomplished so far and what remains. Do NOT repeat earlier long outputs."
5010
+ });
5011
+ spinner.start(`Retrying... (round ${round + 2}/${maxToolRounds})`);
5012
+ continue;
5013
+ }
5014
+ spinner.stop();
5015
+ if (alreadyRendered) process.stdout.write("\n");
5016
+ process.stderr.write(
5017
+ theme.error(
5018
+ `
5019
+ \u26A0 AI returned empty responses twice in a row. Stopping agentic loop.
5020
+ `
5021
+ )
5022
+ );
5023
+ process.stderr.write(
5024
+ theme.dim(
5025
+ ` Likely causes: context window exhausted, max_tokens too low, or content filter.
5026
+ Try: /compact to reduce context, /clear to reset, or /model to switch.
5027
+
5028
+ `
5029
+ )
5030
+ );
5031
+ if (roundUsage.inputTokens > 0 || roundUsage.outputTokens > 0) {
5032
+ this.addSessionUsage(roundUsage);
5033
+ session.addTokenUsage(roundUsage);
5034
+ if (this.shouldShowTokens()) {
5035
+ this.renderer.renderUsage(roundUsage, this.sessionTokenUsage);
5036
+ }
5037
+ }
5038
+ return;
5039
+ }
5040
+ emptyResponseRetries = 0;
4995
5041
  spinner.stop();
4996
5042
  const finalContent = result.content;
4997
5043
  if (!alreadyRendered) {
@@ -5563,7 +5609,7 @@ program.command("web").description("Start Web UI server with browser-based chat
5563
5609
  console.error("Error: Invalid port number. Must be between 1 and 65535.");
5564
5610
  process.exit(1);
5565
5611
  }
5566
- const { startWebServer } = await import("./server-MOTFJN6L.js");
5612
+ const { startWebServer } = await import("./server-46J5MXHG.js");
5567
5613
  await startWebServer({ port, host: options.host });
5568
5614
  });
5569
5615
  program.command("user [action] [username]").description("Manage Web UI users (list | create <name> | delete <name> | reset-password <name> | migrate <name>)").action(async (action, username) => {
@@ -5796,7 +5842,7 @@ program.command("hub [topic]").description("Start multi-agent hub (discuss / bra
5796
5842
  }),
5797
5843
  config.get("customProviders")
5798
5844
  );
5799
- const { startHub } = await import("./hub-HQ5QX7CV.js");
5845
+ const { startHub } = await import("./hub-P3BR4JB5.js");
5800
5846
  await startHub(
5801
5847
  {
5802
5848
  topic: topic ?? "",
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  executeTests,
4
4
  runTestsTool
5
- } from "./chunk-7FOGK5TM.js";
5
+ } from "./chunk-C2MNNHJ6.js";
6
6
  export {
7
7
  executeTests,
8
8
  runTestsTool
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  executeTests,
3
3
  runTestsTool
4
- } from "./chunk-REWBXK2G.js";
4
+ } from "./chunk-H7MNK3YO.js";
5
5
  export {
6
6
  executeTests,
7
7
  runTestsTool
@@ -17,7 +17,7 @@ import {
17
17
  hadPreviousWriteToolCalls,
18
18
  loadDevState,
19
19
  setupProxy
20
- } from "./chunk-2DC5ABAM.js";
20
+ } from "./chunk-G5REL4FK.js";
21
21
  import {
22
22
  AuthManager
23
23
  } from "./chunk-BYNY5JPB.js";
@@ -36,7 +36,7 @@ import {
36
36
  spawnAgentContext,
37
37
  truncateOutput,
38
38
  undoStack
39
- } from "./chunk-FJSEFQ54.js";
39
+ } from "./chunk-G6K64M6X.js";
40
40
  import "./chunk-4BKXL7SM.js";
41
41
  import {
42
42
  AGENTIC_BEHAVIOR_GUIDELINE,
@@ -56,7 +56,7 @@ import {
56
56
  SKILLS_DIR_NAME,
57
57
  VERSION,
58
58
  buildUserIdentityPrompt
59
- } from "./chunk-7FOGK5TM.js";
59
+ } from "./chunk-C2MNNHJ6.js";
60
60
 
61
61
  // src/web/server.ts
62
62
  import express from "express";
@@ -800,6 +800,7 @@ You have a maximum of ${maxToolRounds} tool call rounds for this task. Plan effi
800
800
  let warnedNote = false;
801
801
  let warnedLow = false;
802
802
  let warnedCritical = false;
803
+ let emptyResponseRetries = 0;
803
804
  const ac = new AbortController();
804
805
  this.abortController = ac;
805
806
  try {
@@ -862,6 +863,31 @@ You have a maximum of ${maxToolRounds} tool call rounds for this task. Plan effi
862
863
  roundUsage.cacheCreationTokens += result.usage.cacheCreationTokens ?? 0;
863
864
  roundUsage.cacheReadTokens += result.usage.cacheReadTokens ?? 0;
864
865
  }
866
+ const hasToolCalls = !!(result.toolCalls && result.toolCalls.length > 0);
867
+ const contentBlank = !result.content || result.content.trim() === "";
868
+ if (!hasToolCalls && contentBlank) {
869
+ if (emptyResponseRetries === 0 && round < maxToolRounds - 1) {
870
+ emptyResponseRetries++;
871
+ this.send({
872
+ type: "info",
873
+ message: "\u26A0 AI returned an empty response. Nudging to continue..."
874
+ });
875
+ extraMessages.push({
876
+ role: "user",
877
+ content: "Your previous response was empty \u2014 no text and no tool calls. This usually means the context window is nearly full. Please either: (1) continue the task by calling the next tool you need, or (2) give a concise final text summary of what has been accomplished so far and what remains. Do NOT repeat earlier long outputs."
878
+ });
879
+ continue;
880
+ }
881
+ this.send({
882
+ type: "response_done",
883
+ content: "\u26A0 AI returned empty responses twice in a row. Stopping agentic loop.\n\nLikely causes: context window exhausted, max_tokens too low, or content filter.\nTry: /compact to reduce context, /clear to reset, or switch to a larger-context model.",
884
+ usage: roundUsage
885
+ });
886
+ this.addWebSessionUsage(roundUsage);
887
+ session.addTokenUsage(roundUsage);
888
+ return;
889
+ }
890
+ emptyResponseRetries = 0;
865
891
  if (result.content && !result.toolCalls) {
866
892
  const hasWriteTools = toolDefs.some((t) => t.name === "write_file" || t.name === "edit_file");
867
893
  const alreadyWrote = hadPreviousWriteToolCalls(extraMessages);
@@ -1790,7 +1816,7 @@ ${undoResults.map((r) => ` \u2022 ${r}`).join("\n")}` });
1790
1816
  case "test": {
1791
1817
  this.send({ type: "info", message: "\u{1F9EA} Running tests..." });
1792
1818
  try {
1793
- const { executeTests } = await import("./run-tests-GISOOQZC.js");
1819
+ const { executeTests } = await import("./run-tests-NVCAP42D.js");
1794
1820
  const argStr = args.join(" ").trim();
1795
1821
  let testArgs = {};
1796
1822
  if (argStr) {
@@ -4,11 +4,11 @@ import {
4
4
  getDangerLevel,
5
5
  googleSearchContext,
6
6
  truncateOutput
7
- } from "./chunk-FJSEFQ54.js";
7
+ } from "./chunk-G6K64M6X.js";
8
8
  import "./chunk-4BKXL7SM.js";
9
9
  import {
10
10
  SUBAGENT_ALLOWED_TOOLS
11
- } from "./chunk-7FOGK5TM.js";
11
+ } from "./chunk-C2MNNHJ6.js";
12
12
 
13
13
  // src/hub/task-orchestrator.ts
14
14
  import { createInterface } from "readline";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jinzd-ai-cli",
3
- "version": "0.4.56",
3
+ "version": "0.4.57",
4
4
  "description": "Cross-platform REPL-style AI CLI with multi-provider support",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",