Decision-Anchored Graph Compression for agent/chat traces: preserve decision-critical artifacts with regex, embeddings, and graph algorithms, support varied message formats, and include optional evaluation tools.
Project description
DAGC — Decision-Anchored Graph Compression
dagc shortens agent and chat histories while prioritising the values that
later decisions depend on: tool arguments, IDs, paths, metrics, and confirmed
choices. It is designed for applications that need to reduce context size
without losing the evidence behind an earlier decision.
The core package is local-only. It does not make LLM or network calls unless you configure an optional embedding or evaluation adapter that does.
What it includes
- Decision-aware message compression with configurable token reduction.
- Zero-dependency fallback tokenizer and embedder for local use.
- Optional adapters for
tiktoken, Sentence Transformers, OpenAI, and Cohere. compress_any()for normalising and restoring common message formats.dagc_eval, an optional reproducibility and benchmark toolkit.dagc-server, an optional HTTP proxy for compressing message arrays before forwarding a request to an upstream LLM API.
Install
Install the package from this repository while developing:
pip install -e .
After publishing, install it from PyPI:
pip install dagc
The core package only requires NumPy and SciPy. For model-aligned token counts and semantic embeddings, install the relevant extras:
pip install "dagc[tiktoken,sentence-transformers]"
Quick start
from dagc import compress
compressed = compress(messages, target_reduction=0.85)
response = client.chat.completions.create(
model="gpt-4.1",
messages=compressed,
)
compress() accepts a list of message dictionaries and returns a new list.
The returned messages include _orig_idx, which records their position in the
original trace.
For arbitrary message shapes, use compress_any() instead. It normalises
common message and envelope formats, compresses them, then restores the
original structure by default:
from dagc import compress_any
compressed_payload = compress_any(request_payload, target_reduction=0.85)
Configure production adapters
The default adapters are useful for getting started, but a tokenizer and embedding model matched to your application usually produce better results.
import dagc
from dagc.adapters import SentenceTransformerEmbedder, TiktokenTokenizer
dagc.configure(
tokenizer=TiktokenTokenizer("cl100k_base"),
embedder=SentenceTransformerEmbedder("all-MiniLM-L6-v2"),
)
See examples/byok_openai_embeddings.py for a Mistral embedding example and examples/langgraph_style_node.py for a workflow-node example.
Tuning
from dagc import DAGCConfig, compress
cfg = DAGCConfig(TARGET_REDUCTION=0.90, KEEP_LAST_K=3)
compressed = compress(messages, cfg=cfg)
# Equivalent inline overrides:
compressed = compress(messages, TARGET_REDUCTION=0.90, KEEP_LAST_K=3)
| Field | Default | Purpose |
|---|---|---|
TARGET_REDUCTION |
0.87 |
Requested fraction of tokens to remove. |
KEEP_LAST_K |
1 |
Retains the latest messages as protected context. |
PROTECT_TOOL_CALLS |
True |
Protects tool-call messages during selection. |
PROTECT_JUDGMENTS |
True |
Protects assistant judgments and confirmations. |
USE_CAUSAL_SKELETON |
True |
Uses the causal message graph during selection. |
Protected messages may still have their content shortened when
COMPRESS_PROTECTED=True (the default). Use the settings in DAGCConfig to
adjust those caps for your application.
How compression works
- The extractor identifies tool calls, decisions, and confirmations, then collects the IDs, paths, values, and rationale associated with them.
- The first selection phase reserves budget for decision-critical evidence.
- The remaining budget is filled with causally relevant, task-relevant sentences while reducing redundant context.
- A final pass checks for missing critical values and adds available evidence back when needed.
This is heuristic software, so evaluate it with your own traces before relying on a specific reduction target in production.
Evaluate a trace
dagc_eval measures whether a compressed trace still has enough information
to reproduce the decisions in the original trace.
from dagc_eval import TASKS, compute_drr, generate_trace
trace = generate_trace(TASKS[0])
result = compute_drr(trace)
print(result["DRR_soft"], result["RCI"])
The default evaluation path is deterministic and runs offline. You can also pass a BYOK client for reconstruction attempts that need an LLM:
import openai
from dagc_eval import compute_drr
from dagc_eval.interfaces import OpenAIChatClient
llm = OpenAIChatClient(openai.OpenAI())
result = compute_drr(trace, llm=llm)
The command-line interface exposes the same workflows:
dagc compress trace.json --target-reduction 0.85 -o compressed.json
dagc evaluate trace.json -o report.md
dagc benchmark --n-traces 3 -o benchmark.json
Optional proxy
Install the server extra to run the wire-compatible compression proxy:
pip install "dagc[server]"
export UPSTREAM_BASE_URL="https://your-llm-provider.example"
dagc-server
The proxy looks for a messages, trace, conversation, or turns array in
the request body. If compression fails, it forwards the original request
unchanged.
Project layout
src/dagc/ Core compression, formats, adapters, and graph utilities
src/dagc_eval/ Evaluation, benchmarks, diagnostics, exports, and proxy server
examples/ Runnable integration examples
tests/ Unit and format-robustness tests
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dagc-0.1.0.tar.gz.
File metadata
- Download URL: dagc-0.1.0.tar.gz
- Upload date:
- Size: 71.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
81f516c12ed3b2d18e75ff00a31720963fa54d75a5db49e733fccce703571a98
|
|
| MD5 |
2ba8f0e8ff9a094450c6be29b717a98b
|
|
| BLAKE2b-256 |
1abba19b1c8ea3da882670013c0f71b550c5d490a083cd0c35e6c4ac111182c5
|
File details
Details for the file dagc-0.1.0-py3-none-any.whl.
File metadata
- Download URL: dagc-0.1.0-py3-none-any.whl
- Upload date:
- Size: 70.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
70793134dc47dfb3d37a1b798fe3bc9e985fed187e1509a8e58f477e1f0d45e5
|
|
| MD5 |
3f24f596a1a0ec42466ea9ba620c7e8e
|
|
| BLAKE2b-256 |
a8c83766a46e2ece64db87743ae5ec09118b6afff67f1cf81bf7869be695ce55
|