v3.10.7 — Prompt Enhancer: offline + AI-powered modes, per-provider toggle
This commit is contained in:
@@ -247,6 +247,11 @@ REASONING_ENABLED = True
|
||||
REASONING_EFFORT = "medium"
|
||||
FORCE_MODEL = ""
|
||||
BGP_ROUTES = []
|
||||
PROMPT_ENHANCER = False
|
||||
PROMPT_ENHANCER_MODE = "offline"
|
||||
PROMPT_ENHANCER_MODEL = ""
|
||||
PROMPT_ENHANCER_URL = ""
|
||||
PROMPT_ENHANCER_KEY = ""
|
||||
SERVER = None
|
||||
|
||||
if _IS_WINDOWS:
|
||||
@@ -769,7 +774,7 @@ def _ensure_antigravity_version():
|
||||
def _init_runtime():
|
||||
global CONFIG, PORT, BACKEND, TARGET_URL, API_KEY, OAUTH_PROVIDER, _antigravity_version
|
||||
global MODELS, CC_VERSION, REASONING_ENABLED, REASONING_EFFORT, BGP_ROUTES
|
||||
global _api_key_pool
|
||||
global _api_key_pool, PROMPT_ENHANCER
|
||||
|
||||
CONFIG = load_config()
|
||||
PORT = CONFIG["port"]
|
||||
@@ -782,6 +787,11 @@ def _init_runtime():
|
||||
REASONING_ENABLED = CONFIG.get("reasoning_enabled", True)
|
||||
REASONING_EFFORT = CONFIG.get("reasoning_effort", "medium")
|
||||
FORCE_MODEL = (CONFIG.get("force_model") or "").strip()
|
||||
PROMPT_ENHANCER = CONFIG.get("prompt_enhancer", False)
|
||||
PROMPT_ENHANCER_MODE = CONFIG.get("prompt_enhancer_mode", "offline")
|
||||
PROMPT_ENHANCER_MODEL = CONFIG.get("prompt_enhancer_model", "")
|
||||
PROMPT_ENHANCER_URL = CONFIG.get("prompt_enhancer_url", "")
|
||||
PROMPT_ENHANCER_KEY = CONFIG.get("prompt_enhancer_key", "")
|
||||
BGP_ROUTES = CONFIG.get("bgp_routes", [])
|
||||
_api_key_pool = None
|
||||
if API_KEY and "," in API_KEY and not OAUTH_PROVIDER.startswith("google") and BACKEND not in ("codebuff", "freebuff"):
|
||||
@@ -1694,6 +1704,120 @@ def _adaptive_compact(input_data, model, policy=None):
|
||||
f"items {len(input_data)}->{len(head)+1+len(tail)}", file=sys.stderr)
|
||||
return head + [summary_msg] + tail, True
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════
|
||||
# Prompt Enhancer
|
||||
# ═══════════════════════════════════════════════════════════════════
|
||||
|
||||
_PROMPT_ENHANCER_SYSTEM = """You are a prompt enhancement assistant for a coding agent (Codex CLI).
|
||||
Your job: rewrite the user's latest message to be clearer, more specific, and more actionable.
|
||||
Rules:
|
||||
- Preserve the user's EXACT intent — never change what they want done
|
||||
- Add explicit action verbs and step-by-step clarity
|
||||
- If the message is vague ("fix it", "make it better"), infer context from prior conversation summary and make it specific
|
||||
- Keep the enhanced prompt concise — no longer than 2x the original
|
||||
- If the original prompt is already clear and specific, return it unchanged
|
||||
- Output ONLY the enhanced prompt text, nothing else
|
||||
- Never add tasks the user didn't ask for"""
|
||||
|
||||
_PROMPT_ENHANCER_OFFLINE = """<prompt-enhancer>
|
||||
<instructions>
|
||||
You are a coding agent operating inside a context-compacted session. Follow these rules strictly:
|
||||
|
||||
1. ACTION CLARITY: Re-read the user's latest message. Identify every explicit and implicit action request. Execute ALL of them — do not skip any.
|
||||
|
||||
2. COMPACTED CONTEXT: Previous conversation was summarized. The summary preserves your task history but may lose details. If the user references earlier work ("fix that", "continue", "update it"), infer from the compacted summary what was done and what remains.
|
||||
|
||||
3. NO CLARIFICATION ASKING: Never ask "which file?" or "what exactly?" — infer from context. If truly ambiguous, make a reasonable assumption and proceed. The user can correct you.
|
||||
|
||||
4. DECISIVE EXECUTION: When the user says "fix", "update", "change", "add", "remove" — do it immediately in the relevant file(s). Do not describe what you would do — actually do it.
|
||||
|
||||
5. COMPLETE EDITS: When editing files, make the FULL change requested. Do not partially apply edits or leave placeholders.
|
||||
|
||||
6. PRESERVE WORKING STATE: Never break existing functionality. If changing code, keep all surrounding logic intact.
|
||||
|
||||
7. MULTI-STEP REQUESTS: If the user asks for multiple things, do ALL of them in sequence. Do not stop after the first one.
|
||||
</instructions>
|
||||
</prompt-enhancer>
|
||||
|
||||
"""
|
||||
|
||||
def _enhance_prompt_llm(text, compaction_summary=""):
|
||||
global PROMPT_ENHANCER_MODEL, PROMPT_ENHANCER_URL, PROMPT_ENHANCER_KEY
|
||||
if not PROMPT_ENHANCER_MODEL or not PROMPT_ENHANCER_URL:
|
||||
return text
|
||||
try:
|
||||
messages = [
|
||||
{"role": "system", "content": _PROMPT_ENHANCER_SYSTEM},
|
||||
]
|
||||
if compaction_summary:
|
||||
messages.append({"role": "user", "content": f"Context from earlier conversation (compacted):\n{compaction_summary[:2000]}"})
|
||||
messages.append({"role": "user", "content": f"Enhance this prompt:\n{text}"})
|
||||
body = json.dumps({"model": PROMPT_ENHANCER_MODEL, "messages": messages, "max_tokens": 2000, "temperature": 0.3}).encode()
|
||||
headers = {"Content-Type": "application/json"}
|
||||
if PROMPT_ENHANCER_KEY:
|
||||
headers["Authorization"] = f"Bearer {PROMPT_ENHANCER_KEY}"
|
||||
req = urllib.request.Request(f"{PROMPT_ENHANCER_URL.rstrip('/')}/chat/completions", data=body, headers=headers)
|
||||
resp = urllib.request.urlopen(req, timeout=15)
|
||||
data = json.loads(resp.read())
|
||||
enhanced = data.get("choices", [{}])[0].get("message", {}).get("content", "").strip()
|
||||
if enhanced and len(enhanced) >= len(text) * 0.5:
|
||||
print(f"[prompt-enhancer] AI enhanced: {text[:80]}... -> {enhanced[:80]}...", file=sys.stderr)
|
||||
return enhanced
|
||||
except Exception as e:
|
||||
print(f"[prompt-enhancer] AI enhancement failed: {e}", file=sys.stderr)
|
||||
return text
|
||||
|
||||
def _apply_prompt_enhancer(input_data):
|
||||
global PROMPT_ENHANCER_MODE
|
||||
if not isinstance(input_data, list) or len(input_data) == 0:
|
||||
return input_data
|
||||
last_user_idx = None
|
||||
for i in range(len(input_data) - 1, -1, -1):
|
||||
item = input_data[i]
|
||||
if isinstance(item, dict) and item.get("type") == "message" and item.get("role") == "user":
|
||||
last_user_idx = i
|
||||
break
|
||||
if last_user_idx is None:
|
||||
return input_data
|
||||
item = input_data[last_user_idx]
|
||||
content = item.get("content", "")
|
||||
if isinstance(content, list):
|
||||
text = content[0].get("text", "") if content else ""
|
||||
elif isinstance(content, str):
|
||||
text = content
|
||||
else:
|
||||
return input_data
|
||||
if not text or len(text) < 5:
|
||||
return input_data
|
||||
if text.startswith("<prompt-enhancer>"):
|
||||
return input_data
|
||||
compaction_summary = ""
|
||||
for it in input_data:
|
||||
if isinstance(it, dict) and it.get("type") == "message" and it.get("role") == "user":
|
||||
c = it.get("content", "")
|
||||
t = ""
|
||||
if isinstance(c, list):
|
||||
t = c[0].get("text", "") if c else ""
|
||||
elif isinstance(c, str):
|
||||
t = c
|
||||
if "[Auto-compacted:" in t:
|
||||
compaction_summary = t[:3000]
|
||||
break
|
||||
if PROMPT_ENHANCER_MODE == "ai-powered" and PROMPT_ENHANCER_MODEL and PROMPT_ENHANCER_URL:
|
||||
enhanced = _enhance_prompt_llm(text, compaction_summary)
|
||||
else:
|
||||
enhanced = text
|
||||
enhanced = _PROMPT_ENHANCER_OFFLINE + enhanced
|
||||
new_item = dict(item)
|
||||
if isinstance(item.get("content"), list):
|
||||
new_item["content"] = [{"type": "input_text", "text": enhanced}]
|
||||
else:
|
||||
new_item["content"] = enhanced
|
||||
result = list(input_data)
|
||||
result[last_user_idx] = new_item
|
||||
print(f"[prompt-enhancer] mode={PROMPT_ENHANCER_MODE} enhanced last user message ({len(text)}->{len(enhanced)} chars)", file=sys.stderr)
|
||||
return result
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════
|
||||
# Tool-call pairing validator
|
||||
# ═══════════════════════════════════════════════════════════════════
|
||||
@@ -4294,6 +4418,11 @@ class Handler(http.server.BaseHTTPRequestHandler):
|
||||
body = dict(body)
|
||||
body["input"] = input_data
|
||||
|
||||
if PROMPT_ENHANCER and isinstance(input_data, list):
|
||||
input_data = _apply_prompt_enhancer(input_data)
|
||||
body = dict(body)
|
||||
body["input"] = input_data
|
||||
|
||||
crof_limit = _crof_item_limit(model)
|
||||
_crof_eligible = TARGET_URL and "crof.ai" in TARGET_URL
|
||||
if _crof_eligible and not compacted and isinstance(input_data, list) and len(input_data) > crof_limit:
|
||||
@@ -4467,6 +4596,11 @@ class Handler(http.server.BaseHTTPRequestHandler):
|
||||
body = dict(body)
|
||||
body["input"] = input_data
|
||||
|
||||
if PROMPT_ENHANCER and isinstance(input_data, list):
|
||||
input_data = _apply_prompt_enhancer(input_data)
|
||||
body = dict(body)
|
||||
body["input"] = input_data
|
||||
|
||||
access_token = _refresh_oauth_token()
|
||||
token_name = "google-antigravity-oauth-token.json" if OAUTH_PROVIDER == "google-antigravity" else "google-cli-oauth-token.json"
|
||||
token_path = os.path.join(os.path.expanduser("~"), ".cache", "codex-proxy", token_name)
|
||||
|
||||
Reference in New Issue
Block a user