protocol-proxy 2.0.3 → 2.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "protocol-proxy",
3
- "version": "2.0.3",
3
+ "version": "2.0.7",
4
4
  "description": "OpenAI / Anthropic 协议转换透明代理",
5
5
  "main": "server.js",
6
6
  "bin": {
package/public/app.js CHANGED
@@ -40,7 +40,6 @@ function initProviderDropdown() {
40
40
  const dropdown = document.getElementById('provider-dropdown');
41
41
  const addNameInput = document.getElementById('provider-add-name');
42
42
  const addUrlInput = document.getElementById('provider-add-url');
43
- const addKeyInput = document.getElementById('provider-add-key');
44
43
  const addBtn = document.getElementById('provider-add-btn');
45
44
 
46
45
  trigger.addEventListener('click', (e) => {
@@ -50,7 +49,6 @@ function initProviderDropdown() {
50
49
  editingProviderId = null;
51
50
  addNameInput.value = '';
52
51
  addUrlInput.value = '';
53
- addKeyInput.value = '';
54
52
  addUrlInput.disabled = false;
55
53
  addBtn.textContent = '添加';
56
54
  renderProviderOptions();
@@ -67,7 +65,6 @@ function initProviderDropdown() {
67
65
  addBtn.addEventListener('click', async () => {
68
66
  const name = addNameInput.value.trim();
69
67
  const url = addUrlInput.value.trim();
70
- const apiKey = addKeyInput.value.trim();
71
68
  if (!name || !url) {
72
69
  showToast('请填写供应商名称和地址', true);
73
70
  return;
@@ -79,14 +76,14 @@ function initProviderDropdown() {
79
76
  res = await fetch(`/api/providers/${editingProviderId}`, {
80
77
  method: 'PUT',
81
78
  headers: { 'Content-Type': 'application/json' },
82
- body: JSON.stringify({ name, apiKey }),
79
+ body: JSON.stringify({ name }),
83
80
  });
84
81
  } else {
85
82
  // 新增模式
86
83
  res = await fetch('/api/providers', {
87
84
  method: 'POST',
88
85
  headers: { 'Content-Type': 'application/json' },
89
- body: JSON.stringify({ name, url, apiKey }),
86
+ body: JSON.stringify({ name, url }),
90
87
  });
91
88
  }
92
89
  if (!res.ok) {
@@ -129,7 +126,7 @@ function renderProviderOptions() {
129
126
  <span class="model-option-name">${escapeHtml(p.name)}</span>
130
127
  ${p.name !== p.url ? `<span style="color:#64748b;font-size:12px;margin-left:4px">${escapeHtml(p.url)}</span>` : ''}
131
128
  <span style="margin-left:auto;display:flex;gap:4px">
132
- <button type="button" class="model-option-delete" data-edit-id="${escapeHtml(p.id)}" title="编辑此供应商" style="color:#60a5fa">&times;</button>
129
+ <button type="button" class="model-option-delete" data-edit-id="${escapeHtml(p.id)}" title="编辑此供应商" style="color:#60a5fa;font-size:14px">&#9998;</button>
133
130
  <button type="button" class="model-option-delete" data-delete-id="${escapeHtml(p.id)}" title="删除此供应商">&times;</button>
134
131
  </span>
135
132
  </div>
@@ -202,8 +199,18 @@ function selectProvider(id) {
202
199
  document.getElementById('provider-dropdown-value').textContent = provider
203
200
  ? (provider.name !== provider.url ? `${provider.name} - ${provider.url}` : provider.url)
204
201
  : '选择供应商...';
205
- renderModelOptions();
202
+ // 切换供应商后模型自动选为该供应商模型列表的第一个
203
+ const models = provider?.models || [];
204
+ selectModel(models[0] || '');
206
205
  updateModelAddState();
206
+ // 加载供应商的 API Key
207
+ if (id) {
208
+ fetch(`/api/providers/${id}`).then(r => r.json()).then(p => {
209
+ document.getElementById('target-key').value = p.apiKey || '';
210
+ }).catch(() => {});
211
+ } else {
212
+ document.getElementById('target-key').value = '';
213
+ }
207
214
  }
208
215
 
209
216
  // ==================== Model 下拉框 ====================
@@ -493,6 +500,12 @@ function openModal(id = null) {
493
500
  document.getElementById('auth-token-group').style.display = p.requireAuth ? 'block' : 'none';
494
501
  selectProvider(p.providerId || '');
495
502
  selectModel(p.defaultModel || '');
503
+ // 加载供应商的 API Key
504
+ if (p.providerId) {
505
+ fetch(`/api/providers/${p.providerId}`).then(r => r.json()).then(provider => {
506
+ document.getElementById('target-key').value = provider.apiKey || '';
507
+ }).catch(() => {});
508
+ }
496
509
  } else {
497
510
  document.getElementById('proxy-id').value = '';
498
511
  document.getElementById('auth-token-group').style.display = 'none';
@@ -528,13 +541,32 @@ async function handleSubmit(e) {
528
541
  return;
529
542
  }
530
543
 
544
+ const apiKey = document.getElementById('target-key').value.trim();
545
+ const protocol = document.getElementById('target-protocol').value;
546
+ const defaultModel = document.getElementById('target-model').value.trim() || '';
547
+
548
+ // 同步更新供应商配置
549
+ const providerUpdates = {};
550
+ if (apiKey) providerUpdates.apiKey = apiKey;
551
+ if (protocol) providerUpdates.protocol = protocol;
552
+ if (Object.keys(providerUpdates).length > 0) {
553
+ try {
554
+ await fetch(`/api/providers/${providerId}`, {
555
+ method: 'PUT',
556
+ headers: { 'Content-Type': 'application/json' },
557
+ body: JSON.stringify(providerUpdates),
558
+ });
559
+ await loadProviders();
560
+ } catch {}
561
+ }
562
+
531
563
  const payload = {
532
564
  name: document.getElementById('proxy-name').value.trim(),
533
565
  port,
534
566
  requireAuth: document.getElementById('proxy-auth').value === 'true',
535
567
  authToken: document.getElementById('proxy-auth-token').value.trim() || null,
536
568
  providerId,
537
- defaultModel: document.getElementById('target-model').value.trim() || '',
569
+ defaultModel,
538
570
  };
539
571
 
540
572
  try {
package/public/index.html CHANGED
@@ -85,7 +85,6 @@
85
85
  <div class="model-add-section">
86
86
  <input type="text" class="model-add-input" id="provider-add-name" placeholder="供应商名称">
87
87
  <input type="url" class="model-add-input" id="provider-add-url" placeholder="https://api.example.com">
88
- <input type="password" class="model-add-input" id="provider-add-key" placeholder="API Key">
89
88
  <button type="button" class="btn btn-primary btn-sm" id="provider-add-btn">添加</button>
90
89
  </div>
91
90
  </div>
@@ -93,7 +92,10 @@
93
92
  </div>
94
93
  <div class="form-group">
95
94
  <label>协议</label>
96
- <input type="text" id="target-protocol" readonly placeholder="自动识别" style="background:#1e293b;color:#94a3b8;cursor:not-allowed">
95
+ <select id="target-protocol">
96
+ <option value="openai">OpenAI</option>
97
+ <option value="anthropic">Anthropic</option>
98
+ </select>
97
99
  </div>
98
100
  </div>
99
101
  <div class="form-row">