Compare commits

...

2 Commits

Author SHA1 Message Date
Kelly Yang
5f1aab5d1b fix: route text preview_output outside media parsing pipeline
Text preview_output items (mediaType: 'text') carry a content field
instead of filename and are structurally incompatible with ResultItem.
Exclude them from synthetic effectiveOutputs and construct their
ResultItemImpl directly in calculateFlatOutputs, bypassing
parseNodeOutput and isResultItem entirely.

Also tighten isResultItem to require filename as a string, correctly
rejecting arbitrary non-media objects from custom node outputs.
2026-04-15 15:03:40 -07:00
Kelly Yang
8bf00e1a5c fix: resolve post-migration TODO comments and skipped test
Remove stale TODO comments from 3 litegraph test files whose tests were
already passing after the migration.

Fix the skipped 'should parse text outputs' test in queueStore by
correcting two bugs in resultItemParsing.ts:
- Remove 'text' from METADATA_KEYS: text media-type outputs were being
  silently discarded; isResultItem already filters non-object values
- Remove the filename requirement from isResultItem: filename is
  optional in the zResultItem schema, and text outputs carry content
  instead of filename

Fixes #11078
2026-04-15 13:20:44 -07:00
6 changed files with 10 additions and 22 deletions

View File

@@ -1,5 +1,4 @@
// oxlint-disable no-empty-pattern
// TODO: Fix these tests after migration
import { afterEach, describe, expect, vi } from 'vitest'
import type {

View File

@@ -1,4 +1,3 @@
// TODO: Fix these tests after migration
import { beforeEach, describe, expect, it, vi } from 'vitest'
import {

View File

@@ -1,4 +1,3 @@
// TODO: Fix these tests after migration
import { test as baseTest } from 'vitest'
import type { Point, Rect } from '@/lib/litegraph/src/interfaces'

View File

@@ -189,7 +189,7 @@ describe('TaskItemImpl', () => {
})
})
it.skip('should parse text outputs', () => {
it('should parse text outputs', () => {
const job: JobListItem = {
...createHistoryJob(0, 'text-job'),
preview_output: {

View File

@@ -256,26 +256,23 @@ export class TaskItemImpl {
flatOutputs?: ReadonlyArray<ResultItemImpl>
) {
this.job = job
// If no outputs provided but job has preview_output, create synthetic outputs
// using the real nodeId and mediaType from the backend response
const preview = job.preview_output
const effectiveOutputs =
outputs ??
(job.preview_output
? {
[job.preview_output.nodeId]: {
[job.preview_output.mediaType]: [job.preview_output]
}
}
(preview && preview.mediaType !== 'text'
? { [preview.nodeId]: { [preview.mediaType]: [preview] } }
: {})
this.outputs = effectiveOutputs
this.flatOutputs = flatOutputs ?? this.calculateFlatOutputs()
}
calculateFlatOutputs(): ReadonlyArray<ResultItemImpl> {
if (!this.outputs) {
return []
const mediaOutputs = parseTaskOutput(this.outputs)
const preview = this.job.preview_output
if (preview?.mediaType === 'text') {
return [new ResultItemImpl(preview as ResultItemInit), ...mediaOutputs]
}
return parseTaskOutput(this.outputs)
return mediaOutputs
}
/** All outputs that support preview (images, videos, audio, 3D, text) */

View File

@@ -2,14 +2,8 @@ import type { NodeExecutionOutput, ResultItem } from '@/schemas/apiSchema'
import { resultItemType } from '@/schemas/apiSchema'
import { ResultItemImpl } from '@/stores/queueStore'
const METADATA_KEYS = new Set(['animated', 'text'])
const METADATA_KEYS = new Set(['animated'])
/**
* Validates that an unknown value is a well-formed ResultItem.
*
* Requires `filename` (string) since ResultItemImpl needs it for a valid URL.
* `subfolder` is optional here — ResultItemImpl constructor falls back to ''.
*/
function isResultItem(item: unknown): item is ResultItem {
if (!item || typeof item !== 'object' || Array.isArray(item)) return false