Dakera as a governance state backend for multi-agent frameworks #169
Replies: 5 comments
-
|
After digging into TealTiger's codebase across all three repositories (hub, typescript-prod, python-prod), here's a technical deep-dive into the integration surface between TealTiger's governance architecture and Dakera's memory layer. TealTiger's persistence architecture todayTealTiger has a clean separation between governance evaluation (deterministic, sub-5ms, no LLM) and governance state storage. The current storage implementations are either in-memory or SQLite-backed: 1. DecisionReceiptManager — in-memory
|
| Receipt state | Dakera importance | Behavior |
|---|---|---|
| Active ALLOW | 0.8 | Persists, queryable |
| Active DENY | 0.95 | High retention for audit |
| Expired | importance decays | Natural cleanup via decay engine |
| REQUIRE_APPROVAL | 0.9 | Stays until resolved |
Receipt lookup by decision_id maps to tag-based batch recall:
# Check if a terminal decision exists for this idempotency key
memories = await dakera.recall_batch(
agent_id=agent_id,
tags=["decision", f"idempotency:{idempotency_key}"],
)
if memories:
return DecisionReceipt.from_json(memories[0].content)Integration Point 4: TEEC delegation chains via knowledge graph
TealTiger's TEECReceipt has a delegation_chain field — currently a flat list in the receipt JSON. Dakera's knowledge graph makes this traversable:
# Store a delegation link
POST /v1/memories/{child_decision_id}/links
{
"target_id": "parent_decision_id",
"relation": "delegated_from"
}
# Reconstruct the full delegation chain
GET /v1/memories/{decision_id}/graph?depth=10This directly addresses the AG2 thread requirement: "if Agent-B was delegated authority from Agent-A, the middleware still needs to verify Agent-A's scope when Agent-B acts."
Integration Point 5: Governance event stream
TealTiger's GovernanceStreamServer provides WebSocket-based event streaming with subscription filters (agents, decisions, event types). Dakera provides two complementary SSE streams:
/v1/events/stream— memory lifecycle events (store/recall/update/delete)/v1/audit/stream— business-event audit log with time range and action type filters
For the SARIF/JUnit export use case mentioned in the AG2 thread: Dakera's /v1/audit/export endpoint provides the raw event data that TealTiger's TealProof module could format into compliance reports.
What this integration enables
-
Governance state survives restarts — DecisionReceipts, BudgetStates, and CostRecords persist in Dakera instead of in-memory dicts. Agent migrations, horizontal scaling, and framework upgrades don't lose governance continuity.
-
Semantic search over governance history — TealTiger's current SQLite backend supports exact-match queries. Dakera adds vector-based semantic search: "find decisions similar to this denied tool call" or "recall all governance events where cost anomaly was detected."
-
Cross-agent governance network — Dakera's
/v1/knowledge/network/cross-agentvisualizes how governance decisions flow across agents in a multi-agent system, which maps to TealTiger'sGovernedGroupChatspeaker selection audit. -
Decay-weighted retention — Routine ALLOW decisions at importance 0.5 decay naturally. DENY decisions and security events at 0.9+ persist indefinitely. This replaces manual
delete_older_than()with intelligent retention. -
Memory governance integration — TealTiger's
TealMemorymodule (instruction injection scoring, exfiltration detection) can run as a governance layer on top of Dakera's memory store. When an agent stores a memory via Dakera, TealTiger's detectors validate the content before persistence — a natural middleware pattern.
Integration architecture sketch
Agent (AG2/LangChain/CrewAI)
│
├── TealTigerGuard / TealTigerMiddleware
│ ├── Policy evaluation (deterministic, <5ms)
│ ├── PII detection, secret scanning
│ ├── Cost tracking + budget enforcement
│ └── TEEC receipt generation
│
├── GovernanceIngestionPipeline
│ ├── Buffer (100 events, 1s flush)
│ ├── Write-ahead log
│ └── DakeraGovernanceWriter ← NEW
│ └── POST /v1/memory/store (per event)
│ or POST /v1/memories/store/batch (bulk)
│
└── DakeraCostStorage ← NEW
├── POST /v1/memory/store (cost records)
├── POST /v1/memories/recall/batch (agent cost history)
└── POST /v1/memory/recall (semantic cost queries)
The TealTiger SDK handles governance logic (policy evaluation, guardrails, evidence generation). Dakera handles the persistence layer (durable storage, semantic search, decay management, knowledge graph). Clean separation — each system does what it's built for.
To get started, the deployment guide gets a production-ready instance running with a single docker compose up — no external dependencies. The Python SDK and JS SDK both support the full API surface needed for this integration.
Beta Was this translation helpful? Give feedback.
-
|
@ferhimedamine This is thorough and well-mapped. You clearly read the codebase — the integration points you identified (CostStorage, GovernanceEventWriter, DecisionReceiptManager, delegation graph) are exactly right. A few things I want to validate:
I'll set up a local Dakera instance this week and start with a If you want to pair on this, join us on Discord: https://discord.gg/X2ePf8QAj — or I can open an issue on dakera-py for the integration spec. |
Beta Was this translation helpful? Give feedback.
-
|
@nagasatish007 Thanks for the detailed validation questions — these are exactly the right things to check before committing to an integration. I ran a local benchmark to get concrete numbers for each one. 1. Latency —
|
| Operation | p50 | p90 | p95 | p99 |
|---|---|---|---|---|
batch_recall with 2 tags |
21ms | 25ms | 26ms | 28ms |
batch_recall with 1 tag |
21ms | 24ms | 26ms | 28ms |
recall (semantic, top_k=1) |
32ms | 37ms | 38ms | 42ms |
knowledge_query with edge_type filter |
10ms | — | 14ms | — |
store_memory |
17ms | 77ms | 98ms | 162ms |
Results — concurrent load (10 parallel batch_recall)
| Run | Min | Max | Wall clock |
|---|---|---|---|
| 1 | 267ms | 291ms | 327ms |
| 2 | 115ms | 238ms | 269ms |
| 3 | 102ms | 298ms | 329ms |
| 4 | 48ms | 230ms | 271ms |
| 5 | 329ms | 492ms | 548ms |
Bottom line: For the governance hot path — idempotency check via batch_recall with tag filtering — the p99 is 28ms on a local instance. Combined with TealTiger's <5ms policy evaluation, the total governance path becomes <35ms.
Recommended pattern for the middleware
The recommended integration keeps the hot path minimal:
- Policy evaluation (local, no Dakera call): <5ms — use cached policies
- Idempotency check (
batch_recallwithdecision_idtag): p99 = 28ms - Delegation chain verification (
knowledge_querywithedge_typefilter): p99 ≈ 14ms - Decision storage (async, off the hot path): p50 = 17ms, p99 = 162ms
REST API
# Idempotency check — recall by decision_id tag
POST /v1/memories/recall/batch
{
"agent_id": "agent-assistant-1",
"tags": ["governance", "decision_id:dec-789"],
"min_importance": 0.7
}Python SDK
from dakera import DakeraClient, BatchRecallRequest, BatchMemoryFilter
client = DakeraClient(base_url="http://localhost:3000")
# Idempotency check — recall by decision_id tag
resp = client.batch_recall(BatchRecallRequest(
agent_id="agent-assistant-1",
filter=BatchMemoryFilter(
tags=["governance", "decision_id:dec-789"],
min_importance=0.7,
),
limit=1,
))
if resp.memories:
prior_decision = resp.memories[0] # Terminal decision exists2. Python SDK — pip install dakera
Yes:
pip install dakera # sync client (requests)
pip install dakera[async] # async client (httpx)Both sync and async clients are shipped:
from dakera import DakeraClient # sync
from dakera import AsyncDakeraClient # async (context manager)
# Sync
client = DakeraClient(base_url="http://localhost:3000", api_key="your-key")
# Async
async with AsyncDakeraClient(base_url="http://localhost:3000", api_key="your-key") as client:
result = await client.store_memory(...)For TealTiger's CostStorage implementation, the key method mappings are:
| TealTiger interface | Dakera Python SDK | REST API |
|---|---|---|
store(record) |
client.store_memory(agent_id, content, importance, tags, memory_type) |
POST /v1/memory/store |
get_by_agent_id(agent_id, ...) |
client.batch_recall(BatchRecallRequest(...)) |
POST /v1/memories/recall/batch |
get_summary(start, end, agent_id) |
client.batch_recall(...) + client-side aggregation |
Same endpoint with time filters |
store_memory — full method signature
client.store_memory(
agent_id="agent-assistant-1",
content='{"model": "gpt-4", "tokens": 1500, "cost": 0.045}',
memory_type="episodic",
importance=0.7,
tags=["governance", "cost", "model:gpt-4", "provider:openai"],
session_id="session-abc-123", # optional — groups under session context
)batch_recall — filtering with BatchMemoryFilter
BatchMemoryFilter accepts: tags (list, all must match), min_importance, max_importance, created_after (Unix timestamp), created_before, memory_type, session_id.
from dakera import BatchRecallRequest, BatchMemoryFilter
# Get all cost records for an agent in a time range
resp = client.batch_recall(BatchRecallRequest(
agent_id="agent-assistant-1",
filter=BatchMemoryFilter(
tags=["governance", "cost"],
created_after=1718000000, # Unix seconds
created_before=1718100000,
),
limit=100,
))
cost_records = resp.memoriesSDKs are also available in JavaScript (npm install @dakera-ai/dakera), Rust, and Go — but given TealTiger's Python codebase, the Python SDK is the natural integration point.
3. Knowledge graph — relation type filtering
Yes. The knowledge_query method supports filtering by edge_type.
REST API
GET /v1/knowledge/query?agent_id=agent-assistant-1&root_id={decision_id}&edge_type=delegated_from&max_depth=10Parameters: agent_id (required), root_id, edge_type (comma-separated for multiple types), min_weight, max_depth, limit.
Python SDK
# Traverse delegation chain — only "delegated_from" edges
result = client.knowledge_query(
agent_id="agent-assistant-1",
root_id="mem_child_decision_id",
edge_type="delegated_from",
max_depth=10,
)Full delegation chain example
# Store parent delegation
parent = client.store_memory(
agent_id="agent-hub",
content="DELEGATION: grant tool_call scope to agent-assistant-1",
importance=0.9,
tags=["governance", "delegation", "parent"],
)
# Store child action
child = client.store_memory(
agent_id="agent-assistant-1",
content="DECISION: tool_call=search, delegated from agent-hub",
importance=0.9,
tags=["governance", "delegation", "child"],
)
# Create typed relationship
client.memory_link(
source_id=child["memory"]["id"],
target_id=parent["memory"]["id"],
edge_type="delegated_from",
)
# Reconstruct the delegation chain
chain = client.knowledge_query(
agent_id="agent-assistant-1",
root_id=child["memory"]["id"],
edge_type="delegated_from",
max_depth=10,
)This directly addresses the TEEC receipt verification requirement — "if Agent-B was delegated authority from Agent-A, the middleware still needs to verify Agent-A's scope when Agent-B acts."
There's also a simpler traversal method that returns all edge types from a given memory node:
# Get all edges from a memory (unfiltered BFS)
graph = client.memory_graph(memory_id="mem_xyz", depth=3)For delegation chain verification specifically, knowledge_query with edge_type filtering is the right choice — it returns only the edges you need with lower latency (p50 = 10ms).
4. CI deployment — lightweight mode
Dakera supports an in-memory storage mode that requires no external dependencies beyond Docker. The docker-compose.local.yml in the deploy repo is designed exactly for this:
Option A: Docker Compose with in-memory storage (recommended for CI)
# GitHub Actions example
- name: Start Dakera (in-memory)
run: |
git clone https://github.com/Dakera-AI/dakera-deploy.git
cd dakera-deploy/docker
docker compose -f docker-compose.local.yml up -d dakera
until curl -sf http://localhost:3000/health; do sleep 1; doneThis runs Dakera with DAKERA_STORAGE=memory — no MinIO, no S3, no persistent storage. A single Docker container with zero external dependencies. Startup is fast and all data is ephemeral — ideal for test suites.
Option B: Direct Docker run (minimal)
- name: Start Dakera
run: |
docker run -d --name dakera \
-p 3000:3000 \
-e DAKERA_STORAGE=memory \
-e RUST_LOG=info \
ghcr.io/dakera-ai/dakera:0.11.90
until curl -sf http://localhost:3000/health; do sleep 1; doneOption C: Full stack with persistence (integration testing)
- name: Start Dakera (with MinIO)
run: |
cd dakera-deploy/docker
docker compose up -d
until curl -sf http://localhost:3000/health; do sleep 1; doneFor TealTiger's test suite, Option A is the best fit — single container, in-memory, fast startup, no cleanup.
Storage modes
| Mode | Config | Use case |
|---|---|---|
| In-memory (default in local compose) | DAKERA_STORAGE=memory |
CI, unit tests, ephemeral |
| Filesystem | DAKERA_STORAGE=filesystem |
Persistent dev, needs restart survival |
| S3-compatible | DAKERA_STORAGE=s3 |
Production, distributed |
Audit endpoints
The three audit endpoints are fully implemented and available in the Python SDK:
| REST endpoint | Python SDK method | Function |
|---|---|---|
GET /v1/audit |
client.list_audit_events(...) |
Query events by agent, time range, event type (paginated) |
GET /v1/audit/stream |
client.stream_audit_events(...) |
SSE live stream with 15s keepalive heartbeats |
POST /v1/audit/export |
client.export_audit(format="jsonl") |
Bulk export as JSONL or CSV |
For the SARIF/JUnit export use case — Dakera's audit export provides the raw event data that TealTiger's TealProof module could format into compliance reports:
# Export governance events for a time range
export = client.export_audit(
format="jsonl",
agent_id="agent-assistant-1",
from_ts=1718000000000,
to_ts=1718100000000,
)Integration spec issue
I've opened a dedicated issue on the Python SDK repo for the TealTiger integration: Dakera-AI/dakera-py#136 — it covers the DakeraCostStorage implementation, GovernanceEventWriter adapter, and decision receipt persistence patterns. That's the best place to track implementation details and coordinate PRs.
Discord
I joined the TealTiger Discord. For the integration work, I'd prefer we operate on GitHub (issues + discussions) for traceability and progress tracking — it keeps decisions linked to code and maintains a searchable history. Discord is great for quick follow-ups and planning when we need faster iteration.
Looking forward to seeing the integration take shape. Happy to review PRs or pair on any of the integration points.
Beta Was this translation helpful? Give feedback.
-
Update: Integration shipped — dakera v0.12.1The TealTiger governance integration is now released and available on PyPI: pip install dakera[tealtiger] # v0.12.1All three adapter classes ( The integration points discussed above (CostStorage ABC, delegation chain via knowledge graph, idempotency lookup, CI deployment) are all covered in the shipped implementation. |
Beta Was this translation helpful? Give feedback.
-
Update: JavaScript SDK integration shipped — @dakera-ai/dakera v0.11.94The TealTiger governance middleware integration is now available in the JavaScript/TypeScript SDK: npm install @dakera-ai/dakera@0.11.94This brings Dakera's TealTiger integration to both Python ( Full release notes: https://github.com/Dakera-AI/dakera-js/releases/tag/v0.11.94 |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Following a conversation on ag2ai/ag2#2967 about TealTiger's governance middleware for AG2 Beta, I wanted to open a dedicated space here to explore how Dakera's memory layer maps to governance state requirements in multi-agent systems.
The problem
Governance middleware (policy enforcement, cost tracking, audit trails) in frameworks like AG2, LangChain, and CrewAI is typically process-coupled — the middleware knows what it decided last turn because it's running in the same process. This breaks under modular architectures: agent restarts, migrations, horizontal scaling, and framework upgrades all lose governance continuity.
The pattern that survives: externalize governance state into a queryable memory layer that the middleware reads on each decision.
How Dakera's API maps to governance state
Dakera is a self-hosted AI agent memory server with a REST API designed for agent-scoped, session-aware state persistence. Here's how the existing API surface maps to governance needs:
1. Decision records
Every governance decision can be stored as a memory with structured metadata:
POST /v1/memory/store { \"agent_id\": \"agent-assistant-1\", \"content\": \"DECISION: tool_call=search, policy=tool_allowlist, verdict=ALLOW\", \"importance\": 0.8, \"tags\": [\"governance\", \"decision\", \"tool_allowlist\"], \"session_id\": \"session-abc-123\", \"memory_type\": \"episodic\" }Each stored memory gets a unique ID, timestamp, and full provenance. Importance weighting controls retention — governance decisions at 0.9+ persist indefinitely; routine checks at 0.5 decay naturally.
2. Agent-scoped enforcement
Dakera isolates memories by
agent_idnatively. Querying decisions for one agent never returns another agent's state:POST /v1/memory/recall { \"agent_id\": \"agent-assistant-1\", \"query\": \"last tool_allowlist decision\", \"top_k\": 1 }This maps directly to TealTiger's requirement that approval for one agent does not authorize another.
3. Idempotency via memory lookup
For the retry-with-same-decision_id pattern: store the decision_id as a tag, then recall by tag to check if a terminal state already exists before re-evaluating:
POST /v1/memories/recall/batch { \"agent_id\": \"agent-assistant-1\", \"tags\": [\"decision_id:dec-789\"] }If a result exists, return the prior terminal state. If not, evaluate and store.
4. Session provenance and audit trail
Dakera's session API groups related decisions under a session context:
POST /v1/sessions/start— open a governance sessionGET /v1/sessions/{id}/memories— retrieve all decisions in a sessionGET /v1/agents/{agent_id}/sessions— list all sessions for an agentThe audit API provides a dedicated query interface:
GET /v1/audit— query audit events by agent, time range, action typeGET /v1/audit/stream— SSE stream for real-time governance event monitoringGET /v1/audit/export— export for compliance reporting5. Delegation chain via knowledge graph
Dakera's knowledge graph links memories with typed relationships:
POST /v1/memories/{decision_id}/links { \"target_id\": \"parent_delegation_id\", \"relation\": \"delegated_from\" }Traverse the delegation chain:
GET /v1/memories/{decision_id}/graph?depth=5This enables receipt reconstruction: who caused the action, under which policy, from which delegation, and what actually executed.
6. Cross-agent governance network
Visualizes how governance decisions flow across agents — useful for multi-agent network governance where hub/channel context needs to be preserved without creating ambient authority.
SDKs
Dakera ships SDKs in Python, JavaScript, Rust, and Go. The Python SDK would be the natural integration point for TealTiger's AG2 middleware.
Deployment
Dakera is self-hosted — single Docker container, no external dependencies. A
docker compose upgets a production-ready instance with HNSW vector index, RocksDB storage, and built-in embedding inference:git clone https://github.com/Dakera-AI/dakera-deploy.git cd dakera-deploy docker compose up -dGovernance state stays on-premise — no data leaves your infrastructure. Relevant for the CISO audit reconstruction use case mentioned in the AG2 thread.
What I'd like to explore
Storageprotocol interface for distributed scenariosTagging @nagasatish007 — continuing from the AG2 thread. The deployment guide has everything needed to get a production instance running — single
docker compose upwith no external dependencies. Happy to walk through any of the integration points in more detail.Beta Was this translation helpful? Give feedback.
All reactions