codespy-ai 1.2.3__tar.gz → 1.2.4__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.
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/PKG-INFO +1 -1
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/pyproject.toml +1 -1
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/__init__.py +1 -1
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/agents/review/audit/agent.py +27 -16
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/agents/review/scope/agent.py +57 -9
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/config.py +12 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/config_dspy.py +1 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/workflows/review/pipeline.py +4 -3
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/LICENSE +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/README.md +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/agents/__init__.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/agents/context_safe.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/agents/cost_tracker.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/agents/dspy_config.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/agents/memory/__init__.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/agents/memory/hippocampus/__init__.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/agents/memory/hippocampus/budget.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/agents/memory/hippocampus/cartographer.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/agents/memory/hippocampus/context_memory.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/agents/memory/hippocampus/distiller.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/agents/memory/hippocampus/episode.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/agents/memory/hippocampus/hippocampus.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/agents/memory/pg0_manager.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/agents/memory/postgres.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/agents/review/__init__.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/agents/review/audit/__init__.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/agents/review/code_review/__init__.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/agents/review/code_review/agent.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/agents/review/doc/__init__.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/agents/review/doc/agent.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/agents/review/doc/doc_extractor.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/agents/review/helpers.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/agents/review/models.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/agents/review/scope/__init__.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/agents/review/scope/manifest_parser.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/agents/review/scope/models.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/agents/review/summary/__init__.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/agents/review/summary/agent.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/agents/review/supply_chain/__init__.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/agents/review/supply_chain/agent.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/cli.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/cli_local.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/cli_mcp_server.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/cli_remote.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/config_git.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/config_io.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/config_llm.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/config_memory.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/config_utils.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/__init__.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/cyber/__init__.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/cyber/osv/__init__.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/cyber/osv/client.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/cyber/osv/models.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/cyber/osv/server.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/git/__init__.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/git/base.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/git/client.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/git/github_client.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/git/gitlab_client.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/git/local_diff.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/git/models.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/git/patch_utils.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/git/server.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/mcp_utils.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/parsers/__init__.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/parsers/ripgrep/__init__.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/parsers/ripgrep/client.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/parsers/ripgrep/server.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/parsers/treesitter/__init__.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/parsers/treesitter/base_extractor.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/parsers/treesitter/extractors/__init__.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/parsers/treesitter/extractors/bash.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/parsers/treesitter/extractors/cpp.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/parsers/treesitter/extractors/csharp.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/parsers/treesitter/extractors/go.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/parsers/treesitter/extractors/java.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/parsers/treesitter/extractors/javascript.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/parsers/treesitter/extractors/kotlin.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/parsers/treesitter/extractors/objc.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/parsers/treesitter/extractors/php.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/parsers/treesitter/extractors/python.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/parsers/treesitter/extractors/ripgrep_fallback.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/parsers/treesitter/extractors/ruby.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/parsers/treesitter/extractors/rust.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/parsers/treesitter/extractors/swift.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/parsers/treesitter/extractors/terraform.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/parsers/treesitter/models.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/parsers/treesitter/parser.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/parsers/treesitter/server.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/storage/__init__.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/storage/base.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/storage/filesystem/__init__.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/storage/filesystem/client.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/storage/filesystem/server.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/storage/models.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/storage/s3/__init__.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/storage/s3/client.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/storage/s3/server.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/web/__init__.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/web/client.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/web/models.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/web/server.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/workflows/__init__.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/workflows/review/__init__.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/workflows/review/models.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/workflows/review/reporters/__init__.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/workflows/review/reporters/base.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/workflows/review/reporters/git.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/workflows/review/reporters/stdout.py +0 -0
- {codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/workflows/review/server.py +0 -0
|
@@ -9,6 +9,7 @@ from codespy.agents import SignatureContext, get_cost_tracker
|
|
|
9
9
|
from codespy.agents.context_safe import ContextSafe
|
|
10
10
|
from codespy.agents.memory.hippocampus import ContextMemory, Hippocampus, inject_context_memory
|
|
11
11
|
from codespy.agents.memory.hippocampus.context_memory import Topic
|
|
12
|
+
from codespy.agents.memory.hippocampus.episode import submit_episode_save
|
|
12
13
|
from codespy.agents.review.models import Issue, ReviewContext
|
|
13
14
|
from codespy.agents.review.helpers import deepest_common_folder
|
|
14
15
|
from codespy.config import get_settings
|
|
@@ -16,6 +17,7 @@ from codespy.config_memory import get_episode_store
|
|
|
16
17
|
|
|
17
18
|
if TYPE_CHECKING:
|
|
18
19
|
from codespy.agents.review.scope.models import ScopeResult
|
|
20
|
+
from codespy.agents.memory.hippocampus.episode import EpisodeStore
|
|
19
21
|
|
|
20
22
|
logger = logging.getLogger(__name__)
|
|
21
23
|
|
|
@@ -57,8 +59,13 @@ class Auditor(dspy.Module):
|
|
|
57
59
|
run_id: str | None,
|
|
58
60
|
scopes: list["ScopeResult"] | None,
|
|
59
61
|
topics: list["ScopeResult"] | None = None,
|
|
60
|
-
) -> dspy.Prediction:
|
|
61
|
-
"""Execute the auditor predictor (with or without Hippocampus memory).
|
|
62
|
+
) -> tuple[dspy.Prediction, Hippocampus | None, "EpisodeStore | None", dict[str, str] | None]:
|
|
63
|
+
"""Execute the auditor predictor (with or without Hippocampus memory).
|
|
64
|
+
|
|
65
|
+
Returns:
|
|
66
|
+
Tuple of (result, hippo, store, artifacts) where hippo/store/artifacts
|
|
67
|
+
are None when memory is disabled.
|
|
68
|
+
"""
|
|
62
69
|
question = (
|
|
63
70
|
f"final audit of {review_context.pr_context.repo_slug}: "
|
|
64
71
|
f"pull request {review_context.pr_context.pr_number} "
|
|
@@ -110,25 +117,20 @@ class Auditor(dspy.Module):
|
|
|
110
117
|
all_issues=all_issues,
|
|
111
118
|
)
|
|
112
119
|
hippo.observe(result)
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
"
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
}
|
|
121
|
-
hippo.end_episode(store, artifacts=_artifacts)
|
|
122
|
-
except Exception:
|
|
123
|
-
logger.warning("Audit episode save failed", exc_info=True)
|
|
120
|
+
_artifacts = {
|
|
121
|
+
"audit": (
|
|
122
|
+
f"## Quality Assessment\n\n{result.quality_assessment}\n\n"
|
|
123
|
+
f"## Recommendation\n\n{result.recommendation}\n"
|
|
124
|
+
)
|
|
125
|
+
}
|
|
126
|
+
return result, hippo, store, _artifacts
|
|
124
127
|
else:
|
|
125
128
|
result = auditor(
|
|
126
129
|
pr_title=review_context.pr_context.pr_title,
|
|
127
130
|
summary=review_context.pr_context.summary,
|
|
128
131
|
all_issues=all_issues,
|
|
129
132
|
)
|
|
130
|
-
|
|
131
|
-
return result
|
|
133
|
+
return result, None, None, None
|
|
132
134
|
|
|
133
135
|
def forward(
|
|
134
136
|
self,
|
|
@@ -168,7 +170,7 @@ class Auditor(dspy.Module):
|
|
|
168
170
|
logger.info("Running audit...")
|
|
169
171
|
|
|
170
172
|
with SignatureContext("audit", self._cost_tracker):
|
|
171
|
-
result = self._call_auditor(
|
|
173
|
+
result, hippo, store, _artifacts = self._call_auditor(
|
|
172
174
|
auditor,
|
|
173
175
|
review_context,
|
|
174
176
|
all_issues,
|
|
@@ -177,4 +179,13 @@ class Auditor(dspy.Module):
|
|
|
177
179
|
topics,
|
|
178
180
|
)
|
|
179
181
|
|
|
182
|
+
# Background episode save (after SignatureContext closes)
|
|
183
|
+
if hippo is not None and store is not None:
|
|
184
|
+
def _persist():
|
|
185
|
+
try:
|
|
186
|
+
hippo.end_episode(store, artifacts=_artifacts)
|
|
187
|
+
except Exception:
|
|
188
|
+
logger.warning("Audit episode save failed", exc_info=True)
|
|
189
|
+
submit_episode_save(_persist, name="audit-episode-save")
|
|
190
|
+
|
|
180
191
|
return result.quality_assessment, result.recommendation
|
|
@@ -625,10 +625,17 @@ class ScopeResolver(dspy.Module):
|
|
|
625
625
|
# Extract package name from manifest
|
|
626
626
|
package_name = extract_package_name(manifest_path, repo_path)
|
|
627
627
|
|
|
628
|
-
# Build deterministic description
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
628
|
+
# Build deterministic description with package name and scope type
|
|
629
|
+
parts = []
|
|
630
|
+
if package_name:
|
|
631
|
+
parts.append(package_name)
|
|
632
|
+
parts.append(f"{scope_type.value}")
|
|
633
|
+
if subroot != ".":
|
|
634
|
+
parts.append(f"at {subroot}")
|
|
635
|
+
else:
|
|
636
|
+
parts.append("(repository root)")
|
|
637
|
+
parts.append(f"managed by {pkg_mgr}")
|
|
638
|
+
description = " — ".join([parts[0], " ".join(parts[1:])]) if len(parts) > 1 else " ".join(parts)
|
|
632
639
|
|
|
633
640
|
scopes[subroot] = ScopeResult(
|
|
634
641
|
repo=repo,
|
|
@@ -658,7 +665,9 @@ class ScopeResolver(dspy.Module):
|
|
|
658
665
|
indicator_type, indicator_path = self._find_scope_indicator(file.filename)
|
|
659
666
|
if indicator_path and indicator_type and indicator_path not in scopes:
|
|
660
667
|
# Build deterministic description for indicator-based scope
|
|
661
|
-
|
|
668
|
+
parts = [f"{indicator_type.value}", "scope"]
|
|
669
|
+
parts.append(f"at {indicator_path}")
|
|
670
|
+
description = " ".join(parts)
|
|
662
671
|
scopes[indicator_path] = ScopeResult(
|
|
663
672
|
repo=repo,
|
|
664
673
|
subroot=indicator_path,
|
|
@@ -978,6 +987,33 @@ class ScopeResolver(dspy.Module):
|
|
|
978
987
|
|
|
979
988
|
return [s for s in final_boundaries.values() if s.changed_files]
|
|
980
989
|
|
|
990
|
+
def _finalize_scopes(
|
|
991
|
+
self,
|
|
992
|
+
scopes: list[ScopeResult],
|
|
993
|
+
review_context: ReviewContext,
|
|
994
|
+
) -> list[ScopeResult]:
|
|
995
|
+
"""Finalize scopes by building topics and attaching hierarchical skills.
|
|
996
|
+
|
|
997
|
+
This helper is called both by the fast-path (deterministic resolution only)
|
|
998
|
+
and by _refine_scopes after LLM refinement. It does NOT handle Hippocampus
|
|
999
|
+
binding or episode persistence — those are handled separately.
|
|
1000
|
+
|
|
1001
|
+
Args:
|
|
1002
|
+
scopes: List of ScopeResult to finalize
|
|
1003
|
+
review_context: Review context with PR identity and metadata
|
|
1004
|
+
|
|
1005
|
+
Returns:
|
|
1006
|
+
Finalized list of ScopeResult with skills attached
|
|
1007
|
+
"""
|
|
1008
|
+
pr = review_context.metadata.pr
|
|
1009
|
+
repo_path = review_context.metadata.repo_path
|
|
1010
|
+
|
|
1011
|
+
# Attach hierarchical skills to each scope
|
|
1012
|
+
for scope in scopes:
|
|
1013
|
+
scope.skills = collect_skills(repo_path, scope.subroot)
|
|
1014
|
+
|
|
1015
|
+
return scopes
|
|
1016
|
+
|
|
981
1017
|
async def _refine_scopes(
|
|
982
1018
|
self,
|
|
983
1019
|
scopes: list[ScopeResult],
|
|
@@ -1120,9 +1156,8 @@ class ScopeResolver(dspy.Module):
|
|
|
1120
1156
|
# Add PR URL topic (provides description; not a scope)
|
|
1121
1157
|
pr_ctx = review_context.pr_context
|
|
1122
1158
|
scope_topics.append(pr_ctx.to_topic())
|
|
1123
|
-
#
|
|
1124
|
-
|
|
1125
|
-
scope.skills = collect_skills(repo_path, scope.subroot)
|
|
1159
|
+
# Finalize scopes with hierarchical skills
|
|
1160
|
+
self._finalize_scopes(final_scopes, review_context)
|
|
1126
1161
|
# Bind topics to hippocampus cmem for episode persistence
|
|
1127
1162
|
if hippo is not None and stamp_topic_ids:
|
|
1128
1163
|
stamp_topic_ids.append(pr_ctx.pr_url)
|
|
@@ -1204,7 +1239,20 @@ class ScopeResolver(dspy.Module):
|
|
|
1204
1239
|
)
|
|
1205
1240
|
if orphans:
|
|
1206
1241
|
logger.info("Deterministic identification produced %d orphan(s)", len(orphans))
|
|
1207
|
-
|
|
1242
|
+
|
|
1243
|
+
# Fast-path: skip LLM refinement when clean single-scope resolution
|
|
1244
|
+
if (
|
|
1245
|
+
len(scopes) == 1
|
|
1246
|
+
and not orphans
|
|
1247
|
+
and self._settings.get_scope_skip_refinement()
|
|
1248
|
+
):
|
|
1249
|
+
logger.info(
|
|
1250
|
+
"Deterministic resolution sufficient (1 scope, 0 orphans); "
|
|
1251
|
+
"skipping LLM refinement"
|
|
1252
|
+
)
|
|
1253
|
+
scopes = self._finalize_scopes(scopes, review_context)
|
|
1254
|
+
else:
|
|
1255
|
+
scopes = await self._refine_scopes(scopes, orphans, review_context)
|
|
1208
1256
|
# Log final scopes for visibility
|
|
1209
1257
|
scope_summary = "\n".join(
|
|
1210
1258
|
f" - {s.subroot} ({s.scope_type.value}): {len(s.changed_files)} files"
|
|
@@ -281,6 +281,18 @@ class Settings(BaseSettings):
|
|
|
281
281
|
compact_trajectory=self.memory.compact_trajectory,
|
|
282
282
|
)
|
|
283
283
|
|
|
284
|
+
def get_scope_skip_refinement(self) -> bool:
|
|
285
|
+
"""Whether to skip LLM refinement when deterministic resolution is clean.
|
|
286
|
+
|
|
287
|
+
Returns True (skip) when:
|
|
288
|
+
- There's 1 scope and 0 orphans (single scope, all files assigned)
|
|
289
|
+
- The setting skip_refinement_when_clean is True or not explicitly set
|
|
290
|
+
|
|
291
|
+
Per-signature ``skip_refinement_when_clean`` overrides default (True).
|
|
292
|
+
"""
|
|
293
|
+
val = self.get_signature_config("scope").skip_refinement_when_clean
|
|
294
|
+
return val if val is not None else True # default: skip
|
|
295
|
+
|
|
284
296
|
def get_rlm_threshold(self, module_type: str) -> float:
|
|
285
297
|
"""Resolve RLM fallback threshold for a module type.
|
|
286
298
|
|
|
@@ -51,6 +51,7 @@ class SignatureConfig(BaseModel):
|
|
|
51
51
|
temperature: float | None = None
|
|
52
52
|
max_tokens: int | None = None # Output token budget (reasoning tokens included)
|
|
53
53
|
scan_unchanged: bool | None = None # For supply_chain: scan unmodified artifacts/manifests
|
|
54
|
+
skip_refinement_when_clean: bool | None = None # For scope: skip LLM refinement when 1 scope, 0 orphans
|
|
54
55
|
|
|
55
56
|
memory: MemorySignatureConfig = Field(default_factory=MemorySignatureConfig)
|
|
56
57
|
|
|
@@ -249,10 +249,11 @@ class ReviewPipeline(dspy.Module):
|
|
|
249
249
|
scopes=scopes,
|
|
250
250
|
topics=all_scope_topics,
|
|
251
251
|
)
|
|
252
|
-
#
|
|
253
|
-
|
|
254
|
-
# Ensure all background episode saves complete before returning
|
|
252
|
+
# Ensure all background episode saves complete before stats collection
|
|
253
|
+
# (audit's episode save runs in background and contains distiller/cartographer calls)
|
|
255
254
|
join_episode_saves()
|
|
255
|
+
# Collect per-signature statistics (after all saves complete)
|
|
256
|
+
signature_stats_list = self._collect_signature_stats()
|
|
256
257
|
return ReviewResult(
|
|
257
258
|
pr_number=pr.number,
|
|
258
259
|
pr_title=pr.title,
|
|
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
|
{codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/agents/memory/hippocampus/context_memory.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
|
|
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
|
{codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/parsers/treesitter/base_extractor.py
RENAMED
|
File without changes
|
{codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/parsers/treesitter/extractors/__init__.py
RENAMED
|
File without changes
|
{codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/parsers/treesitter/extractors/bash.py
RENAMED
|
File without changes
|
{codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/parsers/treesitter/extractors/cpp.py
RENAMED
|
File without changes
|
{codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/parsers/treesitter/extractors/csharp.py
RENAMED
|
File without changes
|
|
File without changes
|
{codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/parsers/treesitter/extractors/java.py
RENAMED
|
File without changes
|
{codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/parsers/treesitter/extractors/javascript.py
RENAMED
|
File without changes
|
{codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/parsers/treesitter/extractors/kotlin.py
RENAMED
|
File without changes
|
{codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/parsers/treesitter/extractors/objc.py
RENAMED
|
File without changes
|
{codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/parsers/treesitter/extractors/php.py
RENAMED
|
File without changes
|
{codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/parsers/treesitter/extractors/python.py
RENAMED
|
File without changes
|
|
File without changes
|
{codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/parsers/treesitter/extractors/ruby.py
RENAMED
|
File without changes
|
{codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/parsers/treesitter/extractors/rust.py
RENAMED
|
File without changes
|
{codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/parsers/treesitter/extractors/swift.py
RENAMED
|
File without changes
|
{codespy_ai-1.2.3 → codespy_ai-1.2.4}/src/codespy/tools/parsers/treesitter/extractors/terraform.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
|