Skip to main content

wardhook-core

CI PyPI Python License: MIT

A LangGraph agent runtime with tool calling, retrieval with real source citations, and a one-command FastAPI server.

Part of Wardhook. Works completely on its own — it never imports the other Wardhook packages.

Install

pip install wardhook-core

# with a model provider
pip install "wardhook-core[anthropic]"   # or [openai], [all]

Usage

from wardhook.core import AgentGraph, InMemoryVectorStore, Retriever, chunk_text

store = InMemoryVectorStore()
store.add(chunk_text(open("policy.md").read(), "policy.md"))

agent = AgentGraph(model="claude-opus-5", retriever=Retriever(store))
result = agent.invoke("What excess applies to storm damage?")

print(result["output"])
print(result["citations"][0]["source"])  # -> 'policy.md'

What you get

Provider-agnostic. AgentGraph accepts any object with .invoke(). Pass a ChatAnthropic, a ChatOpenAI, or a test double. Nothing in the base install depends on a provider SDK, so you are never locked in.

agent = AgentGraph(model=ChatOpenAI(model="gpt-4o"))  # instance
agent = AgentGraph(model="anthropic:claude-opus-5")  # name
agent = AgentGraph(model=my_fake)  # test double, no API key

Tools from plain functions. The docstring becomes the description the model reads, so it is required rather than optional.

def lookup_claim(claim_id: str) -> str:
    """Look up the current status of a claim by its identifier."""
    return db.claims.status(claim_id)


agent = AgentGraph(model="claude-opus-5", tools=[lookup_claim])

Citations are structural, not parsed. Retrieval returns records carrying source, chunk position and score. You render or verify them directly; the model cannot invent a citation for a document it was never shown.

for c in result["citations"]:
    print(f"{c['source']} chunk {c['chunk_index']} (score {c['score']:.3f})")

RAG that runs with no API key. Document loading (PDF, Markdown, text), recursive chunking with overlap, and a NumPy vector store. The default embeddings are a classical hashing vectoriser — no model weights, no network — so the pipeline works the moment you install it. Swap in real embeddings for production; the interface is identical.

store = InMemoryVectorStore(embeddings=OpenAIEmbeddings())
store.save("index")  # index.npz + index.json
store = InMemoryVectorStore.load("index", embeddings=OpenAIEmbeddings())

Serve it in one command.

wardhook serve myapp.agents:support_agent --port 8000

Exposes POST /invoke, GET /health, GET /info, and OpenAPI docs at /docs. A production Dockerfile ships with the package.

Composing with the rest of Wardhook

AgentGraph takes guardrails=[...] and telemetry=True, but core does not depend on the packages that provide them. Both attach through structural contracts in wardhook.core.protocols, so any object of the right shape works — from Wardhook, from your codebase, or from somewhere else entirely.

from wardhook.core import AgentGraph
from wardhook.guardrails import PIIRedactor, RoleBasedToolPolicy  # optional install

agent = AgentGraph(
    model="claude-opus-5",
    tools=[lookup_claim],
    guardrails=[PIIRedactor(pack="insurance"), RoleBasedToolPolicy(...)],
    telemetry=True,  # requires wardhook-observability
)

Writing your own takes no dependency at all:

class NoInternalCodenames:
    name = "no-codenames"

    def on_output(self, text, context):
        if "PROJECT_HALCYON" in text:
            return {
                "action": "redact",
                "text": text.replace("PROJECT_HALCYON", "[internal]"),
                "reason": "internal codename",
                "rule": "codename-list",
            }
        return {"action": "allow"}


agent = AgentGraph(model="claude-opus-5", guardrails=[NoInternalCodenames()])

The full contract is three optional hooks — on_input, on_output, on_tool_call — each returning something with an action of "allow", "redact" or "block". Implement only the ones you need.

Notes

  • Guardrails fail closed. If a guardrail raises, the run is blocked and the failure is recorded. Set guardrail_error_policy="allow" or "raise" to change that.
  • Denied tool calls never execute. The model is told it was denied through a normal tool result, so it can recover instead of failing the run.
  • Tool errors go back to the model, not to your caller — an agent that can see a failure can often work around it.

Links

Download files

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

Source Distribution

wardhook_core-0.2.0.tar.gz (89.0 kB view details)

Uploaded Source

Built Distribution

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

wardhook_core-0.2.0-py3-none-any.whl (70.4 kB view details)

Uploaded Python 3

File details

Details for the file wardhook_core-0.2.0.tar.gz.

File metadata

  • Download URL: wardhook_core-0.2.0.tar.gz
  • Upload date:
  • Size: 89.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for wardhook_core-0.2.0.tar.gz
Algorithm Hash digest
SHA256 c5156fe51a934a9199ae03533e6c0790dd64b464bb306451b1f24d55057c1900
MD5 55a23048770c92627364a2c7868bd081
BLAKE2b-256 17acecabac98ba209355f3af8043c5623b4b1637a01050ff0f0ffe43f5da59e9

See more details on using hashes here.

Provenance

The following attestation bundles were made for wardhook_core-0.2.0.tar.gz:

Publisher: release.yml on justicebajaj161/wardhook

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

File details

Details for the file wardhook_core-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: wardhook_core-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 70.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for wardhook_core-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 caf94c43123609806118eb9b4aa7b63f96e4fb83a510720c9cc0bc1411c08fdf
MD5 7a1a0ff21f98487d3315fff9adeed9f7
BLAKE2b-256 7fefa65b8b815c69680e58bb0d340bdc201a49d005bb086075e3fdd80d8e4c98

See more details on using hashes here.

Provenance

The following attestation bundles were made for wardhook_core-0.2.0-py3-none-any.whl:

Publisher: release.yml on justicebajaj161/wardhook

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

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 files

0.1.1

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page