Skip to content

Latest commit

 

History

History
1181 lines (894 loc) · 65 KB

README.en.md

File metadata and controls

1181 lines (894 loc) · 65 KB

GCMP - Multi-Provider AI Chat Models for GitHub Copilot

English | 中文

CI License

Integrates leading Chinese AI model providers into GitHub Copilot Chat, giving developers richer, more locally-tuned AI coding assistant options. Currently supports ZhipuAI, MiniMax, MoonshotAI, DeepSeek, Alibaba Cloud DashScope, Volcengine, Tencent Cloud, Xiaomi MiMo, Baidu Qianfan, StepFun, Ant Ling, XunFei Astron, and LongCat as native providers. Additionally, the extension supports any OpenAI or Anthropic API-compatible models via the Compatible Provider.

🚀 Quick Start

1. Install the Extension

Search for GCMP in the VS Code Extension Marketplace, or use the identifier: vicanent.gcmp

2. Get Started

  1. Open the GitHub Copilot Chat panel in VS Code
  2. Click Manage Models at the bottom of the model selector, then choose a provider from the list
  3. On first use, you'll be prompted to set an API Key. Complete the configuration and return to the model selector to enable the model
  4. Select your target model in the model selector and start chatting with the AI assistant

3. Configure VS Code Utility and GCMP Auxiliary Models (Recommended)

VS Code 1.128+: A startup dialog will automatically detect if chat.utilityModel and chat.utilitySmallModel are configured. If both are unset, a prompt will guide you through the setup. When using non-official Copilot models (BYOK/custom providers), unconfigured utility models will cause "No utility model is configured" errors.

VS Code uses lightweight background models for utility tasks like title generation, commit messages, search, and intent detection. GCMP features such as commit message generation and vision analysis also require their own model selections. If not configured manually, VS Code falls back to Copilot's built-in models, which consume your monthly quota — especially limited for free-tier users. Pointing these tasks to GCMP-provided models saves Copilot quota for more important work.

💡 Quick configuration entry: hover the Token-usage icon in the status bar and click the Set auxiliary tool models link at the bottom of the daily-statistics popup to open a visual panel for unified configuration of all the models below. You can also run GCMP: Set Auxiliary Tool Models from the command palette.

Click to expand detailed parameter descriptions
{
    // General utility tasks: title generation, summaries, intent classification, rename suggestions, terminal commands/fixes, search, VS Code Q&A
    "chat.utilityModel": "gcmp.deepseek/gcmp.deepseek:::deepseek-v4-pro",
    // Lightweight utility tasks: commit messages, branch names, progress messages, todo tracking
    "chat.utilitySmallModel": "gcmp.deepseek/gcmp.deepseek:::deepseek-v4-flash",
    // Inline Chat default model
    "inlineChat.defaultModel": "GLM-4.7 (CodingPlan) (gcmp.zhipu)",
    // Agent-mode sub-agents for exploration/planning (e.g., codebase search, plan generation)
    "chat.exploreAgent.defaultModel": "GLM-4.7 (CodingPlan) (gcmp.zhipu)",
    "chat.planAgent.defaultModel": "GLM-4.7 (CodingPlan) (gcmp.zhipu)",
    // GitHub Copilot Chat dedicated agents (Ask / Implement / Explore)
    "github.copilot.chat.askAgent.model": "GLM-4.7 (CodingPlan) (gcmp.zhipu)",
    "github.copilot.chat.implementAgent.model": "GLM-4.7 (CodingPlan) (gcmp.zhipu)",
    "github.copilot.chat.exploreAgent.model": "GLM-4.7 (CodingPlan) (gcmp.zhipu)",
    // GCMP built-in commit message generation model
    "gcmp.commit.model": {
        "provider": "zhipu",
        "model": "glm-4.7"
    },
    // GCMP built-in vision analysis model (must support image input)
    "gcmp.vision.model": {
        "provider": "zhipu",
        "model": "glm-4.6v"
    }
}

Recommendation: Use a fast-responding model for utilitySmallModel (for example, deepseek-v4-flash). You can pair it with maxInputTokens: 16384 or a similarly low limit for quick tasks.

When editing settings.json, place the cursor on the value and use VS Code IntelliSense to choose from registered models. If left unset, VS Code will use Copilot's built-in models for utility tasks, which may consume Copilot monthly quota for free-tier users. Using a GCMP model here helps avoid that.

You can also run GCMP: Set Auxiliary Tool Models from the command palette to open a visual panel for unified configuration of all the models above.

Shortcut entry: hover the Token-usage icon in the status bar and click the Set auxiliary tool models link at the bottom of the daily-statistics popup to open the same panel.

  • chat.utilitySmallModel: Lightweight utility tasks (default: gpt-4o-mini). Covers chat-title, git-commit-message, git-branch-name, inline-progress-message, prompt-categorizer, todo-tracker, rename-suggestions, terminal-command/quickfix/explain, and workspace-search.
  • chat.utilityModel: General utility tasks (default: CAPI fallback). Covers settings-resolver, explain-code, and vscode-qa.
  • inlineChat.defaultModel: Inline Chat default model, used for in-editor inline chat (Ctrl+I / right-click "Chat Inline").
  • chat.exploreAgent.defaultModel: Explore sub-agent default model, used for search-subagent codebase exploration and search.
  • chat.planAgent.defaultModel: Plan sub-agent default model, used for planning and task decomposition in Agent mode.
  • github.copilot.chat.askAgent.model: Ask Agent default model, used for Ask-mode Q&A.
  • github.copilot.chat.implementAgent.model: Implement Agent default model, used for Implement-mode code generation.
  • github.copilot.chat.exploreAgent.model: Explore Agent default model, used for Explore-mode codebase exploration.
  • gcmp.commit.model: GCMP built-in commit message generation model.
  • gcmp.vision.model: GCMP built-in vision analysis model; choose a model that supports image input.

🤖 Built-in AI Model Providers

This extension only includes first-tier providers with self-developed models (e.g., major cloud vendors with model R&D capabilities). For third-party model access, use the "OpenAI / Anthropic Compatible" mode.

  • Model list: See config/zhipu.json (Coding Plan / PayGo / Free models).
  • Plans: Coding Plan.
    • Usage tracking: Status bar displays remaining cycle quota for GLM Coding Plan.
  • Balance query: Status bar displays account balance alongside usage; tooltip and config panel show total recharge, granted amount, total spend, and available balance.
  • International site: Supports switching to the international site (z.ai).
  • Search: Integrated Web Search MCP and Web Search API, supports #zhipuWebSearch for web searches.
    • Web Search MCP mode is enabled by default. Coding Plan includes: Lite (100/month), Pro (1,000/month), Max (4,000/month).
    • Disable MCP mode in settings to use the Web Search API pay-per-request billing.
  • Model list: See config/minimax.json (Token Plan / PayGo).
  • Plans: Token Plan.
    • Search: Integrated Token Plan web search tool, supports #minimaxWebSearch.
    • Usage tracking: Status bar displays remaining Token Plan quota.
    • International site: Supports international Token Plan.
  • Model list: See config/moonshot.json (Membership / PayGo).
  • Plans: Membership — Kimi membership plan includes the Kimi For Coding coding-model benefit.
    • Search: Integrated Kimi Search web search tool, supports #kimiWebSearch.
    • Usage tracking: Status bar displays remaining quota, top-up wallet balance and expiration, and rate-limit reset time.
  • Balance query: Status bar displays current account balance.
  • Model list: See config/stepfun.json (Step Plan / PayGo).
  • Search: Integrated #stepfunWebSearch MCP web search tool with category filtering.
    • Step Plan subscriptions use MCP; non-subscription users use standard pay-per-request billing.

Ant Group's open-source MoE-architecture LLM family, accessed via Anthropic mode.

LLM service platform under iFLYTEK, accessed via Anthropic SDK mode with dual-plan key management.

LongCat - LongCat

Agentic models from the LongCat API platform, accessed via Anthropic SDK mode.

CLI Coding Tool API Providers

The following providers are themselves AI coding CLI tools (similar to Claude Code) that expose API endpoints for third-party access to their aggregated model capabilities.

Hyper - Charm Hyper

ClinePass - Cline's official model subscription service

  • Model list: See config/clinepass.json.
  • Usage tracking: Status bar displays plan cycle remaining usage, reset time, and total utilization.

CommandCode - Coding CLI and model subscription focused on open models

OAuth Coding Assistant Providers

⚠️ Risk Warning: The following providers access APIs by simulating OAuth authentication of official CLI tools. This may violate third-party terms of service and carries the risk of account bans. Use only if you are fully informed and voluntarily accept the risks.

Codex CLI - OpenAI Codex

OpenAI's official coding assistant Codex CLI tool. Supports authentication via the codex CLI (requires local installation).

npm install -g @openai/codex@latest
  • Supported models: See config/codex.json.
  • Usage tracking: Status bar displays remaining ChatGPT subscription cycle quota.
  • Independent proxy settings: Codex CLI uses its own proxy configuration (independent of the extension-wide gcmp.proxy). You can specify a dedicated proxy for Codex requests via gcmp.providerOverrides.codex.proxy.
{
    "gcmp.providerOverrides": {
        "codex": {
            "proxy": "http://127.0.0.1:10808"
        }
    }
}

Grok Build - xAI Grok Build

xAI's official Grok Build coding assistant CLI tool. Supports OAuth authentication via the grok CLI (requires local installation).

# macOS / Linux
curl -fsSL https://x.ai/cli/install.sh | bash

# Windows PowerShell
irm https://x.ai/cli/install.ps1 | iex
  • Supported models: See config/grok.json.
  • Usage tracking: The status bar displays remaining Grok/SuperGrok subscription quota and reset time. Weekly quota is preferred; unified-billing accounts show monthly quota.
  • Independent proxy settings: Use gcmp.providerOverrides.grok.proxy for Grok requests. Set GROK_CLI_CHAT_PROXY_BASE_URL to override the Grok CLI billing service base URL.

⚙️ Advanced Configuration

GCMP supports customizing AI model behavior parameters through VS Code settings for a more personalized experience.

📝 Note: All settings.json parameter changes take effect immediately.

Click to expand advanced configuration details

General Model Parameters & Extra Features

{
    "gcmp.retry.enabled": true, // Enable auto retry (default true), disable to stop on failure
    "gcmp.retry.maxAttempts": 3 // 1-10, only effective for retryable errors
}
  • gcmp.retry.enabled defaults to true. When enabled, automatically retries retryable errors like 429 rate limit, 503 service unavailable. Set to false to disable retries entirely and stop immediately on failure.
  • gcmp.retry.maxAttempts defaults to 3, controlling the maximum automatic retry count for 429, 502/503/504 server errors, and network connectivity failures.
  • Retry delays increase cumulatively (1s → 3s → 6s → 10s → 15s), capped at 15s.
  • During retries, the status bar shows retry progress (e.g., Model retry #2/3 in 3s), automatically cleared when the model starts returning data.
  • gcmp.maxTokens is deprecated: this setting no longer takes effect; each model now automatically uses its own maxOutputTokens configuration.

Provider-Level Retry Configuration Override

Use gcmp.providerOverrides.{provider}.retry to set per-provider retry strategies that override global gcmp.retry.* behavior. maxAttempts is NOT capped at 1-10, allowing any positive integer or -1 (unlimited retries).

{
    "gcmp.providerOverrides": {
        "xfyun": {
            "retry": {
                "enabled": true,
                "maxAttempts": 15, // Not capped at 1-10
                "maxDelayMs": 30000 // Max delay cap 30s
            },
            "retry.xfyun-coding": {
                // Sub-provider independent strategy (higher priority)
                "enabled": true,
                "maxAttempts": 20,
                "maxDelayMs": 60000
            }
        }
    }
}

Merge priority (field-level merge, each field falls back independently):

providerOverrides["retry.{subProvider}"] → providerOverrides.retry → built-in preset → global default

Special semantics:

Value Meaning
maxAttempts = -1 Unlimited retries (exit only on non-retryable errors)
maxAttempts = 0 Disable retries (override path, equivalent to enabled: false)
preset.maxAttempts = 0 Does not reduce global maxAttempts; use override to force disable
enabled = false Takes effect per the enabled field merge priority

Provider-Level Rate Limiting (limit)

Use gcmp.providerOverrides.{provider}.limit to set request rate limits per provider. Four optional dimensions; 0 or omitted means unlimited for that dimension. Whichever dimension hits its cap first throttles the request (pacing delay or FIFO queue).

Field Meaning
rpm Max requests per minute (paced)
rps Max requests per second (paced)
tpm Max tokens per minute (estimated from input, paced)
parallel Max concurrent in-flight requests; excess requests wait FIFO for a free slot
{
    "gcmp.providerOverrides": {
        "dashscope": {
            "limit": { "rpm": 60, "parallel": 3 },
            // Sub-provider specific limit (higher priority)
            "limit.dashscope-coding": { "rpm": 30 },
            "models": [
                // Model-level limit: overrides same-named provider dimensions field-by-field,
                // and uses an isolated provider::model bucket
                { "id": "deepseek-v4-pro", "limit": { "tpm": 100000 } }
            ]
        }
    }
}

Merge priority (same as retry, field-level merge):

providerOverrides["limit.{subProvider}"] → providerOverrides.limit → built-in preset

Cross-instance behavior: multiple VS Code windows share a Leader-authoritative rate-limit bucket (Leader is elected automatically between windows); dimensions always follow the Leader's local configuration and config edits take effect immediately. When the Leader is unavailable, windows fall back to per-window local buckets and re-probe every 60 seconds, returning to strict cross-instance mode once it recovers. When a window closes or disconnects, its queued requests and held quotas are reclaimed automatically and never block other windows. In Remote scenarios (SSH/WSL) the cross-instance channel is unavailable, so each window always uses its local bucket.

Feature-specific settings such as gcmp.commit.enabled, gcmp.vision.model, and gcmp.zhipu.search.enableMCP are documented in their respective feature sections, not here.

Status-Bar Balance Warning Threshold

Balance-based status bars show a yellow background when the available balance is at or below 20 by default, and a red background for negative balances. Use gcmp.providerOverrides.{provider}.balanceWarning to override the threshold per provider; set it to 0 to highlight only overdrawn accounts.

{
    "gcmp.providerOverrides": {
        "deepseek": {
            "balanceWarning": 10
        },
        "moonshot": {
            "balanceWarning": 30
        },
        "compatible": {
            // Compatible providers without an explicit threshold use this default
            "balanceWarning": 20
        }
    }
}
  • Applies to DeepSeek, Moonshot, balance-only Zhipu/CommandCode views, and every balance provider in the Compatible status bar.
  • The value uses the unit returned by the provider. Usage-plan status bars still warn by usage percentage.
  • Changing the setting repaints the current cached status immediately without sending another balance query.

Debugging & HAR Capture

{
    "gcmp.debug.captureHar": false, // Capture all HTTP requests as HAR files (default false)
    "gcmp.debug.harRetentionCount": 7 // Number of recent HAR files to keep per VS Code instance (0 = disable count-based cleanup only; 2-hour hard deletion still applies)
}
  • When gcmp.debug.captureHar is enabled, GCMP writes HAR 1.2 files under globalStorage/har/, grouped by VS Code instance and date, to help diagnose compatibility and gateway issues.
  • FIM / NES completions, Gist sync, and CLI OAuth refresh requests skip capture by default to avoid recording sensitive credentials and high-frequency duplicate traffic.
  • Credentials in sensitive headers, URL query parameters, and redirect URLs are redacted before writing, but request and response bodies are stored as-is. Keep HAR files secure.
  • HAR files rotate at least every 30 minutes; files older than 2 hours are force-deleted when a new recording starts or a file rotates.
  • harRetentionCount controls how many recent files each process keeps by count; setting it to 0 disables only count-based cleanup, while the 2-hour hard deletion still runs.

Proxy & System Certificate Settings

{
    "gcmp.proxy": "http://127.0.0.1:7890", // Optional global proxy, full URL recommended
    "gcmp.tls.useSystemCertificates": true // Append OS root CAs (enabled by default)
}
  • gcmp.proxy acts as the default proxy for all extension network requests, including chat requests, FIM / NES completions, web search tools, MCP clients, status-bar quota/balance queries, Compatible Provider model discovery requests, and CLI OAuth refresh calls.
  • Proxy precedence is: model.proxy → gcmp.providerOverrides.<provider>.proxy → gcmp.providerOverrides.compatible.proxy (non-built-in only) → gcmp.proxy → VS Code http.proxy → environment variables (HTTPS_PROXY / HTTP_PROXY) → System proxy (auto-detected).
  • Supports host:port shorthand (e.g., 127.0.0.1:7890), but using a full URL like http://127.0.0.1:7890 is recommended.
  • Set to noproxy to bypass all proxies (including system proxies and configured ones). When any layer in the proxy chain is set to noproxy, fallback short-circuits immediately.
  • When no explicit proxy is configured, the extension automatically detects system proxy settings from the Windows Registry or macOS scutil.
  • ⚠️ PAC (Proxy Auto-Config) is not supported. If your system proxy uses PAC, it will be ignored — use an explicit proxy URL instead.

  • gcmp.tls.useSystemCertificates appends operating-system trusted root certificates to Node.js' default CA list, which is useful behind enterprise proxies, internal gateways, or locally installed private root CAs.
  • Authenticated proxy URLs are supported; usernames and passwords are automatically redacted in logs.

Provider Configuration Overrides

GCMP supports overriding provider defaults through the gcmp.providerOverrides setting. Support varies by provider type:

Provider Type Supported Fields models[]
Built-in (deepseek/zhipu etc.) baseUrl, customHeader, proxy, retry, models[] ✅ Full model add/override
Known (aihubmix/openrouter etc.) customHeader, proxy, retry ❌ Use gcmp.compatibleModels instead
Custom (from compatibleModels) customHeader, proxy, retry ❌ Use gcmp.compatibleModels instead
compatible itself customHeader, proxy, retry ❌ Use gcmp.compatibleModels instead

Override precedence:

model-level > providerOverrides.{provider} > providerOverrides.compatible
  • providerOverrides.compatible acts as global defaults for all Compatible Provider models
  • Proxy: model.proxy > providerOverrides.{provider}.proxy > providerOverrides.compatible.proxy (non-built-in only) > gcmp.proxy > VS Code http.proxy > environment variables
  • Custom headers: providerOverrides.{provider}.customHeader > model customHeader > providerOverrides.compatible.customHeader
  • Retry: providerOverrides["retry.{subProvider}"] > providerOverrides.retry > built-in preset > global gcmp.retry.*

Configuration example:

{
    "gcmp.providerOverrides": {
        "dashscope": {
            "proxy": "http://127.0.0.1:7890", // Optional provider-level default proxy
            "models": [
                {
                    "id": "deepseek-v3.2", // Add extra model: not in suggestions, but allows custom additions
                    "name": "Deepseek-V3.2 (DashScope)",
                    "tooltip": "DeepSeek-V3.2 introduces DeepSeek Sparse Attention and is the first DeepSeek model to integrate thinking into tool usage.",
                    "maxInputTokens": 128000,
                    "maxOutputTokens": 16000,
                    "capabilities": {
                        "toolCalling": true,
                        "imageInput": false
                    }
                }
            ]
        },
        "aihubmix": {
            "proxy": "http://127.0.0.1:7890", // proxy override also supported
            "customHeader": { "X-Custom": "value" },
            "retry": {
                // provider-level retry override
                "enabled": true,
                "maxAttempts": 5,
                "maxDelayMs": 30000
            }
        },
        "compatible": {
            "proxy": "http://127.0.0.1:7890" // global default proxy for all Compatible Provider models
        }
    }
}

🔌 Compatible Custom Model Support

GCMP provides a Compatible Provider for any OpenAI or Anthropic API-compatible service. Through the gcmp.compatibleModels setting, you can fully customize model parameters, including extended request parameters.

  1. Launch the configuration wizard via the GCMP: Compatible Provider Settings command.
  2. Edit the gcmp.compatibleModels setting in settings.json.
Click to expand custom model configuration details

Built-in Known Provider IDs and Display Names

Aggregation/relay providers may receive built-in special adaptations and are not listed as standalone providers.
If you need built-in or special adaptation support, please submit an Issue with relevant information.
Known providers support gcmp.providerOverrides.{providerId} for customHeader and proxy overrides.

Provider ID Provider Name Description Balance Query
aiping AI Ping Account balance
aihubmix AIHubMix 10% off API Key balance
openrouter OpenRouter Account balance
siliconflow SiliconFlow Account balance

Configuration example:

{
    "gcmp.compatibleModels": [
        {
            "id": "glm-4.7",
            "name": "GLM-4.7",
            "provider": "zhipu",
            "model": "glm-4.7",
            "sdkMode": "openai",
            "baseUrl": "https://open.bigmodel.cn/api/coding/paas/v4",
            // "proxy": "http://127.0.0.1:7890", // Optional: applies only to this model and to the "Fetch Models" probe request
            // "sdkMode": "anthropic",
            // "baseUrl": "https://open.bigmodel.cn/api/anthropic",
            "maxInputTokens": 128000,
            "maxOutputTokens": 4096,
            "capabilities": {
                "toolCalling": true, // Model must support tool calling in Agent mode
                "imageInput": false
            },
            // customHeader and extraBody are optional
            "customHeader": {
                "X-Model-Specific": "value",
                "X-Custom-Key": "${APIKEY}"
            },
            "extraBody": {
                "temperature": 0.1,
                "top_p": 0.9,
                // "top_p": null, // Some providers don't support temperature + top_p simultaneously
                "thinking": { "type": "disabled" }
            }
            // "webSearchTool": true, // Optional: enable web search (only effective when sdkMode=anthropic or openai-responses)
            // "nativeTools": [{ "type": "web_search" }] // Optional: inject native tools (only effective when sdkMode=openai-responses)
            // "cacheTtl": "1h" // Optional: Anthropic prompt cache TTL (anthropic SDK mode only); omit for the default 5m. 1h cache writes cost about 2x base input price
        }
    ]
}

Tip: if you use OpenAI Responses / compatible proxies and do not want encrypted reasoning (reasoning.encrypted_content) replayed, explicitly set extraBody.include to null or []; in that case the historical chain is replayed via plain reasoning_text, and stripped ThinkingPart entries are restored from StatefulMarker. Include reasoning.encrypted_content when you want ciphertext replayed.

  • gcmp.compatibleModels[*].proxy applies only to the current custom model. When you click "Fetch Models" after entering baseUrl, the same proxy setting is also used for the discovery request.

sdkMode

gcmp.compatibleModels[*].sdkMode specifies the request/streaming parsing mode. Available values: openai (default), openai-sse, openai-responses, anthropic, and gemini-sse (Gemini GenerateContent SSE).

gemini-sse uses x-goog-api-key for official Google endpoints and Authorization: Bearer for third-party gateways, then calls /v1beta/models/{model}:streamGenerateContent?alt=sse; customHeader can override or remove the default authentication header. extraBody.generationConfig is merged into generationConfig, while other fields are forwarded at the Gemini GenerateContent request top level (except protected core fields such as contents, tools, and systemInstruction). Supported serviceTier values are unspecified, standard, flex, and priority.

Anthropic prompt cache TTL: cacheTtl

Models with sdkMode=anthropic can configure gcmp.compatibleModels[*].cacheTtl:

  • Omitted (default): no ttl field is written, so Anthropic's default 5-minute cache applies — identical to previous behavior
  • "5m" / "1h": every block-level cache_control breakpoint in the request carries this TTL uniformly; mixed TTLs (which cause 400s) can never occur
  • "1h" suits sessions with idle gaps longer than 5 minutes but under 1 hour; cache writes cost about 2x base input price, while cache reads remain 0.1x

Note: a top-level cache_control in extraBody is stripped with a warning (it stacks with the 4 auto-injected block-level breakpoints and exceeds the limit, or mixes TTLs into a 400). Use cacheTtl instead.

Custom provider balance/usage query example: intelligent merge of usage + usages

For a Compatible custom provider, you can configure the following under gcmp.providerOverrides.{providerId}:

  • usage: optional; for a single balance query, configuring only this is enough, and it can also serve as the shared defaults for usages
  • usages: optional; use this only when you need multiple named balance/amount query modes, and each item can incrementally override fields from usage

fields.balance computed fields now support sum / subtract / multiply / divide, and paths can contain JSON field paths, constant numbers (for example, 500000), or nested computed field objects, which is useful for conversions like Ticket / 500000 or (total - used) / 500000.

{
    "balance": {
        "operation": "divide",
        "paths": [
            {
                "operation": "subtract",
                "paths": [
                    "data.subscriptions[0].subscription.amount_total",
                    "data.subscriptions[0].subscription.amount_used"
                ]
            },
            500000
        ]
    }
}

Nested objects are evaluated first, and their results then participate in the outer calculation.

Use [*] in a path to match every item in an array and sum the target field. For example, data.subscriptions[*].subscription.amount_total sums amount_total across all subscriptions. If the array or field is missing, or a value cannot be parsed as a finite number, it is treated as 0; this also applies inside nested calculations and to fields.paid and fields.granted.

{
    "balance": {
        "operation": "divide",
        "paths": [
            {
                "operation": "subtract",
                "paths": [
                    "data.subscriptions[*].subscription.amount_total",
                    "data.subscriptions[*].subscription.amount_used"
                ]
            },
            500000
        ]
    }
}

In other words:

  • configure only usage: a single balance query
  • use usages only when you need multiple query modes for different balances/amounts
  • configure neither usage nor usages: no balance/usage query will be registered for this custom provider

For built-in known provider usage / usages reference configurations, see the source file src/utils/knownProviders.ts.

Note: the provider key in gcmp.providerOverrides must match gcmp.compatibleModels[*].provider exactly, including letter case.

For example, the following NekoCode-related snippet is closer to a real-world settings.json setup:

  • multiple models in gcmp.compatibleModels share the same provider: "NekoCode"
  • gcmp.providerOverrides.NekoCode.usage defines the default query URL https://api2.nekoapi.ai/v1/usage and the shared field path balance
  • gcmp.providerOverrides.NekoCode.usages.pay resolves to the same final query config as usage, and only adds the display name Balance
  • gcmp.providerOverrides.NekoCode.usages.sub reuses usage.fields.balance but overrides the query URL to https://api2.nekoapi.ai/v1/user/balance
{
    "gcmp.compatibleModels": [
        {
            "id": "nekocode:gpt-5.5",
            "name": "GPT-5.5 (NekoCode)",
            "provider": "NekoCode",
            "model": "gpt-5.5",
            "sdkMode": "openai-responses",
            "baseUrl": "https://api2.nekoapi.ai/v1",
            "proxy": "noproxy",
            "maxInputTokens": 272000,
            "maxOutputTokens": 128000,
            "capabilities": {
                "toolCalling": true,
                "imageInput": true
            },
            "reasoningDefault": "xhigh",
            "reasoningEffort": ["none", "low", "medium", "high", "xhigh"],
            "extraBody": {
                "store": false,
                "reasoning": {
                    "effort": "xhigh",
                    "summary": "auto"
                }
            },
            "useInstructions": true,
            "customHeader": {
                "version": "0.134.0",
                "user-agent": "codex-tui/0.134.0 (Windows 10.0.26200; x86_64) unknown (codex-tui; 0.134.0)",
                "originator": "codex-tui"
            }
        }
    ],
    "gcmp.providerOverrides": {
        "NekoCode": {
            "usage": {
                "url": "https://api2.nekoapi.ai/v1/usage",
                "fields": {
                    "balance": "balance"
                }
            },
            "usages": {
                "pay": {
                    "displayName": "Balance",
                    "url": "https://api2.nekoapi.ai/v1/usage"
                },
                "sub": {
                    "displayName": "Subscription",
                    "url": "https://api2.nekoapi.ai/v1/user/balance",
                    "fields": {
                        "balance": "remaining"
                    }
                }
            }
        }
    }
}

The effective behavior of this configuration is:

  • providerOverrides.NekoCode applies to all compatible models whose provider is "NekoCode", such as GPT-5.4 (NekoCode) and GPT-5.5 (NekoCode) above
  • pay inherits usage.fields.balance = "balance"
  • sub also inherits usage.fields.balance = "balance"
  • because pay resolves to the same final query config as usage, no extra duplicate default mode will be emitted

The status bar will therefore query and display two named modes:

  • NekoCode / Balance
  • NekoCode / Subscription

💡 FIM / NES Inline Completion Suggestions

  • FIM: Predicts and completes missing code at the cursor position based on context, suitable for single-line/short snippet completion.
  • NES: Provides intelligent code suggestions based on editing context, supporting multi-line code generation.

Important: An API Key must be configured and verified in a chat model first. Select GitHub Copilot Inline Completion via GCMP in the Output panel to view debug info. These use general-purpose LLMs not specifically trained for code completion, so results may not match Copilot's native Tab completion.

Click to expand detailed configuration

FIM / NES Inline Completion Model Configuration

FIM and NES completions use separate model configurations, configurable via gcmp.fimCompletion.modelConfig and gcmp.nesCompletion.modelConfig.

Proxy Configuration: FIM and NES support a proxy field to set a dedicated proxy address (e.g., http://127.0.0.1:7890) for debugging under different network conditions. Authenticated proxies are supported; user credentials are automatically redacted in logs.

  • Enable FIM completion mode (recommended: DeepSeek, Qwen, and other FIM-supporting models):
    • Tested with DeepSeek, SiliconFlow, and special support for Alibaba Cloud DashScope.
{
    "gcmp.fimCompletion.enabled": true, // Enable FIM completion
    "gcmp.fimCompletion.debounceMs": 500, // Debounce delay for auto-triggered completion
    "gcmp.fimCompletion.timeoutMs": 5000, // FIM completion request timeout
    "gcmp.fimCompletion.modelConfig": {
        "provider": "deepseek", // Provider ID; for others, add an OpenAI Compatible custom model provider and set API Key first
        "baseUrl": "https://api.deepseek.com/beta", // ⚠️ DeepSeek FIM requires the beta endpoint
        // "baseUrl": "https://api.siliconflow.cn/v1", // SiliconFlow (provider: `siliconflow`)
        // "baseUrl": "https://dashscope.aliyuncs.com/compatible-mode/v1", // DashScope (provider: `dashscope`)
        // "proxy": "http://127.0.0.1:7890", // Optional: set a dedicated proxy
        "model": "deepseek-chat",
        "maxTokens": 100
        // "extraBody": { "top_p": 0.9 }
    }
}
  • Enable NES manual completion mode:
{
    "gcmp.nesCompletion.enabled": true, // Enable NES completion
    "gcmp.nesCompletion.debounceMs": 500, // Debounce delay for auto-triggered completion
    "gcmp.nesCompletion.timeoutMs": 10000, // NES completion request timeout
    "gcmp.nesCompletion.manualOnly": true, // Enable manual `Alt+/` shortcut trigger
    "gcmp.nesCompletion.modelConfig": {
        "provider": "zhipu", // Provider ID; for others, add an OpenAI Compatible custom model provider and set API Key first
        "baseUrl": "https://open.bigmodel.cn/api/coding/paas/v4", // OpenAI Chat Completion Endpoint BaseUrl
        // "proxy": "http://127.0.0.1:7890", // Optional: set a dedicated proxy
        "model": "glm-4.7", // Recommended: use a performant model; check logs for ``` markdown code fences
        "maxTokens": 200,
        "extraBody": {
            // GLM-4.7 enables thinking by default; disable for faster completion responses
            "thinking": { "type": "disabled" }
        }
    }
}
  • Mixed FIM + NES completion mode:
  • Auto-trigger + manualOnly: false: Intelligently selects provider based on cursor position
    • Cursor at end of line → FIM (suitable for completing current line)
    • Cursor not at end of line → NES (suitable for mid-line editing)
    • If NES returns no result or meaningless completion, falls back to FIM
  • Auto-trigger + manualOnly: true: Only initiates FIM requests (NES requires manual trigger)
  • Manual trigger (press Alt+/): Directly invokes NES, no FIM request
  • Mode toggle (press Shift+Alt+/): Switch between auto/manual (affects NES only)

MistralAI Coding FIM Configuration Example

{
    "gcmp.compatibleModels": [
        {
            "id": "codestral-latest",
            "name": "codestral-latest",
            "provider": "mistral",
            "baseUrl": "https://codestral.mistral.ai/v1",
            "sdkMode": "openai",
            "maxInputTokens": 32000,
            "maxOutputTokens": 4096,
            "capabilities": {
                "toolCalling": true,
                "imageInput": false
            }
        }
    ],
    "gcmp.fimCompletion.enabled": true,
    "gcmp.fimCompletion.debounceMs": 500,
    "gcmp.fimCompletion.timeoutMs": 5000,
    "gcmp.fimCompletion.modelConfig": {
        "provider": "mistral",
        "baseUrl": "https://codestral.mistral.ai/v1/fim",
        // "proxy": "http://127.0.0.1:7890", // Optional: set a dedicated proxy
        "model": "codestral-latest",
        "extraBody": { "code_annotations": null },
        "maxTokens": 100
    }
}

Circuit Breaker

When FIM or NES completion requests fail consecutively, the circuit breaker temporarily pauses requests to prevent endless retries, saving both resources and costs.

Three-state model:

State Description
Closed Normal operation — requests pass through, failures are counted
Open Tripped — all requests are rejected, cooldown countdown begins
HalfOpen Cooldown elapsed — allows one probe request; success restores Closed, failure re-trips Open

Workflow:

  1. Consecutive failures reach failureThreshold → breaker transitions Closed → Open
  2. In Open state, all requests are immediately rejected; wait cooldownSeconds seconds
  3. After cooldown, the first allowRequest() enters HalfOpen and issues one probe request
  4. Probe succeeds (recordSuccess()) → back to Closed, service restored
  5. Probe fails (recordFailure()) → back to Open, cooldown restarts. One retry per cooldown cycle (once every 30 seconds by default) until success or manual "Retry Now"
  6. Request cancelled by user (recordCancellation()) → probe slot is returned, re-probing allowed

Notification: A warning popup appears on the first Open transition (throttled to once per 30 seconds), offering "Retry Now" to reset the breaker or "View Settings" to navigate to the configuration page.

Configuration:

{
    // FIM circuit breaker settings (enabled by default)
    "gcmp.fimCompletion.circuitBreaker": {
        "enabled": true, // Enable circuit breaker
        "failureThreshold": 10, // Default 10, range 2-60
        "cooldownSeconds": 30 // Default 30, range 10-300
    },
    // NES circuit breaker settings (enabled by default)
    "gcmp.nesCompletion.circuitBreaker": {
        "enabled": true, // Enable circuit breaker
        "failureThreshold": 5, // Default 5, range 2-20
        "cooldownSeconds": 30 // Default 30, range 10-300
    }
}

Configuration changes take effect immediately, no VS Code restart needed.

Keyboard Shortcuts

Shortcut Action
Alt+/ Manually trigger completion (NES mode)
Shift+Alt+/ Toggle NES manual trigger mode

🪟 Context Window Usage Status Bar

GCMP provides a status bar indicator showing the current session's context window usage ratio via a pie chart icon.

Click to expand feature details

Key Features

  • Real-time monitoring: The status bar displays the current session's context window usage ratio as a pie chart icon (0/8 ~ 8/8)
  • Hover details: Hover to view the model name, usage percentage, token count, and request kind
  • Incremental estimation: Supports delta estimation based on the previous request's actual API usage. The WebView detail view shows a "this request" increment column (~+xx) to help track per-request token growth in long conversations

📊 Token Usage Statistics

GCMP includes comprehensive token usage tracking to help you monitor and manage AI model consumption.

Click to expand feature details

Key Features

  • Persistent logging: File-based logging with no storage limits, supporting long-term data retention
  • Usage tracking: Records model and usage information for each API request, including:
    • Model info (provider, model ID, model name)
    • Token usage (estimated input, actual input, output, cache, reasoning, etc.)
    • Request status (estimated/completed/failed)
  • Multi-dimensional statistics: View data by date, provider, model, hour, etc.
    • Hourly detail: Supports three-level nesting by hour, provider, and model
      • ⏰ Hour level: Total data for that hour
      • 📦 Provider level: Aggregated data for that provider in that hour
      • ├─ Model level: Detailed data for that model in that hour
      • Providers and models sorted by request count descending; those with no valid requests are hidden
  • Real-time status bar: Status bar displays today's token usage, auto-refreshing every 30 seconds
  • Visual view: WebView detail view supports viewing history and paginated request records
  • Request kind classification: Records and displays the Copilot request kind for each request (e.g., main agent, title generation, commit message, search subagent, vision recognition) so you can track the actual consumption of background utility tasks
  • Real-time Request Metrics: Displays time-to-first-token (TTFT) and time-per-output-token (TPOT) in real time during streaming, naturally refreshed by actual usage once completed
  • Real-time Output Token Estimation: Streaming-phase output tokens and output speed (tokens/s) are estimated in real time via tokenizer; the output column shows the "last received estimation delta" (+xx tks), replaced by actual usage once completed
  • Cache hit rate visualization: The input column combines cache hit count and total input, showing the cache hit rate to help judge cache strategy effectiveness
  • Client cost estimation: Supports peak/off-peak tiered pricing, service-tier billing, and context-size conditional tiers. Estimated costs are displayed inline below token counts, integrated in the status bar, detail view, and multi-day trend view
  • Dual-currency cost display: Pricing configs support listing both USD and RMB, marked by each model's native settlement currency; costs are displayed in dual currencies across the status bar (in Chinese locale), detail view, sidebar date list and session records, and multi-day trend view, with a new USD/RMB currency switch view
  • Multi-day cost view: Cost trend line chart and cost card summary in the multi-day trend view
  • Error classification and retry safeguard: Permanent errors — daily/monthly hard quota exhaustion, billing or plan limits, requests exceeding model context limits — are no longer misclassified as rate limits and retried repeatedly; unlimited retry mode (maxAttempts=-1) now has a 30-minute total elapsed time safeguard

How to Use

  • View statistics: Click the token usage indicator in the status bar, or run GCMP: View Today's Token Usage Details from the command palette
  • History: View statistics for any date in the detail view
  • Data management: Open the log storage directory for manual management

Configuration

{
    "gcmp.usages.retentionDays": 100 // Number of days to retain historical data (0 = permanent)
}

📝 Commit Message Generation

GCMP supports automatically reading repository changes (staged/unstaged/new files) before committing, extracting key diff snippets, and combining relevant historical commits with the repository's overall commit style (in auto mode) to generate commit messages that match your project's conventions.

To avoid sending noisy or potentially sensitive content to the model, commit message generation applies an extra filtering pass before diff analysis:

  • Automatically omits large lockfile / snapshot diff bodies such as package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lockb, and *.snap
  • Automatically skips common sensitive files such as .env*, certificate/private key files, and files under .aws / .ssh / .gnupg / .docker
  • Lets you add your own sensitive file matching rules through gcmp.commit.sensitiveFiles
Click to expand usage details

System Requirements

  • vscode.git extension: This feature depends on VS Code's built-in vscode.git extension to access Git repository information
    • The extension automatically detects Git availability; related buttons are hidden when Git is unavailable
    • If you've disabled the vscode.git extension, the commit message generation feature will be unavailable

Entry Points: Git Source Control View

  • Repository title bar button: Generate Commit Message
  • Change group buttons:
    • On "Staged Changes": Generate Commit Message - Staged Changes
    • On "Changes": Generate Commit Message - Unstaged Changes

Generation Scope (staged / working tree)

  • Generate Commit Message: Default behavior, analyzes staged + working tree (tracked + untracked).
  • Generate Commit Message - Staged Changes: Only analyzes staged, suitable for "incremental/split commits".
  • Generate Commit Message - Unstaged Changes: Only analyzes working tree (tracked + untracked), excluding staged.

Multi-repo workspaces: If the current workspace contains multiple Git repositories, GCMP will attempt to infer the repository from the SCM area you clicked; if inference fails, a repository selector will appear.

Model Selection & Configuration

This feature calls models via the VS Code Language Model API.

  • On first use or when no model is configured, you'll be guided to select a model (or manually run GCMP: Select Commit Message Model).
  • Related settings:
{
    "gcmp.commit.enabled": true, // Enable built-in commit message generation (default true, will be removed in next major version)
    "gcmp.commit.language": "chinese", // Generation language: chinese / english (fallback when auto mode language is unclear)
    "gcmp.commit.format": "auto", // Commit message format: auto (default) / see format details below
    "gcmp.commit.customInstructions": "", // Custom instructions (only effective when format=custom)
    "gcmp.commit.sensitiveFiles": ["*.pem", "**/.env.local", "secrets/**"], // Extra sensitive file path patterns excluded from diff analysis
    "gcmp.commit.model": {
        "provider": "zhipu", // Model provider (providerKey, e.g., zhipu / minimax / compatible)
        "model": "glm-4.7" // Model ID (corresponding to VS Code Language Model's model.id)
    }
}

gcmp.commit.sensitiveFiles Filter Rules

gcmp.commit.sensitiveFiles extends the built-in sensitive file filtering rules. It accepts a list of simple glob-like strings:

  • *.pem: matches any .pem file
  • **/.env.local: matches .env.local in any directory
  • secrets/**: matches all files under the secrets/ directory
  • **/private/*.key: matches .key files under any private directory

When a file matches, it is excluded from commit diff analysis and is not sent to the model for commit message generation.

gcmp.commit.format Format Reference & Examples

Note: The examples below illustrate format patterns only; actual content is auto-generated based on your diff.

  • auto: Auto-infer (references repository history language/style; falls back to plain + gcmp.commit.language when unclear). Default and recommended.

  • plain: Concise one-liner, no type/scope/emoji (suitable for quick commits).

  • custom: Fully controlled by your custom instructions (gcmp.commit.customInstructions).

  • conventional: Conventional Commits (may include scope, typically "title + optional body points").

feat(commit): add commit message generation

- Support staged / unstaged separate generation
- Auto-include relevant historical commits as reference
  • angular: Angular style (type(scope): summary, semantically similar to conventional).
feat(commit): add SCM entry points

- Add entry points to repository title bar and change group bar
  • karma: Karma style (leans towards "single line", kept short).
fix(commit): fix multi-repo selection
  • semantic: Semantic type: message (no scope; may include body points).
feat: add commit message generation

- Auto-identify key diffs from changes
  • emoji: Emoji prefix (no type).
✨ Add commit message generation
  • emojiKarma: Emoji + Karma (emoji + type(scope): msg).
✨ feat(commit): add commit message generation

- Better aligned with existing repository commit style
  • google: Google style (Type: Description).
Feat: Add commit message generation

- Support auto language and format selection based on repo style
  • atom: Atom style (:emoji: message).
:sparkles: Add commit message generation

👁️ Vision Analysis Tools

GCMP includes a set of dedicated vision analysis tools for converting images/screenshots into actionable development artifacts, extracting text, diagnosing errors, understanding technical diagrams, analyzing data visualizations, and comparing UI differences. All vision analysis is delegated to native multimodal GCMP models without relying on third-party MCP backends.

Click to expand vision analysis tool details

Tool List

Tool Reference Purpose
#gcmpUiToArtifact Convert UI screenshots into front-end code, AI prompts, design specs, or natural language descriptions
#gcmpExtractTextFromScreenshot Extract and recognize text (OCR) from screenshots, supporting code, terminal output, documents, etc.
#gcmpDiagnoseErrorScreenshot Analyze error dialogs, stack traces, and exception screenshots to identify root causes and suggest fixes
#gcmpUnderstandTechnicalDiagram Analyze architecture diagrams, flowcharts, UML, ER diagrams, and system design diagrams
#gcmpAnalyzeDataVisualization Extract trends, anomalies, and actionable insights from charts, graphs, and dashboards
#gcmpUiDiffCheck Compare expected/reference UI screenshots against actual implementations to identify visual differences
#gcmpAnalyzeImage General image analysis for visual content not covered by specialized tools

How to Use

Vision tools are invoked via # references, e.g. #gcmpUiToArtifact. When calling a tool, you can paste images, screenshots, or reference image file paths, and the model will generate the corresponding artifact or analysis based on the image content. All tools share the same vision analysis model configuration.

Configuring the Vision Analysis Model

Vision tools rely on a multimodal model specified by gcmp.vision.model. If unset, a selection wizard is launched on first use; you can also manually run GCMP: Select Vision Analysis Model or configure it through the GCMP: Set Auxiliary Tool Models panel.

{
    "gcmp.vision.model": {
        "provider": "zhipu",
        "model": "glm-4.6v"
    }
}
  • The selected model must support image input (capabilities.imageInput: true).
  • Built-in provider models, Compatible Provider models with image input support, and GitHub Copilot native multimodal models are all supported (set provider to copilot and model to the Copilot model ID).
  • If unset, the model selection wizard is launched automatically on first use, so you don't need to fill in JSON manually in advance.

🗝️ API Key Management Panel

GCMP provides a unified API Key management panel to maintain multiple configuration sets per provider/slot (site + key + note) and switch between them at any time.

How to Use

Run GCMP: Manage API Keys from the command palette.

Key Features

  • Multiple config sets: each provider slot can hold several configurations (custom name + site + key + note) with add/edit/delete/activate/deactivate; the status bar refreshes immediately after panel operations and model list caches are invalidated per slot.
  • CLI authentication integrated: Codex / Grok auth status and subscription quota are shown directly in the panel, with terminal sign-in and credential import/refresh; removing authentication now locates the credential file in the file manager for manual deletion.
  • Gist backup & restore: config sets can be backed up to a GitHub Secret Gist and restored across devices (file gcmp-configsets.json, description starts with GCMP ConfigSets); slot and item metadata stay human-readable while each item's apiKey is encrypted individually (AES-256-GCM), with optional custom passphrase support.
View encryption and security documentation for Gist backup

Storage Architecture

Layer Description
Remote Storage GitHub Secret Gist (private), file named gcmp-configsets.json (description starts with GCMP ConfigSets); metadata stays plaintext, only apiKey fields are encrypted individually
Encryption AES-256-GCM (authenticated encryption — confidentiality + integrity)
Key Derivation scrypt (N=16384, r=8, p=1) with GitHub User ID + fixed pepper + optional custom passphrase
Authentication VS Code built-in GitHub OAuth via vscode.authentication API
Token Scope First-time authorization requests gist scope; subsequent operations reuse the session silently

Encryption Flow

GitHub numeric ID + pepper + [custom passphrase] → scrypt(N=16384, r=8, p=1) → AES-256 key
                                                                                 ↓
Each API Key → Random Salt(32B) + Random IV(16B) → AES-256-GCM → Salt+IV+Tag+Ciphertext → JSON
  • Each key is encrypted with an independent random salt and initialization vector — the same plaintext produces different ciphertext each time
  • The encrypted payload includes Salt, IV, Tag (authentication tag), and Ciphertext, all hex-encoded
  • Decryption depends on the GitHub numeric user ID: the same GitHub account derives the same encryption key across devices

Custom Encryption Passphrase

Since this extension is open source, the encryption method (pepper, scrypt parameters, etc.) is visible in the source code. If you want to treat synced Gist data as truly confidential across devices, you must set a custom encryption passphrase.

  • Select "Set Passphrase" from the panel's Gist Sync menu; you'll be asked to enter it twice for confirmation
  • The passphrase is combined with the GitHub user ID and pepper for key derivation — all three are required (minimum 8 characters)
  • After changing the passphrase, data encrypted with the old passphrase cannot be decrypted (different derived key)
  • The passphrase is stored locally via VS Code SecretStorage (OS-level encryption) and is never uploaded to any server
  • Different devices sharing the same GitHub account need to use the same passphrase to decrypt each other's data

Passphrase Verification on Restore

If the local passphrase doesn't match the one used during upload, a prompt will appear on restore:

  • Passphrase set but decryption fails → prompts that the passphrase may have changed; guides you to enter the previous one
  • No passphrase set but data is undecryptable → prompts that the data may have been encrypted with a passphrase on another device; guides you to enter it
  • After entering the passphrase, it is verified automatically: if decryption succeeds, the correct passphrase is stored for future use
  • If only some keys can be decrypted, a mismatch count is shown

Cross-Device Guidance

When setting the passphrase, a notice is displayed explaining that all devices must use the same passphrase:

  • First-time setup: reminds you to remember the passphrase and set it on all devices
  • Changing passphrase: reminds you to update it on all devices

Data Compatibility

  • When setting/changing the passphrase with existing Gist data, you can choose "Set & Re-upload" to immediately rewrite the remote data with the new passphrase
  • Clearing the passphrase requires confirmation; existing encrypted data will become undecryptable afterwards

Security Notes

  • The Gist is visible in the user's Gist list; with a custom passphrase configured, its content can be treated as confidential backup data against offline attackers
  • Without a custom passphrase, do not treat this scheme as strong confidentiality against a determined offline attacker
  • The encryption key is never transmitted over the network
  • Local API keys are stored via VS Code's built-in SecretStorage (OS-level encrypted storage)
  • All network requests use HTTPS

🤝 Contributing

We welcome community contributions! Whether it's reporting bugs, suggesting features, or submitting code, you can help make this project better.

Development Setup

# Clone the project
git clone https://github.com/VicBilibily/GCMP.git
cd GCMP
# Install dependencies
npm install
# Open in VS Code and press F5 to start extension debugging

💰 Sponsor

If you find this project helpful, consider supporting its continued development by viewing the sponsor QR code.

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.