Metadata-Version: 2.4
Name: durin-agent
Version: 0.2.0b8
Summary: Personal AI agent with daily-driver CLI, modal TUI, and graph-based memory
Project-URL: Homepage, https://github.com/mmarmol/durin
Project-URL: Repository, https://github.com/mmarmol/durin
Project-URL: Documentation, https://github.com/mmarmol/durin/blob/main/docs/README.md
Project-URL: Issues, https://github.com/mmarmol/durin/issues
Author: Marcelo Marmol
License: MIT
License-File: LICENSE
Keywords: agent,ai,memory,posture
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: <3.14,>=3.11
Requires-Dist: anthropic<1.0.0,>=0.45.0
Requires-Dist: chardet<8.0.0,>=3.0.2
Requires-Dist: croniter<7.0.0,>=6.0.0
Requires-Dist: dulwich<2.0.0,>=0.22.0
Requires-Dist: filelock>=3.25.2
Requires-Dist: httpx<1.0.0,>=0.28.0
Requires-Dist: jinja2<4.0.0,>=3.1.0
Requires-Dist: json-repair<1.0.0,>=0.57.0
Requires-Dist: jsonpatch<2.0,>=1.33
Requires-Dist: lark-oapi<2.0.0,>=1.4.0
Requires-Dist: litellm>=1.40.0
Requires-Dist: loguru<1.0.0,>=0.7.3
Requires-Dist: markdown-it-py<5.0,>=3.0
Requires-Dist: markitdown[docx,pdf,pptx,xls,xlsx]<0.2.0,>=0.1.6
Requires-Dist: openai>=2.8.0
Requires-Dist: openpyxl<4.0.0,>=3.1.0
Requires-Dist: prompt-toolkit<4.0.0,>=3.0.50
Requires-Dist: pydantic-settings<3.0.0,>=2.12.0
Requires-Dist: pydantic<3.0.0,>=2.12.0
Requires-Dist: pypdf<7.0.0,>=5.0.0
Requires-Dist: python-docx<2.0.0,>=1.1.0
Requires-Dist: python-pptx<2.0.0,>=1.0.0
Requires-Dist: python-telegram-bot[socks]<23.0,>=22.6
Requires-Dist: pyyaml<7.0.0,>=6.0
Requires-Dist: questionary<3.0.0,>=2.0.0
Requires-Dist: rich<16.0.0,>=14.0.0
Requires-Dist: textual<9.0.0,>=8.2.0
Requires-Dist: tiktoken<1.0.0,>=0.12.0
Requires-Dist: typer<1.0.0,>=0.20.0
Requires-Dist: unidecode<2.0,>=1.4
Requires-Dist: watchdog<7.0,>=4.0
Requires-Dist: websockets<17.0,>=13.0
Provides-Extra: api
Requires-Dist: starlette<2,>=1.3; extra == 'api'
Requires-Dist: uvicorn<1,>=0.49; extra == 'api'
Provides-Extra: cross-encoder
Requires-Dist: sentence-transformers<6.0,>=3.0; extra == 'cross-encoder'
Provides-Extra: dev
Requires-Dist: pytest-asyncio<2.0.0,>=1.3.0; extra == 'dev'
Requires-Dist: pytest-cov<8.0.0,>=6.0.0; extra == 'dev'
Requires-Dist: pytest<10.0.0,>=9.0.0; extra == 'dev'
Requires-Dist: ruff>=0.1.0; extra == 'dev'
Provides-Extra: discord
Requires-Dist: discord-py<3.0.0,>=2.5.2; extra == 'discord'
Provides-Extra: local
Requires-Dist: huggingface-hub>=0.20.0; extra == 'local'
Requires-Dist: llama-cpp-python>=0.3.0; extra == 'local'
Provides-Extra: matrix
Requires-Dist: matrix-nio<0.26,>=0.25; extra == 'matrix'
Requires-Dist: mistune<4.0,>=3.0; extra == 'matrix'
Requires-Dist: nh3<1.0,>=0.2; extra == 'matrix'
Provides-Extra: mcp
Requires-Dist: mcp<2.0.0,>=1.26.0; extra == 'mcp'
Provides-Extra: memory
Requires-Dist: fastembed<0.9,>=0.7; extra == 'memory'
Requires-Dist: lancedb<1.0.0,>=0.30.0; extra == 'memory'
Provides-Extra: oauth
Requires-Dist: oauth-cli-kit>=0.1.0; extra == 'oauth'
Provides-Extra: slack
Requires-Dist: slack-sdk<4.0.0,>=3.39.0; extra == 'slack'
Requires-Dist: slackify-markdown<1.0.0,>=0.2.0; extra == 'slack'
Provides-Extra: stt
Requires-Dist: av<19.0.0,>=12.0.0; extra == 'stt'
Requires-Dist: numpy<3.0.0,>=1.24; extra == 'stt'
Requires-Dist: sherpa-onnx<2.0.0,>=1.13.0; extra == 'stt'
Provides-Extra: tts
Requires-Dist: onnxruntime<2.0.0,>=1.17; extra == 'tts'
Requires-Dist: supertonic>=1.3; extra == 'tts'
Provides-Extra: voice
Requires-Dist: sounddevice<1.0.0,>=0.5.0; extra == 'voice'
Provides-Extra: web
Requires-Dist: ddgs<10.0.0,>=9.5.5; extra == 'web'
Requires-Dist: readability-lxml<1.0.0,>=0.8.4; extra == 'web'
Description-Content-Type: text/markdown

<p align="center">
  <img src="https://raw.githubusercontent.com/mmarmol/durin/main/docs/assets/durin-banner.svg" alt="durin" width="820">
</p>

<p align="center">
  <a href="https://pypi.org/project/durin-agent/"><img alt="PyPI" src="https://img.shields.io/pypi/v/durin-agent?color=57b6e6&label=pypi"></a>
  <img alt="Python" src="https://img.shields.io/badge/python-3.11%2B-57b6e6">
  <a href="https://github.com/mmarmol/durin/blob/main/LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/license-MIT-57b6e6"></a>
</p>

**The problem with AI agents isn't that they forget — it's that they improvise.**
durin is built the other way around: it remembers your work, sharpens its own
skills, and runs on adaptable workflows that make it follow the exact steps *you*
define instead of inventing its own. Reliable execution you control — local-first,
on any model.

> durin is named for Tolkien's dwarf-king of Khazad-dûm; the mark is a dwarven
> anvil lit by a forge flame.

## Why durin

### Workflows that follow *your* steps

Left to itself, an LLM agent improvises a different path every time — great for
open-ended chat, unreliable for work you need done *a specific way*. durin lets you
pin it to **adaptable workflows**: visual graphs of nodes with routing, loop-backs,
parallel branches, sub-flows, and human checkpoints. A task then runs the way you
designed it — every time. The agent can pause to ask you, resume exactly where it
stopped, and even **edit and improve a workflow on its own** (with an auto-revert
safety net). Few personal agents give you this much control over *how* the work
gets done.

<p align="center">
  <img src="https://raw.githubusercontent.com/mmarmol/durin/main/docs/assets/mockup-workflow.svg" alt="A durin workflow: nodes, a router, parallel branches, a human checkpoint, and a loop-back" width="860">
</p>

### Loops that chase a goal, not a clock

A workflow runs once; a **loop** runs one *over and over until a goal is actually
met*. You give it a plain-language goal — plus optional **checks** (a shell command
that must exit `0`, or an assertion an LLM judge grades) — and durin takes it from
there: it fires on a **trigger** (a schedule, an inbound message, a webhook, or you
just asking), runs the workflow, checks the result against the goal, and either
closes out or tries again next time. And when it keeps missing after a few
attempts, it doesn't spin forever — it **stops and asks you**.

<p align="center">
  <img src="https://raw.githubusercontent.com/mmarmol/durin/main/docs/assets/mockup-loops.svg" alt="durin's Loops panel: goal-seeking loops with status, checks, and an escalation that pauses to ask you" width="860">
</p>

### A memory that's actually yours

durin builds an **entity graph** from your conversations — people, projects,
documents, decisions — and keeps it as plain markdown *you own*. Recall is instant
and offline: it searches an FTS + vector index **without an LLM in the hot path**,
so it's fast and private. Documents you hand it (PDF, Office, EPUB, web pages) land
in a separate **Library**, kept apart from everyday recall. The markdown is the
source of truth; the search indexes are derived and rebuildable. (Benchmarked at
LoCoMo ≈ 0.79.)

<p align="center">
  <img src="https://raw.githubusercontent.com/mmarmol/durin/main/docs/assets/mockup-memory.svg" alt="durin's memory as a typed entity graph with labelled relations" width="860">
</p>

### A skills ecosystem with guardrails

durin discovers skills from public marketplaces, **security-scans each one** for
scam/malware patterns before you run it, and connects MCP servers from a curated
catalog with one-click install and auto-detected OAuth. Its composition doctrine
keeps behaviour reliable — **prefer deterministic code, use workflows for
structure, treat skills as the through-line the agent follows** — and it sharpens
its own skills over time.

### See exactly what it's running

Every run — workflows, scheduled cron jobs, agent tasks — shows up in a live panel
with per-step detail, status, and the model used. Nothing happens in a black box:
watch a run, open a paused checkpoint, and pick up right where it stopped.

<p align="center">
  <img src="https://raw.githubusercontent.com/mmarmol/durin/main/docs/assets/mockup-runs.svg" alt="durin's Runs panel: live task list with per-step progress" width="860">
</p>

### And more

- **Any model, or none.** 35 provider integrations — Anthropic, OpenAI, Gemini,
  NVIDIA, Mistral, DeepSeek, Groq, Z.AI, Qwen, Moonshot, and more, plus OpenRouter
  and other gateways that reach hundreds of models. Switch mid-conversation, or run
  fully local with Ollama / llama.cpp / vLLM / LM Studio.
- **Talk to it anywhere.** A CLI, a Textual TUI, a browser dashboard, and chat
  channels — Telegram, Slack, Discord, email, WhatsApp, WebSocket — all reach the
  same agent and the same memory.
- **Local-first & private.** Runs as a daemon on your own machine under
  `~/.durin/`; nothing phones home.
- **Personas, voice, and schedules.** Per-channel personas (a SOUL + a model),
  local speech-to-text and text-to-speech, and cron for scheduled work.

### …and it gets sharper while you sleep

A cold-path *dream* runs offline: it consolidates your conversations into the
memory graph and curates your skills, so durin quietly gets better at helping you
over time — without you lifting a finger.

## Quick start

durin installs with [uv](https://docs.astral.sh/uv/), which fetches a compatible
Python for you — nothing on your system has to match. Don't have uv yet?
`curl -LsSf https://astral.sh/uv/install.sh | sh`

```bash
uv tool install --prerelease allow durin-agent   # PyPI (uv picks a compatible Python)
durin onboard                    # interactive setup wizard
durin doctor                     # confirm setup is healthy
durin agent                      # launch the TUI
```

Run the gateway for the browser dashboard plus chat channels:

```bash
durin gateway start              # dashboard at http://127.0.0.1:8765
```

See the [install guide](https://github.com/mmarmol/durin/blob/main/docs/guide/install.md) for prerequisites, optional extras
(memory, local models, audio), and platform notes. For everyday and in-session
commands, see the [CLI reference](https://github.com/mmarmol/durin/blob/main/docs/guide/cli.md).

## Documentation

- [Install · configure · uninstall](https://github.com/mmarmol/durin/blob/main/docs/guide/install.md)
- [CLI & in-session commands](https://github.com/mmarmol/durin/blob/main/docs/guide/cli.md)
- [Configuration reference](https://github.com/mmarmol/durin/blob/main/docs/guide/configuration.md)
- [Providers & models](https://github.com/mmarmol/durin/blob/main/docs/guide/providers.md)
- [Channels](https://github.com/mmarmol/durin/blob/main/docs/guide/channels.md) — Telegram, Slack, Discord, email, and more
- [Documents & your knowledge](https://github.com/mmarmol/durin/blob/main/docs/guide/documents.md)
- [Workflows](https://github.com/mmarmol/durin/blob/main/docs/guide/workflows.md)
- [Loops](https://github.com/mmarmol/durin/blob/main/docs/guide/loops.md) — workflows that repeat until a goal is met
- [How it works (internals)](https://github.com/mmarmol/durin/blob/main/docs/internals/README.md)

## License

MIT
