Observability · Guide
Getting started
Install the package, give it a token, and produce a trace you can click through in Console — without touching a framework yet. Roughly five minutes, and the offline part costs nothing.
1. Pick the package
One library, two published packages. They share a version number and a changelog, and mirror each other's structure.
| Language | Package | Registry | Requires |
|---|---|---|---|
| TypeScript / JavaScript | @cognipeer/observability | npm | Node.js 18+ |
| Python | cognipeer-observability | PyPI | Python 3.9+ |
2. Install
pip install cognipeer-observability # core only, no dependencies
pip install "cognipeer-observability[langchain]" # add the framework you use
pip install "cognipeer-observability[all]" # every integrationnpm install @cognipeer/observabilityThe core has no required dependencies in either language. In Python, framework support arrives through extras; in TypeScript, through optional peer dependencies that nothing loads until you import the matching subpath. Installing this package cannot drag your dependency tree around.
3. Get a token
In Console, go to Settings → API Tokens → Create Token and enable the tracing service on it. The value is shown once.
export COGNIPEER_API_KEY="cpeer_…"
# Self-hosted Console? Point at the host root — the SDK appends the API path itself.
export COGNIPEER_BASE_URL="https://console.acme.internal"With no key present the library disables itself, warns once, and every integration becomes a no-op. That is deliberate: a misconfigured environment must not be able to take down a traced application.
4. Your first trace
This one needs no framework and no model provider, so it runs offline and free. It opens a session, records a step, and records a model call by hand with the tokens and the tool menu it was offered.
import cognipeer_observability as cognipeer
from cognipeer_observability import observe, trace
cognipeer.init(agent={"name": "first-trace", "version": "0.1.0"})
@observe(type="tool_call", tool_name="search")
def search(query: str) -> list[str]:
return ["result-a", "result-b"]
with trace(name="first-trace", thread_id="conv-1") as session:
session.open_span(
"turn-1",
type="ai_call",
label="gpt-4.1-mini",
model="gpt-4.1-mini",
sections=[{"kind": "message", "role": "user", "content": "where is my order?"}],
)
search("order status")
session.close_span(
"turn-1",
sections=[{"kind": "message", "role": "assistant", "content": "Checking now…"}],
input_tokens=1200,
output_tokens=64,
)
cognipeer.flush() # a script can exit before the export landsimport { init, observe, trace, flush } from '@cognipeer/observability';
init({ agent: { name: 'first-trace', version: '0.1.0' } });
const search = observe(async (query: string) => ['result-a', 'result-b'], {
type: 'tool_call',
toolName: 'search',
});
await trace({ name: 'first-trace', threadId: 'conv-1' }, async (session) => {
session.openSpan('turn-1', {
type: 'ai_call',
label: 'gpt-4.1-mini',
model: 'gpt-4.1-mini',
sections: [{ kind: 'message', role: 'user', content: 'where is my order?' }],
});
await search('order status');
session.closeSpan('turn-1', {
sections: [{ kind: 'message', role: 'assistant', content: 'Checking now…' }],
inputTokens: 1200,
outputTokens: 64,
});
});
await flush(); // a script can exit before the export landsRun it, then open Tracing → Sessions in Console. The run appears within a second or two under the agent.name you set, with the model call, its messages and tokens, and search nested underneath as a child.
Flush before a short-lived process exits
Exports are asynchronous by design, so a script, a Lambda handler or a CI job can finish while the last request is still in flight. flush() waits for the queue; shutdown() ends every still-open session first, then flushes. A long-running service needs neither.
5. Attach your framework
The two-line integration replaces step 4 entirely — you keep init(), and the framework's own seam produces the events. Each framework has one guide, on the Console side:
LangChain · LangGraph · OpenAI Agents SDK · Claude Agent SDK · Vercel AI SDK · n8n · Anything OpenTelemetry · Anything else
For the framework-by-framework version of this page, with the wiring snippet for each, see the Console quickstart.
Configuration
Everything reads from the environment, so the code above runs unchanged across dev, staging and production.
| Variable | Default | Meaning |
|---|---|---|
COGNIPEER_API_KEY | — | Console API token. Without it, tracing disables itself and warns once. |
COGNIPEER_BASE_URL | https://console.cognipeer.com | Your Console, for self-hosted installs. Host root, not the API path. |
COGNIPEER_AGENT_NAME | — | Default agent name on every session |
COGNIPEER_AGENT_VERSION | — | Default agent version on every session |
COGNIPEER_CAPTURE_CONTENT | all | all, metadata (structure and tokens, no message bodies) or none |
COGNIPEER_TRACING_ENABLED | true | Master switch |
COGNIPEER_TRACING_MODE | auto | auto, stream (live updates) or batch (one request per run) |
COGNIPEER_DEBUG | false | Log every request the exporter makes, and every failure it swallowed |
Any of these can also be passed to init() — as options in TypeScript, as keyword arguments in Python — and an explicit value takes priority over the environment. The full option set, including redaction patterns, content caps, retries and the delivery thresholds, is in the API reference.
Before production
- Decide what content leaves the process.
COGNIPEER_CAPTURE_CONTENT=metadatakeeps the run structure, tool names, tokens and latency but sends no message bodies. - Set an agent name and version. The version is what makes a before-and-after comparison possible after a prompt change.
- Set a thread id. It is the one thing worth doing beyond the two lines: a
threadId(orthread_id, orgroup_id, depending on the framework) groups a conversation's runs in Tracing → Threads. Use whatever key your application already has — a chat id, a ticket number, a user session.
Next
- JavaScript and TypeScript — subpaths, peers, runtimes, the bundled CLI
- Python — extras, modules, the decorator's four forms
- Examples — runnable programs per framework
- Troubleshooting — when nothing shows up

