Self-hosted autonomous AI agent platform with persistent memory, user-scoped tool sandboxes, and passkey authentication.
AgentStudio provides a streaming chat interface where the assistant can call tools such as web search and sandboxed code execution. The filesystem toolset supports ranged file reads, full writes, unified-diff patch apply, deterministic string replace, recursive directory listing, search, move/rename, delete, and file metadata lookups. Chat supports editing and branching, interleaved tool and thinking blocks, per-message performance and cost metrics, model selection, and per-prompt reasoning effort selection.
Creation workflows are chat-led: New Agent and New Skill actions launch a fresh conversation with a seeded creation prompt. The assistant gathers missing requirements (optionally with ask_user), then executes directly with tool-level approvals where configured.
Autonomous agents with custom roles, system prompts, and model assignments. Agents are created and managed via the chat orchestrator. The agents page provides a read-only browser for viewing agent status and navigating to agent details. Agent detail pages allow editing the assigned model and system prompt.
The memory system stores, retrieves, and consolidates facts over time using PostgreSQL + pgvector. Memory Palace organization is active (wings, rooms, halls, drawers, and closets), and chat context now uses the layered memory stack (L0 identity, L1 essential story, L2 recall, L3 semantic fallback).
Dreaming Agent is a real visible agent that owns memory consolidation work. Its periodic consolidation runs are modeled as standard automations and produce normal chat sessions.
Settings persist default model, theme, notification preferences, per-tool approval requirements, context window configuration, and budget limits.
Tool execution approvals are configured per tool in Settings. Tools marked for approval pause execution until approved.
On server startup, AgentStudio now ensures the configured PostgreSQL database exists, installs the required extensions, and applies bundled Drizzle migrations before serving requests. The Postgres role in DATABASE_URL must be allowed to create the target database and install pgcrypto and vector.
If the target database already contains AgentStudio tables or enums but has no recorded Drizzle migrations, startup treats that state as legacy unmanaged schema, wipes the app schemas, and then reapplies the bundled migrations from scratch.
Build note: bun run build skips database bootstrap entirely. DATABASE_URL is only required when the server actually starts.
- SvelteKit (Svelte 5, TypeScript)
- TailwindCSS v4 + DaisyUI
- PostgreSQL + pgvector
- Drizzle ORM + postgres.js
- OpenRouter SDK
- Playwright E2E
- Adapter Node + Docker (TrueNAS deployment target)
AgentStudio now uses a canonical three-tier responsive system:
- mobile: default styles below 48rem (768px)
- tablet:
tablet:utilities at 48rem and above - desktop:
desktop:utilities at 80rem (1280px) and above
Implementation details:
- The canonical tokens are defined in
src/routes/layout.cssvia Tailwind v4@themebreakpoint variables. - Legacy aliases (
sm,md,lg,xl) are mapped to these tiers for compatibility, but new work should prefertablet:anddesktop:utilities.
- Install dependencies:
bun install- Copy environment variables:
cp .env.example .env- Update
.envvalues for your services:
DATABASE_URLOPENROUTER_API_KEYSEARXNG_URLandSEARXNG_PASSWORDSANDBOX_WORKSPACE(base root for per-user workspaces; defaults to/workspace/users)VAPID_PUBLIC_KEYandVAPID_PRIVATE_KEYORIGIN
Database note:
DATABASE_URLshould point at the final application database name even if that database does not exist yet.- The configured Postgres role must be able to create that database on first start and run
CREATE EXTENSION IF NOT EXISTS pgcryptoandCREATE EXTENSION IF NOT EXISTS vector. - A database with existing AgentStudio schema objects but no Drizzle migration history will be reset on startup before migrations are applied.
- Run the app:
bun run dev- Run checks/tests:
bun run check
bun run test:e2ePlaywright E2E policy:
bun run test:e2eruns with real external integrations (OpenRouter, SearXNG, sandbox tools).- Required env vars for E2E:
DATABASE_URL,AUTH_PASSWORD,OPENROUTER_API_KEY,SEARXNG_URL,SANDBOX_WORKSPACE. - The suite fails fast during global setup if any required dependency is missing or unreachable.
- GitHub Releases now trigger a workflow that builds native artifacts and attaches them to the release.
- If repository secret
TAURI_REMOTE_URLis set, native builds open that hosted URL in the Tauri webview instead of bundled frontend assets. This is the intended mode for thin-shell desktop/mobile releases backed by the Docker-hosted Node app. - Outputs:
- Windows installer
.exe - Android
.apk
- Windows installer
- Workflow file:
.github/workflows/release-native-builds.yml - Trigger: publish a GitHub Release (tag-based release flow)
- Icon source-of-truth:
static/icon.svg. - Generated platform icon files under
src-tauri/iconsare recreated automatically bybun run tauri:iconsin CI and before Tauri dev/build.
bun run android:build:localbuilds a debug APK using the known-good local SDK/NDK + MSVC setup andTAURI_REMOTE_URL=https://agentstudio.derekhearst.com.bun run android:install:localinstalls the latest built APK to a connected device and launches the app.bun run android:run:localbuilds, installs, and launches in one command.
Optional script args:
- Build with a different URL:
powershell -ExecutionPolicy Bypass -File scripts/android-build-local.ps1 -RemoteUrl "https://your-host" - Install a specific APK file:
powershell -ExecutionPolicy Bypass -File scripts/android-install-local.ps1 -ApkPath "path\\to\\app.apk"
For an explicit live-focused subset:
bun run test:e2e:liveNotes:
bun run test:e2eis the primary CI path and uses real integrations.bun run test:e2e:liveremains available for targeted provider-focused runs.- Provider auth errors (for example
User not found) indicate credential/account issues rather than app test harness issues.
- High-level contract:
docs/features.md - Full implementation plan:
docs/plan.md
- Domain-first API boundaries: browser-consumed remote functions live in
src/lib/{domain}. - Server-only internals are colocated in domain folders under
src/lib/**and are only imported by remote functions or+serverroutes. - Route and component imports should prefer domain barrels (for example,
$lib/chat,$lib/agents) over deep*.remotepaths.
- Authentication uses WebAuthn passkeys (no OAuth or password login).
- Native mobile/desktop webviews that do not expose WebAuthn now show an Open in browser to sign in fallback on the login page.
- On first startup, the server seeds an unclaimed
adminaccount and logs a one-time bootstrap claim URL/key. - Admins create new accounts from
/users. - Accounts are claimed by the first successful passkey registration for that username.
- User removal is soft-delete; access is blocked while historical data remains owned by that user.
/Redirects to chat/loginAuthentication/usersAdmin user management/chatConversations/chat/[id]Chat detail/costCost dashboard/agentsAgent management/automationsScheduled automation workflows/memoryMemory explorer/settingsApp configuration