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
26 changes: 25 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,31 @@ Versioning follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

---

## [v1.2.8] — 2026-03-27
## [v1.3.1] — 2026-03-28

### Added

- **Cross-Domain Evaluation Suite (`eval/`, `src/post_sim_artifacts.py`)**: introduced 11 new evaluation question types including **ZD_RESOLUTION**, **SF_RISK**, and **INVOICE_SLA**. The framework now includes specialized scorers for financial credits, NPS drivers, and PR review verdicts to validate RAG performance across the entire business logic stack.
- **Reactive Customer Reply Loop (`src/external_email_ingest.py`)**: implemented a probabilistic customer response system. The simulation now classifies inbound emails (Complaints vs. Feature Requests) and allows customers to autonomously advance **Salesforce Opportunity stages** based on the quality of outbound sales replies.
- **Concurrent Embedding Engine (`src/embed_worker.py`)**: replaced the serial background worker with a `ThreadPoolExecutor`-based system. This supports high-throughput embedding via **Infinity** (up to 16 concurrent calls) while maintaining causal consistency through a new `drain()` synchronization mechanism.
- **Advanced Retrieval Architectures (`eval/eval_e2e.py`)**: added support for **Reciprocal Rank Fusion (RRF)** and **Graph-Augmented Retrievers**, allowing the evaluation agent to fuse BM25 lexical search with dense vector embeddings and 2-hop artifact expansion.

### Changed

- **Stateful Persona Architecture (`src/utils/persona_utils.py`)**: refactored persona generation into a centralized `PersonaUtils` singleton. Voice cards now inject **"CRM Pressure" hints**, causing internal employees to exhibit higher stress and terser communication when they own at-risk deals or urgent Zendesk tickets.
- **CRM-Driven Graph Dynamics (`src/graph_dynamics.py`, `src/flow.py`)**: integrated live Salesforce/Zendesk telemetry into the social graph. Edge weights between liaisons and external contacts now fluctuate based on account sentiment, and stress propagates through the organization when "lighthouse" customers flag risks.
- **Theme-Triggered Incidents (`src/flow.py`)**: updated the incident generator to be reactive to the daily planning theme. Stability "collisions" are now more likely to fire if the daily plan involves high-risk activities like "migrations" or "refactors" identified via keyword triggers.
- **HyDE Query Rewriting (`src/memory.py`)**: migrated the `recall_with_rewrite` logic from a generic callable to a native **Bedrock-hosted Llama 3.3** implementation for more robust hypothetical document generation.

### Fixed

- **PR Review Approval Logic (`src/normal_day.py`)**: fixed a bug where engineers would requested changes indefinitely by implementing "Review Round" guidance, forcing approvals after 3 rounds unless critical bugs are present.
- **Causal Chain Integrity (`src/external_email_ingest.py`)**: corrected an issue where inbound vendor emails were orphaned; all external communications are now properly rooted in a `CausalChainHandler` and tracked through downstream JIRA/Slack artifacts.
- **Cleanup**: deleted the legacy `src/email_gen.py` script in favor of the live, event-driven ingestor system.

---

## [v1.3.0] — 2026-03-27

### Added

Expand Down
61 changes: 58 additions & 3 deletions eval/eval_e2e.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,14 @@

logger = logging.getLogger("orgforge.eval_e2e")

# Lazy import so the module is optional when only using built-in retrievers.
try:
from retrieval_extensions import RRFRetriever, GraphAugmentedRetriever

_EXTENSIONS_AVAILABLE = True
except ImportError:
_EXTENSIONS_AVAILABLE = False

# ── Constants ─────────────────────────────────────────────────────────────────

HF_DATASET_ID = os.environ.get("HF_DATASET_ID", "INSERT_ID_HERE")
Expand Down Expand Up @@ -354,6 +362,7 @@ def retrieve(self, query: str, top_k: int = TOP_K) -> List[str]:


def build_retriever(name: str, region: str = "us-east-1") -> Retriever:
# ── original retrievers ────────────────────────────────────────────────────
if name == "bm25":
return BM25Retriever()
if name == "cohere":
Expand All @@ -362,8 +371,36 @@ def build_retriever(name: str, region: str = "us-east-1") -> Retriever:
return BedrockCohereRetriever(region=region)
if name == "openai":
return OpenAIRetriever()

# ── RRF and Graph retrievers (require retrieval_extensions.py) ─────────────
if not _EXTENSIONS_AVAILABLE:
raise SystemExit(
f"retriever={name!r} requires retrieval_extensions.py in the same "
"directory. Make sure that file is present and importable."
)

# RRF: fuse BM25 + dense retriever
if name == "rrf":
return RRFRetriever([BM25Retriever(), CohereRetriever()])
if name == "rrf-openai":
return RRFRetriever([BM25Retriever(), OpenAIRetriever()])
if name == "rrf-bedrock":
return RRFRetriever([BM25Retriever(), BedrockCohereRetriever(region=region)])

# Graph-Augmented: expand any base retriever along the artifact graph
if name == "graph-bm25":
return GraphAugmentedRetriever(BM25Retriever())
if name == "graph-cohere":
return GraphAugmentedRetriever(CohereRetriever())
if name == "graph-rrf":
base = RRFRetriever([BM25Retriever(), CohereRetriever()])
return GraphAugmentedRetriever(base)

raise ValueError(
f"Unknown retriever: {name!r}. Choose bm25 | cohere | cohere-bedrock | openai"
f"Unknown retriever: {name!r}. "
"Choose bm25 | cohere | cohere-bedrock | openai | "
"rrf | rrf-openai | rrf-bedrock | "
"graph-bm25 | graph-cohere | graph-rrf"
)


Expand Down Expand Up @@ -1163,9 +1200,27 @@ def _parse_args() -> argparse.Namespace:
)
p.add_argument(
"--retriever",
choices=["bm25", "cohere", "cohere-bedrock", "openai"],
choices=[
"bm25",
"cohere",
"cohere-bedrock",
"openai",
# Reciprocal Rank Fusion
"rrf",
"rrf-openai",
"rrf-bedrock",
# Graph-Augmented (1-2 hop artifact expansion)
"graph-bm25",
"graph-cohere",
"graph-rrf",
],
default="bm25",
help="Retriever to use (default: bm25). cohere-bedrock uses Bedrock credentials.",
help=(
"Retriever to use (default: bm25).\n"
" bm25 / cohere / cohere-bedrock / openai — single retrievers\n"
" rrf / rrf-openai / rrf-bedrock — BM25 + dense fusion (RRF)\n"
" graph-bm25 / graph-cohere / graph-rrf — graph-augmented expansion"
),
)
p.add_argument(
"--generator",
Expand Down
Loading
Loading