|
25 | 25 | from app.models.db_models.user import User, UserSettings |
26 | 26 | from app.models.schemas.settings import ProviderType |
27 | 27 | from app.prompts.enhance_prompt import ENHANCE_PROMPT |
| 28 | +from app.prompts.generate_pr_description import ( |
| 29 | + GENERATE_PR_DESCRIPTION_SYSTEM_PROMPT, |
| 30 | + GENERATE_PR_DESCRIPTION_TITLE_PREFIX, |
| 31 | +) |
28 | 32 | from app.prompts.system_prompt import DEFAULT_PERSONA_NAME |
29 | 33 | from app.prompts.generate_title import ( |
30 | 34 | GENERATE_TITLE_SYSTEM_PROMPT, |
|
39 | 43 | from app.services.transports import SandboxTransport |
40 | 44 | from app.services.transports.factory import create_sandbox_transport |
41 | 45 | from app.services.user import UserService |
| 46 | +from app.utils.validators import validate_model_api_keys |
42 | 47 |
|
43 | 48 | settings = get_settings() |
44 | 49 | logger = logging.getLogger(__name__) |
@@ -331,6 +336,41 @@ async def generate_title(self, prompt: str, user: User) -> str | None: |
331 | 336 | logger.debug("Title generation SDK call failed for user %s", user.id) |
332 | 337 | return None |
333 | 338 |
|
| 339 | + async def generate_pr_description( |
| 340 | + self, title: str, diff: str, model_id: str, user: User |
| 341 | + ) -> str: |
| 342 | + user_settings = await UserService( |
| 343 | + session_factory=self.session_factory |
| 344 | + ).get_user_settings(user.id) |
| 345 | + |
| 346 | + validate_model_api_keys(user_settings, model_id) |
| 347 | + env, _, actual_model_id = self._build_auth_env(model_id, user_settings) |
| 348 | + |
| 349 | + options = ClaudeAgentOptions( |
| 350 | + system_prompt=GENERATE_PR_DESCRIPTION_SYSTEM_PROMPT, |
| 351 | + permission_mode="default", |
| 352 | + model=actual_model_id, |
| 353 | + max_turns=1, |
| 354 | + env=env, |
| 355 | + ) |
| 356 | + |
| 357 | + try: |
| 358 | + description = "" |
| 359 | + async with ClaudeSDKClient(options=options) as client: |
| 360 | + user_message = ( |
| 361 | + GENERATE_PR_DESCRIPTION_TITLE_PREFIX + title + "\n\n" + diff |
| 362 | + ) |
| 363 | + await client.query(user_message) |
| 364 | + async for message in client.receive_response(): |
| 365 | + if isinstance(message, ResultMessage) and message.result: |
| 366 | + description = message.result |
| 367 | + |
| 368 | + if not description: |
| 369 | + raise ClaudeAgentException("AI returned an empty description") |
| 370 | + return description |
| 371 | + except ClaudeSDKError as e: |
| 372 | + raise ClaudeAgentException(f"Failed to generate PR description: {e}") from e |
| 373 | + |
334 | 374 | @staticmethod |
335 | 375 | def _build_permission_server( |
336 | 376 | permission_mode: str, chat_id: str, sandbox_provider: str = "docker" |
|
0 commit comments