mpd-llm-cli 0.1.11 → 0.1.12

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);
@@ -140190,8 +140198,15 @@ Make sure it is available in the sandbox`;
140190
140198
  if (toolNameForModel.length > 63) {
140191
140199
  toolNameForModel = toolNameForModel.slice(0, 28) + "___" + toolNameForModel.slice(-32);
140192
140200
  }
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));
140201
+ if (process.env.DEBUG === "true" || process.env.DEBUG_MODE === "true" || process.env.dev === "true") {
140202
+ console.error(`[MCP DEBUG] Registering tool: ${toolNameForModel} (server: ${mcpServerName}, original: ${funcDecl.name})`);
140203
+ console.error(`[MCP DEBUG] Tool parameters:`, JSON.stringify(funcDecl.parameters, null, 2));
140204
+ console.error(`[MCP DEBUG] Tool parametersJsonSchema:`, JSON.stringify(funcDecl.parametersJsonSchema, null, 2));
140205
+ console.error(`[MCP DEBUG] Tool description:`, funcDecl.description);
140206
+ }
140207
+ const parametersSchema = funcDecl.parameters || funcDecl.parametersJsonSchema || { type: import_genai4.Type.OBJECT, properties: {} };
140208
+ sanitizeParameters(parametersSchema);
140209
+ toolRegistry.registerTool(new DiscoveredMCPTool(mcpCallableTool, mcpServerName, toolNameForModel, funcDecl.description ?? "", parametersSchema, funcDecl.name, mcpServerConfig.timeout ?? MCP_DEFAULT_TIMEOUT_MSEC, mcpServerConfig.trust));
140195
140210
  }
140196
140211
  } catch (error) {
140197
140212
  console.error(`Failed to list or register tools for MCP server '${mcpServerName}': ${error}`);
@@ -149798,6 +149813,34 @@ function isFunctionCall(content) {
149798
149813
 
149799
149814
  // packages/core/dist/src/utils/editCorrector.js
149800
149815
  var fs13 = __toESM(require("fs"), 1);
149816
+ function filterIncompleteToolCalls(contents) {
149817
+ const toolCallIds = /* @__PURE__ */ new Set();
149818
+ const toolResponseIds = /* @__PURE__ */ new Set();
149819
+ for (const message of contents) {
149820
+ if (message.parts) {
149821
+ for (const part of message.parts) {
149822
+ if (part.functionCall?.id) {
149823
+ toolCallIds.add(part.functionCall.id);
149824
+ }
149825
+ if (part.functionResponse?.id) {
149826
+ toolResponseIds.add(part.functionResponse.id);
149827
+ }
149828
+ }
149829
+ }
149830
+ }
149831
+ return contents.filter((message) => {
149832
+ if (!message.parts)
149833
+ return true;
149834
+ for (const part of message.parts) {
149835
+ if (part.functionCall?.id) {
149836
+ if (!toolResponseIds.has(part.functionCall.id)) {
149837
+ return false;
149838
+ }
149839
+ }
149840
+ }
149841
+ return true;
149842
+ });
149843
+ }
149801
149844
  var EditModel = DEFAULT_GEMINI_FLASH_MODEL;
149802
149845
  var EditConfig = {
149803
149846
  thinkingConfig: {
@@ -150027,8 +150070,9 @@ If the differences are only in whitespace or formatting, apply similar whitespac
150027
150070
  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
150071
  `.trim();
150029
150072
  const contents = [{ role: "user", parts: [{ text: prompt }] }];
150073
+ const filteredContents = filterIncompleteToolCalls(contents);
150030
150074
  try {
150031
- const result = await geminiClient.generateJson(contents, OLD_STRING_CORRECTION_SCHEMA, abortSignal, EditModel, EditConfig);
150075
+ const result = await geminiClient.generateJson(filteredContents, OLD_STRING_CORRECTION_SCHEMA, abortSignal, EditModel, EditConfig);
150032
150076
  if (result && typeof result.corrected_target_snippet === "string" && result.corrected_target_snippet.length > 0) {
150033
150077
  return result.corrected_target_snippet;
150034
150078
  } else {
@@ -150085,8 +150129,9 @@ If the differences are only in whitespace or formatting, apply similar whitespac
150085
150129
  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
150130
  `.trim();
150087
150131
  const contents = [{ role: "user", parts: [{ text: prompt }] }];
150132
+ const filteredContents = filterIncompleteToolCalls(contents);
150088
150133
  try {
150089
- const result = await geminiClient.generateJson(contents, NEW_STRING_CORRECTION_SCHEMA, abortSignal, EditModel, EditConfig);
150134
+ const result = await geminiClient.generateJson(filteredContents, NEW_STRING_CORRECTION_SCHEMA, abortSignal, EditModel, EditConfig);
150090
150135
  if (result && typeof result.corrected_new_string === "string" && result.corrected_new_string.length > 0) {
150091
150136
  return result.corrected_new_string;
150092
150137
  } else {
@@ -150135,8 +150180,9 @@ If potentially_problematic_new_string is console.log(\\"Hello World\\"), it shou
150135
150180
  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
150181
  `.trim();
150137
150182
  const contents = [{ role: "user", parts: [{ text: prompt }] }];
150183
+ const filteredContents = filterIncompleteToolCalls(contents);
150138
150184
  try {
150139
- const result = await geminiClient.generateJson(contents, CORRECT_NEW_STRING_ESCAPING_SCHEMA, abortSignal, EditModel, EditConfig);
150185
+ const result = await geminiClient.generateJson(filteredContents, CORRECT_NEW_STRING_ESCAPING_SCHEMA, abortSignal, EditModel, EditConfig);
150140
150186
  if (result && typeof result.corrected_new_string_escaping === "string" && result.corrected_new_string_escaping.length > 0) {
150141
150187
  return result.corrected_new_string_escaping;
150142
150188
  } else {
@@ -150180,8 +150226,9 @@ If potentially_problematic_string is console.log(\\"Hello World\\"), it should b
150180
150226
  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
150227
  `.trim();
150182
150228
  const contents = [{ role: "user", parts: [{ text: prompt }] }];
150229
+ const filteredContents = filterIncompleteToolCalls(contents);
150183
150230
  try {
150184
- const result = await client.generateJson(contents, CORRECT_STRING_ESCAPING_SCHEMA, abortSignal, EditModel, EditConfig);
150231
+ const result = await client.generateJson(filteredContents, CORRECT_STRING_ESCAPING_SCHEMA, abortSignal, EditModel, EditConfig);
150185
150232
  if (result && typeof result.corrected_string_escaping === "string" && result.corrected_string_escaping.length > 0) {
150186
150233
  return result.corrected_string_escaping;
150187
150234
  } else {
@@ -157075,12 +157122,24 @@ async function checkNextSpeaker(chat, geminiClient, abortSignal) {
157075
157122
  if (!lastMessage || lastMessage.role !== "model") {
157076
157123
  return null;
157077
157124
  }
157125
+ const hasIncompleteToolCalls = checkForIncompleteToolCalls(curatedHistory);
157126
+ if (hasIncompleteToolCalls) {
157127
+ return {
157128
+ reasoning: "There are pending tool calls that need to be processed, so the model should speak next.",
157129
+ next_speaker: "model"
157130
+ };
157131
+ }
157078
157132
  const contents = [
157079
157133
  ...curatedHistory,
157080
157134
  { role: "user", parts: [{ text: CHECK_PROMPT }] }
157081
157135
  ];
157136
+ const filteredContents = checkForIncompleteToolCalls(contents) ? contents.filter((message) => {
157137
+ if (!message.parts)
157138
+ return true;
157139
+ return !message.parts.some((part) => part.functionCall?.id);
157140
+ }) : contents;
157082
157141
  try {
157083
- const parsedResponse = await geminiClient.generateJson(contents, RESPONSE_SCHEMA, abortSignal);
157142
+ const parsedResponse = await geminiClient.generateJson(filteredContents, RESPONSE_SCHEMA, abortSignal);
157084
157143
  if (parsedResponse && parsedResponse.next_speaker && ["user", "model"].includes(parsedResponse.next_speaker)) {
157085
157144
  return parsedResponse;
157086
157145
  }
@@ -157090,6 +157149,28 @@ async function checkNextSpeaker(chat, geminiClient, abortSignal) {
157090
157149
  return null;
157091
157150
  }
157092
157151
  }
157152
+ function checkForIncompleteToolCalls(history) {
157153
+ const toolCallIds = /* @__PURE__ */ new Set();
157154
+ const toolResponseIds = /* @__PURE__ */ new Set();
157155
+ for (const message of history) {
157156
+ if (message.parts) {
157157
+ for (const part of message.parts) {
157158
+ if (part.functionCall?.id) {
157159
+ toolCallIds.add(part.functionCall.id);
157160
+ }
157161
+ if (part.functionResponse?.id) {
157162
+ toolResponseIds.add(part.functionResponse.id);
157163
+ }
157164
+ }
157165
+ }
157166
+ }
157167
+ for (const callId of toolCallIds) {
157168
+ if (!toolResponseIds.has(callId)) {
157169
+ return true;
157170
+ }
157171
+ }
157172
+ return false;
157173
+ }
157093
157174
 
157094
157175
  // packages/core/dist/src/core/geminiChat.js
157095
157176
  var import_genai19 = require("@google/genai");
@@ -164750,12 +164831,19 @@ var CoreToolScheduler = class {
164750
164831
  return this.toolCalls.some((call) => call.status === "executing" || call.status === "awaiting_approval");
164751
164832
  }
164752
164833
  async schedule(request2, signal) {
164834
+ if (process.env.DEBUG === "true" || process.env.DEBUG_MODE === "true" || process.env.dev === "true") {
164835
+ console.error(`[MCP DEBUG] CoreToolScheduler.schedule called`);
164836
+ console.error(`[MCP DEBUG] Request:`, JSON.stringify(request2, null, 2));
164837
+ }
164753
164838
  if (this.isRunning()) {
164754
164839
  throw new Error("Cannot schedule new tool calls while other tool calls are actively running (executing or awaiting approval).");
164755
164840
  }
164756
164841
  const requestsToProcess = Array.isArray(request2) ? request2 : [request2];
164757
164842
  const toolRegistry = await this.toolRegistry;
164758
164843
  const newToolCalls = requestsToProcess.map((reqInfo) => {
164844
+ if (process.env.DEBUG === "true" || process.env.DEBUG_MODE === "true" || process.env.dev === "true") {
164845
+ console.error(`[MCP DEBUG] Processing request:`, JSON.stringify(reqInfo, null, 2));
164846
+ }
164759
164847
  const toolInstance = toolRegistry.getTool(reqInfo.name);
164760
164848
  if (!toolInstance) {
164761
164849
  return {
@@ -164783,6 +164871,10 @@ var CoreToolScheduler = class {
164783
164871
  if (this.approvalMode === ApprovalMode.YOLO || process.env.YOLO) {
164784
164872
  this.setStatusInternal(reqInfo.callId, "scheduled");
164785
164873
  } else {
164874
+ if (process.env.DEBUG === "true" || process.env.DEBUG_MODE === "true" || process.env.dev === "true") {
164875
+ console.error(`[MCP DEBUG] CoreToolScheduler calling shouldConfirmExecute for: ${reqInfo.name}`);
164876
+ console.error(`[MCP DEBUG] Request args:`, JSON.stringify(reqInfo.args, null, 2));
164877
+ }
164786
164878
  const confirmationDetails = await toolInstance.shouldConfirmExecute(reqInfo.args, signal);
164787
164879
  if (confirmationDetails) {
164788
164880
  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.12";
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);
@@ -140186,8 +140194,15 @@ Make sure it is available in the sandbox`;
140186
140194
  if (toolNameForModel.length > 63) {
140187
140195
  toolNameForModel = toolNameForModel.slice(0, 28) + "___" + toolNameForModel.slice(-32);
140188
140196
  }
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));
140197
+ if (process.env.DEBUG === "true" || process.env.DEBUG_MODE === "true" || process.env.dev === "true") {
140198
+ console.error(`[MCP DEBUG] Registering tool: ${toolNameForModel} (server: ${mcpServerName}, original: ${funcDecl.name})`);
140199
+ console.error(`[MCP DEBUG] Tool parameters:`, JSON.stringify(funcDecl.parameters, null, 2));
140200
+ console.error(`[MCP DEBUG] Tool parametersJsonSchema:`, JSON.stringify(funcDecl.parametersJsonSchema, null, 2));
140201
+ console.error(`[MCP DEBUG] Tool description:`, funcDecl.description);
140202
+ }
140203
+ const parametersSchema = funcDecl.parameters || funcDecl.parametersJsonSchema || { type: Type.OBJECT, properties: {} };
140204
+ sanitizeParameters(parametersSchema);
140205
+ toolRegistry.registerTool(new DiscoveredMCPTool(mcpCallableTool, mcpServerName, toolNameForModel, funcDecl.description ?? "", parametersSchema, funcDecl.name, mcpServerConfig.timeout ?? MCP_DEFAULT_TIMEOUT_MSEC, mcpServerConfig.trust));
140191
140206
  }
140192
140207
  } catch (error) {
140193
140208
  console.error(`Failed to list or register tools for MCP server '${mcpServerName}': ${error}`);
@@ -149794,6 +149809,34 @@ function isFunctionCall(content) {
149794
149809
 
149795
149810
  // packages/core/dist/src/utils/editCorrector.js
149796
149811
  import * as fs13 from "fs";
149812
+ function filterIncompleteToolCalls(contents) {
149813
+ const toolCallIds = /* @__PURE__ */ new Set();
149814
+ const toolResponseIds = /* @__PURE__ */ new Set();
149815
+ for (const message of contents) {
149816
+ if (message.parts) {
149817
+ for (const part of message.parts) {
149818
+ if (part.functionCall?.id) {
149819
+ toolCallIds.add(part.functionCall.id);
149820
+ }
149821
+ if (part.functionResponse?.id) {
149822
+ toolResponseIds.add(part.functionResponse.id);
149823
+ }
149824
+ }
149825
+ }
149826
+ }
149827
+ return contents.filter((message) => {
149828
+ if (!message.parts)
149829
+ return true;
149830
+ for (const part of message.parts) {
149831
+ if (part.functionCall?.id) {
149832
+ if (!toolResponseIds.has(part.functionCall.id)) {
149833
+ return false;
149834
+ }
149835
+ }
149836
+ }
149837
+ return true;
149838
+ });
149839
+ }
149797
149840
  var EditModel = DEFAULT_GEMINI_FLASH_MODEL;
149798
149841
  var EditConfig = {
149799
149842
  thinkingConfig: {
@@ -150023,8 +150066,9 @@ If the differences are only in whitespace or formatting, apply similar whitespac
150023
150066
  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
150067
  `.trim();
150025
150068
  const contents = [{ role: "user", parts: [{ text: prompt }] }];
150069
+ const filteredContents = filterIncompleteToolCalls(contents);
150026
150070
  try {
150027
- const result = await geminiClient.generateJson(contents, OLD_STRING_CORRECTION_SCHEMA, abortSignal, EditModel, EditConfig);
150071
+ const result = await geminiClient.generateJson(filteredContents, OLD_STRING_CORRECTION_SCHEMA, abortSignal, EditModel, EditConfig);
150028
150072
  if (result && typeof result.corrected_target_snippet === "string" && result.corrected_target_snippet.length > 0) {
150029
150073
  return result.corrected_target_snippet;
150030
150074
  } else {
@@ -150081,8 +150125,9 @@ If the differences are only in whitespace or formatting, apply similar whitespac
150081
150125
  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
150126
  `.trim();
150083
150127
  const contents = [{ role: "user", parts: [{ text: prompt }] }];
150128
+ const filteredContents = filterIncompleteToolCalls(contents);
150084
150129
  try {
150085
- const result = await geminiClient.generateJson(contents, NEW_STRING_CORRECTION_SCHEMA, abortSignal, EditModel, EditConfig);
150130
+ const result = await geminiClient.generateJson(filteredContents, NEW_STRING_CORRECTION_SCHEMA, abortSignal, EditModel, EditConfig);
150086
150131
  if (result && typeof result.corrected_new_string === "string" && result.corrected_new_string.length > 0) {
150087
150132
  return result.corrected_new_string;
150088
150133
  } else {
@@ -150131,8 +150176,9 @@ If potentially_problematic_new_string is console.log(\\"Hello World\\"), it shou
150131
150176
  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
150177
  `.trim();
150133
150178
  const contents = [{ role: "user", parts: [{ text: prompt }] }];
150179
+ const filteredContents = filterIncompleteToolCalls(contents);
150134
150180
  try {
150135
- const result = await geminiClient.generateJson(contents, CORRECT_NEW_STRING_ESCAPING_SCHEMA, abortSignal, EditModel, EditConfig);
150181
+ const result = await geminiClient.generateJson(filteredContents, CORRECT_NEW_STRING_ESCAPING_SCHEMA, abortSignal, EditModel, EditConfig);
150136
150182
  if (result && typeof result.corrected_new_string_escaping === "string" && result.corrected_new_string_escaping.length > 0) {
150137
150183
  return result.corrected_new_string_escaping;
150138
150184
  } else {
@@ -150176,8 +150222,9 @@ If potentially_problematic_string is console.log(\\"Hello World\\"), it should b
150176
150222
  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
150223
  `.trim();
150178
150224
  const contents = [{ role: "user", parts: [{ text: prompt }] }];
150225
+ const filteredContents = filterIncompleteToolCalls(contents);
150179
150226
  try {
150180
- const result = await client.generateJson(contents, CORRECT_STRING_ESCAPING_SCHEMA, abortSignal, EditModel, EditConfig);
150227
+ const result = await client.generateJson(filteredContents, CORRECT_STRING_ESCAPING_SCHEMA, abortSignal, EditModel, EditConfig);
150181
150228
  if (result && typeof result.corrected_string_escaping === "string" && result.corrected_string_escaping.length > 0) {
150182
150229
  return result.corrected_string_escaping;
150183
150230
  } else {
@@ -157071,12 +157118,24 @@ async function checkNextSpeaker(chat, geminiClient, abortSignal) {
157071
157118
  if (!lastMessage || lastMessage.role !== "model") {
157072
157119
  return null;
157073
157120
  }
157121
+ const hasIncompleteToolCalls = checkForIncompleteToolCalls(curatedHistory);
157122
+ if (hasIncompleteToolCalls) {
157123
+ return {
157124
+ reasoning: "There are pending tool calls that need to be processed, so the model should speak next.",
157125
+ next_speaker: "model"
157126
+ };
157127
+ }
157074
157128
  const contents = [
157075
157129
  ...curatedHistory,
157076
157130
  { role: "user", parts: [{ text: CHECK_PROMPT }] }
157077
157131
  ];
157132
+ const filteredContents = checkForIncompleteToolCalls(contents) ? contents.filter((message) => {
157133
+ if (!message.parts)
157134
+ return true;
157135
+ return !message.parts.some((part) => part.functionCall?.id);
157136
+ }) : contents;
157078
157137
  try {
157079
- const parsedResponse = await geminiClient.generateJson(contents, RESPONSE_SCHEMA, abortSignal);
157138
+ const parsedResponse = await geminiClient.generateJson(filteredContents, RESPONSE_SCHEMA, abortSignal);
157080
157139
  if (parsedResponse && parsedResponse.next_speaker && ["user", "model"].includes(parsedResponse.next_speaker)) {
157081
157140
  return parsedResponse;
157082
157141
  }
@@ -157086,6 +157145,28 @@ async function checkNextSpeaker(chat, geminiClient, abortSignal) {
157086
157145
  return null;
157087
157146
  }
157088
157147
  }
157148
+ function checkForIncompleteToolCalls(history) {
157149
+ const toolCallIds = /* @__PURE__ */ new Set();
157150
+ const toolResponseIds = /* @__PURE__ */ new Set();
157151
+ for (const message of history) {
157152
+ if (message.parts) {
157153
+ for (const part of message.parts) {
157154
+ if (part.functionCall?.id) {
157155
+ toolCallIds.add(part.functionCall.id);
157156
+ }
157157
+ if (part.functionResponse?.id) {
157158
+ toolResponseIds.add(part.functionResponse.id);
157159
+ }
157160
+ }
157161
+ }
157162
+ }
157163
+ for (const callId of toolCallIds) {
157164
+ if (!toolResponseIds.has(callId)) {
157165
+ return true;
157166
+ }
157167
+ }
157168
+ return false;
157169
+ }
157089
157170
 
157090
157171
  // packages/core/dist/src/core/geminiChat.js
157091
157172
  import { createUserContent } from "@google/genai";
@@ -164746,12 +164827,19 @@ var CoreToolScheduler = class {
164746
164827
  return this.toolCalls.some((call) => call.status === "executing" || call.status === "awaiting_approval");
164747
164828
  }
164748
164829
  async schedule(request2, signal) {
164830
+ if (process.env.DEBUG === "true" || process.env.DEBUG_MODE === "true" || process.env.dev === "true") {
164831
+ console.error(`[MCP DEBUG] CoreToolScheduler.schedule called`);
164832
+ console.error(`[MCP DEBUG] Request:`, JSON.stringify(request2, null, 2));
164833
+ }
164749
164834
  if (this.isRunning()) {
164750
164835
  throw new Error("Cannot schedule new tool calls while other tool calls are actively running (executing or awaiting approval).");
164751
164836
  }
164752
164837
  const requestsToProcess = Array.isArray(request2) ? request2 : [request2];
164753
164838
  const toolRegistry = await this.toolRegistry;
164754
164839
  const newToolCalls = requestsToProcess.map((reqInfo) => {
164840
+ if (process.env.DEBUG === "true" || process.env.DEBUG_MODE === "true" || process.env.dev === "true") {
164841
+ console.error(`[MCP DEBUG] Processing request:`, JSON.stringify(reqInfo, null, 2));
164842
+ }
164755
164843
  const toolInstance = toolRegistry.getTool(reqInfo.name);
164756
164844
  if (!toolInstance) {
164757
164845
  return {
@@ -164779,6 +164867,10 @@ var CoreToolScheduler = class {
164779
164867
  if (this.approvalMode === ApprovalMode.YOLO || process.env.YOLO) {
164780
164868
  this.setStatusInternal(reqInfo.callId, "scheduled");
164781
164869
  } else {
164870
+ if (process.env.DEBUG === "true" || process.env.DEBUG_MODE === "true" || process.env.dev === "true") {
164871
+ console.error(`[MCP DEBUG] CoreToolScheduler calling shouldConfirmExecute for: ${reqInfo.name}`);
164872
+ console.error(`[MCP DEBUG] Request args:`, JSON.stringify(reqInfo.args, null, 2));
164873
+ }
164782
164874
  const confirmationDetails = await toolInstance.shouldConfirmExecute(reqInfo.args, signal);
164783
164875
  if (confirmationDetails) {
164784
164876
  const originalOnConfirm = confirmationDetails.onConfirm;
@@ -165270,7 +165362,7 @@ async function getPackageJson() {
165270
165362
  // packages/cli/src/utils/version.ts
165271
165363
  async function getCliVersion() {
165272
165364
  const pkgJson = await getPackageJson();
165273
- return "0.1.11";
165365
+ return "0.1.12";
165274
165366
  }
165275
165367
 
165276
165368
  // 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.12";
78256
78256
  const httpOptions = {
78257
78257
  headers: {
78258
78258
  "User-Agent": `GeminiCLI/${version3} (${process.platform}; ${process.arch})`
@@ -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);
@@ -213763,8 +213771,15 @@ Make sure it is available in the sandbox`;
213763
213771
  if (toolNameForModel.length > 63) {
213764
213772
  toolNameForModel = toolNameForModel.slice(0, 28) + "___" + toolNameForModel.slice(-32);
213765
213773
  }
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));
213774
+ if (process.env.DEBUG === "true" || process.env.DEBUG_MODE === "true" || process.env.dev === "true") {
213775
+ console.error(`[MCP DEBUG] Registering tool: ${toolNameForModel} (server: ${mcpServerName}, original: ${funcDecl.name})`);
213776
+ console.error(`[MCP DEBUG] Tool parameters:`, JSON.stringify(funcDecl.parameters, null, 2));
213777
+ console.error(`[MCP DEBUG] Tool parametersJsonSchema:`, JSON.stringify(funcDecl.parametersJsonSchema, null, 2));
213778
+ console.error(`[MCP DEBUG] Tool description:`, funcDecl.description);
213779
+ }
213780
+ const parametersSchema = funcDecl.parameters || funcDecl.parametersJsonSchema || { type: Type.OBJECT, properties: {} };
213781
+ sanitizeParameters(parametersSchema);
213782
+ toolRegistry.registerTool(new DiscoveredMCPTool(mcpCallableTool, mcpServerName, toolNameForModel, funcDecl.description ?? "", parametersSchema, funcDecl.name, mcpServerConfig.timeout ?? MCP_DEFAULT_TIMEOUT_MSEC, mcpServerConfig.trust));
213768
213783
  }
213769
213784
  } catch (error) {
213770
213785
  console.error(`Failed to list or register tools for MCP server '${mcpServerName}': ${error}`);
@@ -223388,6 +223403,34 @@ function isFunctionCall(content) {
223388
223403
 
223389
223404
  // packages/core/dist/src/utils/editCorrector.js
223390
223405
  import * as fs15 from "fs";
223406
+ function filterIncompleteToolCalls(contents) {
223407
+ const toolCallIds = /* @__PURE__ */ new Set();
223408
+ const toolResponseIds = /* @__PURE__ */ new Set();
223409
+ for (const message of contents) {
223410
+ if (message.parts) {
223411
+ for (const part of message.parts) {
223412
+ if (part.functionCall?.id) {
223413
+ toolCallIds.add(part.functionCall.id);
223414
+ }
223415
+ if (part.functionResponse?.id) {
223416
+ toolResponseIds.add(part.functionResponse.id);
223417
+ }
223418
+ }
223419
+ }
223420
+ }
223421
+ return contents.filter((message) => {
223422
+ if (!message.parts)
223423
+ return true;
223424
+ for (const part of message.parts) {
223425
+ if (part.functionCall?.id) {
223426
+ if (!toolResponseIds.has(part.functionCall.id)) {
223427
+ return false;
223428
+ }
223429
+ }
223430
+ }
223431
+ return true;
223432
+ });
223433
+ }
223391
223434
  var EditModel = DEFAULT_GEMINI_FLASH_MODEL;
223392
223435
  var EditConfig = {
223393
223436
  thinkingConfig: {
@@ -223617,8 +223660,9 @@ If the differences are only in whitespace or formatting, apply similar whitespac
223617
223660
  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
223661
  `.trim();
223619
223662
  const contents = [{ role: "user", parts: [{ text: prompt }] }];
223663
+ const filteredContents = filterIncompleteToolCalls(contents);
223620
223664
  try {
223621
- const result = await geminiClient.generateJson(contents, OLD_STRING_CORRECTION_SCHEMA, abortSignal, EditModel, EditConfig);
223665
+ const result = await geminiClient.generateJson(filteredContents, OLD_STRING_CORRECTION_SCHEMA, abortSignal, EditModel, EditConfig);
223622
223666
  if (result && typeof result.corrected_target_snippet === "string" && result.corrected_target_snippet.length > 0) {
223623
223667
  return result.corrected_target_snippet;
223624
223668
  } else {
@@ -223675,8 +223719,9 @@ If the differences are only in whitespace or formatting, apply similar whitespac
223675
223719
  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
223720
  `.trim();
223677
223721
  const contents = [{ role: "user", parts: [{ text: prompt }] }];
223722
+ const filteredContents = filterIncompleteToolCalls(contents);
223678
223723
  try {
223679
- const result = await geminiClient.generateJson(contents, NEW_STRING_CORRECTION_SCHEMA, abortSignal, EditModel, EditConfig);
223724
+ const result = await geminiClient.generateJson(filteredContents, NEW_STRING_CORRECTION_SCHEMA, abortSignal, EditModel, EditConfig);
223680
223725
  if (result && typeof result.corrected_new_string === "string" && result.corrected_new_string.length > 0) {
223681
223726
  return result.corrected_new_string;
223682
223727
  } else {
@@ -223725,8 +223770,9 @@ If potentially_problematic_new_string is console.log(\\"Hello World\\"), it shou
223725
223770
  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
223771
  `.trim();
223727
223772
  const contents = [{ role: "user", parts: [{ text: prompt }] }];
223773
+ const filteredContents = filterIncompleteToolCalls(contents);
223728
223774
  try {
223729
- const result = await geminiClient.generateJson(contents, CORRECT_NEW_STRING_ESCAPING_SCHEMA, abortSignal, EditModel, EditConfig);
223775
+ const result = await geminiClient.generateJson(filteredContents, CORRECT_NEW_STRING_ESCAPING_SCHEMA, abortSignal, EditModel, EditConfig);
223730
223776
  if (result && typeof result.corrected_new_string_escaping === "string" && result.corrected_new_string_escaping.length > 0) {
223731
223777
  return result.corrected_new_string_escaping;
223732
223778
  } else {
@@ -223770,8 +223816,9 @@ If potentially_problematic_string is console.log(\\"Hello World\\"), it should b
223770
223816
  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
223817
  `.trim();
223772
223818
  const contents = [{ role: "user", parts: [{ text: prompt }] }];
223819
+ const filteredContents = filterIncompleteToolCalls(contents);
223773
223820
  try {
223774
- const result = await client.generateJson(contents, CORRECT_STRING_ESCAPING_SCHEMA, abortSignal, EditModel, EditConfig);
223821
+ const result = await client.generateJson(filteredContents, CORRECT_STRING_ESCAPING_SCHEMA, abortSignal, EditModel, EditConfig);
223775
223822
  if (result && typeof result.corrected_string_escaping === "string" && result.corrected_string_escaping.length > 0) {
223776
223823
  return result.corrected_string_escaping;
223777
223824
  } else {
@@ -230644,12 +230691,24 @@ async function checkNextSpeaker(chat, geminiClient, abortSignal) {
230644
230691
  if (!lastMessage || lastMessage.role !== "model") {
230645
230692
  return null;
230646
230693
  }
230694
+ const hasIncompleteToolCalls = checkForIncompleteToolCalls(curatedHistory);
230695
+ if (hasIncompleteToolCalls) {
230696
+ return {
230697
+ reasoning: "There are pending tool calls that need to be processed, so the model should speak next.",
230698
+ next_speaker: "model"
230699
+ };
230700
+ }
230647
230701
  const contents = [
230648
230702
  ...curatedHistory,
230649
230703
  { role: "user", parts: [{ text: CHECK_PROMPT }] }
230650
230704
  ];
230705
+ const filteredContents = checkForIncompleteToolCalls(contents) ? contents.filter((message) => {
230706
+ if (!message.parts)
230707
+ return true;
230708
+ return !message.parts.some((part) => part.functionCall?.id);
230709
+ }) : contents;
230651
230710
  try {
230652
- const parsedResponse = await geminiClient.generateJson(contents, RESPONSE_SCHEMA, abortSignal);
230711
+ const parsedResponse = await geminiClient.generateJson(filteredContents, RESPONSE_SCHEMA, abortSignal);
230653
230712
  if (parsedResponse && parsedResponse.next_speaker && ["user", "model"].includes(parsedResponse.next_speaker)) {
230654
230713
  return parsedResponse;
230655
230714
  }
@@ -230659,6 +230718,28 @@ async function checkNextSpeaker(chat, geminiClient, abortSignal) {
230659
230718
  return null;
230660
230719
  }
230661
230720
  }
230721
+ function checkForIncompleteToolCalls(history) {
230722
+ const toolCallIds = /* @__PURE__ */ new Set();
230723
+ const toolResponseIds = /* @__PURE__ */ new Set();
230724
+ for (const message of history) {
230725
+ if (message.parts) {
230726
+ for (const part of message.parts) {
230727
+ if (part.functionCall?.id) {
230728
+ toolCallIds.add(part.functionCall.id);
230729
+ }
230730
+ if (part.functionResponse?.id) {
230731
+ toolResponseIds.add(part.functionResponse.id);
230732
+ }
230733
+ }
230734
+ }
230735
+ }
230736
+ for (const callId of toolCallIds) {
230737
+ if (!toolResponseIds.has(callId)) {
230738
+ return true;
230739
+ }
230740
+ }
230741
+ return false;
230742
+ }
230662
230743
 
230663
230744
  // packages/core/dist/src/core/geminiChat.js
230664
230745
  init_node();
@@ -238601,12 +238682,19 @@ var CoreToolScheduler = class {
238601
238682
  return this.toolCalls.some((call) => call.status === "executing" || call.status === "awaiting_approval");
238602
238683
  }
238603
238684
  async schedule(request2, signal) {
238685
+ if (process.env.DEBUG === "true" || process.env.DEBUG_MODE === "true" || process.env.dev === "true") {
238686
+ console.error(`[MCP DEBUG] CoreToolScheduler.schedule called`);
238687
+ console.error(`[MCP DEBUG] Request:`, JSON.stringify(request2, null, 2));
238688
+ }
238604
238689
  if (this.isRunning()) {
238605
238690
  throw new Error("Cannot schedule new tool calls while other tool calls are actively running (executing or awaiting approval).");
238606
238691
  }
238607
238692
  const requestsToProcess = Array.isArray(request2) ? request2 : [request2];
238608
238693
  const toolRegistry = await this.toolRegistry;
238609
238694
  const newToolCalls = requestsToProcess.map((reqInfo) => {
238695
+ if (process.env.DEBUG === "true" || process.env.DEBUG_MODE === "true" || process.env.dev === "true") {
238696
+ console.error(`[MCP DEBUG] Processing request:`, JSON.stringify(reqInfo, null, 2));
238697
+ }
238610
238698
  const toolInstance = toolRegistry.getTool(reqInfo.name);
238611
238699
  if (!toolInstance) {
238612
238700
  return {
@@ -238634,6 +238722,10 @@ var CoreToolScheduler = class {
238634
238722
  if (this.approvalMode === ApprovalMode.YOLO || process.env.YOLO) {
238635
238723
  this.setStatusInternal(reqInfo.callId, "scheduled");
238636
238724
  } else {
238725
+ if (process.env.DEBUG === "true" || process.env.DEBUG_MODE === "true" || process.env.dev === "true") {
238726
+ console.error(`[MCP DEBUG] CoreToolScheduler calling shouldConfirmExecute for: ${reqInfo.name}`);
238727
+ console.error(`[MCP DEBUG] Request args:`, JSON.stringify(reqInfo.args, null, 2));
238728
+ }
238637
238729
  const confirmationDetails = await toolInstance.shouldConfirmExecute(reqInfo.args, signal);
238638
238730
  if (confirmationDetails) {
238639
238731
  const originalOnConfirm = confirmationDetails.onConfirm;
@@ -243850,7 +243942,7 @@ var LangfuseClient = class {
243850
243942
  name: "MPD LLM CLI Session",
243851
243943
  metadata: {
243852
243944
  ...safeMetadata,
243853
- cli_version: this.safeString("0.1.11", "unknown"),
243945
+ cli_version: this.safeString("0.1.12", "unknown"),
243854
243946
  model: this.safeString(process.env.CUSTOM_LLM_MODEL_NAME, "gemini"),
243855
243947
  auth_type: process.env.USE_CUSTOM_LLM ? "custom_llm" : "google_oauth",
243856
243948
  environment: this.safeString(this.configManager.getConfig()?.environment, "unknown")
@@ -244881,7 +244973,7 @@ var LangfuseIntegration = class {
244881
244973
  const metadata = {
244882
244974
  model: this.config.getModel(),
244883
244975
  auth_type: this.config.getContentGeneratorConfig()?.authType,
244884
- cli_version: "0.1.11",
244976
+ cli_version: "0.1.12",
244885
244977
  start_time: (/* @__PURE__ */ new Date()).toISOString(),
244886
244978
  session_id: this.sessionId
244887
244979
  };
@@ -244951,7 +245043,7 @@ var LangfuseIntegration = class {
244951
245043
  error,
244952
245044
  metadata: {
244953
245045
  session_id: this.sessionId,
244954
- cli_version: "0.1.11",
245046
+ cli_version: "0.1.12",
244955
245047
  auth_type: this.config.getContentGeneratorConfig()?.authType
244956
245048
  }
244957
245049
  });
@@ -248677,7 +248769,7 @@ import { promises as fs33 } from "fs";
248677
248769
  import path37 from "path";
248678
248770
 
248679
248771
  // packages/cli/src/generated/git-commit.ts
248680
- var GIT_COMMIT_INFO = "8163082 (local modifications)";
248772
+ var GIT_COMMIT_INFO = "ed0acae (local modifications)";
248681
248773
 
248682
248774
  // node_modules/read-package-up/index.js
248683
248775
  import path35 from "node:path";
@@ -248890,7 +248982,7 @@ async function getPackageJson() {
248890
248982
  // packages/cli/src/utils/version.ts
248891
248983
  async function getCliVersion() {
248892
248984
  const pkgJson = await getPackageJson();
248893
- return "0.1.11";
248985
+ return "0.1.12";
248894
248986
  }
248895
248987
 
248896
248988
  // packages/cli/src/ui/commands/memoryCommand.ts
@@ -269843,7 +269935,7 @@ var DataCollector = class {
269843
269935
  // 提取元数据
269844
269936
  extractMetadata(data) {
269845
269937
  return {
269846
- cli_version: "0.1.11",
269938
+ cli_version: "0.1.12",
269847
269939
  model: process.env.CUSTOM_LLM_MODEL_NAME || "gemini",
269848
269940
  auth_type: process.env.USE_CUSTOM_LLM ? "custom_llm" : "google_oauth",
269849
269941
  project_path: data.projectPath,
@@ -270350,6 +270442,10 @@ var ToolConfirmationMessage = ({
270350
270442
  /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(Text, { color: Colors.AccentCyan, children: [
270351
270443
  "Tool: ",
270352
270444
  mcpProps.toolName
270445
+ ] }),
270446
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(Box_default, { flexDirection: "column", marginTop: 1, children: [
270447
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Text, { color: Colors.Foreground, children: "Parameters:" }),
270448
+ /* @__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
270449
  ] })
270354
270450
  ] });
270355
270451
  question = `Allow execution of MCP tool "${mcpProps.toolName}" from server "${mcpProps.serverName}"?`;
@@ -277505,8 +277601,9 @@ async function relaunchWithAdditionalArgs(additionalArgs) {
277505
277601
  async function main() {
277506
277602
  loadStartupConfig();
277507
277603
  const workspaceRoot = process.cwd();
277508
- const settings = loadSettings(workspaceRoot);
277604
+ let settings = loadSettings(workspaceRoot);
277509
277605
  await performUserAuthentication();
277606
+ settings = loadSettings(workspaceRoot);
277510
277607
  await cleanupCheckpoints();
277511
277608
  if (settings.errors.length > 0) {
277512
277609
  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.12",
4
4
  "engines": {
5
5
  "node": ">=20.0.0"
6
6
  },