@agent-native/core 0.95.1 → 0.96.0
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 +2 -2
- package/corpus/core/CHANGELOG.md +25 -0
- package/corpus/core/package.json +3 -1
- package/corpus/core/src/a2a/client.ts +11 -1
- package/corpus/core/src/agent/production-agent.ts +87 -27
- package/corpus/core/src/agent/thread-data-builder.ts +7 -5
- package/corpus/core/src/chat-threads/store.ts +20 -1
- package/corpus/core/src/cli/code-agent-executor.ts +1 -0
- package/corpus/core/src/cli/code-agent-runs.ts +14 -0
- package/corpus/core/src/client/AgentPanel.tsx +32 -25
- package/corpus/core/src/client/AssistantChat.tsx +36 -20
- package/corpus/core/src/client/MultiTabAssistantChat.tsx +141 -90
- package/corpus/core/src/client/chat/ChatHistoryList.tsx +404 -0
- package/corpus/core/src/client/chat/index.ts +6 -0
- package/corpus/core/src/client/chat/tool-call-display.tsx +37 -3
- package/corpus/core/src/client/code-agent-chat-adapter.ts +72 -4
- package/corpus/core/src/client/composer/RealtimeVoiceMode.tsx +52 -11
- package/corpus/core/src/client/composer/TiptapComposer.tsx +157 -20
- package/corpus/core/src/client/composer/VoiceButton.tsx +28 -0
- package/corpus/core/src/client/composer/useRealtimeVoiceMode.tsx +5 -0
- package/corpus/core/src/client/conversation/code-agent-transcript.ts +4 -5
- package/corpus/core/src/client/guided-questions.tsx +2 -1
- package/corpus/core/src/client/index.ts +11 -0
- package/corpus/core/src/client/use-chat-threads.ts +10 -1
- package/corpus/core/src/client/voice-provider-status.ts +44 -0
- package/corpus/core/src/code-agents/transcript-normalizer.ts +76 -0
- package/corpus/core/src/deploy/build.ts +12 -11
- package/corpus/core/src/integrations/a2a-continuation-processor.ts +35 -5
- package/corpus/core/src/integrations/adapters/slack.ts +74 -21
- package/corpus/core/src/integrations/webhook-handler.ts +14 -0
- package/corpus/core/src/localization/default-messages.ts +6 -0
- package/corpus/core/src/observability/hosted-model-experiment.ts +118 -0
- package/corpus/core/src/observability/routes.ts +17 -0
- package/corpus/core/src/observability/store.ts +4 -1
- package/corpus/core/src/observability/traces.ts +41 -2
- package/corpus/core/src/scripts/agent-engines/list-agent-engines.ts +19 -1
- package/corpus/core/src/scripts/call-agent.ts +53 -3
- package/corpus/core/src/scripts/chat/search-chats.ts +11 -8
- package/corpus/core/src/secrets/register-framework-secrets.ts +1 -1
- package/corpus/core/src/server/agent-chat-plugin.ts +41 -6
- package/corpus/core/src/server/core-routes-plugin.ts +15 -0
- package/corpus/core/src/server/realtime-voice.ts +71 -24
- package/corpus/core/src/server/voice-providers-status.ts +4 -3
- package/corpus/core/src/shared/cache-control.ts +2 -8
- package/corpus/core/src/styles/agent-native.css +1 -0
- package/corpus/core/src/styles/chat-history-list.css +313 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/observability/SKILL.md +20 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +8 -4
- package/corpus/core/src/vite/client.ts +1 -0
- package/corpus/templates/analytics/AGENTS.md +7 -0
- package/corpus/templates/analytics/actions/bigquery.ts +26 -2
- package/corpus/templates/analytics/actions/data-source-status.ts +18 -0
- package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +5 -4
- package/corpus/templates/analytics/app/global.css +10 -0
- package/corpus/templates/analytics/app/pages/Ask.tsx +25 -2
- package/corpus/templates/analytics/changelog/2026-07-10-analytics-answers-simple-time-bounded-metrics-without-unnece.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-10-analytics-chat-reliably-uses-connected-data-sources-across-s.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-10-chat-threads-now-stay-clear-of-top-actions-and-fade-smoothly.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-10-context-chips-can-now-be-selected-and-removed-one-at-a-time-.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-10-the-ask-composer-no-longer-carries-dashboard-or-panel-contex.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-10-the-ask-section-stays-highlighted-while-its-chat-history-is-.md +6 -0
- package/corpus/templates/analytics/server/lib/bigquery.ts +90 -14
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +82 -7
- package/dist/a2a/client.d.ts +7 -0
- package/dist/a2a/client.d.ts.map +1 -1
- package/dist/a2a/client.js +2 -1
- package/dist/a2a/client.js.map +1 -1
- package/dist/agent/production-agent.d.ts +6 -0
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +63 -26
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/thread-data-builder.d.ts +1 -0
- package/dist/agent/thread-data-builder.d.ts.map +1 -1
- package/dist/agent/thread-data-builder.js +6 -5
- package/dist/agent/thread-data-builder.js.map +1 -1
- package/dist/chat-threads/store.d.ts +10 -0
- package/dist/chat-threads/store.d.ts.map +1 -1
- package/dist/chat-threads/store.js +6 -0
- package/dist/chat-threads/store.js.map +1 -1
- package/dist/cli/code-agent-executor.d.ts.map +1 -1
- package/dist/cli/code-agent-executor.js +1 -0
- package/dist/cli/code-agent-executor.js.map +1 -1
- package/dist/cli/code-agent-runs.d.ts +12 -0
- package/dist/cli/code-agent-runs.d.ts.map +1 -1
- package/dist/cli/code-agent-runs.js +1 -0
- package/dist/cli/code-agent-runs.js.map +1 -1
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +3 -3
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/AssistantChat.d.ts +11 -0
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +7 -4
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +83 -10
- package/dist/client/MultiTabAssistantChat.js.map +1 -1
- package/dist/client/chat/ChatHistoryList.d.ts +88 -0
- package/dist/client/chat/ChatHistoryList.d.ts.map +1 -0
- package/dist/client/chat/ChatHistoryList.js +83 -0
- package/dist/client/chat/ChatHistoryList.js.map +1 -0
- package/dist/client/chat/index.d.ts +1 -0
- package/dist/client/chat/index.d.ts.map +1 -1
- package/dist/client/chat/index.js +1 -0
- package/dist/client/chat/index.js.map +1 -1
- package/dist/client/chat/tool-call-display.d.ts +13 -1
- package/dist/client/chat/tool-call-display.d.ts.map +1 -1
- package/dist/client/chat/tool-call-display.js +10 -2
- package/dist/client/chat/tool-call-display.js.map +1 -1
- package/dist/client/code-agent-chat-adapter.d.ts +17 -1
- package/dist/client/code-agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/code-agent-chat-adapter.js +47 -3
- package/dist/client/code-agent-chat-adapter.js.map +1 -1
- package/dist/client/composer/RealtimeVoiceMode.d.ts +11 -1
- package/dist/client/composer/RealtimeVoiceMode.d.ts.map +1 -1
- package/dist/client/composer/RealtimeVoiceMode.js +5 -3
- package/dist/client/composer/RealtimeVoiceMode.js.map +1 -1
- package/dist/client/composer/TiptapComposer.d.ts +25 -2
- package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/client/composer/TiptapComposer.js +96 -5
- package/dist/client/composer/TiptapComposer.js.map +1 -1
- package/dist/client/composer/VoiceButton.d.ts.map +1 -1
- package/dist/client/composer/VoiceButton.js +21 -1
- package/dist/client/composer/VoiceButton.js.map +1 -1
- package/dist/client/composer/useRealtimeVoiceMode.d.ts.map +1 -1
- package/dist/client/composer/useRealtimeVoiceMode.js +5 -0
- package/dist/client/composer/useRealtimeVoiceMode.js.map +1 -1
- package/dist/client/conversation/code-agent-transcript.d.ts +2 -0
- package/dist/client/conversation/code-agent-transcript.d.ts.map +1 -1
- package/dist/client/conversation/code-agent-transcript.js +3 -5
- package/dist/client/conversation/code-agent-transcript.js.map +1 -1
- package/dist/client/guided-questions.d.ts.map +1 -1
- package/dist/client/guided-questions.js +2 -1
- package/dist/client/guided-questions.js.map +1 -1
- package/dist/client/index.d.ts +3 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +3 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/use-chat-threads.d.ts.map +1 -1
- package/dist/client/use-chat-threads.js +9 -1
- package/dist/client/use-chat-threads.js.map +1 -1
- package/dist/client/voice-provider-status.d.ts +10 -0
- package/dist/client/voice-provider-status.d.ts.map +1 -0
- package/dist/client/voice-provider-status.js +32 -0
- package/dist/client/voice-provider-status.js.map +1 -0
- package/dist/code-agents/transcript-normalizer.d.ts +29 -0
- package/dist/code-agents/transcript-normalizer.d.ts.map +1 -1
- package/dist/code-agents/transcript-normalizer.js +55 -0
- package/dist/code-agents/transcript-normalizer.js.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/deploy/build.d.ts.map +1 -1
- package/dist/deploy/build.js +13 -11
- package/dist/deploy/build.js.map +1 -1
- package/dist/integrations/a2a-continuation-processor.d.ts.map +1 -1
- package/dist/integrations/a2a-continuation-processor.js +25 -5
- package/dist/integrations/a2a-continuation-processor.js.map +1 -1
- package/dist/integrations/adapters/slack.d.ts.map +1 -1
- package/dist/integrations/adapters/slack.js +55 -21
- package/dist/integrations/adapters/slack.js.map +1 -1
- package/dist/integrations/webhook-handler.d.ts.map +1 -1
- package/dist/integrations/webhook-handler.js +11 -0
- package/dist/integrations/webhook-handler.js.map +1 -1
- package/dist/localization/default-messages.d.ts +5 -0
- package/dist/localization/default-messages.d.ts.map +1 -1
- package/dist/localization/default-messages.js +5 -0
- package/dist/localization/default-messages.js.map +1 -1
- package/dist/notifications/routes.d.ts +2 -2
- package/dist/observability/hosted-model-experiment.d.ts +39 -0
- package/dist/observability/hosted-model-experiment.d.ts.map +1 -0
- package/dist/observability/hosted-model-experiment.js +90 -0
- package/dist/observability/hosted-model-experiment.js.map +1 -0
- package/dist/observability/routes.d.ts +1 -1
- package/dist/observability/routes.d.ts.map +1 -1
- package/dist/observability/routes.js +16 -0
- package/dist/observability/routes.js.map +1 -1
- package/dist/observability/store.d.ts.map +1 -1
- package/dist/observability/store.js +4 -1
- package/dist/observability/store.js.map +1 -1
- package/dist/observability/traces.d.ts +6 -0
- package/dist/observability/traces.d.ts.map +1 -1
- package/dist/observability/traces.js +28 -2
- package/dist/observability/traces.js.map +1 -1
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/scripts/agent-engines/list-agent-engines.d.ts.map +1 -1
- package/dist/scripts/agent-engines/list-agent-engines.js +19 -1
- package/dist/scripts/agent-engines/list-agent-engines.js.map +1 -1
- package/dist/scripts/call-agent.d.ts.map +1 -1
- package/dist/scripts/call-agent.js +43 -3
- package/dist/scripts/call-agent.js.map +1 -1
- package/dist/scripts/chat/search-chats.d.ts +1 -1
- package/dist/scripts/chat/search-chats.d.ts.map +1 -1
- package/dist/scripts/chat/search-chats.js +11 -8
- package/dist/scripts/chat/search-chats.js.map +1 -1
- package/dist/secrets/register-framework-secrets.js +1 -1
- package/dist/secrets/register-framework-secrets.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts +11 -0
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +27 -6
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/core-routes-plugin.d.ts +3 -0
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +13 -0
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/realtime-voice.d.ts.map +1 -1
- package/dist/server/realtime-voice.js +55 -21
- package/dist/server/realtime-voice.js.map +1 -1
- package/dist/server/voice-providers-status.d.ts.map +1 -1
- package/dist/server/voice-providers-status.js +2 -3
- package/dist/server/voice-providers-status.js.map +1 -1
- package/dist/shared/cache-control.d.ts +4 -6
- package/dist/shared/cache-control.d.ts.map +1 -1
- package/dist/shared/cache-control.js +2 -7
- package/dist/shared/cache-control.js.map +1 -1
- package/dist/styles/agent-native.css +1 -0
- package/dist/styles/chat-history-list.css +313 -0
- package/dist/templates/workspace-core/.agents/skills/observability/SKILL.md +20 -0
- package/dist/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +8 -4
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +1 -0
- package/dist/vite/client.js.map +1 -1
- package/package.json +3 -1
- package/src/templates/workspace-core/.agents/skills/observability/SKILL.md +20 -0
- package/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +8 -4
|
@@ -2,7 +2,6 @@ import {
|
|
|
2
2
|
IconX,
|
|
3
3
|
IconPlus,
|
|
4
4
|
IconHistory,
|
|
5
|
-
IconSearch,
|
|
6
5
|
IconLink,
|
|
7
6
|
IconLinkOff,
|
|
8
7
|
IconCheck,
|
|
@@ -47,6 +46,11 @@ import {
|
|
|
47
46
|
buildChatModelGroups,
|
|
48
47
|
type EngineModelGroup,
|
|
49
48
|
} from "./chat-model-groups.js";
|
|
49
|
+
import {
|
|
50
|
+
ChatHistoryList,
|
|
51
|
+
type ChatHistoryItem,
|
|
52
|
+
type ChatHistorySection,
|
|
53
|
+
} from "./chat/ChatHistoryList.js";
|
|
50
54
|
import {
|
|
51
55
|
Popover,
|
|
52
56
|
PopoverAnchor,
|
|
@@ -444,6 +448,8 @@ function HistoryPopover({
|
|
|
444
448
|
onClose,
|
|
445
449
|
onLoadMore,
|
|
446
450
|
onSearch,
|
|
451
|
+
onTogglePin,
|
|
452
|
+
onRename,
|
|
447
453
|
}: {
|
|
448
454
|
threads: ChatThreadSummary[];
|
|
449
455
|
openTabIds: Set<string>;
|
|
@@ -456,6 +462,11 @@ function HistoryPopover({
|
|
|
456
462
|
onClose: () => void;
|
|
457
463
|
onLoadMore?: () => void;
|
|
458
464
|
onSearch?: (query: string) => Promise<ChatThreadSummary[]>;
|
|
465
|
+
/** Presence enables the pin/unpin row action. Receives the thread's
|
|
466
|
+
* current pinned state so the caller can flip it. */
|
|
467
|
+
onTogglePin?: (id: string, pinned: boolean) => void;
|
|
468
|
+
/** Presence enables the inline rename row action. */
|
|
469
|
+
onRename?: (id: string, nextTitle: string) => void;
|
|
459
470
|
}) {
|
|
460
471
|
const [search, setSearch] = useState("");
|
|
461
472
|
const [searchResults, setSearchResults] = useState<
|
|
@@ -512,18 +523,26 @@ function HistoryPopover({
|
|
|
512
523
|
)
|
|
513
524
|
: visibleThreads;
|
|
514
525
|
|
|
515
|
-
//
|
|
516
|
-
//
|
|
526
|
+
// Pinned threads always float to the top of `threads` already (see
|
|
527
|
+
// `sortThreadSummaries` in use-chat-threads.ts and the matching server
|
|
528
|
+
// ORDER BY), but pulling them into their own labeled section — instead of
|
|
529
|
+
// just relying on sort order within "All chats" — makes the pin affordance
|
|
530
|
+
// visible at a glance, matching common chat-history UX.
|
|
531
|
+
const pinnedThreads = filtered.filter((t) => t.pinnedAt != null);
|
|
532
|
+
const unpinnedThreads = filtered.filter((t) => t.pinnedAt == null);
|
|
533
|
+
|
|
534
|
+
// When scope is set we split (unpinned) history into two sections so the
|
|
535
|
+
// user can see "this deck's chats" first without losing access to general /
|
|
517
536
|
// other-deck chats. Section labels intentionally use the current
|
|
518
537
|
// resource type (deck/design/dashboard) instead of a generic phrase.
|
|
519
538
|
const sectionedThreads = currentScope
|
|
520
539
|
? {
|
|
521
|
-
scoped:
|
|
540
|
+
scoped: unpinnedThreads.filter(
|
|
522
541
|
(t) =>
|
|
523
542
|
t.scope?.type === currentScope.type &&
|
|
524
543
|
t.scope?.id === currentScope.id,
|
|
525
544
|
),
|
|
526
|
-
other:
|
|
545
|
+
other: unpinnedThreads.filter(
|
|
527
546
|
(t) =>
|
|
528
547
|
!t.scope ||
|
|
529
548
|
t.scope.type !== currentScope.type ||
|
|
@@ -532,6 +551,53 @@ function HistoryPopover({
|
|
|
532
551
|
}
|
|
533
552
|
: null;
|
|
534
553
|
|
|
554
|
+
const toHistoryItem = (thread: ChatThreadSummary): ChatHistoryItem => {
|
|
555
|
+
const isActive = thread.id === activeThreadId;
|
|
556
|
+
const title = thread.title || thread.preview || "Chat";
|
|
557
|
+
return {
|
|
558
|
+
id: thread.id,
|
|
559
|
+
title,
|
|
560
|
+
titleText: title,
|
|
561
|
+
subtitle:
|
|
562
|
+
thread.preview && thread.title !== thread.preview
|
|
563
|
+
? thread.preview
|
|
564
|
+
: undefined,
|
|
565
|
+
detail: thread.scope?.label || undefined,
|
|
566
|
+
timestamp: isActive
|
|
567
|
+
? "Active"
|
|
568
|
+
: openTabIds.has(thread.id)
|
|
569
|
+
? "Open"
|
|
570
|
+
: formatThreadTime(thread.updatedAt),
|
|
571
|
+
pinned: thread.pinnedAt != null,
|
|
572
|
+
};
|
|
573
|
+
};
|
|
574
|
+
|
|
575
|
+
const historySections: ChatHistorySection[] = [
|
|
576
|
+
...(pinnedThreads.length > 0
|
|
577
|
+
? [
|
|
578
|
+
{
|
|
579
|
+
id: "pinned",
|
|
580
|
+
label: "Pinned",
|
|
581
|
+
items: pinnedThreads.map(toHistoryItem),
|
|
582
|
+
},
|
|
583
|
+
]
|
|
584
|
+
: []),
|
|
585
|
+
...(sectionedThreads
|
|
586
|
+
? [
|
|
587
|
+
{
|
|
588
|
+
id: "scoped",
|
|
589
|
+
label: `This ${currentScope!.type}`,
|
|
590
|
+
items: sectionedThreads.scoped.map(toHistoryItem),
|
|
591
|
+
},
|
|
592
|
+
{
|
|
593
|
+
id: "other",
|
|
594
|
+
label: "All chats",
|
|
595
|
+
items: sectionedThreads.other.map(toHistoryItem),
|
|
596
|
+
},
|
|
597
|
+
]
|
|
598
|
+
: [{ id: "all", items: unpinnedThreads.map(toHistoryItem) }]),
|
|
599
|
+
];
|
|
600
|
+
|
|
535
601
|
return (
|
|
536
602
|
<Popover open onOpenChange={(open) => !open && onClose()}>
|
|
537
603
|
<PopoverAnchor asChild>
|
|
@@ -547,90 +613,45 @@ function HistoryPopover({
|
|
|
547
613
|
}}
|
|
548
614
|
className="w-72 rounded-lg p-0"
|
|
549
615
|
>
|
|
550
|
-
<
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
),
|
|
590
|
-
)}
|
|
591
|
-
</>
|
|
592
|
-
)}
|
|
593
|
-
{sectionedThreads.other.length > 0 && (
|
|
594
|
-
<>
|
|
595
|
-
<div className="px-3 pt-2 pb-1 text-[10px] uppercase tracking-wider text-muted-foreground/70">
|
|
596
|
-
All chats
|
|
597
|
-
</div>
|
|
598
|
-
{sectionedThreads.other.map((thread) =>
|
|
599
|
-
renderThreadRow(
|
|
600
|
-
thread,
|
|
601
|
-
activeThreadId,
|
|
602
|
-
openTabIds,
|
|
603
|
-
formatThreadTime,
|
|
604
|
-
onSelect,
|
|
605
|
-
onClose,
|
|
606
|
-
),
|
|
607
|
-
)}
|
|
608
|
-
</>
|
|
609
|
-
)}
|
|
610
|
-
</>
|
|
611
|
-
) : (
|
|
612
|
-
filtered.map((thread) =>
|
|
613
|
-
renderThreadRow(
|
|
614
|
-
thread,
|
|
615
|
-
activeThreadId,
|
|
616
|
-
openTabIds,
|
|
617
|
-
formatThreadTime,
|
|
618
|
-
onSelect,
|
|
619
|
-
onClose,
|
|
620
|
-
),
|
|
621
|
-
)
|
|
622
|
-
)}
|
|
623
|
-
{!search.trim() && hasMoreThreads && (
|
|
624
|
-
<button
|
|
625
|
-
type="button"
|
|
626
|
-
onClick={() => onLoadMore?.()}
|
|
627
|
-
disabled={isLoadingMoreThreads}
|
|
628
|
-
className="mx-1 mt-1 flex w-[calc(100%-0.5rem)] items-center justify-center rounded-md px-3 py-2 text-xs text-muted-foreground hover:bg-accent hover:text-foreground disabled:cursor-default disabled:opacity-60"
|
|
629
|
-
>
|
|
630
|
-
{isLoadingMoreThreads ? "Loading..." : "Load older chats"}
|
|
631
|
-
</button>
|
|
632
|
-
)}
|
|
633
|
-
</div>
|
|
616
|
+
<ChatHistoryList
|
|
617
|
+
sections={historySections}
|
|
618
|
+
activeId={activeThreadId}
|
|
619
|
+
onSelect={(id) => {
|
|
620
|
+
onSelect(id);
|
|
621
|
+
onClose();
|
|
622
|
+
}}
|
|
623
|
+
onTogglePin={
|
|
624
|
+
onTogglePin
|
|
625
|
+
? (id) => {
|
|
626
|
+
const isPinned =
|
|
627
|
+
threads.find((t) => t.id === id)?.pinnedAt != null;
|
|
628
|
+
onTogglePin(id, !isPinned);
|
|
629
|
+
}
|
|
630
|
+
: undefined
|
|
631
|
+
}
|
|
632
|
+
onRename={onRename}
|
|
633
|
+
searchValue={search}
|
|
634
|
+
onSearchChange={setSearch}
|
|
635
|
+
searchPlaceholder="Search chats..."
|
|
636
|
+
searchInputRef={inputRef}
|
|
637
|
+
loading={isSearching}
|
|
638
|
+
loadingLabel="Searching..."
|
|
639
|
+
error={loadError && !search.trim() ? loadError : undefined}
|
|
640
|
+
emptyLabel="No chats yet"
|
|
641
|
+
emptySearchLabel="No matching chats"
|
|
642
|
+
footer={
|
|
643
|
+
!search.trim() && hasMoreThreads ? (
|
|
644
|
+
<button
|
|
645
|
+
type="button"
|
|
646
|
+
onClick={() => onLoadMore?.()}
|
|
647
|
+
disabled={isLoadingMoreThreads}
|
|
648
|
+
className="mx-1 mt-1 flex w-[calc(100%-0.5rem)] items-center justify-center rounded-md px-3 py-2 text-xs text-muted-foreground hover:bg-accent hover:text-foreground disabled:cursor-default disabled:opacity-60"
|
|
649
|
+
>
|
|
650
|
+
{isLoadingMoreThreads ? "Loading..." : "Load older chats"}
|
|
651
|
+
</button>
|
|
652
|
+
) : undefined
|
|
653
|
+
}
|
|
654
|
+
/>
|
|
634
655
|
</PopoverContent>
|
|
635
656
|
</Popover>
|
|
636
657
|
);
|
|
@@ -1074,6 +1095,8 @@ export function MultiTabAssistantChat({
|
|
|
1074
1095
|
isLoadingMoreThreads,
|
|
1075
1096
|
threadsLoadError,
|
|
1076
1097
|
isNewThread,
|
|
1098
|
+
pinThread,
|
|
1099
|
+
renameThread,
|
|
1077
1100
|
} = useChatThreads(apiUrl, storageKey, scope, {
|
|
1078
1101
|
restoreActiveThread,
|
|
1079
1102
|
routeThreadId: threadUrlSyncEnabled ? urlThreadId : undefined,
|
|
@@ -1105,8 +1128,28 @@ export function MultiTabAssistantChat({
|
|
|
1105
1128
|
);
|
|
1106
1129
|
const [runningThreads, setRunningThreads] = useState<Set<string>>(new Set());
|
|
1107
1130
|
const [showHistory, setShowHistory] = useState(false);
|
|
1131
|
+
const [pageOverlayScrolled, setPageOverlayScrolled] = useState(false);
|
|
1108
1132
|
const newThreadIds = useRef<Set<string>>(new Set());
|
|
1109
1133
|
|
|
1134
|
+
useEffect(() => {
|
|
1135
|
+
setPageOverlayScrolled(false);
|
|
1136
|
+
}, [activeThreadId]);
|
|
1137
|
+
|
|
1138
|
+
const handlePageOverlayScroll = useCallback(
|
|
1139
|
+
(event: React.UIEvent<HTMLDivElement>) => {
|
|
1140
|
+
const target = event.target;
|
|
1141
|
+
if (
|
|
1142
|
+
!renderOverlay ||
|
|
1143
|
+
!(target instanceof HTMLElement) ||
|
|
1144
|
+
!target.closest(".agent-chat-scroll")
|
|
1145
|
+
) {
|
|
1146
|
+
return;
|
|
1147
|
+
}
|
|
1148
|
+
setPageOverlayScrolled(target.scrollTop > 1);
|
|
1149
|
+
},
|
|
1150
|
+
[renderOverlay],
|
|
1151
|
+
);
|
|
1152
|
+
|
|
1110
1153
|
// ─── Model state ─────────────────────────────────────────────────────────
|
|
1111
1154
|
const [availableModels, setAvailableModels] = useState<EngineModelGroup[]>(
|
|
1112
1155
|
[],
|
|
@@ -2653,7 +2696,13 @@ export function MultiTabAssistantChat({
|
|
|
2653
2696
|
: null}
|
|
2654
2697
|
|
|
2655
2698
|
{/* Chat content with optional overlay */}
|
|
2656
|
-
<div
|
|
2699
|
+
<div
|
|
2700
|
+
className="relative flex-1 flex flex-col min-h-0"
|
|
2701
|
+
data-agent-page-chat-scrolled={
|
|
2702
|
+
renderOverlay && pageOverlayScrolled ? "" : undefined
|
|
2703
|
+
}
|
|
2704
|
+
onScrollCapture={renderOverlay ? handlePageOverlayScroll : undefined}
|
|
2705
|
+
>
|
|
2657
2706
|
{renderOverlay ? renderOverlay(headerProps) : null}
|
|
2658
2707
|
|
|
2659
2708
|
{/* History popover — rendered inside relative container so positioning works */}
|
|
@@ -2670,6 +2719,8 @@ export function MultiTabAssistantChat({
|
|
|
2670
2719
|
onClose={() => setShowHistory(false)}
|
|
2671
2720
|
onLoadMore={loadMoreThreads}
|
|
2672
2721
|
onSearch={searchThreads}
|
|
2722
|
+
onTogglePin={pinThread}
|
|
2723
|
+
onRename={renameThread}
|
|
2673
2724
|
/>
|
|
2674
2725
|
)}
|
|
2675
2726
|
|