@shipfox/client-agent 0.2.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.
Files changed (182) hide show
  1. package/.storybook/main.ts +1 -0
  2. package/.storybook/preview.css +4 -0
  3. package/.storybook/preview.tsx +56 -0
  4. package/.turbo/turbo-build.log +2 -0
  5. package/.turbo/turbo-type$colon$emit.log +1 -0
  6. package/.turbo/turbo-type.log +1 -0
  7. package/CHANGELOG.md +93 -0
  8. package/LICENSE +21 -0
  9. package/dist/components/add-custom-provider-card.d.ts +4 -0
  10. package/dist/components/add-custom-provider-card.d.ts.map +1 -0
  11. package/dist/components/add-custom-provider-card.js +41 -0
  12. package/dist/components/add-custom-provider-card.js.map +1 -0
  13. package/dist/components/agent-workflow-example.d.ts +11 -0
  14. package/dist/components/agent-workflow-example.d.ts.map +1 -0
  15. package/dist/components/agent-workflow-example.js +38 -0
  16. package/dist/components/agent-workflow-example.js.map +1 -0
  17. package/dist/components/available-provider-card.d.ts +6 -0
  18. package/dist/components/available-provider-card.d.ts.map +1 -0
  19. package/dist/components/available-provider-card.js +41 -0
  20. package/dist/components/available-provider-card.js.map +1 -0
  21. package/dist/components/available-providers-grid.d.ts +10 -0
  22. package/dist/components/available-providers-grid.d.ts.map +1 -0
  23. package/dist/components/available-providers-grid.js +89 -0
  24. package/dist/components/available-providers-grid.js.map +1 -0
  25. package/dist/components/change-default-model-form.d.ts +9 -0
  26. package/dist/components/change-default-model-form.d.ts.map +1 -0
  27. package/dist/components/change-default-model-form.js +98 -0
  28. package/dist/components/change-default-model-form.js.map +1 -0
  29. package/dist/components/custom-model-provider-api-options.d.ts +7 -0
  30. package/dist/components/custom-model-provider-api-options.d.ts.map +1 -0
  31. package/dist/components/custom-model-provider-api-options.js +23 -0
  32. package/dist/components/custom-model-provider-api-options.js.map +1 -0
  33. package/dist/components/custom-model-provider-form.d.ts +8 -0
  34. package/dist/components/custom-model-provider-form.d.ts.map +1 -0
  35. package/dist/components/custom-model-provider-form.js +667 -0
  36. package/dist/components/custom-model-provider-form.js.map +1 -0
  37. package/dist/components/custom-model-provider-form.stories.d.ts +20 -0
  38. package/dist/components/custom-model-provider-form.stories.d.ts.map +1 -0
  39. package/dist/components/custom-model-provider-form.stories.js +104 -0
  40. package/dist/components/custom-model-provider-form.stories.js.map +1 -0
  41. package/dist/components/custom-model-provider-payload.d.ts +39 -0
  42. package/dist/components/custom-model-provider-payload.d.ts.map +1 -0
  43. package/dist/components/custom-model-provider-payload.js +203 -0
  44. package/dist/components/custom-model-provider-payload.js.map +1 -0
  45. package/dist/components/custom-model-provider-slug.d.ts +3 -0
  46. package/dist/components/custom-model-provider-slug.d.ts.map +1 -0
  47. package/dist/components/custom-model-provider-slug.js +14 -0
  48. package/dist/components/custom-model-provider-slug.js.map +1 -0
  49. package/dist/components/default-model-field.d.ts +16 -0
  50. package/dist/components/default-model-field.d.ts.map +1 -0
  51. package/dist/components/default-model-field.js +60 -0
  52. package/dist/components/default-model-field.js.map +1 -0
  53. package/dist/components/form-errors.d.ts +11 -0
  54. package/dist/components/form-errors.d.ts.map +1 -0
  55. package/dist/components/form-errors.js +101 -0
  56. package/dist/components/form-errors.js.map +1 -0
  57. package/dist/components/harness-availability.d.ts +8 -0
  58. package/dist/components/harness-availability.d.ts.map +1 -0
  59. package/dist/components/harness-availability.js +16 -0
  60. package/dist/components/harness-availability.js.map +1 -0
  61. package/dist/components/harnesses-section.d.ts +4 -0
  62. package/dist/components/harnesses-section.d.ts.map +1 -0
  63. package/dist/components/harnesses-section.js +249 -0
  64. package/dist/components/harnesses-section.js.map +1 -0
  65. package/dist/components/harnesses-section.stories.d.ts +25 -0
  66. package/dist/components/harnesses-section.stories.d.ts.map +1 -0
  67. package/dist/components/harnesses-section.stories.js +138 -0
  68. package/dist/components/harnesses-section.stories.js.map +1 -0
  69. package/dist/components/model-provider-usage-modal.d.ts +11 -0
  70. package/dist/components/model-provider-usage-modal.d.ts.map +1 -0
  71. package/dist/components/model-provider-usage-modal.js +349 -0
  72. package/dist/components/model-provider-usage-modal.js.map +1 -0
  73. package/dist/components/model-provider-usage-modal.stories.d.ts +21 -0
  74. package/dist/components/model-provider-usage-modal.stories.d.ts.map +1 -0
  75. package/dist/components/model-provider-usage-modal.stories.js +115 -0
  76. package/dist/components/model-provider-usage-modal.stories.js.map +1 -0
  77. package/dist/components/model-provider-usage-target.d.ts +14 -0
  78. package/dist/components/model-provider-usage-target.d.ts.map +1 -0
  79. package/dist/components/model-provider-usage-target.js +20 -0
  80. package/dist/components/model-provider-usage-target.js.map +1 -0
  81. package/dist/components/model-providers-section.d.ts +4 -0
  82. package/dist/components/model-providers-section.d.ts.map +1 -0
  83. package/dist/components/model-providers-section.js +668 -0
  84. package/dist/components/model-providers-section.js.map +1 -0
  85. package/dist/components/model-providers-section.stories.d.ts +32 -0
  86. package/dist/components/model-providers-section.stories.d.ts.map +1 -0
  87. package/dist/components/model-providers-section.stories.js +442 -0
  88. package/dist/components/model-providers-section.stories.js.map +1 -0
  89. package/dist/components/provider-search.d.ts +4 -0
  90. package/dist/components/provider-search.d.ts.map +1 -0
  91. package/dist/components/provider-search.js +13 -0
  92. package/dist/components/provider-search.js.map +1 -0
  93. package/dist/components/supported-model-provider-catalog-entry.d.ts +8 -0
  94. package/dist/components/supported-model-provider-catalog-entry.d.ts.map +1 -0
  95. package/dist/components/supported-model-provider-catalog-entry.js +9 -0
  96. package/dist/components/supported-model-provider-catalog-entry.js.map +1 -0
  97. package/dist/components/test-and-save-form.d.ts +10 -0
  98. package/dist/components/test-and-save-form.d.ts.map +1 -0
  99. package/dist/components/test-and-save-form.js +138 -0
  100. package/dist/components/test-and-save-form.js.map +1 -0
  101. package/dist/feature.d.ts +9 -0
  102. package/dist/feature.d.ts.map +1 -0
  103. package/dist/feature.js +13 -0
  104. package/dist/feature.js.map +1 -0
  105. package/dist/hooks/api/model-providers.d.ts +334 -0
  106. package/dist/hooks/api/model-providers.d.ts.map +1 -0
  107. package/dist/hooks/api/model-providers.js +190 -0
  108. package/dist/hooks/api/model-providers.js.map +1 -0
  109. package/dist/index.d.ts +9 -0
  110. package/dist/index.d.ts.map +1 -0
  111. package/dist/index.js +10 -0
  112. package/dist/index.js.map +1 -0
  113. package/dist/pages/model-provider-onboarding-page.d.ts +6 -0
  114. package/dist/pages/model-provider-onboarding-page.d.ts.map +1 -0
  115. package/dist/pages/model-provider-onboarding-page.js +295 -0
  116. package/dist/pages/model-provider-onboarding-page.js.map +1 -0
  117. package/dist/pages/model-provider-onboarding-page.stories.d.ts +27 -0
  118. package/dist/pages/model-provider-onboarding-page.stories.d.ts.map +1 -0
  119. package/dist/pages/model-provider-onboarding-page.stories.js +368 -0
  120. package/dist/pages/model-provider-onboarding-page.stories.js.map +1 -0
  121. package/dist/routes/model-provider.d.ts +5 -0
  122. package/dist/routes/model-provider.d.ts.map +1 -0
  123. package/dist/routes/model-provider.js +28 -0
  124. package/dist/routes/model-provider.js.map +1 -0
  125. package/dist/state/model-provider-onboarding.d.ts +3 -0
  126. package/dist/state/model-provider-onboarding.d.ts.map +1 -0
  127. package/dist/state/model-provider-onboarding.js +28 -0
  128. package/dist/state/model-provider-onboarding.js.map +1 -0
  129. package/dist/tsconfig.test.tsbuildinfo +1 -0
  130. package/package.json +114 -0
  131. package/src/components/add-custom-provider-card.tsx +32 -0
  132. package/src/components/agent-workflow-example.test.ts +74 -0
  133. package/src/components/agent-workflow-example.ts +55 -0
  134. package/src/components/available-provider-card.tsx +39 -0
  135. package/src/components/available-providers-grid.test.tsx +55 -0
  136. package/src/components/available-providers-grid.tsx +106 -0
  137. package/src/components/change-default-model-form.tsx +104 -0
  138. package/src/components/custom-model-provider-api-options.test.ts +18 -0
  139. package/src/components/custom-model-provider-api-options.ts +12 -0
  140. package/src/components/custom-model-provider-form.stories.tsx +91 -0
  141. package/src/components/custom-model-provider-form.tsx +710 -0
  142. package/src/components/custom-model-provider-payload.test.ts +170 -0
  143. package/src/components/custom-model-provider-payload.ts +264 -0
  144. package/src/components/custom-model-provider-slug.test.ts +40 -0
  145. package/src/components/custom-model-provider-slug.ts +23 -0
  146. package/src/components/default-model-field.tsx +85 -0
  147. package/src/components/form-errors.test.ts +159 -0
  148. package/src/components/form-errors.ts +102 -0
  149. package/src/components/harness-availability.test.ts +45 -0
  150. package/src/components/harness-availability.ts +35 -0
  151. package/src/components/harnesses-section.stories.tsx +129 -0
  152. package/src/components/harnesses-section.test.tsx +188 -0
  153. package/src/components/harnesses-section.tsx +245 -0
  154. package/src/components/model-provider-usage-modal.stories.tsx +106 -0
  155. package/src/components/model-provider-usage-modal.test.tsx +210 -0
  156. package/src/components/model-provider-usage-modal.tsx +326 -0
  157. package/src/components/model-provider-usage-target.ts +36 -0
  158. package/src/components/model-providers-section.stories.tsx +345 -0
  159. package/src/components/model-providers-section.test.tsx +831 -0
  160. package/src/components/model-providers-section.tsx +645 -0
  161. package/src/components/provider-search.test.ts +45 -0
  162. package/src/components/provider-search.ts +18 -0
  163. package/src/components/supported-model-provider-catalog-entry.ts +19 -0
  164. package/src/components/test-and-save-form.tsx +166 -0
  165. package/src/feature.ts +12 -0
  166. package/src/hooks/api/model-providers.test.ts +167 -0
  167. package/src/hooks/api/model-providers.ts +281 -0
  168. package/src/index.ts +8 -0
  169. package/src/pages/model-provider-onboarding-page.stories.tsx +284 -0
  170. package/src/pages/model-provider-onboarding-page.test.tsx +368 -0
  171. package/src/pages/model-provider-onboarding-page.tsx +290 -0
  172. package/src/routes/model-provider.tsx +20 -0
  173. package/src/state/model-provider-onboarding.test.ts +55 -0
  174. package/src/state/model-provider-onboarding.ts +34 -0
  175. package/test/fixtures/model-providers.ts +111 -0
  176. package/test/setup.ts +3 -0
  177. package/tsconfig.build.json +9 -0
  178. package/tsconfig.build.tsbuildinfo +1 -0
  179. package/tsconfig.json +3 -0
  180. package/tsconfig.test.json +8 -0
  181. package/vercel.json +8 -0
  182. package/vitest.config.ts +72 -0
@@ -0,0 +1,190 @@
1
+ import { apiRequest } from '@shipfox/client-api';
2
+ import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
3
+ export const modelProviderQueryKeys = {
4
+ all: [
5
+ 'model-providers'
6
+ ],
7
+ catalog: ()=>[
8
+ ...modelProviderQueryKeys.all,
9
+ 'catalog'
10
+ ],
11
+ configs: (workspaceId)=>[
12
+ ...modelProviderQueryKeys.all,
13
+ 'configs',
14
+ workspaceId
15
+ ]
16
+ };
17
+ export async function getModelProviderCatalog({ signal } = {}) {
18
+ return await apiRequest('/agent/model-provider-catalog', {
19
+ signal
20
+ });
21
+ }
22
+ export async function listModelProviderConfigs({ workspaceId, signal }) {
23
+ return await apiRequest(`/workspaces/${workspaceId}/agent/model-providers`, {
24
+ signal
25
+ });
26
+ }
27
+ export async function upsertModelProviderConfig({ workspaceId, providerId, body }) {
28
+ return await apiRequest(`/workspaces/${workspaceId}/agent/model-providers/${providerId}`, {
29
+ method: 'PUT',
30
+ body
31
+ });
32
+ }
33
+ export async function createCustomModelProviderConfig({ workspaceId, body }) {
34
+ return await apiRequest(`/workspaces/${workspaceId}/agent/custom-model-providers`, {
35
+ method: 'POST',
36
+ body
37
+ });
38
+ }
39
+ export async function updateCustomModelProviderConfig({ workspaceId, providerId, body }) {
40
+ return await apiRequest(`/workspaces/${workspaceId}/agent/custom-model-providers/${providerId}`, {
41
+ method: 'PUT',
42
+ body
43
+ });
44
+ }
45
+ export async function discoverCustomModelProviderModels({ workspaceId, body }) {
46
+ return await apiRequest(`/workspaces/${workspaceId}/agent/custom-model-providers/discover-models`, {
47
+ method: 'POST',
48
+ body
49
+ });
50
+ }
51
+ export async function discoverCustomModelProviderModelsBySlug({ workspaceId, providerId, body }) {
52
+ return await apiRequest(`/workspaces/${workspaceId}/agent/custom-model-providers/${providerId}/discover-models`, {
53
+ method: 'POST',
54
+ body
55
+ });
56
+ }
57
+ export async function deleteModelProviderConfig({ workspaceId, providerId }) {
58
+ return await apiRequest(`/workspaces/${workspaceId}/agent/model-providers/${providerId}`, {
59
+ method: 'DELETE'
60
+ });
61
+ }
62
+ export async function updateModelProviderDefaultModel({ workspaceId, providerId, body }) {
63
+ return await apiRequest(`/workspaces/${workspaceId}/agent/model-providers/${providerId}/default-model`, {
64
+ method: 'PUT',
65
+ body
66
+ });
67
+ }
68
+ export async function setDefaultModelProvider({ workspaceId, body }) {
69
+ return await apiRequest(`/workspaces/${workspaceId}/agent/default-model-provider`, {
70
+ method: 'PUT',
71
+ body
72
+ });
73
+ }
74
+ export async function setDefaultHarness({ workspaceId, body }) {
75
+ return await apiRequest(`/workspaces/${workspaceId}/agent/default-harness`, {
76
+ method: 'PUT',
77
+ body
78
+ });
79
+ }
80
+ export function useModelProviderCatalogQuery() {
81
+ return useQuery({
82
+ queryKey: modelProviderQueryKeys.catalog(),
83
+ queryFn: ({ signal })=>getModelProviderCatalog({
84
+ signal
85
+ }),
86
+ staleTime: 1000 * 60 * 60
87
+ });
88
+ }
89
+ export function useModelProviderConfigsQuery(workspaceId) {
90
+ return useQuery({
91
+ queryKey: workspaceId ? modelProviderQueryKeys.configs(workspaceId) : [
92
+ ...modelProviderQueryKeys.all,
93
+ 'configs'
94
+ ],
95
+ enabled: Boolean(workspaceId),
96
+ queryFn: ({ signal })=>listModelProviderConfigs({
97
+ workspaceId: workspaceId ?? '',
98
+ signal
99
+ })
100
+ });
101
+ }
102
+ export function useUpsertModelProviderConfigMutation() {
103
+ const queryClient = useQueryClient();
104
+ return useMutation({
105
+ mutationFn: upsertModelProviderConfig,
106
+ onSuccess: async (_config, variables)=>{
107
+ await queryClient.invalidateQueries({
108
+ queryKey: modelProviderQueryKeys.configs(variables.workspaceId)
109
+ });
110
+ }
111
+ });
112
+ }
113
+ export function useCreateCustomModelProviderMutation() {
114
+ const queryClient = useQueryClient();
115
+ return useMutation({
116
+ mutationFn: createCustomModelProviderConfig,
117
+ onSuccess: async (_config, variables)=>{
118
+ await queryClient.invalidateQueries({
119
+ queryKey: modelProviderQueryKeys.configs(variables.workspaceId)
120
+ });
121
+ }
122
+ });
123
+ }
124
+ export function useUpdateCustomModelProviderMutation() {
125
+ const queryClient = useQueryClient();
126
+ return useMutation({
127
+ mutationFn: updateCustomModelProviderConfig,
128
+ onSuccess: async (_config, variables)=>{
129
+ await queryClient.invalidateQueries({
130
+ queryKey: modelProviderQueryKeys.configs(variables.workspaceId)
131
+ });
132
+ }
133
+ });
134
+ }
135
+ export function useDiscoverCustomModelProviderModelsMutation() {
136
+ return useMutation({
137
+ mutationFn: discoverCustomModelProviderModels
138
+ });
139
+ }
140
+ export function useDiscoverCustomModelProviderModelsBySlugMutation() {
141
+ return useMutation({
142
+ mutationFn: discoverCustomModelProviderModelsBySlug
143
+ });
144
+ }
145
+ export function useDeleteModelProviderConfigMutation() {
146
+ const queryClient = useQueryClient();
147
+ return useMutation({
148
+ mutationFn: deleteModelProviderConfig,
149
+ onSuccess: async (_config, variables)=>{
150
+ await queryClient.invalidateQueries({
151
+ queryKey: modelProviderQueryKeys.configs(variables.workspaceId)
152
+ });
153
+ }
154
+ });
155
+ }
156
+ export function useUpdateModelProviderDefaultModelMutation() {
157
+ const queryClient = useQueryClient();
158
+ return useMutation({
159
+ mutationFn: updateModelProviderDefaultModel,
160
+ onSuccess: async (_config, variables)=>{
161
+ await queryClient.invalidateQueries({
162
+ queryKey: modelProviderQueryKeys.configs(variables.workspaceId)
163
+ });
164
+ }
165
+ });
166
+ }
167
+ export function useSetDefaultModelProviderMutation() {
168
+ const queryClient = useQueryClient();
169
+ return useMutation({
170
+ mutationFn: setDefaultModelProvider,
171
+ onSuccess: async (_config, variables)=>{
172
+ await queryClient.invalidateQueries({
173
+ queryKey: modelProviderQueryKeys.configs(variables.workspaceId)
174
+ });
175
+ }
176
+ });
177
+ }
178
+ export function useSetDefaultHarnessMutation() {
179
+ const queryClient = useQueryClient();
180
+ return useMutation({
181
+ mutationFn: setDefaultHarness,
182
+ onSuccess: async (_config, variables)=>{
183
+ await queryClient.invalidateQueries({
184
+ queryKey: modelProviderQueryKeys.configs(variables.workspaceId)
185
+ });
186
+ }
187
+ });
188
+ }
189
+
190
+ //# sourceMappingURL=model-providers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/hooks/api/model-providers.ts"],"sourcesContent":["import type {\n CreateCustomModelProviderBodyDto,\n CustomModelProviderConfigDto,\n DiscoverCustomModelProviderModelsBodyDto,\n DiscoverCustomModelProviderModelsBySlugBodyDto,\n DiscoverCustomModelProviderModelsResponseDto,\n ListModelProviderConfigsResponseDto,\n ModelProviderCatalogResponseDto,\n ModelProviderConfigDto,\n ModelProviderRef,\n SetDefaultHarnessBodyDto,\n SetDefaultHarnessResponseDto,\n SetDefaultModelProviderBodyDto,\n SetDefaultModelProviderResponseDto,\n SupportedModelProviderId,\n UpdateCustomModelProviderBodyDto,\n UpdateModelProviderConfigBodyDto,\n UpdateModelProviderDefaultModelBodyDto,\n} from '@shipfox/api-agent-dto';\nimport {apiRequest} from '@shipfox/client-api';\nimport {useMutation, useQuery, useQueryClient} from '@tanstack/react-query';\n\nexport const modelProviderQueryKeys = {\n all: ['model-providers'] as const,\n catalog: () => [...modelProviderQueryKeys.all, 'catalog'] as const,\n configs: (workspaceId: string) =>\n [...modelProviderQueryKeys.all, 'configs', workspaceId] as const,\n};\n\nexport async function getModelProviderCatalog({signal}: {signal?: AbortSignal} = {}) {\n return await apiRequest<ModelProviderCatalogResponseDto>('/agent/model-provider-catalog', {\n signal,\n });\n}\n\nexport async function listModelProviderConfigs({\n workspaceId,\n signal,\n}: {\n workspaceId: string;\n signal?: AbortSignal;\n}) {\n return await apiRequest<ListModelProviderConfigsResponseDto>(\n `/workspaces/${workspaceId}/agent/model-providers`,\n {signal},\n );\n}\n\nexport async function upsertModelProviderConfig({\n workspaceId,\n providerId,\n body,\n}: {\n workspaceId: string;\n providerId: SupportedModelProviderId;\n body: UpdateModelProviderConfigBodyDto;\n}) {\n return await apiRequest<ModelProviderConfigDto>(\n `/workspaces/${workspaceId}/agent/model-providers/${providerId}`,\n {method: 'PUT', body},\n );\n}\n\nexport async function createCustomModelProviderConfig({\n workspaceId,\n body,\n}: {\n workspaceId: string;\n body: CreateCustomModelProviderBodyDto;\n}) {\n return await apiRequest<CustomModelProviderConfigDto>(\n `/workspaces/${workspaceId}/agent/custom-model-providers`,\n {method: 'POST', body},\n );\n}\n\nexport async function updateCustomModelProviderConfig({\n workspaceId,\n providerId,\n body,\n}: {\n workspaceId: string;\n providerId: ModelProviderRef;\n body: UpdateCustomModelProviderBodyDto;\n}) {\n return await apiRequest<CustomModelProviderConfigDto>(\n `/workspaces/${workspaceId}/agent/custom-model-providers/${providerId}`,\n {method: 'PUT', body},\n );\n}\n\nexport async function discoverCustomModelProviderModels({\n workspaceId,\n body,\n}: {\n workspaceId: string;\n body: DiscoverCustomModelProviderModelsBodyDto;\n}) {\n return await apiRequest<DiscoverCustomModelProviderModelsResponseDto>(\n `/workspaces/${workspaceId}/agent/custom-model-providers/discover-models`,\n {method: 'POST', body},\n );\n}\n\nexport async function discoverCustomModelProviderModelsBySlug({\n workspaceId,\n providerId,\n body,\n}: {\n workspaceId: string;\n providerId: ModelProviderRef;\n body: DiscoverCustomModelProviderModelsBySlugBodyDto;\n}) {\n return await apiRequest<DiscoverCustomModelProviderModelsResponseDto>(\n `/workspaces/${workspaceId}/agent/custom-model-providers/${providerId}/discover-models`,\n {method: 'POST', body},\n );\n}\n\nexport async function deleteModelProviderConfig({\n workspaceId,\n providerId,\n}: {\n workspaceId: string;\n providerId: ModelProviderRef;\n}) {\n return await apiRequest<void>(`/workspaces/${workspaceId}/agent/model-providers/${providerId}`, {\n method: 'DELETE',\n });\n}\n\nexport async function updateModelProviderDefaultModel({\n workspaceId,\n providerId,\n body,\n}: {\n workspaceId: string;\n providerId: SupportedModelProviderId;\n body: UpdateModelProviderDefaultModelBodyDto;\n}) {\n return await apiRequest<ModelProviderConfigDto>(\n `/workspaces/${workspaceId}/agent/model-providers/${providerId}/default-model`,\n {method: 'PUT', body},\n );\n}\n\nexport async function setDefaultModelProvider({\n workspaceId,\n body,\n}: {\n workspaceId: string;\n body: SetDefaultModelProviderBodyDto;\n}) {\n return await apiRequest<SetDefaultModelProviderResponseDto>(\n `/workspaces/${workspaceId}/agent/default-model-provider`,\n {method: 'PUT', body},\n );\n}\n\nexport async function setDefaultHarness({\n workspaceId,\n body,\n}: {\n workspaceId: string;\n body: SetDefaultHarnessBodyDto;\n}) {\n return await apiRequest<SetDefaultHarnessResponseDto>(\n `/workspaces/${workspaceId}/agent/default-harness`,\n {method: 'PUT', body},\n );\n}\n\nexport function useModelProviderCatalogQuery() {\n return useQuery({\n queryKey: modelProviderQueryKeys.catalog(),\n queryFn: ({signal}) => getModelProviderCatalog({signal}),\n staleTime: 1000 * 60 * 60,\n });\n}\n\nexport function useModelProviderConfigsQuery(workspaceId: string | undefined) {\n return useQuery({\n queryKey: workspaceId\n ? modelProviderQueryKeys.configs(workspaceId)\n : [...modelProviderQueryKeys.all, 'configs'],\n enabled: Boolean(workspaceId),\n queryFn: ({signal}) => listModelProviderConfigs({workspaceId: workspaceId ?? '', signal}),\n });\n}\n\nexport function useUpsertModelProviderConfigMutation() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: upsertModelProviderConfig,\n onSuccess: async (_config, variables) => {\n await queryClient.invalidateQueries({\n queryKey: modelProviderQueryKeys.configs(variables.workspaceId),\n });\n },\n });\n}\n\nexport function useCreateCustomModelProviderMutation() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: createCustomModelProviderConfig,\n onSuccess: async (_config, variables) => {\n await queryClient.invalidateQueries({\n queryKey: modelProviderQueryKeys.configs(variables.workspaceId),\n });\n },\n });\n}\n\nexport function useUpdateCustomModelProviderMutation() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: updateCustomModelProviderConfig,\n onSuccess: async (_config, variables) => {\n await queryClient.invalidateQueries({\n queryKey: modelProviderQueryKeys.configs(variables.workspaceId),\n });\n },\n });\n}\n\nexport function useDiscoverCustomModelProviderModelsMutation() {\n return useMutation({mutationFn: discoverCustomModelProviderModels});\n}\n\nexport function useDiscoverCustomModelProviderModelsBySlugMutation() {\n return useMutation({mutationFn: discoverCustomModelProviderModelsBySlug});\n}\n\nexport function useDeleteModelProviderConfigMutation() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: deleteModelProviderConfig,\n onSuccess: async (_config, variables) => {\n await queryClient.invalidateQueries({\n queryKey: modelProviderQueryKeys.configs(variables.workspaceId),\n });\n },\n });\n}\n\nexport function useUpdateModelProviderDefaultModelMutation() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: updateModelProviderDefaultModel,\n onSuccess: async (_config, variables) => {\n await queryClient.invalidateQueries({\n queryKey: modelProviderQueryKeys.configs(variables.workspaceId),\n });\n },\n });\n}\n\nexport function useSetDefaultModelProviderMutation() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: setDefaultModelProvider,\n onSuccess: async (_config, variables) => {\n await queryClient.invalidateQueries({\n queryKey: modelProviderQueryKeys.configs(variables.workspaceId),\n });\n },\n });\n}\n\nexport function useSetDefaultHarnessMutation() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: setDefaultHarness,\n onSuccess: async (_config, variables) => {\n await queryClient.invalidateQueries({\n queryKey: modelProviderQueryKeys.configs(variables.workspaceId),\n });\n },\n });\n}\n"],"names":["apiRequest","useMutation","useQuery","useQueryClient","modelProviderQueryKeys","all","catalog","configs","workspaceId","getModelProviderCatalog","signal","listModelProviderConfigs","upsertModelProviderConfig","providerId","body","method","createCustomModelProviderConfig","updateCustomModelProviderConfig","discoverCustomModelProviderModels","discoverCustomModelProviderModelsBySlug","deleteModelProviderConfig","updateModelProviderDefaultModel","setDefaultModelProvider","setDefaultHarness","useModelProviderCatalogQuery","queryKey","queryFn","staleTime","useModelProviderConfigsQuery","enabled","Boolean","useUpsertModelProviderConfigMutation","queryClient","mutationFn","onSuccess","_config","variables","invalidateQueries","useCreateCustomModelProviderMutation","useUpdateCustomModelProviderMutation","useDiscoverCustomModelProviderModelsMutation","useDiscoverCustomModelProviderModelsBySlugMutation","useDeleteModelProviderConfigMutation","useUpdateModelProviderDefaultModelMutation","useSetDefaultModelProviderMutation","useSetDefaultHarnessMutation"],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ export * from './components/available-provider-card.js';
2
+ export * from './components/form-errors.js';
3
+ export * from './components/harnesses-section.js';
4
+ export * from './components/model-providers-section.js';
5
+ export * from './components/test-and-save-form.js';
6
+ export * from './hooks/api/model-providers.js';
7
+ export * from './pages/model-provider-onboarding-page.js';
8
+ export * from './state/model-provider-onboarding.js';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,yCAAyC,CAAC;AACxD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,mCAAmC,CAAC;AAClD,cAAc,yCAAyC,CAAC;AACxD,cAAc,oCAAoC,CAAC;AACnD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,2CAA2C,CAAC;AAC1D,cAAc,sCAAsC,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,10 @@
1
+ export * from './components/available-provider-card.js';
2
+ export * from './components/form-errors.js';
3
+ export * from './components/harnesses-section.js';
4
+ export * from './components/model-providers-section.js';
5
+ export * from './components/test-and-save-form.js';
6
+ export * from './hooks/api/model-providers.js';
7
+ export * from './pages/model-provider-onboarding-page.js';
8
+ export * from './state/model-provider-onboarding.js';
9
+
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export * from './components/available-provider-card.js';\nexport * from './components/form-errors.js';\nexport * from './components/harnesses-section.js';\nexport * from './components/model-providers-section.js';\nexport * from './components/test-and-save-form.js';\nexport * from './hooks/api/model-providers.js';\nexport * from './pages/model-provider-onboarding-page.js';\nexport * from './state/model-provider-onboarding.js';\n"],"names":[],"mappings":"AAAA,cAAc,0CAA0C;AACxD,cAAc,8BAA8B;AAC5C,cAAc,oCAAoC;AAClD,cAAc,0CAA0C;AACxD,cAAc,qCAAqC;AACnD,cAAc,iCAAiC;AAC/C,cAAc,4CAA4C;AAC1D,cAAc,uCAAuC"}
@@ -0,0 +1,6 @@
1
+ export declare function ModelProviderOnboardingPage({ workspaceId, onSkip, onConfigured, }: {
2
+ workspaceId: string;
3
+ onSkip: () => void;
4
+ onConfigured: () => void;
5
+ }): import("react").JSX.Element;
6
+ //# sourceMappingURL=model-provider-onboarding-page.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-provider-onboarding-page.d.ts","sourceRoot":"","sources":["../../src/pages/model-provider-onboarding-page.tsx"],"names":[],"mappings":"AA+BA,wBAAgB,2BAA2B,CAAC,EAC1C,WAAW,EACX,MAAM,EACN,YAAY,GACb,EAAE;IACD,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,YAAY,EAAE,MAAM,IAAI,CAAC;CAC1B,+BAqKA"}
@@ -0,0 +1,295 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { DEFAULT_HARNESS, harnessSupportsProvider, listHarnessDescriptors } from '@shipfox/api-agent-dto';
3
+ import { QueryLoadError } from '@shipfox/client-ui';
4
+ import { Button } from '@shipfox/react-ui/button';
5
+ import { Callout } from '@shipfox/react-ui/callout';
6
+ import { EmptyState } from '@shipfox/react-ui/empty-state';
7
+ import { Icon } from '@shipfox/react-ui/icon';
8
+ import { Modal, ModalContent, ModalHeader, ModalTitle } from '@shipfox/react-ui/modal';
9
+ import { Skeleton } from '@shipfox/react-ui/skeleton';
10
+ import { toast } from '@shipfox/react-ui/toast';
11
+ import { Header, Text } from '@shipfox/react-ui/typography';
12
+ import { cn } from '@shipfox/react-ui/utils';
13
+ import { useEffect, useMemo, useState } from 'react';
14
+ import { AvailableProvidersGrid, PROVIDER_GRID_CLASS } from '#components/available-providers-grid.js';
15
+ import { modelProviderConfigErrorToFormError } from '#components/form-errors.js';
16
+ import { ModelProviderTestAndSaveForm } from '#components/test-and-save-form.js';
17
+ import { useModelProviderCatalogQuery, useSetDefaultHarnessMutation } from '#hooks/api/model-providers.js';
18
+ import { dismissModelProviderOnboarding } from '#state/model-provider-onboarding.js';
19
+ const SURFACE_CLASS = 'overflow-hidden rounded-8 border border-border-neutral-base bg-background-neutral-base';
20
+ export function ModelProviderOnboardingPage({ workspaceId, onSkip, onConfigured }) {
21
+ const catalogQuery = useModelProviderCatalogQuery();
22
+ const setDefaultHarness = useSetDefaultHarnessMutation();
23
+ const [selectedHarness, setSelectedHarness] = useState(null);
24
+ const [selectedEntry, setSelectedEntry] = useState(null);
25
+ const [defaultHarnessError, setDefaultHarnessError] = useState();
26
+ const [isSettingDefaultHarness, setIsSettingDefaultHarness] = useState(false);
27
+ const supportedProviders = catalogQuery.data?.providers.filter((provider)=>provider.support_status === 'supported') ?? [];
28
+ const filteredProviders = useMemo(()=>{
29
+ if (selectedHarness === null) return [];
30
+ return supportedProviders.filter((provider)=>harnessSupportsProvider(selectedHarness, provider.id));
31
+ }, [
32
+ selectedHarness,
33
+ supportedProviders
34
+ ]);
35
+ useEffect(()=>{
36
+ document.getElementById(selectedHarness === null ? 'model-provider-harness-step' : 'model-provider-provider-step')?.focus();
37
+ }, [
38
+ selectedHarness
39
+ ]);
40
+ function handleSkip() {
41
+ try {
42
+ dismissModelProviderOnboarding(workspaceId);
43
+ } catch {
44
+ // Skip is best-effort persistence; access to the product must not depend on storage.
45
+ }
46
+ onSkip();
47
+ }
48
+ async function handleProviderSaved() {
49
+ if (selectedEntry === null || selectedHarness === null) return;
50
+ setDefaultHarnessError(undefined);
51
+ if (selectedHarness === DEFAULT_HARNESS) {
52
+ toast.success(`${selectedEntry.label} saved`);
53
+ onConfigured();
54
+ return;
55
+ }
56
+ setIsSettingDefaultHarness(true);
57
+ try {
58
+ await setDefaultHarness.mutateAsync({
59
+ workspaceId,
60
+ body: {
61
+ harness_id: selectedHarness
62
+ }
63
+ });
64
+ toast.success(`${selectedEntry.label} saved`);
65
+ onConfigured();
66
+ } catch (error) {
67
+ const mapped = modelProviderConfigErrorToFormError(error);
68
+ setDefaultHarnessError(mapped.message || 'Could not save default harness. Try again.');
69
+ } finally{
70
+ setIsSettingDefaultHarness(false);
71
+ }
72
+ }
73
+ const selectedHarnessDescriptor = selectedHarness === null ? null : listHarnessDescriptors().find((harness)=>harness.id === selectedHarness);
74
+ const headingId = selectedHarness === null ? 'model-provider-harness-step' : 'model-provider-provider-step';
75
+ return /*#__PURE__*/ _jsxs("div", {
76
+ className: "mx-auto flex w-full max-w-[640px] flex-col gap-20",
77
+ children: [
78
+ /*#__PURE__*/ _jsxs("header", {
79
+ className: "flex flex-col gap-12",
80
+ children: [
81
+ /*#__PURE__*/ _jsxs("div", {
82
+ className: "flex items-start justify-between gap-16 max-[520px]:flex-col max-[520px]:gap-8",
83
+ children: [
84
+ /*#__PURE__*/ _jsx(Header, {
85
+ id: headingId,
86
+ variant: "h1",
87
+ tabIndex: -1,
88
+ className: "outline-none",
89
+ children: selectedHarnessDescriptor ? `Configure ${selectedHarnessDescriptor.label}` : 'Choose agent harness'
90
+ }),
91
+ /*#__PURE__*/ _jsx(Button, {
92
+ type: "button",
93
+ variant: "secondary",
94
+ onClick: handleSkip,
95
+ className: "shrink-0",
96
+ children: "Skip for now"
97
+ })
98
+ ]
99
+ }),
100
+ /*#__PURE__*/ _jsx(Text, {
101
+ size: "md",
102
+ className: "text-foreground-neutral-muted",
103
+ children: selectedHarnessDescriptor ? `${selectedHarnessDescriptor.label} needs a compatible model provider. Add your own API key, or go back to choose a different harness.` : 'A harness runs agent steps. Choose the engine you want first, then connect a compatible model provider.'
104
+ })
105
+ ]
106
+ }),
107
+ /*#__PURE__*/ _jsx("section", {
108
+ "aria-labelledby": headingId,
109
+ className: "flex flex-col gap-16",
110
+ children: selectedHarness === null ? /*#__PURE__*/ _jsx(HarnessPicker, {
111
+ onSelect: setSelectedHarness
112
+ }) : /*#__PURE__*/ _jsxs(_Fragment, {
113
+ children: [
114
+ /*#__PURE__*/ _jsx("div", {
115
+ children: /*#__PURE__*/ _jsx(Button, {
116
+ type: "button",
117
+ variant: "transparent",
118
+ onClick: ()=>setSelectedHarness(null),
119
+ children: "Back"
120
+ })
121
+ }),
122
+ /*#__PURE__*/ _jsx(ModelProviderPicker, {
123
+ catalogQuery: catalogQuery,
124
+ supportedProviders: filteredProviders,
125
+ onSelect: (entry)=>{
126
+ setDefaultHarnessError(undefined);
127
+ setSelectedEntry(entry);
128
+ }
129
+ }, selectedHarness)
130
+ ]
131
+ })
132
+ }),
133
+ /*#__PURE__*/ _jsx(Modal, {
134
+ open: selectedEntry !== null,
135
+ onOpenChange: (open)=>{
136
+ if (!open && !isSettingDefaultHarness) {
137
+ setSelectedEntry(null);
138
+ setDefaultHarnessError(undefined);
139
+ }
140
+ },
141
+ children: /*#__PURE__*/ _jsxs(ModalContent, {
142
+ "aria-describedby": undefined,
143
+ children: [
144
+ /*#__PURE__*/ _jsx(ModalTitle, {
145
+ className: "sr-only",
146
+ children: selectedEntry ? `Configure ${selectedEntry.label}` : ''
147
+ }),
148
+ /*#__PURE__*/ _jsx(ModalHeader, {
149
+ children: /*#__PURE__*/ _jsx(Text, {
150
+ size: "lg",
151
+ "aria-hidden": "true",
152
+ className: "overflow-ellipsis overflow-hidden whitespace-nowrap",
153
+ children: selectedEntry ? `Configure ${selectedEntry.label}` : ''
154
+ })
155
+ }),
156
+ isSettingDefaultHarness ? /*#__PURE__*/ _jsx("div", {
157
+ role: "status",
158
+ className: "px-20 pb-8",
159
+ children: /*#__PURE__*/ _jsx(Text, {
160
+ size: "sm",
161
+ className: "text-foreground-neutral-muted",
162
+ children: "Saving harness default..."
163
+ })
164
+ }) : null,
165
+ defaultHarnessError ? /*#__PURE__*/ _jsx("div", {
166
+ className: "px-20 pb-8",
167
+ children: /*#__PURE__*/ _jsx(Callout, {
168
+ role: "alert",
169
+ type: "error",
170
+ children: /*#__PURE__*/ _jsxs("div", {
171
+ className: "flex flex-col gap-8",
172
+ children: [
173
+ /*#__PURE__*/ _jsx(Text, {
174
+ size: "sm",
175
+ bold: true,
176
+ children: "Could not save default harness"
177
+ }),
178
+ /*#__PURE__*/ _jsx(Text, {
179
+ size: "sm",
180
+ children: defaultHarnessError
181
+ })
182
+ ]
183
+ })
184
+ })
185
+ }) : null,
186
+ selectedEntry ? /*#__PURE__*/ _jsx(ModelProviderTestAndSaveForm, {
187
+ workspaceId: workspaceId,
188
+ entry: selectedEntry,
189
+ setAsDefaultOnSave: true,
190
+ onSaved: ()=>{
191
+ void handleProviderSaved();
192
+ }
193
+ }) : null
194
+ ]
195
+ })
196
+ })
197
+ ]
198
+ });
199
+ }
200
+ function HarnessPicker({ onSelect }) {
201
+ return /*#__PURE__*/ _jsx("ul", {
202
+ className: PROVIDER_GRID_CLASS,
203
+ "aria-label": "Agent harnesses",
204
+ children: listHarnessDescriptors().map((harness)=>/*#__PURE__*/ _jsx(HarnessCard, {
205
+ harness: harness,
206
+ onChoose: ()=>onSelect(harness.id)
207
+ }, harness.id))
208
+ });
209
+ }
210
+ function HarnessCard({ harness, onChoose }) {
211
+ return /*#__PURE__*/ _jsx("li", {
212
+ children: /*#__PURE__*/ _jsx("button", {
213
+ type: "button",
214
+ className: cn('group block w-full cursor-pointer p-16 text-left outline-none transition-colors hover:bg-background-components-hover focus-visible:shadow-button-neutral-focus', SURFACE_CLASS),
215
+ "aria-label": `Choose ${harness.label}`,
216
+ onClick: onChoose,
217
+ children: /*#__PURE__*/ _jsxs("div", {
218
+ className: "flex min-w-0 items-center justify-between gap-12",
219
+ children: [
220
+ /*#__PURE__*/ _jsxs("div", {
221
+ className: "flex min-w-0 flex-col gap-4",
222
+ children: [
223
+ /*#__PURE__*/ _jsx(Text, {
224
+ size: "md",
225
+ bold: true,
226
+ className: "min-w-0 truncate",
227
+ children: harness.label
228
+ }),
229
+ /*#__PURE__*/ _jsx(Text, {
230
+ size: "sm",
231
+ className: "text-foreground-neutral-muted",
232
+ children: harness.description
233
+ })
234
+ ]
235
+ }),
236
+ /*#__PURE__*/ _jsxs("div", {
237
+ className: "flex shrink-0 items-center gap-4 text-foreground-neutral-muted transition-colors group-hover:text-foreground-highlight-interactive",
238
+ children: [
239
+ /*#__PURE__*/ _jsx(Text, {
240
+ size: "sm",
241
+ children: "Choose"
242
+ }),
243
+ /*#__PURE__*/ _jsx(Icon, {
244
+ name: "chevronRight",
245
+ className: "size-16"
246
+ })
247
+ ]
248
+ })
249
+ ]
250
+ })
251
+ })
252
+ });
253
+ }
254
+ function ModelProviderPicker({ catalogQuery, supportedProviders, onSelect }) {
255
+ if (catalogQuery.isPending) {
256
+ return /*#__PURE__*/ _jsx("div", {
257
+ role: "status",
258
+ "aria-busy": "true",
259
+ "aria-label": "Loading model providers",
260
+ children: /*#__PURE__*/ _jsx(ModelProviderGridSkeleton, {})
261
+ });
262
+ }
263
+ if (catalogQuery.isError && catalogQuery.data === undefined) {
264
+ return /*#__PURE__*/ _jsx(QueryLoadError, {
265
+ query: catalogQuery,
266
+ subject: "model provider catalog"
267
+ });
268
+ }
269
+ if (catalogQuery.data !== undefined && supportedProviders.length === 0) {
270
+ return /*#__PURE__*/ _jsx(EmptyState, {
271
+ icon: "componentLine",
272
+ title: "No providers available to configure",
273
+ description: "Skip for now and add one later from workspace settings."
274
+ });
275
+ }
276
+ return /*#__PURE__*/ _jsx(AvailableProvidersGrid, {
277
+ entries: supportedProviders,
278
+ onSelect: onSelect
279
+ });
280
+ }
281
+ function ModelProviderGridSkeleton() {
282
+ return /*#__PURE__*/ _jsx("div", {
283
+ className: PROVIDER_GRID_CLASS,
284
+ children: [
285
+ 0,
286
+ 1,
287
+ 2,
288
+ 3
289
+ ].map((card)=>/*#__PURE__*/ _jsx(Skeleton, {
290
+ className: "h-136 w-full"
291
+ }, card))
292
+ });
293
+ }
294
+
295
+ //# sourceMappingURL=model-provider-onboarding-page.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/pages/model-provider-onboarding-page.tsx"],"sourcesContent":["import {\n DEFAULT_HARNESS,\n type Harness,\n type HarnessDescriptor,\n harnessSupportsProvider,\n listHarnessDescriptors,\n type ModelProviderCatalogEntryDto,\n} from '@shipfox/api-agent-dto';\nimport {QueryLoadError} from '@shipfox/client-ui';\nimport {Button} from '@shipfox/react-ui/button';\nimport {Callout} from '@shipfox/react-ui/callout';\nimport {EmptyState} from '@shipfox/react-ui/empty-state';\nimport {Icon} from '@shipfox/react-ui/icon';\nimport {Modal, ModalContent, ModalHeader, ModalTitle} from '@shipfox/react-ui/modal';\nimport {Skeleton} from '@shipfox/react-ui/skeleton';\nimport {toast} from '@shipfox/react-ui/toast';\nimport {Header, Text} from '@shipfox/react-ui/typography';\nimport {cn} from '@shipfox/react-ui/utils';\nimport {useEffect, useMemo, useState} from 'react';\nimport {AvailableProvidersGrid, PROVIDER_GRID_CLASS} from '#components/available-providers-grid.js';\nimport {modelProviderConfigErrorToFormError} from '#components/form-errors.js';\nimport {ModelProviderTestAndSaveForm} from '#components/test-and-save-form.js';\nimport {\n useModelProviderCatalogQuery,\n useSetDefaultHarnessMutation,\n} from '#hooks/api/model-providers.js';\nimport {dismissModelProviderOnboarding} from '#state/model-provider-onboarding.js';\n\nconst SURFACE_CLASS =\n 'overflow-hidden rounded-8 border border-border-neutral-base bg-background-neutral-base';\n\nexport function ModelProviderOnboardingPage({\n workspaceId,\n onSkip,\n onConfigured,\n}: {\n workspaceId: string;\n onSkip: () => void;\n onConfigured: () => void;\n}) {\n const catalogQuery = useModelProviderCatalogQuery();\n const setDefaultHarness = useSetDefaultHarnessMutation();\n const [selectedHarness, setSelectedHarness] = useState<Harness | null>(null);\n const [selectedEntry, setSelectedEntry] = useState<ModelProviderCatalogEntryDto | null>(null);\n const [defaultHarnessError, setDefaultHarnessError] = useState<string | undefined>();\n const [isSettingDefaultHarness, setIsSettingDefaultHarness] = useState(false);\n const supportedProviders =\n catalogQuery.data?.providers.filter((provider) => provider.support_status === 'supported') ??\n [];\n const filteredProviders = useMemo(() => {\n if (selectedHarness === null) return [];\n return supportedProviders.filter((provider) =>\n harnessSupportsProvider(selectedHarness, provider.id),\n );\n }, [selectedHarness, supportedProviders]);\n\n useEffect(() => {\n document\n .getElementById(\n selectedHarness === null ? 'model-provider-harness-step' : 'model-provider-provider-step',\n )\n ?.focus();\n }, [selectedHarness]);\n\n function handleSkip() {\n try {\n dismissModelProviderOnboarding(workspaceId);\n } catch {\n // Skip is best-effort persistence; access to the product must not depend on storage.\n }\n onSkip();\n }\n\n async function handleProviderSaved() {\n if (selectedEntry === null || selectedHarness === null) return;\n\n setDefaultHarnessError(undefined);\n if (selectedHarness === DEFAULT_HARNESS) {\n toast.success(`${selectedEntry.label} saved`);\n onConfigured();\n return;\n }\n\n setIsSettingDefaultHarness(true);\n try {\n await setDefaultHarness.mutateAsync({\n workspaceId,\n body: {harness_id: selectedHarness},\n });\n toast.success(`${selectedEntry.label} saved`);\n onConfigured();\n } catch (error) {\n const mapped = modelProviderConfigErrorToFormError(error);\n setDefaultHarnessError(mapped.message || 'Could not save default harness. Try again.');\n } finally {\n setIsSettingDefaultHarness(false);\n }\n }\n\n const selectedHarnessDescriptor =\n selectedHarness === null\n ? null\n : listHarnessDescriptors().find((harness) => harness.id === selectedHarness);\n const headingId =\n selectedHarness === null ? 'model-provider-harness-step' : 'model-provider-provider-step';\n\n return (\n <div className=\"mx-auto flex w-full max-w-[640px] flex-col gap-20\">\n <header className=\"flex flex-col gap-12\">\n <div className=\"flex items-start justify-between gap-16 max-[520px]:flex-col max-[520px]:gap-8\">\n <Header id={headingId} variant=\"h1\" tabIndex={-1} className=\"outline-none\">\n {selectedHarnessDescriptor\n ? `Configure ${selectedHarnessDescriptor.label}`\n : 'Choose agent harness'}\n </Header>\n <Button type=\"button\" variant=\"secondary\" onClick={handleSkip} className=\"shrink-0\">\n Skip for now\n </Button>\n </div>\n <Text size=\"md\" className=\"text-foreground-neutral-muted\">\n {selectedHarnessDescriptor\n ? `${selectedHarnessDescriptor.label} needs a compatible model provider. Add your own API key, or go back to choose a different harness.`\n : 'A harness runs agent steps. Choose the engine you want first, then connect a compatible model provider.'}\n </Text>\n </header>\n\n <section aria-labelledby={headingId} className=\"flex flex-col gap-16\">\n {selectedHarness === null ? (\n <HarnessPicker onSelect={setSelectedHarness} />\n ) : (\n <>\n <div>\n <Button type=\"button\" variant=\"transparent\" onClick={() => setSelectedHarness(null)}>\n Back\n </Button>\n </div>\n <ModelProviderPicker\n key={selectedHarness}\n catalogQuery={catalogQuery}\n supportedProviders={filteredProviders}\n onSelect={(entry) => {\n setDefaultHarnessError(undefined);\n setSelectedEntry(entry);\n }}\n />\n </>\n )}\n </section>\n\n <Modal\n open={selectedEntry !== null}\n onOpenChange={(open) => {\n if (!open && !isSettingDefaultHarness) {\n setSelectedEntry(null);\n setDefaultHarnessError(undefined);\n }\n }}\n >\n <ModalContent aria-describedby={undefined}>\n <ModalTitle className=\"sr-only\">\n {selectedEntry ? `Configure ${selectedEntry.label}` : ''}\n </ModalTitle>\n <ModalHeader>\n <Text\n size=\"lg\"\n aria-hidden=\"true\"\n className=\"overflow-ellipsis overflow-hidden whitespace-nowrap\"\n >\n {selectedEntry ? `Configure ${selectedEntry.label}` : ''}\n </Text>\n </ModalHeader>\n {isSettingDefaultHarness ? (\n <div role=\"status\" className=\"px-20 pb-8\">\n <Text size=\"sm\" className=\"text-foreground-neutral-muted\">\n Saving harness default...\n </Text>\n </div>\n ) : null}\n {defaultHarnessError ? (\n <div className=\"px-20 pb-8\">\n <Callout role=\"alert\" type=\"error\">\n <div className=\"flex flex-col gap-8\">\n <Text size=\"sm\" bold>\n Could not save default harness\n </Text>\n <Text size=\"sm\">{defaultHarnessError}</Text>\n </div>\n </Callout>\n </div>\n ) : null}\n {selectedEntry ? (\n <ModelProviderTestAndSaveForm\n workspaceId={workspaceId}\n entry={selectedEntry}\n setAsDefaultOnSave\n onSaved={() => {\n void handleProviderSaved();\n }}\n />\n ) : null}\n </ModalContent>\n </Modal>\n </div>\n );\n}\n\nfunction HarnessPicker({onSelect}: {onSelect: (harness: Harness) => void}) {\n return (\n <ul className={PROVIDER_GRID_CLASS} aria-label=\"Agent harnesses\">\n {listHarnessDescriptors().map((harness) => (\n <HarnessCard key={harness.id} harness={harness} onChoose={() => onSelect(harness.id)} />\n ))}\n </ul>\n );\n}\n\nfunction HarnessCard({harness, onChoose}: {harness: HarnessDescriptor; onChoose: () => void}) {\n return (\n <li>\n <button\n type=\"button\"\n className={cn(\n 'group block w-full cursor-pointer p-16 text-left outline-none transition-colors hover:bg-background-components-hover focus-visible:shadow-button-neutral-focus',\n SURFACE_CLASS,\n )}\n aria-label={`Choose ${harness.label}`}\n onClick={onChoose}\n >\n <div className=\"flex min-w-0 items-center justify-between gap-12\">\n <div className=\"flex min-w-0 flex-col gap-4\">\n <Text size=\"md\" bold className=\"min-w-0 truncate\">\n {harness.label}\n </Text>\n <Text size=\"sm\" className=\"text-foreground-neutral-muted\">\n {harness.description}\n </Text>\n </div>\n <div className=\"flex shrink-0 items-center gap-4 text-foreground-neutral-muted transition-colors group-hover:text-foreground-highlight-interactive\">\n <Text size=\"sm\">Choose</Text>\n <Icon name=\"chevronRight\" className=\"size-16\" />\n </div>\n </div>\n </button>\n </li>\n );\n}\n\nfunction ModelProviderPicker({\n catalogQuery,\n supportedProviders,\n onSelect,\n}: {\n catalogQuery: ReturnType<typeof useModelProviderCatalogQuery>;\n supportedProviders: ModelProviderCatalogEntryDto[];\n onSelect: (entry: ModelProviderCatalogEntryDto) => void;\n}) {\n if (catalogQuery.isPending) {\n return (\n <div role=\"status\" aria-busy=\"true\" aria-label=\"Loading model providers\">\n <ModelProviderGridSkeleton />\n </div>\n );\n }\n\n if (catalogQuery.isError && catalogQuery.data === undefined) {\n return <QueryLoadError query={catalogQuery} subject=\"model provider catalog\" />;\n }\n\n if (catalogQuery.data !== undefined && supportedProviders.length === 0) {\n return (\n <EmptyState\n icon=\"componentLine\"\n title=\"No providers available to configure\"\n description=\"Skip for now and add one later from workspace settings.\"\n />\n );\n }\n\n return <AvailableProvidersGrid entries={supportedProviders} onSelect={onSelect} />;\n}\n\nfunction ModelProviderGridSkeleton() {\n return (\n <div className={PROVIDER_GRID_CLASS}>\n {[0, 1, 2, 3].map((card) => (\n <Skeleton key={card} className=\"h-136 w-full\" />\n ))}\n </div>\n );\n}\n"],"names":["DEFAULT_HARNESS","harnessSupportsProvider","listHarnessDescriptors","QueryLoadError","Button","Callout","EmptyState","Icon","Modal","ModalContent","ModalHeader","ModalTitle","Skeleton","toast","Header","Text","cn","useEffect","useMemo","useState","AvailableProvidersGrid","PROVIDER_GRID_CLASS","modelProviderConfigErrorToFormError","ModelProviderTestAndSaveForm","useModelProviderCatalogQuery","useSetDefaultHarnessMutation","dismissModelProviderOnboarding","SURFACE_CLASS","ModelProviderOnboardingPage","workspaceId","onSkip","onConfigured","catalogQuery","setDefaultHarness","selectedHarness","setSelectedHarness","selectedEntry","setSelectedEntry","defaultHarnessError","setDefaultHarnessError","isSettingDefaultHarness","setIsSettingDefaultHarness","supportedProviders","data","providers","filter","provider","support_status","filteredProviders","id","document","getElementById","focus","handleSkip","handleProviderSaved","undefined","success","label","mutateAsync","body","harness_id","error","mapped","message","selectedHarnessDescriptor","find","harness","headingId","div","className","header","variant","tabIndex","type","onClick","size","section","aria-labelledby","HarnessPicker","onSelect","ModelProviderPicker","entry","open","onOpenChange","aria-describedby","aria-hidden","role","bold","setAsDefaultOnSave","onSaved","ul","aria-label","map","HarnessCard","onChoose","li","button","description","name","isPending","aria-busy","ModelProviderGridSkeleton","isError","query","subject","length","icon","title","entries","card"],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import type { StoryObj } from '@storybook/react';
2
+ type Scenario = 'available' | 'loading' | 'catalog-error' | 'no-providers' | 'long-names';
3
+ interface ModelProviderOnboardingStoryProps {
4
+ scenario: Scenario;
5
+ }
6
+ declare function ModelProviderOnboardingStory({ scenario }: ModelProviderOnboardingStoryProps): import("react").JSX.Element;
7
+ declare const meta: {
8
+ title: string;
9
+ component: typeof ModelProviderOnboardingStory;
10
+ parameters: {
11
+ layout: string;
12
+ };
13
+ args: {
14
+ scenario: "available";
15
+ };
16
+ };
17
+ export default meta;
18
+ type Story = StoryObj<typeof meta>;
19
+ export declare const Playground: Story;
20
+ export declare const Loading: Story;
21
+ export declare const CatalogError: Story;
22
+ export declare const NoProvidersAvailable: Story;
23
+ export declare const LongNames: Story;
24
+ export declare const FilteredProviders: Story;
25
+ export declare const NoMatchingProviders: Story;
26
+ export declare const ConfigureModalOpen: Story;
27
+ //# sourceMappingURL=model-provider-onboarding-page.stories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-provider-onboarding-page.stories.d.ts","sourceRoot":"","sources":["../../src/pages/model-provider-onboarding-page.stories.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAO,QAAQ,EAAC,MAAM,kBAAkB,CAAC;AAQrD,KAAK,QAAQ,GAAG,WAAW,GAAG,SAAS,GAAG,eAAe,GAAG,cAAc,GAAG,YAAY,CAAC;AAE1F,UAAU,iCAAiC;IACzC,QAAQ,EAAE,QAAQ,CAAC;CACpB;AA+ED,iBAAS,4BAA4B,CAAC,EAAC,QAAQ,EAAC,EAAE,iCAAiC,+BAuBlF;AAED,QAAA,MAAM,IAAI;;;;;;;;;CAK2C,CAAC;AAEtD,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,UAAU,EAAE,KAAU,CAAC;AAEpC,eAAO,MAAM,OAAO,EAAE,KAMrB,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAM1B,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,KAMlC,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,KAMvB,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,KAW/B,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,KAWjC,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,KAQhC,CAAC"}