mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-07-06 09:21:16 -03:00
feat(agent): enrich_hf_metadata with per-model progress and in-place card update
- PostProcessor returns updates dict from enrich_hf_metadata - AgentService includes updated_data per model in WebSocket progress events - Convert preview_url to HTTP URL via config.get_preview_static_url() - LoraContextMenu: showEnhancedProgress + updateSingleItem per model - BulkContextMenu: same pattern, remove window.location.reload() - Guard empty updated_data and clean up callbacks on HTTP error
This commit is contained in:
@@ -26,6 +26,7 @@ import aiohttp
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
from ...config import config
|
||||||
from ..llm_service import LLMService
|
from ..llm_service import LLMService
|
||||||
from ..websocket_manager import ws_manager
|
from ..websocket_manager import ws_manager
|
||||||
from .post_processor import PostProcessor
|
from .post_processor import PostProcessor
|
||||||
@@ -259,6 +260,7 @@ class AgentService:
|
|||||||
"execute_skill '%s': processing model %d/%d: %s",
|
"execute_skill '%s': processing model %d/%d: %s",
|
||||||
skill_name, processed + 1, total, model_path,
|
skill_name, processed + 1, total, model_path,
|
||||||
)
|
)
|
||||||
|
updated_data: Dict[str, Any] = {}
|
||||||
try:
|
try:
|
||||||
from ...agent_cli import read_metadata
|
from ...agent_cli import read_metadata
|
||||||
metadata = await read_metadata(model_path)
|
metadata = await read_metadata(model_path)
|
||||||
@@ -298,6 +300,11 @@ class AgentService:
|
|||||||
uf = model_result.get("updated_fields", [])
|
uf = model_result.get("updated_fields", [])
|
||||||
if uf:
|
if uf:
|
||||||
updated_models.append({"path": model_path, "updated_fields": uf})
|
updated_models.append({"path": model_path, "updated_fields": uf})
|
||||||
|
updated_data = model_result.get("updates", {})
|
||||||
|
if "preview_url" in updated_data and updated_data["preview_url"]:
|
||||||
|
updated_data["preview_url"] = config.get_preview_static_url(
|
||||||
|
updated_data["preview_url"]
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
errors.extend(
|
errors.extend(
|
||||||
model_result.get("errors", [model_result.get("error", "Unknown error")])
|
model_result.get("errors", [model_result.get("error", "Unknown error")])
|
||||||
@@ -312,6 +319,7 @@ class AgentService:
|
|||||||
progress_callback, skill_name, status="processing",
|
progress_callback, skill_name, status="processing",
|
||||||
total=total, processed=processed, success=success_count,
|
total=total, processed=processed, success=success_count,
|
||||||
current_path=model_path,
|
current_path=model_path,
|
||||||
|
updated_data=updated_data,
|
||||||
)
|
)
|
||||||
|
|
||||||
result = SkillResult(
|
result = SkillResult(
|
||||||
|
|||||||
@@ -253,6 +253,7 @@ class PostProcessor:
|
|||||||
"success": True,
|
"success": True,
|
||||||
"updated_fields": updated_fields,
|
"updated_fields": updated_fields,
|
||||||
"preview_downloaded": preview_downloaded,
|
"preview_downloaded": preview_downloaded,
|
||||||
|
"updates": updates,
|
||||||
"errors": [],
|
"errors": [],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -377,7 +377,6 @@ export class BulkContextMenu extends BaseContextMenu {
|
|||||||
|
|
||||||
const { agentManager } = await import('../../managers/AgentManager.js');
|
const { agentManager } = await import('../../managers/AgentManager.js');
|
||||||
|
|
||||||
// Check if LLM is configured
|
|
||||||
const configured = await agentManager.isLlmConfigured();
|
const configured = await agentManager.isLlmConfigured();
|
||||||
if (!configured) {
|
if (!configured) {
|
||||||
showToast('toast.agent.llmNotConfigured', {}, 'warning');
|
showToast('toast.agent.llmNotConfigured', {}, 'warning');
|
||||||
@@ -386,23 +385,39 @@ export class BulkContextMenu extends BaseContextMenu {
|
|||||||
|
|
||||||
const modelPaths = [...state.selectedModels];
|
const modelPaths = [...state.selectedModels];
|
||||||
|
|
||||||
// Connect WebSocket for progress
|
|
||||||
agentManager.connect();
|
agentManager.connect();
|
||||||
|
|
||||||
// Set up one-time completion handler
|
const progressUI = state.loadingManager.showEnhancedProgress(
|
||||||
|
`Enriching metadata for ${modelPaths.length} models...`
|
||||||
|
);
|
||||||
|
|
||||||
|
const onProgress = (data) => {
|
||||||
|
if (data.status === 'processing' && data.current_path && data.updated_data && Object.keys(data.updated_data).length > 0) {
|
||||||
|
if (state.virtualScroller?.updateSingleItem) {
|
||||||
|
state.virtualScroller.updateSingleItem(data.current_path, data.updated_data);
|
||||||
|
}
|
||||||
|
const pct = data.total > 0 ? Math.floor((data.processed / data.total) * 100) : 0;
|
||||||
|
const name = data.current_path.split('/').pop();
|
||||||
|
progressUI.updateProgress(pct, name, `Processing ${data.processed}/${data.total}: ${name}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
agentManager.onProgress(onProgress);
|
||||||
|
|
||||||
const onComplete = (data) => {
|
const onComplete = (data) => {
|
||||||
const idx = agentManager.completeCallbacks.indexOf(onComplete);
|
const pIdx = agentManager.progressCallbacks.indexOf(onProgress);
|
||||||
if (idx >= 0) agentManager.completeCallbacks.splice(idx, 1);
|
if (pIdx >= 0) agentManager.progressCallbacks.splice(pIdx, 1);
|
||||||
|
const cIdx = agentManager.completeCallbacks.indexOf(onComplete);
|
||||||
|
if (cIdx >= 0) agentManager.completeCallbacks.splice(cIdx, 1);
|
||||||
|
|
||||||
if (data.status === 'completed') {
|
if (data.status === 'completed') {
|
||||||
|
progressUI.complete(data.summary || 'Enrich complete');
|
||||||
showToast(
|
showToast(
|
||||||
'toast.agent.enrichComplete',
|
'toast.agent.enrichComplete',
|
||||||
{ summary: data.summary || 'Done' },
|
{ summary: data.summary || 'Done' },
|
||||||
'success'
|
'success'
|
||||||
);
|
);
|
||||||
// Soft reload to reflect updated metadata
|
|
||||||
window.location.reload();
|
|
||||||
} else if (data.status === 'error') {
|
} else if (data.status === 'error') {
|
||||||
|
state.loadingManager.hide();
|
||||||
showToast(
|
showToast(
|
||||||
'toast.agent.enrichFailed',
|
'toast.agent.enrichFailed',
|
||||||
{ error: data.error || 'Unknown error' },
|
{ error: data.error || 'Unknown error' },
|
||||||
@@ -412,15 +427,14 @@ export class BulkContextMenu extends BaseContextMenu {
|
|||||||
};
|
};
|
||||||
agentManager.onComplete(onComplete);
|
agentManager.onComplete(onComplete);
|
||||||
|
|
||||||
showToast(
|
|
||||||
'toast.agent.enrichStarted',
|
|
||||||
{ count: modelPaths.length },
|
|
||||||
'info'
|
|
||||||
);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await agentManager.executeSkill('enrich_hf_metadata', modelPaths);
|
await agentManager.executeSkill('enrich_hf_metadata', modelPaths);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
const pIdx = agentManager.progressCallbacks.indexOf(onProgress);
|
||||||
|
if (pIdx >= 0) agentManager.progressCallbacks.splice(pIdx, 1);
|
||||||
|
const cIdx = agentManager.completeCallbacks.indexOf(onComplete);
|
||||||
|
if (cIdx >= 0) agentManager.completeCallbacks.splice(cIdx, 1);
|
||||||
|
state.loadingManager.hide();
|
||||||
showToast(
|
showToast(
|
||||||
'toast.agent.enrichFailed',
|
'toast.agent.enrichFailed',
|
||||||
{ error: error.message },
|
{ error: error.message },
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { BaseContextMenu } from './BaseContextMenu.js';
|
import { BaseContextMenu } from './BaseContextMenu.js';
|
||||||
import { ModelContextMenuMixin } from './ModelContextMenuMixin.js';
|
import { ModelContextMenuMixin } from './ModelContextMenuMixin.js';
|
||||||
|
import { state } from '../../state/index.js';
|
||||||
import { getModelApiClient, resetAndReload } from '../../api/modelApiFactory.js';
|
import { getModelApiClient, resetAndReload } from '../../api/modelApiFactory.js';
|
||||||
import { copyLoraSyntax, sendLoraToWorkflow, buildLoraSyntax, showToast } from '../../utils/uiHelpers.js';
|
import { copyLoraSyntax, sendLoraToWorkflow, buildLoraSyntax, showToast } from '../../utils/uiHelpers.js';
|
||||||
import { showExcludeModal, showDeleteModal } from '../../utils/modalUtils.js';
|
import { showExcludeModal, showDeleteModal } from '../../utils/modalUtils.js';
|
||||||
@@ -78,39 +79,54 @@ export class LoraContextMenu extends BaseContextMenu {
|
|||||||
async enrichWithAgent(filePath) {
|
async enrichWithAgent(filePath) {
|
||||||
const { agentManager } = await import('../../managers/AgentManager.js');
|
const { agentManager } = await import('../../managers/AgentManager.js');
|
||||||
|
|
||||||
// Check if LLM is configured
|
|
||||||
const configured = await agentManager.isLlmConfigured();
|
const configured = await agentManager.isLlmConfigured();
|
||||||
if (!configured) {
|
if (!configured) {
|
||||||
showToast('toast.agent.llmNotConfigured', {}, 'warning');
|
showToast('toast.agent.llmNotConfigured', {}, 'warning');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Connect WebSocket for progress
|
|
||||||
agentManager.connect();
|
agentManager.connect();
|
||||||
|
|
||||||
// Set up one-time completion handler
|
const progressUI = state.loadingManager.showEnhancedProgress(
|
||||||
|
'Enriching metadata with AI...'
|
||||||
|
);
|
||||||
|
|
||||||
|
const onProgress = (data) => {
|
||||||
|
if (data.status === 'processing' && data.current_path && data.updated_data && Object.keys(data.updated_data).length > 0) {
|
||||||
|
if (state.virtualScroller?.updateSingleItem) {
|
||||||
|
state.virtualScroller.updateSingleItem(data.current_path, data.updated_data);
|
||||||
|
}
|
||||||
|
const pct = data.total > 0 ? Math.floor((data.processed / data.total) * 100) : 0;
|
||||||
|
const name = data.current_path.split('/').pop();
|
||||||
|
progressUI.updateProgress(pct, name, `Processing ${name}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
agentManager.onProgress(onProgress);
|
||||||
|
|
||||||
const onComplete = (data) => {
|
const onComplete = (data) => {
|
||||||
const idx = agentManager.completeCallbacks.indexOf(onComplete);
|
const pIdx = agentManager.progressCallbacks.indexOf(onProgress);
|
||||||
if (idx >= 0) agentManager.completeCallbacks.splice(idx, 1);
|
if (pIdx >= 0) agentManager.progressCallbacks.splice(pIdx, 1);
|
||||||
|
const cIdx = agentManager.completeCallbacks.indexOf(onComplete);
|
||||||
|
if (cIdx >= 0) agentManager.completeCallbacks.splice(cIdx, 1);
|
||||||
|
|
||||||
if (data.status === 'completed') {
|
if (data.status === 'completed') {
|
||||||
|
progressUI.complete(data.summary || 'Enrich complete');
|
||||||
showToast('toast.agent.enrichComplete', { summary: data.summary || 'Done' }, 'success');
|
showToast('toast.agent.enrichComplete', { summary: data.summary || 'Done' }, 'success');
|
||||||
// Soft reload to reflect updated metadata
|
|
||||||
if (typeof resetAndReload === 'function') {
|
|
||||||
resetAndReload();
|
|
||||||
}
|
|
||||||
} else if (data.status === 'error') {
|
} else if (data.status === 'error') {
|
||||||
|
state.loadingManager.hide();
|
||||||
showToast('toast.agent.enrichFailed', { error: data.error || 'Unknown error' }, 'error');
|
showToast('toast.agent.enrichFailed', { error: data.error || 'Unknown error' }, 'error');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
agentManager.onComplete(onComplete);
|
agentManager.onComplete(onComplete);
|
||||||
|
|
||||||
// Show progress toast
|
|
||||||
showToast('toast.agent.enrichStarted', {}, 'info');
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await agentManager.executeSkill('enrich_hf_metadata', [filePath]);
|
await agentManager.executeSkill('enrich_hf_metadata', [filePath]);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
const pIdx = agentManager.progressCallbacks.indexOf(onProgress);
|
||||||
|
if (pIdx >= 0) agentManager.progressCallbacks.splice(pIdx, 1);
|
||||||
|
const cIdx = agentManager.completeCallbacks.indexOf(onComplete);
|
||||||
|
if (cIdx >= 0) agentManager.completeCallbacks.splice(cIdx, 1);
|
||||||
|
state.loadingManager.hide();
|
||||||
showToast('toast.agent.enrichFailed', { error: error.message }, 'error');
|
showToast('toast.agent.enrichFailed', { error: error.message }, 'error');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user