File size: 4,316 Bytes
4412065
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
"""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}"
    )