Skip to content

Commit 2beae77

Browse files
committed
Release v1.2.0
1 parent fc8bcd0 commit 2beae77

13 files changed

Lines changed: 580 additions & 99 deletions

CHANGELOG.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
88

99

1010

11-
1211
## [Releases]
1312

13+
## v1.2.0 - April 15, 2026
14+
15+
### Added
16+
17+
- Added two new fields in `extract_theorems` to be consistent with `extract_decls` (see below):
18+
- `kind`: always `theorem` for `extract_theorems`.
19+
- `declaration_messages`: same content as `theorem_messages`. `theorem_messages` is now deprecated and will be removed in a future update.
20+
- Added `extract_decls`, an upgraded version of `extract_theorems` that extracts all declaration kinds.
21+
- New `kind` field in each document. Possible values: `theorem`, `def`, `abbrev`, `axiom`, `opaque`, `structure`, `class`, `class inductive`, `inductive`, `instance`, `example`, `unknown`
22+
- Note: Not all fields are meaningful for all declaration kinds (e.g., `proof_length`/`tactic_counts` only apply to theorems/lemmas with tactic proofs.)
23+
- This tool should be used instead of `extract_theorems` as it is a strict superset of functionality. `extract_theorems` will be deprecated in a future update.
24+
25+
### Fixed
26+
27+
- Added "Last Used" and "Requests (24h)" columns to the API key console page for better visibility into API key usage.
28+
29+
1430
## v1.1.1 - April 8, 2026
1531

1632
### Changed

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ Homepage: https://axle.axiommath.ai/
77
## Announcements
88

99
<details open>
10+
<summary><strong>April 15, 2026 - v1.2.0</strong></summary>
11+
12+
New `extract_decls` tool for extracting all declaration kinds, and corresponding updates to `extract_theorems`. Users using `extract_theorems` (which will be deprecated in a future update) should migrate to `extract_decls`. See the [changelog](https://axle.axiommath.ai/v1/docs/changelog/) for details.
13+
14+
</details>
15+
16+
<details>
1017
<summary><strong>April 8, 2026 - v1.1.1</strong></summary>
1118

1219
Default option changes, a Lean version bump, and bug fixes.

axle/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
CheckResponse,
2121
DisproveResponse,
2222
Document,
23+
ExtractDeclsResponse,
2324
ExtractTheoremsResponse,
2425
Have2LemmaResponse,
2526
Have2SorryResponse,
@@ -54,6 +55,7 @@
5455
"CheckResponse",
5556
"DisproveResponse",
5657
"Document",
58+
"ExtractDeclsResponse",
5759
"ExtractTheoremsResponse",
5860
"Have2LemmaResponse",
5961
"Have2SorryResponse",

axle/cli/endpoints.py

Lines changed: 215 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,75 @@ class OutputField(TypedDict, total=False):
149149
}
150150

151151

152+
# Shared Document Fields documentation for extract_theorems and extract_decls
153+
DOCUMENT_FIELDS_BASE = """\
154+
??? "`kind` · str · The kind of declaration"
155+
The kind of the declaration. For `extract_theorems`, this is always `"theorem"`. For `extract_decls`, possible values are: `theorem`, `def`, `abbrev`, `axiom`, `opaque`, `structure`, `class`, `class inductive`, `inductive`, `instance`, `example`, `unknown`.
156+
157+
??? "`declaration` · str · The declaration source code"
158+
The raw source code of this declaration.
159+
160+
??? "`content` · str · Standalone content including declaration and dependencies"
161+
Complete, self-contained Lean code that includes the declaration and all its local dependencies. Can be compiled independently.
162+
163+
??? "`tokens` · list[str] · Raw tokens from the declaration"
164+
The declaration's source code split into tokens.
165+
166+
??? "`signature` · str · Declaration signature (everything before the body)"
167+
The declaration signature, e.g., `theorem foo (x : Nat) : x = x` or `def bar : Nat`.
168+
169+
??? "`type` · str · Pretty-printed type of the declaration"
170+
The type of the declaration as pretty-printed by Lean.
171+
172+
??? "`type_hash` · int · Hash of the canonical type expression"
173+
Hash of the canonical, alpha-invariant type expression. Useful for deduplication.
174+
175+
??? "`is_sorry` · bool · Whether the declaration contains a sorry"
176+
True if the declaration contains a `sorry`.
177+
178+
??? "`index` · int · 0-based index in original file"
179+
Position of this declaration in the original file. Note: indices may not be contiguous (mutual definitions share indices).
180+
181+
??? "`line_pos` · int · 1-based line number where declaration starts"
182+
Line number where the declaration begins.
183+
184+
??? "`end_line_pos` · int · 1-based line number where declaration ends"
185+
Line number where the declaration ends.
186+
187+
??? "`proof_length` · int · Approximate number of tactics in proof"
188+
Rough measure of proof complexity based on tactic count. Only meaningful for theorems/lemmas with tactic proofs.
189+
190+
??? "`tactic_counts` · dict[str, int] · Map of tactic names to occurrence counts"
191+
Breakdown of which tactics are used and how often. Only meaningful for theorems/lemmas with tactic proofs.
192+
193+
??? "`local_type_dependencies` · list[str] · Transitive local dependencies of the type"
194+
Local declarations that the declaration's type depends on (non-transitive).
195+
196+
??? "`local_value_dependencies` · list[str] · Transitive local dependencies of the body"
197+
Local declarations that the declaration's body/proof depends on (non-transitive).
198+
199+
??? "`external_type_dependencies` · list[str] · Immediate external dependencies of the type"
200+
External constants (builtins, imports) that appear in the type.
201+
202+
??? "`external_value_dependencies` · list[str] · Immediate external dependencies of the body"
203+
External constants (builtins, imports) that appear in the body/proof.
204+
205+
??? "`local_syntactic_dependencies` · list[str] · Local constants explicitly written in source"
206+
Local constants that appear literally in source (not from notation/macro expansion).
207+
208+
??? "`external_syntactic_dependencies` · list[str] · External constants explicitly written in source"
209+
External constants that appear literally in source (not from notation/macro expansion).
210+
211+
??? "`declaration_messages` · dict · Messages specific to this declaration"
212+
Lean messages (`errors`, `warnings`, `infos`) specific to this declaration in the original document.
213+
214+
??? "`theorem_messages` · dict · (Deprecated) Messages specific to this declaration"
215+
Lean messages (`errors`, `warnings`, `infos`) specific to this declaration. For `extract_theorems`, this contains the same data as `declaration_messages`. For `extract_decls`, this is always empty.
216+
217+
!!! warning "Deprecated"
218+
This field is deprecated. Use `declaration_messages` instead for new code."""
219+
220+
152221
def tool_messages_output(tool_name: str) -> OutputField:
153222
"""Generate tool_messages output with tool-specific description."""
154223
return {
@@ -496,65 +565,10 @@ class EndpointMetadata(TypedDict, total=False):
496565
"sections": {
497566
"__inputs__": True,
498567
"__outputs__": True,
499-
"Document Fields": """\
568+
"Document Fields": f"""\
500569
Each document in the `documents` dictionary contains:
501570
502-
??? "`declaration` · str · The content of this theorem declaration"
503-
The raw source code of this theorem declaration.
504-
505-
??? "`content` · str · Standalone content including theorem and dependencies"
506-
Complete, self-contained Lean code that includes the theorem and all its local dependencies. Can be compiled independently.
507-
508-
??? "`tokens` · list[str] · Raw tokens from the theorem"
509-
The theorem's source code split into tokens.
510-
511-
??? "`signature` · str · Theorem signature (everything before proof body)"
512-
The theorem signature, e.g., `theorem foo (x : Nat) : x = x`.
513-
514-
??? "`type` · str · Pretty-printed type of the theorem"
515-
The type of the theorem as pretty-printed by Lean.
516-
517-
??? "`type_hash` · int · Hash of the canonical type expression"
518-
Hash of the canonical, alpha-invariant type expression. Useful for deduplication.
519-
520-
??? "`is_sorry` · bool · Whether the theorem contains a sorry"
521-
True if the theorem's proof contains an explicit `sorry`.
522-
523-
??? "`index` · int · 0-based index in original file"
524-
Position of this theorem in the original file. Note: indices may not be contiguous (mutual definitions share indices).
525-
526-
??? "`line_pos` · int · 1-based line number where theorem starts"
527-
Line number where the theorem declaration begins.
528-
529-
??? "`end_line_pos` · int · 1-based line number where theorem ends"
530-
Line number where the theorem declaration ends.
531-
532-
??? "`proof_length` · int · Approximate number of tactics in proof"
533-
Rough measure of proof complexity based on tactic count.
534-
535-
??? "`tactic_counts` · dict[str, int] · Map of tactic names to occurrence counts"
536-
Breakdown of which tactics are used and how often.
537-
538-
??? "`local_type_dependencies` · list[str] · Transitive local dependencies of the type"
539-
Local declarations that the theorem's type depends on (transitively).
540-
541-
??? "`local_value_dependencies` · list[str] · Transitive local dependencies of the proof"
542-
Local declarations that the theorem's proof depends on (transitively).
543-
544-
??? "`external_type_dependencies` · list[str] · Immediate external dependencies of the type"
545-
External constants (builtins, imports) that appear in the type.
546-
547-
??? "`external_value_dependencies` · list[str] · Immediate external dependencies of the proof"
548-
External constants (builtins, imports) that appear in the proof.
549-
550-
??? "`local_syntactic_dependencies` · list[str] · Local constants explicitly written in source"
551-
Local constants that appear literally in source (not from notation/macro expansion).
552-
553-
??? "`external_syntactic_dependencies` · list[str] · External constants explicitly written in source"
554-
External constants that appear literally in source (not from notation/macro expansion).
555-
556-
??? "`theorem_messages` · dict · Messages specific to this theorem"
557-
Lean messages (`errors`, `warnings`, `infos`) specific to this theorem declaration in the original document.""",
571+
{DOCUMENT_FIELDS_BASE}""",
558572
"__python__": True,
559573
"__cli__": True,
560574
"__http__": True,
@@ -577,7 +591,7 @@ class EndpointMetadata(TypedDict, total=False):
577591
-d '{"content": "import Mathlib\\ntheorem foo : 1 = 1 := rfl", "environment": "lean-4.28.0"}' | jq""",
578592
"example_response": """\
579593
{
580-
"content": "import Mathlib\\n\\ntheorem foo : 1 = 1 := rfl\\n",
594+
"content": "import Mathlib\\ntheorem foo : 1 = 1 := rfl",
581595
"lean_messages": {
582596
"errors": [],
583597
"warnings": [],
@@ -594,16 +608,17 @@ class EndpointMetadata(TypedDict, total=False):
594608
},
595609
"documents": {
596610
"foo": {
611+
"kind": "theorem",
597612
"declaration": "theorem foo : 1 = 1 := rfl",
598613
"content": "import Mathlib\\n\\ntheorem foo : 1 = 1 := rfl",
599614
"tokens": ["theorem", "foo", ":", "1", "=", "1", ":=", "rfl"],
600615
"signature": "theorem foo : 1 = 1",
601616
"type": "1 = 1",
602-
"type_hash": 12345678901234567890,
617+
"type_hash": 1326858781,
603618
"is_sorry": false,
604619
"index": 0,
605-
"line_pos": 1,
606-
"end_line_pos": 1,
620+
"line_pos": 2,
621+
"end_line_pos": 2,
607622
"proof_length": 1,
608623
"tactic_counts": {},
609624
"local_value_dependencies": [],
@@ -612,7 +627,8 @@ class EndpointMetadata(TypedDict, total=False):
612627
"external_type_dependencies": ["Eq", "Nat", "OfNat.ofNat", "instOfNatNat"],
613628
"local_syntactic_dependencies": [],
614629
"external_syntactic_dependencies": ["rfl"],
615-
"theorem_messages": {"errors": [], "warnings": [], "infos": []}
630+
"theorem_messages": {"errors": [], "warnings": [], "infos": []},
631+
"declaration_messages": {"errors": [], "warnings": [], "infos": []}
616632
}
617633
}
618634
}""",
@@ -639,6 +655,143 @@ class EndpointMetadata(TypedDict, total=False):
639655
TIMINGS_OUTPUT,
640656
],
641657
},
658+
"extract_decls": {
659+
"title": "Extract Declarations",
660+
"details": "Split a file containing one or more declarations into smaller units, each containing a single declaration along with any required dependencies. Unlike extract_theorems, this works for all declaration kinds (def, theorem, lemma, abbrev, instance, structure, etc.).",
661+
"description": "split file into separate declarations with dependencies",
662+
"cli_output": {
663+
"mode": "multiple_files",
664+
"supports_output_dir": True,
665+
"output_dir_default": "extract_decls/",
666+
"output_file_pattern": "decl_{i}.lean",
667+
"metadata_to_stderr": False,
668+
"force_flag": True,
669+
},
670+
"cli_examples": [
671+
"# Extract to default directory\naxle extract-decls combined.lean --environment lean-4.28.0",
672+
"# Extract to custom directory\naxle extract-decls combined.lean -o my_decls/ --environment lean-4.28.0",
673+
"# Force overwrite\naxle extract-decls combined.lean -o my_decls/ -f --environment lean-4.28.0",
674+
"# Pipeline usage\ncat combined.lean | axle extract-decls - -o output/ --environment lean-4.28.0",
675+
],
676+
"web_ui_example_data": "eyJjb250ZW50Ijoic3RydWN0dXJlIFdlaWdodCB3aGVyZVxuICB2YWwgOiBOYXRcbiAgcG9zIDogdmFsID4gMCA6PSBieSBvbWVnYVxuXG5jbGFzcyBXZWlnaHRlZCAozrEgOiBUeXBlKSB3aGVyZVxuICB3ZWlnaHQgOiDOsSDihpIgV2VpZ2h0XG5cbmRlZiB0cml2aWFsV2VpZ2h0IDogV2VpZ2h0IDo9IOKfqDEsIGJ5IG9tZWdh4p+pXG5cbmluc3RhbmNlIDogV2VpZ2h0ZWQgTmF0IHdoZXJlXG4gIHdlaWdodCBfIDo9IHRyaXZpYWxXZWlnaHQiLCJpZ25vcmVfaW1wb3J0cyI6dHJ1ZSwiZW52aXJvbm1lbnQiOiJsZWFuLTQuMjguMCIsInRpbWVvdXRfc2Vjb25kcyI6MTIwfQ%3D%3D",
677+
"sections": {
678+
"__inputs__": True,
679+
"__outputs__": True,
680+
"Document Fields": f"""\
681+
Each document in the `documents` dictionary contains:
682+
683+
!!! note "Field applicability"
684+
Not all fields are meaningful for all declaration kinds. For example, `proof_length` and `tactic_counts` are only relevant for theorems/lemmas with tactic proofs. For other declaration kinds (def, abbrev, structure, class, inductive, etc.), these fields may be empty or zero.
685+
686+
{DOCUMENT_FIELDS_BASE}""",
687+
"__python__": True,
688+
"__cli__": True,
689+
"__http__": True,
690+
"__response__": True,
691+
},
692+
"python_example": """\
693+
result = await axle.extract_decls(
694+
content="import Mathlib\\ndef foo : Nat := 1\\ntheorem bar : foo = 1 := rfl",
695+
environment="lean-4.28.0",
696+
ignore_imports=False, # Optional
697+
timeout_seconds=120, # Optional
698+
)
699+
700+
print(result.content) # The processed Lean code
701+
for name, doc in result.documents.items():
702+
print(f"{name}: {doc.declaration}")""",
703+
"http_example": """\
704+
curl -s -X POST https://axle.axiommath.ai/api/v1/extract_decls \\
705+
-d '{"content": "import Mathlib\\ndef foo : Nat := 1\\ntheorem bar : foo = 1 := rfl", "environment": "lean-4.28.0"}' | jq""",
706+
"example_response": """\
707+
{
708+
"content": "import Mathlib\\ndef foo : Nat := 1\\ntheorem bar : foo = 1 := rfl",
709+
"lean_messages": {
710+
"errors": [],
711+
"warnings": [],
712+
"infos": []
713+
},
714+
"tool_messages": {
715+
"errors": [],
716+
"warnings": [],
717+
"infos": []
718+
},
719+
"timings": {
720+
"total_ms": 92,
721+
"parse_ms": 87
722+
},
723+
"documents": {
724+
"foo": {
725+
"kind": "def",
726+
"declaration": "def foo : Nat := 1",
727+
"content": "import Mathlib\\n\\ndef foo : Nat := 1",
728+
"tokens": ["def", "foo", ":", "Nat", ":=", "1"],
729+
"signature": "def foo : Nat",
730+
"type": "\u2115",
731+
"type_hash": 421340980,
732+
"is_sorry": false,
733+
"index": 0,
734+
"line_pos": 2,
735+
"end_line_pos": 2,
736+
"proof_length": 1,
737+
"tactic_counts": {},
738+
"local_value_dependencies": [],
739+
"local_type_dependencies": [],
740+
"external_value_dependencies": ["OfNat.ofNat", "Nat", "instOfNatNat"],
741+
"external_type_dependencies": ["Nat"],
742+
"local_syntactic_dependencies": [],
743+
"external_syntactic_dependencies": ["Nat"],
744+
"theorem_messages": {"errors": [], "warnings": [], "infos": []},
745+
"declaration_messages": {"errors": [], "warnings": [], "infos": []}
746+
},
747+
"bar": {
748+
"kind": "theorem",
749+
"declaration": "theorem bar : foo = 1 := rfl",
750+
"content": "import Mathlib\\n\\ndef foo : Nat := 1\\n\\ntheorem bar : foo = 1 := rfl",
751+
"tokens": ["theorem", "bar", ":", "foo", "=", "1", ":=", "rfl"],
752+
"signature": "theorem bar : foo = 1",
753+
"type": "foo = 1",
754+
"type_hash": 254164366,
755+
"is_sorry": false,
756+
"index": 1,
757+
"line_pos": 3,
758+
"end_line_pos": 3,
759+
"proof_length": 1,
760+
"tactic_counts": {},
761+
"local_value_dependencies": ["foo"],
762+
"local_type_dependencies": ["foo"],
763+
"external_value_dependencies": ["rfl", "Nat"],
764+
"external_type_dependencies": ["Eq", "Nat", "OfNat.ofNat", "instOfNatNat"],
765+
"local_syntactic_dependencies": ["foo"],
766+
"external_syntactic_dependencies": ["rfl"],
767+
"theorem_messages": {"errors": [], "warnings": [], "infos": []},
768+
"declaration_messages": {"errors": [], "warnings": [], "infos": []}
769+
}
770+
}
771+
}""",
772+
"inputs": [
773+
{
774+
**CONTENT_INPUT,
775+
"placeholder": "def foo : Nat := 1\ntheorem bar : foo = 1 := rfl",
776+
},
777+
IGNORE_IMPORTS_INPUT,
778+
ENVIRONMENT_INPUT,
779+
TIMEOUT_INPUT,
780+
],
781+
"outputs": [
782+
CONTENT_OUTPUT,
783+
LEAN_MESSAGES_OUTPUT,
784+
tool_messages_output("extraction"),
785+
{
786+
"name": "documents",
787+
"type": "dict",
788+
"description": "Declaration names mapped to self-contained documents",
789+
"details": """\
790+
Dictionary mapping declaration names to self-contained Lean code documents. Each key is a declaration name, and the value is a self-contained breakdown of the declaration, including a content field containing that declaration plus all dependencies it needs (imports, definitions, etc.).""",
791+
},
792+
TIMINGS_OUTPUT,
793+
],
794+
},
642795
"rename": {
643796
"title": "Rename Declarations",
644797
"details": "Rename declarations in Lean code.",

0 commit comments

Comments
 (0)