patchpal 0.4.3__tar.gz → 0.4.4__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 (27) hide show
  1. {patchpal-0.4.3/patchpal.egg-info → patchpal-0.4.4}/PKG-INFO +1 -1
  2. {patchpal-0.4.3 → patchpal-0.4.4}/patchpal/__init__.py +1 -1
  3. {patchpal-0.4.3 → patchpal-0.4.4}/patchpal/agent.py +8 -6
  4. {patchpal-0.4.3 → patchpal-0.4.4/patchpal.egg-info}/PKG-INFO +1 -1
  5. {patchpal-0.4.3 → patchpal-0.4.4}/tests/test_agent.py +37 -6
  6. {patchpal-0.4.3 → patchpal-0.4.4}/LICENSE +0 -0
  7. {patchpal-0.4.3 → patchpal-0.4.4}/MANIFEST.in +0 -0
  8. {patchpal-0.4.3 → patchpal-0.4.4}/README.md +0 -0
  9. {patchpal-0.4.3 → patchpal-0.4.4}/patchpal/cli.py +0 -0
  10. {patchpal-0.4.3 → patchpal-0.4.4}/patchpal/context.py +0 -0
  11. {patchpal-0.4.3 → patchpal-0.4.4}/patchpal/permissions.py +0 -0
  12. {patchpal-0.4.3 → patchpal-0.4.4}/patchpal/skills.py +0 -0
  13. {patchpal-0.4.3 → patchpal-0.4.4}/patchpal/system_prompt.md +0 -0
  14. {patchpal-0.4.3 → patchpal-0.4.4}/patchpal/tools.py +0 -0
  15. {patchpal-0.4.3 → patchpal-0.4.4}/patchpal.egg-info/SOURCES.txt +0 -0
  16. {patchpal-0.4.3 → patchpal-0.4.4}/patchpal.egg-info/dependency_links.txt +0 -0
  17. {patchpal-0.4.3 → patchpal-0.4.4}/patchpal.egg-info/entry_points.txt +0 -0
  18. {patchpal-0.4.3 → patchpal-0.4.4}/patchpal.egg-info/requires.txt +0 -0
  19. {patchpal-0.4.3 → patchpal-0.4.4}/patchpal.egg-info/top_level.txt +0 -0
  20. {patchpal-0.4.3 → patchpal-0.4.4}/pyproject.toml +0 -0
  21. {patchpal-0.4.3 → patchpal-0.4.4}/setup.cfg +0 -0
  22. {patchpal-0.4.3 → patchpal-0.4.4}/tests/test_cli.py +0 -0
  23. {patchpal-0.4.3 → patchpal-0.4.4}/tests/test_context.py +0 -0
  24. {patchpal-0.4.3 → patchpal-0.4.4}/tests/test_guardrails.py +0 -0
  25. {patchpal-0.4.3 → patchpal-0.4.4}/tests/test_operational_safety.py +0 -0
  26. {patchpal-0.4.3 → patchpal-0.4.4}/tests/test_skills.py +0 -0
  27. {patchpal-0.4.3 → patchpal-0.4.4}/tests/test_tools.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: patchpal
3
- Version: 0.4.3
3
+ Version: 0.4.4
4
4
  Summary: A lean Claude Code clone in pure Python
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.4.3"
3
+ __version__ = "0.4.4"
4
4
 
5
5
  from patchpal.agent import create_agent
6
6
  from patchpal.tools import (
@@ -714,8 +714,8 @@ def _supports_prompt_caching(model_id: str) -> bool:
714
714
  # Anthropic models support caching (direct API or via Bedrock)
715
715
  if "anthropic" in model_id.lower() or "claude" in model_id.lower():
716
716
  return True
717
- # Bedrock with Anthropic models
718
- if model_id.startswith("bedrock/") and "anthropic" in model_id.lower():
717
+ # Bedrock Nova models support caching
718
+ if model_id.startswith("bedrock/") and "amazon.nova" in model_id.lower():
719
719
  return True
720
720
  return False
721
721
 
@@ -738,11 +738,13 @@ def _apply_prompt_caching(messages: List[Dict[str, Any]], model_id: str) -> List
738
738
  return messages
739
739
 
740
740
  # Determine cache marker format based on provider
741
- if model_id.startswith("bedrock/"):
742
- # Bedrock uses cachePoint
743
- cache_marker = {"cachePoint": {"type": "ephemeral"}}
741
+ # Anthropic models (direct or via Bedrock) use cache_control
742
+ # Other Bedrock models (Nova, etc.) use cachePoint
743
+ if model_id.startswith("bedrock/") and "anthropic" not in model_id.lower():
744
+ # Non-Anthropic Bedrock models (Nova, etc.) use cachePoint
745
+ cache_marker = {"cachePoint": {"type": "default"}}
744
746
  else:
745
- # Direct Anthropic API uses cache_control
747
+ # Anthropic models (direct or via Bedrock) use cache_control
746
748
  cache_marker = {"cache_control": {"type": "ephemeral"}}
747
749
 
748
750
  # Find system messages (usually at the start)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: patchpal
3
- Version: 0.4.3
3
+ Version: 0.4.4
4
4
  Summary: A lean Claude Code clone in pure Python
5
5
  Author: PatchPal Contributors
6
6
  License-Expression: Apache-2.0
@@ -422,7 +422,11 @@ def test_prompt_caching_detection():
422
422
  assert _supports_prompt_caching("bedrock/anthropic.claude-sonnet-4-5-v1:0")
423
423
  assert _supports_prompt_caching("bedrock/anthropic.claude-v2")
424
424
 
425
- # Non-Anthropic models should not support caching
425
+ # Bedrock Nova models should support caching
426
+ assert _supports_prompt_caching("bedrock/amazon.nova-pro-v1:0")
427
+ assert _supports_prompt_caching("bedrock/amazon.nova-lite-v1:0")
428
+
429
+ # Non-Anthropic/Nova models should not support caching
426
430
  assert not _supports_prompt_caching("openai/gpt-4o")
427
431
  assert not _supports_prompt_caching("ollama_chat/llama3.1")
428
432
 
@@ -454,8 +458,8 @@ def test_prompt_caching_application_anthropic():
454
458
  assert "cache_control" in cached_messages[-2]["content"][0]
455
459
 
456
460
 
457
- def test_prompt_caching_application_bedrock():
458
- """Test that prompt caching markers use correct format for Bedrock."""
461
+ def test_prompt_caching_application_bedrock_anthropic():
462
+ """Test that prompt caching markers use cache_control for Bedrock Anthropic models."""
459
463
  from patchpal.agent import _apply_prompt_caching
460
464
 
461
465
  messages = [
@@ -465,16 +469,43 @@ def test_prompt_caching_application_bedrock():
465
469
  {"role": "user", "content": "How are you?"},
466
470
  ]
467
471
 
468
- # Test with Bedrock
472
+ # Test with Bedrock Anthropic model - should use cache_control (same as direct Anthropic)
469
473
  cached_messages = _apply_prompt_caching(
470
474
  messages.copy(), "bedrock/anthropic.claude-sonnet-4-5-v1:0"
471
475
  )
472
476
 
473
- # System message should have cachePoint inside content block (Bedrock format)
477
+ # System message should have cache_control inside content block (NOT cachePoint)
478
+ assert isinstance(cached_messages[0]["content"], list)
479
+ assert cached_messages[0]["content"][0]["type"] == "text"
480
+ assert "cache_control" in cached_messages[0]["content"][0]
481
+ assert cached_messages[0]["content"][0]["cache_control"] == {"type": "ephemeral"}
482
+
483
+ # Last 2 messages should have cache_control inside content blocks
484
+ assert isinstance(cached_messages[-1]["content"], list)
485
+ assert "cache_control" in cached_messages[-1]["content"][0]
486
+ assert isinstance(cached_messages[-2]["content"], list)
487
+ assert "cache_control" in cached_messages[-2]["content"][0]
488
+
489
+
490
+ def test_prompt_caching_application_bedrock_nova():
491
+ """Test that prompt caching markers use cachePoint for Bedrock Nova models."""
492
+ from patchpal.agent import _apply_prompt_caching
493
+
494
+ messages = [
495
+ {"role": "system", "content": "You are a helpful assistant."},
496
+ {"role": "user", "content": "Hello"},
497
+ {"role": "assistant", "content": "Hi there!"},
498
+ {"role": "user", "content": "How are you?"},
499
+ ]
500
+
501
+ # Test with Bedrock Nova model - should use cachePoint
502
+ cached_messages = _apply_prompt_caching(messages.copy(), "bedrock/amazon.nova-pro-v1:0")
503
+
504
+ # System message should have cachePoint inside content block
474
505
  assert isinstance(cached_messages[0]["content"], list)
475
506
  assert cached_messages[0]["content"][0]["type"] == "text"
476
507
  assert "cachePoint" in cached_messages[0]["content"][0]
477
- assert cached_messages[0]["content"][0]["cachePoint"] == {"type": "ephemeral"}
508
+ assert cached_messages[0]["content"][0]["cachePoint"] == {"type": "default"}
478
509
 
479
510
  # Last 2 messages should have cachePoint inside content blocks
480
511
  assert isinstance(cached_messages[-1]["content"], list)
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