attune-forms
Structured agent ↔ user communication for AI coding agents: typed, validated forms instead of guessing or twenty questions.
Ask an agent for a security audit and it usually either guesses your intent or interrogates you one question at a time. Both failures share a root cause: free-form chat is the only channel most agents have. This library gives agents the other channel — a communication grammar of declarative, validated forms. Independent decisions batch into one round-trip; malformed questions are refused at build time; malformed answers are refused at collection time. Nothing is silently accepted in either direction.
The full argument: "A Communication Grammar for AI Agents".
Install
As a Claude Code plugin (skill + MCP server, no Python setup):
claude plugin marketplace add Smart-AI-Memory/attune-forms
claude plugin install attune-forms@attune-forms
The plugin teaches the session the forms discipline (the forms skill)
and serves four MCP tools — elicitation_render_form,
elicitation_render_widget, elicitation_collect_response,
elicitation_ask — from this package via uvx. Decision cards,
pushback cards, progress forms, deliberation cards, triage boards, and
confirm gates work out of the box; rich HTML renders where the host
supports widgets, degrades to plain questions where it doesn't, and
renders as portable markdown on text-only hosts — with typed replies
parsed back into the same validator.
As a Python library:
pip install attune-forms
Python 3.10+, one runtime dependency (structlog), 510+ tests, CI on Linux/macOS/Windows. Apache 2.0.
The grammar
Beyond the plain field types (text, single/multi select, boolean, number, date, textarea), seven constructs carry conversational meaning:
- Decision — the agent proposes: recommended option first, a "why" rationale, a one-line tradeoff under every alternative. Validates exactly like a single-select; the enrichment is presentation.
- Pushback — structured disagreement: your stated approach appears as an option tagged "your approach", the agent's alternative is badged and ordered first, and overruling the agent is a first-class outcome, not a failure.
- Progress — a status report (done / in-flight / blocked) whose blocked items become a picker: reading the status and unblocking the work are the same gesture.
- Deliberation — several named voices (reviewers, models, teammates) endorse candidate positions; the endorsements render as chips so a 2-1 split is visible at a glance, the synthesis pick is a badge — never the answer — and the user chairs the choice.
- Triage — a ruling per item over a reviewed list (audit findings,
review comments): a shared disposition vocabulary, stable item ids,
and an answer that is the full
{item: disposition}mapping. - Confirm — an approval gate for consequential actions: the consequences are enumerated with severity tags, the answer is one of exactly two options, and nothing is ever pre-selected — a pre-checked approval would defeat the gate, so the validator forbids it.
Quick start
from attune_forms import form_from_dict, select_form_surface, form_to_widget_html
form = form_from_dict({
"title": "Security audit scope",
"fields": [
{"id": "path", "type": "text_input", "label": "Which path?"},
{"id": "depth", "type": "single_select", "label": "How deep?",
"options": ["quick", "standard", "thorough"]},
],
})
if select_form_surface(form) == "widget":
html = form_to_widget_html(form) # render on your widget surface
One schema, every surface
- Renderers —
form_to_widget_html(self-contained interactive widget with postback),form_to_askuserquestion(batched payloads),form_to_elicitation_schema(native MCP elicitation), andform_to_markdown(portable markdown for text-only hosts, with a JSON answer skeleton as the reply format). - Typed-reply ingestion —
markdown_to_answersparses a pasted skeleton or line shorthand deterministically (unknown ids and stray lines become named problems, never guesses);problems_to_markdownre-asks exactly the fields that failed. - Surface routing —
select_form_surfacepicks widget vs fallback; a keyboard-mode opt-out is persisted per project. The form degrades — it never breaks. - Validation —
form_from_dictrefuses malformed definitions;collect_form_responserefuses malformed answers (required fields, option membership) with field-level problems. - Intake templates —
FormTemplate+FieldSlotgenerate a workflow's intake form at ask-time from named candidate providers (PROVIDERS): tools describe what they need once, and the form exists for free. - Telemetry — local-only surface-decision log, disabled via
DO_NOT_TRACK=1orATTUNE_FORMS_TELEMETRY=0. Nothing is ever phoned home.
Host integration seams
Workflow-bound intake templates need two host hooks:
import attune_forms.intake_template as it
it.WORKFLOW_SCHEMA_RESOLVER = my_schema_resolver # name -> input schema
it.TEMPLATE_LOADERS.append(my_registration_loader) # imports template modules
Provenance
Extracted from attune-ai's elicitation subsystem, where the grammar was designed and battle-tested; attune-ai now consumes this package. The grammar's own design decisions were made through its forms — including the review that killed one of its proposed features. See docs/communication-grammar-article.md (the verified master of the article) and CHANGELOG.md.
License
Apache 2.0. Copyright 2026 Smart AI Memory.
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 attune_forms-0.5.0.tar.gz.
File metadata
- Download URL: attune_forms-0.5.0.tar.gz
- Upload date:
- Size: 118.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
792cb5b00a0ee8c8333ac53ab89cf5a85abe04916d19affc98dc8c4f42e1053e
|
|
| MD5 |
0da1e0a756af313c9afb9cc708a2261f
|
|
| BLAKE2b-256 |
9bc15cb4e572e0f16ed67a10b820c50659bd5541540ff48b7f9aff7232da336b
|
Provenance
The following attestation bundles were made for attune_forms-0.5.0.tar.gz:
Publisher:
publish.yml on Smart-AI-Memory/attune-forms
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
attune_forms-0.5.0.tar.gz -
Subject digest:
792cb5b00a0ee8c8333ac53ab89cf5a85abe04916d19affc98dc8c4f42e1053e - Sigstore transparency entry: 2472218232
- Sigstore integration time:
-
Permalink:
Smart-AI-Memory/attune-forms@7d720ee0b6a4e567ac3cc245a93ead829d207d05 -
Branch / Tag:
refs/tags/v0.5.0 - Owner: https://github.com/Smart-AI-Memory
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@7d720ee0b6a4e567ac3cc245a93ead829d207d05 -
Trigger Event:
push
-
Statement type:
File details
Details for the file attune_forms-0.5.0-py3-none-any.whl.
File metadata
- Download URL: attune_forms-0.5.0-py3-none-any.whl
- Upload date:
- Size: 74.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
689b744a6598c901129dea8f10dd9644dbeea9e200f352f20d0ea1bb26a945cb
|
|
| MD5 |
ff31270f0428e0562e59473805c7685a
|
|
| BLAKE2b-256 |
8b86fc369d38d1b4e9433c1fa12b163819e7d02d7a06aa37f21a2310ba78157a
|
Provenance
The following attestation bundles were made for attune_forms-0.5.0-py3-none-any.whl:
Publisher:
publish.yml on Smart-AI-Memory/attune-forms
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
attune_forms-0.5.0-py3-none-any.whl -
Subject digest:
689b744a6598c901129dea8f10dd9644dbeea9e200f352f20d0ea1bb26a945cb - Sigstore transparency entry: 2472218248
- Sigstore integration time:
-
Permalink:
Smart-AI-Memory/attune-forms@7d720ee0b6a4e567ac3cc245a93ead829d207d05 -
Branch / Tag:
refs/tags/v0.5.0 - Owner: https://github.com/Smart-AI-Memory
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@7d720ee0b6a4e567ac3cc245a93ead829d207d05 -
Trigger Event:
push
-
Statement type: