pdd-cli 0.0.48__py3-none-any.whl → 0.0.49__py3-none-any.whl
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.
Potentially problematic release.
This version of pdd-cli might be problematic. Click here for more details.
- pdd/__init__.py +1 -1
- pdd/llm_invoke.py +21 -7
- pdd/sync_orchestration.py +32 -4
- {pdd_cli-0.0.48.dist-info → pdd_cli-0.0.49.dist-info}/METADATA +5 -4
- {pdd_cli-0.0.48.dist-info → pdd_cli-0.0.49.dist-info}/RECORD +9 -9
- {pdd_cli-0.0.48.dist-info → pdd_cli-0.0.49.dist-info}/WHEEL +0 -0
- {pdd_cli-0.0.48.dist-info → pdd_cli-0.0.49.dist-info}/entry_points.txt +0 -0
- {pdd_cli-0.0.48.dist-info → pdd_cli-0.0.49.dist-info}/licenses/LICENSE +0 -0
- {pdd_cli-0.0.48.dist-info → pdd_cli-0.0.49.dist-info}/top_level.txt +0 -0
pdd/__init__.py
CHANGED
pdd/llm_invoke.py
CHANGED
|
@@ -6,7 +6,7 @@ import pandas as pd
|
|
|
6
6
|
import litellm
|
|
7
7
|
import logging # ADDED FOR DETAILED LOGGING
|
|
8
8
|
import importlib.resources
|
|
9
|
-
from litellm.caching.caching import Cache # Fix for LiteLLM v1.
|
|
9
|
+
from litellm.caching.caching import Cache # Fix for LiteLLM v1.75.5+
|
|
10
10
|
|
|
11
11
|
# --- Configure Standard Python Logging ---
|
|
12
12
|
logger = logging.getLogger("pdd.llm_invoke")
|
|
@@ -280,16 +280,22 @@ if GCS_BUCKET_NAME and GCS_HMAC_ACCESS_KEY_ID and GCS_HMAC_SECRET_ACCESS_KEY:
|
|
|
280
280
|
elif 'AWS_REGION_NAME' in os.environ:
|
|
281
281
|
pass # Or just leave it if the temporary setting wasn't done/needed
|
|
282
282
|
|
|
283
|
+
# Check if caching is disabled via environment variable
|
|
284
|
+
if os.getenv("LITELLM_CACHE_DISABLE") == "1":
|
|
285
|
+
logger.info("LiteLLM caching disabled via LITELLM_CACHE_DISABLE=1")
|
|
286
|
+
litellm.cache = None
|
|
287
|
+
cache_configured = True
|
|
288
|
+
|
|
283
289
|
if not cache_configured:
|
|
284
290
|
try:
|
|
285
|
-
# Try
|
|
291
|
+
# Try disk-based cache as a fallback
|
|
286
292
|
sqlite_cache_path = PROJECT_ROOT / "litellm_cache.sqlite"
|
|
287
|
-
configured_cache = Cache(type="
|
|
293
|
+
configured_cache = Cache(type="disk", disk_cache_dir=str(sqlite_cache_path))
|
|
288
294
|
litellm.cache = configured_cache
|
|
289
|
-
logger.info(f"LiteLLM
|
|
295
|
+
logger.info(f"LiteLLM disk cache configured at {sqlite_cache_path}")
|
|
290
296
|
cache_configured = True
|
|
291
297
|
except Exception as e2:
|
|
292
|
-
warnings.warn(f"Failed to configure LiteLLM
|
|
298
|
+
warnings.warn(f"Failed to configure LiteLLM disk cache: {e2}. Caching is disabled.")
|
|
293
299
|
litellm.cache = None
|
|
294
300
|
|
|
295
301
|
if not cache_configured:
|
|
@@ -852,6 +858,10 @@ def llm_invoke(
|
|
|
852
858
|
# --- 3. Iterate Through Candidates and Invoke LLM ---
|
|
853
859
|
last_exception = None
|
|
854
860
|
newly_acquired_keys: Dict[str, bool] = {} # Track keys obtained in this run
|
|
861
|
+
|
|
862
|
+
# Initialize variables for retry section
|
|
863
|
+
response_format = None
|
|
864
|
+
time_kwargs = {}
|
|
855
865
|
|
|
856
866
|
for model_info in candidate_models:
|
|
857
867
|
model_name_litellm = model_info['model']
|
|
@@ -964,7 +974,8 @@ def llm_invoke(
|
|
|
964
974
|
logger.info(f"[INFO] Requesting structured output (Pydantic: {output_pydantic.__name__}) for {model_name_litellm}")
|
|
965
975
|
# Pass the Pydantic model directly if supported, else use json_object
|
|
966
976
|
# LiteLLM handles passing Pydantic models for supported providers
|
|
967
|
-
|
|
977
|
+
response_format = output_pydantic
|
|
978
|
+
litellm_kwargs["response_format"] = response_format
|
|
968
979
|
# As a fallback, one could use:
|
|
969
980
|
# litellm_kwargs["response_format"] = {"type": "json_object"}
|
|
970
981
|
# And potentially enable client-side validation:
|
|
@@ -986,7 +997,9 @@ def llm_invoke(
|
|
|
986
997
|
# Currently known: Anthropic uses 'thinking'
|
|
987
998
|
# Model name comparison is more robust than provider string
|
|
988
999
|
if provider == 'anthropic': # Check provider column instead of model prefix
|
|
989
|
-
|
|
1000
|
+
thinking_param = {"type": "enabled", "budget_tokens": budget}
|
|
1001
|
+
litellm_kwargs["thinking"] = thinking_param
|
|
1002
|
+
time_kwargs["thinking"] = thinking_param
|
|
990
1003
|
if verbose:
|
|
991
1004
|
logger.info(f"[INFO] Requesting Anthropic thinking (budget type) with budget: {budget} tokens for {model_name_litellm}")
|
|
992
1005
|
else:
|
|
@@ -1006,6 +1019,7 @@ def llm_invoke(
|
|
|
1006
1019
|
effort = "medium"
|
|
1007
1020
|
# Use the common 'reasoning_effort' param LiteLLM provides
|
|
1008
1021
|
litellm_kwargs["reasoning_effort"] = effort
|
|
1022
|
+
time_kwargs["reasoning_effort"] = effort
|
|
1009
1023
|
if verbose:
|
|
1010
1024
|
logger.info(f"[INFO] Requesting reasoning_effort='{effort}' (effort type) for {model_name_litellm} based on time={time}")
|
|
1011
1025
|
|
pdd/sync_orchestration.py
CHANGED
|
@@ -17,6 +17,9 @@ from dataclasses import asdict
|
|
|
17
17
|
|
|
18
18
|
import click
|
|
19
19
|
|
|
20
|
+
# --- Constants ---
|
|
21
|
+
MAX_CONSECUTIVE_TESTS = 3 # Allow up to 3 consecutive test attempts
|
|
22
|
+
|
|
20
23
|
# --- Real PDD Component Imports ---
|
|
21
24
|
from .sync_animation import sync_animation
|
|
22
25
|
from .sync_determine_operation import (
|
|
@@ -533,6 +536,27 @@ def sync_orchestration(
|
|
|
533
536
|
})
|
|
534
537
|
break
|
|
535
538
|
|
|
539
|
+
# Detect consecutive test operations (infinite test loop protection)
|
|
540
|
+
if operation == 'test':
|
|
541
|
+
# Count consecutive test operations
|
|
542
|
+
consecutive_tests = 0
|
|
543
|
+
for i in range(len(operation_history) - 1, -1, -1):
|
|
544
|
+
if operation_history[i] == 'test':
|
|
545
|
+
consecutive_tests += 1
|
|
546
|
+
else:
|
|
547
|
+
break
|
|
548
|
+
|
|
549
|
+
# Use module-level constant for max consecutive test attempts
|
|
550
|
+
if consecutive_tests >= MAX_CONSECUTIVE_TESTS:
|
|
551
|
+
errors.append(f"Detected {consecutive_tests} consecutive test operations. Breaking infinite test loop.")
|
|
552
|
+
errors.append("Coverage target may not be achievable with additional test generation.")
|
|
553
|
+
log_sync_event(basename, language, "cycle_detected", {
|
|
554
|
+
"cycle_type": "consecutive-test",
|
|
555
|
+
"consecutive_count": consecutive_tests,
|
|
556
|
+
"operation_history": operation_history[-10:] # Last 10 operations
|
|
557
|
+
})
|
|
558
|
+
break
|
|
559
|
+
|
|
536
560
|
if operation in ['all_synced', 'nothing', 'fail_and_request_manual_merge', 'error', 'analyze_conflict']:
|
|
537
561
|
current_function_name_ref[0] = "synced" if operation in ['all_synced', 'nothing'] else "conflict"
|
|
538
562
|
|
|
@@ -1024,10 +1048,14 @@ def sync_orchestration(
|
|
|
1024
1048
|
success = result.get('success', False)
|
|
1025
1049
|
current_cost_ref[0] += result.get('cost', 0.0)
|
|
1026
1050
|
elif isinstance(result, tuple) and len(result) >= 3:
|
|
1027
|
-
# Tuple return (e.g., from code_generator_main, context_generator_main)
|
|
1028
|
-
# For
|
|
1029
|
-
|
|
1030
|
-
|
|
1051
|
+
# Tuple return (e.g., from code_generator_main, context_generator_main, cmd_test_main)
|
|
1052
|
+
# For test operations, use file existence as success criteria to match local detection
|
|
1053
|
+
if operation == 'test':
|
|
1054
|
+
success = pdd_files['test'].exists()
|
|
1055
|
+
else:
|
|
1056
|
+
# For other operations, success is determined by valid return content
|
|
1057
|
+
# Check if the first element (generated content) is None, which indicates failure
|
|
1058
|
+
success = result[0] is not None
|
|
1031
1059
|
# Extract cost from tuple (usually second-to-last element)
|
|
1032
1060
|
cost = result[-2] if len(result) >= 2 and isinstance(result[-2], (int, float)) else 0.0
|
|
1033
1061
|
current_cost_ref[0] += cost
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pdd-cli
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.49
|
|
4
4
|
Summary: PDD (Prompt-Driven Development) Command Line Interface
|
|
5
5
|
Author: Greg Tanaka
|
|
6
6
|
Author-email: glt@alumni.caltech.edu
|
|
@@ -31,13 +31,14 @@ Requires-Dist: nest_asyncio==1.6.0
|
|
|
31
31
|
Requires-Dist: pandas==2.2.3
|
|
32
32
|
Requires-Dist: psutil==5.9.0
|
|
33
33
|
Requires-Dist: pydantic==2.11.2
|
|
34
|
-
Requires-Dist: litellm
|
|
34
|
+
Requires-Dist: litellm[caching]>=1.75.5
|
|
35
35
|
Requires-Dist: rich==14.0.0
|
|
36
36
|
Requires-Dist: semver==3.0.2
|
|
37
37
|
Requires-Dist: setuptools
|
|
38
38
|
Requires-Dist: pytest
|
|
39
39
|
Requires-Dist: boto3==1.35.99
|
|
40
40
|
Requires-Dist: python-Levenshtein
|
|
41
|
+
Requires-Dist: openai>=1.99.5
|
|
41
42
|
Provides-Extra: dev
|
|
42
43
|
Requires-Dist: commitizen; extra == "dev"
|
|
43
44
|
Requires-Dist: pytest-cov; extra == "dev"
|
|
@@ -46,7 +47,7 @@ Requires-Dist: pytest-asyncio; extra == "dev"
|
|
|
46
47
|
Requires-Dist: z3-solver; extra == "dev"
|
|
47
48
|
Dynamic: license-file
|
|
48
49
|
|
|
49
|
-
.. image:: https://img.shields.io/badge/pdd--cli-v0.0.
|
|
50
|
+
.. image:: https://img.shields.io/badge/pdd--cli-v0.0.49-blue
|
|
50
51
|
:alt: PDD-CLI Version
|
|
51
52
|
|
|
52
53
|
.. image:: https://img.shields.io/badge/Discord-join%20chat-7289DA.svg?logo=discord&logoColor=white&link=https://discord.gg/Yp4RTh8bG7
|
|
@@ -123,7 +124,7 @@ After installation, verify:
|
|
|
123
124
|
|
|
124
125
|
pdd --version
|
|
125
126
|
|
|
126
|
-
You'll see the current PDD version (e.g., 0.0.
|
|
127
|
+
You'll see the current PDD version (e.g., 0.0.49).
|
|
127
128
|
|
|
128
129
|
Getting Started with Examples
|
|
129
130
|
-----------------------------
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
pdd/__init__.py,sha256=
|
|
1
|
+
pdd/__init__.py,sha256=XJgiiw7J4yF8hdCjnIIweAshNfxsBs1CSWV_5_BD3x0,634
|
|
2
2
|
pdd/auto_deps_main.py,sha256=iV2khcgSejiXjh5hiQqeu_BJQOLfTKXhMx14j6vRlf8,3916
|
|
3
3
|
pdd/auto_include.py,sha256=OJcdcwTwJNqHPHKG9P4m9Ij-PiLex0EbuwJP0uiQi_Y,7484
|
|
4
4
|
pdd/auto_update.py,sha256=w6jzTnMiYRNpwQHQxWNiIAwQ0d6xh1iOB3xgDsabWtc,5236
|
|
@@ -41,7 +41,7 @@ pdd/increase_tests.py,sha256=68cM9d1CpaLLm2ISFpJw39xbRjsfwxwS06yAwRoUCHk,4433
|
|
|
41
41
|
pdd/incremental_code_generator.py,sha256=cWo3DJ0PybnrepFEAMibGjTVY3T8mLVvPt5W8cNhuxU,9402
|
|
42
42
|
pdd/insert_includes.py,sha256=hNn8muRULiq3YMNI4W4pEPeM1ckiZ-EgR9WtCyWQ1eQ,5533
|
|
43
43
|
pdd/install_completion.py,sha256=bLMJuMOBDvsEnDAUpgiPesNRGhY_IvBvz8ZvmbTzP4o,5472
|
|
44
|
-
pdd/llm_invoke.py,sha256=
|
|
44
|
+
pdd/llm_invoke.py,sha256=B5DwM4x8N191ehklb_WwahFiNBjEVKFcp8RPetWZl3Y,75892
|
|
45
45
|
pdd/load_prompt_template.py,sha256=4NH8_t5eon_vcyTznqtemJ_yAPkTJm_hSdTRgzj3qEQ,1907
|
|
46
46
|
pdd/logo_animation.py,sha256=n6HJWzuFze2csAAW2-zbxfjvWFYRI4hIdwVBtHBOkj4,20782
|
|
47
47
|
pdd/mcp_config.json,sha256=D3ctWHlShvltbtH37zbYb6smVE0V80_lGjDKDIqsSBE,124
|
|
@@ -61,7 +61,7 @@ pdd/summarize_directory.py,sha256=cRKIVRWcti9SGLDuc40tsNbho7CdVbpWhlI-PoVC7xI,95
|
|
|
61
61
|
pdd/sync_animation.py,sha256=e7Qb4m70BHYpl37CuuF-95j-APctPL4Zm_o1PSTTRFQ,28070
|
|
62
62
|
pdd/sync_determine_operation.py,sha256=16Co4_IE0AZBLPdICi2MqW3730hiyLdqOf2kZcQA2cc,59590
|
|
63
63
|
pdd/sync_main.py,sha256=2XUZZL9oIiNVsVohdsMpvrNoV8XkXhEKyt5bb2HlNHI,13641
|
|
64
|
-
pdd/sync_orchestration.py,sha256=
|
|
64
|
+
pdd/sync_orchestration.py,sha256=FizZkwWPj30WCRVZIVKoyRXR3IxTC0LbcroMenq3xlQ,68320
|
|
65
65
|
pdd/trace.py,sha256=oXHbOMfxeso7m81N5V2ixS_l6BPAlZrH6vifn0IgWbo,5225
|
|
66
66
|
pdd/trace_main.py,sha256=Z8m8UgRZoaojX_H6aDDU7_lB7WNCLwZpFxbPTm1s-6s,4902
|
|
67
67
|
pdd/track_cost.py,sha256=VIrHYh4i2G5T5Dq1plxwuzsG4OrHQgO0GPgFckgsQ_4,3266
|
|
@@ -108,9 +108,9 @@ pdd/prompts/trim_results_start_LLM.prompt,sha256=OKz8fAf1cYWKWgslFOHEkUpfaUDARh3
|
|
|
108
108
|
pdd/prompts/unfinished_prompt_LLM.prompt,sha256=-JgBpiPTQZdWOAwOG1XpfpD9waynFTAT3Jo84eQ4bTw,1543
|
|
109
109
|
pdd/prompts/update_prompt_LLM.prompt,sha256=prIc8uLp2jqnLTHt6JvWDZGanPZipivhhYeXe0lVaYw,1328
|
|
110
110
|
pdd/prompts/xml_convertor_LLM.prompt,sha256=YGRGXJeg6EhM9690f-SKqQrKqSJjLFD51UrPOlO0Frg,2786
|
|
111
|
-
pdd_cli-0.0.
|
|
112
|
-
pdd_cli-0.0.
|
|
113
|
-
pdd_cli-0.0.
|
|
114
|
-
pdd_cli-0.0.
|
|
115
|
-
pdd_cli-0.0.
|
|
116
|
-
pdd_cli-0.0.
|
|
111
|
+
pdd_cli-0.0.49.dist-info/licenses/LICENSE,sha256=-1bjYH-CEjGEQ8VixtnRYuu37kN6F9NxmZSDkBuUQ9o,1062
|
|
112
|
+
pdd_cli-0.0.49.dist-info/METADATA,sha256=oOFDn3p_wev8d-q6JuhsPX6UQpdzN9Hb5feLaP7xEx0,12446
|
|
113
|
+
pdd_cli-0.0.49.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
114
|
+
pdd_cli-0.0.49.dist-info/entry_points.txt,sha256=Kr8HtNVb8uHZtQJNH4DnF8j7WNgWQbb7_Pw5hECSR-I,36
|
|
115
|
+
pdd_cli-0.0.49.dist-info/top_level.txt,sha256=xjnhIACeMcMeDfVNREgQZl4EbTni2T11QkL5r7E-sbE,4
|
|
116
|
+
pdd_cli-0.0.49.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|