mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-10-11 03:38:15 +00:00
Misc
This commit is contained in:
parent
3ac3240d42
commit
0cf0d2a389
3 changed files with 108 additions and 32 deletions
|
|
@ -1,11 +1,15 @@
|
|||
import { Anthropic } from "@anthropic-ai/sdk"
|
||||
import OpenAI from "openai"
|
||||
import * as fsSync from "fs"
|
||||
import * as pathSync from "path"
|
||||
import * as osSync from "os"
|
||||
|
||||
import {
|
||||
type ModelInfo,
|
||||
openAiNativeDefaultModelId,
|
||||
OpenAiNativeModelId,
|
||||
getOpenAiNativeModels,
|
||||
openAiNativeModels,
|
||||
validateModelInfoRecord,
|
||||
OPENAI_NATIVE_DEFAULT_TEMPERATURE,
|
||||
GPT5_DEFAULT_TEMPERATURE,
|
||||
type ReasoningEffort,
|
||||
|
|
@ -31,6 +35,50 @@ export type OpenAiNativeModel = ReturnType<OpenAiNativeHandler["getModel"]>
|
|||
// Constants for model identification
|
||||
const GPT5_MODEL_PREFIX = "gpt-5"
|
||||
|
||||
/**
|
||||
* Host-only sync loader for OpenAI Native models merged with ~/.roo overrides.
|
||||
* Avoids the browser-safe loader in @roo-code/types which may not resolve extras in the extension host bundle.
|
||||
*/
|
||||
function loadMergedOpenAiNativeModelsOnHostSync(): Record<string, ModelInfo> {
|
||||
try {
|
||||
// 1) Inline JSON override
|
||||
let extras: Record<string, ModelInfo> = {}
|
||||
try {
|
||||
const inline = process.env?.ROO_OPENAI_NATIVE_MODELS_JSON
|
||||
if (inline) {
|
||||
const parsed = JSON.parse(inline)
|
||||
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
||||
extras = validateModelInfoRecord(parsed)
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
|
||||
// 2) File-based load when no inline provided
|
||||
if (Object.keys(extras).length === 0) {
|
||||
try {
|
||||
const customPath =
|
||||
process.env.ROO_OPENAI_NATIVE_MODELS_PATH ||
|
||||
pathSync.join(osSync.homedir(), ".roo", "models", "openai-native.json")
|
||||
if (customPath && fsSync.existsSync(customPath)) {
|
||||
const raw = fsSync.readFileSync(customPath, "utf8")
|
||||
const parsed = JSON.parse(raw)
|
||||
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
||||
extras = validateModelInfoRecord(parsed)
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
// ignore file errors
|
||||
}
|
||||
}
|
||||
|
||||
return { ...openAiNativeModels, ...extras } as Record<string, ModelInfo>
|
||||
} catch {
|
||||
return openAiNativeModels as Record<string, ModelInfo>
|
||||
}
|
||||
}
|
||||
|
||||
export class OpenAiNativeHandler extends BaseProvider implements SingleCompletionHandler {
|
||||
protected options: ApiHandlerOptions
|
||||
private client: OpenAI
|
||||
|
|
@ -1222,7 +1270,7 @@ export class OpenAiNativeHandler extends BaseProvider implements SingleCompletio
|
|||
const modelId = this.options.apiModelId
|
||||
|
||||
// Get merged models (built-in + user-defined from ~/.roo/models/openai-native.json)
|
||||
const allModels = getOpenAiNativeModels()
|
||||
const allModels = loadMergedOpenAiNativeModelsOnHostSync()
|
||||
|
||||
let id = modelId && modelId in allModels ? (modelId as OpenAiNativeModelId) : openAiNativeDefaultModelId
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,6 @@ import {
|
|||
ORGANIZATION_ALLOW_ALL,
|
||||
DEFAULT_MODES,
|
||||
DEFAULT_CHECKPOINT_TIMEOUT_SECONDS,
|
||||
getModelId,
|
||||
} from "@roo-code/types"
|
||||
import { TelemetryService } from "@roo-code/telemetry"
|
||||
import { CloudService, BridgeOrchestrator, getRooCodeApiUrl } from "@roo-code/cloud"
|
||||
|
|
@ -1296,31 +1295,6 @@ export class ClineProvider
|
|||
|
||||
// Provider Profile Management
|
||||
|
||||
/**
|
||||
* Updates the current task's API handler if the provider or model has changed.
|
||||
* This prevents unnecessary context condensing when only non-model settings change.
|
||||
* @param providerSettings The new provider settings to apply
|
||||
*/
|
||||
private updateTaskApiHandlerIfNeeded(providerSettings: ProviderSettings): void {
|
||||
const task = this.getCurrentTask()
|
||||
|
||||
if (task && task.apiConfiguration) {
|
||||
// Only rebuild API handler if provider or model actually changed
|
||||
// to avoid triggering unnecessary context condensing
|
||||
const currentProvider = task.apiConfiguration.apiProvider
|
||||
const newProvider = providerSettings.apiProvider
|
||||
const currentModelId = getModelId(task.apiConfiguration)
|
||||
const newModelId = getModelId(providerSettings)
|
||||
|
||||
if (currentProvider !== newProvider || currentModelId !== newModelId) {
|
||||
task.api = buildApiHandler(providerSettings)
|
||||
}
|
||||
} else if (task) {
|
||||
// Fallback: rebuild if apiConfiguration is not available
|
||||
task.api = buildApiHandler(providerSettings)
|
||||
}
|
||||
}
|
||||
|
||||
getProviderProfileEntries(): ProviderSettingsEntry[] {
|
||||
return this.contextProxy.getValues().listApiConfigMeta || []
|
||||
}
|
||||
|
|
@ -1368,7 +1342,11 @@ export class ClineProvider
|
|||
|
||||
// Change the provider for the current task.
|
||||
// TODO: We should rename `buildApiHandler` for clarity (e.g. `getProviderClient`).
|
||||
this.updateTaskApiHandlerIfNeeded(providerSettings)
|
||||
const task = this.getCurrentTask()
|
||||
|
||||
if (task) {
|
||||
task.api = buildApiHandler(providerSettings)
|
||||
}
|
||||
} else {
|
||||
await this.updateGlobalState("listApiConfigMeta", await this.providerSettingsManager.listConfig())
|
||||
}
|
||||
|
|
@ -1425,7 +1403,11 @@ export class ClineProvider
|
|||
}
|
||||
|
||||
// Change the provider for the current task.
|
||||
this.updateTaskApiHandlerIfNeeded(providerSettings)
|
||||
const task = this.getCurrentTask()
|
||||
|
||||
if (task) {
|
||||
task.api = buildApiHandler(providerSettings)
|
||||
}
|
||||
|
||||
await this.postStateToWebview()
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import {
|
|||
type ClineMessage,
|
||||
type TelemetrySetting,
|
||||
type ModelInfo,
|
||||
getOpenAiNativeModels,
|
||||
validateModelInfoRecord,
|
||||
TelemetryEventName,
|
||||
UserSettingsConfig,
|
||||
DEFAULT_CHECKPOINT_TIMEOUT_SECONDS,
|
||||
|
|
@ -55,6 +55,7 @@ import { getWorkspacePath } from "../../utils/path"
|
|||
import { Mode, defaultModeSlug } from "../../shared/modes"
|
||||
import { getModels, flushModels } from "../../api/providers/fetchers/modelCache"
|
||||
import { GetModelsOptions } from "../../shared/api"
|
||||
import { openAiNativeModels } from "@roo-code/types"
|
||||
import { generateSystemPrompt } from "./generateSystemPrompt"
|
||||
import { getCommand } from "../../utils/commands"
|
||||
|
||||
|
|
@ -99,6 +100,51 @@ export const webviewMessageHandler = async (
|
|||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Host-only loader: merge built-in OpenAI native models with user additions from:
|
||||
* - ROO_OPENAI_NATIVE_MODELS_JSON (JSON string)
|
||||
* - ROO_OPENAI_NATIVE_MODELS_PATH or ~/.roo/models/openai-native.json
|
||||
* Returns the merged models record.
|
||||
*/
|
||||
async function getMergedOpenAiNativeModelsOnHost(): Promise<Record<string, ModelInfo>> {
|
||||
try {
|
||||
// 1) Env JSON override
|
||||
let extras: Record<string, any> = {}
|
||||
const inline = process.env?.ROO_OPENAI_NATIVE_MODELS_JSON
|
||||
if (inline) {
|
||||
try {
|
||||
const parsed = JSON.parse(inline)
|
||||
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
||||
extras = validateModelInfoRecord(parsed)
|
||||
}
|
||||
} catch {
|
||||
// ignore malformed env json
|
||||
}
|
||||
}
|
||||
|
||||
// 2) File-based
|
||||
if (Object.keys(extras).length === 0) {
|
||||
const customPath =
|
||||
process.env.ROO_OPENAI_NATIVE_MODELS_PATH ||
|
||||
path.join(os.homedir(), ".roo", "models", "openai-native.json")
|
||||
try {
|
||||
const raw = await fs.readFile(customPath, "utf8")
|
||||
const parsed = JSON.parse(raw)
|
||||
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
||||
extras = validateModelInfoRecord(parsed)
|
||||
}
|
||||
} catch {
|
||||
// missing/invalid file: ignore
|
||||
}
|
||||
}
|
||||
|
||||
const merged = { ...openAiNativeModels, ...extras }
|
||||
return merged as Record<string, ModelInfo>
|
||||
} catch {
|
||||
return openAiNativeModels as Record<string, ModelInfo>
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the target message and all subsequent messages
|
||||
*/
|
||||
|
|
@ -985,7 +1031,7 @@ export const webviewMessageHandler = async (
|
|||
case "requestOpenAiNativeModels": {
|
||||
// Return merged built-ins + user-defined from ~/.roo/models/openai-native.json
|
||||
try {
|
||||
const mergedModels = getOpenAiNativeModels()
|
||||
const mergedModels = await getMergedOpenAiNativeModelsOnHost()
|
||||
provider.postMessageToWebview({ type: "openAiNativeModels", openAiNativeModels: mergedModels })
|
||||
} catch (error) {
|
||||
console.error("Failed to load OpenAI Native models:", error)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue