一键导入
iblai-vibe-agent-sandbox
Add the agent Sandbox tab (OpenClaw instance management, agent prompt configuration, and agent skills) to your Next.js app
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Add the agent Sandbox tab (OpenClaw instance management, agent prompt configuration, and agent skills) to your Next.js app
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
| name | iblai-vibe-agent-sandbox |
| description | Add the agent Sandbox tab (OpenClaw instance management, agent prompt configuration, and agent skills) to your Next.js app |
| globs | null |
| alwaysApply | false |
Add the agent Sandbox tab -- a three-section workspace that connects an agent to an OpenClaw sandbox instance, edits the agent-workspace prompt files (Identity, Soul, User Context, Tools, Agents, Bootstrap, Heartbeat, Memory) backing the agent's runtime behaviour, and assigns reusable Skills to the agent with toggleable enable/disable. Push pulls the current configuration onto the connected sandbox; Auto Push on Save pushes after every edit.









Do NOT add custom styles, colors, or CSS overrides to ibl.ai SDK components. They ship with their own styling. Keep the components as-is. Do NOT implement dark mode unless the user explicitly asks for it.
When building custom UI around SDK components, use the ibl.ai brand:
#0058cc, Gradient: linear-gradient(135deg, #00b0ef, #0058cc)bg-gradient-to-r from-[#2563EB] to-[#93C5FD] text-white@iblai/iblai-js) first, then shadcn/ui for everything else
(npx shadcn@latest add <component>). Do NOT write custom components
when an ibl.ai or shadcn equivalent exists. Both share the same
Tailwind theme and render in ibl.ai brand colors automatically.You MUST run /iblai-vibe-ops-test before telling the user the work is ready.
After all work is complete, start a dev server (pnpm dev) so the user
can see the result at http://localhost:3000.
iblai.env is NOT a .env.local replacement — it only holds the 3
shorthand variables (DOMAIN, PLATFORM, TOKEN). Next.js still reads
its runtime env vars from .env.local.
Use pnpm as the default package manager. Fall back to npm if pnpm
is not installed.
Common setup (brand, conventions, env files, verification): see docs/skill-setup.md.
AGENTS.md:
references/openclaw-post-installation-setup.md.references/nemoclaw-sandbox.md./iblai-vibe-auth)@iblai/mcp in .mcp.json)mentorId (agent UUID). Do NOT invent one.Before proceeding, check for an iblai.env in the project root. Look for
PLATFORM, DOMAIN, and TOKEN variables. If the file does not exist or
is missing these variables, tell the user:
"You need an iblai.env with your platform configuration. Download the
template and fill in your values:
curl -o iblai.env https://raw.githubusercontent.com/iblai/vibe/refs/heads/main/iblai.env"
SandboxConfig, AgentConfigPrompts, and AgentSkills are independent
components — none of them reads from AgentSettingsProvider. They each
take platformKey and mentorUniqueId as required props. Compose them
on a single page so the user sees Sandbox → Prompts → Skills, top to
bottom.
// app/(app)/agents/[mentorId]/sandbox/page.tsx
"use client";
import { useEffect, useState } from "react";
import { useParams } from "next/navigation";
import {
SandboxConfig,
AgentConfigPrompts,
AgentSkills,
} from "@iblai/iblai-js/web-containers";
export default function AgentSandboxPage() {
const { mentorId } = useParams<{ mentorId: string }>();
const [platformKey, setPlatformKey] = useState("");
const [username, setUsername] = useState("");
useEffect(() => {
try {
const raw = localStorage.getItem("userData");
if (raw) {
const parsed = JSON.parse(raw);
setUsername(parsed.user_nicename ?? parsed.username ?? "");
}
const resolvedTenant =
localStorage.getItem("app_tenant") ??
(() => {
try {
return JSON.parse(localStorage.getItem("current_tenant") ?? "{}").key;
} catch { return undefined; }
})() ??
localStorage.getItem("tenant") ??
"";
setPlatformKey(resolvedTenant);
} catch {}
}, []);
if (!platformKey) return null;
return (
<div className="flex h-full flex-col gap-8 bg-white p-6">
<SandboxConfig
platformKey={platformKey}
mentorUniqueId={mentorId}
username={username}
/>
<AgentConfigPrompts
platformKey={platformKey}
mentorUniqueId={mentorId}
/>
<AgentSkills
platformKey={platformKey}
mentorUniqueId={mentorId}
/>
</div>
);
}
AgentConfigPrompts and AgentSkills self-gate on the connected
sandbox config — they each call useGetClawMentorConfigQuery and
short-circuit when no config exists, so it is safe (and intended) to
mount all three together. The Prompts and Skills sections appear only
after the user connects an instance.
SandboxConfig's username prop is optional — if omitted, the
component falls back to getUserName() (which reads from
localStorage.userData). Pass it explicitly when you already have it
to avoid the extra read.
enable_claw)The Sandbox feature is off by default per agent. Whether the
Sandbox tab is shown is governed by enable_claw (boolean) on the
agent's settings — true = show, false/missing = hide. The three
sandbox components themselves render their UI unconditionally; it is
the host app's job to gate the navigation entry and route based on
this flag, so users only see the "advanced" sandbox surface for
agents where it has been opted in.
import { useGetMentorSettingsQuery } from "@iblai/iblai-js/data-layer";
const { data: settings } = useGetMentorSettingsQuery({
org: platformKey,
mentor: mentorId,
});
const sandboxEnabled = settings?.enable_claw === true;
Use sandboxEnabled to:
false.// app/(app)/agents/[mentorId]/sandbox/page.tsx
if (!settings) return null;
if (!sandboxEnabled) {
return (
<div className="p-6 text-sm text-gray-500">
Sandbox is disabled for this agent.
</div>
);
}
return (
<div className="flex h-full flex-col gap-8 bg-white p-6">
<SandboxConfig platformKey={platformKey} mentorUniqueId={mentorId} username={username} />
<AgentConfigPrompts platformKey={platformKey} mentorUniqueId={mentorId} />
<AgentSkills platformKey={platformKey} mentorUniqueId={mentorId} />
</div>
);
enable_claw is set via the standard agent-settings endpoint
(PUT mentors/{mentor_unique_id}/settings/). Toggle it from wherever
your app exposes per-agent admin controls (e.g. the Settings tab in
/iblai-vibe-agent-setting, or a tenant-admin row action):
import { useEditMentorJsonMutation } from "@iblai/iblai-js/data-layer";
const [editMentorJson] = useEditMentorJsonMutation();
await editMentorJson({
mentorId,
org: platformKey,
userId: username,
requestBody: { enable_claw: true },
}).unwrap();
The same mutation un-gates / re-gates the tab — pass false to hide
it again. Pre-existing instances and bound configs are preserved
across toggles; flipping the flag only affects visibility, not data.
get_component_info("SandboxConfig")
get_component_info("AgentConfigPrompts")
get_component_info("AgentSkills")
get_component_info("LLMProviderModal")
All three components import from @iblai/iblai-js/web-containers.
<SandboxConfig>| Prop | Type | Required | Description |
|---|---|---|---|
platformKey | string | Yes | Tenant / org slug |
mentorUniqueId | string | Yes | Agent UUID |
username | string | null | No | Current user. Falls back to getUserName() from localStorage when omitted |
<AgentConfigPrompts>| Prop | Type | Required | Description |
|---|---|---|---|
platformKey | string | Yes | Tenant / org slug |
mentorUniqueId | string | Yes | Agent UUID |
<AgentSkills>| Prop | Type | Required | Description |
|---|---|---|---|
platformKey | string | Yes | Tenant / org slug |
mentorUniqueId | string | Yes | Agent UUID |
OpenClaw), Server URL, Gateway Token. The token write-only —
never read back from the API.LLMProviderModal to pick a provider /
model ({provider}/{name}). Writes to the agent config's model
field.Eight rows, each with a (i) info tooltip and an Edit button
that opens a RichTextEditor modal:
| Field | Backed by | Purpose |
|---|---|---|
| Identity | IDENTITY.md | Agent persona, name, creature type, visual description |
| Soul | SOUL.md | Behavioural guidelines, personality, communication style |
| User Context | USER.md | Deployment context, SSH hosts, device names, TTS voices |
| Tools | TOOLS.md | Tool usage notes, device names, API aliases |
| Agents | AGENTS.md | Multi-agent routing, agent ids, workspaces |
| Bootstrap | BOOTSTRAP.md | One-time first-run instructions |
| Heartbeat | HEARTBEAT.md | Periodic task definitions |
| Memory | MEMORY.md | Seed memory, curated long-term facts |
Updates are upserts — the first PATCH bootstraps the row.
v1.0.0), info tooltip,
enable/disable switch, kebab (Edit / Delete).1.0.0),
Description, Instruction (RichTextEditor).MentorSkillAssignment keyed by skill UUID; flipping off deletes
it. Only enabled=true skills are shown in the toggle list.From @iblai/iblai-js/web-containers:
SandboxConfig, AgentConfigPrompts, AgentSkills — the three
section components.LLMProviderModal — provider/model picker used by the Model row.
Mountable standalone (e.g. for an "override default model" flow
outside the sandbox).getLLMProviderDetails, canSwitchLLm, canSwitchProvider —
helpers for custom UI that needs to mirror the model-picker rules.LLMProvider, Provider — types for the picker.From @iblai/data-layer:
useGetClawMentorConfigQuery,
useCreateClawMentorConfigMutation,
useDeleteClawMentorConfigMutation,
usePushClawConfigMutation — connect / disconnect / push.useGetClawInstancesQuery,
useCreateClawInstanceMutation,
useUpdateClawInstanceMutation,
useDeleteClawInstanceMutation,
useHealthCheckClawInstanceMutation,
useTestConnectivityClawInstanceMutation — instance CRUD + checks.useGetAgentConfigQuery, useUpdateAgentConfigMutation — prompt
fields + model.useGetAgentSkillsQuery, useGetMentorSkillAssignmentsQuery,
useCreateAgentSkillMutation, useUpdateAgentSkillMutation,
useDeleteAgentSkillMutation,
useCreateMentorSkillAssignmentMutation,
useUpdateMentorSkillAssignmentMutation,
useDeleteMentorSkillAssignmentMutation — skills + assignments.AgentSkill, MentorSkillAssignment — payload types.Run /iblai-vibe-ops-test before telling the user the work is ready:
pnpm build -- must pass with zero errorspnpm test -- vitest must passpnpm dev &
npx playwright screenshot http://localhost:3000/agents/<id>/sandbox /tmp/agent-sandbox.png
mentorReducer and mentorMiddlewareinitializeDataLayer(): 5 args (v1.2+)@reduxjs/toolkit: Deduplicated via webpack aliases in next.config.tssonner and @iblai/iblai-web-mentor must be installed
(pnpm add sonner @iblai/iblai-web-mentor)AgentSettingsProvider: All three components take raw props.
If your app already mounts AgentSettingsProvider for sibling tabs,
read its values via useAgentSettings() in the page wrapper and
forward them.mentorUniqueId vs mentorId: The sandbox endpoints key on the
agent's UUID (called mentorUniqueId in the SDK), not the integer
pk. Pass the same UUID you use everywhere else in the agent-* family.usePushClawConfigMutation returns
400 No configuration to push when every agent-config field is
empty. The component mirrors that gate locally — the manual Push
button is disabled until the user has saved at least one prompt.MentorSkillAssignment.skill is the skill's
unique_id, not the integer id. Custom UI joining skills to
assignments must key on skill.unique_id.useGetClawMentorConfigQuery 404s when no agent
has been bound to a sandbox — that's the "not connected" state, not
a failure. The component treats isError as null here. Custom
consumers should do the same.enable_claw gate (advanced toggle): The Sandbox tab is hidden
per agent until enable_claw === true on its settings. The SDK
components do not enforce this gate themselves — the host app reads
it from useGetMentorSettingsQuery and decides whether to render
the tab and route (see Step 2.5). Toggle with editMentorJson
({ enable_claw: true | false }). Existing instances and configs
are preserved across toggles.For custom UI beyond these three components. All endpoints are
prefixed with ${dmUrl}/api/ai-mentor/orgs/{org}/ where dmUrl is
NEXT_PUBLIC_API_BASE_URL. Auth: Authorization: Token <token>.
| Method | Path | Body |
|---|---|---|
| GET | mentors/{mentor_unique_id}/settings/ | Returns the full settings object, including enable_claw: boolean |
| PUT | mentors/{mentor_unique_id}/settings/ | { "enable_claw": true } to show the Sandbox tab for this agent, false to hide it |
enable_claw is the per-agent "advanced sandbox" toggle. The host
app must read it and gate the tab — the SDK components do not.
| Method | Path | Purpose |
|---|---|---|
| GET | claw-instances/ | List instances |
| POST | claw-instances/ | Register a new instance |
| PATCH | claw-instances/{id}/ | Update name / URL / type / token |
| DELETE | claw-instances/{id}/ | Delete |
| POST | claw-instances/{id}/health-check/ | Run a health probe |
| POST | claw-instances/{id}/test-connectivity/ | Run a connectivity probe |
Create / update body:
{
"name": "sarah_ibl_ai",
"server_url": "https://sarah.ibl.ai",
"claw_type": "openclaw",
"gateway_token": "ibl..."
}
gateway_token is write-only. Omit on update to keep the existing value.
| Method | Path | Purpose |
|---|---|---|
| GET | mentors/{mentor_unique_id}/claw-config/ | Read current binding (404 = not connected) |
| POST | mentors/{mentor_unique_id}/claw-config/ | Connect — body { "server": <instanceId>, "enabled": true } |
| DELETE | mentors/{mentor_unique_id}/claw-config/ | Disconnect |
| POST | mentors/{mentor_unique_id}/claw-config/push/ | Push current agent config to the sandbox |
push returns 400 No configuration to push when every agent-config
field is empty. Pre-flight by checking the agent config locally.
| Method | Path | Purpose |
|---|---|---|
| GET | mentors/{mentor_unique_id}/agent-config/ | Read prompts + model |
| PATCH | mentors/{mentor_unique_id}/agent-config/ | Upsert — first write bootstraps the row |
Body fields: identity, soul, user_context, tools,
agents, bootstrap, heartbeat, memory (each is the markdown
body of the corresponding *.md workspace file), plus model
("{provider}/{name}").
| Method | Path | Purpose |
|---|---|---|
| GET | agent-skills/ | List skills available in the tenant |
| POST | agent-skills/ | Create a skill — { name, slug, version, description, instruction } |
| PATCH | agent-skills/{id}/ | Update |
| DELETE | agent-skills/{id}/ | Delete |
| Method | Path | Purpose |
|---|---|---|
| GET | mentors/{mentor_unique_id}/skill-assignments/ | Skills bound to this agent |
| POST | mentors/{mentor_unique_id}/skill-assignments/ | Bind — { "skill": "<skill-uuid>", "enabled": true } |
| PATCH | mentors/{mentor_unique_id}/skill-assignments/{id}/ | Toggle enabled |
| DELETE | mentors/{mentor_unique_id}/skill-assignments/{id}/ | Unbind |
The skill field is the UUID (unique_id), not the integer
primary key — keying assignments by unique_id keeps the binding
stable across skill edits.
404 Not Found on claw-config/ — the agent isn't connected.
Treat as the "not connected" state, not a failure.400 No configuration to push — at least one prompt field must be
populated before pushing.400 Gateway token required — required on instance create; on
edit only when rotating.Build and run your ibl.ai app on desktop and mobile (iOS, Android, macOS, Surface)
Add the agent Access tab (role-based access control for editor and chat roles) to your Next.js app
Add the agent Audit tab (audit log of who changed what and when, with user/date/action filters) to your Next.js app
Wrap the Chat surface with the SDK's AppSidebar — projects dropdown, pinned/recent messages, and host-supplied content/footer menu items
Add the in-process Chat SDK component (full agent surface — message stream, canvas, file attach, voice, prompts) to a Next.js app
Add the agent MCP tab (Model Context Protocol connector management with featured connectors, custom connectors, OAuth, and add/edit dialogs) to your Next.js app