Skip to main content

Add your description here

Project description

Typus (typus-dsl)

Strict typing for loose models.

PyPI - Version PyPi - Python Version Github - Open Issues PyPi - Downloads (Monthly) Github - Commits

Typus is a Python library for Grammar Constrained Decoding (GCD).

Large Language Models (LLMs) are powerful but chaotic. They hallucinate invalid syntax, invent non-existent functions, and break JSON formatting. Typus solves this by generating strict Context-Free Grammars (CFGs) that constrain the LLM's token generation process.

Instead of writing complex EBNF strings by hand, you use a Pythonic Interface to define your constraints—from simple regex patterns to entire semantic domains.

🌟 Why Typus?

  • 🚫 No More Hallucinations: Force the LLM to output exactly what you need (valid JSON, SQL, Python, or CSV).
  • 🐍 Python-First: Define grammars using standard Python operators (|, +) and types (dataclasses, int, str).
  • 🧩 Universal: Define your grammar once and compile it for any target:
    • Llama.cpp / GGUF: Compiles to GBNF.
    • Validators: Compiles to Regex.
    • Parsers: Compiles to Lark (EBNF).
  • 🧠 Cognitive Control: Use Templates to force "Chain of Thought" reasoning before actions.

📦 Installation

pip install typus-dsl
# or with uv
uv add typus-dsl

🏗 The Stack: From Low-Level to High-Level

Typus offers three layers of abstraction depending on your needs.

1. The Grammar DSL (Low Level)

For when you need pixel-perfect control over every character.

Use standard Python operators to define rules.

from typus import Grammar

g = Grammar()
# Define primitives
g.digit = g.regex(r"[0-9]")
g.number = g.digit + g.maybe("." + g.some(g.digit))

# Define structure
g.coordinate = "(" + g.number + ", " + g.number + ")"
g.root = "Point: " + g.coordinate

2. Templates (Mid Level)

For when you want to structure the LLM's thought process.

Mix static prompts with dynamic grammar constraints using Python f-string syntax.

# Force the model to think before it answers
g.root = g.template(
    "Thought: {thought}\nAction: {action}",
    thought=g.some(g.regex(r"[^\n]+"), sep="\n"),
    action="SEARCH" | "CALCULATE"
)

3. The Domain Engine (High Level)

For when you want to project a "Problem Domain" into a target language.

Define your types and functions in Python, and Typus generates the grammar that enforces them in JSON, SQL, HTML, or Python.

# Define the domain once
@dataclass
class User: ...

# Generate a JSON Schema grammar
Json().build(Domain(User))

# Generate a SQL Query grammar
SQLQuery().build(Domain(User))

⚡ Use Cases & Examples

Use Case 1: Semantic Versioning (Regex Validation)

Ensure the model generates valid SemVer strings like v1.0.2 or v2.10.0-rc1.

from typus import Grammar

g = Grammar()
g.digits = g.regex(r"(0|[1-9][0-9]*)")
g.version = g.digits + "." + g.digits + "." + g.digits
g.tag = g.maybe("-" + g.regex(r"[0-9a-z-]+"))

g.root = "v" + g.version + g.tag

print(g.compile("gbnf"))

Use Case 2: Structured Reasoning (Templates)

Force an Agent to provide a reasoning trace before emitting a final JSON answer. This prevents "blind" answering.

from typus import Grammar

g = Grammar()
g.thought = g.some(g.regex(r"[^\n]+"), sep="\n")
g.json_blob = g.regex(r"\{.*\}") # Simplified JSON regex

# The template constrains the structure
g.root = g.template(
    "Reasoning:\n{steps}\n\nFinal Answer:\n{result}",
    steps=g.thought,
    result=g.json_blob
)

Use Case 3: Type-Safe JSON Generation (Domain + JSON)

Define your data schema using Pydantic or Dataclasses, and get a grammar that guarantees the output matches that schema.

from dataclasses import dataclass
from typing import List
from typus.languages import Json

@dataclass
class Product:
    id: int
    name: str
    tags: List[str]

# Generate a strict GBNF grammar for this schema
# The LLM cannot miss a comma, quote, or bracket.
g = Json().build(Product)
print(g.compile("gbnf"))

Use Case 4: Safe SQL Querying (Domain + SQL)

Expose a specific set of "Allowed Queries" to the LLM. The grammar ensures the model can only generate valid SELECT statements for your specific table columns, preventing SQL Injection and hallucinations.

from typus import Grammar, Domain
from typus.languages import SQLQuery

# 1. Define the Schema
@dataclass
class Users:
    name: str
    age: int

# 2. Define allowed access patterns
def get_users_by_name(name: str) -> Users: ...
def get_users_by_age(min_age: int) -> Users: ...

# 3. Build the Grammar
# The LLM can generate: "SELECT name, age FROM Users WHERE name = '...'"
# It CANNOT generate: "DROP TABLE Users"
g = SQLQuery().build(
    Domain(Users, entrypoints=[get_users_by_name, get_users_by_age])
)

🔧 Supported Backends

Typus is compiler-agnostic. You build the AST once, and export it to:

Backend Command Use Case
GBNF g.compile("gbnf") Llama.cpp, llama-python, local GGUF models.
Regex g.compile("regex", max_depth=3) Guidance, Outlines, Standard API validators. Supports bounded recursion.
Lark g.compile("lark") Python Parsing. Use Typus to parse the string the LLM just generated.
JSON Schema (Via Json language) OpenAI / Anthropic structured output APIs.

🛣 Roadmap

  • v0.1: Core DSL (Sequence, Choice, Regex), GBNF Compiler.
  • v0.2: Templates (g.template), Regex Compiler with unrolling.
  • v0.3: Lark Compiler (Round-trip parsing).
  • v0.4: The Domain Engine (typus.domain reflection).
  • v0.5: Language Strategies (Json, SQLQuery, Markdown, Python).

📄 License

MIT License. See LICENSE for details.

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

typus_dsl-0.3.2.tar.gz (28.4 kB view details)

Uploaded Source

Built Distribution

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

typus_dsl-0.3.2-py3-none-any.whl (10.2 kB view details)

Uploaded Python 3

File details

Details for the file typus_dsl-0.3.2.tar.gz.

File metadata

  • Download URL: typus_dsl-0.3.2.tar.gz
  • Upload date:
  • Size: 28.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.17 {"installer":{"name":"uv","version":"0.9.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for typus_dsl-0.3.2.tar.gz
Algorithm Hash digest
SHA256 e16ae13092d576534fd071003e16fec4d2933723e5a91eabad63c297304d075a
MD5 02dea061a5cebfbf7cfbfdee0cf29c70
BLAKE2b-256 71755da06060300c6ede80aee97034693c2216121f015e0cb92462ba0895ce20

See more details on using hashes here.

File details

Details for the file typus_dsl-0.3.2-py3-none-any.whl.

File metadata

  • Download URL: typus_dsl-0.3.2-py3-none-any.whl
  • Upload date:
  • Size: 10.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.17 {"installer":{"name":"uv","version":"0.9.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for typus_dsl-0.3.2-py3-none-any.whl
Algorithm Hash digest
SHA256 49266139527d9836ee19a2169c33a50e71cebbff44ebe5192356384164e24278
MD5 ba99492c9224a83f0f37302d7827b016
BLAKE2b-256 3be2ed19b17f1fc0358a1c936809a7fcb85198868861a2e5b28fd12f5afbf47b

See more details on using hashes here.

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