patchpal 0.22.3__tar.gz → 0.22.5__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.22.3/patchpal.egg-info → patchpal-0.22.5}/PKG-INFO +1 -1
- {patchpal-0.22.3 → patchpal-0.22.5}/patchpal/__init__.py +1 -1
- {patchpal-0.22.3 → patchpal-0.22.5}/patchpal/agent/function_calling.py +4 -4
- {patchpal-0.22.3 → patchpal-0.22.5}/patchpal/context.py +21 -17
- {patchpal-0.22.3 → patchpal-0.22.5/patchpal.egg-info}/PKG-INFO +1 -1
- {patchpal-0.22.3 → patchpal-0.22.5}/LICENSE +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/MANIFEST.in +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/README.md +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/patchpal/agent/__init__.py +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/patchpal/agent/react.py +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/patchpal/cli/__init__.py +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/patchpal/cli/autopilot.py +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/patchpal/cli/interactive.py +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/patchpal/cli/mcp.py +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/patchpal/cli/sandbox.py +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/patchpal/cli/streaming.py +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/patchpal/config.py +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/patchpal/permissions.py +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/patchpal/prompts/react_prompt.md +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/patchpal/prompts/system_prompt.md +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/patchpal/skills.py +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/patchpal/tools/__init__.py +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/patchpal/tools/audit.py +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/patchpal/tools/code_analysis.py +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/patchpal/tools/common.py +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/patchpal/tools/definitions.py +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/patchpal/tools/file_reading.py +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/patchpal/tools/file_writing.py +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/patchpal/tools/find_tool.py +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/patchpal/tools/grep_tool.py +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/patchpal/tools/image_handler.py +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/patchpal/tools/mcp.py +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/patchpal/tools/repo_map.py +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/patchpal/tools/shell_tools.py +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/patchpal/tools/todo_tools.py +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/patchpal/tools/tool_schema.py +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/patchpal/tools/user_interaction.py +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/patchpal/tools/web_tools.py +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/patchpal.egg-info/SOURCES.txt +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/patchpal.egg-info/dependency_links.txt +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/patchpal.egg-info/entry_points.txt +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/patchpal.egg-info/requires.txt +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/patchpal.egg-info/top_level.txt +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/pyproject.toml +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/setup.cfg +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/tests/test_agent.py +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/tests/test_cli.py +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/tests/test_config_dynamic.py +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/tests/test_context.py +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/tests/test_custom_tools.py +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/tests/test_enabled_tools.py +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/tests/test_find_tool.py +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/tests/test_guardrails.py +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/tests/test_image_blocking.py +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/tests/test_maximum_security.py +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/tests/test_mcp_config.py +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/tests/test_memory.py +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/tests/test_operational_safety.py +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/tests/test_optional_tools.py +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/tests/test_permissions.py +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/tests/test_react.py +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/tests/test_reasoning_content.py +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/tests/test_repo_map.py +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/tests/test_simplified_prompt.py +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/tests/test_skills.py +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/tests/test_streaming.py +0 -0
- {patchpal-0.22.3 → patchpal-0.22.5}/tests/test_tools.py +0 -0
|
@@ -741,6 +741,7 @@ It's currently empty (just the template). The file is automatically loaded at se
|
|
|
741
741
|
response = litellm.completion(
|
|
742
742
|
model=self.model_id,
|
|
743
743
|
messages=messages,
|
|
744
|
+
max_tokens=32000, # Explicit output token limit for predictable context usage
|
|
744
745
|
timeout=LLM_TIMEOUT,
|
|
745
746
|
**self.litellm_kwargs,
|
|
746
747
|
)
|
|
@@ -957,10 +958,8 @@ It's currently empty (just the template). The file is automatically loaded at se
|
|
|
957
958
|
|
|
958
959
|
# Check for compaction BEFORE starting work
|
|
959
960
|
# This ensures we never compact mid-execution and lose tool results
|
|
960
|
-
#
|
|
961
|
-
if self.enable_auto_compact and self.context_manager.needs_compaction(
|
|
962
|
-
self.messages, actual_prompt_tokens=self.last_prompt_tokens
|
|
963
|
-
):
|
|
961
|
+
# Always estimates current messages to avoid staleness issues (no actual_prompt_tokens)
|
|
962
|
+
if self.enable_auto_compact and self.context_manager.needs_compaction(self.messages):
|
|
964
963
|
self._perform_auto_compaction()
|
|
965
964
|
|
|
966
965
|
# Agent loop with interrupt handling
|
|
@@ -1080,6 +1079,7 @@ It's currently empty (just the template). The file is automatically loaded at se
|
|
|
1080
1079
|
"messages": messages,
|
|
1081
1080
|
"tools": tools,
|
|
1082
1081
|
"tool_choice": "auto",
|
|
1082
|
+
"max_tokens": 32000, # Explicit output token limit for predictable context usage
|
|
1083
1083
|
"timeout": LLM_TIMEOUT,
|
|
1084
1084
|
"stream": stream,
|
|
1085
1085
|
**self.litellm_kwargs,
|
|
@@ -257,7 +257,10 @@ Be comprehensive but concise. The goal is to continue work seamlessly without lo
|
|
|
257
257
|
self.system_prompt = system_prompt
|
|
258
258
|
self.estimator = TokenEstimator(model_id)
|
|
259
259
|
self.context_limit = self._get_context_limit()
|
|
260
|
-
|
|
260
|
+
# Reserve 16% of context for output (min 4K, max 32K)
|
|
261
|
+
# This ensures older models like GPT-4 (8K) get 1.28K reserve
|
|
262
|
+
# while modern models get full 32K reserve
|
|
263
|
+
self.output_reserve = min(32_000, max(4_000, int(self.context_limit * 0.16)))
|
|
261
264
|
|
|
262
265
|
def _get_context_limit(self) -> int:
|
|
263
266
|
"""Get context limit for model.
|
|
@@ -321,30 +324,31 @@ Be comprehensive but concise. The goal is to continue work seamlessly without lo
|
|
|
321
324
|
) -> bool:
|
|
322
325
|
"""Check if context window needs compaction.
|
|
323
326
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
+
ALWAYS estimates current messages to avoid staleness issues when predicting
|
|
328
|
+
whether the NEXT API call will overflow. Using actual_prompt_tokens from a
|
|
329
|
+
previous call can cause false negatives when large messages are added between
|
|
330
|
+
the last API call and the compaction check.
|
|
327
331
|
|
|
328
|
-
|
|
329
|
-
|
|
332
|
+
Example of staleness bug (fixed):
|
|
333
|
+
- Previous API call: 120K tokens (60% usage)
|
|
334
|
+
- User pastes huge changelog: +90K tokens
|
|
335
|
+
- Total: 210K tokens (exceeds 200K limit)
|
|
336
|
+
- Bug: If we used actual_prompt_tokens=120K, we'd think we're at 60%
|
|
337
|
+
- Fix: Always re-estimate to see the 210K total
|
|
338
|
+
|
|
339
|
+
The actual_prompt_tokens parameter is kept for API compatibility but ignored
|
|
340
|
+
for compaction decisions. Use get_usage_stats() for display purposes where
|
|
341
|
+
actual tokens are appropriate (staleness OK for showing recent stats).
|
|
330
342
|
|
|
331
343
|
Args:
|
|
332
344
|
messages: Current message history
|
|
333
|
-
actual_prompt_tokens:
|
|
345
|
+
actual_prompt_tokens: IGNORED - kept for API compatibility only
|
|
334
346
|
|
|
335
347
|
Returns:
|
|
336
348
|
True if compaction is needed
|
|
337
349
|
"""
|
|
338
|
-
#
|
|
339
|
-
|
|
340
|
-
# Add output reserve to account for response tokens
|
|
341
|
-
total_tokens = actual_prompt_tokens + self.output_reserve
|
|
342
|
-
usage_ratio = total_tokens / self.context_limit
|
|
343
|
-
return usage_ratio >= self.COMPACT_THRESHOLD
|
|
344
|
-
|
|
345
|
-
# Proactive approach (fallback): estimate tokens when API data not available
|
|
346
|
-
# This uses character-based estimation (3 chars per token) which works
|
|
347
|
-
# reliably without requiring tiktoken or network access
|
|
350
|
+
# ALWAYS estimate current messages - never use stale actual_prompt_tokens
|
|
351
|
+
# This ensures we detect large message additions that happen between API calls
|
|
348
352
|
# Note: Dynamic date/time message adds ~30 tokens on each LLM call
|
|
349
353
|
system_tokens = self.estimator.estimate_tokens(self.system_prompt)
|
|
350
354
|
datetime_tokens = 30 # Approximate size of dynamic date/time message
|
|
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
|