Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ DEFAULT_MODEL=anthropic/claude-opus-4-6
# EXTRACTION_MODEL=anthropic/claude-sonnet-4-5-20250929

# DEFAULT_MAX_ITERS=10
# DEFAULT_MAX_LLM_CALLS=30
# Provider reasoning budget: minimal | low | medium | high
# DEFAULT_REASONING_EFFORT=medium
# DEFAULT_TEMPERATURE=0.2
Expand All @@ -151,6 +152,9 @@ DEFAULT_MODEL=anthropic/claude-opus-4-6
# Enable provider-side prompt caching (reduces latency and costs)
# ENABLE_PROMPT_CACHING=true

# Minimum confidence threshold for reported issues (0.0-1.0)
# MIN_CONFIDENCE=0.81

# =============================================================================
# Memory (Hippocampus)
# =============================================================================
Expand Down Expand Up @@ -250,6 +254,7 @@ DEFAULT_MODEL=anthropic/claude-opus-4-6
# Available settings per signature:
# - ENABLED (true/false)
# - MAX_ITERS (integer)
# - MAX_LLM_CALLS (integer) - RLM fallback max calls (unset -> DEFAULT_MAX_LLM_CALLS)
# - MODEL (LiteLLM model string)
# - REASONING_EFFORT (minimal|low|medium|high) - Provider reasoning budget
# - TEMPERATURE (float) - Must be 1 while reasoning is enabled
Expand Down
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
# Changelog

## [1.0.3] - 2026-08-18

### Added
- Configurable `DEFAULT_MAX_LLM_CALLS` setting (default 30) controlling maximum LLM calls for RLM context-overflow fallback
- Configurable `MIN_CONFIDENCE` threshold (default 0.81) for filtering low-confidence issues
- Per-signature `max_llm_calls` override (`SCOPE_MAX_LLM_CALLS`, `CODE_REVIEW_MAX_LLM_CALLS`, `SUPPLY_CHAIN_MAX_LLM_CALLS`, `SUMMARY_MAX_LLM_CALLS`, `DOC_MAX_LLM_CALLS`, `AUDIT_MAX_LLM_CALLS`)
- `ContextSafe` now accepts `max_iters` and `max_llm_calls` parameters for per-module override

### Changed
- `default-max-iters` action input default raised from 3 to 10
- Moved hardcoded `MIN_CONFIDENCE` constant from `helpers.py` to configurable `Settings.min_confidence` field (default 0.81)

### Fixed
- RLM fallback previously hardcoded `max_iters=10, max_llm_calls=20`; now respects per-signature and global configuration

## [1.0.2] - 2026-08-18

### Fixed
Expand Down
52 changes: 45 additions & 7 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ inputs:
default-max-iters:
description: 'Default maximum iterations for all signatures'
required: false
default: '3'
default: '10'

default-reasoning-effort:
description: 'Default reasoning effort for all signatures (minimal|low|medium|high)'
Expand All @@ -93,7 +93,17 @@ inputs:
description: 'Enable provider-side prompt caching (reduces latency and costs)'
required: false
default: 'true'


default-max-llm-calls:
description: 'Maximum LLM calls for RLM fallback (context overflow recovery)'
required: false
default: '30'

min-confidence:
description: 'Minimum confidence threshold (0.0-1.0) for reported issues'
required: false
default: '0.81'

# ==========================================
# SIGNATURE: scope
# ==========================================
Expand All @@ -109,7 +119,11 @@ inputs:
scope-max-iters:
description: 'Max iterations for scope identification'
required: false


scope-max-llm-calls:
description: 'Max LLM calls for scope RLM fallback'
required: false

scope-reasoning-effort:
description: 'Reasoning effort for scope (minimal|low|medium|high)'
required: false
Expand All @@ -133,7 +147,11 @@ inputs:
code-review-max-iters:
description: 'Max iterations for code review'
required: false


code-review-max-llm-calls:
description: 'Max LLM calls for code review RLM fallback'
required: false

code-review-reasoning-effort:
description: 'Reasoning effort for code review (minimal|low|medium|high)'
required: false
Expand Down Expand Up @@ -177,7 +195,11 @@ inputs:
supply-chain-max-iters:
description: 'Max iterations for supply chain security'
required: false


supply-chain-max-llm-calls:
description: 'Max LLM calls for supply chain RLM fallback'
required: false

supply-chain-reasoning-effort:
description: 'Reasoning effort for supply chain (minimal|low|medium|high)'
required: false
Expand All @@ -203,6 +225,10 @@ inputs:
description: 'Model for summary (empty = use default)'
required: false

summary-max-llm-calls:
description: 'Max LLM calls for summary RLM fallback'
required: false

summary-reasoning-effort:
description: 'Reasoning effort for summary (minimal|low|medium|high)'
required: false
Expand Down Expand Up @@ -361,18 +387,22 @@ runs:
LLM_RETRIES: ${{ inputs.llm-retries }}
LLM_TIMEOUT: ${{ inputs.llm-timeout }}
ENABLE_PROMPT_CACHING: ${{ inputs.enable-prompt-caching }}

DEFAULT_MAX_LLM_CALLS: ${{ inputs.default-max-llm-calls }}
MIN_CONFIDENCE: ${{ inputs.min-confidence }}

# Scope identification signature
SCOPE_ENABLED: ${{ inputs.scope-enabled }}
SCOPE_MODEL: ${{ inputs.scope-model }}
SCOPE_MAX_ITERS: ${{ inputs.scope-max-iters }}
SCOPE_MAX_LLM_CALLS: ${{ inputs.scope-max-llm-calls }}
SCOPE_REASONING_EFFORT: ${{ inputs.scope-reasoning-effort }}
SCOPE_TEMPERATURE: ${{ inputs.scope-temperature }}

# Code review signature
CODE_REVIEW_ENABLED: ${{ inputs.code-review-enabled }}
CODE_REVIEW_MODEL: ${{ inputs.code-review-model }}
CODE_REVIEW_MAX_ITERS: ${{ inputs.code-review-max-iters }}
CODE_REVIEW_MAX_LLM_CALLS: ${{ inputs.code-review-max-llm-calls }}
CODE_REVIEW_REASONING_EFFORT: ${{ inputs.code-review-reasoning-effort }}
CODE_REVIEW_TEMPERATURE: ${{ inputs.code-review-temperature }}

Expand All @@ -386,13 +416,15 @@ runs:
SUPPLY_CHAIN_ENABLED: ${{ inputs.supply-chain-enabled }}
SUPPLY_CHAIN_MODEL: ${{ inputs.supply-chain-model }}
SUPPLY_CHAIN_MAX_ITERS: ${{ inputs.supply-chain-max-iters }}
SUPPLY_CHAIN_MAX_LLM_CALLS: ${{ inputs.supply-chain-max-llm-calls }}
SUPPLY_CHAIN_REASONING_EFFORT: ${{ inputs.supply-chain-reasoning-effort }}
SUPPLY_CHAIN_TEMPERATURE: ${{ inputs.supply-chain-temperature }}
SUPPLY_CHAIN_SCAN_UNCHANGED: ${{ inputs.supply-chain-scan-unchanged }}

# Summary signature
SUMMARY_ENABLED: ${{ inputs.summary-enabled }}
SUMMARY_MODEL: ${{ inputs.summary-model }}
SUMMARY_MAX_LLM_CALLS: ${{ inputs.summary-max-llm-calls }}
SUMMARY_REASONING_EFFORT: ${{ inputs.summary-reasoning-effort }}
SUMMARY_TEMPERATURE: ${{ inputs.summary-temperature }}

Expand Down Expand Up @@ -441,18 +473,22 @@ runs:
[ -n "$LLM_RETRIES" ] && DOCKER_ARGS="$DOCKER_ARGS -e LLM_RETRIES"
[ -n "$LLM_TIMEOUT" ] && DOCKER_ARGS="$DOCKER_ARGS -e LLM_TIMEOUT"
[ -n "$ENABLE_PROMPT_CACHING" ] && DOCKER_ARGS="$DOCKER_ARGS -e ENABLE_PROMPT_CACHING"

[ -n "$DEFAULT_MAX_LLM_CALLS" ] && DOCKER_ARGS="$DOCKER_ARGS -e DEFAULT_MAX_LLM_CALLS"
[ -n "$MIN_CONFIDENCE" ] && DOCKER_ARGS="$DOCKER_ARGS -e MIN_CONFIDENCE"

# Scope identification
[ -n "$SCOPE_ENABLED" ] && DOCKER_ARGS="$DOCKER_ARGS -e SCOPE_ENABLED"
[ -n "$SCOPE_MODEL" ] && DOCKER_ARGS="$DOCKER_ARGS -e SCOPE_MODEL"
[ -n "$SCOPE_MAX_ITERS" ] && DOCKER_ARGS="$DOCKER_ARGS -e SCOPE_MAX_ITERS"
[ -n "$SCOPE_MAX_LLM_CALLS" ] && DOCKER_ARGS="$DOCKER_ARGS -e SCOPE_MAX_LLM_CALLS"
[ -n "$SCOPE_REASONING_EFFORT" ] && DOCKER_ARGS="$DOCKER_ARGS -e SCOPE_REASONING_EFFORT"
[ -n "$SCOPE_TEMPERATURE" ] && DOCKER_ARGS="$DOCKER_ARGS -e SCOPE_TEMPERATURE"

# Code review
[ -n "$CODE_REVIEW_ENABLED" ] && DOCKER_ARGS="$DOCKER_ARGS -e CODE_REVIEW_ENABLED"
[ -n "$CODE_REVIEW_MODEL" ] && DOCKER_ARGS="$DOCKER_ARGS -e CODE_REVIEW_MODEL"
[ -n "$CODE_REVIEW_MAX_ITERS" ] && DOCKER_ARGS="$DOCKER_ARGS -e CODE_REVIEW_MAX_ITERS"
[ -n "$CODE_REVIEW_MAX_LLM_CALLS" ] && DOCKER_ARGS="$DOCKER_ARGS -e CODE_REVIEW_MAX_LLM_CALLS"
[ -n "$CODE_REVIEW_REASONING_EFFORT" ] && DOCKER_ARGS="$DOCKER_ARGS -e CODE_REVIEW_REASONING_EFFORT"
[ -n "$CODE_REVIEW_TEMPERATURE" ] && DOCKER_ARGS="$DOCKER_ARGS -e CODE_REVIEW_TEMPERATURE"

Expand All @@ -466,13 +502,15 @@ runs:
[ -n "$SUPPLY_CHAIN_ENABLED" ] && DOCKER_ARGS="$DOCKER_ARGS -e SUPPLY_CHAIN_ENABLED"
[ -n "$SUPPLY_CHAIN_MODEL" ] && DOCKER_ARGS="$DOCKER_ARGS -e SUPPLY_CHAIN_MODEL"
[ -n "$SUPPLY_CHAIN_MAX_ITERS" ] && DOCKER_ARGS="$DOCKER_ARGS -e SUPPLY_CHAIN_MAX_ITERS"
[ -n "$SUPPLY_CHAIN_MAX_LLM_CALLS" ] && DOCKER_ARGS="$DOCKER_ARGS -e SUPPLY_CHAIN_MAX_LLM_CALLS"
[ -n "$SUPPLY_CHAIN_REASONING_EFFORT" ] && DOCKER_ARGS="$DOCKER_ARGS -e SUPPLY_CHAIN_REASONING_EFFORT"
[ -n "$SUPPLY_CHAIN_TEMPERATURE" ] && DOCKER_ARGS="$DOCKER_ARGS -e SUPPLY_CHAIN_TEMPERATURE"
[ -n "$SUPPLY_CHAIN_SCAN_UNCHANGED" ] && DOCKER_ARGS="$DOCKER_ARGS -e SUPPLY_CHAIN_SCAN_UNCHANGED"

# Summary
[ -n "$SUMMARY_ENABLED" ] && DOCKER_ARGS="$DOCKER_ARGS -e SUMMARY_ENABLED"
[ -n "$SUMMARY_MODEL" ] && DOCKER_ARGS="$DOCKER_ARGS -e SUMMARY_MODEL"
[ -n "$SUMMARY_MAX_LLM_CALLS" ] && DOCKER_ARGS="$DOCKER_ARGS -e SUMMARY_MAX_LLM_CALLS"
[ -n "$SUMMARY_REASONING_EFFORT" ] && DOCKER_ARGS="$DOCKER_ARGS -e SUMMARY_REASONING_EFFORT"
[ -n "$SUMMARY_TEMPERATURE" ] && DOCKER_ARGS="$DOCKER_ARGS -e SUMMARY_TEMPERATURE"

Expand Down
11 changes: 11 additions & 0 deletions codespy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ llm:
# Caches system prompts on the LLM provider's servers to reduce latency and costs
enable_prompt_caching: true # ENABLE_PROMPT_CACHING

# Minimum confidence threshold for reported issues (0.0–1.0).
# Issues below this threshold are silently discarded.
min_confidence: 0.81 # MIN_CONFIDENCE


# ============================================================================
# GIT PLATFORMS
Expand Down Expand Up @@ -187,6 +191,7 @@ memory:
default_model: anthropic/claude-opus-4-6 # DEFAULT_MODEL
extraction_model: null # EXTRACTION_MODEL (falls back to default_model)
default_max_iters: 10 # DEFAULT_MAX_ITERS
default_max_llm_calls: 30 # DEFAULT_MAX_LLM_CALLS
default_reasoning_effort: medium # DEFAULT_REASONING_EFFORT (minimal | low | medium | high)
default_temperature: 0.2 # DEFAULT_TEMPERATURE

Expand All @@ -211,6 +216,7 @@ signatures:
supply_chain:
enabled: true # SUPPLY_CHAIN_ENABLED
max_iters: null # SUPPLY_CHAIN_MAX_ITERS
max_llm_calls: null # SUPPLY_CHAIN_MAX_LLM_CALLS
model: null # SUPPLY_CHAIN_MODEL (Haiku 4.5)
reasoning_effort: null # SUPPLY_CHAIN_REASONING_EFFORT
temperature: null # SUPPLY_CHAIN_TEMPERATURE
Expand All @@ -227,6 +233,7 @@ signatures:
code_review:
enabled: true # CODE_REVIEW_ENABLED
max_iters: null # CODE_REVIEW_MAX_ITERS
max_llm_calls: null # CODE_REVIEW_MAX_LLM_CALLS
model: null # CODE_REVIEW_MODEL
reasoning_effort: null # CODE_REVIEW_REASONING_EFFORT
temperature: null # CODE_REVIEW_TEMPERATURE
Expand All @@ -239,6 +246,7 @@ signatures:
# Note: doc extraction is now deterministic (no LLM) — see doc_extractor.py
doc:
enabled: true # DOC_ENABLED
max_llm_calls: null # DOC_MAX_LLM_CALLS
model: null # DOC_MODEL
reasoning_effort: null # DOC_REASONING_EFFORT
temperature: null # DOC_TEMPERATURE
Expand All @@ -251,6 +259,7 @@ signatures:
scope:
enabled: true # SCOPE_ENABLED
max_iters: 20 # SCOPE_MAX_ITERS
max_llm_calls: null # SCOPE_MAX_LLM_CALLS
model: null # SCOPE_MODEL
reasoning_effort: null # SCOPE_REASONING_EFFORT
temperature: null # SCOPE_TEMPERATURE
Expand All @@ -262,6 +271,7 @@ signatures:
# Summarizer signature
summary:
enabled: true # SUMMARY_ENABLED
max_llm_calls: null # SUMMARY_MAX_LLM_CALLS
model: null # SUMMARY_MODEL (falls back to default_model)
reasoning_effort: null # SUMMARY_REASONING_EFFORT
temperature: null # SUMMARY_TEMPERATURE
Expand All @@ -273,6 +283,7 @@ signatures:
# Auditor signature (quality assessment + recommendation after all reviews)
audit:
enabled: true # AUDIT_ENABLED
max_llm_calls: null # AUDIT_MAX_LLM_CALLS
model: null # AUDIT_MODEL
reasoning_effort: null # AUDIT_REASONING_EFFORT
temperature: null # AUDIT_TEMPERATURE
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "codespy-ai"
version = "1.0.2"
version = "1.0.3"
description = "Code review agent powered by DSPy"
readme = "README.md"
license = "MIT"
Expand Down
2 changes: 1 addition & 1 deletion src/codespy/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
"""codespy - Code review agent powered by DSPy."""

__version__ = "1.0.2"
__version__ = "1.0.3"
16 changes: 13 additions & 3 deletions src/codespy/agents/context_safe.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,22 @@ class ContextSafe(dspy.Module):
Transparent to Hippocampus — delegates .signature to inner module.
"""

def __init__(self, module: dspy.Module, signature, tools: list | None = None, name: str = ""):
def __init__(
self,
module: dspy.Module,
signature,
tools: list | None = None,
name: str = "",
max_iters: int | None = None,
max_llm_calls: int | None = None,
):
super().__init__()
self.module = module
self._orig_signature = signature
self._tools = tools
self._name = name or signature.__name__
self._max_iters = max_iters
self._max_llm_calls = max_llm_calls

@property
def signature(self):
Expand Down Expand Up @@ -153,6 +163,6 @@ def _create_rlm_fallback(self) -> dspy.RLM:
return dspy.RLM(
self._get_current_signature(),
tools=self._tools,
max_iters=10,
max_llm_calls=20,
max_iters=self._max_iters or 10,
max_llm_calls=self._max_llm_calls or 20,
)
7 changes: 6 additions & 1 deletion src/codespy/agents/reviewer/modules/auditor.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,12 @@ def forward(
"NEEDS_DISCUSSION" if all_issues else "APPROVE",
)

auditor = ContextSafe(dspy.ChainOfThought(AuditSignature), AuditSignature, name="audit")
auditor = ContextSafe(
dspy.ChainOfThought(AuditSignature),
AuditSignature,
name="audit",
max_llm_calls=self._settings.get_max_llm_calls("audit"),
)
logger.info("Running audit...")

with SignatureContext("audit", self._cost_tracker):
Expand Down
7 changes: 4 additions & 3 deletions src/codespy/agents/reviewer/modules/code_reviewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
from codespy.agents.memory.hippocampus import ContextMemory, Hippocampus
from codespy.agents.reviewer.models import Issue, IssueCategory, ReviewContext, ScopeResult
from codespy.agents.reviewer.modules.helpers import (
MIN_CONFIDENCE,
issues_to_markdown,
make_scope_relative,
resolve_scope_root,
Expand Down Expand Up @@ -238,6 +237,8 @@ async def aforward(
CodeReviewSignature,
tools=tools,
name="code_review",
max_iters=max_iters,
max_llm_calls=self._settings.get_max_llm_calls("code_review"),
)
scoped = make_scope_relative(scope)
logger.info(
Expand Down Expand Up @@ -268,7 +269,7 @@ async def aforward(
)
issues = [
issue for issue in (result.issues or [])
if issue.confidence >= MIN_CONFIDENCE
if issue.confidence >= self._settings.min_confidence
]
await mem.aend_episode(
get_memory_store(self._settings),
Expand All @@ -285,7 +286,7 @@ async def aforward(
)
issues = [
issue for issue in (result.issues or [])
if issue.confidence >= MIN_CONFIDENCE
if issue.confidence >= self._settings.min_confidence
]
restore_repo_paths(issues, scope.subroot)
all_issues.extend(issues)
Expand Down
Loading
Loading