revit-api-docs 0.1.0__tar.gz → 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- revit_api_docs-0.3.0/CHANGELOG.md +263 -0
- revit_api_docs-0.3.0/PKG-INFO +239 -0
- revit_api_docs-0.3.0/README.md +205 -0
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/pipeline/api_parser/parse_chm.py +23 -12
- revit_api_docs-0.3.0/pipeline/build_data_v1_1.py +992 -0
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/pipeline/embedder/embed.py +64 -27
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/pyproject.toml +2 -2
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/revit_api_docs/__init__.py +1 -1
- revit_api_docs-0.3.0/revit_api_docs/bm25.py +239 -0
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/revit_api_docs/config.py +27 -0
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/revit_api_docs/data.py +50 -11
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/revit_api_docs/default_config.yaml +16 -2
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/revit_api_docs/embedder/providers/google.py +2 -1
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/revit_api_docs/embedder/providers/openai.py +4 -1
- revit_api_docs-0.3.0/revit_api_docs/environment.py +277 -0
- revit_api_docs-0.3.0/revit_api_docs/environment.yaml +306 -0
- revit_api_docs-0.3.0/revit_api_docs/reranker.py +595 -0
- revit_api_docs-0.3.0/revit_api_docs/retriever.py +1455 -0
- revit_api_docs-0.3.0/revit_api_docs/server.py +424 -0
- revit_api_docs-0.3.0/tests/conftest.py +210 -0
- revit_api_docs-0.3.0/tests/fixtures/retrieval_queries.yaml +614 -0
- revit_api_docs-0.3.0/tests/fixtures/retrieval_queries_v2.yaml +633 -0
- revit_api_docs-0.3.0/tests/test_bm25_index.py +285 -0
- revit_api_docs-0.3.0/tests/test_bm25_recall.py +136 -0
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/tests/test_data.py +52 -2
- revit_api_docs-0.3.0/tests/test_environment.py +177 -0
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/tests/test_package.py +1 -0
- revit_api_docs-0.3.0/tests/test_rerank.py +653 -0
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/tests/test_retriever.py +89 -31
- revit_api_docs-0.3.0/tests/test_server.py +375 -0
- revit_api_docs-0.3.0/tests/test_shipped_db.py +160 -0
- revit_api_docs-0.3.0/tests/test_vector_search.py +364 -0
- revit_api_docs-0.1.0/CHANGELOG.md +0 -32
- revit_api_docs-0.1.0/PKG-INFO +0 -139
- revit_api_docs-0.1.0/README.md +0 -105
- revit_api_docs-0.1.0/revit_api_docs/reranker.py +0 -177
- revit_api_docs-0.1.0/revit_api_docs/retriever.py +0 -901
- revit_api_docs-0.1.0/revit_api_docs/server.py +0 -244
- revit_api_docs-0.1.0/tests/conftest.py +0 -75
- revit_api_docs-0.1.0/tests/test_server.py +0 -151
- revit_api_docs-0.1.0/tests/test_shipped_db.py +0 -75
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/.gitignore +0 -0
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/LICENSE +0 -0
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/pipeline/__init__.py +0 -0
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/pipeline/api_parser/__init__.py +0 -0
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/pipeline/api_parser/quality_agent.py +0 -0
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/pipeline/demo_dual_store.py +0 -0
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/pipeline/demo_production_real.py +0 -0
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/pipeline/demo_real_golden.py +0 -0
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/pipeline/demo_real_scoring.py +0 -0
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/pipeline/demo_scoring.py +0 -0
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/pipeline/demo_sdk_cleaning.py +0 -0
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/pipeline/embedder/__init__.py +0 -0
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/pipeline/knowledge_builder/__init__.py +0 -0
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/pipeline/run_all.ipynb +0 -0
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/pipeline/sdk_parser/__init__.py +0 -0
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/pipeline/sdk_parser/extract.py +0 -0
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/pipeline/sdk_parser/quality_agent.py +0 -0
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/revit_api_docs/__main__.py +0 -0
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/revit_api_docs/embedder/__init__.py +0 -0
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/revit_api_docs/embedder/providers/__init__.py +0 -0
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/revit_api_docs/embedder/providers/base.py +0 -0
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/revit_api_docs/llm_client.py +0 -0
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/revit_api_docs/prompts/__init__.py +0 -0
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/revit_api_docs/prompts/loader.py +0 -0
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/revit_api_docs/prompts/pipeline.api_quality_stage1_no_html.md +0 -0
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/revit_api_docs/prompts/pipeline.api_quality_stage1_system.md +0 -0
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/revit_api_docs/prompts/pipeline.api_quality_stage1_with_html.md +0 -0
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/revit_api_docs/prompts/pipeline.api_quality_stage2.md +0 -0
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/revit_api_docs/prompts/pipeline.api_quality_stage2_system.md +0 -0
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/revit_api_docs/prompts/pipeline.rewrite_query.md +0 -0
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/revit_api_docs/prompts/pipeline.rewrite_query_system.md +0 -0
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/revit_api_docs/prompts/pipeline.sdk_extract_readme_system.md +0 -0
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/revit_api_docs/prompts/pipeline.sdk_extract_readme_user.md +0 -0
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/revit_api_docs/prompts/pipeline.sdk_golden_code.md +0 -0
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/revit_api_docs/prompts/pipeline.sdk_golden_code_system.md +0 -0
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/revit_api_docs/prompts/pipeline.sdk_quality_file_batch.md +0 -0
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/revit_api_docs/prompts/pipeline.sdk_quality_file_system.md +0 -0
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/revit_api_docs/prompts/pipeline.sdk_quality_project.md +0 -0
- {revit_api_docs-0.1.0 → revit_api_docs-0.3.0}/revit_api_docs/prompts/pipeline.sdk_quality_project_system.md +0 -0
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented here. The format follows
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versions follow
|
|
5
|
+
[Semantic Versioning](https://semver.org/).
|
|
6
|
+
|
|
7
|
+
## [Unreleased]
|
|
8
|
+
|
|
9
|
+
## [0.3.0] - 2026-10-26
|
|
10
|
+
|
|
11
|
+
Vector hits now come back as the entries they describe and count also
|
|
12
|
+
without a reranker; reranking picks its provider from the keys that are set.
|
|
13
|
+
The data set `v1.1-data` adds constructor and interface member pages, and its
|
|
14
|
+
vector store lines up with the SQLite rows.
|
|
15
|
+
|
|
16
|
+
**Upgrading from 0.2.0** (`uvx --refresh revit-api-docs`): on the first start the server replaces an installed
|
|
17
|
+
`v1.0-data` (its `manifest.json` names the old release) with `v1.1-data`, a
|
|
18
|
+
download of 267 MB (all four files); a data directory without a
|
|
19
|
+
manifest (a hand-copied tree) is used as it is. With an embedding key and a
|
|
20
|
+
tree that still holds `v1.0-data`, the first vector query logs the warning
|
|
21
|
+
`vector_store_misaligned`: its record ids do not line up with the SQLite rows,
|
|
22
|
+
and hits are matched by entry name. Without any key nothing changes beyond the
|
|
23
|
+
new entries. Reranker choice: with only `COHERE_API_KEY` set Cohere still
|
|
24
|
+
reranks; with `TYPESAFE_API_KEY` set Jev now reranks without
|
|
25
|
+
`REVIT_API_DOCS_RERANK_PROVIDER=jev` (set the provider to `cohere` to keep
|
|
26
|
+
Cohere).
|
|
27
|
+
|
|
28
|
+
### Added
|
|
29
|
+
|
|
30
|
+
- Data set `v1.1-data` (`RELEASE_TAG`; the download URL and SHA-256 list in
|
|
31
|
+
`data.py` follow it): the 27,596 entries of `v1.0-data` are kept unchanged
|
|
32
|
+
under the same ids, and 1,266 pages of the same reference are appended
|
|
33
|
+
(ids 27,597-28,862): 1,040 constructor pages (`XYZ(Double, Double, Double)
|
|
34
|
+
Constructor`, `Transaction(Document, String) Constructor`, overload lists)
|
|
35
|
+
and 226 members whose C# signature has no `public`, mostly interface
|
|
36
|
+
members (`IExternalEventHandler.Execute`, `IConnector.Origin`,
|
|
37
|
+
`IFailuresPreprocessor.PreprocessFailures`) and explicit interface
|
|
38
|
+
implementations. 28,862 entries in all. Source: `RevitAPI.chm` of the
|
|
39
|
+
Revit 2026.3 SDK, whose pages are the same set as the Revit 2026 reference
|
|
40
|
+
the first release was built from. The API vector store is rebuilt from the
|
|
41
|
+
new SQLite with the same model (`text-embedding-3-large`, 3072 dimensions):
|
|
42
|
+
one record per row and every record id is its row id, so the first vector
|
|
43
|
+
query no longer logs `vector_store_misaligned` (`download` reports
|
|
44
|
+
`aligned`). The SDK files (`revit_sdk.db`, `chromadb_code.tar.gz`) are the
|
|
45
|
+
`v1.0-data` ones.
|
|
46
|
+
- The vector documents are now `name : summary` (`v1.0-data` embedded mostly
|
|
47
|
+
the entry name alone: 21,952 of its 28,863 records); on the 223 test
|
|
48
|
+
queries this raised fused nDCG@5 without a reranker from 0.610 to 0.647
|
|
49
|
+
(task requests 0.438 to 0.459) and left it with Jev at 0.842 against 0.846
|
|
50
|
+
(task requests 0.778 against 0.794).
|
|
51
|
+
- `pipeline/build_data_v1_1.py` (sdist only): builds `v1.1-data` from the
|
|
52
|
+
`v1.0-data` SQLite and the CHM pages: appends the pages the base lacks
|
|
53
|
+
(pages whose name is in the base under another `full_id`, or whose content
|
|
54
|
+
is a base row's under a name the v1.0 rewrite changed, are listed and not
|
|
55
|
+
appended), runs the quality agent on the new rows only, re-embeds every
|
|
56
|
+
row, packages the four release files with `SHA256SUMS.txt` and checks the
|
|
57
|
+
vector store against the rows without an API call.
|
|
58
|
+
|
|
59
|
+
### Fixed
|
|
60
|
+
|
|
61
|
+
- Vector search returned unrelated entries. The vector store of the
|
|
62
|
+
`v1.0-data` release numbers its 28,863 API records independently of the
|
|
63
|
+
27,596 rows of `revit_api.db` (2 ids name the same entry in both), and hits
|
|
64
|
+
were looked up by record id. A hit is now matched to the row whose entry
|
|
65
|
+
name equals the record's `name` metadata (the row with the record's own id
|
|
66
|
+
when it carries that name; among rows sharing a name the one with the
|
|
67
|
+
record's `full_id` or `info`, else the lowest id). 27,591 records (95.6%)
|
|
68
|
+
reach 27,512 rows (99.7%); records without a row are dropped. The SDK sample
|
|
69
|
+
store's ids match its rows, and matching by project name keeps them. The
|
|
70
|
+
name map is built on the first vector query and kept in memory.
|
|
71
|
+
- Consistency probe: on the first vector query 50 records of each vector
|
|
72
|
+
collection are compared with SQLite. When fewer than 90% of the sampled ids
|
|
73
|
+
name the same entry as the row with that id, the warning
|
|
74
|
+
`vector_store_misaligned` is logged and hits are matched by name (`v1.0-data`:
|
|
75
|
+
0/50 ids, 49/50 names). When fewer than 50% of the sampled names are found
|
|
76
|
+
either, vector search is off for the process and keyword search answers
|
|
77
|
+
alone. `revit-api-docs download` prints the check for the installed data set.
|
|
78
|
+
- A second retriever in the same process could not open the vector store
|
|
79
|
+
("An instance of Chroma already exists ... with different settings"): each
|
|
80
|
+
ChromaDB client now gets its own `Settings` object.
|
|
81
|
+
|
|
82
|
+
### Changed
|
|
83
|
+
|
|
84
|
+
- Hybrid ranking by reciprocal rank fusion: the vector hits and the BM25 hits,
|
|
85
|
+
`retrieval.api.top_k` (30) of each, are fused with score = sum of
|
|
86
|
+
1 / (60 + rank), and the best 30 go to the reranker; without a reranker they
|
|
87
|
+
are cut to `top_k`. On equal scores a keyword hit comes first. Before, the
|
|
88
|
+
two lists were merged by distances on different scales, so without a
|
|
89
|
+
reranker vector-only hits never reached the top 5, and up to 60 candidates
|
|
90
|
+
went to the reranker. Without an embedding key the BM25 order and results
|
|
91
|
+
are unchanged. On 223 English test queries without reranking (measured on
|
|
92
|
+
`v1.1-data`): nDCG@5 0.557 with BM25 alone, 0.647 fused, and 0.355 -> 0.459
|
|
93
|
+
on the 113 multi-step task requests, whose answer is among the top 30 for
|
|
94
|
+
82% instead of 72% of them.
|
|
95
|
+
- The default rerank provider is `auto`: Jev when `TYPESAFE_API_KEY` is set,
|
|
96
|
+
otherwise Cohere when `COHERE_API_KEY` is set, otherwise none.
|
|
97
|
+
`REVIT_API_DOCS_RERANK_PROVIDER` (now `auto`, `jev`, `cohere` or `none`)
|
|
98
|
+
still wins, and the `Rerank:` line names the provider that ran. README:
|
|
99
|
+
Jev is the recommended reranker, Cohere optional and the fallback for Jev.
|
|
100
|
+
- Cohere requests time out after 20 s instead of 10 s (the same as Jev); 10 s
|
|
101
|
+
cut off about 1% of calls.
|
|
102
|
+
- `search_revit_api` and `get_code_examples` are unchanged: names,
|
|
103
|
+
parameters and the first output line. The tool description now counts
|
|
104
|
+
28,862 entries.
|
|
105
|
+
- CHM parser (`pipeline/api_parser/parse_chm.py`): `parse_single_html` and
|
|
106
|
+
`parse_all_api_html` take `keep_constructors` (default `False`, the old
|
|
107
|
+
behaviour); the C# signature no longer has to contain `public` (interface
|
|
108
|
+
members such as `void Execute(UIApplication app)` were skipped as a whole
|
|
109
|
+
page); a page with neither a signature nor a members table is still
|
|
110
|
+
skipped.
|
|
111
|
+
- `pipeline.embedder.embed.embed_api_data(..., resume=False,
|
|
112
|
+
document_template="NS")`: with `resume=True` the collection is kept and
|
|
113
|
+
only missing row ids are embedded; `document_template` picks the embedded
|
|
114
|
+
text per API row (`NS` `name : summary`, the default and the `v1.1-data`
|
|
115
|
+
store; `FS` `full_id : summary`, the earlier behaviour; `N` the entry name)
|
|
116
|
+
and is recorded in `meta.json`. `pipeline/build_data_v1_1.py
|
|
117
|
+
--document-template` passes it on (default `NS`).
|
|
118
|
+
|
|
119
|
+
## [0.2.0] - 2026-10-26
|
|
120
|
+
|
|
121
|
+
Better candidates without any key, and an opt-in relevance check: BM25 keyword
|
|
122
|
+
search over an SQLite FTS5 index, optional Jev reranking with a calibrated
|
|
123
|
+
relevance per entry and abstention, a streamable HTTP transport, and curated
|
|
124
|
+
development-environment notes.
|
|
125
|
+
|
|
126
|
+
**Upgrading from 0.1.0** (`uvx --refresh revit-api-docs`): the first search
|
|
127
|
+
builds `sqlite/revit_api_fts.db` (an FTS5 index, 11.8 MB) next to the data set
|
|
128
|
+
in under a second. `search_revit_api` output starts with `Rerank: <reranker>;
|
|
129
|
+
data set: Revit 2026`. Abstention is new and opt-in:
|
|
130
|
+
`REVIT_API_DOCS_MIN_RELEVANCE` (Jev only) only decides whether to abstain and
|
|
131
|
+
drops no entry; the abstention line does not claim that the member is missing.
|
|
132
|
+
|
|
133
|
+
### Added
|
|
134
|
+
|
|
135
|
+
- Jev rerank provider (TypeSafe System One, `POST https://api.typesafe.ai/v1/systemone`,
|
|
136
|
+
one `noul` question per candidate): `REVIT_API_DOCS_RERANK_PROVIDER=jev` with
|
|
137
|
+
`TYPESAFE_API_KEY`. Up to 30 candidates per request, 2 requests in flight,
|
|
138
|
+
2 retries with backoff on 429/529/5xx/timeouts, 20 s timeout. A failed or
|
|
139
|
+
unconfigured Jev call falls back to Cohere (when `COHERE_API_KEY` is set) or
|
|
140
|
+
to no reranking.
|
|
141
|
+
- `search_revit_api` output starts with the reranker that ran
|
|
142
|
+
(`Rerank: jev | cohere | none`, plus `(unavailable: jev)` after a fallback);
|
|
143
|
+
Jev-ranked entries carry `Relevance: 0.00-1.00`.
|
|
144
|
+
- Abstention: with Jev and `REVIT_API_DOCS_MIN_RELEVANCE`, when no entry
|
|
145
|
+
reaches the threshold the output starts with "No entry in the Revit 2026
|
|
146
|
+
data set scored high enough for this query (best relevance x < y)" followed
|
|
147
|
+
by the low-scoring candidates. Other providers never abstain.
|
|
148
|
+
- Streamable HTTP transport: `revit-api-docs serve --transport http --host
|
|
149
|
+
127.0.0.1 --port 8765` (endpoint `/mcp`); stdio remains the default. A
|
|
150
|
+
non-loopback `--host` logs a warning: there is no built-in authentication.
|
|
151
|
+
- Development-environment notes: a curated English corpus shipped with the
|
|
152
|
+
package (`environment.yaml`: target framework, SDK, manifest, reference
|
|
153
|
+
packages for Revit 2024-2027, each with a release range and a source URL),
|
|
154
|
+
matched by keywords. `search_revit_api` appends up to five matching notes,
|
|
155
|
+
also while the data set is still downloading and without any key;
|
|
156
|
+
`revit-api-docs environment [query] [--revit 2027]` prints them. The
|
|
157
|
+
`jev-data-handling` note points at TypeSafe's data processing terms.
|
|
158
|
+
- Retrieval regression fixture `tests/fixtures/retrieval_queries.yaml`: 60
|
|
159
|
+
English queries with verified gold rows in the v1.0-data reference (50
|
|
160
|
+
answerable, 10 not). `tests/test_bm25_recall.py` runs them against the
|
|
161
|
+
shipped data set when it is installed: gold in the BM25 top 30 for at least
|
|
162
|
+
44 of 50 (measured 45), hit@5 at least 36 of 50 (measured 38), and a
|
|
163
|
+
non-empty candidate list for every unanswerable query. No network.
|
|
164
|
+
- A second regression fixture, `tests/fixtures/retrieval_queries_v2.yaml`: 60
|
|
165
|
+
more English queries (40 answerable, 20 not, 9 of those next to a real API,
|
|
166
|
+
such as a class name used as a member or a misspelling), none shared with
|
|
167
|
+
the first set. `tests/test_bm25_recall.py` runs both sets;
|
|
168
|
+
for this one: gold in the BM25 top 30 for at least 33 of 40 (measured 34),
|
|
169
|
+
hit@5 at least 25 of 40 (measured 27), and candidates for at least 19 of the
|
|
170
|
+
20 unanswerable queries (measured 19).
|
|
171
|
+
- `close()` on the rerank providers releases their HTTP client.
|
|
172
|
+
- README: when to turn on Jev (`REVIT_API_DOCS_RERANK_PROVIDER=jev` with a
|
|
173
|
+
TypeSafe key; nDCG@5 0.675 -> 0.871 on the test queries, about $0.23 per
|
|
174
|
+
1,000 queries), what a `REVIT_API_DOCS_MIN_RELEVANCE` of 0.15 filters and
|
|
175
|
+
what it does not, and why not 0.5. Defaults are unchanged.
|
|
176
|
+
|
|
177
|
+
### Changed
|
|
178
|
+
|
|
179
|
+
- The `Rerank:` line also names the data set the entries come from: `Rerank:
|
|
180
|
+
<provider>[ (unavailable: ...)]; data set: Revit <version>`, the version
|
|
181
|
+
taken from the configuration (`revit_version`, 2026 for the v1.0-data
|
|
182
|
+
release). It stays the first line, or the second after an abstention line,
|
|
183
|
+
so an answer can cite the data set version next to a result; the tool
|
|
184
|
+
description and the server instructions say so. The `Rerank:` prefix is
|
|
185
|
+
unchanged.
|
|
186
|
+
- `REVIT_API_DOCS_MIN_RELEVANCE` only decides whether to abstain. When at
|
|
187
|
+
least one entry reaches it, the entries below it are no longer dropped:
|
|
188
|
+
every reranked entry comes back (up to `top_k`) with its `Relevance`, so a
|
|
189
|
+
correct entry scored just under the threshold stays in the list. Abstention
|
|
190
|
+
itself, and the output format, are unchanged.
|
|
191
|
+
- README and the `jev-rerank-provider` environment note describe the
|
|
192
|
+
threshold as a relevance filter: at 0.15 it filters out clearly unrelated
|
|
193
|
+
queries (not about Revit, types the data set does not have) and abstains
|
|
194
|
+
on about 2.5% of the queries that have an answer, but it cannot spot a
|
|
195
|
+
misspelt or misplaced member name, for which the closest real API usually
|
|
196
|
+
comes first and a compile check decides. "No entry scored high enough" is
|
|
197
|
+
described as "nothing relevant, or worded differently", not as "the member
|
|
198
|
+
does not exist"; the README no longer says the value is being validated.
|
|
199
|
+
- The rerank HTTP clients (Jev and Cohere) keep idle connections open for 5
|
|
200
|
+
minutes (`keepalive_expiry=300`; httpx closes them after 5 s), so a query
|
|
201
|
+
after a pause can reuse the connection instead of setting up TLS again.
|
|
202
|
+
The other connection limits stay at httpx's defaults.
|
|
203
|
+
- Keyword search over the API reference ranks with BM25 on an SQLite FTS5
|
|
204
|
+
index instead of LIKE substring scoring. The index is a separate file,
|
|
205
|
+
`sqlite/revit_api_fts.db` next to `revit_api.db` (which is never written),
|
|
206
|
+
built on first use in under a second and rebuilt when the source database's
|
|
207
|
+
SHA-256 or the index format changes; the installer neither downloads nor
|
|
208
|
+
flags it. Identifiers also match by their camel-case parts, so misspelt or
|
|
209
|
+
unknown names (`FiltredElementColector`) get candidates instead of "No API
|
|
210
|
+
entries found". Without vector search the keyword search now hands the
|
|
211
|
+
reranker `retrieval.api.top_k` (30) candidates instead of the requested
|
|
212
|
+
count; with vector search it adds the requested count, as before. A Python
|
|
213
|
+
whose sqlite3 lacks FTS5 keeps the LIKE scorer and logs one warning.
|
|
214
|
+
- The Jev and Cohere rerank providers keep one HTTP client per instance, and
|
|
215
|
+
with it the open connection, instead of building one per call. Against the
|
|
216
|
+
hosted Jev API a Jev-reranked `search_revit_api` call took about 2.1 s
|
|
217
|
+
before (10 candidates); now the first call of a process takes about 2.3 s
|
|
218
|
+
and later ones about 0.4 s (30 candidates).
|
|
219
|
+
- The abstention line no longer claims the class or member may not exist: it
|
|
220
|
+
says that no entry scored high enough and that either the member is absent
|
|
221
|
+
from this version or the data set has it under a different name or wording.
|
|
222
|
+
The tool description and server instructions say the same. A low best score
|
|
223
|
+
cannot tell a missing member from one the candidate search did not bring up.
|
|
224
|
+
- The embedding providers look up their API key before importing the SDK, so
|
|
225
|
+
keyword-only runs (no key) no longer import `openai`; `search` starts about
|
|
226
|
+
2 s faster.
|
|
227
|
+
- `search` and `download` log plain `logger: message` lines to stderr at
|
|
228
|
+
WARNING (`-v` for INFO), with `httpx` request lines hidden; the MCP server's
|
|
229
|
+
logging is unchanged. The index/content mismatch of the shipped data set is
|
|
230
|
+
logged at INFO instead of WARNING.
|
|
231
|
+
- Download progress: on a terminal the line is redrawn in place; in host logs
|
|
232
|
+
and pipes one line per 10% instead of one per second.
|
|
233
|
+
- Tool descriptions and the server instructions state that queries are English
|
|
234
|
+
only.
|
|
235
|
+
- The Cohere reranker shares a provider interface with Jev; its requests and
|
|
236
|
+
its fall-back-to-input-order behaviour are unchanged.
|
|
237
|
+
|
|
238
|
+
## [0.1.0] - 2026-09-20
|
|
239
|
+
|
|
240
|
+
First release, split out of the `revit-api-rag` repository (working-tree copy,
|
|
241
|
+
no git history).
|
|
242
|
+
|
|
243
|
+
### Added
|
|
244
|
+
|
|
245
|
+
- MCP server `revit-api-docs` (stdio) with two read-only tools:
|
|
246
|
+
`search_revit_api(query, top_k)` and `get_code_examples(query, top_k)`.
|
|
247
|
+
- Data set as GitHub Release `v1.0-data` (Revit 2026 API reference SQLite,
|
|
248
|
+
SDK samples SQLite, two ChromaDB indexes); downloaded on first run into the
|
|
249
|
+
per-user data directory, SHA-256 verified, resumable. `REVIT_API_DOCS_DATA_DIR`
|
|
250
|
+
overrides the location; `revit-api-docs download` prefetches.
|
|
251
|
+
- Keyword search over SQLite works with no API key; an OpenAI-compatible
|
|
252
|
+
embedding key adds vector search, `COHERE_API_KEY` adds reranking. Embedding
|
|
253
|
+
or rerank failures fall back to keyword search instead of erroring.
|
|
254
|
+
- CLI: `serve` (default), `download`, `search <query> [--examples] [--top-k]`.
|
|
255
|
+
- Offline data pipeline (`pipeline/`, `uv sync --extra pipeline`) from the old
|
|
256
|
+
repository, importing the package's shared retriever, LLM client and prompts.
|
|
257
|
+
- CI (tests + build on Linux/Windows, Python 3.11/3.13) and PyPI Trusted
|
|
258
|
+
Publishing on version tags.
|
|
259
|
+
|
|
260
|
+
[Unreleased]: https://github.com/revitbridge/revit-api-docs/compare/v0.3.0...HEAD
|
|
261
|
+
[0.3.0]: https://github.com/revitbridge/revit-api-docs/compare/v0.2.0...v0.3.0
|
|
262
|
+
[0.2.0]: https://github.com/revitbridge/revit-api-docs/compare/v0.1.0...v0.2.0
|
|
263
|
+
[0.1.0]: https://github.com/revitbridge/revit-api-docs/releases/tag/v0.1.0
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: revit-api-docs
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: Revit API reference search for MCP hosts: local semantic + keyword lookup over the Revit 2026 API docs and SDK samples
|
|
5
|
+
Project-URL: Homepage, https://github.com/revitbridge/revit-api-docs
|
|
6
|
+
Project-URL: Issues, https://github.com/revitbridge/revit-api-docs/issues
|
|
7
|
+
Project-URL: Changelog, https://github.com/revitbridge/revit-api-docs/blob/main/CHANGELOG.md
|
|
8
|
+
Project-URL: Data, https://github.com/revitbridge/revit-api-docs/releases/tag/v1.1-data
|
|
9
|
+
Author: revitbridge
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: api-docs,bim,mcp,rag,revit
|
|
13
|
+
Classifier: Development Status :: 3 - Alpha
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Topic :: Scientific/Engineering
|
|
21
|
+
Requires-Python: >=3.11
|
|
22
|
+
Requires-Dist: chromadb<2,>=1
|
|
23
|
+
Requires-Dist: httpx>=0.27
|
|
24
|
+
Requires-Dist: mcp<3,>=2
|
|
25
|
+
Requires-Dist: openai<3,>=1
|
|
26
|
+
Requires-Dist: pyyaml>=6
|
|
27
|
+
Provides-Extra: pipeline
|
|
28
|
+
Requires-Dist: beautifulsoup4>=4.12; extra == 'pipeline'
|
|
29
|
+
Requires-Dist: google-genai>=1; extra == 'pipeline'
|
|
30
|
+
Requires-Dist: tqdm>=4.66; extra == 'pipeline'
|
|
31
|
+
Requires-Dist: tree-sitter-c-sharp>=0.20; extra == 'pipeline'
|
|
32
|
+
Requires-Dist: tree-sitter>=0.20; extra == 'pipeline'
|
|
33
|
+
Description-Content-Type: text/markdown
|
|
34
|
+
|
|
35
|
+
# revit-api-docs
|
|
36
|
+
|
|
37
|
+
Revit API reference search as an MCP server: two read-only tools over a local
|
|
38
|
+
copy of the Revit 2026 API documentation (28,862 classes, constructors,
|
|
39
|
+
methods, properties and enums) and the official SDK samples (153 projects).
|
|
40
|
+
|
|
41
|
+
**Optional.** It exists for models that do not know the Revit API well. If
|
|
42
|
+
your model already writes correct Revit code, you do not need it;
|
|
43
|
+
[revit-bridge](https://github.com/revitbridge/revit-bridge) works without it.
|
|
44
|
+
It never talks to Revit and it never calls a model itself.
|
|
45
|
+
|
|
46
|
+
Queries are **English only**: the corpus is the English API reference. A host
|
|
47
|
+
model that talks to its user in another language rewrites the request into
|
|
48
|
+
English API names or English task keywords before calling a tool.
|
|
49
|
+
|
|
50
|
+
## Install
|
|
51
|
+
|
|
52
|
+
Prerequisites: Python 3.11+ with [`uv`](https://docs.astral.sh/uv/) (for
|
|
53
|
+
`uvx`), about 700 MB of disk for the data set, network for the first run.
|
|
54
|
+
|
|
55
|
+
**Claude Desktop** — `claude_desktop_config.json`:
|
|
56
|
+
|
|
57
|
+
```json
|
|
58
|
+
{
|
|
59
|
+
"mcpServers": {
|
|
60
|
+
"revit-api-docs": {
|
|
61
|
+
"command": "uvx",
|
|
62
|
+
"args": ["revit-api-docs"]
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**Claude Code**:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
claude mcp add revit-api-docs -- uvx revit-api-docs
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**Any MCP client** — run `uvx revit-api-docs` as a stdio server.
|
|
75
|
+
|
|
76
|
+
**Any MCP client over HTTP** — run the server with the MCP streamable HTTP
|
|
77
|
+
transport and point the client at `/mcp`:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
uvx revit-api-docs serve --transport http --host 127.0.0.1 --port 8765
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
```json
|
|
84
|
+
{
|
|
85
|
+
"mcpServers": {
|
|
86
|
+
"revit-api-docs": {
|
|
87
|
+
"type": "http",
|
|
88
|
+
"url": "http://127.0.0.1:8765/mcp"
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
(Claude Code: `claude mcp add --transport http revit-api-docs http://127.0.0.1:8765/mcp`.)
|
|
95
|
+
stdio stays the default. The HTTP transport has no built-in authentication:
|
|
96
|
+
keep it on a loopback address, or put it behind a reverse proxy that
|
|
97
|
+
authenticates; the server logs a warning when `--host` is not a loopback
|
|
98
|
+
address.
|
|
99
|
+
|
|
100
|
+
On the first start the server downloads the data set (267 MB, four files) from
|
|
101
|
+
this repository's [`v1.1-data` release](https://github.com/revitbridge/revit-api-docs/releases/tag/v1.1-data)
|
|
102
|
+
into `%LOCALAPPDATA%\revit-api-docs` (Windows) or `~/.local/share/revit-api-docs`
|
|
103
|
+
(Linux; `~/Library/Application Support/revit-api-docs` on macOS), verifies each
|
|
104
|
+
file's SHA-256 and unpacks the vector stores. Tool calls made while that runs
|
|
105
|
+
return a short progress message instead of results. To do it ahead of time:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
uvx revit-api-docs download
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
From a checkout: `uv sync` then `uv run revit-api-docs`.
|
|
112
|
+
|
|
113
|
+
## Use
|
|
114
|
+
|
|
115
|
+
Two tools, both read-only:
|
|
116
|
+
|
|
117
|
+
- `search_revit_api(query, top_k=10)` — API entries with signature, parameters
|
|
118
|
+
and remarks. Query with an API name (`Wall.Create`,
|
|
119
|
+
`FilteredElementCollector OfCategory`) or a short task (`create floor from
|
|
120
|
+
boundary`). The first line names the reranker that ordered the entries
|
|
121
|
+
(`jev`, `cohere` or `none`) and the data set they come from, for example
|
|
122
|
+
`Rerank: none; data set: Revit 2026`; after an abstention line it is the
|
|
123
|
+
second line. Development-environment questions (`target framework for
|
|
124
|
+
Revit 2027 add-in`) also get up to five curated environment notes
|
|
125
|
+
(framework, SDK, manifest, reference packages per Revit release, each with
|
|
126
|
+
its source); these ship with the package and work before the data set is
|
|
127
|
+
installed and without any key.
|
|
128
|
+
- `get_code_examples(query, top_k=3)` — C# from the SDK samples that use the
|
|
129
|
+
matching APIs, with the project name and the APIs each sample touches.
|
|
130
|
+
|
|
131
|
+
Without any API key the server answers from keyword search over the SQLite
|
|
132
|
+
reference: BM25 over a full-text index of entry names, IDs, summaries and
|
|
133
|
+
signatures, where identifiers also match by their camel-case parts, so a
|
|
134
|
+
misspelt or unknown name still gets candidates. The index (11.8 MB) is built
|
|
135
|
+
next to the data set on first use (under a second). With an embedding key it
|
|
136
|
+
adds semantic search over the vector store and fuses the two rankings by rank,
|
|
137
|
+
which helps most with task descriptions that do not name the API. With a
|
|
138
|
+
TypeSafe key it reranks the candidates with Jev, which returns a calibrated
|
|
139
|
+
relevance per entry; with only a Cohere key it reranks with Cohere. With a Jev
|
|
140
|
+
threshold set and no entry reaching it, the output starts with an abstention
|
|
141
|
+
line and then lists the candidates with their relevance, for reference. See
|
|
142
|
+
Configure.
|
|
143
|
+
|
|
144
|
+
Try it from a terminal (installs the data set if needed):
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
uvx revit-api-docs search "Wall.Create"
|
|
148
|
+
uvx revit-api-docs search "rotate element around axis" --examples
|
|
149
|
+
uvx revit-api-docs environment --revit 2027 # environment notes, no data set needed
|
|
150
|
+
uvx revit-api-docs environment "target framework" # notes a query matches
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## Configure
|
|
154
|
+
|
|
155
|
+
All settings are environment variables; there is no config file to edit.
|
|
156
|
+
|
|
157
|
+
| Variable | Default | Meaning |
|
|
158
|
+
|---|---|---|
|
|
159
|
+
| `REVIT_API_DOCS_DATA_DIR` | `%LOCALAPPDATA%\revit-api-docs` (Windows), `~/.local/share/revit-api-docs` (Linux), `~/Library/Application Support/revit-api-docs` (macOS) | Where the data set lives. An existing tree with `sqlite/` and `chromadb/` from the old `revit-api-rag` checkout works as is |
|
|
160
|
+
| `REVIT_API_DOCS_EMBEDDING_API_KEY` | *(unset)* | Key for the embedding endpoint; turns on semantic (vector) search. `OPENROUTER_API_KEY` is used when this is unset |
|
|
161
|
+
| `REVIT_API_DOCS_EMBEDDING_BASE_URL` | `https://openrouter.ai/api/v1` | Any OpenAI-compatible `/embeddings` endpoint |
|
|
162
|
+
| `REVIT_API_DOCS_EMBEDDING_MODEL` | `openai/text-embedding-3-large` | Must produce the same 3072-dimensional space the shipped vectors were built with (`text-embedding-3-large`); another model makes vector search return noise |
|
|
163
|
+
| `TYPESAFE_API_KEY` | *(unset)* | Key for TypeSafe System One (Jev), the recommended reranker: with the default provider `auto` setting this key is enough. At most 30 candidates per request, 2 requests in flight, 2 retries, 20 s timeout |
|
|
164
|
+
| `COHERE_API_KEY` | *(unset)* | Optional. Cohere `rerank-v3.5` (native REST API, 20 s timeout): reranks when it is the only rerank key set, and is the fallback for a failed Jev call when both are set |
|
|
165
|
+
| `REVIT_API_DOCS_RERANK_PROVIDER` | `auto` | `auto`, `jev`, `cohere` or `none`. `auto` reranks with Jev when `TYPESAFE_API_KEY` is set, otherwise with Cohere when `COHERE_API_KEY` is set, otherwise not at all; an explicit value wins. With Jev, a failed or unconfigured call falls back to Cohere when `COHERE_API_KEY` is set, otherwise to no reranking; the first output line says which one ran |
|
|
166
|
+
| `REVIT_API_DOCS_JEV_MODEL` | `jev-latest` | Jev model or alias; pin a version such as `jev-1.14.0` for reproducible results |
|
|
167
|
+
| `REVIT_API_DOCS_MIN_RELEVANCE` | *(unset)* | Probability 0-1 (`retrieval.api.min_relevance`). Only honoured while Jev ranks the results, and it only decides whether to abstain: no entry is dropped, every result keeps its `Relevance` line. When no entry reaches it, `search_revit_api` starts with "No entry in the Revit 2026 data set scored high enough for this query", notes that the member may be absent from this version or listed under a different name or wording, and lists the low-scoring candidates for reference. No effect with Cohere or without reranking. See "Reranking with Jev" below |
|
|
168
|
+
| `REVIT_API_DOCS_RELEASE_URL` | this repository's `v1.1-data` release | Mirror for the data files; the SHA-256 checks still apply |
|
|
169
|
+
| `HTTPS_PROXY` / `HTTP_PROXY` | *(unset)* | Proxy for the embedding and rerank calls |
|
|
170
|
+
|
|
171
|
+
Pass them through the `env` block of your MCP host's server entry.
|
|
172
|
+
|
|
173
|
+
Recommended setup: a `TYPESAFE_API_KEY` (Jev reranking), plus an embedding key
|
|
174
|
+
when requests describe multi-step tasks rather than name APIs. Without any key
|
|
175
|
+
the server runs on BM25 keyword search alone.
|
|
176
|
+
|
|
177
|
+
**Reranking with Jev.** Jev is the recommended reranker, and the default
|
|
178
|
+
provider (`auto`) uses it whenever `TYPESAFE_API_KEY` is set. Cohere is
|
|
179
|
+
optional: `auto` uses it when only `COHERE_API_KEY` is set, and with both keys
|
|
180
|
+
it is the fallback for a failed Jev call. Measured on `v1.0-data`: on 60
|
|
181
|
+
English test queries (50 with a known answer) over the keyword (BM25)
|
|
182
|
+
candidates, with no embedding key, Jev raised nDCG@5 from 0.675 to 0.871 and
|
|
183
|
+
never turned a correct top-5 answer into a miss. On 223 further queries over
|
|
184
|
+
the same candidates Jev reached an nDCG@5 of 0.788 against Cohere's 0.674. Input tokens cost about $0.23 per 1,000
|
|
185
|
+
queries; Cohere bills $2 per 1,000 searches.
|
|
186
|
+
`REVIT_API_DOCS_MIN_RELEVANCE` stays unset by default. Set to 0.15 it filters
|
|
187
|
+
out clearly unrelated queries (questions that are not about Revit, types this
|
|
188
|
+
data set does not have), abstaining on about 2.5% of the queries that do have
|
|
189
|
+
an answer (measured on `v1.0-data`). It cannot spot a misspelt or misplaced
|
|
190
|
+
member name: such a query usually gets the closest real API as the first
|
|
191
|
+
result, to be confirmed with a compile check. **Do not use 0.5**: it
|
|
192
|
+
abstained on 14% of the queries that have an answer. What TypeSafe keeps: see the `jev-data-handling` note
|
|
193
|
+
(`uvx revit-api-docs environment typesafe`).
|
|
194
|
+
|
|
195
|
+
**Vector search.** An embedding key (`REVIT_API_DOCS_EMBEDDING_API_KEY`, or
|
|
196
|
+
`OPENROUTER_API_KEY`) turns it on; each query then costs one embedding request
|
|
197
|
+
(about 0.9 s). The vector hits and the BM25 hits, 30 of each, are fused by
|
|
198
|
+
reciprocal rank (score = sum of 1 / (60 + rank)) and the best 30 go to the
|
|
199
|
+
reranker; without a reranker they are cut to `top_k`. On 223 English test
|
|
200
|
+
queries without reranking (measured on `v1.1-data`), fusion raises nDCG@5
|
|
201
|
+
from 0.557 (BM25 alone) to 0.647, and on the 113 of them that describe a
|
|
202
|
+
multi-step task from 0.355 to 0.459, with an answer among the top 30 for 82%
|
|
203
|
+
of those instead of 72%. Each
|
|
204
|
+
vector hit is matched to its entry by name. On the first vector query the
|
|
205
|
+
server samples 50 records of each vector collection: when the record ids do
|
|
206
|
+
not line up with the rows it logs the warning `vector_store_misaligned` and
|
|
207
|
+
keeps matching by name (the older `v1.0-data` vector store numbers its records
|
|
208
|
+
differently from the rows of `revit_api.db`; `v1.1-data` is aligned and logs
|
|
209
|
+
nothing); when the names are not found either, it turns vector search off
|
|
210
|
+
until the server restarts and answers from keyword search. `revit-api-docs download`
|
|
211
|
+
prints the same check for the installed data set.
|
|
212
|
+
|
|
213
|
+
Privacy: with an embedding, Cohere or TypeSafe key the query text and the
|
|
214
|
+
candidate API entries (public documentation) are sent to that provider. Keep
|
|
215
|
+
queries to API names and generic task descriptions, in English.
|
|
216
|
+
|
|
217
|
+
Data set (`v1.1-data`): the API reference comes from `RevitAPI.chm` of the
|
|
218
|
+
Revit 2026.3 SDK (the same pages as the Revit 2026 reference) and includes
|
|
219
|
+
constructor pages and interface members such as
|
|
220
|
+
`IExternalEventHandler.Execute`: 28,862 entries, of which the 27,596 of
|
|
221
|
+
`v1.0-data` are unchanged under the same ids. The SDK samples (153 projects)
|
|
222
|
+
come from the Revit 2026 SDK. The SQLite databases and ChromaDB indexes were
|
|
223
|
+
built with the pipeline in `pipeline/` (`uv sync --extra pipeline`; needs the
|
|
224
|
+
CHM, the SDK and OpenRouter/Cohere keys in the environment). `v1.1-data` was
|
|
225
|
+
built from `v1.0-data` with `uv run python -m pipeline.build_data_v1_1
|
|
226
|
+
--html-dir <CHM html dir> --base-db <v1.0-data dir>/sqlite/revit_api.db`, which
|
|
227
|
+
appends the pages `v1.0-data` lacked and rebuilds the API vector store so that
|
|
228
|
+
every record id is its row id. The server does not need any of that.
|
|
229
|
+
|
|
230
|
+
Development:
|
|
231
|
+
|
|
232
|
+
```bash
|
|
233
|
+
uv sync
|
|
234
|
+
uv run pytest
|
|
235
|
+
uv build
|
|
236
|
+
uvx --from . revit-api-docs search "Wall.Create"
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
License: MIT. Issues and discussion: <https://github.com/revitbridge/revit-api-docs/issues>.
|