TokenPolice
Docs
SDK reference

Naming steps: set_span_name

Give the next LLM span a readable name. Note the Node scope-local rule.

By default an LLM span is named after the model. When one call is really "the summarizer" or "the router," name it — the label shows up in traces and can be matched by rules.

set_span_name labels the next LLM span only. It's consumed once, then cleared; the call after that goes back to the model name.

import token_police as tp

tp.set_span_name("summarize")
summary = client.chat.completions.create(...)   # this span is "summarize"

client.chat.completions.create(...)             # back to the model name

Node:

import * as tp from "token-police";

tp.setSpanName("summarize");
await client.chat.completions.create(/* ... */);

The Node scope-local gotcha

In Python, set_span_name works anywhere — it's stored on a context variable.

In Node, setSpanName is scope-local: it only takes effect inside a session / agent / chain / workflow scope. Call it at the top level, outside any wrapper, and it's a silent no-op — the span keeps its model name and nothing errors.

Node: name your spans inside a wrapper. If setSpanName seems to do nothing, that call isn't inside a session / agent / chain / workflow — wrap the work first (see Wrapping your app).

// ✅ Node — inside a scope, the name sticks
await tp.workflow({ name: "report" }, async () => {
  tp.setSpanName("summarize");
  await client.chat.completions.create(/* ... */);
});

Next