Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ OPENCODE_PROXY_CLEANUP_MAX_AGE_MS=86400000
# Optional overrides
# OPENCODE_PROXY_PORT=10000
# OPENCODE_SERVER_PORT=10001
# OPENCODE_SERVER_URL=http://127.0.0.1:10001
# BIND_HOST=0.0.0.0
# OPENCODE_PROXY_BIND_HOST=0.0.0.0
# Canonical tool switch (legacy DISABLE_TOOLS also read; canonical wins)
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<p align="center">
<img src="https://img.shields.io/badge/version-1.6.0-blue" alt="Version">
<img src="https://img.shields.io/badge/license-MIT-green" alt="License">
<img src="https://img.shields.io/badge/Node.js-18+-orange" alt="Node">
<img src="https://img.shields.io/badge/Node.js-22.19+-orange" alt="Node">
</p>

> **Language:** [English](./README.md) | [简体中文](./README.zh-CN.md)
Expand Down
2 changes: 1 addition & 1 deletion README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<p align="center">
<img src="https://img.shields.io/badge/version-1.6.0-blue" alt="Version">
<img src="https://img.shields.io/badge/license-MIT-green" alt="License">
<img src="https://img.shields.io/badge/Node.js-18+-orange" alt="Node">
<img src="https://img.shields.io/badge/Node.js-22.19+-orange" alt="Node">
</p>

> **語言:** [English](./README.md) | [简体中文](./README.zh-CN.md)
Expand Down
2 changes: 1 addition & 1 deletion docs/AI_BOT.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ Point at a local gateway (start one with `API_KEY= OPENCODE_PROXY_MANAGE_BACKEND
or fill placeholders — never commit real values:

```bash
export GATEWAY_BASE_URL='http://127.0.0.1:10000' GATEWAY_API_KEY='' CPA_BASE_URL='...' CPA_API_KEY='...'
export GATEWAY_BASE_URL='http://127.0.0.1:10000' GATEWAY_API_KEY='' CPA_BASE_URL=your-cpa-url-here CPA_API_KEY=your-cpa-key-here
export PYTHONPATH=github_bot/src
python3 github_bot/src/github_runner.py --mode=review --dry-run
python3 github_bot/src/github_runner.py --mode=triage --dry-run
Expand Down
16 changes: 14 additions & 2 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

| 变量 | 默认值 | 说明 |
|:-----|:-------|:-----|
| `DISABLE_TOOLS` | `true` | 禁用 OpenCode 工具调用(兼容别名;`OPENCODE_DISABLE_TOOLS` 优先,二者无效值都会让位给下一顺位:canonical env > legacy env > `config.json` > 默认) |
| `OPENCODE_DISABLE_TOOLS` / `DISABLE_TOOLS` | `true` | 禁用 OpenCode 工具调用(兼容别名;`OPENCODE_DISABLE_TOOLS` 优先,二者无效值都会让位给下一顺位:canonical env > legacy env > `config.json` > 默认) |
| `OPENCODE_EXTERNAL_TOOLS_MODE` | `proxy-bridge` | 外部工具桥接模式;当前仅支持 `proxy-bridge` |
| `OPENCODE_EXTERNAL_TOOLS_CONFLICT_POLICY` | `namespace` | 外部工具冲突隔离策略;当前仅支持 `namespace` |
| `OPENCODE_INTERNAL_WEB_FETCH_ENABLED` | `false` | 兼容旧开关;未显式配置 allowlist 时,启用后默认放行 `web_fetch` |
Expand Down Expand Up @@ -72,6 +72,7 @@
| 变量 | 默认值 | 说明 |
|:-----|:-------|:-----|
| `OPENCODE_PROXY_DEBUG` | `false` | 开启调试日志(`config.json` 中用短键 `DEBUG`) |
| `OPENCODE_PROXY_MANAGE_BACKEND` | `false` | 是否由代理拉起本地后端(`config.json` 中用短键 `MANAGE_BACKEND`;prod/`index.ts` 默认 `false`,library/`buildProxyConfig` 默认 `true`——已知双入口差异) |
| `OPENCODE_PATH` | `opencode` | OpenCode 可执行文件路径 |
| `OPENCODE_ZEN_API_KEY` | - | Zen API Key 透传 |

Expand All @@ -92,6 +93,10 @@
"INTERNAL_ALLOWED_TOOLS": ["web_fetch"],
"INTERNAL_TOOL_METRICS_ENABLED": true,
"INTERNAL_TOOL_DISCOVERY_FIXTURE": [],
"HEALTH_DETAILS_ENABLED": true,
"HEALTH_DETAILS_REQUIRE_AUTH": true,
"METRICS_ENABLED": false,
"METRICS_REQUIRE_AUTH": true,
"USE_ISOLATED_HOME": false,
"PROMPT_MODE": "standard",
"OMIT_SYSTEM_PROMPT": false,
Expand All @@ -100,9 +105,16 @@
"CLEANUP_MAX_AGE_MS": 86400000,
"DEBUG": false,
"OPENCODE_SERVER_URL": "http://127.0.0.1:10001",
"OPENCODE_SERVER_PASSWORD": "",
"OPENCODE_PATH": "opencode",
"ZEN_API_KEY": "",
"MANAGE_BACKEND": false,
"REQUEST_TIMEOUT_MS": 180000,
"RETRY_MAX_RETRIES": 3
"RETRY_MAX_RETRIES": 3,
"UPSTREAM_PROXIES": [],
"UPSTREAM_PROXY_STRATEGY": "failover-rr",
"UPSTREAM_PROXY_COOLDOWN_MS": 300000,
"UPSTREAM_PROXY_NO_PROXY": ["localhost", "127.0.0.1", "::1"]
}
```

Expand Down
2 changes: 1 addition & 1 deletion docs/development.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
### Node.js 环境

```bash
# Node.js 18+
# Node.js >=22.19 (engines floor; CI uses 24)
node --version

# npm
Expand Down
6 changes: 3 additions & 3 deletions github_bot/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ To use an external gateway or CPA, export names only (never commit values):

```bash
export GATEWAY_BASE_URL='http://127.0.0.1:10000' # external override; in-job default when unset
export GATEWAY_API_KEY='...' # external gateway key; empty = no-auth localhost
export CPA_BASE_URL='...' # never commit (fallback channel)
export CPA_API_KEY='...' # never commit (fallback channel)
export GATEWAY_API_KEY=your-gateway-key-here # external gateway key; empty = no-auth localhost
export CPA_BASE_URL=your-cpa-url-here # never commit (fallback channel)
export CPA_API_KEY=your-cpa-key-here # never commit (fallback channel)
export PYTHONPATH=github_bot/src
python3 github_bot/src/github_runner.py --mode=review --dry-run
python3 github_bot/src/github_runner.py --mode=triage --dry-run
Expand Down
5 changes: 4 additions & 1 deletion src/proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,10 @@ export function createApp(config: ProxyConfig): CreateAppResult {
const client = rawClient as unknown as ProxyClient;

// Multi-key auth (A): legacy single + list merge; empty = no auth (unchanged).
// Single shared verifier instance (also exposed via ctx for system routes).
// Two verifier instances read the same effective key content (middleware
// here, system routes via ctx.API_KEYS); each copies at construction
// (spread in system routes, filter in keys), so keep the inputs in sync
// instead of assuming a shared reference.
const effectiveApiKeys: string[] = buildEffectiveApiKeys(API_KEY, API_KEYS);
const apiKeyVerifier = createApiKeyVerifier(effectiveApiKeys);

Expand Down
6 changes: 1 addition & 5 deletions src/search/grounding.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// Maps OpenAI-style hosted search tools (`tools:[{type:web_search}]`) onto the
// opencode built-in `websearch` tool and rebuilds `web_search_call` output
// items + `url_citation` annotations from the backend tool parts.
import { asRecord } from '../utils/guards.js';

export const HOSTED_SEARCH_TOOL_TYPES = ['web_search', 'web_search_preview', 'google_search'];
/** True for hosted search tool types, incl. versioned variants (e.g. Anthropic `web_search_20260222`). */
Expand All @@ -18,11 +19,6 @@ export const SEARCH_GROUNDING_INSTRUCTION =
'only from the conversation plus the search results. ' +
'Include the source URLs you relied on verbatim in your answer so they can be cited.';

function asRecord(value: unknown): Record<string, unknown> {
if (value && typeof value === 'object' && !Array.isArray(value)) return value as Record<string, unknown>;
return {};
}

function toolTypeOf(def: unknown): string {
return typeof asRecord(def)['type'] === 'string' ? String(asRecord(def)['type']) : '';
}
Expand Down
Loading