diff options
| author | Ben Sima <ben@bensima.com> | 2025-12-02 11:09:56 -0500 |
|---|---|---|
| committer | Ben Sima <ben@bensima.com> | 2025-12-02 11:09:56 -0500 |
| commit | eb8a78baafa4556fde11cddda4740fe4b733cf31 (patch) | |
| tree | 7e5460199bd339e2a78f8531b2a71d4bb5331499 /Omni | |
| parent | 90b6b21990df76051a9f639cd7596ec3e93de564 (diff) | |
jr: add 'prompt' command to inspect agent system prompt
jr prompt <task-id> constructs and prints the full system prompt
that would be sent to the agent, including:
- Agent configuration (model, cost budget)
- Base instructions
- AGENTS.md content
- Relevant facts from knowledge base
- Retry/progress context if applicable
Useful for debugging agent behavior and token usage.
Diffstat (limited to 'Omni')
| -rw-r--r-- | Omni/Agent/Worker.hs | 55 | ||||
| -rwxr-xr-x | Omni/Jr.hs | 17 |
2 files changed, 71 insertions, 1 deletions
diff --git a/Omni/Agent/Worker.hs b/Omni/Agent/Worker.hs index 45caf9b..110c929 100644 --- a/Omni/Agent/Worker.hs +++ b/Omni/Agent/Worker.hs @@ -1,7 +1,13 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE NoImplicitPrelude #-} -module Omni.Agent.Worker where +module Omni.Agent.Worker + ( start, + buildFullPrompt, + selectModel, + selectCostByComplexity, + ) +where import Alpha import qualified Data.Aeson as Aeson @@ -575,3 +581,50 @@ formatFact f = then "" else " [" <> Text.intercalate ", " (TaskCore.factRelatedFiles f) <> "]" ) + +-- | Build the full system prompt for a task without starting the agent. +-- This is useful for debugging/inspecting what the agent will be told. +buildFullPrompt :: TaskCore.Task -> IO Text +buildFullPrompt task = do + repo <- Directory.getCurrentDirectory + let ns = fromMaybe "." (TaskCore.taskNamespace task) + let basePrompt = buildBasePrompt task ns repo + + maybeRetry <- TaskCore.getRetryContext (TaskCore.taskId task) + progressContent <- TaskCore.getProgressSummary (TaskCore.taskId task) + + let progressPrompt = buildProgressPrompt progressContent + let retryPrompt = buildRetryPrompt maybeRetry + let prompt = basePrompt <> progressPrompt <> retryPrompt + + agentsMd <- + fmap (fromMaybe "") <| do + exists <- Directory.doesFileExist (repo </> "AGENTS.md") + if exists + then Just </ readFile (repo </> "AGENTS.md") + else pure Nothing + + relevantFacts <- getRelevantFacts task + let factsSection = formatFacts relevantFacts + + let systemPrompt = + prompt + <> "\n\nREPOSITORY GUIDELINES (AGENTS.md):\n" + <> agentsMd + <> factsSection + + let model = selectModel task + let costBudget = selectCostByComplexity (TaskCore.taskComplexity task) + + pure + <| Text.unlines + [ "=== AGENT CONFIGURATION ===", + "Model: " <> model, + "Cost budget: " <> tshow costBudget <> " cents", + "", + "=== SYSTEM PROMPT ===", + systemPrompt, + "", + "=== USER PROMPT (task details) ===", + formatTask task + ] @@ -54,6 +54,7 @@ jr Usage: jr task [<args>...] jr work [<task-id>] + jr prompt <task-id> jr web [--port=PORT] jr review [<task-id>] [--auto] jr loop [--delay=SECONDS] @@ -67,6 +68,7 @@ Usage: Commands: task Manage tasks work Start a worker agent on a task + prompt Show the system prompt that would be sent to the agent web Start the web UI server review Review a completed task (show diff, accept/reject) loop Run autonomous work+review loop @@ -94,6 +96,21 @@ move args Just p -> fromMaybe Web.defaultPort (readMaybe p) Nothing -> Web.defaultPort Web.run port + | args `Cli.has` Cli.command "prompt" = do + case Cli.getArg args (Cli.argument "task-id") of + Nothing -> do + IO.hPutStrLn IO.stderr "Error: task-id is required" + Exit.exitFailure + Just tidStr -> do + let tid = Text.pack tidStr + tasks <- TaskCore.loadTasks + case TaskCore.findTask tid tasks of + Nothing -> do + IO.hPutStrLn IO.stderr ("Error: task not found: " <> tidStr) + Exit.exitFailure + Just task -> do + prompt <- AgentWorker.buildFullPrompt task + putText prompt | args `Cli.has` Cli.command "work" = do -- Always run in current directory let path = "." |
