feat: enable idregex_refine by default + AST rewrite of _count_optionals

- idregex_refine=True default across all entry points + CLI
- Added --no-idregex-refine flag to CLI
- Rewrote _count_optionals from SORE string parser to AST walker
- Added _is_pure_bag() helper for bag detection
- Updated _should_try_idregex() to trigger on pure Plus(Alt) bags
- Updated tests for AST-based _count_optionals
- Added RAGSAK v4 experiment results
This commit is contained in:
tobjend 2026-07-13 01:12:54 +02:00
parent 8460c3c862
commit 8b3a454a15
4 changed files with 4694 additions and 47 deletions

View file

@ -351,53 +351,71 @@ def _recursive_split(symbol_seqs, min_subgroup=3, max_depth=3, _depth=0, cluster
def _count_optionals(grammar):
"""Count optional parts in a SORE grammar.
"""Count optional/repetition parts in an AST grammar.
Returns (n_optional, n_concat_parts) counting only top-level parts
of concatenations that end with ?. A grammar like a?.b?.c?.d?.e?
has 5 optional parts out of 5 concat parts = 1.0 ratio (over-approx).
A grammar like a.(b|c).(d|e) has 0 optional parts = 0.0 ratio (structured).
Returns (n_optional, n_concat_parts). A flat optional chain like
a?.b?.c?.d?.e? has 5 optional parts out of 5 concat parts = 1.0 ratio
(over-approx, bag-like). A structured grammar a.(b|c).(d|e) has 0
optional parts = 0.0 ratio.
Walks the AST (Symbol/Concat/Alt/Optional/Plus/Star/Empty). Top-level
concatenation parts that are Optional/Star/Plus count as "optional".
"""
import re
# Split on top-level dots (concatenation)
parts = []
depth = 0
cur = []
for ch in grammar:
if ch == '(':
depth += 1
cur.append(ch)
elif ch == ')':
depth -= 1
cur.append(ch)
elif ch == '.' and depth == 0:
parts.append(''.join(cur))
cur = []
else:
cur.append(ch)
parts.append(''.join(cur))
from bex.grammar import Concat, Alt, Optional, Plus, Star, Symbol, Empty
# Count parts ending with ? (but not +?)
n_optional = sum(1 for p in parts if p.endswith('?') and not p.endswith('+?'))
n_total = len(parts)
return n_optional, n_total
if grammar is None or isinstance(grammar, Empty):
return 0, 0
if isinstance(grammar, Concat):
n_opt = 0
for p in grammar.parts:
if isinstance(p, Optional):
n_opt += 1
elif isinstance(p, (Star, Plus)):
n_opt += 0 # structure, not optional
else:
o, _ = _count_optionals(p)
n_opt += o
return n_opt, len(grammar.parts)
if isinstance(grammar, Optional):
# a true optional counts as one optional part
return 1, 1
if isinstance(grammar, (Star, Plus)):
# repetition provides structure, not optionality
return 0, 1
if isinstance(grammar, Alt):
# an alternation is one structured part (not optional)
return 0, 1
# Symbol / Epsilon: one concrete part, not optional
return 0, 1
def _is_pure_bag(grammar):
"""A pure bag is a single Plus(Alt(...)) of >=2 alternatives (no ordering)."""
from bex.grammar import Plus, Alt, Symbol, Empty
return (isinstance(grammar, Plus)
and isinstance(grammar.child, Alt)
and len(grammar.child.parts) >= 2
and all(isinstance(p, (Symbol, Empty)) for p in grammar.child.parts))
def _should_try_idregex(grammar, n_methods):
"""Decide if iDRegEx refinement is worth trying.
Heuristic: only try if the group is small (10 methods) AND
the CRX grammar is a flat optional chain (high optional ratio).
Heuristic: only try if the group is small (10 methods) AND the CRX
grammar is bag-like either a flat optional chain (high optional ratio)
or a pure Plus(Alt) bag (no ordering).
"""
if n_methods > 10:
return False
if _is_pure_bag(grammar):
return True
n_optional, n_total = _count_optionals(grammar)
if n_total < 3:
return False
return n_optional / n_total > 0.5
def _infer_group(label, group_seqs, group_files, project_root, min_coverage, prefer, kmax, N, include_kore=False, include_idregex=False, method='langsize', min_methods=3, crx_method='standard', min_structure=0.0, split_mixed=False, idregex_refine=False, cluster_method='first-symbol', decompose=False, max_seq_length=5):
def _infer_group(label, group_seqs, group_files, project_root, min_coverage, prefer, kmax, N, include_kore=False, include_idregex=False, method='langsize', min_methods=3, crx_method='standard', min_structure=0.0, split_mixed=False, idregex_refine=True, cluster_method='first-symbol', decompose=False, max_seq_length=5):
"""Infer grammar for one package group. Module-level for ProcessPoolExecutor."""
filtered = frequency_filter(group_seqs, min_coverage=min_coverage)
imports = _extract_imports(group_files)
@ -490,7 +508,7 @@ def _infer_group(label, group_seqs, group_files, project_root, min_coverage, pre
return (label, result, len(filtered), meta)
def analyze_by_package(file_paths, extension, project_root="", min_coverage=DEFAULT_COVERAGE, prefer=None, kmax=2, N=3, min_pkg_size=3, include_kore=False, include_idregex=False, method='langsize', min_methods=3, crx_method='standard', min_structure=0.0, split_mixed=False, idregex_refine=False, cluster_method='first-symbol', decompose=False, max_seq_length=5):
def analyze_by_package(file_paths, extension, project_root="", min_coverage=DEFAULT_COVERAGE, prefer=None, kmax=2, N=3, min_pkg_size=3, include_kore=False, include_idregex=False, method='langsize', min_methods=3, crx_method='standard', min_structure=0.0, split_mixed=False, idregex_refine=True, cluster_method='first-symbol', decompose=False, max_seq_length=5):
"""Preprocess and group by package directory, infer per group.
Groups methods by their file's relative directory path, merging
@ -627,7 +645,7 @@ def _filter_glob(files, include=None, exclude=None):
return files
def analyze_by_reduce(file_paths, extension, project_root="", min_coverage=DEFAULT_COVERAGE, prefer=None, kmax=2, N=3, include_kore=False, include_idregex=False, method='langsize', min_methods=3, crx_method='standard', min_structure=0.0, reduce_threshold=0.15, idregex_refine=False, cluster_method='first-symbol', decompose=False, max_seq_length=5):
def analyze_by_reduce(file_paths, extension, project_root="", min_coverage=DEFAULT_COVERAGE, prefer=None, kmax=2, N=3, include_kore=False, include_idregex=False, method='langsize', min_methods=3, crx_method='standard', min_structure=0.0, reduce_threshold=0.15, idregex_refine=True, cluster_method='first-symbol', decompose=False, max_seq_length=5):
"""Reduce-style analysis: group by directory, then merge similar groups.
Uses Algorithm 4 (Reduce, TODS 2010) to merge directories with similar
@ -680,7 +698,7 @@ def analyze_by_reduce(file_paths, extension, project_root="", min_coverage=DEFAU
return results
def analyze_by_ilocal(file_paths, extension, project_root="", min_coverage=DEFAULT_COVERAGE, prefer=None, kmax=2, N=3, include_kore=False, include_idregex=False, method='langsize', min_methods=3, crx_method='standard', min_structure=0.0, context_strategy="dir", reduce=True, idregex_refine=False, cluster_method='first-symbol', decompose=False, max_seq_length=5):
def analyze_by_ilocal(file_paths, extension, project_root="", min_coverage=DEFAULT_COVERAGE, prefer=None, kmax=2, N=3, include_kore=False, include_idregex=False, method='langsize', min_methods=3, crx_method='standard', min_structure=0.0, context_strategy="dir", reduce=True, idregex_refine=True, cluster_method='first-symbol', decompose=False, max_seq_length=5):
"""iLocal-style analysis: extract (context, sequence) pairs, reduce, infer.
Instead of hard-coding directory as grouping key, this extracts contexts
@ -761,7 +779,7 @@ def analyze_directory(
max_seq_length=4,
reduce_threshold=0.15,
split_mixed=False,
idregex_refine=False,
idregex_refine=True,
cluster_method='first-symbol',
):
"""Scan a directory and run analysis for each language found.
@ -1052,8 +1070,12 @@ def _parse_args(argv=None):
help="Maximum sequence length after decomposition (default: 4)",
)
parser.add_argument(
"--idregex-refine", action="store_true",
help="Run iDRegEx on small groups (≤10 methods) where CRX grammar has many optionals — picks tighter grammar by lang_size",
"--idregex-refine", action="store_true", default=True,
help="Run iDRegEx on small groups (≤10 methods) where CRX grammar has many optionals — picks tighter grammar by lang_size (default: on)",
)
parser.add_argument(
"--no-idregex-refine", dest="idregex_refine", action="store_false",
help="Disable iDRegEx refinement on small groups",
)
return parser.parse_args(argv)

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,264 @@
[ 0.0s] Scanning /home/tobi/Desktop/kesai/RAGSAK ...
[ 0.1s] Preprocessing 462 files across 12 workers ...
[ 2.9s] Preprocess: 1609 methods from 462 .kt files (2.8s)
[ 2.9s] Groups: 120 named, 6 ungrouped methods
[ 2.9s] ├ agents (5 methods)
[ 2.9s] ├ agents/capability/ports/src/main/kotlin/eu/corentic/springrag/agent/capability (5 methods)
[ 2.9s] ├ agents/capability/support/src/main/kotlin/eu/corentic/springrag/agent/capability/support (5 methods)
[ 2.9s] ├ agents/capability/support/src/test/kotlin/eu/corentic/springrag/agent/capability/support (6 methods)
[ 2.9s] ├ agents/examples/simple-rag/src/main/kotlin/eu/corentic/springrag/example/rag/simple (9 methods)
[ 2.9s] ├ agents/examples/simple-rag/src/test/kotlin/eu/corentic/springrag/example/rag/simple (14 methods)
[ 2.9s] ├ agents/rag/embabel/src/main/kotlin/eu/corentic/springrag/agent/rag/embabel (58 methods)
[ 2.9s] ├ agents/rag/embabel/src/main/kotlin/eu/corentic/springrag/agent/rag/embabel/librechat (13 methods)
[ 2.9s] ├ agents/rag/embabel/src/test/kotlin/eu/corentic/springrag/agent/rag/embabel (36 methods)
[ 2.9s] ├ agents/rag/embabel/src/test/kotlin/eu/corentic/springrag/testsupport (3 methods)
[ 2.9s] ├ agents/rag/ports/src/main/kotlin/eu/corentic/springrag/agent/rag (4 methods)
[ 2.9s] ├ agents/rag/ports/src/test/kotlin/eu/corentic/springrag/agent/rag (3 methods)
[ 2.9s] ├ agents/rag/ports/src/test/kotlin/eu/corentic/springrag/model (3 methods)
[ 2.9s] ├ agents/rag/support/src/main/kotlin/eu/corentic/springrag/agent/rag/support (13 methods)
[ 2.9s] ├ agents/rag/support/src/test/kotlin/eu/corentic/springrag/agent/rag/support (11 methods)
[ 2.9s] ├ agents/summarizer/embabel/src/main/kotlin/eu/corentic/springrag/agent/summarizer/embabel (13 methods)
[ 2.9s] ├ agents/summarizer/embabel/src/test/kotlin/eu/corentic/springrag/agent/summarizer/embabel (14 methods)
[ 2.9s] ├ agents/tooling/agent/src/main/kotlin/eu/corentic/springrag/agent/tooling/agent (4 methods)
[ 2.9s] ├ agents/tooling/embabel/src/main/kotlin/eu/corentic/springrag/agent/tooling/embabel (12 methods)
[ 2.9s] ├ agents/tooling/embabel/src/main/kotlin/eu/corentic/springrag/agent/tooling/embabel/recording (11 methods)
[ 2.9s] ├ agents/tooling/embabel/src/test/kotlin/eu/corentic/springrag/agent/tooling/embabel (6 methods)
[ 2.9s] ├ agents/wikipedia/adapters/src/main/kotlin/eu/corentic/springrag/agent/wikipedia (4 methods)
[ 2.9s] ├ agents/wikipedia/adapters/src/test/kotlin/eu/corentic/springrag/agent/wikipedia (8 methods)
[ 2.9s] ├ agents/wikipedia/static/src/main/kotlin/eu/corentic/springrag/agent/wikipedia (3 methods)
[ 2.9s] ├ agents/wikipedia/static/src/test/kotlin/eu/corentic/springrag/agent/wikipedia (3 methods)
[ 2.9s] ├ app/src (6 methods)
[ 2.9s] ├ app/src/e2eTest/kotlin/eu/corentic/springrag/e2e/cucumber/steps (17 methods)
[ 2.9s] ├ app/src/integrationTest/kotlin/eu/corentic/springrag/config (15 methods)
[ 2.9s] ├ app/src/integrationTest/kotlin/eu/corentic/springrag/controller (5 methods)
[ 2.9s] ├ app/src/integrationTest/kotlin/eu/corentic/springrag/service (3 methods)
[ 2.9s] ├ app/src/systemTest/kotlin/eu/corentic/springrag/config (14 methods)
[ 2.9s] ├ app/src/systemTest/kotlin/eu/corentic/springrag/system (46 methods)
[ 2.9s] ├ app/src/test/kotlin/eu/corentic/springrag/architecture (87 methods)
[ 2.9s] ├ app/src/test/kotlin/eu/corentic/springrag/config (3 methods)
[ 2.9s] ├ buildSrc/src/main/kotlin (8 methods)
[ 2.9s] ├ buildSrc/src/test/kotlin (5 methods)
[ 2.9s] ├ entrypoints/agent-mcp-server/src/main/kotlin/eu/corentic/springrag/mcp (3 methods)
[ 2.9s] ├ entrypoints/agent-mcp-server/src/test/kotlin/eu/corentic/springrag/mcp (3 methods)
[ 2.9s] ├ entrypoints/web/src/main/kotlin/eu/corentic/springrag/config (3 methods)
[ 2.9s] ├ entrypoints/web/src/main/kotlin/eu/corentic/springrag/controller (58 methods)
[ 2.9s] ├ entrypoints/web/src/main/kotlin/eu/corentic/springrag/controller/librechat (29 methods)
[ 2.9s] ├ entrypoints/web/src/main/kotlin/eu/corentic/springrag/controller/web (6 methods)
[ 2.9s] ├ entrypoints/web/src/test/kotlin/eu/corentic/springrag/config (4 methods)
[ 2.9s] ├ entrypoints/web/src/test/kotlin/eu/corentic/springrag/controller (83 methods)
[ 2.9s] ├ entrypoints/web/src/test/kotlin/eu/corentic/springrag/controller/auth (5 methods)
[ 2.9s] ├ entrypoints/web/src/test/kotlin/eu/corentic/springrag/controller/librechat (46 methods)
[ 2.9s] ├ entrypoints/web/src/test/kotlin/eu/corentic/springrag/controller/web (10 methods)
[ 2.9s] ├ infrastructure/adapters (3 methods)
[ 2.9s] ├ infrastructure/adapters/ai-provider/src/main/kotlin/eu/corentic/springrag/config (4 methods)
[ 2.9s] ├ infrastructure/adapters/ai-provider/src/main/kotlin/eu/corentic/springrag/health (3 methods)
[ 2.9s] ├ infrastructure/adapters/ai-provider/src/test/kotlin/eu/corentic/springrag/config (6 methods)
[ 2.9s] ├ infrastructure/adapters/ai-provider/src/test/kotlin/eu/corentic/springrag/health (4 methods)
[ 2.9s] ├ infrastructure/adapters/ai-provider/src/test/kotlin/eu/corentic/springrag/service/embedding (5 methods)
[ 2.9s] ├ infrastructure/adapters/ai-provider/src/test/kotlin/eu/corentic/springrag/testsupport (3 methods)
[ 2.9s] ├ infrastructure/adapters/chat-memory/src/test/kotlin/eu/corentic/springrag/config (6 methods)
[ 2.9s] ├ infrastructure/adapters/doc-parser/src (6 methods)
[ 2.9s] ├ infrastructure/adapters/doc-parser/src/main/kotlin/eu/corentic/springrag/config (3 methods)
[ 2.9s] ├ infrastructure/adapters/doc-parser/src/main/kotlin/eu/corentic/springrag/service/docling (21 methods)
[ 2.9s] ├ infrastructure/adapters/doc-parser/src/systemTest/kotlin/eu/corentic/springrag/config (6 methods)
[ 2.9s] ├ infrastructure/adapters/doc-parser/src/test/kotlin/eu/corentic/springrag/config (12 methods)
[ 2.9s] ├ infrastructure/adapters/doc-parser/src/test/kotlin/eu/corentic/springrag/health (3 methods)
[ 2.9s] ├ infrastructure/adapters/doc-parser/src/test/kotlin/eu/corentic/springrag/service/docling (10 methods)
[ 2.9s] ├ infrastructure/adapters/doc-parser/src/test/kotlin/eu/corentic/springrag/testsupport (3 methods)
[ 2.9s] ├ infrastructure/adapters/search/src/main/kotlin/eu/corentic/springrag/health (7 methods)
[ 2.9s] ├ infrastructure/adapters/search/src/main/kotlin/eu/corentic/springrag/model/graph (9 methods)
[ 2.9s] ├ infrastructure/adapters/search/src/main/kotlin/eu/corentic/springrag/repository (24 methods)
[ 2.9s] ├ infrastructure/adapters/search/src/main/kotlin/eu/corentic/springrag/service/agent (3 methods)
[ 2.9s] ├ infrastructure/adapters/search/src/main/kotlin/eu/corentic/springrag/service/cleanup (4 methods)
[ 2.9s] ├ infrastructure/adapters/search/src/main/kotlin/eu/corentic/springrag/service/graph (12 methods)
[ 2.9s] ├ infrastructure/adapters/search/src/main/kotlin/eu/corentic/springrag/service/port/adapter (45 methods)
[ 2.9s] ├ infrastructure/adapters/search/src/main/kotlin/eu/corentic/springrag/service/storage (40 methods)
[ 2.9s] ├ infrastructure/adapters/search/src/systemTest/kotlin/eu/corentic/springrag/config (4 methods)
[ 2.9s] ├ infrastructure/adapters/search/src/systemTest/kotlin/eu/corentic/springrag/repository/graph (23 methods)
[ 2.9s] ├ infrastructure/adapters/search/src/systemTest/kotlin/eu/corentic/springrag/system (6 methods)
[ 2.9s] ├ infrastructure/adapters/search/src/test/kotlin/eu/corentic/springrag/config (3 methods)
[ 2.9s] ├ infrastructure/adapters/search/src/test/kotlin/eu/corentic/springrag/health (6 methods)
[ 2.9s] ├ infrastructure/adapters/search/src/test/kotlin/eu/corentic/springrag/model/graph (7 methods)
[ 2.9s] ├ infrastructure/adapters/search/src/test/kotlin/eu/corentic/springrag/repository (19 methods)
[ 2.9s] ├ infrastructure/adapters/search/src/test/kotlin/eu/corentic/springrag/service/cleanup (4 methods)
[ 2.9s] ├ infrastructure/adapters/search/src/test/kotlin/eu/corentic/springrag/service/graph (30 methods)
[ 2.9s] ├ infrastructure/adapters/search/src/test/kotlin/eu/corentic/springrag/service/port/adapter (28 methods)
[ 2.9s] ├ infrastructure/adapters/search/src/test/kotlin/eu/corentic/springrag/service/storage (3 methods)
[ 2.9s] ├ infrastructure/adapters/search/src/test/kotlin/eu/corentic/springrag/testsupport (3 methods)
[ 2.9s] ├ modules/chat/src/integrationTest/kotlin/eu/corentic/springrag/service/chat (4 methods)
[ 2.9s] ├ modules/chat/src/main/kotlin/eu/corentic/springrag/service/chat (6 methods)
[ 2.9s] ├ modules/chat/src/systemTest/kotlin/eu/corentic/springrag/config (15 methods)
[ 2.9s] ├ modules/chat/src/systemTest/kotlin/eu/corentic/springrag/system (4 methods)
[ 2.9s] ├ modules/chat/src/test/kotlin/eu/corentic/springrag/service/chat (8 methods)
[ 2.9s] ├ modules/common/src/main/kotlin/eu/corentic/springrag/common (7 methods)
[ 2.9s] ├ modules/common/src/main/kotlin/eu/corentic/springrag/common/ids (18 methods)
[ 2.9s] ├ modules/common/src/test/kotlin/eu/corentic/springrag/common/ids (8 methods)
[ 2.9s] ├ modules/ingestion/src/integrationTest/kotlin/eu/corentic/springrag/service/job (34 methods)
[ 2.9s] ├ modules/ingestion/src/main/kotlin/eu/corentic/springrag/batch (16 methods)
[ 2.9s] ├ modules/ingestion/src/main/kotlin/eu/corentic/springrag/batch/listener (16 methods)
[ 2.9s] ├ modules/ingestion/src/main/kotlin/eu/corentic/springrag/batch/model (4 methods)
[ 2.9s] ├ modules/ingestion/src/main/kotlin/eu/corentic/springrag/batch/partition (4 methods)
[ 2.9s] ├ modules/ingestion/src/main/kotlin/eu/corentic/springrag/batch/reader (4 methods)
[ 2.9s] ├ modules/ingestion/src/main/kotlin/eu/corentic/springrag/batch/writer (3 methods)
[ 2.9s] ├ modules/ingestion/src/main/kotlin/eu/corentic/springrag/config (26 methods)
[ 2.9s] ├ modules/ingestion/src/main/kotlin/eu/corentic/springrag/service/chunk (18 methods)
[ 2.9s] ├ modules/ingestion/src/main/kotlin/eu/corentic/springrag/service/document (3 methods)
[ 2.9s] ├ modules/ingestion/src/main/kotlin/eu/corentic/springrag/service/job (62 methods)
[ 2.9s] ├ modules/ingestion/src/test/kotlin/eu/corentic/springrag/batch (17 methods)
[ 2.9s] ├ modules/ingestion/src/test/kotlin/eu/corentic/springrag/batch/listener (34 methods)
[ 2.9s] ├ modules/ingestion/src/test/kotlin/eu/corentic/springrag/batch/model (8 methods)
[ 2.9s] ├ modules/ingestion/src/test/kotlin/eu/corentic/springrag/batch/partition (7 methods)
[ 2.9s] ├ modules/ingestion/src/test/kotlin/eu/corentic/springrag/batch/processor (5 methods)
[ 2.9s] ├ modules/ingestion/src/test/kotlin/eu/corentic/springrag/batch/reader (12 methods)
[ 2.9s] ├ modules/ingestion/src/test/kotlin/eu/corentic/springrag/batch/writer (14 methods)
[ 2.9s] ├ modules/ingestion/src/test/kotlin/eu/corentic/springrag/service/chunk (8 methods)
[ 2.9s] ├ modules/ingestion/src/test/kotlin/eu/corentic/springrag/service/job (49 methods)
[ 2.9s] ├ modules/knowledgebase/ports/src/main/kotlin/eu/corentic/springrag/model (5 methods)
[ 2.9s] ├ modules/knowledgebase/src/main/kotlin/eu/corentic/springrag/service/knowledgebase (11 methods)
[ 2.9s] ├ modules/knowledgebase/src/test/kotlin/eu/corentic/springrag/service/knowledgebase (16 methods)
[ 2.9s] ├ modules/security/src/main/kotlin/eu/corentic/springrag/security/config (5 methods)
[ 2.9s] ├ modules/security/src/main/kotlin/eu/corentic/springrag/security/service (10 methods)
[ 2.9s] ├ modules/security/src/test/kotlin/eu/corentic/springrag/security/config (6 methods)
[ 2.9s] ├ modules/security/src/test/kotlin/eu/corentic/springrag/security/service (15 methods)
[ 2.9s] ├ platform/test-support/src/main/kotlin/eu/corentic/springrag/testcontainers (13 methods)
[ 2.9s] ├ platform/test-support/src/test/kotlin/eu/corentic/springrag/testcontainers (5 methods)
[ 2.9s] └ (other) (6 methods)
[ 2.9s] Inferring 120 groups across 12 workers ...
[ 3.1s] [1/120] agents/rag/embabel/src/test/kotlin/eu/corentic/springrag/testsupport (3 methods) done (0.2s)
[ 3.1s] [2/120] agents/rag/ports/src/test/kotlin/eu/corentic/springrag/agent/rag (3 methods) done (0.2s)
[ 3.2s] [3/120] agents/rag/ports/src/main/kotlin/eu/corentic/springrag/agent/rag (4 methods) done (0.3s)
[ 3.2s] [4/120] agents/rag/embabel/src/main/kotlin/eu/corentic/springrag/agent/rag/embabel/librechat (13 methods) done (0.3s)
[ 3.2s] [5/120] agents/capability/ports/src/main/kotlin/eu/corentic/springrag/agent/capability (5 methods) done (0.3s)
[ 3.2s] [6/120] agents/capability/support/src/test/kotlin/eu/corentic/springrag/agent/capability/support (6 methods) done (0.3s)
[ 3.2s] [7/120] agents/rag/ports/src/test/kotlin/eu/corentic/springrag/model (3 methods) done (0.3s)
[ 3.2s] [8/120] agents/capability/support/src/main/kotlin/eu/corentic/springrag/agent/capability/support (5 methods) done (0.3s)
[ 3.2s] [9/120] agents/examples/simple-rag/src/main/kotlin/eu/corentic/springrag/example/rag/simple (9 methods) done (0.3s)
[ 3.2s] [10/120] agents (5 methods) done (0.3s)
[ 3.3s] [11/120] agents/tooling/agent/src/main/kotlin/eu/corentic/springrag/agent/tooling/agent (4 methods) done (0.4s)
[ 3.3s] [12/120] agents/rag/support/src/main/kotlin/eu/corentic/springrag/agent/rag/support (13 methods) done (0.4s)
[ 3.3s] [13/120] agents/examples/simple-rag/src/test/kotlin/eu/corentic/springrag/example/rag/simple (14 methods) done (0.4s)
[ 3.3s] [14/120] agents/wikipedia/static/src/main/kotlin/eu/corentic/springrag/agent/wikipedia (3 methods) done (0.4s)
[ 3.4s] [15/120] agents/wikipedia/adapters/src/main/kotlin/eu/corentic/springrag/agent/wikipedia (4 methods) done (0.5s)
[ 3.4s] [16/120] agents/wikipedia/static/src/test/kotlin/eu/corentic/springrag/agent/wikipedia (3 methods) done (0.5s)
[ 3.4s] [17/120] agents/tooling/embabel/src/main/kotlin/eu/corentic/springrag/agent/tooling/embabel/recording (11 methods) done (0.5s)
[ 3.4s] [18/120] agents/rag/support/src/test/kotlin/eu/corentic/springrag/agent/rag/support (11 methods) done (0.5s)
[ 3.4s] [19/120] agents/summarizer/embabel/src/main/kotlin/eu/corentic/springrag/agent/summarizer/embabel (13 methods) done (0.5s)
[ 3.5s] [20/120] agents/wikipedia/adapters/src/test/kotlin/eu/corentic/springrag/agent/wikipedia (8 methods) done (0.6s)
[ 3.5s] [21/120] app/src/integrationTest/kotlin/eu/corentic/springrag/service (3 methods) done (0.6s)
[ 3.5s] [22/120] agents/rag/embabel/src/main/kotlin/eu/corentic/springrag/agent/rag/embabel (58 methods) done (0.6s)
[ 3.5s] [23/120] agents/tooling/embabel/src/test/kotlin/eu/corentic/springrag/agent/tooling/embabel (6 methods) done (0.6s)
[ 3.5s] [24/120] agents/rag/embabel/src/test/kotlin/eu/corentic/springrag/agent/rag/embabel (36 methods) done (0.6s)
[ 3.5s] [25/120] agents/summarizer/embabel/src/test/kotlin/eu/corentic/springrag/agent/summarizer/embabel (14 methods) done (0.6s)
[ 3.6s] [26/120] app/src/integrationTest/kotlin/eu/corentic/springrag/controller (5 methods) done (0.7s)
[ 3.6s] [27/120] app/src/integrationTest/kotlin/eu/corentic/springrag/config (15 methods) done (0.7s)
[ 3.6s] [28/120] buildSrc/src/main/kotlin (8 methods) done (0.7s)
[ 3.6s] [29/120] app/src/test/kotlin/eu/corentic/springrag/config (3 methods) done (0.7s)
[ 3.6s] [30/120] app/src/systemTest/kotlin/eu/corentic/springrag/config (14 methods) done (0.7s)
[ 3.7s] [31/120] app/src/e2eTest/kotlin/eu/corentic/springrag/e2e/cucumber/steps (17 methods) done (0.8s)
[ 3.7s] [32/120] agents/tooling/embabel/src/main/kotlin/eu/corentic/springrag/agent/tooling/embabel (12 methods) done (0.8s)
[ 3.7s] [33/120] app/src/test/kotlin/eu/corentic/springrag/architecture (87 methods) done (0.8s)
[ 3.7s] [34/120] buildSrc/src/test/kotlin (5 methods) done (0.8s)
[ 3.7s] [35/120] app/src (6 methods) done (0.8s)
[ 3.8s] [36/120] entrypoints/web/src/main/kotlin/eu/corentic/springrag/controller/librechat (29 methods) done (0.9s)
[ 3.8s] [37/120] entrypoints/web/src/test/kotlin/eu/corentic/springrag/controller/auth (5 methods) done (0.9s)
[ 3.8s] [38/120] entrypoints/agent-mcp-server/src/test/kotlin/eu/corentic/springrag/mcp (3 methods) done (0.9s)
[ 3.8s] [39/120] entrypoints/agent-mcp-server/src/main/kotlin/eu/corentic/springrag/mcp (3 methods) done (0.9s)
[ 3.8s] [40/120] entrypoints/web/src/main/kotlin/eu/corentic/springrag/controller/web (6 methods) done (0.9s)
[ 3.8s] [41/120] entrypoints/web/src/test/kotlin/eu/corentic/springrag/config (4 methods) done (0.9s)
[ 3.8s] [42/120] entrypoints/web/src/main/kotlin/eu/corentic/springrag/config (3 methods) done (0.9s)
[ 3.8s] [43/120] app/src/systemTest/kotlin/eu/corentic/springrag/system (46 methods) done (0.9s)
[ 3.9s] [44/120] entrypoints/web/src/test/kotlin/eu/corentic/springrag/controller/web (10 methods) done (1.0s)
[ 3.9s] [45/120] infrastructure/adapters/ai-provider/src/test/kotlin/eu/corentic/springrag/health (4 methods) done (1.0s)
[ 3.9s] [46/120] infrastructure/adapters/ai-provider/src/main/kotlin/eu/corentic/springrag/health (3 methods) done (1.0s)
[ 3.9s] [47/120] entrypoints/web/src/test/kotlin/eu/corentic/springrag/controller/librechat (46 methods) done (1.0s)
[ 3.9s] [48/120] infrastructure/adapters/ai-provider/src/test/kotlin/eu/corentic/springrag/service/embedding (5 methods) done (1.0s)
[ 3.9s] [49/120] infrastructure/adapters/chat-memory/src/test/kotlin/eu/corentic/springrag/config (6 methods) done (1.0s)
[ 3.9s] [50/120] infrastructure/adapters/ai-provider/src/test/kotlin/eu/corentic/springrag/testsupport (3 methods) done (1.0s)
[ 3.9s] [51/120] infrastructure/adapters/ai-provider/src/test/kotlin/eu/corentic/springrag/config (6 methods) done (1.0s)
[ 4.0s] [52/120] infrastructure/adapters/doc-parser/src/test/kotlin/eu/corentic/springrag/health (3 methods) done (1.1s)
[ 4.0s] [53/120] infrastructure/adapters (3 methods) done (1.1s)
[ 4.0s] [54/120] infrastructure/adapters/doc-parser/src/test/kotlin/eu/corentic/springrag/testsupport (3 methods) done (1.1s)
[ 4.0s] [55/120] infrastructure/adapters/doc-parser/src/main/kotlin/eu/corentic/springrag/config (3 methods) done (1.1s)
[ 4.1s] [56/120] infrastructure/adapters/doc-parser/src/test/kotlin/eu/corentic/springrag/service/docling (10 methods) done (1.2s)
[ 4.1s] [57/120] infrastructure/adapters/doc-parser/src/systemTest/kotlin/eu/corentic/springrag/config (6 methods) done (1.2s)
[ 4.1s] [58/120] infrastructure/adapters/search/src/main/kotlin/eu/corentic/springrag/health (7 methods) done (1.2s)
[ 4.1s] [59/120] infrastructure/adapters/search/src/main/kotlin/eu/corentic/springrag/service/agent (3 methods) done (1.2s)
[ 4.1s] [60/120] infrastructure/adapters/doc-parser/src/main/kotlin/eu/corentic/springrag/service/docling (21 methods) done (1.2s)
[ 4.1s] [61/120] entrypoints/web/src/main/kotlin/eu/corentic/springrag/controller (58 methods) done (1.2s)
[ 4.2s] [62/120] infrastructure/adapters/doc-parser/src/test/kotlin/eu/corentic/springrag/config (12 methods) done (1.3s)
[ 4.2s] [63/120] infrastructure/adapters/search/src/main/kotlin/eu/corentic/springrag/service/graph (12 methods) done (1.3s)
[ 4.2s] [64/120] infrastructure/adapters/search/src/main/kotlin/eu/corentic/springrag/repository (24 methods) done (1.3s)
[ 4.2s] [65/120] infrastructure/adapters/ai-provider/src/main/kotlin/eu/corentic/springrag/config (4 methods) done (1.3s)
[ 4.2s] [66/120] infrastructure/adapters/search/src/systemTest/kotlin/eu/corentic/springrag/config (4 methods) done (1.3s)
[ 4.2s] [67/120] entrypoints/web/src/test/kotlin/eu/corentic/springrag/controller (83 methods) done (1.3s)
[ 4.2s] [68/120] infrastructure/adapters/doc-parser/src (6 methods) done (1.3s)
[ 4.2s] [69/120] infrastructure/adapters/search/src/systemTest/kotlin/eu/corentic/springrag/system (6 methods) done (1.3s)
[ 4.2s] [70/120] infrastructure/adapters/search/src/main/kotlin/eu/corentic/springrag/model/graph (9 methods) done (1.3s)
[ 4.3s] [71/120] infrastructure/adapters/search/src/main/kotlin/eu/corentic/springrag/service/storage (40 methods) done (1.4s)
[ 4.3s] [72/120] infrastructure/adapters/search/src/test/kotlin/eu/corentic/springrag/repository (19 methods) done (1.4s)
[ 4.3s] [73/120] infrastructure/adapters/search/src/test/kotlin/eu/corentic/springrag/health (6 methods) done (1.4s)
[ 4.3s] [74/120] infrastructure/adapters/search/src/test/kotlin/eu/corentic/springrag/config (3 methods) done (1.4s)
[ 4.3s] [75/120] infrastructure/adapters/search/src/test/kotlin/eu/corentic/springrag/service/storage (3 methods) done (1.4s)
[ 4.3s] [76/120] infrastructure/adapters/search/src/main/kotlin/eu/corentic/springrag/service/cleanup (4 methods) done (1.4s)
[ 4.3s] [77/120] infrastructure/adapters/search/src/test/kotlin/eu/corentic/springrag/service/graph (30 methods) done (1.4s)
[ 4.4s] [78/120] infrastructure/adapters/search/src/test/kotlin/eu/corentic/springrag/testsupport (3 methods) done (1.5s)
[ 4.4s] [79/120] modules/chat/src/main/kotlin/eu/corentic/springrag/service/chat (6 methods) done (1.5s)
[ 4.4s] [80/120] modules/common/src/main/kotlin/eu/corentic/springrag/common (7 methods) done (1.5s)
[ 4.4s] [81/120] infrastructure/adapters/search/src/systemTest/kotlin/eu/corentic/springrag/repository/graph (23 methods) done (1.5s)
[ 4.4s] [82/120] modules/common/src/main/kotlin/eu/corentic/springrag/common/ids (18 methods) done (1.5s)
[ 4.4s] [83/120] modules/common/src/test/kotlin/eu/corentic/springrag/common/ids (8 methods) done (1.5s)
[ 4.4s] [84/120] modules/chat/src/integrationTest/kotlin/eu/corentic/springrag/service/chat (4 methods) done (1.5s)
[ 4.4s] [85/120] modules/chat/src/systemTest/kotlin/eu/corentic/springrag/system (4 methods) done (1.5s)
[ 4.5s] [86/120] infrastructure/adapters/search/src/test/kotlin/eu/corentic/springrag/model/graph (7 methods) done (1.6s)
[ 4.5s] [87/120] modules/chat/src/test/kotlin/eu/corentic/springrag/service/chat (8 methods) done (1.6s)
[ 4.5s] [88/120] infrastructure/adapters/search/src/test/kotlin/eu/corentic/springrag/service/cleanup (4 methods) done (1.6s)
[ 4.6s] [89/120] modules/ingestion/src/main/kotlin/eu/corentic/springrag/batch (16 methods) done (1.7s)
[ 4.6s] [90/120] modules/chat/src/systemTest/kotlin/eu/corentic/springrag/config (15 methods) done (1.7s)
[ 4.6s] [91/120] modules/ingestion/src/main/kotlin/eu/corentic/springrag/service/document (3 methods) done (1.7s)
[ 4.6s] [92/120] modules/ingestion/src/main/kotlin/eu/corentic/springrag/batch/model (4 methods) done (1.7s)
[ 4.6s] [93/120] modules/ingestion/src/main/kotlin/eu/corentic/springrag/batch/reader (4 methods) done (1.7s)
[ 4.7s] [94/120] modules/ingestion/src/main/kotlin/eu/corentic/springrag/config (26 methods) done (1.8s)
[ 4.7s] [95/120] modules/ingestion/src/main/kotlin/eu/corentic/springrag/batch/writer (3 methods) done (1.8s)
[ 4.7s] [96/120] infrastructure/adapters/search/src/main/kotlin/eu/corentic/springrag/service/port/adapter (45 methods) done (1.8s)
[ 4.8s] [97/120] modules/ingestion/src/main/kotlin/eu/corentic/springrag/batch/listener (16 methods) done (1.9s)
[ 4.8s] [98/120] modules/ingestion/src/test/kotlin/eu/corentic/springrag/batch/partition (7 methods) done (1.9s)
[ 4.8s] [99/120] modules/ingestion/src/test/kotlin/eu/corentic/springrag/batch/model (8 methods) done (1.9s)
[ 4.8s] [100/120] modules/ingestion/src/main/kotlin/eu/corentic/springrag/service/chunk (18 methods) done (1.9s)
[ 4.8s] [101/120] modules/ingestion/src/test/kotlin/eu/corentic/springrag/batch/reader (12 methods) done (1.9s)
[ 4.8s] [102/120] infrastructure/adapters/search/src/test/kotlin/eu/corentic/springrag/service/port/adapter (28 methods) done (1.9s)
[ 4.8s] [103/120] modules/ingestion/src/test/kotlin/eu/corentic/springrag/batch/processor (5 methods) done (1.9s)
[ 4.8s] [104/120] modules/ingestion/src/main/kotlin/eu/corentic/springrag/batch/partition (4 methods) done (1.9s)
[ 4.9s] [105/120] modules/ingestion/src/integrationTest/kotlin/eu/corentic/springrag/service/job (34 methods) done (2.0s)
[ 4.9s] [106/120] modules/ingestion/src/test/kotlin/eu/corentic/springrag/service/chunk (8 methods) done (2.0s)
[ 4.9s] [107/120] modules/ingestion/src/test/kotlin/eu/corentic/springrag/batch (17 methods) done (2.0s)
[ 4.9s] [108/120] modules/knowledgebase/ports/src/main/kotlin/eu/corentic/springrag/model (5 methods) done (2.0s)
[ 4.9s] [109/120] modules/ingestion/src/test/kotlin/eu/corentic/springrag/batch/listener (34 methods) done (2.0s)
[ 4.9s] [110/120] modules/ingestion/src/test/kotlin/eu/corentic/springrag/batch/writer (14 methods) done (2.0s)
[ 5.0s] [111/120] modules/security/src/test/kotlin/eu/corentic/springrag/security/service (15 methods) done (2.1s)
[ 5.0s] [112/120] modules/knowledgebase/src/test/kotlin/eu/corentic/springrag/service/knowledgebase (16 methods) done (2.1s)
[ 5.0s] [113/120] modules/knowledgebase/src/main/kotlin/eu/corentic/springrag/service/knowledgebase (11 methods) done (2.1s)
[ 5.1s] [114/120] modules/security/src/main/kotlin/eu/corentic/springrag/security/service (10 methods) done (2.2s)
[ 5.2s] [115/120] platform/test-support/src/main/kotlin/eu/corentic/springrag/testcontainers (13 methods) done (2.3s)
[ 5.2s] [116/120] modules/security/src/test/kotlin/eu/corentic/springrag/security/config (6 methods) done (2.3s)
[ 5.2s] [117/120] platform/test-support/src/test/kotlin/eu/corentic/springrag/testcontainers (5 methods) done (2.3s)
[ 5.2s] [118/120] modules/security/src/main/kotlin/eu/corentic/springrag/security/config (5 methods) done (2.3s)
[ 5.4s] [119/120] modules/ingestion/src/test/kotlin/eu/corentic/springrag/service/job (49 methods) done (2.5s)
[ 5.5s] [120/120] modules/ingestion/src/main/kotlin/eu/corentic/springrag/service/job (62 methods) done (2.6s)
[ 5.5s] Preprocessing 17 files across 12 workers ...
[ 5.8s] Preprocess: 89 methods from 17 .js files (0.3s)
[ 5.8s] Groups: 3 named, 1 ungrouped methods
[ 5.8s] ├ compose/patches (17 methods)
[ 5.8s] ├ testing/steps (68 methods)
[ 5.8s] ├ testing/support (3 methods)
[ 5.8s] └ (other) (1 methods)
[ 5.8s] Inferring 3 groups across 12 workers ...
[ 5.9s] [1/3] compose/patches (17 methods) done (0.1s)
[ 5.9s] [2/3] testing/support (3 methods) done (0.2s)
[ 6.0s] [3/3] testing/steps (68 methods) done (0.2s)
[ 6.0s] Preprocessing 5 files across 12 workers ...
[ 6.1s] Preprocessing 1 files across 12 workers ...
[ 6.2s] Preprocess: 44 methods from 1 .go files (0.1s)
[ 6.2s] Groups: 1 named, 0 ungrouped methods
[ 6.2s] ├ tools/setup-ui (44 methods)
[ 6.2s] Inferring 1 groups across 12 workers ...
[ 6.3s] [1/1] tools/setup-ui (44 methods) done (0.1s)

View file

@ -168,44 +168,67 @@ def test_infer_low_coverage_filters_noise():
print(" PASS test_infer_low_coverage_filters_noise")
from bex.grammar import (
Symbol, Concat, Alt, Optional, Plus, Star, Empty,
)
def test_count_optionals_flat_chain():
n_opt, n_total = _count_optionals("a?.b?.c?.d?.e?")
g = Concat([Optional(Symbol('a')), Optional(Symbol('b')), Optional(Symbol('c')),
Optional(Symbol('d')), Optional(Symbol('e'))])
n_opt, n_total = _count_optionals(g)
assert n_opt == 5
assert n_total == 5
def test_count_optionals_no_optionals():
n_opt, n_total = _count_optionals("a.b.c")
g = Concat([Symbol('a'), Symbol('b'), Symbol('c')])
n_opt, n_total = _count_optionals(g)
assert n_opt == 0
assert n_total == 3
def test_count_optionals_mixed():
n_opt, n_total = _count_optionals("return.error?.(request+response)?.data?")
assert n_opt == 3 # error?, (request+response)?, data?
assert n_total == 4 # return.error?.(request+response)?.data?
# return . error? . (request|response)? . data? -> 3 optional of 4 parts
g = Concat([
Symbol('return'),
Optional(Symbol('error')),
Optional(Alt([Symbol('request'), Symbol('response')])),
Optional(Symbol('data')),
])
n_opt, n_total = _count_optionals(g)
assert n_opt == 3
assert n_total == 4
def test_count_optionals_repetition_not_optional():
n_opt, n_total = _count_optionals("a.b+.c?")
assert n_opt == 1 # only c? is optional
# a . b+ . c? -> only c? is optional
g = Concat([Symbol('a'), Plus(Symbol('b')), Optional(Symbol('c'))])
n_opt, n_total = _count_optionals(g)
assert n_opt == 1
assert n_total == 3
def test_should_try_idregex_small_many_optionals():
assert _should_try_idregex("a?.b?.c?.d?.e?", 5) is True
g = Concat([Optional(Symbol('a')), Optional(Symbol('b')), Optional(Symbol('c')),
Optional(Symbol('d')), Optional(Symbol('e'))])
assert _should_try_idregex(g, 5) is True
def test_should_try_idregex_large_group():
assert _should_try_idregex("a?.b?.c?.d?.e?", 15) is False
g = Concat([Optional(Symbol('a')), Optional(Symbol('b')), Optional(Symbol('c')),
Optional(Symbol('d')), Optional(Symbol('e'))])
assert _should_try_idregex(g, 15) is False
def test_should_try_idregex_few_optionals():
assert _should_try_idregex("a.b.c.d.e", 5) is False
g = Concat([Symbol('a'), Symbol('b'), Symbol('c'), Symbol('d'), Symbol('e')])
assert _should_try_idregex(g, 5) is False
def test_should_short_concat():
assert _should_try_idregex("a?.b", 5) is False # too few parts
g = Concat([Optional(Symbol('a')), Symbol('b')])
assert _should_try_idregex(g, 5) is False # too few parts
def run_all():