AgentwatchConsole
Reference

Guarantees

Monitoring that can take down the thing it monitors is worse than no monitoring.

The SDK is built around one constraint: it must be impossible for AgentWatch to affect your agent's behaviour. Everything below follows from that.

It cannot add latency

Traces are POSTed outside the awaited path. Your wrapped function resolves, the value returns to your caller, and the delivery happens after that. The request your user is waiting on never waits on ours.

  • The timeoutMs ceiling exists so a hung connection cannot accumulate open sockets in a long-lived process — not to bound anything your caller is waiting on.
  • Payloads are capped at maxPreviewLength characters per field, so a pathologically long output cannot turn into a slow upload.

It cannot throw

Delivery failures are swallowed. A network partition, an expired key, an outage on our side — none of it produces an exception in your process. Your agent keeps serving traffic untraced, which is the correct failure mode.

That applies to wrapped executions, where nothing is waiting for a result to report. aw.trace() is the deliberate exception: you awaited it, so it resolves to { accepted, reason } and tells you what happened. It still never rejects.

The cost of that choice

For wrapped calls, silence is indistinguishable from success — a wrong API key and a mistyped agent UUID both produce exactly the behaviour you see when everything is fine. Set debug: true to break that silence, or send one manual trace and read its reason.

It cannot change behaviour

watch() returns a function with the same signature as the one you gave it. Arguments pass through untouched, the resolved value is returned unmodified, and thrown errors are re-thrown as-is — the same object, with its stack intact.

ts
const runAgent = watch(myAgentFn, { apiKey, agentId })

// Both of these hold, before and after wrapping:
await runAgent(query) === await myAgentFn(query)   // same value
await runAgent(bad).catch(e => e)                   // same error object
the wrapper is observationally transparent

What leaves your process

Per traced call, one POST containing:

  • The captured input and output, truncated to maxPreviewLength.
  • Latency, status, and — where available — model, token counts, and tool names.
  • Whatever you put in metadata and agentInstructions.

Nothing is read from the environment beyond what you pass in, and no other arguments to your function are captured. If an input carries data you would rather not send, lower maxPreviewLength or redact before the wrapped boundary — see Configuration.

License

MIT. The scoring engine is not in the package — CUSUM and EWMA change-point detection, the LLM-judge correctness gate, and semantic-drift scoring all run server-side on the traces this client sends.