@agent-native/toolkit 0.14.2 → 0.15.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/dist/composer/ComposerPlusMenu.d.ts.map +1 -1
- package/dist/composer/ComposerPlusMenu.js +131 -35
- package/dist/composer/ComposerPlusMenu.js.map +1 -1
- package/dist/composer/MentionPopover.d.ts.map +1 -1
- package/dist/composer/MentionPopover.js +40 -5
- package/dist/composer/MentionPopover.js.map +1 -1
- package/dist/composer/PastedTextChip.d.ts.map +1 -1
- package/dist/composer/PastedTextChip.js +26 -2
- package/dist/composer/PastedTextChip.js.map +1 -1
- package/dist/composer/PastedTextChip.spec.d.ts +2 -0
- package/dist/composer/PastedTextChip.spec.d.ts.map +1 -0
- package/dist/composer/PastedTextChip.spec.js +42 -0
- package/dist/composer/PastedTextChip.spec.js.map +1 -0
- package/dist/composer/PromptComposer.d.ts.map +1 -1
- package/dist/composer/PromptComposer.js +26 -5
- package/dist/composer/PromptComposer.js.map +1 -1
- package/dist/composer/TiptapComposer.d.ts +5 -3
- package/dist/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/composer/TiptapComposer.js +291 -80
- package/dist/composer/TiptapComposer.js.map +1 -1
- package/dist/composer/TiptapComposer.spec.js +60 -3
- package/dist/composer/TiptapComposer.spec.js.map +1 -1
- package/dist/composer/VoiceButton.d.ts.map +1 -1
- package/dist/composer/VoiceButton.js +24 -5
- package/dist/composer/VoiceButton.js.map +1 -1
- package/dist/composer/runtime-adapters.d.ts +1 -0
- package/dist/composer/runtime-adapters.d.ts.map +1 -1
- package/dist/composer/runtime-adapters.js +8 -1
- package/dist/composer/runtime-adapters.js.map +1 -1
- package/dist/composer/runtime-adapters.spec.js +15 -0
- package/dist/composer/runtime-adapters.spec.js.map +1 -1
- package/dist/composer/useRealtimeVoiceMode.d.ts.map +1 -1
- package/dist/composer/useRealtimeVoiceMode.js +204 -68
- package/dist/composer/useRealtimeVoiceMode.js.map +1 -1
- package/dist/composer/useRealtimeVoiceMode.spec.js +27 -1
- package/dist/composer/useRealtimeVoiceMode.spec.js.map +1 -1
- package/dist/context-ui/ContextMeter.d.ts +3 -2
- package/dist/context-ui/ContextMeter.d.ts.map +1 -1
- package/dist/context-ui/ContextMeter.js +23 -3
- package/dist/context-ui/ContextMeter.js.map +1 -1
- package/dist/context-ui/ContextMeter.spec.d.ts +2 -0
- package/dist/context-ui/ContextMeter.spec.d.ts.map +1 -0
- package/dist/context-ui/ContextMeter.spec.js +52 -0
- package/dist/context-ui/ContextMeter.spec.js.map +1 -0
- package/dist/context-ui/ContextSegmentRow.d.ts +5 -3
- package/dist/context-ui/ContextSegmentRow.d.ts.map +1 -1
- package/dist/context-ui/ContextSegmentRow.js +74 -7
- package/dist/context-ui/ContextSegmentRow.js.map +1 -1
- package/dist/context-ui/ContextTreemap.d.ts +3 -2
- package/dist/context-ui/ContextTreemap.d.ts.map +1 -1
- package/dist/context-ui/ContextTreemap.js +5 -2
- package/dist/context-ui/ContextTreemap.js.map +1 -1
- package/dist/context-ui/ContextXRayPanel.d.ts +3 -2
- package/dist/context-ui/ContextXRayPanel.d.ts.map +1 -1
- package/dist/context-ui/ContextXRayPanel.js +112 -23
- package/dist/context-ui/ContextXRayPanel.js.map +1 -1
- package/dist/context-ui/types.d.ts +2 -0
- package/dist/context-ui/types.d.ts.map +1 -1
- package/dist/context-ui/types.js +7 -1
- package/dist/context-ui/types.js.map +1 -1
- package/package.json +2 -2
- package/src/composer/ComposerPlusMenu.tsx +170 -52
- package/src/composer/MentionPopover.tsx +43 -7
- package/src/composer/PastedTextChip.spec.tsx +58 -0
- package/src/composer/PastedTextChip.tsx +35 -7
- package/src/composer/PromptComposer.tsx +28 -7
- package/src/composer/TiptapComposer.spec.ts +90 -3
- package/src/composer/TiptapComposer.tsx +341 -82
- package/src/composer/VoiceButton.tsx +36 -11
- package/src/composer/runtime-adapters.spec.tsx +19 -0
- package/src/composer/runtime-adapters.tsx +12 -2
- package/src/composer/useRealtimeVoiceMode.spec.ts +34 -0
- package/src/composer/useRealtimeVoiceMode.tsx +219 -69
- package/src/context-ui/ContextMeter.spec.tsx +73 -0
- package/src/context-ui/ContextMeter.tsx +34 -4
- package/src/context-ui/ContextSegmentRow.tsx +111 -22
- package/src/context-ui/ContextTreemap.tsx +7 -1
- package/src/context-ui/ContextXRayPanel.tsx +138 -24
- package/src/context-ui/types.ts +14 -0
|
@@ -17,14 +17,49 @@ import type {
|
|
|
17
17
|
ContextSegmentStatus,
|
|
18
18
|
ContextSegmentViewData,
|
|
19
19
|
ContextSystemSectionViewData,
|
|
20
|
+
ContextTranslate,
|
|
20
21
|
} from "./types.js";
|
|
22
|
+
import { fallbackContextTranslate } from "./types.js";
|
|
21
23
|
|
|
22
24
|
interface Group {
|
|
23
25
|
name: string;
|
|
26
|
+
label: string;
|
|
24
27
|
tokens: number;
|
|
25
28
|
segments: ContextSegmentViewData[];
|
|
26
29
|
}
|
|
27
30
|
|
|
31
|
+
function groupLabel(name: string, translate: ContextTranslate): string {
|
|
32
|
+
if (name === "Pinned")
|
|
33
|
+
return translate("agentChat.contextXray.groups.pinned", {
|
|
34
|
+
defaultValue: name,
|
|
35
|
+
});
|
|
36
|
+
if (name === "Tool results")
|
|
37
|
+
return translate("agentChat.contextXray.groups.toolResults", {
|
|
38
|
+
defaultValue: name,
|
|
39
|
+
});
|
|
40
|
+
if (name === "Files read")
|
|
41
|
+
return translate("agentChat.contextXray.groups.filesRead", {
|
|
42
|
+
defaultValue: name,
|
|
43
|
+
});
|
|
44
|
+
if (name === "Conversation")
|
|
45
|
+
return translate("agentChat.contextXray.groups.conversation", {
|
|
46
|
+
defaultValue: name,
|
|
47
|
+
});
|
|
48
|
+
if (name === "Thinking")
|
|
49
|
+
return translate("agentChat.contextXray.groups.thinking", {
|
|
50
|
+
defaultValue: name,
|
|
51
|
+
});
|
|
52
|
+
if (name === "Evicted")
|
|
53
|
+
return translate("agentChat.contextXray.groups.evicted", {
|
|
54
|
+
defaultValue: name,
|
|
55
|
+
});
|
|
56
|
+
if (name === "Task & instructions")
|
|
57
|
+
return translate("agentChat.contextXray.groups.taskInstructions", {
|
|
58
|
+
defaultValue: name,
|
|
59
|
+
});
|
|
60
|
+
return name;
|
|
61
|
+
}
|
|
62
|
+
|
|
28
63
|
function applyOptimisticStatus(
|
|
29
64
|
segments: ContextSegmentViewData[],
|
|
30
65
|
optimistic: Map<string, ContextSegmentStatus>,
|
|
@@ -37,7 +72,10 @@ function applyOptimisticStatus(
|
|
|
37
72
|
);
|
|
38
73
|
}
|
|
39
74
|
|
|
40
|
-
function groupedSegments(
|
|
75
|
+
function groupedSegments(
|
|
76
|
+
segments: ContextSegmentViewData[],
|
|
77
|
+
translate: ContextTranslate,
|
|
78
|
+
): Group[] {
|
|
41
79
|
const map = new Map<string, Group>();
|
|
42
80
|
for (const segment of segments) {
|
|
43
81
|
const name =
|
|
@@ -46,7 +84,12 @@ function groupedSegments(segments: ContextSegmentViewData[]): Group[] {
|
|
|
46
84
|
: segment.status === "evicted"
|
|
47
85
|
? "Evicted"
|
|
48
86
|
: segment.group;
|
|
49
|
-
const group = map.get(name) ?? {
|
|
87
|
+
const group = map.get(name) ?? {
|
|
88
|
+
name,
|
|
89
|
+
label: groupLabel(name, translate),
|
|
90
|
+
tokens: 0,
|
|
91
|
+
segments: [],
|
|
92
|
+
};
|
|
50
93
|
group.tokens += segment.tokenCount;
|
|
51
94
|
group.segments.push(segment);
|
|
52
95
|
map.set(name, group);
|
|
@@ -68,21 +111,35 @@ function groupedSegments(segments: ContextSegmentViewData[]): Group[] {
|
|
|
68
111
|
});
|
|
69
112
|
}
|
|
70
113
|
|
|
71
|
-
function sourceLabel(
|
|
114
|
+
function sourceLabel(
|
|
115
|
+
section: ContextSystemSectionViewData,
|
|
116
|
+
translate: ContextTranslate,
|
|
117
|
+
) {
|
|
118
|
+
const scope = section.sourceRef?.scope;
|
|
119
|
+
const localizedScope =
|
|
120
|
+
scope === "framework"
|
|
121
|
+
? translate("agentChat.contextXray.framework", {
|
|
122
|
+
defaultValue: "framework",
|
|
123
|
+
})
|
|
124
|
+
: scope;
|
|
72
125
|
return (
|
|
73
126
|
section.sourceRef?.path ??
|
|
74
127
|
section.sourceRef?.resourceId ??
|
|
75
|
-
|
|
76
|
-
"framework"
|
|
128
|
+
localizedScope ??
|
|
129
|
+
translate("agentChat.contextXray.framework", {
|
|
130
|
+
defaultValue: "framework",
|
|
131
|
+
})
|
|
77
132
|
);
|
|
78
133
|
}
|
|
79
134
|
|
|
80
135
|
function SystemSectionRow({
|
|
81
136
|
section,
|
|
82
137
|
totalTokens,
|
|
138
|
+
translate,
|
|
83
139
|
}: {
|
|
84
140
|
section: ContextSystemSectionViewData;
|
|
85
141
|
totalTokens: number;
|
|
142
|
+
translate: ContextTranslate;
|
|
86
143
|
}) {
|
|
87
144
|
const share =
|
|
88
145
|
totalTokens > 0 ? Math.round((section.tokenCount / totalTokens) * 100) : 0;
|
|
@@ -96,9 +153,17 @@ function SystemSectionRow({
|
|
|
96
153
|
{section.label}
|
|
97
154
|
</div>
|
|
98
155
|
<div className="truncate text-[11px] text-muted-foreground">
|
|
99
|
-
{sourceLabel(section)} ·
|
|
100
|
-
|
|
101
|
-
{
|
|
156
|
+
{sourceLabel(section, translate)} ·{" "}
|
|
157
|
+
{formatContextTokens(section.tokenCount)}{" "}
|
|
158
|
+
{translate("agentChat.contextXray.tokensShare", {
|
|
159
|
+
defaultValue: "tokens · {{share}}%",
|
|
160
|
+
share,
|
|
161
|
+
})}
|
|
162
|
+
{section.tokenMethod === "estimate"
|
|
163
|
+
? translate("agentChat.contextXray.estimatedSuffix", {
|
|
164
|
+
defaultValue: " · estimated",
|
|
165
|
+
})
|
|
166
|
+
: ""}
|
|
102
167
|
</div>
|
|
103
168
|
{section.preview ? (
|
|
104
169
|
<div className="mt-0.5 line-clamp-2 text-[11px] text-muted-foreground/80">
|
|
@@ -120,6 +185,7 @@ export function ContextXRayPanelView({
|
|
|
120
185
|
governanceLabels = {},
|
|
121
186
|
systemOrderedLabel = "System · ordered, not evictable",
|
|
122
187
|
titleLabel = "Context X-Ray",
|
|
188
|
+
translate = fallbackContextTranslate,
|
|
123
189
|
}: {
|
|
124
190
|
manifest: ContextManifestViewData;
|
|
125
191
|
contextWindow: number;
|
|
@@ -130,6 +196,7 @@ export function ContextXRayPanelView({
|
|
|
130
196
|
governanceLabels?: Partial<Record<"required" | "inherited" | "user", string>>;
|
|
131
197
|
systemOrderedLabel?: string;
|
|
132
198
|
titleLabel?: string;
|
|
199
|
+
translate?: ContextTranslate;
|
|
133
200
|
}) {
|
|
134
201
|
const [mode, setMode] = useState<"list" | "map">("list");
|
|
135
202
|
const [collapsed, setCollapsed] = useState<Set<string>>(new Set());
|
|
@@ -137,7 +204,10 @@ export function ContextXRayPanelView({
|
|
|
137
204
|
() => applyOptimisticStatus(manifest.segments, optimistic),
|
|
138
205
|
[manifest.segments, optimistic],
|
|
139
206
|
);
|
|
140
|
-
const groups = useMemo(
|
|
207
|
+
const groups = useMemo(
|
|
208
|
+
() => groupedSegments(segments, translate),
|
|
209
|
+
[segments, translate],
|
|
210
|
+
);
|
|
141
211
|
const sections = manifest.systemSections ?? [];
|
|
142
212
|
const systemGroups = useMemo(
|
|
143
213
|
() =>
|
|
@@ -173,13 +243,42 @@ export function ContextXRayPanelView({
|
|
|
173
243
|
(segment) => segment.status === "evicted",
|
|
174
244
|
).length;
|
|
175
245
|
const details = [
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
246
|
+
translate("agentChat.contextXray.free", {
|
|
247
|
+
defaultValue: "{{count}} free",
|
|
248
|
+
count: formatContextTokens(headroom),
|
|
249
|
+
}),
|
|
250
|
+
system > 0
|
|
251
|
+
? translate("agentChat.contextXray.system", {
|
|
252
|
+
defaultValue: "{{count}} system",
|
|
253
|
+
count: formatContextTokens(system),
|
|
254
|
+
})
|
|
255
|
+
: null,
|
|
256
|
+
translate("agentChat.contextXray.conversation", {
|
|
257
|
+
defaultValue: "{{count}} conversation",
|
|
258
|
+
count: formatContextTokens(conversation),
|
|
259
|
+
}),
|
|
260
|
+
pinned > 0
|
|
261
|
+
? translate("agentChat.contextXray.pinned", {
|
|
262
|
+
defaultValue: "{{count}} pinned",
|
|
263
|
+
count: pinned,
|
|
264
|
+
})
|
|
265
|
+
: null,
|
|
266
|
+
evicted > 0
|
|
267
|
+
? translate("agentChat.contextXray.evicted", {
|
|
268
|
+
defaultValue: "{{count}} evicted",
|
|
269
|
+
count: evicted,
|
|
270
|
+
})
|
|
271
|
+
: null,
|
|
272
|
+
manifest.tokenCountMethod === "estimate"
|
|
273
|
+
? translate("agentChat.contextXray.estimated", {
|
|
274
|
+
defaultValue: "estimated",
|
|
275
|
+
})
|
|
276
|
+
: null,
|
|
277
|
+
!manifest.enforceable
|
|
278
|
+
? translate("agentChat.contextXray.advisory", {
|
|
279
|
+
defaultValue: "advisory",
|
|
280
|
+
})
|
|
281
|
+
: null,
|
|
183
282
|
].filter((item): item is string => Boolean(item));
|
|
184
283
|
const toggle = (key: string) =>
|
|
185
284
|
setCollapsed((current) => {
|
|
@@ -201,7 +300,7 @@ export function ContextXRayPanelView({
|
|
|
201
300
|
</div>
|
|
202
301
|
<div className="mt-2 h-1 overflow-hidden rounded-full bg-muted/70">
|
|
203
302
|
<div
|
|
204
|
-
className="h-full w-full origin-left rounded-full bg-foreground transition-transform duration-200"
|
|
303
|
+
className="h-full w-full origin-left rounded-full bg-foreground transition-transform duration-200 rtl:origin-right"
|
|
205
304
|
style={{ transform: `scaleX(${Math.min(1, pct / 100)})` }}
|
|
206
305
|
/>
|
|
207
306
|
</div>
|
|
@@ -224,7 +323,9 @@ export function ContextXRayPanelView({
|
|
|
224
323
|
<button
|
|
225
324
|
type="button"
|
|
226
325
|
onClick={() => setMode("list")}
|
|
227
|
-
aria-label="
|
|
326
|
+
aria-label={translate("agentChat.contextXray.showList", {
|
|
327
|
+
defaultValue: "Show context list",
|
|
328
|
+
})}
|
|
228
329
|
className={cn(
|
|
229
330
|
"flex size-7 cursor-pointer items-center justify-center rounded text-muted-foreground",
|
|
230
331
|
mode === "list"
|
|
@@ -235,14 +336,20 @@ export function ContextXRayPanelView({
|
|
|
235
336
|
<IconListDetails className="h-3.5 w-3.5" />
|
|
236
337
|
</button>
|
|
237
338
|
</TooltipTrigger>
|
|
238
|
-
<TooltipContent>
|
|
339
|
+
<TooltipContent>
|
|
340
|
+
{translate("agentChat.contextXray.list", {
|
|
341
|
+
defaultValue: "List",
|
|
342
|
+
})}
|
|
343
|
+
</TooltipContent>
|
|
239
344
|
</Tooltip>
|
|
240
345
|
<Tooltip>
|
|
241
346
|
<TooltipTrigger asChild>
|
|
242
347
|
<button
|
|
243
348
|
type="button"
|
|
244
349
|
onClick={() => setMode("map")}
|
|
245
|
-
aria-label="
|
|
350
|
+
aria-label={translate("agentChat.contextXray.showMap", {
|
|
351
|
+
defaultValue: "Show context map",
|
|
352
|
+
})}
|
|
246
353
|
className={cn(
|
|
247
354
|
"flex size-7 cursor-pointer items-center justify-center rounded text-muted-foreground",
|
|
248
355
|
mode === "map"
|
|
@@ -253,7 +360,11 @@ export function ContextXRayPanelView({
|
|
|
253
360
|
<IconChartTreemap className="h-3.5 w-3.5" />
|
|
254
361
|
</button>
|
|
255
362
|
</TooltipTrigger>
|
|
256
|
-
<TooltipContent>
|
|
363
|
+
<TooltipContent>
|
|
364
|
+
{translate("agentChat.contextXray.map", {
|
|
365
|
+
defaultValue: "Map",
|
|
366
|
+
})}
|
|
367
|
+
</TooltipContent>
|
|
257
368
|
</Tooltip>
|
|
258
369
|
</div>
|
|
259
370
|
</div>
|
|
@@ -261,6 +372,7 @@ export function ContextXRayPanelView({
|
|
|
261
372
|
<ContextTreemapView
|
|
262
373
|
segments={segments}
|
|
263
374
|
systemSections={sections}
|
|
375
|
+
translate={translate}
|
|
264
376
|
onSelect={(id) => {
|
|
265
377
|
if (segments.some((segment) => segment.segmentId === id))
|
|
266
378
|
setCollapsed(new Set());
|
|
@@ -281,7 +393,7 @@ export function ContextXRayPanelView({
|
|
|
281
393
|
<button
|
|
282
394
|
type="button"
|
|
283
395
|
onClick={() => toggle(key)}
|
|
284
|
-
className="flex w-full cursor-pointer items-center gap-2 rounded-sm px-1.5 py-2 text-
|
|
396
|
+
className="flex w-full cursor-pointer items-center gap-2 rounded-sm px-1.5 py-2 text-start hover:bg-accent/35"
|
|
285
397
|
>
|
|
286
398
|
{isCollapsed ? (
|
|
287
399
|
<IconChevronRight className="h-3.5 w-3.5 text-muted-foreground" />
|
|
@@ -313,6 +425,7 @@ export function ContextXRayPanelView({
|
|
|
313
425
|
key={section.segmentId}
|
|
314
426
|
section={section}
|
|
315
427
|
totalTokens={manifest.totalTokens}
|
|
428
|
+
translate={translate}
|
|
316
429
|
/>
|
|
317
430
|
))}
|
|
318
431
|
</div>
|
|
@@ -329,7 +442,7 @@ export function ContextXRayPanelView({
|
|
|
329
442
|
<button
|
|
330
443
|
type="button"
|
|
331
444
|
onClick={() => toggle(group.name)}
|
|
332
|
-
className="flex w-full cursor-pointer items-center gap-2 rounded-sm px-1.5 py-2 text-
|
|
445
|
+
className="flex w-full cursor-pointer items-center gap-2 rounded-sm px-1.5 py-2 text-start hover:bg-accent/35"
|
|
333
446
|
>
|
|
334
447
|
{isCollapsed ? (
|
|
335
448
|
<IconChevronRight className="h-3.5 w-3.5 text-muted-foreground" />
|
|
@@ -343,7 +456,7 @@ export function ContextXRayPanelView({
|
|
|
343
456
|
)}
|
|
344
457
|
/>
|
|
345
458
|
<span className="min-w-0 flex-1 truncate text-xs font-medium">
|
|
346
|
-
{group.
|
|
459
|
+
{group.label}
|
|
347
460
|
</span>
|
|
348
461
|
<span className="text-[11px] text-muted-foreground">
|
|
349
462
|
{formatContextTokens(group.tokens)}
|
|
@@ -362,6 +475,7 @@ export function ContextXRayPanelView({
|
|
|
362
475
|
onPin={() => onPin(segment.segmentId)}
|
|
363
476
|
onEvict={() => onEvict(segment.segmentId)}
|
|
364
477
|
onRestore={() => onRestore(segment.segmentId)}
|
|
478
|
+
translate={translate}
|
|
365
479
|
/>
|
|
366
480
|
))}
|
|
367
481
|
</div>
|
package/src/context-ui/types.ts
CHANGED
|
@@ -41,3 +41,17 @@ export interface ContextManifestViewData {
|
|
|
41
41
|
systemTokens: number;
|
|
42
42
|
conversationTokens: number;
|
|
43
43
|
}
|
|
44
|
+
|
|
45
|
+
export type ContextTranslate = (
|
|
46
|
+
key: string,
|
|
47
|
+
options?: Record<string, unknown>,
|
|
48
|
+
) => string;
|
|
49
|
+
|
|
50
|
+
export const fallbackContextTranslate: ContextTranslate = (key, options) => {
|
|
51
|
+
const template =
|
|
52
|
+
typeof options?.defaultValue === "string" ? options.defaultValue : key;
|
|
53
|
+
return template.replace(/{{\s*([\w$.-]+)\s*}}/g, (match, name: string) => {
|
|
54
|
+
const value = options?.[name];
|
|
55
|
+
return value == null ? match : String(value);
|
|
56
|
+
});
|
|
57
|
+
};
|