diff --git a/apps/console/src/pages/AgentsList.tsx b/apps/console/src/pages/AgentsList.tsx
index 0e97ece1..831e8574 100644
--- a/apps/console/src/pages/AgentsList.tsx
+++ b/apps/console/src/pages/AgentsList.tsx
@@ -98,21 +98,21 @@ export function AgentsList() {
setAuxLoading(true);
try {
const all = await api<{ data: Agent[] }>("/v1/agents?limit=200&status=any");
- setAllAgents(all.data);
+ setAllAgents(all.data ?? []);
await Promise.allSettled([
(async () => {
const sk = await api<{
data: Array<{ id: string; name: string; description: string }>;
}>("/v1/skills");
- setCustomSkills(sk.data);
+ setCustomSkills(sk.data ?? []);
})().catch((e) => console.warn("[AgentsList] /v1/skills aux fetch failed", e)),
(async () => {
const mc = await api<{ data: ModelCard[] }>("/v1/model_cards?limit=200");
- setModelCards(mc.data);
+ setModelCards(mc.data ?? []);
})().catch((e) => console.warn("[AgentsList] /v1/model_cards aux fetch failed", e)),
(async () => {
const rt = await api<{ runtimes: Runtime[] }>("/v1/runtimes");
- setRuntimes(rt.runtimes);
+ setRuntimes(rt.runtimes ?? []);
})().catch((e) => console.warn("[AgentsList] /v1/runtimes aux fetch failed", e)),
]);
} finally {
diff --git a/apps/console/src/pages/RuntimesList.tsx b/apps/console/src/pages/RuntimesList.tsx
index 0e901007..ade84d54 100644
--- a/apps/console/src/pages/RuntimesList.tsx
+++ b/apps/console/src/pages/RuntimesList.tsx
@@ -171,11 +171,11 @@ export function RuntimesList() {
},
{
id: "agents",
- accessorFn: (r) => r.agents.map((a) => a.id).join(", "),
+ accessorFn: (r) => (r.agents ?? []).map((a) => a.id).join(", "),
header: "Agents detected",
cell: ({ row }) => (
- {row.original.agents.length === 0 ? "—" : row.original.agents.map((a) => a.id).join(", ")}
+ {(row.original.agents ?? []).length === 0 ? "—" : (row.original.agents ?? []).map((a) => a.id).join(", ")}
),
},
diff --git a/apps/console/src/pages/agents/AgentFormDialog.tsx b/apps/console/src/pages/agents/AgentFormDialog.tsx
index ae2d4ce5..2163c90a 100644
--- a/apps/console/src/pages/agents/AgentFormDialog.tsx
+++ b/apps/console/src/pages/agents/AgentFormDialog.tsx
@@ -977,7 +977,7 @@ function BasicTab({
{runtimes.map((r) => (
{r.hostname} ({r.status}
- {r.status === "online" && r.agents.length
+ {r.status === "online" && r.agents?.length
? ` · ${r.agents.length} agents`
: ""}
)
diff --git a/docker-compose.yml b/docker-compose.yml
index 61c6afc0..3218c9c0 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -41,6 +41,9 @@ services:
# agent uses to deliver downloadable artefacts. Bind-mounted into
# ./data so files survive `docker stop`.
SESSION_OUTPUTS_DIR: /app/data/session-outputs
+ # Local FS blob store for uploaded files. When FILES_S3_ENDPOINT is
+ # set the S3 backend is used instead and this var is ignored.
+ FILES_BLOB_DIR: /app/data/files-blobs
# Outbound credential injection via the oma-vault sidecar. When set,
# LocalSubprocessSandbox.setOutboundContext wires the subprocess env
# to route HTTPS traffic through oma-vault for header injection.