mirror of
https://github.com/Ed1s0nZ/CyberStrikeAI.git
synced 2026-04-21 10:16:32 +02:00
feat: add Claude API bridge - transparent OpenAI-to-Anthropic protocol conversion
When provider is set to "claude" in config, all OpenAI-compatible API calls are automatically bridged to Anthropic Claude Messages API, including: - Non-streaming and streaming chat completions - Tool calls (function calling) with full bidirectional conversion - Eino multi-agent via HTTP transport hook (claudeRoundTripper) - System message extraction, auth header conversion (Bearer → x-api-key) - SSE stream format conversion (content_block_delta → OpenAI delta) - TestOpenAI handler support for Claude connectivity testing Zero impact when provider is "openai" or empty (default behavior unchanged). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -102,6 +102,10 @@ async function loadConfig(loadTools = true) {
|
||||
currentConfig = await response.json();
|
||||
|
||||
// 填充OpenAI配置
|
||||
const providerEl = document.getElementById('openai-provider');
|
||||
if (providerEl) {
|
||||
providerEl.value = currentConfig.openai.provider || 'openai';
|
||||
}
|
||||
document.getElementById('openai-api-key').value = currentConfig.openai.api_key || '';
|
||||
document.getElementById('openai-base-url').value = currentConfig.openai.base_url || '';
|
||||
document.getElementById('openai-model').value = currentConfig.openai.model || '';
|
||||
@@ -753,6 +757,7 @@ async function applySettings() {
|
||||
});
|
||||
|
||||
// 验证必填字段
|
||||
const provider = document.getElementById('openai-provider')?.value || 'openai';
|
||||
const apiKey = document.getElementById('openai-api-key').value.trim();
|
||||
const baseUrl = document.getElementById('openai-base-url').value.trim();
|
||||
const model = document.getElementById('openai-model').value.trim();
|
||||
@@ -821,6 +826,7 @@ async function applySettings() {
|
||||
const wecomAgentIdVal = document.getElementById('robot-wecom-agent-id')?.value.trim();
|
||||
const config = {
|
||||
openai: {
|
||||
provider: provider,
|
||||
api_key: apiKey,
|
||||
base_url: baseUrl,
|
||||
model: model
|
||||
@@ -981,6 +987,7 @@ async function testOpenAIConnection() {
|
||||
const btn = document.getElementById('test-openai-btn');
|
||||
const resultEl = document.getElementById('test-openai-result');
|
||||
|
||||
const provider = document.getElementById('openai-provider')?.value || 'openai';
|
||||
const baseUrl = document.getElementById('openai-base-url').value.trim();
|
||||
const apiKey = document.getElementById('openai-api-key').value.trim();
|
||||
const model = document.getElementById('openai-model').value.trim();
|
||||
@@ -1001,6 +1008,7 @@ async function testOpenAIConnection() {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
provider: provider,
|
||||
base_url: baseUrl,
|
||||
api_key: apiKey,
|
||||
model: model
|
||||
|
||||
@@ -1365,6 +1365,13 @@
|
||||
<div class="settings-subsection">
|
||||
<h4 data-i18n="settingsBasic.openaiConfig">OpenAI 配置</h4>
|
||||
<div class="settings-form">
|
||||
<div class="form-group">
|
||||
<label for="openai-provider">API 提供商</label>
|
||||
<select id="openai-provider" style="width: 100%; padding: 0.5rem 0.75rem; border: 1px solid var(--border-color, #e2e8f0); border-radius: 6px; background: var(--card-bg, #fff); color: var(--text-color, #2d3748); font-size: 0.875rem;">
|
||||
<option value="openai">OpenAI / 兼容 OpenAI 协议</option>
|
||||
<option value="claude">Claude (Anthropic Messages API)</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="openai-base-url">Base URL <span style="color: red;">*</span></label>
|
||||
<input type="text" id="openai-base-url" data-i18n="settingsBasic.openaiBaseUrlPlaceholder" data-i18n-attr="placeholder" placeholder="https://api.openai.com/v1" required />
|
||||
|
||||
Reference in New Issue
Block a user