aifirst: lift context/agents/tools runtime to lib-aifirst-ui
The mechanism (context surface registry, persona storage + hooks, tool
parser/dispatcher) is now generic and lives in @crema/aifirst-ui/{context,
agents,tools}. This template keeps only the arcadia-shaped configuration:
- agents.ts — owns DEFAULT_AGENTS + legacy/retired migration sets, calls
configureAgents() at module load, re-exports the runtime
- admin-tools.ts — keeps the 19 arcadia tool definitions, binds the
runtime via createToolRuntime(TOOLS), re-exports the bound functions
- admin-context.ts — deleted; 18 routes now import directly from
@crema/aifirst-ui/context
Routes that import from ~/lib/agents and ~/lib/admin-tools are unchanged
(wrapper modules preserve the existing import surface).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -47,7 +47,7 @@ import {
|
||||
} from "~/lib/arcadia/audit-logs"
|
||||
import { pageTitle } from "~/lib/page-meta"
|
||||
import { useSession } from "~/lib/session"
|
||||
import { useRegisterAdminContext } from "~/lib/admin-context"
|
||||
import { useRegisterContext } from "@crema/aifirst-ui/context"
|
||||
|
||||
export const meta = () => pageTitle("Audit log")
|
||||
|
||||
@@ -187,7 +187,7 @@ export default function ActivityRoute() {
|
||||
}),
|
||||
[logs],
|
||||
)
|
||||
useRegisterAdminContext("audit_log", summary)
|
||||
useRegisterContext("audit_log", summary)
|
||||
|
||||
const table = useTable<AuditLog>({
|
||||
data: logs,
|
||||
|
||||
@@ -101,7 +101,7 @@ import {
|
||||
subscribeActiveReasoning,
|
||||
type ReasoningEffort,
|
||||
} from "~/lib/arcadia/llm-configs"
|
||||
import { formatAdminContextForPrompt } from "~/lib/admin-context"
|
||||
import { formatContextForPrompt } from "@crema/aifirst-ui/context"
|
||||
import { ConfirmCard } from "~/components/assistant/confirm-card"
|
||||
import { renderToolResult } from "~/components/assistant/tool-result-renderers"
|
||||
|
||||
@@ -722,7 +722,7 @@ function ChatSurface({
|
||||
ARCADIA_KNOWLEDGE,
|
||||
persona,
|
||||
handoffNote,
|
||||
formatAdminContextForPrompt(),
|
||||
formatContextForPrompt(),
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join("\n\n")
|
||||
|
||||
@@ -63,7 +63,7 @@ import {
|
||||
import { listTenants, type Tenant } from "~/lib/arcadia/tenants"
|
||||
import { pageTitle } from "~/lib/page-meta"
|
||||
import { useSession } from "~/lib/session"
|
||||
import { useRegisterAdminContext } from "~/lib/admin-context"
|
||||
import { useRegisterContext } from "@crema/aifirst-ui/context"
|
||||
|
||||
export const meta = () => pageTitle("Announcements")
|
||||
|
||||
@@ -218,7 +218,7 @@ export default function AnnouncementsRoute() {
|
||||
}),
|
||||
[items],
|
||||
)
|
||||
useRegisterAdminContext("announcements", summary)
|
||||
useRegisterContext("announcements", summary)
|
||||
|
||||
const table = useTable<Announcement>({
|
||||
data: items,
|
||||
|
||||
@@ -90,7 +90,7 @@ wait_for assistant-ui-control
|
||||
\`\`\`"`
|
||||
|
||||
|
||||
import { formatAdminContextForPrompt } from "~/lib/admin-context"
|
||||
import { formatContextForPrompt } from "@crema/aifirst-ui/context"
|
||||
import {
|
||||
buildDenialMessages,
|
||||
classifyCalls,
|
||||
@@ -111,7 +111,7 @@ function buildAdminPreface(activeAgent: Agent | undefined, uiControl: boolean):
|
||||
const persona = activeAgent
|
||||
? `Active persona: ${activeAgent.name} — ${activeAgent.role}\n${activeAgent.prompt}`
|
||||
: ""
|
||||
const ctx = formatAdminContextForPrompt()
|
||||
const ctx = formatContextForPrompt()
|
||||
const parts = [
|
||||
"You are the operator's assistant inside Arcadia Admin. Be precise and direct. You have native function tools attached to this conversation — call them whenever the user asks about live platform state (counts, statuses, listings, lookups). Never invent tenant slugs, user counts, or statuses; if you need data, call a tool.",
|
||||
"Two retrieval surfaces exist for documentation/knowledge: `search_docs` (browser-side, BM25 over the bundled arcadia docs — fast, always available, small corpus) and `search_kb` (server-side, BM25 over arcadia-search — `docs` (arcadia parity), `operator-tools` (arcadia-search + arcadia-admin admin docs), `files` (uploaded files), plus any custom corpora the operator adds via /search). For questions about the bundled arcadia docs either is fine; prefer `search_kb` for richer hits or for content outside the bundled docs (uploaded files, the admin tooling itself, tenant-specific knowledge). If unsure what corpora exist, call `list_search_corpora`. When `search_kb` returns a chunk_id you want to expand, call `read_chunk(chunk_id, corpus)`. When the operator says results look stale or after they've uploaded new files, call `rebuild_search_corpus(tenant, corpus)`.",
|
||||
|
||||
@@ -84,7 +84,7 @@ import {
|
||||
} from "~/lib/arcadia/storage-configs"
|
||||
import { pageTitle } from "~/lib/page-meta"
|
||||
import { useSession } from "~/lib/session"
|
||||
import { useRegisterAdminContext } from "~/lib/admin-context"
|
||||
import { useRegisterContext } from "@crema/aifirst-ui/context"
|
||||
|
||||
export const meta = () => pageTitle("Buckets")
|
||||
|
||||
@@ -194,7 +194,7 @@ export default function BucketsRoute() {
|
||||
}),
|
||||
[activeConfig, buckets],
|
||||
)
|
||||
useRegisterAdminContext("buckets", summary)
|
||||
useRegisterContext("buckets", summary)
|
||||
|
||||
return (
|
||||
<AppShell>
|
||||
|
||||
@@ -35,7 +35,7 @@ import {
|
||||
} from "~/lib/arcadia/health"
|
||||
import { listTenants, type Tenant } from "~/lib/arcadia/tenants"
|
||||
import { listUsers, type User } from "~/lib/arcadia/users"
|
||||
import { useRegisterAdminContext } from "~/lib/admin-context"
|
||||
import { useRegisterContext } from "@crema/aifirst-ui/context"
|
||||
import { pageTitle } from "~/lib/page-meta"
|
||||
import { useSession } from "~/lib/session"
|
||||
|
||||
@@ -96,7 +96,7 @@ export default function HomeRoute() {
|
||||
}
|
||||
}, [data])
|
||||
|
||||
useRegisterAdminContext("overview", stats)
|
||||
useRegisterContext("overview", stats)
|
||||
|
||||
return (
|
||||
<AppShell>
|
||||
|
||||
@@ -65,7 +65,7 @@ import { listUsers, type User } from "~/lib/arcadia/users"
|
||||
import { listRoles, type Role } from "~/lib/arcadia/roles"
|
||||
import { pageTitle } from "~/lib/page-meta"
|
||||
import { useSession } from "~/lib/session"
|
||||
import { useRegisterAdminContext } from "~/lib/admin-context"
|
||||
import { useRegisterContext } from "@crema/aifirst-ui/context"
|
||||
|
||||
export const meta = () => pageTitle("Memberships")
|
||||
|
||||
@@ -272,7 +272,7 @@ export default function MembershipsRoute() {
|
||||
}),
|
||||
[memberships],
|
||||
)
|
||||
useRegisterAdminContext("memberships", summary)
|
||||
useRegisterContext("memberships", summary)
|
||||
|
||||
const table = useTable<Membership>({
|
||||
data: filtered,
|
||||
|
||||
@@ -81,7 +81,7 @@ import {
|
||||
} from "~/lib/arcadia/health"
|
||||
import { pageTitle } from "~/lib/page-meta"
|
||||
import { useSession } from "~/lib/session"
|
||||
import { useRegisterAdminContext } from "~/lib/admin-context"
|
||||
import { useRegisterContext } from "@crema/aifirst-ui/context"
|
||||
|
||||
export const meta = () => pageTitle("Monitoring")
|
||||
|
||||
@@ -193,7 +193,7 @@ export default function MonitoringRoute() {
|
||||
}),
|
||||
[data],
|
||||
)
|
||||
useRegisterAdminContext("monitoring", summary)
|
||||
useRegisterContext("monitoring", summary)
|
||||
|
||||
return (
|
||||
<AppShell>
|
||||
|
||||
@@ -61,7 +61,7 @@ import {
|
||||
import { listDroplets, type Droplet } from "~/lib/arcadia/monitoring"
|
||||
import { pageTitle } from "~/lib/page-meta"
|
||||
import { useSession } from "~/lib/session"
|
||||
import { useRegisterAdminContext } from "~/lib/admin-context"
|
||||
import { useRegisterContext } from "@crema/aifirst-ui/context"
|
||||
|
||||
export const meta = () => pageTitle("Networking")
|
||||
|
||||
@@ -107,7 +107,7 @@ export default function NetworkingRoute() {
|
||||
if (session) refresh()
|
||||
}, [session, refresh])
|
||||
|
||||
useRegisterAdminContext("networking", {
|
||||
useRegisterContext("networking", {
|
||||
firewalls: firewalls.length,
|
||||
vpcs: vpcs.length,
|
||||
domains: domains.length,
|
||||
|
||||
@@ -72,7 +72,7 @@ import {
|
||||
} from "~/lib/arcadia/scheduled-tasks"
|
||||
import { pageTitle } from "~/lib/page-meta"
|
||||
import { useSession } from "~/lib/session"
|
||||
import { useRegisterAdminContext } from "~/lib/admin-context"
|
||||
import { useRegisterContext } from "@crema/aifirst-ui/context"
|
||||
|
||||
export const meta = () => pageTitle("Scheduled tasks")
|
||||
|
||||
@@ -227,7 +227,7 @@ export default function ScheduledTasksRoute() {
|
||||
}),
|
||||
[tasks],
|
||||
)
|
||||
useRegisterAdminContext("scheduled_tasks", summary)
|
||||
useRegisterContext("scheduled_tasks", summary)
|
||||
|
||||
const table = useTable<ScheduledTask>({
|
||||
data: tasks,
|
||||
|
||||
@@ -60,7 +60,7 @@ import {
|
||||
} from "~/lib/search-admin"
|
||||
import { pageTitle } from "~/lib/page-meta"
|
||||
import { useSession } from "~/lib/session"
|
||||
import { useRegisterAdminContext } from "~/lib/admin-context"
|
||||
import { useRegisterContext } from "@crema/aifirst-ui/context"
|
||||
|
||||
export const meta = () => pageTitle("Search")
|
||||
|
||||
@@ -157,7 +157,7 @@ export default function SearchRoute() {
|
||||
}),
|
||||
[tenants, corpora],
|
||||
)
|
||||
useRegisterAdminContext("search", adminSurface)
|
||||
useRegisterContext("search", adminSurface)
|
||||
|
||||
const rebuild = useCallback(
|
||||
async (tenant: string, corpus: string) => {
|
||||
|
||||
@@ -77,7 +77,7 @@ import {
|
||||
} from "~/lib/arcadia/secrets"
|
||||
import { pageTitle } from "~/lib/page-meta"
|
||||
import { useSession } from "~/lib/session"
|
||||
import { useRegisterAdminContext } from "~/lib/admin-context"
|
||||
import { useRegisterContext } from "@crema/aifirst-ui/context"
|
||||
|
||||
export const meta = () => pageTitle("Secrets")
|
||||
|
||||
@@ -234,7 +234,7 @@ export default function SecretsRoute() {
|
||||
}),
|
||||
[secrets],
|
||||
)
|
||||
useRegisterAdminContext("secrets", summary)
|
||||
useRegisterContext("secrets", summary)
|
||||
|
||||
const table = useTable<Secret>({
|
||||
data: filtered,
|
||||
|
||||
@@ -59,7 +59,7 @@ import {
|
||||
} from "~/lib/arcadia/sso"
|
||||
import { pageTitle } from "~/lib/page-meta"
|
||||
import { useSession } from "~/lib/session"
|
||||
import { useRegisterAdminContext } from "~/lib/admin-context"
|
||||
import { useRegisterContext } from "@crema/aifirst-ui/context"
|
||||
|
||||
export const meta = () => pageTitle("SSO")
|
||||
|
||||
@@ -102,7 +102,7 @@ export default function SsoRoute() {
|
||||
if (session) refresh()
|
||||
}, [session, refresh])
|
||||
|
||||
useRegisterAdminContext("sso", {
|
||||
useRegisterContext("sso", {
|
||||
identity_providers: idps.length,
|
||||
enabled_idps: idps.filter((i) => i.enabled).length,
|
||||
active_sessions: sessions.length,
|
||||
|
||||
@@ -70,7 +70,7 @@ import {
|
||||
} from "~/lib/arcadia/status-page"
|
||||
import { pageTitle } from "~/lib/page-meta"
|
||||
import { useSession } from "~/lib/session"
|
||||
import { useRegisterAdminContext } from "~/lib/admin-context"
|
||||
import { useRegisterContext } from "@crema/aifirst-ui/context"
|
||||
|
||||
export const meta = () => pageTitle("Status page")
|
||||
|
||||
@@ -129,7 +129,7 @@ export default function StatusPageRoute() {
|
||||
if (session) refresh()
|
||||
}, [session, refresh])
|
||||
|
||||
useRegisterAdminContext("status_page", {
|
||||
useRegisterContext("status_page", {
|
||||
components: components.length,
|
||||
open_incidents: incidents.filter((i) => i.status !== "resolved").length,
|
||||
subscribers: subscribers.length,
|
||||
|
||||
@@ -77,7 +77,7 @@ import {
|
||||
} from "~/lib/arcadia/storage-configs"
|
||||
import { pageTitle } from "~/lib/page-meta"
|
||||
import { useSession } from "~/lib/session"
|
||||
import { useRegisterAdminContext } from "~/lib/admin-context"
|
||||
import { useRegisterContext } from "@crema/aifirst-ui/context"
|
||||
|
||||
export const meta = () => pageTitle("Storage")
|
||||
|
||||
@@ -250,7 +250,7 @@ export default function StorageRoute() {
|
||||
}),
|
||||
[configs],
|
||||
)
|
||||
useRegisterAdminContext("storage", summary)
|
||||
useRegisterContext("storage", summary)
|
||||
|
||||
const table = useTable<StorageConfig>({
|
||||
data: configs,
|
||||
|
||||
@@ -36,7 +36,7 @@ import {
|
||||
} from "~/lib/arcadia/tenants"
|
||||
import { pageTitle } from "~/lib/page-meta"
|
||||
import { useSession } from "~/lib/session"
|
||||
import { useRegisterAdminContext } from "~/lib/admin-context"
|
||||
import { useRegisterContext } from "@crema/aifirst-ui/context"
|
||||
|
||||
export const meta = () => pageTitle("Tenants")
|
||||
|
||||
@@ -160,7 +160,7 @@ export default function TenantsRoute() {
|
||||
}),
|
||||
[tenants],
|
||||
)
|
||||
useRegisterAdminContext("tenants", tenantSummary)
|
||||
useRegisterContext("tenants", tenantSummary)
|
||||
|
||||
const table = useTable<Tenant>({
|
||||
data: tenants,
|
||||
|
||||
@@ -87,7 +87,7 @@ import {
|
||||
} from "~/lib/arcadia/users"
|
||||
import { pageTitle } from "~/lib/page-meta"
|
||||
import { useSession } from "~/lib/session"
|
||||
import { useRegisterAdminContext } from "~/lib/admin-context"
|
||||
import { useRegisterContext } from "@crema/aifirst-ui/context"
|
||||
import { UserDetailSheet } from "~/components/users/user-detail-sheet"
|
||||
|
||||
export const meta = () => pageTitle("Users")
|
||||
@@ -167,7 +167,7 @@ export default function UsersRoute() {
|
||||
}),
|
||||
[users, invitations, roles],
|
||||
)
|
||||
useRegisterAdminContext("users", summary)
|
||||
useRegisterContext("users", summary)
|
||||
|
||||
return (
|
||||
<AppShell>
|
||||
|
||||
@@ -77,7 +77,7 @@ import {
|
||||
} from "~/lib/arcadia/webhooks"
|
||||
import { pageTitle } from "~/lib/page-meta"
|
||||
import { useSession } from "~/lib/session"
|
||||
import { useRegisterAdminContext } from "~/lib/admin-context"
|
||||
import { useRegisterContext } from "@crema/aifirst-ui/context"
|
||||
|
||||
export const meta = () => pageTitle("Webhooks")
|
||||
|
||||
@@ -228,7 +228,7 @@ export default function WebhooksRoute() {
|
||||
}),
|
||||
[webhooks],
|
||||
)
|
||||
useRegisterAdminContext("webhooks", summary)
|
||||
useRegisterContext("webhooks", summary)
|
||||
|
||||
const table = useTable<Webhook>({
|
||||
data: webhooks,
|
||||
|
||||
Reference in New Issue
Block a user