mpd-llm-cli 0.1.11 → 0.1.13

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/bundle/api.cjs CHANGED
@@ -139956,7 +139956,13 @@ var DiscoveredMCPTool = class _DiscoveredMCPTool extends BaseTool {
139956
139956
  this.timeout = timeout;
139957
139957
  this.trust = trust;
139958
139958
  }
139959
- async shouldConfirmExecute(_params, _abortSignal) {
139959
+ async shouldConfirmExecute(params, _abortSignal) {
139960
+ if (process.env.DEBUG === "true" || process.env.DEBUG_MODE === "true" || process.env.dev === "true") {
139961
+ console.error(`[MCP DEBUG] shouldConfirmExecute called for tool: ${this.name}`);
139962
+ console.error(`[MCP DEBUG] Received params:`, JSON.stringify(params, null, 2));
139963
+ console.error(`[MCP DEBUG] Params type:`, typeof params);
139964
+ console.error(`[MCP DEBUG] Params keys:`, Object.keys(params));
139965
+ }
139960
139966
  const serverAllowListKey = this.serverName;
139961
139967
  const toolAllowListKey = `${this.serverName}.${this.serverToolName}`;
139962
139968
  if (process.env.YOLO) {
@@ -139976,6 +139982,8 @@ var DiscoveredMCPTool = class _DiscoveredMCPTool extends BaseTool {
139976
139982
  // Display original tool name in confirmation
139977
139983
  toolDisplayName: this.name,
139978
139984
  // Display global registry name exposed to model and user
139985
+ args: params,
139986
+ // Include the parameters
139979
139987
  onConfirm: async (outcome) => {
139980
139988
  if (outcome === ToolConfirmationOutcome.ProceedAlwaysServer) {
139981
139989
  _DiscoveredMCPTool.allowlist.add(serverAllowListKey);
@@ -140140,7 +140148,9 @@ Make sure it is available in the sandbox`;
140140
140148
  return;
140141
140149
  }
140142
140150
  mcpClient.onerror = (error) => {
140143
- console.error(`MCP ERROR (${mcpServerName}):`, error.toString());
140151
+ if (process.env.DEBUG === "true" || process.env.DEBUG_MODE === "true" || process.env.dev === "true") {
140152
+ console.error(`MCP ERROR (${mcpServerName}):`, error.toString());
140153
+ }
140144
140154
  updateMCPServerStatus(mcpServerName, MCPServerStatus.DISCONNECTED);
140145
140155
  };
140146
140156
  if (transport instanceof StdioClientTransport && transport.stderr) {
@@ -140190,8 +140200,15 @@ Make sure it is available in the sandbox`;
140190
140200
  if (toolNameForModel.length > 63) {
140191
140201
  toolNameForModel = toolNameForModel.slice(0, 28) + "___" + toolNameForModel.slice(-32);
140192
140202
  }
140193
- sanitizeParameters(funcDecl.parameters);
140194
- toolRegistry.registerTool(new DiscoveredMCPTool(mcpCallableTool, mcpServerName, toolNameForModel, funcDecl.description ?? "", funcDecl.parameters ?? { type: import_genai4.Type.OBJECT, properties: {} }, funcDecl.name, mcpServerConfig.timeout ?? MCP_DEFAULT_TIMEOUT_MSEC, mcpServerConfig.trust));
140203
+ if (process.env.DEBUG === "true" || process.env.DEBUG_MODE === "true" || process.env.dev === "true") {
140204
+ console.error(`[MCP DEBUG] Registering tool: ${toolNameForModel} (server: ${mcpServerName}, original: ${funcDecl.name})`);
140205
+ console.error(`[MCP DEBUG] Tool parameters:`, JSON.stringify(funcDecl.parameters, null, 2));
140206
+ console.error(`[MCP DEBUG] Tool parametersJsonSchema:`, JSON.stringify(funcDecl.parametersJsonSchema, null, 2));
140207
+ console.error(`[MCP DEBUG] Tool description:`, funcDecl.description);
140208
+ }
140209
+ const parametersSchema = funcDecl.parameters || funcDecl.parametersJsonSchema || { type: import_genai4.Type.OBJECT, properties: {} };
140210
+ sanitizeParameters(parametersSchema);
140211
+ toolRegistry.registerTool(new DiscoveredMCPTool(mcpCallableTool, mcpServerName, toolNameForModel, funcDecl.description ?? "", parametersSchema, funcDecl.name, mcpServerConfig.timeout ?? MCP_DEFAULT_TIMEOUT_MSEC, mcpServerConfig.trust));
140195
140212
  }
140196
140213
  } catch (error) {
140197
140214
  console.error(`Failed to list or register tools for MCP server '${mcpServerName}': ${error}`);
@@ -149798,6 +149815,34 @@ function isFunctionCall(content) {
149798
149815
 
149799
149816
  // packages/core/dist/src/utils/editCorrector.js
149800
149817
  var fs13 = __toESM(require("fs"), 1);
149818
+ function filterIncompleteToolCalls(contents) {
149819
+ const toolCallIds = /* @__PURE__ */ new Set();
149820
+ const toolResponseIds = /* @__PURE__ */ new Set();
149821
+ for (const message of contents) {
149822
+ if (message.parts) {
149823
+ for (const part of message.parts) {
149824
+ if (part.functionCall?.id) {
149825
+ toolCallIds.add(part.functionCall.id);
149826
+ }
149827
+ if (part.functionResponse?.id) {
149828
+ toolResponseIds.add(part.functionResponse.id);
149829
+ }
149830
+ }
149831
+ }
149832
+ }
149833
+ return contents.filter((message) => {
149834
+ if (!message.parts)
149835
+ return true;
149836
+ for (const part of message.parts) {
149837
+ if (part.functionCall?.id) {
149838
+ if (!toolResponseIds.has(part.functionCall.id)) {
149839
+ return false;
149840
+ }
149841
+ }
149842
+ }
149843
+ return true;
149844
+ });
149845
+ }
149801
149846
  var EditModel = DEFAULT_GEMINI_FLASH_MODEL;
149802
149847
  var EditConfig = {
149803
149848
  thinkingConfig: {
@@ -150027,8 +150072,9 @@ If the differences are only in whitespace or formatting, apply similar whitespac
150027
150072
  Return ONLY the corrected target snippet in the specified JSON format with the key 'corrected_target_snippet'. If no clear, unique match can be found, return an empty string for 'corrected_target_snippet'.
150028
150073
  `.trim();
150029
150074
  const contents = [{ role: "user", parts: [{ text: prompt }] }];
150075
+ const filteredContents = filterIncompleteToolCalls(contents);
150030
150076
  try {
150031
- const result = await geminiClient.generateJson(contents, OLD_STRING_CORRECTION_SCHEMA, abortSignal, EditModel, EditConfig);
150077
+ const result = await geminiClient.generateJson(filteredContents, OLD_STRING_CORRECTION_SCHEMA, abortSignal, EditModel, EditConfig);
150032
150078
  if (result && typeof result.corrected_target_snippet === "string" && result.corrected_target_snippet.length > 0) {
150033
150079
  return result.corrected_target_snippet;
150034
150080
  } else {
@@ -150085,8 +150131,9 @@ If the differences are only in whitespace or formatting, apply similar whitespac
150085
150131
  Return ONLY the corrected string in the specified JSON format with the key 'corrected_new_string'. If no adjustment is deemed necessary or possible, return the original_new_string.
150086
150132
  `.trim();
150087
150133
  const contents = [{ role: "user", parts: [{ text: prompt }] }];
150134
+ const filteredContents = filterIncompleteToolCalls(contents);
150088
150135
  try {
150089
- const result = await geminiClient.generateJson(contents, NEW_STRING_CORRECTION_SCHEMA, abortSignal, EditModel, EditConfig);
150136
+ const result = await geminiClient.generateJson(filteredContents, NEW_STRING_CORRECTION_SCHEMA, abortSignal, EditModel, EditConfig);
150090
150137
  if (result && typeof result.corrected_new_string === "string" && result.corrected_new_string.length > 0) {
150091
150138
  return result.corrected_new_string;
150092
150139
  } else {
@@ -150135,8 +150182,9 @@ If potentially_problematic_new_string is console.log(\\"Hello World\\"), it shou
150135
150182
  Return ONLY the corrected string in the specified JSON format with the key 'corrected_new_string_escaping'. If no escaping correction is needed, return the original potentially_problematic_new_string.
150136
150183
  `.trim();
150137
150184
  const contents = [{ role: "user", parts: [{ text: prompt }] }];
150185
+ const filteredContents = filterIncompleteToolCalls(contents);
150138
150186
  try {
150139
- const result = await geminiClient.generateJson(contents, CORRECT_NEW_STRING_ESCAPING_SCHEMA, abortSignal, EditModel, EditConfig);
150187
+ const result = await geminiClient.generateJson(filteredContents, CORRECT_NEW_STRING_ESCAPING_SCHEMA, abortSignal, EditModel, EditConfig);
150140
150188
  if (result && typeof result.corrected_new_string_escaping === "string" && result.corrected_new_string_escaping.length > 0) {
150141
150189
  return result.corrected_new_string_escaping;
150142
150190
  } else {
@@ -150180,8 +150228,9 @@ If potentially_problematic_string is console.log(\\"Hello World\\"), it should b
150180
150228
  Return ONLY the corrected string in the specified JSON format with the key 'corrected_string_escaping'. If no escaping correction is needed, return the original potentially_problematic_string.
150181
150229
  `.trim();
150182
150230
  const contents = [{ role: "user", parts: [{ text: prompt }] }];
150231
+ const filteredContents = filterIncompleteToolCalls(contents);
150183
150232
  try {
150184
- const result = await client.generateJson(contents, CORRECT_STRING_ESCAPING_SCHEMA, abortSignal, EditModel, EditConfig);
150233
+ const result = await client.generateJson(filteredContents, CORRECT_STRING_ESCAPING_SCHEMA, abortSignal, EditModel, EditConfig);
150185
150234
  if (result && typeof result.corrected_string_escaping === "string" && result.corrected_string_escaping.length > 0) {
150186
150235
  return result.corrected_string_escaping;
150187
150236
  } else {
@@ -157075,12 +157124,24 @@ async function checkNextSpeaker(chat, geminiClient, abortSignal) {
157075
157124
  if (!lastMessage || lastMessage.role !== "model") {
157076
157125
  return null;
157077
157126
  }
157127
+ const hasIncompleteToolCalls = checkForIncompleteToolCalls(curatedHistory);
157128
+ if (hasIncompleteToolCalls) {
157129
+ return {
157130
+ reasoning: "There are pending tool calls that need to be processed, so the model should speak next.",
157131
+ next_speaker: "model"
157132
+ };
157133
+ }
157078
157134
  const contents = [
157079
157135
  ...curatedHistory,
157080
157136
  { role: "user", parts: [{ text: CHECK_PROMPT }] }
157081
157137
  ];
157138
+ const filteredContents = checkForIncompleteToolCalls(contents) ? contents.filter((message) => {
157139
+ if (!message.parts)
157140
+ return true;
157141
+ return !message.parts.some((part) => part.functionCall?.id);
157142
+ }) : contents;
157082
157143
  try {
157083
- const parsedResponse = await geminiClient.generateJson(contents, RESPONSE_SCHEMA, abortSignal);
157144
+ const parsedResponse = await geminiClient.generateJson(filteredContents, RESPONSE_SCHEMA, abortSignal);
157084
157145
  if (parsedResponse && parsedResponse.next_speaker && ["user", "model"].includes(parsedResponse.next_speaker)) {
157085
157146
  return parsedResponse;
157086
157147
  }
@@ -157090,6 +157151,28 @@ async function checkNextSpeaker(chat, geminiClient, abortSignal) {
157090
157151
  return null;
157091
157152
  }
157092
157153
  }
157154
+ function checkForIncompleteToolCalls(history) {
157155
+ const toolCallIds = /* @__PURE__ */ new Set();
157156
+ const toolResponseIds = /* @__PURE__ */ new Set();
157157
+ for (const message of history) {
157158
+ if (message.parts) {
157159
+ for (const part of message.parts) {
157160
+ if (part.functionCall?.id) {
157161
+ toolCallIds.add(part.functionCall.id);
157162
+ }
157163
+ if (part.functionResponse?.id) {
157164
+ toolResponseIds.add(part.functionResponse.id);
157165
+ }
157166
+ }
157167
+ }
157168
+ }
157169
+ for (const callId of toolCallIds) {
157170
+ if (!toolResponseIds.has(callId)) {
157171
+ return true;
157172
+ }
157173
+ }
157174
+ return false;
157175
+ }
157093
157176
 
157094
157177
  // packages/core/dist/src/core/geminiChat.js
157095
157178
  var import_genai19 = require("@google/genai");
@@ -164750,12 +164833,19 @@ var CoreToolScheduler = class {
164750
164833
  return this.toolCalls.some((call) => call.status === "executing" || call.status === "awaiting_approval");
164751
164834
  }
164752
164835
  async schedule(request2, signal) {
164836
+ if (process.env.DEBUG === "true" || process.env.DEBUG_MODE === "true" || process.env.dev === "true") {
164837
+ console.error(`[MCP DEBUG] CoreToolScheduler.schedule called`);
164838
+ console.error(`[MCP DEBUG] Request:`, JSON.stringify(request2, null, 2));
164839
+ }
164753
164840
  if (this.isRunning()) {
164754
164841
  throw new Error("Cannot schedule new tool calls while other tool calls are actively running (executing or awaiting approval).");
164755
164842
  }
164756
164843
  const requestsToProcess = Array.isArray(request2) ? request2 : [request2];
164757
164844
  const toolRegistry = await this.toolRegistry;
164758
164845
  const newToolCalls = requestsToProcess.map((reqInfo) => {
164846
+ if (process.env.DEBUG === "true" || process.env.DEBUG_MODE === "true" || process.env.dev === "true") {
164847
+ console.error(`[MCP DEBUG] Processing request:`, JSON.stringify(reqInfo, null, 2));
164848
+ }
164759
164849
  const toolInstance = toolRegistry.getTool(reqInfo.name);
164760
164850
  if (!toolInstance) {
164761
164851
  return {
@@ -164783,6 +164873,10 @@ var CoreToolScheduler = class {
164783
164873
  if (this.approvalMode === ApprovalMode.YOLO || process.env.YOLO) {
164784
164874
  this.setStatusInternal(reqInfo.callId, "scheduled");
164785
164875
  } else {
164876
+ if (process.env.DEBUG === "true" || process.env.DEBUG_MODE === "true" || process.env.dev === "true") {
164877
+ console.error(`[MCP DEBUG] CoreToolScheduler calling shouldConfirmExecute for: ${reqInfo.name}`);
164878
+ console.error(`[MCP DEBUG] Request args:`, JSON.stringify(reqInfo.args, null, 2));
164879
+ }
164786
164880
  const confirmationDetails = await toolInstance.shouldConfirmExecute(reqInfo.args, signal);
164787
164881
  if (confirmationDetails) {
164788
164882
  const originalOnConfirm = confirmationDetails.onConfirm;
package/bundle/api.js CHANGED
@@ -27717,7 +27717,7 @@ async function createContentGeneratorConfig(model, authType) {
27717
27717
  return contentGeneratorConfig;
27718
27718
  }
27719
27719
  async function createContentGenerator(config2, sessionId2) {
27720
- const version2 = "0.1.11";
27720
+ const version2 = "0.1.13";
27721
27721
  const httpOptions = {
27722
27722
  headers: {
27723
27723
  "User-Agent": `GeminiCLI/${version2} (${process.platform}; ${process.arch})`
@@ -139952,7 +139952,13 @@ var DiscoveredMCPTool = class _DiscoveredMCPTool extends BaseTool {
139952
139952
  this.timeout = timeout;
139953
139953
  this.trust = trust;
139954
139954
  }
139955
- async shouldConfirmExecute(_params, _abortSignal) {
139955
+ async shouldConfirmExecute(params, _abortSignal) {
139956
+ if (process.env.DEBUG === "true" || process.env.DEBUG_MODE === "true" || process.env.dev === "true") {
139957
+ console.error(`[MCP DEBUG] shouldConfirmExecute called for tool: ${this.name}`);
139958
+ console.error(`[MCP DEBUG] Received params:`, JSON.stringify(params, null, 2));
139959
+ console.error(`[MCP DEBUG] Params type:`, typeof params);
139960
+ console.error(`[MCP DEBUG] Params keys:`, Object.keys(params));
139961
+ }
139956
139962
  const serverAllowListKey = this.serverName;
139957
139963
  const toolAllowListKey = `${this.serverName}.${this.serverToolName}`;
139958
139964
  if (process.env.YOLO) {
@@ -139972,6 +139978,8 @@ var DiscoveredMCPTool = class _DiscoveredMCPTool extends BaseTool {
139972
139978
  // Display original tool name in confirmation
139973
139979
  toolDisplayName: this.name,
139974
139980
  // Display global registry name exposed to model and user
139981
+ args: params,
139982
+ // Include the parameters
139975
139983
  onConfirm: async (outcome) => {
139976
139984
  if (outcome === ToolConfirmationOutcome.ProceedAlwaysServer) {
139977
139985
  _DiscoveredMCPTool.allowlist.add(serverAllowListKey);
@@ -140136,7 +140144,9 @@ Make sure it is available in the sandbox`;
140136
140144
  return;
140137
140145
  }
140138
140146
  mcpClient.onerror = (error) => {
140139
- console.error(`MCP ERROR (${mcpServerName}):`, error.toString());
140147
+ if (process.env.DEBUG === "true" || process.env.DEBUG_MODE === "true" || process.env.dev === "true") {
140148
+ console.error(`MCP ERROR (${mcpServerName}):`, error.toString());
140149
+ }
140140
140150
  updateMCPServerStatus(mcpServerName, MCPServerStatus.DISCONNECTED);
140141
140151
  };
140142
140152
  if (transport instanceof StdioClientTransport && transport.stderr) {
@@ -140186,8 +140196,15 @@ Make sure it is available in the sandbox`;
140186
140196
  if (toolNameForModel.length > 63) {
140187
140197
  toolNameForModel = toolNameForModel.slice(0, 28) + "___" + toolNameForModel.slice(-32);
140188
140198
  }
140189
- sanitizeParameters(funcDecl.parameters);
140190
- toolRegistry.registerTool(new DiscoveredMCPTool(mcpCallableTool, mcpServerName, toolNameForModel, funcDecl.description ?? "", funcDecl.parameters ?? { type: Type.OBJECT, properties: {} }, funcDecl.name, mcpServerConfig.timeout ?? MCP_DEFAULT_TIMEOUT_MSEC, mcpServerConfig.trust));
140199
+ if (process.env.DEBUG === "true" || process.env.DEBUG_MODE === "true" || process.env.dev === "true") {
140200
+ console.error(`[MCP DEBUG] Registering tool: ${toolNameForModel} (server: ${mcpServerName}, original: ${funcDecl.name})`);
140201
+ console.error(`[MCP DEBUG] Tool parameters:`, JSON.stringify(funcDecl.parameters, null, 2));
140202
+ console.error(`[MCP DEBUG] Tool parametersJsonSchema:`, JSON.stringify(funcDecl.parametersJsonSchema, null, 2));
140203
+ console.error(`[MCP DEBUG] Tool description:`, funcDecl.description);
140204
+ }
140205
+ const parametersSchema = funcDecl.parameters || funcDecl.parametersJsonSchema || { type: Type.OBJECT, properties: {} };
140206
+ sanitizeParameters(parametersSchema);
140207
+ toolRegistry.registerTool(new DiscoveredMCPTool(mcpCallableTool, mcpServerName, toolNameForModel, funcDecl.description ?? "", parametersSchema, funcDecl.name, mcpServerConfig.timeout ?? MCP_DEFAULT_TIMEOUT_MSEC, mcpServerConfig.trust));
140191
140208
  }
140192
140209
  } catch (error) {
140193
140210
  console.error(`Failed to list or register tools for MCP server '${mcpServerName}': ${error}`);
@@ -149794,6 +149811,34 @@ function isFunctionCall(content) {
149794
149811
 
149795
149812
  // packages/core/dist/src/utils/editCorrector.js
149796
149813
  import * as fs13 from "fs";
149814
+ function filterIncompleteToolCalls(contents) {
149815
+ const toolCallIds = /* @__PURE__ */ new Set();
149816
+ const toolResponseIds = /* @__PURE__ */ new Set();
149817
+ for (const message of contents) {
149818
+ if (message.parts) {
149819
+ for (const part of message.parts) {
149820
+ if (part.functionCall?.id) {
149821
+ toolCallIds.add(part.functionCall.id);
149822
+ }
149823
+ if (part.functionResponse?.id) {
149824
+ toolResponseIds.add(part.functionResponse.id);
149825
+ }
149826
+ }
149827
+ }
149828
+ }
149829
+ return contents.filter((message) => {
149830
+ if (!message.parts)
149831
+ return true;
149832
+ for (const part of message.parts) {
149833
+ if (part.functionCall?.id) {
149834
+ if (!toolResponseIds.has(part.functionCall.id)) {
149835
+ return false;
149836
+ }
149837
+ }
149838
+ }
149839
+ return true;
149840
+ });
149841
+ }
149797
149842
  var EditModel = DEFAULT_GEMINI_FLASH_MODEL;
149798
149843
  var EditConfig = {
149799
149844
  thinkingConfig: {
@@ -150023,8 +150068,9 @@ If the differences are only in whitespace or formatting, apply similar whitespac
150023
150068
  Return ONLY the corrected target snippet in the specified JSON format with the key 'corrected_target_snippet'. If no clear, unique match can be found, return an empty string for 'corrected_target_snippet'.
150024
150069
  `.trim();
150025
150070
  const contents = [{ role: "user", parts: [{ text: prompt }] }];
150071
+ const filteredContents = filterIncompleteToolCalls(contents);
150026
150072
  try {
150027
- const result = await geminiClient.generateJson(contents, OLD_STRING_CORRECTION_SCHEMA, abortSignal, EditModel, EditConfig);
150073
+ const result = await geminiClient.generateJson(filteredContents, OLD_STRING_CORRECTION_SCHEMA, abortSignal, EditModel, EditConfig);
150028
150074
  if (result && typeof result.corrected_target_snippet === "string" && result.corrected_target_snippet.length > 0) {
150029
150075
  return result.corrected_target_snippet;
150030
150076
  } else {
@@ -150081,8 +150127,9 @@ If the differences are only in whitespace or formatting, apply similar whitespac
150081
150127
  Return ONLY the corrected string in the specified JSON format with the key 'corrected_new_string'. If no adjustment is deemed necessary or possible, return the original_new_string.
150082
150128
  `.trim();
150083
150129
  const contents = [{ role: "user", parts: [{ text: prompt }] }];
150130
+ const filteredContents = filterIncompleteToolCalls(contents);
150084
150131
  try {
150085
- const result = await geminiClient.generateJson(contents, NEW_STRING_CORRECTION_SCHEMA, abortSignal, EditModel, EditConfig);
150132
+ const result = await geminiClient.generateJson(filteredContents, NEW_STRING_CORRECTION_SCHEMA, abortSignal, EditModel, EditConfig);
150086
150133
  if (result && typeof result.corrected_new_string === "string" && result.corrected_new_string.length > 0) {
150087
150134
  return result.corrected_new_string;
150088
150135
  } else {
@@ -150131,8 +150178,9 @@ If potentially_problematic_new_string is console.log(\\"Hello World\\"), it shou
150131
150178
  Return ONLY the corrected string in the specified JSON format with the key 'corrected_new_string_escaping'. If no escaping correction is needed, return the original potentially_problematic_new_string.
150132
150179
  `.trim();
150133
150180
  const contents = [{ role: "user", parts: [{ text: prompt }] }];
150181
+ const filteredContents = filterIncompleteToolCalls(contents);
150134
150182
  try {
150135
- const result = await geminiClient.generateJson(contents, CORRECT_NEW_STRING_ESCAPING_SCHEMA, abortSignal, EditModel, EditConfig);
150183
+ const result = await geminiClient.generateJson(filteredContents, CORRECT_NEW_STRING_ESCAPING_SCHEMA, abortSignal, EditModel, EditConfig);
150136
150184
  if (result && typeof result.corrected_new_string_escaping === "string" && result.corrected_new_string_escaping.length > 0) {
150137
150185
  return result.corrected_new_string_escaping;
150138
150186
  } else {
@@ -150176,8 +150224,9 @@ If potentially_problematic_string is console.log(\\"Hello World\\"), it should b
150176
150224
  Return ONLY the corrected string in the specified JSON format with the key 'corrected_string_escaping'. If no escaping correction is needed, return the original potentially_problematic_string.
150177
150225
  `.trim();
150178
150226
  const contents = [{ role: "user", parts: [{ text: prompt }] }];
150227
+ const filteredContents = filterIncompleteToolCalls(contents);
150179
150228
  try {
150180
- const result = await client.generateJson(contents, CORRECT_STRING_ESCAPING_SCHEMA, abortSignal, EditModel, EditConfig);
150229
+ const result = await client.generateJson(filteredContents, CORRECT_STRING_ESCAPING_SCHEMA, abortSignal, EditModel, EditConfig);
150181
150230
  if (result && typeof result.corrected_string_escaping === "string" && result.corrected_string_escaping.length > 0) {
150182
150231
  return result.corrected_string_escaping;
150183
150232
  } else {
@@ -157071,12 +157120,24 @@ async function checkNextSpeaker(chat, geminiClient, abortSignal) {
157071
157120
  if (!lastMessage || lastMessage.role !== "model") {
157072
157121
  return null;
157073
157122
  }
157123
+ const hasIncompleteToolCalls = checkForIncompleteToolCalls(curatedHistory);
157124
+ if (hasIncompleteToolCalls) {
157125
+ return {
157126
+ reasoning: "There are pending tool calls that need to be processed, so the model should speak next.",
157127
+ next_speaker: "model"
157128
+ };
157129
+ }
157074
157130
  const contents = [
157075
157131
  ...curatedHistory,
157076
157132
  { role: "user", parts: [{ text: CHECK_PROMPT }] }
157077
157133
  ];
157134
+ const filteredContents = checkForIncompleteToolCalls(contents) ? contents.filter((message) => {
157135
+ if (!message.parts)
157136
+ return true;
157137
+ return !message.parts.some((part) => part.functionCall?.id);
157138
+ }) : contents;
157078
157139
  try {
157079
- const parsedResponse = await geminiClient.generateJson(contents, RESPONSE_SCHEMA, abortSignal);
157140
+ const parsedResponse = await geminiClient.generateJson(filteredContents, RESPONSE_SCHEMA, abortSignal);
157080
157141
  if (parsedResponse && parsedResponse.next_speaker && ["user", "model"].includes(parsedResponse.next_speaker)) {
157081
157142
  return parsedResponse;
157082
157143
  }
@@ -157086,6 +157147,28 @@ async function checkNextSpeaker(chat, geminiClient, abortSignal) {
157086
157147
  return null;
157087
157148
  }
157088
157149
  }
157150
+ function checkForIncompleteToolCalls(history) {
157151
+ const toolCallIds = /* @__PURE__ */ new Set();
157152
+ const toolResponseIds = /* @__PURE__ */ new Set();
157153
+ for (const message of history) {
157154
+ if (message.parts) {
157155
+ for (const part of message.parts) {
157156
+ if (part.functionCall?.id) {
157157
+ toolCallIds.add(part.functionCall.id);
157158
+ }
157159
+ if (part.functionResponse?.id) {
157160
+ toolResponseIds.add(part.functionResponse.id);
157161
+ }
157162
+ }
157163
+ }
157164
+ }
157165
+ for (const callId of toolCallIds) {
157166
+ if (!toolResponseIds.has(callId)) {
157167
+ return true;
157168
+ }
157169
+ }
157170
+ return false;
157171
+ }
157089
157172
 
157090
157173
  // packages/core/dist/src/core/geminiChat.js
157091
157174
  import { createUserContent } from "@google/genai";
@@ -164746,12 +164829,19 @@ var CoreToolScheduler = class {
164746
164829
  return this.toolCalls.some((call) => call.status === "executing" || call.status === "awaiting_approval");
164747
164830
  }
164748
164831
  async schedule(request2, signal) {
164832
+ if (process.env.DEBUG === "true" || process.env.DEBUG_MODE === "true" || process.env.dev === "true") {
164833
+ console.error(`[MCP DEBUG] CoreToolScheduler.schedule called`);
164834
+ console.error(`[MCP DEBUG] Request:`, JSON.stringify(request2, null, 2));
164835
+ }
164749
164836
  if (this.isRunning()) {
164750
164837
  throw new Error("Cannot schedule new tool calls while other tool calls are actively running (executing or awaiting approval).");
164751
164838
  }
164752
164839
  const requestsToProcess = Array.isArray(request2) ? request2 : [request2];
164753
164840
  const toolRegistry = await this.toolRegistry;
164754
164841
  const newToolCalls = requestsToProcess.map((reqInfo) => {
164842
+ if (process.env.DEBUG === "true" || process.env.DEBUG_MODE === "true" || process.env.dev === "true") {
164843
+ console.error(`[MCP DEBUG] Processing request:`, JSON.stringify(reqInfo, null, 2));
164844
+ }
164755
164845
  const toolInstance = toolRegistry.getTool(reqInfo.name);
164756
164846
  if (!toolInstance) {
164757
164847
  return {
@@ -164779,6 +164869,10 @@ var CoreToolScheduler = class {
164779
164869
  if (this.approvalMode === ApprovalMode.YOLO || process.env.YOLO) {
164780
164870
  this.setStatusInternal(reqInfo.callId, "scheduled");
164781
164871
  } else {
164872
+ if (process.env.DEBUG === "true" || process.env.DEBUG_MODE === "true" || process.env.dev === "true") {
164873
+ console.error(`[MCP DEBUG] CoreToolScheduler calling shouldConfirmExecute for: ${reqInfo.name}`);
164874
+ console.error(`[MCP DEBUG] Request args:`, JSON.stringify(reqInfo.args, null, 2));
164875
+ }
164782
164876
  const confirmationDetails = await toolInstance.shouldConfirmExecute(reqInfo.args, signal);
164783
164877
  if (confirmationDetails) {
164784
164878
  const originalOnConfirm = confirmationDetails.onConfirm;
@@ -165270,7 +165364,7 @@ async function getPackageJson() {
165270
165364
  // packages/cli/src/utils/version.ts
165271
165365
  async function getCliVersion() {
165272
165366
  const pkgJson = await getPackageJson();
165273
- return "0.1.11";
165367
+ return "0.1.13";
165274
165368
  }
165275
165369
 
165276
165370
  // packages/cli/src/config/sandboxConfig.ts
package/bundle/gemini.js CHANGED
@@ -78252,7 +78252,7 @@ async function createContentGeneratorConfig(model, authType) {
78252
78252
  return contentGeneratorConfig;
78253
78253
  }
78254
78254
  async function createContentGenerator(config2, sessionId2) {
78255
- const version3 = "0.1.11";
78255
+ const version3 = "0.1.13";
78256
78256
  const httpOptions = {
78257
78257
  headers: {
78258
78258
  "User-Agent": `GeminiCLI/${version3} (${process.platform}; ${process.arch})`
@@ -149312,7 +149312,7 @@ var require_homedir = __commonJS({
149312
149312
  "node_modules/resolve/lib/homedir.js"(exports2, module2) {
149313
149313
  "use strict";
149314
149314
  var os23 = __require("os");
149315
- module2.exports = os23.homedir || function homedir14() {
149315
+ module2.exports = os23.homedir || function homedir15() {
149316
149316
  var home = process.env.HOME;
149317
149317
  var user = process.env.LOGNAME || process.env.USER || process.env.LNAME || process.env.USERNAME;
149318
149318
  if (process.platform === "win32") {
@@ -149793,11 +149793,11 @@ var require_async2 = __commonJS({
149793
149793
  var normalizeOptions = require_normalize_options();
149794
149794
  var isCore = require_is_core_module();
149795
149795
  var realpathFS = process.platform !== "win32" && fs51.realpath && typeof fs51.realpath.native === "function" ? fs51.realpath.native : fs51.realpath;
149796
- var homedir14 = getHomedir();
149796
+ var homedir15 = getHomedir();
149797
149797
  var defaultPaths = function() {
149798
149798
  return [
149799
- path53.join(homedir14, ".node_modules"),
149800
- path53.join(homedir14, ".node_libraries")
149799
+ path53.join(homedir15, ".node_modules"),
149800
+ path53.join(homedir15, ".node_libraries")
149801
149801
  ];
149802
149802
  };
149803
149803
  var defaultIsFile = function isFile(file, cb) {
@@ -150283,11 +150283,11 @@ var require_sync = __commonJS({
150283
150283
  var nodeModulesPaths = require_node_modules_paths();
150284
150284
  var normalizeOptions = require_normalize_options();
150285
150285
  var realpathFS = process.platform !== "win32" && fs51.realpathSync && typeof fs51.realpathSync.native === "function" ? fs51.realpathSync.native : fs51.realpathSync;
150286
- var homedir14 = getHomedir();
150286
+ var homedir15 = getHomedir();
150287
150287
  var defaultPaths = function() {
150288
150288
  return [
150289
- path53.join(homedir14, ".node_modules"),
150290
- path53.join(homedir14, ".node_libraries")
150289
+ path53.join(homedir15, ".node_modules"),
150290
+ path53.join(homedir15, ".node_libraries")
150291
150291
  ];
150292
150292
  };
150293
150293
  var defaultIsFile = function isFile(file) {
@@ -190619,7 +190619,7 @@ var require_require_directory = __commonJS({
190619
190619
  "node_modules/require-directory/index.js"(exports2, module2) {
190620
190620
  "use strict";
190621
190621
  var fs51 = __require("fs");
190622
- var join22 = __require("path").join;
190622
+ var join23 = __require("path").join;
190623
190623
  var resolve18 = __require("path").resolve;
190624
190624
  var dirname11 = __require("path").dirname;
190625
190625
  var defaultOptions2 = {
@@ -190656,7 +190656,7 @@ var require_require_directory = __commonJS({
190656
190656
  }
190657
190657
  path53 = !path53 ? dirname11(m.filename) : resolve18(dirname11(m.filename), path53);
190658
190658
  fs51.readdirSync(path53).forEach(function(filename) {
190659
- var joined = join22(path53, filename), files, key, obj;
190659
+ var joined = join23(path53, filename), files, key, obj;
190660
190660
  if (fs51.statSync(joined).isDirectory() && options.recurse) {
190661
190661
  files = requireDirectory(m, joined, options);
190662
190662
  if (Object.keys(files).length) {
@@ -194426,7 +194426,7 @@ var require_minimist = __commonJS({
194426
194426
  var require_rc = __commonJS({
194427
194427
  "node_modules/rc/index.js"(exports2, module2) {
194428
194428
  var cc = require_utils13();
194429
- var join22 = __require("path").join;
194429
+ var join23 = __require("path").join;
194430
194430
  var deepExtend = require_deep_extend();
194431
194431
  var etc = "/etc";
194432
194432
  var win = process.platform === "win32";
@@ -194451,15 +194451,15 @@ var require_rc = __commonJS({
194451
194451
  }
194452
194452
  if (!win)
194453
194453
  [
194454
- join22(etc, name2, "config"),
194455
- join22(etc, name2 + "rc")
194454
+ join23(etc, name2, "config"),
194455
+ join23(etc, name2 + "rc")
194456
194456
  ].forEach(addConfigFile);
194457
194457
  if (home)
194458
194458
  [
194459
- join22(home, ".config", name2, "config"),
194460
- join22(home, ".config", name2),
194461
- join22(home, "." + name2, "config"),
194462
- join22(home, "." + name2 + "rc")
194459
+ join23(home, ".config", name2, "config"),
194460
+ join23(home, ".config", name2),
194461
+ join23(home, "." + name2, "config"),
194462
+ join23(home, "." + name2 + "rc")
194463
194463
  ].forEach(addConfigFile);
194464
194464
  addConfigFile(cc.find("." + name2 + "rc"));
194465
194465
  if (env6.config) addConfigFile(env6.config);
@@ -213523,7 +213523,13 @@ var DiscoveredMCPTool = class _DiscoveredMCPTool extends BaseTool {
213523
213523
  this.timeout = timeout2;
213524
213524
  this.trust = trust;
213525
213525
  }
213526
- async shouldConfirmExecute(_params, _abortSignal) {
213526
+ async shouldConfirmExecute(params, _abortSignal) {
213527
+ if (process.env.DEBUG === "true" || process.env.DEBUG_MODE === "true" || process.env.dev === "true") {
213528
+ console.error(`[MCP DEBUG] shouldConfirmExecute called for tool: ${this.name}`);
213529
+ console.error(`[MCP DEBUG] Received params:`, JSON.stringify(params, null, 2));
213530
+ console.error(`[MCP DEBUG] Params type:`, typeof params);
213531
+ console.error(`[MCP DEBUG] Params keys:`, Object.keys(params));
213532
+ }
213527
213533
  const serverAllowListKey = this.serverName;
213528
213534
  const toolAllowListKey = `${this.serverName}.${this.serverToolName}`;
213529
213535
  if (process.env.YOLO) {
@@ -213543,6 +213549,8 @@ var DiscoveredMCPTool = class _DiscoveredMCPTool extends BaseTool {
213543
213549
  // Display original tool name in confirmation
213544
213550
  toolDisplayName: this.name,
213545
213551
  // Display global registry name exposed to model and user
213552
+ args: params,
213553
+ // Include the parameters
213546
213554
  onConfirm: async (outcome) => {
213547
213555
  if (outcome === ToolConfirmationOutcome.ProceedAlwaysServer) {
213548
213556
  _DiscoveredMCPTool.allowlist.add(serverAllowListKey);
@@ -213713,7 +213721,9 @@ Make sure it is available in the sandbox`;
213713
213721
  return;
213714
213722
  }
213715
213723
  mcpClient.onerror = (error) => {
213716
- console.error(`MCP ERROR (${mcpServerName}):`, error.toString());
213724
+ if (process.env.DEBUG === "true" || process.env.DEBUG_MODE === "true" || process.env.dev === "true") {
213725
+ console.error(`MCP ERROR (${mcpServerName}):`, error.toString());
213726
+ }
213717
213727
  updateMCPServerStatus(mcpServerName, MCPServerStatus.DISCONNECTED);
213718
213728
  };
213719
213729
  if (transport instanceof StdioClientTransport && transport.stderr) {
@@ -213763,8 +213773,15 @@ Make sure it is available in the sandbox`;
213763
213773
  if (toolNameForModel.length > 63) {
213764
213774
  toolNameForModel = toolNameForModel.slice(0, 28) + "___" + toolNameForModel.slice(-32);
213765
213775
  }
213766
- sanitizeParameters(funcDecl.parameters);
213767
- toolRegistry.registerTool(new DiscoveredMCPTool(mcpCallableTool, mcpServerName, toolNameForModel, funcDecl.description ?? "", funcDecl.parameters ?? { type: Type.OBJECT, properties: {} }, funcDecl.name, mcpServerConfig.timeout ?? MCP_DEFAULT_TIMEOUT_MSEC, mcpServerConfig.trust));
213776
+ if (process.env.DEBUG === "true" || process.env.DEBUG_MODE === "true" || process.env.dev === "true") {
213777
+ console.error(`[MCP DEBUG] Registering tool: ${toolNameForModel} (server: ${mcpServerName}, original: ${funcDecl.name})`);
213778
+ console.error(`[MCP DEBUG] Tool parameters:`, JSON.stringify(funcDecl.parameters, null, 2));
213779
+ console.error(`[MCP DEBUG] Tool parametersJsonSchema:`, JSON.stringify(funcDecl.parametersJsonSchema, null, 2));
213780
+ console.error(`[MCP DEBUG] Tool description:`, funcDecl.description);
213781
+ }
213782
+ const parametersSchema = funcDecl.parameters || funcDecl.parametersJsonSchema || { type: Type.OBJECT, properties: {} };
213783
+ sanitizeParameters(parametersSchema);
213784
+ toolRegistry.registerTool(new DiscoveredMCPTool(mcpCallableTool, mcpServerName, toolNameForModel, funcDecl.description ?? "", parametersSchema, funcDecl.name, mcpServerConfig.timeout ?? MCP_DEFAULT_TIMEOUT_MSEC, mcpServerConfig.trust));
213768
213785
  }
213769
213786
  } catch (error) {
213770
213787
  console.error(`Failed to list or register tools for MCP server '${mcpServerName}': ${error}`);
@@ -223388,6 +223405,34 @@ function isFunctionCall(content) {
223388
223405
 
223389
223406
  // packages/core/dist/src/utils/editCorrector.js
223390
223407
  import * as fs15 from "fs";
223408
+ function filterIncompleteToolCalls(contents) {
223409
+ const toolCallIds = /* @__PURE__ */ new Set();
223410
+ const toolResponseIds = /* @__PURE__ */ new Set();
223411
+ for (const message of contents) {
223412
+ if (message.parts) {
223413
+ for (const part of message.parts) {
223414
+ if (part.functionCall?.id) {
223415
+ toolCallIds.add(part.functionCall.id);
223416
+ }
223417
+ if (part.functionResponse?.id) {
223418
+ toolResponseIds.add(part.functionResponse.id);
223419
+ }
223420
+ }
223421
+ }
223422
+ }
223423
+ return contents.filter((message) => {
223424
+ if (!message.parts)
223425
+ return true;
223426
+ for (const part of message.parts) {
223427
+ if (part.functionCall?.id) {
223428
+ if (!toolResponseIds.has(part.functionCall.id)) {
223429
+ return false;
223430
+ }
223431
+ }
223432
+ }
223433
+ return true;
223434
+ });
223435
+ }
223391
223436
  var EditModel = DEFAULT_GEMINI_FLASH_MODEL;
223392
223437
  var EditConfig = {
223393
223438
  thinkingConfig: {
@@ -223617,8 +223662,9 @@ If the differences are only in whitespace or formatting, apply similar whitespac
223617
223662
  Return ONLY the corrected target snippet in the specified JSON format with the key 'corrected_target_snippet'. If no clear, unique match can be found, return an empty string for 'corrected_target_snippet'.
223618
223663
  `.trim();
223619
223664
  const contents = [{ role: "user", parts: [{ text: prompt }] }];
223665
+ const filteredContents = filterIncompleteToolCalls(contents);
223620
223666
  try {
223621
- const result = await geminiClient.generateJson(contents, OLD_STRING_CORRECTION_SCHEMA, abortSignal, EditModel, EditConfig);
223667
+ const result = await geminiClient.generateJson(filteredContents, OLD_STRING_CORRECTION_SCHEMA, abortSignal, EditModel, EditConfig);
223622
223668
  if (result && typeof result.corrected_target_snippet === "string" && result.corrected_target_snippet.length > 0) {
223623
223669
  return result.corrected_target_snippet;
223624
223670
  } else {
@@ -223675,8 +223721,9 @@ If the differences are only in whitespace or formatting, apply similar whitespac
223675
223721
  Return ONLY the corrected string in the specified JSON format with the key 'corrected_new_string'. If no adjustment is deemed necessary or possible, return the original_new_string.
223676
223722
  `.trim();
223677
223723
  const contents = [{ role: "user", parts: [{ text: prompt }] }];
223724
+ const filteredContents = filterIncompleteToolCalls(contents);
223678
223725
  try {
223679
- const result = await geminiClient.generateJson(contents, NEW_STRING_CORRECTION_SCHEMA, abortSignal, EditModel, EditConfig);
223726
+ const result = await geminiClient.generateJson(filteredContents, NEW_STRING_CORRECTION_SCHEMA, abortSignal, EditModel, EditConfig);
223680
223727
  if (result && typeof result.corrected_new_string === "string" && result.corrected_new_string.length > 0) {
223681
223728
  return result.corrected_new_string;
223682
223729
  } else {
@@ -223725,8 +223772,9 @@ If potentially_problematic_new_string is console.log(\\"Hello World\\"), it shou
223725
223772
  Return ONLY the corrected string in the specified JSON format with the key 'corrected_new_string_escaping'. If no escaping correction is needed, return the original potentially_problematic_new_string.
223726
223773
  `.trim();
223727
223774
  const contents = [{ role: "user", parts: [{ text: prompt }] }];
223775
+ const filteredContents = filterIncompleteToolCalls(contents);
223728
223776
  try {
223729
- const result = await geminiClient.generateJson(contents, CORRECT_NEW_STRING_ESCAPING_SCHEMA, abortSignal, EditModel, EditConfig);
223777
+ const result = await geminiClient.generateJson(filteredContents, CORRECT_NEW_STRING_ESCAPING_SCHEMA, abortSignal, EditModel, EditConfig);
223730
223778
  if (result && typeof result.corrected_new_string_escaping === "string" && result.corrected_new_string_escaping.length > 0) {
223731
223779
  return result.corrected_new_string_escaping;
223732
223780
  } else {
@@ -223770,8 +223818,9 @@ If potentially_problematic_string is console.log(\\"Hello World\\"), it should b
223770
223818
  Return ONLY the corrected string in the specified JSON format with the key 'corrected_string_escaping'. If no escaping correction is needed, return the original potentially_problematic_string.
223771
223819
  `.trim();
223772
223820
  const contents = [{ role: "user", parts: [{ text: prompt }] }];
223821
+ const filteredContents = filterIncompleteToolCalls(contents);
223773
223822
  try {
223774
- const result = await client.generateJson(contents, CORRECT_STRING_ESCAPING_SCHEMA, abortSignal, EditModel, EditConfig);
223823
+ const result = await client.generateJson(filteredContents, CORRECT_STRING_ESCAPING_SCHEMA, abortSignal, EditModel, EditConfig);
223775
223824
  if (result && typeof result.corrected_string_escaping === "string" && result.corrected_string_escaping.length > 0) {
223776
223825
  return result.corrected_string_escaping;
223777
223826
  } else {
@@ -225232,8 +225281,8 @@ function many(p) {
225232
225281
  function many1(p) {
225233
225282
  return ab(p, many(p), (head, tail) => [head, ...tail]);
225234
225283
  }
225235
- function ab(pa, pb, join22) {
225236
- return (data, i) => mapOuter(pa(data, i), (ma) => mapInner(pb(data, ma.position), (vb, j) => join22(ma.value, vb, data, i, j)));
225284
+ function ab(pa, pb, join23) {
225285
+ return (data, i) => mapOuter(pa(data, i), (ma) => mapInner(pb(data, ma.position), (vb, j) => join23(ma.value, vb, data, i, j)));
225237
225286
  }
225238
225287
  function left(pa, pb) {
225239
225288
  return ab(pa, pb, (va) => va);
@@ -225241,8 +225290,8 @@ function left(pa, pb) {
225241
225290
  function right(pa, pb) {
225242
225291
  return ab(pa, pb, (va, vb) => vb);
225243
225292
  }
225244
- function abc(pa, pb, pc, join22) {
225245
- return (data, i) => mapOuter(pa(data, i), (ma) => mapOuter(pb(data, ma.position), (mb) => mapInner(pc(data, mb.position), (vc, j) => join22(ma.value, mb.value, vc, data, i, j))));
225293
+ function abc(pa, pb, pc, join23) {
225294
+ return (data, i) => mapOuter(pa(data, i), (ma) => mapOuter(pb(data, ma.position), (mb) => mapInner(pc(data, mb.position), (vc, j) => join23(ma.value, mb.value, vc, data, i, j))));
225246
225295
  }
225247
225296
  function middle(pa, pb, pc) {
225248
225297
  return abc(pa, pb, pc, (ra, rb) => rb);
@@ -230644,12 +230693,24 @@ async function checkNextSpeaker(chat, geminiClient, abortSignal) {
230644
230693
  if (!lastMessage || lastMessage.role !== "model") {
230645
230694
  return null;
230646
230695
  }
230696
+ const hasIncompleteToolCalls = checkForIncompleteToolCalls(curatedHistory);
230697
+ if (hasIncompleteToolCalls) {
230698
+ return {
230699
+ reasoning: "There are pending tool calls that need to be processed, so the model should speak next.",
230700
+ next_speaker: "model"
230701
+ };
230702
+ }
230647
230703
  const contents = [
230648
230704
  ...curatedHistory,
230649
230705
  { role: "user", parts: [{ text: CHECK_PROMPT }] }
230650
230706
  ];
230707
+ const filteredContents = checkForIncompleteToolCalls(contents) ? contents.filter((message) => {
230708
+ if (!message.parts)
230709
+ return true;
230710
+ return !message.parts.some((part) => part.functionCall?.id);
230711
+ }) : contents;
230651
230712
  try {
230652
- const parsedResponse = await geminiClient.generateJson(contents, RESPONSE_SCHEMA, abortSignal);
230713
+ const parsedResponse = await geminiClient.generateJson(filteredContents, RESPONSE_SCHEMA, abortSignal);
230653
230714
  if (parsedResponse && parsedResponse.next_speaker && ["user", "model"].includes(parsedResponse.next_speaker)) {
230654
230715
  return parsedResponse;
230655
230716
  }
@@ -230659,6 +230720,28 @@ async function checkNextSpeaker(chat, geminiClient, abortSignal) {
230659
230720
  return null;
230660
230721
  }
230661
230722
  }
230723
+ function checkForIncompleteToolCalls(history) {
230724
+ const toolCallIds = /* @__PURE__ */ new Set();
230725
+ const toolResponseIds = /* @__PURE__ */ new Set();
230726
+ for (const message of history) {
230727
+ if (message.parts) {
230728
+ for (const part of message.parts) {
230729
+ if (part.functionCall?.id) {
230730
+ toolCallIds.add(part.functionCall.id);
230731
+ }
230732
+ if (part.functionResponse?.id) {
230733
+ toolResponseIds.add(part.functionResponse.id);
230734
+ }
230735
+ }
230736
+ }
230737
+ }
230738
+ for (const callId of toolCallIds) {
230739
+ if (!toolResponseIds.has(callId)) {
230740
+ return true;
230741
+ }
230742
+ }
230743
+ return false;
230744
+ }
230662
230745
 
230663
230746
  // packages/core/dist/src/core/geminiChat.js
230664
230747
  init_node();
@@ -238601,12 +238684,19 @@ var CoreToolScheduler = class {
238601
238684
  return this.toolCalls.some((call) => call.status === "executing" || call.status === "awaiting_approval");
238602
238685
  }
238603
238686
  async schedule(request2, signal) {
238687
+ if (process.env.DEBUG === "true" || process.env.DEBUG_MODE === "true" || process.env.dev === "true") {
238688
+ console.error(`[MCP DEBUG] CoreToolScheduler.schedule called`);
238689
+ console.error(`[MCP DEBUG] Request:`, JSON.stringify(request2, null, 2));
238690
+ }
238604
238691
  if (this.isRunning()) {
238605
238692
  throw new Error("Cannot schedule new tool calls while other tool calls are actively running (executing or awaiting approval).");
238606
238693
  }
238607
238694
  const requestsToProcess = Array.isArray(request2) ? request2 : [request2];
238608
238695
  const toolRegistry = await this.toolRegistry;
238609
238696
  const newToolCalls = requestsToProcess.map((reqInfo) => {
238697
+ if (process.env.DEBUG === "true" || process.env.DEBUG_MODE === "true" || process.env.dev === "true") {
238698
+ console.error(`[MCP DEBUG] Processing request:`, JSON.stringify(reqInfo, null, 2));
238699
+ }
238610
238700
  const toolInstance = toolRegistry.getTool(reqInfo.name);
238611
238701
  if (!toolInstance) {
238612
238702
  return {
@@ -238634,6 +238724,10 @@ var CoreToolScheduler = class {
238634
238724
  if (this.approvalMode === ApprovalMode.YOLO || process.env.YOLO) {
238635
238725
  this.setStatusInternal(reqInfo.callId, "scheduled");
238636
238726
  } else {
238727
+ if (process.env.DEBUG === "true" || process.env.DEBUG_MODE === "true" || process.env.dev === "true") {
238728
+ console.error(`[MCP DEBUG] CoreToolScheduler calling shouldConfirmExecute for: ${reqInfo.name}`);
238729
+ console.error(`[MCP DEBUG] Request args:`, JSON.stringify(reqInfo.args, null, 2));
238730
+ }
238637
238731
  const confirmationDetails = await toolInstance.shouldConfirmExecute(reqInfo.args, signal);
238638
238732
  if (confirmationDetails) {
238639
238733
  const originalOnConfirm = confirmationDetails.onConfirm;
@@ -243850,7 +243944,7 @@ var LangfuseClient = class {
243850
243944
  name: "MPD LLM CLI Session",
243851
243945
  metadata: {
243852
243946
  ...safeMetadata,
243853
- cli_version: this.safeString("0.1.11", "unknown"),
243947
+ cli_version: this.safeString("0.1.13", "unknown"),
243854
243948
  model: this.safeString(process.env.CUSTOM_LLM_MODEL_NAME, "gemini"),
243855
243949
  auth_type: process.env.USE_CUSTOM_LLM ? "custom_llm" : "google_oauth",
243856
243950
  environment: this.safeString(this.configManager.getConfig()?.environment, "unknown")
@@ -244881,7 +244975,7 @@ var LangfuseIntegration = class {
244881
244975
  const metadata = {
244882
244976
  model: this.config.getModel(),
244883
244977
  auth_type: this.config.getContentGeneratorConfig()?.authType,
244884
- cli_version: "0.1.11",
244978
+ cli_version: "0.1.13",
244885
244979
  start_time: (/* @__PURE__ */ new Date()).toISOString(),
244886
244980
  session_id: this.sessionId
244887
244981
  };
@@ -244951,7 +245045,7 @@ var LangfuseIntegration = class {
244951
245045
  error,
244952
245046
  metadata: {
244953
245047
  session_id: this.sessionId,
244954
- cli_version: "0.1.11",
245048
+ cli_version: "0.1.13",
244955
245049
  auth_type: this.config.getContentGeneratorConfig()?.authType
244956
245050
  }
244957
245051
  });
@@ -248677,7 +248771,7 @@ import { promises as fs33 } from "fs";
248677
248771
  import path37 from "path";
248678
248772
 
248679
248773
  // packages/cli/src/generated/git-commit.ts
248680
- var GIT_COMMIT_INFO = "8163082 (local modifications)";
248774
+ var GIT_COMMIT_INFO = "a4e2bd1 (local modifications)";
248681
248775
 
248682
248776
  // node_modules/read-package-up/index.js
248683
248777
  import path35 from "node:path";
@@ -248890,7 +248984,7 @@ async function getPackageJson() {
248890
248984
  // packages/cli/src/utils/version.ts
248891
248985
  async function getCliVersion() {
248892
248986
  const pkgJson = await getPackageJson();
248893
- return "0.1.11";
248987
+ return "0.1.13";
248894
248988
  }
248895
248989
 
248896
248990
  // packages/cli/src/ui/commands/memoryCommand.ts
@@ -249007,11 +249101,76 @@ var clearCommand = {
249007
249101
  }
249008
249102
  };
249009
249103
 
249104
+ // packages/cli/src/ui/commands/logoutCommand.ts
249105
+ import { existsSync as existsSync7, unlinkSync } from "fs";
249106
+ import { join as join12 } from "path";
249107
+ import { homedir as homedir7 } from "os";
249108
+ var logoutCommand = {
249109
+ name: "logout",
249110
+ description: "logout and clear user credentials and settings, then exit",
249111
+ action: async (context2, _args) => {
249112
+ const now = /* @__PURE__ */ new Date();
249113
+ const { sessionStartTime } = context2.session.stats;
249114
+ const wallDuration = now.getTime() - sessionStartTime.getTime();
249115
+ const userJsonPath = join12(homedir7(), ".gemini", "user.json");
249116
+ if (existsSync7(userJsonPath)) {
249117
+ try {
249118
+ unlinkSync(userJsonPath);
249119
+ context2.ui.addItem({
249120
+ type: "info" /* INFO */,
249121
+ text: "\u2705 User credentials cleared"
249122
+ }, now.getTime());
249123
+ } catch (error) {
249124
+ context2.ui.addItem({
249125
+ type: "error" /* ERROR */,
249126
+ text: `\u274C Failed to clear user credentials: ${error}`
249127
+ }, now.getTime());
249128
+ }
249129
+ }
249130
+ const userSettingsPath = join12(homedir7(), ".gemini", "settings.json");
249131
+ if (existsSync7(userSettingsPath)) {
249132
+ try {
249133
+ unlinkSync(userSettingsPath);
249134
+ context2.ui.addItem({
249135
+ type: "info" /* INFO */,
249136
+ text: "\u2705 User settings cleared"
249137
+ }, now.getTime());
249138
+ } catch (error) {
249139
+ context2.ui.addItem({
249140
+ type: "error" /* ERROR */,
249141
+ text: `\u274C Failed to clear user settings: ${error}`
249142
+ }, now.getTime());
249143
+ }
249144
+ }
249145
+ setTimeout(() => {
249146
+ process.exit(0);
249147
+ }, 100);
249148
+ return {
249149
+ type: "message",
249150
+ messageType: "info",
249151
+ content: `\u{1F44B} Logging out... Session duration: ${formatDuration2(wallDuration)}`
249152
+ };
249153
+ }
249154
+ };
249155
+ function formatDuration2(milliseconds) {
249156
+ const seconds = Math.floor(milliseconds / 1e3);
249157
+ const minutes = Math.floor(seconds / 60);
249158
+ const hours = Math.floor(minutes / 60);
249159
+ if (hours > 0) {
249160
+ return `${hours}h ${minutes % 60}m ${seconds % 60}s`;
249161
+ } else if (minutes > 0) {
249162
+ return `${minutes}m ${seconds % 60}s`;
249163
+ } else {
249164
+ return `${seconds}s`;
249165
+ }
249166
+ }
249167
+
249010
249168
  // packages/cli/src/services/CommandService.ts
249011
249169
  var loadBuiltInCommands = async () => [
249012
249170
  clearCommand,
249013
249171
  helpCommand,
249014
- memoryCommand
249172
+ memoryCommand,
249173
+ logoutCommand
249015
249174
  ];
249016
249175
  var CommandService = class {
249017
249176
  constructor(commandLoader = loadBuiltInCommands) {
@@ -266116,10 +266275,10 @@ var getLanguageFromExtension = (extension) => {
266116
266275
  var dotenv = __toESM(require_main(), 1);
266117
266276
  import * as fs36 from "fs";
266118
266277
  import * as path40 from "path";
266119
- import { homedir as homedir7 } from "os";
266278
+ import { homedir as homedir8 } from "os";
266120
266279
  var import_strip_json_comments = __toESM(require_strip_json_comments(), 1);
266121
266280
  var SETTINGS_DIRECTORY_NAME = ".gemini";
266122
- var USER_SETTINGS_DIR = path40.join(homedir7(), SETTINGS_DIRECTORY_NAME);
266281
+ var USER_SETTINGS_DIR = path40.join(homedir8(), SETTINGS_DIRECTORY_NAME);
266123
266282
  var USER_SETTINGS_PATH = path40.join(USER_SETTINGS_DIR, "settings.json");
266124
266283
  var LoadedSettings = class {
266125
266284
  constructor(user, workspace, errors) {
@@ -266202,11 +266361,11 @@ function findEnvFile(startDir) {
266202
266361
  }
266203
266362
  const parentDir = path40.dirname(currentDir);
266204
266363
  if (parentDir === currentDir || !parentDir) {
266205
- const homeGeminiEnvPath = path40.join(homedir7(), GEMINI_CONFIG_DIR, ".env");
266364
+ const homeGeminiEnvPath = path40.join(homedir8(), GEMINI_CONFIG_DIR, ".env");
266206
266365
  if (fs36.existsSync(homeGeminiEnvPath)) {
266207
266366
  return homeGeminiEnvPath;
266208
266367
  }
266209
- const homeEnvPath = path40.join(homedir7(), ".env");
266368
+ const homeEnvPath = path40.join(homedir8(), ".env");
266210
266369
  if (fs36.existsSync(homeEnvPath)) {
266211
266370
  return homeEnvPath;
266212
266371
  }
@@ -269733,7 +269892,7 @@ var import_react62 = __toESM(require_react(), 1);
269733
269892
  // packages/cli/src/telemetry/dataCollector.ts
269734
269893
  import { execSync as execSync2 } from "child_process";
269735
269894
  import { promises as fs38 } from "fs";
269736
- import { join as join16 } from "path";
269895
+ import { join as join17 } from "path";
269737
269896
  var DataCollector = class {
269738
269897
  langfuseClient;
269739
269898
  constructor() {
@@ -269843,7 +270002,7 @@ var DataCollector = class {
269843
270002
  // 提取元数据
269844
270003
  extractMetadata(data) {
269845
270004
  return {
269846
- cli_version: "0.1.11",
270005
+ cli_version: "0.1.13",
269847
270006
  model: process.env.CUSTOM_LLM_MODEL_NAME || "gemini",
269848
270007
  auth_type: process.env.USE_CUSTOM_LLM ? "custom_llm" : "google_oauth",
269849
270008
  project_path: data.projectPath,
@@ -270060,7 +270219,7 @@ var DataCollector = class {
270060
270219
  const walkDir = async (dir) => {
270061
270220
  const entries = await fs38.readdir(dir, { withFileTypes: true });
270062
270221
  for (const entry of entries) {
270063
- const fullPath = join16(dir, entry.name);
270222
+ const fullPath = join17(dir, entry.name);
270064
270223
  if (entry.isDirectory()) {
270065
270224
  dirCount++;
270066
270225
  await walkDir(fullPath);
@@ -270350,6 +270509,10 @@ var ToolConfirmationMessage = ({
270350
270509
  /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(Text, { color: Colors.AccentCyan, children: [
270351
270510
  "Tool: ",
270352
270511
  mcpProps.toolName
270512
+ ] }),
270513
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(Box_default, { flexDirection: "column", marginTop: 1, children: [
270514
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Text, { color: Colors.Foreground, children: "Parameters:" }),
270515
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Box_default, { marginLeft: 1, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Text, { color: Colors.Gray, children: mcpProps.args ? JSON.stringify(mcpProps.args, null, 2) : "No parameters" }) })
270353
270516
  ] })
270354
270517
  ] });
270355
270518
  question = `Allow execution of MCP tool "${mcpProps.toolName}" from server "${mcpProps.serverName}"?`;
@@ -277013,10 +277176,10 @@ async function runNonInteractive(config2, input) {
277013
277176
 
277014
277177
  // packages/cli/src/utils/cleanup.ts
277015
277178
  import { promises as fs49 } from "fs";
277016
- import { join as join17 } from "path";
277179
+ import { join as join18 } from "path";
277017
277180
  async function cleanupCheckpoints() {
277018
277181
  const tempDir = getProjectTempDir(process.cwd());
277019
- const checkpointsDir = join17(tempDir, "checkpoints");
277182
+ const checkpointsDir = join18(tempDir, "checkpoints");
277020
277183
  try {
277021
277184
  await fs49.rm(checkpointsDir, { recursive: true, force: true });
277022
277185
  } catch {
@@ -277024,14 +277187,14 @@ async function cleanupCheckpoints() {
277024
277187
  }
277025
277188
 
277026
277189
  // packages/cli/src/services/AuthService.ts
277027
- import { readFileSync as readFileSync13, writeFileSync as writeFileSync5, existsSync as existsSync11, mkdirSync as mkdirSync4 } from "fs";
277028
- import { join as join19 } from "path";
277029
- import { homedir as homedir11 } from "os";
277190
+ import { readFileSync as readFileSync13, writeFileSync as writeFileSync5, existsSync as existsSync12, mkdirSync as mkdirSync4 } from "fs";
277191
+ import { join as join20 } from "path";
277192
+ import { homedir as homedir12 } from "os";
277030
277193
 
277031
277194
  // packages/cli/src/config/mpdaiConfig.ts
277032
- import { readFileSync as readFileSync12, existsSync as existsSync10 } from "fs";
277033
- import { join as join18 } from "path";
277034
- import { homedir as homedir10 } from "os";
277195
+ import { readFileSync as readFileSync12, existsSync as existsSync11 } from "fs";
277196
+ import { join as join19 } from "path";
277197
+ import { homedir as homedir11 } from "os";
277035
277198
  var MpdaiConfigManager = class _MpdaiConfigManager {
277036
277199
  static instance;
277037
277200
  config = null;
@@ -277048,14 +277211,14 @@ var MpdaiConfigManager = class _MpdaiConfigManager {
277048
277211
  return this.config;
277049
277212
  }
277050
277213
  try {
277051
- const userConfigPath = join18(homedir10(), ".gemini", "config.json");
277052
- if (existsSync10(userConfigPath)) {
277214
+ const userConfigPath = join19(homedir11(), ".gemini", "config.json");
277215
+ if (existsSync11(userConfigPath)) {
277053
277216
  const configContent = readFileSync12(userConfigPath, "utf-8");
277054
277217
  this.config = JSON.parse(configContent);
277055
277218
  return this.config;
277056
277219
  }
277057
- const projectConfigPath = join18(process.cwd(), ".mpdai", "config.json");
277058
- if (existsSync10(projectConfigPath)) {
277220
+ const projectConfigPath = join19(process.cwd(), ".mpdai", "config.json");
277221
+ if (existsSync11(projectConfigPath)) {
277059
277222
  const configContent = readFileSync12(projectConfigPath, "utf-8");
277060
277223
  this.config = JSON.parse(configContent);
277061
277224
  return this.config;
@@ -277111,13 +277274,13 @@ var AuthService = class {
277111
277274
  constructor(authApiUrl) {
277112
277275
  this.mpdaiConfig = MpdaiConfigManager.getInstance();
277113
277276
  this.authApiUrl = authApiUrl || this.mpdaiConfig.getAuthUrl();
277114
- this.userJsonPath = join19(homedir11(), ".gemini", "user.json");
277277
+ this.userJsonPath = join20(homedir12(), ".gemini", "user.json");
277115
277278
  }
277116
277279
  /**
277117
277280
  * 检查本地是否存在用户凭据文件
277118
277281
  */
277119
277282
  hasLocalCredentials() {
277120
- return existsSync11(this.userJsonPath);
277283
+ return existsSync12(this.userJsonPath);
277121
277284
  }
277122
277285
  /**
277123
277286
  * 从本地文件读取用户凭据
@@ -277139,8 +277302,8 @@ var AuthService = class {
277139
277302
  */
277140
277303
  saveCredentials(credentials) {
277141
277304
  try {
277142
- const dir = join19(homedir11(), ".gemini");
277143
- if (!existsSync11(dir)) {
277305
+ const dir = join20(homedir12(), ".gemini");
277306
+ if (!existsSync12(dir)) {
277144
277307
  mkdirSync4(dir, { recursive: true });
277145
277308
  }
277146
277309
  writeFileSync5(this.userJsonPath, JSON.stringify(credentials, null, 2), "utf-8");
@@ -277280,9 +277443,9 @@ var AuthService = class {
277280
277443
  };
277281
277444
 
277282
277445
  // packages/cli/src/services/EnvConfigManager.ts
277283
- import { readFileSync as readFileSync14, writeFileSync as writeFileSync6, existsSync as existsSync12, mkdirSync as mkdirSync5 } from "fs";
277284
- import { join as join20, dirname as dirname10 } from "path";
277285
- import { homedir as homedir12 } from "os";
277446
+ import { readFileSync as readFileSync14, writeFileSync as writeFileSync6, existsSync as existsSync13, mkdirSync as mkdirSync5 } from "fs";
277447
+ import { join as join21, dirname as dirname10 } from "path";
277448
+ import { homedir as homedir13 } from "os";
277286
277449
  var EnvConfigManager = class {
277287
277450
  envPaths;
277288
277451
  constructor() {
@@ -277300,17 +277463,17 @@ var EnvConfigManager = class {
277300
277463
  let currentDir = startDir;
277301
277464
  while (true) {
277302
277465
  for (const envPath of this.envPaths) {
277303
- const fullPath = join20(currentDir, envPath);
277304
- if (existsSync12(fullPath)) {
277466
+ const fullPath = join21(currentDir, envPath);
277467
+ if (existsSync13(fullPath)) {
277305
277468
  return fullPath;
277306
277469
  }
277307
277470
  }
277308
- const parentDir = join20(currentDir, "..");
277471
+ const parentDir = join21(currentDir, "..");
277309
277472
  if (parentDir === currentDir) {
277310
- const homeDir2 = homedir12();
277473
+ const homeDir2 = homedir13();
277311
277474
  for (const envPath of this.envPaths) {
277312
- const fullPath = join20(homeDir2, envPath);
277313
- if (existsSync12(fullPath)) {
277475
+ const fullPath = join21(homeDir2, envPath);
277476
+ if (existsSync13(fullPath)) {
277314
277477
  return fullPath;
277315
277478
  }
277316
277479
  }
@@ -277369,7 +277532,7 @@ var EnvConfigManager = class {
277369
277532
  writeEnvFile(envConfig, envPath) {
277370
277533
  try {
277371
277534
  const dir = dirname10(envPath);
277372
- if (!existsSync12(dir)) {
277535
+ if (!existsSync13(dir)) {
277373
277536
  mkdirSync5(dir, { recursive: true });
277374
277537
  }
277375
277538
  const envContent = Object.entries(envConfig).map(([key, value]) => `${key}=${value}`).join("\n") + "\n";
@@ -277384,8 +277547,8 @@ var EnvConfigManager = class {
277384
277547
  * 更新或创建.env文件
277385
277548
  */
277386
277549
  updateEnvFile(model, targetPath) {
277387
- const envPath = targetPath || this.findEnvFile(process.cwd()) || join20(process.cwd(), ".gemini", ".env");
277388
- const existingConfig = existsSync12(envPath) ? this.readEnvFile(envPath) : {};
277550
+ const envPath = targetPath || this.findEnvFile(process.cwd()) || join21(process.cwd(), ".gemini", ".env");
277551
+ const existingConfig = existsSync13(envPath) ? this.readEnvFile(envPath) : {};
277389
277552
  const newConfig = this.generateEnvConfig(model, existingConfig);
277390
277553
  this.writeEnvFile(newConfig, envPath);
277391
277554
  return envPath;
@@ -277408,9 +277571,9 @@ var EnvConfigManager = class {
277408
277571
  // packages/cli/src/config/startup.ts
277409
277572
  import * as fs50 from "fs";
277410
277573
  import * as path52 from "path";
277411
- import { homedir as homedir13 } from "os";
277574
+ import { homedir as homedir14 } from "os";
277412
277575
  function initializeLangfuseConfig() {
277413
- const langfuseDir = path52.join(homedir13(), ".gemini");
277576
+ const langfuseDir = path52.join(homedir14(), ".gemini");
277414
277577
  const settingsFile = path52.join(langfuseDir, "settings.conf");
277415
277578
  try {
277416
277579
  if (!fs50.existsSync(langfuseDir)) {
@@ -277505,8 +277668,9 @@ async function relaunchWithAdditionalArgs(additionalArgs) {
277505
277668
  async function main() {
277506
277669
  loadStartupConfig();
277507
277670
  const workspaceRoot = process.cwd();
277508
- const settings = loadSettings(workspaceRoot);
277671
+ let settings = loadSettings(workspaceRoot);
277509
277672
  await performUserAuthentication();
277673
+ settings = loadSettings(workspaceRoot);
277510
277674
  await cleanupCheckpoints();
277511
277675
  if (settings.errors.length > 0) {
277512
277676
  for (const error of settings.errors) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mpd-llm-cli",
3
- "version": "0.1.11",
3
+ "version": "0.1.13",
4
4
  "engines": {
5
5
  "node": ">=20.0.0"
6
6
  },