Metadata-Version: 2.4
Name: urirun-flow
Version: 0.2.3
Summary: Author urirun URI flows in typed Python (Pydantic), convert to/from YAML, and run them through urirun when the runtime is installed.
License-Expression: Apache-2.0
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: NOTICE
Requires-Dist: jsonschema>=4.18
Requires-Dist: pydantic>=2
Requires-Dist: pyyaml>=6
Requires-Dist: urirun-connector-router>=0.2.0
Provides-Extra: llm
Requires-Dist: litellm>=1.60; extra == "llm"
Provides-Extra: run
Requires-Dist: urirun>=0.4.190; extra == "run"
Provides-Extra: test
Requires-Dist: pytest>=7; extra == "test"
Dynamic: license-file

# urirun-flow


## AI Cost Tracking

![PyPI](https://img.shields.io/badge/pypi-costs-blue) ![Version](https://img.shields.io/badge/version-0.2.3-blue) ![Python](https://img.shields.io/badge/python-3.9+-blue) ![License](https://img.shields.io/badge/license-Apache--2.0-green)
![AI Cost](https://img.shields.io/badge/AI%20Cost-$0.52-orange) ![Human Time](https://img.shields.io/badge/Human%20Time-29.3h-blue) ![Model](https://img.shields.io/badge/Model-openrouter%2Fqwen%2Fqwen3--coder--next-lightgrey)

- 🤖 **LLM usage:** $0.5160 (30 commits)
- 👤 **Human dev:** ~$2928 (29.3h @ $100/h, 30min dedup)

Generated on 2026-07-05 using [openrouter/qwen/qwen3-coder-next](https://openrouter.ai/qwen/qwen3-coder-next)

---

Author urirun **URI flows** in a typed programming language, and convert them
to/from the canonical YAML flow format — the way **Pydantic** gives data a typed,
validated model that serializes to a schema.

A urirun *flow* is an ordered DAG of URI steps (`query` reads, `command` mutates),
chaining prior results. The interchange format is YAML
(see [examples/17-flows](https://examples.ifuri.com/)); `urirun-flow` lets you build
and validate that flow in code, with autocompletion, and emit the exact YAML a
runner executes.

## Why

YAML is great for sharing and running a flow, but a typed language gives you
**control**: autocompletion of step references, compile-/run-time validation of the
DAG, refactorability, and the ability to compute a flow (loops, conditionals,
parameters) instead of hand-writing YAML. `urirun-flow` is the bridge — round-trip
between the two.

## Use (Python, Pydantic)

```python
from urirun_flow import Flow

flow = Flow(task={"title": "Web recon"}, registry="tools.bindings.json",
            allow=["httpcheck://*", "browser://*", "log://*"])

up   = flow.step("httpcheck://host/url/query/status", id="up", payload={"url": URL})
read = flow.step("browser://chrome/page/query/dom", id="read",
                 payload={"url": URL}, after=[up])
flow.step("log://host/run/command/write", id="audit",
          payload={"detail": read.ref("text")}, after=[read])   # typed reference

print(flow.to_yaml())              # canonical urirun flow YAML
Flow.from_yaml(text)               # parse + validate back into the model
```

`.step()` returns the typed `Step`, so a later step references its output with
`step.ref("field")` — a checked `<id>.<field>` chain rather than a magic string.

The model validates on every build: URIs are well-formed, `depends_on` resolves to a
real step, and the graph is acyclic. `kind` (`query`/`command`) is derived from the URI.

## CLI

```bash
urirun-flow to-yaml web_recon:flow      # import a Python flow object → YAML
urirun-flow validate flow.yaml          # DAG / deps / URIs
urirun-flow from-yaml flow.yaml         # parse + re-emit (normalize / round-trip)
urirun-flow run flow.yaml --execute     # execute through urirun when the runtime is installed
```

The `urirun_flow` import package is owned by this distribution. Typed authoring
and YAML validation need only `urirun-flow`; execution needs the `urirun` runtime
installed as well.

## Proposal: typed flows in any language

The flow is a **language-agnostic contract** (`{task, registry, allow, steps:[{id,
uri, payload, depends_on}]}`). `urirun-flow` is its Python (Pydantic) model; the same
builder→dict mapping is implementable in any typed language and emits the identical
YAML — exactly how the urirun connector SDKs stay in lockstep across languages.

`js/urirun-flow.js` is a runnable JS/TS emitter (typed via `js/urirun-flow.d.ts`) that
builds the **identical** flow contract. `make conformance` builds the same reference
flow in every language and asserts they agree — like `make conformance` for connector
bindings. Verified: **2/2 emitters agree** (Python + JS).

## License

Licensed under Apache-2.0.
