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
10 changes: 1 addition & 9 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -210,10 +210,8 @@ DEFAULT_MODEL=anthropic/claude-opus-4-6
# MEMORY_PG0_PORT=5432
# MEMORY_PG0_DATA_DIR=~/.cache/codespy/pg0 # default; persists on Docker-mounted codespy-cache volume

# Reflection defaults — overridable per-signature via <SIGNATURE>_MEMORY_*
# Memory default — overridable per-signature via <SIGNATURE>_MEMORY_*
# MEMORY_DEFAULT_ENABLED=false
# 0 = reflect once at end_episode
# MEMORY_DEFAULT_MAX_REFLECTS=0

# Whether to compact trajectories (head+tail bounding) before distillation.
# When false, the full trajectory is sent to the Distiller and ContextSafe
Expand Down Expand Up @@ -299,7 +297,6 @@ DEFAULT_MODEL=anthropic/claude-opus-4-6
# - TEMPERATURE (float) - Must be 1 while reasoning is enabled
# - MAX_TOKENS (integer) - Output token budget (unset -> DEFAULT_MAX_TOKENS)
# - MEMORY_ENABLED (true/false) - Hippocampus memory (unset -> MEMORY_DEFAULT_ENABLED)
# - MEMORY_MAX_REFLECTS (integer) - Max mid-run reflections (0 = reflect once at end)

# Examples:
# CODE_REVIEW_ENABLED=true
Expand All @@ -310,33 +307,28 @@ DEFAULT_MODEL=anthropic/claude-opus-4-6
# CODE_REVIEW_MAX_TOKENS=32000

# CODE_REVIEW_MEMORY_ENABLED=true
# CODE_REVIEW_MEMORY_MAX_REFLECTS=1

# SUPPLY_CHAIN_ENABLED=true
# When true: scans ALL artifacts (Dockerfiles, etc.) and manifests
# When false (default): only scans artifacts/manifests modified in the MR
# SUPPLY_CHAIN_SCAN_UNCHANGED=false
# SUPPLY_CHAIN_MEMORY_ENABLED=true
# SUPPLY_CHAIN_MEMORY_MAX_REFLECTS=1

# DOC_ENABLED=true
# DOC_MAX_ITERS=1
# DOC_MAX_LLM_CALLS=2
# DOC_MODEL=anthropic/claude-sonnet-4-5-20250929
# DOC_MEMORY_ENABLED=true
# DOC_MEMORY_MAX_REFLECTS=1

# SCOPE_ENABLED=true
# SCOPE_MAX_ITERS=4
# SCOPE_REASONING_EFFORT=low
# SCOPE_MAX_TOKENS=32000
# SCOPE_MEMORY_ENABLED=true
# SCOPE_MEMORY_MAX_REFLECTS=1

# SUMMARY_ENABLED=true
# SUMMARY_MAX_ITERS=1
# SUMMARY_MAX_LLM_CALLS=2
# SUMMARY_MODEL=anthropic/claude-haiku-4-5-20251001
# SUMMARY_MEMORY_ENABLED=true
# SUMMARY_MEMORY_MAX_REFLECTS=1

17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,23 @@

## [Unreleased]

## [1.2.3] - 2026-09-16

### Changed
- **BREAKING**: `Hippocampus` refactored from wrapper to composable component
- `Hippocampus` no longer inherits from `dspy.Module` or accepts a `module` parameter
- Removed `forward()`, `aforward()` — agents call their own modules and pass `hippo.context_memory`
- Added `observe(result)` / `aobserve(result)` to feed agent results back for reflection
- Added `context_memory` read-only property
- Added `bind_topics(topics, topic_ids)` public method (replaces direct `_topic_ids` access)
- Added `inject_context_memory(module)` standalone utility for signature injection
- All 6 review agents updated to composable pattern
- **Internal**: Flattened `hippocampus/modules/` directory structure
- Moved `distiller.py` and `cartographer.py` from `hippocampus/modules/` to `hippocampus/` package root
- Removed `hippocampus/modules/__init__.py` and deleted `modules/` subdirectory
- Updated imports in `hippocampus.py` and `hippocampus/__init__.py` to reference new locations
- No external API changes — imports through `hippocampus/__init__.py` remain unchanged

## [1.2.2] - 2026-09-16

### Changed
Expand Down
7 changes: 0 additions & 7 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -340,11 +340,6 @@ inputs:
description: 'Bank ID scoping all memory data (e.g., project name or agent name). Defaults to "codespy".'
required: false

memory-max-reflects:
description: 'Max online reflections per agent call (0 = batch-only, default: 0)'
required: false
default: '0'

memory-distiller-model:
description: 'Model for the Distiller reflection module (smaller model recommended)'
required: false
Expand Down Expand Up @@ -553,7 +548,6 @@ runs:
MEMORY_POSTGRES_DATABASE: ${{ inputs.memory-postgres-database }}
MEMORY_POSTGRES_SCHEMA: ${{ inputs.memory-postgres-schema }}
MEMORY_BANK_ID: ${{ inputs.memory-bank-id }}
MEMORY_DEFAULT_MAX_REFLECTS: ${{ inputs.memory-max-reflects }}
MEMORY_DISTILLER_MODEL: ${{ inputs.memory-distiller-model }}
MEMORY_DISTILLER_REASONING_EFFORT: ${{ inputs.memory-distiller-reasoning-effort }}
MEMORY_DISTILLER_TEMPERATURE: ${{ inputs.memory-distiller-temperature }}
Expand Down Expand Up @@ -663,7 +657,6 @@ runs:
[ -n "$MEMORY_POSTGRES_DATABASE" ] && DOCKER_ARGS="$DOCKER_ARGS -e MEMORY_POSTGRES_DATABASE"
[ -n "$MEMORY_POSTGRES_SCHEMA" ] && DOCKER_ARGS="$DOCKER_ARGS -e MEMORY_POSTGRES_SCHEMA"
[ -n "$MEMORY_BANK_ID" ] && DOCKER_ARGS="$DOCKER_ARGS -e MEMORY_BANK_ID"
[ -n "$MEMORY_DEFAULT_MAX_REFLECTS" ] && DOCKER_ARGS="$DOCKER_ARGS -e MEMORY_DEFAULT_MAX_REFLECTS"
[ -n "$MEMORY_DISTILLER_MODEL" ] && DOCKER_ARGS="$DOCKER_ARGS -e MEMORY_DISTILLER_MODEL"
[ -n "$MEMORY_DISTILLER_REASONING_EFFORT" ] && DOCKER_ARGS="$DOCKER_ARGS -e MEMORY_DISTILLER_REASONING_EFFORT"
[ -n "$MEMORY_DISTILLER_TEMPERATURE" ] && DOCKER_ARGS="$DOCKER_ARGS -e MEMORY_DISTILLER_TEMPERATURE"
Expand Down
9 changes: 1 addition & 8 deletions codespy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,8 @@ memory:
# or agent name. When unset, auto-generated from hostname.
bank_id: null # MEMORY_BANK_ID

# Reflection defaults — overridable per-signature via signatures.<name>.memory
# Memory default — overridable per-signature via signatures.<name>.memory
default_enabled: false # MEMORY_DEFAULT_ENABLED
default_max_reflects: 0 # MEMORY_DEFAULT_MAX_REFLECTS (0 = reflect once at end_episode)

# Four independent token budgets, from most to least cost-sensitive:
#
Expand Down Expand Up @@ -250,7 +249,6 @@ signatures:
# When false (default): only scans artifacts/manifests that were modified in the MR
memory:
enabled: null # SUPPLY_CHAIN_MEMORY_ENABLED (null -> memory.default_enabled)
max_reflects: null # SUPPLY_CHAIN_MEMORY_MAX_REFLECTS

# Code Reviewer signature (bugs, security, removed defensive code, code smells)
# Unified code review: bugs, security vulnerabilities, and code smells in a single agent pass per scope
Expand All @@ -264,7 +262,6 @@ signatures:
max_tokens: null # CODE_REVIEW_MAX_TOKENS
memory:
enabled: null # CODE_REVIEW_MEMORY_ENABLED (null -> memory.default_enabled)
max_reflects: null # CODE_REVIEW_MEMORY_MAX_REFLECTS

# Documentation Reviewer signature (compares patches against extracted documentation)
# Note: doc extraction is now deterministic (no LLM) — see doc_extractor.py
Expand All @@ -278,7 +275,6 @@ signatures:
max_tokens: null # DOC_MAX_TOKENS
memory:
enabled: null # DOC_MEMORY_ENABLED (null -> memory.default_enabled)
max_reflects: null # DOC_MEMORY_MAX_REFLECTS

# Scope Identifier signature
scope:
Expand All @@ -291,7 +287,6 @@ signatures:
max_tokens: null # SCOPE_MAX_TOKENS
memory:
enabled: null # SCOPE_MEMORY_ENABLED (null -> memory.default_enabled)
max_reflects: null # SCOPE_MEMORY_MAX_REFLECTS

# Summarizer signature
summary:
Expand All @@ -304,7 +299,6 @@ signatures:
max_tokens: null # SUMMARY_MAX_TOKENS
memory:
enabled: true # SUMMARY_MEMORY_ENABLED (null -> memory.default_enabled)
max_reflects: null # SUMMARY_MEMORY_MAX_REFLECTS

# Auditor signature (quality assessment + recommendation after all reviews)
audit:
Expand All @@ -317,7 +311,6 @@ signatures:
max_tokens: null # AUDIT_MAX_TOKENS
memory:
enabled: null # AUDIT_MEMORY_ENABLED (null -> memory.default_enabled)
max_reflects: null # AUDIT_MEMORY_MAX_REFLECTS

# ============================================================================
# OUTPUT
Expand Down
1 change: 0 additions & 1 deletion docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,6 @@ Brief overview:
| pg0 port | `MEMORY_PG0_PORT` | auto | pg0-embedded port (local dev) |
| pg0 data dir | `MEMORY_PG0_DATA_DIR` | — | pg0-embedded data directory (local dev) |
| Default enabled | `MEMORY_DEFAULT_ENABLED` | `false` | Enable memory globally |
| Max reflects | `MEMORY_DEFAULT_MAX_REFLECTS` | `0` | Reflection iterations (0 = once at end) |
| Context memory tokens | `MEMORY_MAX_CONTEXT_MEMORY_TOKENS` | `16384` | Ceiling on persisted context memory |
| Observation tokens | `MEMORY_MAX_CONTEXT_ITEM_TOKENS` | `512` | Soft per-observation token limit |
| Trajectory tokens | `MEMORY_MAX_TRAJECTORY_TOKENS` | `16384` | Cap on trajectory fed to Distiller |
Expand Down
6 changes: 1 addition & 5 deletions docs/memory.md
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,6 @@ The Distiller also tags each existing context memory observation with an `Observ

These tags inform the Cartographer's edit decisions.

Reflection iterates `max_reflects` times (0 = reflect once at end_episode).

## Token Budgets

| Budget | Env Var | Default | Purpose |
Expand Down Expand Up @@ -215,7 +213,6 @@ Observation capacity ≈ context_memory_tokens / observation_tokens (16384/512 =
| `MEMORY_PG0_DATA_DIR` | `memory.pg0.data_dir` | — | Custom data directory for pg0-embedded |
| `MEMORY_BANK_ID` | `memory.bank_id` | `codespy` | Scopes all memory data |
| `MEMORY_DEFAULT_ENABLED` | `memory.default_enabled` | `false` | Enable memory globally |
| `MEMORY_DEFAULT_MAX_REFLECTS` | `memory.default_max_reflects` | `0` | Reflection iterations |
| `MEMORY_COMPACT_TRAJECTORY` | `memory.compact_trajectory` | `true` | Apply head+tail trajectory bounding before distillation |

### Reflection Module LLM Overrides
Expand All @@ -232,9 +229,8 @@ Each signature's `memory:` block in YAML (or `<SIGNATURE>_MEMORY_*` env vars):
| Setting | Env Var Suffix | Description |
|---------|---------------|-------------|
| enabled | `_MEMORY_ENABLED` | Enable/disable memory for this signature |
| max_reflects | `_MEMORY_MAX_REFLECTS` | Override reflection count |

Example: `CODE_REVIEW_MEMORY_ENABLED=true` or `SUMMARY_MEMORY_MAX_REFLECTS=2`
Example: `CODE_REVIEW_MEMORY_ENABLED=true`

See [Configuration](configuration.md#recommended-model-strategy) for recommended reflection models.

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.2.2"
version = "1.2.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.2.2"
__version__ = "1.2.3"
6 changes: 3 additions & 3 deletions src/codespy/agents/context_safe.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class ContextSafe(dspy.Module):
- Try/catch: if the inner module raises a context overflow error (unknown
models where pre-flight can't estimate), catches it and retries with RLM.

Transparent to Hippocampus — delegates .signature to inner module.
Transparent to inject_context_memory — delegates .signature to inner module.
"""

def __init__(
Expand Down Expand Up @@ -116,7 +116,7 @@ def forward(self, **kwargs) -> dspy.Prediction:
return self._create_rlm_fallback()(**kwargs)

async def aforward(self, **kwargs) -> dspy.Prediction:
"""Async path — used by code_review, scope, supply_chain via Hippocampus.aforward."""
"""Async path — used by code_review, scope, supply_chain, doc via agent.acall()."""
should_fallback, reason = self._should_use_rlm(kwargs)
if should_fallback:
logger.warning(
Expand Down Expand Up @@ -186,7 +186,7 @@ def _should_use_rlm(self, kwargs: dict) -> tuple[bool, str]:
return False, ""

def _get_current_signature(self):
"""Get current signature (may include context_memory if Hippocampus modified it)."""
"""Get current signature (may include context_memory if inject_context_memory was called)."""
sig = getattr(self.module, "signature", None)
if sig is not None:
return sig
Expand Down
10 changes: 7 additions & 3 deletions src/codespy/agents/memory/hippocampus/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,12 @@
join_episode_saves,
submit_episode_save,
)
from codespy.agents.memory.hippocampus.hippocampus import Hippocampus
from codespy.agents.memory.hippocampus.modules.cartographer import Cartographer, CartographerSig
from codespy.agents.memory.hippocampus.modules.distiller import Distiller, DistillerSig
from codespy.agents.memory.hippocampus.hippocampus import (
Hippocampus,
inject_context_memory,
)
from codespy.agents.memory.hippocampus.cartographer import Cartographer, CartographerSig
from codespy.agents.memory.hippocampus.distiller import Distiller, DistillerSig

__all__ = [
"CacheCandidate",
Expand All @@ -39,6 +42,7 @@
"SectionName",
"Topic",
"compute_common_ancestor_topic_id",
"inject_context_memory",
"join_episode_saves",
"make_topic_id",
"submit_episode_save",
Expand Down
Loading
Loading