Skip to content

Commit 486841a

Browse files
author
Arena AI Agent
committed
refactor(architecture): ♻️ implement SOLID principles and Strategy Pattern for experts to maximize code clarity and maintainability
1 parent f2501aa commit 486841a

9 files changed

Lines changed: 219 additions & 143 deletions

File tree

epistemic_forge/experts/__init__.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
from . import claim_expert, dialectic_expert, freelance_expert, kaggle_expert, writing_expert
1+
from . import (
2+
claim_expert,
3+
dialectic_expert,
4+
freelance_expert,
5+
kaggle_expert,
6+
writing_expert,
7+
)
28

39
__all__ = [
410
"claim_expert",

epistemic_forge/experts/base.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
"""Abstract Interface for Neuro-Symbolic Experts.
2+
3+
This module enforces the Strategy Pattern (SOLID Principles).
4+
Every expert MUST implement this interface to guarantee uniform execution
5+
and predictable structured outputs within the L2 Conductor.
6+
"""
7+
8+
from abc import ABC, abstractmethod
9+
from typing import Any, Dict
10+
from pydantic import BaseModel
11+
from epistemic_forge.models import ProjectSpec
12+
13+
14+
class EpistemicExpert(ABC):
15+
"""Base class defining the contract for all cognitive experts."""
16+
17+
@property
18+
@abstractmethod
19+
def expert_name(self) -> str:
20+
"""The formal identifier of the expert (e.g., 'RigorSentinel')."""
21+
pass
22+
23+
@abstractmethod
24+
def analyze(self, spec: ProjectSpec, context: Dict[str, Any]) -> BaseModel:
25+
"""
26+
Executes the expert's specific neuro-symbolic logic.
27+
28+
Args:
29+
spec: The user's project specifications and constraints.
30+
context: The accumulated epistemic state (prior claims, history).
31+
32+
Returns:
33+
A strictly typed Pydantic BaseModel representing the expert's conclusion.
34+
"""
35+
pass

epistemic_forge/experts/claim_expert.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,10 @@ def extract_claims(spec: ProjectSpec, instruction: str) -> Dict[str, Any]:
2929
support_c = Claim(
3030
id="C2",
3131
text=f"Working support: a structured approach to «{title}» improves decision quality under uncertainty.",
32-
support=["Decomposition reduces hidden tradeoffs.", "Explicit objections prevent one-sided writing."],
32+
support=[
33+
"Decomposition reduces hidden tradeoffs.",
34+
"Explicit objections prevent one-sided writing.",
35+
],
3336
objections=["Structure without domain data can become cargo-cult rigor."],
3437
confidence=Confidence.POSSIBLE,
3538
tags=["support"],
Lines changed: 40 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,43 @@
1-
"""L2 Epistemic Synthesis Engine: Hegelian Dialectic."""
1+
"""Hegelian Synthesis Expert Implementation."""
2+
3+
from typing import Dict, Any
4+
from pydantic import BaseModel
5+
6+
from epistemic_forge.experts.base import EpistemicExpert
27
from epistemic_forge.models import ProjectSpec, HegelianDialecticOutput
38
from epistemic_forge.llm import generate_structured
4-
from typing import Dict, Any
59

6-
def run_dialectic(spec: ProjectSpec, claims_bundle: Dict[str, Any]) -> Dict[str, Any]:
7-
"""Execute Hegelian Synthesis to destroy weak assumptions."""
8-
thesis = spec.question
9-
10-
messages = [
11-
{"role": "system", "content": "You are a ruthless Hegelian philosopher and logician. Your goal is to take a premise, construct the most devastating 'Steelman' antithesis possible, and forge a synthesis that represents the nuanced truth."},
12-
{"role": "user", "content": f"Core Premise/Thesis: {thesis}\nProject Domain: {spec.domain.value}\nDestroy this premise with logic, then synthesize."}
13-
]
14-
15-
# Neuro-Symbolic Call: Forcing GPT to return the strict Hegelian schema
16-
result: HegelianDialecticOutput = generate_structured(
17-
messages=messages,
18-
response_model=HegelianDialecticOutput,
19-
model="gpt-4o-mini" # Cost-aware baseline
20-
)
21-
22-
return {
23-
"thesis": thesis,
24-
"antithesis": result.steelmanned_antithesis,
25-
"synthesis": result.synthesis_resolution,
26-
"open_questions": result.remaining_uncertainties,
27-
}
10+
11+
class HegelianExpert(EpistemicExpert):
12+
"""Applies Hegelian dialectic (Thesis -> Antithesis -> Synthesis) to premises."""
13+
14+
@property
15+
def expert_name(self) -> str:
16+
return "Hegelian_Dialectic_Engine"
17+
18+
def analyze(
19+
self, spec: ProjectSpec, context: Dict[str, Any]
20+
) -> HegelianDialecticOutput:
21+
"""Synthesizes the core question by forcing a steelmanned antithesis."""
22+
messages = [
23+
{
24+
"role": "system",
25+
"content": (
26+
"You are a ruthless Hegelian philosopher. Take the user's premise, "
27+
"construct the most devastating 'Steelman' antithesis possible, "
28+
"and forge a synthesis that represents the nuanced truth."
29+
),
30+
},
31+
{
32+
"role": "user",
33+
"content": f"Core Thesis: {spec.question}\nDomain: {spec.domain}\nDestroy and synthesize.",
34+
},
35+
]
36+
37+
# The universal Hermes router handles the LLM complexity internally
38+
return generate_structured(
39+
messages=messages,
40+
response_model=HegelianDialecticOutput,
41+
model=spec.target_model,
42+
api_base=spec.api_base,
43+
)

epistemic_forge/experts/freelance_expert.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
from epistemic_forge.models import ProjectSpec
88

99

10-
def build_client_pack(spec: ProjectSpec, claims_bundle: Dict[str, Any]) -> Dict[str, Any]:
10+
def build_client_pack(
11+
spec: ProjectSpec, claims_bundle: Dict[str, Any]
12+
) -> Dict[str, Any]:
1113
return {
1214
"client_brief": {
1315
"goal": spec.question,
Lines changed: 38 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,41 @@
1-
"""L2 Epistemic Synthesis Engine: Leakage & Rigor Sentinel."""
1+
"""Data Leakage and Scientific Rigor Expert Implementation."""
2+
3+
from typing import Dict, Any
4+
from pydantic import BaseModel
5+
6+
from epistemic_forge.experts.base import EpistemicExpert
27
from epistemic_forge.models import ProjectSpec, RigorSentinelOutput
38
from epistemic_forge.llm import generate_structured
4-
from typing import Dict, Any
59

6-
def build_competition_kit(spec: ProjectSpec, claims_bundle: Dict[str, Any], skills: list) -> Dict[str, Any]:
7-
"""Audit the premise for epistemic blind spots and target leakage."""
8-
9-
messages = [
10-
{"role": "system", "content": "You are a Grandmaster ML Auditor. Your job is to look at a proposed research or data problem and identify 'target leakage'—where the answer is implicitly baked into the question—and propose strict falsification metrics."},
11-
{"role": "user", "content": f"Problem Statement: {spec.question}\nKeywords: {spec.keywords}\nFind the blind spots and establish a robust baseline."}
12-
]
13-
14-
# Neuro-Symbolic Call
15-
result: RigorSentinelOutput = generate_structured(
16-
messages=messages,
17-
response_model=RigorSentinelOutput,
18-
model="gpt-4o-mini"
19-
)
20-
21-
return {
22-
"checklist": result.epistemic_blind_spots,
23-
"metric_alignment": result.falsification_metric,
24-
"baseline_architecture": result.robust_baseline,
25-
"experiment_log_template": {
26-
"status": "Audited by Rigor Sentinel",
27-
"notes": "Ensure no data from the future is used."
28-
}
29-
}
10+
11+
class RigorSentinelExpert(EpistemicExpert):
12+
"""Audits data science/research premises for methodological flaws and leakage."""
13+
14+
@property
15+
def expert_name(self) -> str:
16+
return "Rigor_And_Leakage_Sentinel"
17+
18+
def analyze(
19+
self, spec: ProjectSpec, context: Dict[str, Any]
20+
) -> RigorSentinelOutput:
21+
"""Identifies target leakage and establishes strict falsification metrics."""
22+
messages = [
23+
{
24+
"role": "system",
25+
"content": (
26+
"You are a Grandmaster ML Auditor. Identify 'target leakage' "
27+
"or hidden assumptions in the premise, and propose strict falsification metrics."
28+
),
29+
},
30+
{
31+
"role": "user",
32+
"content": f"Problem Statement: {spec.question}\nKeywords: {spec.keywords}\nFind blind spots.",
33+
},
34+
]
35+
36+
return generate_structured(
37+
messages=messages,
38+
response_model=RigorSentinelOutput,
39+
model=spec.target_model,
40+
api_base=spec.api_base,
41+
)

epistemic_forge/experts/semitic_expert.py

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,32 @@
11
"""L2 Epistemic Synthesis Engine: Semitic NLP & Arabic Logic Expert."""
2+
23
from epistemic_forge.models import ProjectSpec, HegelianDialecticOutput
34
from epistemic_forge.llm import generate_structured
45
from typing import Dict, Any
56

6-
def run_semitic_dialectic(spec: ProjectSpec, claims_bundle: Dict[str, Any]) -> Dict[str, Any]:
7+
8+
def run_semitic_dialectic(
9+
spec: ProjectSpec, claims_bundle: Dict[str, Any]
10+
) -> Dict[str, Any]:
711
"""Execute dialectic reasoning specifically optimized for Arabic/Semitic morphological logic."""
812
thesis = spec.question
9-
13+
1014
messages = [
11-
{"role": "system", "content": "You are a master of Semitic NLP, Arabic logic, and the Scattering Law. Your goal is to analyze the premise in its native Arabic/Semitic context, find morphological or logical blind spots, and synthesize a culturally and logically grounded truth."},
12-
{"role": "user", "content": f"الفرضية الأساسية (Thesis): {thesis}\n\nقم بنسف هذه الفرضية بالمنطق السامي/العربي، ثم استخرج الحقيقة المركبة."}
15+
{
16+
"role": "system",
17+
"content": "You are a master of Semitic NLP, Arabic logic, and the Scattering Law. Your goal is to analyze the premise in its native Arabic/Semitic context, find morphological or logical blind spots, and synthesize a culturally and logically grounded truth.",
18+
},
19+
{
20+
"role": "user",
21+
"content": f"الفرضية الأساسية (Thesis): {thesis}\n\nقم بنسف هذه الفرضية بالمنطق السامي/العربي، ثم استخرج الحقيقة المركبة.",
22+
},
1323
]
14-
24+
1525
# Using Claude 3.5 Sonnet or GPT-4o which are great at Arabic logic
1626
result: HegelianDialecticOutput = generate_structured(
17-
messages=messages,
18-
response_model=HegelianDialecticOutput,
19-
model="gpt-4o"
27+
messages=messages, response_model=HegelianDialecticOutput, model="gpt-4o"
2028
)
21-
29+
2230
return {
2331
"thesis": thesis,
2432
"antithesis_arabic": result.steelmanned_antithesis,
Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,35 @@
11
"""L2 Epistemic Synthesis Engine: Chain of Density Architect."""
2+
23
from epistemic_forge.models import ProjectSpec, ChainOfDensityOutput
34
from epistemic_forge.llm import generate_structured
45
from typing import Dict, Any
56

6-
def outline_and_draft(spec: ProjectSpec, claims_bundle: Dict[str, Any], instruction: str) -> Dict[str, Any]:
7+
8+
def outline_and_draft(
9+
spec: ProjectSpec, claims_bundle: Dict[str, Any], instruction: str
10+
) -> Dict[str, Any]:
711
"""Compress the dialectic into a hyper-dense, falsifiable artifact."""
8-
12+
913
# Gather previous context to compress
10-
raw_context = f"Question: {spec.question}\nClaims: {claims_bundle.get('claims', [])}"
11-
14+
raw_context = (
15+
f"Question: {spec.question}\nClaims: {claims_bundle.get('claims', [])}"
16+
)
17+
1218
messages = [
13-
{"role": "system", "content": "You are a Chain-of-Density Architect. Your goal is to take raw thoughts and compress them into a highly dense, signal-rich artifact stripped of all rhetorical fluff and confident mush. Every word must carry epistemic weight."},
14-
{"role": "user", "content": f"Raw Context:\n{raw_context}\nCompress this."}
19+
{
20+
"role": "system",
21+
"content": "You are a Chain-of-Density Architect. Your goal is to take raw thoughts and compress them into a highly dense, signal-rich artifact stripped of all rhetorical fluff and confident mush. Every word must carry epistemic weight.",
22+
},
23+
{"role": "user", "content": f"Raw Context:\n{raw_context}\nCompress this."},
1524
]
16-
25+
1726
# Neuro-Symbolic Call
1827
result: ChainOfDensityOutput = generate_structured(
19-
messages=messages,
20-
response_model=ChainOfDensityOutput,
21-
model="gpt-4o-mini"
28+
messages=messages, response_model=ChainOfDensityOutput, model="gpt-4o-mini"
2229
)
23-
30+
2431
return {
2532
"density_score": result.information_density_score,
2633
"draft_markdown": f"# Crystallized Artifact\n\n{result.crystallized_claim}\n\n*Density Score: {result.information_density_score}/10*",
27-
"outline": ["Crystallized Core"]
34+
"outline": ["Crystallized Core"],
2835
}

0 commit comments

Comments
 (0)