bgts-context-engine 0.2.0__tar.gz → 0.2.2__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.
- bgts_context_engine-0.2.2/CHANGELOG.md +261 -0
- {bgts_context_engine-0.2.0/src/bgts_context_engine.egg-info → bgts_context_engine-0.2.2}/PKG-INFO +45 -24
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/README.md +43 -22
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/README.tr.md +45 -23
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/pyproject.toml +3 -1
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/__init__.py +1 -1
- bgts_context_engine-0.2.2/src/bce/api/mcp/server.py +123 -0
- bgts_context_engine-0.2.2/src/bce/api/mcp/tools.py +286 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/api/rest/ui/trace.py +29 -112
- bgts_context_engine-0.2.2/src/bce/bench/pr_ablation.py +1413 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/bench/runner.py +1 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/cli.py +276 -3
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/config.py +21 -1
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/core/assembler/assembler.py +37 -1
- bgts_context_engine-0.2.2/src/bce/core/coverage/confidence.py +259 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/core/i18n/catalogs/en.json +3 -3
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/core/i18n/catalogs/tr.json +3 -3
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/core/logging.py +11 -3
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/core/orchestrator/__init__.py +4 -2
- bgts_context_engine-0.2.2/src/bce/core/orchestrator/anchors.py +336 -0
- bgts_context_engine-0.2.2/src/bce/core/orchestrator/bulk.py +117 -0
- bgts_context_engine-0.2.2/src/bce/core/orchestrator/expand.py +383 -0
- bgts_context_engine-0.2.2/src/bce/core/orchestrator/orchestrator.py +278 -0
- bgts_context_engine-0.2.2/src/bce/core/orchestrator/text.py +490 -0
- bgts_context_engine-0.2.2/src/bce/core/scoring/engine.py +327 -0
- bgts_context_engine-0.2.2/src/bce/indexing/churn.py +122 -0
- bgts_context_engine-0.2.2/src/bce/indexing/embedder/embedder.py +130 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/indexing/embedder/encoder.py +38 -7
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/indexing/indexer.py +37 -2
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/jobs/store.py +18 -5
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/jobs/worker.py +11 -3
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/storage/graph/repository.py +401 -0
- bgts_context_engine-0.2.2/src/bce/storage/relational/migrations/0008_graph_label_indexes.sql +38 -0
- bgts_context_engine-0.2.2/src/bce/storage/relational/migrations/0009_fts_identifier_parts.sql +55 -0
- bgts_context_engine-0.2.2/src/bce/storage/relational/migrations/0010_file_churn.sql +21 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/tools/layer3/orchestration.py +104 -62
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2/src/bgts_context_engine.egg-info}/PKG-INFO +45 -24
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bgts_context_engine.egg-info/SOURCES.txt +7 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bgts_context_engine.egg-info/requires.txt +1 -1
- bgts_context_engine-0.2.0/CHANGELOG.md +0 -49
- bgts_context_engine-0.2.0/src/bce/api/mcp/server.py +0 -61
- bgts_context_engine-0.2.0/src/bce/api/mcp/tools.py +0 -262
- bgts_context_engine-0.2.0/src/bce/core/coverage/confidence.py +0 -142
- bgts_context_engine-0.2.0/src/bce/core/orchestrator/anchors.py +0 -119
- bgts_context_engine-0.2.0/src/bce/core/orchestrator/expand.py +0 -167
- bgts_context_engine-0.2.0/src/bce/core/orchestrator/orchestrator.py +0 -77
- bgts_context_engine-0.2.0/src/bce/core/scoring/engine.py +0 -106
- bgts_context_engine-0.2.0/src/bce/indexing/embedder/embedder.py +0 -75
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/LICENSE +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/MANIFEST.in +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/setup.cfg +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/api/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/api/mcp/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/api/rest/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/api/rest/app.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/api/rest/deps.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/api/rest/routes.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/api/rest/schemas.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/api/rest/static/assets/index-Cc4pUpSE.js +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/api/rest/static/assets/index-DrLRaTMU.css +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/api/rest/static/favicon.svg +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/api/rest/static/index.html +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/api/rest/ui/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/api/rest/ui/queries.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/api/rest/ui/router.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/api/rest/ui/schemas.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/bench/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/core/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/core/assembler/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/core/auth/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/core/auth/scope.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/core/coverage/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/core/i18n/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/core/i18n/locale.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/core/i18n/translator.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/core/scoring/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/domain/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/domain/enums.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/domain/models.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/indexing/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/indexing/embedder/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/indexing/extractor/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/indexing/extractor/bridges.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/indexing/extractor/designnote.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/indexing/extractor/extractor.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/indexing/extractor/routes.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/indexing/gitsync/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/indexing/gitsync/bitbucket.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/indexing/gitsync/local.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/indexing/gitsync/remote.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/indexing/linker/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/indexing/linker/linker.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/indexing/parser/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/indexing/parser/_treesitter.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/indexing/parser/base.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/indexing/parser/languages/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/indexing/parser/languages/csharp_provider.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/indexing/parser/languages/go_provider.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/indexing/parser/languages/java_provider.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/indexing/parser/languages/jsts_provider.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/indexing/parser/languages/python_provider.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/indexing/parser/registry.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/indexing/parser/scip/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/indexing/parser/scip/resolver.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/indexing/parser/symbol_id.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/indexing/upserter/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/indexing/upserter/upserter.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/jobs/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/storage/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/storage/graph/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/storage/graph/client.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/storage/relational/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/storage/relational/db.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/storage/relational/migrations/0001_extensions_graph.sql +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/storage/relational/migrations/0002_relational.sql +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/storage/relational/migrations/0003_vector.sql +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/storage/relational/migrations/0004_rls.sql +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/storage/relational/migrations/0005_embeddings_dim.sql +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/storage/relational/migrations/0006_fts.sql +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/storage/relational/migrations/0007_jobs.sql +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/storage/relational/migrator.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/storage/relational/queries.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/storage/vector/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/storage/vector/store.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/tools/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/tools/layer1/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/tools/layer1/primitives.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/tools/layer2/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/tools/layer2/search.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bce/tools/layer3/__init__.py +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bgts_context_engine.egg-info/dependency_links.txt +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bgts_context_engine.egg-info/entry_points.txt +0 -0
- {bgts_context_engine-0.2.0 → bgts_context_engine-0.2.2}/src/bgts_context_engine.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented here.
|
|
4
|
+
|
|
5
|
+
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this
|
|
6
|
+
project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.2.2] - 2026-09-18
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- `bce bench-prs prepare` / `run`: a PR replay ablation that measures what the engine adds on
|
|
15
|
+
top of the embedding model. Each merged PR is replayed against a database indexing the repo
|
|
16
|
+
at the PR's base commit; the title (+ description) is the task and the symbols the diff
|
|
17
|
+
touched in that snapshot are the ground truth. `voyage` (nearest non-test symbol embeddings),
|
|
18
|
+
`voyage_raw` and `bce` (the same neighbours as semantic anchors + explicit/lexical anchors,
|
|
19
|
+
expansion, scoring, narrowing) are scored with Recall/Precision/F1/MRR/Hit@K, a lenient
|
|
20
|
+
recall that credits enclosing symbols, file-level recall/precision, latency and a breakdown
|
|
21
|
+
of returned symbol kinds. `--from-report` re-scores stored result lists without querying.
|
|
22
|
+
`--tune` splits the PRs into a tune and a holdout half and reports each separately, so the
|
|
23
|
+
constants can be fitted on one half and quoted from the other; `--only` narrows a run to a
|
|
24
|
+
few PRs. Each `bce` case also reports `semantic_retention` (the share of the embedding
|
|
25
|
+
model's correct hits the engine still returns) and per-stage timings.
|
|
26
|
+
- `suggest_change_sites` returns a `timings` block (`semantic_ms`, `anchors_ms`, `expand_ms`,
|
|
27
|
+
`candidates_ms`, `score_ms`, `narrow_ms`, `enrich_ms`, `total_ms`); `trace=True` also returns
|
|
28
|
+
the ranked pool before narrowing (`ranked_ids`), for diagnostics.
|
|
29
|
+
- `bce bench-prs run --k 5,10,20` runs once at the largest K and reports every K as an extra
|
|
30
|
+
column (`metrics_at`) - exact because both lists are prefix chains (see narrowing below).
|
|
31
|
+
Each `bce` case carries a `truth_trace`: for every ground-truth symbol, the channel that
|
|
32
|
+
brought it in (`semantic` / `anchor` / `expansion` / none), the stage where it was lost
|
|
33
|
+
(`not_reached`, `narrowed_out`, `returned`), its rank in the model's list, in the scored pool
|
|
34
|
+
and in the answer. The report aggregates these per split and per K, together with a
|
|
35
|
+
task-text axis (`task_stats`: characters, content tokens, code identifiers in the PR text) so
|
|
36
|
+
a "no identifiers in the description" PR can be told from an engine miss. PRs whose diff
|
|
37
|
+
touches no symbol in the snapshot are scored at file level (`file_recall` / `file_precision`)
|
|
38
|
+
instead of being dropped. `--rerun-bce` replays the stored embedding neighbours and re-runs
|
|
39
|
+
only the engine, which turns a constants sweep from an API-bound run into ~100 s per split.
|
|
40
|
+
- `bce churn --repo --name [--commit] [--db-name]` (re)computes per-file git churn for an
|
|
41
|
+
indexed repository; the indexer records it on every run (migration `0010_file_churn`).
|
|
42
|
+
|
|
43
|
+
### Changed
|
|
44
|
+
|
|
45
|
+
- Retrieval scoring is now `scoring-v3`. Anchors carry an evidence *strength* in `[0, 1]`
|
|
46
|
+
(noisy-OR over the sources that nominated them) and the flat `+5.0` anchor floor became
|
|
47
|
+
`3.5 · strength`. On natural-language tasks the floor had split the pool into two disjoint
|
|
48
|
+
bands — every anchor above 7.3, every graph neighbour below 4.9 — so the top-N was the
|
|
49
|
+
highest-degree anchors regardless of evidence, and the functions that actually needed the
|
|
50
|
+
change ranked #25–#478. Proximity is `1 / (1 + distance)` (an anchor and its first hop no
|
|
51
|
+
longer score the same), centrality is log-scaled with weight 0.6 instead of 1.0, the leaf
|
|
52
|
+
penalty dropped from 1.5 to 0.5, unknown `ref_kind` / `provenance` now score at or below the
|
|
53
|
+
weakest known value, and test symbols lose 2.0.
|
|
54
|
+
- Scoring reads the evidence that *reached* a candidate, not only whether it is an anchor.
|
|
55
|
+
Proximity is multiplied by that evidence and the reference kind keeps half its weight
|
|
56
|
+
unconditionally (`3.0 · ref_kind · (0.5 + 0.5 · evidence)`), so a `define` edge off a generic
|
|
57
|
+
name like `Content` is no longer worth what one off the model's best hit is worth.
|
|
58
|
+
- New `w9_kind_prior` (2.0): method/function 1.0, class/struct/enum/property 0.5,
|
|
59
|
+
interface/constructor 0.4. A task describes a change, and the change lands in a body;
|
|
60
|
+
declarations and type shells are where it lives. Without the prior, a constructor reached
|
|
61
|
+
through a `define` edge outscored the anchor itself, and 28% of returned symbols were
|
|
62
|
+
containers against 10% in the diffs being replayed. `demote_redundant_containers` then
|
|
63
|
+
subtracts 1.5 from a container that already has a member in the top `2N`.
|
|
64
|
+
- Explicit-name resolution is discounted by ambiguity: evidence is `1.0 / √matches`, and a name
|
|
65
|
+
matching more than 8 symbols is dropped rather than seeding an anchor per match. A qualified
|
|
66
|
+
`Type.member` reference resolves inside its type and no longer *also* admits the bare tail
|
|
67
|
+
(which handed back the ambiguity the qualifier removed); with the type absent from the graph
|
|
68
|
+
the bare tail is used only while it has at most 3 matches. A member echoing its container's
|
|
69
|
+
name — a C# constructor, a partial-class helper — counts at half the container's evidence.
|
|
70
|
+
Generic member names in PR text (`Content`, `ExternalId`, `IsCancelled`) were the largest
|
|
71
|
+
single source of pool flooding: each resolved to every same-named symbol at full strength and
|
|
72
|
+
each expanded its own callers, referrers and file.
|
|
73
|
+
- Expansion is budgeted and evidence-carrying. It runs only from anchors with strength ≥ 0.3 and
|
|
74
|
+
at most the 20 strongest; weaker anchors stay in the pool at distance 0 unexpanded. Every node
|
|
75
|
+
records `source_strength`, the reaching anchor's strength decayed by 0.6 per hop.
|
|
76
|
+
- Anchor finding filters task text through an English + Turkish stop-word list (function words
|
|
77
|
+
and bug-report filler such as "fix", "missing", "check"), so "the" and "and" no longer produce
|
|
78
|
+
anchors. Only identifier-looking tokens (snake_case, camelCase, digits, ALL_CAPS, backticks,
|
|
79
|
+
`Class.method` tails) resolve as *explicit* symbol names; a plain English word cannot turn
|
|
80
|
+
`Principal.check` into an explicit anchor. The lexical source scores symbols by how many of the
|
|
81
|
+
task's terms they cover, weighted by term rarity, and keeps the best 15 instead of 5 hits per
|
|
82
|
+
term. The semantic source decays evidence hyperbolically with rank, `0.9 / (1 + rank/n)`, so
|
|
83
|
+
the model's #1 is comparable to a moderately ambiguous explicit name and the tail still
|
|
84
|
+
outweighs a lone saturated lexical hit. Rank remains the only model input: a similarity number
|
|
85
|
+
would let the model reorder candidates, which is the one thing the engine does not delegate.
|
|
86
|
+
- Test symbols (`tests/`, `test_*.py`, `*_test.go`, `*.test.ts`, `*Test.java`, ...) are excluded
|
|
87
|
+
from the lexical and semantic anchor sources; the automatic semantic anchor over-fetches and
|
|
88
|
+
keeps the first thirty non-test neighbours. `explicit` and `history` still admit them, and
|
|
89
|
+
`find_anchors(include_tests=True)` disables the filter.
|
|
90
|
+
- Same-file sibling expansion runs only from anchors with strength ≥ 0.7, nearest by line, at
|
|
91
|
+
most 12 per anchor, and never from a container — whose members already arrive through the
|
|
92
|
+
graph — so a weak single-term hit no longer drags its whole file into the pool.
|
|
93
|
+
- Retrieval is a single pass. Task signals are computed for every expanded candidate (with
|
|
94
|
+
partial credit for snake/camel parts, so `diff_command` lights up for "diff command"), rather
|
|
95
|
+
than only for the preliminary top `4 · N` — which, being all anchors, meant no neighbour could
|
|
96
|
+
ever receive one. Candidate features come from `GraphRepository.symbol_features`, five chunked
|
|
97
|
+
queries per 500 symbols instead of four round-trips per symbol.
|
|
98
|
+
- Narrowing builds the answer one slot at a time from two streams - the embedding model's ranks
|
|
99
|
+
and the engine's score order - and returns it in selection order, so `narrow(pool, n)` is
|
|
100
|
+
exactly the first `n` of `narrow(pool, n + 1)` (K-monotonic: a K=20 run can be cut to K=10,
|
|
101
|
+
and asking for more can no longer lose a symbol that K=10 had, which the proportional
|
|
102
|
+
`ceil(N · share)` budgets did - #856 in the 40-PR replay went from 100 % at K=10 to 50 % at
|
|
103
|
+
K=20). Position 1 is always the model's #1. Slot `i` goes to the model's next rank while fewer
|
|
104
|
+
than `i · 0.5` picks came from the model; an engine pick that is itself one of the model's
|
|
105
|
+
ranks counts toward that share, because the reserve exists to keep the model's ranks in the
|
|
106
|
+
answer and an agreed pick does exactly that (without this the streams alternated even when
|
|
107
|
+
they agreed and the engine's own hits sat at positions 10-14 instead of 5). Model picks are
|
|
108
|
+
exempt from the diversity caps; engine picks are capped at `ceil(i · 0.6)` per file and
|
|
109
|
+
`ceil(i · 0.3)` per container, containers overall at `ceil(i · 0.2)`. Two gates were tried on
|
|
110
|
+
the tune split and dropped: a score margin an engine pick had to clear over the model's next
|
|
111
|
+
rank (inert) and pre-emption of slot 1 by strong explicit anchors (a long PR description
|
|
112
|
+
names dozens of identifiers, so "explicit" is cheap there). The planned neighbour reserve was
|
|
113
|
+
dropped earlier for the same reason: evidence-scaled scoring already lets a real neighbour
|
|
114
|
+
outrank a weak anchor, and reserving slots for the best-scoring neighbour cost recall.
|
|
115
|
+
- Scoring is `scoring-v4`: `w10_semantic_rank` (1.0) adds `1 / (1 + rank)` for the model's
|
|
116
|
+
ranked list as an explicit factor, and `w11_churn` (1.0) adds a log-saturated prior from the
|
|
117
|
+
number of commits that touched the symbol's file in the last 500 (`file_churn`, filled by the
|
|
118
|
+
indexer from `git log` at the indexed commit - ancestors only, so a PR-base snapshot never sees
|
|
119
|
+
the PR's own commits). Diffs land where diffs have landed before; on the replay corpus most
|
|
120
|
+
indexed files have no commit in the window at all and a handful of hub files have 20-90, so
|
|
121
|
+
the prior separates the live part of a codebase from its sediment. The prior saturates at 20
|
|
122
|
+
commits.
|
|
123
|
+
- The semantic anchor's strength decays with the model's *absolute* rank,
|
|
124
|
+
`0.9 / (1 + rank / 30)`, instead of `rank / len(list)`, so widening the pool no longer makes
|
|
125
|
+
its tail stronger (rank 29 of a 30-list used to be worth as much as rank 10 of an 11-list),
|
|
126
|
+
and expansion is gated by the model's rank rather than by the list length. Steeper decays
|
|
127
|
+
(8 / 10 / 15) were measured and lost recall@20 and semantic retention.
|
|
128
|
+
- Full-text search tokenises identifiers (migration `0009_fts_identifier_parts`): the
|
|
129
|
+
`symbol_fts.document` is a weighted `tsvector` of the exact name (A), its camelCase /
|
|
130
|
+
snake_case parts (B), the container and file-stem words (C) and the signature / docstring
|
|
131
|
+
(D), so "meeting join" matches `MeetingJoinService` and a class name lends weight to its
|
|
132
|
+
members. Task-text tokenisation is Unicode-aware - Turkish words used to be split at the
|
|
133
|
+
first non-ASCII letter - with `İ` folded to `i`, so the Turkish stop-words finally apply, and
|
|
134
|
+
a Turkish -> English domain vocabulary (generic product / software words: "toplantı" ->
|
|
135
|
+
`meeting`, "takvim" -> `calendar`, "bildirim" -> `notification`, ...; suffixed forms are
|
|
136
|
+
recognised by a Turkish suffix-chain check so `serial`, `listener`, `indirect` are left
|
|
137
|
+
alone) feeds the lexical channel and the task-signal feature. No repository-specific names.
|
|
138
|
+
- `GraphRepository.symbol_features` reads degree and the caller / callee flags from the edge
|
|
139
|
+
label tables in SQL (`<graph>._ag_label_edge`, `<graph>."CALLS"`, both btree-indexed on
|
|
140
|
+
`start_id` / `end_id`) instead of Cypher. `MATCH (s)-[r]->()` expands the untyped pattern over
|
|
141
|
+
every edge x vertex label pair and re-plans it per `UNWIND` row: about 1 s of fixed cost for
|
|
142
|
+
an empty id list and 15-30 s for a 400-symbol pool, which was the entire `candidates` stage
|
|
143
|
+
(median 1 s, p90 15 s in the 40-PR replay). The SQL form measures 20-40 ms for the same pool
|
|
144
|
+
with identical counts; Cypher remains the fallback for clients without a raw connection.
|
|
145
|
+
- The embedder defers `embed_fragment` calls and flushes them in batches of up to 500 texts /
|
|
146
|
+
400k characters across files (`Embedder(defer=True)`, the indexer's default), so a run makes
|
|
147
|
+
a few dozen Voyage requests instead of one per file.
|
|
148
|
+
- Graph reads are batched: `callers_of`, `callees_of`, `referrers_of`, `supertypes_of`,
|
|
149
|
+
`subtypes_of`, `symbols_meta`, `symbols_in_files`, `repos_of_symbols`, `resolve_symbols` and
|
|
150
|
+
`lexical_search_many` all take id/term lists, and expansion consumes them frontier by
|
|
151
|
+
frontier (`src/bce/core/orchestrator/bulk.py`, which falls back to the per-symbol methods).
|
|
152
|
+
The bulk queries use `UNWIND $ids AS sid MATCH (s:Symbol {symbol_id: sid})` rather than
|
|
153
|
+
`WHERE s.symbol_id IN $ids`, which on Apache AGE measured about ten times faster. Together
|
|
154
|
+
with the expansion budget this took a long PR description from ~48 s to under 2 s.
|
|
155
|
+
- The confidence level is computed from anchor *agreement* — strong / corroborated anchors,
|
|
156
|
+
whether the top candidate is one, the share of weak single-source anchors and of test code in
|
|
157
|
+
the selection — instead of counting source tags across all anchors, which reported a pack of
|
|
158
|
+
eight noise anchors as `high`. Coverage gains `strong_anchor_count`,
|
|
159
|
+
`corroborated_anchor_count`, `anchor_agreement_ratio`, `weak_anchor_ratio`,
|
|
160
|
+
`max_anchor_strength`, `test_ratio` and `pool_size`.
|
|
161
|
+
- Context items carry `docstring`, `body`, `is_anchor`, `anchor_strength` and `is_test`;
|
|
162
|
+
bodies are loaded for the selected candidates only (`GraphRepository.get_symbol_detail`).
|
|
163
|
+
|
|
164
|
+
### Fixed
|
|
165
|
+
|
|
166
|
+
- The assembler treated `graph_distance == 0` as missing (`0 or 3`), so anchors were always
|
|
167
|
+
rendered reference-only instead of at full detail.
|
|
168
|
+
- Indexing slowed down quadratically with graph size. AGE creates a label table on its first
|
|
169
|
+
`MERGE` with only a primary key, so every edge upsert's `MATCH (a {gid: ...})` was a sequential
|
|
170
|
+
scan of the growing vertex tables (~24 ms per edge on a 15k-symbol graph, most of a 40-minute
|
|
171
|
+
index). Migration `0008_graph_label_indexes` now creates the vertex labels up front with a GIN
|
|
172
|
+
index on `properties` (`fastupdate = off`), which brings the lookup to ~2 ms and makes the
|
|
173
|
+
embedding calls the remaining cost.
|
|
174
|
+
- `VoyageEncoder` sent a whole file's symbols in one request; files with more than 1000 symbols
|
|
175
|
+
(or over the token ceiling) failed the index with `InvalidRequestError`. Requests are now split
|
|
176
|
+
into batches of at most 500 texts / 400k characters.
|
|
177
|
+
|
|
178
|
+
## [0.2.1] - 2026-09-11
|
|
179
|
+
|
|
180
|
+
### Added
|
|
181
|
+
|
|
182
|
+
- Indexing over MCP: `index_repo` and `reindex_repo`, plus the read-only `get_index_job` and
|
|
183
|
+
`list_index_jobs`. Both write tools take a local working tree and enqueue a job rather than
|
|
184
|
+
indexing inline, because a full index outlives any agent's tool-call timeout. They are gated
|
|
185
|
+
behind `BCE_MCP_ALLOW_WRITE` (default off) and are neither advertised nor dispatchable while
|
|
186
|
+
it is off. With it on, the MCP process also runs job workers, so queued indexing progresses
|
|
187
|
+
without a separate `bce serve`; the pool claims `index` and `reindex` only, so a clone that
|
|
188
|
+
REST enqueued is not run inside an editor-spawned process. Cloning a remote repository is
|
|
189
|
+
deliberately not exposed over MCP: it carries its own credentials and stays on REST and the CLI.
|
|
190
|
+
- `JobWorkerPool(job_types=...)` and `claim_next_job(job_types=...)` restrict a pool to a subset
|
|
191
|
+
of the queue.
|
|
192
|
+
- `bce --env-file PATH` and `BCE_ENV_FILE` load configuration from an explicit `.env`. Editors
|
|
193
|
+
spawn `bce serve-mcp` from their own working directory, so a bare `.env` was never found and the
|
|
194
|
+
MCP server silently ran on defaults — no Voyage key, no database password. `serve` and
|
|
195
|
+
`serve-mcp` accept the option after the command name as well as before it, because that is how
|
|
196
|
+
an MCP config or a service definition is written.
|
|
197
|
+
|
|
198
|
+
### Changed
|
|
199
|
+
|
|
200
|
+
- The MCP catalog is now eight read-only tools instead of fourteen. Removed `semantic_search`,
|
|
201
|
+
`find_similar_code`, `find_implementers`, `get_type_hierarchy`, `get_dependencies`,
|
|
202
|
+
`suggest_change_sites`, `select_repos` and `assemble_context`: an agent picks worse when
|
|
203
|
+
handed a dozen overlapping retrieval tools, and `hybrid_search` and `get_context_for_task`
|
|
204
|
+
already cover what they did. All of them remain available over REST.
|
|
205
|
+
- The optional `mcp` extra is now `mcp>=1.0,<2`. SDK 2.x dropped `Server.list_tools` /
|
|
206
|
+
`Server.call_tool`, so `bce serve-mcp` failed on a default `pip install` of 2.x.
|
|
207
|
+
|
|
208
|
+
### Fixed
|
|
209
|
+
|
|
210
|
+
- The first search on an MCP server no longer hangs. Building the embedding encoder imports
|
|
211
|
+
numpy, and loading that extension lazily from inside a tool call stalled for over three
|
|
212
|
+
minutes on Windows while the same import costs seconds at process start, so the encoder is
|
|
213
|
+
now built during startup. Tool dispatch also moved off the event loop onto a worker thread,
|
|
214
|
+
since its database and HTTP calls are synchronous.
|
|
215
|
+
- The MCP server configures logging, against stderr because stdout carries the protocol. Its job
|
|
216
|
+
worker's failures previously fell through to Python's last-resort handler and surfaced in editor
|
|
217
|
+
logs as bare tracebacks; they are now the same JSON lines the API server emits, and they reach
|
|
218
|
+
the log file too. `setup_logging(stream=...)` makes the console destination overridable.
|
|
219
|
+
|
|
220
|
+
## [0.2.0] - 2026-09-10
|
|
221
|
+
|
|
222
|
+
### Changed
|
|
223
|
+
|
|
224
|
+
- Both READMEs now reference images, videos and sibling documents by absolute URL. PyPI
|
|
225
|
+
renders the long description outside the repository, so relative paths resolved to
|
|
226
|
+
nothing there: the banner was a broken image and every documentation link a dead one.
|
|
227
|
+
- Selecting `BCE_EMBEDDING_PROVIDER=voyage` without its API key no longer falls back to the
|
|
228
|
+
hashing encoder. Both that case and a missing `voyageai` package now raise
|
|
229
|
+
`EncoderConfigError`, which the CLI reports as a single line and the REST API as `503`.
|
|
230
|
+
A substituted encoder is not detectable by nearest-neighbour search, so it returned bad
|
|
231
|
+
anchors instead of an error. An unrecognised provider name is rejected the same way.
|
|
232
|
+
- Removed `Settings.voyage_ready`, whose "ready" no longer matched how the encoder is
|
|
233
|
+
chosen.
|
|
234
|
+
|
|
235
|
+
## [0.1.0] - 2026-09-08
|
|
236
|
+
|
|
237
|
+
First public release.
|
|
238
|
+
|
|
239
|
+
### Added
|
|
240
|
+
|
|
241
|
+
- Deterministic retrieval pipeline: anchor discovery, graph expansion, scoring, narrowing
|
|
242
|
+
and context assembly, with coverage and confidence reporting.
|
|
243
|
+
- Code graph over PostgreSQL with Apache AGE and pgvector in a single database. Layer-3
|
|
244
|
+
results are filtered per user against the `scopes` table, resolved from the
|
|
245
|
+
`X-BCE-User` header.
|
|
246
|
+
- Tree-sitter indexing for Python, JavaScript and TypeScript, with optional grammars for
|
|
247
|
+
Java, C# and Go. Incremental re-indexing driven by `git diff`.
|
|
248
|
+
- Layer 1, 2 and 3 tool surfaces exposed over both REST and MCP.
|
|
249
|
+
- Web interface at `/ui`: a graph explorer and a player that replays each pipeline stage
|
|
250
|
+
for a given task. Ships inside the wheel; English by default with a Turkish catalog.
|
|
251
|
+
- `bce` command line interface: `migrate`, `index`, `index-remote`, `reindex`, `bench`,
|
|
252
|
+
`resolve-symbol`, `find-references`, `languages`, `serve` and `serve-mcp`.
|
|
253
|
+
- Benchmark harness reporting latency, recall, precision and determinism.
|
|
254
|
+
- Docker Compose deployment with PostgreSQL, Apache AGE and pgvector preconfigured.
|
|
255
|
+
- `server.json` manifest describing the stdio server for the official MCP registry.
|
|
256
|
+
|
|
257
|
+
[Unreleased]: https://github.com/bgts-ai-org/bgts-context-engine/compare/v0.2.2...HEAD
|
|
258
|
+
[0.2.2]: https://github.com/bgts-ai-org/bgts-context-engine/compare/v0.2.1...v0.2.2
|
|
259
|
+
[0.2.1]: https://github.com/bgts-ai-org/bgts-context-engine/compare/v0.2.0...v0.2.1
|
|
260
|
+
[0.2.0]: https://github.com/bgts-ai-org/bgts-context-engine/compare/v0.1.0...v0.2.0
|
|
261
|
+
[0.1.0]: https://github.com/bgts-ai-org/bgts-context-engine/releases/tag/v0.1.0
|
{bgts_context_engine-0.2.0/src/bgts_context_engine.egg-info → bgts_context_engine-0.2.2}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bgts-context-engine
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: Deterministic code-graph context engine for AI coding agents - PostgreSQL, Apache AGE and pgvector, over MCP and REST
|
|
5
5
|
Author: Oğuz Öztürk, Enes İyidil
|
|
6
6
|
Maintainer: BGTS
|
|
@@ -42,7 +42,7 @@ Requires-Dist: pytest-cov>=5.0; extra == "dev"
|
|
|
42
42
|
Requires-Dist: ruff>=0.4; extra == "dev"
|
|
43
43
|
Requires-Dist: httpx>=0.27; extra == "dev"
|
|
44
44
|
Provides-Extra: mcp
|
|
45
|
-
Requires-Dist: mcp
|
|
45
|
+
Requires-Dist: mcp<2,>=1.0; extra == "mcp"
|
|
46
46
|
Provides-Extra: embed
|
|
47
47
|
Requires-Dist: voyageai>=0.3; extra == "embed"
|
|
48
48
|
Provides-Extra: langs
|
|
@@ -132,16 +132,30 @@ Then serve it:
|
|
|
132
132
|
|
|
133
133
|
```bash
|
|
134
134
|
bce serve # REST at :8000/docs, web UI at :8000/ui/
|
|
135
|
-
bce serve-mcp # MCP over stdio, for agents
|
|
135
|
+
bce serve-mcp # MCP over stdio, for agents (install the [mcp] extra; see below)
|
|
136
136
|
```
|
|
137
137
|
|
|
138
138
|
## Use it from your agent
|
|
139
139
|
|
|
140
|
-
The MCP surface is behind the `mcp` extra: `
|
|
141
|
-
|
|
142
|
-
|
|
140
|
+
The MCP surface is behind the `mcp` extra (Python MCP SDK 1.x: `mcp>=1.0,<2`). Install it
|
|
141
|
+
so `bce` is on the **user PATH**, not only inside a project `.venv`. Cursor and VS Code
|
|
142
|
+
spawn `bce serve-mcp` themselves and do not activate the venv:
|
|
143
143
|
|
|
144
|
-
|
|
144
|
+
```bash
|
|
145
|
+
pip install "bgts-context-engine[mcp]"
|
|
146
|
+
bce --version # must work in a new terminal, with no venv activated
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Every MCP client uses the same stdio command plus the database in the environment. Do not
|
|
150
|
+
leave `bce serve-mcp` running in a terminal for the editor: stdout is the protocol, so the
|
|
151
|
+
process stays silent, and the IDE starts its own copy.
|
|
152
|
+
|
|
153
|
+
After you add or change the MCP config, **restart Cursor or VS Code** (or Command Palette
|
|
154
|
+
→ “Developer: Reload Window”). The server should then show as enabled with eight tools (ten with indexing enabled).
|
|
155
|
+
Setup detail: [docs/mcp.md](docs/mcp.md).
|
|
156
|
+
|
|
157
|
+
**Cursor** — user config `~/.cursor/mcp.json` (applies to every project), or a project
|
|
158
|
+
`.cursor/mcp.json` that stays local (the directory is gitignored):
|
|
145
159
|
|
|
146
160
|
```json
|
|
147
161
|
{
|
|
@@ -155,31 +169,41 @@ database connection in the environment.
|
|
|
155
169
|
}
|
|
156
170
|
```
|
|
157
171
|
|
|
158
|
-
**
|
|
159
|
-
|
|
160
|
-
```bash
|
|
161
|
-
claude mcp add bgts-context-engine --env BCE_DB_HOST=localhost -- bce serve-mcp
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
**VS Code** — `.vscode/mcp.json`:
|
|
172
|
+
**VS Code** — user MCP settings, or a project `.vscode/mcp.json` (also gitignored):
|
|
165
173
|
|
|
166
174
|
```json
|
|
167
175
|
{
|
|
168
176
|
"servers": {
|
|
169
|
-
"bgts-context-engine": {
|
|
177
|
+
"bgts-context-engine": {
|
|
178
|
+
"type": "stdio",
|
|
179
|
+
"command": "bce",
|
|
180
|
+
"args": ["serve-mcp"],
|
|
181
|
+
"env": { "BCE_DB_HOST": "localhost", "BCE_DB_NAME": "bce" }
|
|
182
|
+
}
|
|
170
183
|
}
|
|
171
184
|
}
|
|
172
185
|
```
|
|
173
186
|
|
|
187
|
+
**Claude Code** — one command:
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
claude mcp add bgts-context-engine --env BCE_DB_HOST=localhost -- bce serve-mcp
|
|
191
|
+
```
|
|
192
|
+
|
|
174
193
|
**Claude Desktop** — same block as Cursor, in `claude_desktop_config.json`.
|
|
175
194
|
|
|
176
|
-
|
|
177
|
-
|
|
195
|
+
If `command: "bce"` stays disconnected, the editor cannot see `bce` on PATH. Install as
|
|
196
|
+
above, or skip a permanent install with `uvx`:
|
|
197
|
+
|
|
198
|
+
```json
|
|
199
|
+
"command": "uvx",
|
|
200
|
+
"args": ["--from", "bgts-context-engine[mcp]", "bce", "serve-mcp"]
|
|
201
|
+
```
|
|
178
202
|
|
|
179
203
|
Then ask your agent something that needs the repository rather than the file you have open:
|
|
180
204
|
*"what breaks if I change the session TTL?"* The agent calls `get_context_for_task`, and the
|
|
181
|
-
|
|
182
|
-
|
|
205
|
+
other tools in [docs/mcp.md](docs/mcp.md) let it drill from there — exact callers, the blast
|
|
206
|
+
radius of a change, the symbol behind a name — without guessing at file names.
|
|
183
207
|
|
|
184
208
|
## What comes back
|
|
185
209
|
|
|
@@ -265,7 +289,7 @@ The full formula, every weight, and the confidence thresholds are in
|
|
|
265
289
|
moves and reformatting, so history and embeddings stay valid.
|
|
266
290
|
- **One database.** Apache AGE and pgvector in the same PostgreSQL, so one query joins a
|
|
267
291
|
graph traversal, a vector search and a SQL filter — and one `pg_dump` backs up the index.
|
|
268
|
-
- **MCP and REST from one implementation.**
|
|
292
|
+
- **MCP and REST from one implementation.** A focused tool set over stdio, the same functions
|
|
269
293
|
over HTTP. Nothing to drift.
|
|
270
294
|
- **A UI that explains itself.** `/ui` ships in the wheel and replays a real retrieval call
|
|
271
295
|
stage by stage: anchors lighting up, expansion spreading, candidates scored and cut.
|
|
@@ -337,7 +361,7 @@ actually ask for reorders this list.
|
|
|
337
361
|
| [Architecture](docs/architecture.md) | the deterministic line, the three layers, indexing |
|
|
338
362
|
| [Retrieval](docs/retrieval.md) | anchors, expansion, every scoring weight, confidence |
|
|
339
363
|
| [Data model](docs/data-model.md) | node labels, edge types, tables, symbol identity |
|
|
340
|
-
| [MCP and API](docs/mcp.md) |
|
|
364
|
+
| [MCP and API](docs/mcp.md) | every tool and endpoint, MCP configuration, the CLI |
|
|
341
365
|
| [Languages](docs/languages.md) | what each parser extracts, and how to add one |
|
|
342
366
|
| [Deployment](docs/deployment.md) | configuration reference, jobs, backup, benchmarking |
|
|
343
367
|
| [Web interface](web/README.md) | developing the frontend |
|
|
@@ -368,6 +392,3 @@ rather than in an issue.
|
|
|
368
392
|
## License
|
|
369
393
|
|
|
370
394
|
[MIT](LICENSE) © BGTS.
|
|
371
|
-
|
|
372
|
-
Built by [Oğuz Öztürk](https://github.com/oztrkoguz) and
|
|
373
|
-
[Enes İyidil](https://github.com/enesiyidil).
|
|
@@ -79,16 +79,30 @@ Then serve it:
|
|
|
79
79
|
|
|
80
80
|
```bash
|
|
81
81
|
bce serve # REST at :8000/docs, web UI at :8000/ui/
|
|
82
|
-
bce serve-mcp # MCP over stdio, for agents
|
|
82
|
+
bce serve-mcp # MCP over stdio, for agents (install the [mcp] extra; see below)
|
|
83
83
|
```
|
|
84
84
|
|
|
85
85
|
## Use it from your agent
|
|
86
86
|
|
|
87
|
-
The MCP surface is behind the `mcp` extra: `
|
|
88
|
-
|
|
89
|
-
|
|
87
|
+
The MCP surface is behind the `mcp` extra (Python MCP SDK 1.x: `mcp>=1.0,<2`). Install it
|
|
88
|
+
so `bce` is on the **user PATH**, not only inside a project `.venv`. Cursor and VS Code
|
|
89
|
+
spawn `bce serve-mcp` themselves and do not activate the venv:
|
|
90
90
|
|
|
91
|
-
|
|
91
|
+
```bash
|
|
92
|
+
pip install "bgts-context-engine[mcp]"
|
|
93
|
+
bce --version # must work in a new terminal, with no venv activated
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Every MCP client uses the same stdio command plus the database in the environment. Do not
|
|
97
|
+
leave `bce serve-mcp` running in a terminal for the editor: stdout is the protocol, so the
|
|
98
|
+
process stays silent, and the IDE starts its own copy.
|
|
99
|
+
|
|
100
|
+
After you add or change the MCP config, **restart Cursor or VS Code** (or Command Palette
|
|
101
|
+
→ “Developer: Reload Window”). The server should then show as enabled with eight tools (ten with indexing enabled).
|
|
102
|
+
Setup detail: [docs/mcp.md](docs/mcp.md).
|
|
103
|
+
|
|
104
|
+
**Cursor** — user config `~/.cursor/mcp.json` (applies to every project), or a project
|
|
105
|
+
`.cursor/mcp.json` that stays local (the directory is gitignored):
|
|
92
106
|
|
|
93
107
|
```json
|
|
94
108
|
{
|
|
@@ -102,31 +116,41 @@ database connection in the environment.
|
|
|
102
116
|
}
|
|
103
117
|
```
|
|
104
118
|
|
|
105
|
-
**
|
|
106
|
-
|
|
107
|
-
```bash
|
|
108
|
-
claude mcp add bgts-context-engine --env BCE_DB_HOST=localhost -- bce serve-mcp
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
**VS Code** — `.vscode/mcp.json`:
|
|
119
|
+
**VS Code** — user MCP settings, or a project `.vscode/mcp.json` (also gitignored):
|
|
112
120
|
|
|
113
121
|
```json
|
|
114
122
|
{
|
|
115
123
|
"servers": {
|
|
116
|
-
"bgts-context-engine": {
|
|
124
|
+
"bgts-context-engine": {
|
|
125
|
+
"type": "stdio",
|
|
126
|
+
"command": "bce",
|
|
127
|
+
"args": ["serve-mcp"],
|
|
128
|
+
"env": { "BCE_DB_HOST": "localhost", "BCE_DB_NAME": "bce" }
|
|
129
|
+
}
|
|
117
130
|
}
|
|
118
131
|
}
|
|
119
132
|
```
|
|
120
133
|
|
|
134
|
+
**Claude Code** — one command:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
claude mcp add bgts-context-engine --env BCE_DB_HOST=localhost -- bce serve-mcp
|
|
138
|
+
```
|
|
139
|
+
|
|
121
140
|
**Claude Desktop** — same block as Cursor, in `claude_desktop_config.json`.
|
|
122
141
|
|
|
123
|
-
|
|
124
|
-
|
|
142
|
+
If `command: "bce"` stays disconnected, the editor cannot see `bce` on PATH. Install as
|
|
143
|
+
above, or skip a permanent install with `uvx`:
|
|
144
|
+
|
|
145
|
+
```json
|
|
146
|
+
"command": "uvx",
|
|
147
|
+
"args": ["--from", "bgts-context-engine[mcp]", "bce", "serve-mcp"]
|
|
148
|
+
```
|
|
125
149
|
|
|
126
150
|
Then ask your agent something that needs the repository rather than the file you have open:
|
|
127
151
|
*"what breaks if I change the session TTL?"* The agent calls `get_context_for_task`, and the
|
|
128
|
-
|
|
129
|
-
|
|
152
|
+
other tools in [docs/mcp.md](docs/mcp.md) let it drill from there — exact callers, the blast
|
|
153
|
+
radius of a change, the symbol behind a name — without guessing at file names.
|
|
130
154
|
|
|
131
155
|
## What comes back
|
|
132
156
|
|
|
@@ -212,7 +236,7 @@ The full formula, every weight, and the confidence thresholds are in
|
|
|
212
236
|
moves and reformatting, so history and embeddings stay valid.
|
|
213
237
|
- **One database.** Apache AGE and pgvector in the same PostgreSQL, so one query joins a
|
|
214
238
|
graph traversal, a vector search and a SQL filter — and one `pg_dump` backs up the index.
|
|
215
|
-
- **MCP and REST from one implementation.**
|
|
239
|
+
- **MCP and REST from one implementation.** A focused tool set over stdio, the same functions
|
|
216
240
|
over HTTP. Nothing to drift.
|
|
217
241
|
- **A UI that explains itself.** `/ui` ships in the wheel and replays a real retrieval call
|
|
218
242
|
stage by stage: anchors lighting up, expansion spreading, candidates scored and cut.
|
|
@@ -284,7 +308,7 @@ actually ask for reorders this list.
|
|
|
284
308
|
| [Architecture](docs/architecture.md) | the deterministic line, the three layers, indexing |
|
|
285
309
|
| [Retrieval](docs/retrieval.md) | anchors, expansion, every scoring weight, confidence |
|
|
286
310
|
| [Data model](docs/data-model.md) | node labels, edge types, tables, symbol identity |
|
|
287
|
-
| [MCP and API](docs/mcp.md) |
|
|
311
|
+
| [MCP and API](docs/mcp.md) | every tool and endpoint, MCP configuration, the CLI |
|
|
288
312
|
| [Languages](docs/languages.md) | what each parser extracts, and how to add one |
|
|
289
313
|
| [Deployment](docs/deployment.md) | configuration reference, jobs, backup, benchmarking |
|
|
290
314
|
| [Web interface](web/README.md) | developing the frontend |
|
|
@@ -315,6 +339,3 @@ rather than in an issue.
|
|
|
315
339
|
## License
|
|
316
340
|
|
|
317
341
|
[MIT](LICENSE) © BGTS.
|
|
318
|
-
|
|
319
|
-
Built by [Oğuz Öztürk](https://github.com/oztrkoguz) and
|
|
320
|
-
[Enes İyidil](https://github.com/enesiyidil).
|
|
@@ -79,16 +79,30 @@ Ardından servis edin:
|
|
|
79
79
|
|
|
80
80
|
```bash
|
|
81
81
|
bce serve # :8000/docs adresinde REST, :8000/ui/ adresinde web arayüzü
|
|
82
|
-
bce serve-mcp # ajanlar için stdio üzerinden MCP
|
|
82
|
+
bce serve-mcp # ajanlar için stdio üzerinden MCP ([mcp] eki gerekir; aşağıya bakın)
|
|
83
83
|
```
|
|
84
84
|
|
|
85
85
|
## Ajanınızdan kullanma
|
|
86
86
|
|
|
87
|
-
MCP yüzeyi `mcp` ekinin arkasındadır: `
|
|
88
|
-
|
|
89
|
-
|
|
87
|
+
MCP yüzeyi `mcp` ekinin arkasındadır (Python MCP SDK 1.x: `mcp>=1.0,<2`). `bce` komutunu
|
|
88
|
+
yalnızca proje `.venv` içine değil, **kullanıcı PATH'ine** kurun. Cursor ve VS Code
|
|
89
|
+
`bce serve-mcp` sürecini kendileri başlatır; sanal ortamı etkinleştirmezler:
|
|
90
90
|
|
|
91
|
-
|
|
91
|
+
```bash
|
|
92
|
+
pip install "bgts-context-engine[mcp]"
|
|
93
|
+
bce --version # venv kapalı, yeni bir terminalde çalışmalı
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Her MCP istemcisi aynı stdio komutunu ve ortamındaki veritabanı bağlantısını kullanır.
|
|
97
|
+
Editör için terminalde `bce serve-mcp` açık bırakmayın: stdout protokoldür, bu yüzden
|
|
98
|
+
süreç sessiz kalır; IDE kendi kopyasını başlatır.
|
|
99
|
+
|
|
100
|
+
MCP yapılandırmasını ekledikten veya değiştirdikten sonra **Cursor veya VS Code'u
|
|
101
|
+
yeniden başlatın** (veya Komut Paleti → “Developer: Reload Window”). Sunucu sekiz araçla
|
|
102
|
+
(indeksleme açıkken on araçla) etkin görünmelidir. Ayrıntı: [docs/mcp.md](docs/mcp.md).
|
|
103
|
+
|
|
104
|
+
**Cursor** — her proje için kullanıcı yapılandırması `~/.cursor/mcp.json`, ya da yerelde
|
|
105
|
+
kalan bir proje `.cursor/mcp.json` (dizin gitignore'dadır):
|
|
92
106
|
|
|
93
107
|
```json
|
|
94
108
|
{
|
|
@@ -102,31 +116,42 @@ veritabanı bağlantısı.
|
|
|
102
116
|
}
|
|
103
117
|
```
|
|
104
118
|
|
|
105
|
-
**
|
|
106
|
-
|
|
107
|
-
```bash
|
|
108
|
-
claude mcp add bgts-context-engine --env BCE_DB_HOST=localhost -- bce serve-mcp
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
**VS Code** — `.vscode/mcp.json`:
|
|
119
|
+
**VS Code** — kullanıcı MCP ayarları, ya da proje `.vscode/mcp.json` (o da gitignore'dadır):
|
|
112
120
|
|
|
113
121
|
```json
|
|
114
122
|
{
|
|
115
123
|
"servers": {
|
|
116
|
-
"bgts-context-engine": {
|
|
124
|
+
"bgts-context-engine": {
|
|
125
|
+
"type": "stdio",
|
|
126
|
+
"command": "bce",
|
|
127
|
+
"args": ["serve-mcp"],
|
|
128
|
+
"env": { "BCE_DB_HOST": "localhost", "BCE_DB_NAME": "bce" }
|
|
129
|
+
}
|
|
117
130
|
}
|
|
118
131
|
}
|
|
119
132
|
```
|
|
120
133
|
|
|
134
|
+
**Claude Code** — tek komut:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
claude mcp add bgts-context-engine --env BCE_DB_HOST=localhost -- bce serve-mcp
|
|
138
|
+
```
|
|
139
|
+
|
|
121
140
|
**Claude Desktop** — `claude_desktop_config.json` içinde Cursor ile aynı blok.
|
|
122
141
|
|
|
123
|
-
|
|
124
|
-
|
|
142
|
+
`"command": "bce"` bağlı kalmazsa editör PATH'te `bce` görmüyordur. Yukarıdaki gibi
|
|
143
|
+
kurun, ya da kalıcı kurulum olmadan `uvx` kullanın:
|
|
144
|
+
|
|
145
|
+
```json
|
|
146
|
+
"command": "uvx",
|
|
147
|
+
"args": ["--from", "bgts-context-engine[mcp]", "bce", "serve-mcp"]
|
|
148
|
+
```
|
|
125
149
|
|
|
126
150
|
Sonra ajanınıza, açık olan dosyayı değil deponun tamamını gerektiren bir şey sorun:
|
|
127
151
|
*"session TTL'i değiştirirsem ne bozulur?"* Ajan `get_context_for_task`'ı çağırır;
|
|
128
|
-
[docs/mcp.md](docs/mcp.md) içindeki
|
|
129
|
-
çağıranlar,
|
|
152
|
+
[docs/mcp.md](docs/mcp.md) içindeki diğer araçlar ise oradan devam etmesini sağlar — kesin
|
|
153
|
+
çağıranlar, bir değişikliğin etki alanı, bir adın arkasındaki sembol — dosya adlarını tahmin
|
|
154
|
+
etmeden.
|
|
130
155
|
|
|
131
156
|
## Ne döner
|
|
132
157
|
|
|
@@ -214,8 +239,8 @@ Formülün tamamı, her ağırlık ve güven eşikleri
|
|
|
214
239
|
Sembol kimlikleri dosya taşımalarından ve yeniden biçimlendirmeden sağ çıkar.
|
|
215
240
|
- **Tek veritabanı.** Apache AGE ve pgvector aynı PostgreSQL içinde; tek sorgu bir graf
|
|
216
241
|
gezinmesini, bir vektör aramasını ve bir SQL filtresini birleştirir.
|
|
217
|
-
- **Tek gerçeklemeden MCP ve REST.** stdio üzerinden
|
|
218
|
-
fonksiyonlar. Aralarında kayma olacak bir şey yok.
|
|
242
|
+
- **Tek gerçeklemeden MCP ve REST.** stdio üzerinden odaklı bir araç kümesi, HTTP üzerinden
|
|
243
|
+
aynı fonksiyonlar. Aralarında kayma olacak bir şey yok.
|
|
219
244
|
- **Kendini açıklayan bir arayüz.** `/ui` wheel içinde gelir ve gerçek bir getirme çağrısını
|
|
220
245
|
aşama aşama oynatır: çapaların yanması, genişlemenin yayılması, adayların skorlanıp
|
|
221
246
|
kesilmesi.
|
|
@@ -290,7 +315,7 @@ Tümü İngilizcedir.
|
|
|
290
315
|
| [Architecture](docs/architecture.md) | deterministik hat, üç katman, indeksleme |
|
|
291
316
|
| [Retrieval](docs/retrieval.md) | çapalar, genişletme, her skorlama ağırlığı, güven |
|
|
292
317
|
| [Data model](docs/data-model.md) | düğüm etiketleri, kenar tipleri, tablolar, sembol kimliği |
|
|
293
|
-
| [MCP and API](docs/mcp.md) |
|
|
318
|
+
| [MCP and API](docs/mcp.md) | her araç ve uç nokta, MCP yapılandırması, CLI |
|
|
294
319
|
| [Languages](docs/languages.md) | her parser'ın çıkardıkları ve yeni dil ekleme |
|
|
295
320
|
| [Deployment](docs/deployment.md) | yapılandırma referansı, işler, yedekleme, ölçüm |
|
|
296
321
|
| [Web interface](web/README.md) | arayüz geliştirme |
|
|
@@ -324,6 +349,3 @@ issue olarak değil, özel kanaldan bildirin.
|
|
|
324
349
|
## Lisans
|
|
325
350
|
|
|
326
351
|
[MIT](LICENSE) © BGTS.
|
|
327
|
-
|
|
328
|
-
[Oğuz Öztürk](https://github.com/oztrkoguz) ve
|
|
329
|
-
[Enes İyidil](https://github.com/enesiyidil) tarafından geliştirildi.
|
|
@@ -69,8 +69,10 @@ dev = [
|
|
|
69
69
|
"httpx>=0.27",
|
|
70
70
|
]
|
|
71
71
|
# Agent-native MCP surface (spec section 7). Optional: the REST API works without it.
|
|
72
|
+
# Pin below 2.x: the Python SDK 2.x removed Server.list_tools / Server.call_tool, which
|
|
73
|
+
# bce serve-mcp still uses.
|
|
72
74
|
mcp = [
|
|
73
|
-
"mcp>=1.0",
|
|
75
|
+
"mcp>=1.0,<2",
|
|
74
76
|
]
|
|
75
77
|
# Voyage AI embeddings (Phase 2). Optional: the hashing fallback works without it.
|
|
76
78
|
embed = [
|