Extensions
Extension contract
Daydream loads an optional Python package named daydream_ext. The package can
change the registry for the current run without a change to the daydream package.
The current extension application programming interface (API) version is 6. The supported version range is 6 through 6. A pull request (PR) is a proposed change in a GitHub repository. A language stack is a group of changed files that use the same language or framework. JavaScript Object Notation (JSON) is the findings data format.
The source repository contains the complete extension contract. Tests compare that contract with the registered names in the source code.
Package layout
Create this package in a source fork. Put it next to the daydream package:
daydream_ext/
└── __init__.py
The module must provide DAYDREAM_EXT_API and register:
DAYDREAM_EXT_API = 6
def register(registry):
pass
The built-in registry exists before Daydream calls register. The function can
add, replace, remove, or reorder registered values.
Add the package to an existing editable install. Then run this command:
uv sync --reinstall-package daydream
The Daydream wheel configuration already includes the daydream_ext package
when the package exists.
Discovery order
Daydream uses this order:
- Daydream loads the package directory from
DAYDREAM_EXT_DIR. - Daydream imports
daydream_extfrom the Python environment. - Daydream uses the built-in registry when no extension exists.
The environment variable must point to the package directory. Daydream loads that package again for each run.
A missing extension is not an error.
Daydream exits with status 1 when the extension is invalid.
This exit occurs before workspace or agent work starts.
The error identifies an incompatible API version, missing function, import failure, or registration failure.
Available changes
An extension can make these changes:
| Registry item | Supported change |
|---|---|
| Phase | Register or replace a FlowStep |
| Loop | Put a LoopGroup in a flow and use BreakLoop |
| Flow | Set a step list or change the order |
| Result | Return Stop from a phase |
| Skill | Replace a named skill slot |
| Prompt | Replace a named prompt builder |
| Stack | Add a file-pattern rule before built-in rules |
| Findings | Read or rewrite the canonical findings file |
| Tools | Register one synchronous tool supervisor |
A tool supervisor returns ToolDecision(veto=False) to allow a tool call.
It returns ToolDecision(veto=True, reason="REASON") to stop that agent turn.
This stop does not affect other concurrent agent turns.
Example
This extension removes low-severity findings. It also blocks Write tool
calls:
import json
from daydream.extensions import FlowStep, ToolDecision
DAYDREAM_EXT_API = 6
async def filter_items(ctx):
items_file = ctx.data["items_file"]
payload = json.loads(items_file.read_text())
payload["items"] = [
item for item in payload["items"]
if item["severity"] != "low"
]
items_file.write_text(json.dumps(payload))
def supervise(name, tool_input, *, phase):
if name == "Write":
return ToolDecision(veto=True, reason="Writes require approval")
return ToolDecision(veto=False)
def register(registry):
registry.register_phase(
FlowStep(name="filter-items", run=filter_items)
)
registry.insert_after(
"deep", anchor="load-items", step="filter-items"
)
registry.register_tool_supervisor(supervise)
The example keeps all top-level keys in the findings file.
The example keeps the held list when a supervisor has added that list.
The tool supervisor must be a synchronous callable. A registry can contain one tool supervisor. A configured built-in tool supervisor and an extension tool supervisor cause a conflict error.
Built-in flows
The registry contains two flows:
deepruns the pull request review process.improveruns a repository audit and writes plans.
Review, comment, shallow, and feedback operations are modes of deep. They are
not separate registered flows.
The deep flow contains these step names:
exploration, intent, per-stack-reviews, per-stack-parse, uncovered-sweep,
arbiter, cross-stack-merge, single-stack-merge, load-items, supervise,
findings-out, post-review, fix-gate, verify, fix, fix-verify, test, commit
The fix and fix-verify steps run inside a fix-verify-loop group.
The group runs at most three rounds. Each round applies fixes, and the
read-only fix-verify step audits the changed hunks.
The improve flow contains these step names:
recon, audit, vet, select-plans, write-plans, publish-improve-issues,
improve-report
Some steps do not run in every mode. For example, review mode stops before the fix steps.
Select a custom registered flow with this command:
daydream --flow FLOW_NAME REPOSITORY_PATH
--flow cannot be combined with --review, --comment, or --shallow.
deep, review, and shallow are built-in aliases. Use
daydream improve for the improve flow.
Stable phase data
An extension phase can read these stable ctx.data keys:
| Key | Value |
|---|---|
diff |
Diff text for the run |
diff_path |
Path to the saved diff |
tier |
Selected exploration tier |
exploration_dir |
Exploration output directory or None |
intent_path |
Intent analysis path |
alts_path |
Alternative review path |
items_file |
Canonical findings JSON path after load-items |
items |
Parsed findings after fix-gate |
intent_authoritative |
Whether current PR text supplied the intent |
Other context keys are internal. Read intent_authoritative with
ctx.data.get("intent_authoritative", False) because a resumed run can omit
the key.
Skills, prompts, and stacks
Use override_skill for a named stack, structural review, verification, or
custom phase. Use add_stack to add a StackRule. Extension stack rules run
before the built-in file-extension table. Daydream uses the first matching extension rule.
Use override_prompt to replace a registered prompt builder. The replacement
must accept the documented arguments. It replaces the complete prompt. The API
does not append text to a built-in prompt.
An extension can configure a custom phase with the normal phase table:
[tool.daydream.phases.policy_check]
backend = "codex"
model = "gpt-5.6-terra"
reasoning_effort = "medium"
The command line has higher priority than this table. See Configuration for the complete priority rules.
Validate an extension
Run validation from any directory:
daydream ext validate
The command reports the extension source and API version. It resolves each flow entry, skill slot, and stack rule. It also reports the tool supervisor. Invalid references exit with status 1. A command-line usage error exits with status 2.
The same registry check runs before an extension flow starts.
Limits
- An extension cannot register a backend.
- An extension cannot remove a built-in file-extension mapping.
- An extension cannot change workspace selection or trajectory-recorder setup.
- An extension cannot run tool supervision before the backend reports the tool event.
- An extension cannot replace internal parse, test, or commit prompts.
- A prompt replacement cannot combine with the built-in prompt.