xists 0.7.0__py3-none-any.whl

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.
Files changed (66) hide show
  1. .env.example +54 -0
  2. LICENSE +21 -0
  3. README.md +238 -0
  4. README.zh-CN.md +218 -0
  5. docs/demo.md +160 -0
  6. docs/performance.md +76 -0
  7. docs/record-schema.md +430 -0
  8. docs/release.md +127 -0
  9. docs/scale-2k-diagnosis.md +82 -0
  10. docs/scaling-experiment.md +156 -0
  11. docs/usage.md +663 -0
  12. docs/v0.6.0-completion.md +32 -0
  13. examples/ci-smoke/eval-cases.json +19 -0
  14. examples/ci-smoke/repos.txt +2 -0
  15. examples/eval-cases-extended.json +1532 -0
  16. examples/eval-cases-smoke.json +182 -0
  17. examples/eval-cases.json +1377 -0
  18. pyproject.toml +56 -0
  19. repos.txt +200 -0
  20. scripts/bench_search.py +85 -0
  21. scripts/check_eval_report.py +173 -0
  22. scripts/diagnose_retrieval_candidates.py +142 -0
  23. scripts/generate_stratified_eval.py +423 -0
  24. scripts/generate_synthetic_index.py +143 -0
  25. scripts/smoke_check.py +115 -0
  26. tests/test_api.py +120 -0
  27. tests/test_check_eval_report.py +153 -0
  28. tests/test_cli.py +2970 -0
  29. tests/test_diagnose_retrieval_candidates.py +46 -0
  30. tests/test_eval.py +821 -0
  31. tests/test_examples.py +75 -0
  32. tests/test_generate_stratified_eval.py +101 -0
  33. tests/test_generate_synthetic_index.py +64 -0
  34. tests/test_github_ingest.py +536 -0
  35. tests/test_llm_profile.py +281 -0
  36. tests/test_package.py +12 -0
  37. tests/test_packaging.py +38 -0
  38. tests/test_performance_smoke.py +44 -0
  39. tests/test_query_transform.py +97 -0
  40. tests/test_rerank.py +128 -0
  41. tests/test_search.py +961 -0
  42. xists/__init__.py +3 -0
  43. xists/api.py +70 -0
  44. xists/cli.py +2438 -0
  45. xists/eval/__init__.py +1 -0
  46. xists/eval/inspect.py +239 -0
  47. xists/eval/judge.py +187 -0
  48. xists/eval/run.py +355 -0
  49. xists/eval/schema.py +131 -0
  50. xists/ingest/__init__.py +1 -0
  51. xists/ingest/github.py +690 -0
  52. xists/profile/__init__.py +1 -0
  53. xists/profile/llm.py +289 -0
  54. xists/records.py +229 -0
  55. xists/search/__init__.py +1 -0
  56. xists/search/confidence.py +99 -0
  57. xists/search/embed.py +322 -0
  58. xists/search/index.py +167 -0
  59. xists/search/query.py +865 -0
  60. xists/search/rerank.py +176 -0
  61. xists/search/transform.py +126 -0
  62. xists-0.7.0.dist-info/METADATA +263 -0
  63. xists-0.7.0.dist-info/RECORD +66 -0
  64. xists-0.7.0.dist-info/WHEEL +4 -0
  65. xists-0.7.0.dist-info/entry_points.txt +2 -0
  66. xists-0.7.0.dist-info/licenses/LICENSE +21 -0
.env.example ADDED
@@ -0,0 +1,54 @@
1
+ # GitHub ingestion
2
+ # Single token:
3
+ GITHUB_TOKEN=your_github_token_here
4
+ # Multiple tokens (comma-separated, for higher rate limits):
5
+ # GITHUB_TOKENS=tok1,tok2,tok3
6
+
7
+ # LLM profile generation (OpenAI-compatible chat completions endpoint)
8
+ # Used only during ingest to turn collected repo evidence into a structured profile.
9
+ # Works with OpenAI, vLLM, Ollama, Together, DeepSeek, Moonshot, etc.
10
+ LLM_API_KEY=your_llm_api_key_here
11
+ LLM_BASE_URL=https://api.deepseek.com
12
+ LLM_MODEL=deepseek-v4-pro
13
+
14
+ # Optional query canonicalization (OpenAI-compatible chat completions endpoint)
15
+ # Used only with `xists search` or `xists eval run` plus --query-transform-mode.
16
+ # It can convert queries into an English retrieval expression for an
17
+ # English-dominant corpus while xists keeps the local index and ranking.
18
+ QUERY_TRANSFORM_API_KEY=your_query_transform_api_key_here
19
+ QUERY_TRANSFORM_BASE_URL=https://api.example.com/v1
20
+ QUERY_TRANSFORM_MODEL=your_chat_model
21
+
22
+ # Embedding vector calculation (OpenAI-compatible embeddings endpoint)
23
+ # Used to compute vectors for:
24
+ # 1. records during `xists index build`
25
+ # 2. the query text during `xists search` / `xists eval run`
26
+ # The endpoint does NOT store your index and does NOT perform vector search.
27
+ # xists keeps vectors in local index.json and does ranking/query locally.
28
+ #
29
+ # IMPORTANT:
30
+ # This single embedding config is shared by:
31
+ # - `xists index build` to embed repository records
32
+ # - `xists search` / `xists eval run` to embed query text
33
+ # The query embedding model must match the model used to build index.json.
34
+ # Do not change EMBEDDING_MODEL after building an index unless you rebuild it:
35
+ # xists index build --force
36
+ #
37
+ # Recommended local CUDA example: BAAI/bge-m3 via TEI on localhost:6597
38
+ # docker-served endpoint: http://localhost:6597/v1 or http://localhost:6597
39
+ # EMBEDDING_API_KEY can be any non-empty placeholder if the local server has no auth.
40
+ EMBEDDING_API_KEY=local
41
+ EMBEDDING_BASE_URL=http://localhost:6597/v1
42
+ EMBEDDING_MODEL=BAAI/bge-m3
43
+
44
+ # Remote embedding APIs can also be used as calculate-only endpoints.
45
+ # They compute vectors, while xists still searches the local index.
46
+ # Example:
47
+ # EMBEDDING_API_KEY=your_remote_embedding_api_key_here
48
+ # EMBEDDING_BASE_URL=https://api.openai.com/v1
49
+ # EMBEDDING_MODEL=text-embedding-3-small
50
+ #
51
+ # For a dual-encoder retrieval service that requires a request role field,
52
+ # enable it explicitly. xists then sends `passage` for index builds and
53
+ # `query` for search/evaluation. Leave unset for ordinary embedding APIs.
54
+ # EMBEDDING_INPUT_TYPE_FIELD=input_type
LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 UsonTong
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
README.md ADDED
@@ -0,0 +1,238 @@
1
+ <div align="center"><a name="readme-top"></a>
2
+
3
+ # xists
4
+
5
+ Find first. Build later.
6
+
7
+ `xists` is a local semantic search engine for selected lists of GitHub repositories. Check if a similar project already exists before you build it.
8
+
9
+ **English** · [简体中文](./README.zh-CN.md)
10
+
11
+ </div>
12
+
13
+ ---
14
+
15
+ ## Why xists?
16
+
17
+ Global GitHub search is often noisy, and traditional keyword matching lacks semantic understanding. `xists` solves this by narrowing the search space: you provide a curated repository list, and `xists` builds a local index for semantic search.
18
+
19
+ - **Before you build**: check if a similar project or existing solution already exists.
20
+ - **Tech decisions**: compare candidates from a curated set using semantic search.
21
+ - **Fast lookups**: quickly find what you need without manually opening dozens of READMEs.
22
+
23
+ ## How it works
24
+
25
+ ```mermaid
26
+ flowchart LR
27
+ A[Repo List] --> B[Ingest Metadata]
28
+ B --> C[Generate LLM Summaries]
29
+ C --> D[Build Local Index]
30
+ D --> E[Search]
31
+ D -. optional .-> F[Evaluate Ranking]
32
+ F -.-> G[Inspect Misses]
33
+ ```
34
+
35
+ 1. **Ingest**: Provide a list of GitHub repos. `xists` fetches their metadata and READMEs.
36
+ 2. **Profile**: It uses an LLM to generate compact, search-optimized summaries for better matching.
37
+ 3. **Index**: It builds a local JSON embedding index.
38
+ 4. **Search**: You query the index using semantic search.
39
+
40
+ ## Local-first index, explicit model endpoints
41
+
42
+ `xists` keeps everything transparent and local:
43
+ - `records.json`: Raw metadata, structure signals, and LLM-generated profiles.
44
+ - `index.json`: The embedding index.
45
+ - `eval-report.json`: Search quality test results.
46
+
47
+ You need a GitHub token for the initial data fetch, plus model endpoints for summaries and embeddings. The records, index, ranking, and evaluation report stay on your machine. An embedding endpoint calculates vectors; xists stores them in local JSON and compares them locally.
48
+
49
+ ## Install and first search
50
+
51
+ Requires Python 3.11+. PyPI publication is prepared for v0.7.0 but has not
52
+ yet been authorized; until then, install directly from a checked-out source
53
+ tree:
54
+
55
+ ```bash
56
+ python -m pip install -e ".[dev]"
57
+ ```
58
+
59
+ After v0.7.0 is published, the equivalent package installation will be:
60
+
61
+ ```bash
62
+ python -m pip install xists
63
+ ```
64
+
65
+ Then create a local configuration file and build an index from repositories
66
+ you control:
67
+
68
+ ```bash
69
+ cp .env.example .env
70
+ # Set the required GitHub, LLM, and embedding variables in .env.
71
+
72
+ xists ingest github --repos repos.txt --output records.json --report report.json
73
+ xists index build --records records.json --output index.json
74
+ xists search "open source firebase alternative" --index index.json
75
+ ```
76
+
77
+ See [the demo walkthrough](docs/demo.md) for endpoint checks, concurrency,
78
+ evaluation, and troubleshooting. No current-schema demo records/index download
79
+ is published yet; the first Release asset will be created only after it passes
80
+ `records validate` and `index verify`.
81
+
82
+ ---
83
+
84
+ ## Quickstart
85
+
86
+ Requires Python 3.11+.
87
+
88
+ ```bash
89
+ # Install
90
+ python -m pip install -e ".[dev]"
91
+
92
+ # Set up config
93
+ cp .env.example .env
94
+ # Edit .env with your GitHub token, LLM model, and embedding model
95
+ ```
96
+
97
+ **Run the pipeline:**
98
+
99
+ ```bash
100
+ # 1. Fetch data & generate summaries
101
+ xists ingest github \
102
+ --repos repos.txt \
103
+ --output demo-records.json \
104
+ --report demo-report.json \
105
+ --github-api graphql
106
+
107
+ # 2. Build the local index
108
+ xists index build \
109
+ --records demo-records.json \
110
+ --output demo-index.json
111
+
112
+ # 3. Search!
113
+ xists search "open source firebase alternative" --index demo-index.json
114
+ xists search "open source firebase alternative" --index demo-index.json --format json
115
+ ```
116
+
117
+ The commands above generate local files and may call the endpoints configured
118
+ in `.env`; use `records.json` / `index.json` instead if you do not want files
119
+ named as demo artifacts.
120
+
121
+ ---
122
+
123
+ ## Python API
124
+
125
+ Use the stable API when another Python program needs the same search behavior
126
+ as the CLI. Configuration is always explicit; importing `xists.api` does not
127
+ read `.env` or send network requests.
128
+
129
+ ```python
130
+ from xists.api import load_index, search
131
+ from xists.search.embed import EmbeddingConfig
132
+
133
+ index = load_index("index.json")
134
+ config = EmbeddingConfig(
135
+ api_key="your-key",
136
+ base_url="https://your-embedding-endpoint/v1",
137
+ model="your-embedding-model",
138
+ )
139
+ result = search("open source firebase alternative", index, embedding_config=config, top_k=5)
140
+ ```
141
+
142
+ `search()` may call the endpoint in `config` to embed the query. It raises
143
+ actionable Python exceptions for invalid indexes, incompatible embedding models,
144
+ and endpoint failures instead of printing or terminating the process.
145
+
146
+ ---
147
+
148
+ ## Data, security, and privacy
149
+
150
+ - `.env` and token files are read only from your local machine; xists does not
151
+ commit, print, telemetry-report, or upload their secret values.
152
+ - `ingest github` sends your GitHub token only to GitHub. `profile refresh` and
153
+ ingest-time profile generation send repository text to the configured LLM
154
+ endpoint. `index build` sends embeddable repository text to the configured
155
+ embedding endpoint; `search` and `eval run` send query text to that endpoint.
156
+ - A local endpoint keeps those requests on your machine or network. A remote
157
+ endpoint receives the corresponding text under that provider's terms; choose
158
+ it only when you are permitted to send the material. xists does not host the
159
+ endpoint, upload your index, or perform vector search remotely.
160
+ - If you share records or indexes, you are responsible for checking repository
161
+ licenses, source content, generated profiles, and any personal or sensitive
162
+ information before distribution.
163
+
164
+ ---
165
+
166
+ ## Search Result Example
167
+
168
+ When you run a search, `xists` returns a compact text view by default for terminal review. Add `--format json` for scripts and agent integrations. v0.2.0 keeps ranking simple: exact repo/name/alias matches are pinned first, then semantic similarity is adjusted by a few explainable metadata signals.
169
+
170
+ Default text output looks like this:
171
+
172
+ ```text
173
+ query: hermes ai agent
174
+ intent: functional
175
+ abstained: False
176
+ results: 1
177
+ 1. repo: NousResearch/hermes-agent
178
+ url: https://github.com/NousResearch/hermes-agent
179
+ confidence: high_confidence
180
+ score: 0.680000
181
+ summary: An agent-oriented project for Hermes models.
182
+ why: matched metadata terms: agent
183
+ ```
184
+
185
+ The JSON output keeps the same ranking evidence in a machine-readable shape:
186
+
187
+ ```json
188
+ {
189
+ "query": "hermes ai agent",
190
+ "results": [
191
+ {
192
+ "repo_id": "NousResearch/hermes-agent",
193
+ "url": "https://github.com/NousResearch/hermes-agent",
194
+ "score": 0.68,
195
+ "semantic_score": 0.63,
196
+ "metadata_score": 0.05,
197
+ "confidence": "high_confidence",
198
+ "why": ["matched metadata terms: agent"]
199
+ }
200
+ ]
201
+ }
202
+ ```
203
+
204
+ `score` is the final ranking score; higher means a stronger match. Use `--format json` when another program or agent needs the structured payload.
205
+
206
+ ---
207
+
208
+ ## Optional Evaluation
209
+
210
+ If you update the repository list, regenerate summaries, or change the search setup, `xists` lets you run fixed test cases to sanity-check whether results changed in a meaningful way.
211
+
212
+ ```bash
213
+ pytest
214
+ xists eval run \
215
+ --cases examples/eval-cases.json \
216
+ --index demo-index.json \
217
+ --output demo-eval-report.json
218
+
219
+ xists eval inspect --report demo-eval-report.json --status serious_mismatch
220
+ ```
221
+
222
+ The report groups results into pragmatic categories:
223
+ - **Exact match**: The specific target repo was #1.
224
+ - **Acceptable alternative**: Not the exact target, but a valid substitute (e.g., returning Vue when you asked for a React-like framework).
225
+ - **Serious mismatch**: The top result missed the core intent.
226
+ - **Insufficient evidence**: The indexed data was too thin to judge.
227
+
228
+ ---
229
+
230
+ ## Commands
231
+
232
+ - `xists doctor`: Check config and file status; add `--check-endpoints` or `--strict` to probe the embedding service.
233
+ - `xists ingest github`: Fetch repo metadata and generate summaries.
234
+ - `xists index build`: Build or incrementally update the local index.
235
+ - `xists search "query"`: Query the local index with readable terminal output by default; add `--format json` for scripts and agents.
236
+ - `xists eval cases` / `xists eval run` / `xists eval inspect`: Validate the dataset and run/review ranking tests.
237
+ - `xists records validate` / `xists records stats` / `xists records inspect`: Check record quality without printing huge payloads to your terminal.
238
+ - `xists index stats` / `xists index verify`: Summarize an index and confirm it is in sync with records.
README.zh-CN.md ADDED
@@ -0,0 +1,218 @@
1
+ <div align="center"><a name="readme-top"></a>
2
+
3
+ # xists
4
+
5
+ 先找,再做。
6
+
7
+ `xists` 是一个面向 GitHub 仓库清单的本地语义搜索工具。造轮子前,先用它查查是否有类似项目或现成方案。
8
+
9
+ [English](./README.md) · **简体中文**
10
+
11
+ </div>
12
+
13
+ ---
14
+
15
+ ## 为什么写 xists?
16
+
17
+ GitHub 的全局搜索常常伴随较高的信息噪音,而传统的关键词匹配又受限于字面约束。`xists` 的核心思路是通过缩小搜索域来提升精度:基于用户提供的特定仓库清单构建本地索引,从而实现更高效的语义检索。
18
+
19
+ - **动手之前**:通过语义检索查一下有没有类似项目或现成方案。
20
+ - **技术选型**:在候选项目池里快速比对,不用挨个翻 README。
21
+ - **快速定位**:告别精确关键词,用你脑海里的描述直接搜。
22
+
23
+ ## 工作流
24
+
25
+ ```mermaid
26
+ flowchart LR
27
+ A[仓库清单] --> B[抓取元数据]
28
+ B --> C[LLM 生成结构化摘要]
29
+ C --> D[构建本地索引]
30
+ D --> E[搜索]
31
+ D -. 可选 .-> F[评测排序质量]
32
+ F -.-> G[检查未命中案例]
33
+ ```
34
+
35
+ 1. **拉取**:提供仓库列表,`xists` 通过 GitHub API 抓取它们的元数据和 README。
36
+ 2. **总结**:调用 LLM 为每个仓库生成适合被检索的结构化短语和简介。
37
+ 3. **索引**:在本地构建基于 Embedding 的 JSON 向量索引。
38
+ 4. **搜索**:直接在本地进行语义检索。
39
+
40
+ ## 本地索引,模型接口显式配置
41
+
42
+ `xists` 所有的中间产物和结果都透明且受你掌控:
43
+ - `records.json`:存放仓库的基础信息和 LLM 生成的特征画像。
44
+ - `index.json`:本地的 Embedding 索引。
45
+ - `eval-report.json`:检索质量评测报告。
46
+
47
+ 首次采集需要 GitHub token;生成摘要与 embedding 还需要模型接口。records、index、排序和评测报告都保留在本机。embedding 接口只负责计算向量;xists 把向量保存为本地 JSON,并在本地完成相似度计算与排序。
48
+
49
+ ## 安装与第一次搜索
50
+
51
+ 环境要求:Python 3.11+。v0.7.0 正在准备 PyPI 首发,但尚未获授权发布;在此之前,请从检出的源码目录安装:
52
+
53
+ ```bash
54
+ python -m pip install -e ".[dev]"
55
+ ```
56
+
57
+ v0.7.0 发布后,对应的安装方式会是:
58
+
59
+ ```bash
60
+ python -m pip install xists
61
+ ```
62
+
63
+ 然后创建本地配置,并从你有权处理的仓库清单构建索引:
64
+
65
+ ```bash
66
+ cp .env.example .env
67
+ # 在 .env 中填写 GitHub、LLM 和 embedding 配置。
68
+
69
+ xists ingest github --repos repos.txt --output records.json --report report.json
70
+ xists index build --records records.json --output index.json
71
+ xists search "open source firebase alternative" --index index.json
72
+ ```
73
+
74
+ 完整的接口预检、并发、评测和排错说明请看[演示流程](docs/demo.md)。目前尚未发布符合当前 schema 的 demo records/index 下载包;首个 Release asset 必须先通过 `records validate` 与 `index verify` 才会提供。
75
+
76
+ ---
77
+
78
+ ## 快速开始
79
+
80
+ 环境要求:Python 3.11+。
81
+
82
+ ```bash
83
+ # 安装
84
+ python -m pip install -e ".[dev]"
85
+
86
+ # 配置
87
+ cp .env.example .env
88
+ # 在 .env 中填入你的 GitHub token、LLM 模型和 embedding 模型配置
89
+ ```
90
+
91
+ **跑通全流程:**
92
+
93
+ ```bash
94
+ # 1. 抓取数据并生成总结
95
+ xists ingest github \
96
+ --repos repos.txt \
97
+ --output demo-records.json \
98
+ --report demo-report.json \
99
+ --github-api graphql
100
+
101
+ # 2. 构建本地向量索引
102
+ xists index build \
103
+ --records demo-records.json \
104
+ --output demo-index.json
105
+
106
+ # 3. 开始搜索!
107
+ xists search "open source firebase alternative" --index demo-index.json
108
+ xists search "open source firebase alternative" --index demo-index.json --format json
109
+ ```
110
+
111
+ 上面的命令会生成本地文件,并可能调用 `.env` 里配置的接口;若不希望使用 demo 命名,请改用 `records.json` 和 `index.json`。
112
+
113
+ ---
114
+
115
+ ## Python API
116
+
117
+ 其他 Python 程序需要使用和 CLI 相同的搜索逻辑时,可以使用稳定 API。配置必须显式传入;导入 `xists.api` 不会读取 `.env`,也不会发起网络请求。
118
+
119
+ ```python
120
+ from xists.api import load_index, search
121
+ from xists.search.embed import EmbeddingConfig
122
+
123
+ index = load_index("index.json")
124
+ config = EmbeddingConfig(
125
+ api_key="your-key",
126
+ base_url="https://your-embedding-endpoint/v1",
127
+ model="your-embedding-model",
128
+ )
129
+ result = search("open source firebase alternative", index, embedding_config=config, top_k=5)
130
+ ```
131
+
132
+ `search()` 会按需调用 `config` 指定的接口来计算查询向量。无效 index、embedding 模型不兼容或接口失败会以可捕获的 Python 异常返回,不会打印信息或结束进程。
133
+
134
+ ---
135
+
136
+ ## 数据、安全与隐私
137
+
138
+ - `.env` 和 token 文件只在本地读取;xists 不会提交、打印、遥测上报或上传其中的密钥。
139
+ - `ingest github` 只会把 GitHub token 发给 GitHub。`profile refresh` 与 ingest 中生成 profile 的步骤会把仓库文本发送给你配置的 LLM 接口。`index build` 会把可 embedding 的仓库文本发送给 embedding 接口;`search` 和 `eval run` 会把查询文本发送给该接口。
140
+ - 选择本地接口时,请求会留在你的机器或网络中;选择远端接口时,对应文本会发送给该提供商,并受其条款约束。xists 不托管接口、不上传你的 index,也不在远端执行向量搜索。
141
+ - 若你分享 records 或 index,需要自行检查仓库许可证、源内容、生成的 profile,以及其中是否包含个人或敏感信息。
142
+
143
+ ---
144
+
145
+ ## 检索结果示例
146
+
147
+ 每次搜索,`xists` 默认都会输出适合终端阅读的紧凑文本。脚本和 agent 集成可以加 `--format json` 获取结构化结果。v0.2.0 的排序刻意保持简单:先固定精确 repo/name/alias 命中,再用少量可解释 metadata 信号调整语义相似度。
148
+
149
+ 默认文本输出类似这样:
150
+
151
+ ```text
152
+ query: hermes ai agent
153
+ intent: functional
154
+ abstained: False
155
+ results: 1
156
+ 1. repo: NousResearch/hermes-agent
157
+ url: https://github.com/NousResearch/hermes-agent
158
+ confidence: high_confidence
159
+ score: 0.680000
160
+ summary: An agent-oriented project for Hermes models.
161
+ why: matched metadata terms: agent
162
+ ```
163
+
164
+ JSON 输出保留相同的排序证据,适合机器读取:
165
+
166
+ ```json
167
+ {
168
+ "query": "hermes ai agent",
169
+ "results": [
170
+ {
171
+ "repo_id": "NousResearch/hermes-agent",
172
+ "url": "https://github.com/NousResearch/hermes-agent",
173
+ "score": 0.68,
174
+ "semantic_score": 0.63,
175
+ "metadata_score": 0.05,
176
+ "confidence": "high_confidence",
177
+ "why": ["matched metadata terms: agent"]
178
+ }
179
+ ]
180
+ }
181
+ ```
182
+
183
+ `score` 是最终排序分数,越高代表匹配越强。其他程序或 agent 需要结构化 payload 时使用 `--format json`。
184
+
185
+ ---
186
+
187
+ ## 可选评测
188
+
189
+ 如果你更换了仓库清单、重新生成了摘要,或调整了搜索配置,`xists` 内置的评测工具可以用固定测试用例帮你检查结果是否有明显变化:
190
+
191
+ ```bash
192
+ pytest
193
+ xists eval run \
194
+ --cases examples/eval-cases.json \
195
+ --index demo-index.json \
196
+ --output demo-eval-report.json
197
+
198
+ # 直接查看错误的 Case
199
+ xists eval inspect --report demo-eval-report.json --status serious_mismatch
200
+ ```
201
+
202
+ 评测报告会将结果分为以下几种务实的类型:
203
+ - **精确命中**:第一名就是预期中的目标仓库。
204
+ - **可接受替代**:第一名不是指定仓库,但也是个合理的同类竞品(比如你搜 React 相关的,它推了 Vue)。
205
+ - **明显不匹配**:第一名完全不符合搜索意图。
206
+ - **证据不足**:索引的数据太少,没法客观判断。
207
+
208
+ ---
209
+
210
+ ## 常用命令一览
211
+
212
+ - `xists doctor`:检查本地配置和文件状态;加 `--check-endpoints` 或 `--strict` 可探测 embedding 服务。
213
+ - `xists ingest github`:拉取仓库信息并生成短语摘要。
214
+ - `xists index build`:构建或增量更新本地向量索引。
215
+ - `xists search "query"`:执行搜索,默认输出适合终端阅读;加 `--format json` 可输出给脚本和 agent 使用的结构化结果。
216
+ - `xists eval cases` / `xists eval run` / `xists eval inspect`:校验评测集并运行、检查检索评测。
217
+ - `xists records validate` / `xists records stats` / `xists records inspect`:检查 records 质量,避免终端被长 JSON 刷屏。
218
+ - `xists index stats` / `xists index verify`:概览 index,并确认它和 records 仍然同步。
docs/demo.md ADDED
@@ -0,0 +1,160 @@
1
+ # Demo Workflow
2
+
3
+ This guide walks through the smallest end-to-end xists workflow using the committed demo inputs.
4
+
5
+ ## Files
6
+
7
+ - `repos.txt`: the current demo repository list in the project root
8
+ - `examples/eval-cases.json`: committed 100-case evaluation baseline
9
+ - `examples/eval-cases-extended.json`: optional 112-case evaluation dataset for broader checking
10
+
11
+ ## 1. Install
12
+
13
+ ```bash
14
+ python -m pip install -e ".[dev]"
15
+ ```
16
+
17
+ ## 2. Configure credentials
18
+
19
+ Create a local `.env` file:
20
+
21
+ ```bash
22
+ cp .env.example .env
23
+ ```
24
+
25
+ Set the required GitHub, LLM, and embedding credentials in `.env`.
26
+
27
+ ## 3. Preflight and endpoint checks
28
+
29
+ Before spending GitHub or LLM quota, verify the local files and configuration:
30
+
31
+ ```bash
32
+ xists doctor \
33
+ --records demo-records.json \
34
+ --index demo-index.json \
35
+ --cases examples/eval-cases.json
36
+ ```
37
+
38
+ `doctor` returns JSON. Missing generated files are warnings because the demo may
39
+ not have been generated yet. Missing embedding or LLM variables are errors with
40
+ `next_steps` entries showing what to set in `.env`.
41
+
42
+ When your embedding service is supposed to be running, probe it with a real
43
+ request before building an index, searching, or running eval:
44
+
45
+ ```bash
46
+ xists doctor \
47
+ --records demo-records.json \
48
+ --index demo-index.json \
49
+ --cases examples/eval-cases.json \
50
+ --check-endpoints
51
+ ```
52
+
53
+ Use `--strict` in scripts or CI-style smoke checks when endpoint failures should
54
+ make the command exit non-zero:
55
+
56
+ ```bash
57
+ xists doctor \
58
+ --records demo-records.json \
59
+ --index demo-index.json \
60
+ --cases examples/eval-cases.json \
61
+ --check-endpoints \
62
+ --strict
63
+ ```
64
+
65
+ If the probe cannot connect, start the embedding server referenced by
66
+ `EMBEDDING_BASE_URL`, confirm the URL is the API root such as
67
+ `http://localhost:6597/v1`, and rerun the strict doctor command before retrying
68
+ `index build`, `search`, or `eval run`.
69
+
70
+ ## 4. Ingest example repositories
71
+
72
+ ```bash
73
+ xists ingest github \
74
+ --repos repos.txt \
75
+ --output demo-records.json \
76
+ --report demo-report.json \
77
+ --github-api graphql \
78
+ --github-batch-size 10 \
79
+ --workers 4
80
+ ```
81
+
82
+ This fetches GitHub data, generates LLM profiles, and writes checkpoints as records finish:
83
+
84
+ - `demo-records.json`
85
+ - `demo-report.json`
86
+
87
+ The ingest command prints progress to stderr while it runs. If your LLM endpoint is rate-limited, reduce `--workers` to `1` or `2`.
88
+
89
+ ## 5. Build the example index
90
+
91
+ ```bash
92
+ xists index build \
93
+ --records demo-records.json \
94
+ --output demo-index.json
95
+ ```
96
+
97
+ ## 6. Run a few searches
98
+
99
+ ```bash
100
+ xists search "frontend ui library" --index demo-index.json
101
+ xists search "python web framework for building apis" --index demo-index.json
102
+ xists search "open source workflow automation platform" --index demo-index.json
103
+ ```
104
+
105
+ Expected results vary by model and repository data, but the top results should usually come from the same neighborhood as the query.
106
+
107
+ ## 7. Optionally evaluate the demo index
108
+
109
+ ```bash
110
+ xists eval cases --cases examples/eval-cases.json
111
+ xists eval run \
112
+ --cases examples/eval-cases.json \
113
+ --index demo-index.json \
114
+ --output demo-eval-report.json
115
+ ```
116
+
117
+ The report includes:
118
+
119
+ - hard retrieval metrics such as `exact_hit_at_1`, `acceptable_hit_at_k`, and `mrr_exact`
120
+ - a readable `summary_text` block for exact top-1, acceptable top-1, serious mismatches, abstains, and wrong high-confidence cases
121
+ - `top_misses`, a sorted list of the most actionable failures
122
+ - confidence counts for top-1 predictions
123
+ - per-case top-1 outcomes in `results`
124
+
125
+ Inspect the failures that matter most:
126
+
127
+ ```bash
128
+ xists eval inspect --report demo-eval-report.json
129
+ xists eval inspect --report demo-eval-report.json --status serious_mismatch
130
+ xists eval inspect --report demo-eval-report.json --tag ai
131
+ ```
132
+
133
+ ## 8. Inspect misses and iterate
134
+
135
+ After changing the repository list, regenerating summaries, or adjusting search behavior, rerun:
136
+
137
+ ```bash
138
+ xists index build --records demo-records.json --output demo-index.json --force
139
+ xists eval cases --cases examples/eval-cases.json
140
+ xists eval run --cases examples/eval-cases.json --index demo-index.json --output demo-eval-report.json
141
+ xists eval inspect --report demo-eval-report.json --status serious_mismatch
142
+ ```
143
+
144
+ That gives you a stable way to sanity-check search behavior before moving on to larger repository lists or evaluation datasets.
145
+
146
+ ## Common run failures
147
+
148
+ - `Embedding is required ... Missing environment variables`: copy `.env.example`
149
+ to `.env` and set `EMBEDDING_API_KEY`, `EMBEDDING_BASE_URL`, and
150
+ `EMBEDDING_MODEL`.
151
+ - `Embedding request failed for all configured endpoints`: the embedding server
152
+ is not reachable at `EMBEDDING_BASE_URL`, the URL points at the wrong API root,
153
+ or the server exposes only one of the supported OpenAI-compatible `/embeddings`
154
+ or TEI `/embed` shapes. Run `xists doctor --check-endpoints --strict` after
155
+ fixing it.
156
+ - `LLM endpoint is not configured`: set `LLM_API_KEY`, `LLM_BASE_URL`, and
157
+ `LLM_MODEL`; this is required for ingest because profiles are LLM-generated.
158
+ - `GitHub token is not configured`: set `GITHUB_TOKEN`/`GITHUB_TOKENS` or pass
159
+ `--token-file` before ingesting. Existing records, indexes, search, and eval do
160
+ not need a GitHub token.