@shipfox/client-agent 5.0.0 → 6.0.2

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 (168) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +57 -0
  3. package/dist/components/available-provider-card.d.ts +2 -2
  4. package/dist/components/available-provider-card.d.ts.map +1 -1
  5. package/dist/components/available-provider-card.js.map +1 -1
  6. package/dist/components/available-providers-grid.d.ts +2 -2
  7. package/dist/components/available-providers-grid.d.ts.map +1 -1
  8. package/dist/components/available-providers-grid.js +1 -1
  9. package/dist/components/available-providers-grid.js.map +1 -1
  10. package/dist/components/change-default-model-form.d.ts +3 -4
  11. package/dist/components/change-default-model-form.d.ts.map +1 -1
  12. package/dist/components/change-default-model-form.js +2 -4
  13. package/dist/components/change-default-model-form.js.map +1 -1
  14. package/dist/components/custom-model-provider-api-options.d.ts +3 -3
  15. package/dist/components/custom-model-provider-api-options.d.ts.map +1 -1
  16. package/dist/components/custom-model-provider-api-options.js.map +1 -1
  17. package/dist/components/custom-model-provider-form.d.ts +2 -2
  18. package/dist/components/custom-model-provider-form.d.ts.map +1 -1
  19. package/dist/components/custom-model-provider-form.js +12 -10
  20. package/dist/components/custom-model-provider-form.js.map +1 -1
  21. package/dist/components/custom-model-provider-form.stories.d.ts.map +1 -1
  22. package/dist/components/custom-model-provider-form.stories.js +11 -11
  23. package/dist/components/custom-model-provider-form.stories.js.map +1 -1
  24. package/dist/components/custom-model-provider-payload.d.ts +9 -9
  25. package/dist/components/custom-model-provider-payload.d.ts.map +1 -1
  26. package/dist/components/custom-model-provider-payload.js +42 -26
  27. package/dist/components/custom-model-provider-payload.js.map +1 -1
  28. package/dist/components/custom-model-provider-slug.d.ts +1 -1
  29. package/dist/components/custom-model-provider-slug.d.ts.map +1 -1
  30. package/dist/components/custom-model-provider-slug.js +3 -3
  31. package/dist/components/custom-model-provider-slug.js.map +1 -1
  32. package/dist/components/default-model-field.d.ts +2 -2
  33. package/dist/components/default-model-field.d.ts.map +1 -1
  34. package/dist/components/default-model-field.js +1 -1
  35. package/dist/components/default-model-field.js.map +1 -1
  36. package/dist/components/harness-availability.d.ts +4 -7
  37. package/dist/components/harness-availability.d.ts.map +1 -1
  38. package/dist/components/harness-availability.js +2 -11
  39. package/dist/components/harness-availability.js.map +1 -1
  40. package/dist/components/harnesses-section.d.ts.map +1 -1
  41. package/dist/components/harnesses-section.js +4 -6
  42. package/dist/components/harnesses-section.js.map +1 -1
  43. package/dist/components/model-provider-usage-modal.d.ts +2 -2
  44. package/dist/components/model-provider-usage-modal.d.ts.map +1 -1
  45. package/dist/components/model-provider-usage-modal.js +4 -4
  46. package/dist/components/model-provider-usage-modal.js.map +1 -1
  47. package/dist/components/model-provider-usage-modal.stories.d.ts.map +1 -1
  48. package/dist/components/model-provider-usage-modal.stories.js +14 -16
  49. package/dist/components/model-provider-usage-modal.stories.js.map +1 -1
  50. package/dist/components/model-provider-usage-target.d.ts +5 -5
  51. package/dist/components/model-provider-usage-target.d.ts.map +1 -1
  52. package/dist/components/model-provider-usage-target.js +10 -8
  53. package/dist/components/model-provider-usage-target.js.map +1 -1
  54. package/dist/components/model-providers-section.d.ts.map +1 -1
  55. package/dist/components/model-providers-section.js +112 -94
  56. package/dist/components/model-providers-section.js.map +1 -1
  57. package/dist/components/model-providers-section.stories.js +8 -4
  58. package/dist/components/model-providers-section.stories.js.map +1 -1
  59. package/dist/components/test-and-save-form.d.ts +3 -3
  60. package/dist/components/test-and-save-form.d.ts.map +1 -1
  61. package/dist/components/test-and-save-form.js +7 -7
  62. package/dist/components/test-and-save-form.js.map +1 -1
  63. package/dist/core/harness-policy.d.ts +11 -0
  64. package/dist/core/harness-policy.d.ts.map +1 -0
  65. package/dist/core/harness-policy.js +71 -0
  66. package/dist/core/harness-policy.js.map +1 -0
  67. package/dist/core/model-provider-management-reducer.d.ts +51 -0
  68. package/dist/core/model-provider-management-reducer.d.ts.map +1 -0
  69. package/dist/core/model-provider-management-reducer.js +43 -0
  70. package/dist/core/model-provider-management-reducer.js.map +1 -0
  71. package/dist/core/models.d.ts +120 -0
  72. package/dist/core/models.d.ts.map +1 -0
  73. package/dist/core/models.js +3 -0
  74. package/dist/core/models.js.map +1 -0
  75. package/dist/core/onboarding-reducer.d.ts +36 -0
  76. package/dist/core/onboarding-reducer.d.ts.map +1 -0
  77. package/dist/core/onboarding-reducer.js +54 -0
  78. package/dist/core/onboarding-reducer.js.map +1 -0
  79. package/dist/core/provider-policy.d.ts +9 -0
  80. package/dist/core/provider-policy.d.ts.map +1 -0
  81. package/dist/core/provider-policy.js +37 -0
  82. package/dist/core/provider-policy.js.map +1 -0
  83. package/dist/feature.d.ts +7 -0
  84. package/dist/feature.d.ts.map +1 -1
  85. package/dist/feature.js +10 -9
  86. package/dist/feature.js.map +1 -1
  87. package/dist/hooks/api/model-provider-command-mapper.d.ts +11 -0
  88. package/dist/hooks/api/model-provider-command-mapper.d.ts.map +1 -0
  89. package/dist/hooks/api/model-provider-command-mapper.js +144 -0
  90. package/dist/hooks/api/model-provider-command-mapper.js.map +1 -0
  91. package/dist/hooks/api/model-provider-mapper.d.ts +11 -0
  92. package/dist/hooks/api/model-provider-mapper.d.ts.map +1 -0
  93. package/dist/hooks/api/model-provider-mapper.js +94 -0
  94. package/dist/hooks/api/model-provider-mapper.js.map +1 -0
  95. package/dist/hooks/api/model-providers.d.ts +60 -295
  96. package/dist/hooks/api/model-providers.d.ts.map +1 -1
  97. package/dist/hooks/api/model-providers.js +51 -37
  98. package/dist/hooks/api/model-providers.js.map +1 -1
  99. package/dist/pages/model-provider-onboarding-page.d.ts.map +1 -1
  100. package/dist/pages/model-provider-onboarding-page.js +57 -45
  101. package/dist/pages/model-provider-onboarding-page.js.map +1 -1
  102. package/dist/routes/inputs.d.ts +4 -0
  103. package/dist/routes/inputs.d.ts.map +1 -0
  104. package/dist/routes/inputs.js +12 -0
  105. package/dist/routes/inputs.js.map +1 -0
  106. package/dist/routes/model-provider.d.ts.map +1 -1
  107. package/dist/routes/model-provider.js +4 -5
  108. package/dist/routes/model-provider.js.map +1 -1
  109. package/dist/state/model-provider-onboarding.d.ts.map +1 -1
  110. package/dist/state/model-provider-onboarding.js +9 -18
  111. package/dist/state/model-provider-onboarding.js.map +1 -1
  112. package/dist/tsconfig.test.tsbuildinfo +1 -1
  113. package/package.json +9 -10
  114. package/src/components/available-provider-card.tsx +2 -2
  115. package/src/components/available-providers-grid.tsx +3 -3
  116. package/src/components/change-default-model-form.tsx +5 -6
  117. package/src/components/custom-model-provider-api-options.ts +3 -3
  118. package/src/components/custom-model-provider-form.stories.tsx +13 -13
  119. package/src/components/custom-model-provider-form.tsx +19 -12
  120. package/src/components/custom-model-provider-payload.test.ts +22 -22
  121. package/src/components/custom-model-provider-payload.ts +69 -54
  122. package/src/components/custom-model-provider-slug.test.ts +1 -1
  123. package/src/components/custom-model-provider-slug.ts +6 -3
  124. package/src/components/default-model-field.tsx +5 -5
  125. package/src/components/harness-availability.test.ts +13 -10
  126. package/src/components/harness-availability.ts +4 -28
  127. package/src/components/harnesses-section.tsx +7 -11
  128. package/src/components/model-provider-usage-modal.stories.tsx +18 -23
  129. package/src/components/model-provider-usage-modal.test.tsx +35 -7
  130. package/src/components/model-provider-usage-modal.tsx +12 -16
  131. package/src/components/model-provider-usage-target.ts +15 -18
  132. package/src/components/model-providers-section.stories.tsx +4 -1
  133. package/src/components/model-providers-section.tsx +112 -125
  134. package/src/components/test-and-save-form.tsx +13 -17
  135. package/src/core/harness-policy.test.ts +15 -0
  136. package/src/core/harness-policy.ts +83 -0
  137. package/src/core/model-provider-management-reducer.test.ts +59 -0
  138. package/src/core/model-provider-management-reducer.ts +72 -0
  139. package/src/core/models.ts +143 -0
  140. package/src/core/onboarding-reducer.test.ts +44 -0
  141. package/src/core/onboarding-reducer.ts +64 -0
  142. package/src/core/provider-policy.ts +53 -0
  143. package/src/feature.ts +12 -10
  144. package/src/hooks/api/model-provider-command-mapper.ts +122 -0
  145. package/src/hooks/api/model-provider-mapper.test.ts +27 -0
  146. package/src/hooks/api/model-provider-mapper.ts +120 -0
  147. package/src/hooks/api/model-providers.test.ts +15 -15
  148. package/src/hooks/api/model-providers.ts +146 -81
  149. package/src/pages/model-provider-onboarding-page.tsx +62 -56
  150. package/src/routes/inputs.test.ts +11 -0
  151. package/src/routes/inputs.ts +9 -0
  152. package/src/routes/model-provider.tsx +4 -3
  153. package/src/state/model-provider-onboarding.test.ts +4 -4
  154. package/src/state/model-provider-onboarding.ts +13 -23
  155. package/test/fixtures/model-providers.ts +1 -1
  156. package/tsconfig.build.tsbuildinfo +1 -1
  157. package/vercel.json +5 -0
  158. package/dist/components/provider-search.d.ts +0 -4
  159. package/dist/components/provider-search.d.ts.map +0 -1
  160. package/dist/components/provider-search.js +0 -13
  161. package/dist/components/provider-search.js.map +0 -1
  162. package/dist/components/supported-model-provider-catalog-entry.d.ts +0 -8
  163. package/dist/components/supported-model-provider-catalog-entry.d.ts.map +0 -1
  164. package/dist/components/supported-model-provider-catalog-entry.js +0 -9
  165. package/dist/components/supported-model-provider-catalog-entry.js.map +0 -1
  166. package/src/components/provider-search.test.ts +0 -45
  167. package/src/components/provider-search.ts +0 -18
  168. package/src/components/supported-model-provider-catalog-entry.ts +0 -19
@@ -0,0 +1,120 @@
1
+ import type {
2
+ CustomModelProviderConfigDto,
3
+ ListModelProviderConfigsResponseDto,
4
+ ModelProviderCatalogEntryDto,
5
+ ModelProviderCatalogResponseDto,
6
+ ModelProviderConfigDto,
7
+ ModelProviderConfigResponseDto,
8
+ SetDefaultHarnessResponseDto,
9
+ SetDefaultModelProviderResponseDto,
10
+ } from '@shipfox/api-agent-dto';
11
+ import type {
12
+ AgentModel,
13
+ BuiltinProviderConfig,
14
+ CustomProviderConfig,
15
+ DefaultHarnessSelection,
16
+ DefaultModelProviderSelection,
17
+ ProviderCatalog,
18
+ ProviderCatalogEntry,
19
+ ProviderConfig,
20
+ ProviderConfiguration,
21
+ } from '#core/models.js';
22
+
23
+ export function toProviderCatalog(response: ModelProviderCatalogResponseDto): ProviderCatalog {
24
+ return {providers: response.providers.map(toProviderCatalogEntry)};
25
+ }
26
+
27
+ export function toProviderCatalogEntry(entry: ModelProviderCatalogEntryDto): ProviderCatalogEntry {
28
+ if (entry.support_status === 'unsupported') {
29
+ return {
30
+ kind: 'unsupported',
31
+ id: entry.id,
32
+ label: entry.label,
33
+ unsupportedReason: entry.unsupported_reason ?? 'Unsupported provider',
34
+ };
35
+ }
36
+ return {
37
+ kind: 'supported',
38
+ id: entry.id,
39
+ label: entry.label,
40
+ defaultModel: entry.default_model,
41
+ credentialFields: entry.credential_fields.map((field) => ({
42
+ key: field.key,
43
+ label: field.label,
44
+ secret: field.secret,
45
+ })),
46
+ models: entry.models.map(toAgentModel),
47
+ };
48
+ }
49
+
50
+ export function toProviderConfiguration(
51
+ response: ListModelProviderConfigsResponseDto,
52
+ ): ProviderConfiguration {
53
+ return {
54
+ configs: response.configs.map(toProviderConfig),
55
+ defaultHarnessId: response.default_harness_id,
56
+ defaultProviderId: response.default_provider_id,
57
+ };
58
+ }
59
+
60
+ export function toDefaultModelProviderSelection(
61
+ response: SetDefaultModelProviderResponseDto,
62
+ ): DefaultModelProviderSelection {
63
+ return {defaultProviderId: response.default_provider_id};
64
+ }
65
+
66
+ export function toDefaultHarnessSelection(
67
+ response: SetDefaultHarnessResponseDto,
68
+ ): DefaultHarnessSelection {
69
+ return {defaultHarnessId: response.default_harness_id};
70
+ }
71
+
72
+ export function toProviderConfig(config: ModelProviderConfigResponseDto): ProviderConfig {
73
+ return config.kind === 'builtin'
74
+ ? toBuiltinProviderConfig(config)
75
+ : toCustomProviderConfig(config);
76
+ }
77
+
78
+ export function toBuiltinProviderConfig(config: ModelProviderConfigDto): BuiltinProviderConfig {
79
+ return {
80
+ kind: 'builtin',
81
+ providerId: config.provider_id,
82
+ defaultModel: config.default_model,
83
+ createdAt: config.created_at,
84
+ updatedAt: config.updated_at,
85
+ };
86
+ }
87
+
88
+ export function toCustomProviderConfig(config: CustomModelProviderConfigDto): CustomProviderConfig {
89
+ return {
90
+ kind: 'custom',
91
+ providerId: config.provider_id,
92
+ displayName: config.display_name,
93
+ api: config.api,
94
+ baseUrl: config.base_url,
95
+ headers: config.headers.map((header) => ({name: header.name, value: header.value})),
96
+ secretHeaderNames: config.secret_header_names,
97
+ models: config.models.map(toAgentModel),
98
+ defaultModel: config.default_model,
99
+ createdAt: config.created_at,
100
+ updatedAt: config.updated_at,
101
+ };
102
+ }
103
+
104
+ function toAgentModel(model: {
105
+ id: string;
106
+ label: string;
107
+ context_window?: number | undefined;
108
+ max_output_tokens?: number | undefined;
109
+ input_image?: boolean | undefined;
110
+ reasoning?: boolean | undefined;
111
+ }): AgentModel {
112
+ return {
113
+ id: model.id,
114
+ label: model.label,
115
+ ...(model.context_window === undefined ? {} : {contextWindow: model.context_window}),
116
+ ...(model.max_output_tokens === undefined ? {} : {maxOutputTokens: model.max_output_tokens}),
117
+ ...(model.input_image === undefined ? {} : {inputImage: model.input_image}),
118
+ ...(model.reasoning === undefined ? {} : {reasoning: model.reasoning}),
119
+ };
120
+ }
@@ -47,7 +47,7 @@ describe('model provider transport', () => {
47
47
  const result = await listModelProviderConfigs({workspaceId: AGENT_TEST_WORKSPACE_ID});
48
48
 
49
49
  const request = fetchImpl.mock.calls[0]?.[0] as Request;
50
- expect(result.default_provider_id).toBe('anthropic');
50
+ expect(result.defaultProviderId).toBe('anthropic');
51
51
  expect(request.url).toBe(
52
52
  `https://api.example.test/workspaces/${AGENT_TEST_WORKSPACE_ID}/agent/model-providers`,
53
53
  );
@@ -66,11 +66,11 @@ describe('model provider transport', () => {
66
66
  const result = await upsertModelProviderConfig({
67
67
  workspaceId: AGENT_TEST_WORKSPACE_ID,
68
68
  providerId: 'anthropic',
69
- body,
69
+ command: {defaultModel: 'claude-haiku-4-5', credentials: {api_key: 'sk-ant-secret'}},
70
70
  });
71
71
 
72
72
  const request = fetchImpl.mock.calls[0]?.[0] as Request;
73
- expect(result.provider_id).toBe('anthropic');
73
+ expect(result.providerId).toBe('anthropic');
74
74
  expect(request.url).toBe(
75
75
  `https://api.example.test/workspaces/${AGENT_TEST_WORKSPACE_ID}/agent/model-providers/anthropic`,
76
76
  );
@@ -102,21 +102,21 @@ describe('model provider transport', () => {
102
102
  return jsonResponse(modelProviderConfig({default_model: null}));
103
103
  });
104
104
  configureApiClient({fetchImpl});
105
- const body = {default_model: null};
105
+ const defaultModel: string | null = null;
106
106
 
107
107
  const result = await updateModelProviderDefaultModel({
108
108
  workspaceId: AGENT_TEST_WORKSPACE_ID,
109
109
  providerId: 'anthropic',
110
- body,
110
+ defaultModel,
111
111
  });
112
112
 
113
113
  const request = fetchImpl.mock.calls[0]?.[0] as Request;
114
- expect(result.default_model).toBeNull();
114
+ expect(result.defaultModel).toBeNull();
115
115
  expect(request.url).toBe(
116
116
  `https://api.example.test/workspaces/${AGENT_TEST_WORKSPACE_ID}/agent/model-providers/anthropic/default-model`,
117
117
  );
118
118
  expect(request.method).toBe('PUT');
119
- expect(requestBody).toEqual(body);
119
+ expect(requestBody).toEqual({default_model: defaultModel});
120
120
  });
121
121
 
122
122
  test('sets the default model provider', async () => {
@@ -126,20 +126,20 @@ describe('model provider transport', () => {
126
126
  return jsonResponse({default_provider_id: 'anthropic'});
127
127
  });
128
128
  configureApiClient({fetchImpl});
129
- const body = {provider_id: 'anthropic'} as const;
129
+ const providerId = 'anthropic';
130
130
 
131
131
  const result = await setDefaultModelProvider({
132
132
  workspaceId: AGENT_TEST_WORKSPACE_ID,
133
- body,
133
+ providerId,
134
134
  });
135
135
 
136
136
  const request = fetchImpl.mock.calls[0]?.[0] as Request;
137
- expect(result.default_provider_id).toBe('anthropic');
137
+ expect(result.defaultProviderId).toBe('anthropic');
138
138
  expect(request.url).toBe(
139
139
  `https://api.example.test/workspaces/${AGENT_TEST_WORKSPACE_ID}/agent/default-model-provider`,
140
140
  );
141
141
  expect(request.method).toBe('PUT');
142
- expect(requestBody).toEqual(body);
142
+ expect(requestBody).toEqual({provider_id: providerId});
143
143
  });
144
144
 
145
145
  test('sets the default harness', async () => {
@@ -149,19 +149,19 @@ describe('model provider transport', () => {
149
149
  return jsonResponse({default_harness_id: 'claude'});
150
150
  });
151
151
  configureApiClient({fetchImpl});
152
- const body = {harness_id: 'claude'} as const;
152
+ const harnessId = 'claude' as const;
153
153
 
154
154
  const result = await setDefaultHarness({
155
155
  workspaceId: AGENT_TEST_WORKSPACE_ID,
156
- body,
156
+ harnessId,
157
157
  });
158
158
 
159
159
  const request = fetchImpl.mock.calls[0]?.[0] as Request;
160
- expect(result.default_harness_id).toBe('claude');
160
+ expect(result.defaultHarnessId).toBe('claude');
161
161
  expect(request.url).toBe(
162
162
  `https://api.example.test/workspaces/${AGENT_TEST_WORKSPACE_ID}/agent/default-harness`,
163
163
  );
164
164
  expect(request.method).toBe('PUT');
165
- expect(requestBody).toEqual(body);
165
+ expect(requestBody).toEqual({harness_id: harnessId});
166
166
  });
167
167
  });
@@ -1,23 +1,14 @@
1
- import type {
2
- CreateCustomModelProviderBodyDto,
3
- CustomModelProviderConfigDto,
4
- DiscoverCustomModelProviderModelsBodyDto,
5
- DiscoverCustomModelProviderModelsBySlugBodyDto,
6
- DiscoverCustomModelProviderModelsResponseDto,
7
- ListModelProviderConfigsResponseDto,
8
- ModelProviderCatalogResponseDto,
9
- ModelProviderConfigDto,
10
- ModelProviderRef,
11
- SetDefaultHarnessBodyDto,
12
- SetDefaultHarnessResponseDto,
13
- SetDefaultModelProviderBodyDto,
14
- SetDefaultModelProviderResponseDto,
15
- SupportedModelProviderId,
16
- UpdateCustomModelProviderBodyDto,
17
- UpdateModelProviderConfigBodyDto,
18
- UpdateModelProviderDefaultModelBodyDto,
1
+ import {
2
+ customModelProviderConfigDtoSchema,
3
+ discoverCustomModelProviderModelsResponseSchema,
4
+ listModelProviderConfigsResponseSchema,
5
+ type ModelProviderRef,
6
+ modelProviderCatalogResponseSchema,
7
+ modelProviderConfigDtoSchema,
8
+ setDefaultHarnessResponseSchema,
9
+ setDefaultModelProviderResponseSchema,
19
10
  } from '@shipfox/api-agent-dto';
20
- import {apiRequest} from '@shipfox/client-api';
11
+ import {checkedApiRequest, emptyResponseSchema} from '@shipfox/client-api';
21
12
  import {
22
13
  type FetchQueryOptions,
23
14
  queryOptions,
@@ -25,6 +16,36 @@ import {
25
16
  useQuery,
26
17
  useQueryClient,
27
18
  } from '@tanstack/react-query';
19
+ import type {
20
+ AgentModel,
21
+ CreateCustomProviderCommand,
22
+ DefaultHarnessSelection,
23
+ DefaultModelProviderSelection,
24
+ DiscoverProviderModelsCommand,
25
+ HarnessId,
26
+ ProviderCatalog,
27
+ ProviderConfig,
28
+ ProviderConfiguration,
29
+ ProviderCredentialsCommand,
30
+ UpdateCustomProviderCommand,
31
+ } from '#core/models.js';
32
+ import {
33
+ toCreateCustomProviderBody,
34
+ toDefaultHarnessBody,
35
+ toDefaultModelBody,
36
+ toDefaultProviderBody,
37
+ toDiscoverModelsBody,
38
+ toDiscoverModelsBySlugBody,
39
+ toProviderCredentialsBody,
40
+ toUpdateCustomProviderBody,
41
+ } from './model-provider-command-mapper.js';
42
+ import {
43
+ toDefaultHarnessSelection,
44
+ toDefaultModelProviderSelection,
45
+ toProviderCatalog,
46
+ toProviderConfig,
47
+ toProviderConfiguration,
48
+ } from './model-provider-mapper.js';
28
49
 
29
50
  export const modelProviderQueryKeys = {
30
51
  all: ['model-providers'] as const,
@@ -38,16 +59,29 @@ type ModelProviderConfigsQueryKey =
38
59
  | readonly ['model-providers', 'configs'];
39
60
 
40
61
  type ModelProviderConfigsQueryOptions = FetchQueryOptions<
41
- ListModelProviderConfigsResponseDto,
62
+ ProviderConfiguration,
42
63
  Error,
43
- ListModelProviderConfigsResponseDto,
64
+ ProviderConfiguration,
44
65
  ModelProviderConfigsQueryKey
45
66
  >;
46
67
 
47
- export async function getModelProviderCatalog({signal}: {signal?: AbortSignal} = {}) {
48
- return await apiRequest<ModelProviderCatalogResponseDto>('/agent/model-provider-catalog', {
49
- signal,
50
- });
68
+ type ModelProviderCatalogQueryOptions = FetchQueryOptions<
69
+ ProviderCatalog,
70
+ Error,
71
+ ProviderCatalog,
72
+ ReturnType<typeof modelProviderQueryKeys.catalog>
73
+ >;
74
+
75
+ export async function getModelProviderCatalog({
76
+ signal,
77
+ }: {
78
+ signal?: AbortSignal;
79
+ } = {}): Promise<ProviderCatalog> {
80
+ return toProviderCatalog(
81
+ await checkedApiRequest(modelProviderCatalogResponseSchema, '/agent/model-provider-catalog', {
82
+ signal,
83
+ }),
84
+ );
51
85
  }
52
86
 
53
87
  export async function listModelProviderConfigs({
@@ -56,10 +90,13 @@ export async function listModelProviderConfigs({
56
90
  }: {
57
91
  workspaceId: string;
58
92
  signal?: AbortSignal;
59
- }) {
60
- return await apiRequest<ListModelProviderConfigsResponseDto>(
61
- `/workspaces/${workspaceId}/agent/model-providers`,
62
- {signal},
93
+ }): Promise<ProviderConfiguration> {
94
+ return toProviderConfiguration(
95
+ await checkedApiRequest(
96
+ listModelProviderConfigsResponseSchema,
97
+ `/workspaces/${workspaceId}/agent/model-providers`,
98
+ {signal},
99
+ ),
63
100
  );
64
101
  }
65
102
 
@@ -78,72 +115,85 @@ export function modelProviderConfigsQueryOptions(
78
115
  export async function upsertModelProviderConfig({
79
116
  workspaceId,
80
117
  providerId,
81
- body,
118
+ command,
82
119
  }: {
83
120
  workspaceId: string;
84
- providerId: SupportedModelProviderId;
85
- body: UpdateModelProviderConfigBodyDto;
86
- }) {
87
- return await apiRequest<ModelProviderConfigDto>(
88
- `/workspaces/${workspaceId}/agent/model-providers/${providerId}`,
89
- {method: 'PUT', body},
121
+ providerId: string;
122
+ command: ProviderCredentialsCommand;
123
+ }): Promise<ProviderConfig> {
124
+ return toProviderConfig(
125
+ await checkedApiRequest(
126
+ modelProviderConfigDtoSchema,
127
+ `/workspaces/${workspaceId}/agent/model-providers/${providerId}`,
128
+ {method: 'PUT', body: toProviderCredentialsBody(command)},
129
+ ),
90
130
  );
91
131
  }
92
132
 
93
133
  export async function createCustomModelProviderConfig({
94
134
  workspaceId,
95
- body,
135
+ command,
96
136
  }: {
97
137
  workspaceId: string;
98
- body: CreateCustomModelProviderBodyDto;
99
- }) {
100
- return await apiRequest<CustomModelProviderConfigDto>(
101
- `/workspaces/${workspaceId}/agent/custom-model-providers`,
102
- {method: 'POST', body},
138
+ command: CreateCustomProviderCommand;
139
+ }): Promise<ProviderConfig> {
140
+ return toProviderConfig(
141
+ await checkedApiRequest(
142
+ customModelProviderConfigDtoSchema,
143
+ `/workspaces/${workspaceId}/agent/custom-model-providers`,
144
+ {method: 'POST', body: toCreateCustomProviderBody(command)},
145
+ ),
103
146
  );
104
147
  }
105
148
 
106
149
  export async function updateCustomModelProviderConfig({
107
150
  workspaceId,
108
151
  providerId,
109
- body,
152
+ command,
110
153
  }: {
111
154
  workspaceId: string;
112
155
  providerId: ModelProviderRef;
113
- body: UpdateCustomModelProviderBodyDto;
114
- }) {
115
- return await apiRequest<CustomModelProviderConfigDto>(
116
- `/workspaces/${workspaceId}/agent/custom-model-providers/${providerId}`,
117
- {method: 'PUT', body},
156
+ command: UpdateCustomProviderCommand;
157
+ }): Promise<ProviderConfig> {
158
+ return toProviderConfig(
159
+ await checkedApiRequest(
160
+ customModelProviderConfigDtoSchema,
161
+ `/workspaces/${workspaceId}/agent/custom-model-providers/${providerId}`,
162
+ {method: 'PUT', body: toUpdateCustomProviderBody(command)},
163
+ ),
118
164
  );
119
165
  }
120
166
 
121
167
  export async function discoverCustomModelProviderModels({
122
168
  workspaceId,
123
- body,
169
+ command,
124
170
  }: {
125
171
  workspaceId: string;
126
- body: DiscoverCustomModelProviderModelsBodyDto;
127
- }) {
128
- return await apiRequest<DiscoverCustomModelProviderModelsResponseDto>(
172
+ command: DiscoverProviderModelsCommand;
173
+ }): Promise<readonly AgentModel[]> {
174
+ const response = await checkedApiRequest(
175
+ discoverCustomModelProviderModelsResponseSchema,
129
176
  `/workspaces/${workspaceId}/agent/custom-model-providers/discover-models`,
130
- {method: 'POST', body},
177
+ {method: 'POST', body: toDiscoverModelsBody(command)},
131
178
  );
179
+ return response.models.map((model) => ({id: model.id, label: model.label}));
132
180
  }
133
181
 
134
182
  export async function discoverCustomModelProviderModelsBySlug({
135
183
  workspaceId,
136
184
  providerId,
137
- body,
185
+ command,
138
186
  }: {
139
187
  workspaceId: string;
140
188
  providerId: ModelProviderRef;
141
- body: DiscoverCustomModelProviderModelsBySlugBodyDto;
142
- }) {
143
- return await apiRequest<DiscoverCustomModelProviderModelsResponseDto>(
189
+ command: DiscoverProviderModelsCommand;
190
+ }): Promise<readonly AgentModel[]> {
191
+ const response = await checkedApiRequest(
192
+ discoverCustomModelProviderModelsResponseSchema,
144
193
  `/workspaces/${workspaceId}/agent/custom-model-providers/${providerId}/discover-models`,
145
- {method: 'POST', body},
194
+ {method: 'POST', body: toDiscoverModelsBySlugBody(command)},
146
195
  );
196
+ return response.models.map((model) => ({id: model.id, label: model.label}));
147
197
  }
148
198
 
149
199
  export async function deleteModelProviderConfig({
@@ -153,54 +203,69 @@ export async function deleteModelProviderConfig({
153
203
  workspaceId: string;
154
204
  providerId: ModelProviderRef;
155
205
  }) {
156
- return await apiRequest<void>(`/workspaces/${workspaceId}/agent/model-providers/${providerId}`, {
157
- method: 'DELETE',
158
- });
206
+ return await checkedApiRequest(
207
+ emptyResponseSchema,
208
+ `/workspaces/${workspaceId}/agent/model-providers/${providerId}`,
209
+ {method: 'DELETE'},
210
+ );
159
211
  }
160
212
 
161
213
  export async function updateModelProviderDefaultModel({
162
214
  workspaceId,
163
215
  providerId,
164
- body,
216
+ defaultModel,
165
217
  }: {
166
218
  workspaceId: string;
167
- providerId: SupportedModelProviderId;
168
- body: UpdateModelProviderDefaultModelBodyDto;
169
- }) {
170
- return await apiRequest<ModelProviderConfigDto>(
171
- `/workspaces/${workspaceId}/agent/model-providers/${providerId}/default-model`,
172
- {method: 'PUT', body},
219
+ providerId: string;
220
+ defaultModel: string | null;
221
+ }): Promise<ProviderConfig> {
222
+ return toProviderConfig(
223
+ await checkedApiRequest(
224
+ modelProviderConfigDtoSchema,
225
+ `/workspaces/${workspaceId}/agent/model-providers/${providerId}/default-model`,
226
+ {method: 'PUT', body: toDefaultModelBody(defaultModel)},
227
+ ),
173
228
  );
174
229
  }
175
230
 
176
231
  export async function setDefaultModelProvider({
177
232
  workspaceId,
178
- body,
233
+ providerId,
179
234
  }: {
180
235
  workspaceId: string;
181
- body: SetDefaultModelProviderBodyDto;
182
- }) {
183
- return await apiRequest<SetDefaultModelProviderResponseDto>(
184
- `/workspaces/${workspaceId}/agent/default-model-provider`,
185
- {method: 'PUT', body},
236
+ providerId: string;
237
+ }): Promise<DefaultModelProviderSelection> {
238
+ return toDefaultModelProviderSelection(
239
+ await checkedApiRequest(
240
+ setDefaultModelProviderResponseSchema,
241
+ `/workspaces/${workspaceId}/agent/default-model-provider`,
242
+ {method: 'PUT', body: toDefaultProviderBody(providerId)},
243
+ ),
186
244
  );
187
245
  }
188
246
 
189
247
  export async function setDefaultHarness({
190
248
  workspaceId,
191
- body,
249
+ harnessId,
192
250
  }: {
193
251
  workspaceId: string;
194
- body: SetDefaultHarnessBodyDto;
195
- }) {
196
- return await apiRequest<SetDefaultHarnessResponseDto>(
197
- `/workspaces/${workspaceId}/agent/default-harness`,
198
- {method: 'PUT', body},
252
+ harnessId: HarnessId;
253
+ }): Promise<DefaultHarnessSelection> {
254
+ return toDefaultHarnessSelection(
255
+ await checkedApiRequest(
256
+ setDefaultHarnessResponseSchema,
257
+ `/workspaces/${workspaceId}/agent/default-harness`,
258
+ {method: 'PUT', body: toDefaultHarnessBody(harnessId)},
259
+ ),
199
260
  );
200
261
  }
201
262
 
202
263
  export function useModelProviderCatalogQuery() {
203
- return useQuery({
264
+ return useQuery(modelProviderCatalogQueryOptions());
265
+ }
266
+
267
+ export function modelProviderCatalogQueryOptions(): ModelProviderCatalogQueryOptions {
268
+ return queryOptions({
204
269
  queryKey: modelProviderQueryKeys.catalog(),
205
270
  queryFn: ({signal}) => getModelProviderCatalog({signal}),
206
271
  staleTime: 1000 * 60 * 60,