mirror of
https://github.com/cline/cline.git
synced 2026-09-02 07:42:19 +08:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a07554f191 | |||
| 474c655240 | |||
| b5157a2376 | |||
| b14db72140 |
@@ -1,5 +0,0 @@
|
||||
---
|
||||
"claude-dev": patch
|
||||
---
|
||||
|
||||
Fix for SAP provider - OrchestrationClient matches the OrchestrationModuleConfig type and no longer uses the invalid promptTemplating property
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
"claude-dev": patch
|
||||
---
|
||||
|
||||
Removed new_task from system prompts, updated slash command prompt, added helper function for native tool calling checks
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
"claude-dev": minor
|
||||
---
|
||||
|
||||
upgrade sap ai-sdk-js packages major version
|
||||
@@ -0,0 +1,48 @@
|
||||
# Git
|
||||
.git
|
||||
.gitignore
|
||||
.gitattributes
|
||||
|
||||
# Node modules
|
||||
node_modules
|
||||
npm-debug.log
|
||||
|
||||
# Build artifacts
|
||||
dist
|
||||
dist-standalone
|
||||
build
|
||||
*.log
|
||||
|
||||
# Generated code
|
||||
src/generated
|
||||
|
||||
# CLI build artifacts
|
||||
cli/bin
|
||||
cli/dist
|
||||
|
||||
# Webview build artifacts
|
||||
webview-ui/dist
|
||||
webview-ui/build
|
||||
|
||||
# IDE
|
||||
.vscode
|
||||
.idea
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# OS
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Documentation
|
||||
*.md
|
||||
!README.md
|
||||
|
||||
# Tests
|
||||
tests
|
||||
*.test.js
|
||||
*.spec.js
|
||||
|
||||
# CI/CD
|
||||
.github
|
||||
.gitlab-ci.yml
|
||||
@@ -0,0 +1,49 @@
|
||||
FROM node:22-slim
|
||||
|
||||
# TARGETARCH enables multi-architecture support without emulation warnings:
|
||||
# - Docker automatically sets TARGETARCH to the build platform's architecture
|
||||
# - On arm64 machines (Apple Silicon): TARGETARCH=arm64, uses linux-arm64 binaries
|
||||
# - On amd64 machines (Intel/AMD): TARGETARCH=amd64, uses linux-x64 binaries
|
||||
# The corresponding platform-specific binaries and native modules (better-sqlite3)
|
||||
# are pre-built by scripts/package-standalone.mjs during the build process.
|
||||
ARG TARGETARCH
|
||||
|
||||
# Install only runtime dependencies
|
||||
RUN apt-get update && apt-get install -y \
|
||||
git curl ca-certificates \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /opt/cline
|
||||
|
||||
# Copy the entire pre-built distribution
|
||||
COPY dist-standalone/ ./
|
||||
|
||||
# Create symlink for Linux native modules
|
||||
# Map Docker's TARGETARCH (arm64/amd64) to Node's platform naming (x64 for amd64)
|
||||
RUN if [ "$TARGETARCH" = "amd64" ]; then \
|
||||
ln -sf /opt/cline/binaries/linux-x64/node_modules/better-sqlite3 /opt/cline/node_modules/better-sqlite3; \
|
||||
else \
|
||||
ln -sf /opt/cline/binaries/linux-$TARGETARCH/node_modules/better-sqlite3 /opt/cline/node_modules/better-sqlite3; \
|
||||
fi
|
||||
|
||||
# Set up CLI binaries
|
||||
# The Linux binaries are already in /opt/cline/bin/ from dist-standalone
|
||||
# Just need to create symlinks to the platform-specific ones
|
||||
RUN cd /opt/cline/bin && \
|
||||
ln -sf cline-linux-$TARGETARCH cline && \
|
||||
ln -sf cline-host-linux-$TARGETARCH cline-host && \
|
||||
chmod +x cline-linux-$TARGETARCH cline-host-linux-$TARGETARCH cline cline-host
|
||||
|
||||
# Add binaries to PATH
|
||||
ENV PATH="/opt/cline/bin:${PATH}"
|
||||
ENV NODE_ENV=production
|
||||
ENV CLINE_HOME=/root/.cline
|
||||
|
||||
RUN mkdir -p $CLINE_HOME
|
||||
|
||||
WORKDIR /workspace
|
||||
|
||||
EXPOSE 8000
|
||||
|
||||
ENTRYPOINT ["/opt/cline/bin/cline"]
|
||||
CMD ["--help"]
|
||||
Generated
+34
-6
@@ -5146,6 +5146,28 @@
|
||||
"node": ">=6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/gray-matter/node_modules/argparse": {
|
||||
"version": "1.0.10",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
|
||||
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"sprintf-js": "~1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/gray-matter/node_modules/js-yaml": {
|
||||
"version": "3.14.1",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
|
||||
"integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"argparse": "^1.0.7",
|
||||
"esprima": "^4.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"js-yaml": "bin/js-yaml.js"
|
||||
}
|
||||
},
|
||||
"node_modules/has-bigints": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz",
|
||||
@@ -6468,9 +6490,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/js-yaml": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
|
||||
"integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
|
||||
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"argparse": "^2.0.1"
|
||||
@@ -10213,6 +10235,12 @@
|
||||
"url": "https://github.com/sponsors/wooorm"
|
||||
}
|
||||
},
|
||||
"node_modules/sprintf-js": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
||||
"integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/stack-utils": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz",
|
||||
@@ -10581,9 +10609,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/tar-fs": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.1.tgz",
|
||||
"integrity": "sha512-LZA0oaPOc2fVo82Txf3gw+AkEd38szODlptMYejQUhndHMLQ9M059uXR+AfS7DNo0NpINvSqDsvyaCrBVkptWg==",
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.0.tgz",
|
||||
"integrity": "sha512-5Mty5y/sOF1YWj1J6GiBodjlDc05CUR8PKXrsnFAiSG0xA+GHeWLovaZPYUDXkH/1iKRf2+M5+OrRgzC7O9b7w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"pump": "^3.0.0",
|
||||
|
||||
@@ -14,9 +14,5 @@
|
||||
"description": "",
|
||||
"dependencies": {
|
||||
"mintlify": "^4.2.23"
|
||||
},
|
||||
"overrides": {
|
||||
"tar-fs": "^3.1.1",
|
||||
"js-yaml": "^4.1.1"
|
||||
}
|
||||
}
|
||||
|
||||
Generated
+1422
File diff suppressed because it is too large
Load Diff
+45
-46
@@ -1,48 +1,47 @@
|
||||
{
|
||||
"name": "cline-evals",
|
||||
"version": "0.1.0",
|
||||
"description": "Evaluation scripts and tools for Cline",
|
||||
"main": "cli/dist/index.js",
|
||||
"scripts": {
|
||||
"build:cli": "cd cli && tsc",
|
||||
"start:cli": "cd cli && node dist/index.js",
|
||||
"dev:cli": "cd cli && ts-node src/index.ts",
|
||||
"diff-eval": "./diff-edits/run_and_open_dashboard.sh",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [
|
||||
"cline",
|
||||
"evaluation",
|
||||
"benchmark",
|
||||
"diff-edits"
|
||||
],
|
||||
"author": "",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"axios": "^1.12.0",
|
||||
"better-sqlite3": "^12.4.1",
|
||||
"chalk": "5.6.2",
|
||||
"dotenv": "^16.5.0",
|
||||
"commander": "^9.4.1",
|
||||
"execa": "^5.1.1",
|
||||
"node-fetch": "^2.7.0",
|
||||
"ora": "^5.4.1",
|
||||
"sqlite": "^4.1.2",
|
||||
"tiktoken": "^1.0.21",
|
||||
"uuid": "^9.0.0",
|
||||
"yargs": "^17.6.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/better-sqlite3": "^7.6.3",
|
||||
"@types/node": "^18.11.18",
|
||||
"@types/node-fetch": "^2.6.12",
|
||||
"@types/uuid": "^9.0.0",
|
||||
"@types/yargs": "^17.0.19",
|
||||
"ts-node": "^10.9.1",
|
||||
"typescript": "^4.9.4"
|
||||
},
|
||||
"overrides": {
|
||||
"tar-fs": "^3.1.1",
|
||||
"js-yaml": "^4.1.1"
|
||||
}
|
||||
"name": "cline-evals",
|
||||
"version": "0.1.0",
|
||||
"description": "Evaluation scripts and tools for Cline",
|
||||
"main": "cli/dist/index.js",
|
||||
"scripts": {
|
||||
"build:cli": "cd cli && tsc",
|
||||
"start:cli": "cd cli && node dist/index.js",
|
||||
"dev:cli": "cd cli && ts-node src/index.ts",
|
||||
"diff-eval": "./diff-edits/run_and_open_dashboard.sh",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [
|
||||
"cline",
|
||||
"evaluation",
|
||||
"benchmark",
|
||||
"diff-edits"
|
||||
],
|
||||
"author": "",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"axios": "^1.12.0",
|
||||
"better-sqlite3": "^12.4.1",
|
||||
"chalk": "5.6.2",
|
||||
"dotenv": "^16.5.0",
|
||||
"commander": "^9.4.1",
|
||||
"execa": "^5.1.1",
|
||||
"node-fetch": "^2.7.0",
|
||||
"ora": "^5.4.1",
|
||||
"sqlite": "^4.1.2",
|
||||
"tiktoken": "^1.0.21",
|
||||
"uuid": "^9.0.0",
|
||||
"yargs": "^17.6.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/better-sqlite3": "^7.6.3",
|
||||
"@types/node": "^18.11.18",
|
||||
"@types/node-fetch": "^2.6.12",
|
||||
"@types/uuid": "^9.0.0",
|
||||
"@types/yargs": "^17.0.19",
|
||||
"ts-node": "^10.9.1",
|
||||
"typescript": "^4.9.4"
|
||||
},
|
||||
"overrides": {
|
||||
"tar-fs": "^3.1.1"
|
||||
}
|
||||
}
|
||||
|
||||
Generated
+860
-187
File diff suppressed because it is too large
Load Diff
+7
-6
@@ -306,6 +306,8 @@
|
||||
"compile-cli-all-platforms": "scripts/build-cli-all-platforms.sh",
|
||||
"compile-cli-man-page": "pandoc cli/man/cline.1.md -s -t man -o cli/man/cline.1",
|
||||
"build:npm": "scripts/build-npm-package.sh",
|
||||
"build:docker:dev": "node scripts/build-docker-dev.mjs",
|
||||
"docker:shell": "node scripts/docker-shell.mjs",
|
||||
"test:install": "bash scripts/test-install.sh",
|
||||
"dev:cli:watch": "node scripts/dev-cli-watch.mjs",
|
||||
"postcompile-standalone": "node scripts/package-standalone.mjs",
|
||||
@@ -442,8 +444,8 @@
|
||||
"@opentelemetry/sdk-trace-node": "^1.30.1",
|
||||
"@opentelemetry/semantic-conventions": "^1.37.0",
|
||||
"@playwright/test": "^1.55.1",
|
||||
"@sap-ai-sdk/ai-api": "^2.1.0",
|
||||
"@sap-ai-sdk/orchestration": "^2.1.0",
|
||||
"@sap-ai-sdk/ai-api": "^1.17.0",
|
||||
"@sap-ai-sdk/orchestration": "^1.17.0",
|
||||
"@sentry/browser": "^9.12.0",
|
||||
"@streamparser/json": "^0.0.22",
|
||||
"@tailwindcss/vite": "^4.1.14",
|
||||
@@ -461,6 +463,7 @@
|
||||
"exceljs": "^4.4.0",
|
||||
"execa": "^9.5.2",
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"firebase": "^11.2.0",
|
||||
"fzf": "^0.5.2",
|
||||
"get-folder-size": "^5.0.0",
|
||||
"globby": "^14.0.2",
|
||||
@@ -470,6 +473,7 @@
|
||||
"image-size": "^2.0.2",
|
||||
"isbinaryfile": "^5.0.2",
|
||||
"jschardet": "^3.1.4",
|
||||
"jwt-decode": "^4.0.0",
|
||||
"mammoth": "^1.11.0",
|
||||
"nanoid": "^5.1.6",
|
||||
"nice-grpc": "^2.1.12",
|
||||
@@ -502,10 +506,7 @@
|
||||
"zod": "^3.24.2"
|
||||
},
|
||||
"overrides": {
|
||||
"tar-fs": ">=3.1.1",
|
||||
"tar": "^7.5.2",
|
||||
"vite": "^7.1.11",
|
||||
"js-yaml": "^4.1.1"
|
||||
"tar-fs": ">=3.1.1"
|
||||
},
|
||||
"c8": {
|
||||
"reporter": [
|
||||
|
||||
+1
-15
@@ -362,7 +362,7 @@ message UpdateSettingsRequest {
|
||||
optional int32 subagent_terminal_output_line_limit = 30;
|
||||
optional string cline_env = 31;
|
||||
optional bool native_tool_call_enabled = 32;
|
||||
optional OnboardingModelGroup onboarding_models = 33;
|
||||
optional bool show_onboarding_flow = 33;
|
||||
}
|
||||
|
||||
message UpdateTerminalConnectionTimeoutRequest {
|
||||
@@ -390,17 +390,3 @@ message OnboardingProgressRequest {
|
||||
optional bool completed = 3;
|
||||
optional string model_selected = 4;
|
||||
}
|
||||
|
||||
message OnboardingModelGroup {
|
||||
repeated OnboardingModel models = 1;
|
||||
}
|
||||
|
||||
message OnboardingModel {
|
||||
string id = 1;
|
||||
string name = 2;
|
||||
int32 score = 3;
|
||||
int32 latency = 4;
|
||||
string badge = 5;
|
||||
string group = 6;
|
||||
OpenRouterModelInfo info = 7;
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import { execSync } from "child_process"
|
||||
|
||||
/**
|
||||
* Build Docker image for Cline CLI
|
||||
* This script builds a Docker image using pre-built binaries from dist-standalone/
|
||||
*
|
||||
* Prerequisites:
|
||||
* - Run `npm run compile-standalone` first to build all platform binaries
|
||||
* - Run `npm run compile-cli` first to build CLI binaries
|
||||
*/
|
||||
|
||||
function runCommand(command, description) {
|
||||
console.log(`\n${description}...`)
|
||||
try {
|
||||
execSync(command, { stdio: "inherit" })
|
||||
console.log("✓ Success\n")
|
||||
} catch (error) {
|
||||
console.error(`✗ Failed: ${error.message}`)
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
function getCommandOutput(command) {
|
||||
try {
|
||||
return execSync(command, { encoding: "utf-8" }).trim()
|
||||
} catch (error) {
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
function buildPrerequisites() {
|
||||
console.log("Building prerequisites...\n")
|
||||
|
||||
// Build standalone (includes cline-core and platform-specific native modules)
|
||||
runCommand("npm run compile-standalone", "Running npm run compile-standalone")
|
||||
|
||||
// Build CLI binaries for all platforms
|
||||
runCommand("npm run compile-cli-all-platforms", "Running npm run compile-cli-all-platforms")
|
||||
|
||||
console.log("✓ All prerequisites built successfully\n")
|
||||
}
|
||||
|
||||
function main() {
|
||||
console.log("🐳 Building Cline CLI Docker Image\n")
|
||||
|
||||
// Remove existing container to ensure clean state after rebuild
|
||||
const containerId = getCommandOutput(`docker ps -aq --filter "name=^cline-cli-dev$"`)
|
||||
if (containerId) {
|
||||
console.log("🗑️ Removing existing container to ensure fresh start...")
|
||||
try {
|
||||
execSync(`docker rm -f cline-cli-dev`, { stdio: "inherit" })
|
||||
console.log("✓ Container removed\n")
|
||||
} catch (error) {
|
||||
console.log("Note: Container cleanup failed, continuing anyway\n")
|
||||
}
|
||||
}
|
||||
|
||||
buildPrerequisites()
|
||||
|
||||
// Build Docker image for native platform
|
||||
// Docker will automatically use the correct architecture (arm64 on Apple Silicon, amd64 on Intel)
|
||||
runCommand("docker build -f docker/Dockerfile -t cline-cli:dev .", "Building Docker image")
|
||||
|
||||
console.log("✅ Docker image built successfully!")
|
||||
console.log("\n📋 Next steps:\n")
|
||||
console.log("Interactive shell:")
|
||||
console.log(" npm run docker:shell\n")
|
||||
console.log("This will:")
|
||||
console.log(" • Reuse existing 'cline-cli-dev' container if running")
|
||||
console.log(" • Start stopped container if it exists")
|
||||
console.log(" • Create new persistent container if none exists")
|
||||
console.log(" • Mount current directory at /workspace")
|
||||
console.log(" • Provide all CLI commands (cline auth, cline task, etc.)")
|
||||
console.log("\nContainer persists between sessions. To remove:")
|
||||
console.log(" docker rm -f cline-cli-dev\n")
|
||||
}
|
||||
|
||||
main()
|
||||
@@ -0,0 +1,66 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import { execSync } from "child_process"
|
||||
import { platform } from "os"
|
||||
|
||||
const CONTAINER_NAME = "cline-cli-dev"
|
||||
|
||||
function runCommand(command) {
|
||||
try {
|
||||
return execSync(command, { encoding: "utf-8" }).trim()
|
||||
} catch (error) {
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
function getCurrentDirectory() {
|
||||
// Get current working directory in a cross-platform way
|
||||
return process.cwd()
|
||||
}
|
||||
|
||||
function main() {
|
||||
console.log("🐳 Cline CLI Docker Shell\n")
|
||||
|
||||
// Check if container exists (running or stopped)
|
||||
const containerId = runCommand(`docker ps -a --filter "name=^${CONTAINER_NAME}$" --format "{{.ID}}"`)
|
||||
|
||||
if (containerId) {
|
||||
// Check if container is running
|
||||
const isRunning = runCommand(`docker ps --filter "id=${containerId}" --format "{{.ID}}"`)
|
||||
|
||||
if (isRunning) {
|
||||
console.log(`📦 Connecting to running container: ${CONTAINER_NAME}\n`)
|
||||
try {
|
||||
execSync(`docker exec -it ${containerId} /bin/bash`, { stdio: "inherit" })
|
||||
} catch (error) {
|
||||
// User exited shell normally
|
||||
}
|
||||
} else {
|
||||
console.log(`▶️ Starting stopped container: ${CONTAINER_NAME}\n`)
|
||||
try {
|
||||
execSync(`docker start ${containerId}`, { stdio: "inherit" })
|
||||
execSync(`docker exec -it ${containerId} /bin/bash`, { stdio: "inherit" })
|
||||
} catch (error) {
|
||||
// User exited shell normally
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.log(`🚀 Creating new container: ${CONTAINER_NAME}\n`)
|
||||
const cwd = getCurrentDirectory()
|
||||
|
||||
try {
|
||||
// Use different volume mount syntax for Windows vs Unix
|
||||
const isWindows = platform() === "win32"
|
||||
const volumeMount = isWindows ? `${cwd.replace(/\\/g, "/")}:/workspace` : `${cwd}:/workspace`
|
||||
|
||||
execSync(
|
||||
`docker run -it --name ${CONTAINER_NAME} -v "${volumeMount}" -w /workspace --entrypoint /bin/bash cline-cli:dev`,
|
||||
{ stdio: "inherit" },
|
||||
)
|
||||
} catch (error) {
|
||||
// User exited shell normally
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
main()
|
||||
@@ -11,7 +11,7 @@ import fs from "fs"
|
||||
import https from "https"
|
||||
import path from "path"
|
||||
import { pipeline } from "stream/promises"
|
||||
import * as tar from "tar"
|
||||
import tar from "tar"
|
||||
import { promisify } from "util"
|
||||
import { createGunzip } from "zlib"
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ const TARGET_PLATFORMS = [
|
||||
{ platform: "darwin", arch: "x64", targetDir: "darwin-x64" },
|
||||
{ platform: "darwin", arch: "arm64", targetDir: "darwin-arm64" },
|
||||
{ platform: "linux", arch: "x64", targetDir: "linux-x64" },
|
||||
{ platform: "linux", arch: "arm64", targetDir: "linux-arm64" },
|
||||
]
|
||||
const SUPPORTED_BINARY_MODULES = ["better-sqlite3"]
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Anthropic } from "@anthropic-ai/sdk"
|
||||
import { ModelInfo } from "@shared/api"
|
||||
import { ClineStorageMessage } from "@/shared/messages/content"
|
||||
import { fetch } from "@/shared/net"
|
||||
import { ApiHandler } from "../../core/api/index"
|
||||
import { ApiStream } from "../../core/api/transform/stream"
|
||||
@@ -33,7 +33,7 @@ export class DifyHandler implements ApiHandler {
|
||||
}
|
||||
}
|
||||
|
||||
async *createMessage(systemPrompt: string, messages: ClineStorageMessage[]): ApiStream {
|
||||
async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream {
|
||||
console.log("[DIFY DEBUG] createMessage called with:", {
|
||||
systemPromptLength: systemPrompt?.length || 0,
|
||||
messagesCount: messages?.length || 0,
|
||||
@@ -255,7 +255,7 @@ export class DifyHandler implements ApiHandler {
|
||||
}
|
||||
}
|
||||
|
||||
private convertMessagesToQuery(systemPrompt: string, messages: ClineStorageMessage[]): string {
|
||||
private convertMessagesToQuery(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): string {
|
||||
// Dify's context is managed by `conversation_id`. The `query` should be the last user message.
|
||||
// The system prompt is typically configured in the Dify App itself.
|
||||
const lastUserMessage = messages.filter((m) => m.role === "user").pop()
|
||||
|
||||
@@ -9,6 +9,14 @@ export interface EnvironmentConfig {
|
||||
appBaseUrl: string
|
||||
apiBaseUrl: string
|
||||
mcpBaseUrl: string
|
||||
firebase: {
|
||||
apiKey: string
|
||||
authDomain: string
|
||||
projectId: string
|
||||
storageBucket?: string
|
||||
messagingSenderId?: string
|
||||
appId?: string
|
||||
}
|
||||
}
|
||||
|
||||
class ClineEndpoint {
|
||||
@@ -55,6 +63,14 @@ class ClineEndpoint {
|
||||
appBaseUrl: "https://staging-app.cline.bot",
|
||||
apiBaseUrl: "https://core-api.staging.int.cline.bot",
|
||||
mcpBaseUrl: "https://core-api.staging.int.cline.bot/v1/mcp",
|
||||
firebase: {
|
||||
apiKey: "AIzaSyASSwkwX1kSO8vddjZkE5N19QU9cVQ0CIk",
|
||||
authDomain: "cline-staging.firebaseapp.com",
|
||||
projectId: "cline-staging",
|
||||
storageBucket: "cline-staging.firebasestorage.app",
|
||||
messagingSenderId: "853479478430",
|
||||
appId: "1:853479478430:web:2de0dba1c63c3262d4578f",
|
||||
},
|
||||
}
|
||||
case Environment.local:
|
||||
return {
|
||||
@@ -62,6 +78,11 @@ class ClineEndpoint {
|
||||
appBaseUrl: "http://localhost:3000",
|
||||
apiBaseUrl: "http://localhost:7777",
|
||||
mcpBaseUrl: "https://api.cline.bot/v1/mcp",
|
||||
firebase: {
|
||||
apiKey: "AIzaSyD8wtkd1I-EICuAg6xgAQpRdwYTvwxZG2w",
|
||||
authDomain: "cline-preview.firebaseapp.com",
|
||||
projectId: "cline-preview",
|
||||
},
|
||||
}
|
||||
default:
|
||||
return {
|
||||
@@ -69,6 +90,14 @@ class ClineEndpoint {
|
||||
appBaseUrl: "https://app.cline.bot",
|
||||
apiBaseUrl: "https://api.cline.bot",
|
||||
mcpBaseUrl: "https://api.cline.bot/v1/mcp",
|
||||
firebase: {
|
||||
apiKey: "AIzaSyC5rx59Xt8UgwdU3PCfzUF7vCwmp9-K2vk",
|
||||
authDomain: "cline-prod.firebaseapp.com",
|
||||
projectId: "cline-prod",
|
||||
storageBucket: "cline-prod.firebasestorage.app",
|
||||
messagingSenderId: "941048379330",
|
||||
appId: "1:941048379330:web:45058eedeefc5cdfcc485b",
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { Anthropic } from "@anthropic-ai/sdk"
|
||||
import { afterEach, beforeEach, describe, it } from "mocha"
|
||||
import sinon from "sinon"
|
||||
import "should"
|
||||
import { ClaudeCodeHandler } from "@core/api/providers/claude-code"
|
||||
import { ClineStorageMessage } from "@/shared/messages/content"
|
||||
|
||||
describe("ClaudeCodeHandler", () => {
|
||||
let handler: ClaudeCodeHandler
|
||||
@@ -71,7 +71,7 @@ describe("ClaudeCodeHandler", () => {
|
||||
runClaudeCodeStub.returns(mockGenerator() as any)
|
||||
|
||||
const systemPrompt = "You are a helpful assistant."
|
||||
const messages: ClineStorageMessage[] = [{ role: "user", content: "Hello" }]
|
||||
const messages: Anthropic.Messages.MessageParam[] = [{ role: "user", content: "Hello" }]
|
||||
|
||||
const usageData: any[] = []
|
||||
|
||||
@@ -140,7 +140,7 @@ describe("ClaudeCodeHandler", () => {
|
||||
runClaudeCodeStub.returns(mockGenerator() as any)
|
||||
|
||||
const systemPrompt = "You are a helpful assistant."
|
||||
const messages: ClineStorageMessage[] = [{ role: "user", content: "Hello" }]
|
||||
const messages: Anthropic.Messages.MessageParam[] = [{ role: "user", content: "Hello" }]
|
||||
|
||||
const usageData: any[] = []
|
||||
|
||||
@@ -199,7 +199,7 @@ describe("ClaudeCodeHandler", () => {
|
||||
runClaudeCodeStub.returns(mockGenerator() as any)
|
||||
|
||||
const systemPrompt = "You are a helpful assistant."
|
||||
const messages: ClineStorageMessage[] = [{ role: "user", content: "Hello" }]
|
||||
const messages: Anthropic.Messages.MessageParam[] = [{ role: "user", content: "Hello" }]
|
||||
|
||||
const usageData: any[] = []
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import 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"
|
||||
import sinon from "sinon"
|
||||
import { ClineStorageMessage } from "@/shared/messages/content"
|
||||
import { mockFetchForTesting } from "@/shared/net"
|
||||
|
||||
const fakeClient = {
|
||||
@@ -109,7 +109,7 @@ describe("LiteLlmHandler", () => {
|
||||
|
||||
it("sends the system prompt and messages with the openai format", async () => {
|
||||
const systemPrompt = "Test System Prompt"
|
||||
const messages: ClineStorageMessage[] = [
|
||||
const messages: Anthropic.Messages.MessageParam[] = [
|
||||
{
|
||||
role: "user",
|
||||
content: "first message",
|
||||
@@ -161,7 +161,7 @@ describe("LiteLlmHandler", () => {
|
||||
|
||||
it("inserts the cache control in the system prompt and the last two user messages", async () => {
|
||||
const systemPrompt = "Test System Prompt"
|
||||
const messages: ClineStorageMessage[] = [
|
||||
const messages: Anthropic.Messages.MessageParam[] = [
|
||||
{
|
||||
role: "user",
|
||||
content: "first message",
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { afterEach, before, beforeEach, describe, it } from "mocha"
|
||||
import "should"
|
||||
import { Anthropic } from "@anthropic-ai/sdk"
|
||||
import { ApiHandlerOptions } from "@shared/api"
|
||||
import axios from "axios"
|
||||
import sinon from "sinon"
|
||||
import { ClineStorageMessage } from "@/shared/messages/content"
|
||||
import { OllamaHandler } from "../ollama"
|
||||
|
||||
describe("OllamaHandler", () => {
|
||||
@@ -59,7 +59,7 @@ describe("OllamaHandler", () => {
|
||||
} as any)
|
||||
|
||||
const systemPrompt = "You are a helpful assistant."
|
||||
const messages: ClineStorageMessage[] = [{ role: "user", content: "Hello" }]
|
||||
const messages: Anthropic.Messages.MessageParam[] = [{ role: "user", content: "Hello" }]
|
||||
|
||||
const result = []
|
||||
const usageInfo = []
|
||||
@@ -114,7 +114,7 @@ describe("OllamaHandler", () => {
|
||||
}
|
||||
|
||||
const systemPrompt = "You are a helpful assistant."
|
||||
const messages: ClineStorageMessage[] = [{ role: "user", content: "Hello" }]
|
||||
const messages: Anthropic.Messages.MessageParam[] = [{ role: "user", content: "Hello" }]
|
||||
|
||||
// Start the request and catch the error
|
||||
let errorMessage = ""
|
||||
@@ -158,7 +158,7 @@ describe("OllamaHandler", () => {
|
||||
} as any)
|
||||
|
||||
const systemPrompt = "You are a helpful assistant."
|
||||
const messages: ClineStorageMessage[] = [{ role: "user", content: "Hello" }]
|
||||
const messages: Anthropic.Messages.MessageParam[] = [{ role: "user", content: "Hello" }]
|
||||
|
||||
const result = []
|
||||
|
||||
@@ -204,7 +204,7 @@ describe("OllamaHandler", () => {
|
||||
}
|
||||
|
||||
const systemPrompt = "You are a helpful assistant."
|
||||
const messages: ClineStorageMessage[] = [{ role: "user", content: "Hello" }]
|
||||
const messages: Anthropic.Messages.MessageParam[] = [{ role: "user", content: "Hello" }]
|
||||
|
||||
const result = []
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ import { Anthropic } from "@anthropic-ai/sdk"
|
||||
import { Tool as AnthropicTool } from "@anthropic-ai/sdk/resources/index"
|
||||
import { Stream as AnthropicStream } from "@anthropic-ai/sdk/streaming"
|
||||
import { AnthropicModelId, anthropicDefaultModelId, anthropicModels, CLAUDE_SONNET_1M_SUFFIX, ModelInfo } from "@shared/api"
|
||||
import { ClineStorageMessage } from "@/shared/messages/content"
|
||||
import { fetch } from "@/shared/net"
|
||||
import { ClineTool } from "@/shared/tools"
|
||||
import { ApiHandler, CommonApiHandlerOptions } from "../index"
|
||||
@@ -44,7 +43,7 @@ export class AnthropicHandler implements ApiHandler {
|
||||
}
|
||||
|
||||
@withRetry()
|
||||
async *createMessage(systemPrompt: string, messages: ClineStorageMessage[], tools?: ClineTool[]): ApiStream {
|
||||
async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[], tools?: ClineTool[]): ApiStream {
|
||||
const client = this.ensureClient()
|
||||
|
||||
const model = this.getModel()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Anthropic } from "@anthropic-ai/sdk"
|
||||
import { AskSageModelId, askSageDefaultModelId, askSageDefaultURL, askSageModels, ModelInfo } from "@shared/api"
|
||||
import { ClineStorageMessage } from "@/shared/messages/content"
|
||||
import { fetch } from "@/shared/net"
|
||||
import { ApiHandler, CommonApiHandlerOptions } from ".."
|
||||
import { withRetry } from "../retry"
|
||||
@@ -47,7 +47,7 @@ export class AskSageHandler implements ApiHandler {
|
||||
}
|
||||
|
||||
@withRetry()
|
||||
async *createMessage(systemPrompt: string, messages: ClineStorageMessage[]): ApiStream {
|
||||
async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream {
|
||||
try {
|
||||
const model = this.getModel()
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Anthropic } from "@anthropic-ai/sdk"
|
||||
import { BasetenModelId, basetenDefaultModelId, basetenModels, ModelInfo } from "@shared/api"
|
||||
import { calculateApiCostOpenAI } from "@utils/cost"
|
||||
import OpenAI from "openai"
|
||||
import { ClineStorageMessage } from "@/shared/messages/content"
|
||||
import { fetch } from "@/shared/net"
|
||||
import { ApiHandler, CommonApiHandlerOptions } from "../"
|
||||
import { withRetry } from "../retry"
|
||||
@@ -98,7 +98,7 @@ export class BasetenHandler implements ApiHandler {
|
||||
}
|
||||
|
||||
@withRetry()
|
||||
async *createMessage(systemPrompt: string, messages: ClineStorageMessage[]): ApiStream {
|
||||
async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream {
|
||||
const client = this.ensureClient()
|
||||
const model = this.getModel()
|
||||
const maxTokens = this.getOptimalMaxTokens(model)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { Anthropic } from "@anthropic-ai/sdk"
|
||||
// Import proper AWS SDK types
|
||||
import type { ContentBlock, Message } from "@aws-sdk/client-bedrock-runtime"
|
||||
import {
|
||||
@@ -11,7 +12,6 @@ import { fromNodeProviderChain } from "@aws-sdk/credential-providers"
|
||||
import { BedrockModelId, bedrockDefaultModelId, bedrockModels, CLAUDE_SONNET_1M_SUFFIX, ModelInfo } from "@shared/api"
|
||||
import { calculateApiCostOpenAI, calculateApiCostQwen } from "@utils/cost"
|
||||
import { ExtensionRegistryInfo } from "@/registry"
|
||||
import { ClineStorageMessage } from "@/shared/messages/content"
|
||||
import { ApiHandler, CommonApiHandlerOptions } from "../"
|
||||
import { withRetry } from "../retry"
|
||||
import { convertToR1Format } from "../transform/r1-format"
|
||||
@@ -121,7 +121,7 @@ export class AwsBedrockHandler implements ApiHandler {
|
||||
}
|
||||
|
||||
@withRetry({ maxRetries: 4 })
|
||||
async *createMessage(systemPrompt: string, messages: ClineStorageMessage[]): ApiStream {
|
||||
async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream {
|
||||
// cross region inference requires prefixing the model id with the region
|
||||
const rawModelId = await this.getModelId()
|
||||
|
||||
@@ -342,7 +342,7 @@ export class AwsBedrockHandler implements ApiHandler {
|
||||
*/
|
||||
private async *createDeepseekMessage(
|
||||
systemPrompt: string,
|
||||
messages: ClineStorageMessage[],
|
||||
messages: Anthropic.Messages.MessageParam[],
|
||||
modelId: string,
|
||||
model: { id: string; info: ModelInfo },
|
||||
): ApiStream {
|
||||
@@ -480,7 +480,7 @@ export class AwsBedrockHandler implements ApiHandler {
|
||||
* First uses convertToR1Format to merge consecutive messages with the same role,
|
||||
* then converts to the string format that DeepSeek R1 expects
|
||||
*/
|
||||
private formatDeepseekR1Prompt(systemPrompt: string, messages: ClineStorageMessage[]): string {
|
||||
private formatDeepseekR1Prompt(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): string {
|
||||
// First use convertToR1Format to merge consecutive messages with the same role
|
||||
const r1Messages = convertToR1Format([{ role: "user", content: systemPrompt }, ...messages])
|
||||
|
||||
@@ -513,7 +513,7 @@ export class AwsBedrockHandler implements ApiHandler {
|
||||
* Estimates token count based on text length (approximate)
|
||||
* Note: This is a rough estimation, as the actual token count depends on the tokenizer
|
||||
*/
|
||||
private estimateInputTokens(systemPrompt: string, messages: ClineStorageMessage[]): number {
|
||||
private estimateInputTokens(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): number {
|
||||
// For Deepseek R1, we estimate the token count of the formatted prompt
|
||||
// The formatted prompt includes special tokens and consistent formatting
|
||||
const formattedPrompt = this.formatDeepseekR1Prompt(systemPrompt, messages)
|
||||
@@ -779,7 +779,7 @@ export class AwsBedrockHandler implements ApiHandler {
|
||||
*/
|
||||
private async *createAnthropicMessage(
|
||||
systemPrompt: string,
|
||||
messages: ClineStorageMessage[],
|
||||
messages: Anthropic.Messages.MessageParam[],
|
||||
modelId: string,
|
||||
model: { id: string; info: ModelInfo },
|
||||
enable1mContextWindow: boolean,
|
||||
@@ -835,7 +835,7 @@ export class AwsBedrockHandler implements ApiHandler {
|
||||
* Formats messages for models using the Converse API specification
|
||||
* Used by both Anthropic and Nova models to avoid code duplication
|
||||
*/
|
||||
private formatMessagesForConverseAPI(messages: ClineStorageMessage[]): Message[] {
|
||||
private formatMessagesForConverseAPI(messages: Anthropic.Messages.MessageParam[]): Message[] {
|
||||
return messages.map((message) => {
|
||||
// Determine role (user or assistant)
|
||||
const role = message.role === "user" ? ConversationRole.USER : ConversationRole.ASSISTANT
|
||||
@@ -968,7 +968,7 @@ export class AwsBedrockHandler implements ApiHandler {
|
||||
*/
|
||||
private async *createNovaMessage(
|
||||
systemPrompt: string,
|
||||
messages: ClineStorageMessage[],
|
||||
messages: Anthropic.Messages.MessageParam[],
|
||||
modelId: string,
|
||||
model: { id: string; info: ModelInfo },
|
||||
): ApiStream {
|
||||
@@ -1008,7 +1008,7 @@ export class AwsBedrockHandler implements ApiHandler {
|
||||
*/
|
||||
private async *createOpenAIMessage(
|
||||
systemPrompt: string,
|
||||
messages: ClineStorageMessage[],
|
||||
messages: Anthropic.Messages.MessageParam[],
|
||||
modelId: string,
|
||||
model: { id: string; info: ModelInfo },
|
||||
): ApiStream {
|
||||
@@ -1143,7 +1143,7 @@ export class AwsBedrockHandler implements ApiHandler {
|
||||
*/
|
||||
private async *createQwenMessage(
|
||||
systemPrompt: string,
|
||||
messages: ClineStorageMessage[],
|
||||
messages: Anthropic.Messages.MessageParam[],
|
||||
modelId: string,
|
||||
model: { id: string; info: ModelInfo },
|
||||
): ApiStream {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Anthropic } from "@anthropic-ai/sdk"
|
||||
import Cerebras from "@cerebras/cerebras_cloud_sdk"
|
||||
import { CerebrasModelId, cerebrasDefaultModelId, cerebrasModels, ModelInfo } from "@shared/api"
|
||||
import { ClineStorageMessage } from "@/shared/messages/content"
|
||||
import { fetch } from "@/shared/net"
|
||||
import { ApiHandler, CommonApiHandlerOptions } from "../index"
|
||||
import { withRetry } from "../retry"
|
||||
@@ -46,7 +46,7 @@ export class CerebrasHandler implements ApiHandler {
|
||||
baseDelay: 5000, // Start with 5 second delay
|
||||
maxDelay: 60000, // Allow up to 60 second delays to respect rate limits
|
||||
})
|
||||
async *createMessage(systemPrompt: string, messages: ClineStorageMessage[]): ApiStream {
|
||||
async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream {
|
||||
const client = this.ensureClient()
|
||||
|
||||
// Convert Anthropic messages to Cerebras format
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
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 { ClineStorageMessage } from "@/shared/messages/content"
|
||||
import { type ApiHandler, CommonApiHandlerOptions } from ".."
|
||||
import { withRetry } from "../retry"
|
||||
import { type ApiStream, ApiStreamUsageChunk } from "../transform/stream"
|
||||
@@ -24,7 +24,7 @@ export class ClaudeCodeHandler implements ApiHandler {
|
||||
baseDelay: 2000,
|
||||
maxDelay: 15000,
|
||||
})
|
||||
async *createMessage(systemPrompt: string, messages: ClineStorageMessage[]): ApiStream {
|
||||
async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream {
|
||||
// Filter out image blocks since Claude Code doesn't support them
|
||||
const filteredMessages = filterMessagesForClaudeCode(messages)
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { Anthropic } from "@anthropic-ai/sdk"
|
||||
import { ModelInfo, openRouterDefaultModelId, openRouterDefaultModelInfo } from "@shared/api"
|
||||
import { shouldSkipReasoningForModel } from "@utils/model-utils"
|
||||
import axios from "axios"
|
||||
@@ -8,7 +9,6 @@ import { ClineAccountService } from "@/services/account/ClineAccountService"
|
||||
import { AuthService } from "@/services/auth/AuthService"
|
||||
import { buildClineExtraHeaders } from "@/services/EnvUtils"
|
||||
import { CLINE_ACCOUNT_AUTH_ERROR_MESSAGE } from "@/shared/ClineAccount"
|
||||
import { ClineStorageMessage } from "@/shared/messages/content"
|
||||
import { fetch, getAxiosSettings } from "@/shared/net"
|
||||
import { ApiHandler, CommonApiHandlerOptions } from "../"
|
||||
import { withRetry } from "../retry"
|
||||
@@ -96,7 +96,7 @@ export class ClineHandler implements ApiHandler {
|
||||
}
|
||||
|
||||
@withRetry()
|
||||
async *createMessage(systemPrompt: string, messages: ClineStorageMessage[], tools?: OpenAITool[]): ApiStream {
|
||||
async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[], tools?: OpenAITool[]): ApiStream {
|
||||
try {
|
||||
const client = await this.ensureClient()
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { Anthropic } from "@anthropic-ai/sdk"
|
||||
import { DeepSeekModelId, deepSeekDefaultModelId, deepSeekModels, ModelInfo } from "@shared/api"
|
||||
import { calculateApiCostOpenAI } from "@utils/cost"
|
||||
import OpenAI from "openai"
|
||||
import type { ChatCompletionTool as OpenAITool } from "openai/resources/chat/completions"
|
||||
import { ClineStorageMessage } from "@/shared/messages/content"
|
||||
import { fetch } from "@/shared/net"
|
||||
import { ApiHandler, CommonApiHandlerOptions } from "../"
|
||||
import { withRetry } from "../retry"
|
||||
@@ -75,7 +75,7 @@ export class DeepSeekHandler implements ApiHandler {
|
||||
}
|
||||
|
||||
@withRetry()
|
||||
async *createMessage(systemPrompt: string, messages: ClineStorageMessage[], tools?: OpenAITool[]): ApiStream {
|
||||
async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[], tools?: OpenAITool[]): ApiStream {
|
||||
const client = this.ensureClient()
|
||||
const model = this.getModel()
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ClineStorageMessage } from "@/shared/messages/content"
|
||||
import { Anthropic } from "@anthropic-ai/sdk"
|
||||
import { fetch } from "@/shared/net"
|
||||
import { ModelInfo } from "../../../shared/api"
|
||||
import { ApiHandler } from "../index"
|
||||
@@ -97,7 +97,7 @@ export class DifyHandler implements ApiHandler {
|
||||
}
|
||||
}
|
||||
|
||||
async *createMessage(systemPrompt: string, messages: ClineStorageMessage[]): ApiStream {
|
||||
async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream {
|
||||
console.log("[DIFY DEBUG] createMessage called with:", {
|
||||
systemPromptLength: systemPrompt?.length || 0,
|
||||
messagesCount: messages?.length || 0,
|
||||
@@ -384,7 +384,7 @@ export class DifyHandler implements ApiHandler {
|
||||
}
|
||||
}
|
||||
|
||||
private convertMessagesToQuery(systemPrompt: string, messages: ClineStorageMessage[]): string {
|
||||
private convertMessagesToQuery(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): string {
|
||||
// Dify's context is managed by `conversation_id`. The `query` should be the last user message.
|
||||
// The system prompt is typically configured in the Dify App itself.
|
||||
const lastUserMessage = messages.filter((m) => m.role === "user").pop()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Anthropic } from "@anthropic-ai/sdk"
|
||||
import { DoubaoModelId, doubaoDefaultModelId, doubaoModels, ModelInfo } from "@shared/api"
|
||||
import OpenAI from "openai"
|
||||
import { ClineStorageMessage } from "@/shared/messages/content"
|
||||
import { fetch } from "@/shared/net"
|
||||
import { ApiHandler, CommonApiHandlerOptions } from ".."
|
||||
import { withRetry } from "../retry"
|
||||
@@ -50,7 +50,7 @@ export class DoubaoHandler implements ApiHandler {
|
||||
}
|
||||
|
||||
@withRetry()
|
||||
async *createMessage(systemPrompt: string, messages: ClineStorageMessage[]): ApiStream {
|
||||
async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream {
|
||||
const client = this.ensureClient()
|
||||
const model = this.getModel()
|
||||
const openAiMessages: OpenAI.Chat.ChatCompletionMessageParam[] = [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Anthropic } from "@anthropic-ai/sdk"
|
||||
import { FireworksModelId, fireworksDefaultModelId, fireworksModels, ModelInfo } from "@shared/api"
|
||||
import OpenAI from "openai"
|
||||
import { ClineStorageMessage } from "@/shared/messages/content"
|
||||
import { fetch } from "@/shared/net"
|
||||
import { ApiHandler, CommonApiHandlerOptions } from ".."
|
||||
import { withRetry } from "../retry"
|
||||
@@ -41,7 +41,7 @@ export class FireworksHandler implements ApiHandler {
|
||||
}
|
||||
|
||||
@withRetry()
|
||||
async *createMessage(systemPrompt: string, messages: ClineStorageMessage[]): ApiStream {
|
||||
async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream {
|
||||
const client = this.ensureClient()
|
||||
const modelId = this.options.fireworksModelId ?? ""
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { Anthropic } from "@anthropic-ai/sdk"
|
||||
// Restore GenerateContentConfig import and add GenerateContentResponseUsageMetadata
|
||||
import {
|
||||
ApiError,
|
||||
@@ -10,7 +11,6 @@ import {
|
||||
} from "@google/genai"
|
||||
import { GeminiModelId, geminiDefaultModelId, geminiModels, ModelInfo } from "@shared/api"
|
||||
import { telemetryService } from "@/services/telemetry"
|
||||
import { ClineStorageMessage } from "@/shared/messages/content"
|
||||
import { ApiHandler, CommonApiHandlerOptions } from "../"
|
||||
import { RetriableError, withRetry } from "../retry"
|
||||
import { convertAnthropicMessageToGemini } from "../transform/gemini-format"
|
||||
@@ -110,7 +110,7 @@ export class GeminiHandler implements ApiHandler {
|
||||
baseDelay: 2000,
|
||||
maxDelay: 15000,
|
||||
})
|
||||
async *createMessage(systemPrompt: string, messages: ClineStorageMessage[], tools?: GoogleTool[]): ApiStream {
|
||||
async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[], tools?: GoogleTool[]): ApiStream {
|
||||
const client = this.ensureClient()
|
||||
const { id: modelId, info } = this.getModel()
|
||||
const contents = messages.map(convertAnthropicMessageToGemini)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { Anthropic } from "@anthropic-ai/sdk"
|
||||
import { GroqModelId, groqDefaultModelId, groqModels, ModelInfo } from "@shared/api"
|
||||
import { calculateApiCostOpenAI } from "@utils/cost"
|
||||
import OpenAI from "openai"
|
||||
import type { ChatCompletionTool as OpenAITool } from "openai/resources/chat/completions"
|
||||
import { ClineStorageMessage } from "@/shared/messages/content"
|
||||
import { fetch } from "@/shared/net"
|
||||
import { ApiHandler, CommonApiHandlerOptions } from "../"
|
||||
import { withRetry } from "../retry"
|
||||
@@ -192,7 +192,7 @@ export class GroqHandler implements ApiHandler {
|
||||
}
|
||||
|
||||
@withRetry()
|
||||
async *createMessage(systemPrompt: string, messages: ClineStorageMessage[], tools?: OpenAITool[]): ApiStream {
|
||||
async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[], tools?: OpenAITool[]): ApiStream {
|
||||
const client = this.ensureClient()
|
||||
const model = this.getModel()
|
||||
const modelFamily = this.detectModelFamily(model.id)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Anthropic } from "@anthropic-ai/sdk"
|
||||
import { hicapModelInfoSaneDefaults, ModelInfo } from "@shared/api"
|
||||
import OpenAI from "openai"
|
||||
import type { ChatCompletionReasoningEffort } from "openai/resources/chat/completions"
|
||||
import { ClineStorageMessage } from "@/shared/messages/content"
|
||||
import { ApiHandler, CommonApiHandlerOptions } from "../index"
|
||||
import { withRetry } from "../retry"
|
||||
import { convertToOpenAiMessages } from "../transform/openai-format"
|
||||
@@ -44,7 +44,7 @@ export class HicapHandler implements ApiHandler {
|
||||
}
|
||||
|
||||
@withRetry()
|
||||
async *createMessage(systemPrompt: string, messages: ClineStorageMessage[]): ApiStream {
|
||||
async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream {
|
||||
const client = this.ensureClient()
|
||||
const modelId = this.options.hicapModelId ?? ""
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Anthropic } from "@anthropic-ai/sdk"
|
||||
import { HuaweiCloudMaasModelId, huaweiCloudMaasDefaultModelId, huaweiCloudMaasModels, ModelInfo } from "@shared/api"
|
||||
import OpenAI from "openai"
|
||||
import type { ChatCompletionTool as OpenAITool } from "openai/resources/chat/completions"
|
||||
import { ClineStorageMessage } from "@/shared/messages/content"
|
||||
import { fetch } from "@/shared/net"
|
||||
import { ApiHandler, CommonApiHandlerOptions } from ".."
|
||||
import { withRetry } from "../retry"
|
||||
@@ -62,7 +62,7 @@ export class HuaweiCloudMaaSHandler implements ApiHandler {
|
||||
}
|
||||
|
||||
@withRetry()
|
||||
async *createMessage(systemPrompt: string, messages: ClineStorageMessage[], tools?: OpenAITool[]): ApiStream {
|
||||
async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[], tools?: OpenAITool[]): ApiStream {
|
||||
const client = this.ensureClient()
|
||||
const model = this.getModel()
|
||||
const openAiMessages: OpenAI.Chat.ChatCompletionMessageParam[] = [
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { Anthropic } from "@anthropic-ai/sdk"
|
||||
import { HuggingFaceModelId, huggingFaceDefaultModelId, huggingFaceModels, ModelInfo } from "@shared/api"
|
||||
import { calculateApiCostOpenAI } from "@utils/cost"
|
||||
import OpenAI from "openai"
|
||||
import type { ChatCompletionTool as OpenAITool } from "openai/resources/chat/completions"
|
||||
import { ClineStorageMessage } from "@/shared/messages/content"
|
||||
import { fetch } from "@/shared/net"
|
||||
import { ApiHandler, CommonApiHandlerOptions } from "../"
|
||||
import { withRetry } from "../retry"
|
||||
@@ -69,7 +69,7 @@ export class HuggingFaceHandler implements ApiHandler {
|
||||
}
|
||||
|
||||
@withRetry()
|
||||
async *createMessage(systemPrompt: string, messages: ClineStorageMessage[], tools?: OpenAITool[]): ApiStream {
|
||||
async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[], tools?: OpenAITool[]): ApiStream {
|
||||
try {
|
||||
const client = this.ensureClient()
|
||||
const model = this.getModel()
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { Anthropic } from "@anthropic-ai/sdk"
|
||||
import { LiteLLMModelInfo, liteLlmDefaultModelId, liteLlmModelInfoSaneDefaults } from "@shared/api"
|
||||
import OpenAI from "openai"
|
||||
import { ClineStorageMessage } from "@/shared/messages/content"
|
||||
import { fetch } from "@/shared/net"
|
||||
import { isAnthropicModelId } from "@/utils/model-utils"
|
||||
import { ApiHandler, CommonApiHandlerOptions } from ".."
|
||||
@@ -184,7 +183,7 @@ export class LiteLlmHandler implements ApiHandler {
|
||||
}
|
||||
|
||||
@withRetry()
|
||||
async *createMessage(systemPrompt: string, messages: ClineStorageMessage[]): ApiStream {
|
||||
async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream {
|
||||
const client = this.ensureClient()
|
||||
const formattedMessages = convertToOpenAiMessages(messages)
|
||||
const systemMessage: OpenAI.Chat.ChatCompletionSystemMessageParam | Anthropic.Messages.TextBlockParam = {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { Anthropic } from "@anthropic-ai/sdk"
|
||||
import { type ModelInfo, openAiModelInfoSaneDefaults } from "@shared/api"
|
||||
import OpenAI from "openai"
|
||||
import type { ChatCompletionTool as OpenAITool } from "openai/resources/chat/completions"
|
||||
import { ClineStorageMessage } from "@/shared/messages/content"
|
||||
import { fetch } from "@/shared/net"
|
||||
import type { ApiHandler, CommonApiHandlerOptions } from "../"
|
||||
import { withRetry } from "../retry"
|
||||
@@ -40,7 +40,7 @@ export class LmStudioHandler implements ApiHandler {
|
||||
}
|
||||
|
||||
@withRetry({ retryAllErrors: true })
|
||||
async *createMessage(systemPrompt: string, messages: ClineStorageMessage[], tools?: OpenAITool[]): ApiStream {
|
||||
async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[], tools?: OpenAITool[]): ApiStream {
|
||||
const client = this.ensureClient()
|
||||
const openAiMessages: OpenAI.Chat.ChatCompletionMessageParam[] = [
|
||||
{ role: "system", content: systemPrompt },
|
||||
|
||||
@@ -2,7 +2,6 @@ import { Anthropic } from "@anthropic-ai/sdk"
|
||||
import { Tool as AnthropicTool } from "@anthropic-ai/sdk/resources/index"
|
||||
import { Stream as AnthropicStream } from "@anthropic-ai/sdk/streaming"
|
||||
import { MinimaxModelId, ModelInfo, minimaxDefaultModelId, minimaxModels } from "@/shared/api"
|
||||
import { ClineStorageMessage } from "@/shared/messages/content"
|
||||
import { fetch } from "@/shared/net"
|
||||
import { ClineTool } from "@/shared/tools"
|
||||
import { ApiHandler, CommonApiHandlerOptions } from "../index"
|
||||
@@ -46,7 +45,7 @@ export class MinimaxHandler implements ApiHandler {
|
||||
}
|
||||
|
||||
@withRetry()
|
||||
async *createMessage(systemPrompt: string, messages: ClineStorageMessage[], tools?: ClineTool[]): ApiStream {
|
||||
async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[], tools?: ClineTool[]): ApiStream {
|
||||
const client = this.ensureClient()
|
||||
const model = this.getModel()
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Anthropic } from "@anthropic-ai/sdk"
|
||||
import { Mistral } from "@mistralai/mistralai"
|
||||
import { HTTPClient } from "@mistralai/mistralai/lib/http"
|
||||
import { Tool as MistralTool } from "@mistralai/mistralai/models/components/tool"
|
||||
import { MistralModelId, ModelInfo, mistralDefaultModelId, mistralModels } from "@shared/api"
|
||||
import type { ChatCompletionTool as OpenAITool } from "openai/resources/chat/completions"
|
||||
import { ClineStorageMessage } from "@/shared/messages/content"
|
||||
import { fetch } from "@/shared/net"
|
||||
import { ApiHandler, CommonApiHandlerOptions } from "../"
|
||||
import { withRetry } from "../retry"
|
||||
@@ -48,7 +48,7 @@ export class MistralHandler implements ApiHandler {
|
||||
}
|
||||
|
||||
@withRetry()
|
||||
async *createMessage(systemPrompt: string, messages: ClineStorageMessage[], tools?: OpenAITool[]): ApiStream {
|
||||
async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[], tools?: OpenAITool[]): ApiStream {
|
||||
const client = this.ensureClient()
|
||||
const stream = await client.chat
|
||||
.stream({
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Anthropic } from "@anthropic-ai/sdk"
|
||||
import OpenAI from "openai"
|
||||
import type { ChatCompletionTool as OpenAITool } from "openai/resources/chat/completions"
|
||||
import { ModelInfo, MoonshotModelId, moonshotDefaultModelId, moonshotModels } from "@/shared/api"
|
||||
import { ClineStorageMessage } from "@/shared/messages/content"
|
||||
import { fetch } from "@/shared/net"
|
||||
import { ApiHandler, CommonApiHandlerOptions } from "../index"
|
||||
import { withRetry } from "../retry"
|
||||
@@ -40,7 +40,7 @@ export class MoonshotHandler implements ApiHandler {
|
||||
}
|
||||
|
||||
@withRetry()
|
||||
async *createMessage(systemPrompt: string, messages: ClineStorageMessage[], tools?: OpenAITool[]): ApiStream {
|
||||
async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[], tools?: OpenAITool[]): ApiStream {
|
||||
const client = this.ensureClient()
|
||||
const model = this.getModel()
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Anthropic } from "@anthropic-ai/sdk"
|
||||
import { type ModelInfo, type NebiusModelId, nebiusDefaultModelId, nebiusModels } from "@shared/api"
|
||||
import OpenAI from "openai"
|
||||
import type { ChatCompletionTool as OpenAITool } from "openai/resources/chat/completions"
|
||||
import { ClineStorageMessage } from "@/shared/messages/content"
|
||||
import { fetch } from "@/shared/net"
|
||||
import { ApiHandler, CommonApiHandlerOptions } from "../index"
|
||||
import { withRetry } from "../retry"
|
||||
@@ -39,7 +39,7 @@ export class NebiusHandler implements ApiHandler {
|
||||
}
|
||||
|
||||
@withRetry()
|
||||
async *createMessage(systemPrompt: string, messages: ClineStorageMessage[], tools?: OpenAITool[]): ApiStream {
|
||||
async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[], tools?: OpenAITool[]): ApiStream {
|
||||
const client = this.ensureClient()
|
||||
const model = this.getModel()
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Anthropic } from "@anthropic-ai/sdk"
|
||||
import { ModelInfo, NousResearchModelId, nousResearchDefaultModelId, nousResearchModels } from "@shared/api"
|
||||
import OpenAI from "openai"
|
||||
import { ClineStorageMessage } from "@/shared/messages/content"
|
||||
import { ApiHandler, CommonApiHandlerOptions } from "../index"
|
||||
import { withRetry } from "../retry"
|
||||
import { convertToOpenAiMessages } from "../transform/openai-format"
|
||||
@@ -37,7 +37,7 @@ export class NousResearchHandler implements ApiHandler {
|
||||
}
|
||||
|
||||
@withRetry()
|
||||
async *createMessage(systemPrompt: string, messages: ClineStorageMessage[]): ApiStream {
|
||||
async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream {
|
||||
const client = this.ensureClient()
|
||||
const model = this.getModel()
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { Anthropic } from "@anthropic-ai/sdk"
|
||||
import { LiteLLMModelInfo, liteLlmDefaultModelId, liteLlmModelInfoSaneDefaults } from "@shared/api"
|
||||
import OpenAI, { APIError, OpenAIError } from "openai"
|
||||
import type { FinalRequestOptions, Headers as OpenAIHeaders } from "openai/core"
|
||||
@@ -10,7 +11,6 @@ import {
|
||||
} from "@/services/auth/oca/utils/constants"
|
||||
import { createOcaHeaders } from "@/services/auth/oca/utils/utils"
|
||||
import { Logger } from "@/services/logging/Logger"
|
||||
import { ClineStorageMessage } from "@/shared/messages/content"
|
||||
import { fetch } from "@/shared/net"
|
||||
import { ApiHandler, type CommonApiHandlerOptions } from ".."
|
||||
import { withRetry } from "../retry"
|
||||
@@ -139,7 +139,7 @@ export class OcaHandler implements ApiHandler {
|
||||
}
|
||||
|
||||
@withRetry()
|
||||
async *createMessage(systemPrompt: string, messages: ClineStorageMessage[], tools?: OpenAITool[]): ApiStream {
|
||||
async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[], tools?: OpenAITool[]): ApiStream {
|
||||
const client = this.ensureClient()
|
||||
const formattedMessages = convertToOpenAiMessages(messages)
|
||||
const systemMessage: OpenAI.Chat.ChatCompletionSystemMessageParam = {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { Anthropic } from "@anthropic-ai/sdk"
|
||||
import { type ModelInfo, openAiModelInfoSaneDefaults } from "@shared/api"
|
||||
import { type Config, type Message, Ollama } from "ollama"
|
||||
import { ClineStorageMessage } from "@/shared/messages/content"
|
||||
import type { ApiHandler, CommonApiHandlerOptions } from "../"
|
||||
import { withRetry } from "../retry"
|
||||
import { convertToOllamaMessages } from "../transform/ollama-format"
|
||||
@@ -48,7 +48,7 @@ export class OllamaHandler implements ApiHandler {
|
||||
}
|
||||
|
||||
@withRetry({ retryAllErrors: true })
|
||||
async *createMessage(systemPrompt: string, messages: ClineStorageMessage[]): ApiStream {
|
||||
async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream {
|
||||
const client = this.ensureClient()
|
||||
const ollamaMessages: Message[] = [{ role: "system", content: systemPrompt }, ...convertToOllamaMessages(messages)]
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { Anthropic } from "@anthropic-ai/sdk"
|
||||
import { ModelInfo, OpenAiNativeModelId, openAiNativeDefaultModelId, openAiNativeModels } from "@shared/api"
|
||||
import { calculateApiCostOpenAI } from "@utils/cost"
|
||||
import OpenAI from "openai"
|
||||
import type { ChatCompletionReasoningEffort, ChatCompletionTool } from "openai/resources/chat/completions"
|
||||
import { ClineStorageMessage } from "@/shared/messages/content"
|
||||
import { fetch } from "@/shared/net"
|
||||
import { ApiHandler, CommonApiHandlerOptions } from "../"
|
||||
import { withRetry } from "../retry"
|
||||
@@ -59,7 +59,11 @@ export class OpenAiNativeHandler implements ApiHandler {
|
||||
}
|
||||
|
||||
@withRetry()
|
||||
async *createMessage(systemPrompt: string, messages: ClineStorageMessage[], tools?: ChatCompletionTool[]): ApiStream {
|
||||
async *createMessage(
|
||||
systemPrompt: string,
|
||||
messages: Anthropic.Messages.MessageParam[],
|
||||
tools?: ChatCompletionTool[],
|
||||
): ApiStream {
|
||||
const client = this.ensureClient()
|
||||
const model = this.getModel()
|
||||
const toolCallProcessor = new ToolCallProcessor()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Anthropic } from "@anthropic-ai/sdk"
|
||||
import { azureOpenAiDefaultApiVersion, ModelInfo, OpenAiCompatibleModelInfo, openAiModelInfoSaneDefaults } from "@shared/api"
|
||||
import OpenAI, { AzureOpenAI } from "openai"
|
||||
import type { ChatCompletionReasoningEffort, ChatCompletionTool } from "openai/resources/chat/completions"
|
||||
import { ClineStorageMessage } from "@/shared/messages/content"
|
||||
import { fetch } from "@/shared/net"
|
||||
import { ApiHandler, CommonApiHandlerOptions } from "../index"
|
||||
import { withRetry } from "../retry"
|
||||
@@ -65,7 +65,11 @@ export class OpenAiHandler implements ApiHandler {
|
||||
}
|
||||
|
||||
@withRetry()
|
||||
async *createMessage(systemPrompt: string, messages: ClineStorageMessage[], tools?: ChatCompletionTool[]): ApiStream {
|
||||
async *createMessage(
|
||||
systemPrompt: string,
|
||||
messages: Anthropic.Messages.MessageParam[],
|
||||
tools?: ChatCompletionTool[],
|
||||
): ApiStream {
|
||||
const client = this.ensureClient()
|
||||
const modelId = this.options.openAiModelId ?? ""
|
||||
const isDeepseekReasoner = modelId.includes("deepseek-reasoner")
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { setTimeout as setTimeoutPromise } from "node:timers/promises"
|
||||
import { Anthropic } from "@anthropic-ai/sdk"
|
||||
import { ModelInfo, openRouterDefaultModelId, openRouterDefaultModelInfo } from "@shared/api"
|
||||
import { shouldSkipReasoningForModel } from "@utils/model-utils"
|
||||
import axios from "axios"
|
||||
import OpenAI from "openai"
|
||||
import type { ChatCompletionTool as OpenAITool } from "openai/resources/chat/completions"
|
||||
import { ClineStorageMessage } from "@/shared/messages/content"
|
||||
import { fetch, getAxiosSettings } from "@/shared/net"
|
||||
import { ApiHandler, CommonApiHandlerOptions } from "../"
|
||||
import { withRetry } from "../retry"
|
||||
@@ -54,7 +54,7 @@ export class OpenRouterHandler implements ApiHandler {
|
||||
}
|
||||
|
||||
@withRetry()
|
||||
async *createMessage(systemPrompt: string, messages: ClineStorageMessage[], tools?: OpenAITool[]): ApiStream {
|
||||
async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[], tools?: OpenAITool[]): ApiStream {
|
||||
const client = this.ensureClient()
|
||||
this.lastGenerationId = undefined
|
||||
|
||||
@@ -214,9 +214,11 @@ export class OpenRouterHandler implements ApiHandler {
|
||||
}
|
||||
|
||||
getModel(): { id: string; info: ModelInfo } {
|
||||
return {
|
||||
id: this.options.openRouterModelId || openRouterDefaultModelId,
|
||||
info: this.options.openRouterModelInfo || openRouterDefaultModelInfo,
|
||||
const modelId = this.options.openRouterModelId
|
||||
const modelInfo = this.options.openRouterModelInfo
|
||||
if (modelId && modelInfo) {
|
||||
return { id: modelId, info: modelInfo }
|
||||
}
|
||||
return { id: openRouterDefaultModelId, info: openRouterDefaultModelInfo }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { promises as fs } from "node:fs"
|
||||
import { Anthropic } from "@anthropic-ai/sdk"
|
||||
import { ModelInfo, QwenCodeModelId, qwenCodeDefaultModelId, qwenCodeModels } from "@shared/api"
|
||||
import OpenAI from "openai"
|
||||
import type { ChatCompletionTool as OpenAITool } from "openai/resources/chat/completions"
|
||||
import * as os from "os"
|
||||
import * as path from "path"
|
||||
import { ClineStorageMessage } from "@/shared/messages/content"
|
||||
import { fetch } from "@/shared/net"
|
||||
import { ApiHandler, CommonApiHandlerOptions } from "../"
|
||||
import { withRetry } from "../retry"
|
||||
@@ -177,7 +177,7 @@ export class QwenCodeHandler implements ApiHandler {
|
||||
}
|
||||
|
||||
@withRetry()
|
||||
async *createMessage(systemPrompt: string, messages: ClineStorageMessage[], tools?: OpenAITool[]): ApiStream {
|
||||
async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[], tools?: OpenAITool[]): ApiStream {
|
||||
await this.ensureAuthenticated()
|
||||
const client = this.ensureClient()
|
||||
const model = this.getModel()
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { Anthropic } from "@anthropic-ai/sdk"
|
||||
import {
|
||||
InternationalQwenModelId,
|
||||
internationalQwenDefaultModelId,
|
||||
@@ -10,7 +11,6 @@ import {
|
||||
} from "@shared/api"
|
||||
import OpenAI from "openai"
|
||||
import type { ChatCompletionTool as OpenAITool } from "openai/resources/chat/completions"
|
||||
import { ClineStorageMessage } from "@/shared/messages/content"
|
||||
import { fetch } from "@/shared/net"
|
||||
import { ApiHandler, CommonApiHandlerOptions } from "../"
|
||||
import { withRetry } from "../retry"
|
||||
@@ -81,7 +81,7 @@ export class QwenHandler implements ApiHandler {
|
||||
}
|
||||
|
||||
@withRetry()
|
||||
async *createMessage(systemPrompt: string, messages: ClineStorageMessage[], tools?: OpenAITool[]): ApiStream {
|
||||
async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[], tools?: OpenAITool[]): ApiStream {
|
||||
const client = this.ensureClient()
|
||||
const model = this.getModel()
|
||||
const isDeepseekReasoner = model.id.includes("deepseek-r1")
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { Anthropic } from "@anthropic-ai/sdk"
|
||||
import { ModelInfo, requestyDefaultModelId, requestyDefaultModelInfo } from "@shared/api"
|
||||
import { calculateApiCostOpenAI } from "@utils/cost"
|
||||
import OpenAI from "openai"
|
||||
import { toRequestyServiceStringUrl } from "@/shared/clients/requesty"
|
||||
import { ClineStorageMessage } from "@/shared/messages/content"
|
||||
import { fetch } from "@/shared/net"
|
||||
import { ApiHandler, CommonApiHandlerOptions } from "../index"
|
||||
import { withRetry } from "../retry"
|
||||
@@ -59,7 +59,7 @@ export class RequestyHandler implements ApiHandler {
|
||||
}
|
||||
|
||||
@withRetry()
|
||||
async *createMessage(systemPrompt: string, messages: ClineStorageMessage[]): ApiStream {
|
||||
async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream {
|
||||
const client = this.ensureClient()
|
||||
const model = this.getModel()
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Anthropic } from "@anthropic-ai/sdk"
|
||||
import { ModelInfo, SambanovaModelId, sambanovaDefaultModelId, sambanovaModels } from "@shared/api"
|
||||
import OpenAI from "openai"
|
||||
import type { ChatCompletionTool as OpenAITool } from "openai/resources/chat/completions"
|
||||
import { ClineStorageMessage } from "@/shared/messages/content"
|
||||
import { fetch } from "@/shared/net"
|
||||
import { ApiHandler, CommonApiHandlerOptions } from "../index"
|
||||
import { withRetry } from "../retry"
|
||||
@@ -42,7 +42,7 @@ export class SambanovaHandler implements ApiHandler {
|
||||
}
|
||||
|
||||
@withRetry()
|
||||
async *createMessage(systemPrompt: string, messages: ClineStorageMessage[], tools?: OpenAITool[]): ApiStream {
|
||||
async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[], tools?: OpenAITool[]): ApiStream {
|
||||
const client = this.ensureClient()
|
||||
const model = this.getModel()
|
||||
|
||||
|
||||
@@ -4,11 +4,10 @@ import {
|
||||
ConversationRole as BedrockConversationRole,
|
||||
type Message as BedrockMessage,
|
||||
} from "@aws-sdk/client-bedrock-runtime"
|
||||
import { ChatMessage, OrchestrationClient, OrchestrationModuleConfig } from "@sap-ai-sdk/orchestration"
|
||||
import { ChatMessages, LlmModuleConfig, OrchestrationClient, TemplatingModuleConfig } from "@sap-ai-sdk/orchestration"
|
||||
import { ModelInfo, SapAiCoreModelId, sapAiCoreDefaultModelId, sapAiCoreModels } from "@shared/api"
|
||||
import axios from "axios"
|
||||
import OpenAI from "openai"
|
||||
import { ClineStorageMessage } from "@/shared/messages/content"
|
||||
import { getAxiosSettings } from "@/shared/net"
|
||||
import { ApiHandler, CommonApiHandlerOptions } from "../"
|
||||
import { withRetry } from "../retry"
|
||||
@@ -116,7 +115,7 @@ namespace Bedrock {
|
||||
* Formats messages for models using the Converse API specification
|
||||
* Used by both Anthropic and Nova models to avoid code duplication
|
||||
*/
|
||||
export function formatMessagesForConverseAPI(messages: ClineStorageMessage[]): BedrockMessage[] {
|
||||
export function formatMessagesForConverseAPI(messages: Anthropic.Messages.MessageParam[]): BedrockMessage[] {
|
||||
return messages.map((message) => {
|
||||
// Determine role (user or assistant)
|
||||
const role = message.role === "user" ? BedrockConversationRole.USER : BedrockConversationRole.ASSISTANT
|
||||
@@ -316,7 +315,7 @@ namespace Gemini {
|
||||
*/
|
||||
export function prepareRequestPayload(
|
||||
systemPrompt: string,
|
||||
messages: ClineStorageMessage[],
|
||||
messages: Anthropic.Messages.MessageParam[],
|
||||
model: { id: SapAiCoreModelId; info: ModelInfo },
|
||||
thinkingBudgetTokens?: number,
|
||||
): any {
|
||||
@@ -459,7 +458,7 @@ export class SapAiCoreHandler implements ApiHandler {
|
||||
}
|
||||
|
||||
@withRetry()
|
||||
async *createMessage(systemPrompt: string, messages: ClineStorageMessage[]): ApiStream {
|
||||
async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream {
|
||||
if (this.options.sapAiCoreUseOrchestrationMode) {
|
||||
yield* this.createMessageWithOrchestration(systemPrompt, messages)
|
||||
} else {
|
||||
@@ -491,31 +490,29 @@ export class SapAiCoreHandler implements ApiHandler {
|
||||
this.isAiCoreEnvSetup = true
|
||||
}
|
||||
|
||||
private async *createMessageWithOrchestration(systemPrompt: string, messages: ClineStorageMessage[]): ApiStream {
|
||||
private async *createMessageWithOrchestration(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream {
|
||||
try {
|
||||
// Ensure AI Core environment variable is set up (only runs once)
|
||||
this.ensureAiCoreEnvSetup()
|
||||
const model = this.getModel()
|
||||
|
||||
const orchestrationConfig: OrchestrationModuleConfig = {
|
||||
promptTemplating: {
|
||||
model: {
|
||||
name: model.id,
|
||||
},
|
||||
prompt: {
|
||||
template: [
|
||||
{
|
||||
role: "system",
|
||||
content: systemPrompt,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
// Define the LLM to be used by the Orchestration pipeline
|
||||
const llm: LlmModuleConfig = {
|
||||
model_name: model.id,
|
||||
}
|
||||
|
||||
const orchestrationClient = new OrchestrationClient(orchestrationConfig, {
|
||||
resourceGroup: this.options.sapAiResourceGroup || "default",
|
||||
})
|
||||
const templating: TemplatingModuleConfig = {
|
||||
template: [
|
||||
{
|
||||
role: "system",
|
||||
content: systemPrompt,
|
||||
},
|
||||
],
|
||||
}
|
||||
const orchestrationClient = new OrchestrationClient(
|
||||
{ llm, templating },
|
||||
{ resourceGroup: this.options.sapAiResourceGroup || "default" },
|
||||
)
|
||||
|
||||
const sapMessages = this.convertMessageParamToSAPMessages(messages)
|
||||
|
||||
@@ -541,7 +538,7 @@ export class SapAiCoreHandler implements ApiHandler {
|
||||
}
|
||||
}
|
||||
|
||||
private async *createMessageWithDeployments(systemPrompt: string, messages: ClineStorageMessage[]): ApiStream {
|
||||
private async *createMessageWithDeployments(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream {
|
||||
const token = await this.getToken()
|
||||
const headers = {
|
||||
Authorization: `Bearer ${token}`,
|
||||
@@ -1043,8 +1040,8 @@ export class SapAiCoreHandler implements ApiHandler {
|
||||
}
|
||||
return { id: sapAiCoreDefaultModelId, info: sapAiCoreModels[sapAiCoreDefaultModelId] }
|
||||
}
|
||||
private convertMessageParamToSAPMessages(messages: ClineStorageMessage[]): ChatMessage[] {
|
||||
private convertMessageParamToSAPMessages(messages: Anthropic.Messages.MessageParam[]): ChatMessages {
|
||||
// Use the existing OpenAI converter since the logic is identical
|
||||
return convertToOpenAiMessages(messages) as ChatMessage[]
|
||||
return convertToOpenAiMessages(messages) as ChatMessages
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Anthropic } from "@anthropic-ai/sdk"
|
||||
import { ModelInfo, openAiModelInfoSaneDefaults } from "@shared/api"
|
||||
import OpenAI from "openai"
|
||||
import type { ChatCompletionTool as OpenAITool } from "openai/resources/chat/completions"
|
||||
import { ClineStorageMessage } from "@/shared/messages/content"
|
||||
import { fetch } from "@/shared/net"
|
||||
import { ApiHandler, CommonApiHandlerOptions } from "../index"
|
||||
import { withRetry } from "../retry"
|
||||
@@ -42,7 +42,7 @@ export class TogetherHandler implements ApiHandler {
|
||||
}
|
||||
|
||||
@withRetry()
|
||||
async *createMessage(systemPrompt: string, messages: ClineStorageMessage[], tools?: OpenAITool[]): ApiStream {
|
||||
async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[], tools?: OpenAITool[]): ApiStream {
|
||||
const client = this.ensureClient()
|
||||
const modelId = this.options.togetherModelId ?? ""
|
||||
const isDeepseekReasoner = modelId.includes("deepseek-reasoner")
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Anthropic } from "@anthropic-ai/sdk"
|
||||
import { ModelInfo, openRouterDefaultModelId, openRouterDefaultModelInfo } from "@shared/api"
|
||||
import OpenAI from "openai"
|
||||
import type { ChatCompletionTool as OpenAITool } from "openai/resources/chat/completions"
|
||||
import { ClineStorageMessage } from "@/shared/messages/content"
|
||||
import { fetch } from "@/shared/net"
|
||||
import { ApiHandler, CommonApiHandlerOptions } from "../index"
|
||||
import { withRetry } from "../retry"
|
||||
@@ -47,7 +47,7 @@ export class VercelAIGatewayHandler implements ApiHandler {
|
||||
}
|
||||
|
||||
@withRetry()
|
||||
async *createMessage(systemPrompt: string, messages: ClineStorageMessage[], tools?: OpenAITool[]): ApiStream {
|
||||
async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[], tools?: OpenAITool[]): ApiStream {
|
||||
const client = this.ensureClient()
|
||||
const modelId = this.getModel().id
|
||||
const modelInfo = this.getModel().info
|
||||
@@ -102,16 +102,22 @@ export class VercelAIGatewayHandler implements ApiHandler {
|
||||
}
|
||||
|
||||
if (!didOutputUsage && chunk.usage) {
|
||||
const inputTokens = chunk.usage.prompt_tokens || 0
|
||||
const outputTokens =
|
||||
(chunk.usage.completion_tokens || 0) + (chunk.usage.completion_tokens_details?.reasoning_tokens || 0)
|
||||
|
||||
const cacheReadTokens = chunk.usage.prompt_tokens_details?.cached_tokens || 0
|
||||
// @ts-ignore - Vercel AI Gateway extends OpenAI types
|
||||
const totalCost = (chunk.usage.cost || 0) + (chunk.usage.cost_details?.upstream_inference_cost || 0)
|
||||
const cacheWriteTokens = chunk.usage.cache_creation_input_tokens || 0
|
||||
|
||||
yield {
|
||||
type: "usage",
|
||||
cacheWriteTokens: 0,
|
||||
cacheReadTokens: chunk.usage.prompt_tokens_details?.cached_tokens || 0,
|
||||
inputTokens: (chunk.usage.prompt_tokens || 0) - (chunk.usage.prompt_tokens_details?.cached_tokens || 0),
|
||||
outputTokens: chunk.usage.completion_tokens || 0,
|
||||
totalCost,
|
||||
inputTokens: inputTokens,
|
||||
outputTokens: outputTokens,
|
||||
cacheWriteTokens: cacheWriteTokens,
|
||||
cacheReadTokens: cacheReadTokens,
|
||||
// @ts-expect-error - Vercel AI Gateway extends OpenAI types
|
||||
totalCost: chunk.usage.cost || 0,
|
||||
}
|
||||
didOutputUsage = true
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { Anthropic } from "@anthropic-ai/sdk"
|
||||
import { Tool as AnthropicTool } from "@anthropic-ai/sdk/resources/index"
|
||||
import { AnthropicVertex } from "@anthropic-ai/vertex-sdk"
|
||||
import { FunctionDeclaration as GoogleTool } from "@google/genai"
|
||||
import { ModelInfo, VertexModelId, vertexDefaultModelId, vertexModels } from "@shared/api"
|
||||
import { ClineStorageMessage } from "@/shared/messages/content"
|
||||
import { ClineTool } from "@/shared/tools"
|
||||
import { ApiHandler, CommonApiHandlerOptions } from "../"
|
||||
import { withRetry } from "../retry"
|
||||
@@ -67,7 +67,7 @@ export class VertexHandler implements ApiHandler {
|
||||
}
|
||||
|
||||
@withRetry()
|
||||
async *createMessage(systemPrompt: string, messages: ClineStorageMessage[], tools?: ClineTool[]): ApiStream {
|
||||
async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[], tools?: ClineTool[]): ApiStream {
|
||||
const model = this.getModel()
|
||||
const modelId = model.id
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { Anthropic } from "@anthropic-ai/sdk"
|
||||
import { ModelInfo, openAiModelInfoSaneDefaults } from "@shared/api"
|
||||
import { SELECTOR_SEPARATOR, stringifyVsCodeLmModelSelector } from "@shared/vsCodeSelectorUtils"
|
||||
import { calculateApiCostAnthropic } from "@utils/cost"
|
||||
import * as vscode from "vscode"
|
||||
import { ClineStorageMessage } from "@/shared/messages/content"
|
||||
import { ApiHandler, CommonApiHandlerOptions, SingleCompletionHandler } from "../"
|
||||
import { withRetry } from "../retry"
|
||||
import { ApiStream } from "../transform/stream"
|
||||
@@ -366,7 +366,7 @@ export class VsCodeLmHandler implements ApiHandler, SingleCompletionHandler {
|
||||
}
|
||||
|
||||
@withRetry()
|
||||
async *createMessage(systemPrompt: string, messages: ClineStorageMessage[]): ApiStream {
|
||||
async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream {
|
||||
// Ensure clean state before starting a new request
|
||||
this.ensureCleanState()
|
||||
const client: vscode.LanguageModelChat = await this.getClient()
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Anthropic } from "@anthropic-ai/sdk"
|
||||
import { ModelInfo, XAIModelId, xaiDefaultModelId, xaiModels } from "@shared/api"
|
||||
import { shouldSkipReasoningForModel } from "@utils/model-utils"
|
||||
import OpenAI from "openai"
|
||||
import type { ChatCompletionTool as OpenAITool } from "openai/resources/chat/completions"
|
||||
import { ChatCompletionReasoningEffort } from "openai/resources/chat/completions"
|
||||
import { ClineStorageMessage } from "@/shared/messages/content"
|
||||
import { fetch } from "@/shared/net"
|
||||
import { ApiHandler, CommonApiHandlerOptions } from "../"
|
||||
import { withRetry } from "../retry"
|
||||
@@ -44,7 +44,7 @@ export class XAIHandler implements ApiHandler {
|
||||
}
|
||||
|
||||
@withRetry()
|
||||
async *createMessage(systemPrompt: string, messages: ClineStorageMessage[], tools?: OpenAITool[]): ApiStream {
|
||||
async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[], tools?: OpenAITool[]): ApiStream {
|
||||
const client = this.ensureClient()
|
||||
const modelId = this.getModel().id
|
||||
// ensure reasoning effort is either "low" or "high" for grok-3-mini
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { Anthropic } from "@anthropic-ai/sdk"
|
||||
import {
|
||||
internationalZAiDefaultModelId,
|
||||
internationalZAiModelId,
|
||||
@@ -9,7 +10,6 @@ import {
|
||||
} from "@shared/api"
|
||||
import OpenAI from "openai"
|
||||
import type { ChatCompletionTool as OpenAITool } from "openai/resources/chat/completions"
|
||||
import { ClineStorageMessage } from "@/shared/messages/content"
|
||||
import { fetch } from "@/shared/net"
|
||||
import { version as extensionVersion } from "../../../../package.json"
|
||||
import { ApiHandler, CommonApiHandlerOptions } from ".."
|
||||
@@ -76,7 +76,7 @@ export class ZAiHandler implements ApiHandler {
|
||||
}
|
||||
|
||||
@withRetry()
|
||||
async *createMessage(systemPrompt: string, messages: ClineStorageMessage[], tools?: OpenAITool[]): ApiStream {
|
||||
async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[], tools?: OpenAITool[]): ApiStream {
|
||||
const client = this.ensureClient()
|
||||
const model = this.getModel()
|
||||
const openAiMessages: OpenAI.Chat.ChatCompletionMessageParam[] = [
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import Anthropic from "@anthropic-ai/sdk"
|
||||
import { ClineContent, ClineStorageMessage } from "@/shared/messages/content"
|
||||
import { ClineStorageMessage } from "@/shared/messages/content"
|
||||
|
||||
/**
|
||||
* Sanitize Anthropic messages by removing reasoning details and adding ephemeral cache control
|
||||
@@ -63,22 +63,14 @@ function removeUnknownParams(param: ClineStorageMessage): Anthropic.Messages.Mes
|
||||
// Construct new content array with known Anthropic content blocks only.
|
||||
return {
|
||||
role: param.role === "user" ? "user" : "assistant",
|
||||
content: Array.isArray(param.content) ? param.content.map(sanitizeAnthropicContentBlock) : param.content, // String content remains unchanged
|
||||
content: Array.isArray(param.content)
|
||||
? param.content.map((item) => {
|
||||
return {
|
||||
...item,
|
||||
// Ensure reasoning_details is removed
|
||||
reasoning_details: undefined,
|
||||
}
|
||||
})
|
||||
: param.content, // String content remains unchanged
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean a content block by removing Cline-specific fields and returning only provider-compatible fields
|
||||
*/
|
||||
function sanitizeAnthropicContentBlock(block: ClineContent): Anthropic.ContentBlock {
|
||||
// Fast path: if no reasoning_details property exists, return as-is
|
||||
// Including reasoning_details in non-openrouter/cline providers may cause API errors
|
||||
if (!("reasoning_details" in block)) {
|
||||
return block as Anthropic.ContentBlock
|
||||
}
|
||||
|
||||
// Remove reasoning_details from text blocks
|
||||
// biome-ignore lint/correctness/noUnusedVariables: intentional destructuring to remove property
|
||||
const { reasoning_details, ...cleanBlock } = block
|
||||
return cleanBlock as Anthropic.ContentBlock
|
||||
}
|
||||
|
||||
@@ -1,29 +1,29 @@
|
||||
import type { Anthropic } from "@anthropic-ai/sdk"
|
||||
import { Anthropic } from "@anthropic-ai/sdk"
|
||||
import { buildApiHandler } from "@core/api"
|
||||
import { tryAcquireTaskLockWithRetry } from "@core/task/TaskLockUtils"
|
||||
import { detectWorkspaceRoots } from "@core/workspace/detection"
|
||||
import { setupWorkspaceManager } from "@core/workspace/setup"
|
||||
import type { WorkspaceRootManager } from "@core/workspace/WorkspaceRootManager"
|
||||
import { WorkspaceRootManager } from "@core/workspace/WorkspaceRootManager"
|
||||
import { cleanupLegacyCheckpoints } from "@integrations/checkpoints/CheckpointMigration"
|
||||
import { downloadTask } from "@integrations/misc/export-markdown"
|
||||
import { ClineAccountService } from "@services/account/ClineAccountService"
|
||||
import { McpHub } from "@services/mcp/McpHub"
|
||||
import type { ApiProvider, ModelInfo } from "@shared/api"
|
||||
import type { ChatContent } from "@shared/ChatContent"
|
||||
import type { ExtensionState, Platform } from "@shared/ExtensionMessage"
|
||||
import type { HistoryItem } from "@shared/HistoryItem"
|
||||
import type { McpMarketplaceCatalog, McpMarketplaceItem } from "@shared/mcp"
|
||||
import type { Settings } from "@shared/storage/state-keys"
|
||||
import type { Mode } from "@shared/storage/types"
|
||||
import type { TelemetrySetting } from "@shared/TelemetrySetting"
|
||||
import type { UserInfo } from "@shared/UserInfo"
|
||||
import { ApiProvider, ModelInfo } from "@shared/api"
|
||||
import { ChatContent } from "@shared/ChatContent"
|
||||
import { ExtensionState, Platform } from "@shared/ExtensionMessage"
|
||||
import { HistoryItem } from "@shared/HistoryItem"
|
||||
import { McpMarketplaceCatalog, McpMarketplaceItem } from "@shared/mcp"
|
||||
import { Settings } from "@shared/storage/state-keys"
|
||||
import { Mode } from "@shared/storage/types"
|
||||
import { TelemetrySetting } from "@shared/TelemetrySetting"
|
||||
import { UserInfo } from "@shared/UserInfo"
|
||||
import { fileExistsAtPath } from "@utils/fs"
|
||||
import axios from "axios"
|
||||
import fs from "fs/promises"
|
||||
import pWaitFor from "p-wait-for"
|
||||
import * as path from "path"
|
||||
import type { FolderLockWithRetryResult } from "src/core/locks/types"
|
||||
import type * as vscode from "vscode"
|
||||
import * as vscode from "vscode"
|
||||
import { ClineEnv } from "@/config"
|
||||
import { HostProvider } from "@/hosts/host-provider"
|
||||
import { ExtensionRegistryInfo } from "@/registry"
|
||||
@@ -35,7 +35,7 @@ import { getDistinctId } from "@/services/logging/distinctId"
|
||||
import { telemetryService } from "@/services/telemetry"
|
||||
import { getAxiosSettings } from "@/shared/net"
|
||||
import { ShowMessageType } from "@/shared/proto/host/window"
|
||||
import type { AuthState } from "@/shared/proto/index.cline"
|
||||
import { AuthState } from "@/shared/proto/index.cline"
|
||||
import { getLatestAnnouncementId } from "@/utils/announcements"
|
||||
import { getCwd, getDesktopDir } from "@/utils/path"
|
||||
import { PromptRegistry } from "../prompts/system-prompt"
|
||||
@@ -47,11 +47,10 @@ import {
|
||||
writeMcpMarketplaceCatalogToCache,
|
||||
} from "../storage/disk"
|
||||
import { fetchRemoteConfig } from "../storage/remote-config/fetch"
|
||||
import { type PersistenceErrorEvent, StateManager } from "../storage/StateManager"
|
||||
import { PersistenceErrorEvent, StateManager } from "../storage/StateManager"
|
||||
import { Task } from "../task"
|
||||
import type { StreamingResponseHandler } from "./grpc-handler"
|
||||
import { StreamingResponseHandler } from "./grpc-handler"
|
||||
import { sendMcpMarketplaceCatalogEvent } from "./mcp/subscribeToMcpMarketplaceCatalog"
|
||||
import { getClineOnboardingModels } from "./models/getClineOnboardingModels"
|
||||
import { appendClineStealthModels } from "./models/refreshOpenRouterModels"
|
||||
import { checkCliInstallation } from "./state/checkCliInstallation"
|
||||
import { sendStateUpdate } from "./state/subscribeToState"
|
||||
@@ -847,7 +846,6 @@ export class Controller {
|
||||
|
||||
async getStateToPostToWebview(): Promise<ExtensionState> {
|
||||
// Get API configuration from cache for immediate access
|
||||
const onboardingModels = getClineOnboardingModels()
|
||||
const apiConfiguration = this.stateManager.getApiConfiguration()
|
||||
const lastShownAnnouncementId = this.stateManager.getGlobalStateKey("lastShownAnnouncementId")
|
||||
const taskHistory = this.stateManager.getGlobalStateKey("taskHistory")
|
||||
@@ -960,7 +958,7 @@ export class Controller {
|
||||
defaultTerminalProfile,
|
||||
isNewUser,
|
||||
welcomeViewCompleted,
|
||||
onboardingModels,
|
||||
showOnboardingFlow: featureFlagsService.getOnboardingEnabled(),
|
||||
mcpResponsesCollapsed,
|
||||
terminalOutputLineLimit,
|
||||
maxConsecutiveMistakes,
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
import { featureFlagsService } from "@/services/feature-flags"
|
||||
import { CLINE_ONBOARDING_MODELS } from "@/shared/cline/onboarding"
|
||||
import { OnboardingModel, OnboardingModelGroup } from "@/shared/proto/cline/state"
|
||||
|
||||
type OnboardingModelOverride = OnboardingModel & { hidden?: boolean }
|
||||
|
||||
let cached: OnboardingModelGroup | null = null
|
||||
|
||||
export function getClineOnboardingModels(): OnboardingModelGroup {
|
||||
if (cached) {
|
||||
return cached
|
||||
}
|
||||
|
||||
const remoteOverrides = featureFlagsService.getOnboardingOverrides()
|
||||
const models = new Map<string, OnboardingModel>(CLINE_ONBOARDING_MODELS.map((model) => [model.id, model]))
|
||||
|
||||
// Apply remote overrides if available
|
||||
if (remoteOverrides) {
|
||||
for (const [id, override] of Object.entries(remoteOverrides) as [string, OnboardingModelOverride][]) {
|
||||
if (override.hidden) {
|
||||
models.delete(id)
|
||||
} else {
|
||||
const baseModel = models.get(id)
|
||||
models.set(id, mergeModelWithOverride(baseModel, override))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cached = { models: Array.from(models.values()) }
|
||||
return cached
|
||||
}
|
||||
|
||||
function mergeModelWithOverride(baseModel: OnboardingModel | undefined, override: OnboardingModelOverride): OnboardingModel {
|
||||
const baseInfo = baseModel?.info
|
||||
const overrideInfo = override.info
|
||||
|
||||
// Merge info with proper defaults
|
||||
const mergedInfo = {
|
||||
...baseInfo,
|
||||
...overrideInfo,
|
||||
supportsPromptCache: overrideInfo?.supportsPromptCache ?? baseInfo?.supportsPromptCache ?? false,
|
||||
tiers: overrideInfo?.tiers ?? baseInfo?.tiers ?? [],
|
||||
}
|
||||
|
||||
// Return merged model, using base as foundation if available
|
||||
return baseModel ? { ...baseModel, ...override, info: mergedInfo } : { ...override, info: mergedInfo }
|
||||
}
|
||||
|
||||
export function clearOnboardingModelsCache(): void {
|
||||
cached = null
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
import type { BooleanRequest } from "@shared/proto/cline/common"
|
||||
import { Empty } from "@shared/proto/cline/common"
|
||||
import type { Controller } from "../index"
|
||||
import { clearOnboardingModelsCache } from "../models/getClineOnboardingModels"
|
||||
|
||||
/**
|
||||
* Sets the welcomeViewCompleted flag to the specified boolean value
|
||||
@@ -21,7 +20,5 @@ export async function setWelcomeViewCompleted(controller: Controller, request: B
|
||||
} catch (error) {
|
||||
console.error("Failed to set welcome view completed:", error)
|
||||
throw error
|
||||
} finally {
|
||||
clearOnboardingModelsCache()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,12 +79,6 @@ export async function executeHook<Name extends keyof Hooks>(options: HookExecuti
|
||||
}
|
||||
hookMessageTs = await say("hook", JSON.stringify(hookMetadata))
|
||||
|
||||
// Reorder messages immediately so hook UI appears above tool UI
|
||||
// This must happen right after creating the hook message, before the hook runs
|
||||
if (hookName === "PreToolUse") {
|
||||
await reorderHookAndToolMessages(messageStateHandler)
|
||||
}
|
||||
|
||||
// Track active hook execution for cancellation (only if cancellable and message was created)
|
||||
if (isCancellable && hookMessageTs !== undefined && setActiveHookExecution) {
|
||||
await setActiveHookExecution({
|
||||
@@ -230,56 +224,3 @@ async function updateHookMessage(
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reorders hook and tool messages so hook UI appears before tool UI.
|
||||
* This is called immediately after a hook message is created.
|
||||
*
|
||||
* The algorithm:
|
||||
* 1. Find the most recent tool message (ask or say with type "tool", "command", "use_mcp_server", or "browser_action_launch")
|
||||
* 2. Find any hook messages that came after it
|
||||
* 3. Delete the tool message
|
||||
* 4. Re-add the tool message at the end (after hook messages)
|
||||
*/
|
||||
async function reorderHookAndToolMessages(messageStateHandler: MessageStateHandler): Promise<void> {
|
||||
const clineMessages = messageStateHandler.getClineMessages()
|
||||
|
||||
// Define all message types that represent tool executions with PreToolUse hooks
|
||||
const toolMessageTypes = ["tool", "command", "use_mcp_server", "browser_action_launch"]
|
||||
|
||||
// Find the most recent tool message
|
||||
let lastToolMessageIndex = -1
|
||||
for (let i = clineMessages.length - 1; i >= 0; i--) {
|
||||
const msgType = clineMessages[i].ask || clineMessages[i].say
|
||||
if (msgType && toolMessageTypes.includes(msgType)) {
|
||||
lastToolMessageIndex = i
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (lastToolMessageIndex === -1) {
|
||||
return // No tool message found, nothing to reorder
|
||||
}
|
||||
|
||||
// Check if there are any hook messages after the tool message
|
||||
let hasHookMessagesAfterTool = false
|
||||
for (let i = lastToolMessageIndex + 1; i < clineMessages.length; i++) {
|
||||
if (clineMessages[i].say === "hook" || clineMessages[i].say === "hook_output") {
|
||||
hasHookMessagesAfterTool = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasHookMessagesAfterTool) {
|
||||
return // No reordering needed
|
||||
}
|
||||
|
||||
// Store the tool message (deep copy to preserve all properties)
|
||||
const toolMessage = { ...clineMessages[lastToolMessageIndex] }
|
||||
|
||||
// Delete the tool message at its current position
|
||||
await messageStateHandler.deleteClineMessage(lastToolMessageIndex)
|
||||
|
||||
// Re-add the tool message at the end (after hook messages)
|
||||
await messageStateHandler.addToClineMessages(toolMessage)
|
||||
}
|
||||
|
||||
@@ -1,40 +1,8 @@
|
||||
import type { ApiProviderInfo } from "@/core/api"
|
||||
import { getDeepPlanningPrompt } from "./commands/deep-planning"
|
||||
|
||||
export const newTaskToolResponse = (enableNativeToolCalls?: boolean) => {
|
||||
const xmlExample = enableNativeToolCalls
|
||||
? ""
|
||||
: `
|
||||
Example:
|
||||
<new_task>
|
||||
<context>1. Current Work:
|
||||
[Detailed description]
|
||||
|
||||
2. Key Technical Concepts:
|
||||
- [Concept 1]
|
||||
- [Concept 2]
|
||||
- [...]
|
||||
|
||||
3. Relevant Files and Code:
|
||||
- [File Name 1]
|
||||
- [Summary of why this file is important]
|
||||
- [Summary of the changes made to this file, if any]
|
||||
- [Important Code Snippet]
|
||||
- [File Name 2]
|
||||
- [Important Code Snippet]
|
||||
- [...]
|
||||
|
||||
4. Problem Solving:
|
||||
[Detailed description]
|
||||
|
||||
5. Pending Tasks and Next Steps:
|
||||
- [Task 1 details & next steps]
|
||||
- [Task 2 details & next steps]
|
||||
- [...]</context>
|
||||
</new_task>
|
||||
`
|
||||
|
||||
return `<explicit_instructions type="new_task">
|
||||
export const newTaskToolResponse = () =>
|
||||
`<explicit_instructions type="new_task">
|
||||
The user has explicitly asked you to help them create a new task with preloaded context, which you will generate. The user may have provided instructions or additional information for you to consider when summarizing existing work and creating the context for the new task.
|
||||
Irrespective of whether additional information or instructions are given, you are ONLY allowed to respond to this message by calling the new_task tool.
|
||||
|
||||
@@ -51,11 +19,15 @@ Parameters:
|
||||
3. Relevant Files and Code: If applicable, enumerate specific files and code sections examined, modified, or created for the task continuation. Pay special attention to the most recent messages and changes.
|
||||
4. Problem Solving: Document problems solved thus far and any ongoing troubleshooting efforts.
|
||||
5. Pending Tasks and Next Steps: Outline all pending tasks that you have explicitly been asked to work on, as well as list the next steps you will take for all outstanding work, if applicable. Include code snippets where they add clarity. For any next steps, include direct quotes from the most recent conversation showing exactly what task you were working on and where you left off. This should be verbatim to ensure there's no information loss in context between tasks.
|
||||
${xmlExample}
|
||||
|
||||
Usage:
|
||||
<new_task>
|
||||
<context>context to preload new task with</context>
|
||||
</new_task>
|
||||
|
||||
Below is the the user's input when they indicated that they wanted to create a new task.
|
||||
</explicit_instructions>\n
|
||||
`
|
||||
}
|
||||
|
||||
export const condenseToolResponse = (focusChainSettings?: { enabled: boolean }) =>
|
||||
`<explicit_instructions type="condense">
|
||||
|
||||
+15
@@ -250,6 +250,21 @@ Usage:
|
||||
<task_progress>Checklist here (required if you used task_progress in previous tool uses)</task_progress>
|
||||
</attempt_completion>
|
||||
|
||||
## new_task
|
||||
Description: Request to create a new task with preloaded context covering the conversation with the user up to this point and key information for continuing with the new task. With this tool, you will create a detailed summary of the conversation so far, paying close attention to the user's explicit requests and your previous actions, with a focus on the most relevant information required for the new task.
|
||||
Among other important areas of focus, this summary should be thorough in capturing technical details, code patterns, and architectural decisions that would be essential for continuing with the new task. The user will be presented with a preview of your generated context and can choose to create a new task or keep chatting in the current conversation. The user may choose to start a new task at any point.
|
||||
Parameters:
|
||||
- context: (required) The context to preload the new task with. If applicable based on the current task, this should include:
|
||||
1. Current Work: Describe in detail what was being worked on prior to this request to create a new task. Pay special attention to the more recent messages / conversation.
|
||||
2. Key Technical Concepts: List all important technical concepts, technologies, coding conventions, and frameworks discussed, which might be relevant for the new task.
|
||||
3. Relevant Files and Code: If applicable, enumerate specific files and code sections examined, modified, or created for the task continuation. Pay special attention to the most recent messages and changes.
|
||||
4. Problem Solving: Document problems solved thus far and any ongoing troubleshooting efforts.
|
||||
5. Pending Tasks and Next Steps: Outline all pending tasks that you have explicitly been asked to work on, as well as list the next steps you will take for all outstanding work, if applicable. Include code snippets where they add clarity. For any next steps, include direct quotes from the most recent conversation showing exactly what task you were working on and where you left off. This should be verbatim to ensure there's no information loss in context between tasks. It's important to be detailed here.
|
||||
Usage:
|
||||
<new_task>
|
||||
<context>context to preload new task with</context>
|
||||
</new_task>
|
||||
|
||||
## plan_mode_respond
|
||||
Description: Respond to the user's inquiry in an effort to plan a solution to the user's task. This tool should ONLY be used when you have already explored the relevant files and are ready to present a concrete plan. DO NOT use this tool to announce what files you're going to read - just read them first. This tool is only available in PLAN MODE. The environment_details will specify the current mode; if it is not PLAN_MODE then you should not use this tool.
|
||||
However, if while writing your response you realize you actually need to do more exploration before providing a complete plan, you can add the optional needs_more_exploration parameter to indicate this. This allows you to acknowledge that you should have done more exploration first, and signals that your next message will use exploration tools instead.
|
||||
|
||||
+15
@@ -216,6 +216,21 @@ Usage:
|
||||
<task_progress>Checklist here (required if you used task_progress in previous tool uses)</task_progress>
|
||||
</attempt_completion>
|
||||
|
||||
## new_task
|
||||
Description: Request to create a new task with preloaded context covering the conversation with the user up to this point and key information for continuing with the new task. With this tool, you will create a detailed summary of the conversation so far, paying close attention to the user's explicit requests and your previous actions, with a focus on the most relevant information required for the new task.
|
||||
Among other important areas of focus, this summary should be thorough in capturing technical details, code patterns, and architectural decisions that would be essential for continuing with the new task. The user will be presented with a preview of your generated context and can choose to create a new task or keep chatting in the current conversation. The user may choose to start a new task at any point.
|
||||
Parameters:
|
||||
- context: (required) The context to preload the new task with. If applicable based on the current task, this should include:
|
||||
1. Current Work: Describe in detail what was being worked on prior to this request to create a new task. Pay special attention to the more recent messages / conversation.
|
||||
2. Key Technical Concepts: List all important technical concepts, technologies, coding conventions, and frameworks discussed, which might be relevant for the new task.
|
||||
3. Relevant Files and Code: If applicable, enumerate specific files and code sections examined, modified, or created for the task continuation. Pay special attention to the most recent messages and changes.
|
||||
4. Problem Solving: Document problems solved thus far and any ongoing troubleshooting efforts.
|
||||
5. Pending Tasks and Next Steps: Outline all pending tasks that you have explicitly been asked to work on, as well as list the next steps you will take for all outstanding work, if applicable. Include code snippets where they add clarity. For any next steps, include direct quotes from the most recent conversation showing exactly what task you were working on and where you left off. This should be verbatim to ensure there's no information loss in context between tasks. It's important to be detailed here.
|
||||
Usage:
|
||||
<new_task>
|
||||
<context>context to preload new task with</context>
|
||||
</new_task>
|
||||
|
||||
## plan_mode_respond
|
||||
Description: Respond to the user's inquiry in an effort to plan a solution to the user's task. This tool should ONLY be used when you have already explored the relevant files and are ready to present a concrete plan. DO NOT use this tool to announce what files you're going to read - just read them first. This tool is only available in PLAN MODE. The environment_details will specify the current mode; if it is not PLAN_MODE then you should not use this tool.
|
||||
However, if while writing your response you realize you actually need to do more exploration before providing a complete plan, you can add the optional needs_more_exploration parameter to indicate this. This allows you to acknowledge that you should have done more exploration first, and signals that your next message will use exploration tools instead.
|
||||
|
||||
+15
@@ -224,6 +224,21 @@ Usage:
|
||||
<command>Your command here (optional)</command>
|
||||
</attempt_completion>
|
||||
|
||||
## new_task
|
||||
Description: Request to create a new task with preloaded context covering the conversation with the user up to this point and key information for continuing with the new task. With this tool, you will create a detailed summary of the conversation so far, paying close attention to the user's explicit requests and your previous actions, with a focus on the most relevant information required for the new task.
|
||||
Among other important areas of focus, this summary should be thorough in capturing technical details, code patterns, and architectural decisions that would be essential for continuing with the new task. The user will be presented with a preview of your generated context and can choose to create a new task or keep chatting in the current conversation. The user may choose to start a new task at any point.
|
||||
Parameters:
|
||||
- context: (required) The context to preload the new task with. If applicable based on the current task, this should include:
|
||||
1. Current Work: Describe in detail what was being worked on prior to this request to create a new task. Pay special attention to the more recent messages / conversation.
|
||||
2. Key Technical Concepts: List all important technical concepts, technologies, coding conventions, and frameworks discussed, which might be relevant for the new task.
|
||||
3. Relevant Files and Code: If applicable, enumerate specific files and code sections examined, modified, or created for the task continuation. Pay special attention to the most recent messages and changes.
|
||||
4. Problem Solving: Document problems solved thus far and any ongoing troubleshooting efforts.
|
||||
5. Pending Tasks and Next Steps: Outline all pending tasks that you have explicitly been asked to work on, as well as list the next steps you will take for all outstanding work, if applicable. Include code snippets where they add clarity. For any next steps, include direct quotes from the most recent conversation showing exactly what task you were working on and where you left off. This should be verbatim to ensure there's no information loss in context between tasks. It's important to be detailed here.
|
||||
Usage:
|
||||
<new_task>
|
||||
<context>context to preload new task with</context>
|
||||
</new_task>
|
||||
|
||||
## plan_mode_respond
|
||||
Description: Respond to the user's inquiry in an effort to plan a solution to the user's task. This tool should ONLY be used when you have already explored the relevant files and are ready to present a concrete plan. DO NOT use this tool to announce what files you're going to read - just read them first. This tool is only available in PLAN MODE. The environment_details will specify the current mode; if it is not PLAN_MODE then you should not use this tool.
|
||||
However, if while writing your response you realize you actually need to do more exploration before providing a complete plan, you can add the optional needs_more_exploration parameter to indicate this. This allows you to acknowledge that you should have done more exploration first, and signals that your next message will use exploration tools instead.
|
||||
|
||||
+15
@@ -250,6 +250,21 @@ Usage:
|
||||
<task_progress>Checklist here (required if you used task_progress in previous tool uses)</task_progress>
|
||||
</attempt_completion>
|
||||
|
||||
## new_task
|
||||
Description: Request to create a new task with preloaded context covering the conversation with the user up to this point and key information for continuing with the new task. With this tool, you will create a detailed summary of the conversation so far, paying close attention to the user's explicit requests and your previous actions, with a focus on the most relevant information required for the new task.
|
||||
Among other important areas of focus, this summary should be thorough in capturing technical details, code patterns, and architectural decisions that would be essential for continuing with the new task. The user will be presented with a preview of your generated context and can choose to create a new task or keep chatting in the current conversation. The user may choose to start a new task at any point.
|
||||
Parameters:
|
||||
- context: (required) The context to preload the new task with. If applicable based on the current task, this should include:
|
||||
1. Current Work: Describe in detail what was being worked on prior to this request to create a new task. Pay special attention to the more recent messages / conversation.
|
||||
2. Key Technical Concepts: List all important technical concepts, technologies, coding conventions, and frameworks discussed, which might be relevant for the new task.
|
||||
3. Relevant Files and Code: If applicable, enumerate specific files and code sections examined, modified, or created for the task continuation. Pay special attention to the most recent messages and changes.
|
||||
4. Problem Solving: Document problems solved thus far and any ongoing troubleshooting efforts.
|
||||
5. Pending Tasks and Next Steps: Outline all pending tasks that you have explicitly been asked to work on, as well as list the next steps you will take for all outstanding work, if applicable. Include code snippets where they add clarity. For any next steps, include direct quotes from the most recent conversation showing exactly what task you were working on and where you left off. This should be verbatim to ensure there's no information loss in context between tasks. It's important to be detailed here.
|
||||
Usage:
|
||||
<new_task>
|
||||
<context>context to preload new task with</context>
|
||||
</new_task>
|
||||
|
||||
## plan_mode_respond
|
||||
Description: Respond to the user's inquiry in an effort to plan a solution to the user's task. This tool should ONLY be used when you have already explored the relevant files and are ready to present a concrete plan. DO NOT use this tool to announce what files you're going to read - just read them first. This tool is only available in PLAN MODE. The environment_details will specify the current mode; if it is not PLAN_MODE then you should not use this tool.
|
||||
However, if while writing your response you realize you actually need to do more exploration before providing a complete plan, you can add the optional needs_more_exploration parameter to indicate this. This allows you to acknowledge that you should have done more exploration first, and signals that your next message will use exploration tools instead.
|
||||
|
||||
@@ -232,6 +232,21 @@ Usage:
|
||||
<task_progress>Checklist here (required if you used task_progress in previous tool uses)</task_progress>
|
||||
</attempt_completion>
|
||||
|
||||
## new_task
|
||||
Description: Request to create a new task with preloaded context covering the conversation with the user up to this point and key information for continuing with the new task. With this tool, you will create a detailed summary of the conversation so far, paying close attention to the user's explicit requests and your previous actions, with a focus on the most relevant information required for the new task.
|
||||
Among other important areas of focus, this summary should be thorough in capturing technical details, code patterns, and architectural decisions that would be essential for continuing with the new task. The user will be presented with a preview of your generated context and can choose to create a new task or keep chatting in the current conversation. The user may choose to start a new task at any point.
|
||||
Parameters:
|
||||
- context: (required) The context to preload the new task with. If applicable based on the current task, this should include:
|
||||
1. Current Work: Describe in detail what was being worked on prior to this request to create a new task. Pay special attention to the more recent messages / conversation.
|
||||
2. Key Technical Concepts: List all important technical concepts, technologies, coding conventions, and frameworks discussed, which might be relevant for the new task.
|
||||
3. Relevant Files and Code: If applicable, enumerate specific files and code sections examined, modified, or created for the task continuation. Pay special attention to the most recent messages and changes.
|
||||
4. Problem Solving: Document problems solved thus far and any ongoing troubleshooting efforts.
|
||||
5. Pending Tasks and Next Steps: Outline all pending tasks that you have explicitly been asked to work on, as well as list the next steps you will take for all outstanding work, if applicable. Include code snippets where they add clarity. For any next steps, include direct quotes from the most recent conversation showing exactly what task you were working on and where you left off. This should be verbatim to ensure there's no information loss in context between tasks. It's important to be detailed here.
|
||||
Usage:
|
||||
<new_task>
|
||||
<context>context to preload new task with</context>
|
||||
</new_task>
|
||||
|
||||
## plan_mode_respond
|
||||
Description: Respond to the user's inquiry in an effort to plan a solution to the user's task. This tool should ONLY be used when you have already explored the relevant files and are ready to present a concrete plan. DO NOT use this tool to announce what files you're going to read - just read them first. This tool is only available in PLAN MODE. The environment_details will specify the current mode; if it is not PLAN_MODE then you should not use this tool.
|
||||
However, if while writing your response you realize you actually need to do more exploration before providing a complete plan, you can add the optional needs_more_exploration parameter to indicate this. This allows you to acknowledge that you should have done more exploration first, and signals that your next message will use exploration tools instead.
|
||||
|
||||
@@ -198,6 +198,21 @@ Usage:
|
||||
<task_progress>Checklist here (required if you used task_progress in previous tool uses)</task_progress>
|
||||
</attempt_completion>
|
||||
|
||||
## new_task
|
||||
Description: Request to create a new task with preloaded context covering the conversation with the user up to this point and key information for continuing with the new task. With this tool, you will create a detailed summary of the conversation so far, paying close attention to the user's explicit requests and your previous actions, with a focus on the most relevant information required for the new task.
|
||||
Among other important areas of focus, this summary should be thorough in capturing technical details, code patterns, and architectural decisions that would be essential for continuing with the new task. The user will be presented with a preview of your generated context and can choose to create a new task or keep chatting in the current conversation. The user may choose to start a new task at any point.
|
||||
Parameters:
|
||||
- context: (required) The context to preload the new task with. If applicable based on the current task, this should include:
|
||||
1. Current Work: Describe in detail what was being worked on prior to this request to create a new task. Pay special attention to the more recent messages / conversation.
|
||||
2. Key Technical Concepts: List all important technical concepts, technologies, coding conventions, and frameworks discussed, which might be relevant for the new task.
|
||||
3. Relevant Files and Code: If applicable, enumerate specific files and code sections examined, modified, or created for the task continuation. Pay special attention to the most recent messages and changes.
|
||||
4. Problem Solving: Document problems solved thus far and any ongoing troubleshooting efforts.
|
||||
5. Pending Tasks and Next Steps: Outline all pending tasks that you have explicitly been asked to work on, as well as list the next steps you will take for all outstanding work, if applicable. Include code snippets where they add clarity. For any next steps, include direct quotes from the most recent conversation showing exactly what task you were working on and where you left off. This should be verbatim to ensure there's no information loss in context between tasks. It's important to be detailed here.
|
||||
Usage:
|
||||
<new_task>
|
||||
<context>context to preload new task with</context>
|
||||
</new_task>
|
||||
|
||||
## plan_mode_respond
|
||||
Description: Respond to the user's inquiry in an effort to plan a solution to the user's task. This tool should ONLY be used when you have already explored the relevant files and are ready to present a concrete plan. DO NOT use this tool to announce what files you're going to read - just read them first. This tool is only available in PLAN MODE. The environment_details will specify the current mode; if it is not PLAN_MODE then you should not use this tool.
|
||||
However, if while writing your response you realize you actually need to do more exploration before providing a complete plan, you can add the optional needs_more_exploration parameter to indicate this. This allows you to acknowledge that you should have done more exploration first, and signals that your next message will use exploration tools instead.
|
||||
|
||||
+15
@@ -208,6 +208,21 @@ Usage:
|
||||
<command>Your command here (optional)</command>
|
||||
</attempt_completion>
|
||||
|
||||
## new_task
|
||||
Description: Request to create a new task with preloaded context covering the conversation with the user up to this point and key information for continuing with the new task. With this tool, you will create a detailed summary of the conversation so far, paying close attention to the user's explicit requests and your previous actions, with a focus on the most relevant information required for the new task.
|
||||
Among other important areas of focus, this summary should be thorough in capturing technical details, code patterns, and architectural decisions that would be essential for continuing with the new task. The user will be presented with a preview of your generated context and can choose to create a new task or keep chatting in the current conversation. The user may choose to start a new task at any point.
|
||||
Parameters:
|
||||
- context: (required) The context to preload the new task with. If applicable based on the current task, this should include:
|
||||
1. Current Work: Describe in detail what was being worked on prior to this request to create a new task. Pay special attention to the more recent messages / conversation.
|
||||
2. Key Technical Concepts: List all important technical concepts, technologies, coding conventions, and frameworks discussed, which might be relevant for the new task.
|
||||
3. Relevant Files and Code: If applicable, enumerate specific files and code sections examined, modified, or created for the task continuation. Pay special attention to the most recent messages and changes.
|
||||
4. Problem Solving: Document problems solved thus far and any ongoing troubleshooting efforts.
|
||||
5. Pending Tasks and Next Steps: Outline all pending tasks that you have explicitly been asked to work on, as well as list the next steps you will take for all outstanding work, if applicable. Include code snippets where they add clarity. For any next steps, include direct quotes from the most recent conversation showing exactly what task you were working on and where you left off. This should be verbatim to ensure there's no information loss in context between tasks. It's important to be detailed here.
|
||||
Usage:
|
||||
<new_task>
|
||||
<context>context to preload new task with</context>
|
||||
</new_task>
|
||||
|
||||
## plan_mode_respond
|
||||
Description: Respond to the user's inquiry in an effort to plan a solution to the user's task. This tool should ONLY be used when you have already explored the relevant files and are ready to present a concrete plan. DO NOT use this tool to announce what files you're going to read - just read them first. This tool is only available in PLAN MODE. The environment_details will specify the current mode; if it is not PLAN_MODE then you should not use this tool.
|
||||
However, if while writing your response you realize you actually need to do more exploration before providing a complete plan, you can add the optional needs_more_exploration parameter to indicate this. This allows you to acknowledge that you should have done more exploration first, and signals that your next message will use exploration tools instead.
|
||||
|
||||
@@ -232,6 +232,21 @@ Usage:
|
||||
<task_progress>Checklist here (required if you used task_progress in previous tool uses)</task_progress>
|
||||
</attempt_completion>
|
||||
|
||||
## new_task
|
||||
Description: Request to create a new task with preloaded context covering the conversation with the user up to this point and key information for continuing with the new task. With this tool, you will create a detailed summary of the conversation so far, paying close attention to the user's explicit requests and your previous actions, with a focus on the most relevant information required for the new task.
|
||||
Among other important areas of focus, this summary should be thorough in capturing technical details, code patterns, and architectural decisions that would be essential for continuing with the new task. The user will be presented with a preview of your generated context and can choose to create a new task or keep chatting in the current conversation. The user may choose to start a new task at any point.
|
||||
Parameters:
|
||||
- context: (required) The context to preload the new task with. If applicable based on the current task, this should include:
|
||||
1. Current Work: Describe in detail what was being worked on prior to this request to create a new task. Pay special attention to the more recent messages / conversation.
|
||||
2. Key Technical Concepts: List all important technical concepts, technologies, coding conventions, and frameworks discussed, which might be relevant for the new task.
|
||||
3. Relevant Files and Code: If applicable, enumerate specific files and code sections examined, modified, or created for the task continuation. Pay special attention to the most recent messages and changes.
|
||||
4. Problem Solving: Document problems solved thus far and any ongoing troubleshooting efforts.
|
||||
5. Pending Tasks and Next Steps: Outline all pending tasks that you have explicitly been asked to work on, as well as list the next steps you will take for all outstanding work, if applicable. Include code snippets where they add clarity. For any next steps, include direct quotes from the most recent conversation showing exactly what task you were working on and where you left off. This should be verbatim to ensure there's no information loss in context between tasks. It's important to be detailed here.
|
||||
Usage:
|
||||
<new_task>
|
||||
<context>context to preload new task with</context>
|
||||
</new_task>
|
||||
|
||||
## plan_mode_respond
|
||||
Description: Respond to the user's inquiry in an effort to plan a solution to the user's task. This tool should ONLY be used when you have already explored the relevant files and are ready to present a concrete plan. DO NOT use this tool to announce what files you're going to read - just read them first. This tool is only available in PLAN MODE. The environment_details will specify the current mode; if it is not PLAN_MODE then you should not use this tool.
|
||||
However, if while writing your response you realize you actually need to do more exploration before providing a complete plan, you can add the optional needs_more_exploration parameter to indicate this. This allows you to acknowledge that you should have done more exploration first, and signals that your next message will use exploration tools instead.
|
||||
|
||||
@@ -250,6 +250,21 @@ Usage:
|
||||
<task_progress>Checklist here (required if you used task_progress in previous tool uses)</task_progress>
|
||||
</attempt_completion>
|
||||
|
||||
## new_task
|
||||
Description: Request to create a new task with preloaded context covering the conversation with the user up to this point and key information for continuing with the new task. With this tool, you will create a detailed summary of the conversation so far, paying close attention to the user's explicit requests and your previous actions, with a focus on the most relevant information required for the new task.
|
||||
Among other important areas of focus, this summary should be thorough in capturing technical details, code patterns, and architectural decisions that would be essential for continuing with the new task. The user will be presented with a preview of your generated context and can choose to create a new task or keep chatting in the current conversation. The user may choose to start a new task at any point.
|
||||
Parameters:
|
||||
- context: (required) The context to preload the new task with. If applicable based on the current task, this should include:
|
||||
1. Current Work: Describe in detail what was being worked on prior to this request to create a new task. Pay special attention to the more recent messages / conversation.
|
||||
2. Key Technical Concepts: List all important technical concepts, technologies, coding conventions, and frameworks discussed, which might be relevant for the new task.
|
||||
3. Relevant Files and Code: If applicable, enumerate specific files and code sections examined, modified, or created for the task continuation. Pay special attention to the most recent messages and changes.
|
||||
4. Problem Solving: Document problems solved thus far and any ongoing troubleshooting efforts.
|
||||
5. Pending Tasks and Next Steps: Outline all pending tasks that you have explicitly been asked to work on, as well as list the next steps you will take for all outstanding work, if applicable. Include code snippets where they add clarity. For any next steps, include direct quotes from the most recent conversation showing exactly what task you were working on and where you left off. This should be verbatim to ensure there's no information loss in context between tasks. It's important to be detailed here.
|
||||
Usage:
|
||||
<new_task>
|
||||
<context>context to preload new task with</context>
|
||||
</new_task>
|
||||
|
||||
## plan_mode_respond
|
||||
Description: Respond to the user's inquiry in an effort to plan a solution to the user's task. This tool should ONLY be used when you have already explored the relevant files and are ready to present a concrete plan. DO NOT use this tool to announce what files you're going to read - just read them first. This tool is only available in PLAN MODE. The environment_details will specify the current mode; if it is not PLAN_MODE then you should not use this tool.
|
||||
However, if while writing your response you realize you actually need to do more exploration before providing a complete plan, you can add the optional needs_more_exploration parameter to indicate this. This allows you to acknowledge that you should have done more exploration first, and signals that your next message will use exploration tools instead.
|
||||
|
||||
@@ -216,6 +216,21 @@ Usage:
|
||||
<task_progress>Checklist here (required if you used task_progress in previous tool uses)</task_progress>
|
||||
</attempt_completion>
|
||||
|
||||
## new_task
|
||||
Description: Request to create a new task with preloaded context covering the conversation with the user up to this point and key information for continuing with the new task. With this tool, you will create a detailed summary of the conversation so far, paying close attention to the user's explicit requests and your previous actions, with a focus on the most relevant information required for the new task.
|
||||
Among other important areas of focus, this summary should be thorough in capturing technical details, code patterns, and architectural decisions that would be essential for continuing with the new task. The user will be presented with a preview of your generated context and can choose to create a new task or keep chatting in the current conversation. The user may choose to start a new task at any point.
|
||||
Parameters:
|
||||
- context: (required) The context to preload the new task with. If applicable based on the current task, this should include:
|
||||
1. Current Work: Describe in detail what was being worked on prior to this request to create a new task. Pay special attention to the more recent messages / conversation.
|
||||
2. Key Technical Concepts: List all important technical concepts, technologies, coding conventions, and frameworks discussed, which might be relevant for the new task.
|
||||
3. Relevant Files and Code: If applicable, enumerate specific files and code sections examined, modified, or created for the task continuation. Pay special attention to the most recent messages and changes.
|
||||
4. Problem Solving: Document problems solved thus far and any ongoing troubleshooting efforts.
|
||||
5. Pending Tasks and Next Steps: Outline all pending tasks that you have explicitly been asked to work on, as well as list the next steps you will take for all outstanding work, if applicable. Include code snippets where they add clarity. For any next steps, include direct quotes from the most recent conversation showing exactly what task you were working on and where you left off. This should be verbatim to ensure there's no information loss in context between tasks. It's important to be detailed here.
|
||||
Usage:
|
||||
<new_task>
|
||||
<context>context to preload new task with</context>
|
||||
</new_task>
|
||||
|
||||
## plan_mode_respond
|
||||
Description: Respond to the user's inquiry in an effort to plan a solution to the user's task. This tool should ONLY be used when you have already explored the relevant files and are ready to present a concrete plan. DO NOT use this tool to announce what files you're going to read - just read them first. This tool is only available in PLAN MODE. The environment_details will specify the current mode; if it is not PLAN_MODE then you should not use this tool.
|
||||
However, if while writing your response you realize you actually need to do more exploration before providing a complete plan, you can add the optional needs_more_exploration parameter to indicate this. This allows you to acknowledge that you should have done more exploration first, and signals that your next message will use exploration tools instead.
|
||||
|
||||
+15
@@ -224,6 +224,21 @@ Usage:
|
||||
<command>Your command here (optional)</command>
|
||||
</attempt_completion>
|
||||
|
||||
## new_task
|
||||
Description: Request to create a new task with preloaded context covering the conversation with the user up to this point and key information for continuing with the new task. With this tool, you will create a detailed summary of the conversation so far, paying close attention to the user's explicit requests and your previous actions, with a focus on the most relevant information required for the new task.
|
||||
Among other important areas of focus, this summary should be thorough in capturing technical details, code patterns, and architectural decisions that would be essential for continuing with the new task. The user will be presented with a preview of your generated context and can choose to create a new task or keep chatting in the current conversation. The user may choose to start a new task at any point.
|
||||
Parameters:
|
||||
- context: (required) The context to preload the new task with. If applicable based on the current task, this should include:
|
||||
1. Current Work: Describe in detail what was being worked on prior to this request to create a new task. Pay special attention to the more recent messages / conversation.
|
||||
2. Key Technical Concepts: List all important technical concepts, technologies, coding conventions, and frameworks discussed, which might be relevant for the new task.
|
||||
3. Relevant Files and Code: If applicable, enumerate specific files and code sections examined, modified, or created for the task continuation. Pay special attention to the most recent messages and changes.
|
||||
4. Problem Solving: Document problems solved thus far and any ongoing troubleshooting efforts.
|
||||
5. Pending Tasks and Next Steps: Outline all pending tasks that you have explicitly been asked to work on, as well as list the next steps you will take for all outstanding work, if applicable. Include code snippets where they add clarity. For any next steps, include direct quotes from the most recent conversation showing exactly what task you were working on and where you left off. This should be verbatim to ensure there's no information loss in context between tasks. It's important to be detailed here.
|
||||
Usage:
|
||||
<new_task>
|
||||
<context>context to preload new task with</context>
|
||||
</new_task>
|
||||
|
||||
## plan_mode_respond
|
||||
Description: Respond to the user's inquiry in an effort to plan a solution to the user's task. This tool should ONLY be used when you have already explored the relevant files and are ready to present a concrete plan. DO NOT use this tool to announce what files you're going to read - just read them first. This tool is only available in PLAN MODE. The environment_details will specify the current mode; if it is not PLAN_MODE then you should not use this tool.
|
||||
However, if while writing your response you realize you actually need to do more exploration before providing a complete plan, you can add the optional needs_more_exploration parameter to indicate this. This allows you to acknowledge that you should have done more exploration first, and signals that your next message will use exploration tools instead.
|
||||
|
||||
@@ -250,6 +250,21 @@ Usage:
|
||||
<task_progress>Checklist here (required if you used task_progress in previous tool uses)</task_progress>
|
||||
</attempt_completion>
|
||||
|
||||
## new_task
|
||||
Description: Request to create a new task with preloaded context covering the conversation with the user up to this point and key information for continuing with the new task. With this tool, you will create a detailed summary of the conversation so far, paying close attention to the user's explicit requests and your previous actions, with a focus on the most relevant information required for the new task.
|
||||
Among other important areas of focus, this summary should be thorough in capturing technical details, code patterns, and architectural decisions that would be essential for continuing with the new task. The user will be presented with a preview of your generated context and can choose to create a new task or keep chatting in the current conversation. The user may choose to start a new task at any point.
|
||||
Parameters:
|
||||
- context: (required) The context to preload the new task with. If applicable based on the current task, this should include:
|
||||
1. Current Work: Describe in detail what was being worked on prior to this request to create a new task. Pay special attention to the more recent messages / conversation.
|
||||
2. Key Technical Concepts: List all important technical concepts, technologies, coding conventions, and frameworks discussed, which might be relevant for the new task.
|
||||
3. Relevant Files and Code: If applicable, enumerate specific files and code sections examined, modified, or created for the task continuation. Pay special attention to the most recent messages and changes.
|
||||
4. Problem Solving: Document problems solved thus far and any ongoing troubleshooting efforts.
|
||||
5. Pending Tasks and Next Steps: Outline all pending tasks that you have explicitly been asked to work on, as well as list the next steps you will take for all outstanding work, if applicable. Include code snippets where they add clarity. For any next steps, include direct quotes from the most recent conversation showing exactly what task you were working on and where you left off. This should be verbatim to ensure there's no information loss in context between tasks. It's important to be detailed here.
|
||||
Usage:
|
||||
<new_task>
|
||||
<context>context to preload new task with</context>
|
||||
</new_task>
|
||||
|
||||
## plan_mode_respond
|
||||
Description: Respond to the user's inquiry in an effort to plan a solution to the user's task. This tool should ONLY be used when you have already explored the relevant files and are ready to present a concrete plan. DO NOT use this tool to announce what files you're going to read - just read them first. This tool is only available in PLAN MODE. The environment_details will specify the current mode; if it is not PLAN_MODE then you should not use this tool.
|
||||
However, if while writing your response you realize you actually need to do more exploration before providing a complete plan, you can add the optional needs_more_exploration parameter to indicate this. This allows you to acknowledge that you should have done more exploration first, and signals that your next message will use exploration tools instead.
|
||||
|
||||
@@ -144,8 +144,6 @@ This ensures your work aligns with the existing codebase structure and avoids un
|
||||
|
||||
This tool is non-blocking, so using it frequently improves user experience and ensures long tasks are completed successfully.
|
||||
|
||||
Additionally, you MUST NOT call act_mode_respond more than once in a row. After using act_mode_respond, your next assistant message MUST either call a different tool or perform additional work without using act_mode_respond again. If you attempt to call act_mode_respond consecutively, the tool call will fail with an explicit error and you must choose a different action instead.
|
||||
|
||||
3. Remember, you have extensive capabilities with access to a wide range of tools that can be used in powerful and clever ways as necessary to accomplish each goal. First, analyze the file structure provided in environment_details to gain context and insights for proceeding effectively. Then, think about which of the provided tools is the most relevant tool to accomplish the user's task. Next, go through each of the required parameters of the relevant tool and determine if the user has directly provided or given enough information to infer a value. When deciding if the parameter can be inferred, carefully consider all the context to see if it supports a specific value. If all of the required parameters are present or can be reasonably inferred, close the thinking tag and proceed with the tool use. BUT, if one of the values for a required parameter is missing, DO NOT invoke the tool (not even with fillers for the missing params) and instead, ask the user to provide the missing parameters using the ask_followup_question tool. DO NOT ask for more information on optional parameters if it is not provided.
|
||||
|
||||
4. **Code Generation Self-Review Loop**: After generating code, evaluate against an internal quality rubric using your reasoning:
|
||||
|
||||
@@ -142,8 +142,6 @@ This ensures your work aligns with the existing codebase structure and avoids un
|
||||
|
||||
This tool is non-blocking, so using it frequently improves user experience and ensures long tasks are completed successfully.
|
||||
|
||||
Additionally, you MUST NOT call act_mode_respond more than once in a row. After using act_mode_respond, your next assistant message MUST either call a different tool or perform additional work without using act_mode_respond again. If you attempt to call act_mode_respond consecutively, the tool call will fail with an explicit error and you must choose a different action instead.
|
||||
|
||||
3. Remember, you have extensive capabilities with access to a wide range of tools that can be used in powerful and clever ways as necessary to accomplish each goal. First, analyze the file structure provided in environment_details to gain context and insights for proceeding effectively. Then, think about which of the provided tools is the most relevant tool to accomplish the user's task. Next, go through each of the required parameters of the relevant tool and determine if the user has directly provided or given enough information to infer a value. When deciding if the parameter can be inferred, carefully consider all the context to see if it supports a specific value. If all of the required parameters are present or can be reasonably inferred, close the thinking tag and proceed with the tool use. BUT, if one of the values for a required parameter is missing, DO NOT invoke the tool (not even with fillers for the missing params) and instead, ask the user to provide the missing parameters using the ask_followup_question tool. DO NOT ask for more information on optional parameters if it is not provided.
|
||||
|
||||
4. **Code Generation Self-Review Loop**: After generating code, evaluate against an internal quality rubric using your reasoning:
|
||||
|
||||
-2
@@ -110,8 +110,6 @@ This ensures your work aligns with the existing codebase structure and avoids un
|
||||
|
||||
This tool is non-blocking, so using it frequently improves user experience and ensures long tasks are completed successfully.
|
||||
|
||||
Additionally, you MUST NOT call act_mode_respond more than once in a row. After using act_mode_respond, your next assistant message MUST either call a different tool or perform additional work without using act_mode_respond again. If you attempt to call act_mode_respond consecutively, the tool call will fail with an explicit error and you must choose a different action instead.
|
||||
|
||||
3. Remember, you have extensive capabilities with access to a wide range of tools that can be used in powerful and clever ways as necessary to accomplish each goal. First, analyze the file structure provided in environment_details to gain context and insights for proceeding effectively. Then, think about which of the provided tools is the most relevant tool to accomplish the user's task. Next, go through each of the required parameters of the relevant tool and determine if the user has directly provided or given enough information to infer a value. When deciding if the parameter can be inferred, carefully consider all the context to see if it supports a specific value. If all of the required parameters are present or can be reasonably inferred, close the thinking tag and proceed with the tool use. BUT, if one of the values for a required parameter is missing, DO NOT invoke the tool (not even with fillers for the missing params) and instead, ask the user to provide the missing parameters using the ask_followup_question tool. DO NOT ask for more information on optional parameters if it is not provided.
|
||||
|
||||
4. **Code Generation Self-Review Loop**: After generating code, evaluate against an internal quality rubric using your reasoning:
|
||||
|
||||
@@ -144,8 +144,6 @@ This ensures your work aligns with the existing codebase structure and avoids un
|
||||
|
||||
This tool is non-blocking, so using it frequently improves user experience and ensures long tasks are completed successfully.
|
||||
|
||||
Additionally, you MUST NOT call act_mode_respond more than once in a row. After using act_mode_respond, your next assistant message MUST either call a different tool or perform additional work without using act_mode_respond again. If you attempt to call act_mode_respond consecutively, the tool call will fail with an explicit error and you must choose a different action instead.
|
||||
|
||||
3. Remember, you have extensive capabilities with access to a wide range of tools that can be used in powerful and clever ways as necessary to accomplish each goal. First, analyze the file structure provided in environment_details to gain context and insights for proceeding effectively. Then, think about which of the provided tools is the most relevant tool to accomplish the user's task. Next, go through each of the required parameters of the relevant tool and determine if the user has directly provided or given enough information to infer a value. When deciding if the parameter can be inferred, carefully consider all the context to see if it supports a specific value. If all of the required parameters are present or can be reasonably inferred, close the thinking tag and proceed with the tool use. BUT, if one of the values for a required parameter is missing, DO NOT invoke the tool (not even with fillers for the missing params) and instead, ask the user to provide the missing parameters using the ask_followup_question tool. DO NOT ask for more information on optional parameters if it is not provided.
|
||||
|
||||
4. **Code Generation Self-Review Loop**: After generating code, evaluate against an internal quality rubric using your reasoning:
|
||||
|
||||
@@ -26,7 +26,7 @@ const NATIVE_GPT_5: ClineToolSpec = {
|
||||
variant: ModelFamily.NATIVE_GPT_5,
|
||||
id,
|
||||
name: "act_mode_respond",
|
||||
description: `Provide a progress update or preamble to the user during ACT MODE execution. This tool allows you to communicate your thought process and planned actions without interrupting the execution flow. After displaying your message, execution automatically continues, allowing you to proceed with subsequent tool calls immediately. This tool is only available in ACT MODE. This tool may not be called immediately after a previous act_mode_respond call.
|
||||
description: `Provide a progress update or preamble to the user during ACT MODE execution. This tool allows you to communicate your thought process and planned actions without interrupting the execution flow. After displaying your message, execution automatically continues, allowing you to proceed with subsequent tool calls immediately. This tool is only available in ACT MODE for OpenAI native models.
|
||||
|
||||
IMPORTANT: Use this tool frequently to create a better user experience. Since it's non-blocking, there's no performance penalty for frequent use.
|
||||
|
||||
@@ -40,7 +40,7 @@ Use this tool when:
|
||||
|
||||
Do NOT use this tool when you have completed all required actions and are ready to present the final output; in that case, use the attempt_completion tool instead.
|
||||
|
||||
CRITICAL CONSTRAINT: You MUST NOT call this tool more than once in a row. After using act_mode_respond, your next assistant message MUST either call a different tool or perform additional work without using act_mode_respond again. If you attempt to call act_mode_respond consecutively, the tool call will fail with an explicit error.`,
|
||||
After calling this tool, you must call a different tool in your next message to continue execution.`,
|
||||
parameters: [
|
||||
{
|
||||
name: "response",
|
||||
|
||||
@@ -109,7 +109,6 @@ export interface SystemPromptContext {
|
||||
readonly isTesting?: boolean
|
||||
readonly runtimePlaceholders?: Readonly<Record<string, unknown>>
|
||||
readonly yoloModeToggled?: boolean
|
||||
readonly clineWebToolsEnabled?: boolean
|
||||
readonly isMultiRootEnabled?: boolean
|
||||
readonly workspaceRoots?: Array<{ path: string; name: string; vcs?: string }>
|
||||
readonly isSubagentsEnabledAndCliInstalled?: boolean
|
||||
|
||||
@@ -59,6 +59,7 @@ export const config = createVariant(ModelFamily.GENERIC)
|
||||
ClineDefaultTool.MCP_ACCESS,
|
||||
ClineDefaultTool.ASK,
|
||||
ClineDefaultTool.ATTEMPT,
|
||||
ClineDefaultTool.NEW_TASK,
|
||||
ClineDefaultTool.PLAN_MODE,
|
||||
ClineDefaultTool.MCP_DOCS,
|
||||
ClineDefaultTool.TODO,
|
||||
|
||||
@@ -47,6 +47,7 @@ export const config = createVariant(ModelFamily.GLM)
|
||||
ClineDefaultTool.MCP_ACCESS,
|
||||
ClineDefaultTool.ASK,
|
||||
ClineDefaultTool.ATTEMPT,
|
||||
ClineDefaultTool.NEW_TASK,
|
||||
ClineDefaultTool.PLAN_MODE,
|
||||
ClineDefaultTool.MCP_DOCS,
|
||||
ClineDefaultTool.TODO,
|
||||
|
||||
@@ -57,6 +57,7 @@ export const config = createVariant(ModelFamily.GPT_5)
|
||||
ClineDefaultTool.MCP_ACCESS,
|
||||
ClineDefaultTool.ASK,
|
||||
ClineDefaultTool.ATTEMPT,
|
||||
ClineDefaultTool.NEW_TASK,
|
||||
ClineDefaultTool.PLAN_MODE,
|
||||
ClineDefaultTool.MCP_DOCS,
|
||||
ClineDefaultTool.TODO,
|
||||
|
||||
@@ -85,8 +85,6 @@ This ensures your work aligns with the existing codebase structure and avoids un
|
||||
|
||||
This tool is non-blocking, so using it frequently improves user experience and ensures long tasks are completed successfully.
|
||||
|
||||
Additionally, you MUST NOT call act_mode_respond more than once in a row. After using act_mode_respond, your next assistant message MUST either call a different tool or perform additional work without using act_mode_respond again. If you attempt to call act_mode_respond consecutively, the tool call will fail with an explicit error and you must choose a different action instead.
|
||||
|
||||
3. Remember, you have extensive capabilities with access to a wide range of tools that can be used in powerful and clever ways as necessary to accomplish each goal. First, analyze the file structure provided in environment_details to gain context and insights for proceeding effectively. Then, think about which of the provided tools is the most relevant tool to accomplish the user's task. Next, go through each of the required parameters of the relevant tool and determine if the user has directly provided or given enough information to infer a value. When deciding if the parameter can be inferred, carefully consider all the context to see if it supports a specific value. If all of the required parameters are present or can be reasonably inferred, close the thinking tag and proceed with the tool use. BUT, if one of the values for a required parameter is missing, DO NOT invoke the tool (not even with fillers for the missing params)${context.yoloModeToggled !== true ? " and instead, ask the user to provide the missing parameters using the ask_followup_question tool" : ""}. DO NOT ask for more information on optional parameters if it is not provided.
|
||||
|
||||
4. **Code Generation Self-Review Loop**: After generating code, evaluate against an internal quality rubric using your reasoning:
|
||||
|
||||
@@ -62,6 +62,7 @@ export const config = createVariant(ModelFamily.NATIVE_GPT_5)
|
||||
ClineDefaultTool.MCP_ACCESS,
|
||||
ClineDefaultTool.ASK,
|
||||
ClineDefaultTool.ATTEMPT,
|
||||
ClineDefaultTool.NEW_TASK,
|
||||
ClineDefaultTool.PLAN_MODE,
|
||||
ClineDefaultTool.MCP_DOCS,
|
||||
ClineDefaultTool.TODO,
|
||||
|
||||
@@ -55,6 +55,7 @@ export const config = createVariant(ModelFamily.NATIVE_NEXT_GEN)
|
||||
ClineDefaultTool.WEB_FETCH,
|
||||
ClineDefaultTool.MCP_ACCESS,
|
||||
ClineDefaultTool.ATTEMPT,
|
||||
ClineDefaultTool.NEW_TASK,
|
||||
ClineDefaultTool.PLAN_MODE,
|
||||
ClineDefaultTool.MCP_DOCS,
|
||||
ClineDefaultTool.TODO,
|
||||
|
||||
@@ -60,6 +60,7 @@ export const config = createVariant(ModelFamily.NEXT_GEN)
|
||||
ClineDefaultTool.MCP_ACCESS,
|
||||
ClineDefaultTool.ASK,
|
||||
ClineDefaultTool.ATTEMPT,
|
||||
ClineDefaultTool.NEW_TASK,
|
||||
ClineDefaultTool.PLAN_MODE,
|
||||
ClineDefaultTool.MCP_DOCS,
|
||||
ClineDefaultTool.TODO,
|
||||
|
||||
@@ -2,7 +2,6 @@ import type { ApiProviderInfo } from "@core/api"
|
||||
import { ClineRulesToggles } from "@shared/cline-rules"
|
||||
import fs from "fs/promises"
|
||||
import { telemetryService } from "@/services/telemetry"
|
||||
import { isNativeToolCallingConfig } from "@/utils/model-utils"
|
||||
import {
|
||||
condenseToolResponse,
|
||||
deepPlanningToolResponse,
|
||||
@@ -38,16 +37,12 @@ export async function parseSlashCommands(
|
||||
globalWorkflowToggles: ClineRulesToggles,
|
||||
ulid: string,
|
||||
focusChainSettings?: { enabled: boolean },
|
||||
enableNativeToolCalls?: boolean,
|
||||
providerInfo?: ApiProviderInfo,
|
||||
): Promise<{ processedText: string; needsClinerulesFileCheck: boolean }> {
|
||||
const SUPPORTED_DEFAULT_COMMANDS = ["newtask", "smol", "compact", "newrule", "reportbug", "deep-planning", "subagent"]
|
||||
|
||||
// Determine if the current provider/model/setting actually uses native tool calling
|
||||
const willUseNativeTools = isNativeToolCallingConfig(providerInfo!, enableNativeToolCalls || false)
|
||||
|
||||
const commandReplacements: Record<string, string> = {
|
||||
newtask: newTaskToolResponse(willUseNativeTools),
|
||||
newtask: newTaskToolResponse(),
|
||||
smol: condenseToolResponse(focusChainSettings),
|
||||
compact: condenseToolResponse(focusChainSettings),
|
||||
newrule: newRuleToolResponse(),
|
||||
|
||||
@@ -172,8 +172,6 @@ export async function readGlobalStateFromDisk(context: ExtensionContext): Promis
|
||||
context.globalState.get<GlobalStateAndSettings["strictPlanModeEnabled"]>("strictPlanModeEnabled")
|
||||
const yoloModeToggled = context.globalState.get<GlobalStateAndSettings["yoloModeToggled"]>("yoloModeToggled")
|
||||
const useAutoCondense = context.globalState.get<GlobalStateAndSettings["useAutoCondense"]>("useAutoCondense")
|
||||
const clineWebToolsEnabled =
|
||||
context.globalState.get<GlobalStateAndSettings["clineWebToolsEnabled"]>("clineWebToolsEnabled")
|
||||
const isNewUser = context.globalState.get<GlobalStateAndSettings["isNewUser"]>("isNewUser")
|
||||
const welcomeViewCompleted =
|
||||
context.globalState.get<GlobalStateAndSettings["welcomeViewCompleted"]>("welcomeViewCompleted")
|
||||
@@ -631,7 +629,6 @@ export async function readGlobalStateFromDisk(context: ExtensionContext): Promis
|
||||
strictPlanModeEnabled: strictPlanModeEnabled ?? true,
|
||||
yoloModeToggled: yoloModeToggled ?? false,
|
||||
useAutoCondense: useAutoCondense ?? false,
|
||||
clineWebToolsEnabled: clineWebToolsEnabled ?? true,
|
||||
isNewUser: isNewUser ?? true,
|
||||
welcomeViewCompleted,
|
||||
lastShownAnnouncementId,
|
||||
|
||||
@@ -113,7 +113,6 @@ export class ToolExecutor {
|
||||
private doesLatestTaskCompletionHaveNewChanges: () => Promise<boolean>,
|
||||
private updateFCListFromToolResponse: (taskProgress: string | undefined) => Promise<void>,
|
||||
private switchToActMode: () => Promise<boolean>,
|
||||
private cancelTask: () => Promise<void>,
|
||||
|
||||
// Atomic hook state helpers from Task
|
||||
private setActiveHookExecution: (hookExecution: NonNullable<typeof taskState.activeHookExecution>) => Promise<void>,
|
||||
@@ -164,7 +163,7 @@ export class ToolExecutor {
|
||||
saveCheckpoint: this.saveCheckpoint,
|
||||
postStateToWebview: async () => {},
|
||||
reinitExistingTaskFromId: async () => {},
|
||||
cancelTask: this.cancelTask,
|
||||
cancelTask: async () => {},
|
||||
updateTaskHistory: async (_: any) => [],
|
||||
executeCommandTool: this.executeCommandTool,
|
||||
doesLatestTaskCompletionHaveNewChanges: this.doesLatestTaskCompletionHaveNewChanges,
|
||||
|
||||
+31
-59
@@ -67,13 +67,7 @@ import { CLINE_MCP_TOOL_IDENTIFIER } from "@shared/mcp"
|
||||
import { convertClineMessageToProto } from "@shared/proto-conversions/cline-message"
|
||||
import { ClineDefaultTool } from "@shared/tools"
|
||||
import { ClineAskResponse } from "@shared/WebviewMessage"
|
||||
import {
|
||||
isClaude4PlusModelFamily,
|
||||
isGPT5ModelFamily,
|
||||
isLocalModel,
|
||||
isNextGenModelFamily,
|
||||
isNextGenModelProvider,
|
||||
} from "@utils/model-utils"
|
||||
import { isClaude4PlusModelFamily, isGPT5ModelFamily, isLocalModel, isNextGenModelFamily, isNextGenModelProvider } from "@utils/model-utils"
|
||||
import { arePathsEqual, getDesktopDir } from "@utils/path"
|
||||
import { filterExistingFiles } from "@utils/tabFiltering"
|
||||
import cloneDeep from "clone-deep"
|
||||
@@ -546,7 +540,6 @@ export class Task {
|
||||
() => this.checkpointManager?.doesLatestTaskCompletionHaveNewChanges() ?? Promise.resolve(false),
|
||||
this.FocusChainManager?.updateFCListFromToolResponse.bind(this.FocusChainManager) || (async () => {}),
|
||||
this.switchToActModeCallback.bind(this),
|
||||
this.cancelTask,
|
||||
// Atomic hook state helpers for ToolExecutor
|
||||
this.setActiveHookExecution.bind(this),
|
||||
this.clearActiveHookExecution.bind(this),
|
||||
@@ -824,33 +817,10 @@ export class Task {
|
||||
return await this.controller.toggleActModeForYoloMode()
|
||||
}
|
||||
|
||||
/**
|
||||
* Unified cancellation handler for hook-requested cancellations.
|
||||
* Ensures state is always saved before aborting, regardless of whether
|
||||
* the user clicked cancel or the hook returned {cancel: true}.
|
||||
*
|
||||
* @param hookName The name of the hook for logging
|
||||
* @param wasCancelled Whether user clicked cancel (vs hook returning cancel: true)
|
||||
*/
|
||||
private async handleHookCancellation(hookName: string, wasCancelled: boolean): Promise<void> {
|
||||
// ALWAYS save state, regardless of cancellation source
|
||||
this.taskState.didFinishAbortingStream = true
|
||||
|
||||
// Save conversation state to disk
|
||||
await this.messageStateHandler.saveClineMessagesAndUpdateHistory()
|
||||
await this.messageStateHandler.overwriteApiConversationHistory(this.messageStateHandler.getApiConversationHistory())
|
||||
|
||||
// Update UI
|
||||
await this.postStateToWebview()
|
||||
|
||||
// Log for debugging/telemetry
|
||||
console.log(`[Task ${this.taskId}] ${hookName} hook cancelled (userInitiated: ${wasCancelled})`)
|
||||
}
|
||||
|
||||
private async runUserPromptSubmitHook(
|
||||
userContent: ClineContent[],
|
||||
_context: "initial_task" | "resume" | "feedback",
|
||||
): Promise<{ cancel?: boolean; wasCancelled?: boolean; contextModification?: string; errorMessage?: string }> {
|
||||
): Promise<{ cancel?: boolean; contextModification?: string; errorMessage?: string }> {
|
||||
const hooksEnabled = this.stateManager.getGlobalSettingsKey("hooksEnabled")
|
||||
|
||||
if (!hooksEnabled) {
|
||||
@@ -973,11 +943,20 @@ export class Task {
|
||||
|
||||
// Handle cancellation from hook
|
||||
if (taskStartResult.cancel === true) {
|
||||
// Always save state regardless of cancellation source
|
||||
await this.handleHookCancellation("TaskStart", taskStartResult.wasCancelled)
|
||||
// If hook was cancelled by user, save state for resume
|
||||
if (taskStartResult.wasCancelled) {
|
||||
// Set flag to allow Controller.cancelTask() to proceed
|
||||
this.taskState.didFinishAbortingStream = true
|
||||
// Save BOTH clineMessages AND apiConversationHistory so Controller.cancelTask() can find the task
|
||||
await this.messageStateHandler.saveClineMessagesAndUpdateHistory()
|
||||
await this.messageStateHandler.overwriteApiConversationHistory(
|
||||
this.messageStateHandler.getApiConversationHistory(),
|
||||
)
|
||||
await this.postStateToWebview()
|
||||
}
|
||||
|
||||
// Let Controller handle the cancellation (it will call abortTask)
|
||||
await this.cancelTask()
|
||||
// abortTask will handle cleanup
|
||||
this.abortTask()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -993,12 +972,6 @@ export class Task {
|
||||
}
|
||||
}
|
||||
|
||||
// Defensive check: Verify task wasn't aborted during hook execution before continuing
|
||||
// Must be OUTSIDE the hooksEnabled block to prevent UserPromptSubmit from running
|
||||
if (this.taskState.abort) {
|
||||
return
|
||||
}
|
||||
|
||||
// Run UserPromptSubmit hook for initial task (after TaskStart for UI ordering)
|
||||
const userPromptHookResult = await this.runUserPromptSubmitHook(userContent, "initial_task")
|
||||
|
||||
@@ -1007,10 +980,9 @@ export class Task {
|
||||
return
|
||||
}
|
||||
|
||||
// Handle hook cancellation
|
||||
// Handle hook cancellation - but DON'T call abortTask()
|
||||
// Controller.cancelTask() already called it, calling again causes double TaskCancel
|
||||
if (userPromptHookResult.cancel === true) {
|
||||
await this.handleHookCancellation("UserPromptSubmit", userPromptHookResult.wasCancelled ?? false)
|
||||
await this.cancelTask()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1121,11 +1093,19 @@ export class Task {
|
||||
|
||||
// Handle cancellation from hook
|
||||
if (taskResumeResult.cancel === true) {
|
||||
// UNIFIED: Always save state regardless of cancellation source
|
||||
await this.handleHookCancellation("TaskResume", taskResumeResult.wasCancelled)
|
||||
// If hook was cancelled by user, save state for resume
|
||||
if (taskResumeResult.wasCancelled) {
|
||||
// Set flag to allow Controller.cancelTask() to proceed
|
||||
this.taskState.didFinishAbortingStream = true
|
||||
// Save BOTH clineMessages AND apiConversationHistory so Controller.cancelTask() can find the task
|
||||
await this.messageStateHandler.saveClineMessagesAndUpdateHistory()
|
||||
await this.messageStateHandler.overwriteApiConversationHistory(
|
||||
this.messageStateHandler.getApiConversationHistory(),
|
||||
)
|
||||
await this.postStateToWebview()
|
||||
}
|
||||
|
||||
// Let Controller handle the cancellation (it will call abortTask)
|
||||
await this.cancelTask()
|
||||
// Return without continuing task - Controller.cancelTask() will handle showing resume button
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1137,13 +1117,6 @@ export class Task {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Defensive check: Verify task wasn't aborted during hook execution before continuing
|
||||
// Must be OUTSIDE the hooksEnabled block to prevent UserPromptSubmit from running
|
||||
if (this.taskState.abort) {
|
||||
return
|
||||
}
|
||||
|
||||
let responseText: string | undefined
|
||||
let responseImages: string[] | undefined
|
||||
let responseFiles: string[] | undefined
|
||||
@@ -1272,7 +1245,7 @@ export class Task {
|
||||
// Handle hook cancellation request
|
||||
if (userPromptHookResult.cancel === true) {
|
||||
// The hook already updated its status to "cancelled" internally and saved state
|
||||
await this.cancelTask()
|
||||
this.abortTask()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -2074,7 +2047,6 @@ export class Task {
|
||||
preferredLanguageInstructions,
|
||||
browserSettings: this.stateManager.getGlobalSettingsKey("browserSettings"),
|
||||
yoloModeToggled: this.stateManager.getGlobalSettingsKey("yoloModeToggled"),
|
||||
clineWebToolsEnabled: this.stateManager.getGlobalSettingsKey("clineWebToolsEnabled"),
|
||||
isMultiRootEnabled: multiRootEnabled,
|
||||
workspaceRoots,
|
||||
isSubagentsEnabledAndCliInstalled,
|
||||
@@ -3263,7 +3235,7 @@ export class Task {
|
||||
globalWorkflowToggles,
|
||||
this.ulid,
|
||||
this.stateManager.getGlobalSettingsKey("focusChainSettings"),
|
||||
this.useNativeToolCalls,
|
||||
this.getCurrentProviderInfo(),
|
||||
)
|
||||
|
||||
if (needsCheck) {
|
||||
|
||||
@@ -89,12 +89,6 @@ export class ToolHookUtils {
|
||||
|
||||
// Handle cancellation from hook
|
||||
if (preToolResult.cancel === true) {
|
||||
// Clear the active hook execution state BEFORE calling cancelTask
|
||||
// This prevents abortTask from trying to "cancel" an already-completed hook
|
||||
await config.callbacks.clearActiveHookExecution()
|
||||
|
||||
// Abort the entire task (consistent with PostToolUse and other hook cancellations)
|
||||
await config.callbacks.cancelTask()
|
||||
throw new PreToolUseHookCancellationError(preToolResult.errorMessage || "PreToolUse hook requested cancellation")
|
||||
}
|
||||
|
||||
|
||||
@@ -110,7 +110,7 @@ export abstract class WebviewProvider {
|
||||
<link rel="stylesheet" type="text/css" href="${stylesUrl}">
|
||||
<link href="${codiconsUrl}" rel="stylesheet" />
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'none';
|
||||
connect-src https://*.posthog.com https://*.cline.bot;
|
||||
connect-src https://*.posthog.com https://*.cline.bot https://*.firebaseauth.com https://*.firebaseio.com https://*.googleapis.com https://*.firebase.com;
|
||||
font-src ${this.getCspSource()} data:;
|
||||
style-src ${this.getCspSource()} 'unsafe-inline';
|
||||
img-src ${this.getCspSource()} https: data:;
|
||||
|
||||
+1
-1
@@ -401,7 +401,7 @@ export async function activate(context: vscode.ExtensionContext) {
|
||||
|
||||
context.subscriptions.push(
|
||||
context.secrets.onDidChange(async (event) => {
|
||||
if (event.key === "cline:clineAccountId") {
|
||||
if (event.key === "clineAccountId" || event.key === "cline:clineAccountId") {
|
||||
// Check if the secret was removed (logout) or added/updated (login)
|
||||
const secretValue = await context.secrets.get(event.key)
|
||||
const activeWebview = WebviewProvider.getVisibleInstance()
|
||||
|
||||
@@ -9,6 +9,7 @@ import { telemetryService } from "@/services/telemetry"
|
||||
import { openExternal } from "@/utils/env"
|
||||
import { featureFlagsService } from "../feature-flags"
|
||||
import { ClineAuthProvider } from "./providers/ClineAuthProvider"
|
||||
import { FirebaseAuthProvider } from "./providers/FirebaseAuthProvider"
|
||||
import { IAuthProvider } from "./providers/IAuthProvider"
|
||||
import { LogoutReason } from "./types"
|
||||
|
||||
@@ -64,6 +65,7 @@ export class AuthService {
|
||||
protected _authenticated: boolean = false
|
||||
protected _clineAuthInfo: ClineAuthInfo | null = null
|
||||
protected _provider: IAuthProvider | null = null
|
||||
protected _fallbackProvider: IAuthProvider | null = null
|
||||
protected _activeAuthStatusUpdateHandlers = new Set<StreamingResponseHandler<AuthState>>()
|
||||
protected _handlerToController = new Map<StreamingResponseHandler<AuthState>, Controller>()
|
||||
protected _controller: Controller
|
||||
@@ -73,7 +75,9 @@ export class AuthService {
|
||||
* @param controller - Optional reference to the Controller instance.
|
||||
*/
|
||||
protected constructor(controller: Controller) {
|
||||
this._initProvider()
|
||||
// Default to firebase for now
|
||||
const providerName = featureFlagsService.getWorkOsAuthEnabled() ? "cline" : "firebase"
|
||||
this._setProvider(providerName)
|
||||
this._controller = controller
|
||||
}
|
||||
|
||||
@@ -116,7 +120,13 @@ export class AuthService {
|
||||
throw new Error("Auth provider is not set")
|
||||
}
|
||||
|
||||
return this.internalGetAuthToken(this._provider)
|
||||
const token = await this.internalGetAuthToken(this._provider)
|
||||
|
||||
if (!token && this._fallbackProvider) {
|
||||
return this.internalGetAuthToken(this._fallbackProvider)
|
||||
}
|
||||
|
||||
return token
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -163,7 +173,8 @@ export class AuthService {
|
||||
}
|
||||
|
||||
// IMPORTANT: Prefix with 'workos:' so backend can route verification to WorkOS provider
|
||||
return clineAccountAuthToken ? `workos:${clineAccountAuthToken}` : null
|
||||
const prefix = provider.name === "cline" ? "workos:" : ""
|
||||
return clineAccountAuthToken ? `${prefix}${clineAccountAuthToken}` : null
|
||||
} catch (error) {
|
||||
console.error("Error getting auth token:", error)
|
||||
return null
|
||||
@@ -174,9 +185,19 @@ export class AuthService {
|
||||
return this._clineAuthInfo?.provider === provider.name
|
||||
}
|
||||
|
||||
protected _initProvider(): void {
|
||||
protected _setProvider(providerName: string): void {
|
||||
// Only ClineAuthProvider is supported going forward
|
||||
this._provider = new ClineAuthProvider()
|
||||
// Keeping the providerName param for forward compatibility/telemetry
|
||||
switch (providerName) {
|
||||
case "cline":
|
||||
this._provider = new ClineAuthProvider()
|
||||
this._fallbackProvider = new FirebaseAuthProvider()
|
||||
break
|
||||
case "firebase":
|
||||
default:
|
||||
this._provider = new FirebaseAuthProvider()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -313,7 +334,13 @@ export class AuthService {
|
||||
throw new Error("Auth provider is not set")
|
||||
}
|
||||
|
||||
return this._provider.retrieveClineAuthInfo(this._controller)
|
||||
const authInfo = await this._provider.retrieveClineAuthInfo(this._controller)
|
||||
|
||||
if (!authInfo && this._fallbackProvider) {
|
||||
return this._fallbackProvider.retrieveClineAuthInfo(this._controller)
|
||||
}
|
||||
|
||||
return authInfo
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -381,14 +408,15 @@ export class AuthService {
|
||||
})
|
||||
|
||||
await Promise.all(streamSends)
|
||||
|
||||
// Identify the user in telemetry if available
|
||||
if (this._clineAuthInfo?.userInfo?.id) {
|
||||
telemetryService.identifyAccount(this._clineAuthInfo.userInfo)
|
||||
// Reset feature flags to ensure they are fetched for the new/logged in user
|
||||
featureFlagsService.reset(this._clineAuthInfo?.userInfo?.id)
|
||||
featureFlagsService.reset()
|
||||
}
|
||||
// Poll feature flags to ensure they are up to date for all users
|
||||
await featureFlagsService.poll(this._clineAuthInfo?.userInfo?.id)
|
||||
await featureFlagsService.poll()
|
||||
|
||||
// Update state in webviews once per unique controller
|
||||
await Promise.all(Array.from(uniqueControllers).map((c) => c.postStateToWebview()))
|
||||
|
||||
@@ -16,7 +16,9 @@ export class AuthServiceMock extends AuthService {
|
||||
throw new Error("AuthServiceMock should only be used in local environment for testing purposes.")
|
||||
}
|
||||
|
||||
this._initProvider()
|
||||
// Support both auth providers, default to firebase for compatibility
|
||||
const authProvider = process.env.E2E_TEST_AUTH_PROVIDER || "firebase"
|
||||
this._setProvider(authProvider)
|
||||
this._controller = controller
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user