@agent-native/dispatch 0.12.1 → 0.12.3
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/components/dispatch-shell.d.ts.map +1 -1
- package/dist/components/dispatch-shell.js +3 -1
- package/dist/components/dispatch-shell.js.map +1 -1
- package/dist/components/layout/Layout.d.ts.map +1 -1
- package/dist/components/layout/Layout.js +39 -20
- package/dist/components/layout/Layout.js.map +1 -1
- package/dist/routes/pages/$appId.d.ts.map +1 -1
- package/dist/routes/pages/$appId.js +3 -2
- package/dist/routes/pages/$appId.js.map +1 -1
- package/dist/routes/pages/agents.d.ts.map +1 -1
- package/dist/routes/pages/agents.js +14 -8
- package/dist/routes/pages/agents.js.map +1 -1
- package/dist/routes/pages/apps.$appId.d.ts.map +1 -1
- package/dist/routes/pages/apps.$appId.js +3 -2
- package/dist/routes/pages/apps.$appId.js.map +1 -1
- package/dist/routes/pages/apps.d.ts.map +1 -1
- package/dist/routes/pages/apps.js +29 -11
- package/dist/routes/pages/apps.js.map +1 -1
- package/dist/routes/pages/destinations.d.ts.map +1 -1
- package/dist/routes/pages/destinations.js +18 -12
- package/dist/routes/pages/destinations.js.map +1 -1
- package/dist/routes/pages/metrics.d.ts.map +1 -1
- package/dist/routes/pages/metrics.js +8 -5
- package/dist/routes/pages/metrics.js.map +1 -1
- package/dist/routes/pages/new-app.d.ts.map +1 -1
- package/dist/routes/pages/new-app.js +3 -2
- package/dist/routes/pages/new-app.js.map +1 -1
- package/package.json +2 -2
- package/src/components/dispatch-shell.tsx +3 -1
- package/src/components/layout/Layout.tsx +63 -28
- package/src/routes/pages/$appId.tsx +15 -12
- package/src/routes/pages/agents.tsx +21 -14
- package/src/routes/pages/apps.$appId.tsx +15 -14
- package/src/routes/pages/apps.tsx +41 -20
- package/src/routes/pages/destinations.tsx +35 -24
- package/src/routes/pages/metrics.tsx +13 -10
- package/src/routes/pages/new-app.tsx +4 -3
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { useState } from "react";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
useActionMutation,
|
|
4
|
+
useActionQuery,
|
|
5
|
+
useT,
|
|
6
|
+
} from "@agent-native/core/client";
|
|
3
7
|
import {
|
|
4
8
|
IconApps,
|
|
5
9
|
IconBrain,
|
|
@@ -71,6 +75,7 @@ const TEMPLATE_ICONS: Record<string, typeof IconMail> = {
|
|
|
71
75
|
};
|
|
72
76
|
|
|
73
77
|
export default function AppsRoute() {
|
|
78
|
+
const t = useT();
|
|
74
79
|
const [showHidden, setShowHidden] = useState(false);
|
|
75
80
|
const [templatesOpen, setTemplatesOpen] = useState(false);
|
|
76
81
|
const { data: apps = [], isLoading: appsLoading } = useActionQuery(
|
|
@@ -103,11 +108,13 @@ export default function AppsRoute() {
|
|
|
103
108
|
|
|
104
109
|
return (
|
|
105
110
|
<DispatchShell
|
|
106
|
-
title="
|
|
111
|
+
title={t("dispatch.nav.apps")}
|
|
107
112
|
description={
|
|
108
113
|
workspaceLabel
|
|
109
|
-
?
|
|
110
|
-
|
|
114
|
+
? t("dispatch.pages.appsDescriptionWithWorkspace", {
|
|
115
|
+
workspace: workspaceLabel,
|
|
116
|
+
})
|
|
117
|
+
: t("dispatch.pages.appsDescription")
|
|
111
118
|
}
|
|
112
119
|
>
|
|
113
120
|
<div className="space-y-8">
|
|
@@ -121,13 +128,19 @@ export default function AppsRoute() {
|
|
|
121
128
|
<div className="min-w-0">
|
|
122
129
|
<h2 className="truncate text-sm font-semibold text-foreground">
|
|
123
130
|
{workspaceLabel
|
|
124
|
-
?
|
|
125
|
-
|
|
131
|
+
? t("dispatch.pages.appsInWorkspace", {
|
|
132
|
+
workspace: workspaceLabel,
|
|
133
|
+
})
|
|
134
|
+
: t("dispatch.pages.workspaceApps")}
|
|
126
135
|
</h2>
|
|
127
136
|
<p className="mt-0.5 text-xs text-muted-foreground">
|
|
128
|
-
{
|
|
137
|
+
{t("dispatch.pages.activeCount", {
|
|
138
|
+
count: visibleApps.length,
|
|
139
|
+
})}
|
|
129
140
|
{archivedApps.length > 0
|
|
130
|
-
? ` · ${
|
|
141
|
+
? ` · ${t("dispatch.pages.hiddenCount", {
|
|
142
|
+
count: archivedApps.length,
|
|
143
|
+
})}`
|
|
131
144
|
: ""}
|
|
132
145
|
</p>
|
|
133
146
|
</div>
|
|
@@ -138,7 +151,7 @@ export default function AppsRoute() {
|
|
|
138
151
|
trigger={
|
|
139
152
|
<Button size="sm">
|
|
140
153
|
<IconPlus size={15} className="mr-1.5" />
|
|
141
|
-
|
|
154
|
+
{t("dispatch.pages.createApp")}
|
|
142
155
|
</Button>
|
|
143
156
|
}
|
|
144
157
|
/>
|
|
@@ -169,12 +182,14 @@ export default function AppsRoute() {
|
|
|
169
182
|
/>
|
|
170
183
|
<div className="min-w-0">
|
|
171
184
|
<h2 className="text-sm font-semibold text-foreground">
|
|
172
|
-
|
|
185
|
+
{t("dispatch.pages.templates")}
|
|
173
186
|
</h2>
|
|
174
187
|
<p className="text-xs text-muted-foreground">
|
|
175
188
|
{templatesLoading
|
|
176
|
-
? "
|
|
177
|
-
:
|
|
189
|
+
? t("dispatch.pages.checkingTemplates")
|
|
190
|
+
: t("dispatch.pages.templatesAvailable", {
|
|
191
|
+
count: typedTemplates.length,
|
|
192
|
+
})}
|
|
178
193
|
</p>
|
|
179
194
|
</div>
|
|
180
195
|
</div>
|
|
@@ -185,7 +200,9 @@ export default function AppsRoute() {
|
|
|
185
200
|
size="sm"
|
|
186
201
|
className="gap-1.5"
|
|
187
202
|
>
|
|
188
|
-
{templatesOpen
|
|
203
|
+
{templatesOpen
|
|
204
|
+
? t("dispatch.pages.hide")
|
|
205
|
+
: t("dispatch.pages.show")}
|
|
189
206
|
<IconChevronDown
|
|
190
207
|
size={14}
|
|
191
208
|
className={cn(
|
|
@@ -225,11 +242,12 @@ export default function AppsRoute() {
|
|
|
225
242
|
/>
|
|
226
243
|
<div className="min-w-0">
|
|
227
244
|
<h2 className="text-sm font-semibold text-foreground">
|
|
228
|
-
|
|
245
|
+
{t("dispatch.pages.hiddenApps")}
|
|
229
246
|
</h2>
|
|
230
247
|
<p className="text-xs text-muted-foreground">
|
|
231
|
-
{
|
|
232
|
-
|
|
248
|
+
{t("dispatch.pages.hiddenAppCount", {
|
|
249
|
+
count: archivedApps.length,
|
|
250
|
+
})}
|
|
233
251
|
</p>
|
|
234
252
|
</div>
|
|
235
253
|
</div>
|
|
@@ -240,7 +258,9 @@ export default function AppsRoute() {
|
|
|
240
258
|
size="sm"
|
|
241
259
|
className="gap-1.5"
|
|
242
260
|
>
|
|
243
|
-
{showHidden
|
|
261
|
+
{showHidden
|
|
262
|
+
? t("dispatch.pages.hide")
|
|
263
|
+
: t("dispatch.pages.show")}
|
|
244
264
|
<IconChevronDown
|
|
245
265
|
size={14}
|
|
246
266
|
className={cn(
|
|
@@ -293,23 +313,24 @@ function AppsSkeletonGrid() {
|
|
|
293
313
|
}
|
|
294
314
|
|
|
295
315
|
function EmptyAppsState() {
|
|
316
|
+
const t = useT();
|
|
296
317
|
return (
|
|
297
318
|
<div className="rounded-lg border border-dashed bg-card px-4 py-10 text-center">
|
|
298
319
|
<div className="mx-auto flex size-10 items-center justify-center rounded-lg bg-muted text-muted-foreground">
|
|
299
320
|
<IconApps size={18} />
|
|
300
321
|
</div>
|
|
301
322
|
<h3 className="mt-3 text-sm font-semibold text-foreground">
|
|
302
|
-
|
|
323
|
+
{t("dispatch.pages.noWorkspaceApps")}
|
|
303
324
|
</h3>
|
|
304
325
|
<p className="mx-auto mt-1 max-w-sm text-sm text-muted-foreground">
|
|
305
|
-
|
|
326
|
+
{t("dispatch.pages.noWorkspaceAppsDescription")}
|
|
306
327
|
</p>
|
|
307
328
|
<div className="mt-4">
|
|
308
329
|
<CreateAppPopover
|
|
309
330
|
trigger={
|
|
310
331
|
<Button size="sm">
|
|
311
332
|
<IconPlus size={15} className="mr-1.5" />
|
|
312
|
-
|
|
333
|
+
{t("dispatch.pages.createApp")}
|
|
313
334
|
</Button>
|
|
314
335
|
}
|
|
315
336
|
/>
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { useState } from "react";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
useActionMutation,
|
|
4
|
+
useActionQuery,
|
|
5
|
+
useT,
|
|
6
|
+
} from "@agent-native/core/client";
|
|
3
7
|
import { toast } from "sonner";
|
|
4
8
|
import { DispatchShell } from "@/components/dispatch-shell";
|
|
5
9
|
import { Button } from "@/components/ui/button";
|
|
@@ -33,15 +37,18 @@ function QuickSendRow({
|
|
|
33
37
|
}: {
|
|
34
38
|
destination: { id: string; name: string };
|
|
35
39
|
}) {
|
|
40
|
+
const t = useT();
|
|
36
41
|
const [text, setText] = useState("");
|
|
37
42
|
const send = useActionMutation("send-platform-message", {
|
|
38
43
|
onSuccess: () => {
|
|
39
|
-
toast.success("
|
|
44
|
+
toast.success(t("dispatch.pages.messageSent"));
|
|
40
45
|
setText("");
|
|
41
46
|
},
|
|
42
47
|
onError: (error) => {
|
|
43
48
|
toast.error(
|
|
44
|
-
error instanceof Error
|
|
49
|
+
error instanceof Error
|
|
50
|
+
? error.message
|
|
51
|
+
: t("dispatch.pages.unableToSendMessage"),
|
|
45
52
|
);
|
|
46
53
|
},
|
|
47
54
|
});
|
|
@@ -50,7 +57,7 @@ function QuickSendRow({
|
|
|
50
57
|
<Input
|
|
51
58
|
value={text}
|
|
52
59
|
onChange={(event) => setText(event.target.value)}
|
|
53
|
-
placeholder="
|
|
60
|
+
placeholder={t("dispatch.pages.quickTestMessage")}
|
|
54
61
|
/>
|
|
55
62
|
<Button
|
|
56
63
|
onClick={() =>
|
|
@@ -61,13 +68,14 @@ function QuickSendRow({
|
|
|
61
68
|
}
|
|
62
69
|
disabled={send.isPending}
|
|
63
70
|
>
|
|
64
|
-
|
|
71
|
+
{t("dispatch.pages.send")}
|
|
65
72
|
</Button>
|
|
66
73
|
</div>
|
|
67
74
|
);
|
|
68
75
|
}
|
|
69
76
|
|
|
70
77
|
export default function DestinationsRoute() {
|
|
78
|
+
const t = useT();
|
|
71
79
|
const { data } = useActionQuery("list-destinations", {});
|
|
72
80
|
const [form, setForm] = useState({
|
|
73
81
|
name: "",
|
|
@@ -79,7 +87,7 @@ export default function DestinationsRoute() {
|
|
|
79
87
|
|
|
80
88
|
const upsert = useActionMutation("upsert-destination", {
|
|
81
89
|
onSuccess: () => {
|
|
82
|
-
toast.success("
|
|
90
|
+
toast.success(t("dispatch.pages.destinationSaved"));
|
|
83
91
|
setForm((current) => ({
|
|
84
92
|
...current,
|
|
85
93
|
name: "",
|
|
@@ -90,18 +98,18 @@ export default function DestinationsRoute() {
|
|
|
90
98
|
},
|
|
91
99
|
});
|
|
92
100
|
const remove = useActionMutation("delete-destination", {
|
|
93
|
-
onSuccess: () => toast.success("
|
|
101
|
+
onSuccess: () => toast.success(t("dispatch.pages.destinationRemoved")),
|
|
94
102
|
});
|
|
95
103
|
|
|
96
104
|
return (
|
|
97
105
|
<DispatchShell
|
|
98
|
-
title="
|
|
99
|
-
description="
|
|
106
|
+
title={t("dispatch.nav.destinations")}
|
|
107
|
+
description={t("dispatch.pages.destinationsDescription")}
|
|
100
108
|
>
|
|
101
109
|
<div className="grid gap-4 xl:grid-cols-[minmax(0,1.1fr)_minmax(0,0.9fr)]">
|
|
102
110
|
<section className="rounded-2xl border bg-card p-5">
|
|
103
111
|
<h2 className="text-lg font-semibold text-foreground">
|
|
104
|
-
|
|
112
|
+
{t("dispatch.pages.savedDestinations")}
|
|
105
113
|
</h2>
|
|
106
114
|
<div className="mt-4 space-y-3">
|
|
107
115
|
{(data || []).map((destination: any) => (
|
|
@@ -129,24 +137,28 @@ export default function DestinationsRoute() {
|
|
|
129
137
|
<AlertDialog>
|
|
130
138
|
<AlertDialogTrigger asChild>
|
|
131
139
|
<Button variant="outline" size="sm">
|
|
132
|
-
|
|
140
|
+
{t("dispatch.pages.delete")}
|
|
133
141
|
</Button>
|
|
134
142
|
</AlertDialogTrigger>
|
|
135
143
|
<AlertDialogContent>
|
|
136
144
|
<AlertDialogHeader>
|
|
137
|
-
<AlertDialogTitle>
|
|
145
|
+
<AlertDialogTitle>
|
|
146
|
+
{t("dispatch.pages.deleteDestinationTitle")}
|
|
147
|
+
</AlertDialogTitle>
|
|
138
148
|
<AlertDialogDescription>
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
149
|
+
{t("dispatch.pages.deleteDestinationDescription", {
|
|
150
|
+
name: destination.name,
|
|
151
|
+
})}
|
|
142
152
|
</AlertDialogDescription>
|
|
143
153
|
</AlertDialogHeader>
|
|
144
154
|
<AlertDialogFooter>
|
|
145
|
-
<AlertDialogCancel>
|
|
155
|
+
<AlertDialogCancel>
|
|
156
|
+
{t("dispatch.pages.cancel")}
|
|
157
|
+
</AlertDialogCancel>
|
|
146
158
|
<AlertDialogAction
|
|
147
159
|
onClick={() => remove.mutate({ id: destination.id })}
|
|
148
160
|
>
|
|
149
|
-
|
|
161
|
+
{t("dispatch.pages.delete")}
|
|
150
162
|
</AlertDialogAction>
|
|
151
163
|
</AlertDialogFooter>
|
|
152
164
|
</AlertDialogContent>
|
|
@@ -157,8 +169,7 @@ export default function DestinationsRoute() {
|
|
|
157
169
|
))}
|
|
158
170
|
{(data?.length || 0) === 0 && (
|
|
159
171
|
<div className="rounded-xl border border-dashed px-4 py-8 text-sm text-muted-foreground">
|
|
160
|
-
|
|
161
|
-
Telegram chat on the right.
|
|
172
|
+
{t("dispatch.pages.noDestinations")}
|
|
162
173
|
</div>
|
|
163
174
|
)}
|
|
164
175
|
</div>
|
|
@@ -166,7 +177,7 @@ export default function DestinationsRoute() {
|
|
|
166
177
|
|
|
167
178
|
<section className="rounded-2xl border bg-card p-5">
|
|
168
179
|
<h2 className="text-lg font-semibold text-foreground">
|
|
169
|
-
|
|
180
|
+
{t("dispatch.pages.addDestination")}
|
|
170
181
|
</h2>
|
|
171
182
|
<div className="mt-4 space-y-3">
|
|
172
183
|
<Input
|
|
@@ -174,7 +185,7 @@ export default function DestinationsRoute() {
|
|
|
174
185
|
onChange={(event) =>
|
|
175
186
|
setForm((current) => ({ ...current, name: event.target.value }))
|
|
176
187
|
}
|
|
177
|
-
placeholder="
|
|
188
|
+
placeholder={t("dispatch.pages.dailyDigestChannel")}
|
|
178
189
|
/>
|
|
179
190
|
<Select
|
|
180
191
|
value={form.platform}
|
|
@@ -218,7 +229,7 @@ export default function DestinationsRoute() {
|
|
|
218
229
|
threadRef: event.target.value,
|
|
219
230
|
}))
|
|
220
231
|
}
|
|
221
|
-
placeholder="
|
|
232
|
+
placeholder={t("dispatch.pages.optionalThreadOrTopicId")}
|
|
222
233
|
/>
|
|
223
234
|
<Textarea
|
|
224
235
|
value={form.notes}
|
|
@@ -228,7 +239,7 @@ export default function DestinationsRoute() {
|
|
|
228
239
|
notes: event.target.value,
|
|
229
240
|
}))
|
|
230
241
|
}
|
|
231
|
-
placeholder="
|
|
242
|
+
placeholder={t("dispatch.pages.destinationNotes")}
|
|
232
243
|
/>
|
|
233
244
|
<Button
|
|
234
245
|
className="w-full"
|
|
@@ -243,7 +254,7 @@ export default function DestinationsRoute() {
|
|
|
243
254
|
}
|
|
244
255
|
disabled={!form.name || !form.destination}
|
|
245
256
|
>
|
|
246
|
-
|
|
257
|
+
{t("dispatch.pages.saveDestination")}
|
|
247
258
|
</Button>
|
|
248
259
|
</div>
|
|
249
260
|
</section>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useMemo, useState, type ReactNode } from "react";
|
|
2
|
-
import { useActionQuery } from "@agent-native/core/client";
|
|
2
|
+
import { useActionQuery, useT } from "@agent-native/core/client";
|
|
3
3
|
import {
|
|
4
4
|
IconActivity,
|
|
5
5
|
IconAlertTriangle,
|
|
@@ -637,6 +637,7 @@ function RecentTable({
|
|
|
637
637
|
}
|
|
638
638
|
|
|
639
639
|
export default function MetricsRoute() {
|
|
640
|
+
const t = useT();
|
|
640
641
|
const [sinceDays, setSinceDays] = useState(30);
|
|
641
642
|
const { data, isLoading, error } = useActionQuery(
|
|
642
643
|
"list-dispatch-usage-metrics",
|
|
@@ -657,11 +658,11 @@ export default function MetricsRoute() {
|
|
|
657
658
|
|
|
658
659
|
return (
|
|
659
660
|
<DispatchShell
|
|
660
|
-
title="
|
|
661
|
+
title={t("dispatch.nav.metrics")}
|
|
661
662
|
description={
|
|
662
663
|
billing.unit === "builder-credits"
|
|
663
|
-
? "
|
|
664
|
-
: "
|
|
664
|
+
? t("dispatch.pages.metricsDescriptionBuilder")
|
|
665
|
+
: t("dispatch.pages.metricsDescriptionLlm")
|
|
665
666
|
}
|
|
666
667
|
>
|
|
667
668
|
<div className="space-y-4">
|
|
@@ -677,9 +678,11 @@ export default function MetricsRoute() {
|
|
|
677
678
|
{error ? (
|
|
678
679
|
<Alert variant="destructive">
|
|
679
680
|
<IconAlertTriangle className="h-4 w-4" />
|
|
680
|
-
<AlertTitle>
|
|
681
|
+
<AlertTitle>{t("dispatch.pages.metricsUnavailable")}</AlertTitle>
|
|
681
682
|
<AlertDescription>
|
|
682
|
-
{error instanceof Error
|
|
683
|
+
{error instanceof Error
|
|
684
|
+
? error.message
|
|
685
|
+
: t("dispatch.pages.unableToLoadUsage")}
|
|
683
686
|
</AlertDescription>
|
|
684
687
|
</Alert>
|
|
685
688
|
) : null}
|
|
@@ -696,25 +699,25 @@ export default function MetricsRoute() {
|
|
|
696
699
|
icon={<IconCoin size={17} />}
|
|
697
700
|
/>
|
|
698
701
|
<MetricCard
|
|
699
|
-
label="
|
|
702
|
+
label={t("dispatch.pages.llmCalls")}
|
|
700
703
|
value={formatNumber(metrics.totals.calls)}
|
|
701
704
|
detail={`${formatNumber(metrics.totals.chatCalls)} chat turns`}
|
|
702
705
|
icon={<IconActivity size={17} />}
|
|
703
706
|
/>
|
|
704
707
|
<MetricCard
|
|
705
|
-
label="
|
|
708
|
+
label={t("dispatch.pages.activeUsers")}
|
|
706
709
|
value={formatNumber(metrics.totals.activeUsers)}
|
|
707
710
|
detail={`${formatNumber(metrics.access.totalUsers)} users with access`}
|
|
708
711
|
icon={<IconUsersGroup size={17} />}
|
|
709
712
|
/>
|
|
710
713
|
<MetricCard
|
|
711
|
-
label="
|
|
714
|
+
label={t("dispatch.pages.workspaceAppsStat")}
|
|
712
715
|
value={formatNumber(metrics.totals.workspaceApps)}
|
|
713
716
|
detail={`${formatNumber(metrics.byApp.length)} with usage`}
|
|
714
717
|
icon={<IconApps size={17} />}
|
|
715
718
|
/>
|
|
716
719
|
<MetricCard
|
|
717
|
-
label="
|
|
720
|
+
label={t("dispatch.pages.chatThreads")}
|
|
718
721
|
value={formatNumber(metrics.totals.chatThreads)}
|
|
719
722
|
detail={`${formatNumber(metrics.totals.chatMessages)} messages`}
|
|
720
723
|
icon={<IconMessages size={17} />}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { NewWorkspaceAppFlow } from "@agent-native/core/client";
|
|
1
|
+
import { NewWorkspaceAppFlow, useT } from "@agent-native/core/client";
|
|
2
2
|
import { DispatchShell } from "@/components/dispatch-shell";
|
|
3
3
|
|
|
4
4
|
export function meta() {
|
|
@@ -6,10 +6,11 @@ export function meta() {
|
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
export default function NewAppRoute() {
|
|
9
|
+
const t = useT();
|
|
9
10
|
return (
|
|
10
11
|
<DispatchShell
|
|
11
|
-
title="
|
|
12
|
-
description="
|
|
12
|
+
title={t("dispatch.pages.newApp")}
|
|
13
|
+
description={t("dispatch.pages.newAppDescription")}
|
|
13
14
|
>
|
|
14
15
|
<NewWorkspaceAppFlow sourceApp="dispatch" className="px-0 py-0" />
|
|
15
16
|
</DispatchShell>
|