This release is a pre-release and may not be stable for production use.
Moiryx
Moiryx lets you define an agent in Markdown, select its model in YAML, and call
it like an async Python object. You can move the same agent from a local
llama-server to OpenRouter, Azure, or Vertex AI without changing Python code.
This project is an alpha. Its primary user-facing API consists of Agent,
@tool, moiryx.yaml, and the optional typed runtime events in
moiryx.events.
Installation
Install the alpha from PyPI:
python -m pip install moiryx==0.1.0a2
For development from this checkout:
python -m pip install -e .
Vertex AI requires the optional Google Gen AI SDK. For a PyPI installation:
python -m pip install "moiryx[google]==0.1.0a2"
From this checkout:
python -m pip install -e ".[google]"
Your first agent with a local llama-server
Start an OpenAI-compatible endpoint and create moiryx.yaml:
providers:
local:
type: openai_compatible
base_url: http://127.0.0.1:8080/v1
models:
local_chat:
provider: local
model: local-model
Save the agent as agents/chat.md:
---
model: local_chat
---
Answer directly and say when you are uncertain.
Call it from Python:
import asyncio
from moiryx import Agent
async def main() -> None:
agent = Agent("agents/chat.md")
answer = await agent("What is the difference between a process and a thread?")
print(answer)
asyncio.run(main())
For a long-lived application, call await agent.aclose() when you are done, or
use async with Agent(...). This releases the provider's HTTP connections. A
one-off script can simply exit.
Built-in tools
Tools are opt-in. Add only the ones an agent needs to its frontmatter:
---
model: local_chat
tools: [read_file, list_files, grep]
---
Inspect files in the workspace and cite the paths you used.
Available tools are read_file, list_files, glob_files, grep,
write_file, edit_file, and shell. File operations stay within
runtime.workspace_root by default.
shellis not a security sandbox. Enable it only for agents and workspaces you trust.
Custom tools
from moiryx import tool
@tool
def word_count(text: str) -> int:
"""Count words in text."""
return len(text.split())
Import the module through the configuration, then select the tool in the agent definition:
tool_modules: [my_tools]
---
model: local_chat
tools: [word_count]
---
Use the tool to count words accurately.
Structured output
Declare the result with an ordinary Pydantic model:
from pydantic import BaseModel, Field
class ReviewResult(BaseModel):
accepted: bool
score: float = Field(ge=0, le=1)
findings: list[str]
Reference it as module:Class in the agent:
---
model: local_chat
output: review_models:ReviewResult
---
Review the change and return a result matching the schema.
await agent(...) returns a ReviewResult instance. JSON embedded in plain
text does not count as a structured result.
Switching providers in YAML
Keep the Python code and agent file; change the model alias configuration:
providers:
router:
type: openrouter
api_key: ${OPENROUTER_API_KEY}
headers:
HTTP-Referer: https://example.invalid
X-OpenRouter-Title: Moiryx example
models:
local_chat:
provider: router
model: provider/model-id
Supported provider types are openai_compatible (including llama-server,
vLLM, and SGLang), openrouter, azure_openai, azure_foundry, and
vertex_ai (using Application Default Credentials or a service account).
Logging and traces
logging:
level: INFO
trace_dir: .moiryx/runs
include_raw_response: false
Each run has its own ID and, when tracing is enabled, an
.moiryx/runs/<run-id>/events.jsonl file. Raw provider responses are off by
default. If enabled, configured secrets and sensitive fields are still
redacted.
Runtime events and conversation history
Agent calls accept an explicit normalized history and an optional event sink:
from moiryx.messages import AssistantMessage, UserMessage
async def continue_conversation():
async def show(event):
print(event.kind)
return await agent(
"Continue",
history=[UserMessage("Question"), AssistantMessage("Earlier answer")],
event_sink=show,
)
For direct iteration, use agent.stream(...):
async def stream_events():
async for event in agent.stream("Continue"):
print(event.kind)
The stream emits typed agent, tool, usage, warning, and terminal lifecycle
events while preserving the normal exception behavior. Provider token deltas
are not yet available; the current stream is semantic and reports progress
around model and tool work. Applications can bind an ambient sink with
moiryx.events.event_sink when nested calls should share one event consumer.
Examples
See examples/ for runnable definitions, the
usage guide for configuration and tools, and the
provider guide for connection examples.
Release files for moiryx 0.1.0a2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| moiryx-0.1.0a2.tar.gz | 93.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| moiryx-0.1.0a2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 155.2 kB
Release files / moiryx-0.1.0a2.tar.gz
| Download URL | moiryx-0.1.0a2.tar.gz |
|---|---|
| Size | 93.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3967fb269da9995d63f15b9258d53d41258ad30ebb2d0b2c8d9a8ba73b3e7180
|
|
BLAKE2b-256 checksum How to use checksums |
6e5b90a27113e0530c70c36aaa633da6ddeb25009bf94435665afece3cd6ce4d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 26, 2026.
Transparency logRelease files / moiryx-0.1.0a2-py3-none-any.whl
| Download URL | moiryx-0.1.0a2-py3-none-any.whl |
|---|---|
| Size | 62.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
23d29c5308f6bf37f253c2d0bfe723eb2a666823903abda8ac309598bc235a06
|
|
BLAKE2b-256 checksum How to use checksums |
2339daedf34f150cc20aab7cf94d0ecf3e882a0625a2e368139e576f1724c7f4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 26, 2026.
Transparency log