Trayntrayn.ai

Connect Your Agent

Connect OpenClaw or a custom SDK agent to a Trayn run.

Before You Connect

Create the API key and training run in the Trayn app first. Your runtime needs:

ValueSource
TRAYN_API_KEYAPI Keys page in the Trayn app.
TRAYN_APP_URLUsually https://app.trayn.ai.
agentIdRequired for direct harness() use. The CLI can resolve it from the run config.
experimentIdCreated when the app starts a run.
trainingRunIdThe active child run.
sandboxTrainingRunUrlSandbox URL with sandbox_overlay=training_run and training_run_id.

TRAYN_API_KEY is mandatory for SDK and CLI runtimes. If it is missing, the CLI fails before launching the browser with a clear configuration error instead of starting a partial run.

OpenClaw Plugin

Use the Trayn OpenClaw plugin when OpenClaw owns the browser-control loop. The plugin uses the same trainingRunId for task config, step capture, memory retrieval, and grading.

{
  "apiBaseUrl": "https://app.trayn.ai",
  "sandboxOrigin": "https://app.trayn.ai",
  "apiKey": "<api-key-from-trayn>",
  "gatewayToken": "..."
}
FieldPurpose
apiBaseUrlTrayn app API origin. Defaults to TRAYN_APP_URL.
sandboxOriginOrigin used for sandbox and grading URLs. Defaults to TRAYN_APP_URL.
apiKeyTrayn API key sent as Bearer to Trayn training APIs.
gatewayTokenOpenClaw gateway token. This is separate from the Trayn API key.

TypeScript SDK

Install the SDK with Bun:

bun add @trayn/agent-sdk
bunx playwright install chromium

Implement Agent and pass the run IDs from the app:

import { harness } from "@trayn/agent-sdk";

await harness({
  agent_id: "{agentId}",
  experiment_id: "{experimentId}",
  training_run_id: "{trainingRunId}",
  url_override: "{sandboxTrainingRunUrl}",
  max_steps: 15,
  agentargs: {
    agent_name: "support-agent",
    make_agent: () => ({
      async init_session(params) {
        console.log(params.agentId, params.trainingRunId, params.goal);
      },
      async get_action(obs) {
        return ["click('42')", { think: "Selecting the matching control." }];
      },
      async store_grades(result) {
        console.log(result.taskCompleted);
      },
    }),
  },
}).run();
interface Agent {
  get_action(obs: Observation): Promise<[string, AgentInfo]>;
  store_grades(result: GradingResult): Promise<void>;
  init_session?(params: {
    agentId: string;
    sessionId: string;
    experimentId: string;
    trainingRunId: string;
    taskId: string;
    host: string;
    goal: string;
    maxSteps?: number;
    startUrl: string;
  }): Promise<void>;
  reset?(): void;
  getRep?(): number;
}

The app-owned OpenClaw run fetches the task, drives the browser, streams steps to Trayn, triggers grading, and writes validated results back through the training APIs.

CLI

The packaged CLI is a control/viewer for that same app-owned OpenClaw run. It resolves agentId and trainingRunId from Trayn, starts or resumes the stored run through the app endpoint, and renders timeline, state, pause, and grading events from the same SDK live-session stream as the browser UI.

TRAYN_APP_URL=https://app.trayn.ai TRAYN_API_KEY=... trayn \
  --url "{sandboxTrainingRunUrl}" \
  --experiment-id "{experimentId}" \
  --training-run-id "{trainingRunId}" \
  --session-id "{sessionId}"

Local repo installs expose the same CLI as trayn after just install.

The CLI calls GET /api/training/training-runs/{trainingRunId}/config, validates any supplied --agent-id, --experiment-id, and --session-id against the server response, then starts or resumes the stored app-owned OpenClaw run through POST /api/agents/{agentId}/run/start. It uses openTrainingRunLiveSession(...) with an API-key-authenticated TrainingRunLiveClient, so the CLI/TUI and browser page receive the same typed timeline, state, pause, and grading events.

Custom Runtime Shape

If you are not using the OpenClaw plugin or @trayn/agent-sdk, keep the same shape:

StepRequirement
Open sandboxUse the app-created sandboxTrainingRunUrl.
AuthenticateSend Authorization: Bearer ${TRAYN_API_KEY} to Trayn training APIs.
Load configRead /api/training/training-runs/{trainingRunId}/config; treat the returned ids and flags as canonical.
Retrieve memoryUse HttpTrainingMemoryClient.retrieve(...) before choosing an action.
ActReturn one valid browser action for the current observation.
FinishCall POST /api/training/training-runs/{trainingRunId}/finish with { "trainingRunId": "..." }.
Save memoryUse HttpTrainingMemoryClient.save(...) with the same run IDs and step screenshot.

Memory Client

Use @trayn/memory when your own runtime needs the same memory route shape the OpenClaw plugin uses.

import {
  buildMemoryRetrievalRequest,
  HttpTrainingMemoryClient,
} from "@trayn/memory";

const client = new HttpTrainingMemoryClient({
  baseUrl: process.env.TRAYN_APP_URL!,
  token: process.env.TRAYN_API_KEY,
});

const result = await client.retrieve(
  buildMemoryRetrievalRequest({
    session: {
      agentId,
      experimentId,
      trainingRunId,
      sessionId,
      host,
      goal,
      maxSteps,
      startUrl,
    },
    turn: {
      mode: "step",
      stepNum,
      currentUrl,
      recentActions,
      lastAction,
      lastError,
      focusedElement,
    },
    environment: {
      url: currentUrl,
      snapshot,
      screenshotBase64,
      elements,
      elementCount: elements.length,
    },
    config: { finalK: 3 },
  })
);

console.log(result.promptSection);

On this page