vexor 0.19.0a1__py3-none-any.whl → 0.21.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.
- vexor/__init__.py +4 -2
- vexor/_bundled_skills/vexor-cli/SKILL.md +1 -0
- vexor/api.py +87 -1
- vexor/cache.py +483 -275
- vexor/cli.py +78 -5
- vexor/config.py +240 -2
- vexor/providers/gemini.py +79 -13
- vexor/providers/openai.py +79 -13
- vexor/services/config_service.py +14 -0
- vexor/services/index_service.py +285 -4
- vexor/services/search_service.py +235 -24
- vexor/text.py +14 -0
- {vexor-0.19.0a1.dist-info → vexor-0.21.0.dist-info}/METADATA +42 -30
- vexor-0.21.0.dist-info/RECORD +33 -0
- vexor-0.19.0a1.dist-info/RECORD +0 -33
- {vexor-0.19.0a1.dist-info → vexor-0.21.0.dist-info}/WHEEL +0 -0
- {vexor-0.19.0a1.dist-info → vexor-0.21.0.dist-info}/entry_points.txt +0 -0
- {vexor-0.19.0a1.dist-info → vexor-0.21.0.dist-info}/licenses/LICENSE +0 -0
vexor/__init__.py
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
from .api import VexorError, clear_index, index, search
|
|
5
|
+
from .api import VexorError, clear_index, index, search, set_config_json, set_data_dir
|
|
6
6
|
|
|
7
7
|
__all__ = [
|
|
8
8
|
"__version__",
|
|
@@ -11,9 +11,11 @@ __all__ = [
|
|
|
11
11
|
"get_version",
|
|
12
12
|
"index",
|
|
13
13
|
"search",
|
|
14
|
+
"set_config_json",
|
|
15
|
+
"set_data_dir",
|
|
14
16
|
]
|
|
15
17
|
|
|
16
|
-
__version__ = "0.
|
|
18
|
+
__version__ = "0.21.0"
|
|
17
19
|
|
|
18
20
|
|
|
19
21
|
def get_version() -> str:
|
|
@@ -31,6 +31,7 @@ vexor "<QUERY>" [--path <ROOT>] [--mode <MODE>] [--ext .py,.md] [--exclude-patte
|
|
|
31
31
|
- `--no-respect-gitignore`: include ignored files
|
|
32
32
|
- `--no-recursive`: only the top directory
|
|
33
33
|
- `--format`: `rich` (default) or `porcelain`/`porcelain-z` for scripts
|
|
34
|
+
- `--no-cache`: in-memory only, do not read/write index cache
|
|
34
35
|
|
|
35
36
|
## Modes (pick the cheapest that works)
|
|
36
37
|
|
vexor/api.py
CHANGED
|
@@ -4,6 +4,7 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
from dataclasses import dataclass
|
|
6
6
|
from pathlib import Path
|
|
7
|
+
from collections.abc import Mapping
|
|
7
8
|
from typing import Sequence
|
|
8
9
|
|
|
9
10
|
from .config import (
|
|
@@ -13,9 +14,12 @@ from .config import (
|
|
|
13
14
|
Config,
|
|
14
15
|
RemoteRerankConfig,
|
|
15
16
|
SUPPORTED_RERANKERS,
|
|
17
|
+
config_from_json,
|
|
16
18
|
load_config,
|
|
17
19
|
resolve_default_model,
|
|
20
|
+
set_config_dir,
|
|
18
21
|
)
|
|
22
|
+
from .cache import set_cache_dir
|
|
19
23
|
from .modes import available_modes, get_strategy
|
|
20
24
|
from .services.index_service import IndexResult, build_index, clear_index_entries
|
|
21
25
|
from .services.search_service import SearchRequest, SearchResponse, perform_search
|
|
@@ -38,6 +42,8 @@ class RuntimeSettings:
|
|
|
38
42
|
model_name: str
|
|
39
43
|
batch_size: int
|
|
40
44
|
embed_concurrency: int
|
|
45
|
+
extract_concurrency: int
|
|
46
|
+
extract_backend: str
|
|
41
47
|
base_url: str | None
|
|
42
48
|
api_key: str | None
|
|
43
49
|
local_cuda: bool
|
|
@@ -47,6 +53,30 @@ class RuntimeSettings:
|
|
|
47
53
|
remote_rerank: RemoteRerankConfig | None
|
|
48
54
|
|
|
49
55
|
|
|
56
|
+
_RUNTIME_CONFIG: Config | None = None
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def set_data_dir(path: Path | str | None) -> None:
|
|
60
|
+
"""Set the base directory for config and cache data."""
|
|
61
|
+
set_config_dir(path)
|
|
62
|
+
set_cache_dir(path)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def set_config_json(
|
|
66
|
+
payload: Mapping[str, object] | str | None, *, replace: bool = False
|
|
67
|
+
) -> None:
|
|
68
|
+
"""Set in-memory config for API calls from a JSON string or mapping."""
|
|
69
|
+
global _RUNTIME_CONFIG
|
|
70
|
+
if payload is None:
|
|
71
|
+
_RUNTIME_CONFIG = None
|
|
72
|
+
return
|
|
73
|
+
base = None if replace else (_RUNTIME_CONFIG or load_config())
|
|
74
|
+
try:
|
|
75
|
+
_RUNTIME_CONFIG = config_from_json(payload, base=base)
|
|
76
|
+
except ValueError as exc:
|
|
77
|
+
raise VexorError(str(exc)) from exc
|
|
78
|
+
|
|
79
|
+
|
|
50
80
|
def search(
|
|
51
81
|
query: str,
|
|
52
82
|
*,
|
|
@@ -62,11 +92,16 @@ def search(
|
|
|
62
92
|
model: str | None = None,
|
|
63
93
|
batch_size: int | None = None,
|
|
64
94
|
embed_concurrency: int | None = None,
|
|
95
|
+
extract_concurrency: int | None = None,
|
|
96
|
+
extract_backend: str | None = None,
|
|
65
97
|
base_url: str | None = None,
|
|
66
98
|
api_key: str | None = None,
|
|
67
99
|
local_cuda: bool | None = None,
|
|
68
100
|
auto_index: bool | None = None,
|
|
69
101
|
use_config: bool = True,
|
|
102
|
+
config: Config | Mapping[str, object] | str | None = None,
|
|
103
|
+
temporary_index: bool = False,
|
|
104
|
+
no_cache: bool = False,
|
|
70
105
|
) -> SearchResponse:
|
|
71
106
|
"""Run a semantic search and return ranked results."""
|
|
72
107
|
|
|
@@ -90,11 +125,15 @@ def search(
|
|
|
90
125
|
model=model,
|
|
91
126
|
batch_size=batch_size,
|
|
92
127
|
embed_concurrency=embed_concurrency,
|
|
128
|
+
extract_concurrency=extract_concurrency,
|
|
129
|
+
extract_backend=extract_backend,
|
|
93
130
|
base_url=base_url,
|
|
94
131
|
api_key=api_key,
|
|
95
132
|
local_cuda=local_cuda,
|
|
96
133
|
auto_index=auto_index,
|
|
97
134
|
use_config=use_config,
|
|
135
|
+
runtime_config=_RUNTIME_CONFIG,
|
|
136
|
+
config_override=config,
|
|
98
137
|
)
|
|
99
138
|
|
|
100
139
|
request = SearchRequest(
|
|
@@ -108,6 +147,8 @@ def search(
|
|
|
108
147
|
model_name=settings.model_name,
|
|
109
148
|
batch_size=settings.batch_size,
|
|
110
149
|
embed_concurrency=settings.embed_concurrency,
|
|
150
|
+
extract_concurrency=settings.extract_concurrency,
|
|
151
|
+
extract_backend=settings.extract_backend,
|
|
111
152
|
provider=settings.provider,
|
|
112
153
|
base_url=settings.base_url,
|
|
113
154
|
api_key=settings.api_key,
|
|
@@ -115,6 +156,8 @@ def search(
|
|
|
115
156
|
exclude_patterns=normalized_excludes,
|
|
116
157
|
extensions=normalized_exts,
|
|
117
158
|
auto_index=settings.auto_index,
|
|
159
|
+
temporary_index=temporary_index,
|
|
160
|
+
no_cache=no_cache,
|
|
118
161
|
rerank=settings.rerank,
|
|
119
162
|
flashrank_model=settings.flashrank_model,
|
|
120
163
|
remote_rerank=settings.remote_rerank,
|
|
@@ -135,10 +178,13 @@ def index(
|
|
|
135
178
|
model: str | None = None,
|
|
136
179
|
batch_size: int | None = None,
|
|
137
180
|
embed_concurrency: int | None = None,
|
|
181
|
+
extract_concurrency: int | None = None,
|
|
182
|
+
extract_backend: str | None = None,
|
|
138
183
|
base_url: str | None = None,
|
|
139
184
|
api_key: str | None = None,
|
|
140
185
|
local_cuda: bool | None = None,
|
|
141
186
|
use_config: bool = True,
|
|
187
|
+
config: Config | Mapping[str, object] | str | None = None,
|
|
142
188
|
) -> IndexResult:
|
|
143
189
|
"""Build or refresh the index for the given directory."""
|
|
144
190
|
|
|
@@ -154,11 +200,15 @@ def index(
|
|
|
154
200
|
model=model,
|
|
155
201
|
batch_size=batch_size,
|
|
156
202
|
embed_concurrency=embed_concurrency,
|
|
203
|
+
extract_concurrency=extract_concurrency,
|
|
204
|
+
extract_backend=extract_backend,
|
|
157
205
|
base_url=base_url,
|
|
158
206
|
api_key=api_key,
|
|
159
207
|
local_cuda=local_cuda,
|
|
160
208
|
auto_index=None,
|
|
161
209
|
use_config=use_config,
|
|
210
|
+
runtime_config=_RUNTIME_CONFIG,
|
|
211
|
+
config_override=config,
|
|
162
212
|
)
|
|
163
213
|
|
|
164
214
|
return build_index(
|
|
@@ -170,6 +220,8 @@ def index(
|
|
|
170
220
|
model_name=settings.model_name,
|
|
171
221
|
batch_size=settings.batch_size,
|
|
172
222
|
embed_concurrency=settings.embed_concurrency,
|
|
223
|
+
extract_concurrency=settings.extract_concurrency,
|
|
224
|
+
extract_backend=settings.extract_backend,
|
|
173
225
|
provider=settings.provider,
|
|
174
226
|
base_url=settings.base_url,
|
|
175
227
|
api_key=settings.api_key,
|
|
@@ -220,6 +272,8 @@ def _validate_mode(mode: str) -> str:
|
|
|
220
272
|
return mode
|
|
221
273
|
|
|
222
274
|
|
|
275
|
+
|
|
276
|
+
|
|
223
277
|
def _normalize_extensions(values: Sequence[str] | str | None) -> tuple[str, ...]:
|
|
224
278
|
return normalize_extensions(_coerce_iterable(values))
|
|
225
279
|
|
|
@@ -242,13 +296,23 @@ def _resolve_settings(
|
|
|
242
296
|
model: str | None,
|
|
243
297
|
batch_size: int | None,
|
|
244
298
|
embed_concurrency: int | None,
|
|
299
|
+
extract_concurrency: int | None,
|
|
300
|
+
extract_backend: str | None,
|
|
245
301
|
base_url: str | None,
|
|
246
302
|
api_key: str | None,
|
|
247
303
|
local_cuda: bool | None,
|
|
248
304
|
auto_index: bool | None,
|
|
249
305
|
use_config: bool,
|
|
306
|
+
runtime_config: Config | None = None,
|
|
307
|
+
config_override: Config | Mapping[str, object] | str | None = None,
|
|
250
308
|
) -> RuntimeSettings:
|
|
251
|
-
config =
|
|
309
|
+
config = (
|
|
310
|
+
runtime_config if (use_config and runtime_config is not None) else None
|
|
311
|
+
)
|
|
312
|
+
if config is None:
|
|
313
|
+
config = load_config() if use_config else Config()
|
|
314
|
+
if config_override is not None:
|
|
315
|
+
config = _apply_config_override(config, config_override)
|
|
252
316
|
provider_value = (provider or config.provider or DEFAULT_PROVIDER).lower()
|
|
253
317
|
rerank_value = (config.rerank or DEFAULT_RERANK).strip().lower()
|
|
254
318
|
if rerank_value not in SUPPORTED_RERANKERS:
|
|
@@ -265,11 +329,21 @@ def _resolve_settings(
|
|
|
265
329
|
embed_value = (
|
|
266
330
|
embed_concurrency if embed_concurrency is not None else config.embed_concurrency
|
|
267
331
|
)
|
|
332
|
+
extract_value = (
|
|
333
|
+
extract_concurrency
|
|
334
|
+
if extract_concurrency is not None
|
|
335
|
+
else config.extract_concurrency
|
|
336
|
+
)
|
|
337
|
+
extract_backend_value = (
|
|
338
|
+
extract_backend if extract_backend is not None else config.extract_backend
|
|
339
|
+
)
|
|
268
340
|
return RuntimeSettings(
|
|
269
341
|
provider=provider_value,
|
|
270
342
|
model_name=model_name,
|
|
271
343
|
batch_size=batch_value,
|
|
272
344
|
embed_concurrency=embed_value,
|
|
345
|
+
extract_concurrency=extract_value,
|
|
346
|
+
extract_backend=extract_backend_value,
|
|
273
347
|
base_url=base_url if base_url is not None else config.base_url,
|
|
274
348
|
api_key=api_key if api_key is not None else config.api_key,
|
|
275
349
|
local_cuda=bool(local_cuda if local_cuda is not None else config.local_cuda),
|
|
@@ -278,3 +352,15 @@ def _resolve_settings(
|
|
|
278
352
|
flashrank_model=config.flashrank_model,
|
|
279
353
|
remote_rerank=config.remote_rerank,
|
|
280
354
|
)
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
def _apply_config_override(
|
|
358
|
+
base: Config,
|
|
359
|
+
override: Config | Mapping[str, object] | str,
|
|
360
|
+
) -> Config:
|
|
361
|
+
if isinstance(override, Config):
|
|
362
|
+
return override
|
|
363
|
+
try:
|
|
364
|
+
return config_from_json(override, base=base)
|
|
365
|
+
except ValueError as exc:
|
|
366
|
+
raise VexorError(str(exc)) from exc
|