Add agent-facing wizard preview
Deploy / deploy (push) Successful in 1m30s
CI / Rust Checks (push) Successful in 5m33s
CI / UI Checks (push) Successful in 5s
CI / Deployment Manifests (push) Successful in 3s
CI / Frontend E2E (push) Successful in 4m19s

This commit is contained in:
github-ops
2026-06-20 20:06:30 +00:00
parent d79ec95028
commit 751a832fcb
5 changed files with 377 additions and 0 deletions
+99
View File
@@ -68,6 +68,7 @@ async function loadOperationForEdit() {
wizardCurrentOperation = detail;
wizardCurrentVersion = draftVersion;
prefillWizardFromEdit(detail, draftVersion);
renderAgentFacingPreview();
}
function setEditModePresentation() {
@@ -98,6 +99,7 @@ function bindWizardLiveActions() {
bindLiveAction('wizard-generate-draft', tKey('wizard.busy.generate'), generateDraftFromWizard);
bindLiveAction('wizard-run-test', tKey('wizard.busy.test'), runWizardTest);
bindClick('wizard-copy-test-response', copyTestResponseToOutputSample);
bindClick('wizard-copy-agent-preview', copyAgentFacingPreview);
bindLiveAction('wizard-export-yaml', tKey('wizard.busy.export_yaml'), exportWizardYaml);
bindLiveAction('wizard-import-yaml', tKey('wizard.busy.import_yaml'), importWizardYaml);
bindLiveAction('wizard-publish-operation', tKey('wizard.busy.publish'), publishWizardOperation);
@@ -108,6 +110,7 @@ function bindWizardLiveActions() {
var yamlInput = document.getElementById('wizard-import-yaml-file');
if (yamlInput) yamlInput.addEventListener('change', handleImportYamlFileSelection);
bindAgentFacingPreview();
}
function bindClick(id, handler) {
@@ -302,6 +305,99 @@ function setTextareaValue(id, value) {
element.value = safeStringify(value);
}
function setTextContent(id, value) {
var element = document.getElementById(id);
if (!element) return;
element.textContent = value || '';
}
function structuredTextOrFallback(id, fallback) {
try {
var value = parseStructuredText(textValue(id));
if (value === null || value === undefined || value === '') return fallback;
return value;
} catch (_error) {
return fallback;
}
}
function buildAgentFacingPreview() {
var inputSchema = structuredTextOrFallback('tool-input-schema', {});
var inputSample = structuredTextOrFallback('wizard-input-sample', {});
var outputSample = structuredTextOrFallback('wizard-output-sample', {});
var toolName = textValue('tool-name') || 'unnamed_tool';
var title = textValue('tool-title') || textValue('tool-display-name') || toolName;
var description = textValue('tool-description');
return {
manifest: {
name: toolName,
title: title,
description: description,
inputSchema: inputSchema,
},
toolCall: {
name: toolName,
arguments: inputSample,
},
successResponse: outputSample,
errorResponse: {
isError: true,
content: [
{
type: 'text',
text: 'Инструмент вернул ошибку. Проверьте входные параметры или состояние внешнего API.',
},
],
},
};
}
function renderAgentFacingPreview() {
var root = document.getElementById('agent-facing-preview-card');
if (!root) return;
var preview = buildAgentFacingPreview();
setTextContent('agent-preview-tool-name', preview.manifest.name);
setTextContent('agent-preview-tool-title', preview.manifest.title);
setTextContent('agent-preview-tool-description', preview.manifest.description);
setTextareaValue('agent-preview-input-schema', preview.manifest.inputSchema);
setTextareaValue('agent-preview-tool-call', preview.toolCall);
setTextareaValue('agent-preview-success-response', preview.successResponse);
setTextareaValue('agent-preview-error-response', preview.errorResponse);
}
function bindAgentFacingPreview() {
[
'tool-name',
'tool-title',
'tool-display-name',
'tool-description',
'tool-input-schema',
'wizard-input-sample',
'wizard-output-sample',
].forEach(function(id) {
var element = document.getElementById(id);
if (!element || element.dataset.agentPreviewBound === 'true') return;
element.dataset.agentPreviewBound = 'true';
element.addEventListener('input', renderAgentFacingPreview);
element.addEventListener('change', renderAgentFacingPreview);
});
renderAgentFacingPreview();
}
function copyAgentFacingPreview() {
var preview = buildAgentFacingPreview();
var content = JSON.stringify(preview.manifest, null, 2);
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(content).then(function() {
showWizardLiveStatus(tKey('wizard.agent_preview.copied'), tKey('wizard.agent_preview.copied_body'));
}).catch(function() {
setTextareaValue('agent-preview-input-schema', preview.manifest.inputSchema);
});
}
}
async function exportWizardYaml() {
await persistCurrentDraft(true);
var yaml = await window.CrankApi.exportOperation(wizardWorkspaceId, wizardEditId, {
@@ -386,6 +482,7 @@ async function generateDraftFromWizard() {
setValue('tool-output-schema', JSON.stringify(crankSchemaToJsonSchema(generated.output_schema), null, 2));
setValue('tool-input-mapping', mappingSetToEditorValue(generated.input_mapping, 'input', wizardProtocol));
setValue('tool-output-mapping', mappingSetToEditorValue(generated.output_mapping, 'output', wizardProtocol));
renderAgentFacingPreview();
showWizardLiveStatus(tKey('wizard.sample.generated'), tKey('wizard.sample.generated_body'));
}
@@ -413,6 +510,7 @@ function copyTestResponseToOutputSample() {
return;
}
setTextareaValue('wizard-output-sample', wizardTestResponsePreview);
renderAgentFacingPreview();
showWizardLiveStatus(tKey('wizard.test.response_copied'), tKey('wizard.test.response_copied_body'));
}
@@ -421,4 +519,5 @@ window.CrankWizardLive = {
loadOperationForEdit: loadOperationForEdit,
bindWizardLiveActions: bindWizardLiveActions,
updateWizardProtocolVisibility: updateWizardProtocolVisibility,
renderAgentFacingPreview: renderAgentFacingPreview,
};