protocol-proxy 2.0.3 → 2.0.6

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.6",
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>
@@ -204,6 +201,14 @@ function selectProvider(id) {
204
201
  : '选择供应商...';
205
202
  renderModelOptions();
206
203
  updateModelAddState();
204
+ // 加载供应商的 API Key
205
+ if (id) {
206
+ fetch(`/api/providers/${id}`).then(r => r.json()).then(p => {
207
+ document.getElementById('target-key').value = p.apiKey || '';
208
+ }).catch(() => {});
209
+ } else {
210
+ document.getElementById('target-key').value = '';
211
+ }
207
212
  }
208
213
 
209
214
  // ==================== Model 下拉框 ====================
@@ -493,6 +498,12 @@ function openModal(id = null) {
493
498
  document.getElementById('auth-token-group').style.display = p.requireAuth ? 'block' : 'none';
494
499
  selectProvider(p.providerId || '');
495
500
  selectModel(p.defaultModel || '');
501
+ // 加载供应商的 API Key
502
+ if (p.providerId) {
503
+ fetch(`/api/providers/${p.providerId}`).then(r => r.json()).then(provider => {
504
+ document.getElementById('target-key').value = provider.apiKey || '';
505
+ }).catch(() => {});
506
+ }
496
507
  } else {
497
508
  document.getElementById('proxy-id').value = '';
498
509
  document.getElementById('auth-token-group').style.display = 'none';
@@ -528,13 +539,32 @@ async function handleSubmit(e) {
528
539
  return;
529
540
  }
530
541
 
542
+ const apiKey = document.getElementById('target-key').value.trim();
543
+ const protocol = document.getElementById('target-protocol').value;
544
+ const defaultModel = document.getElementById('target-model').value.trim() || '';
545
+
546
+ // 同步更新供应商配置
547
+ const providerUpdates = {};
548
+ if (apiKey) providerUpdates.apiKey = apiKey;
549
+ if (protocol) providerUpdates.protocol = protocol;
550
+ if (Object.keys(providerUpdates).length > 0) {
551
+ try {
552
+ await fetch(`/api/providers/${providerId}`, {
553
+ method: 'PUT',
554
+ headers: { 'Content-Type': 'application/json' },
555
+ body: JSON.stringify(providerUpdates),
556
+ });
557
+ await loadProviders();
558
+ } catch {}
559
+ }
560
+
531
561
  const payload = {
532
562
  name: document.getElementById('proxy-name').value.trim(),
533
563
  port,
534
564
  requireAuth: document.getElementById('proxy-auth').value === 'true',
535
565
  authToken: document.getElementById('proxy-auth-token').value.trim() || null,
536
566
  providerId,
537
- defaultModel: document.getElementById('target-model').value.trim() || '',
567
+ defaultModel,
538
568
  };
539
569
 
540
570
  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">