@agent-native/toolkit 0.14.3 → 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 +289 -79
- package/dist/composer/TiptapComposer.js.map +1 -1
- package/dist/composer/TiptapComposer.spec.js +57 -0
- 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 +85 -0
- package/src/composer/TiptapComposer.tsx +338 -81
- 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
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// @vitest-environment happy-dom
|
|
2
|
+
|
|
3
|
+
import React, { act } from "react";
|
|
4
|
+
import { createRoot, type Root } from "react-dom/client";
|
|
5
|
+
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
6
|
+
|
|
7
|
+
import { ContextMeterView } from "./ContextMeter.js";
|
|
8
|
+
import { fallbackContextTranslate } from "./types.js";
|
|
9
|
+
|
|
10
|
+
let container: HTMLDivElement;
|
|
11
|
+
let root: Root;
|
|
12
|
+
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
container = document.createElement("div");
|
|
15
|
+
document.body.appendChild(container);
|
|
16
|
+
root = createRoot(container);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
afterEach(() => {
|
|
20
|
+
act(() => root.unmount());
|
|
21
|
+
container.remove();
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
const manifest = {
|
|
25
|
+
totalTokens: 300,
|
|
26
|
+
rawTokens: 300,
|
|
27
|
+
reclaimedTokens: 0,
|
|
28
|
+
tokenCountMethod: "exact" as const,
|
|
29
|
+
enforceable: true,
|
|
30
|
+
segments: [],
|
|
31
|
+
systemTokens: 100,
|
|
32
|
+
conversationTokens: 200,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
describe("ContextMeterView localization", () => {
|
|
36
|
+
it("interpolates the providerless English fallback", () => {
|
|
37
|
+
expect(
|
|
38
|
+
fallbackContextTranslate("agentChat.contextMeter.summary", {
|
|
39
|
+
defaultValue: "Context {{percent}}% · {{totalTokens}}",
|
|
40
|
+
percent: 25,
|
|
41
|
+
totalTokens: "2.0k",
|
|
42
|
+
}),
|
|
43
|
+
).toBe("Context 25% · 2.0k");
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it("uses the supplied translator for its accessible label", () => {
|
|
47
|
+
const translate = (key: string, options: Record<string, unknown> = {}) => {
|
|
48
|
+
if (key === "agentChat.contextMeter.breakdown") return " AUFTEILUNG";
|
|
49
|
+
if (key === "agentChat.contextMeter.ariaLabel") {
|
|
50
|
+
return `Kontext ${options.percent}% ${options.totalTokens}${options.breakdown}`;
|
|
51
|
+
}
|
|
52
|
+
return String(options.defaultValue ?? key);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
act(() => {
|
|
56
|
+
root.render(
|
|
57
|
+
<ContextMeterView
|
|
58
|
+
manifest={manifest}
|
|
59
|
+
contextWindow={1_200}
|
|
60
|
+
open={false}
|
|
61
|
+
onOpenChange={() => undefined}
|
|
62
|
+
translate={translate}
|
|
63
|
+
>
|
|
64
|
+
<div>Panel</div>
|
|
65
|
+
</ContextMeterView>,
|
|
66
|
+
);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
expect(container.querySelector("button")?.getAttribute("aria-label")).toBe(
|
|
70
|
+
"Kontext 25% 300 AUFTEILUNG",
|
|
71
|
+
);
|
|
72
|
+
});
|
|
73
|
+
});
|
|
@@ -9,7 +9,11 @@ import {
|
|
|
9
9
|
} from "../ui/tooltip.js";
|
|
10
10
|
import { cn } from "../utils.js";
|
|
11
11
|
import { formatContextTokens } from "./format.js";
|
|
12
|
-
import
|
|
12
|
+
import {
|
|
13
|
+
fallbackContextTranslate,
|
|
14
|
+
type ContextManifestViewData,
|
|
15
|
+
type ContextTranslate,
|
|
16
|
+
} from "./types.js";
|
|
13
17
|
|
|
14
18
|
function ContextDonut({ pct, advisory }: { pct: number; advisory: boolean }) {
|
|
15
19
|
const radius = 7.5;
|
|
@@ -50,12 +54,14 @@ export function ContextMeterView({
|
|
|
50
54
|
open,
|
|
51
55
|
onOpenChange,
|
|
52
56
|
children,
|
|
57
|
+
translate = fallbackContextTranslate,
|
|
53
58
|
}: {
|
|
54
59
|
manifest: ContextManifestViewData;
|
|
55
60
|
contextWindow: number;
|
|
56
61
|
open: boolean;
|
|
57
62
|
onOpenChange: (open: boolean) => void;
|
|
58
63
|
children: ReactNode;
|
|
64
|
+
translate?: ContextTranslate;
|
|
59
65
|
}) {
|
|
60
66
|
const pct = Math.min(
|
|
61
67
|
100,
|
|
@@ -70,7 +76,22 @@ export function ContextMeterView({
|
|
|
70
76
|
<PopoverTrigger asChild>
|
|
71
77
|
<button
|
|
72
78
|
type="button"
|
|
73
|
-
aria-label={
|
|
79
|
+
aria-label={translate("agentChat.contextMeter.ariaLabel", {
|
|
80
|
+
defaultValue:
|
|
81
|
+
"Context {{percent}}%, {{totalTokens}}{{breakdown}}. Open Context X-Ray.",
|
|
82
|
+
percent: pct,
|
|
83
|
+
totalTokens: formatContextTokens(manifest.totalTokens),
|
|
84
|
+
breakdown:
|
|
85
|
+
systemTokens > 0
|
|
86
|
+
? translate("agentChat.contextMeter.breakdown", {
|
|
87
|
+
defaultValue:
|
|
88
|
+
" total: {{systemTokens}} system + {{conversationTokens}} conversation",
|
|
89
|
+
systemTokens: formatContextTokens(systemTokens),
|
|
90
|
+
conversationTokens:
|
|
91
|
+
formatContextTokens(conversationTokens),
|
|
92
|
+
})
|
|
93
|
+
: "",
|
|
94
|
+
})}
|
|
74
95
|
className={cn(
|
|
75
96
|
"flex size-7 shrink-0 cursor-pointer items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent/50 hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
76
97
|
open && "bg-accent/60 text-foreground",
|
|
@@ -81,9 +102,18 @@ export function ContextMeterView({
|
|
|
81
102
|
</PopoverTrigger>
|
|
82
103
|
</TooltipTrigger>
|
|
83
104
|
<TooltipContent>
|
|
84
|
-
|
|
105
|
+
{translate("agentChat.contextMeter.summary", {
|
|
106
|
+
defaultValue: "Context {{percent}}% · {{totalTokens}}",
|
|
107
|
+
percent: pct,
|
|
108
|
+
totalTokens: formatContextTokens(manifest.totalTokens),
|
|
109
|
+
})}
|
|
85
110
|
{systemTokens > 0
|
|
86
|
-
?
|
|
111
|
+
? translate("agentChat.contextMeter.summaryBreakdown", {
|
|
112
|
+
defaultValue:
|
|
113
|
+
" ({{systemTokens}} system + {{conversationTokens}} conversation)",
|
|
114
|
+
systemTokens: formatContextTokens(systemTokens),
|
|
115
|
+
conversationTokens: formatContextTokens(conversationTokens),
|
|
116
|
+
})
|
|
87
117
|
: ""}
|
|
88
118
|
</TooltipContent>
|
|
89
119
|
</Tooltip>
|
|
@@ -4,15 +4,46 @@ import type { ReactNode } from "react";
|
|
|
4
4
|
import { Popover, PopoverContent, PopoverTrigger } from "../ui/popover.js";
|
|
5
5
|
import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip.js";
|
|
6
6
|
import { cn } from "../utils.js";
|
|
7
|
-
import {
|
|
8
|
-
import
|
|
7
|
+
import { formatContextTokens } from "./format.js";
|
|
8
|
+
import {
|
|
9
|
+
fallbackContextTranslate,
|
|
10
|
+
type ContextSegmentViewData,
|
|
11
|
+
type ContextTranslate,
|
|
12
|
+
} from "./types.js";
|
|
13
|
+
|
|
14
|
+
function statusLabel(
|
|
15
|
+
segment: ContextSegmentViewData,
|
|
16
|
+
translate: ContextTranslate,
|
|
17
|
+
): string {
|
|
18
|
+
if (segment.protected)
|
|
19
|
+
return translate("agentChat.contextXray.status.protected", {
|
|
20
|
+
defaultValue: "Protected",
|
|
21
|
+
});
|
|
22
|
+
if (segment.status === "pinned")
|
|
23
|
+
return translate("agentChat.contextXray.status.pinned", {
|
|
24
|
+
defaultValue: "Pinned",
|
|
25
|
+
});
|
|
26
|
+
if (segment.status === "evicted")
|
|
27
|
+
return translate("agentChat.contextXray.status.evicted", {
|
|
28
|
+
defaultValue: "Evicted",
|
|
29
|
+
});
|
|
30
|
+
if (segment.status === "summarized")
|
|
31
|
+
return translate("agentChat.contextXray.status.summarized", {
|
|
32
|
+
defaultValue: "Summarized",
|
|
33
|
+
});
|
|
34
|
+
return translate("agentChat.contextXray.status.active", {
|
|
35
|
+
defaultValue: "Active",
|
|
36
|
+
});
|
|
37
|
+
}
|
|
9
38
|
|
|
10
39
|
export function SegmentProvenancePopoverView({
|
|
11
40
|
segment,
|
|
12
41
|
children,
|
|
42
|
+
translate = fallbackContextTranslate,
|
|
13
43
|
}: {
|
|
14
44
|
segment: ContextSegmentViewData;
|
|
15
45
|
children: ReactNode;
|
|
46
|
+
translate?: ContextTranslate;
|
|
16
47
|
}) {
|
|
17
48
|
return (
|
|
18
49
|
<Popover>
|
|
@@ -21,7 +52,9 @@ export function SegmentProvenancePopoverView({
|
|
|
21
52
|
<div className="space-y-2">
|
|
22
53
|
<div>
|
|
23
54
|
<div className="text-[11px] font-medium uppercase text-muted-foreground">
|
|
24
|
-
|
|
55
|
+
{translate("agentChat.contextXray.segment", {
|
|
56
|
+
defaultValue: "Segment",
|
|
57
|
+
})}
|
|
25
58
|
</div>
|
|
26
59
|
<div className="mt-0.5 break-words text-xs text-foreground">
|
|
27
60
|
{segment.label}
|
|
@@ -32,30 +65,46 @@ export function SegmentProvenancePopoverView({
|
|
|
32
65
|
<span className="block font-medium text-foreground">
|
|
33
66
|
{formatContextTokens(segment.tokenCount)}
|
|
34
67
|
</span>
|
|
35
|
-
|
|
68
|
+
{translate("agentChat.contextXray.tokens", {
|
|
69
|
+
defaultValue: "tokens",
|
|
70
|
+
})}
|
|
71
|
+
{segment.tokenMethod === "estimate"
|
|
72
|
+
? translate("agentChat.contextXray.estimatedPrefix", {
|
|
73
|
+
defaultValue: " estimated",
|
|
74
|
+
})
|
|
75
|
+
: ""}
|
|
36
76
|
</div>
|
|
37
77
|
<div>
|
|
38
78
|
<span className="block font-medium text-foreground">
|
|
39
|
-
{
|
|
79
|
+
{statusLabel(segment, translate)}
|
|
40
80
|
</span>
|
|
41
|
-
|
|
81
|
+
{translate("agentChat.contextXray.currentStatus", {
|
|
82
|
+
defaultValue: "current status",
|
|
83
|
+
})}
|
|
42
84
|
</div>
|
|
43
85
|
<div>
|
|
44
86
|
<span className="block font-medium text-foreground">
|
|
45
87
|
{segment.msgIndex ?? "-"}
|
|
46
88
|
</span>
|
|
47
|
-
|
|
89
|
+
{translate("agentChat.contextXray.messageIndex", {
|
|
90
|
+
defaultValue: "message index",
|
|
91
|
+
})}
|
|
48
92
|
</div>
|
|
49
93
|
<div>
|
|
50
94
|
<span className="block font-medium text-foreground">
|
|
51
95
|
{segment.partIndex ?? "-"}
|
|
52
96
|
</span>
|
|
53
|
-
|
|
97
|
+
{translate("agentChat.contextXray.partIndex", {
|
|
98
|
+
defaultValue: "part index",
|
|
99
|
+
})}
|
|
54
100
|
</div>
|
|
55
101
|
</div>
|
|
56
102
|
{segment.protected ? (
|
|
57
103
|
<div className="rounded-md border border-border bg-muted/40 px-2 py-1.5 text-[11px] text-muted-foreground">
|
|
58
|
-
|
|
104
|
+
{translate("agentChat.contextXray.protectedDescription", {
|
|
105
|
+
defaultValue:
|
|
106
|
+
"This segment is part of the active turn and cannot be evicted yet.",
|
|
107
|
+
})}
|
|
59
108
|
</div>
|
|
60
109
|
) : null}
|
|
61
110
|
</div>
|
|
@@ -70,12 +119,14 @@ export function ContextSegmentRowView({
|
|
|
70
119
|
onPin,
|
|
71
120
|
onEvict,
|
|
72
121
|
onRestore,
|
|
122
|
+
translate = fallbackContextTranslate,
|
|
73
123
|
}: {
|
|
74
124
|
segment: ContextSegmentViewData;
|
|
75
125
|
advisory: boolean;
|
|
76
126
|
onPin: () => void;
|
|
77
127
|
onEvict: () => void;
|
|
78
128
|
onRestore: () => void;
|
|
129
|
+
translate?: ContextTranslate;
|
|
79
130
|
}) {
|
|
80
131
|
const disabled = segment.protected || segment.status === "evicted";
|
|
81
132
|
return (
|
|
@@ -91,11 +142,14 @@ export function ContextSegmentRowView({
|
|
|
91
142
|
segment.status === "evicted" && "opacity-60",
|
|
92
143
|
)}
|
|
93
144
|
>
|
|
94
|
-
<SegmentProvenancePopoverView segment={segment}>
|
|
145
|
+
<SegmentProvenancePopoverView segment={segment} translate={translate}>
|
|
95
146
|
<button
|
|
96
147
|
type="button"
|
|
97
|
-
className="min-w-0 flex-1 text-
|
|
98
|
-
aria-label={
|
|
148
|
+
className="min-w-0 flex-1 text-start"
|
|
149
|
+
aria-label={translate("agentChat.contextXray.inspect", {
|
|
150
|
+
defaultValue: "Inspect {{name}}",
|
|
151
|
+
name: segment.label,
|
|
152
|
+
})}
|
|
99
153
|
>
|
|
100
154
|
<div
|
|
101
155
|
className={cn(
|
|
@@ -109,8 +163,15 @@ export function ContextSegmentRowView({
|
|
|
109
163
|
<span>{formatContextTokens(segment.tokenCount)}</span>
|
|
110
164
|
{segment.tokenMethod === "estimate" ? <span>~</span> : null}
|
|
111
165
|
<span>·</span>
|
|
112
|
-
<span>{
|
|
113
|
-
{advisory ?
|
|
166
|
+
<span>{statusLabel(segment, translate)}</span>
|
|
167
|
+
{advisory ? (
|
|
168
|
+
<span>
|
|
169
|
+
·{" "}
|
|
170
|
+
{translate("agentChat.contextXray.advisory", {
|
|
171
|
+
defaultValue: "advisory",
|
|
172
|
+
})}
|
|
173
|
+
</span>
|
|
174
|
+
) : null}
|
|
114
175
|
</div>
|
|
115
176
|
</button>
|
|
116
177
|
</SegmentProvenancePopoverView>
|
|
@@ -122,7 +183,11 @@ export function ContextSegmentRowView({
|
|
|
122
183
|
<IconLock className="h-3.5 w-3.5" />
|
|
123
184
|
</span>
|
|
124
185
|
</TooltipTrigger>
|
|
125
|
-
<TooltipContent>
|
|
186
|
+
<TooltipContent>
|
|
187
|
+
{translate("agentChat.contextXray.protectedDuringTurn", {
|
|
188
|
+
defaultValue: "Protected during active turn",
|
|
189
|
+
})}
|
|
190
|
+
</TooltipContent>
|
|
126
191
|
</Tooltip>
|
|
127
192
|
) : segment.status === "evicted" ||
|
|
128
193
|
segment.status === "summarized" ||
|
|
@@ -135,15 +200,25 @@ export function ContextSegmentRowView({
|
|
|
135
200
|
className="flex size-6 items-center justify-center rounded-md text-muted-foreground hover:bg-background hover:text-foreground"
|
|
136
201
|
aria-label={
|
|
137
202
|
segment.status === "pinned"
|
|
138
|
-
? "
|
|
139
|
-
|
|
203
|
+
? translate("agentChat.contextXray.unpinSegment", {
|
|
204
|
+
defaultValue: "Unpin segment",
|
|
205
|
+
})
|
|
206
|
+
: translate("agentChat.contextXray.restoreSegment", {
|
|
207
|
+
defaultValue: "Restore segment",
|
|
208
|
+
})
|
|
140
209
|
}
|
|
141
210
|
>
|
|
142
211
|
<IconRotate2 className="h-3.5 w-3.5" />
|
|
143
212
|
</button>
|
|
144
213
|
</TooltipTrigger>
|
|
145
214
|
<TooltipContent>
|
|
146
|
-
{segment.status === "pinned"
|
|
215
|
+
{segment.status === "pinned"
|
|
216
|
+
? translate("agentChat.contextXray.unpin", {
|
|
217
|
+
defaultValue: "Unpin",
|
|
218
|
+
})
|
|
219
|
+
: translate("agentChat.contextXray.restore", {
|
|
220
|
+
defaultValue: "Restore",
|
|
221
|
+
})}
|
|
147
222
|
</TooltipContent>
|
|
148
223
|
</Tooltip>
|
|
149
224
|
) : (
|
|
@@ -154,12 +229,18 @@ export function ContextSegmentRowView({
|
|
|
154
229
|
type="button"
|
|
155
230
|
onClick={onPin}
|
|
156
231
|
className="flex size-6 items-center justify-center rounded-md text-muted-foreground hover:bg-background hover:text-foreground"
|
|
157
|
-
aria-label="
|
|
232
|
+
aria-label={translate("agentChat.contextXray.pinSegment", {
|
|
233
|
+
defaultValue: "Pin segment",
|
|
234
|
+
})}
|
|
158
235
|
>
|
|
159
236
|
<IconPin className="h-3.5 w-3.5" />
|
|
160
237
|
</button>
|
|
161
238
|
</TooltipTrigger>
|
|
162
|
-
<TooltipContent>
|
|
239
|
+
<TooltipContent>
|
|
240
|
+
{translate("agentChat.contextXray.pin", {
|
|
241
|
+
defaultValue: "Pin",
|
|
242
|
+
})}
|
|
243
|
+
</TooltipContent>
|
|
163
244
|
</Tooltip>
|
|
164
245
|
<Tooltip>
|
|
165
246
|
<TooltipTrigger asChild>
|
|
@@ -167,13 +248,21 @@ export function ContextSegmentRowView({
|
|
|
167
248
|
type="button"
|
|
168
249
|
onClick={onEvict}
|
|
169
250
|
className="flex size-6 items-center justify-center rounded-md text-muted-foreground hover:bg-background hover:text-destructive"
|
|
170
|
-
aria-label="
|
|
251
|
+
aria-label={translate("agentChat.contextXray.evictSegment", {
|
|
252
|
+
defaultValue: "Evict segment",
|
|
253
|
+
})}
|
|
171
254
|
>
|
|
172
255
|
<IconX className="h-3.5 w-3.5" />
|
|
173
256
|
</button>
|
|
174
257
|
</TooltipTrigger>
|
|
175
258
|
<TooltipContent>
|
|
176
|
-
{advisory
|
|
259
|
+
{advisory
|
|
260
|
+
? translate("agentChat.contextXray.recordEvictionIntent", {
|
|
261
|
+
defaultValue: "Record eviction intent",
|
|
262
|
+
})
|
|
263
|
+
: translate("agentChat.contextXray.evict", {
|
|
264
|
+
defaultValue: "Evict",
|
|
265
|
+
})}
|
|
177
266
|
</TooltipContent>
|
|
178
267
|
</Tooltip>
|
|
179
268
|
</>
|
|
@@ -5,7 +5,9 @@ import { contextGroupFill, formatContextTokens } from "./format.js";
|
|
|
5
5
|
import type {
|
|
6
6
|
ContextSegmentViewData,
|
|
7
7
|
ContextSystemSectionViewData,
|
|
8
|
+
ContextTranslate,
|
|
8
9
|
} from "./types.js";
|
|
10
|
+
import { fallbackContextTranslate } from "./types.js";
|
|
9
11
|
|
|
10
12
|
interface TreemapDatum {
|
|
11
13
|
name: string;
|
|
@@ -52,10 +54,12 @@ export function ContextTreemapView({
|
|
|
52
54
|
segments,
|
|
53
55
|
systemSections = [],
|
|
54
56
|
onSelect,
|
|
57
|
+
translate = fallbackContextTranslate,
|
|
55
58
|
}: {
|
|
56
59
|
segments: ContextSegmentViewData[];
|
|
57
60
|
systemSections?: ContextSystemSectionViewData[];
|
|
58
61
|
onSelect?: (segmentId: string) => void;
|
|
62
|
+
translate?: ContextTranslate;
|
|
59
63
|
}) {
|
|
60
64
|
const containerRef = useRef<HTMLDivElement>(null);
|
|
61
65
|
const [chartWidth, setChartWidth] = useState(0);
|
|
@@ -99,7 +103,9 @@ export function ContextTreemapView({
|
|
|
99
103
|
if (data.length === 0) {
|
|
100
104
|
return (
|
|
101
105
|
<div className="flex h-52 items-center justify-center rounded-md bg-muted/30 text-xs text-muted-foreground">
|
|
102
|
-
|
|
106
|
+
{translate("agentChat.contextXray.noActiveSegments", {
|
|
107
|
+
defaultValue: "No active segments",
|
|
108
|
+
})}
|
|
103
109
|
</div>
|
|
104
110
|
);
|
|
105
111
|
}
|