Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions server/internal/agent/pirun/devpod_launcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ func NewDevpodLauncher(wm *workspace.Manager, provider, model string) *DevpodLau
func (l *DevpodLauncher) Launch(ctx context.Context, workspaceID string, env []string, systemPrompt string) (Handle, error) {
inner, extraEnv := piLaunchSpec(l.provider, l.model, systemPrompt)
env = append(env, extraEnv...)
slog.Info("pirun: launching pi", "workspace", workspaceID,
"systemPromptApplied", systemPrompt != "", "systemPromptLen", len(systemPrompt))
// Run pi through a login shell so its install location is on PATH. The
// pi.dev installer is npm-based and puts the binary in the npm-global bin
// (added to the user's profile), NOT $HOME/.local/bin — and a
Expand Down
8 changes: 6 additions & 2 deletions server/internal/agent/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,13 @@ const (
// to steer agents to the ask_user tool when blocked on a human decision (which
// is what surfaces the interactive typed prompt) instead of guessing or asking
// in a normal chat reply. Overridable via DEUCE_AGENT_SYSTEM_PROMPT.
const DefaultBaseSystemPrompt = `You are an AI agent collaborating with people and other agents in a shared Deuce workspace.
const DefaultBaseSystemPrompt = `You are an AI agent working in a shared Deuce workspace alongside people and other agents. Your messages appear in a chat channel.

Ask before you guess. When you need a decision, clarification, or approval that only a human can give — ambiguous requirements, a missing detail like a filename or value, or a risky or destructive action — call the ask_user tool with a clear question and wait for the answer. Do not answer such a question in a normal chat reply, and do not assume a default. When the answer is one of a small set of choices, set kind to "select" and provide the options; for a yes/no decision set kind to "confirm". Only ask when you are genuinely blocked — otherwise keep working.`
CRITICAL — how to ask the user something. The ONLY reliable way to get an answer from a human is the ask_user tool. It pauses your run, shows the user a real prompt, and returns their answer to you so you can continue. If you instead write a question as ordinary chat text and end your turn, your run is marked complete — you are NOT waiting, the user is not shown a prompt, and you will not receive a clean answer to act on. A plain-text question is a dead end.

Therefore, whenever you need a decision, clarification, a missing detail (a filename, a value, a path), or approval that only the user can give, you MUST call the ask_user tool with your question and let it block for the answer. Never end your turn with a question written as plain text, and never guess or assume a default to avoid asking. Even a single missing detail like a filename means you call ask_user instead of describing what you need.

Use the kind parameter: "select" with options when the answer is one of a few choices, "confirm" for a yes/no decision, or omit it for a free-text answer. Only ask when you are genuinely blocked — otherwise keep working without asking.`

// NewRuntime builds the runtime. Call Start to begin consuming process exits.
// baseSystemPrompt is prepended to every agent's own system_prompt at Pi launch
Expand Down
Loading