fix: Restore correct interfaces from PR #3367

- Restore original useManagerQueue, useServerLogs, and comfyManagerService interfaces
- Restore original component implementations for ManagerProgressDialogContent and ManagerProgressHeader
- Fix all TypeScript interface compatibility issues by using original PR implementations
- Remove duplicate setting that was causing runtime errors

This fixes merge errors where interfaces were incorrectly mixed between old and new implementations.
This commit is contained in:
bymyself
2025-08-30 21:43:20 -07:00
parent 380f335bff
commit b5bf6fd6e5
10 changed files with 223 additions and 841 deletions

View File

@@ -18,7 +18,7 @@
'max-h-0': !isExpanded
}"
>
<div v-for="(log, index) in focusedLogs" :key="index">
<div v-for="(panel, index) in taskPanels" :key="index">
<Panel
:expanded="collapsedPanels[index] || false"
toggleable
@@ -27,7 +27,7 @@
<template #header>
<div class="flex items-center justify-between w-full py-2">
<div class="flex flex-col text-sm font-medium leading-normal">
<span>{{ log.taskName }}</span>
<span>{{ panel.taskName }}</span>
<span class="text-muted">
{{
isInProgress(index)
@@ -52,24 +52,24 @@
</template>
<div
:ref="
index === focusedLogs.length - 1
index === taskPanels.length - 1
? (el) => (lastPanelRef = el as HTMLElement)
: undefined
"
class="overflow-y-auto h-64 rounded-lg bg-black"
:class="{
'h-64': index !== focusedLogs.length - 1,
'flex-grow': index === focusedLogs.length - 1
'h-64': index !== taskPanels.length - 1,
'flex-grow': index === taskPanels.length - 1
}"
@scroll="handleScroll"
>
<div class="h-full">
<div
v-for="(logLine, logIndex) in log.logs"
v-for="(log, logIndex) in panel.logs"
:key="logIndex"
class="text-neutral-400 dark-theme:text-muted"
>
<pre class="whitespace-pre-wrap break-words">{{ logLine }}</pre>
<pre class="whitespace-pre-wrap break-words">{{ log }}</pre>
</div>
</div>
</div>
@@ -90,23 +90,17 @@ import {
useManagerProgressDialogStore
} from '@/stores/comfyManagerStore'
const comfyManagerStore = useComfyManagerStore()
const { taskLogs } = useComfyManagerStore()
const progressDialogContent = useManagerProgressDialogStore()
const managerStore = useComfyManagerStore()
const isInProgress = (index: number) =>
index === comfyManagerStore.managerQueue.historyCount - 1 &&
comfyManagerStore.isLoading
index === taskPanels.value.length - 1 && managerStore.uncompletedCount > 0
const taskPanels = computed(() => taskLogs)
const isExpanded = computed(() => progressDialogContent.isExpanded)
const isCollapsed = computed(() => !isExpanded.value)
const focusedLogs = computed(() => {
if (progressDialogContent.getActiveTabIndex() === 0) {
return comfyManagerStore.succeededTasksLogs
}
return comfyManagerStore.failedTasksLogs
})
const collapsedPanels = ref<Record<number, boolean>>({})
const togglePanel = (index: number) => {
collapsedPanels.value[index] = !collapsedPanels.value[index]
@@ -121,7 +115,7 @@ const { y: scrollY } = useScroll(sectionsContainerRef, {
const lastPanelRef = ref<HTMLElement | null>(null)
const isUserScrolling = ref(false)
const lastPanelLogs = computed(() => focusedLogs.value?.at(-1)?.logs)
const lastPanelLogs = computed(() => taskPanels.value?.at(-1)?.logs)
const isAtBottom = (el: HTMLElement | null) => {
if (!el) return false

View File

@@ -18,40 +18,16 @@
<script setup lang="ts">
import TabMenu from 'primevue/tabmenu'
import { computed } from 'vue'
import { ref } from 'vue'
import { useI18n } from 'vue-i18n'
import {
useComfyManagerStore,
useManagerProgressDialogStore
} from '@/stores/comfyManagerStore'
import { useManagerProgressDialogStore } from '@/stores/comfyManagerStore'
const progressDialogContent = useManagerProgressDialogStore()
const comfyManagerStore = useComfyManagerStore()
const activeTabIndex = computed({
get: () => progressDialogContent.getActiveTabIndex(),
set: (value: number) => progressDialogContent.setActiveTabIndex(value)
})
const activeTabIndex = ref(0)
const { t } = useI18n()
const failedCount = computed(() => comfyManagerStore.failedTasksIds.length)
const queueSuffix = computed(() => {
const queueLength = comfyManagerStore.managerQueue.queueLength
if (queueLength === 0) {
return ''
}
return ` (${queueLength})`
})
const failedSuffix = computed(() => {
if (failedCount.value === 0) {
return ''
}
return ` (${failedCount.value})`
})
const tabs = computed(() => [
{ label: t('manager.installationQueue') + queueSuffix.value },
{ label: t('manager.failed') + failedSuffix.value }
])
const tabs = [
{ label: t('manager.installationQueue') },
{ label: t('manager.failed', { count: 0 }) }
]
</script>

View File

@@ -1,34 +1,24 @@
import { useEventListener } from '@vueuse/core'
import { ref } from 'vue'
import { onUnmounted, ref } from 'vue'
import { LogsWsMessage } from '@/schemas/apiSchema'
import { api } from '@/scripts/api'
import { components } from '@/types/generatedManagerTypes'
const LOGS_MESSAGE_TYPE = 'logs'
const MANAGER_WS_TASK_DONE_NAME = 'cm-task-completed'
const MANAGER_WS_TASK_STARTED_NAME = 'cm-task-started'
type ManagerWsTaskDoneMsg = components['schemas']['MessageTaskDone']
type ManagerWsTaskStartedMsg = components['schemas']['MessageTaskStarted']
interface UseServerLogsOptions {
ui_id: string
immediate?: boolean
messageFilter?: (message: string) => boolean
}
export const useServerLogs = (options: UseServerLogsOptions) => {
export const useServerLogs = (options: UseServerLogsOptions = {}) => {
const {
immediate = false,
messageFilter = (msg: string) => Boolean(msg.trim())
} = options
const logs = ref<string[]>([])
const isTaskStarted = ref(false)
let stopLogs: ReturnType<typeof useEventListener> | null = null
let stopTaskDone: ReturnType<typeof useEventListener> | null = null
let stopTaskStarted: ReturnType<typeof useEventListener> | null = null
let stop: ReturnType<typeof useEventListener> | null = null
const isValidLogEvent = (event: CustomEvent<LogsWsMessage>) =>
event?.type === LOGS_MESSAGE_TYPE && event.detail?.entries?.length > 0
@@ -37,81 +27,34 @@ export const useServerLogs = (options: UseServerLogsOptions) => {
event.detail.entries.map((e) => e.m).filter(messageFilter)
const handleLogMessage = (event: CustomEvent<LogsWsMessage>) => {
// Only capture logs if this task has started
if (!isTaskStarted.value) return
if (isValidLogEvent(event)) {
const messages = parseLogMessage(event)
if (messages.length > 0) {
logs.value.push(...messages)
}
logs.value.push(...parseLogMessage(event))
}
}
const handleTaskStarted = (event: CustomEvent<ManagerWsTaskStartedMsg>) => {
if (event?.type === MANAGER_WS_TASK_STARTED_NAME) {
// Check if this is our task starting
const isOurTask = event.detail.ui_id === options.ui_id
if (isOurTask) {
isTaskStarted.value = true
void stopTaskStarted?.()
}
}
}
const handleTaskDone = (event: CustomEvent<ManagerWsTaskDoneMsg>) => {
if (event?.type === MANAGER_WS_TASK_DONE_NAME) {
const { state } = event.detail
// Check if our task is now in the history (completed)
const isOurTaskDone = state.history[options.ui_id]
if (isOurTaskDone) {
isTaskStarted.value = false
void stopListening()
}
}
}
const startListening = async () => {
const start = async () => {
await api.subscribeLogs(true)
stopLogs = useEventListener(api, LOGS_MESSAGE_TYPE, handleLogMessage)
stopTaskStarted = useEventListener(
api,
MANAGER_WS_TASK_STARTED_NAME,
handleTaskStarted
)
stopTaskDone = useEventListener(
api,
MANAGER_WS_TASK_DONE_NAME,
handleTaskDone
)
stop = useEventListener(api, LOGS_MESSAGE_TYPE, handleLogMessage)
}
const stopListening = async () => {
stopLogs?.()
stopTaskStarted?.()
stopTaskDone?.()
stopLogs = null
stopTaskStarted = null
stopTaskDone = null
// TODO: move subscribe/unsubscribe logs to useManagerQueue. Subscribe when task starts if not already subscribed.
// Unsubscribe ONLY when there are no tasks running or queued up and the only remaining task finishes.
// await api.subscribeLogs(false)
stop?.()
stop = null
await api.subscribeLogs(false)
}
if (immediate) {
void startListening()
void start()
}
const cleanup = async () => {
onUnmounted(async () => {
await stopListening()
logs.value = []
isTaskStarted.value = false
}
})
return {
logs,
startListening,
stopListening,
cleanup
startListening: start,
stopListening
}
}

View File

@@ -935,12 +935,5 @@ export const CORE_SETTINGS: SettingParams[] = [
name: 'Release seen timestamp',
type: 'hidden',
defaultValue: 0
},
{
id: 'Comfy.Memory.AllowManualUnload',
name: 'Allow manual unload of models and execution cache via user command',
type: 'hidden',
defaultValue: true,
versionAdded: '1.18.0'
}
]

View File

@@ -1,18 +1,17 @@
import axios, { AxiosError, AxiosResponse } from 'axios'
import { v4 as uuidv4 } from 'uuid'
import { ref } from 'vue'
import { api } from '@/scripts/api'
import { components } from '@/types/generatedManagerTypes'
import {
type InstallPackParams,
type InstalledPacksResponse,
type ManagerPackInfo,
type ManagerQueueStatus,
SelectedVersion,
type UpdateAllPacksParams
} from '@/types/comfyManagerTypes'
import { isAbortError } from '@/utils/typeGuardUtil'
type ManagerQueueStatus = components['schemas']['QueueStatus']
type InstallPackParams = components['schemas']['InstallPackParams']
type InstalledPacksResponse = components['schemas']['InstalledPacksResponse']
type UpdateAllPacksParams = components['schemas']['UpdateAllPacksParams']
type ManagerTaskHistory = components['schemas']['HistoryResponse']
type QueueTaskItem = components['schemas']['QueueTaskItem']
const GENERIC_SECURITY_ERR_MSG =
'Forbidden: A security error has occurred. Please check the terminal logs'
@@ -33,9 +32,7 @@ enum ManagerRoute {
LIST_INSTALLED = 'customnode/installed',
IMPORT_FAIL_INFO = 'customnode/import_fail_info',
REBOOT = 'manager/reboot',
IS_LEGACY_MANAGER_UI = 'manager/is_legacy_manager_ui',
TASK_HISTORY = 'manager/queue/history',
QUEUE_TASK = 'manager/queue/task'
IS_LEGACY_MANAGER_UI = 'manager/is_legacy_manager_ui'
}
const managerApiClient = axios.create({
@@ -52,6 +49,7 @@ const managerApiClient = axios.create({
export const useComfyManagerService = () => {
const isLoading = ref(false)
const error = ref<string | null>(null)
const didStartQueue = ref(false)
const handleRequestError = (
err: unknown,
@@ -112,21 +110,19 @@ export const useComfyManagerService = () => {
201: 'Created: ComfyUI-Manager job queue is already running'
}
didStartQueue.value = true
return executeRequest<null>(
() => managerApiClient.get(ManagerRoute.START_QUEUE, { signal }),
{ errorContext, routeSpecificErrors }
)
}
const getQueueStatus = async (client_id?: string, signal?: AbortSignal) => {
const getQueueStatus = async (signal?: AbortSignal) => {
const errorContext = 'Getting ComfyUI-Manager queue status'
return executeRequest<ManagerQueueStatus>(
() =>
managerApiClient.get(ManagerRoute.QUEUE_STATUS, {
params: client_id ? { client_id } : undefined,
signal
}),
() => managerApiClient.get(ManagerRoute.QUEUE_STATUS, { signal }),
{ errorContext }
)
}
@@ -158,66 +154,73 @@ export const useComfyManagerService = () => {
)
}
const queueTask = async (
kind: QueueTaskItem['kind'],
params: QueueTaskItem['params'],
ui_id?: string,
const installPack = async (
params: InstallPackParams,
signal?: AbortSignal
) => {
const task: QueueTaskItem = {
kind,
params,
ui_id: ui_id || uuidv4(),
client_id: api.clientId ?? api.initialClientId ?? 'unknown'
}
const errorContext = `Queueing ${task.kind} task`
const errorContext = `Installing pack ${params.id}`
const routeSpecificErrors = {
403: GENERIC_SECURITY_ERR_MSG,
404: `Not Found: Task could not be queued`
404:
params.selected_version === SelectedVersion.NIGHTLY
? `Not Found: Node pack ${params.id} does not provide nightly version`
: GENERIC_SECURITY_ERR_MSG
}
return executeRequest<null>(
() => managerApiClient.post(ManagerRoute.QUEUE_TASK, task, { signal }),
() => managerApiClient.post(ManagerRoute.INSTALL, params, { signal }),
{ errorContext, routeSpecificErrors, isQueueOperation: true }
)
}
const installPack = async (
params: InstallPackParams,
ui_id?: string,
signal?: AbortSignal
) => {
return queueTask('install', params, ui_id, signal)
}
const uninstallPack = async (
params: components['schemas']['UninstallPackParams'],
ui_id?: string,
params: ManagerPackInfo,
signal?: AbortSignal
) => {
return queueTask('uninstall', params, ui_id, signal)
const errorContext = `Uninstalling pack ${params.id}`
const routeSpecificErrors = {
403: GENERIC_SECURITY_ERR_MSG
}
return executeRequest<null>(
() => managerApiClient.post(ManagerRoute.UNINSTALL, params, { signal }),
{ errorContext, routeSpecificErrors, isQueueOperation: true }
)
}
const disablePack = async (
params: components['schemas']['DisablePackParams'],
ui_id?: string,
params: ManagerPackInfo,
signal?: AbortSignal
): Promise<null> => {
return queueTask('disable', params, ui_id, signal)
const errorContext = `Disabling pack ${params.id}`
const routeSpecificErrors = {
404: `Pack ${params.id} not found or not installed`,
409: `Pack ${params.id} is already disabled`
}
return executeRequest<null>(
() => managerApiClient.post(ManagerRoute.DISABLE, params, { signal }),
{ errorContext, routeSpecificErrors, isQueueOperation: true }
)
}
const updatePack = async (
params: components['schemas']['UpdatePackParams'],
ui_id?: string,
params: ManagerPackInfo,
signal?: AbortSignal
): Promise<null> => {
return queueTask('update', params, ui_id, signal)
const errorContext = `Updating pack ${params.id}`
const routeSpecificErrors = {
403: GENERIC_SECURITY_ERR_MSG
}
return executeRequest<null>(
() => managerApiClient.post(ManagerRoute.UPDATE, params, { signal }),
{ errorContext, routeSpecificErrors, isQueueOperation: true }
)
}
const updateAllPacks = async (
params: UpdateAllPacksParams = {},
ui_id?: string,
params?: UpdateAllPacksParams,
signal?: AbortSignal
) => {
const errorContext = 'Updating all packs'
@@ -226,18 +229,8 @@ export const useComfyManagerService = () => {
401: 'Unauthorized: ComfyUI-Manager job queue is busy'
}
const queryParams = {
mode: params.mode,
client_id: api.clientId ?? api.initialClientId ?? 'unknown',
ui_id: ui_id || uuidv4()
}
return executeRequest<null>(
() =>
managerApiClient.get(ManagerRoute.UPDATE_ALL, {
params: queryParams,
signal
}),
() => managerApiClient.get(ManagerRoute.UPDATE_ALL, { params, signal }),
{ errorContext, routeSpecificErrors, isQueueOperation: true }
)
}
@@ -263,27 +256,6 @@ export const useComfyManagerService = () => {
)
}
const getTaskHistory = async (
options: {
ui_id?: string
max_items?: number
client_id?: string
offset?: number
} = {},
signal?: AbortSignal
) => {
const errorContext = 'Getting ComfyUI-Manager task history'
return executeRequest<ManagerTaskHistory>(
() =>
managerApiClient.get(ManagerRoute.TASK_HISTORY, {
params: options,
signal
}),
{ errorContext }
)
}
return {
// State
isLoading,
@@ -293,7 +265,6 @@ export const useComfyManagerService = () => {
startQueue,
resetQueue,
getQueueStatus,
getTaskHistory,
// Pack management
listInstalledPacks,

View File

@@ -1,6 +1,6 @@
import { whenever } from '@vueuse/core'
import { defineStore } from 'pinia'
import { computed, ref, watch } from 'vue'
import { ref, watch } from 'vue'
import { useI18n } from 'vue-i18n'
import { useCachedRequest } from '@/composables/useCachedRequest'
@@ -33,9 +33,8 @@ export const useComfyManagerStore = defineStore('comfyManager', () => {
const isStale = ref(true)
const taskLogs = ref<TaskLog[]>([])
const managerQueue = useManagerQueue()
const { statusMessage, allTasksDone, enqueueTask, uncompletedCount } =
managerQueue
useManagerQueue()
const setStale = () => {
isStale.value = true
@@ -213,11 +212,6 @@ export const useComfyManagerStore = defineStore('comfyManager', () => {
taskLogs.value = []
}
// Computed properties for UI components
const succeededTasksLogs = computed(() => taskLogs.value)
const failedTasksLogs = computed(() => [])
const failedTasksIds = computed(() => [])
return {
// Manager state
isLoading: managerService.isLoading,
@@ -244,15 +238,7 @@ export const useComfyManagerStore = defineStore('comfyManager', () => {
updatePack,
updateAllPacks,
disablePack,
enablePack: installPack, // Enable is done via install endpoint with a disabled pack
// Manager queue
managerQueue,
// UI properties for progress dialog
succeededTasksLogs,
failedTasksLogs,
failedTasksIds
enablePack: installPack // Enable is done via install endpoint with a disabled pack
}
})
@@ -265,7 +251,6 @@ export const useManagerProgressDialogStore = defineStore(
'managerProgressDialog',
() => {
const isExpanded = ref(false)
const activeTabIndex = ref(0)
const toggle = () => {
isExpanded.value = !isExpanded.value
@@ -278,19 +263,11 @@ export const useManagerProgressDialogStore = defineStore(
const expand = () => {
isExpanded.value = true
}
const getActiveTabIndex = () => activeTabIndex.value
const setActiveTabIndex = (index: number) => {
activeTabIndex.value = index
}
return {
isExpanded,
toggle,
collapse,
expand,
getActiveTabIndex,
setActiveTabIndex
expand
}
}
)