@shipfox/client-agent 17.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 +34 -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/custom-model-provider-form.stories.js +1 -1
- package/dist/components/custom-model-provider-form.stories.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/harnesses-section.stories.js +1 -1
- package/dist/components/harnesses-section.stories.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-provider-usage-modal.stories.js +1 -1
- package/dist/components/model-provider-usage-modal.stories.js.map +1 -1
- 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/components/model-providers-section.stories.js +1 -1
- package/dist/components/model-providers-section.stories.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/pages/model-provider-onboarding-page.stories.js +1 -1
- package/dist/pages/model-provider-onboarding-page.stories.js.map +1 -1
- package/dist/routes/agents-settings.d.ts +3 -0
- package/dist/routes/agents-settings.js +3 -0
- package/dist/routes/agents-settings.js.map +1 -1
- package/dist/routes/model-provider.d.ts +3 -0
- package/dist/routes/model-provider.js +3 -0
- package/dist/routes/model-provider.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/custom-model-provider-form.stories.tsx +1 -1
- package/src/components/harnesses-section.stories.tsx +1 -1
- package/src/components/harnesses-section.tsx +116 -106
- package/src/components/model-provider-grid-skeleton.tsx +21 -0
- package/src/components/model-provider-usage-modal.stories.tsx +1 -1
- package/src/components/model-providers-section.stories.tsx +1 -1
- package/src/components/model-providers-section.tsx +208 -191
- package/src/pages/model-provider-onboarding-page.stories.tsx +1 -1
- package/src/pages/model-provider-onboarding-page.tsx +26 -54
- package/src/routes/agents-settings.tsx +1 -0
- package/src/routes/model-provider.tsx +1 -0
- package/tsconfig.build.tsbuildinfo +1 -1
|
@@ -4,17 +4,16 @@ import { IconButton } from '@shipfox/react-ui/button';
|
|
|
4
4
|
import { Callout } from '@shipfox/react-ui/callout';
|
|
5
5
|
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@shipfox/react-ui/dropdown-menu';
|
|
6
6
|
import { Icon } from '@shipfox/react-ui/icon';
|
|
7
|
+
import { Panel, PanelBody, PanelRow } from '@shipfox/react-ui/panel';
|
|
7
8
|
import { Skeleton } from '@shipfox/react-ui/skeleton';
|
|
8
9
|
import { toast } from '@shipfox/react-ui/toast';
|
|
9
10
|
import { Tooltip, TooltipContent, TooltipTrigger } from '@shipfox/react-ui/tooltip';
|
|
10
11
|
import { Header, Text } from '@shipfox/react-ui/typography';
|
|
11
|
-
import { cn } from '@shipfox/react-ui/utils';
|
|
12
12
|
import { useRef, useState } from 'react';
|
|
13
13
|
import { DEFAULT_HARNESS, listHarnesses } from '#core/harness-policy.js';
|
|
14
14
|
import { useModelProviderConfigsQuery, useSetDefaultHarnessMutation } from '#hooks/api/model-providers.js';
|
|
15
15
|
import { modelProviderConfigErrorToFormError } from './form-errors.js';
|
|
16
16
|
import { isHarnessAvailable } from './harness-availability.js';
|
|
17
|
-
const SURFACE_CLASS = 'overflow-hidden rounded-8 border border-border-neutral-base bg-background-neutral-base';
|
|
18
17
|
export function WorkspaceHarnessesSection({ workspaceId }) {
|
|
19
18
|
const configsQuery = useModelProviderConfigsQuery(workspaceId);
|
|
20
19
|
const setDefaultHarness = useSetDefaultHarnessMutation();
|
|
@@ -84,134 +83,141 @@ export function WorkspaceHarnessesSection({ workspaceId }) {
|
|
|
84
83
|
]
|
|
85
84
|
}),
|
|
86
85
|
configsQuery.isPending ? /*#__PURE__*/ _jsx(HarnessRowsSkeleton, {}) : null,
|
|
87
|
-
configsQuery.isError && configsQuery.data === undefined ? /*#__PURE__*/ _jsx(
|
|
88
|
-
className: cn(SURFACE_CLASS, 'px-row'),
|
|
86
|
+
configsQuery.isError && configsQuery.data === undefined ? /*#__PURE__*/ _jsx(Panel, {
|
|
89
87
|
children: /*#__PURE__*/ _jsx(QueryLoadError, {
|
|
90
88
|
query: configsQuery,
|
|
91
|
-
subject: "harnesses"
|
|
89
|
+
subject: "harnesses",
|
|
90
|
+
variant: "panel"
|
|
92
91
|
})
|
|
93
92
|
}) : null,
|
|
94
|
-
configsQuery.data !== undefined ? /*#__PURE__*/ _jsx(
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
93
|
+
configsQuery.data !== undefined ? /*#__PURE__*/ _jsx(Panel, {
|
|
94
|
+
children: /*#__PURE__*/ _jsx(PanelBody, {
|
|
95
|
+
asChild: true,
|
|
96
|
+
children: /*#__PURE__*/ _jsx("ul", {
|
|
97
|
+
children: listHarnesses().map((harness)=>/*#__PURE__*/ _jsx(HarnessRow, {
|
|
98
|
+
harness: harness,
|
|
99
|
+
isDefault: harness.id === defaultHarnessId,
|
|
100
|
+
isAvailable: isHarnessAvailable(harness, configs),
|
|
101
|
+
isSettingDefault: pendingDefaultHarness?.workspaceId === workspaceId,
|
|
102
|
+
defaultError: defaultError?.workspaceId === workspaceId && defaultError.harnessId === harness.id ? defaultError.message : undefined,
|
|
103
|
+
onSetDefault: handleSetDefault
|
|
104
|
+
}, harness.id))
|
|
105
|
+
})
|
|
106
|
+
})
|
|
104
107
|
}) : null
|
|
105
108
|
]
|
|
106
109
|
});
|
|
107
110
|
}
|
|
108
111
|
function HarnessRow({ harness, isDefault, isAvailable, isSettingDefault, defaultError, onSetDefault }) {
|
|
109
112
|
const unavailableCopy = harnessUnavailableCopy(isDefault);
|
|
110
|
-
return /*#__PURE__*/
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
children: /*#__PURE__*/ _jsx(
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
113
|
+
return /*#__PURE__*/ _jsx(PanelRow, {
|
|
114
|
+
asChild: true,
|
|
115
|
+
className: "flex-col items-stretch gap-inline",
|
|
116
|
+
children: /*#__PURE__*/ _jsxs("li", {
|
|
117
|
+
children: [
|
|
118
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
119
|
+
className: "flex items-center justify-between gap-cluster",
|
|
120
|
+
children: [
|
|
121
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
122
|
+
className: "flex min-w-0 items-center gap-inline",
|
|
123
|
+
children: [
|
|
124
|
+
isDefault ? /*#__PURE__*/ _jsxs(_Fragment, {
|
|
125
|
+
children: [
|
|
126
|
+
/*#__PURE__*/ _jsxs(Tooltip, {
|
|
127
|
+
children: [
|
|
128
|
+
/*#__PURE__*/ _jsx(TooltipTrigger, {
|
|
129
|
+
asChild: true,
|
|
130
|
+
children: /*#__PURE__*/ _jsx("span", {
|
|
131
|
+
className: "inline-flex size-16 shrink-0 items-center justify-center",
|
|
132
|
+
children: /*#__PURE__*/ _jsx(Icon, {
|
|
133
|
+
name: "starLine",
|
|
134
|
+
className: "size-16 text-foreground-neutral-muted",
|
|
135
|
+
"aria-hidden": true
|
|
136
|
+
})
|
|
131
137
|
})
|
|
138
|
+
}),
|
|
139
|
+
/*#__PURE__*/ _jsx(TooltipContent, {
|
|
140
|
+
children: "Default harness"
|
|
132
141
|
})
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
name: "errorWarningLine",
|
|
161
|
-
className: "size-16 text-foreground-warning-base",
|
|
162
|
-
"aria-hidden": true
|
|
142
|
+
]
|
|
143
|
+
}),
|
|
144
|
+
/*#__PURE__*/ _jsx("span", {
|
|
145
|
+
className: "sr-only",
|
|
146
|
+
children: "Default harness"
|
|
147
|
+
})
|
|
148
|
+
]
|
|
149
|
+
}) : null,
|
|
150
|
+
/*#__PURE__*/ _jsx(Text, {
|
|
151
|
+
size: "md",
|
|
152
|
+
bold: true,
|
|
153
|
+
className: "truncate",
|
|
154
|
+
children: harness.label
|
|
155
|
+
}),
|
|
156
|
+
!isAvailable ? /*#__PURE__*/ _jsxs(_Fragment, {
|
|
157
|
+
children: [
|
|
158
|
+
/*#__PURE__*/ _jsxs(Tooltip, {
|
|
159
|
+
children: [
|
|
160
|
+
/*#__PURE__*/ _jsx(TooltipTrigger, {
|
|
161
|
+
asChild: true,
|
|
162
|
+
children: /*#__PURE__*/ _jsx("span", {
|
|
163
|
+
className: "inline-flex size-16 shrink-0 items-center justify-center",
|
|
164
|
+
children: /*#__PURE__*/ _jsx(Icon, {
|
|
165
|
+
name: "errorWarningLine",
|
|
166
|
+
className: "size-16 text-foreground-warning-base",
|
|
167
|
+
"aria-hidden": true
|
|
168
|
+
})
|
|
163
169
|
})
|
|
170
|
+
}),
|
|
171
|
+
/*#__PURE__*/ _jsx(TooltipContent, {
|
|
172
|
+
children: unavailableCopy
|
|
164
173
|
})
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
+
]
|
|
175
|
+
}),
|
|
176
|
+
/*#__PURE__*/ _jsx("span", {
|
|
177
|
+
className: "sr-only",
|
|
178
|
+
children: unavailableCopy
|
|
179
|
+
})
|
|
180
|
+
]
|
|
181
|
+
}) : null
|
|
182
|
+
]
|
|
183
|
+
}),
|
|
184
|
+
!isDefault ? /*#__PURE__*/ _jsxs(DropdownMenu, {
|
|
185
|
+
children: [
|
|
186
|
+
/*#__PURE__*/ _jsx(DropdownMenuTrigger, {
|
|
187
|
+
asChild: true,
|
|
188
|
+
children: /*#__PURE__*/ _jsx(IconButton, {
|
|
189
|
+
size: "sm",
|
|
190
|
+
variant: "transparent",
|
|
191
|
+
icon: "more2Line",
|
|
192
|
+
disabled: isSettingDefault,
|
|
193
|
+
"aria-label": `Open ${harness.label} harness actions`
|
|
194
|
+
})
|
|
195
|
+
}),
|
|
196
|
+
/*#__PURE__*/ _jsx(DropdownMenuContent, {
|
|
197
|
+
align: "end",
|
|
198
|
+
children: /*#__PURE__*/ _jsx(DropdownMenuItem, {
|
|
199
|
+
icon: "starLine",
|
|
200
|
+
disabled: isSettingDefault || !isAvailable,
|
|
201
|
+
onSelect: ()=>{
|
|
202
|
+
onSetDefault(harness);
|
|
203
|
+
},
|
|
204
|
+
children: "Set as default"
|
|
174
205
|
})
|
|
175
|
-
]
|
|
176
|
-
}) : null
|
|
177
|
-
]
|
|
178
|
-
}),
|
|
179
|
-
!isDefault ? /*#__PURE__*/ _jsxs(DropdownMenu, {
|
|
180
|
-
children: [
|
|
181
|
-
/*#__PURE__*/ _jsx(DropdownMenuTrigger, {
|
|
182
|
-
asChild: true,
|
|
183
|
-
children: /*#__PURE__*/ _jsx(IconButton, {
|
|
184
|
-
size: "sm",
|
|
185
|
-
variant: "transparent",
|
|
186
|
-
icon: "more2Line",
|
|
187
|
-
disabled: isSettingDefault,
|
|
188
|
-
"aria-label": `Open ${harness.label} harness actions`
|
|
189
|
-
})
|
|
190
|
-
}),
|
|
191
|
-
/*#__PURE__*/ _jsx(DropdownMenuContent, {
|
|
192
|
-
align: "end",
|
|
193
|
-
children: /*#__PURE__*/ _jsx(DropdownMenuItem, {
|
|
194
|
-
icon: "starLine",
|
|
195
|
-
disabled: isSettingDefault || !isAvailable,
|
|
196
|
-
onSelect: ()=>{
|
|
197
|
-
onSetDefault(harness);
|
|
198
|
-
},
|
|
199
|
-
children: "Set as default"
|
|
200
206
|
})
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
})
|
|
213
|
-
|
|
214
|
-
|
|
207
|
+
]
|
|
208
|
+
}) : null
|
|
209
|
+
]
|
|
210
|
+
}),
|
|
211
|
+
defaultError ? /*#__PURE__*/ _jsx(Callout, {
|
|
212
|
+
role: "alert",
|
|
213
|
+
type: "error",
|
|
214
|
+
children: /*#__PURE__*/ _jsx(Text, {
|
|
215
|
+
size: "sm",
|
|
216
|
+
children: defaultError
|
|
217
|
+
})
|
|
218
|
+
}) : null
|
|
219
|
+
]
|
|
220
|
+
})
|
|
215
221
|
});
|
|
216
222
|
}
|
|
217
223
|
function harnessUnavailableCopy(isDefault) {
|
|
@@ -220,27 +226,34 @@ function harnessUnavailableCopy(isDefault) {
|
|
|
220
226
|
return `${base} The stored default harness cannot currently run in this workspace.`;
|
|
221
227
|
}
|
|
222
228
|
function HarnessRowsSkeleton() {
|
|
223
|
-
return /*#__PURE__*/ _jsx(
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
1
|
|
230
|
-
].map((row)=>/*#__PURE__*/ _jsxs("li", {
|
|
231
|
-
className: "flex items-center gap-cluster px-row py-row",
|
|
229
|
+
return /*#__PURE__*/ _jsx(Panel, {
|
|
230
|
+
children: /*#__PURE__*/ _jsx(PanelBody, {
|
|
231
|
+
asChild: true,
|
|
232
|
+
children: /*#__PURE__*/ _jsx("ul", {
|
|
233
|
+
role: "status",
|
|
234
|
+
"aria-label": "Loading harnesses",
|
|
232
235
|
children: [
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
className: "
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
236
|
+
0,
|
|
237
|
+
1
|
|
238
|
+
].map((row)=>/*#__PURE__*/ _jsx(PanelRow, {
|
|
239
|
+
asChild: true,
|
|
240
|
+
className: "justify-start gap-cluster hover:bg-background-neutral-base",
|
|
241
|
+
children: /*#__PURE__*/ _jsxs("li", {
|
|
242
|
+
children: [
|
|
243
|
+
/*#__PURE__*/ _jsx(Skeleton, {
|
|
244
|
+
className: "size-16 shrink-0"
|
|
245
|
+
}),
|
|
246
|
+
/*#__PURE__*/ _jsx(Skeleton, {
|
|
247
|
+
className: "h-16 w-120"
|
|
248
|
+
}),
|
|
249
|
+
/*#__PURE__*/ _jsx(Skeleton, {
|
|
250
|
+
className: "ml-auto size-28 shrink-0"
|
|
251
|
+
})
|
|
252
|
+
]
|
|
253
|
+
})
|
|
254
|
+
}, row))
|
|
255
|
+
})
|
|
256
|
+
})
|
|
244
257
|
});
|
|
245
258
|
}
|
|
246
259
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/harnesses-section.tsx"],"sourcesContent":["import {QueryLoadError} from '@shipfox/client-ui';\nimport {IconButton} from '@shipfox/react-ui/button';\nimport {Callout} from '@shipfox/react-ui/callout';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@shipfox/react-ui/dropdown-menu';\nimport {Icon} from '@shipfox/react-ui/icon';\nimport {Skeleton} from '@shipfox/react-ui/skeleton';\nimport {toast} from '@shipfox/react-ui/toast';\nimport {Tooltip, TooltipContent, TooltipTrigger} from '@shipfox/react-ui/tooltip';\nimport {Header, Text} from '@shipfox/react-ui/typography';\nimport {cn} from '@shipfox/react-ui/utils';\nimport {useRef, useState} from 'react';\nimport {DEFAULT_HARNESS, listHarnesses} from '#core/harness-policy.js';\nimport type {HarnessDescriptor, HarnessId} from '#core/models.js';\nimport {\n useModelProviderConfigsQuery,\n useSetDefaultHarnessMutation,\n} from '#hooks/api/model-providers.js';\nimport {modelProviderConfigErrorToFormError} from './form-errors.js';\nimport {isHarnessAvailable} from './harness-availability.js';\n\nconst SURFACE_CLASS =\n 'overflow-hidden rounded-8 border border-border-neutral-base bg-background-neutral-base';\n\nexport function WorkspaceHarnessesSection({workspaceId}: {workspaceId: string}) {\n const configsQuery = useModelProviderConfigsQuery(workspaceId);\n const setDefaultHarness = useSetDefaultHarnessMutation();\n const activeWorkspaceIdRef = useRef(workspaceId);\n const defaultRequestSeqRef = useRef(0);\n const activeDefaultRequestRef = useRef<{workspaceId: string; id: number} | null>(null);\n const [pendingDefaultHarness, setPendingDefaultHarness] = useState<{\n workspaceId: string;\n harnessId: HarnessId;\n } | null>(null);\n const [defaultError, setDefaultError] = useState<\n {workspaceId: string; harnessId: HarnessId; message: string} | undefined\n >();\n const configs = configsQuery.data?.configs ?? [];\n const defaultHarnessId = configsQuery.data?.defaultHarnessId ?? DEFAULT_HARNESS;\n activeWorkspaceIdRef.current = workspaceId;\n\n function isActiveDefaultRequest(request: {workspaceId: string; id: number}) {\n const activeRequest = activeDefaultRequestRef.current;\n return (\n activeWorkspaceIdRef.current === request.workspaceId &&\n activeRequest?.workspaceId === request.workspaceId &&\n activeRequest.id === request.id\n );\n }\n\n async function handleSetDefault(harness: HarnessDescriptor) {\n if (activeDefaultRequestRef.current?.workspaceId === workspaceId) return;\n\n const request = {workspaceId, id: defaultRequestSeqRef.current + 1};\n defaultRequestSeqRef.current = request.id;\n activeDefaultRequestRef.current = request;\n setPendingDefaultHarness({workspaceId, harnessId: harness.id});\n setDefaultError(undefined);\n try {\n await setDefaultHarness.mutateAsync({\n workspaceId,\n harnessId: harness.id,\n });\n if (!isActiveDefaultRequest(request)) return;\n toast.success(`${harness.label} is now the default harness`);\n } catch (error) {\n if (!isActiveDefaultRequest(request)) return;\n const mapped = modelProviderConfigErrorToFormError(error);\n setDefaultError({\n workspaceId,\n harnessId: harness.id,\n message: mapped.message || 'Could not save default harness. Try again.',\n });\n } finally {\n if (isActiveDefaultRequest(request)) {\n activeDefaultRequestRef.current = null;\n setPendingDefaultHarness(null);\n }\n }\n }\n\n return (\n <section className=\"flex flex-col gap-group\" aria-label=\"Harnesses\">\n <div className=\"flex flex-col gap-tight\">\n <Header variant=\"h3\">Harnesses</Header>\n <Text size=\"sm\" className=\"text-foreground-neutral-muted\">\n Harnesses available to run agent steps in this workspace.\n </Text>\n </div>\n\n {configsQuery.isPending ? <HarnessRowsSkeleton /> : null}\n\n {configsQuery.isError && configsQuery.data === undefined ? (\n <div className={cn(SURFACE_CLASS, 'px-row')}>\n <QueryLoadError query={configsQuery} subject=\"harnesses\" />\n </div>\n ) : null}\n\n {configsQuery.data !== undefined ? (\n <ul className={cn('divide-y divide-border-neutral-base', SURFACE_CLASS)}>\n {listHarnesses().map((harness) => (\n <HarnessRow\n key={harness.id}\n harness={harness}\n isDefault={harness.id === defaultHarnessId}\n isAvailable={isHarnessAvailable(harness, configs)}\n isSettingDefault={pendingDefaultHarness?.workspaceId === workspaceId}\n defaultError={\n defaultError?.workspaceId === workspaceId && defaultError.harnessId === harness.id\n ? defaultError.message\n : undefined\n }\n onSetDefault={handleSetDefault}\n />\n ))}\n </ul>\n ) : null}\n </section>\n );\n}\n\nfunction HarnessRow({\n harness,\n isDefault,\n isAvailable,\n isSettingDefault,\n defaultError,\n onSetDefault,\n}: {\n harness: HarnessDescriptor;\n isDefault: boolean;\n isAvailable: boolean;\n isSettingDefault: boolean;\n defaultError: string | undefined;\n onSetDefault: (harness: HarnessDescriptor) => void;\n}) {\n const unavailableCopy = harnessUnavailableCopy(isDefault);\n\n return (\n <li className=\"flex flex-col gap-inline px-row py-row transition-colors hover:bg-background-components-hover\">\n <div className=\"flex items-center justify-between gap-cluster\">\n <div className=\"flex min-w-0 items-center gap-inline\">\n {isDefault ? (\n <>\n <Tooltip>\n <TooltipTrigger asChild>\n <span className=\"inline-flex size-16 shrink-0 items-center justify-center\">\n <Icon\n name=\"starLine\"\n className=\"size-16 text-foreground-neutral-muted\"\n aria-hidden\n />\n </span>\n </TooltipTrigger>\n <TooltipContent>Default harness</TooltipContent>\n </Tooltip>\n <span className=\"sr-only\">Default harness</span>\n </>\n ) : null}\n <Text size=\"md\" bold className=\"truncate\">\n {harness.label}\n </Text>\n {!isAvailable ? (\n <>\n <Tooltip>\n <TooltipTrigger asChild>\n <span className=\"inline-flex size-16 shrink-0 items-center justify-center\">\n <Icon\n name=\"errorWarningLine\"\n className=\"size-16 text-foreground-warning-base\"\n aria-hidden\n />\n </span>\n </TooltipTrigger>\n <TooltipContent>{unavailableCopy}</TooltipContent>\n </Tooltip>\n <span className=\"sr-only\">{unavailableCopy}</span>\n </>\n ) : null}\n </div>\n {!isDefault ? (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <IconButton\n size=\"sm\"\n variant=\"transparent\"\n icon=\"more2Line\"\n disabled={isSettingDefault}\n aria-label={`Open ${harness.label} harness actions`}\n />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem\n icon=\"starLine\"\n disabled={isSettingDefault || !isAvailable}\n onSelect={() => {\n onSetDefault(harness);\n }}\n >\n Set as default\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n ) : null}\n </div>\n {defaultError ? (\n <Callout role=\"alert\" type=\"error\">\n <Text size=\"sm\">{defaultError}</Text>\n </Callout>\n ) : null}\n </li>\n );\n}\n\nfunction harnessUnavailableCopy(isDefault: boolean): string {\n const base = 'Configure a compatible model provider to use this harness.';\n if (!isDefault) return base;\n return `${base} The stored default harness cannot currently run in this workspace.`;\n}\n\nfunction HarnessRowsSkeleton() {\n return (\n <ul\n role=\"status\"\n aria-label=\"Loading harnesses\"\n className={cn('divide-y divide-border-neutral-base', SURFACE_CLASS)}\n >\n {[0, 1].map((row) => (\n <li key={row} className=\"flex items-center gap-cluster px-row py-row\">\n <Skeleton className=\"size-16 shrink-0\" />\n <Skeleton className=\"h-16 w-120\" />\n <Skeleton className=\"ml-auto size-28 shrink-0\" />\n </li>\n ))}\n </ul>\n );\n}\n"],"names":["QueryLoadError","IconButton","Callout","DropdownMenu","DropdownMenuContent","DropdownMenuItem","DropdownMenuTrigger","Icon","Skeleton","toast","Tooltip","TooltipContent","TooltipTrigger","Header","Text","cn","useRef","useState","DEFAULT_HARNESS","listHarnesses","useModelProviderConfigsQuery","useSetDefaultHarnessMutation","modelProviderConfigErrorToFormError","isHarnessAvailable","SURFACE_CLASS","WorkspaceHarnessesSection","workspaceId","configsQuery","setDefaultHarness","activeWorkspaceIdRef","defaultRequestSeqRef","activeDefaultRequestRef","pendingDefaultHarness","setPendingDefaultHarness","defaultError","setDefaultError","configs","data","defaultHarnessId","current","isActiveDefaultRequest","request","activeRequest","id","handleSetDefault","harness","harnessId","undefined","mutateAsync","success","label","error","mapped","message","section","className","aria-label","div","variant","size","isPending","HarnessRowsSkeleton","isError","query","subject","ul","map","HarnessRow","isDefault","isAvailable","isSettingDefault","onSetDefault","unavailableCopy","harnessUnavailableCopy","li","asChild","span","name","aria-hidden","bold","icon","disabled","align","onSelect","role","type","base","row"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/components/harnesses-section.tsx"],"sourcesContent":["import {QueryLoadError} from '@shipfox/client-ui';\nimport {IconButton} from '@shipfox/react-ui/button';\nimport {Callout} from '@shipfox/react-ui/callout';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@shipfox/react-ui/dropdown-menu';\nimport {Icon} from '@shipfox/react-ui/icon';\nimport {Panel, PanelBody, PanelRow} from '@shipfox/react-ui/panel';\nimport {Skeleton} from '@shipfox/react-ui/skeleton';\nimport {toast} from '@shipfox/react-ui/toast';\nimport {Tooltip, TooltipContent, TooltipTrigger} from '@shipfox/react-ui/tooltip';\nimport {Header, Text} from '@shipfox/react-ui/typography';\nimport {useRef, useState} from 'react';\nimport {DEFAULT_HARNESS, listHarnesses} from '#core/harness-policy.js';\nimport type {HarnessDescriptor, HarnessId} from '#core/models.js';\nimport {\n useModelProviderConfigsQuery,\n useSetDefaultHarnessMutation,\n} from '#hooks/api/model-providers.js';\nimport {modelProviderConfigErrorToFormError} from './form-errors.js';\nimport {isHarnessAvailable} from './harness-availability.js';\n\nexport function WorkspaceHarnessesSection({workspaceId}: {workspaceId: string}) {\n const configsQuery = useModelProviderConfigsQuery(workspaceId);\n const setDefaultHarness = useSetDefaultHarnessMutation();\n const activeWorkspaceIdRef = useRef(workspaceId);\n const defaultRequestSeqRef = useRef(0);\n const activeDefaultRequestRef = useRef<{workspaceId: string; id: number} | null>(null);\n const [pendingDefaultHarness, setPendingDefaultHarness] = useState<{\n workspaceId: string;\n harnessId: HarnessId;\n } | null>(null);\n const [defaultError, setDefaultError] = useState<\n {workspaceId: string; harnessId: HarnessId; message: string} | undefined\n >();\n const configs = configsQuery.data?.configs ?? [];\n const defaultHarnessId = configsQuery.data?.defaultHarnessId ?? DEFAULT_HARNESS;\n activeWorkspaceIdRef.current = workspaceId;\n\n function isActiveDefaultRequest(request: {workspaceId: string; id: number}) {\n const activeRequest = activeDefaultRequestRef.current;\n return (\n activeWorkspaceIdRef.current === request.workspaceId &&\n activeRequest?.workspaceId === request.workspaceId &&\n activeRequest.id === request.id\n );\n }\n\n async function handleSetDefault(harness: HarnessDescriptor) {\n if (activeDefaultRequestRef.current?.workspaceId === workspaceId) return;\n\n const request = {workspaceId, id: defaultRequestSeqRef.current + 1};\n defaultRequestSeqRef.current = request.id;\n activeDefaultRequestRef.current = request;\n setPendingDefaultHarness({workspaceId, harnessId: harness.id});\n setDefaultError(undefined);\n try {\n await setDefaultHarness.mutateAsync({\n workspaceId,\n harnessId: harness.id,\n });\n if (!isActiveDefaultRequest(request)) return;\n toast.success(`${harness.label} is now the default harness`);\n } catch (error) {\n if (!isActiveDefaultRequest(request)) return;\n const mapped = modelProviderConfigErrorToFormError(error);\n setDefaultError({\n workspaceId,\n harnessId: harness.id,\n message: mapped.message || 'Could not save default harness. Try again.',\n });\n } finally {\n if (isActiveDefaultRequest(request)) {\n activeDefaultRequestRef.current = null;\n setPendingDefaultHarness(null);\n }\n }\n }\n\n return (\n <section className=\"flex flex-col gap-group\" aria-label=\"Harnesses\">\n <div className=\"flex flex-col gap-tight\">\n <Header variant=\"h3\">Harnesses</Header>\n <Text size=\"sm\" className=\"text-foreground-neutral-muted\">\n Harnesses available to run agent steps in this workspace.\n </Text>\n </div>\n\n {configsQuery.isPending ? <HarnessRowsSkeleton /> : null}\n\n {configsQuery.isError && configsQuery.data === undefined ? (\n <Panel>\n <QueryLoadError query={configsQuery} subject=\"harnesses\" variant=\"panel\" />\n </Panel>\n ) : null}\n\n {configsQuery.data !== undefined ? (\n <Panel>\n <PanelBody asChild>\n <ul>\n {listHarnesses().map((harness) => (\n <HarnessRow\n key={harness.id}\n harness={harness}\n isDefault={harness.id === defaultHarnessId}\n isAvailable={isHarnessAvailable(harness, configs)}\n isSettingDefault={pendingDefaultHarness?.workspaceId === workspaceId}\n defaultError={\n defaultError?.workspaceId === workspaceId &&\n defaultError.harnessId === harness.id\n ? defaultError.message\n : undefined\n }\n onSetDefault={handleSetDefault}\n />\n ))}\n </ul>\n </PanelBody>\n </Panel>\n ) : null}\n </section>\n );\n}\n\nfunction HarnessRow({\n harness,\n isDefault,\n isAvailable,\n isSettingDefault,\n defaultError,\n onSetDefault,\n}: {\n harness: HarnessDescriptor;\n isDefault: boolean;\n isAvailable: boolean;\n isSettingDefault: boolean;\n defaultError: string | undefined;\n onSetDefault: (harness: HarnessDescriptor) => void;\n}) {\n const unavailableCopy = harnessUnavailableCopy(isDefault);\n\n return (\n <PanelRow asChild className=\"flex-col items-stretch gap-inline\">\n <li>\n <div className=\"flex items-center justify-between gap-cluster\">\n <div className=\"flex min-w-0 items-center gap-inline\">\n {isDefault ? (\n <>\n <Tooltip>\n <TooltipTrigger asChild>\n <span className=\"inline-flex size-16 shrink-0 items-center justify-center\">\n <Icon\n name=\"starLine\"\n className=\"size-16 text-foreground-neutral-muted\"\n aria-hidden\n />\n </span>\n </TooltipTrigger>\n <TooltipContent>Default harness</TooltipContent>\n </Tooltip>\n <span className=\"sr-only\">Default harness</span>\n </>\n ) : null}\n <Text size=\"md\" bold className=\"truncate\">\n {harness.label}\n </Text>\n {!isAvailable ? (\n <>\n <Tooltip>\n <TooltipTrigger asChild>\n <span className=\"inline-flex size-16 shrink-0 items-center justify-center\">\n <Icon\n name=\"errorWarningLine\"\n className=\"size-16 text-foreground-warning-base\"\n aria-hidden\n />\n </span>\n </TooltipTrigger>\n <TooltipContent>{unavailableCopy}</TooltipContent>\n </Tooltip>\n <span className=\"sr-only\">{unavailableCopy}</span>\n </>\n ) : null}\n </div>\n {!isDefault ? (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <IconButton\n size=\"sm\"\n variant=\"transparent\"\n icon=\"more2Line\"\n disabled={isSettingDefault}\n aria-label={`Open ${harness.label} harness actions`}\n />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem\n icon=\"starLine\"\n disabled={isSettingDefault || !isAvailable}\n onSelect={() => {\n onSetDefault(harness);\n }}\n >\n Set as default\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n ) : null}\n </div>\n {defaultError ? (\n <Callout role=\"alert\" type=\"error\">\n <Text size=\"sm\">{defaultError}</Text>\n </Callout>\n ) : null}\n </li>\n </PanelRow>\n );\n}\n\nfunction harnessUnavailableCopy(isDefault: boolean): string {\n const base = 'Configure a compatible model provider to use this harness.';\n if (!isDefault) return base;\n return `${base} The stored default harness cannot currently run in this workspace.`;\n}\n\nfunction HarnessRowsSkeleton() {\n return (\n <Panel>\n <PanelBody asChild>\n <ul role=\"status\" aria-label=\"Loading harnesses\">\n {[0, 1].map((row) => (\n <PanelRow\n asChild\n className=\"justify-start gap-cluster hover:bg-background-neutral-base\"\n key={row}\n >\n <li>\n <Skeleton className=\"size-16 shrink-0\" />\n <Skeleton className=\"h-16 w-120\" />\n <Skeleton className=\"ml-auto size-28 shrink-0\" />\n </li>\n </PanelRow>\n ))}\n </ul>\n </PanelBody>\n </Panel>\n );\n}\n"],"names":["QueryLoadError","IconButton","Callout","DropdownMenu","DropdownMenuContent","DropdownMenuItem","DropdownMenuTrigger","Icon","Panel","PanelBody","PanelRow","Skeleton","toast","Tooltip","TooltipContent","TooltipTrigger","Header","Text","useRef","useState","DEFAULT_HARNESS","listHarnesses","useModelProviderConfigsQuery","useSetDefaultHarnessMutation","modelProviderConfigErrorToFormError","isHarnessAvailable","WorkspaceHarnessesSection","workspaceId","configsQuery","setDefaultHarness","activeWorkspaceIdRef","defaultRequestSeqRef","activeDefaultRequestRef","pendingDefaultHarness","setPendingDefaultHarness","defaultError","setDefaultError","configs","data","defaultHarnessId","current","isActiveDefaultRequest","request","activeRequest","id","handleSetDefault","harness","harnessId","undefined","mutateAsync","success","label","error","mapped","message","section","className","aria-label","div","variant","size","isPending","HarnessRowsSkeleton","isError","query","subject","asChild","ul","map","HarnessRow","isDefault","isAvailable","isSettingDefault","onSetDefault","unavailableCopy","harnessUnavailableCopy","li","span","name","aria-hidden","bold","icon","disabled","align","onSelect","role","type","base","row"],"mappings":"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"}
|
|
@@ -21,7 +21,7 @@ function HarnessesStory({ scenario }) {
|
|
|
21
21
|
client: queryClient,
|
|
22
22
|
children: [
|
|
23
23
|
/*#__PURE__*/ _jsx("div", {
|
|
24
|
-
className: "mx-auto w-full max-w-[760px] bg-background-
|
|
24
|
+
className: "mx-auto w-full max-w-[760px] bg-background-subtle-base p-24",
|
|
25
25
|
children: /*#__PURE__*/ _jsx(WorkspaceHarnessesSection, {
|
|
26
26
|
workspaceId: WORKSPACE_ID
|
|
27
27
|
})
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/harnesses-section.stories.tsx"],"sourcesContent":["import type {ModelProviderConfigDto} from '@shipfox/api-agent-dto';\nimport {configureApiClient} from '@shipfox/client-api';\nimport {Toaster} from '@shipfox/react-ui/toast';\nimport type {Meta, StoryObj} from '@storybook/react';\nimport {QueryClient, QueryClientProvider} from '@tanstack/react-query';\nimport {useMemo} from 'react';\nimport {WorkspaceHarnessesSection} from './harnesses-section.js';\n\nconst WORKSPACE_ID = '11111111-1111-4111-8111-111111111111';\n\ntype Scenario =\n | 'default-pi'\n | 'default-claude'\n | 'claude-unavailable'\n | 'default-claude-unavailable'\n | 'loading'\n | 'error';\n\ninterface HarnessesStoryProps {\n scenario: Scenario;\n}\n\nfunction HarnessesStory({scenario}: HarnessesStoryProps) {\n configureApiClient({\n baseUrl: 'https://api.example.test',\n fetchImpl: fetchForScenario(scenario),\n });\n\n const queryClient = useMemo(\n () => new QueryClient({defaultOptions: {queries: {retry: false}}}),\n [],\n );\n\n return (\n <QueryClientProvider client={queryClient}>\n <div className=\"mx-auto w-full max-w-[760px] bg-background-
|
|
1
|
+
{"version":3,"sources":["../../src/components/harnesses-section.stories.tsx"],"sourcesContent":["import type {ModelProviderConfigDto} from '@shipfox/api-agent-dto';\nimport {configureApiClient} from '@shipfox/client-api';\nimport {Toaster} from '@shipfox/react-ui/toast';\nimport type {Meta, StoryObj} from '@storybook/react';\nimport {QueryClient, QueryClientProvider} from '@tanstack/react-query';\nimport {useMemo} from 'react';\nimport {WorkspaceHarnessesSection} from './harnesses-section.js';\n\nconst WORKSPACE_ID = '11111111-1111-4111-8111-111111111111';\n\ntype Scenario =\n | 'default-pi'\n | 'default-claude'\n | 'claude-unavailable'\n | 'default-claude-unavailable'\n | 'loading'\n | 'error';\n\ninterface HarnessesStoryProps {\n scenario: Scenario;\n}\n\nfunction HarnessesStory({scenario}: HarnessesStoryProps) {\n configureApiClient({\n baseUrl: 'https://api.example.test',\n fetchImpl: fetchForScenario(scenario),\n });\n\n const queryClient = useMemo(\n () => new QueryClient({defaultOptions: {queries: {retry: false}}}),\n [],\n );\n\n return (\n <QueryClientProvider client={queryClient}>\n <div className=\"mx-auto w-full max-w-[760px] bg-background-subtle-base p-24\">\n <WorkspaceHarnessesSection workspaceId={WORKSPACE_ID} />\n </div>\n <Toaster />\n </QueryClientProvider>\n );\n}\n\nconst meta = {\n title: 'Agent/HarnessSettings',\n component: HarnessesStory,\n parameters: {layout: 'fullscreen'},\n args: {scenario: 'default-pi'},\n} satisfies Meta<typeof HarnessesStory>;\n\nexport default meta;\ntype Story = StoryObj<typeof meta>;\n\nexport const Playground: Story = {};\n\nexport const DefaultClaude: Story = {\n args: {scenario: 'default-claude'},\n};\n\nexport const ClaudeUnavailable: Story = {\n args: {scenario: 'claude-unavailable'},\n};\n\nexport const DefaultClaudeUnavailable: Story = {\n args: {scenario: 'default-claude-unavailable'},\n};\n\nexport const Loading: Story = {\n args: {scenario: 'loading'},\n};\n\nexport const ErrorState: Story = {\n args: {scenario: 'error'},\n};\n\nfunction fetchForScenario(scenario: Scenario): typeof fetch {\n return () => {\n if (scenario === 'loading') return new Promise<Response>(() => undefined);\n if (scenario === 'error') return Promise.resolve(errorResponse());\n return Promise.resolve(jsonResponse(configsForScenario(scenario)));\n };\n}\n\nfunction configsForScenario(scenario: Scenario) {\n if (scenario === 'claude-unavailable') {\n return {\n configs: [providerConfig({provider_id: 'openai'})],\n default_provider_id: 'openai',\n default_harness_id: null,\n };\n }\n if (scenario === 'default-claude-unavailable') {\n return {\n configs: [providerConfig({provider_id: 'openai'})],\n default_provider_id: 'openai',\n default_harness_id: 'claude',\n };\n }\n return {\n configs: [providerConfig({provider_id: 'anthropic'})],\n default_provider_id: 'anthropic',\n default_harness_id: scenario === 'default-claude' ? 'claude' : null,\n };\n}\n\nfunction providerConfig(\n overrides: Partial<Omit<ModelProviderConfigDto, 'kind'>> = {},\n): ModelProviderConfigDto {\n return {\n kind: 'builtin',\n provider_id: 'anthropic',\n default_model: null,\n created_at: '2026-05-08T00:00:00.000Z',\n updated_at: '2026-05-08T00:00:00.000Z',\n ...overrides,\n };\n}\n\nfunction jsonResponse(body: unknown, init: ResponseInit = {}) {\n return new Response(JSON.stringify(body), {\n status: 200,\n headers: {'content-type': 'application/json'},\n ...init,\n });\n}\n\nfunction errorResponse() {\n return jsonResponse({code: 'server-error'}, {status: 500, statusText: 'Server error'});\n}\n"],"names":["configureApiClient","Toaster","QueryClient","QueryClientProvider","useMemo","WorkspaceHarnessesSection","WORKSPACE_ID","HarnessesStory","scenario","baseUrl","fetchImpl","fetchForScenario","queryClient","defaultOptions","queries","retry","client","div","className","workspaceId","meta","title","component","parameters","layout","args","Playground","DefaultClaude","ClaudeUnavailable","DefaultClaudeUnavailable","Loading","ErrorState","Promise","undefined","resolve","errorResponse","jsonResponse","configsForScenario","configs","providerConfig","provider_id","default_provider_id","default_harness_id","overrides","kind","default_model","created_at","updated_at","body","init","Response","JSON","stringify","status","headers","code","statusText"],"mappings":";AACA,SAAQA,kBAAkB,QAAO,sBAAsB;AACvD,SAAQC,OAAO,QAAO,0BAA0B;AAEhD,SAAQC,WAAW,EAAEC,mBAAmB,QAAO,wBAAwB;AACvE,SAAQC,OAAO,QAAO,QAAQ;AAC9B,SAAQC,yBAAyB,QAAO,yBAAyB;AAEjE,MAAMC,eAAe;AAcrB,SAASC,eAAe,EAACC,QAAQ,EAAsB;IACrDR,mBAAmB;QACjBS,SAAS;QACTC,WAAWC,iBAAiBH;IAC9B;IAEA,MAAMI,cAAcR,QAClB,IAAM,IAAIF,YAAY;YAACW,gBAAgB;gBAACC,SAAS;oBAACC,OAAO;gBAAK;YAAC;QAAC,IAChE,EAAE;IAGJ,qBACE,MAACZ;QAAoBa,QAAQJ;;0BAC3B,KAACK;gBAAIC,WAAU;0BACb,cAAA,KAACb;oBAA0Bc,aAAab;;;0BAE1C,KAACL;;;AAGP;AAEA,MAAMmB,OAAO;IACXC,OAAO;IACPC,WAAWf;IACXgB,YAAY;QAACC,QAAQ;IAAY;IACjCC,MAAM;QAACjB,UAAU;IAAY;AAC/B;AAEA,eAAeY,KAAK;AAGpB,OAAO,MAAMM,aAAoB,CAAC,EAAE;AAEpC,OAAO,MAAMC,gBAAuB;IAClCF,MAAM;QAACjB,UAAU;IAAgB;AACnC,EAAE;AAEF,OAAO,MAAMoB,oBAA2B;IACtCH,MAAM;QAACjB,UAAU;IAAoB;AACvC,EAAE;AAEF,OAAO,MAAMqB,2BAAkC;IAC7CJ,MAAM;QAACjB,UAAU;IAA4B;AAC/C,EAAE;AAEF,OAAO,MAAMsB,UAAiB;IAC5BL,MAAM;QAACjB,UAAU;IAAS;AAC5B,EAAE;AAEF,OAAO,MAAMuB,aAAoB;IAC/BN,MAAM;QAACjB,UAAU;IAAO;AAC1B,EAAE;AAEF,SAASG,iBAAiBH,QAAkB;IAC1C,OAAO;QACL,IAAIA,aAAa,WAAW,OAAO,IAAIwB,QAAkB,IAAMC;QAC/D,IAAIzB,aAAa,SAAS,OAAOwB,QAAQE,OAAO,CAACC;QACjD,OAAOH,QAAQE,OAAO,CAACE,aAAaC,mBAAmB7B;IACzD;AACF;AAEA,SAAS6B,mBAAmB7B,QAAkB;IAC5C,IAAIA,aAAa,sBAAsB;QACrC,OAAO;YACL8B,SAAS;gBAACC,eAAe;oBAACC,aAAa;gBAAQ;aAAG;YAClDC,qBAAqB;YACrBC,oBAAoB;QACtB;IACF;IACA,IAAIlC,aAAa,8BAA8B;QAC7C,OAAO;YACL8B,SAAS;gBAACC,eAAe;oBAACC,aAAa;gBAAQ;aAAG;YAClDC,qBAAqB;YACrBC,oBAAoB;QACtB;IACF;IACA,OAAO;QACLJ,SAAS;YAACC,eAAe;gBAACC,aAAa;YAAW;SAAG;QACrDC,qBAAqB;QACrBC,oBAAoBlC,aAAa,mBAAmB,WAAW;IACjE;AACF;AAEA,SAAS+B,eACPI,YAA2D,CAAC,CAAC;IAE7D,OAAO;QACLC,MAAM;QACNJ,aAAa;QACbK,eAAe;QACfC,YAAY;QACZC,YAAY;QACZ,GAAGJ,SAAS;IACd;AACF;AAEA,SAASP,aAAaY,IAAa,EAAEC,OAAqB,CAAC,CAAC;IAC1D,OAAO,IAAIC,SAASC,KAAKC,SAAS,CAACJ,OAAO;QACxCK,QAAQ;QACRC,SAAS;YAAC,gBAAgB;QAAkB;QAC5C,GAAGL,IAAI;IACT;AACF;AAEA,SAASd;IACP,OAAOC,aAAa;QAACmB,MAAM;IAAc,GAAG;QAACF,QAAQ;QAAKG,YAAY;IAAc;AACtF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-provider-grid-skeleton.d.ts","sourceRoot":"","sources":["../../src/components/model-provider-grid-skeleton.tsx"],"names":[],"mappings":"AAGA,wBAAgB,yBAAyB,CAAC,EAAC,KAAK,EAAC,EAAE;IAAC,KAAK,EAAE,MAAM,CAAA;CAAC,+BAiBjE"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Panel, PanelBody, PanelCell, PanelGrid } from '@shipfox/react-ui/panel';
|
|
3
|
+
import { Skeleton } from '@shipfox/react-ui/skeleton';
|
|
4
|
+
export function ModelProviderGridSkeleton({ label }) {
|
|
5
|
+
return /*#__PURE__*/ _jsx(Panel, {
|
|
6
|
+
children: /*#__PURE__*/ _jsx(PanelBody, {
|
|
7
|
+
children: /*#__PURE__*/ _jsx(PanelGrid, {
|
|
8
|
+
role: "status",
|
|
9
|
+
"aria-busy": "true",
|
|
10
|
+
"aria-label": label,
|
|
11
|
+
children: [
|
|
12
|
+
0,
|
|
13
|
+
1,
|
|
14
|
+
2,
|
|
15
|
+
3
|
|
16
|
+
].map((tile)=>/*#__PURE__*/ _jsx(PanelCell, {
|
|
17
|
+
children: /*#__PURE__*/ _jsxs("div", {
|
|
18
|
+
className: "flex items-center justify-between gap-cluster px-row py-row",
|
|
19
|
+
children: [
|
|
20
|
+
/*#__PURE__*/ _jsx(Skeleton, {
|
|
21
|
+
className: "h-16 w-100"
|
|
22
|
+
}),
|
|
23
|
+
/*#__PURE__*/ _jsx(Skeleton, {
|
|
24
|
+
className: "h-16 w-64 shrink-0"
|
|
25
|
+
})
|
|
26
|
+
]
|
|
27
|
+
})
|
|
28
|
+
}, tile))
|
|
29
|
+
})
|
|
30
|
+
})
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
//# sourceMappingURL=model-provider-grid-skeleton.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/model-provider-grid-skeleton.tsx"],"sourcesContent":["import {Panel, PanelBody, PanelCell, PanelGrid} from '@shipfox/react-ui/panel';\nimport {Skeleton} from '@shipfox/react-ui/skeleton';\n\nexport function ModelProviderGridSkeleton({label}: {label: string}) {\n return (\n <Panel>\n <PanelBody>\n <PanelGrid role=\"status\" aria-busy=\"true\" aria-label={label}>\n {[0, 1, 2, 3].map((tile) => (\n <PanelCell key={tile}>\n <div className=\"flex items-center justify-between gap-cluster px-row py-row\">\n <Skeleton className=\"h-16 w-100\" />\n <Skeleton className=\"h-16 w-64 shrink-0\" />\n </div>\n </PanelCell>\n ))}\n </PanelGrid>\n </PanelBody>\n </Panel>\n );\n}\n"],"names":["Panel","PanelBody","PanelCell","PanelGrid","Skeleton","ModelProviderGridSkeleton","label","role","aria-busy","aria-label","map","tile","div","className"],"mappings":";AAAA,SAAQA,KAAK,EAAEC,SAAS,EAAEC,SAAS,EAAEC,SAAS,QAAO,0BAA0B;AAC/E,SAAQC,QAAQ,QAAO,6BAA6B;AAEpD,OAAO,SAASC,0BAA0B,EAACC,KAAK,EAAkB;IAChE,qBACE,KAACN;kBACC,cAAA,KAACC;sBACC,cAAA,KAACE;gBAAUI,MAAK;gBAASC,aAAU;gBAAOC,cAAYH;0BACnD;oBAAC;oBAAG;oBAAG;oBAAG;iBAAE,CAACI,GAAG,CAAC,CAACC,qBACjB,KAACT;kCACC,cAAA,MAACU;4BAAIC,WAAU;;8CACb,KAACT;oCAASS,WAAU;;8CACpB,KAACT;oCAASS,WAAU;;;;uBAHRF;;;;AAW5B"}
|
|
@@ -7,7 +7,7 @@ function ModelProviderUsageModalStory({ variant }) {
|
|
|
7
7
|
const entry = variant === 'long-list' ? longListEntry() : anthropicEntry();
|
|
8
8
|
const target = variant === 'custom' ? usageTargetFromCustomConfig(customProviderConfig()) : usageTargetFromCatalogEntry(entry);
|
|
9
9
|
return /*#__PURE__*/ _jsx("div", {
|
|
10
|
-
className: "min-h-screen bg-background-
|
|
10
|
+
className: "min-h-screen bg-background-subtle-base p-24",
|
|
11
11
|
children: /*#__PURE__*/ _jsx(ModelProviderUsageModal, {
|
|
12
12
|
target: target,
|
|
13
13
|
initialModel: target.defaultModel,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/model-provider-usage-modal.stories.tsx"],"sourcesContent":["import type {Meta, StoryObj} from '@storybook/react';\nimport {useState} from 'react';\nimport type {CustomProviderConfig, SupportedProvider} from '#core/models.js';\nimport {ModelProviderUsageModal} from './model-provider-usage-modal.js';\nimport {\n usageTargetFromCatalogEntry,\n usageTargetFromCustomConfig,\n} from './model-provider-usage-target.js';\n\ninterface ModelProviderUsageModalStoryProps {\n variant: 'anthropic' | 'custom' | 'long-list';\n}\n\nfunction ModelProviderUsageModalStory({variant}: ModelProviderUsageModalStoryProps) {\n const [open, setOpen] = useState(true);\n const entry = variant === 'long-list' ? longListEntry() : anthropicEntry();\n const target =\n variant === 'custom'\n ? usageTargetFromCustomConfig(customProviderConfig())\n : usageTargetFromCatalogEntry(entry);\n\n return (\n <div className=\"min-h-screen bg-background-
|
|
1
|
+
{"version":3,"sources":["../../src/components/model-provider-usage-modal.stories.tsx"],"sourcesContent":["import type {Meta, StoryObj} from '@storybook/react';\nimport {useState} from 'react';\nimport type {CustomProviderConfig, SupportedProvider} from '#core/models.js';\nimport {ModelProviderUsageModal} from './model-provider-usage-modal.js';\nimport {\n usageTargetFromCatalogEntry,\n usageTargetFromCustomConfig,\n} from './model-provider-usage-target.js';\n\ninterface ModelProviderUsageModalStoryProps {\n variant: 'anthropic' | 'custom' | 'long-list';\n}\n\nfunction ModelProviderUsageModalStory({variant}: ModelProviderUsageModalStoryProps) {\n const [open, setOpen] = useState(true);\n const entry = variant === 'long-list' ? longListEntry() : anthropicEntry();\n const target =\n variant === 'custom'\n ? usageTargetFromCustomConfig(customProviderConfig())\n : usageTargetFromCatalogEntry(entry);\n\n return (\n <div className=\"min-h-screen bg-background-subtle-base p-24\">\n <ModelProviderUsageModal\n target={target}\n initialModel={target.defaultModel}\n workspaceDefaultHarnessId=\"claude\"\n open={open}\n onOpenChange={setOpen}\n />\n </div>\n );\n}\n\nconst meta = {\n title: 'Agent/ProviderUsageModal',\n component: ModelProviderUsageModalStory,\n parameters: {layout: 'fullscreen'},\n args: {variant: 'anthropic'},\n} satisfies Meta<typeof ModelProviderUsageModalStory>;\n\nexport default meta;\ntype Story = StoryObj<typeof meta>;\n\nexport const Playground: Story = {};\n\nexport const LongModelList: Story = {\n args: {variant: 'long-list'},\n};\n\nexport const CustomProvider: Story = {\n args: {variant: 'custom'},\n};\n\nfunction anthropicEntry(): SupportedProvider {\n return {\n kind: 'supported',\n id: 'anthropic',\n label: 'Anthropic',\n defaultModel: 'claude-opus-4-8',\n credentialFields: [{key: 'api_key', label: 'API key', secret: true}],\n models: [\n {id: 'claude-opus-4-8', label: 'Claude Opus 4.8'},\n {id: 'claude-sonnet-4-8', label: 'Claude Sonnet 4.8'},\n {id: 'claude-haiku-4-5', label: 'Claude Haiku 4.5'},\n ],\n };\n}\n\nfunction longListEntry(): SupportedProvider {\n return {\n kind: 'supported',\n id: 'cloudflare-workers-ai',\n label: 'Cloudflare Workers AI',\n defaultModel: '@cf/moonshotai/kimi-k2.7-code',\n credentialFields: [{key: 'api_token', label: 'API token', secret: true}],\n models: Array.from({length: 56}, (_, index) => ({\n id:\n index === 0\n ? '@cf/moonshotai/kimi-k2.7-code'\n : `provider/research-lab/model-family-${String(index).padStart(2, '0')}-large-context`,\n label: index === 0 ? 'Kimi K2.7 Code' : `Research Model ${index}`,\n })),\n };\n}\n\nfunction customProviderConfig(): CustomProviderConfig {\n return {\n kind: 'custom',\n providerId: 'local-vllm',\n displayName: 'Local vLLM',\n api: 'openai-completions',\n baseUrl: 'http://localhost:8000/v1',\n headers: [],\n secretHeaderNames: [],\n models: [{id: 'llama-3.1', label: 'Llama 3.1'}],\n defaultModel: 'llama-3.1',\n createdAt: '2026-05-08T00:00:00.000Z',\n updatedAt: '2026-05-08T00:00:00.000Z',\n };\n}\n"],"names":["useState","ModelProviderUsageModal","usageTargetFromCatalogEntry","usageTargetFromCustomConfig","ModelProviderUsageModalStory","variant","open","setOpen","entry","longListEntry","anthropicEntry","target","customProviderConfig","div","className","initialModel","defaultModel","workspaceDefaultHarnessId","onOpenChange","meta","title","component","parameters","layout","args","Playground","LongModelList","CustomProvider","kind","id","label","credentialFields","key","secret","models","Array","from","length","_","index","String","padStart","providerId","displayName","api","baseUrl","headers","secretHeaderNames","createdAt","updatedAt"],"mappings":";AACA,SAAQA,QAAQ,QAAO,QAAQ;AAE/B,SAAQC,uBAAuB,QAAO,kCAAkC;AACxE,SACEC,2BAA2B,EAC3BC,2BAA2B,QACtB,mCAAmC;AAM1C,SAASC,6BAA6B,EAACC,OAAO,EAAoC;IAChF,MAAM,CAACC,MAAMC,QAAQ,GAAGP,SAAS;IACjC,MAAMQ,QAAQH,YAAY,cAAcI,kBAAkBC;IAC1D,MAAMC,SACJN,YAAY,WACRF,4BAA4BS,0BAC5BV,4BAA4BM;IAElC,qBACE,KAACK;QAAIC,WAAU;kBACb,cAAA,KAACb;YACCU,QAAQA;YACRI,cAAcJ,OAAOK,YAAY;YACjCC,2BAA0B;YAC1BX,MAAMA;YACNY,cAAcX;;;AAItB;AAEA,MAAMY,OAAO;IACXC,OAAO;IACPC,WAAWjB;IACXkB,YAAY;QAACC,QAAQ;IAAY;IACjCC,MAAM;QAACnB,SAAS;IAAW;AAC7B;AAEA,eAAec,KAAK;AAGpB,OAAO,MAAMM,aAAoB,CAAC,EAAE;AAEpC,OAAO,MAAMC,gBAAuB;IAClCF,MAAM;QAACnB,SAAS;IAAW;AAC7B,EAAE;AAEF,OAAO,MAAMsB,iBAAwB;IACnCH,MAAM;QAACnB,SAAS;IAAQ;AAC1B,EAAE;AAEF,SAASK;IACP,OAAO;QACLkB,MAAM;QACNC,IAAI;QACJC,OAAO;QACPd,cAAc;QACde,kBAAkB;YAAC;gBAACC,KAAK;gBAAWF,OAAO;gBAAWG,QAAQ;YAAI;SAAE;QACpEC,QAAQ;YACN;gBAACL,IAAI;gBAAmBC,OAAO;YAAiB;YAChD;gBAACD,IAAI;gBAAqBC,OAAO;YAAmB;YACpD;gBAACD,IAAI;gBAAoBC,OAAO;YAAkB;SACnD;IACH;AACF;AAEA,SAASrB;IACP,OAAO;QACLmB,MAAM;QACNC,IAAI;QACJC,OAAO;QACPd,cAAc;QACde,kBAAkB;YAAC;gBAACC,KAAK;gBAAaF,OAAO;gBAAaG,QAAQ;YAAI;SAAE;QACxEC,QAAQC,MAAMC,IAAI,CAAC;YAACC,QAAQ;QAAE,GAAG,CAACC,GAAGC,QAAW,CAAA;gBAC9CV,IACEU,UAAU,IACN,kCACA,CAAC,mCAAmC,EAAEC,OAAOD,OAAOE,QAAQ,CAAC,GAAG,KAAK,cAAc,CAAC;gBAC1FX,OAAOS,UAAU,IAAI,mBAAmB,CAAC,eAAe,EAAEA,OAAO;YACnE,CAAA;IACF;AACF;AAEA,SAAS3B;IACP,OAAO;QACLgB,MAAM;QACNc,YAAY;QACZC,aAAa;QACbC,KAAK;QACLC,SAAS;QACTC,SAAS,EAAE;QACXC,mBAAmB,EAAE;QACrBb,QAAQ;YAAC;gBAACL,IAAI;gBAAaC,OAAO;YAAW;SAAE;QAC/Cd,cAAc;QACdgC,WAAW;QACXC,WAAW;IACb;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-providers-section.d.ts","sourceRoot":"","sources":["../../src/components/model-providers-section.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"model-providers-section.d.ts","sourceRoot":"","sources":["../../src/components/model-providers-section.tsx"],"names":[],"mappings":"AAqEA,wBAAgB,8BAA8B,CAAC,EAAC,WAAW,EAAC,EAAE;IAAC,WAAW,EAAE,MAAM,CAAA;CAAC,+BAgVlF"}
|