0.27.0 and Python 0.15.0. Registry availability is established by the completed release workflow. See VERSIONING.md for the versioning, deprecation and runtime support policy. Tested combinations establish the paths below; accepting standard OTLP is broader than testing every instrumentation library.
TypeScript outbound HTTP capture
Since TypeScript0.26.0, createHue and createHueTransport capture outbound HTTP identity by default. HTTP query arguments and supported text bodies follow captureContent; captureHttpBodies: false keeps identity only, and captureHttp: false disables capture. Disabled clients capture nothing. Capture observes request bytes and headers without adding traceparent or changing application headers.
Node.js 22 and 24 observe node:http, node:https, native fetch and undici through diagnostics and per-request byte callbacks. Installed-package loopback checks cover axios, node-fetch v2, got, gaxios, googleapis, Slack WebClient, undici fetch, Linear and Notion. Bun 1.4.2 observes Node HTTP clients and wraps global fetch without cloning or draining an unread response. Create Hue before clients that retain global fetch. Bun’s built-in node-fetch alias bypasses that wrapper; gaxios and googleapis using the alias need an explicit global-fetch implementation or Node. Bun’s fetch wrapper omits unobserved request bodies rather than consume them.
HTTP response content is raw parsed JSON, form fields, or text in output.value; request query and body fields use input.value. HTTP status and allowlisted behavior headers remain separate span attributes. URL userinfo, query strings, fragments and recognized credential-bearing path segments are removed from url.full; credential-named content fields are filtered before the existing redactor runs. Each side is bounded by the receiver’s value cap, 1 MiB by default. Over-cap sides export a structured OTLP truncation placeholder plus the affected key in hue.truncated. Gzip/x-gzip, zlib/raw deflate and Brotli bodies are decoded under the same cap at each encoding layer. Binary, unsupported, malformed, unread and aborted bodies can leave content unavailable. Existing HTTP spans are matched within the same provider and creation execution, once per physical request; Hue normalizes their identity on its export copy while other exporters retain their policy. Hue export traffic is excluded. Model-provider requests keep HTTP identity without content; application tools nested inside model callbacks resume content capture.
Borrowed provider value and count policies remain effective. Captured content accepted and then clipped by the provider exports a structured truncation marker; attributes dropped by its count limit remain absent. URI replacements over the provider’s attribute policy are omitted without a capture failure. Invalid or receiver-over-limit URI replacements report an instrumentation failure. Final spans and live placeholders follow the same policy. Hue also sanitizes HTTP URL-valued span resource.name aliases. Unmatched CLIENT spans have HTTP URLs in names and present URI aliases filtered before and after redaction within stored lengths, leaving missing attributes absent. Custom resource labels and other exporters’ original spans retain their policy.
Existing dependencies
Since Python0.14.0, Hue observes outbound HTTP through requests, httpx and httpx2 sync and async,
urllib.request, aiohttp, httplib2 and urllib3, without new runtime dependencies. Requests use
their existing bytes and headers. capture_http=False disables observation, and
capture_http_bodies=False retains identity without bodies. capture_content=False also disables
HTTP bodies. Captured content uses the existing redactor and credential filtering. URL userinfo,
query strings and fragments are excluded from identity attributes. Recognized credential-bearing
path formats are masked while ordinary identifiers remain. URL identity also passes through the
existing redactor as url.full, including metadata-only capture. Borrowed spans are sanitized
only in Hue’s export copy. Present http.url, http.target and url.path hooks follow the
canonical URL hook. Full URL aliases share the final URL, path aliases share its pathname,
url.query is removed and span names contain only the method.
HTTP URL-valued resource.name metadata is filtered independently in Hue’s copy, including parent
resources, live announcements and log resources, while ordinary service labels remain unchanged.
Captured values declare application/json; original content types are recorded as allowed HTTP
header attributes. Body capture is limited to
eligible text and JSON content, at most 1 MiB per side, with truncation marked. Streaming capture
observes only application-consumed bytes. Calls made through raw sockets, gRPC, WebSockets or
another process are outside this capture. See the Python HTTP capture guide.
Configured OpenTelemetry attribute limits remain authoritative: accepted body cuts use structured
markers, dropped keys remain absent and URI rewrites over the accepted value limit are omitted.
Since Python 0.15.0, raw gzip/x-gzip and zlib/raw deflate capture uses bounded standard-library decoding. Raw Brotli capture requires hue-run[compression] (Brotli >=1.2.1,<2); already-decoded responses need no extra. Encoded input and every decoded layer must fit the capture cap. Python capture permits at most eight encoding layers and sixteen concatenated gzip members per layer. The optional decoder can enable HTTP clients’ own Brotli negotiation; the base SDK adds no decoder or negotiation change. See the Python HTTP capture guide for decoder limits and unavailable content.
The optional HTTPX2 family is verified with httpx2==2.13.1.
@hue-run/sdk core can coexist with AI SDK 6 (installed-package validation covers 6.0.116). The hueTelemetry adapter still requires AI SDK 7 and a compatible @ai-sdk/otel peer; it explicitly rejects AI SDK 6. Keep AI SDK 6 instrumentation on its existing provider and attach Hue transport, or use a standard OTLP exporter. Do not force dependency resolution or upgrade a framework solely to add tracing.
Python declares opentelemetry-api, opentelemetry-sdk and opentelemetry-exporter-otlp-proto-http as >=1.40,<2, so hue-run installs next to applications and opentelemetry-instrumentation-* packages that are on a different OpenTelemetry 1.x release. uv.lock records the certified combination (OpenTelemetry 1.45.1) used by the frozen CI jobs and the release verification; a second CI job re-resolves every direct dependency at its declared floor (uv lock --resolution lowest-direct, OpenTelemetry 1.40.0) and runs the whole behavioral suite, including the installed wheel. The Python transport uses two OpenTelemetry internals, the instrumentation-suppression context key and the OTLP log encoder. Both are present in every release of the range and both are guarded: a missing log encoder raises an ImportError naming the supported range at import time, and a missing suppression key emits a one-time RuntimeWarning, after which Hue exports without OpenTelemetry suppression while its own queues still ignore its export work. A lockfile records what was tested; it does not certify every compatible-looking version.
Content and delivery
Earlier releases require an explicit capture choice. Disabled clients export nothing.
In metadata-only mode both SDKs drop attributes whose keys start with a recognized content prefix: OpenTelemetry GenAI (
gen_ai.input.messages, gen_ai.output.messages, gen_ai.system_instructions, gen_ai.prompt, gen_ai.completion, gen_ai.tool.call.arguments, gen_ai.tool.call.result, gen_ai.tool.definitions, gen_ai.event.content), OpenInference (input.value, output.value, input.images, output.images, llm.input_messages, llm.output_messages, llm.prompts, llm.completions, llm.choices, llm.function_call, llm.tools, llm.invocation_parameters, llm.prompt_template.template, llm.prompt_template.variables, retrieval.documents, embedding.embeddings, reranker.query, reranker.input_documents, reranker.output_documents), OpenLLMetry (traceloop.entity.input, traceloop.entity.output), Langfuse (langfuse.observation.input, langfuse.observation.output, langfuse.observation.status_message, langfuse.observation.model.parameters, langfuse.trace.input, langfuse.trace.output), Vercel AI SDK (ai.prompt, ai.response.text, ai.response.object, ai.response.reasoning, ai.response.files, ai.response.toolCalls, ai.response.body, ai.toolCall.args, ai.toolCall.result, ai.value, ai.values, ai.embedding, ai.embeddings), plus tool.parameters, exception.message and exception.stacktrace. Langfuse’s model name, usage and cost details, observation type, session and user identifiers, trace name, release, environment and metadata.* keys are metadata and pass through. The TypeScript list is exported as contentPrefixes; Python’s CONTENT_PREFIXES is identical and both test suites assert the full list. Unrecognized custom keys (for example a document’s metadata under a custom key) pass through. Before stripping, TypeScript copies the OpenAI hosted MCP serverLabel from a recorded AI SDK 7 extension tool result to mcp.server.name and marks a result carrying an MCP error with error.type mcp_error and ERROR status; both survive metadata-only export.
Neither SDK estimates unavailable token usage or cost. Queues are bounded and in memory; a successful model response does not establish telemetry delivery. Message content recorded through recordMessages / log_inference, including optional gen_ai.system_instructions, travels as the structured body of the gen_ai.client.inference.operation.details log record rather than as the Development-status event attributes; Hue’s receiver reads the body. model() records optional system instructions and tool definitions as the gen_ai.system_instructions and gen_ai.tool.definitions span attributes, only when content is captured (TypeScript 0.8.1, Python 0.5.1; since those releases). In both SDKs an explicit null field keeps its key with an empty value, so it stays distinct from an absent field. Both SDKs set gen_ai.operation.name, gen_ai.provider.name, gen_ai.request.model and gen_ai.conversation.id as attributes on that record when they are known from the enclosing model() span, the caller or the active session, and emit no record in metadata-only mode.
When content is captured, both SDKs (TypeScript 0.8.1, Python 0.5.1; since those releases) replace hosted-tool credentials with "[redacted]" before export: credential-like fields including authorization, authorization_token, headers, api_key, access_token, x-api-key, and keys ending in token, secret, password, apikey or credential (case-insensitively, ignoring - and _) in gen_ai.tool.definitions, ai.prompt.tools and llm.tools.*.tool.json_schema, and in the tools and mcp_servers entries of a raw request or response recorded as input.value, output.value or llm.invocation_parameters. Names of JSON Schema parameters under properties are kept. TypeScript applies redact afterwards. URL userinfo, query values and fragments are removed before export. A tool definition nested more than 256 levels deep rejects its record rather than being exported unchecked.
In metadata-only mode a record whose tool definitions are removed carries hue.tool.names (each definition’s name, Chat Completions function.name or the type of an unnamed built-in tool, in order) and hue.tool.definitions.sha256, the lowercase hex SHA-256 of the RFC 8785 canonical JSON of the credential-scrubbed definition list, taken from gen_ai.tool.definitions, else ai.prompt.tools, else llm.tools.{i}.tool.json_schema in index order. Both SDKs (TypeScript 0.8.1, Python 0.5.1; since those releases) derive the same names and digest from the same definitions; both suites check a shared fixture. Definitions that are not JSON, or longer than 1 MiB of text, produce no summary, and attributes a record already sets are kept. A metadata-only tools/list span from recordProviderToolCalls / record_provider_tool_calls carries the same summary of the listed tools.
Evaluation coverage
Both SDKs expose product-named eval set, evaluator, run and scoring client methods while retaining the older low-level names and v1 paths. They support frozen versions, local runs, built-in and custom evaluators, resumable result uploads and historical rescoring. Hosted judge job and budget methods are available, but credential resolution is not proof of a successful provider call. Activation belongs to the platform environment. Both local evaluation runners download and verify a case’s pinned input files before execution, and both can rescore files already saved on a subject. Python exposes agent-visible input files throughTargetContext.files and local storage through files_directory. TypeScript’s local runner additionally uploads documents returned by a target as verified Hue artifacts and supports connected local workers. Python’s local runner accepts JSON output, with no with_files helper or automatic generated-file uploads; Python also has no native local-worker implementation. Python managed targets separately return files through ManagedTargetResult.files and ManagedOutputFile, as described below. File handling needs a Hue deployment that serves case input files, subject files and the artifact APIs.
The clients do not yet expose every platform REST operation. Dataset editing/archival, case replacement/deletion, promotion from a trace, copying published scorers, experiment/run listing and frozen-trace snapshot reads are not convenience methods in these clients. Trace browsing for coding agents is served by the Hue MCP server with a Read and write key, or a Read key for inspect-only access, not by these clients. Open pull requests are not released functionality.
API responses are limited to 4 MiB by the clients. Full dataset pages can exceed this limit when cases contain large values. Use smaller explicit page limits when listing full cases; the local experiment runner separately reads summaries and individual cases. A response-size failure does not establish that the server rejected the request.
Hue-managed runs
The TypeScript and Python managed target adapters use the same versioned HTTP contract. Hue starts runs against a registered public HTTPS endpoint; the existing agent remains in its own environment. This release supports synchronous targets, verified file transfer, stored outcome recovery and deterministic platform scoring. Hosted AI judges, arbitrary hosted code, manual evaluators and asynchronous targets are outside this managed-run release. See managed runs.Failure isolation
Serving applications should usecreateHueSafe / create_hue_safe, enabled: false / enabled=False for a local kill switch, and bounded safe lifecycle methods. See TypeScript production setup and Python production setup. Helper capture failures omit telemetry, preserve business results/errors and increment diagnostic counters. TypeScript defaults to an 8 MiB combined trace/log queue budget; Python defaults to 8 MiB per signal, including in-flight records. These are telemetry budgets, not process RSS ceilings. A process kill, arbitrary slow user hook, third-party instrumentation or out-of-memory condition remains outside an in-process SDK guarantee.
App-launched local agents
runLocalAgent() shipped in TypeScript 0.3.0 with the restricted
runSimulation() candidate projection; generic evaluations remain compatible. Both paths share
the same provider-aware world lifecycle and uncertainty rules. A matching Hue API deployment is
required. Public package tests exercise local control-plane responses and connection-bundle
handling; they do not call an issued provider facade. These tests do not call the official Gmail
service or establish universal Gmail or Slack parity. Python does not
include a native local-worker implementation.
Scorer forward compatibility
Scorer deferral shipped in TypeScript0.3.1: only known builtin entries and bound local_code scorers execute locally.
Every other kind is reported in deferredScorerVersionIds without a local result upload,
including unknown kinds and built-in entries returned by a newer server. The responsible server or human executor
must complete those scores. Legacy local-code pins still require their exact callback binding.
The V2 connection bundle, provider transport, worker recovery and OpenTelemetry ownership remain
unchanged. Setup is a separate local inspection CLI, not a simulation launcher.