
Security News
Insecure Agents Podcast: How to Keep AI Agents From Bypassing Security Controls
Socket CTO Ahmad Nassri discusses how to keep AI agents from bypassing package blocks, limit credential access, and monitor their actions.
@aibind/sveltekit
Advanced tools
AI SDK bindings for SvelteKit — streaming, structured output, agents, server handlers, and remote functions
AI SDK bindings for SvelteKit. Reactive Svelte 5 classes, server handlers, remote functions, and agents — all wired up with sensible defaults.
🤏 Tiny — Ships only what you use. Tree-shakes per entry point.
🐇 Simple — Three classes: Stream, StructuredStream, Agent. Instantiate and .send().
🧙♀️ Elegant — Svelte 5 runes ($state) on every field. No stores, no boilerplate.
🗃️ Highly customizable — Custom endpoints, custom fetch, per-request system overrides, named model registries.
⚛️ Reactive — Text, loading, error, done — all reactive. Just bind and go.
🔌 Batteries included — Server handler, remote functions, and default endpoints out of the box.
npm install @aibind/sveltekit ai svelte
Peer dependencies: svelte ^5.53, ai ^6.0, @sveltejs/kit ^2.53.
StructuredStream works with any Standard Schema-compatible library. Install one:
# Zod (v4 recommended — has built-in JSON Schema support)
npm install zod
# Valibot (requires JSON Schema converter)
npm install valibot @valibot/to-json-schema
# ArkType (built-in JSON Schema via .toJsonSchema())
npm install arktype
// src/hooks.server.ts
import { createStreamHandler } from '@aibind/sveltekit/server';
import { anthropic } from '@ai-sdk/anthropic';
export const handle = createStreamHandler({
model: anthropic('claude-sonnet-4-20250514')
});
This handles /api/__aibind__/stream and /api/__aibind__/structured automatically.
<script lang="ts">
import { Stream } from '@aibind/sveltekit';
const stream = new Stream({
system: 'You are a helpful assistant.'
});
let prompt = $state('');
</script>
<form onsubmit={(e) => { e.preventDefault(); stream.send(prompt); }}>
<input bind:value={prompt} />
<button disabled={stream.loading}>Send</button>
</form>
{#if stream.text}
<p>{stream.text}</p>
{/if}
@aibind/sveltekit — Client Classesimport { Stream, StructuredStream, defineModels } from '@aibind/sveltekit';
defineModels(models)Define named AI models for type-safe model selection across client and server.
// src/lib/models.server.ts
import { defineModels } from '@aibind/sveltekit';
import { anthropic } from '@ai-sdk/anthropic';
export const models = defineModels({
default: anthropic('claude-sonnet-4-20250514'),
fast: anthropic('claude-haiku-20250514'),
});
export type Models = typeof models.$infer; // 'default' | 'fast'
Pass models to the server handler:
// src/hooks.server.ts
import { createStreamHandler } from '@aibind/sveltekit/server';
import { models } from '$lib/models.server';
export const handle = createStreamHandler({ models });
new Stream(options?)Reactive streaming text. All properties are Svelte 5 $state fields. Endpoint defaults to /api/__aibind__/stream.
const stream = new Stream({
model: 'fast', // optional model key
system: 'You are a poet.',
endpoint: '/api/custom/stream', // override default
fetch: customFetch, // optional custom fetch
onFinish: (text) => console.log(text),
onError: (err) => console.error(err)
});
stream.send('Write a haiku');
stream.send('Now a limerick', { system: 'Override system prompt' });
stream.text; // reactive accumulated text
stream.loading; // true while streaming
stream.error; // Error | null
stream.done; // true when complete
stream.abort(); // cancel in-flight request
stream.retry(); // re-send last prompt
new StructuredStream(options)Streams JSON and parses partial objects as they arrive. Validates the final result with any Standard Schema-compatible library. Endpoint defaults to /api/__aibind__/structured.
import { StructuredStream } from '@aibind/sveltekit';
import { z } from 'zod';
const analysis = new StructuredStream({
schema: z.object({
sentiment: z.enum(['positive', 'negative', 'neutral']),
score: z.number(),
topics: z.array(z.string())
}),
system: 'Analyze sentiment. Return JSON matching the schema.'
});
analysis.send('I love this product!');
analysis.partial; // Partial<T> — updates as JSON streams in
analysis.data; // T | null — fully validated after completion
analysis.raw; // raw JSON string
@aibind/sveltekit/server — Stream Handlerimport { createStreamHandler, ServerAgent } from '@aibind/sveltekit/server';
createStreamHandler(config)SvelteKit handle hook that serves streaming endpoints.
// Single model
export const handle = createStreamHandler({
model: anthropic('claude-sonnet-4-20250514'),
prefix: '/api/__aibind__' // default
});
// Multi-model
export const handle = createStreamHandler({ models });
Handles two routes:
POST {prefix}/stream — text streamingPOST {prefix}/structured — JSON streamingServerAgentServer-side agent with tools, system prompt, and multi-step tool loops.
import { ServerAgent } from '@aibind/sveltekit/server';
import { tool, stepCountIs } from 'ai';
import { z } from 'zod';
const agent = new ServerAgent({
model: anthropic('claude-sonnet-4-20250514'),
system: 'You are a helpful assistant with access to tools.',
tools: {
get_weather: tool({
description: 'Get weather for a city',
inputSchema: z.object({ city: z.string() }),
execute: async ({ city }) => ({ city, temperature: '72°F', condition: 'sunny' })
})
},
stopWhen: stepCountIs(5)
});
// In a SvelteKit endpoint:
export async function POST({ request }) {
const { messages } = await request.json();
const lastMessage = messages[messages.length - 1];
const result = agent.stream(lastMessage.content, {
messages: messages.slice(0, -1)
});
return result.toTextStreamResponse();
}
@aibind/sveltekit/remote — SvelteKit Remote Functionsimport { AIRemote } from '@aibind/sveltekit/remote';
Requires
@sveltejs/kit ^2.53.
new AIRemote(model)Wraps SvelteKit's remote functions with AI SDK.
// src/lib/ai.server.ts
import { AIRemote } from '@aibind/sveltekit/remote';
export const ai = new AIRemote(anthropic('claude-sonnet-4-20250514'));
ai.query(schema, promptFn) — Text response// src/routes/api/summarize.remote.ts
import { ai } from '$lib/ai.server';
import { z } from 'zod';
export const summarize = ai.query(
z.string(),
(text) => `Summarize this: ${text}`
);
ai.structuredQuery({ input, output, prompt }) — Typed responseexport const analyze = ai.structuredQuery({
input: z.string(),
output: z.object({
sentiment: z.enum(['positive', 'negative', 'neutral']),
confidence: z.number()
}),
prompt: (text) => `Analyze: ${text}`,
system: 'Return JSON matching the output schema.'
});
ai.command(schema, handler) — Mutationsexport const generatePost = ai.command(
z.object({ topic: z.string() }),
async (input, { model }) => {
const result = await generateText({ model, prompt: `Write about ${input.topic}` });
await db.posts.create({ content: result.text });
return { id: post.id };
}
);
@aibind/sveltekit/agent — Client Agentimport { Agent } from '@aibind/sveltekit/agent';
new Agent(options?)Reactive agent state. Endpoint defaults to /api/__aibind__/agent.
<script lang="ts">
import { Agent } from '@aibind/sveltekit/agent';
const agent = new Agent();
let prompt = $state('');
</script>
<form onsubmit={(e) => { e.preventDefault(); agent.send(prompt); prompt = ''; }}>
<input bind:value={prompt} />
<button disabled={agent.status === 'running'}>Send</button>
</form>
{#each agent.messages as message (message.id)}
<div class={message.role}>{message.content}</div>
{/each}
{#if agent.status === 'running'}
<button onclick={() => agent.stop()}>Stop</button>
{/if}
Reactive properties:
messages — array of { id, role, content, type } messagesstatus — 'idle' | 'running' | 'awaiting-approval' | 'error'error — Error | nullpendingApproval — { id, toolName, args } | nullMethods:
send(prompt) — send a message, streams response incrementallystop() — abort the current requestapprove(id) / deny(id) — respond to tool approval requests@aibind/sveltekit/markdown — Streaming Markdownimport { StreamMarkdown } from '@aibind/sveltekit/markdown';
Renders streaming markdown with recovery for unterminated syntax. Uses @aibind/markdown under the hood.
<script lang="ts">
import { Stream } from '@aibind/sveltekit';
import { StreamMarkdown } from '@aibind/sveltekit/markdown';
const stream = new Stream({ system: 'You are a helpful assistant.' });
</script>
<StreamMarkdown text={stream.text} streaming={stream.loading} />
Props:
text — markdown string to renderstreaming — when true, applies markdown recovery (closes unterminated bold, code blocks, etc.)class — optional CSS classMIT
FAQs
AI SDK bindings for SvelteKit — streaming, structured output, agents, server handlers, and remote functions
The npm package @aibind/sveltekit receives a total of 26 weekly downloads. As such, @aibind/sveltekit popularity was classified as not popular.
We found that @aibind/sveltekit demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Security News
Socket CTO Ahmad Nassri discusses how to keep AI agents from bypassing package blocks, limit credential access, and monitor their actions.

Security News
GPT-6 Astra tried to plant malicious code in simulated open source projects using fake GitHub accounts and deceptive PRs during an assigned CTF challenge.

Security News
upm uses Node.js to deliver fast npm installs in about 250 KB, with a JavaScript API and security defaults.