From 8046d9a79019736a35d18568ab9a26762e6032bc Mon Sep 17 00:00:00 2001 From: Pat Date: Sun, 15 Mar 2026 18:29:36 -0500 Subject: [PATCH] fix: coerce model to str() before storing in span data MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Codex review: if model kwarg is a non-JSON-serializable object (enum, wrapper type), json.dumps in the sink would crash BEFORE the LLM call runs — breaking the user's code. Previously model was only interpolated into the span name (implicit str), so this regression was introduced by adding data={"model": model}. Fix: str(kwargs.get("model", "unknown")) in all 4 patch variants. Co-Authored-By: Claude Opus 4.6 (1M context) --- sdk/agentguard/instrument.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sdk/agentguard/instrument.py b/sdk/agentguard/instrument.py index d86b75d..5ec0d25 100644 --- a/sdk/agentguard/instrument.py +++ b/sdk/agentguard/instrument.py @@ -235,7 +235,7 @@ def _traced_openai_create( original: Any, tracer: Any, budget_guard: Any, *args: Any, **kwargs: Any ) -> Any: """Shared traced wrapper for sync OpenAI create calls.""" - model = kwargs.get("model", "unknown") + model = str(kwargs.get("model", "unknown")) with tracer.trace(f"llm.openai.{model}", data={"model": model, "provider": "openai"}) as ctx: result = original(*args, **kwargs) _emit_llm_result(ctx, budget_guard, model, "openai", getattr(result, "usage", None)) @@ -294,7 +294,7 @@ def _patch_anthropic_instance(client: Any, tracer: Any, budget_guard: Any = None @functools.wraps(original_create) def traced_create(*args: Any, **kwargs: Any) -> Any: - model = kwargs.get("model", "unknown") + model = str(kwargs.get("model", "unknown")) with tracer.trace(f"llm.anthropic.{model}", data={"model": model, "provider": "anthropic"}) as ctx: result = original_create(*args, **kwargs) _emit_llm_result(ctx, budget_guard, model, "anthropic", getattr(result, "usage", None)) @@ -435,7 +435,7 @@ def _patch_openai_async_instance(client: Any, tracer: Any, budget_guard: Any = N @functools.wraps(original_create) async def traced_create(*args: Any, **kwargs: Any) -> Any: - model = kwargs.get("model", "unknown") + model = str(kwargs.get("model", "unknown")) async with tracer.trace(f"llm.openai.{model}", data={"model": model, "provider": "openai"}) as ctx: result = await original_create(*args, **kwargs) _emit_llm_result(ctx, budget_guard, model, "openai", getattr(result, "usage", None)) @@ -493,7 +493,7 @@ def _patch_anthropic_async_instance(client: Any, tracer: Any, budget_guard: Any @functools.wraps(original_create) async def traced_create(*args: Any, **kwargs: Any) -> Any: - model = kwargs.get("model", "unknown") + model = str(kwargs.get("model", "unknown")) async with tracer.trace(f"llm.anthropic.{model}", data={"model": model, "provider": "anthropic"}) as ctx: result = await original_create(*args, **kwargs) _emit_llm_result(ctx, budget_guard, model, "anthropic", getattr(result, "usage", None))