@copilotz/admin 0.9.38 → 0.9.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +887 -396
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +78 -1
- package/dist/index.d.ts +78 -1
- package/dist/index.js +841 -344
- package/dist/index.js.map +1 -1
- package/dist/styles.css +22 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -45,6 +45,7 @@ __export(index_exports, {
|
|
|
45
45
|
addUsageTotals: () => addUsageTotals,
|
|
46
46
|
agentsModule: () => agentsModule,
|
|
47
47
|
aggregateUsageRows: () => aggregateUsageRows,
|
|
48
|
+
brainModule: () => brainModule,
|
|
48
49
|
buildUsageChartState: () => buildUsageChartState,
|
|
49
50
|
canAccessAdminPermission: () => canAccessAdminPermission,
|
|
50
51
|
collectAdminNavItems: () => collectAdminNavItems,
|
|
@@ -259,13 +260,16 @@ function createAdminClient(options = {}) {
|
|
|
259
260
|
),
|
|
260
261
|
listAgents: async (listOptions = {}) => {
|
|
261
262
|
const windowRange = getRangeWindow(listOptions.range ?? "7d");
|
|
262
|
-
return await requestJson(
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
263
|
+
return await requestJson(
|
|
264
|
+
`${paths.adminBase}/agents`,
|
|
265
|
+
{
|
|
266
|
+
search: listOptions.search,
|
|
267
|
+
namespace: listOptions.namespace,
|
|
268
|
+
from: windowRange.from,
|
|
269
|
+
to: windowRange.to,
|
|
270
|
+
limit: String(listOptions.limit ?? 25)
|
|
271
|
+
}
|
|
272
|
+
);
|
|
269
273
|
},
|
|
270
274
|
getThread: async (threadId) => await requestJson(
|
|
271
275
|
`${paths.threadsBase}/${encodeURIComponent(threadId)}`
|
|
@@ -299,6 +303,19 @@ function createAdminClient(options = {}) {
|
|
|
299
303
|
);
|
|
300
304
|
return normalizeQueueEvent(payload);
|
|
301
305
|
},
|
|
306
|
+
getBrain: async (filters = {}) => await requestJson(`${paths.adminBase}/brain`, {
|
|
307
|
+
namespace: filters.namespace,
|
|
308
|
+
memorySpaceId: filters.memorySpaceId,
|
|
309
|
+
checkpointId: filters.checkpointId,
|
|
310
|
+
agentId: filters.agentId,
|
|
311
|
+
threadId: filters.threadId,
|
|
312
|
+
layer: filters.layer === "all" ? void 0 : filters.layer,
|
|
313
|
+
kind: filters.kind === "all" ? void 0 : filters.kind,
|
|
314
|
+
status: filters.status === "all" ? void 0 : filters.status,
|
|
315
|
+
search: filters.search,
|
|
316
|
+
limit: String(filters.limit ?? 160),
|
|
317
|
+
offset: filters.offset ? String(filters.offset) : void 0
|
|
318
|
+
}),
|
|
302
319
|
listCollections: async () => await requestJson(paths.collectionsBase),
|
|
303
320
|
listCollectionItems: async (collection, listOptions = {}) => await requestJson(
|
|
304
321
|
`${paths.collectionsBase}/${encodeURIComponent(collection)}`,
|
|
@@ -345,8 +362,8 @@ function createAdminClient(options = {}) {
|
|
|
345
362
|
}
|
|
346
363
|
|
|
347
364
|
// src/core/CopilotzAdmin.tsx
|
|
348
|
-
var
|
|
349
|
-
var
|
|
365
|
+
var import_react11 = __toESM(require("react"), 1);
|
|
366
|
+
var import_lucide_react14 = require("lucide-react");
|
|
350
367
|
|
|
351
368
|
// src/lib/utils.ts
|
|
352
369
|
var import_clsx = require("clsx");
|
|
@@ -2001,19 +2018,491 @@ function AgentDetailPage({ context }) {
|
|
|
2001
2018
|
] });
|
|
2002
2019
|
}
|
|
2003
2020
|
|
|
2004
|
-
// src/modules/
|
|
2021
|
+
// src/modules/brain/index.tsx
|
|
2005
2022
|
var import_react3 = __toESM(require("react"), 1);
|
|
2006
2023
|
var import_lucide_react7 = require("lucide-react");
|
|
2007
2024
|
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
2025
|
+
var BRAIN_LAYERS = ["all", "knowledge", "working"];
|
|
2026
|
+
var BRAIN_STATUSES = ["active", "all", "superseded", "archived"];
|
|
2027
|
+
var BRAIN_KINDS = [
|
|
2028
|
+
"all",
|
|
2029
|
+
"decision",
|
|
2030
|
+
"fact",
|
|
2031
|
+
"preference",
|
|
2032
|
+
"task",
|
|
2033
|
+
"constraint",
|
|
2034
|
+
"current_state",
|
|
2035
|
+
"challenge",
|
|
2036
|
+
"risk",
|
|
2037
|
+
"open_question",
|
|
2038
|
+
"next_action"
|
|
2039
|
+
];
|
|
2040
|
+
function brainModule() {
|
|
2041
|
+
return {
|
|
2042
|
+
group: "data",
|
|
2043
|
+
icon: import_lucide_react7.Brain,
|
|
2044
|
+
id: "brain",
|
|
2045
|
+
label: "Brain",
|
|
2046
|
+
navItems: [{
|
|
2047
|
+
group: "data",
|
|
2048
|
+
icon: import_lucide_react7.Brain,
|
|
2049
|
+
id: "brain",
|
|
2050
|
+
label: "Brain",
|
|
2051
|
+
order: 10,
|
|
2052
|
+
routeId: "brain"
|
|
2053
|
+
}],
|
|
2054
|
+
routes: [{
|
|
2055
|
+
id: "brain",
|
|
2056
|
+
title: "Brain",
|
|
2057
|
+
render: (context) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(BrainPage, { context })
|
|
2058
|
+
}]
|
|
2059
|
+
};
|
|
2060
|
+
}
|
|
2061
|
+
function BrainPage({ context }) {
|
|
2062
|
+
const [search, setSearch] = import_react3.default.useState("");
|
|
2063
|
+
const [layer, setLayer] = import_react3.default.useState("all");
|
|
2064
|
+
const [status, setStatus] = import_react3.default.useState(
|
|
2065
|
+
"active"
|
|
2066
|
+
);
|
|
2067
|
+
const [kind, setKind] = import_react3.default.useState("all");
|
|
2068
|
+
const [agentId, setAgentId] = import_react3.default.useState("");
|
|
2069
|
+
const [response, setResponse] = import_react3.default.useState(
|
|
2070
|
+
null
|
|
2071
|
+
);
|
|
2072
|
+
const [selectedNode, setSelectedNode] = import_react3.default.useState(
|
|
2073
|
+
null
|
|
2074
|
+
);
|
|
2075
|
+
const [loading, setLoading] = import_react3.default.useState(false);
|
|
2076
|
+
const [error, setError] = import_react3.default.useState(null);
|
|
2077
|
+
const loadBrain = import_react3.default.useCallback(async () => {
|
|
2078
|
+
setLoading(true);
|
|
2079
|
+
setError(null);
|
|
2080
|
+
try {
|
|
2081
|
+
const next = await context.client.getBrain({
|
|
2082
|
+
namespace: context.scope.namespace || void 0,
|
|
2083
|
+
search: search.trim() || void 0,
|
|
2084
|
+
layer,
|
|
2085
|
+
status,
|
|
2086
|
+
kind,
|
|
2087
|
+
agentId: agentId.trim() || void 0,
|
|
2088
|
+
limit: 180
|
|
2089
|
+
});
|
|
2090
|
+
setResponse(next);
|
|
2091
|
+
setSelectedNode(
|
|
2092
|
+
(current) => current && next.nodes.some((node) => node.id === current.id) ? current : next.nodes[0] ?? null
|
|
2093
|
+
);
|
|
2094
|
+
} catch (cause) {
|
|
2095
|
+
setError(cause instanceof Error ? cause.message : "Failed to load brain");
|
|
2096
|
+
setResponse(null);
|
|
2097
|
+
setSelectedNode(null);
|
|
2098
|
+
} finally {
|
|
2099
|
+
setLoading(false);
|
|
2100
|
+
}
|
|
2101
|
+
}, [
|
|
2102
|
+
agentId,
|
|
2103
|
+
context.client,
|
|
2104
|
+
context.scope.namespace,
|
|
2105
|
+
kind,
|
|
2106
|
+
layer,
|
|
2107
|
+
search,
|
|
2108
|
+
status
|
|
2109
|
+
]);
|
|
2110
|
+
import_react3.default.useEffect(() => {
|
|
2111
|
+
void loadBrain();
|
|
2112
|
+
}, [context.refreshKey, context.scope.namespace, loadBrain]);
|
|
2113
|
+
const data = response ?? emptyBrainResponse();
|
|
2114
|
+
const knowledgeCount = data.stats.byLayer.knowledge ?? 0;
|
|
2115
|
+
const workingCount = data.stats.byLayer.working ?? 0;
|
|
2116
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "space-y-4", children: [
|
|
2117
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
2118
|
+
PageHeader,
|
|
2119
|
+
{
|
|
2120
|
+
title: "Brain",
|
|
2121
|
+
description: "Unified knowledge and working state for the active namespace.",
|
|
2122
|
+
badges: [
|
|
2123
|
+
{
|
|
2124
|
+
label: context.scope.namespace ?? "all namespaces",
|
|
2125
|
+
variant: "secondary"
|
|
2126
|
+
}
|
|
2127
|
+
],
|
|
2128
|
+
actions: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
2129
|
+
Button,
|
|
2130
|
+
{
|
|
2131
|
+
disabled: loading,
|
|
2132
|
+
onClick: () => void loadBrain(),
|
|
2133
|
+
size: "sm",
|
|
2134
|
+
type: "button",
|
|
2135
|
+
variant: "outline",
|
|
2136
|
+
children: [
|
|
2137
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react7.RefreshCw, { className: cn("size-3", loading && "animate-spin") }),
|
|
2138
|
+
"Refresh"
|
|
2139
|
+
]
|
|
2140
|
+
}
|
|
2141
|
+
)
|
|
2142
|
+
}
|
|
2143
|
+
),
|
|
2144
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
2145
|
+
MetricStrip,
|
|
2146
|
+
{
|
|
2147
|
+
items: [
|
|
2148
|
+
{
|
|
2149
|
+
label: "Brain nodes",
|
|
2150
|
+
value: data.stats.total,
|
|
2151
|
+
detail: `${data.pageInfo.returned} shown`,
|
|
2152
|
+
icon: import_lucide_react7.Brain
|
|
2153
|
+
},
|
|
2154
|
+
{
|
|
2155
|
+
label: "Knowledge",
|
|
2156
|
+
value: knowledgeCount,
|
|
2157
|
+
detail: "Durable nodes",
|
|
2158
|
+
icon: import_lucide_react7.CircleDot
|
|
2159
|
+
},
|
|
2160
|
+
{
|
|
2161
|
+
label: "Working",
|
|
2162
|
+
value: workingCount,
|
|
2163
|
+
detail: "Current state",
|
|
2164
|
+
icon: import_lucide_react7.Sparkles
|
|
2165
|
+
},
|
|
2166
|
+
{
|
|
2167
|
+
label: "Clusters",
|
|
2168
|
+
value: data.clusters.length,
|
|
2169
|
+
detail: "Layer and kind",
|
|
2170
|
+
icon: import_lucide_react7.Network
|
|
2171
|
+
}
|
|
2172
|
+
]
|
|
2173
|
+
}
|
|
2174
|
+
),
|
|
2175
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
2176
|
+
FilterBar,
|
|
2177
|
+
{
|
|
2178
|
+
actions: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
2179
|
+
Button,
|
|
2180
|
+
{
|
|
2181
|
+
disabled: loading,
|
|
2182
|
+
onClick: () => void loadBrain(),
|
|
2183
|
+
size: "sm",
|
|
2184
|
+
type: "button",
|
|
2185
|
+
children: [
|
|
2186
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react7.Search, { className: "size-3" }),
|
|
2187
|
+
"Search"
|
|
2188
|
+
]
|
|
2189
|
+
}
|
|
2190
|
+
),
|
|
2191
|
+
onSearchChange: setSearch,
|
|
2192
|
+
searchPlaceholder: "Search brain",
|
|
2193
|
+
searchValue: search,
|
|
2194
|
+
children: [
|
|
2195
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
2196
|
+
Select,
|
|
2197
|
+
{
|
|
2198
|
+
value: layer,
|
|
2199
|
+
onValueChange: (value) => setLayer(value),
|
|
2200
|
+
children: [
|
|
2201
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SelectTrigger, { className: "h-8 w-[140px] text-xs", "aria-label": "Layer", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SelectValue, {}) }),
|
|
2202
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SelectContent, { children: BRAIN_LAYERS.map((option) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SelectItem, { value: option, children: option === "all" ? "All layers" : formatLabel(option) }, option)) })
|
|
2203
|
+
]
|
|
2204
|
+
}
|
|
2205
|
+
),
|
|
2206
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
2207
|
+
Select,
|
|
2208
|
+
{
|
|
2209
|
+
value: status,
|
|
2210
|
+
onValueChange: (value) => setStatus(value),
|
|
2211
|
+
children: [
|
|
2212
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SelectTrigger, { className: "h-8 w-[140px] text-xs", "aria-label": "Status", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SelectValue, {}) }),
|
|
2213
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SelectContent, { children: BRAIN_STATUSES.map((option) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SelectItem, { value: option, children: option === "all" ? "All statuses" : formatLabel(option) }, option)) })
|
|
2214
|
+
]
|
|
2215
|
+
}
|
|
2216
|
+
),
|
|
2217
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
2218
|
+
Select,
|
|
2219
|
+
{
|
|
2220
|
+
value: kind,
|
|
2221
|
+
onValueChange: (value) => setKind(value),
|
|
2222
|
+
children: [
|
|
2223
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SelectTrigger, { className: "h-8 w-[170px] text-xs", "aria-label": "Kind", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SelectValue, {}) }),
|
|
2224
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SelectContent, { children: BRAIN_KINDS.map((option) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SelectItem, { value: option, children: option === "all" ? "All kinds" : formatLabel(option) }, option)) })
|
|
2225
|
+
]
|
|
2226
|
+
}
|
|
2227
|
+
),
|
|
2228
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
2229
|
+
Input,
|
|
2230
|
+
{
|
|
2231
|
+
className: "h-8 w-[190px]",
|
|
2232
|
+
onChange: (event) => setAgentId(event.target.value),
|
|
2233
|
+
onKeyDown: (event) => {
|
|
2234
|
+
if (event.key === "Enter") void loadBrain();
|
|
2235
|
+
},
|
|
2236
|
+
placeholder: "Agent ID",
|
|
2237
|
+
value: agentId
|
|
2238
|
+
}
|
|
2239
|
+
)
|
|
2240
|
+
]
|
|
2241
|
+
}
|
|
2242
|
+
),
|
|
2243
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(EmptyState, { title: "Unable to load brain", description: error }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
2244
|
+
InspectorPanel,
|
|
2245
|
+
{
|
|
2246
|
+
side: selectedNode ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(BrainNodeInspector, { node: selectedNode }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
2247
|
+
EmptyState,
|
|
2248
|
+
{
|
|
2249
|
+
icon: import_lucide_react7.Brain,
|
|
2250
|
+
title: "No node selected",
|
|
2251
|
+
description: "Select a node from the map or table."
|
|
2252
|
+
}
|
|
2253
|
+
),
|
|
2254
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "space-y-4", children: [
|
|
2255
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
2256
|
+
BrainMap,
|
|
2257
|
+
{
|
|
2258
|
+
clusters: data.clusters,
|
|
2259
|
+
edges: data.edges,
|
|
2260
|
+
loading,
|
|
2261
|
+
nodes: data.nodes,
|
|
2262
|
+
onSelectNode: setSelectedNode,
|
|
2263
|
+
selectedNodeId: selectedNode?.id ?? null
|
|
2264
|
+
}
|
|
2265
|
+
),
|
|
2266
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
2267
|
+
ResourceTable,
|
|
2268
|
+
{
|
|
2269
|
+
rows: data.nodes,
|
|
2270
|
+
getRowKey: (row) => row.id,
|
|
2271
|
+
onRowClick: setSelectedNode,
|
|
2272
|
+
empty: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
2273
|
+
EmptyState,
|
|
2274
|
+
{
|
|
2275
|
+
icon: import_lucide_react7.Brain,
|
|
2276
|
+
title: loading ? "Loading brain" : "No brain nodes",
|
|
2277
|
+
description: loading ? "Fetching brain nodes for the active namespace." : "Knowledge and working-state nodes will appear here."
|
|
2278
|
+
}
|
|
2279
|
+
),
|
|
2280
|
+
columns: [
|
|
2281
|
+
{
|
|
2282
|
+
id: "node",
|
|
2283
|
+
header: "Node",
|
|
2284
|
+
className: "max-w-[360px]",
|
|
2285
|
+
render: (row) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "min-w-0", children: [
|
|
2286
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "truncate font-medium", children: row.name }),
|
|
2287
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "truncate text-xs text-muted-foreground", children: row.content || "-" })
|
|
2288
|
+
] })
|
|
2289
|
+
},
|
|
2290
|
+
{
|
|
2291
|
+
id: "layer",
|
|
2292
|
+
header: "Layer",
|
|
2293
|
+
render: (row) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(LayerBadge, { layer: row.layer })
|
|
2294
|
+
},
|
|
2295
|
+
{
|
|
2296
|
+
id: "kind",
|
|
2297
|
+
header: "Kind",
|
|
2298
|
+
render: (row) => formatLabel(row.kind)
|
|
2299
|
+
},
|
|
2300
|
+
{
|
|
2301
|
+
id: "status",
|
|
2302
|
+
header: "Status",
|
|
2303
|
+
render: (row) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(StatusBadge, { status: row.status })
|
|
2304
|
+
},
|
|
2305
|
+
{
|
|
2306
|
+
id: "agent",
|
|
2307
|
+
header: "Agent",
|
|
2308
|
+
className: "max-w-[160px] truncate font-mono text-xs",
|
|
2309
|
+
render: (row) => row.agentId ?? "-"
|
|
2310
|
+
}
|
|
2311
|
+
]
|
|
2312
|
+
}
|
|
2313
|
+
)
|
|
2314
|
+
] })
|
|
2315
|
+
}
|
|
2316
|
+
)
|
|
2317
|
+
] });
|
|
2318
|
+
}
|
|
2319
|
+
function BrainMap({
|
|
2320
|
+
clusters,
|
|
2321
|
+
edges,
|
|
2322
|
+
loading,
|
|
2323
|
+
nodes,
|
|
2324
|
+
onSelectNode,
|
|
2325
|
+
selectedNodeId
|
|
2326
|
+
}) {
|
|
2327
|
+
const nodeById = import_react3.default.useMemo(
|
|
2328
|
+
() => new Map(nodes.map((node) => [node.id, node])),
|
|
2329
|
+
[nodes]
|
|
2330
|
+
);
|
|
2331
|
+
if (nodes.length === 0) {
|
|
2332
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex min-h-[360px] items-center justify-center rounded-lg border bg-background", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
2333
|
+
EmptyState,
|
|
2334
|
+
{
|
|
2335
|
+
icon: import_lucide_react7.Brain,
|
|
2336
|
+
title: loading ? "Loading map" : "No map data",
|
|
2337
|
+
description: loading ? "Building the namespace brain map." : "The map will appear once brain nodes exist."
|
|
2338
|
+
}
|
|
2339
|
+
) });
|
|
2340
|
+
}
|
|
2341
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "overflow-hidden rounded-lg border bg-background", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
2342
|
+
"svg",
|
|
2343
|
+
{
|
|
2344
|
+
className: "block h-[420px] w-full bg-muted/20",
|
|
2345
|
+
role: "img",
|
|
2346
|
+
viewBox: "0 0 1000 600",
|
|
2347
|
+
children: [
|
|
2348
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("rect", { fill: "transparent", height: "600", width: "1000" }),
|
|
2349
|
+
clusters.map((cluster) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("g", { children: [
|
|
2350
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
2351
|
+
"circle",
|
|
2352
|
+
{
|
|
2353
|
+
cx: cluster.x * 1e3,
|
|
2354
|
+
cy: cluster.y * 600,
|
|
2355
|
+
fill: cluster.layer === "working" ? "#ecfeff" : "#eef2ff",
|
|
2356
|
+
opacity: "0.7",
|
|
2357
|
+
r: Math.max(46, Math.min(96, 34 + cluster.count * 8)),
|
|
2358
|
+
stroke: cluster.layer === "working" ? "#0891b2" : "#4f46e5",
|
|
2359
|
+
strokeOpacity: "0.18"
|
|
2360
|
+
}
|
|
2361
|
+
),
|
|
2362
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
2363
|
+
"text",
|
|
2364
|
+
{
|
|
2365
|
+
className: "fill-muted-foreground text-[11px]",
|
|
2366
|
+
textAnchor: "middle",
|
|
2367
|
+
x: cluster.x * 1e3,
|
|
2368
|
+
y: cluster.y * 600 - 40,
|
|
2369
|
+
children: cluster.label
|
|
2370
|
+
}
|
|
2371
|
+
)
|
|
2372
|
+
] }, cluster.id)),
|
|
2373
|
+
edges.map((edge) => {
|
|
2374
|
+
const source = nodeById.get(edge.sourceNodeId);
|
|
2375
|
+
const target = nodeById.get(edge.targetNodeId);
|
|
2376
|
+
if (!source || !target) return null;
|
|
2377
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
2378
|
+
"line",
|
|
2379
|
+
{
|
|
2380
|
+
stroke: edge.type === "contradicts" ? "#dc2626" : "#64748b",
|
|
2381
|
+
strokeOpacity: "0.32",
|
|
2382
|
+
strokeWidth: edge.type === "supports" ? 2 : 1.3,
|
|
2383
|
+
x1: source.x * 1e3,
|
|
2384
|
+
x2: target.x * 1e3,
|
|
2385
|
+
y1: source.y * 600,
|
|
2386
|
+
y2: target.y * 600
|
|
2387
|
+
},
|
|
2388
|
+
edge.id
|
|
2389
|
+
);
|
|
2390
|
+
}),
|
|
2391
|
+
nodes.map((node) => {
|
|
2392
|
+
const isSelected = node.id === selectedNodeId;
|
|
2393
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
2394
|
+
"g",
|
|
2395
|
+
{
|
|
2396
|
+
className: "cursor-pointer",
|
|
2397
|
+
onClick: () => onSelectNode(node),
|
|
2398
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
2399
|
+
"circle",
|
|
2400
|
+
{
|
|
2401
|
+
cx: node.x * 1e3,
|
|
2402
|
+
cy: node.y * 600,
|
|
2403
|
+
fill: nodeColor(node),
|
|
2404
|
+
r: isSelected ? 9 : 6,
|
|
2405
|
+
stroke: isSelected ? "#0f172a" : "#ffffff",
|
|
2406
|
+
strokeWidth: isSelected ? 3 : 2,
|
|
2407
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("title", { children: `${node.name} \xB7 ${formatLabel(node.kind)}` })
|
|
2408
|
+
}
|
|
2409
|
+
)
|
|
2410
|
+
},
|
|
2411
|
+
node.id
|
|
2412
|
+
);
|
|
2413
|
+
})
|
|
2414
|
+
]
|
|
2415
|
+
}
|
|
2416
|
+
) });
|
|
2417
|
+
}
|
|
2418
|
+
function BrainNodeInspector({ node }) {
|
|
2419
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "space-y-3", children: [
|
|
2420
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "rounded-lg border bg-background p-4", children: [
|
|
2421
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
2422
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(LayerBadge, { layer: node.layer }),
|
|
2423
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(StatusBadge, { status: node.status }),
|
|
2424
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Badge, { variant: "outline", children: formatLabel(node.kind) })
|
|
2425
|
+
] }),
|
|
2426
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("h3", { className: "mt-3 text-base font-semibold", children: node.name }),
|
|
2427
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "mt-2 text-sm leading-6 text-muted-foreground", children: node.content || "-" }),
|
|
2428
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("dl", { className: "mt-4 grid gap-2 text-xs", children: [
|
|
2429
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(InspectorRow, { label: "Agent", value: node.agentId }),
|
|
2430
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(InspectorRow, { label: "Thread", value: node.threadId }),
|
|
2431
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(InspectorRow, { label: "Memory space", value: node.memorySpaceId }),
|
|
2432
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(InspectorRow, { label: "Checkpoint", value: node.checkpointId }),
|
|
2433
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(InspectorRow, { label: "Source field", value: node.sourceField }),
|
|
2434
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
2435
|
+
InspectorRow,
|
|
2436
|
+
{
|
|
2437
|
+
label: "Updated",
|
|
2438
|
+
value: formatDateTime(node.updatedAt)
|
|
2439
|
+
}
|
|
2440
|
+
)
|
|
2441
|
+
] })
|
|
2442
|
+
] }),
|
|
2443
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(JsonPanel, { title: "Node JSON", value: node, minHeight: 300 })
|
|
2444
|
+
] });
|
|
2445
|
+
}
|
|
2446
|
+
function InspectorRow({
|
|
2447
|
+
label,
|
|
2448
|
+
value
|
|
2449
|
+
}) {
|
|
2450
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "grid grid-cols-[110px_minmax(0,1fr)] gap-2", children: [
|
|
2451
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("dt", { className: "text-muted-foreground", children: label }),
|
|
2452
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("dd", { className: "truncate font-mono", children: value || "-" })
|
|
2453
|
+
] });
|
|
2454
|
+
}
|
|
2455
|
+
function LayerBadge({ layer }) {
|
|
2456
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Badge, { variant: layer === "working" ? "secondary" : "default", children: formatLabel(layer) });
|
|
2457
|
+
}
|
|
2458
|
+
function nodeColor(node) {
|
|
2459
|
+
if (node.layer === "working") return "#0891b2";
|
|
2460
|
+
if (node.kind === "decision") return "#4f46e5";
|
|
2461
|
+
if (node.kind === "risk") return "#dc2626";
|
|
2462
|
+
if (node.kind === "preference") return "#16a34a";
|
|
2463
|
+
return "#475569";
|
|
2464
|
+
}
|
|
2465
|
+
function formatLabel(value) {
|
|
2466
|
+
return value.replaceAll("_", " ").replace(/\b\w/g, (letter) => letter.toUpperCase());
|
|
2467
|
+
}
|
|
2468
|
+
function formatDateTime(value) {
|
|
2469
|
+
if (!value) return "-";
|
|
2470
|
+
const date = new Date(value);
|
|
2471
|
+
if (Number.isNaN(date.getTime())) return value;
|
|
2472
|
+
return date.toLocaleString();
|
|
2473
|
+
}
|
|
2474
|
+
function emptyBrainResponse() {
|
|
2475
|
+
return {
|
|
2476
|
+
nodes: [],
|
|
2477
|
+
edges: [],
|
|
2478
|
+
clusters: [],
|
|
2479
|
+
stats: {
|
|
2480
|
+
total: 0,
|
|
2481
|
+
byLayer: {},
|
|
2482
|
+
byKind: {},
|
|
2483
|
+
byStatus: {}
|
|
2484
|
+
},
|
|
2485
|
+
pageInfo: {
|
|
2486
|
+
limit: 0,
|
|
2487
|
+
offset: 0,
|
|
2488
|
+
returned: 0
|
|
2489
|
+
}
|
|
2490
|
+
};
|
|
2491
|
+
}
|
|
2492
|
+
|
|
2493
|
+
// src/modules/collections/index.tsx
|
|
2494
|
+
var import_react4 = __toESM(require("react"), 1);
|
|
2495
|
+
var import_lucide_react8 = require("lucide-react");
|
|
2496
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
2008
2497
|
function collectionsModule() {
|
|
2009
2498
|
return {
|
|
2010
2499
|
group: "data",
|
|
2011
|
-
icon:
|
|
2500
|
+
icon: import_lucide_react8.Database,
|
|
2012
2501
|
id: "collections",
|
|
2013
2502
|
label: "Collections",
|
|
2014
2503
|
navItems: [{
|
|
2015
2504
|
group: "data",
|
|
2016
|
-
icon:
|
|
2505
|
+
icon: import_lucide_react8.Database,
|
|
2017
2506
|
id: "collections",
|
|
2018
2507
|
label: "Collections",
|
|
2019
2508
|
order: 20,
|
|
@@ -2023,23 +2512,23 @@ function collectionsModule() {
|
|
|
2023
2512
|
{
|
|
2024
2513
|
id: "collections",
|
|
2025
2514
|
title: "Collections",
|
|
2026
|
-
render: (context) => /* @__PURE__ */ (0,
|
|
2515
|
+
render: (context) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(CollectionsPage, { context })
|
|
2027
2516
|
},
|
|
2028
2517
|
{
|
|
2029
2518
|
id: "collections.detail",
|
|
2030
2519
|
title: "Collection Item",
|
|
2031
|
-
render: (context) => /* @__PURE__ */ (0,
|
|
2520
|
+
render: (context) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(CollectionDetailPage, { context })
|
|
2032
2521
|
}
|
|
2033
2522
|
]
|
|
2034
2523
|
};
|
|
2035
2524
|
}
|
|
2036
2525
|
function CollectionsPage({ context }) {
|
|
2037
|
-
const [collections, setCollections] =
|
|
2038
|
-
const [selected, setSelected] =
|
|
2039
|
-
const [search, setSearch] =
|
|
2040
|
-
const [items, setItems] =
|
|
2041
|
-
const [error, setError] =
|
|
2042
|
-
|
|
2526
|
+
const [collections, setCollections] = import_react4.default.useState([]);
|
|
2527
|
+
const [selected, setSelected] = import_react4.default.useState(null);
|
|
2528
|
+
const [search, setSearch] = import_react4.default.useState("");
|
|
2529
|
+
const [items, setItems] = import_react4.default.useState([]);
|
|
2530
|
+
const [error, setError] = import_react4.default.useState(null);
|
|
2531
|
+
import_react4.default.useEffect(() => {
|
|
2043
2532
|
let active = true;
|
|
2044
2533
|
void context.client.listCollections().then((names) => {
|
|
2045
2534
|
if (!active) return;
|
|
@@ -2052,7 +2541,7 @@ function CollectionsPage({ context }) {
|
|
|
2052
2541
|
active = false;
|
|
2053
2542
|
};
|
|
2054
2543
|
}, [context.client, context.refreshKey]);
|
|
2055
|
-
|
|
2544
|
+
import_react4.default.useEffect(() => {
|
|
2056
2545
|
if (!selected) return;
|
|
2057
2546
|
let active = true;
|
|
2058
2547
|
setError(null);
|
|
@@ -2069,30 +2558,30 @@ function CollectionsPage({ context }) {
|
|
|
2069
2558
|
active = false;
|
|
2070
2559
|
};
|
|
2071
2560
|
}, [context.client, context.refreshKey, context.scope.namespace, search, selected]);
|
|
2072
|
-
return /* @__PURE__ */ (0,
|
|
2073
|
-
/* @__PURE__ */ (0,
|
|
2561
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "space-y-4", children: [
|
|
2562
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
2074
2563
|
PageHeader,
|
|
2075
2564
|
{
|
|
2076
2565
|
title: "Collections",
|
|
2077
2566
|
description: "Schema-aware collection browsing with advanced JSON fallback for records that do not have custom editors.",
|
|
2078
|
-
actions: selected && /* @__PURE__ */ (0,
|
|
2567
|
+
actions: selected && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
2079
2568
|
Button,
|
|
2080
2569
|
{
|
|
2081
2570
|
onClick: () => context.navigate("collections.detail", { collection: selected }),
|
|
2082
2571
|
size: "sm",
|
|
2083
2572
|
type: "button",
|
|
2084
2573
|
children: [
|
|
2085
|
-
/* @__PURE__ */ (0,
|
|
2574
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react8.Plus, { className: "size-3" }),
|
|
2086
2575
|
"New"
|
|
2087
2576
|
]
|
|
2088
2577
|
}
|
|
2089
2578
|
)
|
|
2090
2579
|
}
|
|
2091
2580
|
),
|
|
2092
|
-
/* @__PURE__ */ (0,
|
|
2093
|
-
/* @__PURE__ */ (0,
|
|
2094
|
-
/* @__PURE__ */ (0,
|
|
2095
|
-
/* @__PURE__ */ (0,
|
|
2581
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "grid gap-4 lg:grid-cols-[240px_minmax(0,1fr)]", children: [
|
|
2582
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "overflow-hidden rounded-lg border bg-background", children: [
|
|
2583
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "border-b px-3 py-2 text-xs font-medium uppercase tracking-wide text-muted-foreground", children: "Collections" }),
|
|
2584
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "max-h-[620px] overflow-auto p-1", children: collections.map((collection) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
2096
2585
|
"button",
|
|
2097
2586
|
{
|
|
2098
2587
|
className: `flex w-full items-center rounded-md px-2 py-1.5 text-left text-sm ${selected === collection ? "bg-accent text-accent-foreground" : "hover:bg-muted"}`,
|
|
@@ -2103,8 +2592,8 @@ function CollectionsPage({ context }) {
|
|
|
2103
2592
|
collection
|
|
2104
2593
|
)) })
|
|
2105
2594
|
] }),
|
|
2106
|
-
/* @__PURE__ */ (0,
|
|
2107
|
-
/* @__PURE__ */ (0,
|
|
2595
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "space-y-3", children: [
|
|
2596
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
2108
2597
|
FilterBar,
|
|
2109
2598
|
{
|
|
2110
2599
|
onSearchChange: setSearch,
|
|
@@ -2112,7 +2601,7 @@ function CollectionsPage({ context }) {
|
|
|
2112
2601
|
searchValue: search
|
|
2113
2602
|
}
|
|
2114
2603
|
),
|
|
2115
|
-
error ? /* @__PURE__ */ (0,
|
|
2604
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(EmptyState, { title: "Unable to load collection", description: error }) : selected ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
2116
2605
|
ResourceTable,
|
|
2117
2606
|
{
|
|
2118
2607
|
rows: items,
|
|
@@ -2121,10 +2610,10 @@ function CollectionsPage({ context }) {
|
|
|
2121
2610
|
collection: selected,
|
|
2122
2611
|
itemId: getItemId(item)
|
|
2123
2612
|
}),
|
|
2124
|
-
empty: /* @__PURE__ */ (0,
|
|
2613
|
+
empty: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
2125
2614
|
EmptyState,
|
|
2126
2615
|
{
|
|
2127
|
-
icon:
|
|
2616
|
+
icon: import_lucide_react8.Database,
|
|
2128
2617
|
title: `No ${selected} records`,
|
|
2129
2618
|
description: "Create a record or adjust the current filters."
|
|
2130
2619
|
}
|
|
@@ -2133,16 +2622,16 @@ function CollectionsPage({ context }) {
|
|
|
2133
2622
|
{
|
|
2134
2623
|
id: "id",
|
|
2135
2624
|
header: "ID",
|
|
2136
|
-
render: (item) => /* @__PURE__ */ (0,
|
|
2625
|
+
render: (item) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "max-w-sm truncate font-mono text-xs", children: getItemId(item) })
|
|
2137
2626
|
},
|
|
2138
2627
|
{
|
|
2139
2628
|
id: "preview",
|
|
2140
2629
|
header: "Preview",
|
|
2141
|
-
render: (item) => /* @__PURE__ */ (0,
|
|
2630
|
+
render: (item) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "max-w-xl truncate text-sm", children: getItemPreview(item) })
|
|
2142
2631
|
}
|
|
2143
2632
|
]
|
|
2144
2633
|
}
|
|
2145
|
-
) : /* @__PURE__ */ (0,
|
|
2634
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(EmptyState, { title: "No collections" })
|
|
2146
2635
|
] })
|
|
2147
2636
|
] })
|
|
2148
2637
|
] });
|
|
@@ -2150,10 +2639,10 @@ function CollectionsPage({ context }) {
|
|
|
2150
2639
|
function CollectionDetailPage({ context }) {
|
|
2151
2640
|
const collection = context.route.params?.collection;
|
|
2152
2641
|
const itemId = context.route.params?.itemId ?? null;
|
|
2153
|
-
const [item, setItem] =
|
|
2154
|
-
const [error, setError] =
|
|
2642
|
+
const [item, setItem] = import_react4.default.useState(null);
|
|
2643
|
+
const [error, setError] = import_react4.default.useState(null);
|
|
2155
2644
|
const isNew = !itemId;
|
|
2156
|
-
|
|
2645
|
+
import_react4.default.useEffect(() => {
|
|
2157
2646
|
if (!collection || !itemId) {
|
|
2158
2647
|
setItem(null);
|
|
2159
2648
|
return;
|
|
@@ -2171,8 +2660,8 @@ function CollectionDetailPage({ context }) {
|
|
|
2171
2660
|
active = false;
|
|
2172
2661
|
};
|
|
2173
2662
|
}, [collection, context.client, context.refreshKey, context.scope.namespace, itemId]);
|
|
2174
|
-
if (!collection) return /* @__PURE__ */ (0,
|
|
2175
|
-
if (error) return /* @__PURE__ */ (0,
|
|
2663
|
+
if (!collection) return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(EmptyState, { title: "Collection not selected" });
|
|
2664
|
+
if (error) return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(EmptyState, { title: "Unable to load item", description: error });
|
|
2176
2665
|
const Editor = context.collectionEditors[collection];
|
|
2177
2666
|
const save = async (value) => {
|
|
2178
2667
|
if (isNew) {
|
|
@@ -2192,14 +2681,14 @@ function CollectionDetailPage({ context }) {
|
|
|
2192
2681
|
});
|
|
2193
2682
|
setItem(updated);
|
|
2194
2683
|
};
|
|
2195
|
-
return /* @__PURE__ */ (0,
|
|
2196
|
-
/* @__PURE__ */ (0,
|
|
2684
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "space-y-4", children: [
|
|
2685
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
2197
2686
|
PageHeader,
|
|
2198
2687
|
{
|
|
2199
2688
|
title: isNew ? `New ${collection}` : `${collection} / ${itemId}`,
|
|
2200
2689
|
description: "Schema-aware editors can override this view. Advanced JSON remains available as a fallback.",
|
|
2201
|
-
actions: /* @__PURE__ */ (0,
|
|
2202
|
-
!isNew && itemId && /* @__PURE__ */ (0,
|
|
2690
|
+
actions: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
2691
|
+
!isNew && itemId && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
2203
2692
|
Button,
|
|
2204
2693
|
{
|
|
2205
2694
|
onClick: () => {
|
|
@@ -2211,12 +2700,12 @@ function CollectionDetailPage({ context }) {
|
|
|
2211
2700
|
type: "button",
|
|
2212
2701
|
variant: "destructive",
|
|
2213
2702
|
children: [
|
|
2214
|
-
/* @__PURE__ */ (0,
|
|
2703
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react8.Trash2, { className: "size-3" }),
|
|
2215
2704
|
"Delete"
|
|
2216
2705
|
]
|
|
2217
2706
|
}
|
|
2218
2707
|
),
|
|
2219
|
-
/* @__PURE__ */ (0,
|
|
2708
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
2220
2709
|
Button,
|
|
2221
2710
|
{
|
|
2222
2711
|
onClick: () => context.navigate("collections"),
|
|
@@ -2229,7 +2718,7 @@ function CollectionDetailPage({ context }) {
|
|
|
2229
2718
|
] })
|
|
2230
2719
|
}
|
|
2231
2720
|
),
|
|
2232
|
-
Editor ? /* @__PURE__ */ (0,
|
|
2721
|
+
Editor ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
2233
2722
|
Editor,
|
|
2234
2723
|
{
|
|
2235
2724
|
collection,
|
|
@@ -2240,7 +2729,7 @@ function CollectionDetailPage({ context }) {
|
|
|
2240
2729
|
onSaved: setItem,
|
|
2241
2730
|
onDeleted: () => context.navigate("collections")
|
|
2242
2731
|
}
|
|
2243
|
-
) : /* @__PURE__ */ (0,
|
|
2732
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
2244
2733
|
JsonPanel,
|
|
2245
2734
|
{
|
|
2246
2735
|
title: "Advanced JSON",
|
|
@@ -2265,18 +2754,18 @@ function getItemPreview(item) {
|
|
|
2265
2754
|
}
|
|
2266
2755
|
|
|
2267
2756
|
// src/modules/events/index.tsx
|
|
2268
|
-
var
|
|
2269
|
-
var
|
|
2270
|
-
var
|
|
2757
|
+
var import_react5 = __toESM(require("react"), 1);
|
|
2758
|
+
var import_lucide_react9 = require("lucide-react");
|
|
2759
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
2271
2760
|
function eventsModule() {
|
|
2272
2761
|
return {
|
|
2273
2762
|
group: "operate",
|
|
2274
|
-
icon:
|
|
2763
|
+
icon: import_lucide_react9.Activity,
|
|
2275
2764
|
id: "events",
|
|
2276
2765
|
label: "Events",
|
|
2277
2766
|
navItems: [{
|
|
2278
2767
|
group: "operate",
|
|
2279
|
-
icon:
|
|
2768
|
+
icon: import_lucide_react9.Activity,
|
|
2280
2769
|
id: "events",
|
|
2281
2770
|
label: "Events",
|
|
2282
2771
|
order: 30,
|
|
@@ -2285,7 +2774,7 @@ function eventsModule() {
|
|
|
2285
2774
|
routes: [{
|
|
2286
2775
|
id: "events",
|
|
2287
2776
|
title: "Events",
|
|
2288
|
-
render: (context) => /* @__PURE__ */ (0,
|
|
2777
|
+
render: (context) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(EventsPage, { context })
|
|
2289
2778
|
}]
|
|
2290
2779
|
};
|
|
2291
2780
|
}
|
|
@@ -2299,17 +2788,17 @@ var EVENT_STATUSES = [
|
|
|
2299
2788
|
"overwritten"
|
|
2300
2789
|
];
|
|
2301
2790
|
function EventsPage({ context }) {
|
|
2302
|
-
const [threadId, setThreadId] =
|
|
2303
|
-
const [status, setStatus] =
|
|
2791
|
+
const [threadId, setThreadId] = import_react5.default.useState("");
|
|
2792
|
+
const [status, setStatus] = import_react5.default.useState(
|
|
2304
2793
|
"all"
|
|
2305
2794
|
);
|
|
2306
|
-
const [eventType, setEventType] =
|
|
2307
|
-
const [traceId, setTraceId] =
|
|
2308
|
-
const [events, setEvents] =
|
|
2309
|
-
const [selectedEvent, setSelectedEvent] =
|
|
2310
|
-
const [error, setError] =
|
|
2311
|
-
const [loading, setLoading] =
|
|
2312
|
-
const [hasLoaded, setHasLoaded] =
|
|
2795
|
+
const [eventType, setEventType] = import_react5.default.useState("");
|
|
2796
|
+
const [traceId, setTraceId] = import_react5.default.useState("");
|
|
2797
|
+
const [events, setEvents] = import_react5.default.useState([]);
|
|
2798
|
+
const [selectedEvent, setSelectedEvent] = import_react5.default.useState(null);
|
|
2799
|
+
const [error, setError] = import_react5.default.useState(null);
|
|
2800
|
+
const [loading, setLoading] = import_react5.default.useState(false);
|
|
2801
|
+
const [hasLoaded, setHasLoaded] = import_react5.default.useState(false);
|
|
2313
2802
|
const inspect = async () => {
|
|
2314
2803
|
setHasLoaded(true);
|
|
2315
2804
|
setLoading(true);
|
|
@@ -2335,21 +2824,21 @@ function EventsPage({ context }) {
|
|
|
2335
2824
|
setLoading(false);
|
|
2336
2825
|
}
|
|
2337
2826
|
};
|
|
2338
|
-
|
|
2827
|
+
import_react5.default.useEffect(() => {
|
|
2339
2828
|
void inspect();
|
|
2340
2829
|
}, [context.client, context.refreshKey, context.scope.namespace]);
|
|
2341
|
-
return /* @__PURE__ */ (0,
|
|
2342
|
-
/* @__PURE__ */ (0,
|
|
2830
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "space-y-4", children: [
|
|
2831
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
2343
2832
|
PageHeader,
|
|
2344
2833
|
{
|
|
2345
2834
|
title: "Events",
|
|
2346
2835
|
description: "Queue and event inspection across the active namespace."
|
|
2347
2836
|
}
|
|
2348
2837
|
),
|
|
2349
|
-
/* @__PURE__ */ (0,
|
|
2838
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
2350
2839
|
FilterBar,
|
|
2351
2840
|
{
|
|
2352
|
-
actions: /* @__PURE__ */ (0,
|
|
2841
|
+
actions: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
2353
2842
|
Button,
|
|
2354
2843
|
{
|
|
2355
2844
|
disabled: loading,
|
|
@@ -2357,13 +2846,13 @@ function EventsPage({ context }) {
|
|
|
2357
2846
|
size: "sm",
|
|
2358
2847
|
type: "button",
|
|
2359
2848
|
children: [
|
|
2360
|
-
/* @__PURE__ */ (0,
|
|
2849
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react9.Search, { className: "size-3" }),
|
|
2361
2850
|
loading ? "Loading" : "Inspect"
|
|
2362
2851
|
]
|
|
2363
2852
|
}
|
|
2364
2853
|
),
|
|
2365
2854
|
children: [
|
|
2366
|
-
/* @__PURE__ */ (0,
|
|
2855
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
2367
2856
|
Input,
|
|
2368
2857
|
{
|
|
2369
2858
|
className: "h-8 w-[220px]",
|
|
@@ -2375,18 +2864,18 @@ function EventsPage({ context }) {
|
|
|
2375
2864
|
value: threadId
|
|
2376
2865
|
}
|
|
2377
2866
|
),
|
|
2378
|
-
/* @__PURE__ */ (0,
|
|
2867
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
2379
2868
|
Select,
|
|
2380
2869
|
{
|
|
2381
2870
|
value: status,
|
|
2382
2871
|
onValueChange: (value) => setStatus(value),
|
|
2383
2872
|
children: [
|
|
2384
|
-
/* @__PURE__ */ (0,
|
|
2385
|
-
/* @__PURE__ */ (0,
|
|
2873
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SelectTrigger, { className: "h-8 w-[150px] text-xs", "aria-label": "Status", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SelectValue, {}) }),
|
|
2874
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SelectContent, { children: EVENT_STATUSES.map((option) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SelectItem, { value: option, children: option === "all" ? "All statuses" : option }, option)) })
|
|
2386
2875
|
]
|
|
2387
2876
|
}
|
|
2388
2877
|
),
|
|
2389
|
-
/* @__PURE__ */ (0,
|
|
2878
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
2390
2879
|
Input,
|
|
2391
2880
|
{
|
|
2392
2881
|
className: "h-8 w-[180px]",
|
|
@@ -2398,7 +2887,7 @@ function EventsPage({ context }) {
|
|
|
2398
2887
|
value: eventType
|
|
2399
2888
|
}
|
|
2400
2889
|
),
|
|
2401
|
-
/* @__PURE__ */ (0,
|
|
2890
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
2402
2891
|
Input,
|
|
2403
2892
|
{
|
|
2404
2893
|
className: "h-8 w-[180px]",
|
|
@@ -2413,21 +2902,21 @@ function EventsPage({ context }) {
|
|
|
2413
2902
|
]
|
|
2414
2903
|
}
|
|
2415
2904
|
),
|
|
2416
|
-
error ? /* @__PURE__ */ (0,
|
|
2905
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(EmptyState, { title: "Unable to inspect event", description: error }) : !hasLoaded && loading ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
2417
2906
|
EmptyState,
|
|
2418
2907
|
{
|
|
2419
|
-
icon:
|
|
2908
|
+
icon: import_lucide_react9.Activity,
|
|
2420
2909
|
title: "Loading events",
|
|
2421
2910
|
description: "Fetching recent queue events for the active namespace."
|
|
2422
2911
|
}
|
|
2423
|
-
) : /* @__PURE__ */ (0,
|
|
2424
|
-
/* @__PURE__ */ (0,
|
|
2912
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "grid gap-4 xl:grid-cols-[1fr_420px]", children: [
|
|
2913
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
2425
2914
|
ResourceTable,
|
|
2426
2915
|
{
|
|
2427
2916
|
rows: events,
|
|
2428
2917
|
getRowKey: (row) => row.id,
|
|
2429
2918
|
onRowClick: setSelectedEvent,
|
|
2430
|
-
empty: /* @__PURE__ */ (0,
|
|
2919
|
+
empty: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
2431
2920
|
EmptyState,
|
|
2432
2921
|
{
|
|
2433
2922
|
title: "No matching events",
|
|
@@ -2449,7 +2938,7 @@ function EventsPage({ context }) {
|
|
|
2449
2938
|
{
|
|
2450
2939
|
id: "status",
|
|
2451
2940
|
header: "Status",
|
|
2452
|
-
render: (row) => /* @__PURE__ */ (0,
|
|
2941
|
+
render: (row) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(StatusBadge, { status: row.status })
|
|
2453
2942
|
},
|
|
2454
2943
|
{
|
|
2455
2944
|
id: "trace",
|
|
@@ -2459,19 +2948,19 @@ function EventsPage({ context }) {
|
|
|
2459
2948
|
{
|
|
2460
2949
|
id: "created",
|
|
2461
2950
|
header: "Created",
|
|
2462
|
-
render: (row) =>
|
|
2951
|
+
render: (row) => formatDateTime2(row.createdAt)
|
|
2463
2952
|
}
|
|
2464
2953
|
]
|
|
2465
2954
|
}
|
|
2466
2955
|
),
|
|
2467
|
-
selectedEvent ? /* @__PURE__ */ (0,
|
|
2956
|
+
selectedEvent ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
2468
2957
|
JsonPanel,
|
|
2469
2958
|
{
|
|
2470
2959
|
title: "Event JSON",
|
|
2471
2960
|
value: selectedEvent,
|
|
2472
2961
|
minHeight: 420
|
|
2473
2962
|
}
|
|
2474
|
-
) : /* @__PURE__ */ (0,
|
|
2963
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
2475
2964
|
EmptyState,
|
|
2476
2965
|
{
|
|
2477
2966
|
title: "No event selected",
|
|
@@ -2481,7 +2970,7 @@ function EventsPage({ context }) {
|
|
|
2481
2970
|
] })
|
|
2482
2971
|
] });
|
|
2483
2972
|
}
|
|
2484
|
-
function
|
|
2973
|
+
function formatDateTime2(value) {
|
|
2485
2974
|
if (!value) return "-";
|
|
2486
2975
|
const date = new Date(value);
|
|
2487
2976
|
if (Number.isNaN(date.getTime())) return value;
|
|
@@ -2494,18 +2983,18 @@ function formatDateTime(value) {
|
|
|
2494
2983
|
}
|
|
2495
2984
|
|
|
2496
2985
|
// src/modules/overview/index.tsx
|
|
2497
|
-
var
|
|
2498
|
-
var
|
|
2499
|
-
var
|
|
2986
|
+
var import_react6 = __toESM(require("react"), 1);
|
|
2987
|
+
var import_lucide_react10 = require("lucide-react");
|
|
2988
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
2500
2989
|
function overviewModule() {
|
|
2501
2990
|
return {
|
|
2502
2991
|
group: "operate",
|
|
2503
|
-
icon:
|
|
2992
|
+
icon: import_lucide_react10.Activity,
|
|
2504
2993
|
id: "overview",
|
|
2505
2994
|
label: "Overview",
|
|
2506
2995
|
navItems: [{
|
|
2507
2996
|
group: "operate",
|
|
2508
|
-
icon:
|
|
2997
|
+
icon: import_lucide_react10.Activity,
|
|
2509
2998
|
id: "overview",
|
|
2510
2999
|
label: "Overview",
|
|
2511
3000
|
order: 10,
|
|
@@ -2514,17 +3003,17 @@ function overviewModule() {
|
|
|
2514
3003
|
routes: [{
|
|
2515
3004
|
id: "overview",
|
|
2516
3005
|
title: "Overview",
|
|
2517
|
-
render: (context) => /* @__PURE__ */ (0,
|
|
3006
|
+
render: (context) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(OverviewPage, { context })
|
|
2518
3007
|
}]
|
|
2519
3008
|
};
|
|
2520
3009
|
}
|
|
2521
3010
|
function OverviewPage({ context }) {
|
|
2522
|
-
const [overview, setOverview] =
|
|
2523
|
-
const [threads, setThreads] =
|
|
2524
|
-
const [agents, setAgents] =
|
|
2525
|
-
const [error, setError] =
|
|
2526
|
-
const [isLoading, setIsLoading] =
|
|
2527
|
-
|
|
3011
|
+
const [overview, setOverview] = import_react6.default.useState(null);
|
|
3012
|
+
const [threads, setThreads] = import_react6.default.useState([]);
|
|
3013
|
+
const [agents, setAgents] = import_react6.default.useState([]);
|
|
3014
|
+
const [error, setError] = import_react6.default.useState(null);
|
|
3015
|
+
const [isLoading, setIsLoading] = import_react6.default.useState(false);
|
|
3016
|
+
import_react6.default.useEffect(() => {
|
|
2528
3017
|
let active = true;
|
|
2529
3018
|
setIsLoading(true);
|
|
2530
3019
|
setError(null);
|
|
@@ -2557,11 +3046,11 @@ function OverviewPage({ context }) {
|
|
|
2557
3046
|
};
|
|
2558
3047
|
}, [context.client, context.refreshKey, context.scope.namespace]);
|
|
2559
3048
|
if (error) {
|
|
2560
|
-
return /* @__PURE__ */ (0,
|
|
3049
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(EmptyState, { title: "Unable to load overview", description: error });
|
|
2561
3050
|
}
|
|
2562
3051
|
const queueFailures = (overview?.queueTotals.failed ?? 0) + (overview?.queueTotals.expired ?? 0);
|
|
2563
|
-
return /* @__PURE__ */ (0,
|
|
2564
|
-
/* @__PURE__ */ (0,
|
|
3052
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "space-y-4", children: [
|
|
3053
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
2565
3054
|
PageHeader,
|
|
2566
3055
|
{
|
|
2567
3056
|
title: "Overview",
|
|
@@ -2572,41 +3061,41 @@ function OverviewPage({ context }) {
|
|
|
2572
3061
|
]
|
|
2573
3062
|
}
|
|
2574
3063
|
),
|
|
2575
|
-
/* @__PURE__ */ (0,
|
|
3064
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
2576
3065
|
MetricStrip,
|
|
2577
3066
|
{
|
|
2578
3067
|
items: [
|
|
2579
3068
|
{
|
|
2580
3069
|
detail: `${formatNumber(overview?.threadTotals.active ?? 0)} active`,
|
|
2581
|
-
icon:
|
|
3070
|
+
icon: import_lucide_react10.MessageSquare,
|
|
2582
3071
|
label: "Threads",
|
|
2583
3072
|
value: formatNumber(overview?.threadTotals.total ?? 0)
|
|
2584
3073
|
},
|
|
2585
3074
|
{
|
|
2586
3075
|
detail: `${formatNumber(overview?.participantTotals.agents ?? 0)} agents`,
|
|
2587
|
-
icon:
|
|
3076
|
+
icon: import_lucide_react10.Users,
|
|
2588
3077
|
label: "Participants",
|
|
2589
3078
|
value: formatNumber(overview?.participantTotals.total ?? 0)
|
|
2590
3079
|
},
|
|
2591
3080
|
{
|
|
2592
3081
|
detail: `${formatNumber(overview?.llmTotals.totalCalls ?? 0)} LLM calls`,
|
|
2593
|
-
icon:
|
|
3082
|
+
icon: import_lucide_react10.Wallet,
|
|
2594
3083
|
label: "Cost",
|
|
2595
3084
|
value: formatMetricValue(overview?.llmTotals.totalCostUsd ?? 0, "cost")
|
|
2596
3085
|
},
|
|
2597
3086
|
{
|
|
2598
3087
|
detail: `${formatNumber(queueFailures)} failures/expired`,
|
|
2599
|
-
icon: queueFailures > 0 ?
|
|
3088
|
+
icon: queueFailures > 0 ? import_lucide_react10.AlertTriangle : import_lucide_react10.Sparkles,
|
|
2600
3089
|
label: "Queue",
|
|
2601
3090
|
value: formatNumber(overview?.queueTotals.total ?? 0)
|
|
2602
3091
|
}
|
|
2603
3092
|
]
|
|
2604
3093
|
}
|
|
2605
3094
|
),
|
|
2606
|
-
/* @__PURE__ */ (0,
|
|
2607
|
-
/* @__PURE__ */ (0,
|
|
2608
|
-
/* @__PURE__ */ (0,
|
|
2609
|
-
/* @__PURE__ */ (0,
|
|
3095
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "grid gap-4 xl:grid-cols-2", children: [
|
|
3096
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("section", { className: "space-y-3", children: [
|
|
3097
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(PageHeader, { title: "Recent Threads" }),
|
|
3098
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
2610
3099
|
ResourceTable,
|
|
2611
3100
|
{
|
|
2612
3101
|
rows: threads,
|
|
@@ -2616,15 +3105,15 @@ function OverviewPage({ context }) {
|
|
|
2616
3105
|
{
|
|
2617
3106
|
id: "name",
|
|
2618
3107
|
header: "Thread",
|
|
2619
|
-
render: (thread) => /* @__PURE__ */ (0,
|
|
2620
|
-
/* @__PURE__ */ (0,
|
|
2621
|
-
/* @__PURE__ */ (0,
|
|
3108
|
+
render: (thread) => /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { children: [
|
|
3109
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "max-w-md truncate font-medium", children: thread.name || thread.threadId }),
|
|
3110
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "max-w-md truncate text-xs text-muted-foreground", children: thread.summary ?? thread.lastMessagePreview ?? "No summary" })
|
|
2622
3111
|
] })
|
|
2623
3112
|
},
|
|
2624
3113
|
{
|
|
2625
3114
|
id: "status",
|
|
2626
3115
|
header: "Status",
|
|
2627
|
-
render: (thread) => /* @__PURE__ */ (0,
|
|
3116
|
+
render: (thread) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(StatusBadge, { status: thread.status })
|
|
2628
3117
|
},
|
|
2629
3118
|
{
|
|
2630
3119
|
align: "right",
|
|
@@ -2636,9 +3125,9 @@ function OverviewPage({ context }) {
|
|
|
2636
3125
|
}
|
|
2637
3126
|
)
|
|
2638
3127
|
] }),
|
|
2639
|
-
/* @__PURE__ */ (0,
|
|
2640
|
-
/* @__PURE__ */ (0,
|
|
2641
|
-
/* @__PURE__ */ (0,
|
|
3128
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("section", { className: "space-y-3", children: [
|
|
3129
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(PageHeader, { title: "Top Agents" }),
|
|
3130
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
2642
3131
|
ResourceTable,
|
|
2643
3132
|
{
|
|
2644
3133
|
rows: agents,
|
|
@@ -2648,11 +3137,11 @@ function OverviewPage({ context }) {
|
|
|
2648
3137
|
{
|
|
2649
3138
|
id: "agent",
|
|
2650
3139
|
header: "Agent",
|
|
2651
|
-
render: (agent) => /* @__PURE__ */ (0,
|
|
2652
|
-
/* @__PURE__ */ (0,
|
|
2653
|
-
/* @__PURE__ */ (0,
|
|
2654
|
-
/* @__PURE__ */ (0,
|
|
2655
|
-
/* @__PURE__ */ (0,
|
|
3140
|
+
render: (agent) => /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
3141
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react10.Bot, { className: "size-4 text-muted-foreground" }),
|
|
3142
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { children: [
|
|
3143
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "font-medium", children: agent.displayName }),
|
|
3144
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "text-xs text-muted-foreground", children: agent.agentId })
|
|
2656
3145
|
] })
|
|
2657
3146
|
] })
|
|
2658
3147
|
},
|
|
@@ -2677,18 +3166,18 @@ function OverviewPage({ context }) {
|
|
|
2677
3166
|
}
|
|
2678
3167
|
|
|
2679
3168
|
// src/modules/participants/index.tsx
|
|
2680
|
-
var
|
|
2681
|
-
var
|
|
2682
|
-
var
|
|
3169
|
+
var import_react7 = __toESM(require("react"), 1);
|
|
3170
|
+
var import_lucide_react11 = require("lucide-react");
|
|
3171
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
2683
3172
|
function participantsModule() {
|
|
2684
3173
|
return {
|
|
2685
3174
|
group: "data",
|
|
2686
|
-
icon:
|
|
3175
|
+
icon: import_lucide_react11.Users,
|
|
2687
3176
|
id: "participants",
|
|
2688
3177
|
label: "Participants",
|
|
2689
3178
|
navItems: [{
|
|
2690
3179
|
group: "data",
|
|
2691
|
-
icon:
|
|
3180
|
+
icon: import_lucide_react11.Users,
|
|
2692
3181
|
id: "participants",
|
|
2693
3182
|
label: "Participants",
|
|
2694
3183
|
order: 10,
|
|
@@ -2698,21 +3187,21 @@ function participantsModule() {
|
|
|
2698
3187
|
{
|
|
2699
3188
|
id: "participants",
|
|
2700
3189
|
title: "Participants",
|
|
2701
|
-
render: (context) => /* @__PURE__ */ (0,
|
|
3190
|
+
render: (context) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ParticipantsPage, { context })
|
|
2702
3191
|
},
|
|
2703
3192
|
{
|
|
2704
3193
|
id: "participants.detail",
|
|
2705
3194
|
title: "Participant Detail",
|
|
2706
|
-
render: (context) => /* @__PURE__ */ (0,
|
|
3195
|
+
render: (context) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ParticipantDetailPage, { context })
|
|
2707
3196
|
}
|
|
2708
3197
|
]
|
|
2709
3198
|
};
|
|
2710
3199
|
}
|
|
2711
3200
|
function ParticipantsPage({ context }) {
|
|
2712
|
-
const [search, setSearch] =
|
|
2713
|
-
const [participants, setParticipants] =
|
|
2714
|
-
const [error, setError] =
|
|
2715
|
-
|
|
3201
|
+
const [search, setSearch] = import_react7.default.useState("");
|
|
3202
|
+
const [participants, setParticipants] = import_react7.default.useState([]);
|
|
3203
|
+
const [error, setError] = import_react7.default.useState(null);
|
|
3204
|
+
import_react7.default.useEffect(() => {
|
|
2716
3205
|
let active = true;
|
|
2717
3206
|
setError(null);
|
|
2718
3207
|
void context.client.listParticipants({
|
|
@@ -2728,15 +3217,15 @@ function ParticipantsPage({ context }) {
|
|
|
2728
3217
|
active = false;
|
|
2729
3218
|
};
|
|
2730
3219
|
}, [context.client, context.refreshKey, context.scope.namespace, search]);
|
|
2731
|
-
return /* @__PURE__ */ (0,
|
|
2732
|
-
/* @__PURE__ */ (0,
|
|
3220
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "space-y-4", children: [
|
|
3221
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
2733
3222
|
PageHeader,
|
|
2734
3223
|
{
|
|
2735
3224
|
title: "Participants",
|
|
2736
3225
|
description: "Humans, agents, and jobs observed by Copilotz across conversations."
|
|
2737
3226
|
}
|
|
2738
3227
|
),
|
|
2739
|
-
/* @__PURE__ */ (0,
|
|
3228
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
2740
3229
|
FilterBar,
|
|
2741
3230
|
{
|
|
2742
3231
|
onSearchChange: setSearch,
|
|
@@ -2744,7 +3233,7 @@ function ParticipantsPage({ context }) {
|
|
|
2744
3233
|
searchValue: search
|
|
2745
3234
|
}
|
|
2746
3235
|
),
|
|
2747
|
-
error ? /* @__PURE__ */ (0,
|
|
3236
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(EmptyState, { title: "Unable to load participants", description: error }) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
2748
3237
|
ResourceTable,
|
|
2749
3238
|
{
|
|
2750
3239
|
rows: participants,
|
|
@@ -2752,10 +3241,10 @@ function ParticipantsPage({ context }) {
|
|
|
2752
3241
|
onRowClick: (participant) => context.navigate("participants.detail", {
|
|
2753
3242
|
participantId: participant.externalId
|
|
2754
3243
|
}),
|
|
2755
|
-
empty: /* @__PURE__ */ (0,
|
|
3244
|
+
empty: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
2756
3245
|
EmptyState,
|
|
2757
3246
|
{
|
|
2758
|
-
icon:
|
|
3247
|
+
icon: import_lucide_react11.Users,
|
|
2759
3248
|
title: "No participants",
|
|
2760
3249
|
description: "Participants appear after messages or jobs are processed."
|
|
2761
3250
|
}
|
|
@@ -2764,15 +3253,15 @@ function ParticipantsPage({ context }) {
|
|
|
2764
3253
|
{
|
|
2765
3254
|
id: "participant",
|
|
2766
3255
|
header: "Participant",
|
|
2767
|
-
render: (participant) => /* @__PURE__ */ (0,
|
|
2768
|
-
/* @__PURE__ */ (0,
|
|
2769
|
-
/* @__PURE__ */ (0,
|
|
3256
|
+
render: (participant) => /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { children: [
|
|
3257
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "max-w-md truncate font-medium", children: participant.displayName }),
|
|
3258
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "max-w-md truncate text-xs text-muted-foreground", children: participant.externalId })
|
|
2770
3259
|
] })
|
|
2771
3260
|
},
|
|
2772
3261
|
{
|
|
2773
3262
|
id: "type",
|
|
2774
3263
|
header: "Type",
|
|
2775
|
-
render: (participant) => /* @__PURE__ */ (0,
|
|
3264
|
+
render: (participant) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(StatusBadge, { status: participant.participantType })
|
|
2776
3265
|
},
|
|
2777
3266
|
{
|
|
2778
3267
|
id: "scope",
|
|
@@ -2798,9 +3287,9 @@ function ParticipantsPage({ context }) {
|
|
|
2798
3287
|
}
|
|
2799
3288
|
function ParticipantDetailPage({ context }) {
|
|
2800
3289
|
const participantId = context.route.params?.participantId;
|
|
2801
|
-
const [participant, setParticipant] =
|
|
2802
|
-
const [error, setError] =
|
|
2803
|
-
|
|
3290
|
+
const [participant, setParticipant] = import_react7.default.useState(null);
|
|
3291
|
+
const [error, setError] = import_react7.default.useState(null);
|
|
3292
|
+
import_react7.default.useEffect(() => {
|
|
2804
3293
|
if (!participantId) return;
|
|
2805
3294
|
let active = true;
|
|
2806
3295
|
setError(null);
|
|
@@ -2816,19 +3305,19 @@ function ParticipantDetailPage({ context }) {
|
|
|
2816
3305
|
};
|
|
2817
3306
|
}, [context.client, context.refreshKey, context.scope.namespace, participantId]);
|
|
2818
3307
|
if (!participantId) {
|
|
2819
|
-
return /* @__PURE__ */ (0,
|
|
3308
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(EmptyState, { title: "Participant not selected" });
|
|
2820
3309
|
}
|
|
2821
3310
|
if (error) {
|
|
2822
|
-
return /* @__PURE__ */ (0,
|
|
3311
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(EmptyState, { title: "Unable to load participant", description: error });
|
|
2823
3312
|
}
|
|
2824
3313
|
const memories = Array.isArray(participant?.memories) ? participant.memories.length : 0;
|
|
2825
|
-
return /* @__PURE__ */ (0,
|
|
2826
|
-
/* @__PURE__ */ (0,
|
|
3314
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "space-y-4", children: [
|
|
3315
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
2827
3316
|
PageHeader,
|
|
2828
3317
|
{
|
|
2829
3318
|
title: String(participant?.displayName ?? participantId),
|
|
2830
3319
|
description: "Participant profile, activity-ready metrics, and advanced record data.",
|
|
2831
|
-
actions: /* @__PURE__ */ (0,
|
|
3320
|
+
actions: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
2832
3321
|
"button",
|
|
2833
3322
|
{
|
|
2834
3323
|
className: "text-sm text-muted-foreground hover:text-foreground",
|
|
@@ -2839,7 +3328,7 @@ function ParticipantDetailPage({ context }) {
|
|
|
2839
3328
|
)
|
|
2840
3329
|
}
|
|
2841
3330
|
),
|
|
2842
|
-
/* @__PURE__ */ (0,
|
|
3331
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
2843
3332
|
MetricStrip,
|
|
2844
3333
|
{
|
|
2845
3334
|
items: [
|
|
@@ -2849,24 +3338,24 @@ function ParticipantDetailPage({ context }) {
|
|
|
2849
3338
|
]
|
|
2850
3339
|
}
|
|
2851
3340
|
),
|
|
2852
|
-
/* @__PURE__ */ (0,
|
|
3341
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(JsonPanel, { title: "Advanced JSON", value: participant, minHeight: 460 })
|
|
2853
3342
|
] });
|
|
2854
3343
|
}
|
|
2855
3344
|
|
|
2856
3345
|
// src/modules/threads/index.tsx
|
|
2857
|
-
var
|
|
2858
|
-
var
|
|
2859
|
-
var
|
|
3346
|
+
var import_react8 = __toESM(require("react"), 1);
|
|
3347
|
+
var import_lucide_react12 = require("lucide-react");
|
|
3348
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
2860
3349
|
var MESSAGE_PAGE_SIZE = 50;
|
|
2861
3350
|
function threadsModule() {
|
|
2862
3351
|
return {
|
|
2863
3352
|
group: "operate",
|
|
2864
|
-
icon:
|
|
3353
|
+
icon: import_lucide_react12.MessageSquare,
|
|
2865
3354
|
id: "threads",
|
|
2866
3355
|
label: "Threads",
|
|
2867
3356
|
navItems: [{
|
|
2868
3357
|
group: "operate",
|
|
2869
|
-
icon:
|
|
3358
|
+
icon: import_lucide_react12.MessageSquare,
|
|
2870
3359
|
id: "threads",
|
|
2871
3360
|
label: "Threads",
|
|
2872
3361
|
order: 40,
|
|
@@ -2876,22 +3365,22 @@ function threadsModule() {
|
|
|
2876
3365
|
{
|
|
2877
3366
|
id: "threads",
|
|
2878
3367
|
title: "Threads",
|
|
2879
|
-
render: (context) => /* @__PURE__ */ (0,
|
|
3368
|
+
render: (context) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ThreadsPage, { context })
|
|
2880
3369
|
},
|
|
2881
3370
|
{
|
|
2882
3371
|
id: "threads.detail",
|
|
2883
3372
|
title: "Thread Detail",
|
|
2884
|
-
render: (context) => /* @__PURE__ */ (0,
|
|
3373
|
+
render: (context) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ThreadDetailPage, { context })
|
|
2885
3374
|
}
|
|
2886
3375
|
]
|
|
2887
3376
|
};
|
|
2888
3377
|
}
|
|
2889
3378
|
function ThreadsPage({ context }) {
|
|
2890
|
-
const [search, setSearch] =
|
|
2891
|
-
const [threads, setThreads] =
|
|
2892
|
-
const [error, setError] =
|
|
2893
|
-
const [isLoading, setIsLoading] =
|
|
2894
|
-
|
|
3379
|
+
const [search, setSearch] = import_react8.default.useState("");
|
|
3380
|
+
const [threads, setThreads] = import_react8.default.useState([]);
|
|
3381
|
+
const [error, setError] = import_react8.default.useState(null);
|
|
3382
|
+
const [isLoading, setIsLoading] = import_react8.default.useState(false);
|
|
3383
|
+
import_react8.default.useEffect(() => {
|
|
2895
3384
|
let active = true;
|
|
2896
3385
|
setIsLoading(true);
|
|
2897
3386
|
setError(null);
|
|
@@ -2910,8 +3399,8 @@ function ThreadsPage({ context }) {
|
|
|
2910
3399
|
active = false;
|
|
2911
3400
|
};
|
|
2912
3401
|
}, [context.client, context.refreshKey, context.scope.namespace, search]);
|
|
2913
|
-
return /* @__PURE__ */ (0,
|
|
2914
|
-
/* @__PURE__ */ (0,
|
|
3402
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "space-y-4", children: [
|
|
3403
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
2915
3404
|
PageHeader,
|
|
2916
3405
|
{
|
|
2917
3406
|
title: "Threads",
|
|
@@ -2919,7 +3408,7 @@ function ThreadsPage({ context }) {
|
|
|
2919
3408
|
badges: isLoading ? [{ label: "Loading" }] : []
|
|
2920
3409
|
}
|
|
2921
3410
|
),
|
|
2922
|
-
/* @__PURE__ */ (0,
|
|
3411
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
2923
3412
|
FilterBar,
|
|
2924
3413
|
{
|
|
2925
3414
|
onSearchChange: setSearch,
|
|
@@ -2927,16 +3416,16 @@ function ThreadsPage({ context }) {
|
|
|
2927
3416
|
searchValue: search
|
|
2928
3417
|
}
|
|
2929
3418
|
),
|
|
2930
|
-
error ? /* @__PURE__ */ (0,
|
|
3419
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(EmptyState, { title: "Unable to load threads", description: error }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
2931
3420
|
ResourceTable,
|
|
2932
3421
|
{
|
|
2933
3422
|
rows: threads,
|
|
2934
3423
|
getRowKey: (thread) => thread.threadId,
|
|
2935
3424
|
onRowClick: (thread) => context.navigate("threads.detail", { threadId: thread.threadId }),
|
|
2936
|
-
empty: /* @__PURE__ */ (0,
|
|
3425
|
+
empty: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
2937
3426
|
EmptyState,
|
|
2938
3427
|
{
|
|
2939
|
-
icon:
|
|
3428
|
+
icon: import_lucide_react12.MessageSquare,
|
|
2940
3429
|
title: "No threads",
|
|
2941
3430
|
description: "Threads will appear after conversations start flowing."
|
|
2942
3431
|
}
|
|
@@ -2945,15 +3434,15 @@ function ThreadsPage({ context }) {
|
|
|
2945
3434
|
{
|
|
2946
3435
|
id: "thread",
|
|
2947
3436
|
header: "Thread",
|
|
2948
|
-
render: (thread) => /* @__PURE__ */ (0,
|
|
2949
|
-
/* @__PURE__ */ (0,
|
|
2950
|
-
/* @__PURE__ */ (0,
|
|
3437
|
+
render: (thread) => /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "min-w-0", children: [
|
|
3438
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "max-w-xl truncate font-medium", children: thread.name || thread.threadId }),
|
|
3439
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "max-w-xl truncate text-xs text-muted-foreground", children: thread.summary ?? thread.lastMessagePreview ?? "No summary yet" })
|
|
2951
3440
|
] })
|
|
2952
3441
|
},
|
|
2953
3442
|
{
|
|
2954
3443
|
id: "status",
|
|
2955
3444
|
header: "Status",
|
|
2956
|
-
render: (thread) => /* @__PURE__ */ (0,
|
|
3445
|
+
render: (thread) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(StatusBadge, { status: thread.status })
|
|
2957
3446
|
},
|
|
2958
3447
|
{
|
|
2959
3448
|
align: "right",
|
|
@@ -2972,7 +3461,7 @@ function ThreadsPage({ context }) {
|
|
|
2972
3461
|
{
|
|
2973
3462
|
id: "activity",
|
|
2974
3463
|
header: "Last activity",
|
|
2975
|
-
render: (thread) =>
|
|
3464
|
+
render: (thread) => formatDateTime3(thread.lastActivityAt)
|
|
2976
3465
|
}
|
|
2977
3466
|
]
|
|
2978
3467
|
}
|
|
@@ -2982,7 +3471,7 @@ function ThreadsPage({ context }) {
|
|
|
2982
3471
|
function ThreadDetailPage({ context }) {
|
|
2983
3472
|
const threadId = context.route.params?.threadId;
|
|
2984
3473
|
if (!threadId) {
|
|
2985
|
-
return /* @__PURE__ */ (0,
|
|
3474
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
2986
3475
|
EmptyState,
|
|
2987
3476
|
{
|
|
2988
3477
|
title: "Thread not selected",
|
|
@@ -2990,19 +3479,19 @@ function ThreadDetailPage({ context }) {
|
|
|
2990
3479
|
}
|
|
2991
3480
|
);
|
|
2992
3481
|
}
|
|
2993
|
-
return /* @__PURE__ */ (0,
|
|
3482
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ThreadInspector, { context, threadId });
|
|
2994
3483
|
}
|
|
2995
3484
|
function ThreadInspector({
|
|
2996
3485
|
context,
|
|
2997
3486
|
threadId
|
|
2998
3487
|
}) {
|
|
2999
|
-
const [thread, setThread] =
|
|
3000
|
-
const [messages, setMessages] =
|
|
3001
|
-
const [pageInfo, setPageInfo] =
|
|
3002
|
-
const [isLoading, setIsLoading] =
|
|
3003
|
-
const [isLoadingMore, setIsLoadingMore] =
|
|
3004
|
-
const [error, setError] =
|
|
3005
|
-
|
|
3488
|
+
const [thread, setThread] = import_react8.default.useState(null);
|
|
3489
|
+
const [messages, setMessages] = import_react8.default.useState([]);
|
|
3490
|
+
const [pageInfo, setPageInfo] = import_react8.default.useState(null);
|
|
3491
|
+
const [isLoading, setIsLoading] = import_react8.default.useState(true);
|
|
3492
|
+
const [isLoadingMore, setIsLoadingMore] = import_react8.default.useState(false);
|
|
3493
|
+
const [error, setError] = import_react8.default.useState(null);
|
|
3494
|
+
import_react8.default.useEffect(() => {
|
|
3006
3495
|
let active = true;
|
|
3007
3496
|
setIsLoading(true);
|
|
3008
3497
|
setError(null);
|
|
@@ -3043,13 +3532,13 @@ function ThreadInspector({
|
|
|
3043
3532
|
}
|
|
3044
3533
|
};
|
|
3045
3534
|
if (isLoading) {
|
|
3046
|
-
return /* @__PURE__ */ (0,
|
|
3535
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(EmptyState, { icon: import_lucide_react12.Loader2, title: "Loading thread" });
|
|
3047
3536
|
}
|
|
3048
3537
|
if (error) {
|
|
3049
|
-
return /* @__PURE__ */ (0,
|
|
3538
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(EmptyState, { title: "Unable to load thread", description: error });
|
|
3050
3539
|
}
|
|
3051
|
-
return /* @__PURE__ */ (0,
|
|
3052
|
-
/* @__PURE__ */ (0,
|
|
3540
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "space-y-4", children: [
|
|
3541
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
3053
3542
|
PageHeader,
|
|
3054
3543
|
{
|
|
3055
3544
|
title: thread?.name ?? threadId,
|
|
@@ -3058,7 +3547,7 @@ function ThreadInspector({
|
|
|
3058
3547
|
{ label: thread?.status ?? "unknown" },
|
|
3059
3548
|
{ label: `${messages.length}${pageInfo?.hasMoreBefore ? "+" : ""} messages`, variant: "secondary" }
|
|
3060
3549
|
],
|
|
3061
|
-
actions: /* @__PURE__ */ (0,
|
|
3550
|
+
actions: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
3062
3551
|
Button,
|
|
3063
3552
|
{
|
|
3064
3553
|
onClick: () => context.navigate("threads"),
|
|
@@ -3070,14 +3559,14 @@ function ThreadInspector({
|
|
|
3070
3559
|
)
|
|
3071
3560
|
}
|
|
3072
3561
|
),
|
|
3073
|
-
/* @__PURE__ */ (0,
|
|
3562
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
3074
3563
|
InspectorPanel,
|
|
3075
3564
|
{
|
|
3076
|
-
side: /* @__PURE__ */ (0,
|
|
3077
|
-
children: /* @__PURE__ */ (0,
|
|
3078
|
-
/* @__PURE__ */ (0,
|
|
3079
|
-
/* @__PURE__ */ (0,
|
|
3080
|
-
pageInfo?.hasMoreBefore && /* @__PURE__ */ (0,
|
|
3565
|
+
side: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(JsonPanel, { title: "Thread JSON", value: thread, minHeight: 420 }),
|
|
3566
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "overflow-hidden rounded-lg border bg-background", children: [
|
|
3567
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex items-center justify-between border-b px-4 py-2", children: [
|
|
3568
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "text-sm font-medium", children: "Timeline" }),
|
|
3569
|
+
pageInfo?.hasMoreBefore && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
|
|
3081
3570
|
Button,
|
|
3082
3571
|
{
|
|
3083
3572
|
disabled: isLoadingMore,
|
|
@@ -3086,51 +3575,51 @@ function ThreadInspector({
|
|
|
3086
3575
|
type: "button",
|
|
3087
3576
|
variant: "ghost",
|
|
3088
3577
|
children: [
|
|
3089
|
-
isLoadingMore ? /* @__PURE__ */ (0,
|
|
3578
|
+
isLoadingMore ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react12.Loader2, { className: "size-3 animate-spin" }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react12.ChevronUp, { className: "size-3" }),
|
|
3090
3579
|
"Load older"
|
|
3091
3580
|
]
|
|
3092
3581
|
}
|
|
3093
3582
|
)
|
|
3094
3583
|
] }),
|
|
3095
|
-
messages.length === 0 ? /* @__PURE__ */ (0,
|
|
3584
|
+
messages.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(EmptyState, { title: "No messages", description: "This thread has no messages yet." }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "divide-y", children: messages.map((message) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(MessageRow, { message }, message.id)) })
|
|
3096
3585
|
] })
|
|
3097
3586
|
}
|
|
3098
3587
|
)
|
|
3099
3588
|
] });
|
|
3100
3589
|
}
|
|
3101
3590
|
function MessageRow({ message }) {
|
|
3102
|
-
const [expanded, setExpanded] =
|
|
3591
|
+
const [expanded, setExpanded] = import_react8.default.useState(false);
|
|
3103
3592
|
const hasToolCalls = Array.isArray(message.toolCalls) && message.toolCalls.length > 0;
|
|
3104
3593
|
const hasReasoning = Boolean(message.reasoning);
|
|
3105
3594
|
const hasMetadata = Boolean(message.metadata && Object.keys(message.metadata).length);
|
|
3106
|
-
return /* @__PURE__ */ (0,
|
|
3107
|
-
/* @__PURE__ */ (0,
|
|
3108
|
-
/* @__PURE__ */ (0,
|
|
3109
|
-
/* @__PURE__ */ (0,
|
|
3110
|
-
/* @__PURE__ */ (0,
|
|
3111
|
-
/* @__PURE__ */ (0,
|
|
3112
|
-
message.targetId && /* @__PURE__ */ (0,
|
|
3595
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "px-4 py-3", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex items-start gap-3", children: [
|
|
3596
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(SenderIcon, { senderType: message.senderType }),
|
|
3597
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "min-w-0 flex-1", children: [
|
|
3598
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex flex-wrap items-center gap-2 text-xs", children: [
|
|
3599
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "font-medium", children: message.senderId ?? message.senderUserId ?? message.senderType }),
|
|
3600
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Badge, { variant: "outline", className: "text-[10px]", children: message.senderType }),
|
|
3601
|
+
message.targetId && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(Badge, { variant: "secondary", className: "text-[10px]", children: [
|
|
3113
3602
|
"to ",
|
|
3114
3603
|
message.targetId
|
|
3115
3604
|
] }),
|
|
3116
|
-
message.createdAt && /* @__PURE__ */ (0,
|
|
3605
|
+
message.createdAt && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "text-muted-foreground", children: formatDateTime3(message.createdAt) })
|
|
3117
3606
|
] }),
|
|
3118
|
-
message.content && /* @__PURE__ */ (0,
|
|
3119
|
-
(hasToolCalls || hasReasoning || hasMetadata) && /* @__PURE__ */ (0,
|
|
3120
|
-
/* @__PURE__ */ (0,
|
|
3607
|
+
message.content && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("p", { className: "mt-1 whitespace-pre-wrap break-words text-sm", children: message.content }),
|
|
3608
|
+
(hasToolCalls || hasReasoning || hasMetadata) && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "mt-2", children: [
|
|
3609
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
|
|
3121
3610
|
"button",
|
|
3122
3611
|
{
|
|
3123
3612
|
className: "inline-flex items-center gap-1 text-xs text-muted-foreground hover:text-foreground",
|
|
3124
3613
|
onClick: () => setExpanded((value) => !value),
|
|
3125
3614
|
type: "button",
|
|
3126
3615
|
children: [
|
|
3127
|
-
hasToolCalls && /* @__PURE__ */ (0,
|
|
3128
|
-
hasReasoning && !hasToolCalls && /* @__PURE__ */ (0,
|
|
3616
|
+
hasToolCalls && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react12.Wrench, { className: "size-3" }),
|
|
3617
|
+
hasReasoning && !hasToolCalls && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react12.Cpu, { className: "size-3" }),
|
|
3129
3618
|
"Details"
|
|
3130
3619
|
]
|
|
3131
3620
|
}
|
|
3132
3621
|
),
|
|
3133
|
-
expanded && /* @__PURE__ */ (0,
|
|
3622
|
+
expanded && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("pre", { className: "mt-2 max-h-72 overflow-auto rounded-md bg-muted p-3 text-xs", children: JSON.stringify({
|
|
3134
3623
|
...hasToolCalls ? { toolCalls: message.toolCalls } : {},
|
|
3135
3624
|
...hasReasoning ? { reasoning: message.reasoning } : {},
|
|
3136
3625
|
...hasMetadata ? { metadata: message.metadata } : {}
|
|
@@ -3143,16 +3632,16 @@ function SenderIcon({ senderType }) {
|
|
|
3143
3632
|
const base = "flex size-7 shrink-0 items-center justify-center rounded-full";
|
|
3144
3633
|
switch (senderType) {
|
|
3145
3634
|
case "agent":
|
|
3146
|
-
return /* @__PURE__ */ (0,
|
|
3635
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: cn(base, "bg-primary/10 text-primary"), children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react12.Bot, { className: "size-3.5" }) });
|
|
3147
3636
|
case "user":
|
|
3148
|
-
return /* @__PURE__ */ (0,
|
|
3637
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: cn(base, "bg-secondary text-secondary-foreground"), children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react12.User, { className: "size-3.5" }) });
|
|
3149
3638
|
case "tool":
|
|
3150
|
-
return /* @__PURE__ */ (0,
|
|
3639
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: cn(base, "bg-muted text-muted-foreground"), children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react12.Wrench, { className: "size-3.5" }) });
|
|
3151
3640
|
default:
|
|
3152
|
-
return /* @__PURE__ */ (0,
|
|
3641
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: cn(base, "bg-muted text-muted-foreground"), children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react12.Cpu, { className: "size-3.5" }) });
|
|
3153
3642
|
}
|
|
3154
3643
|
}
|
|
3155
|
-
function
|
|
3644
|
+
function formatDateTime3(value) {
|
|
3156
3645
|
if (!value) return "No activity";
|
|
3157
3646
|
const date = new Date(value);
|
|
3158
3647
|
if (Number.isNaN(date.getTime())) return value;
|
|
@@ -3165,17 +3654,17 @@ function formatDateTime2(value) {
|
|
|
3165
3654
|
}
|
|
3166
3655
|
|
|
3167
3656
|
// src/modules/usage/index.tsx
|
|
3168
|
-
var
|
|
3657
|
+
var import_react9 = __toESM(require("react"), 1);
|
|
3169
3658
|
var import_recharts = require("recharts");
|
|
3170
|
-
var
|
|
3659
|
+
var import_lucide_react13 = require("lucide-react");
|
|
3171
3660
|
|
|
3172
3661
|
// src/components/ui/chart.tsx
|
|
3173
|
-
var
|
|
3662
|
+
var React13 = __toESM(require("react"), 1);
|
|
3174
3663
|
var RechartsPrimitive = __toESM(require("recharts"), 1);
|
|
3175
|
-
var
|
|
3176
|
-
var ChartContext =
|
|
3664
|
+
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
3665
|
+
var ChartContext = React13.createContext(null);
|
|
3177
3666
|
function useChart() {
|
|
3178
|
-
const context =
|
|
3667
|
+
const context = React13.useContext(ChartContext);
|
|
3179
3668
|
if (!context) {
|
|
3180
3669
|
throw new Error("useChart must be used within a ChartContainer");
|
|
3181
3670
|
}
|
|
@@ -3188,9 +3677,9 @@ function ChartContainer({
|
|
|
3188
3677
|
children,
|
|
3189
3678
|
...props
|
|
3190
3679
|
}) {
|
|
3191
|
-
const uniqueId =
|
|
3680
|
+
const uniqueId = React13.useId();
|
|
3192
3681
|
const chartId = `chart-${id ?? uniqueId.replace(/:/g, "")}`;
|
|
3193
|
-
return /* @__PURE__ */ (0,
|
|
3682
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ChartContext.Provider, { value: config, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
|
|
3194
3683
|
"div",
|
|
3195
3684
|
{
|
|
3196
3685
|
"data-chart": chartId,
|
|
@@ -3200,10 +3689,10 @@ function ChartContainer({
|
|
|
3200
3689
|
),
|
|
3201
3690
|
...props,
|
|
3202
3691
|
children: [
|
|
3203
|
-
/* @__PURE__ */ (0,
|
|
3692
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("style", { children: Object.entries(config).map(([key, item]) => {
|
|
3204
3693
|
return `[data-chart=${chartId}] { --color-${key}: ${item.color}; }`;
|
|
3205
3694
|
}).join("\n") }),
|
|
3206
|
-
/* @__PURE__ */ (0,
|
|
3695
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(RechartsPrimitive.ResponsiveContainer, { children })
|
|
3207
3696
|
]
|
|
3208
3697
|
}
|
|
3209
3698
|
) });
|
|
@@ -3222,7 +3711,7 @@ function ChartTooltipContent({
|
|
|
3222
3711
|
const value = typeof item.value === "number" ? item.value : Number(item.value ?? 0);
|
|
3223
3712
|
return sum + (Number.isFinite(value) ? value : 0);
|
|
3224
3713
|
}, 0);
|
|
3225
|
-
return /* @__PURE__ */ (0,
|
|
3714
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
|
|
3226
3715
|
"div",
|
|
3227
3716
|
{
|
|
3228
3717
|
className: cn(
|
|
@@ -3230,28 +3719,28 @@ function ChartTooltipContent({
|
|
|
3230
3719
|
className
|
|
3231
3720
|
),
|
|
3232
3721
|
children: [
|
|
3233
|
-
/* @__PURE__ */ (0,
|
|
3234
|
-
/* @__PURE__ */ (0,
|
|
3235
|
-
/* @__PURE__ */ (0,
|
|
3722
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "mb-2 flex items-center justify-between gap-4 border-b pb-2", children: [
|
|
3723
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("p", { className: "text-xs font-medium text-muted-foreground", children: labelFormatter ? labelFormatter(label) : label }),
|
|
3724
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("p", { className: "text-xs font-semibold text-foreground", children: formatter ? formatter(total) : total })
|
|
3236
3725
|
] }),
|
|
3237
|
-
/* @__PURE__ */ (0,
|
|
3726
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "space-y-1.5", children: payload.filter((item) => Number(item.value ?? 0) > 0).map((item) => {
|
|
3238
3727
|
const key = String(item.dataKey ?? item.name ?? "");
|
|
3239
3728
|
const itemConfig = config[key];
|
|
3240
3729
|
const color = item.color ?? itemConfig?.color ?? "currentColor";
|
|
3241
|
-
return /* @__PURE__ */ (0,
|
|
3730
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
|
|
3242
3731
|
"div",
|
|
3243
3732
|
{
|
|
3244
3733
|
className: "grid grid-cols-[0.6rem_1fr_auto] items-center gap-2",
|
|
3245
3734
|
children: [
|
|
3246
|
-
/* @__PURE__ */ (0,
|
|
3735
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3247
3736
|
"span",
|
|
3248
3737
|
{
|
|
3249
3738
|
className: "size-2 rounded-[2px]",
|
|
3250
3739
|
style: { backgroundColor: color }
|
|
3251
3740
|
}
|
|
3252
3741
|
),
|
|
3253
|
-
/* @__PURE__ */ (0,
|
|
3254
|
-
/* @__PURE__ */ (0,
|
|
3742
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "max-w-48 truncate text-muted-foreground", children: itemConfig?.label ?? item.name ?? key }),
|
|
3743
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "font-medium text-foreground", children: formatter ? formatter(item.value ?? 0) : item.value })
|
|
3255
3744
|
]
|
|
3256
3745
|
},
|
|
3257
3746
|
key
|
|
@@ -3267,11 +3756,11 @@ function ChartLegendContent({
|
|
|
3267
3756
|
}) {
|
|
3268
3757
|
const config = useChart();
|
|
3269
3758
|
if (!payload?.length) return null;
|
|
3270
|
-
return /* @__PURE__ */ (0,
|
|
3759
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: cn("flex flex-wrap items-center gap-x-4 gap-y-2", className), children: payload.map((item) => {
|
|
3271
3760
|
const key = String(item.dataKey ?? item.value ?? "");
|
|
3272
3761
|
const itemConfig = config[key];
|
|
3273
|
-
return /* @__PURE__ */ (0,
|
|
3274
|
-
/* @__PURE__ */ (0,
|
|
3762
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
3763
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3275
3764
|
"span",
|
|
3276
3765
|
{
|
|
3277
3766
|
className: "size-2 rounded-[2px]",
|
|
@@ -3280,13 +3769,13 @@ function ChartLegendContent({
|
|
|
3280
3769
|
}
|
|
3281
3770
|
}
|
|
3282
3771
|
),
|
|
3283
|
-
/* @__PURE__ */ (0,
|
|
3772
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "max-w-52 truncate text-xs text-muted-foreground", children: itemConfig?.label ?? item.value ?? key })
|
|
3284
3773
|
] }, key);
|
|
3285
3774
|
}) });
|
|
3286
3775
|
}
|
|
3287
3776
|
|
|
3288
3777
|
// src/modules/usage/index.tsx
|
|
3289
|
-
var
|
|
3778
|
+
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
3290
3779
|
var USAGE_DIMENSIONS = [
|
|
3291
3780
|
"total",
|
|
3292
3781
|
"input",
|
|
@@ -3314,12 +3803,12 @@ var STATUS_OPTIONS = [
|
|
|
3314
3803
|
function usageModule() {
|
|
3315
3804
|
return {
|
|
3316
3805
|
group: "operate",
|
|
3317
|
-
icon:
|
|
3806
|
+
icon: import_lucide_react13.BarChart3,
|
|
3318
3807
|
id: "usage",
|
|
3319
3808
|
label: "Usage",
|
|
3320
3809
|
navItems: [{
|
|
3321
3810
|
group: "operate",
|
|
3322
|
-
icon:
|
|
3811
|
+
icon: import_lucide_react13.BarChart3,
|
|
3323
3812
|
id: "usage",
|
|
3324
3813
|
label: "Usage",
|
|
3325
3814
|
order: 20,
|
|
@@ -3328,70 +3817,70 @@ function usageModule() {
|
|
|
3328
3817
|
routes: [{
|
|
3329
3818
|
id: "usage",
|
|
3330
3819
|
title: "Usage",
|
|
3331
|
-
render: (context) => /* @__PURE__ */ (0,
|
|
3820
|
+
render: (context) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(UsagePage, { context })
|
|
3332
3821
|
}]
|
|
3333
3822
|
};
|
|
3334
3823
|
}
|
|
3335
3824
|
function UsagePage({ context }) {
|
|
3336
|
-
const [period, setPeriod] =
|
|
3825
|
+
const [period, setPeriod] = import_react9.default.useState(
|
|
3337
3826
|
"7d"
|
|
3338
3827
|
);
|
|
3339
|
-
const [interval, setInterval] =
|
|
3340
|
-
const [workload, setWorkload] =
|
|
3341
|
-
const [metricKind, setMetricKind] =
|
|
3828
|
+
const [interval, setInterval] = import_react9.default.useState("day");
|
|
3829
|
+
const [workload, setWorkload] = import_react9.default.useState("all");
|
|
3830
|
+
const [metricKind, setMetricKind] = import_react9.default.useState(
|
|
3342
3831
|
"calls"
|
|
3343
3832
|
);
|
|
3344
|
-
const [dimension, setDimension] =
|
|
3345
|
-
const [groupBy, setGroupBy] =
|
|
3346
|
-
const [attribution, setAttribution] =
|
|
3833
|
+
const [dimension, setDimension] = import_react9.default.useState("total");
|
|
3834
|
+
const [groupBy, setGroupBy] = import_react9.default.useState("kind");
|
|
3835
|
+
const [attribution, setAttribution] = import_react9.default.useState(
|
|
3347
3836
|
"initiatedBy"
|
|
3348
3837
|
);
|
|
3349
|
-
const [participantType, setParticipantType] =
|
|
3350
|
-
const [threadId, setThreadId] =
|
|
3351
|
-
const [participantId, setParticipantId] =
|
|
3352
|
-
const [provider, setProvider] =
|
|
3353
|
-
const [model, setModel] =
|
|
3354
|
-
const [resource, setResource] =
|
|
3355
|
-
const [operation, setOperation] =
|
|
3356
|
-
const [status, setStatus] =
|
|
3838
|
+
const [participantType, setParticipantType] = import_react9.default.useState("all");
|
|
3839
|
+
const [threadId, setThreadId] = import_react9.default.useState("");
|
|
3840
|
+
const [participantId, setParticipantId] = import_react9.default.useState("");
|
|
3841
|
+
const [provider, setProvider] = import_react9.default.useState("");
|
|
3842
|
+
const [model, setModel] = import_react9.default.useState("");
|
|
3843
|
+
const [resource, setResource] = import_react9.default.useState("");
|
|
3844
|
+
const [operation, setOperation] = import_react9.default.useState("");
|
|
3845
|
+
const [status, setStatus] = import_react9.default.useState(
|
|
3357
3846
|
"all"
|
|
3358
3847
|
);
|
|
3359
|
-
const [customFrom, setCustomFrom] =
|
|
3360
|
-
const [customTo, setCustomTo] =
|
|
3361
|
-
const [usage, setUsage] =
|
|
3362
|
-
const [error, setError] =
|
|
3363
|
-
const [isLoading, setIsLoading] =
|
|
3364
|
-
const range =
|
|
3848
|
+
const [customFrom, setCustomFrom] = import_react9.default.useState("");
|
|
3849
|
+
const [customTo, setCustomTo] = import_react9.default.useState("");
|
|
3850
|
+
const [usage, setUsage] = import_react9.default.useState(null);
|
|
3851
|
+
const [error, setError] = import_react9.default.useState(null);
|
|
3852
|
+
const [isLoading, setIsLoading] = import_react9.default.useState(false);
|
|
3853
|
+
const range = import_react9.default.useMemo(
|
|
3365
3854
|
() => getUsageRange(period, customFrom, customTo),
|
|
3366
3855
|
[customFrom, customTo, period]
|
|
3367
3856
|
);
|
|
3368
|
-
const metricOptions =
|
|
3857
|
+
const metricOptions = import_react9.default.useMemo(
|
|
3369
3858
|
() => getUsageMetricOptions(workload),
|
|
3370
3859
|
[workload]
|
|
3371
3860
|
);
|
|
3372
|
-
const groupOptions =
|
|
3861
|
+
const groupOptions = import_react9.default.useMemo(
|
|
3373
3862
|
() => getUsageGroupOptions(workload),
|
|
3374
3863
|
[workload]
|
|
3375
3864
|
);
|
|
3376
3865
|
const showLlmFields = workload === "llm";
|
|
3377
3866
|
const showResourceFields = workload !== "llm";
|
|
3378
3867
|
const showDimension = metricKind === "tokens" || metricKind === "cost" && workload === "llm";
|
|
3379
|
-
|
|
3868
|
+
import_react9.default.useEffect(() => {
|
|
3380
3869
|
if (!metricOptions.includes(metricKind)) {
|
|
3381
3870
|
setMetricKind(metricOptions[0]);
|
|
3382
3871
|
}
|
|
3383
3872
|
}, [metricKind, metricOptions]);
|
|
3384
|
-
|
|
3873
|
+
import_react9.default.useEffect(() => {
|
|
3385
3874
|
if (!groupOptions.includes(groupBy)) {
|
|
3386
3875
|
setGroupBy(groupOptions[0]);
|
|
3387
3876
|
}
|
|
3388
3877
|
}, [groupBy, groupOptions]);
|
|
3389
|
-
|
|
3878
|
+
import_react9.default.useEffect(() => {
|
|
3390
3879
|
if (!showDimension && dimension !== "total") {
|
|
3391
3880
|
setDimension("total");
|
|
3392
3881
|
}
|
|
3393
3882
|
}, [dimension, showDimension]);
|
|
3394
|
-
|
|
3883
|
+
import_react9.default.useEffect(() => {
|
|
3395
3884
|
let active = true;
|
|
3396
3885
|
setIsLoading(true);
|
|
3397
3886
|
setError(null);
|
|
@@ -3449,16 +3938,16 @@ function UsagePage({ context }) {
|
|
|
3449
3938
|
]);
|
|
3450
3939
|
const points = usage?.points ?? [];
|
|
3451
3940
|
const totals = usage?.totals ?? EMPTY_USAGE_TOTALS;
|
|
3452
|
-
const chartState =
|
|
3941
|
+
const chartState = import_react9.default.useMemo(
|
|
3453
3942
|
() => buildUsageChartState(points, metricKind, dimension, interval),
|
|
3454
3943
|
[dimension, interval, metricKind, points]
|
|
3455
3944
|
);
|
|
3456
|
-
const rows =
|
|
3945
|
+
const rows = import_react9.default.useMemo(
|
|
3457
3946
|
() => aggregateUsageRows(points, metricKind, dimension),
|
|
3458
3947
|
[dimension, metricKind, points]
|
|
3459
3948
|
);
|
|
3460
|
-
return /* @__PURE__ */ (0,
|
|
3461
|
-
/* @__PURE__ */ (0,
|
|
3949
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "space-y-4", children: [
|
|
3950
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3462
3951
|
PageHeader,
|
|
3463
3952
|
{
|
|
3464
3953
|
title: "Usage",
|
|
@@ -3471,8 +3960,8 @@ function UsagePage({ context }) {
|
|
|
3471
3960
|
]
|
|
3472
3961
|
}
|
|
3473
3962
|
),
|
|
3474
|
-
/* @__PURE__ */ (0,
|
|
3475
|
-
/* @__PURE__ */ (0,
|
|
3963
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(FilterBar, { children: [
|
|
3964
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3476
3965
|
UsageSelect,
|
|
3477
3966
|
{
|
|
3478
3967
|
label: "Period",
|
|
@@ -3481,7 +3970,7 @@ function UsagePage({ context }) {
|
|
|
3481
3970
|
value: period
|
|
3482
3971
|
}
|
|
3483
3972
|
),
|
|
3484
|
-
/* @__PURE__ */ (0,
|
|
3973
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3485
3974
|
UsageSelect,
|
|
3486
3975
|
{
|
|
3487
3976
|
label: "Bucket",
|
|
@@ -3490,7 +3979,7 @@ function UsagePage({ context }) {
|
|
|
3490
3979
|
value: interval
|
|
3491
3980
|
}
|
|
3492
3981
|
),
|
|
3493
|
-
/* @__PURE__ */ (0,
|
|
3982
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3494
3983
|
UsageSelect,
|
|
3495
3984
|
{
|
|
3496
3985
|
label: "Workload",
|
|
@@ -3500,7 +3989,7 @@ function UsagePage({ context }) {
|
|
|
3500
3989
|
formatOption: getUsageKindLabel
|
|
3501
3990
|
}
|
|
3502
3991
|
),
|
|
3503
|
-
/* @__PURE__ */ (0,
|
|
3992
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3504
3993
|
UsageSelect,
|
|
3505
3994
|
{
|
|
3506
3995
|
label: "Measure",
|
|
@@ -3510,7 +3999,7 @@ function UsagePage({ context }) {
|
|
|
3510
3999
|
formatOption: getUsageMetricLabel
|
|
3511
4000
|
}
|
|
3512
4001
|
),
|
|
3513
|
-
/* @__PURE__ */ (0,
|
|
4002
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3514
4003
|
UsageSelect,
|
|
3515
4004
|
{
|
|
3516
4005
|
label: "Group",
|
|
@@ -3520,7 +4009,7 @@ function UsagePage({ context }) {
|
|
|
3520
4009
|
formatOption: getUsageGroupLabel
|
|
3521
4010
|
}
|
|
3522
4011
|
),
|
|
3523
|
-
/* @__PURE__ */ (0,
|
|
4012
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3524
4013
|
UsageSelect,
|
|
3525
4014
|
{
|
|
3526
4015
|
label: "Actor",
|
|
@@ -3530,7 +4019,7 @@ function UsagePage({ context }) {
|
|
|
3530
4019
|
formatOption: getUsageAttributionLabel
|
|
3531
4020
|
}
|
|
3532
4021
|
),
|
|
3533
|
-
showDimension && /* @__PURE__ */ (0,
|
|
4022
|
+
showDimension && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3534
4023
|
UsageSelect,
|
|
3535
4024
|
{
|
|
3536
4025
|
label: "Dimension",
|
|
@@ -3541,9 +4030,9 @@ function UsagePage({ context }) {
|
|
|
3541
4030
|
}
|
|
3542
4031
|
)
|
|
3543
4032
|
] }),
|
|
3544
|
-
/* @__PURE__ */ (0,
|
|
3545
|
-
period === "custom" && /* @__PURE__ */ (0,
|
|
3546
|
-
/* @__PURE__ */ (0,
|
|
4033
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(FilterBar, { children: [
|
|
4034
|
+
period === "custom" && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [
|
|
4035
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3547
4036
|
Input,
|
|
3548
4037
|
{
|
|
3549
4038
|
className: "h-8 w-[190px]",
|
|
@@ -3552,7 +4041,7 @@ function UsagePage({ context }) {
|
|
|
3552
4041
|
value: customFrom
|
|
3553
4042
|
}
|
|
3554
4043
|
),
|
|
3555
|
-
/* @__PURE__ */ (0,
|
|
4044
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3556
4045
|
Input,
|
|
3557
4046
|
{
|
|
3558
4047
|
className: "h-8 w-[190px]",
|
|
@@ -3562,7 +4051,7 @@ function UsagePage({ context }) {
|
|
|
3562
4051
|
}
|
|
3563
4052
|
)
|
|
3564
4053
|
] }),
|
|
3565
|
-
/* @__PURE__ */ (0,
|
|
4054
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3566
4055
|
UsageSelect,
|
|
3567
4056
|
{
|
|
3568
4057
|
label: "Actor type",
|
|
@@ -3571,7 +4060,7 @@ function UsagePage({ context }) {
|
|
|
3571
4060
|
value: participantType
|
|
3572
4061
|
}
|
|
3573
4062
|
),
|
|
3574
|
-
/* @__PURE__ */ (0,
|
|
4063
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3575
4064
|
UsageSelect,
|
|
3576
4065
|
{
|
|
3577
4066
|
label: "Status",
|
|
@@ -3580,7 +4069,7 @@ function UsagePage({ context }) {
|
|
|
3580
4069
|
value: status
|
|
3581
4070
|
}
|
|
3582
4071
|
),
|
|
3583
|
-
/* @__PURE__ */ (0,
|
|
4072
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3584
4073
|
Input,
|
|
3585
4074
|
{
|
|
3586
4075
|
className: "h-8 w-[170px]",
|
|
@@ -3589,7 +4078,7 @@ function UsagePage({ context }) {
|
|
|
3589
4078
|
value: threadId
|
|
3590
4079
|
}
|
|
3591
4080
|
),
|
|
3592
|
-
/* @__PURE__ */ (0,
|
|
4081
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3593
4082
|
Input,
|
|
3594
4083
|
{
|
|
3595
4084
|
className: "h-8 w-[170px]",
|
|
@@ -3598,8 +4087,8 @@ function UsagePage({ context }) {
|
|
|
3598
4087
|
value: participantId
|
|
3599
4088
|
}
|
|
3600
4089
|
),
|
|
3601
|
-
showResourceFields && /* @__PURE__ */ (0,
|
|
3602
|
-
/* @__PURE__ */ (0,
|
|
4090
|
+
showResourceFields && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [
|
|
4091
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3603
4092
|
Input,
|
|
3604
4093
|
{
|
|
3605
4094
|
className: "h-8 w-[170px]",
|
|
@@ -3608,7 +4097,7 @@ function UsagePage({ context }) {
|
|
|
3608
4097
|
value: resource
|
|
3609
4098
|
}
|
|
3610
4099
|
),
|
|
3611
|
-
/* @__PURE__ */ (0,
|
|
4100
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3612
4101
|
Input,
|
|
3613
4102
|
{
|
|
3614
4103
|
className: "h-8 w-[150px]",
|
|
@@ -3618,8 +4107,8 @@ function UsagePage({ context }) {
|
|
|
3618
4107
|
}
|
|
3619
4108
|
)
|
|
3620
4109
|
] }),
|
|
3621
|
-
showLlmFields && /* @__PURE__ */ (0,
|
|
3622
|
-
/* @__PURE__ */ (0,
|
|
4110
|
+
showLlmFields && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [
|
|
4111
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3623
4112
|
Input,
|
|
3624
4113
|
{
|
|
3625
4114
|
className: "h-8 w-[140px]",
|
|
@@ -3628,7 +4117,7 @@ function UsagePage({ context }) {
|
|
|
3628
4117
|
value: provider
|
|
3629
4118
|
}
|
|
3630
4119
|
),
|
|
3631
|
-
/* @__PURE__ */ (0,
|
|
4120
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3632
4121
|
Input,
|
|
3633
4122
|
{
|
|
3634
4123
|
className: "h-8 w-[140px]",
|
|
@@ -3639,58 +4128,58 @@ function UsagePage({ context }) {
|
|
|
3639
4128
|
)
|
|
3640
4129
|
] })
|
|
3641
4130
|
] }),
|
|
3642
|
-
/* @__PURE__ */ (0,
|
|
4131
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3643
4132
|
MetricStrip,
|
|
3644
4133
|
{
|
|
3645
4134
|
items: [
|
|
3646
4135
|
{
|
|
3647
4136
|
detail: `${formatMetricValue(totals.unpricedCalls, "unpriced")} unpriced`,
|
|
3648
|
-
icon:
|
|
4137
|
+
icon: import_lucide_react13.DollarSign,
|
|
3649
4138
|
label: "Spend",
|
|
3650
4139
|
value: formatMetricValue(totals.totalCostUsd, "cost")
|
|
3651
4140
|
},
|
|
3652
4141
|
{
|
|
3653
4142
|
detail: `${formatMetricValue(totals.failedCalls, "failures")} failed`,
|
|
3654
|
-
icon:
|
|
4143
|
+
icon: import_lucide_react13.Activity,
|
|
3655
4144
|
label: "Calls",
|
|
3656
4145
|
value: formatMetricValue(totals.totalCalls, "calls")
|
|
3657
4146
|
},
|
|
3658
4147
|
{
|
|
3659
4148
|
detail: "Tool and resource runtime",
|
|
3660
|
-
icon:
|
|
4149
|
+
icon: import_lucide_react13.Clock,
|
|
3661
4150
|
label: "Duration",
|
|
3662
4151
|
value: formatMetricValue(totals.totalDurationMs, "duration")
|
|
3663
4152
|
},
|
|
3664
4153
|
{
|
|
3665
4154
|
detail: `${formatMetricValue(totals.inputTokens, "tokens")} input`,
|
|
3666
|
-
icon:
|
|
4155
|
+
icon: import_lucide_react13.Sparkles,
|
|
3667
4156
|
label: "Tokens",
|
|
3668
4157
|
value: formatMetricValue(totals.totalTokens, "tokens")
|
|
3669
4158
|
},
|
|
3670
4159
|
{
|
|
3671
4160
|
detail: "Custom metering",
|
|
3672
|
-
icon:
|
|
4161
|
+
icon: import_lucide_react13.Coins,
|
|
3673
4162
|
label: "Credits",
|
|
3674
4163
|
value: formatMetricValue(totals.totalCredits, "credits")
|
|
3675
4164
|
},
|
|
3676
4165
|
{
|
|
3677
4166
|
detail: "Failed or aborted work",
|
|
3678
|
-
icon:
|
|
4167
|
+
icon: import_lucide_react13.AlertTriangle,
|
|
3679
4168
|
label: "Failures",
|
|
3680
4169
|
value: formatMetricValue(totals.failedCalls, "failures")
|
|
3681
4170
|
}
|
|
3682
4171
|
]
|
|
3683
4172
|
}
|
|
3684
4173
|
),
|
|
3685
|
-
error ? /* @__PURE__ */ (0,
|
|
4174
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(EmptyState, { title: "Unable to load usage", description: error }) : chartState.data.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3686
4175
|
EmptyState,
|
|
3687
4176
|
{
|
|
3688
4177
|
title: "No usage",
|
|
3689
4178
|
description: "Metered LLM, tool, and resource records will appear here after work is captured in the usage ledger."
|
|
3690
4179
|
}
|
|
3691
|
-
) : /* @__PURE__ */ (0,
|
|
3692
|
-
/* @__PURE__ */ (0,
|
|
3693
|
-
/* @__PURE__ */ (0,
|
|
4180
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [
|
|
4181
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Card, { className: "h-[320px] py-3", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(CardContent, { className: "h-full px-3", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(UsageChart, { chartState, metricKind }) }) }),
|
|
4182
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3694
4183
|
UsageRowsTable,
|
|
3695
4184
|
{
|
|
3696
4185
|
dimension,
|
|
@@ -3710,19 +4199,19 @@ function UsageSelect({
|
|
|
3710
4199
|
options,
|
|
3711
4200
|
value
|
|
3712
4201
|
}) {
|
|
3713
|
-
return /* @__PURE__ */ (0,
|
|
3714
|
-
/* @__PURE__ */ (0,
|
|
3715
|
-
/* @__PURE__ */ (0,
|
|
4202
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(Select, { value, onValueChange, children: [
|
|
4203
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(SelectTrigger, { className: "h-8 w-[132px] text-xs", "aria-label": label, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(SelectValue, {}) }),
|
|
4204
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(SelectContent, { children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(SelectItem, { value: option, children: formatOption ? formatOption(option) : option }, option)) })
|
|
3716
4205
|
] });
|
|
3717
4206
|
}
|
|
3718
4207
|
function UsageChart({
|
|
3719
4208
|
chartState,
|
|
3720
4209
|
metricKind
|
|
3721
4210
|
}) {
|
|
3722
|
-
return /* @__PURE__ */ (0,
|
|
3723
|
-
/* @__PURE__ */ (0,
|
|
3724
|
-
/* @__PURE__ */ (0,
|
|
3725
|
-
/* @__PURE__ */ (0,
|
|
4211
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(ChartContainer, { className: "h-full w-full", config: chartState.config, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_recharts.BarChart, { accessibilityLayer: true, data: chartState.data, margin: { left: 8, right: 8, top: 12 }, children: [
|
|
4212
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_recharts.CartesianGrid, { vertical: false }),
|
|
4213
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_recharts.XAxis, { dataKey: "label", tickLine: false, axisLine: false, tickMargin: 10 }),
|
|
4214
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3726
4215
|
import_recharts.YAxis,
|
|
3727
4216
|
{
|
|
3728
4217
|
axisLine: false,
|
|
@@ -3731,10 +4220,10 @@ function UsageChart({
|
|
|
3731
4220
|
width: 64
|
|
3732
4221
|
}
|
|
3733
4222
|
),
|
|
3734
|
-
/* @__PURE__ */ (0,
|
|
4223
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3735
4224
|
import_recharts.Tooltip,
|
|
3736
4225
|
{
|
|
3737
|
-
content: /* @__PURE__ */ (0,
|
|
4226
|
+
content: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3738
4227
|
ChartTooltipContent,
|
|
3739
4228
|
{
|
|
3740
4229
|
formatter: (value) => formatMetricValue(Number(value), metricKind),
|
|
@@ -3744,8 +4233,8 @@ function UsageChart({
|
|
|
3744
4233
|
cursor: false
|
|
3745
4234
|
}
|
|
3746
4235
|
),
|
|
3747
|
-
/* @__PURE__ */ (0,
|
|
3748
|
-
chartState.series.map((series) => /* @__PURE__ */ (0,
|
|
4236
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_recharts.Legend, { content: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(ChartLegendContent, { className: "justify-center pt-3" }) }),
|
|
4237
|
+
chartState.series.map((series) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3749
4238
|
import_recharts.Bar,
|
|
3750
4239
|
{
|
|
3751
4240
|
dataKey: series.id,
|
|
@@ -3766,7 +4255,7 @@ function UsageRowsTable({
|
|
|
3766
4255
|
}) {
|
|
3767
4256
|
const totalValue = getUsageTotalValue(totals, metricKind, dimension);
|
|
3768
4257
|
const valueHeader = (metricKind === "tokens" || metricKind === "cost") && dimension !== "total" ? `${getUsageDimensionLabel(dimension)} ${getUsageMetricLabel(metricKind)}` : getUsageMetricLabel(metricKind);
|
|
3769
|
-
return /* @__PURE__ */ (0,
|
|
4258
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3770
4259
|
ResourceTable,
|
|
3771
4260
|
{
|
|
3772
4261
|
rows: rows.slice(0, 80),
|
|
@@ -3775,9 +4264,9 @@ function UsageRowsTable({
|
|
|
3775
4264
|
{
|
|
3776
4265
|
id: "group",
|
|
3777
4266
|
header: getUsageGroupLabel(groupBy),
|
|
3778
|
-
render: (row) => /* @__PURE__ */ (0,
|
|
3779
|
-
/* @__PURE__ */ (0,
|
|
3780
|
-
row.groupKey !== row.groupLabel && /* @__PURE__ */ (0,
|
|
4267
|
+
render: (row) => /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "min-w-0", children: [
|
|
4268
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "max-w-80 truncate font-medium", children: row.groupLabel }),
|
|
4269
|
+
row.groupKey !== row.groupLabel && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "max-w-80 truncate text-xs text-muted-foreground", children: row.groupKey })
|
|
3781
4270
|
] })
|
|
3782
4271
|
},
|
|
3783
4272
|
{
|
|
@@ -3906,6 +4395,7 @@ function defaultCopilotzModules() {
|
|
|
3906
4395
|
usageModule(),
|
|
3907
4396
|
eventsModule(),
|
|
3908
4397
|
threadsModule(),
|
|
4398
|
+
brainModule(),
|
|
3909
4399
|
agentsModule(),
|
|
3910
4400
|
participantsModule(),
|
|
3911
4401
|
collectionsModule()
|
|
@@ -3985,17 +4475,17 @@ function firstAccessibleRoute(modules, permissions) {
|
|
|
3985
4475
|
}
|
|
3986
4476
|
|
|
3987
4477
|
// src/core/scope.tsx
|
|
3988
|
-
var
|
|
3989
|
-
var
|
|
3990
|
-
var AdminContext = (0,
|
|
4478
|
+
var import_react10 = require("react");
|
|
4479
|
+
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
4480
|
+
var AdminContext = (0, import_react10.createContext)(null);
|
|
3991
4481
|
function AdminProvider({
|
|
3992
4482
|
children,
|
|
3993
4483
|
value
|
|
3994
4484
|
}) {
|
|
3995
|
-
return /* @__PURE__ */ (0,
|
|
4485
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(AdminContext.Provider, { value, children });
|
|
3996
4486
|
}
|
|
3997
4487
|
function useAdmin() {
|
|
3998
|
-
const context = (0,
|
|
4488
|
+
const context = (0, import_react10.useContext)(AdminContext);
|
|
3999
4489
|
if (!context) {
|
|
4000
4490
|
throw new Error("useAdmin must be used inside CopilotzAdmin");
|
|
4001
4491
|
}
|
|
@@ -4003,7 +4493,7 @@ function useAdmin() {
|
|
|
4003
4493
|
}
|
|
4004
4494
|
|
|
4005
4495
|
// src/core/CopilotzAdmin.tsx
|
|
4006
|
-
var
|
|
4496
|
+
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
4007
4497
|
var DEFAULT_BRANDING = {
|
|
4008
4498
|
title: "Copilotz Admin",
|
|
4009
4499
|
subtitle: "Operate and configure Copilotz projects",
|
|
@@ -4039,11 +4529,11 @@ function CopilotzAdmin({
|
|
|
4039
4529
|
permissions = {},
|
|
4040
4530
|
scope: scopeProp
|
|
4041
4531
|
}) {
|
|
4042
|
-
const modules = (0,
|
|
4532
|
+
const modules = (0, import_react11.useMemo)(
|
|
4043
4533
|
() => modulesProp ?? defaultCopilotzModules(),
|
|
4044
4534
|
[modulesProp]
|
|
4045
4535
|
);
|
|
4046
|
-
const adminClient = (0,
|
|
4536
|
+
const adminClient = (0, import_react11.useMemo)(
|
|
4047
4537
|
() => client ?? createAdminClient({
|
|
4048
4538
|
baseUrl: clientConfig?.baseUrl ?? config?.baseUrl,
|
|
4049
4539
|
paths: clientConfig?.paths,
|
|
@@ -4051,7 +4541,7 @@ function CopilotzAdmin({
|
|
|
4051
4541
|
}),
|
|
4052
4542
|
[client, clientConfig, config]
|
|
4053
4543
|
);
|
|
4054
|
-
const branding = (0,
|
|
4544
|
+
const branding = (0, import_react11.useMemo)(
|
|
4055
4545
|
() => ({
|
|
4056
4546
|
...DEFAULT_BRANDING,
|
|
4057
4547
|
...config?.branding ?? {},
|
|
@@ -4059,30 +4549,30 @@ function CopilotzAdmin({
|
|
|
4059
4549
|
}),
|
|
4060
4550
|
[brandingProp, config?.branding]
|
|
4061
4551
|
);
|
|
4062
|
-
const [namespace, setNamespaceState] = (0,
|
|
4552
|
+
const [namespace, setNamespaceState] = (0, import_react11.useState)(
|
|
4063
4553
|
scopeProp?.namespace ?? config?.namespace ?? ""
|
|
4064
4554
|
);
|
|
4065
|
-
const scope = (0,
|
|
4555
|
+
const scope = (0, import_react11.useMemo)(() => ({
|
|
4066
4556
|
...scopeProp ?? {},
|
|
4067
4557
|
namespace
|
|
4068
4558
|
}), [namespace, scopeProp]);
|
|
4069
|
-
const routes = (0,
|
|
4559
|
+
const routes = (0, import_react11.useMemo)(
|
|
4070
4560
|
() => collectAdminRoutes(modules, permissions),
|
|
4071
4561
|
[modules, permissions]
|
|
4072
4562
|
);
|
|
4073
|
-
const navItems = (0,
|
|
4563
|
+
const navItems = (0, import_react11.useMemo)(
|
|
4074
4564
|
() => collectAdminNavItems(modules, permissions),
|
|
4075
4565
|
[modules, permissions]
|
|
4076
4566
|
);
|
|
4077
|
-
const collectionEditors = (0,
|
|
4567
|
+
const collectionEditors = (0, import_react11.useMemo)(
|
|
4078
4568
|
() => collectCollectionEditors(modules),
|
|
4079
4569
|
[modules]
|
|
4080
4570
|
);
|
|
4081
4571
|
const initialRouteId = routeFromLegacyPage(config?.defaultPage) ?? firstAccessibleRoute(modules, permissions);
|
|
4082
|
-
const [route, setRoute] = (0,
|
|
4572
|
+
const [route, setRoute] = (0, import_react11.useState)({
|
|
4083
4573
|
routeId: initialRouteId
|
|
4084
4574
|
});
|
|
4085
|
-
const [refreshKey, setRefreshKey] = (0,
|
|
4575
|
+
const [refreshKey, setRefreshKey] = (0, import_react11.useState)(0);
|
|
4086
4576
|
const activeRoute = routes.get(route.routeId) ?? routes.get(firstAccessibleRoute(modules, permissions));
|
|
4087
4577
|
const navigate = (routeId, params) => {
|
|
4088
4578
|
const next = { routeId, params };
|
|
@@ -4103,7 +4593,7 @@ function CopilotzAdmin({
|
|
|
4103
4593
|
scope,
|
|
4104
4594
|
setNamespace: setNamespaceState
|
|
4105
4595
|
};
|
|
4106
|
-
return /* @__PURE__ */ (0,
|
|
4596
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(AdminProvider, { value: runtime, children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(TooltipProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SidebarProvider, { defaultOpen: true, children: /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
4107
4597
|
"div",
|
|
4108
4598
|
{
|
|
4109
4599
|
className: cn(
|
|
@@ -4111,7 +4601,7 @@ function CopilotzAdmin({
|
|
|
4111
4601
|
className
|
|
4112
4602
|
),
|
|
4113
4603
|
children: [
|
|
4114
|
-
/* @__PURE__ */ (0,
|
|
4604
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
4115
4605
|
AdminShellSidebar,
|
|
4116
4606
|
{
|
|
4117
4607
|
branding,
|
|
@@ -4123,8 +4613,8 @@ function CopilotzAdmin({
|
|
|
4123
4613
|
scopeOptions: scope.availableNamespaces
|
|
4124
4614
|
}
|
|
4125
4615
|
),
|
|
4126
|
-
/* @__PURE__ */ (0,
|
|
4127
|
-
/* @__PURE__ */ (0,
|
|
4616
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SidebarInset, { children: /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex h-full min-h-0 flex-col", children: [
|
|
4617
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
4128
4618
|
AdminShellHeader,
|
|
4129
4619
|
{
|
|
4130
4620
|
brandingActions: branding.actions,
|
|
@@ -4133,7 +4623,7 @@ function CopilotzAdmin({
|
|
|
4133
4623
|
title: activeRoute?.title ?? "Admin"
|
|
4134
4624
|
}
|
|
4135
4625
|
),
|
|
4136
|
-
/* @__PURE__ */ (0,
|
|
4626
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("main", { className: "min-h-0 flex-1 overflow-auto bg-muted/20", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "mx-auto flex w-full max-w-[1600px] flex-col gap-4 p-4 lg:p-5", children: activeRoute ? activeRoute.render(runtime) : /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "rounded-lg border bg-background p-8 text-sm text-muted-foreground", children: "No accessible admin route is configured." }) }) })
|
|
4137
4627
|
] }) })
|
|
4138
4628
|
]
|
|
4139
4629
|
}
|
|
@@ -4152,57 +4642,57 @@ function AdminShellSidebar({
|
|
|
4152
4642
|
group,
|
|
4153
4643
|
items: navItems.filter((item) => (item.group ?? "extensions") === group)
|
|
4154
4644
|
})).filter((entry) => entry.items.length > 0);
|
|
4155
|
-
return /* @__PURE__ */ (0,
|
|
4156
|
-
/* @__PURE__ */ (0,
|
|
4157
|
-
/* @__PURE__ */ (0,
|
|
4158
|
-
/* @__PURE__ */ (0,
|
|
4159
|
-
/* @__PURE__ */ (0,
|
|
4160
|
-
/* @__PURE__ */ (0,
|
|
4645
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(Sidebar, { collapsible: "icon", children: [
|
|
4646
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SidebarHeader, { children: /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-center gap-3 px-2 py-3", children: [
|
|
4647
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "flex size-8 shrink-0 items-center justify-center rounded-md bg-primary text-primary-foreground", children: branding.logo ?? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_lucide_react14.Bot, { className: "size-4" }) }),
|
|
4648
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "min-w-0 group-data-[collapsible=icon]:hidden", children: [
|
|
4649
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "truncate text-sm font-semibold", children: branding.title }),
|
|
4650
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "truncate text-xs text-muted-foreground", children: branding.subtitle })
|
|
4161
4651
|
] })
|
|
4162
4652
|
] }) }),
|
|
4163
|
-
/* @__PURE__ */ (0,
|
|
4164
|
-
index > 0 && /* @__PURE__ */ (0,
|
|
4165
|
-
/* @__PURE__ */ (0,
|
|
4166
|
-
/* @__PURE__ */ (0,
|
|
4167
|
-
/* @__PURE__ */ (0,
|
|
4168
|
-
const Icon2 = item.icon ??
|
|
4169
|
-
return /* @__PURE__ */ (0,
|
|
4653
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SidebarContent, { children: grouped.map(({ group, items }, index) => /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_react11.default.Fragment, { children: [
|
|
4654
|
+
index > 0 && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SidebarSeparator, {}),
|
|
4655
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(SidebarGroup, { children: [
|
|
4656
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SidebarGroupLabel, { className: "group-data-[collapsible=icon]:hidden", children: ADMIN_GROUP_LABELS[group] }),
|
|
4657
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SidebarGroupContent, { children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SidebarMenu, { children: items.map((item) => {
|
|
4658
|
+
const Icon2 = item.icon ?? import_lucide_react14.LayoutDashboard;
|
|
4659
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SidebarMenuItem, { children: /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
4170
4660
|
SidebarMenuButton,
|
|
4171
4661
|
{
|
|
4172
4662
|
isActive: route.routeId === item.routeId,
|
|
4173
4663
|
onClick: () => onNavigate(item.routeId),
|
|
4174
4664
|
tooltip: item.label,
|
|
4175
4665
|
children: [
|
|
4176
|
-
/* @__PURE__ */ (0,
|
|
4177
|
-
/* @__PURE__ */ (0,
|
|
4666
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(Icon2, {}),
|
|
4667
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { children: item.label })
|
|
4178
4668
|
]
|
|
4179
4669
|
}
|
|
4180
4670
|
) }, item.id);
|
|
4181
4671
|
}) }) })
|
|
4182
4672
|
] })
|
|
4183
4673
|
] }, group)) }),
|
|
4184
|
-
/* @__PURE__ */ (0,
|
|
4185
|
-
/* @__PURE__ */ (0,
|
|
4186
|
-
/* @__PURE__ */ (0,
|
|
4187
|
-
/* @__PURE__ */ (0,
|
|
4674
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(SidebarFooter, { children: [
|
|
4675
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "group-data-[collapsible=icon]:hidden", children: [
|
|
4676
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("label", { className: "mb-1 block px-2 text-xs font-medium text-muted-foreground", children: "Namespace" }),
|
|
4677
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
4188
4678
|
Select,
|
|
4189
4679
|
{
|
|
4190
4680
|
value: namespace || "__all__",
|
|
4191
4681
|
onValueChange: (value) => onNamespaceChange(value === "__all__" ? "" : value),
|
|
4192
4682
|
children: [
|
|
4193
|
-
/* @__PURE__ */ (0,
|
|
4194
|
-
/* @__PURE__ */ (0,
|
|
4195
|
-
/* @__PURE__ */ (0,
|
|
4196
|
-
scopeOptions?.map((option) => /* @__PURE__ */ (0,
|
|
4197
|
-
namespace && !scopeOptions?.some((option) => option.id === namespace) && /* @__PURE__ */ (0,
|
|
4683
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SelectTrigger, { className: "h-8 text-xs", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SelectValue, { placeholder: "All namespaces" }) }),
|
|
4684
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(SelectContent, { children: [
|
|
4685
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SelectItem, { value: "__all__", children: "All namespaces" }),
|
|
4686
|
+
scopeOptions?.map((option) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SelectItem, { value: option.id, children: option.label ?? option.id }, option.id)),
|
|
4687
|
+
namespace && !scopeOptions?.some((option) => option.id === namespace) && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SelectItem, { value: namespace, children: namespace })
|
|
4198
4688
|
] })
|
|
4199
4689
|
]
|
|
4200
4690
|
}
|
|
4201
4691
|
)
|
|
4202
4692
|
] }),
|
|
4203
|
-
/* @__PURE__ */ (0,
|
|
4693
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "hidden justify-center group-data-[collapsible=icon]:flex", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_lucide_react14.ChevronsUpDown, { className: "size-4 text-muted-foreground" }) })
|
|
4204
4694
|
] }),
|
|
4205
|
-
/* @__PURE__ */ (0,
|
|
4695
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SidebarRail, {})
|
|
4206
4696
|
] });
|
|
4207
4697
|
}
|
|
4208
4698
|
function AdminShellHeader({
|
|
@@ -4211,17 +4701,17 @@ function AdminShellHeader({
|
|
|
4211
4701
|
onRefresh,
|
|
4212
4702
|
title
|
|
4213
4703
|
}) {
|
|
4214
|
-
return /* @__PURE__ */ (0,
|
|
4215
|
-
/* @__PURE__ */ (0,
|
|
4216
|
-
/* @__PURE__ */ (0,
|
|
4217
|
-
/* @__PURE__ */ (0,
|
|
4704
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("header", { className: "flex min-h-12 shrink-0 items-center gap-2 border-b bg-background/95 px-3 backdrop-blur supports-[backdrop-filter]:bg-background/80", children: [
|
|
4705
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(Tooltip, { children: [
|
|
4706
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SidebarTrigger, { className: "-ml-1" }) }),
|
|
4707
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(TooltipContent, { children: "Toggle sidebar" })
|
|
4218
4708
|
] }),
|
|
4219
|
-
/* @__PURE__ */ (0,
|
|
4220
|
-
/* @__PURE__ */ (0,
|
|
4221
|
-
/* @__PURE__ */ (0,
|
|
4709
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
|
|
4710
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_lucide_react14.Database, { className: "size-4 text-muted-foreground" }),
|
|
4711
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("h1", { className: "truncate text-sm font-medium", children: title })
|
|
4222
4712
|
] }),
|
|
4223
|
-
/* @__PURE__ */ (0,
|
|
4224
|
-
/* @__PURE__ */ (0,
|
|
4713
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(Tooltip, { children: [
|
|
4714
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
4225
4715
|
Button,
|
|
4226
4716
|
{
|
|
4227
4717
|
className: "size-8",
|
|
@@ -4230,10 +4720,10 @@ function AdminShellHeader({
|
|
|
4230
4720
|
size: "icon",
|
|
4231
4721
|
type: "button",
|
|
4232
4722
|
variant: "ghost",
|
|
4233
|
-
children: /* @__PURE__ */ (0,
|
|
4723
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_lucide_react14.RefreshCw, { className: "size-4" })
|
|
4234
4724
|
}
|
|
4235
4725
|
) }),
|
|
4236
|
-
/* @__PURE__ */ (0,
|
|
4726
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(TooltipContent, { children: "Refresh" })
|
|
4237
4727
|
] }),
|
|
4238
4728
|
brandingActions
|
|
4239
4729
|
] });
|
|
@@ -4260,27 +4750,27 @@ function mergeAdminConfig(baseConfig = defaultAdminConfig, userConfig) {
|
|
|
4260
4750
|
}
|
|
4261
4751
|
|
|
4262
4752
|
// src/useCopilotzAdmin.ts
|
|
4263
|
-
var
|
|
4753
|
+
var import_react12 = require("react");
|
|
4264
4754
|
function useCopilotzAdmin(options = {}) {
|
|
4265
|
-
const [range, setRange] = (0,
|
|
4266
|
-
const [interval, setInterval] = (0,
|
|
4755
|
+
const [range, setRange] = (0, import_react12.useState)(options.range ?? "7d");
|
|
4756
|
+
const [interval, setInterval] = (0, import_react12.useState)(
|
|
4267
4757
|
options.interval ?? "day"
|
|
4268
4758
|
);
|
|
4269
|
-
const [overview, setOverview] = (0,
|
|
4270
|
-
const [activity, setActivity] = (0,
|
|
4271
|
-
const [threads, setThreads] = (0,
|
|
4272
|
-
const [participants, setParticipants] = (0,
|
|
4273
|
-
const [agents, setAgents] = (0,
|
|
4274
|
-
const [isLoading, setIsLoading] = (0,
|
|
4275
|
-
const [error, setError] = (0,
|
|
4276
|
-
const client = (0,
|
|
4759
|
+
const [overview, setOverview] = (0, import_react12.useState)(null);
|
|
4760
|
+
const [activity, setActivity] = (0, import_react12.useState)([]);
|
|
4761
|
+
const [threads, setThreads] = (0, import_react12.useState)([]);
|
|
4762
|
+
const [participants, setParticipants] = (0, import_react12.useState)([]);
|
|
4763
|
+
const [agents, setAgents] = (0, import_react12.useState)([]);
|
|
4764
|
+
const [isLoading, setIsLoading] = (0, import_react12.useState)(true);
|
|
4765
|
+
const [error, setError] = (0, import_react12.useState)(null);
|
|
4766
|
+
const client = (0, import_react12.useMemo)(
|
|
4277
4767
|
() => createAdminClient({
|
|
4278
4768
|
baseUrl: options.baseUrl,
|
|
4279
4769
|
getRequestHeaders: options.getRequestHeaders
|
|
4280
4770
|
}),
|
|
4281
4771
|
[options.baseUrl, options.getRequestHeaders]
|
|
4282
4772
|
);
|
|
4283
|
-
const fetchAll = (0,
|
|
4773
|
+
const fetchAll = (0, import_react12.useCallback)(async () => {
|
|
4284
4774
|
setIsLoading(true);
|
|
4285
4775
|
setError(null);
|
|
4286
4776
|
try {
|
|
@@ -4326,7 +4816,7 @@ function useCopilotzAdmin(options = {}) {
|
|
|
4326
4816
|
options.threadSearch,
|
|
4327
4817
|
range
|
|
4328
4818
|
]);
|
|
4329
|
-
(0,
|
|
4819
|
+
(0, import_react12.useEffect)(() => {
|
|
4330
4820
|
void fetchAll();
|
|
4331
4821
|
}, [fetchAll]);
|
|
4332
4822
|
return {
|
|
@@ -4364,6 +4854,7 @@ function useCopilotzAdmin(options = {}) {
|
|
|
4364
4854
|
addUsageTotals,
|
|
4365
4855
|
agentsModule,
|
|
4366
4856
|
aggregateUsageRows,
|
|
4857
|
+
brainModule,
|
|
4367
4858
|
buildUsageChartState,
|
|
4368
4859
|
canAccessAdminPermission,
|
|
4369
4860
|
collectAdminNavItems,
|