mirror of
https://github.com/pacnpal/Roo-Code.git
synced 2025-12-20 12:21:13 -05:00
Adds unbound provider to roo cline
This commit is contained in:
committed by
Vignesh Subbiah
parent
db0ec64d1c
commit
62dcfbe549
@@ -14,6 +14,7 @@ import { DeepSeekHandler } from "./providers/deepseek"
|
||||
import { MistralHandler } from "./providers/mistral"
|
||||
import { VsCodeLmHandler } from "./providers/vscode-lm"
|
||||
import { ApiStream } from "./transform/stream"
|
||||
import { UnboundHandler } from "./providers/unbound"
|
||||
|
||||
export interface SingleCompletionHandler {
|
||||
completePrompt(prompt: string): Promise<string>
|
||||
@@ -53,6 +54,8 @@ export function buildApiHandler(configuration: ApiConfiguration): ApiHandler {
|
||||
return new VsCodeLmHandler(options)
|
||||
case "mistral":
|
||||
return new MistralHandler(options)
|
||||
case "unbound":
|
||||
return new UnboundHandler(options)
|
||||
default:
|
||||
return new AnthropicHandler(options)
|
||||
}
|
||||
|
||||
59
src/api/providers/unbound.ts
Normal file
59
src/api/providers/unbound.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
import { ApiHandlerOptions, unboundModels, UnboundModelId, unboundDefaultModelId, ModelInfo } from "../../shared/api"
|
||||
import { ApiStream } from "../transform/stream"
|
||||
import { Anthropic } from "@anthropic-ai/sdk"
|
||||
import { ApiHandler } from "../index"
|
||||
|
||||
export class UnboundHandler implements ApiHandler {
|
||||
private unboundApiKey: string
|
||||
private unboundModelId: string
|
||||
private unboundBaseUrl: string = "https://ai-gateway-43843357113.us-west1.run.app/v1"
|
||||
private options: ApiHandlerOptions
|
||||
|
||||
constructor(options: ApiHandlerOptions) {
|
||||
this.options = options
|
||||
this.unboundApiKey = options.unboundApiKey || ""
|
||||
this.unboundModelId = options.unboundModelId || ""
|
||||
}
|
||||
|
||||
async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream {
|
||||
const response = await fetch(`${this.unboundBaseUrl}/chat/completions`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${this.unboundApiKey}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
model: this.unboundModelId,
|
||||
messages: [{ role: "system", content: systemPrompt }, ...messages],
|
||||
}),
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`)
|
||||
}
|
||||
|
||||
const data = await response.json()
|
||||
|
||||
yield {
|
||||
type: "text",
|
||||
text: data.choices[0]?.message?.content || "",
|
||||
}
|
||||
yield {
|
||||
type: "usage",
|
||||
inputTokens: data.usage?.prompt_tokens || 0,
|
||||
outputTokens: data.usage?.completion_tokens || 0,
|
||||
}
|
||||
}
|
||||
|
||||
getModel(): { id: UnboundModelId; info: ModelInfo } {
|
||||
const modelId = this.options.apiModelId
|
||||
if (modelId && modelId in unboundModels) {
|
||||
const id = modelId as UnboundModelId
|
||||
return { id, info: unboundModels[id] }
|
||||
}
|
||||
return {
|
||||
id: unboundDefaultModelId,
|
||||
info: unboundModels[unboundDefaultModelId],
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -62,6 +62,7 @@ type SecretKey =
|
||||
| "openAiNativeApiKey"
|
||||
| "deepSeekApiKey"
|
||||
| "mistralApiKey"
|
||||
| "unboundApiKey"
|
||||
type GlobalStateKey =
|
||||
| "apiProvider"
|
||||
| "apiModelId"
|
||||
@@ -120,6 +121,7 @@ type GlobalStateKey =
|
||||
| "experimentalDiffStrategy"
|
||||
| "autoApprovalEnabled"
|
||||
| "customModes" // Array of custom modes
|
||||
| "unboundModelId"
|
||||
|
||||
export const GlobalFileNames = {
|
||||
apiConversationHistory: "api_conversation_history.json",
|
||||
@@ -1309,6 +1311,8 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
openRouterUseMiddleOutTransform,
|
||||
vsCodeLmModelSelector,
|
||||
mistralApiKey,
|
||||
unboundApiKey,
|
||||
unboundModelId,
|
||||
} = apiConfiguration
|
||||
await this.updateGlobalState("apiProvider", apiProvider)
|
||||
await this.updateGlobalState("apiModelId", apiModelId)
|
||||
@@ -1347,6 +1351,8 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
await this.updateGlobalState("openRouterUseMiddleOutTransform", openRouterUseMiddleOutTransform)
|
||||
await this.updateGlobalState("vsCodeLmModelSelector", vsCodeLmModelSelector)
|
||||
await this.storeSecret("mistralApiKey", mistralApiKey)
|
||||
await this.storeSecret("unboundApiKey", unboundApiKey)
|
||||
await this.updateGlobalState("unboundModelId", unboundModelId)
|
||||
if (this.cline) {
|
||||
this.cline.api = buildApiHandler(apiConfiguration)
|
||||
}
|
||||
@@ -2001,6 +2007,8 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
experimentalDiffStrategy,
|
||||
autoApprovalEnabled,
|
||||
customModes,
|
||||
unboundApiKey,
|
||||
unboundModelId,
|
||||
] = await Promise.all([
|
||||
this.getGlobalState("apiProvider") as Promise<ApiProvider | undefined>,
|
||||
this.getGlobalState("apiModelId") as Promise<string | undefined>,
|
||||
@@ -2070,6 +2078,8 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
this.getGlobalState("experimentalDiffStrategy") as Promise<boolean | undefined>,
|
||||
this.getGlobalState("autoApprovalEnabled") as Promise<boolean | undefined>,
|
||||
this.customModesManager.getCustomModes(),
|
||||
this.getSecret("unboundApiKey") as Promise<string | undefined>,
|
||||
this.getGlobalState("unboundModelId") as Promise<string | undefined>,
|
||||
])
|
||||
|
||||
let apiProvider: ApiProvider
|
||||
@@ -2125,6 +2135,8 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
openRouterBaseUrl,
|
||||
openRouterUseMiddleOutTransform,
|
||||
vsCodeLmModelSelector,
|
||||
unboundApiKey,
|
||||
unboundModelId,
|
||||
},
|
||||
lastShownAnnouncementId,
|
||||
customInstructions,
|
||||
@@ -2273,6 +2285,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
"openAiNativeApiKey",
|
||||
"deepSeekApiKey",
|
||||
"mistralApiKey",
|
||||
"unboundApiKey",
|
||||
]
|
||||
for (const key of secretKeys) {
|
||||
await this.storeSecret(key, undefined)
|
||||
|
||||
@@ -14,6 +14,7 @@ export type ApiProvider =
|
||||
| "deepseek"
|
||||
| "vscode-lm"
|
||||
| "mistral"
|
||||
| "unbound"
|
||||
|
||||
export interface ApiHandlerOptions {
|
||||
apiModelId?: string
|
||||
@@ -57,6 +58,8 @@ export interface ApiHandlerOptions {
|
||||
deepSeekBaseUrl?: string
|
||||
deepSeekApiKey?: string
|
||||
includeMaxTokens?: boolean
|
||||
unboundApiKey?: string
|
||||
unboundModelId?: string
|
||||
}
|
||||
|
||||
export type ApiConfiguration = ApiHandlerOptions & {
|
||||
@@ -593,3 +596,11 @@ export const mistralModels = {
|
||||
outputPrice: 0.9,
|
||||
},
|
||||
} as const satisfies Record<string, ModelInfo>
|
||||
|
||||
// Unbound Security
|
||||
export type UnboundModelId = keyof typeof unboundModels
|
||||
export const unboundDefaultModelId = "gpt-4o"
|
||||
export const unboundModels = {
|
||||
"gpt-4o": openAiNativeModels["gpt-4o"],
|
||||
"claude-3-5-sonnet-20241022": anthropicModels["claude-3-5-sonnet-20241022"],
|
||||
} as const satisfies Record<string, ModelInfo>
|
||||
|
||||
Reference in New Issue
Block a user