diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..6dcd3d2 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,68 @@ +name: Release + +on: + push: + tags: ["v*"] + workflow_dispatch: + +permissions: + contents: read + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + + - uses: actions/setup-python@v7 + with: + python-version: "3.12" + cache: pip + + - name: Verify tag matches project version + if: startsWith(github.ref, 'refs/tags/') + run: | + project_version="$(python -c 'import tomllib, pathlib; print(tomllib.loads(pathlib.Path("pyproject.toml").read_text())["project"]["version"])')" + tag_version="${GITHUB_REF_NAME#v}" + if [ "$project_version" != "$tag_version" ]; then + echo "::error::Tag ${GITHUB_REF_NAME} does not match pyproject version ${project_version}" + exit 1 + fi + echo "Releasing ${project_version} from ${GITHUB_REF_NAME}" + + - name: Build distributions + run: | + python -m pip install --upgrade build twine + python -m build + twine check dist/* + + - name: Smoke test built wheel + run: | + python -m venv /tmp/smoke + /tmp/smoke/bin/pip install --quiet dist/*.whl + /tmp/smoke/bin/python -c "import flowroute; print(flowroute.__version__)" + /tmp/smoke/bin/flowroute route \ + --catalog examples/workflows.yaml \ + --text "Where is order 4812?" + + - uses: actions/upload-artifact@v7 + with: + name: dist + path: dist/ + + publish: + needs: build + runs-on: ubuntu-latest + environment: + name: pypi + url: https://pypi.org/p/flowroute + permissions: + id-token: write + steps: + - uses: actions/download-artifact@v8 + with: + name: dist + path: dist/ + + - name: Publish to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 diff --git a/README.md b/README.md index ee2c57c..468870c 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,10 @@ # FlowRoute +[![CI](https://github.com/open-first/FlowRoute/actions/workflows/ci.yml/badge.svg)](https://github.com/open-first/FlowRoute/actions/workflows/ci.yml) +[![Docs](https://github.com/open-first/FlowRoute/actions/workflows/docs.yml/badge.svg)](https://open-first.github.io/FlowRoute/) +[![Python](https://img.shields.io/badge/python-3.10%2B-blue)](https://www.python.org/downloads/) +[![License](https://img.shields.io/badge/license-Apache--2.0-blue)](LICENSE) + FlowRoute is a small, safety-oriented router that maps a natural-language request to a deterministic workflow without using a generative LLM for the routing decision. @@ -12,6 +17,25 @@ It returns exactly one of three outcomes: FlowRoute never executes workflows. Authorization, argument validation, confirmation, idempotency, and side effects remain in the workflow orchestrator. +**[Read the documentation](https://open-first.github.io/FlowRoute/)** · +[Quick start](#quick-start) · +[Production mode](#production-mode) + +## When FlowRoute fits + +Use FlowRoute when: + +- workflows are narrow, named, and deterministic; +- users express the same intent in varied language; +- a safe fallback is available for ambiguous requests; +- inference cost or latency matters; and +- false routing is more expensive than abstention. + +Use an LLM or planner when the task requires explanation, advice, strategy, open-ended +generation, or several dependent actions. FlowRoute is a selector, not an orchestrator, an agent +framework, or a general-purpose intent classifier; its job is to decide whether a request belongs +to a known workflow and to abstain when it does not. + ## Status Version 0.2 provides a **production-hardened routing runtime and research scaffold**, but it does @@ -37,6 +61,10 @@ flowchart TD F --> I["LLM_REQUIRED"] ``` +Each stage may only narrow the candidate set. Retrieval proposes; the verifier judges one +request-contract pair at a time; calibration decides whether the best candidate clears the risk +tier it was assigned. Schema completeness is deterministic and can override an unsafe prediction. + ## Quick start Requires Python 3.10 or newer. @@ -78,10 +106,14 @@ Run unit tests without installing development tools: PYTHONPATH=src python -m unittest discover -s tests -v ``` -## Developer documentation +## Documentation -The complete developer guide is authored as portable Markdown under `docs/` and configured for -MkDocs: +The complete developer guide is published at +**[open-first.github.io/FlowRoute](https://open-first.github.io/FlowRoute/)**. It covers +installation, contracts, Python, HTTP and CLI integration, routing internals, training, dataset +design, evaluation, safety, production requirements, and troubleshooting. + +The source is portable Markdown under `docs/`, configured for MkDocs: ```bash pip install -r requirements-docs.txt @@ -94,10 +126,6 @@ Build a static site that can be uploaded to any static host: mkdocs build --strict ``` -Start with [the documentation home](docs/index.md). It covers installation, contracts, Python, -HTTP and CLI integration, routing internals, training, dataset design, evaluation, safety, -production requirements, and troubleshooting. - ## Python API ```python @@ -140,6 +168,31 @@ curl -s http://127.0.0.1:8000/v1/route \ The development service also exposes `GET /health`, `GET /health/live`, and `GET /health/ready`. A stale `catalog_version` returns HTTP 409. +## Workflow contracts + +Contracts describe capability boundaries, inputs, effects, and risk—not executable code. + +```yaml +- id: calendar.cancel_event + version: 1.0.0 + name: Cancel a calendar event + description: Cancel one existing event the current user may modify. + positive_capabilities: + - cancel an existing meeting + exclusions: + - decline an invitation + - delete a recurring series without confirmation + required_inputs: + - name: event_id + pattern: '\b(?Pevt_[A-Za-z0-9_-]+)\b' + side_effect: external_write + risk_tier: medium + confirmation: required_if_recurring +``` + +For safety, external or destructive contracts must declare both exclusions and a confirmation +policy. Regex extraction is optional; trusted structured context takes precedence. + ## Production mode ```python @@ -182,33 +235,8 @@ Production mode: - emits privacy-conscious structured telemetry; and - supports atomic bundle reload and rollback through `RouterRuntime`. -See [Production mode](docs/operations/production-mode.md) and -[Artifact manifests](docs/operations/artifact-manifests.md). - -## Workflow contracts - -Contracts describe capability boundaries, inputs, effects, and risk—not executable code. - -```yaml -- id: calendar.cancel_event - version: 1.0.0 - name: Cancel a calendar event - description: Cancel one existing event the current user may modify. - positive_capabilities: - - cancel an existing meeting - exclusions: - - decline an invitation - - delete a recurring series without confirmation - required_inputs: - - name: event_id - pattern: '\b(?Pevt_[A-Za-z0-9_-]+)\b' - side_effect: external_write - risk_tier: medium - confirmation: required_if_recurring -``` - -For safety, external or destructive contracts must declare both exclusions and a confirmation -policy. Regex extraction is optional; trusted structured context takes precedence. +See [Production mode](https://open-first.github.io/FlowRoute/operations/production-mode/) and +[Artifact manifests](https://open-first.github.io/FlowRoute/operations/artifact-manifests/). ## Plug in Hugging Face checkpoints @@ -279,6 +307,26 @@ docs/ architecture and research implementation notes 6. Report false-route rate together with route coverage and confidence intervals. 7. Fill every `TBD` in the model and dataset cards; publish checkpoint hashes. +## Contributing + +Contributions are welcome. [CONTRIBUTING.md](CONTRIBUTING.md) states the rules that protect the +safety boundary: keep the router separate from workflow execution; add a regression test for every +routing or abstention change; never weaken a risk threshold to make one example pass; and do not +add benchmark numbers without a reproducible evaluation artifact. + +`main` is protected. Work on a branch and open a pull request; CI must pass on Python 3.10 and +3.12, and documentation changes must also survive `mkdocs build --strict`. + +## Security + +Do not open a public issue for a suspected vulnerability. Use GitHub's private +vulnerability-reporting feature, or follow [SECURITY.md](SECURITY.md). + +## Citation + +If you use FlowRoute in research, cite the software through [CITATION.cff](CITATION.cff). GitHub +renders a ready-made citation from that file under **Cite this repository**. + ## License Apache-2.0. Dataset and model artifacts may have separate licenses; document them before release.