Spaces:
Sleeping
Sleeping
Upload folder using huggingface_hub
Browse files
README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
| 1 |
---
|
| 2 |
title: Logic Engine
|
| 3 |
-
emoji:
|
| 4 |
colorFrom: blue
|
| 5 |
colorTo: indigo
|
| 6 |
sdk: docker
|
|
@@ -8,227 +8,6 @@ pinned: false
|
|
| 8 |
app_port: 7860
|
| 9 |
---
|
| 10 |
|
| 11 |
-
|
| 12 |
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
[](https://github.com/kayba-ai/agentic-context-engine/stargazers)
|
| 16 |
-
[](https://kayba.ai)
|
| 17 |
-
[](https://discord.gg/mqCqH7sTyK)
|
| 18 |
-
[](https://twitter.com/kaybaai)
|
| 19 |
-
[](https://kayba-ai.github.io/agentic-context-engine/latest/)
|
| 20 |
-
|
| 21 |
-
> [!TIP]
|
| 22 |
-
> ACE is the open-source engine behind [Kayba](https://kayba.ai). If you'd rather have the whole loop managed for you, from failure investigation to fixes shipped as PRs, [get a demo](https://kayba.ai).
|
| 23 |
-
|
| 24 |
-
---
|
| 25 |
-
|
| 26 |
-
**AI agents don't learn from experience.** They repeat the same mistakes every session, forget what worked, and ignore what failed. ACE is the open-source engine that adds a persistent learning loop. It also powers [Kayba](https://kayba.ai), the managed service that does this for your production agents automatically.
|
| 27 |
-
|
| 28 |
-
<img src="examples/seahorse-emoji-ace.gif" alt="ACE learns from mistakes in real time" width="70%"/>
|
| 29 |
-
|
| 30 |
-
> The agent claims a seahorse emoji exists. ACE reflects on the error, and on the next attempt, the agent responds correctly — without human intervention.
|
| 31 |
-
|
| 32 |
-
---
|
| 33 |
-
|
| 34 |
-
## Proven Results
|
| 35 |
-
|
| 36 |
-
| Metric | Result | Context |
|
| 37 |
-
|:-------|:-------|:--------|
|
| 38 |
-
| **2x consistency** | Doubles pass^4 on Tau2 airline benchmark | 15 learned strategies, no reward signals |
|
| 39 |
-
| **49% token reduction** | Browser automation costs cut nearly in half | 10-run learning curve |
|
| 40 |
-
| **$1.50 learning cost** | Claude Code translated 14k lines to TypeScript | Zero build errors, all tests passing |
|
| 41 |
-
|
| 42 |
-
---
|
| 43 |
-
|
| 44 |
-
## Quick Start
|
| 45 |
-
|
| 46 |
-
```bash
|
| 47 |
-
uv add ace-framework
|
| 48 |
-
```
|
| 49 |
-
|
| 50 |
-
**Option A** — Interactive setup (recommended):
|
| 51 |
-
|
| 52 |
-
```bash
|
| 53 |
-
ace setup # Walks you through model selection, API keys, and connection validation
|
| 54 |
-
```
|
| 55 |
-
|
| 56 |
-
**Option B** — Manual configuration:
|
| 57 |
-
|
| 58 |
-
```bash
|
| 59 |
-
export OPENAI_API_KEY="your-key" # or ANTHROPIC_API_KEY, or any of 100+ supported providers
|
| 60 |
-
```
|
| 61 |
-
|
| 62 |
-
Then use it:
|
| 63 |
-
|
| 64 |
-
```python
|
| 65 |
-
from ace import ACELiteLLM
|
| 66 |
-
|
| 67 |
-
agent = ACELiteLLM(model="gpt-4o-mini")
|
| 68 |
-
|
| 69 |
-
# First attempt — the agent may hallucinate
|
| 70 |
-
answer = agent.ask("Is there a seahorse emoji?")
|
| 71 |
-
|
| 72 |
-
# Feed a correction — ACE extracts a strategy and updates the Skillbook
|
| 73 |
-
agent.learn_from_feedback("There is no seahorse emoji in Unicode.")
|
| 74 |
-
|
| 75 |
-
# Subsequent calls benefit from the learned strategy
|
| 76 |
-
answer = agent.ask("Is there a seahorse emoji?")
|
| 77 |
-
|
| 78 |
-
# Inspect what the agent has learned
|
| 79 |
-
print(agent.get_strategies())
|
| 80 |
-
```
|
| 81 |
-
|
| 82 |
-
No fine-tuning, no training data, no vector database.
|
| 83 |
-
|
| 84 |
-
[-> Quick Start Guide](https://kayba-ai.github.io/agentic-context-engine/latest/getting-started/quick-start/) | [-> Setup Guide](https://kayba-ai.github.io/agentic-context-engine/latest/getting-started/setup/) | [-> Hosted API: Where Do Traces Come From?](https://kayba-ai.github.io/agentic-context-engine/latest/integrations/hosted-api/#where-do-traces-come-from)
|
| 85 |
-
|
| 86 |
-
---
|
| 87 |
-
|
| 88 |
-
## How It Works
|
| 89 |
-
|
| 90 |
-
ACE maintains a **Skillbook** — a persistent collection of strategies that evolves with every task. Three specialized roles manage the learning loop:
|
| 91 |
-
|
| 92 |
-
| Role | Responsibility |
|
| 93 |
-
|:-----|:---------------|
|
| 94 |
-
| **Agent** | Executes tasks, enhanced with Skillbook strategies |
|
| 95 |
-
| **Reflector** | Analyzes execution traces to extract what worked and what failed |
|
| 96 |
-
| **SkillManager** | Curates the Skillbook — adds, refines, and removes strategies |
|
| 97 |
-
|
| 98 |
-
The **Recursive Reflector** is the key innovation: instead of summarizing traces in a single pass, it writes and executes Python code in a sandboxed environment to programmatically search for patterns, isolate errors, and iterate until it finds actionable insights.
|
| 99 |
-
|
| 100 |
-
```mermaid
|
| 101 |
-
flowchart LR
|
| 102 |
-
Skillbook[(Skillbook)]
|
| 103 |
-
Start([Task]) --> Agent[Agent]
|
| 104 |
-
Agent <--> Environment[Environment]
|
| 105 |
-
Environment -- Trace --> Reflector[Reflector]
|
| 106 |
-
Reflector --> SkillManager[SkillManager]
|
| 107 |
-
SkillManager -- Updates --> Skillbook
|
| 108 |
-
Skillbook -. Strategies .-> Agent
|
| 109 |
-
```
|
| 110 |
-
|
| 111 |
-
All roles are backed by [PydanticAI](https://ai.pydantic.dev/) agents with structured output validation. PydanticAI routes to 100+ LLM providers through its LiteLLM integration, with native support for OpenAI, Anthropic, Google, Bedrock, Groq, and more.
|
| 112 |
-
|
| 113 |
-
*Based on the [ACE paper](https://arxiv.org/abs/2510.04618) (Stanford & SambaNova) and [Dynamic Cheatsheet](https://arxiv.org/abs/2504.07952).*
|
| 114 |
-
|
| 115 |
-
---
|
| 116 |
-
|
| 117 |
-
## Runners
|
| 118 |
-
|
| 119 |
-
| Runner | Class | Description |
|
| 120 |
-
|:-------|:------|:------------|
|
| 121 |
-
| **LiteLLM** | `ACELiteLLM` | Batteries-included agent with `.ask()`, `.learn()`, `.save()` — accepts any [LiteLLM model string](https://docs.litellm.ai/docs/providers) |
|
| 122 |
-
| **Core** | `ACE` | Full learning loop with batch epochs and evaluation |
|
| 123 |
-
| **Trace Analyser** | `TraceAnalyser` | Learn from pre-recorded traces without re-running tasks |
|
| 124 |
-
| **browser-use** | `BrowserUse` | Browser automation that improves with each run |
|
| 125 |
-
| **LangChain** | `LangChain` | Wrap any LangChain chain or agent with learning |
|
| 126 |
-
| **Claude Code** | `ClaudeCode` | Claude Code CLI tasks with learning |
|
| 127 |
-
|
| 128 |
-
```bash
|
| 129 |
-
uv add 'ace-framework[browser-use]' # Browser automation
|
| 130 |
-
uv add 'ace-framework[langchain]' # LangChain
|
| 131 |
-
uv add 'ace-framework[logfire]' # Observability (auto-instruments PydanticAI)
|
| 132 |
-
uv add 'ace-framework[mcp]' # MCP server for IDE integration
|
| 133 |
-
uv add 'ace-framework[deduplication]' # Embedding-based skill deduplication
|
| 134 |
-
```
|
| 135 |
-
|
| 136 |
-
Have existing agent logs? Extract strategies from them directly:
|
| 137 |
-
|
| 138 |
-
```python
|
| 139 |
-
from ace import ACELiteLLM
|
| 140 |
-
|
| 141 |
-
agent = ACELiteLLM(model="gpt-4o-mini")
|
| 142 |
-
agent.learn_from_traces(your_existing_traces)
|
| 143 |
-
print(agent.get_strategies())
|
| 144 |
-
```
|
| 145 |
-
|
| 146 |
-
[-> Examples](examples/)
|
| 147 |
-
|
| 148 |
-
---
|
| 149 |
-
|
| 150 |
-
## Benchmarks
|
| 151 |
-
|
| 152 |
-
### Tau2 — Multi-Step Agentic Tasks
|
| 153 |
-
|
| 154 |
-
[tau2-bench](https://github.com/sierra-research/tau2-bench) by Sierra Research: airline domain tasks requiring tool use and policy adherence. Claude Haiku 4.5 agent, strategies learned on the train split with no reward signals, evaluated on the held-out test split.
|
| 155 |
-
|
| 156 |
-
<img src="benchmarks/tasks/tau_bench/Tau2Benchmark Result Haiku4.5.png" alt="Tau2 Benchmark — ACE doubles consistency at pass^4" width="35%"/>
|
| 157 |
-
|
| 158 |
-
*pass^k = probability all k independent attempts succeed. ACE doubles consistency at pass^4 with 15 learned strategies.*
|
| 159 |
-
|
| 160 |
-
### Claude Code — Autonomous Translation
|
| 161 |
-
|
| 162 |
-
ACE + Claude Code translated this library from Python to TypeScript with zero supervision:
|
| 163 |
-
|
| 164 |
-
| Metric | Result |
|
| 165 |
-
|:-------|:-------|
|
| 166 |
-
| Duration | ~4 hours |
|
| 167 |
-
| Commits | 119 |
|
| 168 |
-
| Lines written | ~14,000 |
|
| 169 |
-
| Build errors | 0 |
|
| 170 |
-
| Tests | All passing |
|
| 171 |
-
| Learning cost | ~$1.50 |
|
| 172 |
-
|
| 173 |
-
---
|
| 174 |
-
|
| 175 |
-
## Pipeline Architecture
|
| 176 |
-
|
| 177 |
-
ACE is built on a composable pipeline engine. Each step declares what it requires and what it produces:
|
| 178 |
-
|
| 179 |
-
```
|
| 180 |
-
AgentStep -> EvaluateStep -> ReflectStep -> UpdateStep -> DeduplicateStep
|
| 181 |
-
```
|
| 182 |
-
|
| 183 |
-
Use `learning_tail()` for the standard learning sequence, or compose custom pipelines:
|
| 184 |
-
|
| 185 |
-
```python
|
| 186 |
-
from ace import Pipeline, AgentStep, EvaluateStep, learning_tail
|
| 187 |
-
|
| 188 |
-
steps = [AgentStep(agent, skillbook), EvaluateStep(env)] + learning_tail(reflector, skill_manager, skillbook)
|
| 189 |
-
pipeline = Pipeline(steps)
|
| 190 |
-
```
|
| 191 |
-
|
| 192 |
-
The pipeline engine ([`pipeline/`](pipeline/)) is framework-agnostic with `requires`/`provides` contracts, immutable context, and error isolation. See [Pipeline Design](docs/design/PIPELINE_DESIGN.md) and [Architecture](docs/design/ACE_ARCHITECTURE.md).
|
| 193 |
-
|
| 194 |
-
---
|
| 195 |
-
|
| 196 |
-
## CLI
|
| 197 |
-
|
| 198 |
-
| Command | Description |
|
| 199 |
-
|:--------|:------------|
|
| 200 |
-
| `ace setup` | Interactive setup — model selection, API keys, connection validation |
|
| 201 |
-
| `ace models <query>` | Search available models with pricing |
|
| 202 |
-
| `ace validate <model>` | Test a model connection |
|
| 203 |
-
| `ace config` | Show current configuration |
|
| 204 |
-
| `kayba` | Cloud CLI — upload traces, fetch insights, manage prompts |
|
| 205 |
-
| `ace-mcp` | MCP server for IDE integration |
|
| 206 |
-
|
| 207 |
-
---
|
| 208 |
-
|
| 209 |
-
## Documentation
|
| 210 |
-
|
| 211 |
-
- [Full Documentation](https://kayba-ai.github.io/agentic-context-engine/latest/) — Guides, API reference, examples
|
| 212 |
-
- [Quick Start](https://kayba-ai.github.io/agentic-context-engine/latest/getting-started/quick-start/) — 5-minute setup
|
| 213 |
-
- [Setup Guide](https://kayba-ai.github.io/agentic-context-engine/latest/getting-started/setup/) — Configuration and providers
|
| 214 |
-
- [Hosted API Guide](https://kayba-ai.github.io/agentic-context-engine/latest/integrations/hosted-api/) — Hosted CLI, trace upload, prompt install
|
| 215 |
-
- [Architecture](docs/design/ACE_ARCHITECTURE.md) — Core concepts and system design
|
| 216 |
-
- [Code Reference](docs/design/ACE_REFERENCE.md) — Implementations, API, usage examples
|
| 217 |
-
- [Design Decisions](docs/design/ACE_DECISIONS.md) — Rejected alternatives and rationale
|
| 218 |
-
- [Pipeline Engine](docs/design/PIPELINE_DESIGN.md) — Step composition and context flow
|
| 219 |
-
- [Examples](examples/) — Runnable demos
|
| 220 |
-
- [Changelog](CHANGELOG.md) — Version history
|
| 221 |
-
|
| 222 |
-
---
|
| 223 |
-
|
| 224 |
-
## Contributing
|
| 225 |
-
|
| 226 |
-
Contributions are welcome. See [Contributing Guidelines](CONTRIBUTING.md).
|
| 227 |
-
|
| 228 |
-
---
|
| 229 |
-
|
| 230 |
-
<div align="center">
|
| 231 |
-
|
| 232 |
-
**Built by [Kayba](https://kayba.ai) and the open-source community.**
|
| 233 |
-
|
| 234 |
-
</div>
|
|
|
|
| 1 |
---
|
| 2 |
title: Logic Engine
|
| 3 |
+
emoji: 🤖
|
| 4 |
colorFrom: blue
|
| 5 |
colorTo: indigo
|
| 6 |
sdk: docker
|
|
|
|
| 8 |
app_port: 7860
|
| 9 |
---
|
| 10 |
|
| 11 |
+
# Logic Engine - Node 2
|
| 12 |
|
| 13 |
+
FastAPI backend for the Manus UI Clone. Exposes a /chat endpoint.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
main.py
CHANGED
|
@@ -16,44 +16,58 @@ app.add_middleware(
|
|
| 16 |
|
| 17 |
class ChatRequest(BaseModel):
|
| 18 |
prompt: str
|
| 19 |
-
model: str = "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 20 |
|
| 21 |
@app.get("/")
|
| 22 |
def root():
|
| 23 |
return {"status": "Logic Engine is running", "endpoints": ["/chat", "/health"]}
|
| 24 |
|
| 25 |
-
|
| 26 |
@app.post("/chat")
|
| 27 |
async def chat_endpoint(request: ChatRequest):
|
| 28 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 29 |
|
| 30 |
if not api_key:
|
| 31 |
-
# Graceful fallback when no API key is configured
|
| 32 |
return {
|
| 33 |
"response": (
|
| 34 |
-
f
|
| 35 |
-
"No
|
| 36 |
-
"via the Providers panel in the UI or in the Space Secrets settings on Hugging Face."
|
| 37 |
),
|
| 38 |
"doc": True
|
| 39 |
}
|
| 40 |
|
| 41 |
-
|
| 42 |
-
# Use OpenAI-compatible API via httpx (works with OpenAI & Groq)
|
| 43 |
-
base_url = "https://api.groq.com/openai/v1" if os.environ.get("GROQ_API_KEY") else "https://api.openai.com/v1"
|
| 44 |
-
chosen_key = os.environ.get("GROQ_API_KEY") or os.environ.get("OPENAI_API_KEY")
|
| 45 |
-
model = "llama-3.1-8b-instant" if os.environ.get("GROQ_API_KEY") else request.model
|
| 46 |
|
| 47 |
-
|
|
|
|
| 48 |
resp = await client.post(
|
| 49 |
f"{base_url}/chat/completions",
|
| 50 |
-
headers={
|
|
|
|
|
|
|
|
|
|
| 51 |
json={
|
| 52 |
-
"model": model,
|
| 53 |
"messages": [
|
| 54 |
-
{"role": "system", "content": "You are Manus, a helpful autonomous AI agent."},
|
| 55 |
-
{"role": "user", "content": request.prompt}
|
| 56 |
-
]
|
|
|
|
| 57 |
}
|
| 58 |
)
|
| 59 |
resp.raise_for_status()
|
|
@@ -61,6 +75,8 @@ async def chat_endpoint(request: ChatRequest):
|
|
| 61 |
reply = data["choices"][0]["message"]["content"]
|
| 62 |
return {"response": reply, "doc": True}
|
| 63 |
|
|
|
|
|
|
|
| 64 |
except Exception as e:
|
| 65 |
raise HTTPException(status_code=500, detail=str(e))
|
| 66 |
|
|
|
|
| 16 |
|
| 17 |
class ChatRequest(BaseModel):
|
| 18 |
prompt: str
|
| 19 |
+
model: str = "llama-3.1-8b-instant"
|
| 20 |
+
api_key: str = ""
|
| 21 |
+
provider: str = "Groq"
|
| 22 |
+
|
| 23 |
+
PROVIDER_BASES = {
|
| 24 |
+
"OpenAI": "https://api.openai.com/v1",
|
| 25 |
+
"Anthropic": "https://api.anthropic.com/v1",
|
| 26 |
+
"Groq": "https://api.groq.com/openai/v1",
|
| 27 |
+
"HuggingFace": "https://api-inference.huggingface.co/v1",
|
| 28 |
+
"OpenRouter": "https://openrouter.ai/api/v1",
|
| 29 |
+
"Nvidia": "https://integrate.api.nvidia.com/v1",
|
| 30 |
+
}
|
| 31 |
|
| 32 |
@app.get("/")
|
| 33 |
def root():
|
| 34 |
return {"status": "Logic Engine is running", "endpoints": ["/chat", "/health"]}
|
| 35 |
|
|
|
|
| 36 |
@app.post("/chat")
|
| 37 |
async def chat_endpoint(request: ChatRequest):
|
| 38 |
+
# Priority: key from frontend → env vars
|
| 39 |
+
api_key = (
|
| 40 |
+
request.api_key.strip()
|
| 41 |
+
or os.environ.get("GROQ_API_KEY", "")
|
| 42 |
+
or os.environ.get("OPENAI_API_KEY", "")
|
| 43 |
+
)
|
| 44 |
|
| 45 |
if not api_key:
|
|
|
|
| 46 |
return {
|
| 47 |
"response": (
|
| 48 |
+
f'[Logic Engine] Received: "{request.prompt}"\n\n'
|
| 49 |
+
"No API key configured. Please add your key via the Providers panel."
|
|
|
|
| 50 |
),
|
| 51 |
"doc": True
|
| 52 |
}
|
| 53 |
|
| 54 |
+
base_url = PROVIDER_BASES.get(request.provider, PROVIDER_BASES["Groq"])
|
|
|
|
|
|
|
|
|
|
|
|
|
| 55 |
|
| 56 |
+
try:
|
| 57 |
+
async with httpx.AsyncClient(timeout=60) as client:
|
| 58 |
resp = await client.post(
|
| 59 |
f"{base_url}/chat/completions",
|
| 60 |
+
headers={
|
| 61 |
+
"Authorization": f"Bearer {api_key}",
|
| 62 |
+
"Content-Type": "application/json",
|
| 63 |
+
},
|
| 64 |
json={
|
| 65 |
+
"model": request.model,
|
| 66 |
"messages": [
|
| 67 |
+
{"role": "system", "content": "You are Manus, a helpful and concise autonomous AI agent."},
|
| 68 |
+
{"role": "user", "content": request.prompt},
|
| 69 |
+
],
|
| 70 |
+
"temperature": 0.7,
|
| 71 |
}
|
| 72 |
)
|
| 73 |
resp.raise_for_status()
|
|
|
|
| 75 |
reply = data["choices"][0]["message"]["content"]
|
| 76 |
return {"response": reply, "doc": True}
|
| 77 |
|
| 78 |
+
except httpx.HTTPStatusError as e:
|
| 79 |
+
raise HTTPException(status_code=e.response.status_code, detail=f"Provider error: {e.response.text}")
|
| 80 |
except Exception as e:
|
| 81 |
raise HTTPException(status_code=500, detail=str(e))
|
| 82 |
|