patchpal 0.25.1__tar.gz → 0.25.2__tar.gz
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.
- {patchpal-0.25.1/patchpal.egg-info → patchpal-0.25.2}/PKG-INFO +1 -1
- {patchpal-0.25.1 → patchpal-0.25.2}/patchpal/__init__.py +1 -1
- {patchpal-0.25.1 → patchpal-0.25.2}/patchpal/agent/function_calling.py +27 -3
- {patchpal-0.25.1 → patchpal-0.25.2/patchpal.egg-info}/PKG-INFO +1 -1
- {patchpal-0.25.1 → patchpal-0.25.2}/LICENSE +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/MANIFEST.in +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/README.md +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/patchpal/agent/__init__.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/patchpal/agent/bedrock_profile_utils.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/patchpal/agent/react.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/patchpal/cli/__init__.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/patchpal/cli/autopilot.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/patchpal/cli/interactive.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/patchpal/cli/mcp.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/patchpal/cli/sandbox.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/patchpal/cli/streaming.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/patchpal/config.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/patchpal/context.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/patchpal/permissions.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/patchpal/prompts/react_prompt.md +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/patchpal/prompts/system_prompt.md +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/patchpal/skills.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/patchpal/tools/__init__.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/patchpal/tools/audit.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/patchpal/tools/browser_tools.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/patchpal/tools/code_analysis.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/patchpal/tools/common.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/patchpal/tools/definitions.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/patchpal/tools/file_reading.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/patchpal/tools/file_writing.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/patchpal/tools/find_tool.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/patchpal/tools/grep_tool.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/patchpal/tools/image_handler.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/patchpal/tools/mcp.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/patchpal/tools/repo_map.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/patchpal/tools/shell_tools.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/patchpal/tools/todo_tools.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/patchpal/tools/tool_schema.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/patchpal/tools/user_interaction.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/patchpal/tools/web_tools.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/patchpal.egg-info/SOURCES.txt +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/patchpal.egg-info/dependency_links.txt +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/patchpal.egg-info/entry_points.txt +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/patchpal.egg-info/requires.txt +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/patchpal.egg-info/top_level.txt +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/pyproject.toml +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/setup.cfg +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/tests/test_agent.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/tests/test_cli.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/tests/test_config_dynamic.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/tests/test_context.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/tests/test_custom_tools.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/tests/test_enabled_tools.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/tests/test_find_tool.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/tests/test_guardrails.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/tests/test_image_blocking.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/tests/test_maximum_security.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/tests/test_mcp_config.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/tests/test_memory.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/tests/test_memory_locations.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/tests/test_operational_safety.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/tests/test_optional_tools.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/tests/test_permissions.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/tests/test_react.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/tests/test_reasoning_content.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/tests/test_repo_map.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/tests/test_simplified_prompt.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/tests/test_skills.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/tests/test_streaming.py +0 -0
- {patchpal-0.25.1 → patchpal-0.25.2}/tests/test_tools.py +0 -0
|
@@ -1161,6 +1161,12 @@ Repository root takes priority if both exist."""
|
|
|
1161
1161
|
The agent's final response
|
|
1162
1162
|
"""
|
|
1163
1163
|
# Agent loop
|
|
1164
|
+
# Track consecutive empty responses (no content + no tool calls).
|
|
1165
|
+
# Common with some local models (e.g., GPT-OSS-120B on vLLM) due to
|
|
1166
|
+
# intermittent harmony-format parsing hiccups. A bounded retry usually
|
|
1167
|
+
# recovers since the failure is probabilistic.
|
|
1168
|
+
empty_response_retries = 0
|
|
1169
|
+
empty_response_max_retries = int(os.environ.get("PATCHPAL_EMPTY_RETRY_MAX", "2"))
|
|
1164
1170
|
for iteration in range(max_iterations):
|
|
1165
1171
|
# Clear any stale pending images from previous iteration (safety check)
|
|
1166
1172
|
# Images should already be injected, but this prevents accumulation on error
|
|
@@ -1335,6 +1341,8 @@ Repository root takes priority if both exist."""
|
|
|
1335
1341
|
|
|
1336
1342
|
# Check if there are tool calls
|
|
1337
1343
|
if hasattr(assistant_message, "tool_calls") and assistant_message.tool_calls:
|
|
1344
|
+
# A non-empty turn succeeded; reset the empty-response retry budget
|
|
1345
|
+
empty_response_retries = 0
|
|
1338
1346
|
# Print explanation text before executing tools (render as markdown)
|
|
1339
1347
|
if assistant_message.content and assistant_message.content.strip():
|
|
1340
1348
|
console = Console()
|
|
@@ -1834,9 +1842,25 @@ Repository root takes priority if both exist."""
|
|
|
1834
1842
|
if assistant_message.content:
|
|
1835
1843
|
return assistant_message.content
|
|
1836
1844
|
else:
|
|
1837
|
-
# Model returned no content and no tool calls
|
|
1838
|
-
# This
|
|
1839
|
-
#
|
|
1845
|
+
# Model returned no content and no tool calls.
|
|
1846
|
+
# This happens intermittently with some local models
|
|
1847
|
+
# (e.g., GPT-OSS-120B on vLLM) due to harmony-format parsing
|
|
1848
|
+
# hiccups. Because the failure is probabilistic, retry the turn
|
|
1849
|
+
# a bounded number of times before giving up.
|
|
1850
|
+
if empty_response_retries < empty_response_max_retries:
|
|
1851
|
+
empty_response_retries += 1
|
|
1852
|
+
# Drop the empty assistant message so it doesn't pollute history
|
|
1853
|
+
if self.messages and self.messages[-1] is assistant_msg:
|
|
1854
|
+
self.messages.pop()
|
|
1855
|
+
print(
|
|
1856
|
+
f"\033[2m↻ Empty response from model; retrying "
|
|
1857
|
+
f"({empty_response_retries}/{empty_response_max_retries})...\033[0m",
|
|
1858
|
+
flush=True,
|
|
1859
|
+
)
|
|
1860
|
+
continue
|
|
1861
|
+
|
|
1862
|
+
# Retries exhausted: surface the honest failure.
|
|
1863
|
+
# Using "NO_RESPONSE:" prefix for programmatic detection.
|
|
1840
1864
|
return "NO_RESPONSE: Model returned empty response. Try rephrasing your request or type 'continue' to prompt again."
|
|
1841
1865
|
|
|
1842
1866
|
# Max iterations reached
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|