@agent-native/core 0.76.9 → 0.76.10
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/README.md +1 -1
- package/corpus/core/CHANGELOG.md +33 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/scripts/generate-og-font-data.mjs +9 -5
- package/corpus/core/src/client/AgentPanel.tsx +70 -1
- package/corpus/core/src/client/AssistantChat.tsx +1 -3
- package/corpus/core/src/client/MultiTabAssistantChat.tsx +0 -62
- package/corpus/core/src/client/composer/TiptapComposer.tsx +6 -13
- package/corpus/core/src/server/og-fonts-data.ts +7 -4
- package/corpus/core/src/server/og-fonts.ts +10 -3
- package/corpus/core/src/server/social-og-image.ts +45 -6
- package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +199 -19
- package/corpus/templates/analytics/app/pages/adhoc/AdhocRouter.tsx +1 -21
- package/corpus/templates/analytics/app/pages/adhoc/DashboardSkeleton.tsx +35 -0
- package/corpus/templates/analytics/app/pages/adhoc/explorer-dashboard/index.tsx +3 -23
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +3 -26
- package/corpus/templates/analytics/changelog/2026-06-24-daily-dashboard-charts-now-use-local-day-buckets-and-show-th.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-24-dashboard-loading-placeholders-now-span-the-available-page-w.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-24-first-party-dashboard-dates-now-align-to-pacific-time-for-da.md +6 -0
- package/corpus/templates/analytics/server/lib/first-party-metric-catalog.ts +19 -7
- package/dist/client/AgentPanel.d.ts +5 -1
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +23 -4
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/AssistantChat.d.ts +1 -3
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +1 -17
- package/dist/client/MultiTabAssistantChat.js.map +1 -1
- package/dist/client/composer/TiptapComposer.d.ts +4 -0
- package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/client/composer/TiptapComposer.js +5 -9
- package/dist/client/composer/TiptapComposer.js.map +1 -1
- package/dist/server/og-fonts-data.d.ts +1 -0
- package/dist/server/og-fonts-data.d.ts.map +1 -1
- package/dist/server/og-fonts-data.js +5 -4
- package/dist/server/og-fonts-data.js.map +1 -1
- package/dist/server/og-fonts.d.ts +1 -0
- package/dist/server/og-fonts.d.ts.map +1 -1
- package/dist/server/og-fonts.js +10 -4
- package/dist/server/og-fonts.js.map +1 -1
- package/dist/server/social-og-image.d.ts.map +1 -1
- package/dist/server/social-og-image.js +33 -6
- package/dist/server/social-og-image.js.map +1 -1
- package/package.json +1 -1
package/corpus/README.md
CHANGED
package/corpus/core/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,38 @@
|
|
|
1
1
|
# @agent-native/core
|
|
2
2
|
|
|
3
|
+
## 0.76.10
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 2be975e: Animate the standard agent sidebar drawer when it opens and closes.
|
|
8
|
+
- 2be975e: Durable background diagnostics: preserve the background-function worker's last
|
|
9
|
+
`diag_stage` (`route_entered` / `auth_failed` / etc., or `none` if it never
|
|
10
|
+
reached the route) in the foreground circuit-breaker's
|
|
11
|
+
`foreground_inline_recovery` detail instead of overwriting it. This makes a
|
|
12
|
+
silent worker death diagnosable from `/runs/active` without reading the
|
|
13
|
+
unreadable Netlify background-function logs. `readBackgroundRunClaim` now also
|
|
14
|
+
returns `diagStage`.
|
|
15
|
+
- 2be975e: Durable background agent runs: add a foreground **circuit-breaker** so a dead
|
|
16
|
+
background worker can no longer break chat. A Netlify async background function
|
|
17
|
+
returns `202` the instant it enqueues the invocation, but the worker may never
|
|
18
|
+
execute — e.g. the generated function wrapper fails to import `./main.mjs` or
|
|
19
|
+
hand off to the Nitro `_process-run` route, so it never reaches
|
|
20
|
+
`claimBackgroundRun` and the run is reaped as "worker never claimed the run".
|
|
21
|
+
After a successful dispatch the foreground now polls briefly for the worker to
|
|
22
|
+
actually claim the run; if it doesn't within the grace window, the turn is
|
|
23
|
+
recovered **inline** (the same safe atomic-claim path used for a fast dispatch
|
|
24
|
+
failure), so a dead worker degrades to a working synchronous turn instead of a
|
|
25
|
+
reaped failure. Also harden the generated background-function wrapper to pass
|
|
26
|
+
Netlify's `context` through to the Nitro handler and wrap the handoff in
|
|
27
|
+
try/catch so a pre-route failure is logged loudly instead of silently swallowed
|
|
28
|
+
behind the async 202.
|
|
29
|
+
- 2be975e: Bundle an Arabic-capable OG image font so localized Arabic docs previews render real text instead of missing-glyph boxes.
|
|
30
|
+
- 2be975e: Show a New chat button on full-page Ask chat surfaces with visible conversation tabs after a conversation starts.
|
|
31
|
+
- 2be975e: Add an `agentNative()` Vite plugin preset so app `vite.config.ts` files can use
|
|
32
|
+
Vite's native `defineConfig` while keeping Agent-Native framework defaults.
|
|
33
|
+
- 2be975e: Stop showing previous scoped chats in the empty chat state.
|
|
34
|
+
- 2be975e: Let the agent composer model picker shrink to its content instead of forcing a tall popover.
|
|
35
|
+
|
|
3
36
|
## 0.76.9
|
|
4
37
|
|
|
5
38
|
### Patch Changes
|
package/corpus/core/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// Regenerates src/server/og-fonts-data.ts by base64-encoding the bundled
|
|
3
|
-
//
|
|
3
|
+
// OG image fonts. The fonts are embedded as base64 (rather than read
|
|
4
4
|
// from disk at runtime) so that OG image text renders consistently regardless
|
|
5
5
|
// of the host's system fonts or how the serverless bundle is traced — the
|
|
6
6
|
// font bytes always travel with the compiled JS. Run after updating the .ttf
|
|
@@ -17,13 +17,17 @@ const fonts = [
|
|
|
17
17
|
constName: "LIBERATION_SANS_BOLD_BASE64",
|
|
18
18
|
file: "../src/assets/fonts/LiberationSans-Bold.ttf",
|
|
19
19
|
},
|
|
20
|
+
{
|
|
21
|
+
constName: "NOTO_NASKH_ARABIC_BASE64",
|
|
22
|
+
file: "../src/assets/fonts/NotoNaskhArabic-Variable.ttf",
|
|
23
|
+
},
|
|
20
24
|
];
|
|
21
25
|
|
|
22
26
|
const banner = `// AUTO-GENERATED by scripts/generate-og-font-data.mjs — do not edit by hand.
|
|
23
|
-
// Base64-encoded
|
|
24
|
-
//
|
|
25
|
-
//
|
|
26
|
-
// src/assets/fonts/
|
|
27
|
+
// Base64-encoded OG image fonts, embedded so the OG image renderer always has
|
|
28
|
+
// script coverage independent of host system fonts or serverless asset tracing.
|
|
29
|
+
// See src/assets/fonts/LICENSE_LIBERATION and
|
|
30
|
+
// src/assets/fonts/LICENSE_NOTO_NASKH_ARABIC for licensing. Regenerate with:
|
|
27
31
|
// node scripts/generate-og-font-data.mjs
|
|
28
32
|
`;
|
|
29
33
|
|
|
@@ -374,6 +374,18 @@ export function shouldShowAgentPanelChatTabBar(
|
|
|
374
374
|
return mainTabs.length > 1 || hasSubTabs;
|
|
375
375
|
}
|
|
376
376
|
|
|
377
|
+
export function shouldShowAgentPanelPageNewChatButton(
|
|
378
|
+
tabs: MultiTabAssistantChatHeaderProps["tabs"],
|
|
379
|
+
activeTabId: string,
|
|
380
|
+
activeTabMessageCount: number,
|
|
381
|
+
) {
|
|
382
|
+
const activeTab = tabs.find((tab) => tab.id === activeTabId);
|
|
383
|
+
return (
|
|
384
|
+
Boolean(activeTabId) &&
|
|
385
|
+
(activeTabMessageCount > 0 || activeTab?.status === "running")
|
|
386
|
+
);
|
|
387
|
+
}
|
|
388
|
+
|
|
377
389
|
export function shouldShowAgentPanelCliTabBar(cliTabs: string[]) {
|
|
378
390
|
return cliTabs.length > 1;
|
|
379
391
|
}
|
|
@@ -532,6 +544,8 @@ export interface AgentPanelProps extends Omit<
|
|
|
532
544
|
chatNotice?: React.ReactNode;
|
|
533
545
|
/** Show the chat thread tab row when the panel header is hidden. Default: true. */
|
|
534
546
|
showTabBar?: boolean;
|
|
547
|
+
/** Show a compact New chat action in page chat when the main header is hidden. */
|
|
548
|
+
showPageNewChatButton?: boolean;
|
|
535
549
|
/** Capability gate for source edits and CLI access. */
|
|
536
550
|
codeAccess?: AgentPanelCodeAccess;
|
|
537
551
|
}
|
|
@@ -649,6 +663,7 @@ function AgentPanelInner({
|
|
|
649
663
|
threadUrlSync,
|
|
650
664
|
chatNotice,
|
|
651
665
|
showTabBar = true,
|
|
666
|
+
showPageNewChatButton = false,
|
|
652
667
|
codeAccess,
|
|
653
668
|
...assistantChatProps
|
|
654
669
|
}: AgentPanelProps) {
|
|
@@ -1246,6 +1261,43 @@ function AgentPanelInner({
|
|
|
1246
1261
|
],
|
|
1247
1262
|
);
|
|
1248
1263
|
|
|
1264
|
+
const renderPageChatOverlay = useCallback(
|
|
1265
|
+
({
|
|
1266
|
+
activeTabId,
|
|
1267
|
+
activeTabMessageCount,
|
|
1268
|
+
addTab,
|
|
1269
|
+
tabs,
|
|
1270
|
+
}: MultiTabAssistantChatHeaderProps) => {
|
|
1271
|
+
if (
|
|
1272
|
+
!shouldShowAgentPanelPageNewChatButton(
|
|
1273
|
+
tabs,
|
|
1274
|
+
activeTabId,
|
|
1275
|
+
activeTabMessageCount,
|
|
1276
|
+
)
|
|
1277
|
+
) {
|
|
1278
|
+
return null;
|
|
1279
|
+
}
|
|
1280
|
+
|
|
1281
|
+
return (
|
|
1282
|
+
<div className="pointer-events-none absolute inset-x-0 top-3 z-[60] flex justify-end px-3 sm:top-4 sm:px-4">
|
|
1283
|
+
<button
|
|
1284
|
+
type="button"
|
|
1285
|
+
data-agent-page-new-chat=""
|
|
1286
|
+
aria-label={t("agentPanel.newChat")}
|
|
1287
|
+
onClick={() => {
|
|
1288
|
+
addTab();
|
|
1289
|
+
}}
|
|
1290
|
+
className="pointer-events-auto inline-flex h-8 items-center gap-1.5 rounded-md border border-border bg-background/95 px-2.5 text-xs font-medium text-foreground shadow-sm backdrop-blur transition-colors hover:bg-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
|
1291
|
+
>
|
|
1292
|
+
<IconPlus size={14} />
|
|
1293
|
+
<span>{t("agentPanel.newChat")}</span>
|
|
1294
|
+
</button>
|
|
1295
|
+
</div>
|
|
1296
|
+
);
|
|
1297
|
+
},
|
|
1298
|
+
[t],
|
|
1299
|
+
);
|
|
1300
|
+
|
|
1249
1301
|
// Ref callback: scroll the active tab into view in the overflow container.
|
|
1250
1302
|
// Uses getBoundingClientRect for reliable positioning regardless of offsetParent.
|
|
1251
1303
|
const activeTabRefCb = useCallback((el: HTMLDivElement | null) => {
|
|
@@ -1591,7 +1643,11 @@ function AgentPanelInner({
|
|
|
1591
1643
|
showHeader={false}
|
|
1592
1644
|
renderHeader={showHeader ? renderChatHeader : undefined}
|
|
1593
1645
|
showTabBar={showTabBar}
|
|
1594
|
-
renderOverlay={
|
|
1646
|
+
renderOverlay={
|
|
1647
|
+
showPageNewChatButton && !showHeader
|
|
1648
|
+
? renderPageChatOverlay
|
|
1649
|
+
: undefined
|
|
1650
|
+
}
|
|
1595
1651
|
contentHidden={mode !== "chat"}
|
|
1596
1652
|
emptyStateText={emptyStateText}
|
|
1597
1653
|
emptyStateAddon={emptyStateAddon}
|
|
@@ -2181,6 +2237,13 @@ export interface AgentChatSurfaceProps extends AgentPanelProps {
|
|
|
2181
2237
|
chatViewTransition?: boolean;
|
|
2182
2238
|
}
|
|
2183
2239
|
|
|
2240
|
+
export function shouldDefaultAgentChatSurfacePageNewChatButton(
|
|
2241
|
+
mode: AgentChatSurfaceMode | undefined,
|
|
2242
|
+
showTabBar: boolean | undefined,
|
|
2243
|
+
): boolean {
|
|
2244
|
+
return mode === "page" && showTabBar !== false;
|
|
2245
|
+
}
|
|
2246
|
+
|
|
2184
2247
|
/**
|
|
2185
2248
|
* Reusable chat surface backed by AgentPanel internals.
|
|
2186
2249
|
*
|
|
@@ -2195,15 +2258,21 @@ export function AgentChatSurface({
|
|
|
2195
2258
|
isFullscreen,
|
|
2196
2259
|
style,
|
|
2197
2260
|
chatViewTransition = false,
|
|
2261
|
+
showPageNewChatButton,
|
|
2198
2262
|
...props
|
|
2199
2263
|
}: AgentChatSurfaceProps) {
|
|
2200
2264
|
const pageMode = mode === "page";
|
|
2265
|
+
const defaultShowPageNewChatButton =
|
|
2266
|
+
shouldDefaultAgentChatSurfacePageNewChatButton(mode, props.showTabBar);
|
|
2201
2267
|
|
|
2202
2268
|
return (
|
|
2203
2269
|
<AgentPanel
|
|
2204
2270
|
{...props}
|
|
2205
2271
|
defaultMode={defaultMode}
|
|
2206
2272
|
isFullscreen={isFullscreen ?? pageMode}
|
|
2273
|
+
showPageNewChatButton={
|
|
2274
|
+
showPageNewChatButton ?? defaultShowPageNewChatButton
|
|
2275
|
+
}
|
|
2207
2276
|
className={cn(
|
|
2208
2277
|
pageMode && "h-full min-h-0 w-full overflow-hidden bg-background",
|
|
2209
2278
|
chatViewTransition && AGENT_CHAT_VIEW_TRANSITION_CLASS,
|
|
@@ -637,9 +637,7 @@ export interface AssistantChatProps {
|
|
|
637
637
|
suggestions?: string[];
|
|
638
638
|
/** Context-aware suggestions merged with `suggestions`. Enabled by default. */
|
|
639
639
|
dynamicSuggestions?: AgentDynamicSuggestionsOption;
|
|
640
|
-
/** Optional content rendered in the empty state, above the suggestion buttons.
|
|
641
|
-
* Used by MultiTabAssistantChat to surface "previous chats for this design"
|
|
642
|
-
* when the current thread is empty but the scope has other threads. */
|
|
640
|
+
/** Optional content rendered in the empty state, above the suggestion buttons. */
|
|
643
641
|
emptyStateAddon?: React.ReactNode;
|
|
644
642
|
/** Whether to show the header bar. Default: true */
|
|
645
643
|
showHeader?: boolean;
|
|
@@ -342,57 +342,6 @@ function ScopeBadge({
|
|
|
342
342
|
);
|
|
343
343
|
}
|
|
344
344
|
|
|
345
|
-
/**
|
|
346
|
-
* Empty-state addon shown when the user starts a fresh chat inside a
|
|
347
|
-
* scoped surface that already has other threads. Surfaces those threads
|
|
348
|
-
* inline so chats don't feel "lost" after the user navigates away and
|
|
349
|
-
* back — the chip popover lists them too, but this nudge is visible
|
|
350
|
-
* without any extra clicks.
|
|
351
|
-
*/
|
|
352
|
-
function PreviousScopedChatsHint({
|
|
353
|
-
scope,
|
|
354
|
-
threads,
|
|
355
|
-
onSelectThread,
|
|
356
|
-
}: {
|
|
357
|
-
scope: ChatThreadScope;
|
|
358
|
-
threads: ChatThreadSummary[];
|
|
359
|
-
onSelectThread: (id: string) => void;
|
|
360
|
-
}) {
|
|
361
|
-
const MAX_INLINE = 3;
|
|
362
|
-
const shown = threads.slice(0, MAX_INLINE);
|
|
363
|
-
const remaining = threads.length - shown.length;
|
|
364
|
-
const scopeLabel = scope.label || `this ${formatScopeType(scope.type)}`;
|
|
365
|
-
return (
|
|
366
|
-
<div className="flex w-full max-w-[280px] flex-col gap-1.5">
|
|
367
|
-
<div className="text-[10px] uppercase tracking-wider text-muted-foreground/70 text-center">
|
|
368
|
-
Previous chats for {scopeLabel}
|
|
369
|
-
</div>
|
|
370
|
-
<div className="flex flex-col gap-1">
|
|
371
|
-
{shown.map((thread) => (
|
|
372
|
-
<button
|
|
373
|
-
key={thread.id}
|
|
374
|
-
type="button"
|
|
375
|
-
onClick={() => onSelectThread(thread.id)}
|
|
376
|
-
className="flex items-baseline justify-between gap-2 rounded-md border border-border px-2.5 py-1.5 text-start hover:bg-accent cursor-pointer"
|
|
377
|
-
>
|
|
378
|
-
<span className="truncate text-[12px] text-foreground">
|
|
379
|
-
{thread.title || thread.preview || "Chat"}
|
|
380
|
-
</span>
|
|
381
|
-
<span className="shrink-0 text-[10px] text-muted-foreground">
|
|
382
|
-
{formatThreadTime(thread.updatedAt)}
|
|
383
|
-
</span>
|
|
384
|
-
</button>
|
|
385
|
-
))}
|
|
386
|
-
</div>
|
|
387
|
-
{remaining > 0 && (
|
|
388
|
-
<div className="text-[10px] text-muted-foreground/70 text-center">
|
|
389
|
-
+{remaining} more
|
|
390
|
-
</div>
|
|
391
|
-
)}
|
|
392
|
-
</div>
|
|
393
|
-
);
|
|
394
|
-
}
|
|
395
|
-
|
|
396
345
|
/**
|
|
397
346
|
* Thin confirmation banner shown briefly after detach. The chip itself
|
|
398
347
|
* unmounts the moment scope clears on the active thread, so this banner
|
|
@@ -2777,17 +2726,6 @@ export function MultiTabAssistantChat({
|
|
|
2777
2726
|
? `Ask about ${tabScope.label}`
|
|
2778
2727
|
: props.emptyStateText
|
|
2779
2728
|
}
|
|
2780
|
-
emptyStateAddon={
|
|
2781
|
-
tabId === activeThreadId &&
|
|
2782
|
-
tabScope &&
|
|
2783
|
-
otherScopedThreads.length > 0 ? (
|
|
2784
|
-
<PreviousScopedChatsHint
|
|
2785
|
-
scope={tabScope}
|
|
2786
|
-
threads={otherScopedThreads}
|
|
2787
|
-
onSelectThread={openFromHistory}
|
|
2788
|
-
/>
|
|
2789
|
-
) : undefined
|
|
2790
|
-
}
|
|
2791
2729
|
ref={(handle) => {
|
|
2792
2730
|
if (handle) {
|
|
2793
2731
|
chatRefs.current.set(tabId, handle);
|
|
@@ -596,6 +596,11 @@ const FRIENDLY_MODEL_NAMES: Record<string, string> = {
|
|
|
596
596
|
"deepseek-v3-1": "DeepSeek v3.1",
|
|
597
597
|
};
|
|
598
598
|
|
|
599
|
+
export const MODEL_SELECTOR_POPOVER_STYLE = {
|
|
600
|
+
fontSize: 13,
|
|
601
|
+
maxHeight: "min(500px, var(--radix-popover-content-available-height, 500px))",
|
|
602
|
+
} satisfies React.CSSProperties;
|
|
603
|
+
|
|
599
604
|
function friendlyModelName(model: string): string {
|
|
600
605
|
if (FRIENDLY_MODEL_NAMES[model]) return FRIENDLY_MODEL_NAMES[model];
|
|
601
606
|
// Claude: claude-{tier}-{major}-{minor}[-dateYYYYMMDD] → Tier Major.Minor
|
|
@@ -835,19 +840,7 @@ function ModelSelector({
|
|
|
835
840
|
collisionPadding={8}
|
|
836
841
|
data-agent-native-composer-popover="true"
|
|
837
842
|
className="z-[260] box-border w-72 overflow-y-auto rounded-lg border-border p-0 py-1 shadow-lg"
|
|
838
|
-
style={
|
|
839
|
-
providerGroups.length > 0
|
|
840
|
-
? {
|
|
841
|
-
fontSize: 13,
|
|
842
|
-
height:
|
|
843
|
-
"min(500px, var(--radix-popover-content-available-height, 500px))",
|
|
844
|
-
}
|
|
845
|
-
: {
|
|
846
|
-
fontSize: 13,
|
|
847
|
-
maxHeight:
|
|
848
|
-
"min(500px, var(--radix-popover-content-available-height, 500px))",
|
|
849
|
-
}
|
|
850
|
-
}
|
|
843
|
+
style={MODEL_SELECTOR_POPOVER_STYLE}
|
|
851
844
|
>
|
|
852
845
|
{showBuilderCta && (
|
|
853
846
|
<>
|