java-codebase-rag 0.9.0__tar.gz → 0.9.1__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.
- {java_codebase_rag-0.9.0/java_codebase_rag.egg-info → java_codebase_rag-0.9.1}/PKG-INFO +1 -1
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/java_codebase_rag/config.py +27 -3
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/java_codebase_rag/lance_optimize.py +25 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/java_codebase_rag/pipeline.py +20 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1/java_codebase_rag.egg-info}/PKG-INFO +1 -1
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/java_codebase_rag.egg-info/SOURCES.txt +1 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/java_index_flow_lancedb.py +66 -6
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/pyproject.toml +1 -1
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/server.py +25 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_config.py +4 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_lance_optimize.py +75 -14
- java_codebase_rag-0.9.1/tests/test_pipeline.py +103 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/LICENSE +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/README.md +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/ast_java.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/brownfield_events.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/build_ast_graph.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/chunk_heuristics.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/graph_enrich.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/graph_types.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/index_common.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/java_codebase_rag/__init__.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/java_codebase_rag/_fdlimit.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/java_codebase_rag/_stdio.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/java_codebase_rag/cli.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/java_codebase_rag/cli_format.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/java_codebase_rag/cli_progress.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/java_codebase_rag/install_data/agents/explorer-rag-cli.md +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/java_codebase_rag/install_data/agents/explorer-rag-enhanced.md +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/java_codebase_rag/install_data/skills/explore-codebase/SKILL.md +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/java_codebase_rag/install_data/skills/explore-codebase-cli/SKILL.md +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/java_codebase_rag/installer.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/java_codebase_rag/jrag.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/java_codebase_rag/jrag_envelope.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/java_codebase_rag/jrag_hints.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/java_codebase_rag/jrag_render.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/java_codebase_rag/progress.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/java_codebase_rag.egg-info/dependency_links.txt +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/java_codebase_rag.egg-info/entry_points.txt +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/java_codebase_rag.egg-info/requires.txt +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/java_codebase_rag.egg-info/top_level.txt +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/java_index_v1_common.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/java_ontology.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/ladybug_queries.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/mcp_hints.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/mcp_v2.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/path_filtering.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/pr_analysis.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/resolve_service.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/search_lancedb.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/setup.cfg +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_agent_skills_static.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_assign_endpoint_client_extraction.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_ast_graph_build.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_ast_java_calls.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_ast_java_capabilities.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_ast_java_thread_safety.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_bank_chat_brownfield_integration.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_brownfield_clients.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_brownfield_events.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_brownfield_overrides.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_brownfield_routes.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_call_edge_matching.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_call_edges_e2e.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_call_graph_receiver_resolution.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_call_graph_smoke_roundtrip.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_call_invariant.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_cli_progress_stdout_invariant.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_cli_quiet_parity.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_client_hint_recovery.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_client_node_extraction.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_client_role_rename.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_cross_service_resolution_flag.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_edge_navigation_doc.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_fd_limit.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_feign_not_exposer.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_graph_enrich.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_graph_only_boot.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_incremental_graph.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_install_data_sync.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_installer.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_installer_integration.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_installer_surface.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_java_codebase_rag_cli.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_jrag_auto_scope.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_jrag_envelope.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_jrag_listing.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_jrag_locate.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_jrag_orientation.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_jrag_render.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_jrag_status.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_jrag_token_budget.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_jrag_traversal_compose.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_jrag_traversal_direct.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_ladybug_queries.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_lancedb_e2e.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_mcp_hints.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_mcp_server_project_root.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_mcp_tools.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_mcp_v2.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_mcp_v2_compose.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_meta_chain_core.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_microservice_scope.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_outgoing_call_extraction.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_packaging_metadata.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_path_filtering.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_pr_analysis.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_progress.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_resolve_routes_messaging_layer_c.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_resolve_service.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_route_extraction.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_schema_consistency.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_search_lancedb.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_search_lancedb_capability.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_string_value_atoms.py +0 -0
- {java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_vectors_progress.py +0 -0
|
@@ -47,15 +47,39 @@ ENV_RUN_HEAVY = "JAVA_CODEBASE_RAG_RUN_HEAVY"
|
|
|
47
47
|
COCOINDEX_MAX_INFLIGHT_COMPONENTS_ENV = "COCOINDEX_MAX_INFLIGHT_COMPONENTS"
|
|
48
48
|
COCOINDEX_DEFAULT_MAX_INFLIGHT_COMPONENTS = "256"
|
|
49
49
|
|
|
50
|
+
# Lance native DataFusion hash-join memory pool ceiling (FairSpillPool). The
|
|
51
|
+
# lance default is ~100 MiB, tuned for query workloads — too small for the
|
|
52
|
+
# single big ``merge_insert`` cocoindex emits at the end of a flow component.
|
|
53
|
+
# On ``--full-reprocess`` (all rows match the existing table → bulk-update
|
|
54
|
+
# path) the hash join builds on a large side and exhausts the pool somewhere
|
|
55
|
+
# around 75k-100k chunks: "Resources exhausted: Failed to allocate ... for
|
|
56
|
+
# HashJoinInput ... N MiB remain available for the total pool". cocoindex is a
|
|
57
|
+
# bare pass-through to lancedb (it never sets a Session/memory_limit), so it
|
|
58
|
+
# inherits this default — we raise it here. FairSpillPool is a *reservation
|
|
59
|
+
# ceiling*, not a pre-allocation: setting 1 GiB does not reserve 1 GiB upfront,
|
|
60
|
+
# it just allows the join to grow before spilling/erroring, so it is safe on
|
|
61
|
+
# memory-constrained hosts. An operator can still override via their own
|
|
62
|
+
# ``LANCE_MEM_POOL_SIZE`` (subprocess_env copies os.environ, and apply is via
|
|
63
|
+
# ``setdefault`` so the operator value wins). Increment is unaffected (tiny
|
|
64
|
+
# batch → tiny hash table); only the full-reprocess write path is at risk.
|
|
65
|
+
LANCE_MEM_POOL_SIZE_ENV = "LANCE_MEM_POOL_SIZE"
|
|
66
|
+
LANCE_DEFAULT_MEM_POOL_SIZE = "1073741824" # 1 GiB
|
|
67
|
+
|
|
50
68
|
|
|
51
69
|
def cocoindex_subprocess_env_defaults() -> dict[str, str]:
|
|
52
|
-
"""Env defaults applied to every CocoIndex subprocess
|
|
70
|
+
"""Env defaults applied to every CocoIndex subprocess.
|
|
71
|
+
|
|
72
|
+
Bounds CocoIndex concurrency (``COCOINDEX_MAX_INFLIGHT_COMPONENTS``; see
|
|
73
|
+
:issue:`306`) and raises the Lance hash-join memory ceiling
|
|
74
|
+
(``LANCE_MEM_POOL_SIZE``) so a large full-reprocess does not exhaust the
|
|
75
|
+
default ~100 MiB pool mid-``merge_insert``.
|
|
53
76
|
|
|
54
77
|
Apply with ``env.setdefault(...)`` so a caller-provided (operator) value
|
|
55
|
-
always wins.
|
|
78
|
+
always wins.
|
|
56
79
|
"""
|
|
57
80
|
return {
|
|
58
|
-
COCOINDEX_MAX_INFLIGHT_COMPONENTS_ENV: COCOINDEX_DEFAULT_MAX_INFLIGHT_COMPONENTS
|
|
81
|
+
COCOINDEX_MAX_INFLIGHT_COMPONENTS_ENV: COCOINDEX_DEFAULT_MAX_INFLIGHT_COMPONENTS,
|
|
82
|
+
LANCE_MEM_POOL_SIZE_ENV: LANCE_DEFAULT_MEM_POOL_SIZE,
|
|
59
83
|
}
|
|
60
84
|
|
|
61
85
|
_DEFAULT_EMBEDDING_MODEL = "sentence-transformers/all-MiniLM-L6-v2"
|
|
@@ -184,6 +184,31 @@ async def optimize_lance_tables(
|
|
|
184
184
|
|
|
185
185
|
if last_exc is None:
|
|
186
186
|
results[name] = "ok"
|
|
187
|
+
# Best-effort BTREE scalar index on the primary key ("id").
|
|
188
|
+
# cocoindex's merge_insert defaults to use_index=True but
|
|
189
|
+
# never creates a scalar PK index itself (declaring
|
|
190
|
+
# primary_key in the schema does NOT auto-build a lance
|
|
191
|
+
# index), so without this every merge_insert — increment
|
|
192
|
+
# included — is a forced full scan of the PK column,
|
|
193
|
+
# O(existing rows). On a large repo that scan dominates
|
|
194
|
+
# increment wall-clock; with the index present the join does
|
|
195
|
+
# lookups (~O(batch*log N)). Failure is non-fatal (the table
|
|
196
|
+
# is still correct, just un-indexed) and never alters the
|
|
197
|
+
# "ok" status, mirroring the FTS block below. ``replace=True``
|
|
198
|
+
# keeps it idempotent across runs; table.optimize() above
|
|
199
|
+
# maintains it on subsequent runs.
|
|
200
|
+
try:
|
|
201
|
+
from lancedb.index import BTree
|
|
202
|
+
await table.create_index("id", config=BTree(), replace=True)
|
|
203
|
+
except Exception as exc:
|
|
204
|
+
low = str(exc).lower()
|
|
205
|
+
if not any(
|
|
206
|
+
w in low for w in ("exist", "duplicate", "already", "same name")
|
|
207
|
+
) and not quiet:
|
|
208
|
+
print(
|
|
209
|
+
f"java-codebase-rag: optimize: {name} id-index skipped: {exc}",
|
|
210
|
+
file=sys.stderr,
|
|
211
|
+
)
|
|
187
212
|
# Best-effort FTS index at index time (PR-SEARCH-3) so hybrid
|
|
188
213
|
# search works on all tables (java/sql/yaml) without a
|
|
189
214
|
# first-query race. Failure is non-fatal — the lazy
|
|
@@ -132,6 +132,26 @@ def run_cocoindex_update(
|
|
|
132
132
|
on_progress: Callable[[ProgressEvent], None] | None = None,
|
|
133
133
|
on_progress_console: object | None = None,
|
|
134
134
|
) -> subprocess.CompletedProcess[str]:
|
|
135
|
+
if full_reprocess:
|
|
136
|
+
# A full reprocess rebuilds every row, so DROP the Lance target tables
|
|
137
|
+
# first and let cocoindex recreate them via the fast INSERT path. The
|
|
138
|
+
# in-place alternative (cocoindex's bulk-update merge_insert) emits
|
|
139
|
+
# ~one deletion-vector + version commit PER matched row — O(rows) of
|
|
140
|
+
# tiny file IO that scales to multi-minute hangs on large repos
|
|
141
|
+
# (measured ~83s sys time / 3474 deletion files for 3475 chunks on
|
|
142
|
+
# Shopizer; drop+recreate is ~3.6s sys / 0 deletions, ~3.7x faster and
|
|
143
|
+
# hang-free). Output is identical either way (full recompute); only the
|
|
144
|
+
# write path differs. Drop failure is non-fatal — if it somehow fails,
|
|
145
|
+
# the update falls back to the slow in-place path. The same fix is
|
|
146
|
+
# applied on the async server path (``server.run_refresh_pipeline``).
|
|
147
|
+
drop = run_cocoindex_drop(env, quiet=quiet)
|
|
148
|
+
if drop.returncode != 0 and not is_cocoindex_preflight_blocker(drop):
|
|
149
|
+
print(
|
|
150
|
+
"java-codebase-rag: drop-before-reprocess failed "
|
|
151
|
+
f"(exit {drop.returncode}); falling back to in-place update: "
|
|
152
|
+
f"{(drop.stderr or '').strip()[:200]}",
|
|
153
|
+
file=sys.stderr,
|
|
154
|
+
)
|
|
135
155
|
result = _run_cocoindex_update_impl(
|
|
136
156
|
env,
|
|
137
157
|
full_reprocess=full_reprocess,
|
|
@@ -101,6 +101,7 @@ tests/test_microservice_scope.py
|
|
|
101
101
|
tests/test_outgoing_call_extraction.py
|
|
102
102
|
tests/test_packaging_metadata.py
|
|
103
103
|
tests/test_path_filtering.py
|
|
104
|
+
tests/test_pipeline.py
|
|
104
105
|
tests/test_pr_analysis.py
|
|
105
106
|
tests/test_progress.py
|
|
106
107
|
tests/test_resolve_routes_messaging_layer_c.py
|
|
@@ -112,6 +112,38 @@ _NUM_TXN_BEFORE_OPTIMIZE = 10**12
|
|
|
112
112
|
# parent clamps to total on the terminal event anyway).
|
|
113
113
|
_VECTORS_TICK_EVERY = 25
|
|
114
114
|
|
|
115
|
+
# Bounded concurrency for the per-file drain in app_main. cocoindex's embedder
|
|
116
|
+
# is ``@coco.fn.as_async(batching=True, runner=GPU, max_batch_size=64)`` — but
|
|
117
|
+
# its batching layer only coalesces calls that are in flight SIMULTANEOUSLY. A
|
|
118
|
+
# serial ``async for … await`` loop keeps just one file's chunks (avg 1–3) in
|
|
119
|
+
# flight, so real batches stay tiny and MPS idles between them (measured ~138
|
|
120
|
+
# chunks/s vs the ~235 chunks/s ceiling at batch=64 for all-MiniLM-L6-v2).
|
|
121
|
+
# Draining many files at once with a semaphore puts their chunks in flight
|
|
122
|
+
# together → the embedder coalesces them into full batches → MPS climbs toward
|
|
123
|
+
# the ceiling. Measured on Shopizer (1167 files / 3475 chunks): full init drops
|
|
124
|
+
# from ~46.7s (serial) to ~36.0s (32) / ~34.3s (64), with identical row output.
|
|
125
|
+
#
|
|
126
|
+
# This stays inside ONE component, so the earlier mount_each→app_main win is
|
|
127
|
+
# preserved: still exactly ONE merge_insert per table at commit. Memoization
|
|
128
|
+
# (``@coco.fn(memo=True)``) and the lock-guarded tick counter are safe under
|
|
129
|
+
# concurrency; ``parse_java`` uses a per-thread tree-sitter Parser (already
|
|
130
|
+
# routed via ``asyncio.to_thread``) and ``splitter.split`` is synchronous so the
|
|
131
|
+
# event loop cannot reenter it.
|
|
132
|
+
#
|
|
133
|
+
# Default 64 is sized to MATCH the embedder's hardcoded max_batch_size=64 (the
|
|
134
|
+
# decorator above; not a constructor arg, so not raisable from the flow): ~64
|
|
135
|
+
# files in flight reliably fills a 64-chunk batch and saturates MPS. Going higher
|
|
136
|
+
# buys nothing — the batch is already capped — and lower underfills it. Memory
|
|
137
|
+
# is NOT the limiting factor here: cocoindex buffers ALL staged rows until the
|
|
138
|
+
# single final merge_insert regardless of concurrency, so peak RSS is set by
|
|
139
|
+
# total chunk count (the commit buffer), not by how many files process at once.
|
|
140
|
+
# Set to ``1`` for the old serial behavior; raise/lower only if you have also
|
|
141
|
+
# changed the effective batch size or are constraining the commit buffer itself.
|
|
142
|
+
_FILE_CONCURRENCY = max(
|
|
143
|
+
1,
|
|
144
|
+
int(os.environ.get("JAVA_CODEBASE_RAG_FILE_CONCURRENCY", "64") or "64"),
|
|
145
|
+
)
|
|
146
|
+
|
|
115
147
|
# Thread-safe counter: cocoindex may call process_*_file concurrently
|
|
116
148
|
# (mount_each parallelism is implementation-defined). A module-level lock guards
|
|
117
149
|
# both the counter and the emission so two threads never interleave a tick.
|
|
@@ -533,6 +565,29 @@ async def process_yaml_file(
|
|
|
533
565
|
)
|
|
534
566
|
|
|
535
567
|
|
|
568
|
+
async def _drain_files_concurrently(
|
|
569
|
+
files: Any, process_fn: Any, table: Any, sem: asyncio.Semaphore
|
|
570
|
+
) -> None:
|
|
571
|
+
"""Run ``process_fn(file, table)`` over every file with bounded concurrency.
|
|
572
|
+
|
|
573
|
+
Replaces the serial ``async for … await process_*_file`` loop so the
|
|
574
|
+
embedder's batching layer sees many files' chunks in flight at once (see
|
|
575
|
+
``_FILE_CONCURRENCY``). Materializes the async iterable up front — file
|
|
576
|
+
handles are lightweight and cocoindex already realized the collection when
|
|
577
|
+
the walker mounted, so this is not a second walk. An empty collection is a
|
|
578
|
+
no-op (e.g. SQL/YAML tables on a repo with none).
|
|
579
|
+
"""
|
|
580
|
+
items = [f async for _, f in files.items()]
|
|
581
|
+
if not items:
|
|
582
|
+
return
|
|
583
|
+
|
|
584
|
+
async def _one(_file: Any) -> None:
|
|
585
|
+
async with sem:
|
|
586
|
+
await process_fn(_file, table)
|
|
587
|
+
|
|
588
|
+
await asyncio.gather(*(_one(f) for f in items))
|
|
589
|
+
|
|
590
|
+
|
|
536
591
|
@coco.fn
|
|
537
592
|
async def app_main() -> None:
|
|
538
593
|
java_schema = await lancedb.TableSchema.from_class(
|
|
@@ -646,12 +701,17 @@ async def app_main() -> None:
|
|
|
646
701
|
# unchanged files still skip re-embedding on incremental; _RowHandler.
|
|
647
702
|
# reconcile skips rows whose fingerprint is unchanged → increment carries
|
|
648
703
|
# only changed rows in its single merge_insert.
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
async for
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
704
|
+
#
|
|
705
|
+
# PERF (concurrency): drain files with a bounded semaphore instead of a
|
|
706
|
+
# serial ``async for … await``. See ``_FILE_CONCURRENCY`` — this is what
|
|
707
|
+
# lets the embedder's batching layer fill real batches (embedding dominates
|
|
708
|
+
# init cost, and serial files starve it). One shared semaphore bounds total
|
|
709
|
+
# in-flight work; tables are drained in order (java dominates, sql/yaml are
|
|
710
|
+
# usually near-empty).
|
|
711
|
+
_sem = asyncio.Semaphore(_FILE_CONCURRENCY)
|
|
712
|
+
await _drain_files_concurrently(java_files, process_java_file, java_table, _sem)
|
|
713
|
+
await _drain_files_concurrently(sql_files, process_sql_file, sql_table, _sem)
|
|
714
|
+
await _drain_files_concurrently(yaml_files, process_yaml_file, yaml_table, _sem)
|
|
655
715
|
|
|
656
716
|
|
|
657
717
|
app = coco.App(
|
|
@@ -349,6 +349,31 @@ async def run_refresh_pipeline(
|
|
|
349
349
|
)
|
|
350
350
|
proc: asyncio.subprocess.Process | None = None
|
|
351
351
|
out_b, err_b = b"", b""
|
|
352
|
+
# DROP the Lance target tables so the update takes the fast INSERT path
|
|
353
|
+
# instead of cocoindex's in-place bulk-update, which emits ~one deletion-
|
|
354
|
+
# vector + version commit PER matched row — O(rows) of tiny file IO that
|
|
355
|
+
# hangs for many minutes on large repos. Drop+recreate is identical output
|
|
356
|
+
# for a full rebuild (the very thing --full-reprocess means). Same fix on
|
|
357
|
+
# the sync path: pipeline.run_cocoindex_update. Drop failure is non-fatal:
|
|
358
|
+
# the update falls back to the slow in-place path.
|
|
359
|
+
try:
|
|
360
|
+
drop_proc = await asyncio.create_subprocess_exec(
|
|
361
|
+
str(cocoindex_bin),
|
|
362
|
+
"drop",
|
|
363
|
+
_COCOINDEX_TARGET,
|
|
364
|
+
"-f",
|
|
365
|
+
cwd=str(flow_path.parent),
|
|
366
|
+
env=_cocoindex_subprocess_env(root),
|
|
367
|
+
stdout=asyncio.subprocess.PIPE,
|
|
368
|
+
stderr=asyncio.subprocess.PIPE,
|
|
369
|
+
)
|
|
370
|
+
await drop_proc.communicate()
|
|
371
|
+
except Exception as exc:
|
|
372
|
+
print(
|
|
373
|
+
f"java-codebase-rag: drop-before-reprocess failed ({exc!s}); "
|
|
374
|
+
"falling back to in-place update",
|
|
375
|
+
file=sys.stderr,
|
|
376
|
+
)
|
|
352
377
|
if quiet:
|
|
353
378
|
try:
|
|
354
379
|
proc = await asyncio.create_subprocess_exec(
|
|
@@ -506,6 +506,10 @@ def test_cocoindex_subprocess_env_defaults_uses_real_inflight_env_var() -> None:
|
|
|
506
506
|
assert defaults["COCOINDEX_MAX_INFLIGHT_COMPONENTS"] == "256"
|
|
507
507
|
# The bogus name from the broken #293 fix must NOT leak back in.
|
|
508
508
|
assert "COCOINDEX_SOURCE_MAX_INFLIGHT_ROWS" not in defaults
|
|
509
|
+
# Lance native hash-join pool ceiling, raised from the ~100 MiB default so a
|
|
510
|
+
# large full-reprocess merge_insert does not exhaust it mid-commit. Applied
|
|
511
|
+
# via setdefault, so an operator's own value still wins.
|
|
512
|
+
assert defaults["LANCE_MEM_POOL_SIZE"] == "1073741824"
|
|
509
513
|
|
|
510
514
|
|
|
511
515
|
class TestConfigSourcePointer:
|
|
@@ -123,31 +123,92 @@ async def test_optimize_builds_fts_index_after_success(monkeypatch, tmp_path) ->
|
|
|
123
123
|
table = _FakeTable(name, [None]) # optimize succeeds on first try
|
|
124
124
|
conn = _FakeConnection(table_names={name}, tables={name: table})
|
|
125
125
|
_install_fake_lancedb(monkeypatch, conn)
|
|
126
|
-
|
|
127
|
-
index_mod = types.ModuleType("lancedb.index")
|
|
128
|
-
|
|
129
|
-
class FTS: # stands in for lancedb.index.FTS config object
|
|
130
|
-
pass
|
|
131
|
-
|
|
132
|
-
index_mod.FTS = FTS
|
|
133
|
-
monkeypatch.setitem(sys.modules, "lancedb.index", index_mod)
|
|
126
|
+
fts_cls, _btree_cls = _install_fake_lancedb_index(monkeypatch)
|
|
134
127
|
|
|
135
128
|
results = await lance_optimize.optimize_lance_tables(tmp_path, quiet=True)
|
|
136
129
|
|
|
137
130
|
assert results[name] == "ok"
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
131
|
+
# optimize now builds TWO indices (BTREE on "id" + FTS on "text"); find the
|
|
132
|
+
# FTS one by column rather than asserting on call count / order.
|
|
133
|
+
fts_calls = [
|
|
134
|
+
c for c in table.create_index_calls if c["args"] and c["args"][0] == "text"
|
|
135
|
+
]
|
|
136
|
+
assert len(fts_calls) == 1, (
|
|
137
|
+
f"expected one FTS create_index on 'text', got {table.create_index_calls}"
|
|
144
138
|
)
|
|
139
|
+
call = fts_calls[0]
|
|
145
140
|
assert call["kwargs"].get("replace") is True, (
|
|
146
141
|
f"FTS index must be built with replace=True, got kwargs={call['kwargs']}"
|
|
147
142
|
)
|
|
143
|
+
assert isinstance(call["kwargs"].get("config"), fts_cls), (
|
|
144
|
+
f"FTS index config must be a lancedb.index.FTS, got kwargs={call['kwargs']}"
|
|
145
|
+
)
|
|
148
146
|
assert conn.closed is True
|
|
149
147
|
|
|
150
148
|
|
|
149
|
+
async def test_optimize_builds_btree_pk_index_after_success(monkeypatch, tmp_path) -> None:
|
|
150
|
+
"""A successful optimize builds a BTREE scalar index on the ``id`` PK.
|
|
151
|
+
|
|
152
|
+
cocoindex's ``merge_insert`` defaults to ``use_index=True`` but never creates
|
|
153
|
+
a scalar PK index itself (declaring ``primary_key`` does NOT auto-build a
|
|
154
|
+
lance index), so without this every ``merge_insert`` — increment included —
|
|
155
|
+
is a forced full scan of the PK column (O(existing rows)). The BTREE index
|
|
156
|
+
flips that to ~O(batch*log N) lookups. Guards the path against silent
|
|
157
|
+
regression under the broad ``except`` that swallows index-build failures.
|
|
158
|
+
"""
|
|
159
|
+
import types
|
|
160
|
+
|
|
161
|
+
from java_codebase_rag import lance_optimize
|
|
162
|
+
|
|
163
|
+
name = lance_optimize.LANCE_TABLE_NAMES[0]
|
|
164
|
+
table = _FakeTable(name, [None]) # optimize succeeds on first try
|
|
165
|
+
conn = _FakeConnection(table_names={name}, tables={name: table})
|
|
166
|
+
_install_fake_lancedb(monkeypatch, conn)
|
|
167
|
+
_fts_cls, btree_cls = _install_fake_lancedb_index(monkeypatch)
|
|
168
|
+
|
|
169
|
+
results = await lance_optimize.optimize_lance_tables(tmp_path, quiet=True)
|
|
170
|
+
|
|
171
|
+
assert results[name] == "ok"
|
|
172
|
+
id_calls = [
|
|
173
|
+
c for c in table.create_index_calls if c["args"] and c["args"][0] == "id"
|
|
174
|
+
]
|
|
175
|
+
assert len(id_calls) == 1, (
|
|
176
|
+
f"expected one BTREE create_index on 'id', got {table.create_index_calls}"
|
|
177
|
+
)
|
|
178
|
+
call = id_calls[0]
|
|
179
|
+
assert call["kwargs"].get("replace") is True, (
|
|
180
|
+
f"BTREE PK index must be built with replace=True, got kwargs={call['kwargs']}"
|
|
181
|
+
)
|
|
182
|
+
assert isinstance(call["kwargs"].get("config"), btree_cls), (
|
|
183
|
+
f"BTREE PK index config must be a lancedb.index.BTree, got kwargs={call['kwargs']}"
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
def _install_fake_lancedb_index(monkeypatch):
|
|
188
|
+
"""Make ``from lancedb.index import FTS, BTree`` resolve to stand-in classes.
|
|
189
|
+
|
|
190
|
+
Returns the ``(FTS, BTree)`` config stand-ins so a test can assert the right
|
|
191
|
+
config object was passed. Both the FTS path (PR-SEARCH-3) and the BTREE PK
|
|
192
|
+
path build their index config via a local ``from lancedb.index import ...``;
|
|
193
|
+
without a stand-in those imports hit the broad ``except`` and silently no-op,
|
|
194
|
+
leaving the path unexercised.
|
|
195
|
+
"""
|
|
196
|
+
import types
|
|
197
|
+
|
|
198
|
+
index_mod = types.ModuleType("lancedb.index")
|
|
199
|
+
|
|
200
|
+
class FTS: # stands in for lancedb.index.FTS config object
|
|
201
|
+
pass
|
|
202
|
+
|
|
203
|
+
class BTree: # stands in for lancedb.index.BTree config object
|
|
204
|
+
pass
|
|
205
|
+
|
|
206
|
+
index_mod.FTS = FTS
|
|
207
|
+
index_mod.BTree = BTree
|
|
208
|
+
monkeypatch.setitem(sys.modules, "lancedb.index", index_mod)
|
|
209
|
+
return FTS, BTree
|
|
210
|
+
|
|
211
|
+
|
|
151
212
|
async def test_optimize_does_not_retry_non_conflict_error(monkeypatch, tmp_path) -> None:
|
|
152
213
|
"""A non-conflict exception is re-raised (captured per-table), never retried."""
|
|
153
214
|
from java_codebase_rag import lance_optimize
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"""Tests for ``java_codebase_rag.pipeline`` subprocess helpers.
|
|
2
|
+
|
|
3
|
+
Focus: ``run_cocoindex_update`` drops the Lance target tables before a *full
|
|
4
|
+
reprocess* so the update takes the fast INSERT path. The in-place alternative
|
|
5
|
+
(cocoindex's bulk-update ``merge_insert``) emits ~one deletion-vector + version
|
|
6
|
+
commit per matched row — O(rows) of tiny file IO that hangs for many minutes on
|
|
7
|
+
large repos. Drop+recreate is identical output for a full rebuild.
|
|
8
|
+
"""
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import subprocess
|
|
12
|
+
|
|
13
|
+
from java_codebase_rag import pipeline
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def _ok() -> subprocess.CompletedProcess:
|
|
17
|
+
return subprocess.CompletedProcess(args=[], returncode=0, stdout="", stderr="")
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def _stub_impl(monkeypatch, seen: dict) -> None:
|
|
21
|
+
"""Replace the impl + post-optimize with no-op stubs (no cocoindex/lancedb)."""
|
|
22
|
+
|
|
23
|
+
def fake_impl(env, **kwargs):
|
|
24
|
+
seen["update"] = seen.get("update", 0) + 1
|
|
25
|
+
seen["full_reprocess"] = kwargs.get("full_reprocess")
|
|
26
|
+
return _ok()
|
|
27
|
+
|
|
28
|
+
monkeypatch.setattr(pipeline, "_run_cocoindex_update_impl", fake_impl)
|
|
29
|
+
monkeypatch.setattr(pipeline, "_maybe_run_serialized_optimize", lambda *a, **k: None)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def test_full_reprocess_drops_tables_first(monkeypatch) -> None:
|
|
33
|
+
"""full_reprocess=True drops exactly once before the update (INSERT path)."""
|
|
34
|
+
seen: dict = {}
|
|
35
|
+
_stub_impl(monkeypatch, seen)
|
|
36
|
+
drops: list[dict] = []
|
|
37
|
+
|
|
38
|
+
def fake_drop(env, *, quiet):
|
|
39
|
+
drops.append(env)
|
|
40
|
+
return _ok()
|
|
41
|
+
|
|
42
|
+
monkeypatch.setattr(pipeline, "run_cocoindex_drop", fake_drop)
|
|
43
|
+
|
|
44
|
+
pipeline.run_cocoindex_update({"X": "1"}, full_reprocess=True, quiet=True)
|
|
45
|
+
|
|
46
|
+
assert len(drops) == 1, "full_reprocess must drop exactly once before update"
|
|
47
|
+
assert drops[0] == {"X": "1"}, "drop must receive the same env as the update"
|
|
48
|
+
assert seen["update"] == 1
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def test_increment_does_not_drop(monkeypatch) -> None:
|
|
52
|
+
"""full_reprocess=False (increment) must NOT drop — it would lose the table."""
|
|
53
|
+
seen: dict = {}
|
|
54
|
+
_stub_impl(monkeypatch, seen)
|
|
55
|
+
drops: list[dict] = []
|
|
56
|
+
|
|
57
|
+
def fake_drop(env, *, quiet):
|
|
58
|
+
drops.append(env)
|
|
59
|
+
return _ok()
|
|
60
|
+
|
|
61
|
+
monkeypatch.setattr(pipeline, "run_cocoindex_drop", fake_drop)
|
|
62
|
+
|
|
63
|
+
pipeline.run_cocoindex_update({}, full_reprocess=False, quiet=True)
|
|
64
|
+
|
|
65
|
+
assert drops == [], "increment must not drop the tables"
|
|
66
|
+
assert seen["update"] == 1
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def test_drop_failure_falls_back_to_inplace(monkeypatch, capsys) -> None:
|
|
70
|
+
"""A non-preflight drop failure does not abort — the update still runs in-place."""
|
|
71
|
+
seen: dict = {}
|
|
72
|
+
_stub_impl(monkeypatch, seen)
|
|
73
|
+
monkeypatch.setattr(
|
|
74
|
+
pipeline,
|
|
75
|
+
"run_cocoindex_drop",
|
|
76
|
+
lambda env, *, quiet: subprocess.CompletedProcess(
|
|
77
|
+
args=[], returncode=2, stdout="", stderr="boom"
|
|
78
|
+
),
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
pipeline.run_cocoindex_update({}, full_reprocess=True, quiet=True)
|
|
82
|
+
|
|
83
|
+
assert seen["update"] == 1, "update must still run after a non-fatal drop failure"
|
|
84
|
+
assert "drop-before-reprocess failed" in capsys.readouterr().err
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def test_drop_preflight_blocker_is_silent(monkeypatch, capsys) -> None:
|
|
88
|
+
"""A preflight drop stub (cocoindex not installed, e.g. graph-only) is not noisy."""
|
|
89
|
+
seen: dict = {}
|
|
90
|
+
_stub_impl(monkeypatch, seen)
|
|
91
|
+
monkeypatch.setattr(
|
|
92
|
+
pipeline,
|
|
93
|
+
"run_cocoindex_drop",
|
|
94
|
+
lambda env, *, quiet: subprocess.CompletedProcess(
|
|
95
|
+
args=["cocoindex"], returncode=127, stdout="", stderr="not found"
|
|
96
|
+
),
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
pipeline.run_cocoindex_update({}, full_reprocess=True, quiet=True)
|
|
100
|
+
|
|
101
|
+
assert seen["update"] == 1
|
|
102
|
+
# 127 preflight is expected on graph-only installs and must NOT warn.
|
|
103
|
+
assert "drop-before-reprocess failed" not in capsys.readouterr().err
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/java_codebase_rag.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/java_codebase_rag.egg-info/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|
{java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/java_codebase_rag.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_assign_endpoint_client_extraction.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_bank_chat_brownfield_integration.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_call_graph_receiver_resolution.py
RENAMED
|
File without changes
|
{java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_call_graph_smoke_roundtrip.py
RENAMED
|
File without changes
|
|
File without changes
|
{java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_cli_progress_stdout_invariant.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_cross_service_resolution_flag.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{java_codebase_rag-0.9.0 → java_codebase_rag-0.9.1}/tests/test_resolve_routes_messaging_layer_c.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|