Pulastya B commited on
Commit
24ea09f
·
1 Parent(s): fed3e24

Fix: Add mock tool responses for all blocking points

Browse files

- Mistral requires every tool call to have matching response
- Loop detection, intent blocking now add mock responses
- Fixes 'Not the same number of function calls and responses'
- Prevents 400 errors when blocking tool execution

Files changed (1) hide show
  1. src/orchestrator.py +109 -0
src/orchestrator.py CHANGED
@@ -2183,6 +2183,21 @@ You are a DOER. Complete workflows based on user intent."""
2183
  "user_intent": user_intent
2184
  })
2185
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2186
  messages.append(block_warning)
2187
  continue
2188
 
@@ -2216,6 +2231,20 @@ You are a DOER. Complete workflows based on user intent."""
2216
  f"PROCEED to the next workflow step immediately!"
2217
  )
2218
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2219
  messages.append(block_warning)
2220
  continue
2221
 
@@ -2234,6 +2263,20 @@ You are a DOER. Complete workflows based on user intent."""
2234
  f"DO NOT call execute_python_code for time feature extraction!"
2235
  )
2236
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2237
  messages.append(block_warning)
2238
  continue
2239
 
@@ -2253,6 +2296,20 @@ You are a DOER. Complete workflows based on user intent."""
2253
  f"DO NOT call create_time_features again!"
2254
  )
2255
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2256
  messages.append(block_warning)
2257
  continue
2258
 
@@ -2271,6 +2328,20 @@ You are a DOER. Complete workflows based on user intent."""
2271
  f"DO NOT call encode_categorical again!"
2272
  )
2273
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2274
  messages.append(block_warning)
2275
  continue
2276
 
@@ -2289,6 +2360,20 @@ You are a DOER. Complete workflows based on user intent."""
2289
  f"DO NOT call smart_type_inference after encoding!"
2290
  )
2291
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2292
  messages.append(block_warning)
2293
  continue
2294
 
@@ -2345,6 +2430,30 @@ You are a DOER. Complete workflows based on user intent."""
2345
 
2346
  # Otherwise, force LLM to move on with VERY STRONG warning
2347
  next_step = self._determine_next_step(tool_name, completed_tools)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2348
  loop_warning = {
2349
  "role": "user",
2350
  "content": (
 
2183
  "user_intent": user_intent
2184
  })
2185
 
2186
+ # CRITICAL: Add mock tool response to maintain message balance
2187
+ if self.provider in ["mistral", "groq"]:
2188
+ messages.append({
2189
+ "role": "tool",
2190
+ "tool_call_id": tool_call_id,
2191
+ "name": tool_name,
2192
+ "content": json.dumps({"blocked": True, "reason": block_reason})
2193
+ })
2194
+ elif self.provider == "gemini":
2195
+ messages.append({
2196
+ "role": "tool",
2197
+ "name": tool_name,
2198
+ "content": json.dumps({"blocked": True, "reason": block_reason})
2199
+ })
2200
+
2201
  messages.append(block_warning)
2202
  continue
2203
 
 
2231
  f"PROCEED to the next workflow step immediately!"
2232
  )
2233
  }
2234
+ # CRITICAL: Add mock tool response
2235
+ if self.provider in ["mistral", "groq"]:
2236
+ messages.append({
2237
+ "role": "tool",
2238
+ "tool_call_id": tool_call_id,
2239
+ "name": tool_name,
2240
+ "content": json.dumps({"blocked": True, "reason": "Encoding already done"})
2241
+ })
2242
+ elif self.provider == "gemini":
2243
+ messages.append({
2244
+ "role": "tool",
2245
+ "name": tool_name,
2246
+ "content": json.dumps({"blocked": True, "reason": "Encoding already done"})
2247
+ })
2248
  messages.append(block_warning)
2249
  continue
2250
 
 
2263
  f"DO NOT call execute_python_code for time feature extraction!"
2264
  )
2265
  }
2266
+ # CRITICAL: Add mock tool response
2267
+ if self.provider in ["mistral", "groq"]:
2268
+ messages.append({
2269
+ "role": "tool",
2270
+ "tool_call_id": tool_call_id,
2271
+ "name": tool_name,
2272
+ "content": json.dumps({"blocked": True, "reason": "Time features already extracted"})
2273
+ })
2274
+ elif self.provider == "gemini":
2275
+ messages.append({
2276
+ "role": "tool",
2277
+ "name": tool_name,
2278
+ "content": json.dumps({"blocked": True, "reason": "Time features already extracted"})
2279
+ })
2280
  messages.append(block_warning)
2281
  continue
2282
 
 
2296
  f"DO NOT call create_time_features again!"
2297
  )
2298
  }
2299
+ # CRITICAL: Add mock tool response
2300
+ if self.provider in ["mistral", "groq"]:
2301
+ messages.append({
2302
+ "role": "tool",
2303
+ "tool_call_id": tool_call_id,
2304
+ "name": tool_name,
2305
+ "content": json.dumps({"blocked": True, "reason": "Time features already extracted"})
2306
+ })
2307
+ elif self.provider == "gemini":
2308
+ messages.append({
2309
+ "role": "tool",
2310
+ "name": tool_name,
2311
+ "content": json.dumps({"blocked": True, "reason": "Time features already extracted"})
2312
+ })
2313
  messages.append(block_warning)
2314
  continue
2315
 
 
2328
  f"DO NOT call encode_categorical again!"
2329
  )
2330
  }
2331
+ # CRITICAL: Add mock tool response
2332
+ if self.provider in ["mistral", "groq"]:
2333
+ messages.append({
2334
+ "role": "tool",
2335
+ "tool_call_id": tool_call_id,
2336
+ "name": tool_name,
2337
+ "content": json.dumps({"blocked": True, "reason": "Categorical encoding already done"})
2338
+ })
2339
+ elif self.provider == "gemini":
2340
+ messages.append({
2341
+ "role": "tool",
2342
+ "name": tool_name,
2343
+ "content": json.dumps({"blocked": True, "reason": "Categorical encoding already done"})
2344
+ })
2345
  messages.append(block_warning)
2346
  continue
2347
 
 
2360
  f"DO NOT call smart_type_inference after encoding!"
2361
  )
2362
  }
2363
+ # CRITICAL: Add mock tool response
2364
+ if self.provider in ["mistral", "groq"]:
2365
+ messages.append({
2366
+ "role": "tool",
2367
+ "tool_call_id": tool_call_id,
2368
+ "name": tool_name,
2369
+ "content": json.dumps({"blocked": True, "reason": "Type inference not needed after encoding"})
2370
+ })
2371
+ elif self.provider == "gemini":
2372
+ messages.append({
2373
+ "role": "tool",
2374
+ "name": tool_name,
2375
+ "content": json.dumps({"blocked": True, "reason": "Type inference not needed after encoding"})
2376
+ })
2377
  messages.append(block_warning)
2378
  continue
2379
 
 
2430
 
2431
  # Otherwise, force LLM to move on with VERY STRONG warning
2432
  next_step = self._determine_next_step(tool_name, completed_tools)
2433
+
2434
+ # CRITICAL: Add mock tool response to maintain message balance
2435
+ # (Mistral API requires: every tool call must have a matching tool response)
2436
+ if self.provider in ["mistral", "groq"]:
2437
+ messages.append({
2438
+ "role": "tool",
2439
+ "tool_call_id": tool_call_id,
2440
+ "name": tool_name,
2441
+ "content": json.dumps({
2442
+ "blocked": True,
2443
+ "reason": f"Loop detected: {tool_name} called {tool_call_counter[tool_name]} times consecutively",
2444
+ "last_successful_file": self._get_last_successful_file(workflow_history)
2445
+ })
2446
+ })
2447
+ elif self.provider == "gemini":
2448
+ messages.append({
2449
+ "role": "tool",
2450
+ "name": tool_name,
2451
+ "content": json.dumps({
2452
+ "blocked": True,
2453
+ "reason": f"Loop detected: {tool_name} called {tool_call_counter[tool_name]} times consecutively"
2454
+ })
2455
+ })
2456
+
2457
  loop_warning = {
2458
  "role": "user",
2459
  "content": (