Metadata-Version: 2.4
Name: relayr-ai
Version: 0.1.1
Summary: The bridge between artifactr and reflexr: events from chats and artifacts become events for rules, and runs act back in the chat as proposals and notices.
Keywords: agents,llm,events,rules,collaboration,artifacts,pydantic-ai
Author: Alex Nodeland
Author-email: Alex Nodeland <alex@ournature.studio>
License-Expression: MIT
License-File: LICENSE
Classifier: Development Status :: 2 - Pre-Alpha
Classifier: Framework :: Pydantic :: 2
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
Classifier: Typing :: Typed
Requires-Dist: artifactr-ai>=0.2.0
Requires-Dist: reflexr>=0.1.0
Requires-Dist: pydantic>=2.13
Requires-Dist: pydantic-ai-slim>=2.51
Requires-Dist: opentelemetry-api>=1.45
Requires-Dist: evalr>=0.1.0 ; extra == 'evals'
Requires-Dist: langfuse>=4.15,<5 ; extra == 'langfuse'
Requires-Dist: artifactr-ai[langfuse]>=0.2.0 ; extra == 'langfuse'
Requires-Dist: reflexr[langfuse]>=0.1.0 ; extra == 'langfuse'
Requires-Dist: evalr[langfuse]>=0.1.0 ; extra == 'langfuse'
Requires-Dist: lattice-core-ai>=0.1.0 ; extra == 'otel'
Requires-Dist: opentelemetry-sdk>=1.45 ; extra == 'otel'
Requires-Dist: relayr-ai[sql] ; extra == 'postgres'
Requires-Dist: asyncpg>=0.31 ; extra == 'postgres'
Requires-Dist: lattice-core-ai[sql]>=0.1.0 ; extra == 'sql'
Requires-Dist: sqlalchemy[asyncio]>=2.1 ; extra == 'sql'
Requires-Dist: alembic>=1.20 ; extra == 'sql'
Requires-Dist: relayr-ai[sql] ; extra == 'sqlite'
Requires-Dist: aiosqlite>=0.22 ; extra == 'sqlite'
Requires-Python: >=3.12
Project-URL: Homepage, https://lattice.alexnodeland.com/relayr/
Project-URL: Documentation, https://lattice.alexnodeland.com/relayr/
Project-URL: Repository, https://github.com/alexnodeland/lattice
Project-URL: Issues, https://github.com/alexnodeland/lattice/issues
Project-URL: Changelog, https://github.com/alexnodeland/lattice/blob/main/packages/relayr/CHANGELOG.md
Provides-Extra: evals
Provides-Extra: langfuse
Provides-Extra: otel
Provides-Extra: postgres
Provides-Extra: sql
Provides-Extra: sqlite
Description-Content-Type: text/markdown

<picture>
  <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/alexnodeland/lattice/main/docs/relayr/assets/brand/banner-dark.svg">
  <img alt="relayr: the bridge between artifactr and reflexr." src="https://raw.githubusercontent.com/alexnodeland/lattice/main/docs/relayr/assets/brand/banner-light.svg" width="100%">
</picture>

<p>
  <a href="https://lattice.alexnodeland.com/relayr/"><img alt="Docs" src="https://img.shields.io/badge/docs-lattice.alexnodeland.com%2Frelayr-9E0A5E"></a>
  <a href="https://github.com/alexnodeland/lattice/actions/workflows/nightly.yml"><img alt="Nightly" src="https://github.com/alexnodeland/lattice/actions/workflows/nightly.yml/badge.svg?branch=main"></a>
  <img alt="Python 3.12, 3.13 and 3.14" src="https://img.shields.io/badge/python-3.12%20%7C%203.13%20%7C%203.14-9E0A5E">
  <img alt="Coverage: 100%" src="https://img.shields.io/badge/coverage-100%25-9E0A5E">
  <img alt="Typed: pyright strict" src="https://img.shields.io/badge/typed-pyright%20strict-9E0A5E">
  <a href="https://github.com/alexnodeland/lattice/blob/main/packages/relayr/LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/license-MIT-9E0A5E"></a>
</p>

**relayr** is the bridge between [artifactr](https://lattice.alexnodeland.com/artifactr/) and [reflexr](https://lattice.alexnodeland.com/reflexr/): events from chats and artifacts become events for rules, and runs act back in the chat as proposals and notices. It uses only the two libraries' public APIs, and neither library imports it or the other.

> **Status:** built: the [v0.1 plan](https://lattice.alexnodeland.com/relayr/rfcs/0001-v0.1-implementation-plan/). Both adapters, telemetry across the bridge, rules from chat and evaluation, and stackr's template wires it all into an application. It is on PyPI as `relayr-ai`, since the name `relayr` on PyPI is an unrelated project, and it is imported as `relayr`: `uv add relayr-ai`.

## Why

An application can mount artifactr and reflexr side by side, on one database and one telemetry setup, over one shared context: the same tenant and workspace ids name the same context in both. But the two halves don't talk to each other. A rule can't see what people say in a thread, and a run can't put its result in front of the people it concerns. Each application that wants this would write its own glue, and meet the same hard parts: duplicate and lost deliveries, rules that trigger themselves, two kinds of session that don't line up, and events that anyone could forge. [stackr's RFC-0002](https://lattice.alexnodeland.com/stackr/rfcs/0002-the-combined-system/) designs the bridge once, and relayr is where it is built.

## What it does

- **Inbound: chats and artifacts become events (built).** One follower per workspace, with a lease, a cursor and dead letters, publishes selected artifactr events into reflexr under the `artifactr` namespace, such as `artifactr:message_posted`, `artifactr:artifact_changed` and `artifactr:proposal_resolved`, so that a message fires a rule exactly once, across a restart and a redelivery ([ADR-0006](https://lattice.alexnodeland.com/relayr/adr/0006-bridged-types-in-the-artifactr-namespace/)).
- **Outbound: runs act as participants (built).** A pydantic-ai capability and helpers let a run act in artifactr as its rule's own external agent, `reflexr:<rule>`, so artifactr's rules apply to it: under a `propose` write policy its edits are proposals, and relayr never resolves one ([ADR-0002](https://lattice.alexnodeland.com/relayr/adr/0002-the-outbound-actor-an-external-agent-per-rule/)).
- **Notices by default (built).** A rule's messages start no turn in the thread, unless the rule's allowlist grants it ([ADR-0007](https://lattice.alexnodeland.com/relayr/adr/0007-notices-by-default/)).
- **Chains and sessions kept apart, and linked (built).** A thread is never a causal chain, and a chain never joins a thread's session or model history; traces are linked, and Langfuse sessions tagged, across the two ([ADR-0003](https://lattice.alexnodeland.com/relayr/adr/0003-a-thread-is-never-a-chain/), [ADR-0004](https://lattice.alexnodeland.com/relayr/adr/0004-sessions-linked-not-continued/)).
- **Rules from chat (built).** A rule drafted in a thread is a `rule` artifact, reviewed as a proposal, and goes live in reflexr's stored rules only when a person who may install rules accepts it, with provenance recorded both ways. A rule changed in reflexr directly is proposed back to its artifact ([ADR-0005](https://lattice.alexnodeland.com/relayr/adr/0005-where-a-rules-source-of-truth-lives/)).
- **Evaluation (built).** Proposal outcomes become feedback on the runs that proposed them, with measures of acceptance, rewrites and rules from chat that stay live, in the `evals` extra.
- **A ledger of its own (built)**, in memory or in SQL, behind the `sql`, `sqlite` and `postgres` extras.

## Documentation

relayr's documentation is its section of lattice's site, at **<https://lattice.alexnodeland.com/relayr/>**, built from [`docs/relayr/`](https://github.com/alexnodeland/lattice/tree/main/docs/relayr).

- [Bridging artifactr into reflexr](https://lattice.alexnodeland.com/relayr/guides/inbound/): wiring the followers into an application.
- [Acting in artifactr from rules](https://lattice.alexnodeland.com/relayr/guides/outbound/): the outbound adapter, allowlists and loops.
- [Tracing across the bridge](https://lattice.alexnodeland.com/relayr/guides/telemetry/): links, Langfuse tags and counters.
- [Rules from chat](https://lattice.alexnodeland.com/relayr/guides/rules/): drafting, previewing and installing rules, and drift.
- [Evaluating the bridge's rules](https://lattice.alexnodeland.com/relayr/guides/evaluation/): proposal outcomes and the measures.
- [Architecture](https://lattice.alexnodeland.com/relayr/architecture/): what exists, and how it works.
- [Architecture decision records](https://lattice.alexnodeland.com/relayr/adr/): why each part is the way it is.
- [RFCs](https://lattice.alexnodeland.com/relayr/rfcs/): the v0.1 plan, its phases and what each waits on.
- [The combined system](https://lattice.alexnodeland.com/stackr/rfcs/0002-the-combined-system/), stackr's RFC-0002: the design relayr builds.
- [Brand](https://lattice.alexnodeland.com/relayr/assets/brand/): the mark and its colours.

## Contributing

See [CONTRIBUTING.md](https://github.com/alexnodeland/lattice/blob/main/CONTRIBUTING.md) for setup, the trunk-based workflow, and the RFC and ADR process.

## License

[MIT](https://github.com/alexnodeland/lattice/blob/main/packages/relayr/LICENSE)
