Heuristic:Wandb Weave Sentinel Value Handling
| Knowledge Sources | |
|---|---|
| Domains | Integrations, Tracing, Debugging |
| Last Updated | 2026-02-14 12:00 GMT |
Overview
Cached sentinel detection pattern for filtering out LLM SDK placeholder values (NOT_GIVEN, omit) from traced function inputs.
Description
LLM provider SDKs (OpenAI, Anthropic, Cohere, Cerebras) use special sentinel values as default parameters to distinguish "not provided" from explicit `None`. When Weave traces these function calls, it must detect and exclude these sentinel values from the recorded inputs to avoid polluting traces with meaningless defaults. The detection uses a cached identity-check pattern that only imports sentinel values if the respective package is already loaded in `sys.modules`, preventing unnecessary import side effects.
Usage
Use this heuristic when debugging why certain default parameters appear or don't appear in traced calls, when adding a new LLM integration that uses sentinel patterns, or when understanding the op decoration pipeline. This affects how `@weave.op` processes and records function arguments.
The Insight (Rule of Thumb)
- Action: When adding a new LLM integration with sentinel values, add a `Sentinel` entry to the `_sentinels_to_check` list in `weave/trace/op.py`.
- Value: Each entry needs: `package` (import name), `path` (module path), `name` (attribute name).
- Trade-off: Adding sentinels improves trace cleanliness but requires maintenance as SDKs evolve.
- Action: Always use identity checks (`is`) not equality (`==`) for sentinel comparison.
- Value: Sentinel values are typically singleton instances; identity check is both correct and fast.
- Trade-off: None — identity check is strictly better for singletons.
- Action: Cached sentinels are checked first (O(1) dict lookup), then uncached sentinels are lazily loaded.
- Value: Cache prevents repeated imports; only imports when package is already in `sys.modules`.
- Trade-off: Cache memory is negligible; import avoidance prevents side effects and startup cost.
- Action: Special handling for `openai.Omit` — it's a class (type), not an instance, so requires `isinstance` check in addition to identity check.
- Value: Both `param.default is sentinel` and `isinstance(param.default, sentinel)` are checked.
- Trade-off: Slightly more complex but handles both singleton instances and class-based sentinels.
Reasoning
Without sentinel filtering, every traced OpenAI/Anthropic/Cohere call would include dozens of `NOT_GIVEN` values in its inputs, making traces noisy and harder to read. The lazy-import pattern is critical because importing provider SDKs can be expensive and may have side effects (e.g., network calls for API key validation). By checking `sys.modules` first, the sentinel detection is zero-cost for providers that aren't being used.
The `_SENTINEL_CACHE` dictionary uses the `Sentinel` dataclass (which is frozen/hashable) as keys, ensuring efficient lookups and preventing duplicate imports.
Code Evidence
Sentinel definitions from `weave/trace/op.py:89-109`:
_SENTINEL_CACHE: dict[Sentinel, Any] = {}
@dataclass(frozen=True)
class Sentinel:
package: str
path: str
name: str
_sentinels_to_check = [
Sentinel(package="openai", path="openai._types", name="NOT_GIVEN"),
Sentinel(package="openai", path="openai._types", name="omit"),
Sentinel(package="openai", path="openai._types", name="Omit"),
Sentinel(package="cohere", path="cohere.base_client", name="COHERE_NOT_GIVEN"),
Sentinel(package="anthropic", path="anthropic._types", name="NOT_GIVEN"),
Sentinel(package="cerebras", path="cerebras.cloud.sdk._types", name="NOT_GIVEN"),
]
Lazy import pattern from `weave/trace/op.py:112-140`:
def _check_param_is_sentinel(param: inspect.Parameter, sentinel: Sentinel) -> bool:
if sentinel in _SENTINEL_CACHE:
return param.default is _SENTINEL_CACHE[sentinel]
if sentinel.package in sys.modules:
try:
module = __import__(sentinel.path, fromlist=[sentinel.name])
sentinel_value = getattr(module, sentinel.name)
_SENTINEL_CACHE[sentinel] = sentinel_value
if param.default is sentinel_value:
return True
except (ImportError, AttributeError):
_SENTINEL_CACHE[sentinel] = None
return False
Combined identity and isinstance check from `weave/trace/op.py:148-156`:
for sentinel in _SENTINEL_CACHE.values():
if sentinel is not None:
if param.default is sentinel:
return True
if isinstance(sentinel, type) and isinstance(param.default, sentinel):
return True