@moguiyu/dsh-tavily 0.1.4 → 0.1.5
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/lib/client.js +61 -74
- package/package.json +1 -1
- package/src/client.js +61 -74
package/lib/client.js
CHANGED
|
@@ -144,10 +144,6 @@ window.__ModuleLoader__.load({
|
|
|
144
144
|
}
|
|
145
145
|
}
|
|
146
146
|
|
|
147
|
-
const hasPending = Object.values(removing).some(Boolean)
|
|
148
|
-
|| Object.values(replacing).some(Boolean)
|
|
149
|
-
|| adds.some((item) => item.value.trim().length > 0)
|
|
150
|
-
|
|
151
147
|
const saveStrategy = async (next) => {
|
|
152
148
|
setBusy(true)
|
|
153
149
|
setNotice(null)
|
|
@@ -191,29 +187,46 @@ window.__ModuleLoader__.load({
|
|
|
191
187
|
}
|
|
192
188
|
}
|
|
193
189
|
|
|
194
|
-
const
|
|
190
|
+
const saveRemove = async (masked) => {
|
|
195
191
|
setBusy(true)
|
|
196
192
|
setNotice(null)
|
|
197
193
|
try {
|
|
198
|
-
const addValues = adds.map((item) => item.value.trim()).filter((value) => value.length > 0)
|
|
199
|
-
const removeMasked = [
|
|
200
|
-
...Object.keys(removing).filter((masked) => removing[masked] === true),
|
|
201
|
-
...Object.keys(replacing).filter((masked) => replacing[masked] === true)
|
|
202
|
-
]
|
|
203
194
|
const response = await fetch('/api/tavily-manager', {
|
|
204
195
|
method: 'POST',
|
|
205
196
|
headers: { 'content-type': 'application/json' },
|
|
206
|
-
body: JSON.stringify({ add:
|
|
197
|
+
body: JSON.stringify({ add: [], remove: [masked], strategy })
|
|
207
198
|
})
|
|
208
199
|
const data = await response.json()
|
|
209
|
-
if (!data.ok) { setNotice({ error: data.error || '
|
|
210
|
-
setNotice({ ok: '
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
200
|
+
if (!data.ok) { setNotice({ error: data.error || 'Delete failed' }); return }
|
|
201
|
+
setNotice({ ok: 'Key removed.' })
|
|
202
|
+
setConfirm((current) => Object.assign({}, current, { [masked]: false }))
|
|
203
|
+
setRemoving((current) => Object.assign({}, current, { [masked]: false }))
|
|
204
|
+
setRevealed((current) => Object.assign({}, current, { [masked]: false }))
|
|
205
|
+
await refresh()
|
|
206
|
+
} catch (error) {
|
|
207
|
+
setNotice({ error: String(error && error.message ? error.message : error) })
|
|
208
|
+
} finally {
|
|
209
|
+
setBusy(false)
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
const saveReplace = async (masked) => {
|
|
214
|
+
const value = typeof replaceDrafts[masked] === 'string' ? replaceDrafts[masked].trim() : ''
|
|
215
|
+
if (!value) return
|
|
216
|
+
setBusy(true)
|
|
217
|
+
setNotice(null)
|
|
218
|
+
try {
|
|
219
|
+
const response = await fetch('/api/tavily-manager', {
|
|
220
|
+
method: 'POST',
|
|
221
|
+
headers: { 'content-type': 'application/json' },
|
|
222
|
+
body: JSON.stringify({ add: [value], remove: [masked], strategy })
|
|
223
|
+
})
|
|
224
|
+
const data = await response.json()
|
|
225
|
+
if (!data.ok) { setNotice({ error: data.error || 'Update failed' }); return }
|
|
226
|
+
setNotice({ ok: 'Key updated.' })
|
|
227
|
+
setReplacing((current) => Object.assign({}, current, { [masked]: false }))
|
|
228
|
+
setReplaceDrafts((current) => Object.assign({}, current, { [masked]: '' }))
|
|
229
|
+
setRevealed((current) => Object.assign({}, current, { [masked]: false }))
|
|
217
230
|
await refresh()
|
|
218
231
|
} catch (error) {
|
|
219
232
|
setNotice({ error: String(error && error.message ? error.message : error) })
|
|
@@ -249,6 +262,7 @@ window.__ModuleLoader__.load({
|
|
|
249
262
|
setConfirm((current) => Object.assign({}, current, { [masked]: false }))
|
|
250
263
|
setRemoving((current) => Object.assign({}, current, { [masked]: true }))
|
|
251
264
|
setRevealed((current) => Object.assign({}, current, { [masked]: false }))
|
|
265
|
+
saveRemove(masked)
|
|
252
266
|
}
|
|
253
267
|
|
|
254
268
|
const restore = (masked) => {
|
|
@@ -314,16 +328,21 @@ window.__ModuleLoader__.load({
|
|
|
314
328
|
react.createElement('thead', null,
|
|
315
329
|
react.createElement('tr', null,
|
|
316
330
|
react.createElement('th', { style: headStyle }, 'Key'),
|
|
331
|
+
react.createElement('th', { style: headStyle }, 'Usage'),
|
|
317
332
|
react.createElement('th', { style: headStyle }, 'Saved'),
|
|
318
333
|
react.createElement('th', { style: headStyle }, 'Actions')
|
|
319
334
|
)
|
|
320
335
|
),
|
|
321
336
|
react.createElement('tbody', null,
|
|
322
|
-
(server !== null ? server.keys : []).map((key) => {
|
|
337
|
+
(server !== null ? server.keys : []).map((key, index) => {
|
|
323
338
|
const masked = key.masked
|
|
324
339
|
const isRemoved = removing[masked] === true
|
|
325
340
|
const isReplacing = replacing[masked] === true
|
|
326
341
|
const isRevealed = typeof revealed[masked] === 'string'
|
|
342
|
+
const usageRow = usage !== null && usage.ok === true ? usage.perKey[index] : null
|
|
343
|
+
const pct = usageRow && usageRow.ok && usageRow.planLimit != null && usageRow.planLimit > 0 && usageRow.planUsage != null
|
|
344
|
+
? Math.min(100, Math.round((usageRow.planUsage / usageRow.planLimit) * 100))
|
|
345
|
+
: null
|
|
327
346
|
return react.createElement('tr', { key: masked, style: { borderBottom: '1px solid var(--dsw-alias-border-l2)', opacity: isRemoved ? 0.45 : 1 } },
|
|
328
347
|
react.createElement('td', { style: Object.assign({}, cellStyle, { fontFamily: 'var(--ds-font-family-code, monospace)', fontSize: 12, wordBreak: 'break-all' }) },
|
|
329
348
|
isReplacing
|
|
@@ -342,11 +361,14 @@ window.__ModuleLoader__.load({
|
|
|
342
361
|
})
|
|
343
362
|
)
|
|
344
363
|
),
|
|
364
|
+
react.createElement('td', { style: cellStyle },
|
|
365
|
+
react.createElement(UsageCircle, { percent: pct, label: pct != null ? pct + '%' : (usageRow && usageRow.ok && usageRow.planUsage != null ? String(usageRow.planUsage) : '—') })
|
|
366
|
+
),
|
|
345
367
|
react.createElement('td', { style: Object.assign({}, cellStyle, { color: 'var(--dsw-alias-label-tertiary)', whiteSpace: 'nowrap' }) }, formatDate(key.savedAt)),
|
|
346
368
|
react.createElement('td', { style: cellStyle },
|
|
347
369
|
isReplacing
|
|
348
370
|
? react.createElement('span', { style: { display: 'inline-flex', gap: 2 } },
|
|
349
|
-
react.createElement(IconButton, { icon: 'check', title: '
|
|
371
|
+
react.createElement(IconButton, { icon: 'check', title: 'Save key', onClick: () => saveReplace(masked), disabled: busy || (typeof replaceDrafts[masked] === 'string' ? replaceDrafts[masked].trim().length === 0 : true) }),
|
|
350
372
|
react.createElement(IconButton, { icon: 'close', title: 'Cancel', onClick: () => cancelReplace(masked), disabled: busy })
|
|
351
373
|
)
|
|
352
374
|
: react.createElement('span', { style: { display: 'inline-flex', gap: 2 } },
|
|
@@ -376,6 +398,7 @@ window.__ModuleLoader__.load({
|
|
|
376
398
|
})
|
|
377
399
|
),
|
|
378
400
|
react.createElement('td', { style: cellStyle }, '—'),
|
|
401
|
+
react.createElement('td', { style: cellStyle }, '—'),
|
|
379
402
|
react.createElement('td', { style: cellStyle },
|
|
380
403
|
react.createElement('span', { style: { display: 'inline-flex', gap: 2 } },
|
|
381
404
|
react.createElement(IconButton, { icon: 'check', title: 'Save key', onClick: () => saveAdd(item), disabled: busy || item.value.trim().length === 0 }),
|
|
@@ -385,63 +408,27 @@ window.__ModuleLoader__.load({
|
|
|
385
408
|
))
|
|
386
409
|
)
|
|
387
410
|
),
|
|
388
|
-
react.createElement('div', { style: { display: 'flex', gap: 8, alignItems: 'center' } },
|
|
389
|
-
react.createElement('button', { type: 'button', style: btn, onClick: () => setAdds((current) => [...current, { id: 'add-' + Date.now() + '-' + Math.random().toString(36).slice(2, 7), value: '' }]), disabled: busy }, '+ Add key')
|
|
411
|
+
react.createElement('div', { style: { display: 'flex', gap: 8, alignItems: 'center', flexWrap: 'wrap' } },
|
|
412
|
+
react.createElement('button', { type: 'button', style: btn, onClick: () => setAdds((current) => [...current, { id: 'add-' + Date.now() + '-' + Math.random().toString(36).slice(2, 7), value: '' }]), disabled: busy }, '+ Add key'),
|
|
413
|
+
react.createElement('button', { type: 'button', style: btn, onClick: refresh, disabled: busy }, 'Refresh usage')
|
|
390
414
|
),
|
|
391
|
-
react.createElement('div', { style: {
|
|
392
|
-
react.createElement('
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
)
|
|
402
|
-
),
|
|
403
|
-
react.createElement('div', { style: { display: 'flex', gap: 8, alignItems: 'center' } },
|
|
404
|
-
react.createElement('button', { type: 'button', style: Object.assign({}, btn, { height: 32, background: 'var(--dsw-alias-button-primary-fill)', color: 'var(--dsw-alias-label-primary-foreground)' }), onClick: save, disabled: busy || !hasPending }, 'Save key changes'),
|
|
405
|
-
notice !== null && react.createElement('span', { style: { fontSize: 13, color: notice.ok ? 'var(--dsw-alias-state-success-primary)' : 'var(--dsw-alias-state-error-primary)' } }, notice.ok ? notice.ok : String(notice.error))
|
|
406
|
-
),
|
|
407
|
-
react.createElement('div', { style: { border: '1px solid var(--dsw-alias-border-l2)', borderRadius: 12, padding: '12px 14px', display: 'flex', flexDirection: 'column', gap: 8 } },
|
|
408
|
-
react.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: 8, justifyContent: 'space-between' } },
|
|
409
|
-
react.createElement('span', { style: { fontWeight: 500, fontSize: 13 } }, 'Tavily Usage'),
|
|
410
|
-
react.createElement('button', { type: 'button', style: btn, onClick: refresh, disabled: busy }, 'Refresh')
|
|
415
|
+
react.createElement('div', { style: { display: 'flex', flexDirection: 'column', gap: 6 } },
|
|
416
|
+
react.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' } },
|
|
417
|
+
react.createElement('label', { style: { fontWeight: 500, fontSize: 13 } }, 'Key usage strategy'),
|
|
418
|
+
react.createElement('select', {
|
|
419
|
+
style: { maxWidth: 280, height: 32, border: '1px solid var(--dsw-alias-border-l2)', borderRadius: 8, background: 'var(--dsw-alias-bg-layer-1)', color: 'var(--dsw-alias-label-primary)', padding: '0 10px', fontSize: 13 },
|
|
420
|
+
value: strategy,
|
|
421
|
+
onChange: (event) => saveStrategy(event.target.value),
|
|
422
|
+
disabled: busy
|
|
423
|
+
}, STRATEGIES.map((option) => react.createElement('option', { key: option.id, value: option.id }, option.label))),
|
|
424
|
+
notice !== null && react.createElement('span', { style: { fontSize: 13, color: notice.ok ? 'var(--dsw-alias-state-success-primary)' : 'var(--dsw-alias-state-error-primary)' } }, notice.ok ? notice.ok : String(notice.error))
|
|
411
425
|
),
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
usage !== null && usage.ok === true && react.createElement('div', { style: { display: 'flex', flexDirection: 'column', gap: 8 } },
|
|
415
|
-
react.createElement('div', { style: { fontSize: 13 } },
|
|
416
|
-
usage.totals.keys + ' key(s) (' + usage.totals.okKeys + ' readable)' + (usage.totals.planLimit !== null ? ' · plan usage ' + usage.totals.planUsage + ' / ' + usage.totals.planLimit : '')
|
|
417
|
-
),
|
|
418
|
-
react.createElement('table', { style: { width: '100%', borderCollapse: 'collapse', fontSize: 13 } },
|
|
419
|
-
react.createElement('thead', null,
|
|
420
|
-
react.createElement('tr', null,
|
|
421
|
-
react.createElement('th', { style: headStyle }, 'API Key'),
|
|
422
|
-
react.createElement('th', { style: headStyle }, 'Usage')
|
|
423
|
-
)
|
|
424
|
-
),
|
|
425
|
-
react.createElement('tbody', null,
|
|
426
|
-
(server !== null ? server.keys : []).map((key, index) => {
|
|
427
|
-
const row = usage.perKey[index]
|
|
428
|
-
const pct = row && row.ok && row.planLimit != null && row.planLimit > 0 && row.planUsage != null
|
|
429
|
-
? Math.min(100, Math.round((row.planUsage / row.planLimit) * 100))
|
|
430
|
-
: null
|
|
431
|
-
return react.createElement('tr', { key: key.masked, style: { borderBottom: '1px solid var(--dsw-alias-border-l2)' } },
|
|
432
|
-
react.createElement('td', { style: Object.assign({}, cellStyle, { fontFamily: 'var(--ds-font-family-code, monospace)', fontSize: 12, wordBreak: 'break-all' }) }, key.masked),
|
|
433
|
-
react.createElement('td', { style: cellStyle },
|
|
434
|
-
react.createElement(UsageCircle, { percent: pct, label: pct != null ? pct + '%' : (row && row.ok && row.planUsage != null ? String(row.planUsage) : '—') })
|
|
435
|
-
)
|
|
436
|
-
)
|
|
437
|
-
})
|
|
438
|
-
)
|
|
439
|
-
)
|
|
426
|
+
react.createElement('p', { style: { margin: 0, fontSize: 12, color: 'var(--dsw-alias-label-tertiary)' } },
|
|
427
|
+
(STRATEGIES.find((option) => option.id === strategy) || STRATEGIES[0]).hint + ' Saved immediately when selected; the first key then becomes primary for web_search.'
|
|
440
428
|
)
|
|
441
429
|
),
|
|
442
|
-
react.createElement('p', { style: { margin: 0, fontSize: 12, color: 'var(--dsw-alias-
|
|
443
|
-
|
|
444
|
-
)
|
|
430
|
+
usageError !== null && react.createElement('p', { style: { margin: 0, fontSize: 12, color: 'var(--dsw-alias-state-error-primary)' } }, String(usageError)),
|
|
431
|
+
usage !== null && usage.ok === false && react.createElement('p', { style: { margin: 0, fontSize: 12, color: 'var(--dsw-alias-state-error-primary)' } }, String(usage.error))
|
|
445
432
|
)
|
|
446
433
|
)
|
|
447
434
|
)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@moguiyu/dsh-tavily",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "Tavily Search for DSH: multiple API keys, rotation/failover, usage gauge, settings card, and web_search toggle in one plugin.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.js",
|
package/src/client.js
CHANGED
|
@@ -149,10 +149,6 @@ export function factory(require) {
|
|
|
149
149
|
}
|
|
150
150
|
}
|
|
151
151
|
|
|
152
|
-
const hasPending = Object.values(removing).some(Boolean)
|
|
153
|
-
|| Object.values(replacing).some(Boolean)
|
|
154
|
-
|| adds.some((item) => item.value.trim().length > 0)
|
|
155
|
-
|
|
156
152
|
const saveStrategy = async (next) => {
|
|
157
153
|
setBusy(true)
|
|
158
154
|
setNotice(null)
|
|
@@ -196,29 +192,46 @@ export function factory(require) {
|
|
|
196
192
|
}
|
|
197
193
|
}
|
|
198
194
|
|
|
199
|
-
const
|
|
195
|
+
const saveRemove = async (masked) => {
|
|
200
196
|
setBusy(true)
|
|
201
197
|
setNotice(null)
|
|
202
198
|
try {
|
|
203
|
-
const addValues = adds.map((item) => item.value.trim()).filter((value) => value.length > 0)
|
|
204
|
-
const removeMasked = [
|
|
205
|
-
...Object.keys(removing).filter((masked) => removing[masked] === true),
|
|
206
|
-
...Object.keys(replacing).filter((masked) => replacing[masked] === true)
|
|
207
|
-
]
|
|
208
199
|
const response = await fetch('/api/tavily-manager', {
|
|
209
200
|
method: 'POST',
|
|
210
201
|
headers: { 'content-type': 'application/json' },
|
|
211
|
-
body: JSON.stringify({ add:
|
|
202
|
+
body: JSON.stringify({ add: [], remove: [masked], strategy })
|
|
212
203
|
})
|
|
213
204
|
const data = await response.json()
|
|
214
|
-
if (!data.ok) { setNotice({ error: data.error || '
|
|
215
|
-
setNotice({ ok: '
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
205
|
+
if (!data.ok) { setNotice({ error: data.error || 'Delete failed' }); return }
|
|
206
|
+
setNotice({ ok: 'Key removed.' })
|
|
207
|
+
setConfirm((current) => Object.assign({}, current, { [masked]: false }))
|
|
208
|
+
setRemoving((current) => Object.assign({}, current, { [masked]: false }))
|
|
209
|
+
setRevealed((current) => Object.assign({}, current, { [masked]: false }))
|
|
210
|
+
await refresh()
|
|
211
|
+
} catch (error) {
|
|
212
|
+
setNotice({ error: String(error && error.message ? error.message : error) })
|
|
213
|
+
} finally {
|
|
214
|
+
setBusy(false)
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
const saveReplace = async (masked) => {
|
|
219
|
+
const value = typeof replaceDrafts[masked] === 'string' ? replaceDrafts[masked].trim() : ''
|
|
220
|
+
if (!value) return
|
|
221
|
+
setBusy(true)
|
|
222
|
+
setNotice(null)
|
|
223
|
+
try {
|
|
224
|
+
const response = await fetch('/api/tavily-manager', {
|
|
225
|
+
method: 'POST',
|
|
226
|
+
headers: { 'content-type': 'application/json' },
|
|
227
|
+
body: JSON.stringify({ add: [value], remove: [masked], strategy })
|
|
228
|
+
})
|
|
229
|
+
const data = await response.json()
|
|
230
|
+
if (!data.ok) { setNotice({ error: data.error || 'Update failed' }); return }
|
|
231
|
+
setNotice({ ok: 'Key updated.' })
|
|
232
|
+
setReplacing((current) => Object.assign({}, current, { [masked]: false }))
|
|
233
|
+
setReplaceDrafts((current) => Object.assign({}, current, { [masked]: '' }))
|
|
234
|
+
setRevealed((current) => Object.assign({}, current, { [masked]: false }))
|
|
222
235
|
await refresh()
|
|
223
236
|
} catch (error) {
|
|
224
237
|
setNotice({ error: String(error && error.message ? error.message : error) })
|
|
@@ -254,6 +267,7 @@ export function factory(require) {
|
|
|
254
267
|
setConfirm((current) => Object.assign({}, current, { [masked]: false }))
|
|
255
268
|
setRemoving((current) => Object.assign({}, current, { [masked]: true }))
|
|
256
269
|
setRevealed((current) => Object.assign({}, current, { [masked]: false }))
|
|
270
|
+
saveRemove(masked)
|
|
257
271
|
}
|
|
258
272
|
|
|
259
273
|
const restore = (masked) => {
|
|
@@ -319,16 +333,21 @@ export function factory(require) {
|
|
|
319
333
|
react.createElement('thead', null,
|
|
320
334
|
react.createElement('tr', null,
|
|
321
335
|
react.createElement('th', { style: headStyle }, 'Key'),
|
|
336
|
+
react.createElement('th', { style: headStyle }, 'Usage'),
|
|
322
337
|
react.createElement('th', { style: headStyle }, 'Saved'),
|
|
323
338
|
react.createElement('th', { style: headStyle }, 'Actions')
|
|
324
339
|
)
|
|
325
340
|
),
|
|
326
341
|
react.createElement('tbody', null,
|
|
327
|
-
(server !== null ? server.keys : []).map((key) => {
|
|
342
|
+
(server !== null ? server.keys : []).map((key, index) => {
|
|
328
343
|
const masked = key.masked
|
|
329
344
|
const isRemoved = removing[masked] === true
|
|
330
345
|
const isReplacing = replacing[masked] === true
|
|
331
346
|
const isRevealed = typeof revealed[masked] === 'string'
|
|
347
|
+
const usageRow = usage !== null && usage.ok === true ? usage.perKey[index] : null
|
|
348
|
+
const pct = usageRow && usageRow.ok && usageRow.planLimit != null && usageRow.planLimit > 0 && usageRow.planUsage != null
|
|
349
|
+
? Math.min(100, Math.round((usageRow.planUsage / usageRow.planLimit) * 100))
|
|
350
|
+
: null
|
|
332
351
|
return react.createElement('tr', { key: masked, style: { borderBottom: '1px solid var(--dsw-alias-border-l2)', opacity: isRemoved ? 0.45 : 1 } },
|
|
333
352
|
react.createElement('td', { style: Object.assign({}, cellStyle, { fontFamily: 'var(--ds-font-family-code, monospace)', fontSize: 12, wordBreak: 'break-all' }) },
|
|
334
353
|
isReplacing
|
|
@@ -347,11 +366,14 @@ export function factory(require) {
|
|
|
347
366
|
})
|
|
348
367
|
)
|
|
349
368
|
),
|
|
369
|
+
react.createElement('td', { style: cellStyle },
|
|
370
|
+
react.createElement(UsageCircle, { percent: pct, label: pct != null ? pct + '%' : (usageRow && usageRow.ok && usageRow.planUsage != null ? String(usageRow.planUsage) : '—') })
|
|
371
|
+
),
|
|
350
372
|
react.createElement('td', { style: Object.assign({}, cellStyle, { color: 'var(--dsw-alias-label-tertiary)', whiteSpace: 'nowrap' }) }, formatDate(key.savedAt)),
|
|
351
373
|
react.createElement('td', { style: cellStyle },
|
|
352
374
|
isReplacing
|
|
353
375
|
? react.createElement('span', { style: { display: 'inline-flex', gap: 2 } },
|
|
354
|
-
react.createElement(IconButton, { icon: 'check', title: '
|
|
376
|
+
react.createElement(IconButton, { icon: 'check', title: 'Save key', onClick: () => saveReplace(masked), disabled: busy || (typeof replaceDrafts[masked] === 'string' ? replaceDrafts[masked].trim().length === 0 : true) }),
|
|
355
377
|
react.createElement(IconButton, { icon: 'close', title: 'Cancel', onClick: () => cancelReplace(masked), disabled: busy })
|
|
356
378
|
)
|
|
357
379
|
: react.createElement('span', { style: { display: 'inline-flex', gap: 2 } },
|
|
@@ -381,6 +403,7 @@ export function factory(require) {
|
|
|
381
403
|
})
|
|
382
404
|
),
|
|
383
405
|
react.createElement('td', { style: cellStyle }, '—'),
|
|
406
|
+
react.createElement('td', { style: cellStyle }, '—'),
|
|
384
407
|
react.createElement('td', { style: cellStyle },
|
|
385
408
|
react.createElement('span', { style: { display: 'inline-flex', gap: 2 } },
|
|
386
409
|
react.createElement(IconButton, { icon: 'check', title: 'Save key', onClick: () => saveAdd(item), disabled: busy || item.value.trim().length === 0 }),
|
|
@@ -390,63 +413,27 @@ export function factory(require) {
|
|
|
390
413
|
))
|
|
391
414
|
)
|
|
392
415
|
),
|
|
393
|
-
react.createElement('div', { style: { display: 'flex', gap: 8, alignItems: 'center' } },
|
|
394
|
-
react.createElement('button', { type: 'button', style: btn, onClick: () => setAdds((current) => [...current, { id: 'add-' + Date.now() + '-' + Math.random().toString(36).slice(2, 7), value: '' }]), disabled: busy }, '+ Add key')
|
|
416
|
+
react.createElement('div', { style: { display: 'flex', gap: 8, alignItems: 'center', flexWrap: 'wrap' } },
|
|
417
|
+
react.createElement('button', { type: 'button', style: btn, onClick: () => setAdds((current) => [...current, { id: 'add-' + Date.now() + '-' + Math.random().toString(36).slice(2, 7), value: '' }]), disabled: busy }, '+ Add key'),
|
|
418
|
+
react.createElement('button', { type: 'button', style: btn, onClick: refresh, disabled: busy }, 'Refresh usage')
|
|
395
419
|
),
|
|
396
|
-
react.createElement('div', { style: {
|
|
397
|
-
react.createElement('
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
)
|
|
407
|
-
),
|
|
408
|
-
react.createElement('div', { style: { display: 'flex', gap: 8, alignItems: 'center' } },
|
|
409
|
-
react.createElement('button', { type: 'button', style: Object.assign({}, btn, { height: 32, background: 'var(--dsw-alias-button-primary-fill)', color: 'var(--dsw-alias-label-primary-foreground)' }), onClick: save, disabled: busy || !hasPending }, 'Save key changes'),
|
|
410
|
-
notice !== null && react.createElement('span', { style: { fontSize: 13, color: notice.ok ? 'var(--dsw-alias-state-success-primary)' : 'var(--dsw-alias-state-error-primary)' } }, notice.ok ? notice.ok : String(notice.error))
|
|
411
|
-
),
|
|
412
|
-
react.createElement('div', { style: { border: '1px solid var(--dsw-alias-border-l2)', borderRadius: 12, padding: '12px 14px', display: 'flex', flexDirection: 'column', gap: 8 } },
|
|
413
|
-
react.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: 8, justifyContent: 'space-between' } },
|
|
414
|
-
react.createElement('span', { style: { fontWeight: 500, fontSize: 13 } }, 'Tavily Usage'),
|
|
415
|
-
react.createElement('button', { type: 'button', style: btn, onClick: refresh, disabled: busy }, 'Refresh')
|
|
420
|
+
react.createElement('div', { style: { display: 'flex', flexDirection: 'column', gap: 6 } },
|
|
421
|
+
react.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' } },
|
|
422
|
+
react.createElement('label', { style: { fontWeight: 500, fontSize: 13 } }, 'Key usage strategy'),
|
|
423
|
+
react.createElement('select', {
|
|
424
|
+
style: { maxWidth: 280, height: 32, border: '1px solid var(--dsw-alias-border-l2)', borderRadius: 8, background: 'var(--dsw-alias-bg-layer-1)', color: 'var(--dsw-alias-label-primary)', padding: '0 10px', fontSize: 13 },
|
|
425
|
+
value: strategy,
|
|
426
|
+
onChange: (event) => saveStrategy(event.target.value),
|
|
427
|
+
disabled: busy
|
|
428
|
+
}, STRATEGIES.map((option) => react.createElement('option', { key: option.id, value: option.id }, option.label))),
|
|
429
|
+
notice !== null && react.createElement('span', { style: { fontSize: 13, color: notice.ok ? 'var(--dsw-alias-state-success-primary)' : 'var(--dsw-alias-state-error-primary)' } }, notice.ok ? notice.ok : String(notice.error))
|
|
416
430
|
),
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
usage !== null && usage.ok === true && react.createElement('div', { style: { display: 'flex', flexDirection: 'column', gap: 8 } },
|
|
420
|
-
react.createElement('div', { style: { fontSize: 13 } },
|
|
421
|
-
usage.totals.keys + ' key(s) (' + usage.totals.okKeys + ' readable)' + (usage.totals.planLimit !== null ? ' · plan usage ' + usage.totals.planUsage + ' / ' + usage.totals.planLimit : '')
|
|
422
|
-
),
|
|
423
|
-
react.createElement('table', { style: { width: '100%', borderCollapse: 'collapse', fontSize: 13 } },
|
|
424
|
-
react.createElement('thead', null,
|
|
425
|
-
react.createElement('tr', null,
|
|
426
|
-
react.createElement('th', { style: headStyle }, 'API Key'),
|
|
427
|
-
react.createElement('th', { style: headStyle }, 'Usage')
|
|
428
|
-
)
|
|
429
|
-
),
|
|
430
|
-
react.createElement('tbody', null,
|
|
431
|
-
(server !== null ? server.keys : []).map((key, index) => {
|
|
432
|
-
const row = usage.perKey[index]
|
|
433
|
-
const pct = row && row.ok && row.planLimit != null && row.planLimit > 0 && row.planUsage != null
|
|
434
|
-
? Math.min(100, Math.round((row.planUsage / row.planLimit) * 100))
|
|
435
|
-
: null
|
|
436
|
-
return react.createElement('tr', { key: key.masked, style: { borderBottom: '1px solid var(--dsw-alias-border-l2)' } },
|
|
437
|
-
react.createElement('td', { style: Object.assign({}, cellStyle, { fontFamily: 'var(--ds-font-family-code, monospace)', fontSize: 12, wordBreak: 'break-all' }) }, key.masked),
|
|
438
|
-
react.createElement('td', { style: cellStyle },
|
|
439
|
-
react.createElement(UsageCircle, { percent: pct, label: pct != null ? pct + '%' : (row && row.ok && row.planUsage != null ? String(row.planUsage) : '—') })
|
|
440
|
-
)
|
|
441
|
-
)
|
|
442
|
-
})
|
|
443
|
-
)
|
|
444
|
-
)
|
|
431
|
+
react.createElement('p', { style: { margin: 0, fontSize: 12, color: 'var(--dsw-alias-label-tertiary)' } },
|
|
432
|
+
(STRATEGIES.find((option) => option.id === strategy) || STRATEGIES[0]).hint + ' Saved immediately when selected; the first key then becomes primary for web_search.'
|
|
445
433
|
)
|
|
446
434
|
),
|
|
447
|
-
react.createElement('p', { style: { margin: 0, fontSize: 12, color: 'var(--dsw-alias-
|
|
448
|
-
|
|
449
|
-
)
|
|
435
|
+
usageError !== null && react.createElement('p', { style: { margin: 0, fontSize: 12, color: 'var(--dsw-alias-state-error-primary)' } }, String(usageError)),
|
|
436
|
+
usage !== null && usage.ok === false && react.createElement('p', { style: { margin: 0, fontSize: 12, color: 'var(--dsw-alias-state-error-primary)' } }, String(usage.error))
|
|
450
437
|
)
|
|
451
438
|
)
|
|
452
439
|
)
|