@caretive/caret-cli 0.0.1
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/.npmrc.tmp +2 -0
- package/README.md +72 -0
- package/cmd/cline/main.go +348 -0
- package/cmd/cline-host/main.go +71 -0
- package/e2e/default_update_test.go +154 -0
- package/e2e/helpers_test.go +378 -0
- package/e2e/main_test.go +47 -0
- package/e2e/mixed_stress_test.go +120 -0
- package/e2e/sqlite_helper.go +161 -0
- package/e2e/start_list_test.go +178 -0
- package/go.mod +64 -0
- package/go.sum +162 -0
- package/man/cline.1 +331 -0
- package/man/cline.1.md +332 -0
- package/package.json +54 -0
- package/pkg/cli/auth/auth_cline_provider.go +285 -0
- package/pkg/cli/auth/auth_menu.go +323 -0
- package/pkg/cli/auth/auth_subscription.go +130 -0
- package/pkg/cli/auth/byo_quick_setup.go +247 -0
- package/pkg/cli/auth/models_cline.go +141 -0
- package/pkg/cli/auth/models_list_fetch.go +156 -0
- package/pkg/cli/auth/models_list_static.go +69 -0
- package/pkg/cli/auth/providers_byo.go +184 -0
- package/pkg/cli/auth/providers_list.go +517 -0
- package/pkg/cli/auth/update_api_configurations.go +647 -0
- package/pkg/cli/auth/wizard_byo.go +764 -0
- package/pkg/cli/auth/wizard_byo_bedrock.go +193 -0
- package/pkg/cli/auth/wizard_byo_oca.go +366 -0
- package/pkg/cli/auth.go +43 -0
- package/pkg/cli/clerror/cline_error.go +187 -0
- package/pkg/cli/config/manager.go +208 -0
- package/pkg/cli/config/settings_renderer.go +198 -0
- package/pkg/cli/config.go +152 -0
- package/pkg/cli/display/ansi.go +27 -0
- package/pkg/cli/display/banner.go +211 -0
- package/pkg/cli/display/deduplicator.go +95 -0
- package/pkg/cli/display/markdown_renderer.go +139 -0
- package/pkg/cli/display/renderer.go +304 -0
- package/pkg/cli/display/segment_streamer.go +212 -0
- package/pkg/cli/display/streaming.go +134 -0
- package/pkg/cli/display/system_renderer.go +269 -0
- package/pkg/cli/display/tool_renderer.go +455 -0
- package/pkg/cli/display/tool_result_parser.go +371 -0
- package/pkg/cli/display/typewriter.go +210 -0
- package/pkg/cli/doctor.go +65 -0
- package/pkg/cli/global/cline-clients.go +501 -0
- package/pkg/cli/global/global.go +113 -0
- package/pkg/cli/global/registry.go +304 -0
- package/pkg/cli/handlers/ask_handlers.go +339 -0
- package/pkg/cli/handlers/handler.go +130 -0
- package/pkg/cli/handlers/say_handlers.go +521 -0
- package/pkg/cli/instances.go +506 -0
- package/pkg/cli/logs.go +382 -0
- package/pkg/cli/output/coordinator.go +167 -0
- package/pkg/cli/output/input_model.go +497 -0
- package/pkg/cli/sqlite/locks.go +366 -0
- package/pkg/cli/task/history_handler.go +72 -0
- package/pkg/cli/task/input_handler.go +577 -0
- package/pkg/cli/task/manager.go +1283 -0
- package/pkg/cli/task/settings_parser.go +754 -0
- package/pkg/cli/task/stream_coordinator.go +60 -0
- package/pkg/cli/task.go +675 -0
- package/pkg/cli/terminal/keyboard.go +695 -0
- package/pkg/cli/tui/HELP_WANTED.md +1 -0
- package/pkg/cli/types/history.go +17 -0
- package/pkg/cli/types/messages.go +329 -0
- package/pkg/cli/types/state.go +59 -0
- package/pkg/cli/updater/updater.go +409 -0
- package/pkg/cli/version.go +43 -0
- package/pkg/common/constants.go +6 -0
- package/pkg/common/schema.go +54 -0
- package/pkg/common/types.go +54 -0
- package/pkg/common/utils.go +185 -0
- package/pkg/generated/field_overrides.go +39 -0
- package/pkg/generated/providers.go +1584 -0
- package/pkg/hostbridge/diff.go +351 -0
- package/pkg/hostbridge/disabled/watch.go +39 -0
- package/pkg/hostbridge/disabled/window.go +63 -0
- package/pkg/hostbridge/disabled/workspace.go +66 -0
- package/pkg/hostbridge/env.go +166 -0
- package/pkg/hostbridge/grpc_server.go +113 -0
- package/pkg/hostbridge/simple.go +43 -0
- package/pkg/hostbridge/simple_workspace.go +85 -0
- package/pkg/hostbridge/window.go +129 -0
- package/scripts/publish-caret-cli.sh +39 -0
|
@@ -0,0 +1,647 @@
|
|
|
1
|
+
package auth
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"context"
|
|
5
|
+
"fmt"
|
|
6
|
+
|
|
7
|
+
"github.com/cline/cli/pkg/cli/global"
|
|
8
|
+
"github.com/cline/cli/pkg/cli/task"
|
|
9
|
+
"github.com/cline/grpc-go/cline"
|
|
10
|
+
"google.golang.org/protobuf/proto"
|
|
11
|
+
"google.golang.org/protobuf/types/known/fieldmaskpb"
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
// updateApiConfigurationPartial is a helper that calls the gRPC method with optional verbose logging.
|
|
15
|
+
// This replaces the Manager.updateApiConfigurationPartial method to keep auth-specific code in the auth package.
|
|
16
|
+
func updateApiConfigurationPartial(ctx context.Context, manager *task.Manager, request *cline.UpdateApiConfigurationPartialRequest) error {
|
|
17
|
+
if global.Config.Verbose {
|
|
18
|
+
fmt.Println("[DEBUG] Updating API configuration (partial)")
|
|
19
|
+
if request.UpdateMask != nil && len(request.UpdateMask.Paths) > 0 {
|
|
20
|
+
fmt.Printf("[DEBUG] Field mask paths: %v\n", request.UpdateMask.Paths)
|
|
21
|
+
}
|
|
22
|
+
if request.ApiConfiguration != nil {
|
|
23
|
+
apiConfig := request.ApiConfiguration
|
|
24
|
+
if apiConfig.PlanModeApiProvider != nil {
|
|
25
|
+
fmt.Printf("[DEBUG] Plan mode provider: %s\n", *apiConfig.PlanModeApiProvider)
|
|
26
|
+
}
|
|
27
|
+
if apiConfig.ActModeApiProvider != nil {
|
|
28
|
+
fmt.Printf("[DEBUG] Act mode provider: %s\n", *apiConfig.ActModeApiProvider)
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Call the Models service to update API configuration
|
|
34
|
+
_, err := manager.GetClient().Models.UpdateApiConfigurationPartial(ctx, request)
|
|
35
|
+
if err != nil {
|
|
36
|
+
return fmt.Errorf("failed to update API configuration (partial): %w", err)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if global.Config.Verbose {
|
|
40
|
+
fmt.Println("[DEBUG] API configuration updated successfully (partial)")
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return nil
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// ProviderFields defines all the field names associated with a specific provider
|
|
47
|
+
type ProviderFields struct {
|
|
48
|
+
APIKeyField string // API key field name (e.g., "apiKey", "openAiApiKey")
|
|
49
|
+
BaseURLField string // Base URL field name (optional, empty if not applicable)
|
|
50
|
+
PlanModeModelIDField string // Plan mode model ID field (e.g., "planModeApiModelId")
|
|
51
|
+
ActModeModelIDField string // Act mode model ID field (e.g., "actModeApiModelId")
|
|
52
|
+
PlanModeModelInfoField string // Plan mode model info field (optional, empty if not applicable)
|
|
53
|
+
ActModeModelInfoField string // Act mode model info field (optional, empty if not applicable)
|
|
54
|
+
// Provider-specific additional model ID fields
|
|
55
|
+
PlanModeProviderSpecificModelIDField string // e.g., "planModeOpenRouterModelId"
|
|
56
|
+
ActModeProviderSpecificModelIDField string // e.g., "actModeOpenRouterModelId"
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// GetProviderFields returns the field mapping for a given provider
|
|
60
|
+
func GetProviderFields(provider cline.ApiProvider) (ProviderFields, error) {
|
|
61
|
+
switch provider {
|
|
62
|
+
case cline.ApiProvider_ANTHROPIC:
|
|
63
|
+
return ProviderFields{
|
|
64
|
+
APIKeyField: "apiKey",
|
|
65
|
+
PlanModeModelIDField: "planModeApiModelId",
|
|
66
|
+
ActModeModelIDField: "actModeApiModelId",
|
|
67
|
+
}, nil
|
|
68
|
+
|
|
69
|
+
case cline.ApiProvider_OPENAI:
|
|
70
|
+
return ProviderFields{
|
|
71
|
+
APIKeyField: "openAiApiKey",
|
|
72
|
+
BaseURLField: "openAiBaseUrl",
|
|
73
|
+
PlanModeModelIDField: "planModeApiModelId",
|
|
74
|
+
ActModeModelIDField: "actModeApiModelId",
|
|
75
|
+
PlanModeProviderSpecificModelIDField: "planModeOpenAiModelId",
|
|
76
|
+
ActModeProviderSpecificModelIDField: "actModeOpenAiModelId",
|
|
77
|
+
}, nil
|
|
78
|
+
|
|
79
|
+
case cline.ApiProvider_OPENROUTER:
|
|
80
|
+
return ProviderFields{
|
|
81
|
+
APIKeyField: "openRouterApiKey",
|
|
82
|
+
PlanModeModelIDField: "planModeApiModelId",
|
|
83
|
+
ActModeModelIDField: "actModeApiModelId",
|
|
84
|
+
PlanModeModelInfoField: "planModeOpenRouterModelInfo",
|
|
85
|
+
ActModeModelInfoField: "actModeOpenRouterModelInfo",
|
|
86
|
+
PlanModeProviderSpecificModelIDField: "planModeOpenRouterModelId",
|
|
87
|
+
ActModeProviderSpecificModelIDField: "actModeOpenRouterModelId",
|
|
88
|
+
}, nil
|
|
89
|
+
|
|
90
|
+
case cline.ApiProvider_XAI:
|
|
91
|
+
return ProviderFields{
|
|
92
|
+
APIKeyField: "xaiApiKey",
|
|
93
|
+
PlanModeModelIDField: "planModeApiModelId",
|
|
94
|
+
ActModeModelIDField: "actModeApiModelId",
|
|
95
|
+
}, nil
|
|
96
|
+
|
|
97
|
+
case cline.ApiProvider_BEDROCK:
|
|
98
|
+
return ProviderFields{
|
|
99
|
+
APIKeyField: "awsAccessKey",
|
|
100
|
+
PlanModeModelIDField: "planModeApiModelId",
|
|
101
|
+
ActModeModelIDField: "actModeApiModelId",
|
|
102
|
+
PlanModeProviderSpecificModelIDField: "planModeAwsBedrockCustomModelBaseId",
|
|
103
|
+
ActModeProviderSpecificModelIDField: "actModeAwsBedrockCustomModelBaseId",
|
|
104
|
+
}, nil
|
|
105
|
+
|
|
106
|
+
case cline.ApiProvider_GEMINI:
|
|
107
|
+
return ProviderFields{
|
|
108
|
+
APIKeyField: "geminiApiKey",
|
|
109
|
+
PlanModeModelIDField: "planModeApiModelId",
|
|
110
|
+
ActModeModelIDField: "actModeApiModelId",
|
|
111
|
+
}, nil
|
|
112
|
+
|
|
113
|
+
case cline.ApiProvider_OPENAI_NATIVE:
|
|
114
|
+
return ProviderFields{
|
|
115
|
+
APIKeyField: "openAiNativeApiKey",
|
|
116
|
+
PlanModeModelIDField: "planModeApiModelId",
|
|
117
|
+
ActModeModelIDField: "actModeApiModelId",
|
|
118
|
+
}, nil
|
|
119
|
+
|
|
120
|
+
case cline.ApiProvider_OLLAMA:
|
|
121
|
+
return ProviderFields{
|
|
122
|
+
APIKeyField: "ollamaBaseUrl",
|
|
123
|
+
PlanModeModelIDField: "planModeApiModelId",
|
|
124
|
+
ActModeModelIDField: "actModeApiModelId",
|
|
125
|
+
PlanModeProviderSpecificModelIDField: "planModeOllamaModelId",
|
|
126
|
+
ActModeProviderSpecificModelIDField: "actModeOllamaModelId",
|
|
127
|
+
}, nil
|
|
128
|
+
|
|
129
|
+
case cline.ApiProvider_CEREBRAS:
|
|
130
|
+
return ProviderFields{
|
|
131
|
+
APIKeyField: "cerebrasApiKey",
|
|
132
|
+
PlanModeModelIDField: "planModeApiModelId",
|
|
133
|
+
ActModeModelIDField: "actModeApiModelId",
|
|
134
|
+
}, nil
|
|
135
|
+
|
|
136
|
+
case cline.ApiProvider_CLINE:
|
|
137
|
+
return ProviderFields{
|
|
138
|
+
APIKeyField: "clineApiKey",
|
|
139
|
+
PlanModeModelIDField: "planModeApiModelId",
|
|
140
|
+
ActModeModelIDField: "actModeApiModelId",
|
|
141
|
+
PlanModeModelInfoField: "planModeOpenRouterModelInfo",
|
|
142
|
+
ActModeModelInfoField: "actModeOpenRouterModelInfo",
|
|
143
|
+
PlanModeProviderSpecificModelIDField: "planModeOpenRouterModelId",
|
|
144
|
+
ActModeProviderSpecificModelIDField: "actModeOpenRouterModelId",
|
|
145
|
+
}, nil
|
|
146
|
+
|
|
147
|
+
case cline.ApiProvider_OCA:
|
|
148
|
+
return ProviderFields{
|
|
149
|
+
APIKeyField: "ocaApiKey",
|
|
150
|
+
PlanModeModelIDField: "planModeApiModelId",
|
|
151
|
+
ActModeModelIDField: "actModeApiModelId",
|
|
152
|
+
PlanModeModelInfoField: "planModeOcaModelInfo",
|
|
153
|
+
ActModeModelInfoField: "actModeOcaModelInfo",
|
|
154
|
+
PlanModeProviderSpecificModelIDField: "planModeOcaModelId",
|
|
155
|
+
ActModeProviderSpecificModelIDField: "actModeOcaModelId",
|
|
156
|
+
}, nil
|
|
157
|
+
case cline.ApiProvider_HICAP:
|
|
158
|
+
return ProviderFields{
|
|
159
|
+
APIKeyField: "hicapApiKey",
|
|
160
|
+
PlanModeModelInfoField: "planModeHicapModelInfo",
|
|
161
|
+
ActModeModelInfoField: "actModeHicapModelInfo",
|
|
162
|
+
PlanModeProviderSpecificModelIDField: "planModeHicapModelId",
|
|
163
|
+
ActModeProviderSpecificModelIDField: "actModeHicapModelId",
|
|
164
|
+
}, nil
|
|
165
|
+
|
|
166
|
+
case cline.ApiProvider_NOUSRESEARCH:
|
|
167
|
+
return ProviderFields{
|
|
168
|
+
APIKeyField: "nousResearchApiKey",
|
|
169
|
+
PlanModeModelIDField: "planModeApiModelId",
|
|
170
|
+
ActModeModelIDField: "actModeApiModelId",
|
|
171
|
+
PlanModeProviderSpecificModelIDField: "planModeNousResearchModelId",
|
|
172
|
+
ActModeProviderSpecificModelIDField: "actModeNousResearchModelId",
|
|
173
|
+
}, nil
|
|
174
|
+
|
|
175
|
+
default:
|
|
176
|
+
return ProviderFields{}, fmt.Errorf("unsupported provider: %v", provider)
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// ProviderUpdatesPartial defines optional fields for partial provider updates
|
|
181
|
+
// Uses pointers to distinguish between "not provided" and "set to empty"
|
|
182
|
+
type ProviderUpdatesPartial struct {
|
|
183
|
+
ModelID *string // New model ID (optional)
|
|
184
|
+
APIKey *string // New API key (optional)
|
|
185
|
+
ModelInfo interface{} // New model info (optional, provider-specific)
|
|
186
|
+
BaseURL *string // New base URL (optional, e.g., for OCA, Ollama)
|
|
187
|
+
RefreshToken *string // New refresh token (optional, e.g., for OCA)
|
|
188
|
+
Mode *string // New mode (optional, e.g., "internal" or "external" for OCA)
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// GetModelIDFieldName returns the appropriate model ID field name for a provider and mode.
|
|
192
|
+
// This helper centralizes the logic for determining whether to use provider-specific
|
|
193
|
+
// or generic model ID fields.
|
|
194
|
+
func GetModelIDFieldName(provider cline.ApiProvider, mode string) (string, error) {
|
|
195
|
+
fields, err := GetProviderFields(provider)
|
|
196
|
+
if err != nil {
|
|
197
|
+
return "", err
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if mode == "plan" {
|
|
201
|
+
// Use provider-specific field if available, otherwise use generic field
|
|
202
|
+
if fields.PlanModeProviderSpecificModelIDField != "" {
|
|
203
|
+
return fields.PlanModeProviderSpecificModelIDField, nil
|
|
204
|
+
}
|
|
205
|
+
return fields.PlanModeModelIDField, nil
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Act mode
|
|
209
|
+
if fields.ActModeProviderSpecificModelIDField != "" {
|
|
210
|
+
return fields.ActModeProviderSpecificModelIDField, nil
|
|
211
|
+
}
|
|
212
|
+
return fields.ActModeModelIDField, nil
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// buildProviderFieldMask builds a list of camelCase field paths for the field mask.
|
|
216
|
+
// When includeProviderEnums is true, the provider enum fields are included (for setting active provider).
|
|
217
|
+
// When false, only the data fields are included (for configuring without activating).
|
|
218
|
+
func buildProviderFieldMask(fields ProviderFields, includeAPIKey bool, includeModelID bool, includeModelInfo bool, includeBaseURL bool, includeProviderEnums bool) []string {
|
|
219
|
+
var fieldPaths []string
|
|
220
|
+
|
|
221
|
+
// Include provider enums if requested (used when setting active provider)
|
|
222
|
+
if includeProviderEnums {
|
|
223
|
+
fieldPaths = append(fieldPaths, "planModeApiProvider", "actModeApiProvider")
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// Add API key field if requested
|
|
227
|
+
if includeAPIKey {
|
|
228
|
+
fieldPaths = append(fieldPaths, fields.APIKeyField)
|
|
229
|
+
// Special case: Bedrock also needs secret key
|
|
230
|
+
if fields.APIKeyField == "awsAccessKey" {
|
|
231
|
+
fieldPaths = append(fieldPaths, "awsSecretKey")
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// Add base URL field if requested and applicable
|
|
236
|
+
if includeBaseURL && fields.BaseURLField != "" {
|
|
237
|
+
fieldPaths = append(fieldPaths, fields.BaseURLField)
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// Add model ID fields if requested
|
|
241
|
+
if includeModelID {
|
|
242
|
+
// Only include provider-specific fields if they exist, otherwise use generic fields
|
|
243
|
+
if fields.PlanModeProviderSpecificModelIDField != "" {
|
|
244
|
+
// Provider has specific fields - use ONLY those
|
|
245
|
+
fieldPaths = append(fieldPaths, fields.PlanModeProviderSpecificModelIDField)
|
|
246
|
+
fieldPaths = append(fieldPaths, fields.ActModeProviderSpecificModelIDField)
|
|
247
|
+
} else {
|
|
248
|
+
// Provider uses generic fields - update those
|
|
249
|
+
fieldPaths = append(fieldPaths, fields.PlanModeModelIDField)
|
|
250
|
+
fieldPaths = append(fieldPaths, fields.ActModeModelIDField)
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// Add model info fields if requested and applicable
|
|
255
|
+
if includeModelInfo && fields.PlanModeModelInfoField != "" {
|
|
256
|
+
fieldPaths = append(fieldPaths, fields.PlanModeModelInfoField)
|
|
257
|
+
fieldPaths = append(fieldPaths, fields.ActModeModelInfoField)
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
return fieldPaths
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// setAPIKeyField sets the appropriate API key field in the config based on the field name
|
|
264
|
+
func setAPIKeyField(apiConfig *cline.ModelsApiConfiguration, fieldName string, value *string) {
|
|
265
|
+
switch fieldName {
|
|
266
|
+
case "apiKey":
|
|
267
|
+
apiConfig.ApiKey = value
|
|
268
|
+
case "openAiApiKey":
|
|
269
|
+
apiConfig.OpenAiApiKey = value
|
|
270
|
+
case "openAiNativeApiKey":
|
|
271
|
+
apiConfig.OpenAiNativeApiKey = value
|
|
272
|
+
case "openRouterApiKey":
|
|
273
|
+
apiConfig.OpenRouterApiKey = value
|
|
274
|
+
case "xaiApiKey":
|
|
275
|
+
apiConfig.XaiApiKey = value
|
|
276
|
+
case "awsAccessKey":
|
|
277
|
+
apiConfig.AwsAccessKey = value
|
|
278
|
+
case "geminiApiKey":
|
|
279
|
+
apiConfig.GeminiApiKey = value
|
|
280
|
+
case "ollamaBaseUrl":
|
|
281
|
+
apiConfig.OllamaBaseUrl = value
|
|
282
|
+
case "cerebrasApiKey":
|
|
283
|
+
apiConfig.CerebrasApiKey = value
|
|
284
|
+
case "clineApiKey":
|
|
285
|
+
apiConfig.ClineApiKey = value
|
|
286
|
+
case "ocaApiKey":
|
|
287
|
+
apiConfig.OcaApiKey = value
|
|
288
|
+
case "hicapApiKey":
|
|
289
|
+
apiConfig.HicapApiKey = value
|
|
290
|
+
case "nousResearchApiKey":
|
|
291
|
+
apiConfig.NousResearchApiKey = value
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// setProviderSpecificModelID sets the appropriate provider-specific model ID fields when possible
|
|
296
|
+
func setProviderSpecificModelID(apiConfig *cline.ModelsApiConfiguration, fieldName string, value *string) {
|
|
297
|
+
switch fieldName {
|
|
298
|
+
case "planModeOpenAiModelId":
|
|
299
|
+
apiConfig.PlanModeOpenAiModelId = value
|
|
300
|
+
apiConfig.ActModeOpenAiModelId = value
|
|
301
|
+
case "planModeOpenRouterModelId":
|
|
302
|
+
apiConfig.PlanModeOpenRouterModelId = value
|
|
303
|
+
apiConfig.ActModeOpenRouterModelId = value
|
|
304
|
+
case "planModeOllamaModelId":
|
|
305
|
+
apiConfig.PlanModeOllamaModelId = value
|
|
306
|
+
apiConfig.ActModeOllamaModelId = value
|
|
307
|
+
case "planModeAwsBedrockCustomModelBaseId":
|
|
308
|
+
apiConfig.PlanModeAwsBedrockCustomModelBaseId = value
|
|
309
|
+
apiConfig.ActModeAwsBedrockCustomModelBaseId = value
|
|
310
|
+
case "planModeOcaModelId":
|
|
311
|
+
apiConfig.PlanModeOcaModelId = value
|
|
312
|
+
apiConfig.ActModeOcaModelId = value
|
|
313
|
+
case "planModeHicapModelId":
|
|
314
|
+
apiConfig.PlanModeHicapModelId = value
|
|
315
|
+
apiConfig.ActModeHicapModelId = value
|
|
316
|
+
case "planModeNousResearchModelId":
|
|
317
|
+
apiConfig.PlanModeNousResearchModelId = value
|
|
318
|
+
apiConfig.ActModeNousResearchModelId = value
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// AddProviderPartial configures a new provider with all necessary fields using partial updates.
|
|
323
|
+
func AddProviderPartial(ctx context.Context, manager *task.Manager, provider cline.ApiProvider, modelID string, apiKey string, baseURL string, modelInfo interface{}) error {
|
|
324
|
+
// Get field mapping for this provider
|
|
325
|
+
fields, err := GetProviderFields(provider)
|
|
326
|
+
if err != nil {
|
|
327
|
+
return err
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// Build a ModelsApiConfiguration with only the relevant provider fields set
|
|
331
|
+
apiConfig := &cline.ModelsApiConfiguration{}
|
|
332
|
+
|
|
333
|
+
// Set API key field
|
|
334
|
+
if apiKey != "" || fields.APIKeyField != "ollamaBaseUrl" {
|
|
335
|
+
setAPIKeyField(apiConfig, fields.APIKeyField, proto.String(apiKey))
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// Set base URL field if provided and applicable
|
|
339
|
+
includeBaseURL := false
|
|
340
|
+
if baseURL != "" && fields.BaseURLField != "" {
|
|
341
|
+
setBaseURLField(apiConfig, fields.BaseURLField, proto.String(baseURL))
|
|
342
|
+
includeBaseURL = true
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// Set model ID fields
|
|
346
|
+
apiConfig.PlanModeApiModelId = proto.String(modelID)
|
|
347
|
+
apiConfig.ActModeApiModelId = proto.String(modelID)
|
|
348
|
+
|
|
349
|
+
// Set provider-specific model ID fields if applicable
|
|
350
|
+
if fields.PlanModeProviderSpecificModelIDField != "" {
|
|
351
|
+
setProviderSpecificModelID(apiConfig, fields.PlanModeProviderSpecificModelIDField, proto.String(modelID))
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
// Set model info if applicable and provided
|
|
355
|
+
if fields.PlanModeModelInfoField != "" && modelInfo != nil {
|
|
356
|
+
if openRouterInfo, ok := modelInfo.(*cline.OpenRouterModelInfo); ok {
|
|
357
|
+
apiConfig.PlanModeOpenRouterModelInfo = openRouterInfo
|
|
358
|
+
apiConfig.ActModeOpenRouterModelInfo = openRouterInfo
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// Build field mask including all fields we're setting (without provider enums)
|
|
363
|
+
includeModelInfo := fields.PlanModeModelInfoField != "" && modelInfo != nil
|
|
364
|
+
fieldPaths := buildProviderFieldMask(fields, true, true, includeModelInfo, includeBaseURL, false)
|
|
365
|
+
|
|
366
|
+
// Create field mask
|
|
367
|
+
fieldMask := &fieldmaskpb.FieldMask{Paths: fieldPaths}
|
|
368
|
+
|
|
369
|
+
// Apply the partial update
|
|
370
|
+
request := &cline.UpdateApiConfigurationPartialRequest{
|
|
371
|
+
ApiConfiguration: apiConfig,
|
|
372
|
+
UpdateMask: fieldMask,
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
if err := updateApiConfigurationPartial(ctx, manager, request); err != nil {
|
|
376
|
+
return fmt.Errorf("failed to update API configuration: %w", err)
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
return nil
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// UpdateProviderPartial updates specific fields for an existing provider using partial updates.
|
|
383
|
+
// If setAsActive is true, this will also set the provider as the active provider for both Plan and Act modes.
|
|
384
|
+
func UpdateProviderPartial(ctx context.Context, manager *task.Manager, provider cline.ApiProvider, updates ProviderUpdatesPartial, setAsActive bool) error {
|
|
385
|
+
// Get field mapping for this provider
|
|
386
|
+
fields, err := GetProviderFields(provider)
|
|
387
|
+
if err != nil {
|
|
388
|
+
return err
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
// Build a ModelsApiConfiguration with only the fields being updated
|
|
392
|
+
apiConfig := &cline.ModelsApiConfiguration{}
|
|
393
|
+
|
|
394
|
+
// Set provider enum for BOTH Plan and Act modes if setAsActive is true
|
|
395
|
+
if setAsActive {
|
|
396
|
+
apiConfig.PlanModeApiProvider = &provider
|
|
397
|
+
apiConfig.ActModeApiProvider = &provider
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// Track what we're updating for field mask
|
|
401
|
+
includeAPIKey := updates.APIKey != nil
|
|
402
|
+
includeModelID := updates.ModelID != nil
|
|
403
|
+
includeModelInfo := updates.ModelInfo != nil && fields.PlanModeModelInfoField != ""
|
|
404
|
+
|
|
405
|
+
// Update API key if provided
|
|
406
|
+
if updates.APIKey != nil {
|
|
407
|
+
setAPIKeyField(apiConfig, fields.APIKeyField, updates.APIKey)
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
// Update model ID if provided
|
|
411
|
+
if updates.ModelID != nil {
|
|
412
|
+
// Only set provider-specific fields if they exist, otherwise use generic fields
|
|
413
|
+
if fields.PlanModeProviderSpecificModelIDField != "" {
|
|
414
|
+
setProviderSpecificModelID(apiConfig, fields.PlanModeProviderSpecificModelIDField, updates.ModelID)
|
|
415
|
+
} else {
|
|
416
|
+
// Provider uses generic fields - set those
|
|
417
|
+
apiConfig.PlanModeApiModelId = updates.ModelID
|
|
418
|
+
apiConfig.ActModeApiModelId = updates.ModelID
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
// Update model info if provided
|
|
423
|
+
if updates.ModelInfo != nil && fields.PlanModeModelInfoField != "" {
|
|
424
|
+
if openRouterInfo, ok := updates.ModelInfo.(*cline.OpenRouterModelInfo); ok {
|
|
425
|
+
apiConfig.PlanModeOpenRouterModelInfo = openRouterInfo
|
|
426
|
+
apiConfig.ActModeOpenRouterModelInfo = openRouterInfo
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
// Build field mask for only the fields being updated
|
|
431
|
+
fieldPaths := buildProviderFieldMask(fields, includeAPIKey, includeModelID, includeModelInfo, false, setAsActive)
|
|
432
|
+
|
|
433
|
+
// Create field mask
|
|
434
|
+
fieldMask := &fieldmaskpb.FieldMask{Paths: fieldPaths}
|
|
435
|
+
|
|
436
|
+
// Apply the partial update
|
|
437
|
+
request := &cline.UpdateApiConfigurationPartialRequest{
|
|
438
|
+
ApiConfiguration: apiConfig,
|
|
439
|
+
UpdateMask: fieldMask,
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
if err := updateApiConfigurationPartial(ctx, manager, request); err != nil {
|
|
443
|
+
return fmt.Errorf("failed to update API configuration: %w", err)
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
return nil
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
// RemoveProviderPartial removes a provider by clearing its API key using partial updates
|
|
450
|
+
func RemoveProviderPartial(ctx context.Context, manager *task.Manager, provider cline.ApiProvider) error {
|
|
451
|
+
// Get field mapping for this provider
|
|
452
|
+
fields, err := GetProviderFields(provider)
|
|
453
|
+
if err != nil {
|
|
454
|
+
return err
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
// Build an EMPTY ModelsApiConfiguration (or one with empty API key field)
|
|
458
|
+
// Fields in the mask without values will be cleared
|
|
459
|
+
apiConfig := &cline.ModelsApiConfiguration{}
|
|
460
|
+
|
|
461
|
+
// Build field mask with only the API key field(s)
|
|
462
|
+
// For Bedrock, include both access key and secret key
|
|
463
|
+
fieldPaths := []string{fields.APIKeyField}
|
|
464
|
+
if provider == cline.ApiProvider_BEDROCK {
|
|
465
|
+
fieldPaths = append(fieldPaths, "awsSecretKey")
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
// Create field mask
|
|
469
|
+
fieldMask := &fieldmaskpb.FieldMask{Paths: fieldPaths}
|
|
470
|
+
|
|
471
|
+
// Apply the partial update (clearing API key by including in mask without value)
|
|
472
|
+
request := &cline.UpdateApiConfigurationPartialRequest{
|
|
473
|
+
ApiConfiguration: apiConfig,
|
|
474
|
+
UpdateMask: fieldMask,
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
if err := updateApiConfigurationPartial(ctx, manager, request); err != nil {
|
|
478
|
+
return fmt.Errorf("failed to update API configuration: %w", err)
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
return nil
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
// setBaseURLField sets the appropriate base URL field in the config based on the field name
|
|
485
|
+
func setBaseURLField(apiConfig *cline.ModelsApiConfiguration, fieldName string, value *string) {
|
|
486
|
+
switch fieldName {
|
|
487
|
+
case "ocaBaseUrl":
|
|
488
|
+
apiConfig.OcaBaseUrl = value
|
|
489
|
+
case "ollamaBaseUrl":
|
|
490
|
+
apiConfig.OllamaBaseUrl = value
|
|
491
|
+
case "openAiBaseUrl":
|
|
492
|
+
apiConfig.OpenAiBaseUrl = value
|
|
493
|
+
case "geminiBaseUrl":
|
|
494
|
+
apiConfig.GeminiBaseUrl = value
|
|
495
|
+
case "liteLlmBaseUrl":
|
|
496
|
+
apiConfig.LiteLlmBaseUrl = value
|
|
497
|
+
case "anthropicBaseUrl":
|
|
498
|
+
apiConfig.AnthropicBaseUrl = value
|
|
499
|
+
case "requestyBaseUrl":
|
|
500
|
+
apiConfig.RequestyBaseUrl = value
|
|
501
|
+
case "lmStudioBaseUrl":
|
|
502
|
+
apiConfig.LmStudioBaseUrl = value
|
|
503
|
+
case "oca":
|
|
504
|
+
apiConfig.OcaBaseUrl = value
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
// setRefreshTokenField sets the appropriate refresh token field in the config
|
|
509
|
+
func setRefreshTokenField(apiConfig *cline.ModelsApiConfiguration, fieldName string, value *string) {
|
|
510
|
+
switch fieldName {
|
|
511
|
+
case "ocaRefreshToken":
|
|
512
|
+
apiConfig.OcaRefreshToken = value
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
// setModeField sets the appropriate mode field in the config
|
|
517
|
+
func setModeField(apiConfig *cline.ModelsApiConfiguration, fieldName string, value *string) {
|
|
518
|
+
switch fieldName {
|
|
519
|
+
case "ocaMode":
|
|
520
|
+
apiConfig.OcaMode = value
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
// BedrockOptionalFields holds optional configuration fields for AWS Bedrock
|
|
525
|
+
type BedrockOptionalFields struct {
|
|
526
|
+
SessionToken *string // Optional: AWS session token for temporary credentials
|
|
527
|
+
Region *string // Optional: AWS region
|
|
528
|
+
UseCrossRegionInference *bool // Optional: Enable cross-region inference
|
|
529
|
+
UseGlobalInference *bool // Optional: Use global inference endpoint
|
|
530
|
+
UsePromptCache *bool // Optional: Enable prompt caching
|
|
531
|
+
Authentication *string // Optional: Authentication method
|
|
532
|
+
UseProfile *bool // Optional: Use AWS profile
|
|
533
|
+
Profile *string // Optional: AWS profile name
|
|
534
|
+
Endpoint *string // Optional: Custom endpoint URL
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
// OcaOptionalFields holds optional configuration fields for Oracle Code Assist
|
|
538
|
+
type OcaOptionalFields struct {
|
|
539
|
+
BaseURL *string // Optional: Base URL
|
|
540
|
+
Mode *string // Optional: Mode ("internal" or "external")
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
// setBedrockOptionalFields sets optional Bedrock-specific fields in the API configuration
|
|
544
|
+
func setBedrockOptionalFields(apiConfig *cline.ModelsApiConfiguration, fields *BedrockOptionalFields) {
|
|
545
|
+
if fields == nil {
|
|
546
|
+
return
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
if fields.SessionToken != nil {
|
|
550
|
+
apiConfig.AwsSessionToken = fields.SessionToken
|
|
551
|
+
}
|
|
552
|
+
if fields.Region != nil {
|
|
553
|
+
apiConfig.AwsRegion = fields.Region
|
|
554
|
+
}
|
|
555
|
+
if fields.UseCrossRegionInference != nil {
|
|
556
|
+
apiConfig.AwsUseCrossRegionInference = fields.UseCrossRegionInference
|
|
557
|
+
}
|
|
558
|
+
if fields.UseGlobalInference != nil {
|
|
559
|
+
apiConfig.AwsUseGlobalInference = fields.UseGlobalInference
|
|
560
|
+
}
|
|
561
|
+
if fields.UsePromptCache != nil {
|
|
562
|
+
apiConfig.AwsBedrockUsePromptCache = fields.UsePromptCache
|
|
563
|
+
}
|
|
564
|
+
if fields.Authentication != nil {
|
|
565
|
+
apiConfig.AwsAuthentication = fields.Authentication
|
|
566
|
+
}
|
|
567
|
+
if fields.UseProfile != nil {
|
|
568
|
+
apiConfig.AwsUseProfile = fields.UseProfile
|
|
569
|
+
}
|
|
570
|
+
if fields.Profile != nil {
|
|
571
|
+
apiConfig.AwsProfile = fields.Profile
|
|
572
|
+
}
|
|
573
|
+
if fields.Endpoint != nil {
|
|
574
|
+
apiConfig.AwsBedrockEndpoint = fields.Endpoint
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
// setOcaOptionalFields sets optional Oca-specific fields in the API configuration
|
|
579
|
+
func setOcaOptionalFields(apiConfig *cline.ModelsApiConfiguration, fields *OcaOptionalFields) {
|
|
580
|
+
if fields == nil {
|
|
581
|
+
return
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
if fields.Mode != nil {
|
|
585
|
+
apiConfig.OcaMode = fields.Mode
|
|
586
|
+
}
|
|
587
|
+
if fields.BaseURL != nil {
|
|
588
|
+
apiConfig.OcaBaseUrl = fields.BaseURL
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
// buildBedrockOptionalFieldMask builds field mask paths for Bedrock optional fields that have values
|
|
593
|
+
func buildBedrockOptionalFieldMask(fields *BedrockOptionalFields) []string {
|
|
594
|
+
if fields == nil {
|
|
595
|
+
return nil
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
var fieldPaths []string
|
|
599
|
+
|
|
600
|
+
if fields.SessionToken != nil {
|
|
601
|
+
fieldPaths = append(fieldPaths, "awsSessionToken")
|
|
602
|
+
}
|
|
603
|
+
if fields.Region != nil {
|
|
604
|
+
fieldPaths = append(fieldPaths, "awsRegion")
|
|
605
|
+
}
|
|
606
|
+
if fields.UseCrossRegionInference != nil {
|
|
607
|
+
fieldPaths = append(fieldPaths, "awsUseCrossRegionInference")
|
|
608
|
+
}
|
|
609
|
+
if fields.UseGlobalInference != nil {
|
|
610
|
+
fieldPaths = append(fieldPaths, "awsUseGlobalInference")
|
|
611
|
+
}
|
|
612
|
+
if fields.UsePromptCache != nil {
|
|
613
|
+
fieldPaths = append(fieldPaths, "awsBedrockUsePromptCache")
|
|
614
|
+
}
|
|
615
|
+
if fields.Authentication != nil {
|
|
616
|
+
fieldPaths = append(fieldPaths, "awsAuthentication")
|
|
617
|
+
}
|
|
618
|
+
if fields.UseProfile != nil {
|
|
619
|
+
fieldPaths = append(fieldPaths, "awsUseProfile")
|
|
620
|
+
}
|
|
621
|
+
if fields.Profile != nil {
|
|
622
|
+
fieldPaths = append(fieldPaths, "awsProfile")
|
|
623
|
+
}
|
|
624
|
+
if fields.Endpoint != nil {
|
|
625
|
+
fieldPaths = append(fieldPaths, "awsBedrockEndpoint")
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
return fieldPaths
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
// buildOcaOptionalFieldMask builds field mask paths for Bedrock optional fields that have values
|
|
632
|
+
func buildOcaOptionalFieldMask(fields *OcaOptionalFields) []string {
|
|
633
|
+
if fields == nil {
|
|
634
|
+
return nil
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
var fieldPaths []string
|
|
638
|
+
|
|
639
|
+
if fields.Mode != nil {
|
|
640
|
+
fieldPaths = append(fieldPaths, "ocaMode")
|
|
641
|
+
}
|
|
642
|
+
if fields.BaseURL != nil {
|
|
643
|
+
fieldPaths = append(fieldPaths, "ocaBaseUrl")
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
return fieldPaths
|
|
647
|
+
}
|