English · 简体中文
Why Purrcept · Quick start · Model layer · Boundaries · Documentation
Purrcept Core is a Python-native, effect-driven foundation for composable agents. Plain
generator flows decide what happens next, typed Effect values describe one step, an
Executor performs it, and AgentDriver advances the run.
The optional purrcept_core.models standard library adds provider-neutral conversations,
prompts, function tools, streaming events, context policies, and backend conformance—without
taking ownership of provider clients, credentials, persistence, or the application runtime.
[!IMPORTANT]
0.5.0is an alpha release. The main development path is in place, but focused API changes may still follow real Provider and Runtime integration feedback before1.0.
The execution model
Every yielded operation passes through one execution boundary. That gives cancellation,
middleware, progress, lifecycle events, retries, approvals, and testing a precise step to act on.
A model tool loop does not bypass this model: one conversation.ask() can yield
Generate → InvokeTool → Generate, with every generation and tool call remaining an independent
Effect.
Why Purrcept
- Compose with ordinary Python. Use generators,
yield from, conditions, loops, nested flows, return values, and normal exception handling. - Observe every side effect. Run and Effect identifiers, step indexes, progress, success, failure, and cancellation all cross the same driver lifecycle.
- Keep reality at the edge. The Runtime owns provider clients, credentials, databases, scheduling, persistence, and platform policy.
- Switch Providers without changing agent semantics. The model layer defines immutable messages, requests, responses, tools, streaming events, cache intent, and error categories.
- Extend by composition. Extensions are ordinary Python packages and explicitly supplied objects—installing or importing a package does not silently enable it.
Quick start
Purrcept Core is currently developed from source. From a checkout:
pip install -e .
Or install the full contributor environment and run the first offline example:
uv sync --all-groups
uv run python examples/01_inline_effect.py
Define one typed Effect, compose it in a Flow, and run it through the driver:
import asyncio
from dataclasses import dataclass
from purrcept_core import (
AgentDriver,
AgentFlow,
Effect,
ExecutionContext,
InlineExecutor,
perform,
)
@dataclass(frozen=True, slots=True)
class Add(Effect[int]):
left: int
right: int
def execute(self, context: ExecutionContext[None]) -> int:
return self.left + self.right
def calculate() -> AgentFlow[int]:
first = yield from perform(Add(1, 2))
return (yield from perform(Add(first, 4)))
async def main() -> None:
result = await AgentDriver(InlineExecutor()).run(calculate(), host=None)
print(result)
asyncio.run(main())
7
perform() preserves the result type of Effect[T]. The Runtime owns the event loop; Core never
calls asyncio.run() internally.
Add the model layer
Bind a Runtime-owned backend to a model, then let Conversation run the observable tool loop:
from purrcept_core import AgentFlow
from purrcept_core.models import Model, tool
@tool
async def search(query: str) -> list[str]:
"""Search a trusted application data source."""
return [f"Result for {query}"]
def researcher(model: Model, question: str) -> AgentFlow[str]:
conversation = model.conversation(
instructions="Separate verified facts from assumptions.",
tools=(search,),
cache="auto",
)
result = yield from conversation.ask(question)
return result.text
The concrete ModelBackend comes from a Provider package. It receives immutable,
provider-neutral requests and maps them to its SDK or transport. Core supplies a deterministic
Backend Conformance Kit so adapters can verify request
semantics, streaming order, errors, cancellation, tool transactions, and reminder removal without
making real network calls.
The separately developed
purrcept_litellm package is one concrete adapter
for LiteLLM Chat Completions.
Choose the boundary you need
| Layer | Owns | Reach for it when |
|---|---|---|
| Effect kernel | Flow, Effect, Executor, AgentDriver |
Any operation needs explicit orchestration, observation, or policy. |
| Model standard library | Model, Conversation, prompts, tools, context, model events |
An agent needs Provider-neutral model and tool semantics. |
| Provider package | ModelBackend, SDK mapping, transport errors |
A concrete model service must implement the Core protocol. |
| Runtime / application | Clients, credentials, host resources, persistence, scheduling | Real resources and product policy must be owned and enforced. |
Deliberately outside Core
Core does not create event loops, background tasks, provider clients, database connections, or process-wide singletons. It does not provide platform sessions, Memory/RAG, task scheduling, durable execution, HTTP/CLI services, a global tool registry, or hidden retries and fallbacks.
Effects and handlers are normal in-process Python code. The unified execution boundary makes them observable and wrappable; it is not a sandbox or permission boundary. The Runtime must enforce authorization and decide which inputs, outputs, and errors are safe to record.
Model capabilities at a glance
- Immutable message, content, request, response, usage, continuation, and streaming-event values.
PromptTemplate, composable render policies, localPromptLibrary, and deterministicPromptCompiler.- Transactional
Conversationturns, snapshots, restore, fork, scoped reminders, dynamicReminderSource, prompt traces, and complete-request token budgets. - Typed Python function tools with generated JSON Schema, argument validation, result encoding, and explicit error policy.
- Append-only, sliding-window, and injected token-budget context policies.
- Provider-neutral cache intent, continuation policy, structured model errors, and an offline backend conformance suite.
For the full contracts and examples, see Model standard capabilities.
Documentation
Start here
Build and extend
Reference, compatibility, and architecture decisions
Development
Purrcept Core targets Python 3.11 through 3.14, publishes py.typed, uses strict Pyright, and
enforces 100% branch coverage.
uv sync --all-groups
uv run ruff check .
uv run ruff format --check .
uv run pyright
uv run pytest --cov=purrcept_core --cov-report=term-missing
uv build
Read CONTRIBUTING.md before changing a public contract. New behavior should arrive with focused tests and matching narrative documentation.
Project status
- Current version:
0.5.0alpha. - Supported Python versions:
3.11,3.12,3.13, and3.14. - Runtime dependency: Pydantic v2, used internally by function tools without entering the public model protocol.
- Licensing and the public PyPI package name still require project-owner confirmation before a public release.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file purrcept_core-0.5.0.tar.gz.
File metadata
- Download URL: purrcept_core-0.5.0.tar.gz
- Upload date:
- Size: 225.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.12.7 {"installer":{"name":"uv","version":"0.12.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e84852ea1c1097f5e9e9688c6e40fc3828d3e4d99bc0751df0a98cf6e3e7dfbb
|
|
| MD5 |
c47506796016b689992db49f8924028f
|
|
| BLAKE2b-256 |
44b2dbba13c4529c61e14e7abc9a67a0f93ea51a93fef0d9d2d05c440d51f2d3
|
File details
Details for the file purrcept_core-0.5.0-py3-none-any.whl.
File metadata
- Download URL: purrcept_core-0.5.0-py3-none-any.whl
- Upload date:
- Size: 105.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.12.7 {"installer":{"name":"uv","version":"0.12.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a56c60497fde89f3826e9d8d52399dbac4ed4f0804f2e2f6e36067b0ba1877a0
|
|
| MD5 |
74f0f5d0d2f1ec6c364af803433e5d98
|
|
| BLAKE2b-256 |
8f900afc1742f84114d10df7c660b5ed135dbaa8876fba5abb63cfbcfac4cb7d
|