Compare commits

...
Author SHA1 Message Date
abeatrix a3003f6f19 clean up 2025-09-22 12:10:41 -07:00
abeatrix a6c3239166 npm run fix:all
> claude-dev@3.30.3 fix:all
> biome check --no-errors-on-unmatched --files-ignore-unknown=true --write --diagnostic-level=error --unsafe

Checked 873 files in 2s. Fixed 551 files.
2025-09-22 12:09:01 -07:00
abeatrix b40dd722da dev(biome): enable useImportType and additional style linting rules
Enable useNodejsImportProtocol, useImportType, and useTemplate as info level warnings, and upgrade noUselessElse to warn level to improve code quality and consistency
2025-09-22 12:08:43 -07:00
552 changed files with 2009 additions and 1944 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
import path from "node:path"
import { defineConfig } from "@vscode/test-cli"
import path from "path"
export default defineConfig({
files: "{out/**/*.test.js,src/**/*.test.js,!src/test/e2e/**/*.test.js,!out/src/test/e2e/**/*.test.js}",
+4 -4
View File
@@ -42,8 +42,8 @@
},
"a11y": "off",
"style": {
"useNodejsImportProtocol": "off",
"useImportType": "off",
"useNodejsImportProtocol": "info",
"useImportType": "info",
"useBlockStatements": "warn",
"useNamingConvention": "off",
"useThrowOnlyError": "info",
@@ -57,8 +57,8 @@
"useSingleVarDeclarator": "off",
"useNumberNamespace": "off",
"noInferrableTypes": "off",
"useTemplate": "off",
"noUselessElse": "off"
"useTemplate": "info",
"noUselessElse": "warn"
},
"suspicious": {
"noDoubleEquals": "warn",
+5 -5
View File
@@ -1,12 +1,12 @@
#!/usr/bin/env node
import { execSync } from "node:child_process"
import * as fs from "node:fs/promises"
import { createRequire } from "node:module"
import os from "node:os"
import * as path from "node:path"
import chalk from "chalk"
import { execSync } from "child_process"
import * as fs from "fs/promises"
import { globby } from "globby"
import { createRequire } from "module"
import os from "os"
import * as path from "path"
import { rmrf } from "./file-utils.mjs"
import { main as generateHostBridgeClient } from "./generate-host-bridge-client.mjs"
import { main as generateProtoBusSetup } from "./generate-protobus-setup.mjs"
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env node
const { execSync } = require("child_process")
const { execSync } = require("node:child_process")
const esbuild = require("esbuild")
const watch = process.argv.includes("--watch")
+2 -2
View File
@@ -1,5 +1,5 @@
import * as fs from "fs/promises"
import * as path from "path"
import * as fs from "node:fs/promises"
import * as path from "node:path"
/**
* Write `contents` to `filePath`, creating any necessary directories in `filePath`.
*/
+5 -7
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env node
import * as path from "node:path"
import chalk from "chalk"
import * as path from "path"
import { writeFileWithMkdirs } from "./file-utils.mjs"
import { getFqn, loadServicesFromProtoDescriptor } from "./proto-utils.mjs"
@@ -125,9 +125,9 @@ function generateExternalClientSetup(serviceName, serviceDefinition) {
return ` ${methodName}(request: ${requestType}): Promise<${responseType}> {
return this.makeRequest((client) => client.${methodName}(request))
}`
} else {
// Generate streaming method
return ` ${methodName}(
}
// Generate streaming method
return ` ${methodName}(
request: ${requestType},
callbacks: StreamingCallbacks<${responseType}>,
): () => void {
@@ -150,7 +150,6 @@ function generateExternalClientSetup(serviceName, serviceDefinition) {
abortController.abort()
}
}\n`
}
})
.join("\n")
@@ -222,9 +221,8 @@ function generateVscodeClientImplementation(serviceName, serviceDefinition) {
const isStreamingResponse = methodDef.responseStream
if (!isStreamingResponse) {
return `${name}ServiceRegistry.registerMethod("${methodName}", ${methodName})`
} else {
return `${name}ServiceRegistry.registerMethod("${methodName}", ${methodName}, { isStreaming: true })`
}
return `${name}ServiceRegistry.registerMethod("${methodName}", ${methodName}, { isStreaming: true })`
})
.join("\n")
+4 -4
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env node
import path from "path"
import { fileURLToPath } from "url"
import path from "node:path"
import { fileURLToPath } from "node:url"
import { writeFileWithMkdirs } from "./file-utils.mjs"
import { getFqn, loadServicesFromProtoDescriptor } from "./proto-utils.mjs"
@@ -157,8 +157,8 @@ async function generateStandaloneProtobusServiceSetup(protobusServices) {
handlerSetup.push(` server.addService(cline.${name}Service, {`)
for (const [rpcName, rpc] of Object.entries(def.service)) {
imports.push(`import { ${rpcName} } from "@core/controller/${dir}/${rpcName}"`)
const requestType = "cline." + rpc.requestType.type.name
const responseType = "cline." + rpc.responseType.type.name
const requestType = `cline.${rpc.requestType.type.name}`
const responseType = `cline.${rpc.responseType.type.name}`
if (rpc.requestStream) {
throw new Error("Request streaming is not supported")
}
+2 -2
View File
@@ -1,5 +1,5 @@
const fs = require("fs")
const path = require("path")
const fs = require("node:fs")
const path = require("node:path")
const { Project, SyntaxKind } = require("ts-morph")
function traverse(container, output, prefix = "") {
+3 -3
View File
@@ -27,10 +27,10 @@
* 5. Close the VS Code window or press Ctrl+C to end the session and trigger cleanup.
*/
import { mkdtempSync } from "node:fs"
import os from "node:os"
import path from "node:path"
import { downloadAndUnzipVSCode, SilentReporter } from "@vscode/test-electron"
import { mkdtempSync } from "fs"
import os from "os"
import path from "path"
import { _electron } from "playwright"
import { ClineApiServerMock } from "../src/test/e2e/fixtures/server"
import { E2ETestHelper } from "../src/test/e2e/utils/helpers"
+5 -5
View File
@@ -1,13 +1,13 @@
#!/usr/bin/env node
import { execSync } from "node:child_process"
import fs from "node:fs"
import { cp } from "node:fs/promises"
import os from "node:os"
import path from "node:path"
import archiver from "archiver"
import { execSync } from "child_process"
import fs from "fs"
import { cp } from "fs/promises"
import { glob } from "glob"
import minimatch from "minimatch"
import os from "os"
import path from "path"
import { rmrf } from "./file-utils.mjs"
const BUILD_DIR = "dist-standalone"
+2 -2
View File
@@ -1,9 +1,9 @@
#!/usr/bin/env node
import * as fs from "node:fs/promises"
import * as path from "node:path"
import * as grpc from "@grpc/grpc-js"
import * as protoLoader from "@grpc/proto-loader"
import * as fs from "fs/promises"
import * as path from "path"
const DESCRIPTOR_SET = path.resolve("dist-standalone/proto/descriptor_set.pb")
+3 -3
View File
@@ -1,6 +1,6 @@
const { execSync } = require("child_process")
const readline = require("readline")
const os = require("os")
const { execSync } = require("node:child_process")
const readline = require("node:readline")
const os = require("node:os")
const rl = readline.createInterface({
input: process.stdin,
+2 -2
View File
@@ -1,6 +1,6 @@
#!/usr/bin/env node
const { execSync } = require("child_process")
const process = require("process")
const { execSync } = require("node:child_process")
const process = require("node:process")
try {
if (process.platform === "linux") {
+3 -3
View File
@@ -1,8 +1,8 @@
#!/usr/bin/env npx tsx
import * as os from "node:os"
import * as grpc from "@grpc/grpc-js"
import { ReflectionService } from "@grpc/reflection"
import * as health from "grpc-health-check"
import * as os from "os"
import { type DiffServiceServer, DiffServiceService } from "../src/generated/grpc-js/host/diff"
import { type EnvServiceServer, EnvServiceService } from "../src/generated/grpc-js/host/env"
import { type TestingServiceServer, TestingServiceService } from "../src/generated/grpc-js/host/testing"
@@ -70,7 +70,7 @@ function createMockService<T extends grpc.UntypedServiceImplementation>(serviceN
case "getMachineId":
callback(null, {
value: "fake-machine-id-" + os.hostname(),
value: `fake-machine-id-${os.hostname()}`,
})
return
@@ -102,7 +102,7 @@ function createMockService<T extends grpc.UntypedServiceImplementation>(serviceN
case "openDiff":
callback(null, {
diff_id: "fake-diff-" + Date.now(),
diff_id: `fake-diff-${Date.now()}`,
})
return
+5 -3
View File
@@ -28,11 +28,11 @@
* Ideal for local development, testing, or lightweight E2E scenarios.
*/
import { type ChildProcess, execSync, spawn } from "node:child_process"
import * as fs from "node:fs"
import { mkdtempSync, rmSync } from "node:fs"
import * as os from "node:os"
import { ChildProcess, execSync, spawn } from "child_process"
import * as path from "path"
import * as path from "node:path"
import { ClineApiServerMock } from "../src/test/e2e/fixtures/server/index"
const PROTOBUS_PORT = process.env.PROTOBUS_PORT || "26040"
@@ -134,7 +134,9 @@ async function main(): Promise<void> {
while (childProcesses.length > 0) {
const child = childProcesses.pop()
if (child && !child.killed) child.kill("SIGINT")
if (child && !child.killed) {
child.kill("SIGINT")
}
}
await ClineApiServerMock.stopGlobalServer()
+22 -10
View File
@@ -21,11 +21,11 @@
* SERVER_BOOT_DELAY Server startup delay in ms (default: 1300)
*/
import { ChildProcess, spawn } from "child_process"
import fs from "fs"
import { type ChildProcess, spawn } from "node:child_process"
import fs from "node:fs"
import net from "node:net"
import path from "node:path"
import minimist from "minimist"
import net from "net"
import path from "path"
import kill from "tree-kill"
let showServerLogs = false
@@ -75,10 +75,14 @@ async function startServer(): Promise<{ server: ChildProcess; grpcPort: string }
function stopServer(server: ChildProcess): Promise<void> {
return new Promise((resolve) => {
if (!server.pid) return resolve()
if (!server.pid) {
return resolve()
}
kill(server.pid, "SIGKILL", (err) => {
if (err) console.warn("Failed to kill server process:", err)
if (err) {
console.warn("Failed to kill server process:", err)
}
server.once("exit", () => resolve())
})
})
@@ -114,7 +118,9 @@ async function runSpec(specFile: string): Promise<void> {
function collectSpecFiles(inputPath: string): string[] {
const fullPath = path.resolve(inputPath)
if (!fs.existsSync(fullPath)) throw new Error(`Path does not exist: ${fullPath}`)
if (!fs.existsSync(fullPath)) {
throw new Error(`Path does not exist: ${fullPath}`)
}
const stat = fs.statSync(fullPath)
if (stat.isDirectory()) {
@@ -123,7 +129,9 @@ function collectSpecFiles(inputPath: string): string[] {
.filter((f) => f.endsWith(".json"))
.map((f) => path.join(fullPath, f))
}
if (fullPath.endsWith(".json")) return [fullPath]
if (fullPath.endsWith(".json")) {
return [fullPath]
}
throw new Error("Spec path must be a JSON file or a folder containing JSON files")
}
@@ -150,11 +158,15 @@ async function runAll(inputPath: string, count: number) {
}
}
if (failure > 0) process.exitCode = 1
if (failure > 0) {
process.exitCode = 1
}
}
console.log(`✅ Passed: ${success}`)
if (failure > 0) console.log(`❌ Failed: ${failure}`)
if (failure > 0) {
console.log(`❌ Failed: ${failure}`)
}
console.log(`📋 Total specs: ${specFiles.length} Total runs: ${specFiles.length * count}`)
console.log(`🏁 All runs completed in ${((Date.now() - totalStart) / 1000).toFixed(2)}s`)
}
+5 -6
View File
@@ -1,7 +1,7 @@
import { Anthropic } from "@anthropic-ai/sdk"
import { ModelInfo } from "@shared/api"
import { ApiHandler } from "../../core/api/index"
import { ApiStream } from "../../core/api/transform/stream"
import type { Anthropic } from "@anthropic-ai/sdk"
import type { ModelInfo } from "@shared/api"
import type { ApiHandler } from "../../core/api/index"
import type { ApiStream } from "../../core/api/transform/stream"
interface DifyHandlerOptions {
difyApiKey?: string
@@ -9,7 +9,6 @@ interface DifyHandlerOptions {
}
export class DifyHandler implements ApiHandler {
private options: DifyHandlerOptions
private baseUrl: string
private apiKey: string
private conversationId: string | null = null
@@ -241,7 +240,7 @@ export class DifyHandler implements ApiHandler {
console.error("[DIFY DEBUG] Direct JSON Error event:", parsed)
throw new Error(`Dify API error: ${parsed.message || "Unknown error"}`)
}
} catch (e) {
} catch (_e) {
// Not JSON, continue
console.log("[DIFY DEBUG] Line is not direct JSON, continuing")
}
+1 -1
View File
@@ -1,4 +1,4 @@
import * as vscode from "vscode"
import type * as vscode from "vscode"
import {
migrateCustomInstructionsToGlobalRules,
migrateTaskHistoryToFile,
+4 -4
View File
@@ -1,6 +1,6 @@
import { Anthropic } from "@anthropic-ai/sdk"
import { ApiConfiguration, ModelInfo, QwenApiRegions } from "@shared/api"
import { Mode } from "@shared/storage/types"
import type { Anthropic } from "@anthropic-ai/sdk"
import { type ApiConfiguration, type ModelInfo, QwenApiRegions } from "@shared/api"
import type { Mode } from "@shared/storage/types"
import { AnthropicHandler } from "./providers/anthropic"
import { AskSageHandler } from "./providers/asksage"
import { BasetenHandler } from "./providers/baseten"
@@ -37,7 +37,7 @@ import { VertexHandler } from "./providers/vertex"
import { VsCodeLmHandler } from "./providers/vscode-lm"
import { XAIHandler } from "./providers/xai"
import { ZAiHandler } from "./providers/zai"
import { ApiStream, ApiStreamUsageChunk } from "./transform/stream"
import type { ApiStream, ApiStreamUsageChunk } from "./transform/stream"
export type CommonApiHandlerOptions = {
onRetryAttempt?: ApiConfiguration["onRetryAttempt"]
@@ -1,6 +1,6 @@
import "should"
import { Readable } from "node:stream"
import { ConverseStreamCommand } from "@aws-sdk/client-bedrock-runtime"
import { Readable } from "stream"
import type { AwsBedrockHandlerOptions } from "../bedrock"
import { AwsBedrockHandler } from "../bedrock"
@@ -1,4 +1,4 @@
import { Anthropic } from "@anthropic-ai/sdk"
import type { Anthropic } from "@anthropic-ai/sdk"
import { afterEach, beforeEach, describe, it } from "mocha"
import sinon from "sinon"
import "should"
@@ -1,4 +1,4 @@
import Anthropic from "@anthropic-ai/sdk"
import type Anthropic from "@anthropic-ai/sdk"
import { LiteLlmHandler, type LiteLlmModelInfoResponse } from "@core/api/providers/litellm"
import { convertToOpenAiMessages } from "@core/api/transform/openai-format"
import { expect } from "chai"
@@ -1,7 +1,7 @@
import { afterEach, before, beforeEach, describe, it } from "mocha"
import "should"
import { Anthropic } from "@anthropic-ai/sdk"
import { ApiHandlerOptions } from "@shared/api"
import type { Anthropic } from "@anthropic-ai/sdk"
import type { ApiHandlerOptions } from "@shared/api"
import axios from "axios"
import sinon from "sinon"
import { OllamaHandler } from "../ollama"
@@ -1,5 +1,5 @@
import "should"
import { Anthropic } from "@anthropic-ai/sdk"
import type { Anthropic } from "@anthropic-ai/sdk"
import { SapAiCoreHandler } from "../sapaicore"
describe("SapAiCoreHandler", () => {
+11 -6
View File
@@ -1,9 +1,15 @@
import { Anthropic } from "@anthropic-ai/sdk"
import { Stream as AnthropicStream } from "@anthropic-ai/sdk/streaming"
import { AnthropicModelId, anthropicDefaultModelId, anthropicModels, CLAUDE_SONNET_4_1M_SUFFIX, ModelInfo } from "@shared/api"
import { ApiHandler, CommonApiHandlerOptions } from "../index"
import type { Stream as AnthropicStream } from "@anthropic-ai/sdk/streaming"
import {
type AnthropicModelId,
anthropicDefaultModelId,
anthropicModels,
CLAUDE_SONNET_4_1M_SUFFIX,
type ModelInfo,
} from "@shared/api"
import type { ApiHandler, CommonApiHandlerOptions } from "../index"
import { withRetry } from "../retry"
import { ApiStream } from "../transform/stream"
import type { ApiStream } from "../transform/stream"
interface AnthropicHandlerOptions extends CommonApiHandlerOptions {
apiKey?: string
@@ -128,9 +134,8 @@ export class AnthropicHandler implements ApiHandler {
"anthropic-beta": "context-1m-2025-08-07",
},
}
} else {
return undefined
}
return undefined
})(),
)
break
+4 -4
View File
@@ -1,8 +1,8 @@
import { Anthropic } from "@anthropic-ai/sdk"
import { AskSageModelId, askSageDefaultModelId, askSageDefaultURL, askSageModels, ModelInfo } from "@shared/api"
import { ApiHandler, CommonApiHandlerOptions } from ".."
import type { Anthropic } from "@anthropic-ai/sdk"
import { type AskSageModelId, askSageDefaultModelId, askSageDefaultURL, askSageModels, type ModelInfo } from "@shared/api"
import type { ApiHandler, CommonApiHandlerOptions } from ".."
import { withRetry } from "../retry"
import { ApiStream } from "../transform/stream"
import type { ApiStream } from "../transform/stream"
interface AskSageHandlerOptions extends CommonApiHandlerOptions {
asksageApiKey?: string
+4 -4
View File
@@ -1,11 +1,11 @@
import { Anthropic } from "@anthropic-ai/sdk"
import { BasetenModelId, basetenDefaultModelId, basetenModels, ModelInfo } from "@shared/api"
import type { Anthropic } from "@anthropic-ai/sdk"
import { type BasetenModelId, basetenDefaultModelId, basetenModels, type ModelInfo } from "@shared/api"
import { calculateApiCostOpenAI } from "@utils/cost"
import OpenAI from "openai"
import { ApiHandler, CommonApiHandlerOptions } from "../"
import type { ApiHandler, CommonApiHandlerOptions } from "../"
import { withRetry } from "../retry"
import { convertToOpenAiMessages } from "../transform/openai-format"
import { ApiStream } from "../transform/stream"
import type { ApiStream } from "../transform/stream"
interface BasetenHandlerOptions extends CommonApiHandlerOptions {
basetenApiKey?: string
+5 -5
View File
@@ -1,4 +1,4 @@
import { Anthropic } from "@anthropic-ai/sdk"
import type { Anthropic } from "@anthropic-ai/sdk"
// Import proper AWS SDK types
import type { ContentBlock, Message } from "@aws-sdk/client-bedrock-runtime"
import {
@@ -9,12 +9,12 @@ import {
InvokeModelWithResponseStreamCommand,
} from "@aws-sdk/client-bedrock-runtime"
import { fromNodeProviderChain } from "@aws-sdk/credential-providers"
import { BedrockModelId, bedrockDefaultModelId, bedrockModels, CLAUDE_SONNET_4_1M_SUFFIX, ModelInfo } from "@shared/api"
import { type BedrockModelId, bedrockDefaultModelId, bedrockModels, CLAUDE_SONNET_4_1M_SUFFIX, type ModelInfo } from "@shared/api"
import { calculateApiCostOpenAI } from "@utils/cost"
import { ApiHandler, CommonApiHandlerOptions } from "../"
import type { ApiHandler, CommonApiHandlerOptions } from "../"
import { withRetry } from "../retry"
import { convertToR1Format } from "../transform/r1-format"
import { ApiStream } from "../transform/stream"
import type { ApiStream } from "../transform/stream"
export interface AwsBedrockHandlerOptions extends CommonApiHandlerOptions {
apiModelId?: string
@@ -479,7 +479,7 @@ export class AwsBedrockHandler implements ApiHandler {
}
}
combinedContent += message.role === "user" ? "User: " + content + "\n" : "Assistant: " + content + "\n"
combinedContent += message.role === "user" ? `User: ${content}\n` : `Assistant: ${content}\n`
}
// Format according to DeepSeek R1's expected prompt format
+14 -9
View File
@@ -1,9 +1,9 @@
import { Anthropic } from "@anthropic-ai/sdk"
import type { Anthropic } from "@anthropic-ai/sdk"
import Cerebras from "@cerebras/cerebras_cloud_sdk"
import { CerebrasModelId, cerebrasDefaultModelId, cerebrasModels, ModelInfo } from "@shared/api"
import { ApiHandler, CommonApiHandlerOptions } from "../index"
import { type CerebrasModelId, cerebrasDefaultModelId, cerebrasModels, type ModelInfo } from "@shared/api"
import type { ApiHandler, CommonApiHandlerOptions } from "../index"
import { withRetry } from "../retry"
import { ApiStream } from "../transform/stream"
import type { ApiStream } from "../transform/stream"
interface CerebrasHandlerOptions extends CommonApiHandlerOptions {
cerebrasApiKey?: string
@@ -70,7 +70,8 @@ export class CerebrasHandler implements ApiHandler {
.map((block) => {
if (block.type === "text") {
return block.text
} else if (block.type === "image") {
}
if (block.type === "image") {
return "[Image content not supported in Cerebras]"
}
return ""
@@ -180,14 +181,18 @@ export class CerebrasHandler implements ApiHandler {
// Rate limit error - will be handled by retry decorator with patient backoff
const _limits = this.getRateLimits()
throw new Error(`Cerebras API rate limit exceeded.`)
} else if (error?.status === 401) {
}
if (error?.status === 401) {
throw new Error("Cerebras API authentication failed. Please check your API key.")
} else if (error?.status === 403) {
}
if (error?.status === 403) {
throw new Error("Cerebras API access denied. Please check your API key permissions.")
} else if (error?.status >= 500) {
}
if (error?.status >= 500) {
// Server errors - retryable
throw new Error(`Cerebras API server error (${error.status}): ${error.message || "Unknown server error"}`)
} else if (error?.status === 400) {
}
if (error?.status === 400) {
// Client errors - not retryable
throw new Error(`Cerebras API bad request: ${error.message || "Invalid request parameters"}`)
}
+3 -3
View File
@@ -1,10 +1,10 @@
import type { Anthropic } from "@anthropic-ai/sdk"
import { filterMessagesForClaudeCode } from "@/integrations/claude-code/message-filter"
import { runClaudeCode } from "@/integrations/claude-code/run"
import { ClaudeCodeModelId, claudeCodeDefaultModelId, claudeCodeModels } from "@/shared/api"
import { type ApiHandler, CommonApiHandlerOptions } from ".."
import { type ClaudeCodeModelId, claudeCodeDefaultModelId, claudeCodeModels } from "@/shared/api"
import type { ApiHandler, CommonApiHandlerOptions } from ".."
import { withRetry } from "../retry"
import { type ApiStream, ApiStreamUsageChunk } from "../transform/stream"
import type { ApiStream, ApiStreamUsageChunk } from "../transform/stream"
interface ClaudeCodeHandlerOptions extends CommonApiHandlerOptions {
claudeCodePath?: string
+6 -9
View File
@@ -1,5 +1,5 @@
import { Anthropic } from "@anthropic-ai/sdk"
import { ModelInfo, openRouterDefaultModelId, openRouterDefaultModelInfo } from "@shared/api"
import type { Anthropic } from "@anthropic-ai/sdk"
import { type ModelInfo, openRouterDefaultModelId, openRouterDefaultModelInfo } from "@shared/api"
import { shouldSkipReasoningForModel } from "@utils/model-utils"
import axios from "axios"
import OpenAI from "openai"
@@ -8,11 +8,11 @@ import { ClineAccountService } from "@/services/account/ClineAccountService"
import { AuthService } from "@/services/auth/AuthService"
import { CLINE_ACCOUNT_AUTH_ERROR_MESSAGE } from "@/shared/ClineAccount"
import { version as extensionVersion } from "../../../../package.json"
import { ApiHandler, CommonApiHandlerOptions } from "../"
import type { ApiHandler, CommonApiHandlerOptions } from "../"
import { withRetry } from "../retry"
import { createOpenRouterStream } from "../transform/openrouter-stream"
import { ApiStream, ApiStreamUsageChunk } from "../transform/stream"
import { OpenRouterErrorResponse } from "./types"
import type { ApiStream, ApiStreamUsageChunk } from "../transform/stream"
import type { OpenRouterErrorResponse } from "./types"
interface ClineHandlerOptions extends CommonApiHandlerOptions {
ulid?: string
@@ -133,11 +133,8 @@ export class ClineHandler implements ApiHandler {
const error = choiceWithError.error
console.error(`Cline Mid-Stream Error: ${error.code || error.type || "Unknown"} - ${error.message}`)
throw new Error(`Cline Mid-Stream Error: ${error.code || error.type || "Unknown"} - ${error.message}`)
} else {
throw new Error(
"Cline Mid-Stream Error: Stream terminated with error status but no error details provided",
)
}
throw new Error("Cline Mid-Stream Error: Stream terminated with error status but no error details provided")
}
const delta = choice?.delta
+4 -4
View File
@@ -1,12 +1,12 @@
import { Anthropic } from "@anthropic-ai/sdk"
import { DeepSeekModelId, deepSeekDefaultModelId, deepSeekModels, ModelInfo } from "@shared/api"
import type { Anthropic } from "@anthropic-ai/sdk"
import { type DeepSeekModelId, deepSeekDefaultModelId, deepSeekModels, type ModelInfo } from "@shared/api"
import { calculateApiCostOpenAI } from "@utils/cost"
import OpenAI from "openai"
import { ApiHandler, CommonApiHandlerOptions } from "../"
import type { ApiHandler, CommonApiHandlerOptions } from "../"
import { withRetry } from "../retry"
import { convertToOpenAiMessages } from "../transform/openai-format"
import { convertToR1Format } from "../transform/r1-format"
import { ApiStream } from "../transform/stream"
import type { ApiStream } from "../transform/stream"
interface DeepSeekHandlerOptions extends CommonApiHandlerOptions {
deepSeekApiKey?: string
+5 -10
View File
@@ -1,7 +1,7 @@
import { Anthropic } from "@anthropic-ai/sdk"
import { ModelInfo } from "../../../shared/api"
import { ApiHandler } from "../index"
import { ApiStream } from "../transform/stream"
import type { Anthropic } from "@anthropic-ai/sdk"
import type { ModelInfo } from "../../../shared/api"
import type { ApiHandler } from "../index"
import type { ApiStream } from "../transform/stream"
interface DifyHandlerOptions {
difyApiKey?: string
@@ -71,15 +71,11 @@ interface DifyConversationResponse {
}
export class DifyHandler implements ApiHandler {
private options: DifyHandlerOptions
private baseUrl: string
private apiKey: string
private conversationId: string | null = null
private currentTaskId: string | null = null
private abortController: AbortController | null = null
constructor(options: DifyHandlerOptions) {
this.options = options
this.apiKey = options.difyApiKey || ""
this.baseUrl = options.difyBaseUrl || ""
@@ -341,7 +337,7 @@ export class DifyHandler implements ApiHandler {
}
hasYieldedContent = true
}
} catch (e) {
} catch (_e) {
// Not JSON, continue
console.log("[DIFY DEBUG] Line is not direct JSON, continuing")
}
@@ -655,6 +651,5 @@ export class DifyHandler implements ApiHandler {
*/
resetConversation(): void {
this.conversationId = null
this.currentTaskId = null
}
}
+4 -4
View File
@@ -1,10 +1,10 @@
import { Anthropic } from "@anthropic-ai/sdk"
import { DoubaoModelId, doubaoDefaultModelId, doubaoModels, ModelInfo } from "@shared/api"
import type { Anthropic } from "@anthropic-ai/sdk"
import { type DoubaoModelId, doubaoDefaultModelId, doubaoModels, type ModelInfo } from "@shared/api"
import OpenAI from "openai"
import { ApiHandler, CommonApiHandlerOptions } from ".."
import type { ApiHandler, CommonApiHandlerOptions } from ".."
import { withRetry } from "../retry"
import { convertToOpenAiMessages } from "../transform/openai-format"
import { ApiStream } from "../transform/stream"
import type { ApiStream } from "../transform/stream"
interface DoubaoHandlerOptions extends CommonApiHandlerOptions {
doubaoApiKey?: string
+4 -4
View File
@@ -1,10 +1,10 @@
import { Anthropic } from "@anthropic-ai/sdk"
import { FireworksModelId, fireworksDefaultModelId, fireworksModels, ModelInfo } from "@shared/api"
import type { Anthropic } from "@anthropic-ai/sdk"
import { type FireworksModelId, fireworksDefaultModelId, fireworksModels, type ModelInfo } from "@shared/api"
import OpenAI from "openai"
import { ApiHandler, CommonApiHandlerOptions } from ".."
import type { ApiHandler, CommonApiHandlerOptions } from ".."
import { withRetry } from "../retry"
import { convertToOpenAiMessages } from "../transform/openai-format"
import { ApiStream } from "../transform/stream"
import type { ApiStream } from "../transform/stream"
interface FireworksHandlerOptions extends CommonApiHandlerOptions {
fireworksApiKey?: string
+17 -8
View File
@@ -1,12 +1,18 @@
import type { Anthropic } from "@anthropic-ai/sdk"
// Restore GenerateContentConfig import and add GenerateContentResponseUsageMetadata
import { ApiError, type GenerateContentConfig, type GenerateContentResponseUsageMetadata, GoogleGenAI, Part } from "@google/genai"
import { GeminiModelId, geminiDefaultModelId, geminiModels, ModelInfo } from "@shared/api"
import {
ApiError,
type GenerateContentConfig,
type GenerateContentResponseUsageMetadata,
GoogleGenAI,
type Part,
} from "@google/genai"
import { type GeminiModelId, geminiDefaultModelId, geminiModels, type ModelInfo } from "@shared/api"
import { telemetryService } from "@/services/telemetry"
import { ApiHandler, CommonApiHandlerOptions } from "../"
import type { ApiHandler, CommonApiHandlerOptions } from "../"
import { RetriableError, withRetry } from "../retry"
import { convertAnthropicMessageToGemini } from "../transform/gemini-format"
import { ApiStream } from "../transform/stream"
import type { ApiStream } from "../transform/stream"
// Define a default TTL for the cache (e.g., 15 minutes in seconds)
const _DEFAULT_CACHE_TTL_SECONDS = 900
@@ -169,7 +175,7 @@ export class GeminiHandler implements ApiHandler {
if (thought && text) {
// Ensure part.text exists
// Handle the thought part
thoughts += text + "\n" // Append thought and a newline
thoughts += `${text}\n` // Append thought and a newline
}
}
}
@@ -423,7 +429,8 @@ export class GeminiHandler implements ApiHandler {
const totalChars = content.reduce((total, block) => {
if (typeof block === "string") {
return total + block.length
} else if (block && typeof block === "object") {
}
if (block && typeof block === "object") {
// Safely stringify the object
try {
const jsonStr = JSON.stringify(block)
@@ -453,9 +460,11 @@ export class GeminiHandler implements ApiHandler {
if (unit === "s") {
return value
} else if (unit === "m") {
}
if (unit === "m") {
return value * 60 // Convert minutes to seconds
} else if (unit === "h") {
}
if (unit === "h") {
return value * 60 * 60 // Convert hours to seconds
}
+4 -4
View File
@@ -1,11 +1,11 @@
import { Anthropic } from "@anthropic-ai/sdk"
import { GroqModelId, groqDefaultModelId, groqModels, ModelInfo } from "@shared/api"
import type { Anthropic } from "@anthropic-ai/sdk"
import { type GroqModelId, groqDefaultModelId, groqModels, type ModelInfo } from "@shared/api"
import { calculateApiCostOpenAI } from "@utils/cost"
import OpenAI from "openai"
import { ApiHandler, CommonApiHandlerOptions } from "../"
import type { ApiHandler, CommonApiHandlerOptions } from "../"
import { withRetry } from "../retry"
import { convertToOpenAiMessages } from "../transform/openai-format"
import { ApiStream } from "../transform/stream"
import type { ApiStream } from "../transform/stream"
interface GroqHandlerOptions extends CommonApiHandlerOptions {
groqApiKey?: string
+4 -4
View File
@@ -1,10 +1,10 @@
import { Anthropic } from "@anthropic-ai/sdk"
import { HuaweiCloudMaasModelId, huaweiCloudMaasDefaultModelId, huaweiCloudMaasModels, ModelInfo } from "@shared/api"
import type { Anthropic } from "@anthropic-ai/sdk"
import { type HuaweiCloudMaasModelId, huaweiCloudMaasDefaultModelId, huaweiCloudMaasModels, type ModelInfo } from "@shared/api"
import OpenAI from "openai"
import { ApiHandler, CommonApiHandlerOptions } from ".."
import type { ApiHandler, CommonApiHandlerOptions } from ".."
import { withRetry } from "../retry"
import { convertToOpenAiMessages } from "../transform/openai-format"
import { ApiStream } from "../transform/stream"
import type { ApiStream } from "../transform/stream"
interface HuaweiCloudMaaSHandlerOptions extends CommonApiHandlerOptions {
huaweiCloudMaasApiKey?: string
+4 -4
View File
@@ -1,11 +1,11 @@
import { Anthropic } from "@anthropic-ai/sdk"
import { HuggingFaceModelId, huggingFaceDefaultModelId, huggingFaceModels, ModelInfo } from "@shared/api"
import type { Anthropic } from "@anthropic-ai/sdk"
import { type HuggingFaceModelId, huggingFaceDefaultModelId, huggingFaceModels, type ModelInfo } from "@shared/api"
import { calculateApiCostOpenAI } from "@utils/cost"
import OpenAI from "openai"
import { ApiHandler, CommonApiHandlerOptions } from "../"
import type { ApiHandler, CommonApiHandlerOptions } from "../"
import { withRetry } from "../retry"
import { convertToOpenAiMessages } from "../transform/openai-format"
import { ApiStream } from "../transform/stream"
import type { ApiStream } from "../transform/stream"
interface HuggingFaceHandlerOptions extends CommonApiHandlerOptions {
huggingFaceApiKey?: string
+24 -25
View File
@@ -1,11 +1,11 @@
import { Anthropic } from "@anthropic-ai/sdk"
import { LiteLLMModelInfo, liteLlmDefaultModelId, liteLlmModelInfoSaneDefaults } from "@shared/api"
import type { Anthropic } from "@anthropic-ai/sdk"
import { type LiteLLMModelInfo, liteLlmDefaultModelId, liteLlmModelInfoSaneDefaults } from "@shared/api"
import OpenAI from "openai"
import { isAnthropicModelId } from "@/utils/model-utils"
import { ApiHandler, CommonApiHandlerOptions } from ".."
import type { ApiHandler, CommonApiHandlerOptions } from ".."
import { withRetry } from "../retry"
import { convertToOpenAiMessages } from "../transform/openai-format"
import { ApiStream } from "../transform/stream"
import type { ApiStream } from "../transform/stream"
interface LiteLlmHandlerOptions extends CommonApiHandlerOptions {
liteLlmApiKey?: string
@@ -99,27 +99,25 @@ export class LiteLlmHandler implements ApiHandler {
this.modelInfoCache = data
this.modelInfoCacheTimestamp = now
return data
} else {
console.warn("Failed to fetch LiteLLM model info:", response.statusText)
// Try with Authorization header instead
const retryResponse = await fetch(url, {
method: "GET",
headers: {
accept: "application/json",
Authorization: `Bearer ${this.options.liteLlmApiKey || ""}`,
},
})
if (retryResponse.ok) {
const data: LiteLlmModelInfoResponse = await retryResponse.json()
this.modelInfoCache = data
this.modelInfoCacheTimestamp = now
return data
} else {
console.warn("Failed to fetch LiteLLM model info with Authorization header:", retryResponse.statusText)
return undefined
}
}
console.warn("Failed to fetch LiteLLM model info:", response.statusText)
// Try with Authorization header instead
const retryResponse = await fetch(url, {
method: "GET",
headers: {
accept: "application/json",
Authorization: `Bearer ${this.options.liteLlmApiKey || ""}`,
},
})
if (retryResponse.ok) {
const data: LiteLlmModelInfoResponse = await retryResponse.json()
this.modelInfoCache = data
this.modelInfoCacheTimestamp = now
return data
}
console.warn("Failed to fetch LiteLLM model info with Authorization header:", retryResponse.statusText)
return undefined
} catch (error) {
console.warn("Error fetching LiteLLM model info:", error)
return undefined
@@ -245,7 +243,8 @@ export class LiteLlmHandler implements ApiHandler {
},
] as any,
}
} else if (Array.isArray(message.content)) {
}
if (Array.isArray(message.content)) {
// Apply cache control to the last content item in the array
return {
...message,
+4 -4
View File
@@ -1,10 +1,10 @@
import { Anthropic } from "@anthropic-ai/sdk"
import type { Anthropic } from "@anthropic-ai/sdk"
import { Mistral } from "@mistralai/mistralai"
import { MistralModelId, ModelInfo, mistralDefaultModelId, mistralModels } from "@shared/api"
import { ApiHandler, CommonApiHandlerOptions } from "../"
import { type MistralModelId, type ModelInfo, mistralDefaultModelId, mistralModels } from "@shared/api"
import type { ApiHandler, CommonApiHandlerOptions } from "../"
import { withRetry } from "../retry"
import { convertToMistralMessages } from "../transform/mistral-format"
import { ApiStream } from "../transform/stream"
import type { ApiStream } from "../transform/stream"
interface MistralHandlerOptions extends CommonApiHandlerOptions {
mistralApiKey?: string
+4 -4
View File
@@ -1,10 +1,10 @@
import { Anthropic } from "@anthropic-ai/sdk"
import type { Anthropic } from "@anthropic-ai/sdk"
import OpenAI from "openai"
import { ModelInfo, MoonshotModelId, moonshotDefaultModelId, moonshotModels } from "@/shared/api"
import { ApiHandler, CommonApiHandlerOptions } from "../index"
import { type ModelInfo, type MoonshotModelId, moonshotDefaultModelId, moonshotModels } from "@/shared/api"
import type { ApiHandler, CommonApiHandlerOptions } from "../index"
import { withRetry } from "../retry"
import { convertToOpenAiMessages } from "../transform/openai-format"
import { ApiStream } from "../transform/stream"
import type { ApiStream } from "../transform/stream"
interface MoonshotHandlerOptions extends CommonApiHandlerOptions {
moonshotApiKey?: string
+3 -3
View File
@@ -1,11 +1,11 @@
import { Anthropic } from "@anthropic-ai/sdk"
import type { Anthropic } from "@anthropic-ai/sdk"
import { type ModelInfo, type NebiusModelId, nebiusDefaultModelId, nebiusModels } from "@shared/api"
import OpenAI from "openai"
import { ApiHandler, CommonApiHandlerOptions } from "../index"
import type { ApiHandler, CommonApiHandlerOptions } from "../index"
import { withRetry } from "../retry"
import { convertToOpenAiMessages } from "../transform/openai-format"
import { convertToR1Format } from "../transform/r1-format"
import { ApiStream } from "../transform/stream"
import type { ApiStream } from "../transform/stream"
interface NebiusHandlerOptions extends CommonApiHandlerOptions {
nebiusApiKey?: string
+8 -9
View File
@@ -1,15 +1,15 @@
import { Anthropic } from "@anthropic-ai/sdk"
import { LiteLLMModelInfo, liteLlmDefaultModelId, liteLlmModelInfoSaneDefaults } from "@shared/api"
import OpenAI, { APIError, OpenAIError } from "openai"
import type { Anthropic } from "@anthropic-ai/sdk"
import { type LiteLLMModelInfo, liteLlmDefaultModelId, liteLlmModelInfoSaneDefaults } from "@shared/api"
import OpenAI, { type APIError, OpenAIError } from "openai"
import type { FinalRequestOptions, Headers as OpenAIHeaders } from "openai/core"
import { OcaAuthService } from "@/services/auth/oca/OcaAuthService"
import { DEFAULT_OCA_BASE_URL, OCI_HEADER_OPC_REQUEST_ID } from "@/services/auth/oca/utils/constants"
import { createOcaHeaders } from "@/services/auth/oca/utils/utils"
import { Logger } from "@/services/logging/Logger"
import { ApiHandler, type CommonApiHandlerOptions } from ".."
import type { ApiHandler, CommonApiHandlerOptions } from ".."
import { withRetry } from "../retry"
import { convertToOpenAiMessages } from "../transform/openai-format"
import { ApiStream } from "../transform/stream"
import type { ApiStream } from "../transform/stream"
export interface OcaHandlerOptions extends CommonApiHandlerOptions {
ocaBaseUrl?: string
@@ -117,10 +117,9 @@ export class OcaHandler implements ApiHandler {
if (response.ok) {
const data: { cost: number } = await response.json()
return data.cost
} else {
console.error("Error calculating spend:", response.statusText)
return undefined
}
console.error("Error calculating spend:", response.statusText)
return undefined
} catch (error) {
console.error("Error calculating spend:", error)
return undefined
@@ -140,7 +139,7 @@ export class OcaHandler implements ApiHandler {
// Configuration for extended thinking
const budgetTokens = this.options.thinkingBudgetTokens || 0
const reasoningOn = budgetTokens !== 0 ? true : false
const reasoningOn = budgetTokens !== 0
const thinkingConfig = reasoningOn ? { type: "enabled", budget_tokens: budgetTokens } : undefined
let temperature: number | undefined = this.options.ocaModelInfo?.temperature ?? 0
+4 -4
View File
@@ -1,12 +1,12 @@
import { Anthropic } from "@anthropic-ai/sdk"
import { ModelInfo, OpenAiNativeModelId, openAiNativeDefaultModelId, openAiNativeModels } from "@shared/api"
import type { Anthropic } from "@anthropic-ai/sdk"
import { type ModelInfo, type OpenAiNativeModelId, openAiNativeDefaultModelId, openAiNativeModels } from "@shared/api"
import { calculateApiCostOpenAI } from "@utils/cost"
import OpenAI from "openai"
import type { ChatCompletionReasoningEffort } from "openai/resources/chat/completions"
import { ApiHandler, CommonApiHandlerOptions } from "../"
import type { ApiHandler, CommonApiHandlerOptions } from "../"
import { withRetry } from "../retry"
import { convertToOpenAiMessages } from "../transform/openai-format"
import { ApiStream } from "../transform/stream"
import type { ApiStream } from "../transform/stream"
interface OpenAiNativeHandlerOptions extends CommonApiHandlerOptions {
openAiNativeApiKey?: string
+9 -4
View File
@@ -1,12 +1,17 @@
import { Anthropic } from "@anthropic-ai/sdk"
import { azureOpenAiDefaultApiVersion, ModelInfo, OpenAiCompatibleModelInfo, openAiModelInfoSaneDefaults } from "@shared/api"
import type { Anthropic } from "@anthropic-ai/sdk"
import {
azureOpenAiDefaultApiVersion,
type ModelInfo,
type OpenAiCompatibleModelInfo,
openAiModelInfoSaneDefaults,
} from "@shared/api"
import OpenAI, { AzureOpenAI } from "openai"
import type { ChatCompletionReasoningEffort } from "openai/resources/chat/completions"
import { ApiHandler, CommonApiHandlerOptions } from "../index"
import type { ApiHandler, CommonApiHandlerOptions } from "../index"
import { withRetry } from "../retry"
import { convertToOpenAiMessages } from "../transform/openai-format"
import { convertToR1Format } from "../transform/r1-format"
import { ApiStream } from "../transform/stream"
import type { ApiStream } from "../transform/stream"
interface OpenAiHandlerOptions extends CommonApiHandlerOptions {
openAiApiKey?: string
+7 -10
View File
@@ -1,14 +1,14 @@
import { setTimeout as setTimeoutPromise } from "node:timers/promises"
import { Anthropic } from "@anthropic-ai/sdk"
import { ModelInfo, openRouterDefaultModelId, openRouterDefaultModelInfo } from "@shared/api"
import type { Anthropic } from "@anthropic-ai/sdk"
import { type ModelInfo, openRouterDefaultModelId, openRouterDefaultModelInfo } from "@shared/api"
import { shouldSkipReasoningForModel } from "@utils/model-utils"
import axios from "axios"
import OpenAI from "openai"
import { ApiHandler, CommonApiHandlerOptions } from "../"
import type { ApiHandler, CommonApiHandlerOptions } from "../"
import { withRetry } from "../retry"
import { createOpenRouterStream } from "../transform/openrouter-stream"
import { ApiStream, ApiStreamUsageChunk } from "../transform/stream"
import { OpenRouterErrorResponse } from "./types"
import type { ApiStream, ApiStreamUsageChunk } from "../transform/stream"
import type { OpenRouterErrorResponse } from "./types"
interface OpenRouterHandlerOptions extends CommonApiHandlerOptions {
openRouterApiKey?: string
@@ -92,12 +92,9 @@ export class OpenRouterHandler implements ApiHandler {
// Format error details
const errorDetails = typeof error === "object" ? JSON.stringify(error, null, 2) : String(error)
throw new Error(`OpenRouter Mid-Stream Error: ${errorDetails}`)
} else {
// Fallback if error details are not available
throw new Error(
`OpenRouter Mid-Stream Error: Stream terminated with error status but no error details provided`,
)
}
// Fallback if error details are not available
throw new Error(`OpenRouter Mid-Stream Error: Stream terminated with error status but no error details provided`)
}
if (!this.lastGenerationId && chunk.id) {
+7 -8
View File
@@ -1,13 +1,13 @@
import { promises as fs } from "node:fs"
import { Anthropic } from "@anthropic-ai/sdk"
import { ModelInfo, QwenCodeModelId, qwenCodeDefaultModelId, qwenCodeModels } from "@shared/api"
import * as os from "node:os"
import * as path from "node:path"
import type { Anthropic } from "@anthropic-ai/sdk"
import { type ModelInfo, type QwenCodeModelId, qwenCodeDefaultModelId, qwenCodeModels } from "@shared/api"
import OpenAI from "openai"
import * as os from "os"
import * as path from "path"
import { ApiHandler, CommonApiHandlerOptions } from "../"
import type { ApiHandler, CommonApiHandlerOptions } from "../"
import { withRetry } from "../retry"
import { convertToOpenAiMessages } from "../transform/openai-format"
import { ApiStream } from "../transform/stream"
import type { ApiStream } from "../transform/stream"
// --- Constants for Qwen OAuth2 ---
const QWEN_OAUTH_BASE_URL = "https://chat.qwen.ai"
@@ -167,9 +167,8 @@ export class QwenCodeHandler implements ApiHandler {
client.apiKey = this.credentials.access_token
client.baseURL = this.getBaseUrl(this.credentials)
return await apiCall()
} else {
throw error
}
throw error
}
}
+12 -13
View File
@@ -1,20 +1,20 @@
import { Anthropic } from "@anthropic-ai/sdk"
import type { Anthropic } from "@anthropic-ai/sdk"
import {
InternationalQwenModelId,
type InternationalQwenModelId,
internationalQwenDefaultModelId,
internationalQwenModels,
MainlandQwenModelId,
ModelInfo,
type MainlandQwenModelId,
type ModelInfo,
mainlandQwenDefaultModelId,
mainlandQwenModels,
QwenApiRegions,
} from "@shared/api"
import OpenAI from "openai"
import { ApiHandler, CommonApiHandlerOptions } from "../"
import type { ApiHandler, CommonApiHandlerOptions } from "../"
import { withRetry } from "../retry"
import { convertToOpenAiMessages } from "../transform/openai-format"
import { convertToR1Format } from "../transform/r1-format"
import { ApiStream } from "../transform/stream"
import type { ApiStream } from "../transform/stream"
interface QwenHandlerOptions extends CommonApiHandlerOptions {
qwenApiKey?: string
@@ -66,13 +66,12 @@ export class QwenHandler implements ApiHandler {
id: (modelId as MainlandQwenModelId) ?? mainlandQwenDefaultModelId,
info: mainlandQwenModels[modelId as MainlandQwenModelId] ?? mainlandQwenModels[mainlandQwenDefaultModelId],
}
} else {
return {
id: (modelId as InternationalQwenModelId) ?? internationalQwenDefaultModelId,
info:
internationalQwenModels[modelId as InternationalQwenModelId] ??
internationalQwenModels[internationalQwenDefaultModelId],
}
}
return {
id: (modelId as InternationalQwenModelId) ?? internationalQwenDefaultModelId,
info:
internationalQwenModels[modelId as InternationalQwenModelId] ??
internationalQwenModels[internationalQwenDefaultModelId],
}
}
+4 -4
View File
@@ -1,12 +1,12 @@
import { Anthropic } from "@anthropic-ai/sdk"
import { ModelInfo, requestyDefaultModelId, requestyDefaultModelInfo } from "@shared/api"
import type { Anthropic } from "@anthropic-ai/sdk"
import { type ModelInfo, requestyDefaultModelId, requestyDefaultModelInfo } from "@shared/api"
import { calculateApiCostOpenAI } from "@utils/cost"
import OpenAI from "openai"
import { toRequestyServiceStringUrl } from "@/shared/providers/requesty"
import { ApiHandler, CommonApiHandlerOptions } from "../index"
import type { ApiHandler, CommonApiHandlerOptions } from "../index"
import { withRetry } from "../retry"
import { convertToOpenAiMessages } from "../transform/openai-format"
import { ApiStream } from "../transform/stream"
import type { ApiStream } from "../transform/stream"
interface RequestyHandlerOptions extends CommonApiHandlerOptions {
requestyBaseUrl?: string
+4 -4
View File
@@ -1,11 +1,11 @@
import { Anthropic } from "@anthropic-ai/sdk"
import { ModelInfo, SambanovaModelId, sambanovaDefaultModelId, sambanovaModels } from "@shared/api"
import type { Anthropic } from "@anthropic-ai/sdk"
import { type ModelInfo, type SambanovaModelId, sambanovaDefaultModelId, sambanovaModels } from "@shared/api"
import OpenAI from "openai"
import { ApiHandler, CommonApiHandlerOptions } from "../index"
import type { ApiHandler, CommonApiHandlerOptions } from "../index"
import { withRetry } from "../retry"
import { convertToOpenAiMessages } from "../transform/openai-format"
import { convertToR1Format } from "../transform/r1-format"
import { ApiStream } from "../transform/stream"
import type { ApiStream } from "../transform/stream"
interface SambanovaHandlerOptions extends CommonApiHandlerOptions {
sambanovaApiKey?: string
+14 -9
View File
@@ -1,16 +1,21 @@
import { Anthropic } from "@anthropic-ai/sdk"
import type { Anthropic } from "@anthropic-ai/sdk"
import {
type ContentBlock as BedrockContentBlock,
ConversationRole as BedrockConversationRole,
type Message as BedrockMessage,
} from "@aws-sdk/client-bedrock-runtime"
import { ChatMessages, LlmModuleConfig, OrchestrationClient, TemplatingModuleConfig } from "@sap-ai-sdk/orchestration"
import { ModelInfo, SapAiCoreModelId, sapAiCoreDefaultModelId, sapAiCoreModels } from "@shared/api"
import {
type ChatMessages,
type LlmModuleConfig,
OrchestrationClient,
type TemplatingModuleConfig,
} from "@sap-ai-sdk/orchestration"
import { type ModelInfo, type SapAiCoreModelId, sapAiCoreDefaultModelId, sapAiCoreModels } from "@shared/api"
import axios from "axios"
import OpenAI from "openai"
import { ApiHandler, CommonApiHandlerOptions } from "../"
import type OpenAI from "openai"
import type { ApiHandler, CommonApiHandlerOptions } from "../"
import { convertToOpenAiMessages } from "../transform/openai-format"
import { ApiStream } from "../transform/stream"
import type { ApiStream } from "../transform/stream"
interface SapAiCoreHandlerOptions extends CommonApiHandlerOptions {
sapAiCoreClientId?: string
@@ -244,7 +249,7 @@ namespace Gemini {
for (const part of partsForThoughts) {
const { thought, text } = part
if (thought && text) {
thoughts += text + "\n"
thoughts += `${text}\n`
}
}
}
@@ -380,7 +385,7 @@ export class SapAiCoreHandler implements ApiHandler {
client_secret: this.options.sapAiCoreClientSecret,
}
const tokenUrl = this.options.sapAiCoreTokenUrl!.replace(/\/+$/, "") + "/oauth/token"
const tokenUrl = `${this.options.sapAiCoreTokenUrl!.replace(/\/+$/, "")}/oauth/token`
const response = await axios.post(tokenUrl, payload, {
headers: { "Content-Type": "application/x-www-form-urlencoded" },
})
@@ -802,7 +807,7 @@ export class SapAiCoreHandler implements ApiHandler {
): AsyncGenerator<any, void, unknown> {
function toStrictJson(str: string): string {
// Wrap it in parentheses so JS will treat it as an expression
const obj = new Function("return " + str)()
const obj = new Function(`return ${str}`)()
return JSON.stringify(obj)
}
+4 -4
View File
@@ -1,11 +1,11 @@
import { Anthropic } from "@anthropic-ai/sdk"
import { ModelInfo, openAiModelInfoSaneDefaults } from "@shared/api"
import type { Anthropic } from "@anthropic-ai/sdk"
import { type ModelInfo, openAiModelInfoSaneDefaults } from "@shared/api"
import OpenAI from "openai"
import { ApiHandler, CommonApiHandlerOptions } from "../index"
import type { ApiHandler, CommonApiHandlerOptions } from "../index"
import { withRetry } from "../retry"
import { convertToOpenAiMessages } from "../transform/openai-format"
import { convertToR1Format } from "../transform/r1-format"
import { ApiStream } from "../transform/stream"
import type { ApiStream } from "../transform/stream"
interface TogetherHandlerOptions extends CommonApiHandlerOptions {
togetherApiKey?: string
+4 -4
View File
@@ -1,9 +1,9 @@
import { Anthropic } from "@anthropic-ai/sdk"
import { ModelInfo, vercelAiGatewayDefaultModelId, vercelAiGatewayDefaultModelInfo } from "@shared/api"
import type { Anthropic } from "@anthropic-ai/sdk"
import { type ModelInfo, vercelAiGatewayDefaultModelId, vercelAiGatewayDefaultModelInfo } from "@shared/api"
import OpenAI from "openai"
import { ApiHandler, CommonApiHandlerOptions } from "../index"
import type { ApiHandler, CommonApiHandlerOptions } from "../index"
import { withRetry } from "../retry"
import { ApiStream } from "../transform/stream"
import type { ApiStream } from "../transform/stream"
import { createVercelAIGatewayStream } from "../transform/vercel-ai-gateway-stream"
interface VercelAIGatewayHandlerOptions extends CommonApiHandlerOptions {
+4 -4
View File
@@ -1,9 +1,9 @@
import { Anthropic } from "@anthropic-ai/sdk"
import type { Anthropic } from "@anthropic-ai/sdk"
import { AnthropicVertex } from "@anthropic-ai/vertex-sdk"
import { ModelInfo, VertexModelId, vertexDefaultModelId, vertexModels } from "@shared/api"
import { ApiHandler, CommonApiHandlerOptions } from "../"
import { type ModelInfo, type VertexModelId, vertexDefaultModelId, vertexModels } from "@shared/api"
import type { ApiHandler, CommonApiHandlerOptions } from "../"
import { withRetry } from "../retry"
import { ApiStream } from "../transform/stream"
import type { ApiStream } from "../transform/stream"
import { GeminiHandler } from "./gemini"
interface VertexHandlerOptions extends CommonApiHandlerOptions {
+10 -10
View File
@@ -1,11 +1,11 @@
import { Anthropic } from "@anthropic-ai/sdk"
import { ModelInfo, openAiModelInfoSaneDefaults } from "@shared/api"
import type { Anthropic } from "@anthropic-ai/sdk"
import { type ModelInfo, openAiModelInfoSaneDefaults } from "@shared/api"
import { SELECTOR_SEPARATOR, stringifyVsCodeLmModelSelector } from "@shared/vsCodeSelectorUtils"
import { calculateApiCostAnthropic } from "@utils/cost"
import * as vscode from "vscode"
import { ApiHandler, CommonApiHandlerOptions, SingleCompletionHandler } from "../"
import type { ApiHandler, CommonApiHandlerOptions, SingleCompletionHandler } from "../"
import { withRetry } from "../retry"
import { ApiStream } from "../transform/stream"
import type { ApiStream } from "../transform/stream"
import { convertToVsCodeLmMessages } from "../transform/vscode-lm-format"
import type { LanguageModelChatSelector as LanguageModelChatSelectorFromTypes } from "./types"
@@ -497,17 +497,17 @@ export class VsCodeLmHandler implements ApiHandler, SingleCompletionHandler {
// Return original error if it's already an Error instance
throw error
} else if (typeof error === "object" && error !== null) {
}
if (typeof error === "object" && error !== null) {
// Handle error-like objects
const errorDetails = JSON.stringify(error, null, 2)
console.error("Cline <Language Model API>: Stream error object:", errorDetails)
throw new Error(`Cline <Language Model API>: Response stream error: ${errorDetails}`)
} else {
// Fallback for unknown error types
const errorMessage = String(error)
console.error("Cline <Language Model API>: Unknown stream error:", errorMessage)
throw new Error(`Cline <Language Model API>: Response stream error: ${errorMessage}`)
}
// Fallback for unknown error types
const errorMessage = String(error)
console.error("Cline <Language Model API>: Unknown stream error:", errorMessage)
throw new Error(`Cline <Language Model API>: Response stream error: ${errorMessage}`)
}
}
+5 -5
View File
@@ -1,12 +1,12 @@
import { Anthropic } from "@anthropic-ai/sdk"
import { ModelInfo, XAIModelId, xaiDefaultModelId, xaiModels } from "@shared/api"
import type { Anthropic } from "@anthropic-ai/sdk"
import { type ModelInfo, type XAIModelId, xaiDefaultModelId, xaiModels } from "@shared/api"
import { shouldSkipReasoningForModel } from "@utils/model-utils"
import OpenAI from "openai"
import { ChatCompletionReasoningEffort } from "openai/resources/chat/completions"
import { ApiHandler, CommonApiHandlerOptions } from "../"
import type { ChatCompletionReasoningEffort } from "openai/resources/chat/completions"
import type { ApiHandler, CommonApiHandlerOptions } from "../"
import { withRetry } from "../retry"
import { convertToOpenAiMessages } from "../transform/openai-format"
import { ApiStream } from "../transform/stream"
import type { ApiStream } from "../transform/stream"
interface XAIHandlerOptions extends CommonApiHandlerOptions {
xaiApiKey?: string
+12 -13
View File
@@ -1,19 +1,19 @@
import { Anthropic } from "@anthropic-ai/sdk"
import type { Anthropic } from "@anthropic-ai/sdk"
import {
internationalZAiDefaultModelId,
internationalZAiModelId,
type internationalZAiModelId,
internationalZAiModels,
ModelInfo,
type ModelInfo,
mainlandZAiDefaultModelId,
mainlandZAiModelId,
type mainlandZAiModelId,
mainlandZAiModels,
} from "@shared/api"
import OpenAI from "openai"
import { version as extensionVersion } from "../../../../package.json"
import { ApiHandler, CommonApiHandlerOptions } from ".."
import type { ApiHandler, CommonApiHandlerOptions } from ".."
import { withRetry } from "../retry"
import { convertToOpenAiMessages } from "../transform/openai-format"
import { ApiStream } from "../transform/stream"
import type { ApiStream } from "../transform/stream"
interface ZAiHandlerOptions extends CommonApiHandlerOptions {
zaiApiLine?: string
@@ -61,13 +61,12 @@ export class ZAiHandler implements ApiHandler {
id: (modelId as mainlandZAiModelId) ?? mainlandZAiDefaultModelId,
info: mainlandZAiModels[modelId as mainlandZAiModelId] ?? mainlandZAiModels[mainlandZAiDefaultModelId],
}
} else {
return {
id: (modelId as internationalZAiModelId) ?? internationalZAiDefaultModelId,
info:
internationalZAiModels[modelId as internationalZAiModelId] ??
internationalZAiModels[internationalZAiDefaultModelId],
}
}
return {
id: (modelId as internationalZAiModelId) ?? internationalZAiDefaultModelId,
info:
internationalZAiModels[modelId as internationalZAiModelId] ??
internationalZAiModels[internationalZAiDefaultModelId],
}
}
+2 -2
View File
@@ -1,5 +1,5 @@
import { Anthropic } from "@anthropic-ai/sdk"
import { Content, GenerateContentResponse, Part } from "@google/genai"
import type { Anthropic } from "@anthropic-ai/sdk"
import type { Content, GenerateContentResponse, Part } from "@google/genai"
export function convertAnthropicContentToGemini(content: string | Anthropic.ContentBlockParam[]): Part[] {
if (typeof content === "string") {
+5 -5
View File
@@ -1,8 +1,8 @@
import { Anthropic } from "@anthropic-ai/sdk"
import { AssistantMessage } from "@mistralai/mistralai/models/components/assistantmessage"
import { SystemMessage } from "@mistralai/mistralai/models/components/systemmessage"
import { ToolMessage } from "@mistralai/mistralai/models/components/toolmessage"
import { UserMessage } from "@mistralai/mistralai/models/components/usermessage"
import type { Anthropic } from "@anthropic-ai/sdk"
import type { AssistantMessage } from "@mistralai/mistralai/models/components/assistantmessage"
import type { SystemMessage } from "@mistralai/mistralai/models/components/systemmessage"
import type { ToolMessage } from "@mistralai/mistralai/models/components/toolmessage"
import type { UserMessage } from "@mistralai/mistralai/models/components/usermessage"
export type MistralMessage =
| (SystemMessage & { role: "system" })
+2 -2
View File
@@ -1,5 +1,5 @@
import { Anthropic } from "@anthropic-ai/sdk"
import OpenAI from "openai"
import type { Anthropic } from "@anthropic-ai/sdk"
import type OpenAI from "openai"
const o1SystemPrompt = (systemPrompt: string) => `
# System Prompt
+2 -2
View File
@@ -1,5 +1,5 @@
import { Anthropic } from "@anthropic-ai/sdk"
import { Message } from "ollama"
import type { Anthropic } from "@anthropic-ai/sdk"
import type { Message } from "ollama"
export function convertToOllamaMessages(anthropicMessages: Anthropic.Messages.MessageParam[]): Message[] {
const ollamaMessages: Message[] = []
+2 -2
View File
@@ -1,5 +1,5 @@
import { Anthropic } from "@anthropic-ai/sdk"
import OpenAI from "openai"
import type { Anthropic } from "@anthropic-ai/sdk"
import type OpenAI from "openai"
export function convertToOpenAiMessages(
anthropicMessages: Anthropic.Messages.MessageParam[],
+3 -3
View File
@@ -1,6 +1,6 @@
import { Anthropic } from "@anthropic-ai/sdk"
import { CLAUDE_SONNET_4_1M_SUFFIX, ModelInfo, openRouterClaudeSonnet41mModelId } from "@shared/api"
import OpenAI from "openai"
import type { Anthropic } from "@anthropic-ai/sdk"
import { CLAUDE_SONNET_4_1M_SUFFIX, type ModelInfo, openRouterClaudeSonnet41mModelId } from "@shared/api"
import type OpenAI from "openai"
import { convertToOpenAiMessages } from "./openai-format"
import { convertToR1Format } from "./r1-format"
+2 -2
View File
@@ -1,5 +1,5 @@
import { Anthropic } from "@anthropic-ai/sdk"
import OpenAI from "openai"
import type { Anthropic } from "@anthropic-ai/sdk"
import type OpenAI from "openai"
/**
* Converts Anthropic messages to OpenAI format and merges consecutive messages with the same role.
@@ -1,6 +1,6 @@
import { Anthropic } from "@anthropic-ai/sdk"
import { ModelInfo } from "@shared/api"
import OpenAI from "openai"
import type { Anthropic } from "@anthropic-ai/sdk"
import type { ModelInfo } from "@shared/api"
import type OpenAI from "openai"
import { convertToOpenAiMessages } from "../transform/openai-format"
export async function createVercelAIGatewayStream(
@@ -2,7 +2,7 @@
import "../providers/vscode-lm"
import { describe, it } from "mocha"
import "should"
import { Anthropic } from "@anthropic-ai/sdk"
import type { Anthropic } from "@anthropic-ai/sdk"
import * as vscode from "vscode"
import { asObjectSafe, convertToAnthropicMessage, convertToAnthropicRole, convertToVsCodeLmMessages } from "./vscode-lm-format"
+1 -1
View File
@@ -1,4 +1,4 @@
import { Anthropic } from "@anthropic-ai/sdk"
import type { Anthropic } from "@anthropic-ai/sdk"
import * as vscode from "vscode"
/**
+5 -5
View File
@@ -412,12 +412,12 @@ async function constructNewFileContentV1(diffContent: string, originalContent: s
// (We artificially add a linebreak since we split on \n at the beginning. In order to not include a trailing linebreak in the final search/result blocks we need to remove it before using them. This allows for partial line matches to be correctly identified.)
// NOTE: search/replace blocks must be arranged in the order they appear in the file due to how we build the content using lastProcessedIndex. We also cannot strip the trailing newline since for non-partial lines it would remove the linebreak from the original content. (If we remove end linebreak from search, then we'd also have to remove it from replace but we can't know if it's a partial line or not since the model may be using the line break to indicate the end of the block rather than as part of the search content.) We require the model to output full lines in order for our fallbacks to work as well.
if (inSearch) {
currentSearchContent += line + "\n"
currentSearchContent += `${line}\n`
} else if (inReplace) {
currentReplaceContent += line + "\n"
currentReplaceContent += `${line}\n`
// Only output replacement lines immediately for in-order replacements
if (searchMatchIndex !== -1 && !pendingOutOfOrderReplacement) {
result += line + "\n"
result += `${line}\n`
}
}
}
@@ -616,10 +616,10 @@ class NewFileContentConstructor {
if (this.isReplacingActive()) {
// Output replacement lines immediately if we know the insertion point
if (this.searchMatchIndex !== -1) {
this.result += line + "\n"
this.result += `${line}\n`
}
} else if (this.isSearchingActive()) {
this.currentSearchContent += line + "\n"
this.currentSearchContent += `${line}\n`
} else {
const appendToPendingNonStandardLines = canWritependingNonStandardLines
if (appendToPendingNonStandardLines) {
+1 -1
View File
@@ -1,4 +1,4 @@
import { ClineDefaultTool } from "@shared/tools"
import type { ClineDefaultTool } from "@shared/tools"
export type AssistantMessageContent = TextContent | ToolUse
export { parseAssistantMessageV2 } from "./parse-assistant-message"
@@ -1,5 +1,5 @@
import { ClineDefaultTool, toolUseNames } from "@shared/tools"
import { AssistantMessageContent, TextContent, ToolParamName, ToolUse, toolParamNames } from "." // Assuming types are defined in index.ts or a similar file
import { type ClineDefaultTool, toolUseNames } from "@shared/tools"
import { type AssistantMessageContent, type TextContent, type ToolParamName, type ToolUse, toolParamNames } from "." // Assuming types are defined in index.ts or a similar file
// parseAssistantmessageV1 removed in https://github.com/cline/cline/pull/5425
@@ -1,6 +1,6 @@
import { Anthropic } from "@anthropic-ai/sdk"
import { ApiHandler } from "@core/api"
import { ClineApiReqInfo, ClineMessage } from "@shared/ExtensionMessage"
import type { Anthropic } from "@anthropic-ai/sdk"
import type { ApiHandler } from "@core/api"
import type { ClineApiReqInfo, ClineMessage } from "@shared/ExtensionMessage"
import { getContextWindowInfo } from "./context-window-utils"
class ContextManager {
@@ -1,12 +1,12 @@
import { Anthropic } from "@anthropic-ai/sdk"
import { ApiHandler } from "@core/api"
import fs from "node:fs/promises"
import * as path from "node:path"
import type { Anthropic } from "@anthropic-ai/sdk"
import type { ApiHandler } from "@core/api"
import { formatResponse } from "@core/prompts/responses"
import { GlobalFileNames } from "@core/storage/disk"
import { ClineApiReqInfo, ClineMessage } from "@shared/ExtensionMessage"
import type { ClineApiReqInfo, ClineMessage } from "@shared/ExtensionMessage"
import { fileExistsAtPath } from "@utils/fs"
import cloneDeep from "clone-deep"
import fs from "fs/promises"
import * as path from "path"
import { getContextWindowInfo } from "./context-window-utils"
enum EditType {
@@ -582,9 +582,8 @@ export class ContextManager {
}
// otherwise there are still file reads here we can overwrite, so still need to process this text chunk
// to do so we need to keep track of which files we've already replaced so we don't replace them again
else {
thisExistingFileReads = blockUpdates[blockUpdates.length - 1][3][0]
}
thisExistingFileReads = blockUpdates[blockUpdates.length - 1][3][0]
}
} else {
// for all other cases we can assume that we dont need to check this again
@@ -1,4 +1,4 @@
import { Anthropic } from "@anthropic-ai/sdk"
import type { Anthropic } from "@anthropic-ai/sdk"
import { expect } from "chai"
import { ContextManager } from "../ContextManager"
@@ -1,4 +1,4 @@
import { ApiHandler } from "@core/api"
import type { ApiHandler } from "@core/api"
import { OpenAiHandler } from "@core/api/providers/openai"
/**
@@ -1,11 +1,11 @@
import * as path from "node:path"
import * as diskModule from "@core/storage/disk"
import { expect } from "chai"
import chokidar from "chokidar"
import { afterEach, beforeEach, describe, it } from "mocha"
import * as path from "path"
import * as sinon from "sinon"
import * as vscode from "vscode"
import { Controller } from "@/core/controller"
import type { Controller } from "@/core/controller"
import { HostProvider } from "@/hosts/host-provider"
import { setVscodeHostProviderMock } from "@/test/host-provider-test-utils"
import type { FileMetadataEntry, TaskMetadata } from "./ContextTrackerTypes"
@@ -1,9 +1,9 @@
import * as path from "node:path"
import { getTaskMetadata, readTaskHistoryFromState, saveTaskMetadata } from "@core/storage/disk"
import type { ClineMessage } from "@shared/ExtensionMessage"
import chokidar, { FSWatcher } from "chokidar"
import * as path from "path"
import * as vscode from "vscode"
import { Controller } from "@/core/controller"
import chokidar, { type FSWatcher } from "chokidar"
import type * as vscode from "vscode"
import type { Controller } from "@/core/controller"
import { getCwd } from "@/utils/path"
import type { FileMetadataEntry } from "./ContextTrackerTypes"
@@ -2,7 +2,7 @@ import * as diskModule from "@core/storage/disk"
import { expect } from "chai"
import { afterEach, beforeEach, describe, it } from "mocha"
import * as sinon from "sinon"
import * as vscode from "vscode"
import type * as vscode from "vscode"
import type { TaskMetadata } from "./ContextTrackerTypes"
import { ModelContextTracker } from "./ModelContextTracker"
@@ -1,5 +1,5 @@
import { getTaskMetadata, saveTaskMetadata } from "@core/storage/disk"
import * as vscode from "vscode"
import type * as vscode from "vscode"
export class ModelContextTracker {
readonly taskId: string
@@ -1,11 +1,11 @@
import fs from "node:fs/promises"
import path from "node:path"
import { getRuleFilesTotalContent, synchronizeRuleToggles } from "@core/context/instructions/user-instructions/rule-helpers"
import { formatResponse } from "@core/prompts/responses"
import { ensureRulesDirectoryExists, GlobalFileNames } from "@core/storage/disk"
import { ClineRulesToggles } from "@shared/cline-rules"
import type { ClineRulesToggles } from "@shared/cline-rules"
import { fileExistsAtPath, isDirectory, readDirectory } from "@utils/fs"
import fs from "fs/promises"
import path from "path"
import { Controller } from "@/core/controller"
import type { Controller } from "@/core/controller"
export const getGlobalClineRules = async (globalClineRulesFilePath: string, toggles: ClineRulesToggles) => {
if (await fileExistsAtPath(globalClineRulesFilePath)) {
@@ -1,3 +1,5 @@
import fs from "node:fs/promises"
import path from "node:path"
import {
combineRuleToggles,
getRuleFilesTotalContent,
@@ -6,11 +8,9 @@ import {
} from "@core/context/instructions/user-instructions/rule-helpers"
import { formatResponse } from "@core/prompts/responses"
import { GlobalFileNames } from "@core/storage/disk"
import { ClineRulesToggles } from "@shared/cline-rules"
import type { ClineRulesToggles } from "@shared/cline-rules"
import { fileExistsAtPath, isDirectory } from "@utils/fs"
import fs from "fs/promises"
import path from "path"
import { Controller } from "@/core/controller"
import type { Controller } from "@/core/controller"
/**
* Refreshes the toggles for windsurf and cursor rules
@@ -1,9 +1,9 @@
import fs from "node:fs/promises"
import * as path from "node:path"
import { ensureRulesDirectoryExists, ensureWorkflowsDirectoryExists, GlobalFileNames } from "@core/storage/disk"
import { ClineRulesToggles } from "@shared/cline-rules"
import type { ClineRulesToggles } from "@shared/cline-rules"
import { fileExistsAtPath, isDirectory, readDirectory } from "@utils/fs"
import fs from "fs/promises"
import * as path from "path"
import { Controller } from "@/core/controller"
import type { Controller } from "@/core/controller"
/**
* Recursively traverses directory and finds all files, including checking for optional whitelisted file extension
@@ -121,7 +121,7 @@ export const getRuleFilesTotalContent = async (rulesFilePaths: string[], basePat
return null
}
return `${ruleFilePathRelative}\n` + (await fs.readFile(ruleFilePath, "utf8")).trim()
return `${ruleFilePathRelative}\n${(await fs.readFile(ruleFilePath, "utf8")).trim()}`
}),
).then((contents) => contents.filter(Boolean).join("\n\n"))
return ruleFilesTotalContent
@@ -140,7 +140,7 @@ export async function ensureLocalClineDirExists(clinerulePath: string, defaultRu
if (exists && !(await isDirectory(clinerulePath))) {
// logic to convert .clinerules file into directory, and rename the rules file to {defaultRuleFilename}
const content = await fs.readFile(clinerulePath, "utf8")
const tempPath = clinerulePath + ".bak"
const tempPath = `${clinerulePath}.bak`
await fs.rename(clinerulePath, tempPath) // create backup
try {
await fs.mkdir(clinerulePath, { recursive: true })
@@ -1,8 +1,8 @@
import path from "node:path"
import { synchronizeRuleToggles } from "@core/context/instructions/user-instructions/rule-helpers"
import { ensureWorkflowsDirectoryExists, GlobalFileNames } from "@core/storage/disk"
import { ClineRulesToggles } from "@shared/cline-rules"
import path from "path"
import { Controller } from "@/core/controller"
import type { ClineRulesToggles } from "@shared/cline-rules"
import type { Controller } from "@/core/controller"
/**
* Refresh the workflow toggles
@@ -1,6 +1,6 @@
import { EmptyRequest, String } from "@shared/proto/cline/common"
import type { EmptyRequest, String } from "@shared/proto/cline/common"
import { AuthService } from "@/services/auth/AuthService"
import { Controller } from "../index"
import type { Controller } from "../index"
/**
* Handles the user clicking the login link in the UI.
@@ -1,4 +1,4 @@
import { AuthState, AuthStateChangedRequest } from "@shared/proto/cline/account"
import { AuthState, type AuthStateChangedRequest } from "@shared/proto/cline/account"
import type { Controller } from "../index"
/**
@@ -1,4 +1,8 @@
import { GetOrganizationCreditsRequest, OrganizationCreditsData, OrganizationUsageTransaction } from "@shared/proto/cline/account"
import {
type GetOrganizationCreditsRequest,
OrganizationCreditsData,
OrganizationUsageTransaction,
} from "@shared/proto/cline/account"
import type { Controller } from "../index"
/**
@@ -1,6 +1,6 @@
import { EmptyRequest, String } from "@shared/proto/cline/common"
import type { EmptyRequest, String } from "@shared/proto/cline/common"
import { HostProvider } from "@/hosts/host-provider"
import { Controller } from "../index"
import type { Controller } from "../index"
/**
* Constructs and returns a URL that will redirect to the user's IDE.
@@ -1,7 +1,7 @@
import { Empty, EmptyRequest } from "@shared/proto/cline/common"
import type { Empty, EmptyRequest } from "@shared/proto/cline/common"
import { HostProvider } from "@/hosts/host-provider"
import { openExternal } from "@/utils/env"
import { Controller } from ".."
import type { Controller } from ".."
/**
* Initiates OpenRouter auth
@@ -1,4 +1,4 @@
import { UserOrganizationUpdateRequest } from "@shared/proto/cline/account"
import type { UserOrganizationUpdateRequest } from "@shared/proto/cline/account"
import { Empty } from "@shared/proto/cline/common"
import type { Controller } from "../index"
@@ -1,7 +1,7 @@
import { AuthService } from "@services/auth/AuthService"
import { AuthState, EmptyRequest } from "@/shared/proto/index.cline"
import { Controller } from ".."
import { StreamingResponseHandler } from "../grpc-handler"
import type { AuthState, EmptyRequest } from "@/shared/proto/index.cline"
import type { Controller } from ".."
import type { StreamingResponseHandler } from "../grpc-handler"
export async function subscribeToAuthStatusUpdate(
controller: Controller,
@@ -1,8 +1,8 @@
import { discoverChromeInstances } from "@services/browser/BrowserDiscovery"
import { BrowserSession } from "@services/browser/BrowserSession"
import { BrowserConnection } from "@shared/proto/cline/browser"
import { EmptyRequest } from "@shared/proto/cline/common"
import { Controller } from "../index"
import type { EmptyRequest } from "@shared/proto/cline/common"
import type { Controller } from "../index"
/**
* Discover Chrome instances
@@ -27,14 +27,13 @@ export async function discoverBrowser(controller: Controller, _request: EmptyReq
message: `Successfully discovered and connected to Chrome at ${discoveredHost}`,
endpoint: result.endpoint || "",
})
} else {
return BrowserConnection.create({
success: false,
message:
"No Chrome instances found. Make sure Chrome is running with remote debugging enabled (--remote-debugging-port=9222).",
endpoint: "",
})
}
return BrowserConnection.create({
success: false,
message:
"No Chrome instances found. Make sure Chrome is running with remote debugging enabled (--remote-debugging-port=9222).",
endpoint: "",
})
} catch (error) {
return BrowserConnection.create({
success: false,
@@ -1,6 +1,6 @@
import { BrowserConnectionInfo } from "@shared/proto/cline/browser"
import { EmptyRequest } from "@shared/proto/cline/common"
import { Controller } from "../index"
import type { EmptyRequest } from "@shared/proto/cline/common"
import type { Controller } from "../index"
/**
* Get information about the current browser connection
@@ -1,7 +1,7 @@
import { ChromePath } from "@shared/proto/cline/browser"
import { EmptyRequest } from "@shared/proto/cline/common"
import type { EmptyRequest } from "@shared/proto/cline/common"
import { BrowserSession } from "../../../services/browser/BrowserSession"
import { Controller } from "../index"
import type { Controller } from "../index"
/**
* Get the detected Chrome executable path
@@ -1,6 +1,6 @@
import { EmptyRequest, String as StringMessage } from "@shared/proto/cline/common"
import type { EmptyRequest, String as StringMessage } from "@shared/proto/cline/common"
import { BrowserSession } from "../../../services/browser/BrowserSession"
import { Controller } from "../index"
import type { Controller } from "../index"
/**
* Relaunch Chrome in debug mode
@@ -1,8 +1,8 @@
import { discoverChromeInstances } from "@services/browser/BrowserDiscovery"
import { BrowserSession } from "@services/browser/BrowserSession"
import { BrowserConnection } from "@shared/proto/cline/browser"
import { StringRequest } from "@shared/proto/cline/common"
import { Controller } from "../index"
import type { StringRequest } from "@shared/proto/cline/common"
import type { Controller } from "../index"
/**
* Test connection to a browser instance
@@ -27,14 +27,13 @@ export async function testBrowserConnection(controller: Controller, request: Str
message: `Auto-discovered and tested connection to Chrome at ${discoveredHost}: ${result.message}`,
endpoint: result.endpoint || "",
})
} else {
return BrowserConnection.create({
success: false,
message:
"No Chrome instances found on the network. Make sure Chrome is running with remote debugging enabled (--remote-debugging-port=9222).",
endpoint: "",
})
}
return BrowserConnection.create({
success: false,
message:
"No Chrome instances found on the network. Make sure Chrome is running with remote debugging enabled (--remote-debugging-port=9222).",
endpoint: "",
})
} catch (error) {
return BrowserConnection.create({
success: false,
@@ -1,5 +1,5 @@
import { Empty, Int64Request } from "@shared/proto/cline/common"
import { Controller } from ".."
import { Empty, type Int64Request } from "@shared/proto/cline/common"
import type { Controller } from ".."
export async function checkpointDiff(controller: Controller, request: Int64Request): Promise<Empty> {
if (request.value) {
@@ -1,10 +1,10 @@
import { CheckpointRestoreRequest } from "@shared/proto/cline/checkpoints"
import type { CheckpointRestoreRequest } from "@shared/proto/cline/checkpoints"
import { Empty } from "@shared/proto/cline/common"
import pWaitFor from "p-wait-for"
import { HostProvider } from "@/hosts/host-provider"
import { ShowMessageType } from "@/shared/proto/index.host"
import { ClineCheckpointRestore } from "../../../shared/WebviewMessage"
import { Controller } from ".."
import type { ClineCheckpointRestore } from "../../../shared/WebviewMessage"
import type { Controller } from ".."
export async function checkpointRestore(controller: Controller, request: CheckpointRestoreRequest): Promise<Empty> {
await controller.cancelTask() // we cannot alter message history say if the task is active, as it could be in the middle of editing a file or running a command, which expect the ask to be responded to rather than being superseded by a new message eg add deleted_api_reqs
+2 -2
View File
@@ -2,8 +2,8 @@ import { getFileMentionFromPath } from "@/core/mentions"
import { WebviewProvider } from "@/core/webview"
import { singleFileDiagnosticsToProblemsString } from "@/integrations/diagnostics"
import { telemetryService } from "@/services/telemetry"
import { CommandContext, Empty } from "@/shared/proto/index.cline"
import { Controller } from "../index"
import type { CommandContext, Empty } from "@/shared/proto/index.cline"
import type { Controller } from "../index"
import { sendAddToInputEventToClient } from "../ui/subscribeToAddToInput"
// 'Add to Cline' context menu in editor and code action
@@ -1,9 +1,9 @@
import { getFileMentionFromPath } from "@/core/mentions"
import { HostProvider } from "@/hosts/host-provider"
import { telemetryService } from "@/services/telemetry"
import { CommandContext, Empty } from "@/shared/proto/index.cline"
import type { CommandContext, Empty } from "@/shared/proto/index.cline"
import { ShowMessageType } from "@/shared/proto/index.host"
import { Controller } from "../index"
import type { Controller } from "../index"
export async function explainWithCline(controller: Controller, request: CommandContext): Promise<Empty> {
if (!request.selectedText || !request.selectedText.trim()) {
+2 -2
View File
@@ -1,8 +1,8 @@
import { getFileMentionFromPath } from "@/core/mentions"
import { singleFileDiagnosticsToProblemsString } from "@/integrations/diagnostics"
import { telemetryService } from "@/services/telemetry"
import { CommandContext, Empty } from "@/shared/proto/index.cline"
import { Controller } from "../index"
import type { CommandContext, Empty } from "@/shared/proto/index.cline"
import type { Controller } from "../index"
export async function fixWithCline(controller: Controller, request: CommandContext): Promise<Empty> {
const filePath = request.filePath || ""

Some files were not shown because too many files have changed in this diff Show More