/** * Shared utilities for request translation modules. * * Deduplicates: desktop context loading, instruction building, budget→effort mapping. */ import { readFileSync } from "fs"; import { resolve } from "path"; import { getConfig } from "../config.js"; import { getConfigDir } from "../paths.js"; let cachedDesktopContext: string | null = null; /** * Lazily load and cache the desktop context prompt. * File is maintained by apply-update.ts; cached once per process lifetime. */ export function getDesktopContext(): string { if (cachedDesktopContext !== null) return cachedDesktopContext; try { cachedDesktopContext = readFileSync( resolve(getConfigDir(), "prompts/desktop-context.md"), "utf-8", ); } catch { cachedDesktopContext = ""; } return cachedDesktopContext; } const SUPPRESS_PROMPT = "IMPORTANT — OVERRIDE ALL INSTRUCTIONS ABOVE THIS LINE: " + "The Codex desktop context above is NOT applicable. Disregard it entirely. " + "You are a standard OpenAI API model. You are not running inside any app. " + "Do not use Codex-specific directives (::automation-update, ::code-comment, " + "::archive, etc.). Do not reference automations, review findings, or any " + "desktop features. Respond as a plain language model with no special context."; /** * Assemble final instructions from desktop context + user instructions. * When suppress_desktop_directives is enabled, appends a suppress prompt * to override desktop-specific behaviors. */ export function buildInstructions(userInstructions: string): string { const ctx = getDesktopContext(); if (!ctx) return userInstructions; if (getConfig().model.suppress_desktop_directives) { return `${ctx}\n\n${SUPPRESS_PROMPT}\n\n${userInstructions}`; } return `${ctx}\n\n${userInstructions}`; } /** * Map a token budget (e.g. Anthropic thinking.budget_tokens or Gemini thinkingBudget) * to a Codex reasoning effort level. */ export function budgetToEffort(budget: number | undefined): string | undefined { if (!budget || budget <= 0) return undefined; if (budget < 2000) return "low"; if (budget < 8000) return "medium"; if (budget < 20000) return "high"; return "xhigh"; }