patchpal 0.24.4__tar.gz → 0.24.6__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.
Files changed (70) hide show
  1. {patchpal-0.24.4/patchpal.egg-info → patchpal-0.24.6}/PKG-INFO +1 -1
  2. {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/__init__.py +1 -1
  3. {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/agent/bedrock_profile_utils.py +87 -21
  4. {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/agent/function_calling.py +8 -1
  5. {patchpal-0.24.4 → patchpal-0.24.6/patchpal.egg-info}/PKG-INFO +1 -1
  6. {patchpal-0.24.4 → patchpal-0.24.6}/LICENSE +0 -0
  7. {patchpal-0.24.4 → patchpal-0.24.6}/MANIFEST.in +0 -0
  8. {patchpal-0.24.4 → patchpal-0.24.6}/README.md +0 -0
  9. {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/agent/__init__.py +0 -0
  10. {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/agent/react.py +0 -0
  11. {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/cli/__init__.py +0 -0
  12. {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/cli/autopilot.py +0 -0
  13. {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/cli/interactive.py +0 -0
  14. {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/cli/mcp.py +0 -0
  15. {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/cli/sandbox.py +0 -0
  16. {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/cli/streaming.py +0 -0
  17. {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/config.py +0 -0
  18. {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/context.py +0 -0
  19. {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/permissions.py +0 -0
  20. {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/prompts/react_prompt.md +0 -0
  21. {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/prompts/system_prompt.md +0 -0
  22. {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/skills.py +0 -0
  23. {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/tools/__init__.py +0 -0
  24. {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/tools/audit.py +0 -0
  25. {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/tools/browser_tools.py +0 -0
  26. {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/tools/code_analysis.py +0 -0
  27. {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/tools/common.py +0 -0
  28. {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/tools/definitions.py +0 -0
  29. {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/tools/file_reading.py +0 -0
  30. {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/tools/file_writing.py +0 -0
  31. {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/tools/find_tool.py +0 -0
  32. {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/tools/grep_tool.py +0 -0
  33. {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/tools/image_handler.py +0 -0
  34. {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/tools/mcp.py +0 -0
  35. {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/tools/repo_map.py +0 -0
  36. {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/tools/shell_tools.py +0 -0
  37. {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/tools/todo_tools.py +0 -0
  38. {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/tools/tool_schema.py +0 -0
  39. {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/tools/user_interaction.py +0 -0
  40. {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/tools/web_tools.py +0 -0
  41. {patchpal-0.24.4 → patchpal-0.24.6}/patchpal.egg-info/SOURCES.txt +0 -0
  42. {patchpal-0.24.4 → patchpal-0.24.6}/patchpal.egg-info/dependency_links.txt +0 -0
  43. {patchpal-0.24.4 → patchpal-0.24.6}/patchpal.egg-info/entry_points.txt +0 -0
  44. {patchpal-0.24.4 → patchpal-0.24.6}/patchpal.egg-info/requires.txt +0 -0
  45. {patchpal-0.24.4 → patchpal-0.24.6}/patchpal.egg-info/top_level.txt +0 -0
  46. {patchpal-0.24.4 → patchpal-0.24.6}/pyproject.toml +0 -0
  47. {patchpal-0.24.4 → patchpal-0.24.6}/setup.cfg +0 -0
  48. {patchpal-0.24.4 → patchpal-0.24.6}/tests/test_agent.py +0 -0
  49. {patchpal-0.24.4 → patchpal-0.24.6}/tests/test_cli.py +0 -0
  50. {patchpal-0.24.4 → patchpal-0.24.6}/tests/test_config_dynamic.py +0 -0
  51. {patchpal-0.24.4 → patchpal-0.24.6}/tests/test_context.py +0 -0
  52. {patchpal-0.24.4 → patchpal-0.24.6}/tests/test_custom_tools.py +0 -0
  53. {patchpal-0.24.4 → patchpal-0.24.6}/tests/test_enabled_tools.py +0 -0
  54. {patchpal-0.24.4 → patchpal-0.24.6}/tests/test_find_tool.py +0 -0
  55. {patchpal-0.24.4 → patchpal-0.24.6}/tests/test_guardrails.py +0 -0
  56. {patchpal-0.24.4 → patchpal-0.24.6}/tests/test_image_blocking.py +0 -0
  57. {patchpal-0.24.4 → patchpal-0.24.6}/tests/test_maximum_security.py +0 -0
  58. {patchpal-0.24.4 → patchpal-0.24.6}/tests/test_mcp_config.py +0 -0
  59. {patchpal-0.24.4 → patchpal-0.24.6}/tests/test_memory.py +0 -0
  60. {patchpal-0.24.4 → patchpal-0.24.6}/tests/test_memory_locations.py +0 -0
  61. {patchpal-0.24.4 → patchpal-0.24.6}/tests/test_operational_safety.py +0 -0
  62. {patchpal-0.24.4 → patchpal-0.24.6}/tests/test_optional_tools.py +0 -0
  63. {patchpal-0.24.4 → patchpal-0.24.6}/tests/test_permissions.py +0 -0
  64. {patchpal-0.24.4 → patchpal-0.24.6}/tests/test_react.py +0 -0
  65. {patchpal-0.24.4 → patchpal-0.24.6}/tests/test_reasoning_content.py +0 -0
  66. {patchpal-0.24.4 → patchpal-0.24.6}/tests/test_repo_map.py +0 -0
  67. {patchpal-0.24.4 → patchpal-0.24.6}/tests/test_simplified_prompt.py +0 -0
  68. {patchpal-0.24.4 → patchpal-0.24.6}/tests/test_skills.py +0 -0
  69. {patchpal-0.24.4 → patchpal-0.24.6}/tests/test_streaming.py +0 -0
  70. {patchpal-0.24.4 → patchpal-0.24.6}/tests/test_tools.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: patchpal
3
- Version: 0.24.4
3
+ Version: 0.24.6
4
4
  Summary: An agentic coding and automation assistant, supporting both local and cloud LLMs
5
5
  Author: PatchPal Contributors
6
6
  License-Expression: Apache-2.0
@@ -1,6 +1,6 @@
1
1
  """PatchPal - An open-source Claude Code clone implemented purely in Python."""
2
2
 
3
- __version__ = "0.24.4"
3
+ __version__ = "0.24.6"
4
4
 
5
5
  from patchpal.agent import create_agent, create_react_agent
6
6
  from patchpal.cli.autopilot import autopilot_loop
@@ -29,32 +29,56 @@ def _extract_model_from_arn(arn: str) -> str | None:
29
29
  else:
30
30
  region = os.getenv("AWS_REGION_NAME") or os.getenv("AWS_REGION") or "us-east-1"
31
31
 
32
- # Check for custom Bedrock endpoint (VPC endpoint, custom domain, etc.)
33
- # The control plane and runtime may use the same VPC endpoint base
34
- custom_endpoint = (
35
- os.getenv("AWS_BEDROCK_ENDPOINT")
36
- or os.getenv("AWS_ENDPOINT_URL_BEDROCK")
37
- or os.getenv("AWS_ENDPOINT_URL")
32
+ # Check for custom Bedrock RUNTIME endpoint (for reference/debugging only)
33
+ # Note: We don't use runtime endpoint for control plane API
34
+ runtime_endpoint = (
35
+ os.getenv("AWS_BEDROCK_ENDPOINT") # PatchPal-specific (runtime only)
36
+ or os.getenv("AWS_ENDPOINT_URL_BEDROCK_RUNTIME") # AWS SDK standard (runtime)
38
37
  )
39
38
 
40
- # CRITICAL FIX: Derive control plane endpoint from runtime VPC endpoint
41
- # Scenario: User has VPC endpoint for runtime but not explicit control plane endpoint
42
- # Problem: boto3.client("bedrock") defaults to public endpoint, not VPC endpoint
43
- # Solution: Automatically derive control plane VPC endpoint from runtime endpoint
44
- # VPC endpoint pattern:
45
- # Runtime: vpce-{id}.bedrock-runtime.{region}.vpce.amazonaws.com
46
- # Control plane: vpce-{id}.bedrock.{region}.vpce.amazonaws.com
47
- # This matches the automatic derivation in sandbox.py endpoint detection
48
- if custom_endpoint and "bedrock-runtime" in custom_endpoint:
49
- # Try to construct control plane VPC endpoint by removing -runtime
50
- control_endpoint = custom_endpoint.replace("bedrock-runtime", "bedrock")
51
- else:
52
- control_endpoint = custom_endpoint
39
+ # Determine control plane endpoint for get_inference_profile API
40
+ # Priority order:
41
+ # 1. Explicit control plane endpoint variables
42
+ # 2. None (let boto3 use default public endpoint)
43
+ control_endpoint = (
44
+ os.getenv("AWS_ENDPOINT_URL_BEDROCK") # AWS SDK standard (control plane)
45
+ or os.getenv("AWS_BEDROCK_CONTROL_ENDPOINT") # PatchPal-specific (control plane)
46
+ )
47
+
48
+ # If no explicit control plane endpoint, let boto3 use default endpoint resolution
49
+ # This handles:
50
+ # - Standard AWS regions (bedrock.us-east-1.amazonaws.com)
51
+ # - GovCloud regions (bedrock.us-gov-east-1.amazonaws.com)
52
+ # - FIPS endpoints (if configured in boto3)
53
+ #
54
+ # IMPORTANT: Even if user has AWS_BEDROCK_ENDPOINT (runtime VPC endpoint),
55
+ # we DON'T use it for control plane because:
56
+ # 1. AWS_BEDROCK_ENDPOINT is runtime-only (for inference)
57
+ # 2. Many users only create runtime VPC endpoint
58
+ # 3. Control plane API is read-only and less sensitive
59
+ # 4. Public control plane endpoint is often acceptable
60
+ # 5. If user needs control plane VPC endpoint, they should set:
61
+ # AWS_ENDPOINT_URL_BEDROCK or AWS_BEDROCK_CONTROL_ENDPOINT
62
+
63
+ # Debug output
64
+ if os.getenv("PATCHPAL_DEBUG") == "true":
65
+ import sys
66
+
67
+ print("\n\033[2m[DEBUG] Control plane endpoint determination:\033[0m", file=sys.stderr)
68
+ print(
69
+ f"\033[2m[DEBUG] Runtime endpoint (not used): {runtime_endpoint or 'None'}\033[0m",
70
+ file=sys.stderr,
71
+ )
72
+ print(
73
+ f"\033[2m[DEBUG] Control endpoint: {control_endpoint or 'boto3 default (public)'}\033[0m",
74
+ file=sys.stderr,
75
+ )
53
76
 
54
77
  # Create bedrock client
55
78
  if control_endpoint:
56
79
  bedrock = boto3.client("bedrock", region_name=region, endpoint_url=control_endpoint)
57
80
  else:
81
+ # Let boto3 use default endpoint resolution (public endpoint)
58
82
  bedrock = boto3.client("bedrock", region_name=region)
59
83
 
60
84
  # Get inference profile details
@@ -77,8 +101,36 @@ def _extract_model_from_arn(arn: str) -> str | None:
77
101
  return parts[1]
78
102
 
79
103
  return None
80
- except Exception:
81
- # API call failed or boto3 not available
104
+ except ImportError as e:
105
+ # boto3 not available - can't query AWS API
106
+ import os
107
+
108
+ if os.getenv("PATCHPAL_DEBUG") == "true":
109
+ import sys
110
+
111
+ print(
112
+ f"\n\033[2m[DEBUG] boto3 not available, cannot extract model from ARN: {e}\033[0m",
113
+ file=sys.stderr,
114
+ )
115
+ return None
116
+ except Exception as e:
117
+ # API call failed
118
+ # Add debug logging for troubleshooting
119
+ import os
120
+
121
+ if os.getenv("PATCHPAL_DEBUG") == "true":
122
+ import sys
123
+
124
+ print(f"\n\033[2m[DEBUG] Failed to extract model from ARN: {e}\033[0m", file=sys.stderr)
125
+ print(f"\033[2m[DEBUG] ARN: {arn}\033[0m", file=sys.stderr)
126
+ print(
127
+ f"\033[2m[DEBUG] Region: {region if 'region' in locals() else 'unknown'}\033[0m",
128
+ file=sys.stderr,
129
+ )
130
+ print(
131
+ f"\033[2m[DEBUG] Control endpoint: {control_endpoint if 'control_endpoint' in locals() else 'unknown'}\033[0m",
132
+ file=sys.stderr,
133
+ )
82
134
  return None
83
135
 
84
136
 
@@ -142,6 +194,20 @@ def detect_model_capabilities(
142
194
  arn = model_id.replace("bedrock/converse/", "").replace("bedrock/", "")
143
195
  detected_model = _extract_model_from_arn(arn)
144
196
 
197
+ # Debug output
198
+ import os
199
+
200
+ if os.getenv("PATCHPAL_DEBUG") == "true":
201
+ import sys
202
+
203
+ print(
204
+ "\n\033[2m[DEBUG] Attempting to extract model from ARN via AWS API\033[0m",
205
+ file=sys.stderr,
206
+ )
207
+ print(f"\033[2m[DEBUG] Full model_id: {model_id}\033[0m", file=sys.stderr)
208
+ print(f"\033[2m[DEBUG] Extracted ARN: {arn}\033[0m", file=sys.stderr)
209
+ print(f"\033[2m[DEBUG] Result from AWS API: {detected_model}\033[0m", file=sys.stderr)
210
+
145
211
  try:
146
212
  # Try with Anthropic-style cache_control AND tools (matches real usage)
147
213
  response = litellm.completion(
@@ -1807,7 +1807,14 @@ Repository root takes priority if both exist."""
1807
1807
  ):
1808
1808
  self._perform_auto_compaction()
1809
1809
 
1810
- return assistant_message.content or "Task completed"
1810
+ # Return content if available, otherwise indicate model didn't respond
1811
+ if assistant_message.content:
1812
+ return assistant_message.content
1813
+ else:
1814
+ # Model returned no content and no tool calls
1815
+ # This can happen with some local models (e.g., GPT-OSS-120B)
1816
+ # Using "NO_RESPONSE:" prefix for programmatic detection
1817
+ return "NO_RESPONSE: Model returned empty response. Try rephrasing your request or type 'continue' to prompt again."
1811
1818
 
1812
1819
  # Max iterations reached
1813
1820
  return (
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: patchpal
3
- Version: 0.24.4
3
+ Version: 0.24.6
4
4
  Summary: An agentic coding and automation assistant, supporting both local and cloud LLMs
5
5
  Author: PatchPal Contributors
6
6
  License-Expression: Apache-2.0
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