Every Runflow agent needs a main.ts file at the project root. It must export an async function main() — this is the function the Runflow engine calls when your agent receives a message.
Copy
import { Agent, openai } from '@runflow-ai/sdk';import { identify } from '@runflow-ai/sdk/observability';// Create your agentconst agent = new Agent({ name: 'My First Agent', instructions: 'You are a helpful assistant. Be concise and friendly.', model: openai('gpt-4o'),});// Entry point — called by Runflow engineexport async function main(input: any) { // 1. Identify the user (connects memory, traces, and metrics to this person) identify(input.email || input.phone || 'anonymous'); // 2. Process the message const result = await agent.process({ message: input.message, sessionId: input.sessionId, }); // 3. Return the response return { message: result.message, };}
The main.ts file and the export async function main() are required. Without them, your agent won’t work when deployed or tested with rf test.
Enable conversation history so your agent remembers previous messages:
Copy
const agent = new Agent({ name: 'My First Agent', instructions: 'You are a helpful assistant. Be concise and friendly.', model: openai('gpt-4o'), memory: { maxTurns: 20, // Remember last 20 messages },});
Memory is automatically bound to the user you identified with identify(). Same user = same conversation history across sessions.
Tools let your agent perform actions — call APIs, query databases, send messages. Create them in separate files under tools/:
tools/weather.ts
Copy
import { createTool } from '@runflow-ai/sdk';import { z } from 'zod';export const weatherTool = createTool({ id: 'get-weather', description: 'Get current weather for a city', inputSchema: z.object({ city: z.string().describe('City name (e.g., "São Paulo")'), }), execute: async ({ context }) => { const geoRes = await fetch( `https://geocoding-api.open-meteo.com/v1/search?name=${encodeURIComponent(context.city)}&count=1` ); const geo = await geoRes.json(); if (!geo.results?.length) { return { error: `City "${context.city}" not found` }; } const { latitude, longitude, name, country } = geo.results[0]; const weatherRes = await fetch( `https://api.open-meteo.com/v1/forecast?latitude=${latitude}&longitude=${longitude}¤t=temperature_2m` ); const weather = await weatherRes.json(); return { city: name, country, temperature: Math.round(weather.current.temperature_2m), unit: 'celsius', }; },});
Then register it in your agent:
main.ts
Copy
import { Agent, openai } from '@runflow-ai/sdk';import { identify } from '@runflow-ai/sdk/observability';import { weatherTool } from './tools/weather';const agent = new Agent({ name: 'My First Agent', instructions: `You are a helpful assistant.## Tools- Use the weather tool when users ask about temperature or weather conditions- Present results clearly`, model: openai('gpt-4o'), memory: { maxTurns: 20 }, tools: { getWeather: weatherTool, },});export async function main(input: any) { identify(input.email || input.phone || 'anonymous'); const result = await agent.process({ message: input.message, sessionId: input.sessionId, }); return { message: result.message, };}
Always mention your tools in the agent’s instructions. The LLM needs to know when to use each tool. Be specific: “Use the weather tool when users ask about temperature or weather conditions.”