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:

  1. Daydream loads the package directory from DAYDREAM_EXT_DIR.
  2. Daydream imports daydream_ext from the Python environment.
  3. 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:

  • deep runs the pull request review process.
  • improve runs 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.

Back to Daydream