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.
- {patchpal-0.24.4/patchpal.egg-info → patchpal-0.24.6}/PKG-INFO +1 -1
- {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/__init__.py +1 -1
- {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/agent/bedrock_profile_utils.py +87 -21
- {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/agent/function_calling.py +8 -1
- {patchpal-0.24.4 → patchpal-0.24.6/patchpal.egg-info}/PKG-INFO +1 -1
- {patchpal-0.24.4 → patchpal-0.24.6}/LICENSE +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/MANIFEST.in +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/README.md +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/agent/__init__.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/agent/react.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/cli/__init__.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/cli/autopilot.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/cli/interactive.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/cli/mcp.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/cli/sandbox.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/cli/streaming.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/config.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/context.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/permissions.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/prompts/react_prompt.md +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/prompts/system_prompt.md +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/skills.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/tools/__init__.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/tools/audit.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/tools/browser_tools.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/tools/code_analysis.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/tools/common.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/tools/definitions.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/tools/file_reading.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/tools/file_writing.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/tools/find_tool.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/tools/grep_tool.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/tools/image_handler.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/tools/mcp.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/tools/repo_map.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/tools/shell_tools.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/tools/todo_tools.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/tools/tool_schema.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/tools/user_interaction.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/patchpal/tools/web_tools.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/patchpal.egg-info/SOURCES.txt +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/patchpal.egg-info/dependency_links.txt +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/patchpal.egg-info/entry_points.txt +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/patchpal.egg-info/requires.txt +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/patchpal.egg-info/top_level.txt +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/pyproject.toml +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/setup.cfg +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/tests/test_agent.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/tests/test_cli.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/tests/test_config_dynamic.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/tests/test_context.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/tests/test_custom_tools.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/tests/test_enabled_tools.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/tests/test_find_tool.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/tests/test_guardrails.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/tests/test_image_blocking.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/tests/test_maximum_security.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/tests/test_mcp_config.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/tests/test_memory.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/tests/test_memory_locations.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/tests/test_operational_safety.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/tests/test_optional_tools.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/tests/test_permissions.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/tests/test_react.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/tests/test_reasoning_content.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/tests/test_repo_map.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/tests/test_simplified_prompt.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/tests/test_skills.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/tests/test_streaming.py +0 -0
- {patchpal-0.24.4 → patchpal-0.24.6}/tests/test_tools.py +0 -0
|
@@ -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 (
|
|
33
|
-
#
|
|
34
|
-
|
|
35
|
-
os.getenv("AWS_BEDROCK_ENDPOINT")
|
|
36
|
-
or os.getenv("
|
|
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
|
-
#
|
|
41
|
-
#
|
|
42
|
-
#
|
|
43
|
-
#
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
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
|
|
81
|
-
#
|
|
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
|
-
|
|
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 (
|
|
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
|