fix: tester.html 파라미터 스키마 렌더링 오류 수정 및 객체 재귀 탐색 기능 추가
Some checks failed
Deploy to OCIWP / deploy (push) Failing after 12s
Some checks failed
Deploy to OCIWP / deploy (push) Failing after 12s
This commit is contained in:
@@ -207,7 +207,7 @@
|
||||
<svg class="w-3 h-3 text-zinc-500" fill="currentColor" viewBox="0 0 20 20"><path d="M10 18a8 8 0 100-16 8 8 0 000 16zM9 9a1 1 0 012 0v4a1 1 0 11-2 0V9zm1-5a1 1 0 110 2 1 1 0 010-2z"></path></svg>
|
||||
Auto-saved to LocalStorage
|
||||
</div>
|
||||
<button onclick="resetPayload()" class="btn-sm py-2 px-4 text-red-400 hover:text-red-300 border border-red-500/30 hover:border-red-400 mr-2" style="font-size:12px;" title="저장된 페이로드를 삭제하고 스키마 기본값으로 초기화합니다">Reset to Schema</button>
|
||||
<button onclick="resetPayload()" class="btn-sm py-2 px-4 text-red-400 hover:text-red-300 border border-red-500/30 hover:border-red-400 mr-2" style="font-size:12px;" title="?€?¥ë<C2A5>œ ?˜ì<CB9C>´ë¡œë“œë¥??? œ?˜ê³ ?¤í‚¤ë§?기본값으ë¡?초기?”í•©?ˆë‹¤">Reset to Schema</button>
|
||||
<button onclick="closePayloadModal()" class="btn-sm py-2 px-4">Cancel</button>
|
||||
<button onclick="savePayload()" class="btn-execute py-2 px-4" style="font-size:12px;">Save & Apply</button>
|
||||
</div>
|
||||
@@ -369,24 +369,42 @@
|
||||
localStorage.setItem('mcp_tester_payloads', JSON.stringify(dict));
|
||||
}
|
||||
|
||||
function generateDummyForSchema(schema) {
|
||||
if (!schema) return null;
|
||||
if (schema.example !== undefined) return schema.example;
|
||||
if (schema.examples && Array.isArray(schema.examples) && schema.examples.length > 0) return schema.examples[0];
|
||||
if (schema.default !== undefined) return schema.default;
|
||||
|
||||
if (schema.type === 'object') {
|
||||
const obj = {};
|
||||
if (schema.properties) {
|
||||
for (const [k, v] of Object.entries(schema.properties)) {
|
||||
obj[k] = generateDummyForSchema(v);
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
} else if (schema.type === 'array') {
|
||||
return [generateDummyForSchema(schema.items || {})];
|
||||
} else if (schema.type === 'string') {
|
||||
if (schema.enum && schema.enum.length > 0) return schema.enum[0];
|
||||
return "test_string";
|
||||
} else if (schema.type === 'integer' || schema.type === 'number') {
|
||||
return schema.minimum !== undefined ? schema.minimum : 1;
|
||||
} else if (schema.type === 'boolean') {
|
||||
return true;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function generateDummyPayload(tool) {
|
||||
if (tool._customPayload) return tool._customPayload;
|
||||
|
||||
const schema = tool.parametersSchema;
|
||||
const schema = tool.inputSchema || (tool.inputSchema || tool.parametersSchema);
|
||||
if (!schema || !schema.properties) return {};
|
||||
|
||||
const payload = {};
|
||||
for (const [key, value] of Object.entries(schema.properties)) {
|
||||
if (value.example !== undefined) payload[key] = value.example;
|
||||
else if (value.examples && Array.isArray(value.examples) && value.examples.length > 0) payload[key] = value.examples[0];
|
||||
else if (value.default !== undefined) payload[key] = value.default;
|
||||
else {
|
||||
if (value.type === 'string') {
|
||||
if (value.enum && value.enum.length > 0) payload[key] = value.enum[0];
|
||||
else payload[key] = "test_string";
|
||||
} else if (value.type === 'integer' || value.type === 'number') payload[key] = value.minimum !== undefined ? value.minimum : 1;
|
||||
else if (value.type === 'boolean') payload[key] = true;
|
||||
else payload[key] = null;
|
||||
}
|
||||
payload[key] = generateDummyForSchema(value);
|
||||
}
|
||||
return payload;
|
||||
}
|
||||
@@ -480,9 +498,9 @@
|
||||
tool._responseData = res.data;
|
||||
|
||||
if (tool._isFailed) {
|
||||
appendLog(`❌ [ERROR] ${tool.name} failed (${res.status}) - ${res.latency}ms`, 'error');
|
||||
appendLog(`??[ERROR] ${tool.name} failed (${res.status}) - ${res.latency}ms`, 'error');
|
||||
} else {
|
||||
appendLog(`✅ [SUCCESS] ${tool.name} completed - ${res.latency}ms`, 'success');
|
||||
appendLog(`??[SUCCESS] ${tool.name} completed - ${res.latency}ms`, 'success');
|
||||
}
|
||||
|
||||
// Update UI if visible
|
||||
@@ -746,7 +764,7 @@
|
||||
}
|
||||
|
||||
function renderSmartForm(tool, payloadToUse = null) {
|
||||
const schema = tool.parametersSchema;
|
||||
const schema = (tool.inputSchema || tool.parametersSchema);
|
||||
const form = document.getElementById('payloadFormContainer');
|
||||
form.innerHTML = '';
|
||||
|
||||
@@ -834,18 +852,18 @@
|
||||
if (currentEditIndex === -1) return;
|
||||
const tool = allTools[currentEditIndex];
|
||||
|
||||
// 로컬 스토리지에서 삭제
|
||||
// 로컬 ?¤í† 리ì??<3F>서 ?? œ
|
||||
const savedPayloads = JSON.parse(localStorage.getItem('mcp_tester_payloads') || '{}');
|
||||
delete savedPayloads[tool.name];
|
||||
localStorage.setItem('mcp_tester_payloads', JSON.stringify(savedPayloads));
|
||||
|
||||
// 런타임 상태 초기화
|
||||
// ?°í????<3F>태 초기??
|
||||
tool._customPayload = null;
|
||||
|
||||
// 새 스키마 기반 기본 페이로드 생성
|
||||
// ???¤í‚¤ë§?기반 기본 ?˜ì<CB9C>´ë¡œë“œ ?<3F>성
|
||||
const freshPayload = generateDummyPayload(tool);
|
||||
|
||||
// UI 업데이트
|
||||
// UI ?…ë<E280A6>°?´íЏ
|
||||
document.getElementById('payloadEditor').value = JSON.stringify(freshPayload, null, 2);
|
||||
renderSmartForm(tool, freshPayload);
|
||||
}
|
||||
@@ -1048,8 +1066,8 @@
|
||||
// Or we just map /mcp/api/v1/tools/call and use tool names as different request bodies,
|
||||
// but for documentation purposes, mapping them as separate virtual paths is usually better to view in Swagger UI.
|
||||
currentExportJson.forEach(tool => {
|
||||
const schemaProps = tool.parametersSchema?.properties || {};
|
||||
const required = tool.parametersSchema?.required || [];
|
||||
const schemaProps = (tool.inputSchema || tool.parametersSchema)?.properties || {};
|
||||
const required = (tool.inputSchema || tool.parametersSchema)?.required || [];
|
||||
|
||||
paths[`/mcp/api/v1/tools/call?name=${tool.name}`] = {
|
||||
post: {
|
||||
@@ -1133,8 +1151,8 @@
|
||||
md += `### \`${tool.name}\`\n\n`;
|
||||
md += `**Description:** ${tool.description || 'N/A'}\n\n`;
|
||||
|
||||
const props = tool.parametersSchema?.properties || {};
|
||||
const reqs = tool.parametersSchema?.required || [];
|
||||
const props = (tool.inputSchema || tool.parametersSchema)?.properties || {};
|
||||
const reqs = (tool.inputSchema || tool.parametersSchema)?.required || [];
|
||||
|
||||
if (Object.keys(props).length > 0) {
|
||||
md += `#### Parameters\n\n`;
|
||||
@@ -1142,7 +1160,7 @@
|
||||
md += `|------|------|----------|-------------|---------|\n`;
|
||||
Object.keys(props).forEach(p => {
|
||||
const pData = props[p];
|
||||
const isReq = reqs.includes(p) ? '✅ Yes' : '❌ No';
|
||||
const isReq = reqs.includes(p) ? '??Yes' : '??No';
|
||||
let example = pData.example !== undefined ? pData.example : (pData.examples ? pData.examples[0] : '');
|
||||
if (typeof example === 'object') example = JSON.stringify(example);
|
||||
md += `| \`${p}\` | \`${pData.type || 'string'}\` | ${isReq} | ${pData.description || ''} | \`${example}\` |\n`;
|
||||
|
||||
Reference in New Issue
Block a user