Skip to main content

A small, composable Python framework for building goal-directed LLM agents (GAME loop + Capability hooks).

Project description

zurvan

A small, composable Python framework for building goal-directed LLM agents.

What it is

zurvan runs a GAME loop — Goals, Actions, Memory, Environment — over an LLM. Behaviour like plan-first, time-aware, prompt-injection-resistant, or progress-tracking is composed by passing a list of Capability instances rather than by subclassing Agent. With no capabilities it reduces to a plain Goals → Actions → Memory cycle.

LLM providers are abstracted behind AgentLanguage. Built-in subclasses (via LiteLLM) cover OpenAI, Gemini, and Groq.

Install

pip install zurvan

Requires Python 3.11+.

Quick start

from zurvan import (
    Action,
    ActionRegistry,
    Agent,
    AgentFunctionCallingActionLanguageOpenAI,
    Environment,
    Goal,
)

def terminate(message: str) -> str:
    return message

actions = ActionRegistry()
actions.register(Action(
    name="terminate",
    function=terminate,
    description="End the conversation with a final message.",
    parameters={
        "type": "object",
        "properties": {"message": {"type": "string"}},
        "required": ["message"],
    },
    terminal=True,
))

agent = Agent(
    goals=[Goal(priority=1, name="Greet", description="Greet the user warmly.")],
    agent_language=AgentFunctionCallingActionLanguageOpenAI(model="openai/gpt-4o-mini"),
    action_registry=actions,
    environment=Environment(),
)

memory = agent.run("Say hi.")

Pydantic-validated tool inputs

Action accepts either a JSON-Schema dict (parameters=) or a Pydantic model (input_model=). With a model, the schema sent to the LLM is derived from the model and the model's args are validated before the function runs — a ValidationError is caught by Environment and fed back to the LLM as a failed-tool result, so the model gets a chance to retry with corrected args.

from typing import Literal
from pydantic import BaseModel
from zurvan import Action

class GetWeatherArgs(BaseModel):
    city: str
    unit: Literal["c", "f"] = "c"

def get_weather(city: str, unit: str = "c") -> str:
    return f"It's nice in {city} ({unit}°)"

action = Action(
    name="get_weather",
    function=get_weather,
    description="Look up the weather for a city.",
    input_model=GetWeatherArgs,
)

parameters= and input_model= are mutually exclusive — pass exactly one.

Capabilities

Capabilities hook into every loop phase (init, start_agent_loop, process_prompt, process_response, process_action, process_result, process_new_memories, end_agent_loop, should_terminate, terminate). Compose them — don't subclass Agent.

from zurvan import Agent, CanaryCapability, TimeAwareCapability

agent = Agent(
    ...,
    capabilities=[CanaryCapability(), TimeAwareCapability()],
)

License

MIT.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

zurvan-0.1.0.tar.gz (25.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

zurvan-0.1.0-py3-none-any.whl (35.9 kB view details)

Uploaded Python 3

File details

Details for the file zurvan-0.1.0.tar.gz.

File metadata

  • Download URL: zurvan-0.1.0.tar.gz
  • Upload date:
  • Size: 25.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for zurvan-0.1.0.tar.gz
Algorithm Hash digest
SHA256 d3146afbc79900889c98162f02bea19fa96ffa6f94c4a4b6a5cfcadde6d57f7f
MD5 a766d7cd99908da5d80b8ce9b92d2b43
BLAKE2b-256 ddb6e1029f40daaa74869a55c05523fb2a49ef30abb9d032039157781034e571

See more details on using hashes here.

Provenance

The following attestation bundles were made for zurvan-0.1.0.tar.gz:

Publisher: release.yml on aliafsahnoudeh/zurvan

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file zurvan-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: zurvan-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 35.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for zurvan-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6a5a9217b926bc21945cdca0fe85e5867900cbf4d2df402fe94ceb3bc0ff80a2
MD5 eff3371afc4878d4f6d0fd19abc034de
BLAKE2b-256 1402d33ee833b0061f76e0a4901e3eccaf27a4d97edf9f5000d991f5ea19cadf

See more details on using hashes here.

Provenance

The following attestation bundles were made for zurvan-0.1.0-py3-none-any.whl:

Publisher: release.yml on aliafsahnoudeh/zurvan

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page