(
transcript: string,
options: BuildWorkspaceStatusPromptOptions = {}
)
| 67 | * is a sidebar status, not a workspace title. |
| 68 | */ |
| 69 | export function buildWorkspaceStatusPrompt( |
| 70 | transcript: string, |
| 71 | options: BuildWorkspaceStatusPromptOptions = {} |
| 72 | ): string { |
| 73 | // Sentinel for an empty window. AgentStatusService skips empty inputs in |
| 74 | // practice, but the model still needs something to ground on. |
| 75 | const body = transcript.trim().length > 0 ? transcript : "(no recent transcript)"; |
| 76 | // Surface live streaming state as a leading instruction. AgentStatusService |
| 77 | // already tracks `snapshot.streaming` to pick cadence; passing it through |
| 78 | // lets the model resolve genuinely ambiguous transcripts (e.g. the model |
| 79 | // wrote "Deploying service…" but no [tool … done] has arrived yet) toward |
| 80 | // present-progressive tense instead of guessing past tense. |
| 81 | const livenessHint = options.streaming |
| 82 | ? 'The agent is actively streaming a response right now. The activity is in progress: prefer present-progressive tense (e.g. "Deploying service", not "Deployed service").\n\n' |
| 83 | : "The agent's most recent turn has finished streaming, but that does NOT necessarily mean the underlying activity completed. Only use past tense when there is direct evidence of completion in the transcript (see Tense rule below).\n\n"; |
| 84 | return [ |
| 85 | "You produce a short sidebar status summarizing the most recent activity in an AI coding agent's chat.\n\n", |
| 86 | livenessHint, |
| 87 | "Recent chat transcript (oldest first, newest last):\n", |
| 88 | "<transcript>\n", |
| 89 | body, |
| 90 | "\n</transcript>\n\n", |
| 91 | // Tool-call lifecycle markers come from formatMessageForTranscript in |
| 92 | // agentStatusService.ts. They distinguish in-flight calls (no result yet) |
| 93 | // from completed ones, which is the single best signal the small model |
| 94 | // has for deciding whether the activity has actually finished. |
| 95 | "Tool-call markers in the transcript:\n", |
| 96 | "- `[tool <name> running]` — the call was sent but no result has come back yet (in progress).\n", |
| 97 | "- `[tool <name> done]` — the tool returned (completed; may have succeeded or failed).\n", |
| 98 | "- A line prefixed `Assistant (in progress):` is the assistant message currently being streamed — it is not finalized.\n\n", |
| 99 | "Requirements:\n", |
| 100 | "- Describe the specific activity the agent was last working on, drawn from the actual transcript content.\n", |
| 101 | "- Always name a concrete activity (file, feature, bug, command, etc.) from the transcript. Generic non-informative phrasing is rejected and not shown.\n", |
| 102 | // Tense rule is the core fix for the historical "Deployed service" while |
| 103 | // still deploying bug. Past tense now requires *evidence* in the |
| 104 | // transcript, not vibes about how complete the prose sounds. |
| 105 | '- Tense: default to present-progressive (e.g. "Deploying service", "Running tests"). Use past tense ONLY when there is direct evidence the activity finished — every tool call relevant to it shows `[tool … done]` AND the assistant has summarized or otherwise handed back control. When uncertain, use present-progressive.\n', |
| 106 | '- Counter-example: if the transcript shows `[tool bash running]` for a deploy, write "Deploying service", not "Deployed service".\n', |
| 107 | // The sidebar renders the emoji through EmojiIcon, which maps a fixed |
| 108 | // set of glyphs to Lucide icons. Emojis outside this set fall back to |
| 109 | // a generic Sparkles icon, which looks identical regardless of the |
| 110 | // activity. Restrict the model to glyphs we know render correctly. |
| 111 | "- emoji: must be exactly one of: 🔍 📝 ✅ ❌ 🚀 ⏳ 🔗 🔄 🧪 🤔 🔧 🛠 🔔 🌐 📖 📦 💤 💡 ⚠. Pick the one that best matches the activity (🔍 investigating, 📝 writing, ✅ done/completed, ❌ failed, 🚀 deploying/launching, ⏳ waiting, 🔄 refreshing/iterating, 🧪 testing, 🤔 deciding, 🔧 🛠 fixing/building, 🌐 network/web, 📖 reading docs, 📦 packaging, 💤 idle, 💡 planning, ⚠ warning).\n", |
| 112 | "- message: 2-6 words, verb-led, sentence case, no punctuation, no quotes.\n", |
| 113 | '- Examples (in progress): "Investigating crash", "Implementing sidebar status", "Running tests", "Reading config files".\n', |
| 114 | '- Examples (completed): "Wrote tests", "Fixed sidebar bug", "Investigated crash", "Refactored config loader".\n\n', |
| 115 | "Call propose_status exactly once with your chosen emoji and message. Do not emit any text response.", |
| 116 | ].join(""); |
| 117 | } |
| 118 | |
| 119 | /** |
| 120 | * Generate a sidebar agent-status summary using the same "small model" path |
no outgoing calls
no test coverage detected