Agent Observability & Tool Caching
Punk observes model calls at the gateway, but production agents also do useful work outside the model request: CRM reads, web fetches, ticket writes, email sends, database checks, and other tools. The SDK adds that missing context.
Use traceTool(...) when you need tool-call evidence, side-effect classification, read-only tool-result caching, replay safety, and policy visibility.
Install
npm install @punktechnologies/sdk
Create one client per app, agent, and optional subject identity:
import { Punk } from "@punktechnologies/sdk";
const punk = new Punk({
app: "support-app",
agent: "triage-agent",
subject: "user-123"
});
new Punk() also reads PUNK_BASE_URL, PUNK_API_KEY, PUNK_APP, PUNK_AGENT, and PUNK_SUBJECT; explicit options override the environment.
Trace A Read-Only Tool
const lookupAccount = punk.traceTool({
name: "crm.lookupAccount",
sideEffectLevel: 1,
ttlSeconds: 300,
execute: async (args: { accountId: string }) => crm.get(args.accountId)
});
const chat = await punk.openai.chat({
model: "gpt-4o-mini",
messages: [{ role: "user", content: "Classify ticket for acct_42." }]
});
const account = await punk.withRun(chat, () =>
lookupAccount({ accountId: "acct_42" })
);
Because this tool is level 1 and has a TTL, Punk can cache the result per tenant/app/subject safety dimensions. The tool still executes normally if tracing or cache calls fail; telemetry never breaks the user path.
Side-Effect Levels
| Level | Meaning | Example | Cache behavior |
|---|---|---|---|
| 0 | Pure computation | parse, format, math | Cacheable with TTL. |
| 1 | Read-only external | CRM read, search, fetch | Cacheable with TTL. |
| 2 | Reversible/idempotent write | upsert with idempotency key | Not cached; planned side effect recorded. |
| 3 | User-visible write | email, Slack, ticket creation | Not cached; policy and replay/shadow suppression apply. |
| 4 | High-impact write | payment, deletion, permission change | Not cached; approval posture should be strict. |
Undeclared tools default to level 3. That is conservative: user-visible writes should not be replayed or cached by accident.
Trace A Write Tool
const sendEmail = punk.traceTool({
name: "email.send",
sideEffectLevel: 3,
execute: async (args: { to: string; body: string }) => mailer.send(args)
});
await punk.withRun(chat, () =>
sendEmail({ to: "customer@example.com", body: "We are looking into this." })
);
Wrap related tools in the same withRun(...) callback when they belong to the same model run. You can still pass { runId } explicitly when framework boundaries make context wrapping awkward.
For side-effect levels 2 and higher, Punk records side_effect.planned before execution. Replay and shadow runs can suppress those actions while still proving whether the optimized route would have chosen the same plan.
Read Evidence
const detail = await punk.runDetail(chat.runId);
console.log(await punk.explain(chat.runId));
console.log(detail.events);
console.log(await punk.sideEffectsForRun(chat.runId));
console.log(await punk.savingsForRun(chat.runId));
await punk.feedback(chat.runId, 1);
Tool traces, feedback, and route explanations feed the learning loop. Promotion still requires replay and shadow evidence before an artifact can serve future traffic.
Read next: SDK, Governance, OpenAI-Compatible AI Gateway.