Version: 0.1.1 | Last Updated: 2026-03-21
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Applications Layer β
β (adana, adana-repl, dana-code, dana-init, dana-cli) β
ββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββ
β
ββββββββββββββββββββββββ΄βββββββββββββββββββββββββββββββββββββββ
β Agent Layer β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β STARAgent (STAR Loop Implementation) ββ
β β ββ Communicator (LLM interface) ββ
β β ββ State (Conversation state) ββ
β β ββ Learner (Learning from interactions) ββ
β β ββ Observer (Introspection & metrics) ββ
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββ
β
ββββββββββββββββββββββββ΄βββββββββββββββββββββββββββββββββββββββ
β Core Systems Layer β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β Resource System Timeline Workflows ββ
β β ββ BashResource ββ Entry ββ BaseWorkflow ββ
β β ββ FileIOResource ββ Compressor ββ Executor ββ
β β ββ SearchResource ββ Serializer ββ Validation ββ
β β ββ CustomResources ββ
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β Memory Prompts Skills Reminder ββ
β β ββ STMemory ββ Builder ββ Registry ββ Context ββ
β β ββ LTMemory ββ API ββ Executor ββ
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββ
β
ββββββββββββββββββββββββ΄βββββββββββββββββββββββββββββββββββββββ
β LLM Abstraction Layer β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β CodecRuntimeBase (Unified interface) ββ
β β ββ NativeToolsCodec (Claude, GPT-4 Turbo) ββ
β β ββ CSXMLCodec (Non-native tool use) ββ
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β Provider Implementations ββ
β β ββ OpenAI ββ Azure OpenAI ββ
β β ββ Anthropic ββ Gemini ββ
β β ββ Anthropic-Like ββ Local (LLaMA/Ollama) ββ
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββ
β
ββββββββββββββββββββββββ΄βββββββββββββββββββββββββββββββββββββββ
β Data Persistence & Infrastructure β
β ββ Repository Layer (File, Database adapters) β
β ββ Configuration (config.json, environment) β
β ββ Logging (structlog) β
β ββ Utilities (common functions, helpers) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
User Input
β
βΌ
βββββββββββββββββββββββ
β SEE (Perceive) β
β β’ Parse intent β
β β’ Analyze context β
β β’ Load memory β
ββββββββββ¬βββββββββββββ
β
βΌ
βββββββββββββββββββββββ
β THINK (Reason) β
β β’ Prompt building β
β β’ LLM inference β
β β’ Tool planning β
ββββββββββ¬βββββββββββββ
β
βΌ
βββββββββββββββββββββββ
β ACT (Execute) β
β β’ Call resources β
β β’ Collect results β
β β’ Update timeline β
ββββββββββ¬βββββββββββββ
β
βΌ
βββββββββββββββββββββββ
β REFLECT (Learn) β
β β’ Analyze outcome β
β β’ Update memory β
β β’ Metrics capture β
ββββββββββ¬βββββββββββββ
β
βΌ
Response
STARAgent
ββ Communicator (LLM Communication)
β ββ Runtime (Provider abstraction)
β β ββ Codec (Tool schema conversion)
β β ββ NativeToolsCodec
β β ββ CSXMLCodec
β ββ Prompt Builder
β β ββ System prompt
β β ββ Tool schemas
β β ββ Conversation history
β ββ LLM Providers
β ββ OpenAI
β ββ Anthropic
β ββ Gemini
β ββ Others
β
ββ State (Conversation State)
β ββ Timeline (History)
β β ββ User entries
β β ββ Assistant entries
β β ββ Tool results
β β ββ Compression logic
β ββ Short-term memory
β ββ Tool cache
β
ββ Learner (Learning System)
β ββ Long-term memory
β β ββ Lessons
β β ββ Episodes
β β ββ Facts
β β ββ Patterns
β ββ Feedback processing
β
ββ Observer (Metrics & Introspection)
ββ Token tracking
ββ Performance metrics
ββ Error logging
ββ Debug information
User Message
β
βΌ
Timeline.add_entry(UserEntry)
β
βΌ
check_should_compress()
β
ββ Yes β Timeline.compress()
β (LLM-based summarization)
β
βΌ
Prompt.build(
system_prompt,
timeline_entries,
tool_schemas,
memory_context
)
β
βΌ
Runtime.complete(
messages,
tools
) β Handles provider-specific format
β
ββ OpenAI: native tools
ββ Anthropic: native tools
ββ Others: XML-based tools
β
βΌ
Parse Response (ToolCalls + Text)
β
ββ Tool Calls
β β
β ββ for each tool_call:
β β
β ββ ResourceRegistry.get(tool_name)
β ββ Execute with parameters
β ββ Timeline.add_entry(ToolResultEntry)
β
ββ Text Content
β β
β ββ Timeline.add_entry(AssistantEntry)
β
βΌ
Optional Refinement (if tool errors or incomplete)
β
βΌ
Learner.process_interaction(
context,
outcome,
feedback
)
β
βΌ
Return Response to User
STARAgent
β
ββ Resource Registry (Global)
β
ββ BashResource
β ββ execute(command)
β ββ Tool Schema: {name, description, parameters}
β
ββ FileIOResource
β ββ read(path)
β ββ write(path, content)
β ββ list_dir(path)
β
ββ FileEditResource
β ββ edit_file(path, old, new)
β ββ Shows diff before applying
β
ββ SearchResource
β ββ search(query, num_results)
β ββ Returns structured results
β
ββ WebResearchResource
β ββ research(topic, sources)
β ββ HTML extraction
β ββ Content synthesis
β ββ Multi-source aggregation
β
ββ TaskResource
β ββ create(title, description)
β ββ update(id, status)
β ββ list(filter)
β
ββ TodoResource
β ββ add(title)
β ββ complete(id)
β ββ list()
β
ββ SkillResource
β ββ execute_skill(name, args)
β ββ Load from .claude/skills/
β
ββ MCPResource
β ββ Call MCP servers
β ββ Server discovery
β ββ Protocol handling
β
ββ CustomResources (User-defined)
ββ Extend BaseResource
ββ Annotated methods = tools
ββ Auto schema generation
WorkflowExecutor
β
ββ Parse workflow definition
β (steps, conditions, parallel tasks)
β
ββ For each step:
β β
β ββ Validate inputs
β ββ Execute step (CallableWorkflow)
β ββ Collect outputs
β ββ Handle errors/retries
β ββ Pass outputs to next step
β
ββ Conditional branches
β ββ Evaluate condition
β ββ Route to correct step
β
ββ Parallel execution
β ββ Run concurrent steps
β ββ Gather results
β
βΌ
Return aggregated results
Runtime (Abstract Interface)
β
ββ CodecRuntimeBase
β β
β ββ __init__(codec: ToolCodec, ...)
β ββ async complete(messages, tools) -> Response
β
ββ DefaultRuntime
β ββ Try providers in priority order
β ββ Fallback on provider failure
β
ββ ProviderSpecificRuntime (OpenAI, Anthropic, etc.)
β ββ Provider-specific optimizations
β
ββ Codec System
β
ββ NativeToolsCodec
β ββ Anthropic native tools
β ββ OpenAI function calling
β ββ No XML conversion needed
β
ββ CSXMLCodec
ββ Convert tools to XML format
ββ Parse XML responses
ββ For non-native providers
config.json
{
"llm_providers": {
"openai": {
"priority": 100,
"api_key": "${OPENAI_API_KEY}",
"models": ["gpt-4.1", "gpt-4.1-mini", "o3", "o4-mini"]
},
"anthropic": {
"priority": 90,
"api_key": "${ANTHROPIC_API_KEY}",
"models": ["claude-sonnet-4-6", "claude-opus-4-6"]
},
"gemini": {
"priority": 85,
"api_key": "${GOOGLE_API_KEY}",
"models": ["gemini-2.5-flash", "gemini-2.5-pro"]
},
"azure": {
"priority": 40,
"api_key": "${AZURE_OPENAI_KEY}",
"endpoint": "${AZURE_ENDPOINT}"
}
}
}
DefaultRuntime tries providers in priority order (high to low).
STARAgent
β
ββ Short-Term Memory (STMemory)
β ββ Per-session cache
β ββ Fast retrieval
β ββ Location: dana/core/memory/
β
ββ Long-Term Memory (LTMemory)
ββ Persistent markdown files
ββ 4 memory types:
β ββ Lesson (Key learnings)
β ββ Episode (Significant interactions)
β ββ Fact (Factual information)
β ββ Pattern (Observed patterns)
β
ββ Storage: ~/.dana/memory/ or configured path
ββ Retrieval: Embedding-based search (optional)
ββ Location: dana/lib/memory/
User Message + Context
β
ββ PromptBuilder.build()
β β
β ββ 1. System Prompt
β β ββ Model instructions, capabilities
β β
β ββ 2. Memory Context
β β ββ STMemory retrieval
β β ββ LTMemory search results
β β
β ββ 3. Tool Schemas
β β ββ Names, descriptions
β β ββ Parameter schemas (JSON)
β β
β ββ 4. Conversation Timeline
β β ββ Recent entries (uncompressed)
β β ββ Older entries (if compressed)
β β
β ββ 5. Reminder Context
β ββ Dynamic context injected
β
βΌ
Final Prompt β LLM
Timeline.add_entry(entry)
β
ββ Update token count
β
ββ Check compression threshold
β
ββ If tokens < threshold * max_tokens: OK
β
ββ If tokens >= threshold * max_tokens:
β
ββ Compress older entries
β β
β ββ LLM-based summarization
β ββ Summarize 3-5 oldest entries
β ββ Replace with summary
β ββ Maintain token budget
β
ββ Continue conversation
Default Settings:
max_tokens: 4096compression_threshold: 0.8 (compress at 80% usage)- Compression reduces tokens to ~60% of original
The compression pipeline now has three additional layers for parity with OpenClaude-style engines:
- Single-knob heuristic trigger (P3) β
DANA_COMPACT_TRIGGER_TOKENS(default 150000, clamp[8k, 2M]) gatesneeds_compression(). Optionalsystem_tokens_fn/tools_tokens_fncallbacks fold system-prompt and tools-schema size into the estimate. Alwayslen(str)/4. - Cheap client-side shrink (P6) β
cheap_shrink_tool_results()stubs oldtool_resultbodies to"[cleared for context budget]"while preservingtool_call_id. Opt-in viaCompressedTimelineConfig.enable_cheap_shrink_tool_results. A predictive gate skips shrink when it cannot close the token gap alone β prevents vacuous summaries over stubs. - Reactive compact + circuit breaker (P2) β
PromptTooLongErrorraised by providers is caught inllm_caller._invoke_llm_sync/async, which callstimeline.reactive_compact(attempt)(drop 5β10β20 oldest kept entries + forward-orphan pruning + full summary) with exponential backoff 1s/3s. After 3 consecutive failures the circuit opens; cooldownDANA_CIRCUIT_COOLDOWN_SECONDS(default 300s) plus half-open probe provide automatic recovery. Kill switch viaDANA_DISABLE_REACTIVE_COMPACT=1.
Provider PTL mapping:
| Provider | Detection |
|---|---|
| Anthropic / Anthropic-like | BadRequestError body type="invalid_request_error" + "prompt is too long" in message |
| OpenAI / Azure / Moonshot | APIStatusError body code="context_length_exceeded" |
| Gemini | No SDK error β post-hoc WARNING log on finish_reason=="MAX_TOKENS" (reactive compact unavailable; tune DANA_COMPACT_TRIGGER_TOKENS conservatively) |
Telemetry: dana/core/timeline/telemetry.py exposes
CompressionLogFields TypedDict allowlist. An AST-based unit test asserts
log extra={...} keys stay within the allowlist (no prompt-content leakage).
Resource Execution
β
ββ Try: execute tool
β β
β ββ Success β Return result
β β
β ββ Error:
β β
β ββ Catch specific exception
β β
β ββ Log error with context
β β
β ββ Decide on retry (transient vs permanent)
β β ββ Transient (network): retry with backoff
β β ββ Permanent (invalid): fail immediately
β β
β ββ Return error to agent
β ββ Agent may retry with different params
β
ββ Timeline.add_entry(ToolErrorEntry)
Agent.stream_response(messages)
β
ββ Runtime.stream_complete(messages, tools)
β β
β ββ Provider-specific streaming
β (Server-Sent Events or chunked)
β
ββ Token-by-token yield
β
ββ Collect full response
β
ββ Parse tool calls if present
β
ββ Timeline.add_entry(AssistantEntry)
- Async throughout: All I/O is non-blocking
- Tool execution: Sequential by default (preserves order)
- Multiple agents: Can run concurrently with asyncio.gather()
- Web research: Concurrent HTTP requests within single research task
class MyResource(BaseResource):
async def my_tool(self, param: str) -> str:
return f"result: {param}"class MyWorkflow(BaseWorkflow):
async def execute(self, context):
result1 = await self.step1()
result2 = await self.step2(result1)
return result2class DatabaseMemory(LTMemory):
async def save(self, memory):
await db.insert(memory)Implement provider interface + add to config.json
| Operation | Latency | Notes |
|---|---|---|
| Message processing | <5s avg | Depends on LLM |
| Tool execution | Variable | Depends on tool |
| Timeline compression | 1-2s | LLM-based |
| Memory retrieval | <100ms | Embedding search |
| Resource lookup | <1ms | Hash registry |
| Streaming first token | 1-3s | LLM latency |
- Input Validation: Pydantic models for all inputs
- Code Execution: Python sandbox with restricted builtins
- Environment Secrets: Never logged, loaded from .env
- Tool Filtering: Only allowed resources accessible
- Command Execution: Bash sandboxing where possible
Version: 0.1.1 | Last Updated: 2026-03-21