Skip to main content

AI context observability. See what your LLM saw.

Project description

SeeCtx

AI context observability. See what your LLM saw.

SeeCtx captures a ContextPack for every LLM call your agent makes — what context went in, what got excluded and why, which model was used, what came out, and what it cost. One line of code. Zero config.

pip install seectx[openai,server]
from seectx import wrap, serve
from openai import OpenAI

client = wrap(OpenAI())

# Use the client exactly as before — every call is now captured
response = client.chat.completions.create(
    model="gpt-4o",
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "What is context engineering?"},
    ]
)

serve()  # Open http://localhost:4100

For short scripts, call flush() before the process exits, or use an explicit run session so SeeCtx can close the run cleanly:

from seectx import flush, start_run, wrap
from openai import OpenAI

with start_run(app_name="support-agent"):
    client = wrap(OpenAI())
    client.chat.completions.create(
        model="gpt-4o",
        messages=[{"role": "user", "content": "Summarize this ticket"}],
    )

# Optional outside a context manager; useful in notebooks and scripts.
flush()

Why

You're building AI agents. They call LLMs dozens of times per run. Each call gets a different context window — different system prompts, retrieved documents, tool results, conversation history. When something goes wrong, you're staring at logs trying to reconstruct what the model actually saw.

SeeCtx records the full context assembly for every step. Not just the input/output — the decisions: what sections were included, what was rejected (and why), how the token budget was spent, and how context drifted step over step.

Integrations

OpenAI

from seectx import wrap
from openai import OpenAI

client = wrap(OpenAI())
# All chat.completions.create() calls are now captured

Anthropic

from seectx import wrap
import anthropic

client = wrap(anthropic.Anthropic())
# All messages.create() calls are now captured

LangGraph

from seectx import observe

graph = observe(build_my_agent())
result = graph.invoke({"input": "resolve this case"})
# Every LLM call in every node — captured with delegation links

Transparent Proxy (Zero Code Changes)

Intercept any LLM traffic without modifying your application. The proxy auto-detects Anthropic, OpenAI, and Ollama request formats on the same port.

# Start proxy + viewer in one command
seectx proxy --provider ollama --port 4050 --viewer-port 4100

Or from Python:

from seectx import proxy

proxy(provider="ollama", proxy_port=4050, viewer_port=4100, working_dir=".")

Point your client at the proxy instead of the real API:

from openai import OpenAI

# Instead of connecting to Ollama directly, go through SeeCtx
client = OpenAI(base_url="http://localhost:4050/v1", api_key="unused")
response = client.chat.completions.create(
    model="llama3.2",
    messages=[{"role": "user", "content": "Hello"}]
)

Works with any provider:

Provider Proxy command Client base URL
Ollama seectx proxy --provider ollama http://localhost:4050/v1
OpenAI seectx proxy --provider openai http://localhost:4050/v1
Anthropic seectx proxy --provider anthropic http://localhost:4050

Every API call appears in the viewer at http://localhost:4100 in real time.

What Gets Captured

Each ContextPack records:

Layer What you see
Sections Every piece of context — system prompt, user message, tool results, retrieval chunks, memory, instructions. 8 section types.
Token Budget How many tokens each section used. What got rejected and why (budget exceeded, relevance filtered, TTL expired, duplicate, policy blocked, dependency missing, manual exclusion).
Model Provider, model name, temperature, max_tokens, top_p, stop sequences.
Output Generated text, tool calls with arguments, stop reason.
Metrics Latency, input/output tokens, cache hits, estimated cost (40+ models priced).
Multi-Agent Parent run, parent step, delegation scope, inherited sections — full lineage across agent handoffs.

Features

Context Assembler

Budget-aware context builder with automatic rejection tracking:

from seectx import ContextAssembler

assembler = ContextAssembler(budget=4000)
assembler.add(system_prompt_section)
assembler.add(retrieval_section)      # auto-rejected if budget exceeded
budget = assembler.build_budget()     # includes rejection ledger

Redaction Policies

Ship ContextPacks without leaking sensitive data:

from seectx import set_redaction_policy, RedactionPolicy

set_redaction_policy(RedactionPolicy.HASH)       # SHA-256 all content
set_redaction_policy(RedactionPolicy.TRUNCATE)    # First 100 chars only
set_redaction_policy(RedactionPolicy.DROP_CONTENT) # Structure without content

Stored ContextPacks include a redaction_policy field so the viewer and audit exports can tell whether raw content, hashes, truncated content, dropped content, or a custom redactor was used.

Local Deletion

SeeCtx stores captures locally by default. Delete one run or purge a storage directory from the CLI:

seectx rm <run_id> --dir .seectx
seectx purge --dir .seectx

Context Drift Detection

Track how context evolves across steps:

from seectx import diff_context_packs

diff = diff_context_packs(step_1_pack, step_2_pack)
# Shows added, removed, and modified sections between steps

Source Discovery

SeeCtx scans your working directory to build a Source Inventory — everything that was available to the context assembly process, not just what made it into the LLM call.

from seectx import discover_sources

inventory = discover_sources(working_dir=".")
print(f"{inventory.total_sources} sources, {inventory.total_tokens_available:,} tokens available")

Automatically detects 15+ context source patterns:

Pattern Type
SKILL.md Skill (Claude)
CLAUDE.md, .claude/settings.json Agent config
.cursorrules, .cursor/rules/ Agent config (Cursor)
.clinerules, .windsurfrules Agent config
.github/copilot-instructions.md Agent config (Copilot)
.mcp.json, mcp.json Tool definition (MCP)
system_prompt.txt, system_prompt.md Agent config
.env, .env.local Environment
.py, .ts, .go, etc. Code files
.md, .txt, .rst Documentation

Respects .seectxignore for excluding paths. Hashes content (SHA-256) for change detection across steps.

Each source tracks a status: included (sent to LLM), considered (evaluated but not sent), available (on disk), excluded (filtered out), or stale (outdated version used).

This is the pre-assembly layer — SeeCtx's two-layer context model:

  • Layer 1: Source Inventory — What was available to the context builder
  • Layer 2: Wire Context — What was actually sent to the LLM

The gap between these two layers is where hallucinations, stale context, and assembly blind spots live.

Cost Estimation

Built-in pricing for 40+ models:

from seectx import estimate_cost

cost = estimate_cost("gpt-4o", input_tokens=1500, output_tokens=500)

Conformance Levels

Three levels of observability depth:

  • L1 Capture — Basic fields: sections, model, output, metrics
  • L2 Budget — Rejection ledger populated with exclusion reasons
  • L3 Multi-Agent — Delegation links across agent handoffs

ContextPack Format

ContextPack is an open JSON format. Here's what one looks like:

{
  "format_version": "0.1.0",
  "run_id": "run_abc123",
  "step_id": "step_0",
  "step_index": 0,
  "sections": [
    {
      "type": "system_prompt",
      "section_id": "sec_001",
      "source": "system",
      "token_count": 150,
      "content": "You are a customer support agent..."
    },
    {
      "type": "retrieval",
      "section_id": "sec_002",
      "source": "knowledge_base",
      "token_count": 800,
      "content": "Order #12345 was shipped on..."
    }
  ],
  "token_budget": {
    "total_budget": 4096,
    "total_used": 950,
    "rejected": [
      {
        "section_id": "sec_003",
        "section_type": "retrieval",
        "token_count": 3500,
        "reason": "budget_exceeded"
      }
    ]
  },
  "model": {
    "provider": "openai",
    "model": "gpt-4o",
    "temperature": 0.7
  },
  "output": {
    "type": "text",
    "text": "I can see your order #12345 was shipped...",
    "stop_reason": "stop"
  },
  "metrics": {
    "latency_ms": 1250,
    "input_tokens": 950,
    "output_tokens": 85,
    "cost_estimate_usd": 0.0034
  }
}

The full spec is in spec/CONTEXTPACK_SPEC.md with a JSON Schema at spec/context-pack.schema.json.

Installation

# Just OpenAI
pip install seectx[openai]

# Just Anthropic
pip install seectx[anthropic]

# LangGraph agents
pip install seectx[langgraph]

# With the viewer UI
pip install seectx[openai,server]

# Everything
pip install seectx[all]

Requires Python 3.10+.

Viewer

seectx serve
# or
python -c "from seectx import serve; serve()"

Opens a local UI at http://localhost:4100 showing all captured runs and steps. Three-column layout: run timeline, step detail with tabbed views (Context, Budget, Drift, Sources, Output, Model, Raw JSON), and a metadata sidebar.

Viewer Tabs

Tab What it shows
Context Every section in the context window, color-coded by type (system prompt, user message, tool result, retrieval, memory, instruction)
Budget Token allocation per section, rejected candidates with rejection reasons
Drift Visual diff between consecutive steps — what was added, removed, or modified
Sources Pre-assembly inventory: all upstream sources, inclusion status, compression ratio, source-level drift with insight metrics
Output Model response including tool calls with structured display
Model Provider, model name, temperature, parameters
Raw Full ContextPack JSON

Real-Time Testing

With Ollama

Terminal 1 — Start proxy + viewer:

cd your-project/
pip install seectx[all] openai
python -c "from seectx import proxy; proxy(provider='ollama', proxy_port=4050, viewer_port=4100, working_dir='.')"

Terminal 2 — Chat through the proxy:

python -c "from openai import OpenAI;client=OpenAI(base_url='http://localhost:4050/v1',api_key='unused');msgs=[];exec(\"while True:\n q=input('You: ')\n if q.lower()=='quit':break\n msgs.append({'role':'user','content':q})\n r=client.chat.completions.create(model='llama3.2',messages=msgs)\n print(f'\\n{r.choices[0].message.content}\\n')\n msgs.append({'role':'assistant','content':r.choices[0].message.content})\")"

Open http://localhost:4100 — every message appears live.

The proxy and viewer bind to 127.0.0.1 by default so captured context stays local. Use --host 0.0.0.0 only when you intentionally want to expose them to a container or trusted LAN.

With Anthropic (Claude)

# Terminal 1
python -c "from seectx import proxy; proxy(provider='anthropic', proxy_port=4050, viewer_port=4100, working_dir='.')"

# Terminal 2
export ANTHROPIC_API_KEY=your-key
python -c "from anthropic import Anthropic;c=Anthropic(base_url='http://localhost:4050');msgs=[];exec(\"while True:\n q=input('You: ')\n if q=='quit':break\n msgs.append({'role':'user','content':q})\n r=c.messages.create(model='claude-sonnet-4-20250514',max_tokens=1024,messages=msgs)\n print(f'\\n{r.content[0].text}\\n')\n msgs.append({'role':'assistant','content':r.content[0].text})\")"

With OpenAI

# Terminal 1
python -c "from seectx import proxy; proxy(provider='openai', proxy_port=4050, viewer_port=4100, working_dir='.')"

# Terminal 2
export OPENAI_API_KEY=your-key
python -c "from openai import OpenAI;client=OpenAI(base_url='http://localhost:4050/v1');msgs=[];exec(\"while True:\n q=input('You: ')\n if q=='quit':break\n msgs.append({'role':'user','content':q})\n r=client.chat.completions.create(model='gpt-4o',messages=msgs)\n print(f'\\n{r.choices[0].message.content}\\n')\n msgs.append({'role':'assistant','content':r.choices[0].message.content})\")"

CLI Reference

# Start proxy (captures LLM traffic) + viewer
seectx proxy --provider <ollama|openai|anthropic> [--port 4050] [--viewer-port 4100] [--working-dir .] [--host 127.0.0.1]

# Start viewer only (browse previously captured runs)
seectx serve [--port 4100] [--storage-dir ~/.seectx]

# List captured runs
seectx ls

# Inspect a specific run
seectx inspect <run-id>

Development

git clone https://github.com/arq-ai-labs/seectx.git
cd seectx
pip install -e ".[dev]"
pytest tests/ -v

License

Apache 2.0

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

seectx-0.1.0.tar.gz (134.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

seectx-0.1.0-py3-none-any.whl (113.5 kB view details)

Uploaded Python 3

File details

Details for the file seectx-0.1.0.tar.gz.

File metadata

  • Download URL: seectx-0.1.0.tar.gz
  • Upload date:
  • Size: 134.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for seectx-0.1.0.tar.gz
Algorithm Hash digest
SHA256 fc351f6558d0ad11c83245b7d3f2a70ba45f9e3dcf8150f5154f151a1ce3eff9
MD5 9dde0920e45736ec02a302bc46071a1b
BLAKE2b-256 f3b58ae05107ba8e0e542ead8d2c51e1200fa1b6f550789a28511415158ccdb2

See more details on using hashes here.

Provenance

The following attestation bundles were made for seectx-0.1.0.tar.gz:

Publisher: publish.yml on arq-ai-labs/seectx

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file seectx-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: seectx-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 113.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for seectx-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1edea14b77cdd89c065a2953578a6d5c8fc1d4467043d6abd9393ce0f31097b7
MD5 28035d5dc18a352019c9c88ae4034a77
BLAKE2b-256 84168370b144968af36efdc60adc358849d94e91c761c94428bf6b88ce29e646

See more details on using hashes here.

Provenance

The following attestation bundles were made for seectx-0.1.0-py3-none-any.whl:

Publisher: publish.yml on arq-ai-labs/seectx

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page