> Fetch clean Markdown by appending `.md` to any page URL under https://signalwire.com/docs or requesting it with the HTTP header `Accept: text/markdown`. The root index at https://signalwire.com/docs/llms.txt lists the available documentation indexes. # runApp > Main entry point that starts a LiveWire agent. [jobcontext]: /docs/server-sdks/reference/typescript/agents/livewire/job-context [defineagent]: #defineagent [jobprocess]: /docs/server-sdks/reference/typescript/agents/livewire/job-context ## **runApp** ```typescript {1} function runApp(options: any): void ``` The main entry point for a LiveWire application. It prints the ASCII banner, runs the prewarm function (if defined), creates a `JobContext`, prints a random tip, invokes the registered entry function, and starts the underlying SignalWire agent. This mirrors `cli.runApp()` from `@livekit/agents-js`. It is also available as `cli.runApp`. ### Parameters **`options`** `any` — required The agent definition returned by [`defineAgent()`](#defineagent), or an object with `entry` and optional `prewarm` functions. --- ### Returns `void` -- This function runs the agent lifecycle asynchronously. ### Lifecycle 1. Prints the LiveWire ASCII banner to stderr. 2. If the agent definition has a `prewarm` function, calls it with a fresh [`JobProcess`][jobprocess] instance. Logs an informational message noting that warm process pools are not needed on SignalWire. 3. Creates a [`JobContext`][jobcontext]. 4. Prints a random "Did you know?" tip to stderr. 5. Calls the `entry` function with the `JobContext`. If the entry function is async, it is awaited. 6. After entry completes, starts the underlying SignalWire agent if one was bound. ### Example ```typescript {27} import { Agent, AgentSession, JobContext, tool, defineAgent, runApp, } from '@signalwire/sdk/livewire'; const getTime = tool({ description: 'Get the current time.', execute: () => new Date().toISOString(), }); const agentDef = defineAgent({ entry: async (ctx: JobContext) => { await ctx.connect(); await ctx.waitForParticipant(); const agent = new Agent({ instructions: 'You are a helpful assistant that can tell the time.', tools: { getTime }, }); const session = new AgentSession(); await session.start({ agent, room: ctx.room }); session.generateReply({ instructions: 'Greet the user.' }); }, }); runApp(agentDef); ``` --- ## **defineAgent** ```typescript {1} function defineAgent(agent: { entry: (ctx: JobContext) => Promise; prewarm?: (proc: JobProcess) => any; }): { entry: (ctx: JobContext) => Promise; prewarm?: (proc: JobProcess) => any } ``` Wraps an entry function (and optional prewarm function) into an agent definition object that can be passed to `runApp()`. This mirrors `defineAgent()` from `@livekit/agents-js`. ### Parameters **`entry`** `(ctx: JobContext) => Promise` — required The main entry function for the agent. Receives a [`JobContext`][jobcontext] and should create an `Agent`, an `AgentSession`, and call `session.start()`. --- **`prewarm`** `(proc: JobProcess) => any` — default: undefined Optional setup function called before the entry function. Receives a [`JobProcess`][jobprocess] whose `userData` object can be used to share state with the entry function. --- ### Returns The same object, for passing to `runApp()`. ### Example ```typescript {3} import { defineAgent, runApp, JobContext, JobProcess } from '@signalwire/sdk/livewire'; const agentDef = defineAgent({ prewarm: (proc: JobProcess) => { proc.userData.greeting = 'Welcome to Acme Corp!'; }, entry: async (ctx: JobContext) => { const greeting = ctx.proc.userData.greeting ?? 'Hello!'; // ... set up agent and session }, }); runApp(agentDef); ``` > Main entry point that starts a LiveWire agent.