### Install promptree Source: https://github.com/tkaluza/promptree/blob/main/README.md Install the promptree package using pip. Optional extras like 'watch' or 'pydantic-ai' can be installed with the package. ```bash pip install promptree ``` ```bash pip install promptree[watch] ``` ```bash pip install promptree[pydantic-ai] ``` -------------------------------- ### Pre-commit Hook Configuration Source: https://github.com/tkaluza/promptree/blob/main/README.md Example configuration for wiring up the promptree-check hook in a .pre-commit-hooks.yaml file. ```yaml - repo: https://github.com/your-org/promptree rev: v0.1.0 hooks: - id: promptree-check files: ^prompts/ ``` -------------------------------- ### Raw OpenAI Client Integration with Promptree Source: https://github.com/tkaluza/promptree/blob/main/README.md Example of using promptree with the raw OpenAI Python client to create chat completions, accessing prompts via the generated tree. ```python from openai import OpenAI from promptree import Promptree client = OpenAI() prompts = Promptree("./prompts") client.chat.completions.create( model="gpt-4o", messages=[ {"role": "system", "content": prompts.system(name="Claude")}, {"role": "user", "content": prompts.user.greeting(name="Tim")}, ], ) ``` -------------------------------- ### pydantic-ai Agent with Promptree Source: https://github.com/tkaluza/promptree/blob/main/README.md Example of integrating promptree with pydantic-ai agents. Demonstrates static and dynamic instruction rendering using generated prompt tree. ```python from dataclasses import dataclass from pydantic_ai import Agent, RunContext from prompts import tree as prompts @dataclass class MyDeps: user_name: str language: str agent = Agent("openai:gpt-4o", deps_type=MyDeps) # Static: render once at agent creation agent_static = Agent( "openai:gpt-4o", instructions=prompts.system(name="Claude"), ) # Dynamic: re-evaluated every run with access to ctx.deps @agent.instructions def dynamic_instructions(ctx: RunContext[MyDeps]) -> str: return prompts.system( name=ctx.deps.user_name, language=ctx.deps.language, ) result = agent.run_sync( prompts.user.greeting(name="Tim"), deps=MyDeps(user_name="Tim", language="en"), ) print(result.output) ``` -------------------------------- ### LangChain Integration with Promptree Source: https://github.com/tkaluza/promptree/blob/main/README.md Example of using promptree with LangChain to construct message lists, utilizing the generated prompt tree for content. ```python from langchain_core.messages import HumanMessage, SystemMessage from promptree import Promptree prompts = Promptree("./prompts") messages = [ SystemMessage(content=prompts.system(name="Claude")), HumanMessage(content=prompts.user.greeting(name="Tim")), ] ``` -------------------------------- ### GitHub Actions CI for Promptree Stubs Source: https://context7.com/tkaluza/promptree/llms.txt Example of how to add a GitHub Actions step to enforce promptree stub consistency in a CI pipeline. ```yaml - name: Check promptree stubs run: promptree check ./prompts ``` -------------------------------- ### Lazy Child Resolution and Ambiguity Source: https://context7.com/tkaluza/promptree/llms.txt TemplateNode resolves children lazily and caches them. Accessing ambiguous names (e.g., `greeting.md` and `greeting.txt`) raises `AmbiguousTemplateError`. Private attributes starting with `_` are ignored. ```python from promptree import Promptree, AmbiguousTemplateError prompts = Promptree("./prompts") # Accessing a directory returns a TemplateNode user_node = prompts.user print(repr(user_node)) # → TemplateNode(user/, children=['farewell', 'greeting']) # Tab-completion works in interactive shells — dir() returns valid names print(dir(prompts.user)) # → ['farewell', 'greeting'] # Ambiguous files (same stem, different extensions) raise at access time # Given: prompts/greeting.md AND prompts/greeting.txt try: _ = prompts.greeting except AmbiguousTemplateError as e: print(e) # → 'greeting' matches multiple files: ['greeting.md', 'greeting.txt']. # Rename files to remove ambiguity. # Private names (starting with _) are never resolved as templates try: _ = prompts._private except AttributeError: print("Private attributes are not resolved from the filesystem") ``` -------------------------------- ### Basic Promptree Usage Source: https://context7.com/tkaluza/promptree/llms.txt Demonstrates initializing Promptree with a directory and rendering a child template. ```python features = Promptree("./jinja_prompts") print(features.child(title="Intro", body="Hello world")) ``` -------------------------------- ### CLI - `promptree generate` Source: https://context7.com/tkaluza/promptree/llms.txt The `promptree generate` command-line interface is used to create `__init__.py` and `__init__.pyi` files within a specified prompt directory. It can optionally watch for file changes and regenerate stubs automatically. Various options allow customization of extensions, stub source line embedding, and link modes. ```APIDOC ## CLI — `promptree generate` Generates `__init__.py` and `__init__.pyi` inside the prompt directory. Skips writing `__init__.py` if the existing file does not start with the promptree-generated header (hand-written init files are preserved). Optionally watches for filesystem changes and regenerates automatically. ```bash # Basic generation promptree generate ./prompts # → wrote ./prompts/__init__.py # → wrote ./prompts/__init__.pyi # Skip stub generation (runtime module only) promptree generate ./prompts --init-only # Override recognised extensions promptree generate ./prompts --extensions .md .txt .jinja # Embed up to 5 template lines in stubs instead of the default 10 promptree generate ./prompts --stub-source-lines 5 # Use absolute file:// links instead of relative paths promptree generate ./prompts --stub-link-mode file-uri # Watch mode — regenerates whenever templates change (requires promptree[watch]) promptree generate ./prompts --watch # Run as a module python -m promptree generate ./prompts # Show version promptree --version ``` ``` -------------------------------- ### CLI: Generate Stubs Source: https://context7.com/tkaluza/promptree/llms.txt Generates __init__.py and __init__.pyi files in the specified prompt directory. Use options to customize extensions, source line embedding, link modes, or enable watch mode. ```bash # Basic generation promptree generate ./prompts # Skip stub generation (runtime module only) promptree generate ./prompts --init-only # Override recognised extensions promptree generate ./prompts --extensions .md .txt .jinja # Embed up to 5 template lines in stubs instead of the default 10 promptree generate ./prompts --stub-source-lines 5 # Use absolute file:// links instead of relative paths promptree generate ./prompts --stub-link-mode file-uri # Watch mode — regenerates whenever templates change (requires promptree[watch]) promptree generate ./prompts --watch # Run as a module python -m promptree generate ./prompts # Show version promptree --version ``` -------------------------------- ### Programmatic Stub Generation Source: https://context7.com/tkaluza/promptree/llms.txt Generates __init__.py and __init__.pyi files from a prompt directory. Use 'relative' mode for committed files or 'file-uri' for absolute local links. ```python from pathlib import Path from promptree._generator import generate_stubs prompt_dir = Path("./prompts") # Generate with relative source links (default — suitable for committed files) init_py, init_pyi = generate_stubs( prompt_dir, project_root=Path.cwd(), # base for relative stub source links stub_source_lines=10, # embed first 10 non-empty template lines stub_link_mode="relative", # or "file-uri" for absolute local links ) print(init_py) print(init_pyi) # Write to disk manually if needed (prompt_dir / "__init__.py").write_text(init_py, encoding="utf-8") (prompt_dir / "__init__.pyi").write_text(init_pyi, encoding="utf-8") # file-uri mode — absolute links, useful for local VS Code "Go to Definition" _, pyi_uri = generate_stubs(prompt_dir, stub_link_mode="file-uri") ``` -------------------------------- ### Raw OpenAI Client with Promptree Source: https://context7.com/tkaluza/promptree/llms.txt Shows how to use promptree-generated prompts directly with the OpenAI client's chat completions. ```python from openai import OpenAI from prompts import tree as prompts client = OpenAI() client.chat.completions.create( model="gpt-4o", messages=[ {"role": "system", "content": prompts.system(name="Claude")}, {"role": "user", "content": prompts.user.greeting(name="Tim")}, ], ) ``` -------------------------------- ### Promptree(path, *, extensions, globals) Source: https://context7.com/tkaluza/promptree/llms.txt Initializes the root prompt tree object, loading templates from the specified directory. It supports custom file extensions and global variables for templates. ```APIDOC ## Promptree(path, *, extensions, globals) — Root prompt tree Creates the root tree object backed by a Jinja `FileSystemLoader`. All templates in the directory become accessible as callable attributes. Sub-directories become nested `TemplateNode` attributes. Raises `NotADirectoryError` when the path does not exist. ### Parameters - **path** (str) - Required - The filesystem path to the directory containing prompt templates. - **extensions** (tuple[str], optional) - The set of recognized file extensions for templates. Defaults to (".jinja", ".j2", ".md", ".txt", ".html", ".xml"). - **globals** (dict, optional) - A dictionary of global variables to be available in all templates. ### Request Example ```python from promptree import Promptree prompts = Promptree("./prompts") prompts_with_globals = Promptree("./prompts", globals={"app_name": "MyApp"}) prompts_custom = Promptree("./prompts", extensions=(".md", ".txt")) ``` ### Response Returns a `Promptree` instance representing the root of the prompt directory. ### Error Handling - `NotADirectoryError`: If the provided `path` does not exist or is not a directory. - `jinja2.UndefinedError`: Raised at render time if a required template variable is missing. - `TemplateNotFoundError`: Raised if an attribute access does not correspond to a template or directory. ``` -------------------------------- ### Generate Stubs with File URI Links Source: https://github.com/tkaluza/promptree/blob/main/README.md Generate prompt packages with stub files linked using file URIs for better local VS Code navigation. ```bash promptree generate ./prompts --stub-link-mode file-uri ``` -------------------------------- ### Basic Promptree Usage Source: https://github.com/tkaluza/promptree/blob/main/README.md Instantiate Promptree with a directory path to access prompts using dot notation. This usage is runtime-dynamic. ```python from promptree import Promptree prompts = Promptree("./prompts") print(prompts.system(name="Claude")) print(prompts.user.greeting(name="Tim")) print(prompts.user.farewell(name="Tim")) ``` -------------------------------- ### LangChain Integration with Promptree Source: https://context7.com/tkaluza/promptree/llms.txt Demonstrates how to use promptree-generated prompts with LangChain's HumanMessage and SystemMessage. ```python from langchain_core.messages import HumanMessage, SystemMessage from prompts import tree as prompts messages = [ SystemMessage(content=prompts.system(name="Claude")), HumanMessage(content=prompts.user.greeting(name="Tim")), ] ``` -------------------------------- ### Pre-commit Configuration for Promptree Source: https://context7.com/tkaluza/promptree/llms.txt Integrates the promptree-check hook into a .pre-commit-config.yaml file to enforce stub freshness. ```yaml repos: - repo: https://github.com/your-org/promptree rev: v0.2.0 hooks: - id: promptree-check files: ^prompts/ ``` -------------------------------- ### Promptree CLI Commands Source: https://github.com/tkaluza/promptree/blob/main/README.md Common promptree CLI commands for generating packages, checking stub consistency, and displaying the version. The CLI can also be run as a module. ```bash promptree generate ./prompts promptree check ./prompts promptree --version ``` ```bash python -m promptree generate ./prompts ``` -------------------------------- ### Basic Promptree Usage Source: https://context7.com/tkaluza/promptree/llms.txt Instantiate Promptree to access templates via dot-notation. Subdirectories become nested attributes. Missing variables raise `UndefinedError` at render time. ```python from promptree import Promptree # Basic usage — dot-notation access to templates prompts = Promptree("./prompts") # prompts/system.md → "System prompt for {{ name }}." # prompts/user/greeting.md → "Hello {{ name }}!" # prompts/user/farewell.txt → "Goodbye {{ name }}" print(prompts.system(name="Claude")) # → System prompt for Claude. print(prompts.user.greeting(name="Tim")) # → Hello Tim! print(prompts.user.farewell(name="Tim")) # → Goodbye Tim. # Pass Jinja globals so every template can access shared values without # having to pass them on every call. prompts_with_globals = Promptree("./prompts", globals={"app_name": "MyApp"}) # Templates can now reference {{ app_name }} without it being passed per-call. # Override the set of recognised file extensions (defaults shown below) # (".jinja", ".j2", ".md", ".txt", ".html", ".xml") prompts_custom = Promptree("./prompts", extensions=(".md", ".txt")) # Missing variable → jinja2.UndefinedError at render time (StrictUndefined) try: prompts.system() # 'name' not supplied except Exception as e: print(type(e).__name__, e) # → UndefinedError 'name' is undefined # Non-existent attribute → TemplateNotFoundError from promptree import TemplateNotFoundError try: prompts.nonexistent except TemplateNotFoundError as e: print(e) # → No template or directory 'nonexistent' in /path/to/prompts ``` -------------------------------- ### CLI - `promptree check` Source: https://context7.com/tkaluza/promptree/llms.txt The `promptree check` command is designed for integration into CI/CD pipelines and pre-commit hooks. It regenerates stubs in memory and compares them against the on-disk files, exiting with a non-zero status code if any discrepancies are found. It respects the same options as the `generate` command for consistency. ```APIDOC ## CLI — `promptree check` Regenerates stubs in memory and exits non-zero if the on-disk files are stale. Designed for pre-commit hooks and CI pipelines. Ignores hand-written `__init__.py` files (those not starting with the auto-generated header). ```bash # Check stubs are up to date promptree check ./prompts # → exits 0 if up to date, 1 with a unified diff if stale # Match the same options used during generation promptree check ./prompts --stub-source-lines 5 --stub-link-mode file-uri ``` ```yaml # .pre-commit-config.yaml — wire up the bundled hook repos: - repo: https://github.com/your-org/promptree rev: v0.2.0 hooks: - id: promptree-check files: ^prompts/ ``` ```yaml # GitHub Actions — CI enforcement - name: Check promptree stubs run: promptree check ./prompts ``` ``` -------------------------------- ### Generate Prompt Package Source: https://github.com/tkaluza/promptree/blob/main/README.md Use the promptree CLI to generate an importable Python package with type stubs from your prompt directory. This enables IDE autocomplete. ```bash promptree generate ./prompts ``` -------------------------------- ### Promptree Exception Handling Source: https://context7.com/tkaluza/promptree/llms.txt Illustrates how to catch specific promptree errors like TemplateNotFoundError and AmbiguousTemplateError, as well as the generic PromptreeError. ```python from promptree import ( PromptreeError, AmbiguousTemplateError, TemplateNotFoundError, ) from promptree import Promptree prompts = Promptree("./prompts") # Catch any promptree error generically try: result = prompts.missing_template(name="Alice") except PromptreeError as e: print(f"Promptree error: {e}") # Catch specific errors try: _ = prompts.nonexistent except TemplateNotFoundError as e: print(f"Not found: {e}") try: # Triggered when prompts/ contains both greeting.md and greeting.txt _ = prompts.greeting except AmbiguousTemplateError as e: print(f"Ambiguous: {e}") ``` -------------------------------- ### Import and Use Generated Prompt Package Source: https://github.com/tkaluza/promptree/blob/main/README.md Import the generated 'tree' object from the prompt package for type-safe access to prompts, providing IDE autocomplete. ```python from prompts import tree print(tree.system(name="Claude")) print(tree.user.greeting(name="Tim")) ``` -------------------------------- ### Programmatic Stub Generation Source: https://context7.com/tkaluza/promptree/llms.txt The `generate_stubs` function provides a programmatic API to scan prompt directories, resolve template variables, and return the content for `__init__.py` and `__init__.pyi` files. This is useful when you need the generated stub content without writing directly to disk. ```APIDOC ## `generate_stubs(prompt_dir, extensions, project_root, stub_source_lines, stub_link_mode) → tuple[str, str]` Programmatic stub generation API. Scans the prompt directory, resolves all template variables (following `extends` / `include` chains), and returns the content of `__init__.py` and `__init__.pyi` as strings. The CLI wraps this function; call it directly when you need the output without writing to disk. ```python from pathlib import Path from promptree._generator import generate_stubs prompt_dir = Path("./prompts") # Generate with relative source links (default — suitable for committed files) init_py, init_pyi = generate_stubs( prompt_dir, project_root=Path.cwd(), # base for relative stub source links stub_source_lines=10, # embed first 10 non-empty template lines stub_link_mode="relative", # or "file-uri" for absolute local links ) print(init_py) # → """Auto-generated by promptree. Do not edit.""" # from promptree import Promptree as _Promptree # from pathlib import Path as _Path # tree = _Promptree(str(_Path(__file__).parent)) print(init_pyi) # → from typing import Any # # class _SystemNode: # def __call__(self, *, name: Any) -> str: # """[Source](./prompts/system.md) # # System prompt for {{ name }}. # """ # ... # ... # tree: _PromptreeType # Write to disk manually if needed (prompt_dir / "__init__.py").write_text(init_py, encoding="utf-8") (prompt_dir / "__init__.pyi").write_text(init_pyi, encoding="utf-8") # file-uri mode — absolute links, useful for local VS Code "Go to Definition" _, pyi_uri = generate_stubs(prompt_dir, stub_link_mode="file-uri") # stub docstrings contain: [Source](file:///home/user/project/prompts/system.md) ``` ``` -------------------------------- ### Promptree Check for CI/Pre-commit Source: https://github.com/tkaluza/promptree/blob/main/README.md Use 'promptree check' to ensure prompt stub files are up-to-date. It exits non-zero if files are stale, making it suitable for pre-commit hooks and CI. ```bash promptree check ./prompts ``` -------------------------------- ### Pydantic-AI Integration with Promptree Source: https://context7.com/tkaluza/promptree/llms.txt Integrates promptree-generated prompts with pydantic-ai Agents, using typed dependencies for context. ```python # --- pydantic_ai integration --- from dataclasses import dataclass from pydantic_ai import Agent, RunContext from prompts import tree as prompts @dataclass class Deps: user_name: str agent = Agent("openai:gpt-4o", deps_type=Deps) @agent.instructions def instructions(ctx: RunContext[Deps]) -> str: return prompts.system(name=ctx.deps.user_name) result = agent.run_sync(prompts.user.greeting(name="Tim"), deps=Deps("Tim")) print(result.output) ``` -------------------------------- ### Generated Package - Typed Import Source: https://context7.com/tkaluza/promptree/llms.txt Once `promptree generate` is executed, the prompt directory is transformed into an importable Python package. You can import the `tree` object from this package to leverage IDE autocompletion and precise call signatures for your prompts, enhancing development experience and reducing errors. ```APIDOC ## Generated Package — Typed Import After running `promptree generate`, the prompt directory becomes an importable Python package. Import the `tree` object to get full IDE autocomplete and precise call signatures. ```python # After: promptree generate ./prompts from prompts import tree # IDE knows tree.system requires `name: Any` and returns str print(tree.system(name="Claude")) # → System prompt for Claude. print(tree.user.greeting(name="Tim")) # → Hello Tim! # --- pydantic_ai integration --- from dataclasses import dataclass from pydantic_ai import Agent, RunContext from prompts import tree as prompts @dataclass class Deps: user_name: str agent = Agent("openai:gpt-4o", deps_type=Deps) @agent.instructions def instructions(ctx: RunContext[Deps]) -> str: return prompts.system(name=ctx.deps.user_name) result = agent.run_sync(prompts.user.greeting(name="Tim"), deps=Deps("Tim")) print(result.output) ``` ``` -------------------------------- ### CLI: Check Stubs Source: https://context7.com/tkaluza/promptree/llms.txt Checks if on-disk stubs are up-to-date with the prompt templates. Exits with a non-zero status code if stale, suitable for CI/pre-commit hooks. Options should match generation settings. ```bash # Check stubs are up to date promptree check ./prompts # Match the same options used during generation promptree check ./prompts --stub-source-lines 5 --stub-link-mode file-uri ``` -------------------------------- ### TemplateCallable(**kwargs) → str Source: https://context7.com/tkaluza/promptree/llms.txt Represents a single Jinja template file and is callable to render the template with provided keyword arguments. It also exposes the variables required for rendering. ```APIDOC ## TemplateCallable(**kwargs) → str — Render a single template `TemplateCallable` wraps a single Jinja template file. It is callable: keyword arguments are forwarded to `jinja2.Template.render`. It also exposes a `variables` property listing all undeclared template variables (computed once and cached). ### Parameters - **kwargs** - Required/Optional - Keyword arguments representing the variables needed to render the template. The specific arguments depend on the template's content. ### Properties - **variables** (frozenset) - A frozenset containing the names of all undeclared variables in the template. ### Response Returns a string which is the rendered output of the template. ### Request Example ```python from promptree import Promptree prompts = Promptree("./prompts") tpl = prompts.user.greeting # Inspect required variables print(tpl.variables) # Render the template result = tpl(name="Alice") print(result) ``` ``` -------------------------------- ### TemplateNode.__getattr__(name) Source: https://context7.com/tkaluza/promptree/llms.txt Lazily resolves child nodes or template callables based on the attribute name. Handles ambiguity between files and directories. ```APIDOC ## TemplateNode.__getattr__(name) — Lazy child resolution `TemplateNode` (the base class of `Promptree`) resolves children lazily on first attribute access and caches the result in `__dict__`. A name that matches a directory returns a child `TemplateNode`; a name that matches exactly one template file returns a `TemplateCallable`. Raises `AmbiguousTemplateError` when both a directory and a file (or multiple files) share the same stem. ### Parameters - **name** (str) - Required - The name of the attribute to access, corresponding to a subdirectory or template file. ### Response - Returns a `TemplateNode` if the name corresponds to a subdirectory. - Returns a `TemplateCallable` if the name corresponds to a single template file. ### Error Handling - `AmbiguousTemplateError`: Raised if the `name` matches multiple files with the same stem but different extensions. - `AttributeError`: Raised for private names (starting with `_`). ``` -------------------------------- ### Rendering a Single Template Source: https://context7.com/tkaluza/promptree/llms.txt TemplateCallable wraps a Jinja template file and is callable with keyword arguments for rendering. The `variables` property lists undeclared template variables. ```python from promptree import Promptree prompts = Promptree("./prompts") # TemplateCallable is obtained by attribute access on a tree or node tpl = prompts.user.greeting # Inspect required variables before calling print(tpl.variables) # → frozenset({'name'}) print(repr(tpl)) # → TemplateCallable(greeting.md, vars={'name'}) # Render by passing variables as keyword arguments result = tpl(name="Alice") print(result) # → Hello Alice! # Templates with no variables are called with no arguments static = Promptree("./no_vars_prompts").static print(static.variables) # → frozenset() print(static()) # → Static prompt. # Full Jinja features — extends and include — work transparently. ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.