Typed markdown documents backed by Pydantic models
Project description
Archetype
Type safety for agents and agentic systems.
Archetype gives you the tools — backed by Pydantic models — to validate data at agent boundaries and guide agent behavior. In agentic systems, structured data moves between agents as LLM-generated markdown — patient assessments, contract analyses, audit findings, software designs. Because this data is generated and non-deterministic, producers and consumers diverge silently: a required section gets dropped, a heading gets renamed, a field comes back in the wrong format. The failure surfaces and nothing catches it, so the error propagates through the system silently.
Archetype makes the Pydantic model the contract at every agent boundary. At boundaries, it injects markdown format specifications into the agent and validates markdown files the agent generates. Inside agents, field descriptions from the model provide semantic context in instructions and prompts. One change to the Pydantic model propagates to every touchpoint of the corresponding markdown file.
Capabilities
| Capability | Description |
|---|---|
| Template generation | Embed markdown format specifications into any text an agent reads: instructions, prompts, skills, etc. |
| Markdown parsing and validation | Validate agent-generated markdown against the model — missing sections, misnamed fields, and type mismatches surface as errors you can prompt the agent to correct. |
| Annotation-driven layout | Declare how each field renders — as a heading, code block, list, or table — directly on the model. No separate template files or format strings. |
| Structural validation at class definition | Markdown modeling errors are caught at definition time, not mid-run. |
| Instance rendering | Render a populated model instance to well-formed markdown — no format strings, no templates to maintain. |
| Field descriptions as semantic context | Field descriptions flow from the model into agent instructions, giving agents the semantic context they need to reason correctly. |
Installation
pip install archetype-md
Quickstart
from typing import Annotated
from archetype.markdown import (
MarkdownDocument,
MarkdownHeader,
AsHeading,
AsBulletList,
TextTemplate,
render_template,
render_instance,
validate_markdown,
)
class Finding(MarkdownHeader):
title: Annotated[str, TextTemplate("Finding {ordinal} — {value}")]
description: Annotated[str, AsHeading()]
recommendations: Annotated[list[str], AsBulletList()]
class Review(MarkdownDocument):
title: Annotated[str, TextTemplate("{value}")]
summary: Annotated[str, AsHeading()]
findings: list[Finding]
# Generate a blank template (e.g. to hand to an LLM)
template = render_template(Review)
# Parse markdown back into a validated model instance
review = validate_markdown(produced_markdown, Review)
# Render a populated instance back to markdown
output = render_instance(review)
Modules
archetype.markdown
Typed markdown documents backed by Pydantic models.
| Symbol | Purpose |
|---|---|
MarkdownDocument |
Base class for top-level documents (adds optional YAML frontmatter) |
MarkdownHeader |
Base class for heading-shaped sub-documents |
render_template(cls) |
Emit an annotated skeleton with placeholder comments |
render_instance(obj) |
Render a populated instance to markdown |
validate_markdown(text, cls) |
Parse markdown and return a validated instance |
template_fields(cls) |
Iterate FieldInfo entries for use in Jinja templates |
extract_subtree(text, heading) |
Extract a named section from markdown text |
Field annotations (attached via Annotated[T, ...]):
| Annotation | Field type | Renders as |
|---|---|---|
AsHeading() |
str |
Markdown heading section |
AsCodeBlock(language=...) |
str |
Fenced code block |
AsBulletList() |
list[str] |
Bullet list |
AsNumberedList() |
list[str] |
Numbered list |
AsTable() |
list[BaseModel] |
Markdown table |
TextTemplate("{value}") |
str (title field) |
Formatted heading text |
archetype.templating
Jinja-based template resolution with markdown-aware globals.
from archetype.templating import resolve
instructions = resolve(
template_text,
feature=state.feature_definition,
)
resolve runs with strict undefined semantics — any missing variable raises jinja2.UndefinedError immediately. Two globals are available inside every template: template_fields(ModelClass) and render_template(ModelClass).
Design
The model is the contract. Annotations on fields drive all rendering and parsing behaviour. No separate config, no code generation — change the model, everything updates.
Strict by default. validate_markdown raises MarkdownValidationError with field-localized messages on any mismatch. resolve raises on undefined template paths. Silent partial results are not produced.
Development
pdm install
pdm run test
pdm run lint
pdm run typecheck
Project details
Release history Release notifications | RSS feed
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 archetype_md-0.1.1.tar.gz.
File metadata
- Download URL: archetype_md-0.1.1.tar.gz
- Upload date:
- Size: 41.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8e4b432f421f5a619fc493ff4cd97b5299ea3b0c80a1ed714c9b0c90e7a8ae0c
|
|
| MD5 |
d60b6dc917be66a3be40d1fee3102218
|
|
| BLAKE2b-256 |
144bbfd3e796a2a8337692909fa3ddb4fc4f517b0309fb8641ccad23cd5f1660
|
Provenance
The following attestation bundles were made for archetype_md-0.1.1.tar.gz:
Publisher:
publish.yml on monkeynaut-ai/archetype
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
archetype_md-0.1.1.tar.gz -
Subject digest:
8e4b432f421f5a619fc493ff4cd97b5299ea3b0c80a1ed714c9b0c90e7a8ae0c - Sigstore transparency entry: 1741893302
- Sigstore integration time:
-
Permalink:
monkeynaut-ai/archetype@8d7c4e593bf6d29a8f09207b90fe6ecd11b42d5a -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/monkeynaut-ai
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@8d7c4e593bf6d29a8f09207b90fe6ecd11b42d5a -
Trigger Event:
push
-
Statement type:
File details
Details for the file archetype_md-0.1.1-py3-none-any.whl.
File metadata
- Download URL: archetype_md-0.1.1-py3-none-any.whl
- Upload date:
- Size: 33.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
edcd979b37be4fcae478b45b9a0dec69b8a566ed72852c08b46967005db5bb23
|
|
| MD5 |
8bab047ccb3c0347dc7da94f6ff54c5e
|
|
| BLAKE2b-256 |
7f71f874d8f042ba0f906e679dc005c8be433f18a7cbbe7cea01a5fc9b09fa34
|
Provenance
The following attestation bundles were made for archetype_md-0.1.1-py3-none-any.whl:
Publisher:
publish.yml on monkeynaut-ai/archetype
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
archetype_md-0.1.1-py3-none-any.whl -
Subject digest:
edcd979b37be4fcae478b45b9a0dec69b8a566ed72852c08b46967005db5bb23 - Sigstore transparency entry: 1741893331
- Sigstore integration time:
-
Permalink:
monkeynaut-ai/archetype@8d7c4e593bf6d29a8f09207b90fe6ecd11b42d5a -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/monkeynaut-ai
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@8d7c4e593bf6d29a8f09207b90fe6ecd11b42d5a -
Trigger Event:
push
-
Statement type: