Bring your own agent
Runtype is a set of components, not only a hosted runtime. An agent built with Flue, the Cloudflare Agents SDK, the Vercel AI SDK, LangGraph, the OpenAI Agents SDK, Mastra, or your own loop can keep running where it runs today and still use Runtype’s Runs and Logs, trace trees, cost estimates, eval capture, Persona chat widget, surfaces, and the trace-to-eval improvement loop.
This page is the map. Pick the lane that serves what you need; the lanes compose.
Three lanes
What each lane gives you
Be precise about the two eval steps: capturing a case needs a transcript on the run, and re-running a suite needs Runtype to be able to call the agent.
Before you begin
- Create an agent to own the runs. Ingested traces are filed under a
Runtype agent ID. Any agent works as an attribution target; for lane B,
create it as an
externalagent. Read theagent_...ID from the agent’s page orlist_agents. - Create a telemetry API key. On the dashboard Settings → API Keys
page, choose the Telemetry Ingest permission group (
TELEMETRY:WRITE, append-only). Steps: Create a telemetry API key.
Lane A: send telemetry to Runtype
Flue on Cloudflare Workers, no code
Flue 2 agents deployed with @flue/vite and @cloudflare/vite-plugin are traced
by Workers Observability automatically: an invoke_agent span per run, a chat
span per model turn, and an execute_tool span per tool call, in OpenTelemetry
GenAI semantic conventions with conversation content included by default.
Export those traces to Runtype:
-
In the Cloudflare dashboard, open Workers Observability and add a destination of type Traces. Set the endpoint to
https://api.runtype.com/v1/otel/v1/tracesand add two custom headers:Exporting Workers traces to an OTLP destination requires a Workers Paid plan.
-
Reference the destination in
wrangler.jsoncand sample every request while you iterate:wrangler.jsonc -
Build and deploy (
npx vite build && npx wrangler deploy), then run one conversation. It appears under the agent’s Runs with a transcript, so you can capture it as an eval case.
To keep prompts and tool payloads out of the export, register
instrument(createCloudflareTracing({ content: false })) from
@flue/runtime/cloudflare at module scope in app.ts. This also removes the
transcript, and with it eval capture.
Think apps use the same destination and store no payloads unless the agent
class sets storeMessages = true and storeTools = true. An app built on the
Cloudflare Agents SDK (agents) requires explicit model instrumentation:
swap
the ai import for wrapAISDK(ai, { storeMessages: true, storeTools: true })
from agents/observability/ai. Local captures grouped WebSocket turns into
one trace; deployed captures used separate traces for turns and approval
continuations. Runtype currently files one run per trace, so a request paused
for approval can appear as multiple runs. Logical-run support remains
incomplete. See
Cloudflare Agents SDK
for the current status before pointing one at Runtype.
Workers infrastructure requests and force-closed spans can carry agent attribution without agent activity telemetry. Runtype retains them in Logs as diagnostics and creates no Run when they have no GenAI operation, model or inference signal, or recognized Runtype execution telemetry.
Flue on Node, Cloud Run, or another host
Flue’s instrument() accepts either of two instrumentations. Point exactly one
of them at Runtype; both emit an invoke_agent span per run, so exporting both
to the same endpoint doubles token counts and cost.
Both need your application to own the OpenTelemetry SDK and exporter. The full pipeline, attribution options, and flush rules are in Instrumenting a Flue agent.
Any OpenTelemetry-instrumented agent
Use the stock exporter settings. Runtype accepts OTLP over HTTP, not gRPC:
Runtype reads invoke_agent, chat, and execute_tool spans anywhere in the
trace (an enclosing HTTP server span is fine) and the GenAI content attributes
for the transcript. Details, attribution precedence, and the JSON compatibility
endpoint: Reporting telemetry from an external agent.
Lane B: let Runtype call your agent
Register the agent with its endpoint through POST /v1/agents (the MCP
create_agent tool takes the same fields as agent_type and external_config):
A runtype-stream endpoint answers POST {endpoint} with a JSON body of
{ "messages": [{ "role": "user", "content": "..." }], "context": { "conversationId": "..." } }
and streams a text/event-stream response in Runtype’s unified event
vocabulary: execution_start first, text and tool frames in between, and one
terminal execution_complete or execution_error last, with each frame’s SSE
id: mirroring its 0-based seq. The event schemas are the
ExecutionStreamEvent union in the API reference, the same
stream the Runtype API emits for its own agents. For a Flue agent, one route
does the work: run the turn with init(agent, { id: conversationId }) and
handle.dispatch(message), then map each chunk that handle.read(receipt, { onEvent })
delivers onto the matching unified frame. Omit protocol for an endpoint that
speaks A2A JSON-RPC.
Once registered, test the agent from its dashboard page, the MCP execute_agent
tool, or the SDK; add it to a product as a capability; or generate a Persona
embed for it.
The improvement loop for an external agent
Improving your agents from production traces describes the loop for hosted agents. For an external agent, two steps change:
- Fix happens in your repository, not with
update_agent. - Verify with
run_eval_suiteonly when Runtype can call the agent (lane B over A2A). Otherwise re-run the scenario against your redeployed agent and inspect the resulting run. The captured cases remain the regression record.
Runs ingested over telemetry show an external badge in the Runs view, and their timings and cost are what the agent reported rather than what Runtype metered.
Troubleshooting
-
Verify the key and endpoint with an empty export. The response is
200with{}; a403means the key lacksTELEMETRY:WRITE.cURL smoke test -
A run that stays in flight never received its closing
invoke_agentspan. Flush the provider before the process exits or the handler returns. -
A rejected trace with
ambiguous_agent_attributionmeans two invocations shared one trace or no attribution source resolved. Set theruntype.agent.idresource attribute or thex-runtype-agent-idheader. -
An attributed trace with no Run has no GenAI operation, model or inference signal, or recognized Runtype execution telemetry. Runtype retains it as a diagnostic in Logs.
-
A
500response while exporting a diagnostic trace means Runtype could not retain it durably. Retry the export. Runtype has not accepted the trace. -
Doubled tokens and cost mean two instrumentations export to the same endpoint.
-
A tool card that reads “No tool content in this trace” means content capture is off on the producer.
-
A
partial_successresponse in the exporter log means some traces named an agent the key cannot use; the accepted traces are stored.
Next steps
- Instrumenting a Flue agent: the Node pipeline, attribution, and tool-content options.
- Reporting telemetry from an external agent: the generic OTLP contract.
- Improving your agents from production traces: the capture-fix-verify loop.
- Connect Runtype to coding agents: run the loop from Claude Code, Cursor, or Codex.