@nocobase/app-plugin-agents 1.0.0-beta.18 → 1.0.0-beta.20
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/CHANGELOG.md +46 -0
- package/README.md +19 -1
- package/dist/client/api/client.d.ts +29 -1
- package/dist/client/api/client.d.ts.map +1 -1
- package/dist/client/api/client.js +40 -0
- package/dist/client/api/client.js.map +1 -1
- package/dist/client/api/keys.d.ts +8 -0
- package/dist/client/api/keys.d.ts.map +1 -1
- package/dist/client/api/keys.js +19 -0
- package/dist/client/api/keys.js.map +1 -1
- package/dist/client/chat/message-model.js +1 -1
- package/dist/client/chat/message-model.js.map +1 -1
- package/dist/client/locales/de-DE.d.ts.map +1 -1
- package/dist/client/locales/de-DE.js +93 -3
- package/dist/client/locales/de-DE.js.map +1 -1
- package/dist/client/locales/en-US.d.ts +80 -2
- package/dist/client/locales/en-US.d.ts.map +1 -1
- package/dist/client/locales/en-US.js +81 -3
- package/dist/client/locales/en-US.js.map +1 -1
- package/dist/client/locales/es-ES.d.ts.map +1 -1
- package/dist/client/locales/es-ES.js +102 -3
- package/dist/client/locales/es-ES.js.map +1 -1
- package/dist/client/locales/fr-FR.d.ts.map +1 -1
- package/dist/client/locales/fr-FR.js +102 -3
- package/dist/client/locales/fr-FR.js.map +1 -1
- package/dist/client/locales/id-ID.d.ts.map +1 -1
- package/dist/client/locales/id-ID.js +93 -3
- package/dist/client/locales/id-ID.js.map +1 -1
- package/dist/client/locales/ja-JP.d.ts.map +1 -1
- package/dist/client/locales/ja-JP.js +93 -3
- package/dist/client/locales/ja-JP.js.map +1 -1
- package/dist/client/locales/pt-BR.d.ts.map +1 -1
- package/dist/client/locales/pt-BR.js +102 -3
- package/dist/client/locales/pt-BR.js.map +1 -1
- package/dist/client/locales/runtimes.en-US.d.ts +12 -0
- package/dist/client/locales/runtimes.en-US.d.ts.map +1 -1
- package/dist/client/locales/runtimes.en-US.js +15 -3
- package/dist/client/locales/runtimes.en-US.js.map +1 -1
- package/dist/client/locales/runtimes.zh-CN.d.ts.map +1 -1
- package/dist/client/locales/runtimes.zh-CN.js +14 -2
- package/dist/client/locales/runtimes.zh-CN.js.map +1 -1
- package/dist/client/locales/vi-VN.d.ts.map +1 -1
- package/dist/client/locales/vi-VN.js +93 -3
- package/dist/client/locales/vi-VN.js.map +1 -1
- package/dist/client/locales/zh-CN.d.ts.map +1 -1
- package/dist/client/locales/zh-CN.js +81 -3
- package/dist/client/locales/zh-CN.js.map +1 -1
- package/dist/client/locales/zh-TW.d.ts.map +1 -1
- package/dist/client/locales/zh-TW.js +93 -3
- package/dist/client/locales/zh-TW.js.map +1 -1
- package/dist/client/pages/agents/agent-dialog.js +1 -1
- package/dist/client/pages/agents/agent-dialog.js.map +1 -1
- package/dist/client/pages/agents/available-models-drawer.d.ts +7 -0
- package/dist/client/pages/agents/available-models-drawer.d.ts.map +1 -0
- package/dist/client/pages/agents/available-models-drawer.js +330 -0
- package/dist/client/pages/agents/available-models-drawer.js.map +1 -0
- package/dist/client/pages/agents/cleanup-drawer.d.ts +7 -0
- package/dist/client/pages/agents/cleanup-drawer.d.ts.map +1 -0
- package/dist/client/pages/agents/cleanup-drawer.js +214 -0
- package/dist/client/pages/agents/cleanup-drawer.js.map +1 -0
- package/dist/client/pages/agents/runner-agents.d.ts.map +1 -1
- package/dist/client/pages/agents/runner-agents.js +21 -111
- package/dist/client/pages/agents/runner-agents.js.map +1 -1
- package/dist/client/pages/runtimes/connect.d.ts.map +1 -1
- package/dist/client/pages/runtimes/connect.js +5 -6
- package/dist/client/pages/runtimes/connect.js.map +1 -1
- package/dist/client/pages/runtimes/index.js +1 -1
- package/dist/client/pages/runtimes/index.js.map +1 -1
- package/dist/client/pages/runtimes/quota.d.ts +1 -1
- package/dist/client/pages/runtimes/quota.d.ts.map +1 -1
- package/dist/client/pages/runtimes/quota.js +4 -1
- package/dist/client/pages/runtimes/quota.js.map +1 -1
- package/dist/client/pages/runtimes/runner-cells.d.ts +1 -1
- package/dist/client/pages/runtimes/runner-cells.d.ts.map +1 -1
- package/dist/client/pages/runtimes/runner-cells.js +34 -8
- package/dist/client/pages/runtimes/runner-cells.js.map +1 -1
- package/dist/client/pages/runtimes/runner-overview.d.ts.map +1 -1
- package/dist/client/pages/runtimes/runner-overview.js +6 -8
- package/dist/client/pages/runtimes/runner-overview.js.map +1 -1
- package/dist/client/pages/runtimes/runner-sheet.js +3 -1
- package/dist/client/pages/runtimes/runner-sheet.js.map +1 -1
- package/dist/client/pages/runtimes/runner-tools.d.ts.map +1 -1
- package/dist/client/pages/runtimes/runner-tools.js +4 -6
- package/dist/client/pages/runtimes/runner-tools.js.map +1 -1
- package/dist/database/migrations/.manifest.json +4 -0
- package/dist/database/migrations/202610280001_ag_explicit_runner_tools.d.ts +5 -0
- package/dist/database/migrations/202610280001_ag_explicit_runner_tools.d.ts.map +1 -0
- package/dist/database/migrations/202610280001_ag_explicit_runner_tools.js +23 -0
- package/dist/database/migrations/202610280001_ag_explicit_runner_tools.js.map +1 -0
- package/dist/package.json +4 -2
- package/dist/server/core/agents/agent.history.d.ts +2 -0
- package/dist/server/core/agents/agent.history.d.ts.map +1 -1
- package/dist/server/core/agents/agent.history.js +4 -0
- package/dist/server/core/agents/agent.history.js.map +1 -1
- package/dist/server/core/agents/agent.service.d.ts +43 -1
- package/dist/server/core/agents/agent.service.d.ts.map +1 -1
- package/dist/server/core/agents/agent.service.js +207 -26
- package/dist/server/core/agents/agent.service.js.map +1 -1
- package/dist/server/core/agents/agent.store.d.ts +2 -0
- package/dist/server/core/agents/agent.store.d.ts.map +1 -1
- package/dist/server/core/agents/agent.store.js +4 -0
- package/dist/server/core/agents/agent.store.js.map +1 -1
- package/dist/server/core/agents/available-models.d.ts +41 -0
- package/dist/server/core/agents/available-models.d.ts.map +1 -0
- package/dist/server/core/agents/available-models.js +225 -0
- package/dist/server/core/agents/available-models.js.map +1 -0
- package/dist/server/core/agents/index.d.ts +1 -0
- package/dist/server/core/agents/index.d.ts.map +1 -1
- package/dist/server/core/agents/index.js +1 -0
- package/dist/server/core/agents/index.js.map +1 -1
- package/dist/server/core/runs/claim.d.ts.map +1 -1
- package/dist/server/core/runs/claim.js +3 -3
- package/dist/server/core/runs/claim.js.map +1 -1
- package/dist/server/core/runs/ports.d.ts +2 -0
- package/dist/server/core/runs/ports.d.ts.map +1 -1
- package/dist/server/core/runs/ports.js.map +1 -1
- package/dist/server/core/runs/preview.d.ts.map +1 -1
- package/dist/server/core/runs/preview.js +1 -0
- package/dist/server/core/runs/preview.js.map +1 -1
- package/dist/server/core/runs/run.service.d.ts +1 -1
- package/dist/server/core/runs/run.service.d.ts.map +1 -1
- package/dist/server/core/runs/run.service.js +17 -2
- package/dist/server/core/runs/run.service.js.map +1 -1
- package/dist/server/core/runs/run.store.d.ts.map +1 -1
- package/dist/server/core/runs/run.store.js +1 -0
- package/dist/server/core/runs/run.store.js.map +1 -1
- package/dist/server/core/runs/transitions.d.ts +1 -1
- package/dist/server/core/runs/transitions.d.ts.map +1 -1
- package/dist/server/core/runs/workload.d.ts.map +1 -1
- package/dist/server/core/runs/workload.js +2 -1
- package/dist/server/core/runs/workload.js.map +1 -1
- package/dist/server/online/agent/messages/projection.d.ts.map +1 -1
- package/dist/server/online/agent/messages/projection.js +4 -0
- package/dist/server/online/agent/messages/projection.js.map +1 -1
- package/dist/server/routes/admin.d.ts.map +1 -1
- package/dist/server/routes/admin.js +133 -2
- package/dist/server/routes/admin.js.map +1 -1
- package/dist/server/routes/runners/admin.d.ts.map +1 -1
- package/dist/server/routes/runners/admin.js +27 -18
- package/dist/server/routes/runners/admin.js.map +1 -1
- package/dist/server/routes/runners/runner.d.ts.map +1 -1
- package/dist/server/routes/runners/runner.js +5 -0
- package/dist/server/routes/runners/runner.js.map +1 -1
- package/dist/server/routes/runners/runs.d.ts.map +1 -1
- package/dist/server/routes/runners/runs.js +9 -3
- package/dist/server/routes/runners/runs.js.map +1 -1
- package/dist/server/routes/schemas.d.ts +35 -2
- package/dist/server/routes/schemas.d.ts.map +1 -1
- package/dist/server/routes/schemas.js +146 -5
- package/dist/server/routes/schemas.js.map +1 -1
- package/dist/server/runners/runner.service.d.ts +1 -2
- package/dist/server/runners/runner.service.d.ts.map +1 -1
- package/dist/server/runners/runner.service.js +36 -16
- package/dist/server/runners/runner.service.js.map +1 -1
- package/dist/server/runners/runner.store.d.ts +1 -1
- package/dist/server/runners/runner.store.d.ts.map +1 -1
- package/dist/server/runners/runner.store.js +15 -4
- package/dist/server/runners/runner.store.js.map +1 -1
- package/dist/server/runners/tool-detection.d.ts +3 -0
- package/dist/server/runners/tool-detection.d.ts.map +1 -0
- package/dist/server/runners/tool-detection.js +9 -0
- package/dist/server/runners/tool-detection.js.map +1 -0
- package/dist/shared/agents.d.ts +114 -0
- package/dist/shared/agents.d.ts.map +1 -1
- package/dist/shared/agents.js +16 -1
- package/dist/shared/agents.js.map +1 -1
- package/dist/shared/model-catalog.d.ts +14 -2
- package/dist/shared/model-catalog.d.ts.map +1 -1
- package/dist/shared/model-catalog.js +46 -2
- package/dist/shared/model-catalog.js.map +1 -1
- package/dist/shared/runners.d.ts +20 -14
- package/dist/shared/runners.d.ts.map +1 -1
- package/dist/shared/runners.js +21 -11
- package/dist/shared/runners.js.map +1 -1
- package/dist/shared/runs.d.ts +1 -0
- package/dist/shared/runs.d.ts.map +1 -1
- package/dist/shared/runs.js.map +1 -1
- package/docs/ui-message-clients.md +3 -1
- package/docs/ui-messages.md +3 -1
- package/package.json +13 -11
- package/skills/nocobase-app-plugin-agents/SKILL.md +3 -1
- package/skills/nocobase-app-plugin-agents/references/extension-points.md +2 -0
- package/skills/nocobase-app-plugin-agents/references/online-agent.md +2 -0
- package/skills/nocobase-app-plugin-agents/references/runners.md +4 -0
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Every tool a runner has selected, grouped so a tool reporting hundreds of models (the discovery bug this replaced)
|
|
4
|
+
* reads as one collapsed row until someone opens it: add an agent from a model that has none, or see the state of
|
|
5
|
+
* one that already does. A large drawer, not a dialog, because the group list and a tool's own models can be long —
|
|
6
|
+
* a combined search (tool and model name), a status filter defaulting to "Available", per-tool collapse (open by
|
|
7
|
+
* default under `DEFAULT_EXPAND_THRESHOLD` models, with its own search once expanded), multi-select across pages and
|
|
8
|
+
* a sticky "Add" bar that opens a second step to confirm what each selected model is good at before creating
|
|
9
|
+
* anything. The application's recommended combinations never show a checkbox here: a runner reporting one signed in
|
|
10
|
+
* creates and enables it on its own. Only the tools a runtime has checked are ever detected, so a tool nobody checked
|
|
11
|
+
* never appears in this list at all.
|
|
12
|
+
*/
|
|
13
|
+
import { CheckIcon } from 'lucide-react';
|
|
14
|
+
import { useTranslation } from '@nocobase/i18n/client';
|
|
15
|
+
import { useInfiniteQuery, useMutation, useQueries, useQueryClient, } from '@tanstack/react-query';
|
|
16
|
+
import { useMemo, useRef, useState } from 'react';
|
|
17
|
+
import { Virtuoso } from 'react-virtuoso';
|
|
18
|
+
import { agentNameOf, TOOL_LABELS, TOOL_SIGN_IN, } from '../../../shared/model-catalog.js';
|
|
19
|
+
import { modelSuggestion } from '../../model-suggestion.js';
|
|
20
|
+
import { agentsKeys } from '../../api/keys.js';
|
|
21
|
+
import { AgListSkeleton, AgLoadError } from '../../components/ag-states.js';
|
|
22
|
+
import { AgTag } from '../../components/ag-tag.js';
|
|
23
|
+
import { Button } from '../../components/ui/button.js';
|
|
24
|
+
import { Checkbox } from '../../components/ui/checkbox.js';
|
|
25
|
+
import { Collapsible, CollapsibleContent, CollapsibleTrigger, } from '../../components/ui/collapsible.js';
|
|
26
|
+
import { Field, FieldError, FieldLabel } from '../../components/ui/field.js';
|
|
27
|
+
import { Input } from '../../components/ui/input.js';
|
|
28
|
+
import { Sheet, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, } from '../../components/ui/sheet.js';
|
|
29
|
+
import { Textarea } from '../../components/ui/textarea.js';
|
|
30
|
+
import { useAgentsApi } from '../../hooks/use-agents-api.js';
|
|
31
|
+
import { errorText, useNotify } from '../../hooks/use-notify.js';
|
|
32
|
+
/** Exactly the drawer's four filter buttons. */
|
|
33
|
+
const STATUS_FILTERS = [
|
|
34
|
+
'available',
|
|
35
|
+
'needsSetup',
|
|
36
|
+
'versionTooOld',
|
|
37
|
+
'failed',
|
|
38
|
+
];
|
|
39
|
+
/** A group with this many models or fewer starts open; a larger one starts collapsed. */
|
|
40
|
+
const DEFAULT_EXPAND_THRESHOLD = 10;
|
|
41
|
+
/** Rows loaded past this count in one group switch from a plain list to a virtualized one. */
|
|
42
|
+
const VIRTUALIZE_THRESHOLD = 30;
|
|
43
|
+
const PAGE_SIZE = 50;
|
|
44
|
+
/** A reason or detail line longer than this starts collapsed, with a toggle to read the rest. */
|
|
45
|
+
const REASON_CLAMP_LENGTH = 160;
|
|
46
|
+
const STATUS_TONE = {
|
|
47
|
+
available: 'green',
|
|
48
|
+
needsSetup: 'amber',
|
|
49
|
+
versionTooOld: 'amber',
|
|
50
|
+
failed: 'red',
|
|
51
|
+
};
|
|
52
|
+
function rowKey(tool, model) {
|
|
53
|
+
return `${tool}\u0000${model}`;
|
|
54
|
+
}
|
|
55
|
+
/** Setup actions and diagnostic output have different jobs: keep the command visible once, with raw output opt-in. */
|
|
56
|
+
function SetupGuidance({ group, }) {
|
|
57
|
+
const { t } = useTranslation();
|
|
58
|
+
const command = TOOL_SIGN_IN[group.tool];
|
|
59
|
+
if (group.status !== 'needsSetup')
|
|
60
|
+
return (_jsx(ExpandableText, { text: (group.statusDetail ??
|
|
61
|
+
t(group.status === 'versionTooOld'
|
|
62
|
+
? 'agents.available.minimumVersionUnknown'
|
|
63
|
+
: 'agents.available.noDetail')) +
|
|
64
|
+
(group.status === 'versionTooOld'
|
|
65
|
+
? ' ' + t('agents.available.upgradeAdvice')
|
|
66
|
+
: '') }));
|
|
67
|
+
const [before, after] = t('agents.available.setupCommand', {
|
|
68
|
+
command: '\u0000',
|
|
69
|
+
}).split('\u0000');
|
|
70
|
+
return (_jsxs("div", { className: 'space-y-2 pt-3 text-sm text-muted-foreground', children: [_jsx("p", { children: command ? (_jsxs(_Fragment, { children: [before, _jsx("code", { className: 'rounded bg-muted px-1 py-0.5 font-mono text-foreground', children: command }), after] })) : (t('agents.available.setupUnknown')) }), group.statusDetail ? (_jsxs("details", { children: [_jsx("summary", { className: 'cursor-pointer', children: t('agents.available.details') }), _jsx("p", { className: 'whitespace-pre-wrap break-words pt-2', children: group.statusDetail })] })) : null] }));
|
|
71
|
+
}
|
|
72
|
+
function modelName(model) {
|
|
73
|
+
return agentNameOf(model.tool, model.model, model.displayModel);
|
|
74
|
+
}
|
|
75
|
+
function ExpandableText({ text }) {
|
|
76
|
+
const { t } = useTranslation();
|
|
77
|
+
const [expanded, setExpanded] = useState(false);
|
|
78
|
+
const long = text.length > REASON_CLAMP_LENGTH;
|
|
79
|
+
return (_jsxs("p", { className: 'pt-3 text-sm text-muted-foreground', children: [long && !expanded ? `${text.slice(0, REASON_CLAMP_LENGTH)}…` : text, long ? (_jsx(Button, { type: 'button', variant: 'link', size: 'sm', className: 'h-auto p-0 pl-1 align-baseline', onClick: () => setExpanded((value) => !value), children: t(expanded
|
|
80
|
+
? 'agents.available.showLess'
|
|
81
|
+
: 'agents.available.showMore') })) : null] }));
|
|
82
|
+
}
|
|
83
|
+
export function AvailableModelsDrawer({ open, onClose, }) {
|
|
84
|
+
const { t, i18n } = useTranslation();
|
|
85
|
+
const api = useAgentsApi();
|
|
86
|
+
const notify = useNotify();
|
|
87
|
+
const queryClient = useQueryClient();
|
|
88
|
+
const [search, setSearch] = useState('');
|
|
89
|
+
const [statuses, setStatuses] = useState(() => new Set(['available']));
|
|
90
|
+
const [toggled, setToggled] = useState(() => new Set());
|
|
91
|
+
const [selected, setSelected] = useState(() => new Map());
|
|
92
|
+
const [groupSearches, setGroupSearches] = useState(() => new Map());
|
|
93
|
+
const [step, setStep] = useState('select');
|
|
94
|
+
const [drafts, setDrafts] = useState(() => new Map());
|
|
95
|
+
const submittingRef = useRef(false);
|
|
96
|
+
const [rowErrors, setRowErrors] = useState(() => new Map());
|
|
97
|
+
const q = search.trim();
|
|
98
|
+
const forceExpand = q !== '';
|
|
99
|
+
// Each status already has a server-side model filter and count. Empty (or all four) means no filter.
|
|
100
|
+
const filters = useMemo(() => statuses.size === 0 || statuses.size === STATUS_FILTERS.length
|
|
101
|
+
? [undefined]
|
|
102
|
+
: STATUS_FILTERS.filter((status) => statuses.has(status)), [statuses]);
|
|
103
|
+
const reset = () => {
|
|
104
|
+
setSearch('');
|
|
105
|
+
setStatuses(new Set(['available']));
|
|
106
|
+
setToggled(new Set());
|
|
107
|
+
setGroupSearches(new Map());
|
|
108
|
+
setSelected(new Map());
|
|
109
|
+
setDrafts(new Map());
|
|
110
|
+
setStep('select');
|
|
111
|
+
setRowErrors(new Map());
|
|
112
|
+
};
|
|
113
|
+
const removeSucceeded = (keys) => {
|
|
114
|
+
setSelected((current) => new Map([...current].filter(([key]) => !keys.has(key))));
|
|
115
|
+
setDrafts((current) => new Map([...current].filter(([key]) => !keys.has(key))));
|
|
116
|
+
};
|
|
117
|
+
// Both steps and every dismissal share one request owner. The ref also closes the same-tick submit race.
|
|
118
|
+
const entries = [...selected.values()];
|
|
119
|
+
const bulkCreate = useMutation({
|
|
120
|
+
mutationFn: async () => {
|
|
121
|
+
const results = await Promise.all(entries.map((model) => {
|
|
122
|
+
const key = rowKey(model.tool, model.model);
|
|
123
|
+
return api
|
|
124
|
+
.createRunnerAgent({
|
|
125
|
+
tool: model.tool,
|
|
126
|
+
model: model.model,
|
|
127
|
+
...(model.displayModel
|
|
128
|
+
? { displayModel: model.displayModel }
|
|
129
|
+
: {}),
|
|
130
|
+
description: (drafts.get(key) ?? '').trim(),
|
|
131
|
+
})
|
|
132
|
+
.then(() => ({ key, ok: true }), (error) => ({ key, ok: false, error }));
|
|
133
|
+
}));
|
|
134
|
+
return results;
|
|
135
|
+
},
|
|
136
|
+
onSuccess: (results) => {
|
|
137
|
+
const succeeded = new Set(results.filter((r) => r.ok).map((r) => r.key));
|
|
138
|
+
const failed = results.filter((r) => !r.ok);
|
|
139
|
+
void queryClient.invalidateQueries({ queryKey: agentsKeys.agents });
|
|
140
|
+
void queryClient.invalidateQueries({
|
|
141
|
+
queryKey: agentsKeys.availableModelsAll,
|
|
142
|
+
});
|
|
143
|
+
if (failed.length === 0) {
|
|
144
|
+
notify.success(t('agents.available.addedCount', { count: succeeded.size }));
|
|
145
|
+
reset();
|
|
146
|
+
onClose();
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
// Partial (or total) failure: drop only what succeeded from the selection and drafts, so the failed rows stay
|
|
150
|
+
// on screen with what was typed and their own real reason, instead of discarding everything and closing.
|
|
151
|
+
setRowErrors(new Map(failed.map((r) => [
|
|
152
|
+
r.key,
|
|
153
|
+
errorText(t, r.error, t('common.requestFailed')),
|
|
154
|
+
])));
|
|
155
|
+
removeSucceeded(succeeded);
|
|
156
|
+
notify.error(undefined, succeeded.size === 0
|
|
157
|
+
? t('agents.available.addFailed', { failed: failed.length })
|
|
158
|
+
: t('agents.available.addedPartial', {
|
|
159
|
+
succeeded: succeeded.size,
|
|
160
|
+
failed: failed.length,
|
|
161
|
+
}));
|
|
162
|
+
},
|
|
163
|
+
onError: (error) => notify.error(error),
|
|
164
|
+
onSettled: () => {
|
|
165
|
+
submittingRef.current = false;
|
|
166
|
+
},
|
|
167
|
+
});
|
|
168
|
+
const submit = () => {
|
|
169
|
+
if (submittingRef.current)
|
|
170
|
+
return;
|
|
171
|
+
submittingRef.current = true;
|
|
172
|
+
bulkCreate.mutate();
|
|
173
|
+
};
|
|
174
|
+
const groupQueries = useQueries({
|
|
175
|
+
queries: filters.map((status) => ({
|
|
176
|
+
queryKey: agentsKeys.availableModelGroups(q, status ?? ''),
|
|
177
|
+
queryFn: () => api.availableModelGroups({ q: q || undefined, status }),
|
|
178
|
+
enabled: open && step === 'select',
|
|
179
|
+
})),
|
|
180
|
+
});
|
|
181
|
+
const mergedGroups = new Map();
|
|
182
|
+
for (const query of groupQueries)
|
|
183
|
+
for (const group of query.data?.data ?? []) {
|
|
184
|
+
const previous = mergedGroups.get(group.tool);
|
|
185
|
+
mergedGroups.set(group.tool, previous
|
|
186
|
+
? {
|
|
187
|
+
...group,
|
|
188
|
+
modelCount: previous.modelCount + group.modelCount,
|
|
189
|
+
recommendedCount: previous.recommendedCount + group.recommendedCount,
|
|
190
|
+
}
|
|
191
|
+
: group);
|
|
192
|
+
}
|
|
193
|
+
const groups = {
|
|
194
|
+
data: groupQueries.every((query) => query.data !== undefined)
|
|
195
|
+
? {
|
|
196
|
+
data: [...mergedGroups.values()].sort((a, b) => a.tool.localeCompare(b.tool)),
|
|
197
|
+
}
|
|
198
|
+
: undefined,
|
|
199
|
+
isError: groupQueries.some((query) => query.isError),
|
|
200
|
+
error: groupQueries.find((query) => query.isError)?.error,
|
|
201
|
+
refetch: () => Promise.all(groupQueries.map((query) => query.refetch())),
|
|
202
|
+
};
|
|
203
|
+
const toggle = (tool) => setToggled((current) => {
|
|
204
|
+
const next = new Set(current);
|
|
205
|
+
if (next.has(tool))
|
|
206
|
+
next.delete(tool);
|
|
207
|
+
else
|
|
208
|
+
next.add(tool);
|
|
209
|
+
return next;
|
|
210
|
+
});
|
|
211
|
+
const setRowSelected = (model, checked) => setSelected((current) => {
|
|
212
|
+
const next = new Map(current);
|
|
213
|
+
const key = rowKey(model.tool, model.model);
|
|
214
|
+
if (checked)
|
|
215
|
+
next.set(key, model);
|
|
216
|
+
else
|
|
217
|
+
next.delete(key);
|
|
218
|
+
return next;
|
|
219
|
+
});
|
|
220
|
+
// Pre-fills a draft from the catalog's suggestion (or leaves it for the confirm step to mark as needed) the first
|
|
221
|
+
// time a model is selected; going back and forth keeps whatever was already typed.
|
|
222
|
+
const goToConfirm = (addedModel) => {
|
|
223
|
+
setDrafts((current) => {
|
|
224
|
+
const entries = addedModel
|
|
225
|
+
? [addedModel, ...selected.values()]
|
|
226
|
+
: [...selected.values()];
|
|
227
|
+
const next = new Map(current);
|
|
228
|
+
for (const model of entries) {
|
|
229
|
+
const key = rowKey(model.tool, model.model);
|
|
230
|
+
if (!next.has(key))
|
|
231
|
+
next.set(key, modelSuggestion(model, i18n.language, t));
|
|
232
|
+
}
|
|
233
|
+
return next;
|
|
234
|
+
});
|
|
235
|
+
setStep('confirm');
|
|
236
|
+
};
|
|
237
|
+
return (_jsx(Sheet, { open: open, onOpenChange: (next, details) => {
|
|
238
|
+
if (!next && submittingRef.current) {
|
|
239
|
+
details.cancel();
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
if (!next) {
|
|
243
|
+
reset();
|
|
244
|
+
onClose();
|
|
245
|
+
}
|
|
246
|
+
}, children: _jsx(SheetContent, { className: 'flex w-full flex-col gap-0 data-[side=right]:w-full data-[side=right]:sm:max-w-[780px]', "data-testid": 'available-models-drawer', "aria-busy": bulkCreate.isPending, showCloseButton: !bulkCreate.isPending, children: step === 'confirm' ? (_jsx(ConfirmStep, { selected: selected, drafts: drafts, onDraftChange: (key, value) => setDrafts((current) => new Map(current).set(key, value)), pending: bulkCreate.isPending, rowErrors: rowErrors, onSubmit: submit, onBack: () => setStep('select') })) : (_jsxs(_Fragment, { children: [_jsxs(SheetHeader, { className: 'shrink-0', children: [_jsx(SheetTitle, { children: t('agents.available.title') }), _jsx(SheetDescription, { children: t('agents.available.description') })] }), _jsxs("div", { className: 'shrink-0 space-y-3 border-b px-4 pb-3 sm:px-6', children: [_jsx(Input, { value: search, onChange: (event) => setSearch(event.target.value), placeholder: t('agents.discovery.search'), "aria-label": t('agents.discovery.search'), "data-testid": 'available-models-search' }), _jsx("div", { className: 'flex flex-wrap gap-2', children: STATUS_FILTERS.map((option) => (_jsxs(Button, { type: 'button', size: 'sm', variant: statuses.has(option) ? 'default' : 'outline', "aria-pressed": statuses.has(option), onClick: () => setStatuses((current) => {
|
|
247
|
+
const next = new Set(current);
|
|
248
|
+
if (next.has(option))
|
|
249
|
+
next.delete(option);
|
|
250
|
+
else
|
|
251
|
+
next.add(option);
|
|
252
|
+
return next;
|
|
253
|
+
}), "data-testid": `available-models-filter-${option}`, children: [statuses.has(option) ? _jsx(CheckIcon, { "aria-hidden": true }) : null, t(`agents.available.status.${option}`)] }, option))) })] }), _jsx("div", { className: 'min-h-0 flex-1 space-y-2 overflow-y-auto px-4 py-3 sm:px-6', children: groups.isError && !groups.data ? (_jsx(AgLoadError, { title: t('agents.loadFailed'), error: groups.error, onRetry: () => void groups.refetch() })) : !groups.data ? (_jsx(AgListSkeleton, {})) : groups.data.data.length === 0 ? (_jsx("p", { className: 'text-sm text-muted-foreground', children: t('agents.noneInFilter') })) : (groups.data.data.map((group) => (_jsx(ToolGroup, { group: group, q: q, filters: filters, groupQuery: groupSearches.get(group.tool) ?? '', onGroupQueryChange: (value) => setGroupSearches((current) => new Map(current).set(group.tool, value)), expanded: toggled.has(group.tool) !==
|
|
254
|
+
group.modelCount <= DEFAULT_EXPAND_THRESHOLD, forceExpand: forceExpand, onToggle: () => toggle(group.tool), selected: selected, onSelect: setRowSelected, onAddOne: (model) => {
|
|
255
|
+
setRowSelected(model, true);
|
|
256
|
+
goToConfirm(model);
|
|
257
|
+
} }, group.tool)))) }), _jsxs(SheetFooter, { "data-fixed-sheet-footer": true, className: 'shrink-0 flex-row items-center justify-between border-t', children: [_jsx("div", { className: 'text-sm text-muted-foreground', children: selected.size > 0
|
|
258
|
+
? t('agents.available.selectedCount', {
|
|
259
|
+
count: selected.size,
|
|
260
|
+
})
|
|
261
|
+
: null }), _jsxs("div", { className: 'flex gap-2', children: [_jsx(Button, { variant: 'outline', onClick: () => {
|
|
262
|
+
reset();
|
|
263
|
+
onClose();
|
|
264
|
+
}, children: t('actions.close') }), _jsx(Button, { disabled: selected.size === 0, onClick: () => goToConfirm(), "data-testid": 'available-models-add-selected', children: t('agents.available.addSelected', { count: selected.size }) })] })] })] })) }) }));
|
|
265
|
+
}
|
|
266
|
+
function ToolGroup({ group, q, filters, groupQuery, onGroupQueryChange, expanded, forceExpand, onToggle, selected, onSelect, onAddOne, }) {
|
|
267
|
+
const { t } = useTranslation();
|
|
268
|
+
const api = useAgentsApi();
|
|
269
|
+
const open = forceExpand || expanded;
|
|
270
|
+
const effectiveQuery = groupQuery.trim() || q;
|
|
271
|
+
const rows = useInfiniteQuery({
|
|
272
|
+
queryKey: agentsKeys.availableModelRows(group.tool, effectiveQuery, filters.join(',')),
|
|
273
|
+
queryFn: async ({ pageParam }) => {
|
|
274
|
+
const pages = await Promise.all(filters.map((status) => api.availableModelRows(group.tool, {
|
|
275
|
+
q: effectiveQuery || undefined,
|
|
276
|
+
status,
|
|
277
|
+
page: pageParam,
|
|
278
|
+
pageSize: PAGE_SIZE,
|
|
279
|
+
})));
|
|
280
|
+
return {
|
|
281
|
+
data: pages.flatMap((page) => page.data),
|
|
282
|
+
total: pages.reduce((total, page) => total + page.meta.total, 0),
|
|
283
|
+
page: pageParam,
|
|
284
|
+
hasMore: pages.some((page) => page.meta.page * page.meta.pageSize < page.meta.total),
|
|
285
|
+
};
|
|
286
|
+
},
|
|
287
|
+
initialPageParam: 1,
|
|
288
|
+
getNextPageParam: (last) => (last.hasMore ? last.page + 1 : undefined),
|
|
289
|
+
enabled: open && group.modelCount > 0,
|
|
290
|
+
});
|
|
291
|
+
const loaded = useMemo(() => (rows.data?.pages.flatMap((page) => page.data) ?? []).sort((a, b) => (a.displayModel ?? a.model).localeCompare(b.displayModel ?? b.model)), [rows.data]);
|
|
292
|
+
return (_jsx(Collapsible, { open: open, onOpenChange: onToggle, children: _jsxs("div", { className: 'rounded-lg border', children: [_jsxs(CollapsibleTrigger, { className: 'flex w-full items-center justify-between gap-3 p-3 text-left', "data-testid": `available-models-group-${group.tool}`, children: [_jsx("span", { className: 'font-medium', children: t('agents.available.group', {
|
|
293
|
+
count: rows.data?.pages[0].total ?? group.modelCount,
|
|
294
|
+
tool: TOOL_LABELS[group.tool],
|
|
295
|
+
runners: t('agents.available.runners', {
|
|
296
|
+
count: group.runnerCount,
|
|
297
|
+
}),
|
|
298
|
+
}) }), _jsx(AgTag, { tone: STATUS_TONE[group.status], dot: true, children: t(`agents.available.status.${group.status}`) })] }), _jsxs(CollapsibleContent, { className: 'border-t px-3 pb-3', children: [group.status !== 'available' ? (_jsx(SetupGuidance, { group: group })) : null, group.modelCount === 0 ? null : (_jsxs(_Fragment, { children: [group.modelCount > DEFAULT_EXPAND_THRESHOLD ||
|
|
299
|
+
groupQuery !== '' ? (_jsx(Input, { value: groupQuery, onChange: (event) => onGroupQueryChange(event.target.value), placeholder: t('agents.available.groupSearchPlaceholder'), "aria-label": t('agents.available.groupSearchPlaceholder'), className: 'mt-3', "data-testid": `available-models-group-search-${group.tool}` })) : null, rows.isError && !rows.data ? (_jsx(AgLoadError, { title: t('agents.loadFailed'), error: rows.error, onRetry: () => void rows.refetch() })) : !rows.data ? (_jsx("p", { role: 'status', className: 'pt-3 text-sm text-muted-foreground', children: t('common.loading') })) : loaded.length === 0 ? (_jsx("p", { className: 'pt-3 text-sm text-muted-foreground', children: t('agents.available.noModels') })) : (_jsxs("div", { className: 'pt-2', children: [loaded.length > VIRTUALIZE_THRESHOLD ? (_jsx(Virtuoso, { style: { height: 320 }, data: loaded, computeItemKey: (_, model) => rowKey(model.tool, model.model), endReached: () => {
|
|
300
|
+
if (rows.hasNextPage && !rows.isFetchingNextPage)
|
|
301
|
+
void rows.fetchNextPage();
|
|
302
|
+
}, itemContent: (_, model) => (_jsx("div", { className: 'py-1', children: _jsx(ModelRow, { model: model, groupStatus: group.status, checked: selected.has(rowKey(model.tool, model.model)), onSelect: onSelect, onAddOne: onAddOne }) })) })) : (_jsx("div", { className: 'space-y-1', children: loaded.map((model) => (_jsx(ModelRow, { model: model, groupStatus: group.status, checked: selected.has(rowKey(model.tool, model.model)), onSelect: onSelect, onAddOne: onAddOne }, rowKey(model.tool, model.model)))) })), rows.hasNextPage ? (_jsx(Button, { type: 'button', variant: 'outline', size: 'sm', className: 'mt-2', disabled: rows.isFetchingNextPage, onClick: () => void rows.fetchNextPage(), children: t('agents.loadMore') })) : null] }))] }))] })] }) }));
|
|
303
|
+
}
|
|
304
|
+
function ModelRow({ model, groupStatus, checked, onSelect, onAddOne, }) {
|
|
305
|
+
const { t } = useTranslation();
|
|
306
|
+
const added = model.agentId !== null;
|
|
307
|
+
return (_jsxs("div", { "data-testid": `available-model-${model.tool}-${model.model}`, className: 'flex items-center gap-3 rounded-md p-2 hover:bg-muted/50', children: [_jsx(Checkbox, { "aria-label": t('agents.cleanup.select', {
|
|
308
|
+
name: modelName(model),
|
|
309
|
+
}), checked: checked, disabled: added || model.availability !== 'available', onCheckedChange: (next) => onSelect(model, next === true) }), _jsxs("div", { className: 'min-w-0 flex-1', children: [_jsx("div", { className: 'font-medium', children: modelName(model) }), _jsxs("div", { className: 'flex flex-wrap items-center gap-x-2 text-xs text-muted-foreground', children: [_jsx("span", { children: model.model }), model.recommended ? (_jsx("span", { children: t('agents.available.recommended') })) : null, _jsx("span", { children: t('agents.available.runners', { count: model.runners.ready }) })] })] }), model.availability !== groupStatus ? (_jsx(AgTag, { tone: STATUS_TONE[model.availability], children: t(`agents.available.status.${model.availability}`) })) : null, added ? (_jsx(AgTag, { tone: 'grey', children: t('agents.available.added') })) : (_jsx(Button, { type: 'button', size: 'sm', variant: 'outline', disabled: model.availability !== 'available', onClick: () => onAddOne(model), "data-testid": `available-model-create-${model.tool}-${model.model}`, children: t('agents.available.add') }))] }));
|
|
310
|
+
}
|
|
311
|
+
function ConfirmStep({ selected, drafts, onDraftChange, pending, rowErrors, onSubmit, onBack, }) {
|
|
312
|
+
const { t } = useTranslation();
|
|
313
|
+
const entries = [...selected.values()];
|
|
314
|
+
const invalid = entries.filter((model) => (drafts.get(rowKey(model.tool, model.model)) ?? '').trim() === '');
|
|
315
|
+
return (_jsxs(_Fragment, { children: [_jsxs(SheetHeader, { className: 'shrink-0', children: [_jsx(SheetTitle, { children: t('agents.available.confirmTitle', { count: entries.length }) }), _jsx(SheetDescription, { children: t('agents.enable.goodAtHint') })] }), _jsx("form", { id: 'available-models-confirm-form', className: 'min-h-0 flex-1 space-y-4 overflow-y-auto px-4 pb-1 sm:px-6', onSubmit: (event) => {
|
|
316
|
+
event.preventDefault();
|
|
317
|
+
if (pending)
|
|
318
|
+
return;
|
|
319
|
+
if (invalid.length > 0)
|
|
320
|
+
return;
|
|
321
|
+
onSubmit();
|
|
322
|
+
}, children: entries.map((model) => {
|
|
323
|
+
const key = rowKey(model.tool, model.model);
|
|
324
|
+
const goodAt = drafts.get(key) ?? '';
|
|
325
|
+
const missing = goodAt.trim() === '';
|
|
326
|
+
const rowError = rowErrors.get(key);
|
|
327
|
+
return (_jsxs(Field, { "data-invalid": missing ? true : undefined, children: [_jsx(FieldLabel, { htmlFor: `confirm-good-at-${key}`, children: modelName(model) }), _jsx(Textarea, { id: `confirm-good-at-${key}`, rows: 3, disabled: pending, value: goodAt, onChange: (event) => onDraftChange(key, event.target.value), "aria-invalid": missing ? true : undefined, placeholder: goodAt === '' ? t('agents.available.goodAtNeeded') : undefined, "data-testid": `available-model-good-at-${model.tool}-${model.model}` }), rowError ? (_jsx(FieldError, { "data-testid": `available-model-error-${model.tool}-${model.model}`, children: rowError })) : null, missing ? (_jsx(FieldError, { children: t('agents.enable.goodAtRequired') })) : null] }, key));
|
|
328
|
+
}) }), _jsxs(SheetFooter, { "data-fixed-sheet-footer": true, className: 'shrink-0 flex-row justify-end border-t', children: [_jsx(Button, { variant: 'outline', type: 'button', onClick: onBack, disabled: pending, children: t('actions.back') }), _jsx(Button, { type: 'submit', form: 'available-models-confirm-form', disabled: pending || invalid.length > 0, "data-testid": 'available-models-confirm-submit', children: t('agents.available.confirmAction', { count: entries.length }) })] })] }));
|
|
329
|
+
}
|
|
330
|
+
//# sourceMappingURL=available-models-drawer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"available-models-drawer.js","sourceRoot":"","sources":["../../../../client/pages/agents/available-models-drawer.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type ReactElement } from 'react';
|
|
2
|
+
export interface CleanupDrawerProps {
|
|
3
|
+
readonly open: boolean;
|
|
4
|
+
readonly onClose: () => void;
|
|
5
|
+
}
|
|
6
|
+
export declare function CleanupDrawer({ open, onClose, }: CleanupDrawerProps): ReactElement;
|
|
7
|
+
//# sourceMappingURL=cleanup-drawer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cleanup-drawer.d.ts","sourceRoot":"","sources":["../../../../client/pages/agents/cleanup-drawer.tsx"],"names":[],"mappings":"AAgBA,OAAO,EAAqB,KAAK,YAAY,EAAE,MAAM,OAAO,CAAC;AAoD7D,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC;CAC9B;AAED,wBAAgB,aAAa,CAAC,EAC5B,IAAI,EACJ,OAAO,GACR,EAAE,kBAAkB,GAAG,YAAY,CAyOnC"}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useTranslation } from '@nocobase/i18n/client';
|
|
3
|
+
import { useInfiniteQuery, useMutation, useQuery, useQueryClient, } from '@tanstack/react-query';
|
|
4
|
+
import { useMemo, useState } from 'react';
|
|
5
|
+
import { Virtuoso } from 'react-virtuoso';
|
|
6
|
+
import { TOOL_LABELS } from '../../../shared/model-catalog.js';
|
|
7
|
+
import { agentsKeys } from '../../api/keys.js';
|
|
8
|
+
import { AgListSkeleton, AgLoadError } from '../../components/ag-states.js';
|
|
9
|
+
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogPortal, AlertDialogOverlay, AlertDialogTitle, } from '../../components/ui/alert-dialog.js';
|
|
10
|
+
import { Button } from '../../components/ui/button.js';
|
|
11
|
+
import { Checkbox } from '../../components/ui/checkbox.js';
|
|
12
|
+
import { Collapsible, CollapsibleContent, CollapsibleTrigger, } from '../../components/ui/collapsible.js';
|
|
13
|
+
import { Sheet, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, } from '../../components/ui/sheet.js';
|
|
14
|
+
import { useAgentsApi } from '../../hooks/use-agents-api.js';
|
|
15
|
+
import { useFormatters } from '../../lib/format.js';
|
|
16
|
+
import { errorText, useNotify } from '../../hooks/use-notify.js';
|
|
17
|
+
const VIRTUALIZE_THRESHOLD = 30;
|
|
18
|
+
const PAGE_SIZE = 50;
|
|
19
|
+
/** How many ids one "select all in group" page fetch asks for; large enough that most groups need only one call. */
|
|
20
|
+
const SELECT_ALL_PAGE_SIZE = 500;
|
|
21
|
+
/** `POST /agents/cleanup` refuses more ids than this at once; a bigger selection is sent in several requests. */
|
|
22
|
+
const CLEANUP_BATCH_SIZE = 256;
|
|
23
|
+
function chunk(items, size) {
|
|
24
|
+
const chunks = [];
|
|
25
|
+
for (let index = 0; index < items.length; index += size)
|
|
26
|
+
chunks.push(items.slice(index, index + size));
|
|
27
|
+
return chunks;
|
|
28
|
+
}
|
|
29
|
+
export function CleanupDrawer({ open, onClose, }) {
|
|
30
|
+
const { t } = useTranslation();
|
|
31
|
+
const api = useAgentsApi();
|
|
32
|
+
const notify = useNotify();
|
|
33
|
+
const queryClient = useQueryClient();
|
|
34
|
+
const [selected, setSelected] = useState(() => new Map());
|
|
35
|
+
const [confirming, setConfirming] = useState(false);
|
|
36
|
+
const reset = () => {
|
|
37
|
+
setSelected(new Map());
|
|
38
|
+
setConfirming(false);
|
|
39
|
+
};
|
|
40
|
+
const groups = useQuery({
|
|
41
|
+
queryKey: agentsKeys.cleanupGroups(''),
|
|
42
|
+
queryFn: () => api.cleanupGroups(),
|
|
43
|
+
enabled: open,
|
|
44
|
+
});
|
|
45
|
+
const setRowSelected = (candidate, checked) => setSelected((current) => {
|
|
46
|
+
const next = new Map(current);
|
|
47
|
+
if (checked)
|
|
48
|
+
next.set(candidate.id, candidate);
|
|
49
|
+
else
|
|
50
|
+
next.delete(candidate.id);
|
|
51
|
+
return next;
|
|
52
|
+
});
|
|
53
|
+
const setGroupSelected = (group, checked) => setSelected((current) => {
|
|
54
|
+
const next = new Map(current);
|
|
55
|
+
for (const candidate of group)
|
|
56
|
+
if (checked)
|
|
57
|
+
next.set(candidate.id, candidate);
|
|
58
|
+
else
|
|
59
|
+
next.delete(candidate.id);
|
|
60
|
+
return next;
|
|
61
|
+
});
|
|
62
|
+
// Clears a whole group's selection, including ids a "select all" picked up from a page this group's own list
|
|
63
|
+
// never loaded: scans the authoritative selection map by `tool`, not the group's own (possibly partial) `loaded`.
|
|
64
|
+
const clearGroupSelection = (tool) => setSelected((current) => {
|
|
65
|
+
const next = new Map(current);
|
|
66
|
+
for (const [id, candidate] of current)
|
|
67
|
+
if ((candidate.tool ?? null) === tool)
|
|
68
|
+
next.delete(id);
|
|
69
|
+
return next;
|
|
70
|
+
});
|
|
71
|
+
const remove = useMutation({
|
|
72
|
+
mutationFn: async () => {
|
|
73
|
+
const ids = [...selected.keys()];
|
|
74
|
+
const batches = chunk(ids, CLEANUP_BATCH_SIZE);
|
|
75
|
+
// `allSettled`, not `all`: one batch's request failing (network, a 500) must not discard the ids another
|
|
76
|
+
// batch already removed. Each outcome is matched back to its own batch by index to know which ids to retry.
|
|
77
|
+
const outcomes = await Promise.allSettled(batches.map((batch) => api.cleanup(batch)));
|
|
78
|
+
const removed = [];
|
|
79
|
+
const skipped = [];
|
|
80
|
+
const failed = [];
|
|
81
|
+
let lastError;
|
|
82
|
+
outcomes.forEach((outcome, index) => {
|
|
83
|
+
if (outcome.status === 'fulfilled') {
|
|
84
|
+
removed.push(...outcome.value.removed);
|
|
85
|
+
skipped.push(...outcome.value.skipped);
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
failed.push(...batches[index]);
|
|
89
|
+
lastError = outcome.reason;
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
return { removed, skipped, failed, lastError };
|
|
93
|
+
},
|
|
94
|
+
onSuccess: ({ removed, skipped, failed, lastError }) => {
|
|
95
|
+
void queryClient.invalidateQueries({ queryKey: agentsKeys.agents });
|
|
96
|
+
void queryClient.invalidateQueries({
|
|
97
|
+
queryKey: agentsKeys.cleanupCandidatesAll,
|
|
98
|
+
});
|
|
99
|
+
if (failed.length === 0) {
|
|
100
|
+
setSelected(new Map());
|
|
101
|
+
setConfirming(false);
|
|
102
|
+
notify.success(t('agents.cleanup.done', {
|
|
103
|
+
removed: removed.length,
|
|
104
|
+
skipped: skipped.length,
|
|
105
|
+
}));
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
// Partial (or total) failure: keep only the ids whose batch failed selected, so the confirmation that stays
|
|
109
|
+
// open names exactly what is left to retry, and a removed or skipped id is never reported as untouched.
|
|
110
|
+
setSelected((current) => {
|
|
111
|
+
const next = new Map();
|
|
112
|
+
for (const id of failed) {
|
|
113
|
+
const candidate = current.get(id);
|
|
114
|
+
if (candidate)
|
|
115
|
+
next.set(id, candidate);
|
|
116
|
+
}
|
|
117
|
+
return next;
|
|
118
|
+
});
|
|
119
|
+
// `notify.error`'s own fallback logic would replace this count summary with a bare reason translation when
|
|
120
|
+
// `lastError` is a recognized API error; call it with no error so the summary (which already embeds the real
|
|
121
|
+
// reason) is always what shows.
|
|
122
|
+
notify.error(undefined, t('agents.cleanup.partialFailure', {
|
|
123
|
+
removed: removed.length,
|
|
124
|
+
skipped: skipped.length,
|
|
125
|
+
failed: failed.length,
|
|
126
|
+
reason: errorText(t, lastError, t('common.requestFailed')),
|
|
127
|
+
}));
|
|
128
|
+
},
|
|
129
|
+
onError: (error) => notify.error(error),
|
|
130
|
+
});
|
|
131
|
+
const tools = useMemo(() => [...new Set([...selected.values()].map((c) => c.tool))], [selected]);
|
|
132
|
+
const toolNames = tools
|
|
133
|
+
.map((tool) => (tool ? TOOL_LABELS[tool] : ''))
|
|
134
|
+
.filter(Boolean)
|
|
135
|
+
.join(', ');
|
|
136
|
+
return (_jsxs(Sheet, { open: open, onOpenChange: (next) => {
|
|
137
|
+
if (!next) {
|
|
138
|
+
reset();
|
|
139
|
+
onClose();
|
|
140
|
+
}
|
|
141
|
+
}, children: [_jsxs(SheetContent, { className: 'flex w-full flex-col gap-0 data-[side=right]:w-full data-[side=right]:sm:max-w-[780px]', "data-testid": 'cleanup-drawer', children: [_jsxs(SheetHeader, { className: 'shrink-0', children: [_jsx(SheetTitle, { children: t('agents.cleanup.title') }), _jsx(SheetDescription, { children: t('agents.cleanup.description') })] }), _jsx("div", { className: 'min-h-0 flex-1 space-y-2 overflow-y-auto px-4 py-3 sm:px-6', children: groups.isError && !groups.data ? (_jsx(AgLoadError, { title: t('agents.loadFailed'), error: groups.error, onRetry: () => void groups.refetch() })) : !groups.data ? (_jsx(AgListSkeleton, {})) : groups.data.data.length === 0 ? (_jsx("p", { className: 'text-sm text-muted-foreground', children: t('agents.cleanup.none') })) : (groups.data.data.map((group) => (_jsx(CleanupToolGroup, { group: group, selected: selected, onSelectRow: setRowSelected, onSelectGroup: setGroupSelected, onClearGroup: clearGroupSelection }, group.tool ?? '')))) }), _jsxs(SheetFooter, { "data-fixed-sheet-footer": true, className: 'shrink-0 flex-row items-center justify-between border-t', children: [_jsx("div", { className: 'text-sm text-muted-foreground', children: selected.size > 0
|
|
142
|
+
? t('agents.cleanup.selectedCount', { count: selected.size })
|
|
143
|
+
: null }), _jsxs("div", { className: 'flex gap-2', children: [_jsx(Button, { variant: 'outline', onClick: onClose, children: t('actions.close') }), _jsx(Button, { variant: 'destructive', disabled: selected.size === 0 || remove.isPending, "data-testid": 'cleanup-open-confirm', onClick: () => setConfirming(true), children: t('agents.cleanup.remove', { count: selected.size }) })] })] })] }), _jsxs(AlertDialog, { open: confirming, onOpenChange: setConfirming, children: [_jsx(AlertDialogPortal, { children: _jsx(AlertDialogOverlay, { forceRender: true, "data-testid": 'cleanup-confirm-overlay' }) }), _jsxs(AlertDialogContent, { "data-testid": 'cleanup-confirm', children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { children: t('agents.cleanup.confirmTitle', { count: selected.size }) }), _jsx(AlertDialogDescription, { children: t('agents.cleanup.confirmDescription', {
|
|
144
|
+
tools: toolNames,
|
|
145
|
+
}) })] }), _jsxs(AlertDialogFooter, { children: [_jsx(AlertDialogCancel, { children: t('actions.back') }), _jsx(AlertDialogAction, { disabled: remove.isPending, onClick: () => remove.mutate(), "data-testid": 'cleanup-confirm-submit', children: t('agents.cleanup.confirmAction', {
|
|
146
|
+
count: selected.size,
|
|
147
|
+
}) })] })] })] })] }));
|
|
148
|
+
}
|
|
149
|
+
function CleanupToolGroup({ group, selected, onSelectRow, onSelectGroup, onClearGroup, }) {
|
|
150
|
+
const { t } = useTranslation();
|
|
151
|
+
const format = useFormatters();
|
|
152
|
+
const api = useAgentsApi();
|
|
153
|
+
const [open, setOpen] = useState(false);
|
|
154
|
+
const [selectingAll, setSelectingAll] = useState(false);
|
|
155
|
+
const label = group.tool ? TOOL_LABELS[group.tool] : '';
|
|
156
|
+
const rows = useInfiniteQuery({
|
|
157
|
+
queryKey: agentsKeys.cleanupRows(group.tool ?? '', ''),
|
|
158
|
+
queryFn: ({ pageParam }) => api.cleanupRows(group.tool, {
|
|
159
|
+
page: pageParam,
|
|
160
|
+
pageSize: PAGE_SIZE,
|
|
161
|
+
}),
|
|
162
|
+
initialPageParam: 1,
|
|
163
|
+
getNextPageParam: (last) => last.meta.page * last.meta.pageSize < last.meta.total
|
|
164
|
+
? last.meta.page + 1
|
|
165
|
+
: undefined,
|
|
166
|
+
enabled: open && group.tool !== null,
|
|
167
|
+
});
|
|
168
|
+
const loaded = useMemo(() => rows.data?.pages.flatMap((page) => page.data) ?? [], [rows.data]);
|
|
169
|
+
// The authoritative count from the server, not `loaded`: a "select all" can have picked up ids from pages this
|
|
170
|
+
// group's own list never fetched, so checking only `loaded` would under-report (or under-clear) the selection.
|
|
171
|
+
const selectedInGroup = useMemo(() => [...selected.values()].filter((c) => (c.tool ?? null) === group.tool)
|
|
172
|
+
.length, [selected, group.tool]);
|
|
173
|
+
const allSelected = group.count > 0 && selectedInGroup >= group.count;
|
|
174
|
+
const selectAllInGroup = async (checked) => {
|
|
175
|
+
if (!checked) {
|
|
176
|
+
onClearGroup(group.tool);
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
if (!group.tool)
|
|
180
|
+
return;
|
|
181
|
+
setSelectingAll(true);
|
|
182
|
+
try {
|
|
183
|
+
const all = [];
|
|
184
|
+
let page = 1;
|
|
185
|
+
for (;;) {
|
|
186
|
+
const answer = await api.cleanupRows(group.tool, {
|
|
187
|
+
page,
|
|
188
|
+
pageSize: SELECT_ALL_PAGE_SIZE,
|
|
189
|
+
});
|
|
190
|
+
all.push(...answer.data);
|
|
191
|
+
if (answer.meta.page * answer.meta.pageSize >= answer.meta.total)
|
|
192
|
+
break;
|
|
193
|
+
page += 1;
|
|
194
|
+
}
|
|
195
|
+
onSelectGroup(all, true);
|
|
196
|
+
}
|
|
197
|
+
finally {
|
|
198
|
+
setSelectingAll(false);
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
return (_jsx(Collapsible, { open: open, onOpenChange: setOpen, children: _jsxs("div", { className: 'rounded-lg border', children: [_jsx(CollapsibleTrigger, { className: 'flex w-full items-center justify-between gap-3 p-3 text-left', "data-testid": `cleanup-group-${group.tool ?? 'none'}`, children: _jsx("span", { className: 'font-medium', children: t('agents.cleanup.group', { count: group.count, tool: label }) }) }), _jsx(CollapsibleContent, { className: 'border-t px-3 pb-3', children: rows.isError && !rows.data ? (_jsx(AgLoadError, { title: t('agents.loadFailed'), error: rows.error, onRetry: () => void rows.refetch() })) : !rows.data ? (_jsx(AgListSkeleton, { rows: 2 })) : (_jsxs("div", { className: 'pt-2', children: [_jsx(Button, { type: 'button', variant: 'outline', size: 'sm', className: 'mb-2', disabled: selectingAll, onClick: () => void selectAllInGroup(!allSelected), "data-testid": `cleanup-group-select-all-${group.tool ?? 'none'}`, children: t(allSelected
|
|
202
|
+
? 'agents.cleanup.clearGroup'
|
|
203
|
+
: 'agents.cleanup.selectGroup', { tool: label }) }), loaded.length > VIRTUALIZE_THRESHOLD ? (_jsx(Virtuoso, { style: { height: 320 }, data: loaded, computeItemKey: (_, row) => row.id, endReached: () => {
|
|
204
|
+
if (rows.hasNextPage && !rows.isFetchingNextPage)
|
|
205
|
+
void rows.fetchNextPage();
|
|
206
|
+
}, itemContent: (_, candidate) => (_jsx("div", { className: 'py-1', children: _jsx(CandidateRow, { candidate: candidate, checked: selected.has(candidate.id), onSelect: onSelectRow, formatRelative: format.relative }) })) })) : (_jsx("div", { className: 'space-y-1', children: loaded.map((candidate) => (_jsx(CandidateRow, { candidate: candidate, checked: selected.has(candidate.id), onSelect: onSelectRow, formatRelative: format.relative }, candidate.id))) })), rows.hasNextPage ? (_jsx(Button, { type: 'button', variant: 'outline', size: 'sm', className: 'mt-2', disabled: rows.isFetchingNextPage, onClick: () => void rows.fetchNextPage(), children: t('agents.loadMore') })) : null] })) })] }) }));
|
|
207
|
+
}
|
|
208
|
+
function CandidateRow({ candidate, checked, onSelect, formatRelative, }) {
|
|
209
|
+
const { t } = useTranslation();
|
|
210
|
+
return (_jsxs("div", { "data-testid": `cleanup-candidate-${candidate.id}`, className: 'flex items-center gap-3 rounded-md p-2 hover:bg-muted/50', children: [_jsx(Checkbox, { "aria-label": t('agents.cleanup.select', { name: candidate.name }), checked: checked, onCheckedChange: (next) => onSelect(candidate, next === true) }), _jsxs("div", { className: 'min-w-0 flex-1', children: [_jsx("div", { className: 'font-medium', children: candidate.name }), _jsxs("div", { className: 'text-xs text-muted-foreground', children: [t('agents.cleanup.neverEnabled'), " \u00B7", ' ', t('agents.cleanup.createdAt', {
|
|
211
|
+
when: formatRelative(candidate.createdAt),
|
|
212
|
+
})] })] })] }));
|
|
213
|
+
}
|
|
214
|
+
//# sourceMappingURL=cleanup-drawer.js.map
|