fa-mcp-sdk 0.4.17 → 0.4.19
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/cli-template/FA-MCP-SDK-DOC/08-agent-tester-and-headless-api.md +21 -10
- package/cli-template/package.json +1 -1
- package/config/_local.yaml +312 -148
- package/config/default.yaml +312 -212
- package/config/local.yaml +5 -1
- package/dist/core/_types_/config.d.ts +1 -0
- package/dist/core/_types_/config.d.ts.map +1 -1
- package/dist/core/agent-tester/agent-tester-router.d.ts.map +1 -1
- package/dist/core/agent-tester/agent-tester-router.js +6 -0
- package/dist/core/agent-tester/agent-tester-router.js.map +1 -1
- package/dist/core/agent-tester/services/TesterAgentService.d.ts.map +1 -1
- package/dist/core/agent-tester/services/TesterAgentService.js +14 -8
- package/dist/core/agent-tester/services/TesterAgentService.js.map +1 -1
- package/dist/core/web/static/agent-tester/index.html +69 -49
- package/dist/core/web/static/agent-tester/script.js +254 -82
- package/dist/core/web/static/agent-tester/styles.css +134 -0
- package/package.json +1 -1
|
@@ -1,6 +1,32 @@
|
|
|
1
1
|
const API_BASE = '/agent-tester';
|
|
2
2
|
const trim = (s) => String(s || '').trim();
|
|
3
3
|
|
|
4
|
+
const LLM_LS_KEY = 'mcpAgentLlmSettings';
|
|
5
|
+
const LLM_PRESET_MODELS = [
|
|
6
|
+
'gpt-5.4',
|
|
7
|
+
'gpt-5.4-mini',
|
|
8
|
+
'gpt-5.4-nano',
|
|
9
|
+
'gpt-5.3-codex',
|
|
10
|
+
'gpt-5.2',
|
|
11
|
+
'gpt-5.1',
|
|
12
|
+
'gpt-5-nano',
|
|
13
|
+
'gpt-5-mini',
|
|
14
|
+
'gpt-4.1',
|
|
15
|
+
'gpt-4.1-mini',
|
|
16
|
+
'gpt-4.1-nano',
|
|
17
|
+
'gpt-4o',
|
|
18
|
+
'gpt-4o-mini',
|
|
19
|
+
];
|
|
20
|
+
const LLM_DEFAULTS = {
|
|
21
|
+
baseURL: '',
|
|
22
|
+
apiKey: '',
|
|
23
|
+
model: 'gpt-5.4-nano',
|
|
24
|
+
temperature: 0.2,
|
|
25
|
+
maxTokens: 2048,
|
|
26
|
+
maxTurns: 10,
|
|
27
|
+
toolResultLimitChars: 20000,
|
|
28
|
+
};
|
|
29
|
+
|
|
4
30
|
/**
|
|
5
31
|
* Wrapper around fetch that always includes credentials (session cookie).
|
|
6
32
|
*/
|
|
@@ -348,16 +374,26 @@ class McpAgentTester {
|
|
|
348
374
|
this.headersSection = document.getElementById('headersSection');
|
|
349
375
|
this.dynamicHeaders = document.getElementById('dynamicHeaders');
|
|
350
376
|
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
this.
|
|
354
|
-
this.
|
|
355
|
-
this.
|
|
356
|
-
this.
|
|
357
|
-
this.
|
|
358
|
-
this.
|
|
359
|
-
this.
|
|
360
|
-
this.
|
|
377
|
+
// LLM settings — collapsed view + modal
|
|
378
|
+
this.modelDisplay = document.getElementById('modelDisplay');
|
|
379
|
+
this.llmSettingsBtn = document.getElementById('llmSettingsBtn');
|
|
380
|
+
this.apiKeyWarning = document.getElementById('apiKeyWarning');
|
|
381
|
+
this.llmModal = document.getElementById('llmModal');
|
|
382
|
+
this.llmModalClose = document.getElementById('llmModalClose');
|
|
383
|
+
this.llmModalCancel = document.getElementById('llmModalCancel');
|
|
384
|
+
this.llmModalSave = document.getElementById('llmModalSave');
|
|
385
|
+
this.llmApiKeyToggle = document.getElementById('llmApiKeyToggle');
|
|
386
|
+
this.llmBaseUrl = document.getElementById('llmBaseUrl');
|
|
387
|
+
this.llmApiKey = document.getElementById('llmApiKey');
|
|
388
|
+
this.llmModelName = document.getElementById('llmModelName');
|
|
389
|
+
this.llmModelDropdownToggle = document.getElementById('llmModelDropdownToggle');
|
|
390
|
+
this.llmModelDropdownList = document.getElementById('llmModelDropdownList');
|
|
391
|
+
this.llmTemperature = document.getElementById('llmTemperature');
|
|
392
|
+
this.llmMaxTokens = document.getElementById('llmMaxTokens');
|
|
393
|
+
this.llmMaxTurns = document.getElementById('llmMaxTurns');
|
|
394
|
+
this.llmLimitChars = document.getElementById('llmLimitChars');
|
|
395
|
+
|
|
396
|
+
this.llmSettings = { ...LLM_DEFAULTS };
|
|
361
397
|
|
|
362
398
|
this.systemPromptTextarea = document.getElementById('systemPrompt');
|
|
363
399
|
this.customPromptTextarea = document.getElementById('customPrompt');
|
|
@@ -404,20 +440,25 @@ class McpAgentTester {
|
|
|
404
440
|
this.serverUrlDropdown.addEventListener('click', (e) => this.toggleUrlDropdown(e));
|
|
405
441
|
document.addEventListener('click', (e) => this.handleClickOutside(e));
|
|
406
442
|
|
|
407
|
-
this.modelSelect.addEventListener('change', () => {
|
|
408
|
-
this.handleModelSelectChange();
|
|
409
|
-
this.saveFormValuesToStorage();
|
|
410
|
-
});
|
|
411
443
|
this.systemPromptTextarea.addEventListener('input', () => this.saveFormValuesToStorage());
|
|
412
444
|
this.customPromptTextarea.addEventListener('input', () => this.saveFormValuesToStorage());
|
|
413
445
|
|
|
414
|
-
|
|
415
|
-
this.
|
|
416
|
-
this.
|
|
417
|
-
this.
|
|
418
|
-
this.
|
|
419
|
-
this.
|
|
420
|
-
this.
|
|
446
|
+
// LLM settings modal
|
|
447
|
+
this.llmSettingsBtn.addEventListener('click', () => this.openLlmModal());
|
|
448
|
+
this.llmModalClose.addEventListener('click', () => this.closeLlmModal());
|
|
449
|
+
this.llmModalCancel.addEventListener('click', () => this.closeLlmModal());
|
|
450
|
+
this.llmModalSave.addEventListener('click', () => this.saveLlmModal());
|
|
451
|
+
this.llmApiKeyToggle.addEventListener('click', () => this.toggleApiKeyVisibility());
|
|
452
|
+
this.llmModelDropdownToggle.addEventListener('click', (e) => this.toggleLlmModelDropdown(e));
|
|
453
|
+
this.renderLlmModelDropdown();
|
|
454
|
+
this.llmModal.addEventListener('click', (e) => {
|
|
455
|
+
if (e.target === this.llmModal) { this.closeLlmModal(); }
|
|
456
|
+
});
|
|
457
|
+
document.addEventListener('keydown', (e) => {
|
|
458
|
+
if (e.key === 'Escape' && this.llmModal.style.display === 'flex') {
|
|
459
|
+
this.closeLlmModal();
|
|
460
|
+
}
|
|
461
|
+
});
|
|
421
462
|
|
|
422
463
|
document.querySelectorAll('.btn-enlarge').forEach(btn => {
|
|
423
464
|
btn.addEventListener('click', () => this.openPromptModal(btn.dataset.target));
|
|
@@ -518,6 +559,7 @@ class McpAgentTester {
|
|
|
518
559
|
this.handleServerUrlChange();
|
|
519
560
|
this.renderSavedUrls();
|
|
520
561
|
await this.loadDefaultConfig();
|
|
562
|
+
this.initLlmSettings();
|
|
521
563
|
await this.loadCurrentServer();
|
|
522
564
|
this.currentSystemPrompt = this.systemPromptTextarea.value;
|
|
523
565
|
|
|
@@ -606,6 +648,7 @@ class McpAgentTester {
|
|
|
606
648
|
this.defaultMcpUrl = config.defaultMcpUrl || null;
|
|
607
649
|
this.authEnabled = !!config.authEnabled;
|
|
608
650
|
this.configHttpHeaders = config.httpHeaders || {};
|
|
651
|
+
this.llmDefaults = config.llmDefaults || {};
|
|
609
652
|
if (config.defaultMcpUrl) {
|
|
610
653
|
const serverUrlInput = document.getElementById('serverUrl');
|
|
611
654
|
if (!this.mcpConfig.url && !serverUrlInput.value) {
|
|
@@ -1176,7 +1219,7 @@ class McpAgentTester {
|
|
|
1176
1219
|
const message = this.messageInput.value.trim();
|
|
1177
1220
|
if (!message) {return;}
|
|
1178
1221
|
|
|
1179
|
-
if (!this.
|
|
1222
|
+
if (!this.validateLlmSettings()) {
|
|
1180
1223
|
return;
|
|
1181
1224
|
}
|
|
1182
1225
|
|
|
@@ -1379,63 +1422,209 @@ class McpAgentTester {
|
|
|
1379
1422
|
});
|
|
1380
1423
|
}
|
|
1381
1424
|
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1425
|
+
initLlmSettings () {
|
|
1426
|
+
let stored = {};
|
|
1427
|
+
try {
|
|
1428
|
+
stored = JSON.parse(localStorage.getItem(LLM_LS_KEY) || '{}');
|
|
1429
|
+
} catch { stored = {}; }
|
|
1430
|
+
|
|
1431
|
+
const merged = { ...LLM_DEFAULTS, ...stored };
|
|
1432
|
+
const cfg = this.llmDefaults || {};
|
|
1433
|
+
let touched = false;
|
|
1434
|
+
|
|
1435
|
+
if (!merged.baseURL && cfg.baseURL) { merged.baseURL = cfg.baseURL; touched = true; }
|
|
1436
|
+
if (!merged.apiKey && cfg.apiKey) { merged.apiKey = cfg.apiKey; touched = true; }
|
|
1437
|
+
|
|
1438
|
+
this.llmSettings = merged;
|
|
1439
|
+
|
|
1440
|
+
if (touched) { this.saveLlmSettings(); }
|
|
1441
|
+
|
|
1442
|
+
this.migrateLegacyLlmSettings();
|
|
1443
|
+
this.renderModelDisplay();
|
|
1385
1444
|
}
|
|
1386
1445
|
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1446
|
+
migrateLegacyLlmSettings () {
|
|
1447
|
+
try {
|
|
1448
|
+
const legacy = JSON.parse(localStorage.getItem('mcpAgentFormValues') || '{}');
|
|
1449
|
+
let dirty = false;
|
|
1450
|
+
const numericFields = new Set(['temperature', 'maxTokens', 'maxTurns', 'toolResultLimitChars']);
|
|
1451
|
+
const map = {
|
|
1452
|
+
customBaseUrl: 'baseURL',
|
|
1453
|
+
customApiKey: 'apiKey',
|
|
1454
|
+
customModelName: 'model',
|
|
1455
|
+
modelTemperature: 'temperature',
|
|
1456
|
+
modelMaxTokens: 'maxTokens',
|
|
1457
|
+
modelMaxTurns: 'maxTurns',
|
|
1458
|
+
toolResultLimitChars: 'toolResultLimitChars',
|
|
1459
|
+
};
|
|
1460
|
+
for (const [from, to] of Object.entries(map)) {
|
|
1461
|
+
const raw = legacy[from];
|
|
1462
|
+
if (raw == null || raw === '') { continue; }
|
|
1463
|
+
const current = this.llmSettings[to];
|
|
1464
|
+
const isEmpty = current == null || current === '' || current === LLM_DEFAULTS[to];
|
|
1465
|
+
if (!isEmpty) { continue; }
|
|
1466
|
+
const v = numericFields.has(to) ? Number(raw) : raw;
|
|
1467
|
+
if (numericFields.has(to) && Number.isNaN(v)) { continue; }
|
|
1468
|
+
this.llmSettings[to] = v;
|
|
1469
|
+
dirty = true;
|
|
1470
|
+
}
|
|
1471
|
+
// Legacy preset model (not 'other'): reuse if current model is still a default
|
|
1472
|
+
if (legacy.model && legacy.model !== 'other' && (this.llmSettings.model === LLM_DEFAULTS.model || !this.llmSettings.model)) {
|
|
1473
|
+
this.llmSettings.model = legacy.model;
|
|
1474
|
+
dirty = true;
|
|
1475
|
+
}
|
|
1476
|
+
if (dirty) { this.saveLlmSettings(); this.renderModelDisplay(); }
|
|
1477
|
+
} catch { /* ignore */ }
|
|
1478
|
+
}
|
|
1479
|
+
|
|
1480
|
+
saveLlmSettings () {
|
|
1481
|
+
try {
|
|
1482
|
+
localStorage.setItem(LLM_LS_KEY, JSON.stringify(this.llmSettings));
|
|
1483
|
+
} catch (e) {
|
|
1484
|
+
console.error('Failed to save LLM settings:', e);
|
|
1390
1485
|
}
|
|
1486
|
+
}
|
|
1391
1487
|
|
|
1392
|
-
|
|
1393
|
-
const
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1488
|
+
renderModelDisplay () {
|
|
1489
|
+
const name = trim(this.llmSettings.model) || '—';
|
|
1490
|
+
this.modelDisplay.textContent = name;
|
|
1491
|
+
this.apiKeyWarning.style.display = this.llmSettings.apiKey ? 'none' : 'block';
|
|
1492
|
+
}
|
|
1397
1493
|
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1494
|
+
openLlmModal () {
|
|
1495
|
+
const s = this.llmSettings;
|
|
1496
|
+
this.llmBaseUrl.value = s.baseURL || '';
|
|
1497
|
+
this.llmApiKey.value = s.apiKey || '';
|
|
1498
|
+
this.llmModelName.value = s.model || '';
|
|
1499
|
+
this.llmTemperature.value = s.temperature ?? LLM_DEFAULTS.temperature;
|
|
1500
|
+
this.llmMaxTokens.value = s.maxTokens ?? LLM_DEFAULTS.maxTokens;
|
|
1501
|
+
this.llmMaxTurns.value = s.maxTurns ?? LLM_DEFAULTS.maxTurns;
|
|
1502
|
+
this.llmLimitChars.value = s.toolResultLimitChars ?? LLM_DEFAULTS.toolResultLimitChars;
|
|
1404
1503
|
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1504
|
+
// Reset API key visibility to hidden on open
|
|
1505
|
+
this.llmApiKey.type = 'password';
|
|
1506
|
+
const icon = this.llmApiKeyToggle.querySelector('.material-icons-round');
|
|
1507
|
+
if (icon) { icon.textContent = 'visibility'; }
|
|
1508
|
+
|
|
1509
|
+
this.llmModal.style.display = 'flex';
|
|
1510
|
+
}
|
|
1511
|
+
|
|
1512
|
+
closeLlmModal () {
|
|
1513
|
+
this.closeLlmModelDropdown();
|
|
1514
|
+
this.llmModal.style.display = 'none';
|
|
1515
|
+
}
|
|
1516
|
+
|
|
1517
|
+
saveLlmModal () {
|
|
1518
|
+
const baseURL = trim(this.llmBaseUrl.value);
|
|
1519
|
+
const apiKey = trim(this.llmApiKey.value);
|
|
1520
|
+
const model = trim(this.llmModelName.value);
|
|
1521
|
+
const temperature = parseFloat(this.llmTemperature.value);
|
|
1522
|
+
const maxTokens = parseInt(this.llmMaxTokens.value, 10);
|
|
1523
|
+
const maxTurns = parseInt(this.llmMaxTurns.value, 10);
|
|
1524
|
+
const toolResultLimitChars = parseInt(this.llmLimitChars.value, 10);
|
|
1525
|
+
|
|
1526
|
+
const missing = [];
|
|
1527
|
+
if (!model) { missing.push('Model Name'); }
|
|
1528
|
+
// baseURL is optional (OpenAI default) — empty means use provider default
|
|
1529
|
+
// apiKey intentionally not required here — its absence triggers the red warning instead
|
|
1530
|
+
if (Number.isNaN(temperature)) { missing.push('Temperature'); }
|
|
1531
|
+
if (!maxTokens) { missing.push('Max Tokens'); }
|
|
1532
|
+
if (!maxTurns) { missing.push('Max Turns'); }
|
|
1533
|
+
if (!toolResultLimitChars) { missing.push('Limit (chars)'); }
|
|
1534
|
+
|
|
1535
|
+
if (missing.length) {
|
|
1536
|
+
this.showToast(`Missing required fields: ${missing.join(', ')}`, 'error');
|
|
1537
|
+
return;
|
|
1408
1538
|
}
|
|
1409
1539
|
|
|
1410
|
-
|
|
1540
|
+
this.llmSettings = { baseURL, apiKey, model, temperature, maxTokens, maxTurns, toolResultLimitChars };
|
|
1541
|
+
this.saveLlmSettings();
|
|
1542
|
+
this.renderModelDisplay();
|
|
1543
|
+
this.closeLlmModal();
|
|
1544
|
+
this.showToast('LLM settings saved', 'success');
|
|
1411
1545
|
}
|
|
1412
1546
|
|
|
1413
|
-
|
|
1414
|
-
const
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1547
|
+
toggleApiKeyVisibility () {
|
|
1548
|
+
const icon = this.llmApiKeyToggle.querySelector('.material-icons-round');
|
|
1549
|
+
if (this.llmApiKey.type === 'password') {
|
|
1550
|
+
this.llmApiKey.type = 'text';
|
|
1551
|
+
if (icon) { icon.textContent = 'visibility_off'; }
|
|
1552
|
+
} else {
|
|
1553
|
+
this.llmApiKey.type = 'password';
|
|
1554
|
+
if (icon) { icon.textContent = 'visibility'; }
|
|
1555
|
+
}
|
|
1556
|
+
}
|
|
1557
|
+
|
|
1558
|
+
renderLlmModelDropdown () {
|
|
1559
|
+
this.llmModelDropdownList.innerHTML = '';
|
|
1560
|
+
LLM_PRESET_MODELS.forEach((name) => {
|
|
1561
|
+
const item = document.createElement('div');
|
|
1562
|
+
item.className = 'dropdown-item';
|
|
1563
|
+
item.setAttribute('data-testid', `at-llm-model-option-${name}`);
|
|
1564
|
+
item.textContent = name;
|
|
1565
|
+
item.addEventListener('click', (e) => {
|
|
1566
|
+
e.stopPropagation();
|
|
1567
|
+
this.llmModelName.value = name;
|
|
1568
|
+
this.closeLlmModelDropdown();
|
|
1569
|
+
});
|
|
1570
|
+
this.llmModelDropdownList.appendChild(item);
|
|
1571
|
+
});
|
|
1572
|
+
}
|
|
1573
|
+
|
|
1574
|
+
toggleLlmModelDropdown (e) {
|
|
1575
|
+
e.preventDefault();
|
|
1576
|
+
e.stopPropagation();
|
|
1577
|
+
const visible = this.llmModelDropdownList.style.display !== 'none';
|
|
1578
|
+
if (visible) {
|
|
1579
|
+
this.closeLlmModelDropdown();
|
|
1580
|
+
} else {
|
|
1581
|
+
this.openLlmModelDropdown();
|
|
1582
|
+
}
|
|
1583
|
+
}
|
|
1584
|
+
|
|
1585
|
+
openLlmModelDropdown () {
|
|
1586
|
+
this.llmModelDropdownList.style.display = 'block';
|
|
1587
|
+
this.llmModelDropdownToggle.classList.add('active');
|
|
1588
|
+
// Close on outside click (one-shot)
|
|
1589
|
+
setTimeout(() => {
|
|
1590
|
+
const onDocClick = (ev) => {
|
|
1591
|
+
if (!this.llmModelDropdownList.contains(ev.target) && ev.target !== this.llmModelDropdownToggle) {
|
|
1592
|
+
this.closeLlmModelDropdown();
|
|
1593
|
+
document.removeEventListener('click', onDocClick);
|
|
1594
|
+
}
|
|
1430
1595
|
};
|
|
1596
|
+
document.addEventListener('click', onDocClick);
|
|
1597
|
+
}, 0);
|
|
1598
|
+
}
|
|
1599
|
+
|
|
1600
|
+
closeLlmModelDropdown () {
|
|
1601
|
+
this.llmModelDropdownList.style.display = 'none';
|
|
1602
|
+
this.llmModelDropdownToggle.classList.remove('active');
|
|
1603
|
+
}
|
|
1604
|
+
|
|
1605
|
+
validateLlmSettings () {
|
|
1606
|
+
const s = this.llmSettings;
|
|
1607
|
+
const missing = [];
|
|
1608
|
+
// baseURL is optional — empty means use provider default (OpenAI)
|
|
1609
|
+
if (!s.apiKey) { missing.push('API Key'); }
|
|
1610
|
+
if (!s.model) { missing.push('Model Name'); }
|
|
1611
|
+
if (missing.length) {
|
|
1612
|
+
this.showToast(`Cannot send message — missing: ${missing.join(', ')}. Open LLM Settings.`, 'error');
|
|
1613
|
+
return false;
|
|
1431
1614
|
}
|
|
1615
|
+
return true;
|
|
1616
|
+
}
|
|
1432
1617
|
|
|
1618
|
+
getModelConfig () {
|
|
1619
|
+
const s = this.llmSettings;
|
|
1433
1620
|
return {
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1621
|
+
baseURL: s.baseURL,
|
|
1622
|
+
apiKey: s.apiKey,
|
|
1623
|
+
model: s.model,
|
|
1624
|
+
temperature: s.temperature,
|
|
1625
|
+
maxTokens: s.maxTokens,
|
|
1626
|
+
maxTurns: s.maxTurns,
|
|
1627
|
+
toolResultLimitChars: s.toolResultLimitChars,
|
|
1439
1628
|
};
|
|
1440
1629
|
}
|
|
1441
1630
|
|
|
@@ -1471,16 +1660,8 @@ class McpAgentTester {
|
|
|
1471
1660
|
const formData = {
|
|
1472
1661
|
serverUrl: this.serverUrlInput.value,
|
|
1473
1662
|
transport: this.transportSelect.value,
|
|
1474
|
-
model: this.modelSelect.value,
|
|
1475
1663
|
agentPrompt: trim(this.systemPromptTextarea.value),
|
|
1476
1664
|
customPrompt: trim(this.customPromptTextarea.value),
|
|
1477
|
-
customBaseUrl: trim(this.customBaseUrl.value),
|
|
1478
|
-
customApiKey: trim(this.customApiKey.value),
|
|
1479
|
-
customModelName: trim(this.customModelName.value),
|
|
1480
|
-
modelTemperature: this.modelTemperature.value,
|
|
1481
|
-
modelMaxTokens: this.modelMaxTokens.value,
|
|
1482
|
-
modelMaxTurns: this.modelMaxTurns.value,
|
|
1483
|
-
toolResultLimitChars: this.toolResultLimitChars.value,
|
|
1484
1665
|
};
|
|
1485
1666
|
localStorage.setItem('mcpAgentFormValues', JSON.stringify(formData));
|
|
1486
1667
|
}
|
|
@@ -1509,17 +1690,8 @@ class McpAgentTester {
|
|
|
1509
1690
|
const formData = JSON.parse(stored);
|
|
1510
1691
|
if (formData.serverUrl) {this.serverUrlInput.value = formData.serverUrl;}
|
|
1511
1692
|
if (formData.transport) {this.transportSelect.value = formData.transport;}
|
|
1512
|
-
if (formData.model) {this.modelSelect.value = formData.model;}
|
|
1513
1693
|
if (formData.agentPrompt) {this.systemPromptTextarea.value = trim(formData.agentPrompt);}
|
|
1514
1694
|
if (formData.customPrompt) {this.customPromptTextarea.value = trim(formData.customPrompt);}
|
|
1515
|
-
if (formData.customBaseUrl) {this.customBaseUrl.value = formData.customBaseUrl;}
|
|
1516
|
-
if (formData.customApiKey) {this.customApiKey.value = formData.customApiKey;}
|
|
1517
|
-
if (formData.customModelName) {this.customModelName.value = formData.customModelName;}
|
|
1518
|
-
if (formData.modelTemperature) {this.modelTemperature.value = formData.modelTemperature;}
|
|
1519
|
-
if (formData.modelMaxTokens) {this.modelMaxTokens.value = formData.modelMaxTokens;}
|
|
1520
|
-
if (formData.modelMaxTurns) {this.modelMaxTurns.value = formData.modelMaxTurns;}
|
|
1521
|
-
if (formData.toolResultLimitChars) {this.toolResultLimitChars.value = formData.toolResultLimitChars;}
|
|
1522
|
-
this.handleModelSelectChange();
|
|
1523
1695
|
}
|
|
1524
1696
|
} catch (error) {
|
|
1525
1697
|
console.error('Error loading form values from storage:', error);
|
|
@@ -1489,6 +1489,140 @@ body {
|
|
|
1489
1489
|
opacity: 0.9;
|
|
1490
1490
|
}
|
|
1491
1491
|
|
|
1492
|
+
/* ============================================
|
|
1493
|
+
Model Display (collapsed LLM block)
|
|
1494
|
+
============================================ */
|
|
1495
|
+
|
|
1496
|
+
.model-display-row {
|
|
1497
|
+
display: flex;
|
|
1498
|
+
align-items: center;
|
|
1499
|
+
gap: 8px;
|
|
1500
|
+
}
|
|
1501
|
+
|
|
1502
|
+
.model-display {
|
|
1503
|
+
flex: 1;
|
|
1504
|
+
padding: 8px 12px;
|
|
1505
|
+
background: var(--bg-input);
|
|
1506
|
+
border: 1px solid var(--border-input);
|
|
1507
|
+
border-radius: var(--radius);
|
|
1508
|
+
font-family: 'Fira Code', monospace;
|
|
1509
|
+
font-size: 0.85rem;
|
|
1510
|
+
color: var(--text);
|
|
1511
|
+
user-select: text;
|
|
1512
|
+
overflow: hidden;
|
|
1513
|
+
text-overflow: ellipsis;
|
|
1514
|
+
white-space: nowrap;
|
|
1515
|
+
}
|
|
1516
|
+
|
|
1517
|
+
.api-key-warning {
|
|
1518
|
+
margin-top: 6px;
|
|
1519
|
+
color: #d93025;
|
|
1520
|
+
font-size: 0.75rem;
|
|
1521
|
+
font-weight: 500;
|
|
1522
|
+
}
|
|
1523
|
+
|
|
1524
|
+
[data-theme="dark"] .api-key-warning {
|
|
1525
|
+
color: #f28b82;
|
|
1526
|
+
}
|
|
1527
|
+
|
|
1528
|
+
/* ============================================
|
|
1529
|
+
LLM Settings Modal
|
|
1530
|
+
============================================ */
|
|
1531
|
+
|
|
1532
|
+
.llm-modal-overlay {
|
|
1533
|
+
position: fixed;
|
|
1534
|
+
inset: 0;
|
|
1535
|
+
background: rgba(0, 0, 0, 0.5);
|
|
1536
|
+
backdrop-filter: blur(4px);
|
|
1537
|
+
z-index: 1000;
|
|
1538
|
+
display: flex;
|
|
1539
|
+
align-items: center;
|
|
1540
|
+
justify-content: center;
|
|
1541
|
+
padding: 24px;
|
|
1542
|
+
}
|
|
1543
|
+
|
|
1544
|
+
.llm-modal {
|
|
1545
|
+
background: var(--bg-sidebar);
|
|
1546
|
+
border: 1px solid var(--border);
|
|
1547
|
+
border-radius: var(--radius-lg);
|
|
1548
|
+
width: 100%;
|
|
1549
|
+
max-width: 520px;
|
|
1550
|
+
max-height: 95vh;
|
|
1551
|
+
display: flex;
|
|
1552
|
+
flex-direction: column;
|
|
1553
|
+
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
|
|
1554
|
+
}
|
|
1555
|
+
|
|
1556
|
+
/* Compact dropdown items inside LLM modal so all preset models fit without scroll */
|
|
1557
|
+
.llm-modal .dropdown-list {
|
|
1558
|
+
max-height: 420px;
|
|
1559
|
+
}
|
|
1560
|
+
|
|
1561
|
+
.llm-modal .dropdown-item {
|
|
1562
|
+
padding: 4px 12px;
|
|
1563
|
+
font-size: 0.8rem;
|
|
1564
|
+
}
|
|
1565
|
+
|
|
1566
|
+
.llm-modal-header {
|
|
1567
|
+
display: flex;
|
|
1568
|
+
align-items: center;
|
|
1569
|
+
justify-content: space-between;
|
|
1570
|
+
padding: 16px 20px;
|
|
1571
|
+
border-bottom: 1px solid var(--border);
|
|
1572
|
+
}
|
|
1573
|
+
|
|
1574
|
+
.llm-modal-header h3 {
|
|
1575
|
+
font-size: 0.95rem;
|
|
1576
|
+
font-weight: 600;
|
|
1577
|
+
color: var(--text);
|
|
1578
|
+
margin: 0;
|
|
1579
|
+
}
|
|
1580
|
+
|
|
1581
|
+
.llm-modal-body {
|
|
1582
|
+
padding: 16px 20px;
|
|
1583
|
+
overflow: visible;
|
|
1584
|
+
display: flex;
|
|
1585
|
+
flex-direction: column;
|
|
1586
|
+
gap: 12px;
|
|
1587
|
+
}
|
|
1588
|
+
|
|
1589
|
+
.llm-modal-body .form-row {
|
|
1590
|
+
display: flex;
|
|
1591
|
+
gap: 12px;
|
|
1592
|
+
}
|
|
1593
|
+
|
|
1594
|
+
.llm-modal-body .form-row .form-group {
|
|
1595
|
+
flex: 1;
|
|
1596
|
+
}
|
|
1597
|
+
|
|
1598
|
+
.llm-modal-body .input-with-toggle {
|
|
1599
|
+
display: flex;
|
|
1600
|
+
gap: 4px;
|
|
1601
|
+
align-items: stretch;
|
|
1602
|
+
}
|
|
1603
|
+
|
|
1604
|
+
.llm-modal-body .input-with-toggle input {
|
|
1605
|
+
flex: 1;
|
|
1606
|
+
}
|
|
1607
|
+
|
|
1608
|
+
.llm-modal-body .input-with-toggle .btn-icon {
|
|
1609
|
+
flex-shrink: 0;
|
|
1610
|
+
}
|
|
1611
|
+
|
|
1612
|
+
.llm-modal-footer {
|
|
1613
|
+
display: flex;
|
|
1614
|
+
justify-content: flex-end;
|
|
1615
|
+
gap: 8px;
|
|
1616
|
+
padding: 12px 20px;
|
|
1617
|
+
border-top: 1px solid var(--border);
|
|
1618
|
+
}
|
|
1619
|
+
|
|
1620
|
+
.llm-modal-footer .btn {
|
|
1621
|
+
padding: 8px 20px;
|
|
1622
|
+
font-size: 0.8rem;
|
|
1623
|
+
font-weight: 600;
|
|
1624
|
+
}
|
|
1625
|
+
|
|
1492
1626
|
/* ============================================
|
|
1493
1627
|
Auth Overlay (Login Screen)
|
|
1494
1628
|
============================================ */
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fa-mcp-sdk",
|
|
3
3
|
"productName": "FA MCP SDK",
|
|
4
|
-
"version": "0.4.
|
|
4
|
+
"version": "0.4.19",
|
|
5
5
|
"description": "Core infrastructure and templates for building Model Context Protocol (MCP) servers with TypeScript",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "dist/core/index.js",
|