@shipfox/client-agent 21.0.0 → 22.0.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/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +16 -0
- package/dist/components/add-custom-provider-card.d.ts.map +1 -1
- package/dist/components/add-custom-provider-card.js +11 -31
- package/dist/components/add-custom-provider-card.js.map +1 -1
- package/dist/components/available-provider-card.d.ts.map +1 -1
- package/dist/components/available-provider-card.js +11 -31
- package/dist/components/available-provider-card.js.map +1 -1
- package/dist/components/available-providers-grid.d.ts +0 -1
- package/dist/components/available-providers-grid.d.ts.map +1 -1
- package/dist/components/available-providers-grid.js +33 -27
- package/dist/components/available-providers-grid.js.map +1 -1
- package/dist/components/harnesses-section.d.ts.map +1 -1
- package/dist/components/harnesses-section.js +147 -134
- package/dist/components/harnesses-section.js.map +1 -1
- package/dist/components/model-provider-grid-skeleton.d.ts +4 -0
- package/dist/components/model-provider-grid-skeleton.d.ts.map +1 -0
- package/dist/components/model-provider-grid-skeleton.js +34 -0
- package/dist/components/model-provider-grid-skeleton.js.map +1 -0
- package/dist/components/model-providers-section.d.ts.map +1 -1
- package/dist/components/model-providers-section.js +253 -245
- package/dist/components/model-providers-section.js.map +1 -1
- package/dist/pages/model-provider-onboarding-page.d.ts.map +1 -1
- package/dist/pages/model-provider-onboarding-page.js +32 -64
- package/dist/pages/model-provider-onboarding-page.js.map +1 -1
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/src/components/add-custom-provider-card.tsx +9 -23
- package/src/components/available-provider-card.tsx +9 -23
- package/src/components/available-providers-grid.tsx +36 -29
- package/src/components/harnesses-section.tsx +116 -106
- package/src/components/model-provider-grid-skeleton.tsx +21 -0
- package/src/components/model-providers-section.tsx +208 -191
- package/src/pages/model-provider-onboarding-page.tsx +26 -54
- package/tsconfig.build.tsbuildinfo +1 -1
|
@@ -17,11 +17,11 @@ import {
|
|
|
17
17
|
ModalHeader,
|
|
18
18
|
ModalTitle,
|
|
19
19
|
} from '@shipfox/react-ui/modal';
|
|
20
|
+
import {Panel, PanelBody, PanelRow} from '@shipfox/react-ui/panel';
|
|
20
21
|
import {Skeleton} from '@shipfox/react-ui/skeleton';
|
|
21
22
|
import {toast} from '@shipfox/react-ui/toast';
|
|
22
23
|
import {Tooltip, TooltipContent, TooltipTrigger} from '@shipfox/react-ui/tooltip';
|
|
23
24
|
import {Header, Text} from '@shipfox/react-ui/typography';
|
|
24
|
-
import {cn} from '@shipfox/react-ui/utils';
|
|
25
25
|
import {useEffect, useMemo, useReducer, useRef, useState} from 'react';
|
|
26
26
|
import {
|
|
27
27
|
type ManagementModal,
|
|
@@ -46,10 +46,11 @@ import {
|
|
|
46
46
|
useSetDefaultModelProviderMutation,
|
|
47
47
|
} from '#hooks/api/model-providers.js';
|
|
48
48
|
import {AddCustomProviderCard} from './add-custom-provider-card.js';
|
|
49
|
-
import {AvailableProvidersGrid
|
|
49
|
+
import {AvailableProvidersGrid} from './available-providers-grid.js';
|
|
50
50
|
import {ChangeDefaultModelForm} from './change-default-model-form.js';
|
|
51
51
|
import {CustomModelProviderForm} from './custom-model-provider-form.js';
|
|
52
52
|
import {modelProviderConfigErrorToFormError} from './form-errors.js';
|
|
53
|
+
import {ModelProviderGridSkeleton} from './model-provider-grid-skeleton.js';
|
|
53
54
|
import {ModelProviderUsageModal} from './model-provider-usage-modal.js';
|
|
54
55
|
import {
|
|
55
56
|
type ModelProviderUsageTarget,
|
|
@@ -58,9 +59,6 @@ import {
|
|
|
58
59
|
} from './model-provider-usage-target.js';
|
|
59
60
|
import {ModelProviderTestAndSaveForm} from './test-and-save-form.js';
|
|
60
61
|
|
|
61
|
-
const SURFACE_CLASS =
|
|
62
|
-
'overflow-hidden rounded-8 border border-border-neutral-base bg-background-neutral-base';
|
|
63
|
-
|
|
64
62
|
type UsageTarget = {
|
|
65
63
|
target: ModelProviderUsageTarget;
|
|
66
64
|
initialModel: string | null;
|
|
@@ -132,74 +130,83 @@ export function WorkspaceModelProvidersSection({workspaceId}: {workspaceId: stri
|
|
|
132
130
|
) : null}
|
|
133
131
|
|
|
134
132
|
{configsQuery.isError && configsQuery.data === undefined ? (
|
|
135
|
-
<
|
|
136
|
-
<QueryLoadError query={configsQuery} subject="model provider configs" />
|
|
137
|
-
</
|
|
133
|
+
<Panel>
|
|
134
|
+
<QueryLoadError query={configsQuery} subject="model provider configs" variant="panel" />
|
|
135
|
+
</Panel>
|
|
138
136
|
) : null}
|
|
139
137
|
|
|
140
138
|
{configsQuery.data !== undefined && configs.length === 0 ? (
|
|
141
|
-
<
|
|
139
|
+
<Panel>
|
|
142
140
|
<EmptyState
|
|
143
141
|
icon="key2Line"
|
|
144
142
|
title="No providers configured"
|
|
145
143
|
description="Configure a provider below to run agent steps with workspace-managed credentials."
|
|
144
|
+
variant="panel"
|
|
146
145
|
/>
|
|
147
|
-
</
|
|
146
|
+
</Panel>
|
|
148
147
|
) : null}
|
|
149
148
|
|
|
150
149
|
{configs.length > 0 ? (
|
|
151
|
-
<
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
150
|
+
<Panel>
|
|
151
|
+
<PanelBody asChild>
|
|
152
|
+
<ul>
|
|
153
|
+
{configs.map((config) => {
|
|
154
|
+
const catalogEntry = providerById.get(config.providerId);
|
|
155
|
+
const entry =
|
|
156
|
+
catalogEntry && isSupportedProvider(catalogEntry) ? catalogEntry : undefined;
|
|
157
|
+
const builtinConfig = isBuiltinModelProviderConfig(config) ? config : undefined;
|
|
158
|
+
const customConfig = isCustomModelProviderConfig(config) ? config : undefined;
|
|
159
|
+
return (
|
|
160
|
+
<ConfiguredProviderRow
|
|
161
|
+
key={config.providerId}
|
|
162
|
+
workspaceId={workspaceId}
|
|
163
|
+
config={config}
|
|
164
|
+
entry={entry}
|
|
165
|
+
isDefault={config.providerId === defaultProviderId}
|
|
166
|
+
onEdit={() => {
|
|
167
|
+
if (entry && builtinConfig) {
|
|
168
|
+
dispatchModal({
|
|
169
|
+
type: 'edit-builtin',
|
|
170
|
+
provider: entry,
|
|
171
|
+
config: builtinConfig,
|
|
172
|
+
});
|
|
173
|
+
} else if (customConfig) {
|
|
174
|
+
dispatchModal({type: 'edit-custom', config: customConfig});
|
|
175
|
+
}
|
|
176
|
+
}}
|
|
177
|
+
onChangeDefaultModel={() => {
|
|
178
|
+
if (entry && builtinConfig)
|
|
179
|
+
dispatchModal({
|
|
180
|
+
type: 'change-default-model',
|
|
181
|
+
provider: entry,
|
|
182
|
+
config: builtinConfig,
|
|
183
|
+
});
|
|
184
|
+
}}
|
|
185
|
+
onShowUsage={() => {
|
|
186
|
+
if (entry && builtinConfig) {
|
|
187
|
+
setPendingUsageTarget(null);
|
|
188
|
+
dispatchModal({
|
|
189
|
+
type: 'show-usage',
|
|
190
|
+
providerId: entry.id,
|
|
191
|
+
initialModel: builtinConfig.defaultModel,
|
|
192
|
+
restoreFocusToConfiguredProviders: false,
|
|
193
|
+
});
|
|
194
|
+
} else if (customConfig) {
|
|
195
|
+
setPendingUsageTarget(null);
|
|
196
|
+
dispatchModal({
|
|
197
|
+
type: 'show-usage',
|
|
198
|
+
providerId: customConfig.providerId,
|
|
199
|
+
initialModel: customConfig.defaultModel,
|
|
200
|
+
restoreFocusToConfiguredProviders: false,
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
}}
|
|
204
|
+
/>
|
|
205
|
+
);
|
|
206
|
+
})}
|
|
207
|
+
</ul>
|
|
208
|
+
</PanelBody>
|
|
209
|
+
</Panel>
|
|
203
210
|
) : null}
|
|
204
211
|
</section>
|
|
205
212
|
|
|
@@ -211,12 +218,14 @@ export function WorkspaceModelProvidersSection({workspaceId}: {workspaceId: stri
|
|
|
211
218
|
</Text>
|
|
212
219
|
</div>
|
|
213
220
|
|
|
214
|
-
{catalogQuery.isPending || configsQuery.isPending ?
|
|
221
|
+
{catalogQuery.isPending || configsQuery.isPending ? (
|
|
222
|
+
<ModelProviderGridSkeleton label="Loading available providers" />
|
|
223
|
+
) : null}
|
|
215
224
|
|
|
216
225
|
{catalogQuery.isError && catalogQuery.data === undefined ? (
|
|
217
|
-
<
|
|
218
|
-
<QueryLoadError query={catalogQuery} subject="model provider catalog" />
|
|
219
|
-
</
|
|
226
|
+
<Panel>
|
|
227
|
+
<QueryLoadError query={catalogQuery} subject="model provider catalog" variant="panel" />
|
|
228
|
+
</Panel>
|
|
220
229
|
) : null}
|
|
221
230
|
|
|
222
231
|
{configsLoaded ? (
|
|
@@ -244,25 +253,35 @@ export function WorkspaceModelProvidersSection({workspaceId}: {workspaceId: stri
|
|
|
244
253
|
) : null}
|
|
245
254
|
|
|
246
255
|
{unsupportedProviders.length > 0 ? (
|
|
247
|
-
<
|
|
248
|
-
|
|
249
|
-
<
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
256
|
+
<Panel>
|
|
257
|
+
<PanelBody asChild>
|
|
258
|
+
<ul>
|
|
259
|
+
{unsupportedProviders.map((entry) => (
|
|
260
|
+
<PanelRow
|
|
261
|
+
asChild
|
|
262
|
+
className="items-start justify-start gap-cluster opacity-70 hover:bg-background-neutral-base"
|
|
263
|
+
key={entry.id}
|
|
264
|
+
>
|
|
265
|
+
<li>
|
|
266
|
+
<Icon
|
|
267
|
+
name="forbid2Line"
|
|
268
|
+
className="mt-[2px] size-18 shrink-0 text-foreground-neutral-muted"
|
|
269
|
+
aria-hidden
|
|
270
|
+
/>
|
|
271
|
+
<div className="flex min-w-0 flex-1 flex-col gap-tight">
|
|
272
|
+
<Text size="md" bold className="truncate">
|
|
273
|
+
{entry.label}
|
|
274
|
+
</Text>
|
|
275
|
+
<Text size="sm" className="text-foreground-neutral-muted">
|
|
276
|
+
{entry.unsupportedReason}
|
|
277
|
+
</Text>
|
|
278
|
+
</div>
|
|
279
|
+
</li>
|
|
280
|
+
</PanelRow>
|
|
281
|
+
))}
|
|
282
|
+
</ul>
|
|
283
|
+
</PanelBody>
|
|
284
|
+
</Panel>
|
|
266
285
|
) : null}
|
|
267
286
|
</section>
|
|
268
287
|
|
|
@@ -468,91 +487,93 @@ function ConfiguredProviderRow({
|
|
|
468
487
|
}
|
|
469
488
|
|
|
470
489
|
return (
|
|
471
|
-
<
|
|
472
|
-
<
|
|
473
|
-
<div className="flex
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
<
|
|
478
|
-
<
|
|
479
|
-
<
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
<
|
|
497
|
-
<
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
490
|
+
<PanelRow asChild className="flex-col items-stretch gap-inline">
|
|
491
|
+
<li>
|
|
492
|
+
<div className="flex items-center justify-between gap-cluster">
|
|
493
|
+
<div className="flex min-w-0 items-center gap-inline">
|
|
494
|
+
{isDefault ? (
|
|
495
|
+
<>
|
|
496
|
+
<Tooltip>
|
|
497
|
+
<TooltipTrigger asChild>
|
|
498
|
+
<span className="inline-flex size-16 shrink-0 items-center justify-center">
|
|
499
|
+
<Icon
|
|
500
|
+
name="starLine"
|
|
501
|
+
className="size-16 text-foreground-neutral-muted"
|
|
502
|
+
aria-hidden
|
|
503
|
+
/>
|
|
504
|
+
</span>
|
|
505
|
+
</TooltipTrigger>
|
|
506
|
+
<TooltipContent>Default provider</TooltipContent>
|
|
507
|
+
</Tooltip>
|
|
508
|
+
<span className="sr-only">Default provider</span>
|
|
509
|
+
</>
|
|
510
|
+
) : null}
|
|
511
|
+
<Text size="md" bold className="truncate">
|
|
512
|
+
{label}
|
|
513
|
+
</Text>
|
|
514
|
+
</div>
|
|
515
|
+
<DropdownMenu>
|
|
516
|
+
<DropdownMenuTrigger asChild>
|
|
517
|
+
<IconButton
|
|
518
|
+
size="sm"
|
|
519
|
+
variant="transparent"
|
|
520
|
+
icon="more2Line"
|
|
521
|
+
aria-label={`Open ${label} provider actions`}
|
|
522
|
+
/>
|
|
523
|
+
</DropdownMenuTrigger>
|
|
524
|
+
<DropdownMenuContent align="end">
|
|
525
|
+
{!isDefault ? (
|
|
526
|
+
<DropdownMenuItem
|
|
527
|
+
icon="starLine"
|
|
528
|
+
disabled={setDefault.isPending || (!entry && !customConfig)}
|
|
529
|
+
onSelect={() => {
|
|
530
|
+
void handleSetDefault();
|
|
531
|
+
}}
|
|
532
|
+
>
|
|
533
|
+
Set as default
|
|
534
|
+
</DropdownMenuItem>
|
|
535
|
+
) : null}
|
|
536
|
+
{isBuiltinConfig ? (
|
|
537
|
+
<DropdownMenuItem
|
|
538
|
+
icon="settings3Line"
|
|
539
|
+
disabled={!entry}
|
|
540
|
+
onSelect={onChangeDefaultModel}
|
|
541
|
+
>
|
|
542
|
+
Change default model
|
|
543
|
+
</DropdownMenuItem>
|
|
544
|
+
) : null}
|
|
545
|
+
<DropdownMenuItem icon="bookOpenLine" disabled={!canUse} onSelect={onShowUsage}>
|
|
546
|
+
View workflow example
|
|
547
|
+
</DropdownMenuItem>
|
|
548
|
+
<DropdownMenuItem icon="editLine" disabled={!canEdit} onSelect={onEdit}>
|
|
549
|
+
{customConfig ? 'Edit' : 'Edit credentials'}
|
|
550
|
+
</DropdownMenuItem>
|
|
506
551
|
<DropdownMenuItem
|
|
507
|
-
icon="
|
|
508
|
-
disabled={setDefault.isPending || (!entry && !customConfig)}
|
|
552
|
+
icon="deleteBinLine"
|
|
509
553
|
onSelect={() => {
|
|
510
|
-
|
|
554
|
+
setDeleteOpen(true);
|
|
511
555
|
}}
|
|
512
556
|
>
|
|
513
|
-
|
|
514
|
-
</DropdownMenuItem>
|
|
515
|
-
) : null}
|
|
516
|
-
{isBuiltinConfig ? (
|
|
517
|
-
<DropdownMenuItem
|
|
518
|
-
icon="settings3Line"
|
|
519
|
-
disabled={!entry}
|
|
520
|
-
onSelect={onChangeDefaultModel}
|
|
521
|
-
>
|
|
522
|
-
Change default model
|
|
557
|
+
Delete
|
|
523
558
|
</DropdownMenuItem>
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
{defaultError ? (
|
|
543
|
-
<Callout role="alert" type="error">
|
|
544
|
-
<Text size="sm">{defaultError}</Text>
|
|
545
|
-
</Callout>
|
|
546
|
-
) : null}
|
|
547
|
-
<DeleteModelProviderDialog
|
|
548
|
-
open={deleteOpen}
|
|
549
|
-
onOpenChange={handleDeleteOpenChange}
|
|
550
|
-
label={label}
|
|
551
|
-
errorMessage={deleteError}
|
|
552
|
-
isLoading={deleteConfig.isPending}
|
|
553
|
-
onDelete={handleDelete}
|
|
554
|
-
/>
|
|
555
|
-
</li>
|
|
559
|
+
</DropdownMenuContent>
|
|
560
|
+
</DropdownMenu>
|
|
561
|
+
</div>
|
|
562
|
+
{defaultError ? (
|
|
563
|
+
<Callout role="alert" type="error">
|
|
564
|
+
<Text size="sm">{defaultError}</Text>
|
|
565
|
+
</Callout>
|
|
566
|
+
) : null}
|
|
567
|
+
<DeleteModelProviderDialog
|
|
568
|
+
open={deleteOpen}
|
|
569
|
+
onOpenChange={handleDeleteOpenChange}
|
|
570
|
+
label={label}
|
|
571
|
+
errorMessage={deleteError}
|
|
572
|
+
isLoading={deleteConfig.isPending}
|
|
573
|
+
onDelete={handleDelete}
|
|
574
|
+
/>
|
|
575
|
+
</li>
|
|
576
|
+
</PanelRow>
|
|
556
577
|
);
|
|
557
578
|
}
|
|
558
579
|
|
|
@@ -602,31 +623,27 @@ function DeleteModelProviderDialog({
|
|
|
602
623
|
|
|
603
624
|
function ModelProviderRowsSkeleton({label}: {label: string}) {
|
|
604
625
|
return (
|
|
605
|
-
<
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
{[0, 1, 2, 3].map((card) => (
|
|
628
|
-
<Skeleton key={card} className="h-136 w-full" />
|
|
629
|
-
))}
|
|
630
|
-
</div>
|
|
626
|
+
<Panel>
|
|
627
|
+
<PanelBody asChild>
|
|
628
|
+
<ul role="status" aria-label={label}>
|
|
629
|
+
{[0, 1, 2].map((row) => (
|
|
630
|
+
<PanelRow
|
|
631
|
+
asChild
|
|
632
|
+
className="justify-start gap-cluster hover:bg-background-neutral-base"
|
|
633
|
+
key={row}
|
|
634
|
+
>
|
|
635
|
+
<li>
|
|
636
|
+
<Skeleton className="size-32 shrink-0" />
|
|
637
|
+
<div className="flex min-w-0 flex-1 flex-col gap-inline">
|
|
638
|
+
<Skeleton className="h-16 w-120" />
|
|
639
|
+
<Skeleton className="h-14 w-180" />
|
|
640
|
+
</div>
|
|
641
|
+
<Skeleton className="h-28 w-96 shrink-0" />
|
|
642
|
+
</li>
|
|
643
|
+
</PanelRow>
|
|
644
|
+
))}
|
|
645
|
+
</ul>
|
|
646
|
+
</PanelBody>
|
|
647
|
+
</Panel>
|
|
631
648
|
);
|
|
632
649
|
}
|
|
@@ -2,15 +2,14 @@ import {QueryLoadError} from '@shipfox/client-ui';
|
|
|
2
2
|
import {Button} from '@shipfox/react-ui/button';
|
|
3
3
|
import {Callout} from '@shipfox/react-ui/callout';
|
|
4
4
|
import {EmptyState} from '@shipfox/react-ui/empty-state';
|
|
5
|
-
import {Icon} from '@shipfox/react-ui/icon';
|
|
6
5
|
import {Modal, ModalContent, ModalHeader, ModalTitle} from '@shipfox/react-ui/modal';
|
|
7
|
-
import {
|
|
6
|
+
import {Panel, PanelBody, PanelCell, PanelCellAction, PanelGrid} from '@shipfox/react-ui/panel';
|
|
8
7
|
import {toast} from '@shipfox/react-ui/toast';
|
|
9
8
|
import {Header, Text} from '@shipfox/react-ui/typography';
|
|
10
|
-
import {cn} from '@shipfox/react-ui/utils';
|
|
11
9
|
import {useEffect, useMemo, useReducer} from 'react';
|
|
12
|
-
import {AvailableProvidersGrid
|
|
10
|
+
import {AvailableProvidersGrid} from '#components/available-providers-grid.js';
|
|
13
11
|
import {modelProviderConfigErrorToFormError} from '#components/form-errors.js';
|
|
12
|
+
import {ModelProviderGridSkeleton} from '#components/model-provider-grid-skeleton.js';
|
|
14
13
|
import {ModelProviderTestAndSaveForm} from '#components/test-and-save-form.js';
|
|
15
14
|
import {DEFAULT_HARNESS, harnessSupportsProvider, listHarnesses} from '#core/harness-policy.js';
|
|
16
15
|
import type {HarnessDescriptor, HarnessId, SupportedProvider} from '#core/models.js';
|
|
@@ -22,9 +21,6 @@ import {
|
|
|
22
21
|
} from '#hooks/api/model-providers.js';
|
|
23
22
|
import {dismissModelProviderOnboarding} from '#state/model-provider-onboarding.js';
|
|
24
23
|
|
|
25
|
-
const SURFACE_CLASS =
|
|
26
|
-
'overflow-hidden rounded-8 border border-border-neutral-base bg-background-neutral-base';
|
|
27
|
-
|
|
28
24
|
export function ModelProviderOnboardingPage({
|
|
29
25
|
workspaceId,
|
|
30
26
|
onSkip,
|
|
@@ -104,7 +100,7 @@ export function ModelProviderOnboardingPage({
|
|
|
104
100
|
: 'model-provider-provider-step';
|
|
105
101
|
|
|
106
102
|
return (
|
|
107
|
-
<div className="
|
|
103
|
+
<div className="flex w-full flex-col gap-section">
|
|
108
104
|
<header className="flex flex-col gap-cluster">
|
|
109
105
|
<div className="flex items-start justify-between gap-group max-[520px]:flex-col max-[520px]:gap-inline">
|
|
110
106
|
<Header id={headingId} variant="h1" tabIndex={-1} className="outline-none">
|
|
@@ -216,42 +212,32 @@ export function ModelProviderOnboardingPage({
|
|
|
216
212
|
|
|
217
213
|
function HarnessPicker({onSelect}: {onSelect: (harness: HarnessId) => void}) {
|
|
218
214
|
return (
|
|
219
|
-
<
|
|
220
|
-
|
|
221
|
-
<
|
|
222
|
-
|
|
223
|
-
|
|
215
|
+
<Panel>
|
|
216
|
+
<PanelBody>
|
|
217
|
+
<PanelGrid aria-label="Agent harnesses">
|
|
218
|
+
{listHarnesses().map((harness) => (
|
|
219
|
+
<HarnessCard key={harness.id} harness={harness} onChoose={() => onSelect(harness.id)} />
|
|
220
|
+
))}
|
|
221
|
+
</PanelGrid>
|
|
222
|
+
</PanelBody>
|
|
223
|
+
</Panel>
|
|
224
224
|
);
|
|
225
225
|
}
|
|
226
226
|
|
|
227
227
|
function HarnessCard({harness, onChoose}: {harness: HarnessDescriptor; onChoose: () => void}) {
|
|
228
228
|
return (
|
|
229
|
-
<
|
|
230
|
-
<
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
<Text size="md" bold className="min-w-0 truncate">
|
|
242
|
-
{harness.label}
|
|
243
|
-
</Text>
|
|
244
|
-
<Text size="sm" className="text-foreground-neutral-muted">
|
|
245
|
-
{harness.description}
|
|
246
|
-
</Text>
|
|
247
|
-
</div>
|
|
248
|
-
<div className="flex shrink-0 items-center gap-tight text-foreground-neutral-muted transition-colors group-hover:text-foreground-highlight-interactive">
|
|
249
|
-
<Text size="sm">Choose</Text>
|
|
250
|
-
<Icon name="chevronRight" className="size-16" />
|
|
251
|
-
</div>
|
|
252
|
-
</div>
|
|
253
|
-
</button>
|
|
254
|
-
</li>
|
|
229
|
+
<PanelCell>
|
|
230
|
+
<PanelCellAction action="Choose" aria-label={`Choose ${harness.label}`} onClick={onChoose}>
|
|
231
|
+
<span className="flex min-w-0 flex-col gap-tight">
|
|
232
|
+
<Text as="span" size="md" bold className="min-w-0 truncate">
|
|
233
|
+
{harness.label}
|
|
234
|
+
</Text>
|
|
235
|
+
<Text as="span" size="sm" className="text-foreground-neutral-muted">
|
|
236
|
+
{harness.description}
|
|
237
|
+
</Text>
|
|
238
|
+
</span>
|
|
239
|
+
</PanelCellAction>
|
|
240
|
+
</PanelCell>
|
|
255
241
|
);
|
|
256
242
|
}
|
|
257
243
|
|
|
@@ -265,11 +251,7 @@ function ModelProviderPicker({
|
|
|
265
251
|
onSelect: (entry: SupportedProvider) => void;
|
|
266
252
|
}) {
|
|
267
253
|
if (catalogQuery.isPending) {
|
|
268
|
-
return
|
|
269
|
-
<div role="status" aria-busy="true" aria-label="Loading model providers">
|
|
270
|
-
<ModelProviderGridSkeleton />
|
|
271
|
-
</div>
|
|
272
|
-
);
|
|
254
|
+
return <ModelProviderGridSkeleton label="Loading model providers" />;
|
|
273
255
|
}
|
|
274
256
|
|
|
275
257
|
if (catalogQuery.isError && catalogQuery.data === undefined) {
|
|
@@ -288,13 +270,3 @@ function ModelProviderPicker({
|
|
|
288
270
|
|
|
289
271
|
return <AvailableProvidersGrid entries={supportedProviders} onSelect={onSelect} />;
|
|
290
272
|
}
|
|
291
|
-
|
|
292
|
-
function ModelProviderGridSkeleton() {
|
|
293
|
-
return (
|
|
294
|
-
<div className={PROVIDER_GRID_CLASS}>
|
|
295
|
-
{[0, 1, 2, 3].map((card) => (
|
|
296
|
-
<Skeleton key={card} className="h-136 w-full" />
|
|
297
|
-
))}
|
|
298
|
-
</div>
|
|
299
|
-
);
|
|
300
|
-
}
|