pydantic-ai-okf
Open Knowledge Format (OKF) plugin for Pydantic AI.
OKF represents knowledge as a bundle: a directory tree of markdown documents ("concepts") with YAML frontmatter, cross-linked with ordinary markdown links. This package lets Pydantic AI agents consume OKF bundles through progressive disclosure - an overview of each bundle is injected into the system prompt, and the agent browses, searches, and reads individual concepts on demand through tools.
OKFToolset- a Pydantic AI toolset providinglist_concepts,read_concept, andsearch_concepts, with a per-bundle overview injected into the system prompt.OKFCapability- the same integration via the Pydantic AIcapabilities=[...]API, with deferred loading for declarative agent specs.Bundle- a standalone API for loading, traversing, searching, and conformance-checking OKF bundles (no agent or LLM required).- Permissive by design - per OKF §9, malformed frontmatter, unknown types,
and broken links never fail a load; problems are reported by
Bundle.validate()instead. - Git bundles - load bundles distributed as git repositories via the
optional
gitextra. - Fully typed, high test coverage, no LLM calls in tests.
Installation
pip install pydantic-ai-okf
pip install "pydantic-ai-okf[git]" # to load bundles from git repositories
# or: uv add pydantic-ai-okf
Quick start
Give an agent a bundle (toolset)
from pydantic_ai import Agent
from pydantic_ai_okf import OKFToolset
agent = Agent(
'openai:gpt-5.6',
toolsets=[OKFToolset(bundles=['./knowledge'])],
)
result = agent.run_sync('Which table should I join to get customer revenue?')
print(result.output)
That is the whole integration. On every request the agent receives a short system-prompt block explaining OKF plus each bundle's overview, and it is given three tools to explore on demand (see How agents consume a bundle).
Give an agent a bundle (capability)
from pydantic_ai import Agent
from pydantic_ai_okf import OKFCapability
agent = Agent('openai:gpt-5.6', capabilities=[OKFCapability(bundles=['./knowledge'])])
Set defer_loading=True (with a stable id) to hide the knowledge tools and
instructions behind the agent's load_capability tool until the model loads
them explicitly - useful when an agent has many capabilities and you don't want
every bundle overview in the prompt at once:
agent = Agent(
'openai:gpt-5.6',
capabilities=[OKFCapability(id='okf', bundles=['./knowledge'], defer_loading=True)],
)
Multiple bundles
Pass several; names must be unique (they default to the directory name). Use
Bundle(path, name=...) to disambiguate, and the model can target one with the
tools' optional bundle= argument.
from pydantic_ai_okf import Bundle, OKFToolset
toolset = OKFToolset(bundles=[
Bundle('./rfc9396', name='rfc9396'),
Bundle('./internal-apis', name='apis'),
])
Use a bundle without an agent
Everything the tools do is available directly:
from pydantic_ai_okf import Bundle
bundle = Bundle('./knowledge')
bundle.okf_version # '0.1' (from the bundle-root index.md, if present)
bundle.concept_ids # ['datasets/sales', 'tables/orders', ...]
concept = bundle.get('tables/orders') # also accepts '/tables/orders.md'
concept.type # 'BigQuery Table' (the one required field)
concept.description # one-line summary
concept.tags # ['sales', 'orders']
concept.extra # {producer-defined frontmatter keys}
concept.body # markdown after the frontmatter
for hit in bundle.search('revenue', tags=['sales']):
print(hit.score, hit.concept.concept_id)
bundle.validate() # [] for a conformant bundle, else ConformanceIssue list
Load a bundle from git
Requires the git extra.
from pydantic_ai_okf import Bundle
bundle = Bundle.from_git(
'https://github.com/acme/knowledge.git',
ref='v1.2.0', # optional branch, tag, or commit
subdirectory='okf', # optional bundle root within the repository
)
How agents consume a bundle
When you register an OKFToolset / OKFCapability, two things happen on each
run:
-
Instructions are injected. A system-prompt block explains what OKF is (concepts, IDs, cross-links) and how to explore, then lists each bundle's
name,okf_version,concept_count, and overview. The overview is the bundle-rootindex.mdbody, or a synthesized listing if there is none - so a good rootindex.mdis the single best thing an author can do to help agents navigate a bundle. -
Three tools are registered:
Tool What it does list_concepts(directory, bundle)List concepts and subdirectories in a directory. read_concept(concept_id, bundle)Read a full concept document (frontmatter + body). search_concepts(query, tags, bundle)Keyword/tag search over titles, descriptions, tags, types, IDs, and bodies. The
bundleargument is optional when a single bundle is configured. Unknown IDs, directories, or bundle names raiseModelRetrywith close-match suggestions so the model can self-correct (seemax_retries).
The intended flow is progressive disclosure: search_concepts /
list_concepts to find candidates, then read_concept only what's needed.
Customizing the injected instructions
Not every model knows what OKF is, and you may want to add domain framing. There are three levels of control.
1. Replace the template (instruction_template, on both OKFToolset and
OKFCapability). Your template must contain the {bundles_list}
placeholder, which is where the per-bundle overview is injected. Escape any
literal braces as {{/}}.
OKFToolset(
bundles=['./rfc9396'],
instruction_template=(
"You are an OAuth compliance assistant. Prefer normative text over "
"examples and preserve MUST/SHOULD/MAY exactly.\n\n"
"{bundles_list}\n\n"
"Cite the concept IDs and RFC sections you used."
),
)
2. Layer on agent-level instructions. Pydantic AI combines the agent's own
instructions with the toolset's, so you can keep the OKF block and just add
guidance:
Agent(
'openai:gpt-5.6',
toolsets=[OKFToolset(bundles=['./knowledge'])],
instructions='You are a data catalog expert. Answer only from the bundle.',
)
3. Full control - subclass and override build_instructions (an async
method) to change how each bundle block is rendered, drop the overview, or add
navigation hints.
Authoring / bundle structure (brief)
A bundle is just a directory of markdown files; the only hard requirement (OKF
§9) is that every non-reserved .md file has a YAML frontmatter block with a
non-empty type:
---
type: BigQuery Table # required
title: Customer Orders # recommended
description: One row per order.
tags: [sales, orders]
resource: https://… # optional canonical URI
# any additional producer-defined keys are preserved on Concept.extra
---
# Schema
… body markdown, cross-linking other concepts as [orders](/tables/orders.md) …
index.mdandlog.mdare reserved (directory listing and change log).index.mdfiles carry no frontmatter - except the bundle-rootindex.md, which may declareokf_version: "0.1".- Loading is permissive: nothing above is enforced at load time. Call
Bundle.validate()to get the list of conformance issues.
Reference
OKFToolset / OKFCapability options
| Option | Default | Description |
|---|---|---|
bundles |
required | Local directories (str/Path) and/or pre-loaded Bundle instances; names must be unique. |
instruction_template |
built-in | Custom system-prompt template; must contain {bundles_list}. |
exclude_tools |
None |
Tool names to skip registering (list_concepts, read_concept, search_concepts). |
auto_reload |
False |
Re-scan bundle directories before each agent run. |
max_retries |
3 |
Retry budget for ModelRetry-raising tool calls, so a model can act on close-match suggestions before failing. |
id |
None |
Stable identifier (required when defer_loading=True). |
defer_loading |
False |
(capability only) Hide tools/instructions behind load_capability. |
Bundle API
| Member | Description |
|---|---|
Bundle(path, name=...) |
Load a bundle from a local directory. |
Bundle.from_git(url, ref=…, subdirectory=…) |
Clone a git repo and load it as a bundle (git extra). |
get(concept_id) |
Look up a concept; tolerates /tables/orders.md link spellings. Returns None if absent. |
concepts / concept_ids |
All concepts / IDs, ordered by ID. |
directories() / list_directory(dir) |
Traverse the hierarchy. |
index(dir) / log(dir) |
Reserved index.md / log.md content (OKF §6, §7). |
overview() / synthesize_index(dir) |
Progressive-disclosure listings (what the toolset injects). |
search(query, tags=…, limit=…) |
Ranked keyword search returning SearchResults. |
validate() |
OKF §9 conformance issues found during the scan (empty if conformant). |
reload() |
Re-scan the directory from disk. |
Concept fields
type (required), title, description, resource, tags, timestamp,
extra (producer-defined keys), body, text, concept_id, path,
has_frontmatter, and display_title (falls back to the filename).
Development
make install # sync the locked environment
make check # ruff + mypy
make test # unit tests
make coverage # tests with the coverage gate
make build # build sdist + wheel
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 pydantic_ai_okf-0.1.0.tar.gz.
File metadata
- Download URL: pydantic_ai_okf-0.1.0.tar.gz
- Upload date:
- Size: 17.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7b62bb216e2f219fe83fa4e9e104cc415dadd29d82c9a058491e02ca2f230c38
|
|
| MD5 |
a6f8ec9c404ae27c33c94fbdc46f0ee3
|
|
| BLAKE2b-256 |
4a674b473e1189aa11c967d5fa1f64b6317666dab9969ee766a3aafe689ab0c5
|
Provenance
The following attestation bundles were made for pydantic_ai_okf-0.1.0.tar.gz:
Publisher:
publish.yaml on sbo-inc/pydantic-ai-okf
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pydantic_ai_okf-0.1.0.tar.gz -
Subject digest:
7b62bb216e2f219fe83fa4e9e104cc415dadd29d82c9a058491e02ca2f230c38 - Sigstore transparency entry: 2204699381
- Sigstore integration time:
-
Permalink:
sbo-inc/pydantic-ai-okf@da0d154fe45b0c0117988801231b7d5c71122a54 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/sbo-inc
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yaml@da0d154fe45b0c0117988801231b7d5c71122a54 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pydantic_ai_okf-0.1.0-py3-none-any.whl.
File metadata
- Download URL: pydantic_ai_okf-0.1.0-py3-none-any.whl
- Upload date:
- Size: 21.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fa13cdd8b97d4f2a4eb4fcc2f0a9c211652c401759bb4a8c6cf87fb94341bc18
|
|
| MD5 |
4c42abf9e680c21b92ab6207348810d5
|
|
| BLAKE2b-256 |
7e4baf82dc730bf60b412bb68a267b884ceadc4a560fb1bed7f06fdc1bd64987
|
Provenance
The following attestation bundles were made for pydantic_ai_okf-0.1.0-py3-none-any.whl:
Publisher:
publish.yaml on sbo-inc/pydantic-ai-okf
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pydantic_ai_okf-0.1.0-py3-none-any.whl -
Subject digest:
fa13cdd8b97d4f2a4eb4fcc2f0a9c211652c401759bb4a8c6cf87fb94341bc18 - Sigstore transparency entry: 2204699382
- Sigstore integration time:
-
Permalink:
sbo-inc/pydantic-ai-okf@da0d154fe45b0c0117988801231b7d5c71122a54 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/sbo-inc
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yaml@da0d154fe45b0c0117988801231b7d5c71122a54 -
Trigger Event:
push
-
Statement type: