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

LaneWhat you doWhat it unlocks
A. Send telemetry to RuntypeExport OpenTelemetry traces to https://api.runtype.com/v1/otelThe Runs view, Logs, trace trees, token usage, and a display-only cost estimate. With conversation content on the spans: the run’s transcript and eval case capture.
B. Let Runtype call your agentRegister an external agent whose endpoint speaks Runtype’s unified stream (runtype-stream) or A2ATesting from the dashboard, MCP, or SDK; Persona chat widgets; surfaces and products; schedules. Tool calls and cost are recorded per run. An A2A endpoint can also be an eval suite target.
C. Run a Runtype agent on your cloudExport an agent authored in Runtype and host it with @runtypelabs/runtime (Self-hosting)The agent keeps reporting to Runtype from your infrastructure. Enterprise plan; the export endpoints are a limited preview.

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.

Runtype featureA: telemetry inB: Runtype calls the agent
Runs, Logs, trace tree, cost estimateYes over OTLP. The JSON endpoint POST /v1/executions/ingest produces Runs without a trace tree.Yes
Transcript on the runYes when the spans carry conversation content: the gen_ai.* content attributes, or a supported framework’s own vocabulary (Send traces from a supported framework)Yes
Capture a run as an eval caseYes with a transcript. Flue, the Vercel AI SDK, LangGraph, the OpenAI Agents SDK and Mastra all send one by default.Yes
Re-run an eval suite against the agentNoA2A endpoint: yes (recorded-tool replay cases are skipped). runtype-stream endpoint: no; re-run the scenario yourself and inspect the next run.
Persona chat, surfaces, products, schedulesNoYes

Before you begin

  1. 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 external agent. Read the agent_... ID from the agent’s page or list_agents.
  2. 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:

  1. 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/traces and add two custom headers:

    HeaderValue
    AuthorizationBearer rt_YOUR_TELEMETRY_KEY
    x-runtype-agent-idagent_YOUR_AGENT_ID

    Exporting Workers traces to an OTLP destination requires a Workers Paid plan.

  2. Reference the destination in wrangler.jsonc and sample every request while you iterate:

    wrangler.jsonc
    1{
    2 "observability": {
    3 "traces": {
    4 "enabled": true,
    5 "destinations": ["runtype"],
    6 "head_sampling_rate": 1,
    7 },
    8 },
    9}
  3. 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.

InstrumentationChoose it for
@runtypelabs/flue-otelThe improvement loop and loop analytics. From 0.5 it sends the transcript, system prompt and tool content by default (each kind can be switched off), so runs can be captured, and it adds an exact iteration count, a run-level stop reason, and summed usage.
@flue/opentelemetryStock instrumentation. It exports the conversation by default, so runs carry a transcript and can be captured; Runtype derives loop structure from Flue’s own attributes, without the exact iteration count or run-level stop reason.

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:

Environment variables
$OTEL_EXPORTER_OTLP_ENDPOINT=https://api.runtype.com/v1/otel
$OTEL_EXPORTER_OTLP_HEADERS=authorization=Bearer rt_YOUR_API_KEY,x-runtype-agent-id=agent_YOUR_AGENT_ID
$OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf

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):

External agent with a runtype-stream endpoint
1{
2 "name": "Support agent (Flue)",
3 "agentType": "external",
4 "externalConfig": {
5 "endpoint": "https://my-worker.example.workers.dev/dispatch",
6 "protocol": "runtype-stream",
7 "framework": "flue",
8 "auth": { "type": "bearer", "credentials": "{{secret:MY_AGENT_TOKEN}}" }
9 }
10}

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_suite only 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 200 with {}; a 403 means the key lacks TELEMETRY:WRITE.

    cURL smoke test
    $curl -X POST https://api.runtype.com/v1/otel/v1/traces \
    > -H "Authorization: Bearer $RUNTYPE_API_KEY" \
    > -H "Content-Type: application/json" \
    > -d '{"resourceSpans": []}'
  • A run that stays in flight never received its closing invoke_agent span. Flush the provider before the process exits or the handler returns.

  • A rejected trace with ambiguous_agent_attribution means two invocations shared one trace or no attribution source resolved. Set the runtype.agent.id resource attribute or the x-runtype-agent-id header.

  • 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 500 response 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_success response in the exporter log means some traces named an agent the key cannot use; the accepted traces are stored.

Next steps