Skip to content
This repository was archived by the owner on Jun 25, 2026. It is now read-only.
This repository was archived by the owner on Jun 25, 2026. It is now read-only.

Agent-driven actions: let the agent decide what to do #192

Description

@rtzll

Summary

Replace the fixed worker pipeline (agent → commit → push → PR) with a capability-based model where the agent decides which actions to take. The worker provides tools (push code, post review, leave comment, etc.) and the agent invokes whichever combination makes sense.

Motivation

Today the worker unconditionally runs: run_agent → prepare_commit → push_branch → pr_create. Every run produces a branch and PR, even when the right response might be a review comment, an approval, or doing nothing.

This prevents use cases like:

  • @bot mentioned on a PR the bot didn't create → agent reviews and comments
  • Agent finds nothing to fix → posts "looks good" instead of an empty PR
  • Agent finds a bug AND fixes it → pushes code AND explains the fix in a comment
  • Future actions we haven't thought of yet

Rather than adding mode flags (--review, --comment-only) and deciding upfront, the agent should assess the situation and pick the right actions.

Design

Current flow (fixed pipeline)

trigger → run agent → prepare_commit → push_branch → pr_create → done

Proposed flow (agent-driven)

trigger → set up workspace → run agent with available actions → report outcomes

Worker becomes a capability provider

The generic part stays: clone repo, checkout branch, set up workspace, write instructions. After that, the agent runs with a set of available actions it can invoke:

Action What it does
push_changes Stage, commit, push branch, create/update PR
post_review Submit a PR review with inline file/line comments
post_comment Post a general comment on the issue/PR
approve Approve the PR
request_changes Request changes on the PR
(future) Whatever new capabilities we add

The agent can invoke any combination — push a fix AND leave a comment, or just approve, or do nothing.

How actions are exposed to the agent

This depends on the agent runtime:

  • Claude/direct runtimes: Tool definitions passed to the model. Agent calls them as tool use.
  • Goose: Extensions or shell commands the agent can invoke.
  • Any runtime: At minimum, the agent can write structured output (e.g., a JSON actions file) that the worker interprets post-run.

The simplest starting point is probably a structured output contract: the agent writes an actions.json (or similar) declaring what it wants to do, and the worker executes those actions. This works across all runtimes without runtime-specific tool integration.

Worker post-agent execution

Instead of hardcoded stages, the worker reads the agent's requested actions and executes them:

1. Parse agent output / actions file
2. For each action:
   - push_changes → git add, commit, push, create/update PR
   - post_review → GitHub API: create review with inline comments
   - post_comment → GitHub API: post comment
   - approve → GitHub API: submit approval
3. Record all executed actions in meta.json

If the agent requests no actions (or no actions file exists), the worker falls back to current behavior for backwards compatibility.

meta.json changes

Currently records PRNumber, PRURL, HeadSHA. Extend to capture all actions taken:

{
  "actions_taken": ["push_changes", "post_review"],
  "pr_number": 42,
  "pr_url": "...",
  "head_sha": "abc123",
  "review_id": 789,
  "comments_posted": 1
}

Orchestrator changes

finalizeDetachedRun() currently derives status from whether a PR was created. With multiple action types:

  • Any action succeeded → StatusSucceeded
  • PR created → StatusReview (existing, preserved)
  • No actions, no error → StatusSucceeded
  • Error → StatusFailed

Notification posting adapts based on which actions the agent took — don't post a completion comment if the agent already posted its own.

Relation to #191

Issue #191 (configurable bot identity) gives the agent a name and identity. This issue gives it agency. Together they enable: @my-agent on any PR → agent assesses the situation → takes whatever actions make sense → posts under its own identity.

The bot identity work (#191) should land first since the agent needs a token to post reviews/comments as itself.

Key files

  • internal/worker/worker.go — Pipeline stages to refactor into conditional actions
  • cmd/rascal-runner/main.go — Runner entry point
  • internal/orchestrator/execution.gofinalizeDetachedRun() status logic
  • internal/orchestrator/notifications.go — Post-run comment logic
  • internal/orchestrator/webhook.go — Trigger handling (needs @mention support)
  • internal/github/client.go — Needs PR review API support (create review, inline comments)

Implementation phases

  1. Action contract — Define the structured output format agents use to declare actions
  2. Worker refactor — Make post-agent stages conditional based on agent output
  3. Review/comment actions — Implement post_review and post_comment via GitHub API
  4. @mention trigger — Webhook handler recognizes bot mentions on any PR/issue
  5. Agent instructions — Update instruction templates to explain available actions
  6. Backwards compat — If no actions declared, fall back to current push+PR behavior

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions