eve
Version:
Filesystem-first framework for durable backend AI agents that run anywhere.
133 lines (99 loc) • 6.12 kB
text/mdx
---
title: "useEveAgent (Svelte)"
description: "Use the eve Svelte binding and its Svelte-specific reactive interface."
---
`useEveAgent()` from `eve/svelte` exposes the shared eve frontend client through Svelte 5 reactive getters and methods. Read the [frontend overview](./overview) for session behavior, messages, human input, authorization, callbacks, reducers, and persistence. This page covers the Svelte-specific interface.
On SvelteKit, register the [`eveSvelteKit` Vite plugin](./sveltekit) to mount the agent routes on the application origin.
## Basic usage
Call the binding once for a conversation and read its reactive getters directly. The returned object is not a Svelte store, so its fields do not use the `$` prefix:
```svelte
<script lang="ts">
import { useEveAgent } from "eve/svelte";
const agent = useEveAgent();
let message = $state("");
let isBusy = $derived(agent.status === "submitted" || agent.status === "streaming");
let isInputDisabled = $derived(isBusy || agent.status === "resuming");
async function handleSubmit() {
const text = message.trim();
if (!text || isInputDisabled) return;
message = "";
await agent.send(text);
}
</script>
{#each agent.data.messages as item}
<p>{item.role}: {JSON.stringify(item.parts)}</p>
{/each}
<form onsubmit={(event) => {
event.preventDefault();
void handleSubmit();
}}>
<input bind:value={message} disabled={isInputDisabled} />
<button type="submit" disabled={isInputDisabled}>Send</button>
</form>
```
## What it returns
The state fields are reactive getters; the commands are ordinary methods:
| Property | Svelte shape |
| ---------------------------------------------- | --------------------------------- |
| `data` | `TData` |
| `status` | `UseEveAgentStatus` |
| `error` | `Error \| undefined` |
| `events` | `readonly MessageStreamEvent[]` |
| `session` | `ClientSessionState \| undefined` |
| `send`, `respond`, `resume`, `cancel`, `reset` | Methods |
Read the getters directly in templates, `$derived`, or `$effect`. The [shared returned-state reference](./overview#returned-state) describes what each value and command does.
## Send a message
Call `agent.send(text)` for text or pass content parts for attachments. The API and transport behavior match the [shared sending guide](./overview#sending-and-streaming); only reactive access differs in Svelte.
## Human-in-the-loop prompts
Pending requests appear in `agent.data.messages`. Use the Svelte exports when narrowing message parts, then answer through `agent.respond()`:
```svelte
<script lang="ts">
import { useEveAgent } from "eve/svelte";
const agent = useEveAgent();
const pendingRequests = $derived(
agent.data.messages.flatMap((message) =>
message.parts.flatMap((part) => {
if (part.type !== "dynamic-tool" || part.state !== "approval-requested") return [];
const request = part.toolMetadata?.eve?.inputRequest;
return request ? [request] : [];
}),
),
);
</script>
{#each pendingRequests as request (request.requestId)}
<fieldset>
<legend>
{request.kind === "tool-approval"
? "Approval required"
: request.kind === "question"
? "Question"
: "Session limit"}
</legend>
<p>{request.prompt}</p>
{#each request.options ?? [] as option (option.id)}
<button
type="button"
onclick={() =>
void agent.respond([{ requestId: request.requestId, optionId: option.id }])}
>
{option.label}
</button>
{/each}
</fieldset>
{/each}
```
See [Human-in-the-loop prompts](./overview#human-in-the-loop-prompts) for request semantics and rendering guidance.
## Cancel, reset, and resume
Call `agent.cancel()` to stop the durable server-side turn while the binding remains attached through settlement. Destroying the component only disconnects its local stream; it does not cancel server execution. Call `agent.reset()` to clear local state and start a new session. Pass `initialSession`, `initialEvents`, and `resume: true` to restore a saved conversation and follow an in-flight turn. During bounded catch-up, `agent.status` is `"resuming"`; keep the hydrated conversation visible, disable submission, and wait for `"ready"`, `"error"`, or `"streaming"`. Use `agent.resume()` directly when restoration is controlled imperatively. See [Resumable sessions](./overview#resumable-sessions) for the persistence contract and [Sending and streaming](./overview#sending-and-streaming) for cancellation behavior.
## Custom host and credentials
Pass `host`, `auth`, or `headers` to the binding using the same options as the other frontend bindings. See [Custom hosts and headers](./overview#custom-hosts-and-headers).
## Attach page context per turn
Pass `clientContext` to `send()` or `respond()`, or use `prepareSend` to add context before every turn. See [Attach page context per turn](./overview#attach-page-context-per-turn).
## Lifecycle callbacks
Pass `onEvent`, `onError`, `onFinish`, or `onSessionChange` when the application needs lifecycle notifications. See [Lifecycle callbacks](./overview#lifecycle-callbacks) for callback timing and optimistic projection behavior.
## Custom reducer
Import `EveAgentReducer` from `eve/svelte` when projecting events into application-specific state. The resulting `agent.data` uses the reducer's `TData` type. See [Custom reducer](./overview#custom-reducer) for the reducer contract and client projection events.
## What to read next
- [SvelteKit](./sveltekit): register the Vite plugin and mount the eve runtime.
- [Frontend overview](./overview): use the shared frontend API.
- [Sessions, runs, and streaming](../../concepts/sessions-runs-and-streaming): understand the underlying session protocol.