pdd-cli 0.0.45__py3-none-any.whl → 0.0.118__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.
- pdd/__init__.py +40 -8
- pdd/agentic_bug.py +323 -0
- pdd/agentic_bug_orchestrator.py +497 -0
- pdd/agentic_change.py +231 -0
- pdd/agentic_change_orchestrator.py +526 -0
- pdd/agentic_common.py +598 -0
- pdd/agentic_crash.py +534 -0
- pdd/agentic_e2e_fix.py +319 -0
- pdd/agentic_e2e_fix_orchestrator.py +426 -0
- pdd/agentic_fix.py +1294 -0
- pdd/agentic_langtest.py +162 -0
- pdd/agentic_update.py +387 -0
- pdd/agentic_verify.py +183 -0
- pdd/architecture_sync.py +565 -0
- pdd/auth_service.py +210 -0
- pdd/auto_deps_main.py +71 -51
- pdd/auto_include.py +245 -5
- pdd/auto_update.py +125 -47
- pdd/bug_main.py +196 -23
- pdd/bug_to_unit_test.py +2 -0
- pdd/change_main.py +11 -4
- pdd/cli.py +22 -1181
- pdd/cmd_test_main.py +350 -150
- pdd/code_generator.py +60 -18
- pdd/code_generator_main.py +790 -57
- pdd/commands/__init__.py +48 -0
- pdd/commands/analysis.py +306 -0
- pdd/commands/auth.py +309 -0
- pdd/commands/connect.py +290 -0
- pdd/commands/fix.py +163 -0
- pdd/commands/generate.py +257 -0
- pdd/commands/maintenance.py +175 -0
- pdd/commands/misc.py +87 -0
- pdd/commands/modify.py +256 -0
- pdd/commands/report.py +144 -0
- pdd/commands/sessions.py +284 -0
- pdd/commands/templates.py +215 -0
- pdd/commands/utility.py +110 -0
- pdd/config_resolution.py +58 -0
- pdd/conflicts_main.py +8 -3
- pdd/construct_paths.py +589 -111
- pdd/context_generator.py +10 -2
- pdd/context_generator_main.py +175 -76
- pdd/continue_generation.py +53 -10
- pdd/core/__init__.py +33 -0
- pdd/core/cli.py +527 -0
- pdd/core/cloud.py +237 -0
- pdd/core/dump.py +554 -0
- pdd/core/errors.py +67 -0
- pdd/core/remote_session.py +61 -0
- pdd/core/utils.py +90 -0
- pdd/crash_main.py +262 -33
- pdd/data/language_format.csv +71 -63
- pdd/data/llm_model.csv +20 -18
- pdd/detect_change_main.py +5 -4
- pdd/docs/prompting_guide.md +864 -0
- pdd/docs/whitepaper_with_benchmarks/data_and_functions/benchmark_analysis.py +495 -0
- pdd/docs/whitepaper_with_benchmarks/data_and_functions/creation_compare.py +528 -0
- pdd/fix_code_loop.py +523 -95
- pdd/fix_code_module_errors.py +6 -2
- pdd/fix_error_loop.py +491 -92
- pdd/fix_errors_from_unit_tests.py +4 -3
- pdd/fix_main.py +278 -21
- pdd/fix_verification_errors.py +12 -100
- pdd/fix_verification_errors_loop.py +529 -286
- pdd/fix_verification_main.py +294 -89
- pdd/frontend/dist/assets/index-B5DZHykP.css +1 -0
- pdd/frontend/dist/assets/index-DQ3wkeQ2.js +449 -0
- pdd/frontend/dist/index.html +376 -0
- pdd/frontend/dist/logo.svg +33 -0
- pdd/generate_output_paths.py +139 -15
- pdd/generate_test.py +218 -146
- pdd/get_comment.py +19 -44
- pdd/get_extension.py +8 -9
- pdd/get_jwt_token.py +318 -22
- pdd/get_language.py +8 -7
- pdd/get_run_command.py +75 -0
- pdd/get_test_command.py +68 -0
- pdd/git_update.py +70 -19
- pdd/incremental_code_generator.py +2 -2
- pdd/insert_includes.py +13 -4
- pdd/llm_invoke.py +1711 -181
- pdd/load_prompt_template.py +19 -12
- pdd/path_resolution.py +140 -0
- pdd/pdd_completion.fish +25 -2
- pdd/pdd_completion.sh +30 -4
- pdd/pdd_completion.zsh +79 -4
- pdd/postprocess.py +14 -4
- pdd/preprocess.py +293 -24
- pdd/preprocess_main.py +41 -6
- pdd/prompts/agentic_bug_step10_pr_LLM.prompt +182 -0
- pdd/prompts/agentic_bug_step1_duplicate_LLM.prompt +73 -0
- pdd/prompts/agentic_bug_step2_docs_LLM.prompt +129 -0
- pdd/prompts/agentic_bug_step3_triage_LLM.prompt +95 -0
- pdd/prompts/agentic_bug_step4_reproduce_LLM.prompt +97 -0
- pdd/prompts/agentic_bug_step5_root_cause_LLM.prompt +123 -0
- pdd/prompts/agentic_bug_step6_test_plan_LLM.prompt +107 -0
- pdd/prompts/agentic_bug_step7_generate_LLM.prompt +172 -0
- pdd/prompts/agentic_bug_step8_verify_LLM.prompt +119 -0
- pdd/prompts/agentic_bug_step9_e2e_test_LLM.prompt +289 -0
- pdd/prompts/agentic_change_step10_identify_issues_LLM.prompt +1006 -0
- pdd/prompts/agentic_change_step11_fix_issues_LLM.prompt +984 -0
- pdd/prompts/agentic_change_step12_create_pr_LLM.prompt +131 -0
- pdd/prompts/agentic_change_step1_duplicate_LLM.prompt +73 -0
- pdd/prompts/agentic_change_step2_docs_LLM.prompt +101 -0
- pdd/prompts/agentic_change_step3_research_LLM.prompt +126 -0
- pdd/prompts/agentic_change_step4_clarify_LLM.prompt +164 -0
- pdd/prompts/agentic_change_step5_docs_change_LLM.prompt +981 -0
- pdd/prompts/agentic_change_step6_devunits_LLM.prompt +1005 -0
- pdd/prompts/agentic_change_step7_architecture_LLM.prompt +1044 -0
- pdd/prompts/agentic_change_step8_analyze_LLM.prompt +1027 -0
- pdd/prompts/agentic_change_step9_implement_LLM.prompt +1077 -0
- pdd/prompts/agentic_crash_explore_LLM.prompt +49 -0
- pdd/prompts/agentic_e2e_fix_step1_unit_tests_LLM.prompt +90 -0
- pdd/prompts/agentic_e2e_fix_step2_e2e_tests_LLM.prompt +91 -0
- pdd/prompts/agentic_e2e_fix_step3_root_cause_LLM.prompt +89 -0
- pdd/prompts/agentic_e2e_fix_step4_fix_e2e_tests_LLM.prompt +96 -0
- pdd/prompts/agentic_e2e_fix_step5_identify_devunits_LLM.prompt +91 -0
- pdd/prompts/agentic_e2e_fix_step6_create_unit_tests_LLM.prompt +106 -0
- pdd/prompts/agentic_e2e_fix_step7_verify_tests_LLM.prompt +116 -0
- pdd/prompts/agentic_e2e_fix_step8_run_pdd_fix_LLM.prompt +120 -0
- pdd/prompts/agentic_e2e_fix_step9_verify_all_LLM.prompt +146 -0
- pdd/prompts/agentic_fix_explore_LLM.prompt +45 -0
- pdd/prompts/agentic_fix_harvest_only_LLM.prompt +48 -0
- pdd/prompts/agentic_fix_primary_LLM.prompt +85 -0
- pdd/prompts/agentic_update_LLM.prompt +925 -0
- pdd/prompts/agentic_verify_explore_LLM.prompt +45 -0
- pdd/prompts/auto_include_LLM.prompt +122 -905
- pdd/prompts/change_LLM.prompt +3093 -1
- pdd/prompts/detect_change_LLM.prompt +686 -27
- pdd/prompts/example_generator_LLM.prompt +22 -1
- pdd/prompts/extract_code_LLM.prompt +5 -1
- pdd/prompts/extract_program_code_fix_LLM.prompt +7 -1
- pdd/prompts/extract_prompt_update_LLM.prompt +7 -8
- pdd/prompts/extract_promptline_LLM.prompt +17 -11
- pdd/prompts/find_verification_errors_LLM.prompt +6 -0
- pdd/prompts/fix_code_module_errors_LLM.prompt +12 -2
- pdd/prompts/fix_errors_from_unit_tests_LLM.prompt +9 -0
- pdd/prompts/fix_verification_errors_LLM.prompt +22 -0
- pdd/prompts/generate_test_LLM.prompt +41 -7
- pdd/prompts/generate_test_from_example_LLM.prompt +115 -0
- pdd/prompts/increase_tests_LLM.prompt +1 -5
- pdd/prompts/insert_includes_LLM.prompt +316 -186
- pdd/prompts/prompt_code_diff_LLM.prompt +119 -0
- pdd/prompts/prompt_diff_LLM.prompt +82 -0
- pdd/prompts/trace_LLM.prompt +25 -22
- pdd/prompts/unfinished_prompt_LLM.prompt +85 -1
- pdd/prompts/update_prompt_LLM.prompt +22 -1
- pdd/pytest_output.py +127 -12
- pdd/remote_session.py +876 -0
- pdd/render_mermaid.py +236 -0
- pdd/server/__init__.py +52 -0
- pdd/server/app.py +335 -0
- pdd/server/click_executor.py +587 -0
- pdd/server/executor.py +338 -0
- pdd/server/jobs.py +661 -0
- pdd/server/models.py +241 -0
- pdd/server/routes/__init__.py +31 -0
- pdd/server/routes/architecture.py +451 -0
- pdd/server/routes/auth.py +364 -0
- pdd/server/routes/commands.py +929 -0
- pdd/server/routes/config.py +42 -0
- pdd/server/routes/files.py +603 -0
- pdd/server/routes/prompts.py +1322 -0
- pdd/server/routes/websocket.py +473 -0
- pdd/server/security.py +243 -0
- pdd/server/terminal_spawner.py +209 -0
- pdd/server/token_counter.py +222 -0
- pdd/setup_tool.py +648 -0
- pdd/simple_math.py +2 -0
- pdd/split_main.py +3 -2
- pdd/summarize_directory.py +237 -195
- pdd/sync_animation.py +8 -4
- pdd/sync_determine_operation.py +839 -112
- pdd/sync_main.py +351 -57
- pdd/sync_orchestration.py +1400 -756
- pdd/sync_tui.py +848 -0
- pdd/template_expander.py +161 -0
- pdd/template_registry.py +264 -0
- pdd/templates/architecture/architecture_json.prompt +237 -0
- pdd/templates/generic/generate_prompt.prompt +174 -0
- pdd/trace.py +168 -12
- pdd/trace_main.py +4 -3
- pdd/track_cost.py +140 -63
- pdd/unfinished_prompt.py +51 -4
- pdd/update_main.py +567 -67
- pdd/update_model_costs.py +2 -2
- pdd/update_prompt.py +19 -4
- {pdd_cli-0.0.45.dist-info → pdd_cli-0.0.118.dist-info}/METADATA +29 -11
- pdd_cli-0.0.118.dist-info/RECORD +227 -0
- {pdd_cli-0.0.45.dist-info → pdd_cli-0.0.118.dist-info}/licenses/LICENSE +1 -1
- pdd_cli-0.0.45.dist-info/RECORD +0 -116
- {pdd_cli-0.0.45.dist-info → pdd_cli-0.0.118.dist-info}/WHEEL +0 -0
- {pdd_cli-0.0.45.dist-info → pdd_cli-0.0.118.dist-info}/entry_points.txt +0 -0
- {pdd_cli-0.0.45.dist-info → pdd_cli-0.0.118.dist-info}/top_level.txt +0 -0
pdd/core/utils.py
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Helper functions for the PDD CLI.
|
|
3
|
+
"""
|
|
4
|
+
import os
|
|
5
|
+
import sys
|
|
6
|
+
import subprocess
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from typing import Optional
|
|
9
|
+
import click
|
|
10
|
+
|
|
11
|
+
from ..install_completion import (
|
|
12
|
+
get_current_shell,
|
|
13
|
+
get_shell_rc_path,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
def _first_pending_command(ctx: click.Context) -> Optional[str]:
|
|
17
|
+
"""Return the first subcommand scheduled for this invocation."""
|
|
18
|
+
for arg in ctx.protected_args:
|
|
19
|
+
if not arg.startswith("-"):
|
|
20
|
+
return arg
|
|
21
|
+
return None
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _api_env_exists() -> bool:
|
|
25
|
+
"""Check whether the ~/.pdd/api-env file exists."""
|
|
26
|
+
return (Path.home() / ".pdd" / "api-env").exists()
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def _completion_installed() -> bool:
|
|
30
|
+
"""Check if the shell RC file already sources the PDD completion script."""
|
|
31
|
+
shell = get_current_shell()
|
|
32
|
+
rc_path = get_shell_rc_path(shell) if shell else None
|
|
33
|
+
if not rc_path:
|
|
34
|
+
return False
|
|
35
|
+
|
|
36
|
+
try:
|
|
37
|
+
content = Path(rc_path).read_text(encoding="utf-8")
|
|
38
|
+
except (OSError, UnicodeDecodeError):
|
|
39
|
+
return False
|
|
40
|
+
|
|
41
|
+
return "PDD CLI completion" in content or "pdd_completion" in content
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def _project_has_local_configuration() -> bool:
|
|
45
|
+
"""Detect project-level env configuration that should suppress reminders."""
|
|
46
|
+
cwd = Path.cwd()
|
|
47
|
+
|
|
48
|
+
env_file = cwd / ".env"
|
|
49
|
+
if env_file.exists():
|
|
50
|
+
try:
|
|
51
|
+
env_content = env_file.read_text(encoding="utf-8")
|
|
52
|
+
except (OSError, UnicodeDecodeError):
|
|
53
|
+
env_content = ""
|
|
54
|
+
if any(token in env_content for token in ("OPENAI_API_KEY=", "GOOGLE_API_KEY=", "ANTHROPIC_API_KEY=")):
|
|
55
|
+
return True
|
|
56
|
+
|
|
57
|
+
project_pdd_dir = cwd / ".pdd"
|
|
58
|
+
if project_pdd_dir.exists():
|
|
59
|
+
return True
|
|
60
|
+
|
|
61
|
+
return False
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def _should_show_onboarding_reminder(ctx: click.Context) -> bool:
|
|
65
|
+
"""Determine whether to display the onboarding reminder banner."""
|
|
66
|
+
suppress = os.getenv("PDD_SUPPRESS_SETUP_REMINDER", "").lower()
|
|
67
|
+
if suppress in {"1", "true", "yes"}:
|
|
68
|
+
return False
|
|
69
|
+
|
|
70
|
+
first_command = _first_pending_command(ctx)
|
|
71
|
+
if first_command == "setup":
|
|
72
|
+
return False
|
|
73
|
+
|
|
74
|
+
if _api_env_exists():
|
|
75
|
+
return False
|
|
76
|
+
|
|
77
|
+
if _project_has_local_configuration():
|
|
78
|
+
return False
|
|
79
|
+
|
|
80
|
+
if _completion_installed():
|
|
81
|
+
return False
|
|
82
|
+
|
|
83
|
+
return True
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def _run_setup_utility() -> None:
|
|
87
|
+
"""Execute the interactive setup utility script."""
|
|
88
|
+
result = subprocess.run([sys.executable, "-m", "pdd.setup_tool"])
|
|
89
|
+
if result.returncode not in (0, None):
|
|
90
|
+
raise RuntimeError(f"Setup utility exited with status {result.returncode}")
|
pdd/crash_main.py
CHANGED
|
@@ -1,12 +1,21 @@
|
|
|
1
1
|
import sys
|
|
2
2
|
from typing import Tuple, Optional, Dict, Any
|
|
3
|
+
import json
|
|
3
4
|
import click
|
|
4
5
|
from rich import print as rprint
|
|
5
|
-
from . import
|
|
6
|
+
from rich.console import Console
|
|
7
|
+
from rich.panel import Panel
|
|
6
8
|
from pathlib import Path
|
|
7
9
|
|
|
10
|
+
import requests
|
|
11
|
+
import os
|
|
12
|
+
|
|
13
|
+
from .config_resolution import resolve_effective_config
|
|
8
14
|
from .construct_paths import construct_paths
|
|
9
15
|
from .fix_code_loop import fix_code_loop
|
|
16
|
+
from .core.cloud import CloudConfig
|
|
17
|
+
from .get_language import get_language
|
|
18
|
+
|
|
10
19
|
# Import fix_code_module_errors conditionally or ensure it's always available
|
|
11
20
|
try:
|
|
12
21
|
from .fix_code_module_errors import fix_code_module_errors
|
|
@@ -14,6 +23,19 @@ except ImportError:
|
|
|
14
23
|
# Handle case where fix_code_module_errors might not be available if not needed
|
|
15
24
|
fix_code_module_errors = None
|
|
16
25
|
|
|
26
|
+
# Cloud request timeout
|
|
27
|
+
CLOUD_REQUEST_TIMEOUT = 400 # seconds
|
|
28
|
+
|
|
29
|
+
console = Console()
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _env_flag_enabled(name: str) -> bool:
|
|
33
|
+
"""Return True when an env var is set to a truthy value."""
|
|
34
|
+
value = os.environ.get(name)
|
|
35
|
+
if value is None:
|
|
36
|
+
return False
|
|
37
|
+
return str(value).strip().lower() in {"1", "true", "yes", "on"}
|
|
38
|
+
|
|
17
39
|
def crash_main(
|
|
18
40
|
ctx: click.Context,
|
|
19
41
|
prompt_file: str,
|
|
@@ -24,7 +46,10 @@ def crash_main(
|
|
|
24
46
|
output_program: Optional[str] = None,
|
|
25
47
|
loop: bool = False,
|
|
26
48
|
max_attempts: Optional[int] = None,
|
|
27
|
-
budget: Optional[float] = None
|
|
49
|
+
budget: Optional[float] = None,
|
|
50
|
+
agentic_fallback: bool = True,
|
|
51
|
+
strength: Optional[float] = None,
|
|
52
|
+
temperature: Optional[float] = None,
|
|
28
53
|
) -> Tuple[bool, str, str, int, float, str]:
|
|
29
54
|
"""
|
|
30
55
|
Main function to fix errors in a code module and its calling program that caused a crash.
|
|
@@ -39,6 +64,7 @@ def crash_main(
|
|
|
39
64
|
:param loop: Enable iterative fixing process.
|
|
40
65
|
:param max_attempts: Maximum number of fix attempts before giving up.
|
|
41
66
|
:param budget: Maximum cost allowed for the fixing process.
|
|
67
|
+
:param agentic_fallback: Enable agentic fallback if the primary fix mechanism fails.
|
|
42
68
|
:return: A tuple containing:
|
|
43
69
|
- bool: Success status
|
|
44
70
|
- str: The final fixed code module
|
|
@@ -54,9 +80,9 @@ def crash_main(
|
|
|
54
80
|
quiet = ctx.params.get("quiet", ctx.obj.get("quiet", False))
|
|
55
81
|
verbose = ctx.params.get("verbose", ctx.obj.get("verbose", False))
|
|
56
82
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
83
|
+
# Store parameter values for later resolution
|
|
84
|
+
param_strength = strength
|
|
85
|
+
param_temperature = temperature
|
|
60
86
|
|
|
61
87
|
try:
|
|
62
88
|
input_file_paths = {
|
|
@@ -77,8 +103,20 @@ def crash_main(
|
|
|
77
103
|
force=force,
|
|
78
104
|
quiet=quiet,
|
|
79
105
|
command="crash",
|
|
80
|
-
command_options=command_options
|
|
106
|
+
command_options=command_options,
|
|
107
|
+
context_override=ctx.obj.get('context'),
|
|
108
|
+
confirm_callback=ctx.obj.get('confirm_callback')
|
|
109
|
+
)
|
|
110
|
+
# Use centralized config resolution with proper priority:
|
|
111
|
+
# CLI > pddrc > defaults
|
|
112
|
+
effective_config = resolve_effective_config(
|
|
113
|
+
ctx,
|
|
114
|
+
resolved_config,
|
|
115
|
+
param_overrides={"strength": param_strength, "temperature": param_temperature}
|
|
81
116
|
)
|
|
117
|
+
strength = effective_config["strength"]
|
|
118
|
+
temperature = effective_config["temperature"]
|
|
119
|
+
time_param = effective_config["time"]
|
|
82
120
|
|
|
83
121
|
prompt_content = input_strings["prompt_file"]
|
|
84
122
|
code_content = input_strings["code_file"]
|
|
@@ -91,10 +129,33 @@ def crash_main(
|
|
|
91
129
|
code_updated: bool = False
|
|
92
130
|
program_updated: bool = False
|
|
93
131
|
|
|
132
|
+
# Determine cloud vs local execution preference
|
|
133
|
+
is_local_execution_preferred = ctx.obj.get('local', False)
|
|
134
|
+
cloud_only = _env_flag_enabled("PDD_CLOUD_ONLY") or _env_flag_enabled("PDD_NO_LOCAL_FALLBACK")
|
|
135
|
+
current_execution_is_local = is_local_execution_preferred and not cloud_only
|
|
136
|
+
|
|
137
|
+
# Cloud execution tracking
|
|
138
|
+
cloud_execution_attempted = False
|
|
139
|
+
cloud_execution_succeeded = False
|
|
140
|
+
|
|
94
141
|
if loop:
|
|
142
|
+
# Determine if loop should use cloud for LLM calls (hybrid mode)
|
|
143
|
+
# Local program execution stays local, but LLM fix calls can go to cloud
|
|
144
|
+
use_cloud_for_loop = not is_local_execution_preferred and not cloud_only
|
|
145
|
+
|
|
146
|
+
# If cloud_only is set but we're in loop mode, we still use hybrid approach
|
|
147
|
+
if cloud_only and not is_local_execution_preferred:
|
|
148
|
+
use_cloud_for_loop = True
|
|
149
|
+
|
|
150
|
+
if verbose:
|
|
151
|
+
mode_desc = "hybrid (local execution + cloud LLM)" if use_cloud_for_loop else "local"
|
|
152
|
+
console.print(Panel(f"Performing {mode_desc} crash fix loop...", title="[blue]Mode[/blue]", expand=False))
|
|
153
|
+
|
|
95
154
|
success, final_program, final_code, attempts, cost, model = fix_code_loop(
|
|
96
155
|
code_file, prompt_content, program_file, strength, temperature,
|
|
97
|
-
max_attempts
|
|
156
|
+
max_attempts if max_attempts is not None else 3, budget or 5.0, error_file, verbose, time_param,
|
|
157
|
+
prompt_file=prompt_file, agentic_fallback=agentic_fallback,
|
|
158
|
+
use_cloud=use_cloud_for_loop
|
|
98
159
|
)
|
|
99
160
|
# Always set final_code/final_program to something non-empty
|
|
100
161
|
if not final_code:
|
|
@@ -104,33 +165,182 @@ def crash_main(
|
|
|
104
165
|
code_updated = final_code != original_code_content
|
|
105
166
|
program_updated = final_program != original_program_content
|
|
106
167
|
else:
|
|
107
|
-
|
|
108
|
-
|
|
168
|
+
# Single-pass mode: attempt cloud first, fallback to local
|
|
169
|
+
if not current_execution_is_local:
|
|
170
|
+
if verbose:
|
|
171
|
+
console.print(Panel("Attempting cloud crash fix execution...", title="[blue]Mode[/blue]", expand=False))
|
|
109
172
|
|
|
110
|
-
|
|
111
|
-
program_content, prompt_content, code_content, error_content,
|
|
112
|
-
strength, temperature, verbose, time_param
|
|
113
|
-
)
|
|
114
|
-
success = True
|
|
115
|
-
attempts = 1
|
|
173
|
+
jwt_token = CloudConfig.get_jwt_token(verbose=verbose)
|
|
116
174
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
175
|
+
if not jwt_token:
|
|
176
|
+
if cloud_only:
|
|
177
|
+
console.print("[red]Cloud authentication failed.[/red]")
|
|
178
|
+
raise click.UsageError("Cloud authentication failed")
|
|
179
|
+
console.print("[yellow]Cloud authentication failed. Falling back to local execution.[/yellow]")
|
|
180
|
+
current_execution_is_local = True
|
|
122
181
|
|
|
123
|
-
|
|
124
|
-
|
|
182
|
+
if jwt_token and not current_execution_is_local:
|
|
183
|
+
cloud_execution_attempted = True
|
|
184
|
+
# Build cloud payload
|
|
185
|
+
payload = {
|
|
186
|
+
"programContent": program_content,
|
|
187
|
+
"promptContent": prompt_content,
|
|
188
|
+
"codeContent": code_content,
|
|
189
|
+
"errorContent": error_content,
|
|
190
|
+
"language": language,
|
|
191
|
+
"strength": strength,
|
|
192
|
+
"temperature": temperature,
|
|
193
|
+
"time": time_param if time_param is not None else 0.25,
|
|
194
|
+
"verbose": verbose,
|
|
195
|
+
"programPath": program_file,
|
|
196
|
+
"codePath": code_file,
|
|
197
|
+
}
|
|
125
198
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
199
|
+
headers = {
|
|
200
|
+
"Authorization": f"Bearer {jwt_token}",
|
|
201
|
+
"Content-Type": "application/json"
|
|
202
|
+
}
|
|
203
|
+
cloud_url = CloudConfig.get_endpoint_url("crashCode")
|
|
131
204
|
|
|
132
|
-
|
|
133
|
-
|
|
205
|
+
try:
|
|
206
|
+
response = requests.post(
|
|
207
|
+
cloud_url,
|
|
208
|
+
json=payload,
|
|
209
|
+
headers=headers,
|
|
210
|
+
timeout=CLOUD_REQUEST_TIMEOUT
|
|
211
|
+
)
|
|
212
|
+
response.raise_for_status()
|
|
213
|
+
|
|
214
|
+
response_data = response.json()
|
|
215
|
+
fixed_code = response_data.get("fixedCode", "")
|
|
216
|
+
fixed_program = response_data.get("fixedProgram", "")
|
|
217
|
+
update_code = response_data.get("updateCode", False)
|
|
218
|
+
update_program = response_data.get("updateProgram", False)
|
|
219
|
+
cost = float(response_data.get("totalCost", 0.0))
|
|
220
|
+
model = response_data.get("modelName", "cloud_model")
|
|
221
|
+
|
|
222
|
+
if not (fixed_code or fixed_program):
|
|
223
|
+
if cloud_only:
|
|
224
|
+
console.print("[red]Cloud execution returned no fixed code.[/red]")
|
|
225
|
+
raise click.UsageError("Cloud execution returned no fixed code")
|
|
226
|
+
console.print("[yellow]Cloud execution returned no fixed code. Falling back to local.[/yellow]")
|
|
227
|
+
current_execution_is_local = True
|
|
228
|
+
else:
|
|
229
|
+
cloud_execution_succeeded = True
|
|
230
|
+
success = True
|
|
231
|
+
attempts = 1
|
|
232
|
+
|
|
233
|
+
# Fallback if fixed_program is empty but update_program is True
|
|
234
|
+
if update_program and not fixed_program.strip():
|
|
235
|
+
fixed_program = program_content
|
|
236
|
+
if update_code and not fixed_code.strip():
|
|
237
|
+
fixed_code = code_content
|
|
238
|
+
|
|
239
|
+
final_code = fixed_code if update_code else code_content
|
|
240
|
+
final_program = fixed_program if update_program else program_content
|
|
241
|
+
|
|
242
|
+
# Always set final_code/final_program to something non-empty
|
|
243
|
+
if not final_code:
|
|
244
|
+
final_code = original_code_content
|
|
245
|
+
if not final_program:
|
|
246
|
+
final_program = original_program_content
|
|
247
|
+
|
|
248
|
+
code_updated = final_code != original_code_content
|
|
249
|
+
program_updated = final_program != original_program_content
|
|
250
|
+
|
|
251
|
+
if verbose:
|
|
252
|
+
console.print(Panel(
|
|
253
|
+
f"Cloud crash fix completed. Model: {model}, Cost: ${cost:.6f}",
|
|
254
|
+
title="[green]Cloud Success[/green]",
|
|
255
|
+
expand=False
|
|
256
|
+
))
|
|
257
|
+
|
|
258
|
+
except requests.exceptions.Timeout:
|
|
259
|
+
if cloud_only:
|
|
260
|
+
console.print(f"[red]Cloud execution timed out ({CLOUD_REQUEST_TIMEOUT}s).[/red]")
|
|
261
|
+
raise click.UsageError("Cloud execution timed out")
|
|
262
|
+
console.print(f"[yellow]Cloud execution timed out ({CLOUD_REQUEST_TIMEOUT}s). Falling back to local.[/yellow]")
|
|
263
|
+
current_execution_is_local = True
|
|
264
|
+
|
|
265
|
+
except requests.exceptions.HTTPError as e:
|
|
266
|
+
status_code = e.response.status_code if e.response else 0
|
|
267
|
+
err_content = e.response.text[:200] if e.response else "No response content"
|
|
268
|
+
|
|
269
|
+
# Non-recoverable errors: do NOT fall back to local
|
|
270
|
+
if status_code == 402: # Insufficient credits
|
|
271
|
+
try:
|
|
272
|
+
error_data = e.response.json()
|
|
273
|
+
current_balance = error_data.get("currentBalance", "unknown")
|
|
274
|
+
estimated_cost = error_data.get("estimatedCost", "unknown")
|
|
275
|
+
console.print(f"[red]Insufficient credits. Current balance: {current_balance}, estimated cost: {estimated_cost}[/red]")
|
|
276
|
+
except Exception:
|
|
277
|
+
console.print(f"[red]Insufficient credits: {err_content}[/red]")
|
|
278
|
+
raise click.UsageError("Insufficient credits for cloud crash fix")
|
|
279
|
+
elif status_code == 401: # Authentication error
|
|
280
|
+
console.print(f"[red]Authentication failed: {err_content}[/red]")
|
|
281
|
+
raise click.UsageError("Cloud authentication failed")
|
|
282
|
+
elif status_code == 403: # Authorization error (not approved)
|
|
283
|
+
console.print(f"[red]Access denied: {err_content}[/red]")
|
|
284
|
+
raise click.UsageError("Access denied - user not approved")
|
|
285
|
+
elif status_code == 400: # Validation error
|
|
286
|
+
console.print(f"[red]Invalid request: {err_content}[/red]")
|
|
287
|
+
raise click.UsageError(f"Invalid request: {err_content}")
|
|
288
|
+
else:
|
|
289
|
+
# Recoverable errors (5xx, unexpected errors): fall back to local
|
|
290
|
+
if cloud_only:
|
|
291
|
+
console.print(f"[red]Cloud HTTP error ({status_code}): {err_content}[/red]")
|
|
292
|
+
raise click.UsageError(f"Cloud HTTP error ({status_code}): {err_content}")
|
|
293
|
+
console.print(f"[yellow]Cloud HTTP error ({status_code}): {err_content}. Falling back to local.[/yellow]")
|
|
294
|
+
current_execution_is_local = True
|
|
295
|
+
|
|
296
|
+
except requests.exceptions.RequestException as e:
|
|
297
|
+
if cloud_only:
|
|
298
|
+
console.print(f"[red]Cloud network error: {e}[/red]")
|
|
299
|
+
raise click.UsageError(f"Cloud network error: {e}")
|
|
300
|
+
console.print(f"[yellow]Cloud network error: {e}. Falling back to local.[/yellow]")
|
|
301
|
+
current_execution_is_local = True
|
|
302
|
+
|
|
303
|
+
except json.JSONDecodeError:
|
|
304
|
+
if cloud_only:
|
|
305
|
+
console.print("[red]Cloud returned invalid JSON.[/red]")
|
|
306
|
+
raise click.UsageError("Cloud returned invalid JSON")
|
|
307
|
+
console.print("[yellow]Cloud returned invalid JSON. Falling back to local.[/yellow]")
|
|
308
|
+
current_execution_is_local = True
|
|
309
|
+
|
|
310
|
+
# Local execution path (when cloud failed/skipped or local preferred)
|
|
311
|
+
if not cloud_execution_succeeded:
|
|
312
|
+
if fix_code_module_errors is None:
|
|
313
|
+
raise ImportError("fix_code_module_errors is required but not available.")
|
|
314
|
+
|
|
315
|
+
if verbose:
|
|
316
|
+
console.print(Panel("Performing local crash fix...", title="[blue]Mode[/blue]", expand=False))
|
|
317
|
+
|
|
318
|
+
update_program, update_code, fixed_program, fixed_code, _, cost, model = fix_code_module_errors(
|
|
319
|
+
program_content, prompt_content, code_content, error_content,
|
|
320
|
+
strength, temperature, time_param, verbose,
|
|
321
|
+
program_path=program_file,
|
|
322
|
+
code_path=code_file,
|
|
323
|
+
)
|
|
324
|
+
success = True
|
|
325
|
+
attempts = 1
|
|
326
|
+
|
|
327
|
+
# Fallback if fixed_program is empty but update_program is True
|
|
328
|
+
if update_program and not fixed_program.strip():
|
|
329
|
+
fixed_program = program_content
|
|
330
|
+
if update_code and not fixed_code.strip():
|
|
331
|
+
fixed_code = code_content
|
|
332
|
+
|
|
333
|
+
final_code = fixed_code if update_code else code_content
|
|
334
|
+
final_program = fixed_program if update_program else program_content
|
|
335
|
+
|
|
336
|
+
# Always set final_code/final_program to something non-empty
|
|
337
|
+
if not final_code:
|
|
338
|
+
final_code = original_code_content
|
|
339
|
+
if not final_program:
|
|
340
|
+
final_program = original_program_content
|
|
341
|
+
|
|
342
|
+
code_updated = final_code != original_code_content
|
|
343
|
+
program_updated = final_program != original_program_content
|
|
134
344
|
|
|
135
345
|
output_code_path_str = output_file_paths.get("output")
|
|
136
346
|
output_program_path_str = output_file_paths.get("output_program")
|
|
@@ -161,20 +371,39 @@ def crash_main(
|
|
|
161
371
|
if code_updated:
|
|
162
372
|
rprint(f"[bold]Fixed code saved to:[/bold] {output_code_path_str}")
|
|
163
373
|
else:
|
|
164
|
-
rprint(f"[
|
|
374
|
+
rprint(f"[bold]Code saved to:[/bold] {output_code_path_str} [dim](not modified)[/dim]")
|
|
165
375
|
if output_program_path_str:
|
|
166
376
|
if program_updated:
|
|
167
377
|
rprint(f"[bold]Fixed program saved to:[/bold] {output_program_path_str}")
|
|
168
378
|
else:
|
|
169
|
-
rprint(f"[
|
|
379
|
+
rprint(f"[bold]Program saved to:[/bold] {output_program_path_str} [dim](not modified)[/dim]")
|
|
380
|
+
|
|
381
|
+
if verbose:
|
|
382
|
+
rprint("\n[bold]Verbose diagnostics:[/bold]")
|
|
383
|
+
rprint(f" Code file: {code_file}")
|
|
384
|
+
rprint(f" Program file: {program_file}")
|
|
385
|
+
rprint(f" Code updated: {code_updated}")
|
|
386
|
+
rprint(f" Program updated: {program_updated}")
|
|
387
|
+
rprint(f" Original code length: {len(original_code_content)} chars")
|
|
388
|
+
rprint(f" Final code length: {len(final_code)} chars")
|
|
389
|
+
rprint(f" Original program length: {len(original_program_content)} chars")
|
|
390
|
+
rprint(f" Final program length: {len(final_program)} chars")
|
|
170
391
|
|
|
171
392
|
return success, final_code, final_program, attempts, cost, model
|
|
172
393
|
|
|
173
394
|
except FileNotFoundError as e:
|
|
174
395
|
if not quiet:
|
|
175
396
|
rprint(f"[bold red]Error:[/bold red] Input file not found: {e}")
|
|
176
|
-
sys.exit(1)
|
|
397
|
+
# Return error result instead of sys.exit(1) to allow orchestrator to handle gracefully
|
|
398
|
+
return False, "", "", 0, 0.0, f"FileNotFoundError: {e}"
|
|
399
|
+
except click.Abort:
|
|
400
|
+
# User cancelled - re-raise to stop the sync loop
|
|
401
|
+
raise
|
|
402
|
+
except click.UsageError:
|
|
403
|
+
# Re-raise UsageError for proper CLI handling (e.g., cloud auth failures, insufficient credits)
|
|
404
|
+
raise
|
|
177
405
|
except Exception as e:
|
|
178
406
|
if not quiet:
|
|
179
407
|
rprint(f"[bold red]An unexpected error occurred:[/bold red] {str(e)}")
|
|
180
|
-
sys.exit(1)
|
|
408
|
+
# Return error result instead of sys.exit(1) to allow orchestrator to handle gracefully
|
|
409
|
+
return False, "", "", 0, 0.0, f"Error: {e}"
|
pdd/data/language_format.csv
CHANGED
|
@@ -1,63 +1,71 @@
|
|
|
1
|
-
language,comment,extension
|
|
2
|
-
Python,#,.py
|
|
3
|
-
Java,//,.java
|
|
4
|
-
C++,//,.cpp
|
|
5
|
-
JavaScript,//,.js
|
|
6
|
-
HTML,"<!-- -->",.html
|
|
7
|
-
CSS,"/**/",.css
|
|
8
|
-
Ruby,#,.rb
|
|
9
|
-
PHP,//,.php
|
|
10
|
-
Swift,//,.swift
|
|
11
|
-
Go,//,.go
|
|
12
|
-
Rust,//,.rs
|
|
13
|
-
Kotlin,//,.kt
|
|
14
|
-
TypeScript,//,.ts
|
|
15
|
-
TypeScriptReact,//,.tsx
|
|
16
|
-
C#,//,.cs
|
|
17
|
-
SQL,--,.sql
|
|
18
|
-
Shell,#,.sh
|
|
19
|
-
Bash,#,.sh
|
|
20
|
-
Fish,#,.fish
|
|
21
|
-
Zsh,#,.zsh
|
|
22
|
-
PowerShell,#,.ps1
|
|
23
|
-
Perl,#,.pl
|
|
24
|
-
R,#,.R
|
|
25
|
-
MATLAB,%,.m
|
|
26
|
-
Lua,--,.lua
|
|
27
|
-
Haskell,--,.hs
|
|
28
|
-
Scala,//,.scala
|
|
29
|
-
Groovy,//,.groovy
|
|
30
|
-
Dart,//,.dart
|
|
31
|
-
F#,//,.fs
|
|
32
|
-
YAML,#,.yml
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
1
|
+
language,comment,extension,run_command,run_test_command
|
|
2
|
+
Python,#,.py,python {file},python -m pytest {file} -v
|
|
3
|
+
Java,//,.java,java {file},
|
|
4
|
+
C++,//,.cpp,,
|
|
5
|
+
JavaScript,//,.js,node {file},
|
|
6
|
+
HTML,"<!-- -->",.html,,
|
|
7
|
+
CSS,"/**/",.css,,
|
|
8
|
+
Ruby,#,.rb,ruby {file},
|
|
9
|
+
PHP,//,.php,php {file},
|
|
10
|
+
Swift,//,.swift,swift {file},swift test
|
|
11
|
+
Go,//,.go,go run {file},go test -v {file}
|
|
12
|
+
Rust,//,.rs,,cargo test
|
|
13
|
+
Kotlin,//,.kt,kotlin {file},
|
|
14
|
+
TypeScript,//,.ts,npx tsx {file},
|
|
15
|
+
TypeScriptReact,//,.tsx,npx tsx {file},
|
|
16
|
+
C#,//,.cs,dotnet run {file},dotnet test
|
|
17
|
+
SQL,--,.sql,,
|
|
18
|
+
Shell,#,.sh,sh {file},
|
|
19
|
+
Bash,#,.sh,bash {file},
|
|
20
|
+
Fish,#,.fish,fish {file},
|
|
21
|
+
Zsh,#,.zsh,zsh {file},
|
|
22
|
+
PowerShell,#,.ps1,pwsh {file},
|
|
23
|
+
Perl,#,.pl,perl {file},
|
|
24
|
+
R,#,.R,Rscript {file},
|
|
25
|
+
MATLAB,%,.m,,
|
|
26
|
+
Lua,--,.lua,lua {file},
|
|
27
|
+
Haskell,--,.hs,runhaskell {file},
|
|
28
|
+
Scala,//,.scala,scala {file},
|
|
29
|
+
Groovy,//,.groovy,groovy {file},
|
|
30
|
+
Dart,//,.dart,dart run {file},
|
|
31
|
+
F#,//,.fs,dotnet fsi {file},
|
|
32
|
+
YAML,#,.yml,,
|
|
33
|
+
YAML,#,.yaml,,
|
|
34
|
+
JSON,del,.json,,
|
|
35
|
+
JSONL,del,.jsonl,,
|
|
36
|
+
XML,"<!-- -->",.xml,,
|
|
37
|
+
Makefile,#,,,
|
|
38
|
+
CSV,del,.csv,,
|
|
39
|
+
Markdown,del,.md,,
|
|
40
|
+
LaTeX,%,.tex,,
|
|
41
|
+
Assembly,;,.asm,,
|
|
42
|
+
Fortran,!,.f90,gfortran -o {file}.out {file} && ./{file}.out,
|
|
43
|
+
COBOL,*>,.cob,,
|
|
44
|
+
Lisp,;,.lisp,sbcl --script {file},
|
|
45
|
+
Prolog,%,.pl,swipl -s {file},
|
|
46
|
+
Erlang,%,.erl,escript {file},
|
|
47
|
+
Clojure,;,.clj,clojure {file},
|
|
48
|
+
Julia,#,.jl,julia {file},
|
|
49
|
+
Elixir,#,.ex,elixir {file},
|
|
50
|
+
Pascal,//,.pas,fpc {file} && ./{file},
|
|
51
|
+
VBScript,"'",.vbs,cscript {file},
|
|
52
|
+
CoffeeScript,#,.coffee,coffee {file},
|
|
53
|
+
Objective-C,//,.m,,
|
|
54
|
+
Scheme,;,.scm,scheme --script {file},
|
|
55
|
+
Tcl,#,.tcl,tclsh {file},
|
|
56
|
+
D,//,.d,rdmd {file},
|
|
57
|
+
Ada,--,.ada,,
|
|
58
|
+
Nim,#,.nim,nim r {file},
|
|
59
|
+
OCaml,"(**)",.ml,ocaml {file},
|
|
60
|
+
LLM,del,.prompt,,
|
|
61
|
+
prompt,del,.prompt,,
|
|
62
|
+
TOML,#,.toml,,
|
|
63
|
+
Log,del,.log,,
|
|
64
|
+
reStructuredText,del,.rst,,
|
|
65
|
+
Text,del,.txt,,
|
|
66
|
+
INI,;,.ini,,
|
|
67
|
+
Verilog,//,.v,,
|
|
68
|
+
Systemverilog,//,.sv,,
|
|
69
|
+
Prisma,///,.prisma,,
|
|
70
|
+
Lean,--,.lean,lean {file},
|
|
71
|
+
Agda,--,.agda,,
|
pdd/data/llm_model.csv
CHANGED
|
@@ -1,18 +1,20 @@
|
|
|
1
|
-
provider,model,input,output,coding_arena_elo,base_url,api_key,max_reasoning_tokens,structured_output,reasoning_type
|
|
2
|
-
OpenAI,gpt-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
Google,vertex_ai/gemini-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
OpenAI,
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
OpenAI,
|
|
18
|
-
|
|
1
|
+
provider,model,input,output,coding_arena_elo,base_url,api_key,max_reasoning_tokens,structured_output,reasoning_type,location
|
|
2
|
+
OpenAI,gpt-5-nano,0.05,0.4,1249,,OPENAI_API_KEY,0,True,none,
|
|
3
|
+
Google,vertex_ai/gemini-3-flash-preview,0.5,3.0,1430,,VERTEX_CREDENTIALS,0,True,effort,global
|
|
4
|
+
Google,gemini/gemini-3-pro-preview,1.25,10.0,1487,,GEMINI_API_KEY,0,True,effort,
|
|
5
|
+
Google,vertex_ai/claude-sonnet-4-5,3.0,15.0,1370,,VERTEX_CREDENTIALS,128000,True,budget,
|
|
6
|
+
Google,vertex_ai/gemini-3-pro-preview,1.25,10.0,1487,,VERTEX_CREDENTIALS,0,True,effort,
|
|
7
|
+
OpenAI,gpt-5.1-codex-mini,0.25,2.0,1325,,OPENAI_API_KEY,0,True,effort,
|
|
8
|
+
OpenAI,gpt-5.2,1.75,14.0,1486,,OPENAI_API_KEY,0,True,effort,
|
|
9
|
+
OpenAI,gpt-5.1-codex,1.25,10.0,1478,,OPENAI_API_KEY,0,True,effort,
|
|
10
|
+
OpenAI,gpt-5.1-codex-max,1.25,10.0,1480,,OPENAI_API_KEY,0,True,effort,
|
|
11
|
+
Google,vertex_ai/deepseek-ai/deepseek-v3.2-maas,0.28,0.42,1450,,VERTEX_CREDENTIALS,0,True,effort,global
|
|
12
|
+
Fireworks,fireworks_ai/accounts/fireworks/models/qwen3-coder-480b-a35b-instruct,0.45,1.80,1363,,FIREWORKS_API_KEY,0,False,none,
|
|
13
|
+
Google,vertex_ai/claude-opus-4-5,5.0,25.0,1465,,VERTEX_CREDENTIALS,128000,True,budget,global
|
|
14
|
+
OpenAI,openai/mlx-community/Qwen3-30B-A3B-4bit,0,0,1040,http://localhost:8080,,0,False,none,
|
|
15
|
+
lm_studio,lm_studio/openai-gpt-oss-120b-mlx-6,0.0001,0,1082,http://localhost:1234/v1,,0,True,effort,
|
|
16
|
+
Fireworks,fireworks_ai/accounts/fireworks/models/glm-4p7,0.60,2.20,1481,,FIREWORKS_API_KEY,0,False,none,
|
|
17
|
+
OpenAI,groq/moonshotai/kimi-k2-instruct-0905,1.0,3.0,1330,,GROQ_API_KEY,0,True,none,
|
|
18
|
+
Anthropic,anthropic/claude-sonnet-4-5-20250929,3.0,15.0,1370,,ANTHROPIC_API_KEY,128000,True,budget,
|
|
19
|
+
Anthropic,anthropic/claude-opus-4-5-20251101,5.0,25.0,1474,,ANTHROPIC_API_KEY,128000,True,budget,
|
|
20
|
+
Anthropic,anthropic/claude-haiku-4-5-20251001,1.0,5.0,1270,,ANTHROPIC_API_KEY,128000,True,budget,
|