Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

Pages

Pages are React components that render custom UI views for a deployed agent. They live in pages/ and use SDK hooks to read from stores, invoke skills, and display structured data. This is how you build dashboards, morning briefs, investigation views, and other composed screens.

pages/
├── ops-dashboard.tsx
├── morning-brief.tsx
└── deal-detail.tsx

Page Format

Each page file exports a page config object and a default React component:

export const page = {
  name: "ops-dashboard",
  description: "Facility overview — alerts and device status",
  stores: ["active-alerts", "zone-status"],
  automations: ["scan-alerts"],
};
 
export default function OpsDashboard() {
  const [alerts, setAlerts] = React.useState([]);
 
  React.useEffect(() => {
    fetch("/api/stores/active-alerts")
      .then((res) => res.json())
      .then((data) => setAlerts(data.documents || []))
      .catch(() => {});
  }, []);
 
  return (
    <div
      style={{
        padding: "24px",
        background: "#0f1117",
        minHeight: "100%",
        color: "#e4e4e7",
      }}
    >
      <h1>Operations Dashboard</h1>
      <p>{alerts.length} active alerts</p>
    </div>
  );
}

Page Config

FieldTypeDefaultDescription
namestringfilenamePage identifier and URL slug
descriptionstringShown in the page header and sidebar tooltip
storesstring[]Stores this page reads from. Shown in the data source bar with links.
automationsstring[]Automations that populate the page data. Shown in the data source bar with status, toggle, and run button.
iconstringLucide icon name (e.g., 'shield', 'monitor', 'bar-chart')
hiddenbooleanfalseIf true, excluded from sidebar

When stores or automations are declared, the runtime automatically shows a data source bar above the page with store links, automation live/paused toggle, schedule, and a run button. This is a platform feature — no code required in the page itself.

SDK Hooks

Pages use hooks from @amodalai/react to access agent data:

HookDescription
useStoreList(store, options)Fetch multiple documents with filtering, sorting, and pagination
useStore(store, key)Fetch a single document by key
useSkillAction(skill, options)Invoke a skill from the page

useStoreList

const { data, loading, error, refresh } = useStoreList("classified-alerts", {
  filter: { severity: "P1" },
  sort: { field: "timestamp", order: "desc" },
  limit: 50,
  refreshInterval: 10000, // auto-refresh every 10s
});

useStore

const { data: alert } = useStore("classified-alerts", alertId);

useSkillAction

const { invoke, loading } = useSkillAction("triage");
 
const handleTriage = () => {
  invoke({ query: "Triage the latest alerts" });
};

Sidebar Integration

Pages appear in the agent UI under a Pages section. The name is auto-formatted from the filename (ops-dashboard → "Ops Dashboard"). Click a page to navigate to /pages/{pageName}.

Hidden pages (hidden: true) are excluded from the sidebar but still accessible via direct URL — useful for detail pages navigated to from other pages.

Context Pages

Pages with context params are detail views that receive route parameters:

export const page = {
  name: "deal-detail",
  icon: "file-text",
  context: { dealId: "string" },
  hidden: true, // navigated to, not shown in sidebar
};
 
export default function DealDetail({ dealId }: { dealId: string }) {
  const { data: deal } = useStore("deals", dealId);
  // ...
}

Entity Pages vs. Composed Pages

  • Entity pages are auto-generated from store definitions — list and detail views come for free without writing page files
  • Composed pages are what you define in pages/ — custom views that combine data from multiple stores with custom layout and logic

Only composed pages need explicit page files. If you just need a list/detail view of a single store, the runtime generates that automatically.

Deploying Page Changes

In Studio, page edits follow the normal source workflow: edit, review the diff, commit, deploy, and promote when ready. This keeps dashboard changes tied to the same deploy history as skills, knowledge, connections, stores, and automations.

Example: Surveillance Dashboard

import { useStoreList } from "@amodalai/react";
 
export const page = {
  name: "ops-dashboard",
  icon: "shield",
  description: "Facility surveillance overview",
};
 
export default function OpsDashboard() {
  const { data: alerts } = useStoreList("classified-alerts", {
    sort: { field: "confidence", order: "desc" },
    limit: 10,
  });
  const { data: zones } = useStoreList("zone-status");
  const { data: devices } = useStoreList("device-profiles");
 
  return (
    <div className="grid grid-cols-2 gap-4">
      <section>
        <h2>Active Alerts</h2>
        {alerts?.map((a) => (
          <AlertCard key={a.key} alert={a.payload} />
        ))}
      </section>
      <section>
        <h2>Zone Status</h2>
        {zones?.map((z) => (
          <ZoneCard key={z.key} zone={z.payload} />
        ))}
      </section>
    </div>
  );
}