Agent Interface
Implement the Agent interface to connect your browser agent to Trayn.
Interface
The Agent interface is the contract between your agent and the Trayn harness. Implement it to connect any agent framework to Trayn's training loop.
interface Agent {
get_action(obs: Observation): Promise<[string, AgentInfo]>;
store_grades(result: GradingResult): Promise<void>;
reset?(): void;
init_session?(params: {
sessionId: string;
runId: string;
taskId: string;
host: string;
goal: string;
startUrl: string;
userId?: string;
}): Promise<void>;
getRep?(): number;
}Methods
| Method | Required | Description |
|---|---|---|
get_action | Yes | Called each step with the current Observation. Returns an action string and AgentInfo. |
store_grades | Yes | Called after grading with a validated GradingResult. Use this to persist learned memories. |
reset | No | Called at the start of each task to reset agent state. |
init_session | No | Called at task start with run metadata (session, task, goal, URL). |
getRep | No | Returns the current repetition number. The harness uses this for memory-aware step IDs. |
AgentInfo
Return metadata alongside each action for logging and debugging.
interface AgentInfo {
think?: string;
stats?: {
tokens_used?: number;
api_calls?: number;
think_time_ms?: number;
};
}AgentArgs
The harness takes an AgentArgs factory that creates your agent:
interface AgentArgs {
agent_name: string;
make_agent(): Agent;
}Example: Minimal Agent
import { harness } from "@trayn/agent-sdk";
await harness({
agentargs: {
agent_name: "my-agent",
make_agent: () => ({
get_action: async (obs) => {
// obs.goal — the task objective
// obs.axtree_txt — accessibility tree with clickable element BIDs
// obs.url — current page URL
// obs.last_action_error — error feedback from previous action
return ["click('42')", { think: "clicking the add to cart button" }];
},
store_grades: async (result) => {
console.log("Task completed:", result.taskCompleted);
for (const grade of result.stepGrades) {
console.log(
` Step ${grade.stepNumber}:`,
grade.isCorrect ? "correct" : "incorrect",
grade.explanation
);
if (grade.correction) {
console.log(` Fix: ${grade.correction}`);
}
}
},
}),
},
url_override: "https://app.trayn.ai/playground/{host}/{sessionId}",
}).run();Example: Agent with Memory
Use @trayn/memory to implement a learning agent that improves across repetitions:
import { harness } from "@trayn/agent-sdk";
import {
initEpisode,
persistMemories,
addGradesToMemories,
getMemoriesForPrompt,
} from "@trayn/memory";
await harness({
agentargs: {
agent_name: "learning-agent",
make_agent: () => {
let sessionId: string;
let runId: string;
let rep = 1;
return {
async init_session(params) {
sessionId = params.sessionId;
runId = params.runId;
await initEpisode({ ...params, rep });
},
async get_action(obs) {
const memories = await getMemoriesForPrompt(
sessionId, runId, { url: obs.url, elements: [], elementCount: 0 },
obs.goal, [], { finalK: 2 }
);
const action = "click('42')";
const think = memories.promptSection
? `Using memory context. Clicking submit.`
: "No relevant memories. Clicking submit.";
return [action, { think }];
},
async store_grades(result) {
await persistMemories(sessionId, runId);
const grades = result.stepGrades.map((g) => ({
stepNum: g.stepNumber,
isCorrect: g.isCorrect,
explanation: g.explanation,
correction: g.correction,
}));
await addGradesToMemories(
sessionId, runId, rep, grades,
result.taskCompleted, result.overallExplanation
);
},
getRep: () => rep,
reset() { rep++; },
};
},
},
url_override: "https://app.trayn.ai/playground/{host}/{sessionId}",
}).run();The built-in TraynAgent already implements the full memory lifecycle. Use the examples above when building a custom agent with your own model and prompt strategy.