From 199822258bbeb40e7845abb5ade3e2e1b61b8c3f Mon Sep 17 00:00:00 2001 From: gleox Date: Thu, 14 May 2026 10:11:42 +0800 Subject: [PATCH] =?UTF-8?q?feat(openai):=20=E6=94=AF=E6=8C=81=E9=80=9A?= =?UTF-8?q?=E8=BF=87=E7=8E=AF=E5=A2=83=E5=8F=98=E9=87=8F=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E4=BB=A3=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 6 ++++++ CHANGELOG_zh.md | 6 ++++++ CLAUDE.md | 4 +++- README.md | 12 ++++++++++++ README_zh.md | 12 ++++++++++++ docs/DESIGN.md | 4 +++- package-lock.json | 16 +++++++++++++--- package.json | 3 ++- src/llm.ts | 5 ++++- 9 files changed, 61 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b956e77..bf86a04 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. +## [1.3.10] - 2026-05-14 + +### Added + +- OpenAI provider now supports system proxy via `HTTPS_PROXY` / `HTTP_PROXY` / `NO_PROXY` environment variables + ## [1.3.9] - 2026-03-16 ### Added diff --git a/CHANGELOG_zh.md b/CHANGELOG_zh.md index 08d7595..36b81b4 100644 --- a/CHANGELOG_zh.md +++ b/CHANGELOG_zh.md @@ -2,6 +2,12 @@ [English](./CHANGELOG.md) +## [1.3.10] - 2026-05-14 + +### 新增 + +- OpenAI provider 支持通过 `HTTPS_PROXY` / `HTTP_PROXY` / `NO_PROXY` 环境变量设置系统代理 + ## [1.3.9] - 2026-03-16 ### 新增 diff --git a/CLAUDE.md b/CLAUDE.md index c1ab744..078a238 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -13,7 +13,7 @@ Seven source files in `src/`: - **index.ts** — CLI entry point (Commander.js). Routes to openai or claude provider based on config - **config.ts** — Reads env vars into a `Config` object. `provider` field selects openai/claude. Exports `GenerateResult` type - **git.ts** — Runs `git diff --cached` and `git commit -m` -- **llm.ts** — Sends diff to OpenAI-compatible chat completions endpoint, returns `GenerateResult` with token usage +- **llm.ts** — Sends diff to OpenAI-compatible chat completions endpoint via undici fetch with EnvHttpProxyAgent (supports HTTPS_PROXY/HTTP_PROXY/NO_PROXY), returns `GenerateResult` with token usage - **claude.ts** — Calls `claude -p` CLI to generate commit messages (Claude reads diff + source files itself), returns `GenerateResult` - **prompt.ts** — Builds system prompt enforcing Conventional Commits format - **update-check.ts** — Non-blocking version check against GitHub, 24h cache in `~/.ai-commit/.update-check` @@ -39,3 +39,5 @@ ai-commit -d # dry-run test Required: `AI_COMMIT_API_KEY` (only for openai provider) Optional: `AI_COMMIT_PROVIDER` (openai/claude, default openai), `AI_COMMIT_API_URL` (default DeepSeek), `AI_COMMIT_MODEL`, `AI_COMMIT_LANGUAGE` (en/zh), `AI_COMMIT_MAX_TOKENS` (500) + +Proxy: `HTTPS_PROXY` / `HTTP_PROXY` (for openai provider), `NO_PROXY` (bypass) diff --git a/README.md b/README.md index 89bee65..d24cdfa 100644 --- a/README.md +++ b/README.md @@ -160,6 +160,18 @@ ai-commit --uninstall | `AI_COMMIT_MAX_TOKENS` | Max tokens for generation | `500` | | `AI_COMMIT_EMOJI` | Always add emoji (`true` / `false`) | `false` | +### Proxy + +OpenAI provider supports system proxy via standard environment variables: + +```bash +export HTTPS_PROXY="http://127.0.0.1:7890" +# or +export HTTP_PROXY="http://127.0.0.1:7890" +``` + +Both `HTTPS_PROXY` / `https_proxy` and `HTTP_PROXY` / `http_proxy` are recognized. `NO_PROXY` / `no_proxy` is also supported to bypass proxy for specific hosts. + ## Changelog See [CHANGELOG.md](./CHANGELOG.md) for release history. diff --git a/README_zh.md b/README_zh.md index 18aadd9..9ef953b 100644 --- a/README_zh.md +++ b/README_zh.md @@ -162,6 +162,18 @@ ai-commit --uninstall | `AI_COMMIT_MAX_TOKENS` | 最大生成 token 数 | `500` | | `AI_COMMIT_EMOJI` | 始终添加 emoji(`true` / `false`) | `false` | +### 代理 + +OpenAI provider 支持通过标准环境变量设置系统代理: + +```bash +export HTTPS_PROXY="http://127.0.0.1:7890" +# 或 +export HTTP_PROXY="http://127.0.0.1:7890" +``` + +支持 `HTTPS_PROXY` / `https_proxy` 和 `HTTP_PROXY` / `http_proxy`。同时支持 `NO_PROXY` / `no_proxy` 跳过指定主机的代理。 + ## 更新日志 查看 [CHANGELOG_zh.md](./CHANGELOG_zh.md) 了解完整版本历史。 diff --git a/docs/DESIGN.md b/docs/DESIGN.md index c05b156..5338c50 100644 --- a/docs/DESIGN.md +++ b/docs/DESIGN.md @@ -22,7 +22,7 @@ AI Commit 是一个命令行工具,通过分析 `git diff` 内容,调用大 |------|------|------| | 语言 | Node.js (TypeScript) | 生态成熟,npm 分发方便,跨平台 | | CLI 框架 | Commander.js | 轻量、主流 | -| HTTP 请求 | node-fetch / 内置 fetch | 调用 LLM API | +| HTTP 请求 | undici fetch + EnvHttpProxyAgent | 调用 LLM API,支持系统代理 | | 交互 | Inquirer.js | 终端交互体验好 | | 包管理 | npm | 通过 `npx` 可免安装使用 | @@ -130,6 +130,8 @@ async function generateCommitMessageWithClaude(diff: string, config: Config): Pr ```typescript async function generateCommitMessage(diff: string, config: Config): Promise; // 构建请求体,调用 OpenAI 兼容 API,返回生成的 commit message +// 使用 undici 的 EnvHttpProxyAgent 自动读取 HTTPS_PROXY/HTTP_PROXY/NO_PROXY 环境变量 +// 支持系统代理,无需额外配置 ``` 请求体格式(OpenAI 兼容): diff --git a/package-lock.json b/package-lock.json index 03b7b05..6d3a69c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,16 +1,17 @@ { "name": "ai-commit-cli", - "version": "1.0.0", + "version": "1.3.7", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ai-commit-cli", - "version": "1.0.0", + "version": "1.3.7", "license": "MIT", "dependencies": { "@inquirer/prompts": "^8.3.0", - "commander": "^12.1.0" + "commander": "^12.1.0", + "undici": "^8.2.0" }, "bin": { "ai-commit": "dist/index.js" @@ -664,6 +665,15 @@ "node": ">=14.17" } }, + "node_modules/undici": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-8.2.0.tgz", + "integrity": "sha512-Z+4Hx9GE26Lh9Upwfnc8C7SsrpBPGaM/Gm6kMFtiG7c+5IvQKlXi/t+9x9DrrCh29cww5TSP9YdVaBcnLDs5fQ==", + "license": "MIT", + "engines": { + "node": ">=22.19.0" + } + }, "node_modules/undici-types": { "version": "6.21.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", diff --git a/package.json b/package.json index 506c139..6362fde 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,8 @@ ], "dependencies": { "@inquirer/prompts": "^8.3.0", - "commander": "^12.1.0" + "commander": "^12.1.0", + "undici": "^8.2.0" }, "devDependencies": { "@types/node": "^20.14.0", diff --git a/src/llm.ts b/src/llm.ts index b486182..bf36664 100644 --- a/src/llm.ts +++ b/src/llm.ts @@ -1,6 +1,7 @@ import { Config, GenerateResult } from "./config"; import { getSystemPrompt } from "./prompt"; import { prepareDiffContent } from "./git"; +import { EnvHttpProxyAgent, fetch as undiciFetch } from "undici"; interface ChatResponse { choices: { message: { content: string } }[]; @@ -9,6 +10,7 @@ interface ChatResponse { export async function generateCommitMessage(diff: string, config: Config): Promise { const content = prepareDiffContent(diff); + const dispatcher = new EnvHttpProxyAgent(); const body = { model: config.model, @@ -20,13 +22,14 @@ export async function generateCommitMessage(diff: string, config: Config): Promi temperature: 0.3, }; - const response = await fetch(config.apiUrl, { + const response = await undiciFetch(config.apiUrl, { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${config.apiKey}`, }, body: JSON.stringify(body), + dispatcher, }); if (!response.ok) {