Multi-step guided interactive workflows that walk users through complex tasks
Tasks
Run a built-in wizard
Goal: run a guided wizard and read its result.
Steps:
import asyncio
from attune.wizards import get_wizard
async def main() -> None:
wizard_cls = get_wizard("security")
if wizard_cls is None:
print("unknown wizard")
return
result = await wizard_cls().run(initial_context={"path": "src/"})
print("success:", result.success)
print("output:", result.generated_output)
print("cost:", result.total_cost)
asyncio.run(main())
Verify: run() is a coroutine — await it. The result is a
WizardResult with success, collected_data, generated_output,
tasks, total_cost, total_duration_ms, and error on failure.
initial_context seeds the run.
Discover what's available
Goal: list the registered wizards and their metadata.
Steps:
from attune.wizards import get_wizard, list_wizards
for cfg in list_wizards():
print(f"{cfg.wizard_id}: {cfg.name} ({cfg.domain})")
print(f" ~{cfg.estimated_duration_minutes} min, {cfg.estimated_cost_range}")
cls = get_wizard("test-gen") # -> TestGenWizard class, or None
Verify: list_wizards() returns WizardConfig objects (sync). The
five built-ins are debug, refactor, release-prep, security,
and test-gen. get_wizard(id) returns the class or None.
Register a custom wizard
Goal: make your own wizard discoverable.
Steps:
from attune.wizards import BaseWizard, register_wizard
class MyWizard(BaseWizard):
def build_prompt_context(self, step):
...
def process_step_result(self, step, result):
...
register_wizard("my-wizard", MyWizard)
Verify: after register_wizard, get_wizard("my-wizard") returns
your class and it appears in list_wizards(). For a config-only
wizard, build a ConfigDrivenWizard(config, steps) or persist a
definition with save_custom_wizard(data).