Skip to content

Commit 8e6e42e

Browse files
authored
Merge pull request #84 from kayba-ai/cleanup
Clean up imports and remove unused exports from ace and ace_next
2 parents a57fa7a + 7ca5603 commit 8e6e42e

25 files changed

Lines changed: 243 additions & 302 deletions

AGENTS.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ When changes to code alter architecture, add new modules, change public APIs, re
1414

1515
### Project Structure
1616
- `ace/` — core library (skillbook, roles, adapters, integrations, observability)
17-
- `ace_next/` — pipeline-based rewrite (see `docs/ACE_DESIGN.md`)
18-
- `pipeline/` — generic pipeline engine (see `docs/PIPELINE_DESIGN.md`)
17+
- `ace_next/` — pipeline-based rewrite built on top of `pipeline/` (see `docs/ACE_DESIGN.md`)
18+
- `pipeline/` — generic pipeline engine that `ace_next` is built on (see `docs/PIPELINE_DESIGN.md`)
1919
- `tests/` — unit/integration tests (pytest + unittest)
2020
- `examples/` — runnable demos grouped by integration
2121
- `benchmarks/`, `scripts/` — research/evaluation tooling (not shipped to PyPI)

README.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
⭐ Star this repo if you find it useful!
1616

17+
> **🚀 ACE v2 is coming.** We're rebuilding the framework from the ground up — a cleaner architecture, a modular pipeline engine, first-class async support, and a dramatically simpler API. Everything you love about ACE, refined and supercharged. Follow the progress in [`ace_next/`](ace_next/) and [`pipeline/`](pipeline/), or join the [Discord](https://discord.gg/mqCqH7sTyK) to stay in the loop.
18+
1719
---
1820

1921
## What is ACE?
@@ -182,16 +184,14 @@ flowchart LR
182184

183185
## Documentation
184186

185-
- [Quick Start Guide](docs/QUICK_START.md) - Get running in 5 minutes
186-
- [Setup Guide](docs/SETUP_GUIDE.md) - Installation, configuration, providers
187-
- [Integration Guide](docs/INTEGRATION_GUIDE.md) - Add ACE to existing agents
188-
- [API Reference](docs/API_REFERENCE.md) - Complete API documentation
189-
- [Complete Guide to ACE](docs/COMPLETE_GUIDE_TO_ACE.md) - Deep dive into concepts
190-
- [Prompt Engineering](docs/PROMPT_ENGINEERING.md) - Advanced prompt techniques
191-
- [Insight Source Tracing](docs/INSIGHT_SOURCES.md) - Track skill provenance and query origins
192-
- [Agentic System Prompting](examples/agentic-system-prompting/README.md) - Automatically generate prompt improvements from past traces
187+
**📖 [docs.kayba.ai](https://kayba-ai.github.io/agentic-context-engine/latest/)** — Full documentation with guides, API reference, and examples.
188+
189+
Quick links:
190+
- [Quick Start Guide](https://kayba-ai.github.io/agentic-context-engine/latest/getting-started/quickstart/) - Get running in 5 minutes
191+
- [Setup Guide](https://kayba-ai.github.io/agentic-context-engine/latest/getting-started/setup/) - Installation, configuration, providers
192+
- [Integration Guide](https://kayba-ai.github.io/agentic-context-engine/latest/integrations/browser-use/) - Add ACE to existing agents
193+
- [API Reference](https://kayba-ai.github.io/agentic-context-engine/latest/api/) - Complete API documentation
193194
- [Examples](examples/) - Ready-to-run code examples
194-
- [Benchmarks](benchmarks/README.md) - Evaluate ACE performance
195195
- [Changelog](CHANGELOG.md) - Recent changes
196196

197197
---

ace/__init__.py

Lines changed: 16 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from typing import Optional
44
from .skillbook import Skill, Skillbook
55
from .updates import UpdateOperation, UpdateBatch
6-
from .llm import LLMClient, DummyLLMClient, TransformersLLMClient
6+
from .llm import LLMClient, DummyLLMClient
77
from .roles import (
88
Agent,
99
ReplayAgent,
@@ -22,121 +22,56 @@
2222
TaskEnvironment,
2323
SimpleEnvironment,
2424
EnvironmentResult,
25-
ACEStepResult,
26-
)
27-
from .async_learning import (
28-
LearningTask,
29-
ReflectionResult,
30-
ThreadSafeSkillbook,
31-
AsyncLearningPipeline,
3225
)
26+
from .deduplication import DeduplicationConfig
3327

3428
# Import optional feature detection
35-
from .features import has_opik, has_litellm
36-
37-
# Import observability components if available
38-
if has_opik():
39-
try:
40-
from .observability import OpikIntegration as _OpikIntegration
41-
42-
OpikIntegration: Optional[type] = _OpikIntegration
43-
OBSERVABILITY_AVAILABLE = True
44-
except ImportError:
45-
OpikIntegration: Optional[type] = None # type: ignore
46-
OBSERVABILITY_AVAILABLE = False
47-
else:
48-
OpikIntegration: Optional[type] = None # type: ignore
49-
OBSERVABILITY_AVAILABLE = False
29+
from .features import has_litellm
5030

51-
# Import production LLM clients if available
31+
# Import production LLM client if available
5232
if has_litellm():
5333
try:
5434
from .llm_providers import LiteLLMClient as _LiteLLMClient
5535

5636
LiteLLMClient: Optional[type] = _LiteLLMClient
57-
LITELLM_AVAILABLE = True
5837
except ImportError:
5938
LiteLLMClient: Optional[type] = None # type: ignore
60-
LITELLM_AVAILABLE = False
6139
else:
6240
LiteLLMClient: Optional[type] = None # type: ignore
63-
LITELLM_AVAILABLE = False
6441

65-
# Import Claude Code CLI LLM client (uses subscription auth, no API key needed)
66-
try:
67-
from .llm_providers import (
68-
ClaudeCodeLLMClient as _ClaudeCodeLLMClient,
69-
CLAUDE_CODE_CLI_AVAILABLE as _CLAUDE_CODE_CLI_AVAILABLE,
70-
)
71-
72-
ClaudeCodeLLMClient: Optional[type] = _ClaudeCodeLLMClient
73-
CLAUDE_CODE_CLI_AVAILABLE = _CLAUDE_CODE_CLI_AVAILABLE
74-
except ImportError:
75-
ClaudeCodeLLMClient: Optional[type] = None # type: ignore
76-
CLAUDE_CODE_CLI_AVAILABLE = False
77-
78-
# Import integrations (LiteLLM, browser-use, LangChain, Claude Code, etc.) if available
42+
# Import integrations if available
7943
try:
8044
from .integrations import (
8145
ACELiteLLM as _ACELiteLLM,
8246
ACEAgent as _ACEAgent,
8347
ACELangChain as _ACELangChain,
8448
ACEClaudeCode as _ACEClaudeCode,
8549
wrap_skillbook_context as _wrap_skillbook_context,
86-
BROWSER_USE_AVAILABLE as _BROWSER_USE_AVAILABLE,
87-
LANGCHAIN_AVAILABLE as _LANGCHAIN_AVAILABLE,
88-
CLAUDE_CODE_AVAILABLE as _CLAUDE_CODE_AVAILABLE,
8950
)
9051

9152
ACELiteLLM: Optional[type] = _ACELiteLLM
9253
ACEAgent: Optional[type] = _ACEAgent
9354
ACELangChain: Optional[type] = _ACELangChain
9455
ACEClaudeCode: Optional[type] = _ACEClaudeCode
9556
wrap_skillbook_context: Optional[type] = _wrap_skillbook_context # type: ignore
96-
BROWSER_USE_AVAILABLE = _BROWSER_USE_AVAILABLE
97-
LANGCHAIN_AVAILABLE = _LANGCHAIN_AVAILABLE
98-
CLAUDE_CODE_AVAILABLE = _CLAUDE_CODE_AVAILABLE
9957
except ImportError:
10058
ACELiteLLM: Optional[type] = None # type: ignore
10159
ACEAgent: Optional[type] = None # type: ignore
10260
ACELangChain: Optional[type] = None # type: ignore
10361
ACEClaudeCode: Optional[type] = None # type: ignore
10462
wrap_skillbook_context: Optional[type] = None # type: ignore
105-
BROWSER_USE_AVAILABLE = False
106-
LANGCHAIN_AVAILABLE = False
107-
CLAUDE_CODE_AVAILABLE = False
108-
109-
# Import deduplication module
110-
from .deduplication import (
111-
DeduplicationConfig,
112-
DeduplicationManager,
113-
)
114-
115-
# Import recursive reflector module
116-
from .reflector import (
117-
RecursiveConfig,
118-
RecursiveReflector,
119-
TraceSandbox,
120-
TraceContext,
121-
)
122-
123-
# Import insight source tracing
124-
from .insight_source import InsightSource, TraceReference
125-
126-
# Import unified PromptManager
127-
from .prompt_manager import PromptManager
12863

12964
__all__ = [
130-
# Core components
65+
# Core data types
13166
"Skill",
13267
"Skillbook",
13368
"UpdateOperation",
13469
"UpdateBatch",
70+
# LLM clients
13571
"LLMClient",
13672
"DummyLLMClient",
137-
"TransformersLLMClient",
13873
"LiteLLMClient",
139-
"ClaudeCodeLLMClient", # Claude Code CLI client (subscription auth)
74+
# Roles
14075
"Agent",
14176
"ReplayAgent",
14277
"Reflector",
@@ -145,45 +80,21 @@
14580
"AgentOutput",
14681
"ReflectorOutput",
14782
"SkillManagerOutput",
83+
# Adaptation loops
84+
"ACEBase",
14885
"OfflineACE",
14986
"OnlineACE",
150-
"ACEBase",
15187
"Sample",
15288
"TaskEnvironment",
15389
"SimpleEnvironment",
15490
"EnvironmentResult",
155-
"ACEStepResult",
156-
# Deduplication
91+
# Integrations
92+
"ACELiteLLM",
93+
"ACEAgent",
94+
"ACELangChain",
95+
"ACEClaudeCode",
96+
# Configuration
15797
"DeduplicationConfig",
158-
"DeduplicationManager",
159-
# Recursive reflector
160-
"RecursiveConfig",
161-
"RecursiveReflector",
162-
"TraceSandbox",
163-
"TraceContext",
164-
# Out-of-box integrations
165-
"ACELiteLLM", # LiteLLM integration (quick start)
166-
"ACEAgent", # Browser-use integration
167-
"ACELangChain", # LangChain integration (complex workflows)
168-
"ACEClaudeCode", # Claude Code CLI integration
16998
# Utilities
17099
"wrap_skillbook_context",
171-
# Async learning
172-
"LearningTask",
173-
"ReflectionResult",
174-
"ThreadSafeSkillbook",
175-
"AsyncLearningPipeline",
176-
# Feature flags
177-
"OpikIntegration",
178-
"LITELLM_AVAILABLE",
179-
"CLAUDE_CODE_CLI_AVAILABLE", # Claude Code CLI available
180-
"OBSERVABILITY_AVAILABLE",
181-
"BROWSER_USE_AVAILABLE",
182-
"LANGCHAIN_AVAILABLE",
183-
"CLAUDE_CODE_AVAILABLE",
184-
# Insight source tracing
185-
"InsightSource",
186-
"TraceReference",
187-
# Prompt management
188-
"PromptManager",
189100
]

ace/integrations/claude_code/learner.py

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -33,21 +33,41 @@
3333
from pathlib import Path
3434
from typing import List, Optional, Any
3535

36-
from dotenv import load_dotenv
37-
from tenacity import (
38-
retry,
39-
stop_after_attempt,
40-
wait_exponential,
41-
)
36+
try:
37+
from dotenv import load_dotenv
38+
except ImportError:
39+
load_dotenv = None # type: ignore[assignment]
40+
41+
try:
42+
from tenacity import (
43+
retry,
44+
stop_after_attempt,
45+
wait_exponential,
46+
)
47+
except ImportError:
48+
# Fallback: no-op retry decorator when tenacity is not installed
49+
def retry(**kwargs): # type: ignore[misc]
50+
def decorator(func):
51+
return func
52+
53+
return decorator
54+
55+
def stop_after_attempt(n): # type: ignore[misc]
56+
return n
57+
58+
def wait_exponential(**kwargs): # type: ignore[misc]
59+
return None
60+
4261

4362
# Load .env file from ~/.ace/.env or current directory
44-
_env_paths = [
45-
Path.home() / ".ace" / ".env",
46-
Path.cwd() / ".env",
47-
]
48-
for _env_path in _env_paths:
49-
if _env_path.exists():
50-
load_dotenv(_env_path)
63+
if load_dotenv is not None:
64+
_env_paths = [
65+
Path.home() / ".ace" / ".env",
66+
Path.cwd() / ".env",
67+
]
68+
for _env_path in _env_paths:
69+
if _env_path.exists():
70+
load_dotenv(_env_path)
5171
break
5272

5373
from ...skillbook import Skillbook

ace/llm_providers/instructor_client.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,15 @@
1212

1313
logger = logging.getLogger(__name__)
1414

15-
# Instructor is a core dependency - always available
16-
import instructor
1715
from litellm import completion
1816

17+
try:
18+
import instructor
19+
20+
INSTRUCTOR_AVAILABLE = True
21+
except ImportError:
22+
INSTRUCTOR_AVAILABLE = False
23+
1924
T = TypeVar("T", bound=BaseModel)
2025

2126

@@ -51,7 +56,7 @@ class InstructorClient:
5156
def __init__(
5257
self,
5358
llm: LLMClient,
54-
mode=instructor.Mode.MD_JSON,
59+
mode=None,
5560
max_retries: int = 3,
5661
):
5762
"""
@@ -63,9 +68,14 @@ def __init__(
6368
MD_JSON works with all models including local ones; use Mode.JSON for OpenAI structured outputs
6469
max_retries: Maximum validation retries
6570
"""
71+
if not INSTRUCTOR_AVAILABLE:
72+
raise ImportError(
73+
"instructor is required for InstructorClient. "
74+
"Install it with: pip install ace-framework[instructor]"
75+
)
6676

6777
self.llm = llm
68-
self.mode = mode
78+
self.mode = mode if mode is not None else instructor.Mode.MD_JSON
6979
self.max_retries = max_retries
7080

7181
# Patch LiteLLM completion function with Instructor
@@ -212,7 +222,7 @@ def complete_structured(
212222

213223

214224
def wrap_with_instructor(
215-
llm: LLMClient, mode=instructor.Mode.MD_JSON, max_retries: int = 3
225+
llm: LLMClient, mode=None, max_retries: int = 3
216226
) -> InstructorClient:
217227
"""
218228
Convenience function to wrap an LLM client with Instructor capabilities.

ace/roles.py

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -191,9 +191,15 @@ def __init__(
191191
if hasattr(llm, "complete_structured"):
192192
self.llm = llm
193193
else:
194-
from .llm_providers.instructor_client import wrap_with_instructor
194+
from .llm_providers.instructor_client import (
195+
INSTRUCTOR_AVAILABLE,
196+
wrap_with_instructor,
197+
)
195198

196-
self.llm = wrap_with_instructor(llm, max_retries=max_retries) # type: ignore[assignment]
199+
if INSTRUCTOR_AVAILABLE:
200+
self.llm = wrap_with_instructor(llm, max_retries=max_retries) # type: ignore[assignment]
201+
else:
202+
self.llm = llm
197203

198204
self.prompt_template = prompt_template
199205
self.max_retries = max_retries
@@ -575,9 +581,15 @@ def __init__(
575581
if hasattr(llm, "complete_structured"):
576582
self.llm = llm
577583
else:
578-
from .llm_providers.instructor_client import wrap_with_instructor
584+
from .llm_providers.instructor_client import (
585+
INSTRUCTOR_AVAILABLE,
586+
wrap_with_instructor,
587+
)
579588

580-
self.llm = wrap_with_instructor(llm, max_retries=max_retries) # type: ignore[assignment]
589+
if INSTRUCTOR_AVAILABLE:
590+
self.llm = wrap_with_instructor(llm, max_retries=max_retries) # type: ignore[assignment]
591+
else:
592+
self.llm = llm
581593

582594
self.prompt_template = prompt_template
583595
self.mode = mode
@@ -802,9 +814,15 @@ def __init__(
802814
if hasattr(llm, "complete_structured"):
803815
self.llm = llm
804816
else:
805-
from .llm_providers.instructor_client import wrap_with_instructor
817+
from .llm_providers.instructor_client import (
818+
INSTRUCTOR_AVAILABLE,
819+
wrap_with_instructor,
820+
)
806821

807-
self.llm = wrap_with_instructor(llm, max_retries=max_retries) # type: ignore[assignment]
822+
if INSTRUCTOR_AVAILABLE:
823+
self.llm = wrap_with_instructor(llm, max_retries=max_retries) # type: ignore[assignment]
824+
else:
825+
self.llm = llm
808826

809827
self.prompt_template = prompt_template
810828
self.max_retries = max_retries

0 commit comments

Comments
 (0)