@agent-native/toolkit 0.13.7 → 0.13.9
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/chat-history/ChatHistoryList.d.ts.map +1 -1
- package/dist/chat-history/ChatHistoryList.js +12 -5
- package/dist/chat-history/ChatHistoryList.js.map +1 -1
- package/dist/chat-history.css +7 -1
- package/dist/collab-ui/PresenceBar.d.ts +4 -1
- package/dist/collab-ui/PresenceBar.d.ts.map +1 -1
- package/dist/collab-ui/PresenceBar.js +19 -12
- package/dist/collab-ui/PresenceBar.js.map +1 -1
- package/dist/collab-ui/RecentEditHighlights.d.ts +3 -1
- package/dist/collab-ui/RecentEditHighlights.d.ts.map +1 -1
- package/dist/collab-ui/RecentEditHighlights.js +17 -9
- package/dist/collab-ui/RecentEditHighlights.js.map +1 -1
- package/dist/composer/PromptComposer.d.ts +3 -1
- package/dist/composer/PromptComposer.d.ts.map +1 -1
- package/dist/composer/PromptComposer.js +3 -3
- package/dist/composer/PromptComposer.js.map +1 -1
- package/dist/composer/TiptapComposer.d.ts +8 -4
- package/dist/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/composer/TiptapComposer.js +35 -19
- package/dist/composer/TiptapComposer.js.map +1 -1
- package/dist/composer/TiptapComposer.spec.js +2 -1
- package/dist/composer/TiptapComposer.spec.js.map +1 -1
- package/dist/composer/runtime-adapters.d.ts +4 -0
- package/dist/composer/runtime-adapters.d.ts.map +1 -1
- package/dist/composer/runtime-adapters.js +2 -2
- package/dist/composer/runtime-adapters.js.map +1 -1
- package/dist/editor.css +2 -0
- package/dist/ui/dropdown-menu.d.ts.map +1 -1
- package/dist/ui/dropdown-menu.js +8 -2
- package/dist/ui/dropdown-menu.js.map +1 -1
- package/package.json +1 -1
- package/src/chat-history/ChatHistoryList.tsx +36 -24
- package/src/chat-history.css +7 -1
- package/src/collab-ui/PresenceBar.tsx +44 -17
- package/src/collab-ui/RecentEditHighlights.tsx +22 -8
- package/src/composer/PromptComposer.tsx +6 -2
- package/src/composer/TiptapComposer.spec.ts +2 -1
- package/src/composer/TiptapComposer.tsx +61 -28
- package/src/composer/runtime-adapters.tsx +6 -2
- package/src/editor.css +2 -0
- package/src/ui/dropdown-menu.tsx +4 -0
|
@@ -580,7 +580,7 @@ export interface TiptapComposerProps {
|
|
|
580
580
|
references: Reference[],
|
|
581
581
|
attachments?: ReadonlyArray<unknown>,
|
|
582
582
|
options?: TiptapComposerSubmitOptions,
|
|
583
|
-
) => void
|
|
583
|
+
) => void | Promise<void>;
|
|
584
584
|
/** Return false to stop a submit before it enters the chat runtime. */
|
|
585
585
|
onBeforeSubmit?: () => boolean | Promise<boolean>;
|
|
586
586
|
/**
|
|
@@ -631,20 +631,24 @@ export interface TiptapComposerProps {
|
|
|
631
631
|
voiceEnabled?: boolean;
|
|
632
632
|
/** Selected model override for this conversation */
|
|
633
633
|
selectedModel?: string;
|
|
634
|
-
/** Selected
|
|
634
|
+
/** Selected effort override for this conversation */
|
|
635
635
|
selectedEffort?: ReasoningEffort;
|
|
636
|
+
/** Show the legacy provider-level Auto model option (default: true). */
|
|
637
|
+
showAutoModelOption?: boolean;
|
|
636
638
|
/** Available models grouped by provider */
|
|
637
639
|
availableModels?: Array<{
|
|
638
640
|
engine: string;
|
|
639
641
|
label: string;
|
|
640
642
|
models: string[];
|
|
641
643
|
configured: boolean;
|
|
644
|
+
statusLabel?: string;
|
|
645
|
+
isSubscription?: boolean;
|
|
642
646
|
}>;
|
|
643
647
|
/** Whether the model list is still being resolved. */
|
|
644
648
|
modelListLoading?: boolean;
|
|
645
649
|
/** Callback when user picks a model */
|
|
646
650
|
onModelChange?: (model: string, engine: string) => void;
|
|
647
|
-
/** Callback when user picks
|
|
651
|
+
/** Callback when user picks an effort */
|
|
648
652
|
onEffortChange?: (effort: ReasoningEffort) => void;
|
|
649
653
|
/**
|
|
650
654
|
* Disable Builder/provider status polling for hosts that supply provider
|
|
@@ -844,7 +848,7 @@ function ModeSelector({
|
|
|
844
848
|
|
|
845
849
|
const FRIENDLY_MODEL_NAMES: Record<string, string> = {
|
|
846
850
|
auto: "Default model",
|
|
847
|
-
"codex-cli": "
|
|
851
|
+
"codex-cli": "Codex",
|
|
848
852
|
"claude-fable-5": "Fable 5",
|
|
849
853
|
"kimi-k2-5": "Kimi K2.5",
|
|
850
854
|
"deepseek-v3-1": "DeepSeek v3.1",
|
|
@@ -959,7 +963,7 @@ function latestModelsOnly(models: string[]): string[] {
|
|
|
959
963
|
return true;
|
|
960
964
|
}
|
|
961
965
|
// GPT: family = gpt-{major} (e.g. gpt-5.6-sol and gpt-5.6-luna are different)
|
|
962
|
-
// OpenAI
|
|
966
|
+
// OpenAI effort: each is its own family
|
|
963
967
|
// Gemini: family = gemini-{major} + variant
|
|
964
968
|
const gemini = m.match(/^gemini-(\d+(?:\.\d+)?)-(.+?)(?:-preview)?$/);
|
|
965
969
|
if (gemini) {
|
|
@@ -1046,6 +1050,7 @@ function ModelSelector({
|
|
|
1046
1050
|
model,
|
|
1047
1051
|
effort,
|
|
1048
1052
|
engines,
|
|
1053
|
+
showAutoModelOption = true,
|
|
1049
1054
|
modelListLoading = false,
|
|
1050
1055
|
onChange,
|
|
1051
1056
|
onEffortChange,
|
|
@@ -1061,7 +1066,10 @@ function ModelSelector({
|
|
|
1061
1066
|
label: string;
|
|
1062
1067
|
models: string[];
|
|
1063
1068
|
configured: boolean;
|
|
1069
|
+
statusLabel?: string;
|
|
1070
|
+
isSubscription?: boolean;
|
|
1064
1071
|
}>;
|
|
1072
|
+
showAutoModelOption?: boolean;
|
|
1065
1073
|
modelListLoading?: boolean;
|
|
1066
1074
|
onChange: (model: string, engine: string) => void;
|
|
1067
1075
|
onEffortChange?: (effort: ReasoningEffort) => void;
|
|
@@ -1075,7 +1083,9 @@ function ModelSelector({
|
|
|
1075
1083
|
const reasoning = adapters.models?.reasoning;
|
|
1076
1084
|
const defaultEffort = reasoning?.defaultEffort ?? DEFAULT_REASONING_EFFORT;
|
|
1077
1085
|
const [open, setOpen] = useState(false);
|
|
1078
|
-
const autoModelGroup =
|
|
1086
|
+
const autoModelGroup = showAutoModelOption
|
|
1087
|
+
? engines.find((group) => group.models.includes("auto"))
|
|
1088
|
+
: undefined;
|
|
1079
1089
|
const providerGroups = useMemo(
|
|
1080
1090
|
() =>
|
|
1081
1091
|
engines
|
|
@@ -1123,12 +1133,12 @@ function ModelSelector({
|
|
|
1123
1133
|
});
|
|
1124
1134
|
}, []);
|
|
1125
1135
|
|
|
1126
|
-
// The
|
|
1136
|
+
// The effort list is collapsed by default — it's a secondary
|
|
1127
1137
|
// control most users don't touch, so it stays tucked behind a header that
|
|
1128
1138
|
// reveals the current effort at a glance. Reset to collapsed on each open.
|
|
1129
|
-
const [
|
|
1139
|
+
const [effortExpanded, setEffortExpanded] = useState(false);
|
|
1130
1140
|
useEffect(() => {
|
|
1131
|
-
if (open)
|
|
1141
|
+
if (open) setEffortExpanded(false);
|
|
1132
1142
|
}, [open]);
|
|
1133
1143
|
|
|
1134
1144
|
// The optional image-model section follows the same collapsed-by-default
|
|
@@ -1155,12 +1165,16 @@ function ModelSelector({
|
|
|
1155
1165
|
const hasConfiguredBuilderModels = providerGroups.some(
|
|
1156
1166
|
(group) => group.engine === "builder" && group.configured,
|
|
1157
1167
|
);
|
|
1168
|
+
const hasConnectedSubscription = providerGroups.some(
|
|
1169
|
+
(group) => group.configured && group.isSubscription,
|
|
1170
|
+
);
|
|
1158
1171
|
const showBuilderCta =
|
|
1159
1172
|
(builderFlow.hasFetchedStatus ||
|
|
1160
1173
|
(!providerConnectStatusEnabled && !!onConnectProvider)) &&
|
|
1161
1174
|
!builderFlow.configured &&
|
|
1162
1175
|
!builderFlow.envManaged &&
|
|
1163
|
-
!hasConfiguredBuilderModels
|
|
1176
|
+
!hasConfiguredBuilderModels &&
|
|
1177
|
+
!hasConnectedSubscription;
|
|
1164
1178
|
const onlyConnectPathAvailable = shouldShowOnlyConnectPath(
|
|
1165
1179
|
showBuilderCta,
|
|
1166
1180
|
providerGroups,
|
|
@@ -1188,7 +1202,7 @@ function ModelSelector({
|
|
|
1188
1202
|
data-agent-composer-slot="model-button"
|
|
1189
1203
|
aria-label={`Model: ${friendlyModelName(model)}${
|
|
1190
1204
|
effortOptions.length > 0
|
|
1191
|
-
? `.
|
|
1205
|
+
? `. Effort: ${effortLabel(selectedEffort)}`
|
|
1192
1206
|
: ""
|
|
1193
1207
|
}`}
|
|
1194
1208
|
className="agent-composer-model-button flex min-w-0 max-w-[10.5rem] shrink items-center gap-1 rounded-md px-2 py-1 text-[12px] font-medium text-muted-foreground hover:bg-accent/50 hover:text-foreground"
|
|
@@ -1352,6 +1366,17 @@ function ModelSelector({
|
|
|
1352
1366
|
const groupKey = `${group.engine}:${group.label}`;
|
|
1353
1367
|
const isExpanded = expandedGroups.has(groupKey);
|
|
1354
1368
|
const ChevronIcon = isExpanded ? IconChevronDown : IconChevronRight;
|
|
1369
|
+
const isLocalRuntime =
|
|
1370
|
+
group.engine === "codex-cli" || group.engine === "claude-cli";
|
|
1371
|
+
const canConnectLocalRuntime =
|
|
1372
|
+
isLocalRuntime && Boolean(onConnectLocalRuntime);
|
|
1373
|
+
const statusLabel =
|
|
1374
|
+
group.statusLabel ??
|
|
1375
|
+
(!group.configured
|
|
1376
|
+
? canConnectLocalRuntime
|
|
1377
|
+
? "sign in"
|
|
1378
|
+
: "needs API key"
|
|
1379
|
+
: undefined);
|
|
1355
1380
|
return (
|
|
1356
1381
|
<div key={groupKey}>
|
|
1357
1382
|
<div className="flex items-center hover:bg-accent/30">
|
|
@@ -1371,21 +1396,24 @@ function ModelSelector({
|
|
|
1371
1396
|
</span>
|
|
1372
1397
|
)}
|
|
1373
1398
|
</button>
|
|
1374
|
-
{!group.configured && (
|
|
1399
|
+
{!group.configured && statusLabel && (
|
|
1375
1400
|
<button
|
|
1376
1401
|
type="button"
|
|
1377
|
-
className="text-[10px] text-muted-foreground/60 hover:text-foreground cursor-pointer pe-3 py-1.5"
|
|
1402
|
+
className="ms-auto max-w-[9rem] shrink-0 text-end text-[10px] text-muted-foreground/60 hover:text-foreground cursor-pointer pe-3 py-1.5"
|
|
1378
1403
|
onClick={() =>
|
|
1379
|
-
|
|
1404
|
+
canConnectLocalRuntime
|
|
1380
1405
|
? connectLocalRuntime(group.engine)
|
|
1381
1406
|
: openLlmSettings()
|
|
1382
1407
|
}
|
|
1383
1408
|
>
|
|
1384
|
-
{
|
|
1385
|
-
? "sign in"
|
|
1386
|
-
: "needs API key"}
|
|
1409
|
+
{statusLabel}
|
|
1387
1410
|
</button>
|
|
1388
1411
|
)}
|
|
1412
|
+
{group.configured && statusLabel && (
|
|
1413
|
+
<span className="ms-auto max-w-[9rem] shrink-0 pe-3 text-end text-[10px] text-muted-foreground/70">
|
|
1414
|
+
{statusLabel}
|
|
1415
|
+
</span>
|
|
1416
|
+
)}
|
|
1389
1417
|
</div>
|
|
1390
1418
|
{isExpanded &&
|
|
1391
1419
|
models.map((m) => (
|
|
@@ -1394,10 +1422,7 @@ function ModelSelector({
|
|
|
1394
1422
|
type="button"
|
|
1395
1423
|
onClick={() => {
|
|
1396
1424
|
if (!group.configured) {
|
|
1397
|
-
if (
|
|
1398
|
-
group.engine === "codex-cli" &&
|
|
1399
|
-
onConnectLocalRuntime
|
|
1400
|
-
) {
|
|
1425
|
+
if (canConnectLocalRuntime) {
|
|
1401
1426
|
connectLocalRuntime(group.engine);
|
|
1402
1427
|
} else {
|
|
1403
1428
|
openLlmSettings();
|
|
@@ -1441,26 +1466,26 @@ function ModelSelector({
|
|
|
1441
1466
|
<div className="flex items-center hover:bg-accent/30">
|
|
1442
1467
|
<button
|
|
1443
1468
|
type="button"
|
|
1444
|
-
aria-expanded={
|
|
1445
|
-
onClick={() =>
|
|
1469
|
+
aria-expanded={effortExpanded}
|
|
1470
|
+
onClick={() => setEffortExpanded((prev) => !prev)}
|
|
1446
1471
|
className="flex flex-1 min-w-0 items-center gap-1.5 px-2 py-1.5 cursor-pointer text-start"
|
|
1447
1472
|
>
|
|
1448
|
-
{
|
|
1473
|
+
{effortExpanded ? (
|
|
1449
1474
|
<IconChevronDown className="h-3 w-3 shrink-0 text-muted-foreground" />
|
|
1450
1475
|
) : (
|
|
1451
1476
|
<IconChevronRight className="h-3 w-3 shrink-0 text-muted-foreground rtl:-scale-x-100" />
|
|
1452
1477
|
)}
|
|
1453
1478
|
<span className="text-[11px] font-medium text-muted-foreground uppercase tracking-wide shrink-0">
|
|
1454
|
-
|
|
1479
|
+
Effort
|
|
1455
1480
|
</span>
|
|
1456
|
-
{!
|
|
1481
|
+
{!effortExpanded && (
|
|
1457
1482
|
<span className="text-[11px] text-muted-foreground/80 truncate">
|
|
1458
1483
|
{effortLabel(selectedEffort)}
|
|
1459
1484
|
</span>
|
|
1460
1485
|
)}
|
|
1461
1486
|
</button>
|
|
1462
1487
|
</div>
|
|
1463
|
-
{
|
|
1488
|
+
{effortExpanded &&
|
|
1464
1489
|
effortOptions.map((option) => (
|
|
1465
1490
|
<button
|
|
1466
1491
|
key={option}
|
|
@@ -1540,6 +1565,7 @@ export function TiptapComposer({
|
|
|
1540
1565
|
voiceEnabled = DEFAULT_VOICE_DICTATION_ENABLED,
|
|
1541
1566
|
selectedModel,
|
|
1542
1567
|
selectedEffort,
|
|
1568
|
+
showAutoModelOption = true,
|
|
1543
1569
|
availableModels,
|
|
1544
1570
|
modelListLoading,
|
|
1545
1571
|
onModelChange,
|
|
@@ -2625,7 +2651,13 @@ export function TiptapComposer({
|
|
|
2625
2651
|
}
|
|
2626
2652
|
|
|
2627
2653
|
if (onSubmit) {
|
|
2628
|
-
|
|
2654
|
+
try {
|
|
2655
|
+
await onSubmit(text, references, attachments, { intent });
|
|
2656
|
+
} catch {
|
|
2657
|
+
// Hosts own their submit errors. Keep the draft and attachments
|
|
2658
|
+
// available for recovery when a host rejects the submission.
|
|
2659
|
+
return;
|
|
2660
|
+
}
|
|
2629
2661
|
// Clear any pending attachments now that the host has them.
|
|
2630
2662
|
void composerRuntime.clearAttachments().catch(() => {});
|
|
2631
2663
|
if (!clearOnSubmit) {
|
|
@@ -2985,6 +3017,7 @@ export function TiptapComposer({
|
|
|
2985
3017
|
model={selectedModel}
|
|
2986
3018
|
effort={selectedEffort}
|
|
2987
3019
|
engines={availableModels}
|
|
3020
|
+
showAutoModelOption={showAutoModelOption}
|
|
2988
3021
|
modelListLoading={modelListLoading}
|
|
2989
3022
|
onChange={onModelChange}
|
|
2990
3023
|
onEffortChange={onEffortChange}
|
|
@@ -26,6 +26,10 @@ export interface EngineModelGroup {
|
|
|
26
26
|
label: string;
|
|
27
27
|
models: string[];
|
|
28
28
|
configured: boolean;
|
|
29
|
+
/** Provider-owned connection state shown at the far edge of the row. */
|
|
30
|
+
statusLabel?: string;
|
|
31
|
+
/** Marks a configured local subscription so setup CTAs can stay hidden. */
|
|
32
|
+
isSubscription?: boolean;
|
|
29
33
|
}
|
|
30
34
|
|
|
31
35
|
export interface ComposerModelState {
|
|
@@ -180,7 +184,7 @@ const fallbackModels = {
|
|
|
180
184
|
useChatModels: () => ({
|
|
181
185
|
selectedModel: "auto",
|
|
182
186
|
selectedEngine: "auto",
|
|
183
|
-
selectedEffort: "
|
|
187
|
+
selectedEffort: "high" as ReasoningEffort,
|
|
184
188
|
availableModels: [],
|
|
185
189
|
isLoading: false,
|
|
186
190
|
onModelChange: () => {},
|
|
@@ -277,7 +281,7 @@ export function useComposerRuntimeAdapters() {
|
|
|
277
281
|
return useContext(ComposerRuntimeAdaptersContext);
|
|
278
282
|
}
|
|
279
283
|
|
|
280
|
-
export const DEFAULT_REASONING_EFFORT: ReasoningEffort = "
|
|
284
|
+
export const DEFAULT_REASONING_EFFORT: ReasoningEffort = "high";
|
|
281
285
|
export function getReasoningEffortOptionsForModel(
|
|
282
286
|
_model?: string,
|
|
283
287
|
): ReasoningEffort[] {
|
package/src/editor.css
CHANGED
package/src/ui/dropdown-menu.tsx
CHANGED
|
@@ -54,6 +54,8 @@ const DropdownMenuSubContent = React.forwardRef<
|
|
|
54
54
|
<DropdownMenuPrimitive.SubContent
|
|
55
55
|
ref={ref}
|
|
56
56
|
className={cn(
|
|
57
|
+
// compositing-ok: Radix content mounts on open and unmounts on close,
|
|
58
|
+
// so the promoted layer is retired with it.
|
|
57
59
|
"z-[290] min-w-[8rem] origin-[var(--radix-dropdown-menu-content-transform-origin)] overflow-hidden rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-lg will-change-[transform,opacity] data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:duration-100 data-[state=open]:duration-150 data-[state=closed]:ease-out data-[state=open]:ease-out data-[side=bottom]:slide-in-from-top-1 data-[side=left]:slide-in-from-right-1 data-[side=right]:slide-in-from-left-1 data-[side=top]:slide-in-from-bottom-1 motion-reduce:data-[state=open]:zoom-in-100 motion-reduce:data-[state=closed]:zoom-out-100 motion-reduce:data-[side=bottom]:slide-in-from-top-0 motion-reduce:data-[side=left]:slide-in-from-right-0 motion-reduce:data-[side=right]:slide-in-from-left-0 motion-reduce:data-[side=top]:slide-in-from-bottom-0",
|
|
58
60
|
className,
|
|
59
61
|
)}
|
|
@@ -83,6 +85,8 @@ const DropdownMenuContent = React.forwardRef<
|
|
|
83
85
|
ref={ref}
|
|
84
86
|
sideOffset={sideOffset}
|
|
85
87
|
className={cn(
|
|
88
|
+
// compositing-ok: Radix content mounts on open and unmounts on close,
|
|
89
|
+
// so the promoted layer is retired with it.
|
|
86
90
|
"z-[290] min-w-[8rem] origin-[var(--radix-dropdown-menu-content-transform-origin)] overflow-hidden rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md will-change-[transform,opacity] data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:duration-100 data-[state=open]:duration-150 data-[state=closed]:ease-out data-[state=open]:ease-out data-[side=bottom]:slide-in-from-top-1 data-[side=left]:slide-in-from-right-1 data-[side=right]:slide-in-from-left-1 data-[side=top]:slide-in-from-bottom-1 motion-reduce:data-[state=open]:zoom-in-100 motion-reduce:data-[state=closed]:zoom-out-100 motion-reduce:data-[side=bottom]:slide-in-from-top-0 motion-reduce:data-[side=left]:slide-in-from-right-0 motion-reduce:data-[side=right]:slide-in-from-left-0 motion-reduce:data-[side=top]:slide-in-from-bottom-0",
|
|
87
91
|
className,
|
|
88
92
|
)}
|