diff options
Diffstat (limited to 'configuration.html')
| -rw-r--r-- | configuration.html | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/configuration.html b/configuration.html new file mode 100644 index 0000000..1823478 --- /dev/null +++ b/configuration.html @@ -0,0 +1,80 @@ +<!doctype html> +<html lang="en"> +<head> +<meta charset="utf-8"> +<meta name="viewport" content="width=device-width, initial-scale=1"> +<title>panto — Configuration</title> +<link rel="stylesheet" href="_ds/pantograph-design-system-56a1c74e-41c1-486b-ba3c-4eabdfacef31/styles.css"> +<link rel="stylesheet" href="_shared/components.css"> +<link rel="stylesheet" href="_shared/docs.css"> +</head> +<body> +<div class="pd-app"> +<header class="pd-header"> +<div class="pd-header__left"> +<button class="pd-menu" type="button" aria-label="Menu" data-menu-toggle><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" width="1em" height="1em"><path d="M4 12h16"/><path d="M4 6h16"/><path d="M4 18h16"/></svg></button> +<a class="pd-brand" href="index.html"><img src="assets/logo-mark.svg" width="28" height="28" alt=""><span class="pd-brand__word">panto</span><span class="pd-brand__div">/</span><span class="pd-brand__sub">docs</span></a> +<span class="pg-badge pg-badge--outline">CLI</span> +</div> +<nav class="pd-nav"><a href="index.html" class="pd-nav__link">Getting started</a><a href="cli.html" class="pd-nav__link">Command line</a><a href="configuration.html" class="pd-nav__link pd-nav__link--active">Configuration</a><a href="keybindings.html" class="pd-nav__link">Key bindings</a><a href="lua.html" class="pd-nav__link">Lua extensions</a></nav> +<div class="pd-header__right"><a class="pd-ghlink" href="https://code.tjp.lol/pantograph.git/" target="_blank" rel="noreferrer"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" width="1em" height="1em"><path d="M15 22v-4a4.8 4.8 0 0 0-1-3.5c3 0 6-2 6-5.5.08-1.25-.27-2.48-1-3.5.28-1.15.28-2.35 0-3.5 0 0-1 0-3 1.5-2.64-.5-5.36-.5-8 0C6 .5 5 .5 5 .5c-.3 1.15-.3 2.35 0 3.5A5.4 5.4 0 0 0 4 7.5c0 3.5 3 5.5 6 5.5-.39.49-.68 1.05-.85 1.65-.17.6-.22 1.23-.15 1.85v4"/><path d="M9 18c-4.51 2-5-2-7-2"/></svg> Source</a></div> +</header> +<div class="pd-shell"> +<aside class="pd-sidebar"><div class="pd-sidebar__scroll"><div class="pd-navsec"><p class="pd-navsec__title"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" width="1em" height="1em"><path d="m16.24 7.76-1.804 5.411a2 2 0 0 1-1.265 1.265L7.76 16.24l1.804-5.411a2 2 0 0 1 1.265-1.265z"/><circle cx="12" cy="12" r="10"/></svg>Getting started</p><ul class="pd-navsec__list"><li><a href="index.html#overview" class="pd-navsec__link">Overview</a></li><li><a href="index.html#install" class="pd-navsec__link">Install</a></li><li><a href="index.html#first-run" class="pd-navsec__link">First run</a></li><li><a href="index.html#authenticate" class="pd-navsec__link">Authenticate</a></li></ul></div><div class="pd-navsec"><p class="pd-navsec__title"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" width="1em" height="1em"><path d="m4 17 6-6-6-6"/><path d="M12 19h8"/></svg>Command line</p><ul class="pd-navsec__list"><li><a href="cli.html#starting" class="pd-navsec__link">Starting a session</a></li><li><a href="cli.html#sessions" class="pd-navsec__link"><code>panto sessions</code></a></li><li><a href="cli.html#models" class="pd-navsec__link"><code>panto models</code></a></li><li><a href="cli.html#auth" class="pd-navsec__link"><code>panto auth</code></a></li><li><a href="cli.html#bootstrap" class="pd-navsec__link"><code>panto bootstrap</code></a></li><li><a href="cli.html#lua" class="pd-navsec__link"><code>panto lua</code></a></li><li><a href="cli.html#slash-commands" class="pd-navsec__link">Slash commands</a></li><li><a href="cli.html#environment" class="pd-navsec__link">Environment</a></li></ul></div><div class="pd-navsec pd-navsec--current"><p class="pd-navsec__title"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" width="1em" height="1em"><path d="M3 5h11"/><path d="M19 5h2"/><path d="M3 12h6"/><path d="M14 12h7"/><path d="M3 19h10"/><path d="M18 19h3"/><circle cx="16" cy="5" r="2"/><circle cx="11" cy="12" r="2"/><circle cx="15" cy="19" r="2"/></svg>Configuration</p><ul class="pd-navsec__list"><li><a href="configuration.html#files" class="pd-navsec__link pd-navsec__link--active">Files & layers</a></li><li><a href="configuration.html#providers" class="pd-navsec__link"><code>[providers]</code></a></li><li><a href="configuration.html#auth" class="pd-navsec__link"><code>[auth]</code></a></li><li><a href="configuration.html#defaults" class="pd-navsec__link"><code>[defaults]</code></a></li><li><a href="configuration.html#policies" class="pd-navsec__link">Tools & extensions</a></li><li><a href="configuration.html#compaction" class="pd-navsec__link"><code>[compaction]</code></a></li><li><a href="configuration.html#models" class="pd-navsec__link"><code>models.toml</code></a></li><li><a href="configuration.html#system-prompt" class="pd-navsec__link">System prompt</a></li></ul></div><div class="pd-navsec"><p class="pd-navsec__title"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" width="1em" height="1em"><rect x="2" y="4" width="20" height="16" rx="2"/><path d="M6 8h.001"/><path d="M10 8h.001"/><path d="M14 8h.001"/><path d="M18 8h.001"/><path d="M8 12h.001"/><path d="M12 12h.001"/><path d="M16 12h.001"/><path d="M7 16h10"/></svg>Key bindings</p><ul class="pd-navsec__list"><li><a href="keybindings.html#editing" class="pd-navsec__link">Editing & cursor</a></li><li><a href="keybindings.html#submit" class="pd-navsec__link">Submit & newline</a></li><li><a href="keybindings.html#control" class="pd-navsec__link">Selectors & control</a></li><li><a href="keybindings.html#terminal" class="pd-navsec__link">Terminal protocol</a></li></ul></div><div class="pd-navsec"><p class="pd-navsec__title"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" width="1em" height="1em"><path d="M2.97 12.92A2 2 0 0 0 2 14.63v3.24a2 2 0 0 0 .97 1.71l3 1.8a2 2 0 0 0 2.06 0L12 19v-5.5l-5-3-4.03 2.42Z"/><path d="m7 16.5-4.74-2.85"/><path d="m7 16.5 5-3"/><path d="M7 16.5v5.17"/><path d="M12 13.5V19l3.97 2.38a2 2 0 0 0 2.06 0l3-1.8a2 2 0 0 0 .97-1.71v-3.24a2 2 0 0 0-.97-1.71L17 10.5l-5 3Z"/><path d="m17 16.5-5-3"/><path d="m17 16.5 4.74-2.85"/><path d="M17 16.5v5.17"/><path d="M7.97 4.42A2 2 0 0 0 7 6.13v4.37l5 3 5-3V6.13a2 2 0 0 0-.97-1.71l-3-1.8a2 2 0 0 0-2.06 0l-3 1.8Z"/><path d="M12 8 7.26 5.15"/><path d="m12 8 4.74-2.85"/><path d="M12 13.5V8"/></svg>Lua extensions</p><ul class="pd-navsec__list"><li><a href="lua.html#overview" class="pd-navsec__link">Overview</a></li><li><a href="lua.html#loading" class="pd-navsec__link">Loading extensions</a></li><li><a href="lua.html#tools" class="pd-navsec__link"><code>register_tool</code></a></li><li><a href="lua.html#commands" class="pd-navsec__link"><code>register_command</code></a></li><li><a href="lua.html#events" class="pd-navsec__link">Events: on & emit</a></li><li><a href="lua.html#components" class="pd-navsec__link">Lua components</a></li><li><a href="lua.html#runtime" class="pd-navsec__link">Runtime & luarocks</a></li></ul></div></div></aside> +<div class="pd-scrim"></div> +<main class="pd-main"><article class="pd-doc" data-screen-label="Configuration"><p class="panto-eyebrow pd-eyebrow">Reference</p><h1 class="pd-doc__h1">Configuration</h1><div class="pd-doc__meta"><span class="pg-badge pg-badge--neutral">TOML</span></div><p class="pd-lead">panto is configured by layered <code>config.toml</code> files, plus a separate <code>models.toml</code> for model aliases and pricing. Define providers, pick a default model, and gate tools and extensions — everything you specify, nothing you don’t.</p><h2 id="files" class="pd-h2">Files & layers</h2><p class="pd-body">Four files are read and merged, lowest precedence first. Missing files are skipped silently.</p><div class="pd-table-wrap"><table class="pd-table"><thead><tr><th>Layer</th><th>Path</th><th>Role</th></tr></thead><tbody><tr><td class="mono">base</td><td class="mono">$PANTO_HOME/config.toml · else $XDG_DATA_HOME/panto/config.toml</td><td>Auto-generated by bootstrap. Lowest precedence.</td></tr><tr><td class="mono">user</td><td class="mono">$XDG_CONFIG_HOME/panto/config.toml · else ~/.config/panto/config.toml</td><td>Your personal, machine-wide settings.</td></tr><tr><td class="mono">project</td><td class="mono">./.panto/config.toml</td><td>Checked-in, per-project settings.</td></tr><tr><td class="mono">local</td><td class="mono">./.panto/config.local.toml</td><td>Personal per-project overrides — git-ignore this. Highest precedence.</td></tr></tbody></table></div><p class="pd-body"><strong>Merge semantics:</strong> tables merge recursively, but scalars <em>and arrays</em> from a higher layer overwrite wholesale. A project file that sets <code>tools.deny</code> replaces the array entirely — it doesn’t append to a user-level list. Tables accumulate, so a provider defined only at the base layer survives even when a higher layer adds another.</p><div class="pg-code"><div class="pg-code__bar"><span class="pg-code__name">config.toml</span><span class="pg-code__lang">toml</span><button class="pg-code__copy" type="button" aria-label="Copy code"><svg class="pg-code__copyglyph" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="11" height="11" rx="2"/><path d="M5 15V5a2 2 0 0 1 2-2h10"/></svg><svg class="pg-code__check" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="m20 6-11 11-5-5"/></svg><span class="pg-code__label">Copy</span></button></div><div class="pg-code__scroll"><pre><code># ~/.config/panto/config.toml (user layer) + +[defaults] +model = "anthropic:sonnet" # <provider>:<alias> + +[providers.anthropic] +style = "anthropic_messages" +base_url = "https://api.anthropic.com" +auth = "anthropic_api" # draws its key from [auth.anthropic_api] + +[auth.anthropic_api] +key = "${env:ANTHROPIC_API_KEY}" # resolved at load + +[tools] +deny = ["std.bash"] # allow every tool except the shell</code></pre></div></div><div class="pg-callout pg-callout--tip"><span class="pg-callout__icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 18h6"/><path d="M10 22h4"/><path d="M15.09 14c.18-.98.65-1.74 1.41-2.5A4.65 4.65 0 0 0 18 8 6 6 0 0 0 6 8c0 1 .23 2.23 1.5 3.5A4.61 4.61 0 0 1 8.91 14"/></svg></span><div class="pg-callout__body"><p class="pg-callout__title">The local layer</p><code>./.panto/config.local.toml</code> is meant to be git-ignored: apply your own overrides on top of the checked-in <code>project</code> layer without committing them.</div></div><h2 id="providers" class="pd-h2">[providers.<name>]</h2><p class="pd-body">A provider is pure transport: an API shape and a base URL, plus the name of the auth session that supplies its credential. The chosen name is what you reference on the left of a <code>provider:alias</code> model.</p><div class="pd-opts"><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">style</span><span class="pd-opt__type">string</span><span class="pg-badge pg-badge--danger">required</span></div><div class="pd-opt__desc">The wire protocol: <code>anthropic_messages</code>, <code>openai_chat</code>, or <code>openai_responses</code>.</div></div><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">dialect</span><span class="pd-opt__type">"codex"</span></div><div class="pd-opt__desc">A sub-dialect for styles that share a protocol family. Only <code>style = "openai_responses"</code> accepts it today, with the single value <code>"codex"</code> (the Codex Responses variant).</div></div><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">base_url</span><span class="pd-opt__type">string</span><span class="pg-badge pg-badge--danger">required</span></div><div class="pd-opt__desc">The API base URL requests are sent to.</div></div><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">auth</span><span class="pd-opt__type">string</span><span class="pg-badge pg-badge--danger">required</span></div><div class="pd-opt__desc">Names the <a href="#auth"><code>[auth.<name>]</code></a> session that supplies this provider’s credential. (Provider-level <code>api_key</code> is no longer accepted — auth lives in one place.)</div></div><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">prompt_cache</span><span class="pd-opt__type">bool</span><span class="pg-badge pg-badge--neutral">default true</span></div><div class="pd-opt__desc"><code>anthropic_messages</code> only. Place one advancing <code>cache_control</code> breakpoint on each request. Ignored for other styles.</div></div><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">extra_headers</span><span class="pd-opt__type">table</span></div><div class="pd-opt__desc">A table of static string headers merged onto every model request (see below).</div></div><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">model_catalog_name</span><span class="pd-opt__type">string</span></div><div class="pd-opt__desc">Maps this provider onto a <a href="https://models.dev" target="_blank" rel="noreferrer">models.dev</a> catalog key (e.g. <code>"github-copilot"</code>) for <a href="cli.html#models"><code>panto models sync</code></a>. Defaults to the provider name.</div></div></div><div class="pg-code"><div class="pg-code__bar"><span class="pg-code__name">config.toml</span><span class="pg-code__lang">toml</span><button class="pg-code__copy" type="button" aria-label="Copy code"><svg class="pg-code__copyglyph" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="11" height="11" rx="2"/><path d="M5 15V5a2 2 0 0 1 2-2h10"/></svg><svg class="pg-code__check" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="m20 6-11 11-5-5"/></svg><span class="pg-code__label">Copy</span></button></div><div class="pg-code__scroll"><pre><code>[providers.copilot] +style = "openai_chat" +base_url = "https://api.individual.githubcopilot.com" +auth = "github_copilot" + +[providers.copilot.extra_headers] +Copilot-Integration-Id = "vscode-chat" +X-Initiator = "user"</code></pre></div></div><div class="pg-callout pg-callout--note"><span class="pg-callout__icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M12 16v-4"/><path d="M12 8h.01"/></svg></span><div class="pg-callout__body"><p class="pg-callout__title">Unresolved providers vanish</p>If a provider’s <code>api_key</code> auth session resolves to empty (its env var isn’t set), the provider is dropped — export the key to bring it back. OAuth providers always survive and resolve at turn time.</div></div><h2 id="auth" class="pd-h2">[auth.<name>]</h2><p class="pd-body">A named auth session supplies a credential. Its <code>type</code> is inferred when omitted: a <code>key</code> implies <code>api_key</code>; a <code>client_id</code> implies <code>oauth_device</code>.</p><h3 id="auth-subst" class="pd-h3">Substitution</h3><p class="pd-body">Every auth value supports <code>${…}</code> substitution. <code>${env:VAR}</code> reads the environment; <code>${name}</code> reads another key in the same section (handy for a shared <code>domain</code>). An unresolved reference becomes the empty string.</p><h3 id="auth-apikey" class="pd-h3">API-key sessions</h3><div class="pd-opts"><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">key</span><span class="pd-opt__type">string</span><span class="pg-badge pg-badge--danger">required</span></div><div class="pd-opt__desc">The API key — usually <code>"${env:VAR}"</code>, but a literal works too. Resolved eagerly at load; an empty result leaves the session unresolved.</div></div><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">type</span><span class="pd-opt__type">"api_key"</span></div><div class="pd-opt__desc">Optional; inferred from the presence of <code>key</code>.</div></div></div><h3 id="auth-oauth" class="pd-h3">OAuth device sessions</h3><div class="pd-opts"><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">client_id</span><span class="pd-opt__type">string</span><span class="pg-badge pg-badge--danger">required</span></div><div class="pd-opt__desc">The OAuth client id.</div></div><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">device_code_url</span><span class="pd-opt__type">string</span><span class="pg-badge pg-badge--danger">required</span></div><div class="pd-opt__desc">Endpoint that issues the device + user codes.</div></div><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">token_url</span><span class="pd-opt__type">string</span><span class="pg-badge pg-badge--danger">required</span></div><div class="pd-opt__desc">Endpoint polled for the access token.</div></div><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">dialect</span><span class="pd-opt__type">"token" | "codex"</span><span class="pg-badge pg-badge--neutral">default token</span></div><div class="pd-opt__desc">Flow dialect. <code>codex</code> additionally requires <code>device_poll_url</code>.</div></div><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">scope</span><span class="pd-opt__type">string</span></div><div class="pd-opt__desc">Requested OAuth scopes.</div></div><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">verification_url</span><span class="pd-opt__type">string</span></div><div class="pd-opt__desc">Override the URL shown to the user.</div></div><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">device_poll_url</span><span class="pd-opt__type">string</span></div><div class="pd-opt__desc">Distinct poll endpoint (required for <code>codex</code>).</div></div><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">token_request_format</span><span class="pd-opt__type">"form" | "json"</span><span class="pg-badge pg-badge--neutral">default form</span></div><div class="pd-opt__desc">How the token request body is encoded.</div></div><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">redirect_uri / account_id_jwt_claim</span><span class="pd-opt__type">string</span></div><div class="pd-opt__desc">Optional flow details.</div></div><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">exchange_url</span><span class="pd-opt__type">string</span></div><div class="pd-opt__desc">Enables an optional secondary token exchange. Companions: <code>exchange_method</code> (default <code>GET</code>), <code>exchange_token_path</code> (default <code>token</code>), <code>exchange_expires_path</code>, <code>exchange_base_url_path</code> — JSON paths into the exchange response.</div></div></div><div class="pg-code"><div class="pg-code__bar"><span class="pg-code__name">config.toml</span><span class="pg-code__lang">toml</span><button class="pg-code__copy" type="button" aria-label="Copy code"><svg class="pg-code__copyglyph" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="11" height="11" rx="2"/><path d="M5 15V5a2 2 0 0 1 2-2h10"/></svg><svg class="pg-code__check" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="m20 6-11 11-5-5"/></svg><span class="pg-code__label">Copy</span></button></div><div class="pg-code__scroll"><pre><code>[auth.github_copilot] +client_id = "Iv1.b507a08c87ecfe98" +domain = "github.com" # an ordinary sibling key… +device_code_url = "https://${domain}/login/device/code" # …reused here +token_url = "https://${domain}/login/oauth/access_token" +scope = "read:user" + +# optional secondary token exchange +exchange_url = "https://api.${domain}/copilot_internal/v2/token" +exchange_expires_path = "expires_at" +exchange_base_url_path = "endpoints.api"</code></pre></div></div><h2 id="defaults" class="pd-h2">[defaults]</h2><div class="pd-opts"><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">model</span><span class="pd-opt__type">string</span></div><div class="pd-opt__desc">The default model, as <code>"<provider>:<alias>"</code> (exactly one colon, both halves non-empty). The provider must resolve.</div></div></div><p class="pd-body">Model selection falls through in order: an explicit override (a future <code>--model</code>), then <code>defaults.model</code>, then — if exactly one provider resolved and it has exactly one alias in <code>models.toml</code> — that one. Otherwise panto asks you to set a default.</p><h2 id="policies" class="pd-h2">Tools & extensions</h2><p class="pd-body"><code>[tools]</code> and <code>[extensions]</code> share the same shape: allow- and deny-lists of glob patterns over dotted names (the standard tools live under the <code>std.</code> namespace — <code>std.read</code>, <code>std.write</code>, <code>std.edit</code>, <code>std.bash</code>).</p><div class="pd-opts"><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">allow</span><span class="pd-opt__type">string[]</span></div><div class="pd-opt__desc">Glob patterns. <strong>Empty means allow-all</strong> (still subject to <code>deny</code>).</div></div><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">deny</span><span class="pd-opt__type">string[]</span></div><div class="pd-opt__desc">Glob patterns. A name is denied if it matches any deny pattern.</div></div></div><p class="pd-body">A name is permitted when it matches at least one <code>allow</code> pattern (or allow is empty) <em>and</em> matches no <code>deny</code> pattern.</p><div class="pg-code"><div class="pg-code__bar"><span class="pg-code__name">config.toml</span><span class="pg-code__lang">toml</span><button class="pg-code__copy" type="button" aria-label="Copy code"><svg class="pg-code__copyglyph" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="11" height="11" rx="2"/><path d="M5 15V5a2 2 0 0 1 2-2h10"/></svg><svg class="pg-code__check" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="m20 6-11 11-5-5"/></svg><span class="pg-code__label">Copy</span></button></div><div class="pg-code__scroll"><pre><code>[tools] +allow = ["std.*"] # only the standard tools +deny = ["std.bash"] # …but never the shell</code></pre></div></div><div class="pg-callout pg-callout--danger"><span class="pg-callout__icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="m15 9-6 6"/><path d="m9 9 6 6"/></svg></span><div class="pg-callout__body"><p class="pg-callout__title">Conflicts are fatal</p>The same pattern in both <code>allow</code> and <code>deny</code> for one kind is a hard error — panto refuses to start rather than guess.</div></div><h2 id="compaction" class="pd-h2">[compaction]</h2><p class="pd-body">panto compacts long conversations automatically; this section tunes it. The manual <a href="cli.html#slash-commands"><code>/compact</code></a> command uses the same settings.</p><div class="pd-opts"><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">keep_verbatim</span><span class="pd-opt__type">int</span><span class="pg-badge pg-badge--neutral">default 20000</span></div><div class="pd-opt__desc">Token budget for the recent tail kept verbatim when compacting.</div></div><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">model</span><span class="pd-opt__type">string</span></div><div class="pd-opt__desc">Optional <code>provider:alias</code> override for the model that writes the summary. Defaults to the active chat model.</div></div></div><h2 id="models" class="pd-h2">models.toml</h2><p class="pd-body">Model <em>aliases</em> live in <code>$XDG_CONFIG_HOME/panto/models.toml</code>, separate from <code>config.toml</code>. Each entry is keyed <code>[<provider>.<alias>]</code> — the provider matches a <code>[providers.<name>]</code>, the alias is the short name you reference. A referenced alias with no entry isn’t an error: it’s used verbatim as the wire name with default knobs.</p><p class="pd-body"><code>models.toml</code> is layered exactly like <code>config.toml</code> (base → user → project → local). The base layer is auto-generated — <a href="cli.html#models"><code>panto models sync</code></a> fetches the catalog and writes it — so your user and project entries always layer on top and win.</p><h3 id="models-common" class="pd-h3">Common keys</h3><div class="pd-opts"><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">model</span><span class="pd-opt__type">string</span></div><div class="pd-opt__desc">Wire model id sent to the API. Defaults to the alias.</div></div><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">context_window</span><span class="pd-opt__type">int</span></div><div class="pd-opt__desc">Total input context window, used for the footer’s context-usage display. Optional.</div></div><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">max_tokens</span><span class="pd-opt__type">int</span></div><div class="pd-opt__desc">Per-request output token cap.</div></div><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">input / output / cache_read / cache_write</span><span class="pd-opt__type">float</span></div><div class="pd-opt__desc">Pricing in USD per million tokens. All optional; omitted means unknown.</div></div></div><h3 id="models-openai" class="pd-h3">openai_chat only</h3><div class="pd-opts"><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">reasoning</span><span class="pd-opt__type">string</span><span class="pg-badge pg-badge--neutral">default default</span></div><div class="pd-opt__desc">One of <code>default</code>, <code>off</code>, <code>minimal</code>, <code>low</code>, <code>medium</code>, <code>high</code>.</div></div></div><h3 id="models-anthropic" class="pd-h3">anthropic_messages only</h3><div class="pd-opts"><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">thinking</span><span class="pd-opt__type">string</span><span class="pg-badge pg-badge--neutral">default disabled</span></div><div class="pd-opt__desc"><code>disabled</code>, <code>enabled</code>, or <code>adaptive</code>.</div></div><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">effort</span><span class="pd-opt__type">string</span><span class="pg-badge pg-badge--neutral">default medium</span></div><div class="pd-opt__desc"><code>low</code> · <code>medium</code> · <code>high</code> · <code>xhigh</code> · <code>max</code>. Used when <code>thinking = "adaptive"</code>.</div></div><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">thinking_budget_tokens</span><span class="pd-opt__type">int</span><span class="pg-badge pg-badge--neutral">default 32000</span></div><div class="pd-opt__desc">Reasoning-token budget when <code>thinking = "enabled"</code>.</div></div><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">thinking_interleaved</span><span class="pd-opt__type">bool</span><span class="pg-badge pg-badge--neutral">default false</span></div><div class="pd-opt__desc">Send the interleaved-thinking beta header (honoured when <code>thinking = "enabled"</code>).</div></div><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">api_version</span><span class="pd-opt__type">string</span><span class="pg-badge pg-badge--neutral">default 2023-06-01</span></div><div class="pd-opt__desc">The <code>anthropic-version</code> header.</div></div></div><div class="pg-code"><div class="pg-code__bar"><span class="pg-code__name">models.toml</span><span class="pg-code__lang">toml</span><button class="pg-code__copy" type="button" aria-label="Copy code"><svg class="pg-code__copyglyph" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="11" height="11" rx="2"/><path d="M5 15V5a2 2 0 0 1 2-2h10"/></svg><svg class="pg-code__check" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="m20 6-11 11-5-5"/></svg><span class="pg-code__label">Copy</span></button></div><div class="pg-code__scroll"><pre><code># ~/.config/panto/models.toml + +[anthropic.sonnet] +model = "claude-sonnet-4-20250514" # wire name; defaults to the alias +max_tokens = 8192 +thinking = "enabled" +thinking_budget_tokens = 16000 +input = 3.0 # USD per million tokens +output = 15.0 +cache_read = 0.30 +cache_write = 3.75 + +[openai.gpt] +model = "gpt-4o" +reasoning = "medium" +input = 2.5 +output = 10.0</code></pre></div></div><h2 id="system-prompt" class="pd-h2">System prompt</h2><p class="pd-body">The agent’s system prompt is sourced by convention from Markdown files across the same base → user → project layers (base is <code>$PANTO_HOME/agent</code>, where bootstrap stages the bundled default):</p><div class="pd-opts"><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">SYSTEM.md</span></div><div class="pd-opt__desc">Replaces the system prompt for that layer.</div></div><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">APPEND_SYSTEM.md</span></div><div class="pd-opt__desc">Appends to it — for small, additive house rules.</div></div><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">COMPACTION.md</span></div><div class="pd-opt__desc">Overrides the summary prompt used during <a href="#compaction">compaction</a> (last layer wins; a built-in default applies otherwise).</div></div></div><p class="pd-body">On resume, prompt changes are reconciled without rewriting the existing conversation.</p><nav class="pd-prevnext"><a class="pd-pn pd-pn--prev" href="cli.html"><span class="pd-pn__dir">← Previous</span><span class="pd-pn__title">Command line</span></a><a class="pd-pn pd-pn--next" href="keybindings.html"><span class="pd-pn__dir">Next →</span><span class="pd-pn__title">Key bindings</span></a></nav></article></main> +<aside class="pd-toc"><p class="pd-toc__title">On this page</p><ul class="pd-toc__list"><li><a href="#files" class="pd-toc__link pd-toc__link--active">Files & layers</a></li><li><a href="#providers" class="pd-toc__link">[providers]</a></li><li><a href="#auth" class="pd-toc__link">[auth]</a></li><li><a href="#defaults" class="pd-toc__link">[defaults]</a></li><li><a href="#policies" class="pd-toc__link">Tools & extensions</a></li><li><a href="#compaction" class="pd-toc__link">[compaction]</a></li><li><a href="#models" class="pd-toc__link">models.toml</a></li><li><a href="#system-prompt" class="pd-toc__link">System prompt</a></li></ul></aside> +</div> +</div> +<script src="_shared/docs.js"></script> +</body> +</html>
\ No newline at end of file |
