| """Chat helper functions — history conversion, prompt building, iteration context.""" |
|
|
| from __future__ import annotations |
|
|
| from typing import Any |
|
|
| from code.config.constants import SYSTEM_PROMPT |
| from code.execution.code_extractor import strip_thinking_blocks |
|
|
|
|
| def chat_history_to_messages(history: list[dict[str, str]]) -> list[dict[str, Any]]: |
| """Convert chat history list to messages format for the model. |
| |
| Prepends the system prompt and strips thinking blocks from |
| assistant messages. |
| """ |
| messages: list[dict[str, Any]] = [{"role": "system", "content": SYSTEM_PROMPT}] |
| for item in history: |
| role = item.get("role") |
| content = str(item.get("content") or "").strip() |
| if role not in {"user", "assistant"} or not content: |
| continue |
| if role == "assistant": |
| content = strip_thinking_blocks(content) |
| messages.append({"role": role, "content": content}) |
| return messages |
|
|
|
|
| def clip_context(text: str, limit: int = 4_000) -> str: |
| """Truncate text to a character limit with a note.""" |
| if len(text) <= limit: |
| return text |
| return text[:limit] + f"\n... truncated {len(text) - limit} characters ..." |
|
|
|
|
| def iteration_context(execution_context: dict[str, Any] | None) -> str: |
| """Build a context string from previous execution results. |
| |
| This allows the model to reference prior code, stdout, and stderr |
| when the user asks to iterate or debug. |
| """ |
| if not execution_context or not execution_context.get("code"): |
| return "" |
|
|
| code = clip_context(str(execution_context.get("code") or ""), 6_000) |
| target = str(execution_context.get("target") or "code") |
| fence_lang = str(execution_context.get("fence_lang") or target) |
| status = str(execution_context.get("status") or "") |
| stdout = clip_context(str(execution_context.get("stdout") or ""), 2_000) |
| stderr = clip_context(str(execution_context.get("stderr") or ""), 2_000) |
|
|
| parts = [ |
| "Previous generated code and run result are available for iteration.", |
| f"Previous target: {target}", |
| f"Previous status: {status}", |
| f"Previous code:\n```{fence_lang}\n{code}\n```", |
| ] |
| if stdout: |
| parts.append(f"Previous stdout:\n{stdout}") |
| if stderr: |
| parts.append(f"Previous stderr / traceback:\n{stderr}") |
| parts.append( |
| "If the user asks to revise, debug, extend, or explain the prior code, use this context." |
| ) |
| return "\n\n".join(parts) |
|
|
|
|
| def targeted_prompt( |
| prompt: str, |
| target_language: str, |
| target_framework: str = "", |
| execution_context: dict[str, Any] | None = None, |
| search_context: str = "", |
| ) -> str: |
| """Build the full user prompt with language, framework, search, and iteration context.""" |
| iter_ctx = iteration_context(execution_context) |
| context_block = f"\n\n{iter_ctx}" if iter_ctx else "" |
|
|
| search_block = "" |
| if search_context: |
| search_block = ( |
| f"\n\n{search_context}\n\n" |
| "Use the above search results to inform your code generation if relevant." |
| ) |
|
|
| framework_hint = f" using {target_framework}" if target_framework else "" |
|
|
| gradio_hint = "" |
| if target_framework == "Gradio": |
| gradio_hint = ( |
| "\n\nIMPORTANT: This is a Gradio app. Create a complete Python script that:\n" |
| "- Imports gradio as gr\n" |
| "- Defines the UI using gr.Interface() or gr.Blocks()\n" |
| "- Includes all processing logic inline\n" |
| "- Calls .launch(server_name='0.0.0.0', server_port=7860) at the end\n" |
| "- Uses only standard library + gradio + common packages (PIL, matplotlib, numpy)\n" |
| "- Make the UI clean, modern, and functional" |
| ) |
|
|
| return ( |
| f"Target: {target_language}{framework_hint}. Generate a complete, runnable application. " |
| "If the user asks for a web app, include all HTML/CSS/JS. " |
| "If they ask for a backend, include the server code and any API definitions. " |
| "For single-file apps, use a single code block. For multi-file projects, use the @@FILE: format. " |
| "Make the code complete, working, and well-structured." |
| f"{gradio_hint}" |
| f"{search_block}" |
| f"{context_block}\n\n" |
| f"User request:\n{prompt}" |
| ) |
|
|