Skip to content

Repository files navigation

ZeoCore

CI PyPI version Python versions Coverage License: MIT

A typed capability-authoring framework for Python. Write a tool once — validated input, one method of real work, a structured result — and run it inside any runner that respects the contract. No inheritance ceremony, no framework lock-in, no untyped **kwargs soup.

import logging
from pydantic import BaseModel
from zeo_core.contracts import CapabilityResult
from zeo_core.tools import BaseZeoTool, ToolContext


class GreetRequest(BaseModel):
    name: str


class GreetTool(BaseZeoTool):
    name = "greet"
    version = "1.0.0"

    def run(self, request: GreetRequest, ctx: ToolContext) -> CapabilityResult[str]:
        return CapabilityResult.ok(data=f"Hello, {request.name}!")


# A runner builds the context; this is what that looks like:
ctx = ToolContext(
    run_id="demo-run-001",
    tool_name="greet",
    tool_version="1.0.0",
    logger=logging.getLogger("greet"),
    fs=None,
    work_dir="/tmp",
    output_dir="/tmp",
)

result = GreetTool().run(GreetRequest(name="World"), ctx)
print(result.data)    # Hello, World!
print(result.status)  # CapabilityStatus.success

Every tool takes a typed request, runs against an immutable ToolContext (logger, filesystem, config, and any services the runner wires in), and returns a CapabilityResult — success or failure, always structured, always inspectable, never a bare exception or an untyped dict. mypy checks it end to end.

Why a typed result instead of "just raise an exception"

Exceptions are for things the caller didn't expect. A CapabilityResult is for things the tool expects and needs to report cleanly: validation failed, a downstream API returned an error, an optional integration wasn't configured. Callers get one shape to check (result.status) instead of a try/except matrix, and a runner orchestrating many tools can log, retry, or persist every result the same way, without special-casing which tool happens to throw what.

If a tool does hit something genuinely exceptional, ZeoCore's typed error hierarchy (ZeoError and its subclasses — ZeoFileNotFoundError, ZeoValidationError, ZeoApiError, and more) gives you specific, catchable exception types instead of parsing a string message. See examples/error_handling.py for the full pattern.

Install

pip install zeocore

Optional integrations ship as extras, so you only install what you use:

Extra What it adds
zeocore[github] GitHub API integration
zeocore[drive] Google Drive
zeocore[gmail] Gmail
zeocore[google] Drive + Gmail auth plumbing together
zeocore[notion] Notion
zeocore[pandoc] Document conversion via Pandoc
zeocore[llms] OpenAI / Anthropic / tiktoken clients
zeocore[http] FastAPI-based HTTP adapter for exposing tools over REST
zeocore[all] Every integration above, no http/dev/lint

dev and lint extras exist too, for contributors — see CONTRIBUTING.md.

More examples

Every example is runnable as-is: python examples/<name>.py. None of them are illustrative fragments — each one actually executes and prints real output, because a code sample that's never run is a code sample that's already stale.

What's in the package

Module What it's for
zeo_core.tools The framework itself — BaseZeoTool, ToolContext, and optional mixins (IntegrationEnabledMixin, LifecycleMixin, ToolEnvInitializerMixin).
zeo_core.contracts The data contracts tools speak — CapabilityResult, artifact/manifest models, common enums and IDs.
zeo_core.core Filesystem operations, path resolution, a typed error hierarchy, MIME detection, serialization, logging, an operation registry.
zeo_core.config YAML/env-var configuration loading and per-tool config models.
zeo_core.integrations Adapters for GitHub, Google Drive/Mail, LLM providers, Notion, Pandoc, and a database layer.
zeo_core.modules Plugin discovery and explicit-loading registry.
zeo_core.prompt Prompt template selection and enhancement utilities.
zeo_core.adapters An optional HTTP adapter (FastAPI-based) for exposing tools over a REST API.

See GET-STARTED.md for a fuller walkthrough of each area, including the configuration file format and error-handling patterns.

Quality bar

  • mypy --strict, clean across the whole source tree.
  • 2005 tests, 90%+ coverage, enforced as a hard CI floor (--cov-fail-under=90) — a pull request that drops coverage fails the gate.
  • CI runs the full suite on Python 3.10, 3.11, 3.12, and 3.13 on every push, not just whatever version the maintainer happens to have installed. That matrix has already caught and fixed three genuine cross-version stdlib behavior differences before they shipped — see CHANGELOG.md for specifics.
  • Production code is not allowed to detect that it's under test (a dedicated CI check fails the build if it finds "pytest" in sys.modules or similar) — if a test needs different behavior, it injects it, rather than the library quietly special-casing itself for its own test suite.

Project status

ZeoCore just published its first release. The API is typed and tested, but it hasn't yet had real-world usage outside the project that built it — some rough edges are likely, and the surface may still shift before a 1.0. Issues, questions, and API feedback are genuinely welcome; this is a good time to influence the shape of things.

Contributing

See CONTRIBUTING.md for dev environment setup, the verification gate, and how to submit a change. This project follows the Contributor Covenant.

Project links

PyPI · Source · Issues · Changelog · Get started · Contributing

License

MIT — see LICENSE.

About

A typed capability-authoring framework for Python — write tools that validate input, do their work, and return a structured result.

Resources

Code of conduct

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages