opencode-plugin-orca2
v0.2.2
Published
OpenCode plugin for orchestrating agentic workflows via TOML definitions with file-based state management
Downloads
334
Maintainers
Readme
Orca2 OpenCode Orchestration Plugin
NOTE
This is a complete rewrite of the initial release and is still under active development. See: NEW_SPEC.md
I am working through validating workflows and tooling with it. Expect changes. I will remove this notice when I am satisfied the orca2 is fully tested and working. I have released working examples of rpi, ocr and qr-dpi workflows.
What Is This?
Orca2 is a plugin for OpenCode that orchestrates agentic workflows via TOML definitions. It uses file-based state management to track progress, making workflows transparent, auditable, and resilient to process restarts. It also manages task list completion on a per-task basis using generated artifacts to manage state across multi-step loops.
Why Use Orca2?
To learning harness engineering. To understand and reason about agentic orchestration patterns.
Orca2 simplifies the design of complex multi-step workflows with:
- State persists to disk - Workflow progress survives restarts
- Human-in-the-loop - You can intervene at any point
- Retry logic - Failed tasks can automatically retry
- Task iteration - Process multiple tasks in sequence
- Loop patterns - like Generate → Validate → Retry (GAN) cycles
Common use cases:
- Research → Plan → Implement RPI and QRSPI workflows
- Code generation with validation (GAN) loops
- Multi-phase project execution
- Batch processing of tasks
Quick Start
Installation
Add to your project's opencode.json:
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["opencode-plugin-orca2"]
}OpenCode automatically installs dependencies and loads the plugin.
Invocation
Invoke workflows with the pattern:
#{<workflow> <job> [<process>]}Example:
#{rpi 01-foundations}
#{ocr task-1}
#{extract rms}Workflows
Workflows let you orchestrate a sequence of steps with prompts where orchestration state is managed automatically by the generation and existence of the workflow output files -- artifacts created by each step.
Project Types
There are two project types:
- Single-File Projects: where each workflow job acts on a single input file. The job is contained inside sub-directory (using the filename slug) that encloses the input file along with the work artifacts generated by the job.
- Multi-File Projects: where each workflow job acts on multiple project files and the job is contained inside the
thoughtssub-directory inside that project working directory.
Jobs
Jobs are uniquely identified self-contained directories that encapsulate the file based state machines of work artifacts generated by the agentic workflow inference.
<job>/single-file project job directorythoughts/<job>/multi-file project job directory
Processes
Processes allow workflows steps to be tailored to a specific processes. For example you may have a ocr workflow containing pdf2img -> transcribe -> extract steps. A process could be used by the extraction step to specify a set of values to extract for a specific class of documents.
Create workflow files
Create TOML files in the workflow/ directory to define workflows in your current OpenCode development project.
Create workflow/rpi.toml:
description = "Design capture, research, plan, and implement pipeline"
retry = 3
[[step]]
name = "research"
description = "Research the codebase"
prompt = [ "prompt.md" ]
output = "research.md"
[[step]]
name = "plan"
description = "Create technical plan"
prompt = [ "prompt.md", "research.md" ]
output = "plan.md"
[[step]]
name = "implement"
description = "Implement plan"
prompt = [ "prompt.md", "plan.md", "research.md" ]
output = "report.md"Along with corresponding step prompts:
workflow/rpi/research.mdResearch promptworkflow/rpi/plan.mdPlan promptworkflow/rpi/implement.mdImplement prompt
Which might generate the following work artifacts:
thoughts/<job>/prompt.mdUser feature requestthoughts/<job>/research.mdCodebase researchthoughts/<job>/plan.mdTechnical planthoughts/<job>/report.mdImplementation report
Use the workflow by typing # followed by the workflow name and arguments inside curly brackets { }.
#{rpi 02-new-feature}Step Prompts
Workflow steps comprise a prompt file path and output file path. Prompt files provide context for each step.
[[step]]
name = "plan"
description = "Create technical plan"
prompt = [ "prompt.md", "research.md" ]
output = "plan.md"Path Resolution
Multi-file projects (single_file = false):
- prompt:
thoughts/<job>/<step.prompt>in the project directory - output:
thoughts/<job>/<step.output>in the project directory
Single-file projects (single_file = true):
- prompt:
<job>/<step.prompt>in the project directory - output:
<job>/<step.output>in the project directory
Arguments
During each step, description field values, filename field values and the prompt content itself undergoes argument substitution using $IDENTIFIER syntax for placeholders.
| Variable | Description | Example |
|----------|-------------|---------|
| $PROJECT_PATH | Project working directory | ~/dev/project |
| $JOB_PATH | Job directory path | thoughts/01-foundation |
| $WORKFLOW | Workflow identifier | rpi |
| $PROCESS | Process identifier | rms |
| $STEP | Current step identifier | plan |
| $OUTPUT | Current step output path | thoughts/01-foundation/plan.md |
| $EACH | Current iteration filename (no extension) | page-1 |
| $INDEX | 1-indexed iteration number | 1 |
Iteration / While Arguments
Iteration and while loops generate multi-file outputs, where each file inside the directory specified by iterate or while, correlates to an output file to be generated. In this mode the orchestrator internally manages a task list, checking which output files are completed and halting when repeated failures exceed the retry count.
The iterate and while step fields provide $EACH and $INDEX placeholders for argument substitution, $INPUT comprises <job>/<resolved.input> and $OUTPUT comprises <job>/<step>/<resolved.output> path.
$INPUTthe current subtask input path (e.g.thoughts/01-foundation/plan/phase-1.md)$OUTPUTthe current subtask output path (e.g.thoughts/01-foundation/implement/report-1.md)$EACHThe current iteration filename, excluding path and extension (e.g.phase-1)$INDEXThe current 1-indexed iteration number (e.g.1)
[[step]]
name = "implement"
description = "Implement technical plan $INDEX"
iterate = "plan"
input = "plan/$EACH.md"
prompt = [ "design.md", "research.md" ]
output = "report-$INDEX.md"Loops
Multi-file iteration occurs inside a single step, whereas the while loop enabled multi-file output to occur across multiple steps, where each file inside the directory specified by while, correlates to an output file to be generated.
[[step]]
name = "implement"
description = "Implement technical plan $INDEX"
while = "plan"
input = "plan/$EACH.md"
prompt = [ "design.md", "research.md", "verdict-$INDEX.md" ]
output = "report-$INDEX.md"
[[step]]
name = "validate"
description = "Validate plan $INDEX implementation"
while = "plan"
input = "implement/report-$INDEX.md"
prompt = [ "design.md", "research.md" ]
output = "verdict-$INDEX.md"
loop = "implement"Process Arguments
The process step field also provides $EACH and $PROCESS placeholders.
$EACHThe current process filename, excluding path and extension (e.g.date-of-contract)$PROCESSThe user specified process identifier (e.g.rms)
single_file = true
# ...
[[step]]
name = "extract"
description = "Extract semantic data from content"
parallel = true
process = true
prompt = [ "doc.md" ]
output = "$EACH.md"
concatenate = "$PROCESS-extracted.md"TOML Workflow Fields
Orchestrations are comprised of toml workflow files, and markdown step prompts. They expect the agent to generate output files, the existence of which provide the state mechanism for workflow orchestration.
Workflow Format
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| description | string | Yes | Human-readable workflow description |
| single_file | boolean | No | Enable single file job mode (default: false) |
| retry | number | No | Max retries per step (default: 3) |
| debug | boolean | No | Enable verbose logging (default: false) |
| stats | boolean | No | Output a session statistics file (default: false) |
| step | array | Yes | Array of step definitions |
Step Definition Syntax
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| name | string | Yes | Unique step identifier |
| description | string | Yes | Human-readable step description |
| subtask | boolean | No | Spawn subtask (default: false) |
| parallel | boolean | No | Spawn parallel subtasks (default: false) |
| process | boolean | No | Run custom process configuration (default: false) |
| dialog | boolean | No | Pauses workflow with open-ended chat until output created |
| retry | number | No | Max retries for this step (overrides default retry) |
| HITL | boolean | No | Halt if retry count exceeded (default: false) |
| generate | boolean | No | This step generates an iterable set of files (default: false) |
| iterate | string | No | Iterate all files in specified subdirectory relative to job path |
| while | string | No | Iterate the next file in specified subdirectory across multiple steps |
| loop | string | No | Loop to target while output incomplete |
| input | string | No | Subtask input file path (for iterate/while/process steps) |
| prompt | string[] | No | Prompt file paths (accepts single string or array) |
| output | string | No | Output file path |
| concatenate | string | No | Concatenated output file path on completion |
Context window Behavior
By default, steps are inferenced sequentially within the main context window. A combination of the step prompt, subtask input, and prompts provide the full context for each step or subtask. As the workflow progresses, only step prompts from subsequent steps and or input prompts from subsequent tasks are included in the main context window. However if the workflow resumes, the current step rebuilds the full prompt before it continues. Parallel and subtask modifiers spawn independent child sessions that each build full prompts.
Dialog Steps
The dialog field enables open-ended chat with the user. When set to true, the workflow pauses and waits for the user to respond to questions. This is useful for:
- Requirements gathering sessions
- User interviews and feedback
- Collaborative planning
- Any scenario requiring extended human interaction
Example:
[[step]]
name = "research"
description = "Research the codebase"
dialog = true
prompt = [ "prompt.md" ]
output = "research.md"What happens:
- Workflow reaches the dialog step and sends the initial prompt
- Workflow pauses - no automatic retries occur
- User can chat normally with the agent
- When the output file is created, workflow automatically resumes
- Next step proceeds normally
Error Handling
If expected output is missing after max retries, the workflow halts. This requires human intervention.
To recover:
- Check the error log
- Manually create missing output files OR
- Fix the issue and re-invoke the workflow
Examples
Copy workflow directory into you project.
Research Plan Implement (rpi)
See workflow/rpi.toml for a complete example of sequential and subtask steps with iteration.
Prerequisites:
- Create a thoughts directory for you next feature request in
thoughts/NN-feature - Write a prompt in
thoughts/NN-feature/prompt.mdoutlining your# User Request - The agent will research the codebase, then ask you questions
Run the rpi workflow:
#{rpi NN-function}Optical Character Recognition (ocr)
See workflow/ocr.toml for a complete example of generate, iterate, and process steps with concatenation.
Prerequisites:
- A multi-modal model like Qwen 3.6
- Install my OpenCode tool pdf2img
- Create a per-document directory for the document you want to analyze
job-N/. - Create a process directory
process/process-1containing a list of prompts for values you want extracted
Run the ocr workflow:
#{ocr task-N process}Questions Research Design-Alignment Plan Implement (qr-dpi)
See workflow/qr-dpi.toml for a task list and generate-validate loop pattern.
Prerequisites:
- Create a thoughts directory for you next feature request in
thoughts/NN-feature - Write a prompt in
thoughts/NN-feature/prompt.mdoutlining your# User Request - The agent will ask you questions, research the codebase, then ask additional questions
Run the rpi workflow:
#{qr-dpi NN-function}Troubleshooting
Workflow Not Starting
Symptom: Invocation has no effect
Check:
- Workflow file exists at
workflow/<name>.toml - Plugin is in
opencode.json - Step prompt files exist at
workflow/<workflow>/<step-name>.md
Output Files Not Detected
Symptom: Workflow stuck waiting for output
Check:
- Output file paths match exactly (case-sensitive)
- Files are created in the correct directory
- No typos in
outputfield
Max Retries Exceeded
Symptom: Workflow halts with error
Check:
- Review error log for missing outputs
- Manually create missing files OR
- Investigate why step cannot complete
References
The examples draw on knowledge and techniques shared by Dex Horthy and Matt Pocock
- 12-Factor Agents: Patterns of reliable LLM applications — Dex Horthy, HumanLayer
- No Vibes Allowed: Solving Hard Problems in Complex Codebases — Dex Horthy, HumanLayer
- It Ain't Broke: Why Software Fundamentals Matter More Than Ever — Matt Pocock, AI Hero
- Everything We Got Wrong About Research-Plan-Implement — Dex Horthy, HumanLayer
License
MIT
Authors
- @whpthomas - Concept, logic and troubleshooting
- Qwen3.5 122B A10B int4 AutoRound ~ DGX Spark - Research and coding
