@agent-native/core 0.76.0 → 0.76.2
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/corpus/core/CHANGELOG.md +56 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/agent/durable-background.ts +58 -18
- package/corpus/core/src/agent/production-agent.ts +54 -0
- package/corpus/core/src/agent/run-manager.ts +27 -0
- package/corpus/core/src/agent/run-store.ts +185 -4
- package/corpus/core/src/deploy/build.ts +8 -6
- package/corpus/core/src/server/agent-chat-plugin.ts +71 -0
- package/corpus/core/src/server/auth.ts +13 -0
- package/corpus/templates/analytics/app/components/layout/CommandPalette.tsx +12 -12
- package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +23 -23
- package/corpus/templates/analytics/app/pages/analyses/AnalysesList.tsx +2 -2
- package/corpus/templates/brain/app/routes/knowledge.tsx +6 -6
- package/corpus/templates/brain/app/routes/ops.tsx +4 -4
- package/corpus/templates/brain/app/routes/search.tsx +4 -4
- package/corpus/templates/brain/app/routes/settings.tsx +3 -3
- package/corpus/templates/brain/app/routes/sources.tsx +3 -3
- package/corpus/templates/dispatch/app/routes/integrations.tsx +3 -3
- package/corpus/templates/mail/app/components/email/EmailThread.tsx +10 -10
- package/corpus/templates/mail/app/pages/DraftQueuePage.tsx +3 -3
- package/corpus/templates/mail/app/pages/InboxPage.tsx +3 -3
- package/corpus/templates/mail/app/pages/SettingsPage.tsx +2 -2
- package/corpus/templates/plan/app/pages/PlansPage.tsx +3 -3
- package/corpus/templates/slides/app/components/deck/DeckCard.tsx +4 -4
- package/corpus/templates/slides/app/components/layout/Layout.tsx +1 -1
- package/corpus/templates/slides/app/components/layout/Sidebar.tsx +4 -4
- package/corpus/templates/slides/app/pages/Index.tsx +3 -3
- package/corpus/templates/videos/app/components/layout/NavSidebar.tsx +1 -1
- package/corpus/templates/videos/app/pages/ComponentLibraryView.tsx +1 -1
- package/corpus/templates/videos/app/pages/DesignSystems.tsx +1 -1
- package/dist/agent/durable-background.d.ts +19 -3
- package/dist/agent/durable-background.d.ts.map +1 -1
- package/dist/agent/durable-background.js +47 -17
- package/dist/agent/durable-background.js.map +1 -1
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +34 -1
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/run-manager.d.ts +8 -0
- package/dist/agent/run-manager.d.ts.map +1 -1
- package/dist/agent/run-manager.js +18 -1
- package/dist/agent/run-manager.js.map +1 -1
- package/dist/agent/run-store.d.ts +99 -0
- package/dist/agent/run-store.d.ts.map +1 -1
- package/dist/agent/run-store.js +155 -4
- package/dist/agent/run-store.js.map +1 -1
- package/dist/deploy/build.d.ts +6 -4
- package/dist/deploy/build.d.ts.map +1 -1
- package/dist/deploy/build.js +8 -6
- package/dist/deploy/build.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +58 -1
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +12 -0
- package/dist/server/auth.js.map +1 -1
- package/package.json +1 -1
|
@@ -152,6 +152,7 @@ import {
|
|
|
152
152
|
} from "../a2a/auth-policy.js";
|
|
153
153
|
import {
|
|
154
154
|
AGENT_CHAT_PROCESS_RUN_PATH,
|
|
155
|
+
extractProcessRunId,
|
|
155
156
|
prepareProcessRunRequest,
|
|
156
157
|
} from "../agent/durable-background.js";
|
|
157
158
|
import {
|
|
@@ -7174,6 +7175,14 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
7174
7175
|
status: run.status,
|
|
7175
7176
|
heartbeatAt: run.heartbeatAt,
|
|
7176
7177
|
lastProgressAt: run.lastProgressAt,
|
|
7178
|
+
// Durable-background diagnostics: how the run was dispatched and
|
|
7179
|
+
// the last reached `_process-run` worker stage (JSON
|
|
7180
|
+
// `{stage,detail?,at}`). Surfaced here so a silent background
|
|
7181
|
+
// worker death is diagnosable from the client WITHOUT the
|
|
7182
|
+
// unreadable Netlify background-function logs — read
|
|
7183
|
+
// `/runs/active?threadId=...` and inspect `diagStage`.
|
|
7184
|
+
dispatchMode: run.dispatchMode ?? null,
|
|
7185
|
+
diagStage: run.diagStage ?? null,
|
|
7177
7186
|
// Server clock so the client computes "stuck" elapsed time
|
|
7178
7187
|
// server-relative, immune to client clock skew.
|
|
7179
7188
|
serverNow: Date.now(),
|
|
@@ -7791,6 +7800,19 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
7791
7800
|
setResponseStatus(event, 405);
|
|
7792
7801
|
return { error: "Method not allowed" };
|
|
7793
7802
|
}
|
|
7803
|
+
// DIAGNOSTIC: load the run-store diagnostic recorder. Each stage we
|
|
7804
|
+
// reach is written onto the run row (diag_stage) so a silent failure
|
|
7805
|
+
// INSIDE the Netlify background function — whose logs we cannot read —
|
|
7806
|
+
// is still diagnosable from the client via /runs/active. Best-effort:
|
|
7807
|
+
// the import + every record call is wrapped so diagnostics can never
|
|
7808
|
+
// break the worker path.
|
|
7809
|
+
const diag = await import("../agent/run-store.js")
|
|
7810
|
+
.then((m) => ({
|
|
7811
|
+
record: m.recordRunDiagnostic,
|
|
7812
|
+
stages: m.RUN_DIAG_STAGE,
|
|
7813
|
+
}))
|
|
7814
|
+
.catch(() => null);
|
|
7815
|
+
|
|
7794
7816
|
// Consume the body ONCE (h3 v2's web Request stream is single-use).
|
|
7795
7817
|
let processBody: any;
|
|
7796
7818
|
try {
|
|
@@ -7800,6 +7822,18 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
7800
7822
|
return { error: "Invalid request body" };
|
|
7801
7823
|
}
|
|
7802
7824
|
|
|
7825
|
+
// Record "the route handler was entered" against the run BEFORE auth
|
|
7826
|
+
// runs. This is the proof the bg-fn invocation actually reached Nitro
|
|
7827
|
+
// (vs. dying at the function entry / never being invoked). The runId
|
|
7828
|
+
// is parsed without authenticating so we can attach it even on a
|
|
7829
|
+
// subsequent auth failure.
|
|
7830
|
+
const diagRunId = extractProcessRunId(processBody);
|
|
7831
|
+
if (diag && diagRunId) {
|
|
7832
|
+
await diag
|
|
7833
|
+
.record(diagRunId, diag.stages.routeEntered)
|
|
7834
|
+
.catch(() => {});
|
|
7835
|
+
}
|
|
7836
|
+
|
|
7803
7837
|
// Validate + HMAC-authenticate the self-dispatch and prepare the
|
|
7804
7838
|
// background-worker body. Pure decision (unit-tested in
|
|
7805
7839
|
// durable-background.spec.ts); the route only wires it to h3.
|
|
@@ -7808,10 +7842,36 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
7808
7842
|
getHeader(event, "authorization"),
|
|
7809
7843
|
);
|
|
7810
7844
|
if (!prepared.ok) {
|
|
7845
|
+
// DIAGNOSTIC: record the auth/validation failure ONTO the run
|
|
7846
|
+
// before returning the error status. Without this, a 401 (e.g.
|
|
7847
|
+
// A2A_SECRET missing/mismatched in the bg-fn env, or the path not
|
|
7848
|
+
// bypassing session auth) inside the unreadable bg function would
|
|
7849
|
+
// leave the run to time out with NO clue. The detail carries the
|
|
7850
|
+
// status + whether A2A_SECRET is even present in this isolate.
|
|
7851
|
+
if (diag && prepared.runId) {
|
|
7852
|
+
const a2aPresent = Boolean(
|
|
7853
|
+
process.env.A2A_SECRET && process.env.A2A_SECRET.length > 0,
|
|
7854
|
+
);
|
|
7855
|
+
await diag
|
|
7856
|
+
.record(
|
|
7857
|
+
prepared.runId,
|
|
7858
|
+
diag.stages.authFailed,
|
|
7859
|
+
`status=${prepared.status} error=${prepared.error} a2aSecretPresent=${a2aPresent}`,
|
|
7860
|
+
)
|
|
7861
|
+
.catch(() => {});
|
|
7862
|
+
}
|
|
7811
7863
|
setResponseStatus(event, prepared.status);
|
|
7812
7864
|
return { error: prepared.error };
|
|
7813
7865
|
}
|
|
7814
7866
|
|
|
7867
|
+
// DIAGNOSTIC: auth + body validation passed. Reaching here proves the
|
|
7868
|
+
// request was authenticated and we are about to invoke the worker.
|
|
7869
|
+
if (diag) {
|
|
7870
|
+
await diag
|
|
7871
|
+
.record(prepared.runId, diag.stages.authPassed)
|
|
7872
|
+
.catch(() => {});
|
|
7873
|
+
}
|
|
7874
|
+
|
|
7815
7875
|
// Stash the verified+augmented body for the handler — the body stream
|
|
7816
7876
|
// is already consumed, so the handler reads this instead.
|
|
7817
7877
|
(event as any).context = (event as any).context ?? {};
|
|
@@ -7821,6 +7881,17 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
7821
7881
|
return await invokeAgentChatHandler(event);
|
|
7822
7882
|
} catch (err: any) {
|
|
7823
7883
|
console.error("[agent-chat] _process-run failed:", err);
|
|
7884
|
+
// DIAGNOSTIC: the worker invocation threw at the route boundary —
|
|
7885
|
+
// record the message so the failure cause is readable client-side.
|
|
7886
|
+
if (diag) {
|
|
7887
|
+
await diag
|
|
7888
|
+
.record(
|
|
7889
|
+
prepared.runId,
|
|
7890
|
+
diag.stages.routeThrew,
|
|
7891
|
+
err instanceof Error ? err.message : String(err),
|
|
7892
|
+
)
|
|
7893
|
+
.catch(() => {});
|
|
7894
|
+
}
|
|
7824
7895
|
setResponseStatus(event, 500);
|
|
7825
7896
|
return { error: "process-run failed" };
|
|
7826
7897
|
}
|
|
@@ -1627,6 +1627,19 @@ function createAuthGuardFn(): (
|
|
|
1627
1627
|
return;
|
|
1628
1628
|
}
|
|
1629
1629
|
|
|
1630
|
+
// Durable-background AGENT-CHAT processor. The foreground POST self-dispatches
|
|
1631
|
+
// a long chat turn here (through the Netlify `-background` function, which
|
|
1632
|
+
// rewrites its default url to this path); the route HMAC-verifies the
|
|
1633
|
+
// dispatch (same internal-token scheme as agent-teams above) plus an atomic
|
|
1634
|
+
// SQL claim. The self-dispatch carries ONLY a Bearer HMAC token and NO
|
|
1635
|
+
// session cookie, so without this bypass the blanket 401-for-/_agent-native/*
|
|
1636
|
+
// gate below blocks the worker before `prepareProcessRunRequest` ever runs —
|
|
1637
|
+
// the run is never claimed, its heartbeat never starts, and it times out with
|
|
1638
|
+
// no visible progress. Exact path only (mirrors agent-teams).
|
|
1639
|
+
if (p === "/_agent-native/agent-chat/_process-run") {
|
|
1640
|
+
return;
|
|
1641
|
+
}
|
|
1642
|
+
|
|
1630
1643
|
// Read-only agent chat share links. The random token is the bearer secret;
|
|
1631
1644
|
// the route returns a sanitized transcript plus bounded run summaries and
|
|
1632
1645
|
// exposes no write surface, live event stream, tool payloads, or owner APIs.
|
|
@@ -76,7 +76,7 @@ function CommandLoadingGroup({
|
|
|
76
76
|
forceMount
|
|
77
77
|
value={`${heading} loading ${index + 1}`}
|
|
78
78
|
>
|
|
79
|
-
<Skeleton className="
|
|
79
|
+
<Skeleton className="me-2 h-4 w-4 shrink-0 rounded-sm" />
|
|
80
80
|
<Skeleton
|
|
81
81
|
className={`h-4 rounded ${
|
|
82
82
|
loadingRowWidths[index % loadingRowWidths.length]
|
|
@@ -303,10 +303,10 @@ export function CommandPalette() {
|
|
|
303
303
|
"dashboard",
|
|
304
304
|
)}
|
|
305
305
|
>
|
|
306
|
-
<IconLayoutDashboard className="
|
|
306
|
+
<IconLayoutDashboard className="me-2 h-4 w-4 text-muted-foreground" />
|
|
307
307
|
<span className="truncate">{d.name}</span>
|
|
308
308
|
{d.hiddenAt ? (
|
|
309
|
-
<span className="
|
|
309
|
+
<span className="ms-2 rounded border border-border px-1.5 py-0.5 text-[10px] font-medium text-muted-foreground">
|
|
310
310
|
Hidden
|
|
311
311
|
</span>
|
|
312
312
|
) : null}
|
|
@@ -331,10 +331,10 @@ export function CommandPalette() {
|
|
|
331
331
|
"dashboard",
|
|
332
332
|
)}
|
|
333
333
|
>
|
|
334
|
-
<IconLayoutDashboard className="
|
|
334
|
+
<IconLayoutDashboard className="me-2 h-4 w-4 text-muted-foreground" />
|
|
335
335
|
<span className="truncate">{d.name}</span>
|
|
336
336
|
{d.hiddenAt ? (
|
|
337
|
-
<span className="
|
|
337
|
+
<span className="ms-2 rounded border border-border px-1.5 py-0.5 text-[10px] font-medium text-muted-foreground">
|
|
338
338
|
Hidden
|
|
339
339
|
</span>
|
|
340
340
|
) : null}
|
|
@@ -362,7 +362,7 @@ export function CommandPalette() {
|
|
|
362
362
|
"tool",
|
|
363
363
|
)}
|
|
364
364
|
>
|
|
365
|
-
<IconTool className="
|
|
365
|
+
<IconTool className="me-2 h-4 w-4 text-muted-foreground" />
|
|
366
366
|
{extension.name}
|
|
367
367
|
</CommandItem>
|
|
368
368
|
))}
|
|
@@ -376,7 +376,7 @@ export function CommandPalette() {
|
|
|
376
376
|
onSelect={() => go(`/dashboards/${d.id}`)}
|
|
377
377
|
keywords={commandPaletteKeywords(d.name, "dashboard")}
|
|
378
378
|
>
|
|
379
|
-
<IconFlask className="
|
|
379
|
+
<IconFlask className="me-2 h-4 w-4 text-muted-foreground" />
|
|
380
380
|
{d.name}
|
|
381
381
|
</CommandItem>
|
|
382
382
|
))}
|
|
@@ -389,7 +389,7 @@ export function CommandPalette() {
|
|
|
389
389
|
onSelect={() => go(t.href)}
|
|
390
390
|
keywords={commandPaletteKeywords(t.name, "tool")}
|
|
391
391
|
>
|
|
392
|
-
<IconTool className="
|
|
392
|
+
<IconTool className="me-2 h-4 w-4 text-muted-foreground" />
|
|
393
393
|
{t.name}
|
|
394
394
|
</CommandItem>
|
|
395
395
|
))}
|
|
@@ -405,9 +405,9 @@ export function CommandPalette() {
|
|
|
405
405
|
keywords={["theme", "dark", "light", "mode"]}
|
|
406
406
|
>
|
|
407
407
|
{isDark ? (
|
|
408
|
-
<IconSun className="
|
|
408
|
+
<IconSun className="me-2 h-4 w-4 text-muted-foreground" />
|
|
409
409
|
) : (
|
|
410
|
-
<IconMoon className="
|
|
410
|
+
<IconMoon className="me-2 h-4 w-4 text-muted-foreground" />
|
|
411
411
|
)}
|
|
412
412
|
Toggle {isDark ? "light" : "dark"} mode
|
|
413
413
|
</CommandItem>
|
|
@@ -427,7 +427,7 @@ export function CommandPalette() {
|
|
|
427
427
|
"changes",
|
|
428
428
|
)}
|
|
429
429
|
>
|
|
430
|
-
<IconHistory className="
|
|
430
|
+
<IconHistory className="me-2 h-4 w-4 text-muted-foreground" />
|
|
431
431
|
What's new
|
|
432
432
|
</CommandItem>
|
|
433
433
|
</CommandGroup>
|
|
@@ -448,7 +448,7 @@ export function CommandPalette() {
|
|
|
448
448
|
"chart",
|
|
449
449
|
)}
|
|
450
450
|
>
|
|
451
|
-
<IconChartBar className="
|
|
451
|
+
<IconChartBar className="me-2 h-4 w-4 text-muted-foreground" />
|
|
452
452
|
{c.name}
|
|
453
453
|
</CommandItem>
|
|
454
454
|
))}
|
|
@@ -499,7 +499,7 @@ function SortableRow({
|
|
|
499
499
|
<div ref={setNodeRef} style={style} className="group/item relative min-w-0">
|
|
500
500
|
<button
|
|
501
501
|
type="button"
|
|
502
|
-
className="absolute -
|
|
502
|
+
className="absolute -start-4 top-1/2 z-10 -translate-y-1/2 cursor-grab rounded p-1 text-muted-foreground/30 opacity-0 transition-colors hover:text-muted-foreground/60 group-hover/item:opacity-100 active:cursor-grabbing"
|
|
503
503
|
aria-label={`Drag ${name}`}
|
|
504
504
|
{...attributes}
|
|
505
505
|
{...listeners}
|
|
@@ -527,7 +527,7 @@ function SortableRow({
|
|
|
527
527
|
setIsRenaming(false);
|
|
528
528
|
}
|
|
529
529
|
}}
|
|
530
|
-
className="min-w-0 flex-1 bg-transparent px-2 py-1.5
|
|
530
|
+
className="min-w-0 flex-1 bg-transparent px-2 py-1.5 pe-12 text-xs outline-none"
|
|
531
531
|
/>
|
|
532
532
|
) : (
|
|
533
533
|
<Tooltip>
|
|
@@ -537,7 +537,7 @@ function SortableRow({
|
|
|
537
537
|
onFocus={onPrefetch}
|
|
538
538
|
onMouseEnter={onPrefetch}
|
|
539
539
|
onTouchStart={onPrefetch}
|
|
540
|
-
className="min-w-0 flex-1 px-2 py-1.5
|
|
540
|
+
className="min-w-0 flex-1 px-2 py-1.5 pe-12 text-xs transition-[padding] md:pe-2 md:group-hover/item:pe-12 md:group-focus-within/item:pe-12"
|
|
541
541
|
>
|
|
542
542
|
<span className="block truncate">{name}</span>
|
|
543
543
|
</Link>
|
|
@@ -545,7 +545,7 @@ function SortableRow({
|
|
|
545
545
|
<TooltipContent side="right">{name}</TooltipContent>
|
|
546
546
|
</Tooltip>
|
|
547
547
|
)}
|
|
548
|
-
<div className="pointer-events-none absolute
|
|
548
|
+
<div className="pointer-events-none absolute end-1 top-1/2 flex -translate-y-1/2 items-center gap-0.5 opacity-100 transition-opacity md:opacity-0 md:group-hover/item:opacity-100 md:group-focus-within/item:opacity-100">
|
|
549
549
|
<Tooltip>
|
|
550
550
|
<TooltipTrigger asChild>
|
|
551
551
|
<button
|
|
@@ -588,7 +588,7 @@ function SortableRow({
|
|
|
588
588
|
setIsRenaming(true);
|
|
589
589
|
}}
|
|
590
590
|
>
|
|
591
|
-
<IconPencil className="
|
|
591
|
+
<IconPencil className="me-2 h-3.5 w-3.5" />
|
|
592
592
|
Rename
|
|
593
593
|
</DropdownMenuItem>
|
|
594
594
|
{onSetVisibility && visibility !== undefined && (
|
|
@@ -601,15 +601,15 @@ function SortableRow({
|
|
|
601
601
|
}}
|
|
602
602
|
>
|
|
603
603
|
{visibility === "private" ? (
|
|
604
|
-
<IconBuilding className="
|
|
604
|
+
<IconBuilding className="me-2 h-3.5 w-3.5" />
|
|
605
605
|
) : (
|
|
606
|
-
<IconLock className="
|
|
606
|
+
<IconLock className="me-2 h-3.5 w-3.5" />
|
|
607
607
|
)}
|
|
608
608
|
{visibility === "private" ? "Share with org" : "Make private"}
|
|
609
609
|
</DropdownMenuItem>
|
|
610
610
|
)}
|
|
611
611
|
<DropdownMenuItem onSelect={copyLink}>
|
|
612
|
-
<IconLink className="
|
|
612
|
+
<IconLink className="me-2 h-3.5 w-3.5" />
|
|
613
613
|
Copy link
|
|
614
614
|
</DropdownMenuItem>
|
|
615
615
|
{onUnhide && hidden ? (
|
|
@@ -619,7 +619,7 @@ function SortableRow({
|
|
|
619
619
|
void runUnhide();
|
|
620
620
|
}}
|
|
621
621
|
>
|
|
622
|
-
<IconEye className="
|
|
622
|
+
<IconEye className="me-2 h-3.5 w-3.5" />
|
|
623
623
|
Unhide
|
|
624
624
|
</DropdownMenuItem>
|
|
625
625
|
) : onHide ? (
|
|
@@ -629,7 +629,7 @@ function SortableRow({
|
|
|
629
629
|
void runHide();
|
|
630
630
|
}}
|
|
631
631
|
>
|
|
632
|
-
<IconEyeOff className="
|
|
632
|
+
<IconEyeOff className="me-2 h-3.5 w-3.5" />
|
|
633
633
|
Hide
|
|
634
634
|
</DropdownMenuItem>
|
|
635
635
|
) : null}
|
|
@@ -642,7 +642,7 @@ function SortableRow({
|
|
|
642
642
|
void runArchive();
|
|
643
643
|
}}
|
|
644
644
|
>
|
|
645
|
-
<IconArchive className="
|
|
645
|
+
<IconArchive className="me-2 h-3.5 w-3.5" />
|
|
646
646
|
Archive
|
|
647
647
|
</DropdownMenuItem>
|
|
648
648
|
<DropdownMenuSeparator />
|
|
@@ -654,7 +654,7 @@ function SortableRow({
|
|
|
654
654
|
}}
|
|
655
655
|
className="text-destructive focus:text-destructive"
|
|
656
656
|
>
|
|
657
|
-
<IconTrash className="
|
|
657
|
+
<IconTrash className="me-2 h-3.5 w-3.5" />
|
|
658
658
|
Delete permanently
|
|
659
659
|
</DropdownMenuItem>
|
|
660
660
|
</>
|
|
@@ -667,7 +667,7 @@ function SortableRow({
|
|
|
667
667
|
}}
|
|
668
668
|
className="text-destructive focus:text-destructive"
|
|
669
669
|
>
|
|
670
|
-
<IconTrash className="
|
|
670
|
+
<IconTrash className="me-2 h-3.5 w-3.5" />
|
|
671
671
|
Delete
|
|
672
672
|
</DropdownMenuItem>
|
|
673
673
|
)}
|
|
@@ -789,7 +789,7 @@ function SortableDashboardItem({
|
|
|
789
789
|
}
|
|
790
790
|
>
|
|
791
791
|
{isActive && allSubviews.length > 0 && (
|
|
792
|
-
<div className="
|
|
792
|
+
<div className="ms-6 mt-0.5 space-y-0.5">
|
|
793
793
|
{allSubviews.map((sv) => {
|
|
794
794
|
const currentSearch = new URLSearchParams(location.search);
|
|
795
795
|
const svUrl = new URL(sv.href, window.location.origin);
|
|
@@ -805,7 +805,7 @@ function SortableDashboardItem({
|
|
|
805
805
|
<div
|
|
806
806
|
key={sv.id}
|
|
807
807
|
className={cn(
|
|
808
|
-
"group/sv flex items-center gap-1 rounded-md
|
|
808
|
+
"group/sv flex items-center gap-1 rounded-md pe-1 transition-all",
|
|
809
809
|
isSubviewActive
|
|
810
810
|
? "bg-primary/10 text-primary"
|
|
811
811
|
: "text-muted-foreground/70 hover:bg-sidebar-accent/50 hover:text-primary",
|
|
@@ -1842,7 +1842,7 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
1842
1842
|
{!mobile && (
|
|
1843
1843
|
<div
|
|
1844
1844
|
onMouseDown={handleResizeStart}
|
|
1845
|
-
className="absolute
|
|
1845
|
+
className="absolute end-0 top-0 bottom-0 w-1 cursor-col-resize hover:bg-primary/30 active:bg-primary/50 z-10"
|
|
1846
1846
|
/>
|
|
1847
1847
|
)}
|
|
1848
1848
|
<div className="flex h-12 shrink-0 items-center border-b border-border px-4 lg:px-6">
|
|
@@ -1959,7 +1959,7 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
1959
1959
|
<button
|
|
1960
1960
|
type="button"
|
|
1961
1961
|
onClick={toggleDashOpen}
|
|
1962
|
-
className="flex min-w-0 flex-1 items-center gap-3 px-3 py-2 text-
|
|
1962
|
+
className="flex min-w-0 flex-1 items-center gap-3 px-3 py-2 text-start"
|
|
1963
1963
|
aria-expanded={dashOpen}
|
|
1964
1964
|
>
|
|
1965
1965
|
<IconChartBar className="h-4 w-4 shrink-0" />
|
|
@@ -1977,7 +1977,7 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
1977
1977
|
<button
|
|
1978
1978
|
type="button"
|
|
1979
1979
|
onClick={toggleDashOpen}
|
|
1980
|
-
className="
|
|
1980
|
+
className="me-1 flex h-7 w-7 shrink-0 items-center justify-center rounded-md text-muted-foreground/70 hover:bg-sidebar-accent hover:text-foreground"
|
|
1981
1981
|
aria-label={
|
|
1982
1982
|
dashOpen ? "Collapse dashboards" : "Expand dashboards"
|
|
1983
1983
|
}
|
|
@@ -2001,7 +2001,7 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
2001
2001
|
items={displayedDashboards.map((d) => d.id)}
|
|
2002
2002
|
strategy={verticalListSortingStrategy}
|
|
2003
2003
|
>
|
|
2004
|
-
<div className="
|
|
2004
|
+
<div className="ms-4 min-w-0 space-y-0.5">
|
|
2005
2005
|
{displayedDashboards.map((d) => (
|
|
2006
2006
|
<SortableDashboardItem
|
|
2007
2007
|
key={d.id}
|
|
@@ -2062,7 +2062,7 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
2062
2062
|
<button
|
|
2063
2063
|
type="button"
|
|
2064
2064
|
onClick={toggleAnalysesOpen}
|
|
2065
|
-
className="flex min-w-0 flex-1 items-center gap-3 px-3 py-2 text-
|
|
2065
|
+
className="flex min-w-0 flex-1 items-center gap-3 px-3 py-2 text-start"
|
|
2066
2066
|
aria-expanded={analysesOpen}
|
|
2067
2067
|
>
|
|
2068
2068
|
<IconReportAnalytics className="h-4 w-4 shrink-0" />
|
|
@@ -2084,7 +2084,7 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
2084
2084
|
<button
|
|
2085
2085
|
type="button"
|
|
2086
2086
|
onClick={toggleAnalysesOpen}
|
|
2087
|
-
className="
|
|
2087
|
+
className="me-1 flex h-7 w-7 shrink-0 items-center justify-center rounded-md text-muted-foreground/70 hover:bg-sidebar-accent hover:text-foreground"
|
|
2088
2088
|
aria-label={
|
|
2089
2089
|
analysesOpen ? "Collapse analyses" : "Expand analyses"
|
|
2090
2090
|
}
|
|
@@ -2108,7 +2108,7 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
2108
2108
|
items={displayedAnalyses.map((a) => a.id)}
|
|
2109
2109
|
strategy={verticalListSortingStrategy}
|
|
2110
2110
|
>
|
|
2111
|
-
<div className="
|
|
2111
|
+
<div className="ms-4 min-w-0 space-y-0.5">
|
|
2112
2112
|
{displayedAnalyses.map((a) => (
|
|
2113
2113
|
<SortableRow
|
|
2114
2114
|
key={a.id}
|
|
@@ -2233,7 +2233,7 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
2233
2233
|
<TooltipTrigger asChild>
|
|
2234
2234
|
<PopoverTrigger asChild>
|
|
2235
2235
|
<button className="flex items-center justify-center rounded-lg p-2 text-muted-foreground transition-all hover:text-primary cursor-pointer hover:bg-sidebar-accent/50">
|
|
2236
|
-
<IconLogout className="h-4 w-4" />
|
|
2236
|
+
<IconLogout className="h-4 w-4 rtl:-scale-x-100" />
|
|
2237
2237
|
</button>
|
|
2238
2238
|
</PopoverTrigger>
|
|
2239
2239
|
</TooltipTrigger>
|
|
@@ -78,13 +78,13 @@ export default function AnalysesList() {
|
|
|
78
78
|
</p>
|
|
79
79
|
{analyses && analyses.length > 0 && (
|
|
80
80
|
<div className="relative">
|
|
81
|
-
<IconSearch className="absolute
|
|
81
|
+
<IconSearch className="absolute start-2.5 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-muted-foreground/60 pointer-events-none" />
|
|
82
82
|
<input
|
|
83
83
|
type="search"
|
|
84
84
|
placeholder="Search analyses…"
|
|
85
85
|
value={searchQuery}
|
|
86
86
|
onChange={(e) => setSearchQuery(e.target.value)}
|
|
87
|
-
className="h-8 rounded-md border border-input bg-background
|
|
87
|
+
className="h-8 rounded-md border border-input bg-background ps-8 pe-3 text-xs placeholder:text-muted-foreground/60 focus:outline-none focus:ring-2 focus:ring-ring"
|
|
88
88
|
/>
|
|
89
89
|
</div>
|
|
90
90
|
)}
|
|
@@ -163,12 +163,12 @@ export default function KnowledgeRoute() {
|
|
|
163
163
|
<Card>
|
|
164
164
|
<CardContent className="flex flex-col gap-3 p-4 lg:flex-row lg:items-center">
|
|
165
165
|
<div className="relative min-w-0 flex-1">
|
|
166
|
-
<IconSearch className="pointer-events-none absolute
|
|
166
|
+
<IconSearch className="pointer-events-none absolute start-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" />
|
|
167
167
|
<Input
|
|
168
168
|
value={query}
|
|
169
169
|
onChange={(event) => updateParam("q", event.target.value)}
|
|
170
170
|
placeholder="Search memories, topics, source names..."
|
|
171
|
-
className="
|
|
171
|
+
className="ps-9"
|
|
172
172
|
/>
|
|
173
173
|
</div>
|
|
174
174
|
<div className="flex flex-col gap-2 sm:flex-row">
|
|
@@ -217,8 +217,8 @@ export default function KnowledgeRoute() {
|
|
|
217
217
|
<TableHead>Source</TableHead>
|
|
218
218
|
<TableHead>Status</TableHead>
|
|
219
219
|
<TableHead>Company context</TableHead>
|
|
220
|
-
<TableHead className="text-
|
|
221
|
-
<TableHead className="text-
|
|
220
|
+
<TableHead className="text-end">Confidence</TableHead>
|
|
221
|
+
<TableHead className="text-end">Cites</TableHead>
|
|
222
222
|
</TableRow>
|
|
223
223
|
</TableHeader>
|
|
224
224
|
<TableBody>
|
|
@@ -262,12 +262,12 @@ export default function KnowledgeRoute() {
|
|
|
262
262
|
onPreview={() => void openCanonicalPreview(row)}
|
|
263
263
|
/>
|
|
264
264
|
</TableCell>
|
|
265
|
-
<TableCell className="text-
|
|
265
|
+
<TableCell className="text-end">
|
|
266
266
|
{typeof row.confidence === "number"
|
|
267
267
|
? formatPercent(row.confidence)
|
|
268
268
|
: "n/a"}
|
|
269
269
|
</TableCell>
|
|
270
|
-
<TableCell className="text-
|
|
270
|
+
<TableCell className="text-end">
|
|
271
271
|
{row.citations ?? 0}
|
|
272
272
|
</TableCell>
|
|
273
273
|
</TableRow>
|
|
@@ -416,11 +416,11 @@ export default function OpsRoute() {
|
|
|
416
416
|
<TableHead>Status</TableHead>
|
|
417
417
|
<TableHead>Capture</TableHead>
|
|
418
418
|
<TableHead>Source</TableHead>
|
|
419
|
-
<TableHead className="text-
|
|
419
|
+
<TableHead className="text-end">Attempts</TableHead>
|
|
420
420
|
<TableHead>Run after</TableHead>
|
|
421
421
|
<TableHead>Updated</TableHead>
|
|
422
422
|
<TableHead>Reason</TableHead>
|
|
423
|
-
<TableHead className="text-
|
|
423
|
+
<TableHead className="text-end">Action</TableHead>
|
|
424
424
|
</TableRow>
|
|
425
425
|
</TableHeader>
|
|
426
426
|
<TableBody>
|
|
@@ -474,7 +474,7 @@ export default function OpsRoute() {
|
|
|
474
474
|
</p>
|
|
475
475
|
</div>
|
|
476
476
|
</TableCell>
|
|
477
|
-
<TableCell className="text-
|
|
477
|
+
<TableCell className="text-end tabular-nums">
|
|
478
478
|
{item.attempts}
|
|
479
479
|
</TableCell>
|
|
480
480
|
<TableCell className="whitespace-nowrap text-sm text-muted-foreground">
|
|
@@ -491,7 +491,7 @@ export default function OpsRoute() {
|
|
|
491
491
|
"No issue recorded"}
|
|
492
492
|
</p>
|
|
493
493
|
</TableCell>
|
|
494
|
-
<TableCell className="text-
|
|
494
|
+
<TableCell className="text-end">
|
|
495
495
|
<Button
|
|
496
496
|
size="sm"
|
|
497
497
|
variant="outline"
|
|
@@ -144,12 +144,12 @@ export default function SearchRoute() {
|
|
|
144
144
|
<Card>
|
|
145
145
|
<CardContent className="grid gap-3 p-4">
|
|
146
146
|
<div className="relative">
|
|
147
|
-
<IconSearch className="pointer-events-none absolute
|
|
147
|
+
<IconSearch className="pointer-events-none absolute start-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" />
|
|
148
148
|
<Input
|
|
149
149
|
value={query}
|
|
150
150
|
onChange={(event) => updateParam("q", event.target.value)}
|
|
151
151
|
placeholder="Search decisions, customer facts, source names, transcripts, or policy snippets..."
|
|
152
|
-
className="h-11
|
|
152
|
+
className="h-11 ps-9 text-base"
|
|
153
153
|
autoFocus
|
|
154
154
|
/>
|
|
155
155
|
</div>
|
|
@@ -420,10 +420,10 @@ function SearchResultDetails({
|
|
|
420
420
|
</Badge>
|
|
421
421
|
) : null}
|
|
422
422
|
</div>
|
|
423
|
-
<SheetTitle className="text-
|
|
423
|
+
<SheetTitle className="text-start text-xl leading-7">
|
|
424
424
|
{result.title}
|
|
425
425
|
</SheetTitle>
|
|
426
|
-
<SheetDescription className="text-
|
|
426
|
+
<SheetDescription className="text-start leading-6">
|
|
427
427
|
{body}
|
|
428
428
|
</SheetDescription>
|
|
429
429
|
</SheetHeader>
|
|
@@ -608,9 +608,9 @@ function NumberField({
|
|
|
608
608
|
max={max}
|
|
609
609
|
value={value}
|
|
610
610
|
onChange={(event) => onChange(Number(event.target.value))}
|
|
611
|
-
className="rounded-
|
|
611
|
+
className="rounded-e-none"
|
|
612
612
|
/>
|
|
613
|
-
<div className="flex min-w-20 items-center justify-center rounded-
|
|
613
|
+
<div className="flex min-w-20 items-center justify-center rounded-e-md border border-s-0 border-input bg-muted px-3 text-sm text-muted-foreground">
|
|
614
614
|
{suffix}
|
|
615
615
|
</div>
|
|
616
616
|
</div>
|
|
@@ -653,7 +653,7 @@ function PolicyRow({ label, value }: { label: string; value: string }) {
|
|
|
653
653
|
return (
|
|
654
654
|
<div className="flex items-center justify-between gap-3">
|
|
655
655
|
<span className="min-w-0 text-muted-foreground">{label}</span>
|
|
656
|
-
<span className="max-w-40 truncate text-
|
|
656
|
+
<span className="max-w-40 truncate text-end font-medium capitalize">
|
|
657
657
|
{value.replace(/_/g, " ")}
|
|
658
658
|
</span>
|
|
659
659
|
</div>
|
|
@@ -1074,7 +1074,7 @@ function ProviderCatalog({
|
|
|
1074
1074
|
variant="outline"
|
|
1075
1075
|
className={`${grantStateClass(grantState)} w-fit max-w-full`}
|
|
1076
1076
|
>
|
|
1077
|
-
<GrantIcon className="
|
|
1077
|
+
<GrantIcon className="me-1 size-3" />
|
|
1078
1078
|
{grantStateLabel(grantState)}
|
|
1079
1079
|
</Badge>
|
|
1080
1080
|
<Badge
|
|
@@ -2037,7 +2037,7 @@ export default function SourcesRoute() {
|
|
|
2037
2037
|
{enqueueCapturesDistillation.isPending ? (
|
|
2038
2038
|
<IconLoader2 className="size-4 animate-spin" />
|
|
2039
2039
|
) : (
|
|
2040
|
-
<IconSend className="size-4" />
|
|
2040
|
+
<IconSend className="size-4 rtl:-scale-x-100" />
|
|
2041
2041
|
)}
|
|
2042
2042
|
Queue selected
|
|
2043
2043
|
</Button>
|
|
@@ -2205,7 +2205,7 @@ export default function SourcesRoute() {
|
|
|
2205
2205
|
{enqueueDistillation.isPending ? (
|
|
2206
2206
|
<IconLoader2 className="size-4 animate-spin" />
|
|
2207
2207
|
) : (
|
|
2208
|
-
<IconSend className="size-4" />
|
|
2208
|
+
<IconSend className="size-4 rtl:-scale-x-100" />
|
|
2209
2209
|
)}
|
|
2210
2210
|
{queueActionLabel(queue)}
|
|
2211
2211
|
</Button>
|
|
@@ -1072,7 +1072,7 @@ function Modal({
|
|
|
1072
1072
|
return (
|
|
1073
1073
|
<Dialog open={open} onOpenChange={(next) => !next && onClose()}>
|
|
1074
1074
|
<DialogContent className="max-h-[92vh] max-w-2xl overflow-y-auto p-0">
|
|
1075
|
-
<DialogHeader className="border-b p-4
|
|
1075
|
+
<DialogHeader className="border-b p-4 pe-10">
|
|
1076
1076
|
<DialogTitle className="text-base">{title}</DialogTitle>
|
|
1077
1077
|
{description ? (
|
|
1078
1078
|
<DialogDescription>{description}</DialogDescription>
|
|
@@ -1784,7 +1784,7 @@ function SetupWizard({
|
|
|
1784
1784
|
onClick={() => onStepChange(step - 1)}
|
|
1785
1785
|
disabled={saving}
|
|
1786
1786
|
>
|
|
1787
|
-
<IconArrowLeft size={14} />
|
|
1787
|
+
<IconArrowLeft size={14} className="rtl:-scale-x-100" />
|
|
1788
1788
|
Back
|
|
1789
1789
|
</Button>
|
|
1790
1790
|
) : null}
|
|
@@ -1795,7 +1795,7 @@ function SetupWizard({
|
|
|
1795
1795
|
disabled={!canAdvance || loading || saving}
|
|
1796
1796
|
>
|
|
1797
1797
|
Next
|
|
1798
|
-
<IconArrowRight size={14} />
|
|
1798
|
+
<IconArrowRight size={14} className="rtl:-scale-x-100" />
|
|
1799
1799
|
</Button>
|
|
1800
1800
|
) : (
|
|
1801
1801
|
<Button
|