> ## Documentation Index
> Fetch the complete documentation index at: https://docs.livepeer.org/llms.txt
> Use this file to discover all available pages before exploring further.

# ComfyStream Changelog

> Release history for ComfyStream, a ComfyUI custom node for running real-time media workflows with AI-powered video and audio processing.

export const CustomCardTitle = ({icon, title, variant = "card", iconSize, style = {}, className = "", ...rest}) => {
  const variants = {
    card: {
      display: 'flex',
      alignItems: 'center',
      gap: "var(--lp-spacing-2)",
      marginBottom: "var(--lp-spacing-3)",
      color: 'var(--lp-color-text-primary)',
      fontSize: '1rem',
      fontWeight: 600
    },
    accordion: {
      display: 'inline-flex',
      alignItems: 'center',
      gap: "var(--lp-spacing-2)"
    },
    tab: {
      display: 'inline-flex',
      alignItems: 'center',
      gap: '0.4rem',
      fontSize: '0.875rem'
    }
  };
  const sizes = {
    card: 20,
    accordion: 18,
    tab: 14
  };
  const size = iconSize || sizes[variant] || 20;
  const baseStyle = variants[variant] || variants.card;
  return variant === 'card' ? <div className={className} style={{
    ...baseStyle,
    ...style
  }} {...rest}>
      {typeof icon === 'string' ? <Icon icon={icon} size={size} color="var(--lp-color-accent)" /> : icon}
      {title}
    </div> : <span className={className} style={{
    ...baseStyle,
    ...style
  }} {...rest}>
      {typeof icon === 'string' ? <Icon icon={icon} size={size} color="var(--lp-color-accent)" /> : icon}
      {title}
    </span>;
};

export const Subtitle = ({style = {}, text, children, variant = 'default', fontSize = '', fontWeight = '', fontStyle = '', marginTop = '', marginBottom = '', color = '', className = '', ...rest}) => {
  const renderInlineCode = (value, keyPrefix) => {
    return value.split(/(`[^`]+`)/g).map((segment, index) => {
      if (segment.startsWith('`') && segment.endsWith('`')) {
        return <code key={`${keyPrefix}-code-${index}`}>{segment.slice(1, -1)}</code>;
      }
      return segment;
    });
  };
  const renderInlineMarkup = (value, keyPrefix = 'subtitle') => {
    if (typeof value !== 'string') {
      return value;
    }
    return value.split(/(\*\*[\s\S]+?\*\*)/g).map((segment, index) => {
      if (segment.startsWith('**') && segment.endsWith('**')) {
        const inner = segment.slice(2, -2);
        return <strong key={`${keyPrefix}-strong-${index}`}>
            {renderInlineCode(inner, `${keyPrefix}-strong-${index}`)}
          </strong>;
      }
      return renderInlineCode(segment, `${keyPrefix}-${index}`);
    });
  };
  const renderContent = (value, keyPrefix) => {
    if (Array.isArray(value)) {
      return value.map((item, index) => renderContent(item, `${keyPrefix}-${index}`));
    }
    return renderInlineMarkup(value, keyPrefix);
  };
  const variants = {
    default: {
      fontSize: '1rem',
      fontStyle: 'italic',
      color: 'var(--lp-color-accent)',
      marginBottom: 0
    },
    changelog: {
      fontSize: '0.8rem',
      fontStyle: 'normal',
      fontWeight: 700,
      color: 'var(--lp-color-text-primary)',
      marginBottom: 0
    }
  };
  const base = variants[variant] || variants.default;
  return <span className={className} style={{
    ...base,
    ...fontSize ? {
      fontSize
    } : {},
    ...fontWeight ? {
      fontWeight
    } : {},
    ...fontStyle ? {
      fontStyle
    } : {},
    ...marginTop ? {
      marginTop
    } : {},
    ...marginBottom ? {
      marginBottom
    } : {},
    ...color ? {
      color
    } : {},
    ...style
  }} {...rest}>
      {renderContent(text, 'text')}
      {renderContent(children, 'children')}
    </span>;
};

export const LazyLoad = ({children, height = "200px", offset = "200px", fadeDuration = 400, className = "", style = {}, ...rest}) => {
  const ref = useRef(null);
  const [visible, setVisible] = useState(false);
  const [ready, setReady] = useState(false);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const observer = new IntersectionObserver(([entry]) => {
      if (entry.isIntersecting) {
        setVisible(true);
        observer.disconnect();
      }
    }, {
      rootMargin: offset
    });
    observer.observe(el);
    return () => observer.disconnect();
  }, []);
  useEffect(() => {
    if (!visible) return;
    const frameId = requestAnimationFrame(() => {
      setReady(true);
    });
    return () => cancelAnimationFrame(frameId);
  }, [visible]);
  const placeholder = <div ref={ref} className={className} style={{
    minHeight: height,
    ...style
  }} {...rest} />;
  if (!visible) return placeholder;
  return <div ref={ref} className={className} style={{
    opacity: ready ? 1 : 0,
    transition: `opacity ${fadeDuration}ms ease-in`,
    ...style
  }} {...rest}>
      {children}
    </div>;
};

export const ScrollBox = ({children, maxHeight = 300, showHint = true, ariaLabel = "Scrollable content", style = {}, className = "", ...rest}) => {
  const contentRef = useRef(null);
  const [isOverflowing, setIsOverflowing] = useState(false);
  useEffect(() => {
    const checkOverflow = () => {
      if (contentRef.current) {
        const maxHeightPx = typeof maxHeight === "number" ? maxHeight : parseInt(maxHeight, 10) || 300;
        setIsOverflowing(contentRef.current.scrollHeight > maxHeightPx);
      }
    };
    checkOverflow();
    window.addEventListener("resize", checkOverflow);
    return () => window.removeEventListener("resize", checkOverflow);
  }, [maxHeight, children]);
  return <div className={className} style={{
    position: "relative",
    ...style
  }} {...rest}>
      <div ref={contentRef} role="region" tabIndex={0} aria-label={ariaLabel} style={{
    maxHeight: typeof maxHeight === "number" ? `${maxHeight}px` : maxHeight,
    overflowY: "auto",
    paddingRight: 4
  }} onScroll={e => {
    const el = e.target;
    const atBottom = el.scrollHeight - el.scrollTop <= el.clientHeight + 10;
    const hint = el.parentNode.querySelector("[data-scroll-hint]");
    if (hint) hint.style.opacity = atBottom ? "0" : "1";
  }}>
        {children}
      </div>
      {showHint && isOverflowing && <div data-scroll-hint style={{
    fontSize: 11,
    color: "var(--lp-color-text-muted)",
    textAlign: "center",
    marginTop: 8,
    transition: "opacity 0.2s"
  }}>
          Scroll for more ↓
        </div>}
    </div>;
};

export const DoubleIconLink = ({label = '', labelColor, href = '#', text = '', iconLeft = 'github', iconLeftColor, iconRight = 'arrow-up-right', iconRightColor = 'var(--lp-color-accent)', className = '', style = {}, ...rest}) => {
  return <span className={className} style={{
    whiteSpace: 'nowrap',
    display: 'inline-flex',
    alignItems: 'center',
    gap: "var(--lp-spacing-1)",
    marginLeft: '0.3rem',
    ...style
  }} {...rest}>
      {text && <span style={{
    marginRight: 8
  }}>{text}</span>}
      <Icon icon={iconLeft} color={iconLeftColor} />
      <a href={href} style={{
    color: {
      labelColor
    }
  }}>
        {label}
      </a>
      <div style={{
    marginRight: '0.3rem'
  }}>
        <Icon icon={iconRight} size={12} color={iconRightColor} />
      </div>
    </span>;
};

export const LinkArrow = ({href, label, description, newline = true, borderColor, className = '', style = {}, ...rest}) => {
  const linkArrowStyle = {
    display: 'inline-flex',
    alignItems: 'center',
    justifyContent: 'center',
    gap: "var(--lp-spacing-1)",
    width: 'fit-content',
    ...borderColor && ({
      borderColor
    })
  };
  return <span className={className} style={style} {...rest}>
      {newline && <br />}
      <span style={linkArrowStyle}>
        <a href={href} target="_blank" rel="noopener noreferrer">
          {label}
        </a>
        <Icon icon="arrow-up-right" size={14} color="var(--lp-color-accent)" />
      </span>
      {description && description}
      {description && <div style={{
    height: "var(--lp-spacing-3)"
  }} />}
    </span>;
};

export const InlineDivider = ({margin = "0.75rem 0", padding = "0", color = "var(--lp-color-border-default)", opacity = 0.4, height = "1px", className = "", style = {}, ...rest}) => <hr role="separator" className={className} style={{
  border: "none",
  margin,
  padding,
  height,
  backgroundColor: color,
  opacity,
  ...style
}} {...rest} />;

export const CustomDivider = ({color = "var(--lp-color-border-default)", middleText = "", spacing = "default", style = {}, className = "", ...rest}) => {
  const spacingPresets = {
    default: {
      margin: "24px 0"
    },
    overlap: {
      margin: "-1rem 0 -1rem 0"
    },
    tight: {
      margin: "0 0 -1rem 0"
    },
    section: {
      margin: "0 0 -2rem 0"
    },
    sectionOverlap: {
      margin: "-1rem 0 -2rem 0"
    },
    deepOverlap: {
      margin: "-1rem 0 -1.5rem 0"
    }
  };
  const spacingStyle = spacingPresets[spacing] || spacingPresets.default;
  return <div role="separator" aria-orientation="horizontal" className={className} style={{
    display: "flex",
    alignItems: "center",
    ...spacingStyle,
    fontSize: style?.fontSize || "16px",
    height: "fit-content",
    ...style
  }} {...rest}>
      <span style={{
    marginRight: "var(--lp-spacing-px-8)",
    opacity: 0.2
  }}>
        <Icon icon="/snippets/assets/logos/Livepeer-Logo-Symbol-Theme.svg" />
      </span>
      <div style={{
    flex: 1,
    height: "1px",
    background: "var(--lp-color-border-default)",
    opacity: 0.4
  }}></div>
      {middleText && <>
          <Icon icon="circle" size={2} />
          <span style={{
    margin: "0 8px",
    fontWeight: "bold",
    color: color,
    opacity: 0.7
  }}>
            {middleText}
          </span>
          <Icon icon="circle" size={2} />
        </>}
      <div style={{
    flex: 1,
    height: "1px",
    background: "var(--lp-color-border-default)",
    opacity: 0.4
  }}></div>
      <span style={{
    marginLeft: "var(--lp-spacing-px-8)",
    opacity: 0.2
  }}>
        <span style={{
    display: "inline-block",
    transform: "scaleX(-1)"
  }}>
          <Icon icon="/snippets/assets/logos/Livepeer-Logo-Symbol-Theme.svg" />
        </span>
      </span>
    </div>;
};

<Tip>
  This page is an automated workflow.
  <Subtitle variant="changelog" style={{fontSize: "0.95rem", marginTop: "0.25rem"}}>Subscribe to this changelog's <LinkArrow label="RSS Feed" href="/v2/resources/changelog/comfystream/rss.xml" newline={false} /></Subtitle>
</Tip>

<CustomDivider style={{margin: "-0.5rem 0 -1.5rem 0"}} />

Track releases for <LinkArrow label="ComfyStream" href="https://github.com/livepeer/comfystream/releases" newline={false} /> on GitHub.

<CustomDivider />

<LazyLoad height="600px">
  <Update label="v0.1.8" tags={["Features", "Fixes"]} rss={{ title: "ComfyStream v0.1.8", description: "This release upgrades the ComfyStream docker runtime to target torch `2.8.0+cu128` and addresses recent security fixes" }} description={<Subtitle variant="changelog">December 2025</Subtitle>}>
    ## v0.1.8

    <CustomCardTitle variant="tab" icon="user-robot" title="_AI Summary_" />

    This release upgrades the ComfyStream docker runtime to target torch `2.8.0+cu128` and addresses recent security fixes

    <InlineDivider margin="1rem 0" />

    <DoubleIconLink label="View release on GitHub" href="https://github.com/livepeer/comfystream/releases/tag/v0.1.8" iconLeft="github" />
  </Update>

  <Update label="v0.1.7" tags={["Features", "Fixes"]} rss={{ title: "ComfyStream v0.1.7", description: "This release provides Livepeer network integration via pytrickle, allowing Orchestrators to deploy and advertise cust..." }} description={<Subtitle variant="changelog">November 2025</Subtitle>}>
    ## v0.1.7

    <CustomCardTitle variant="tab" icon="user-robot" title="_AI Summary_" />

    This release provides Livepeer network integration via [pytrickle](https://github.com/livepeer/pytrickle/), allowing Orchestrators to deploy and advertise custom AI pipeline capabilities using `livepeer/comfyui-base:stable`.

    This release also improves the ComfyStream Pipeline class interface with pause, resume, and stop methods for better control of running prompts.

    TensorRT engines are built the same as for development use, refer to [comfystream docs](https://docs.comfystream.org/technical/get-started/install#run-the-docker-container)

    For more information on the **Bring-Your-Own-Container** (BYOC) initiative, please refer to [go-livepeer docs](https://github.com/livepeer/go-livepeer/blob/master/doc/byoc.md)

    <InlineDivider margin="1rem 0" />

    <DoubleIconLink label="View release on GitHub" href="https://github.com/livepeer/comfystream/releases/tag/v0.1.7" iconLeft="github" />
  </Update>

  <Update label="v0.1.6" tags={["Features", "Fixes", "Performance"]} rss={{ title: "ComfyStream v0.1.6", description: "This release introduces several major features and enhancements, including support for \"pytrickle\" in ComfyStream BYO..." }} description={<Subtitle variant="changelog">October 2025</Subtitle>}>
    ## v0.1.6

    <CustomCardTitle variant="tab" icon="user-robot" title="_AI Summary_" />

    ## Release Notes Summery

    This release introduces several major features and enhancements, including support for "pytrickle" in ComfyStream BYOC workflows, the addition of FasterLivePortrait and updated opencv-cuda support for Python 3.12, and the debut of ComfyUI-Manager with blacklist loading for improved performance. The UI has been refreshed to remove inline elements, and all documentation links have been updated to point to the new docs.comfystream.org. Models now use TAESD safetensors instead of PTH files for better efficiency. Critical bug fixes include updates to the pyproject.toml for ComfyUI registry compatibility, improved Docker image dependencies, added input timeouts to tensor loading nodes, and enhanced logging for input exceptions. Audio transcription workflows now use the correct sample rate, and unnecessary GitHub workflow triggers have been removed. Numerous dependency updates have also been made, such as bumping pytrickle, replacing deprecated pynvml, and upgrading Next.js, setup-node, and brace-expansion. The version is now bumped to 0.1.6, reflecting these improvements and fixes.

    Download the docker images for comfystream from official livepeer [dockerhub](https://hub.docker.com/r/livepeer/comfystream).

    <InlineDivider margin="1rem 0" />

    <DoubleIconLink label="View release on GitHub" href="https://github.com/livepeer/comfystream/releases/tag/v0.1.6" iconLeft="github" />
  </Update>

  <Update label="v0.1.5" tags={["Features", "Fixes"]} rss={{ title: "ComfyStream v0.1.5", description: "This release adds support for audio driven workflows and text outputs. An example real-time text transcription demo w..." }} description={<Subtitle variant="changelog">September 2025</Subtitle>}>
    ## v0.1.5

    <CustomCardTitle variant="tab" icon="user-robot" title="_AI Summary_" />

    This release adds support for audio driven workflows and text outputs. An example real-time text transcription [demo workflow](https://github.com/livepeer/comfystream/blob/main/workflows/comfystream/audio-transcription-api.json) using Whisper has been added.

    The docker ComfyUI workspace has been upgraded to v0.3.56. ComfyStream is updated to support newer versions of ComfyUI

    <InlineDivider margin="1rem 0" />

    <DoubleIconLink label="View release on GitHub" href="https://github.com/livepeer/comfystream/releases/tag/v0.1.5" iconLeft="github" />
  </Update>

  <Update label="v0.1.4" tags={["Features"]} rss={{ title: "ComfyStream v0.1.4", description: "This release adds support for RTX 5090 GPUs using PyTorch `2.7.1+cu128`. The minimum supported NVIDIA CUDA driver ver..." }} description={<Subtitle variant="changelog">August 2025</Subtitle>}>
    ## v0.1.4

    <CustomCardTitle variant="tab" icon="user-robot" title="_AI Summary_" />

    This release adds support for RTX 5090 GPUs using PyTorch `2.7.1+cu128`. The minimum supported NVIDIA CUDA driver version is `570.124.06` with `CUDA 12.8`

    This is a fast-follow release to [v0.1.3](https://github.com/livepeer/comfystream/releases/tag/v0.1.3)

    <InlineDivider margin="1rem 0" />

    <DoubleIconLink label="View release on GitHub" href="https://github.com/livepeer/comfystream/releases/tag/v0.1.4" iconLeft="github" />
  </Update>

  <Update label="v0.1.3" tags={["Features", "Fixes"]} rss={{ title: "ComfyStream v0.1.3", description: "* docs: Adding workflow for FasterLivePortrait by @JJassonn69 in https://github.com/livepeer/comfystream/pull/286" }} description={<Subtitle variant="changelog">July 2025</Subtitle>}>
    ## v0.1.3

    <CustomCardTitle variant="tab" icon="user-robot" title="_AI Summary_" />

    ## What's Changed

    * docs: Adding workflow for FasterLivePortrait
    * fix: pin numpy\<2.0
    * fix devcontainer stuck loading in post-script
    * fix: bind to correct host in server manager
    * fix conda env install
    * improve volume mount for persistent storage
    * feat: add `--api` and `--ui` flags to entrypoint.sh
    * fix: hostname arg for ui entrypoint flag
    * refactor: update base image to CUDA 12.8 and TensorRT 10.12
    * release: 0.1.3 bump comfystream ver

    <InlineDivider margin="1rem 0" />

    <DoubleIconLink label="View release on GitHub" href="https://github.com/livepeer/comfystream/releases/tag/v0.1.3" iconLeft="github" />
  </Update>

  <Update label="v0.1.2" tags={["Features", "Fixes"]} rss={{ title: "ComfyStream v0.1.2", description: "This releases adds a token-gated external MPEG stream egress endpoint to ComfySteam. A demo page is available to view..." }} description={<Subtitle variant="changelog">June 2025</Subtitle>}>
    ## v0.1.2

    <CustomCardTitle variant="tab" icon="user-robot" title="_AI Summary_" />

    This releases adds a token-gated external MPEG stream egress endpoint to ComfySteam. A demo page is available to view the MPEG stream, which can also be used as an OBS Video Source to capture output for live streaming. Additionally a bug fix was made to `comfystream.client.update_prompts` and python packages have been pinned to improve stability.

    <InlineDivider margin="1rem 0" />

    <DoubleIconLink label="View release on GitHub" href="https://github.com/livepeer/comfystream/releases/tag/v0.1.2" iconLeft="github" />
  </Update>

  <Update label="v0.1.1" tags={["Release"]} rss={{ title: "ComfyStream v0.1.1", description: "* qualify volume mount copy with --server flag by @eliteprox in https://github.com/livepeer/comfystream/pull/152" }} description={<Subtitle variant="changelog">June 2025</Subtitle>}>
    ## v0.1.1

    <CustomCardTitle variant="tab" icon="user-robot" title="_AI Summary_" />

    ## What's Changed

    * qualify volume mount copy with --server flag
    * \[COMFY-77] workflows: Remove separate build workflows for base and final images
    * refactor(dev): remove deprecated Tensordock spinup script
    * \[COMFY-77] Update docker.yaml
    * \[COMFY-80] docker.yaml: Trigger workflow in ai-runner after comfyui-base is built

    <InlineDivider margin="1rem 0" />

    <DoubleIconLink label="View release on GitHub" href="https://github.com/livepeer/comfystream/releases/tag/v0.1.1" iconLeft="github" />
  </Update>

  <Update label="v0.1.0" tags={["Features", "Fixes"]} rss={{ title: "ComfyStream v0.1.0", description: "ComfyStream v0.1.0 includes multi-resolution support, an improved depth map and an exportable pipeline class for easi..." }} description={<Subtitle variant="changelog">April 2025</Subtitle>}>
    ## v0.1.0

    <CustomCardTitle variant="tab" icon="user-robot" title="_AI Summary_" />

    ComfyStream v0.1.0 includes multi-resolution support, an improved depth map and an exportable pipeline class for easier integration. This release is available as a docker image at `livepeer/comfyui-base:v0.1.0` and `livepeer/comfystream:v0.1.0`

    New Features / Nodes

    * Super Resolution node with OpenCV
    * Multi-resolution support with tensorrt engine compilation examples (default engine supports ranges of height/width from 448px to 744px)
    * Exports the [comfystream.pipeline](https://github.com/livepeer/comfystream/blob/f0f7d7e349fca2565ba198127afdb96b5fcd8e79/src/comfystream/pipeline.py) class from `Pipeline.py` to make it easier to integrate ComfyStream into your own application through the python package namespace

    New Models

    * Depth Anything V2 large model with tensorrt compilation

    **NOTE**: Due to a version dependency, ComfyStream must be run with ComfyUI version 0.3.27 or older [https://github.com/comfyanonymous/ComfyUI/releases/tag/v0.3.27](https://github.com/comfyanonymous/ComfyUI/releases/tag/v0.3.27)

    <InlineDivider margin="1rem 0" />

    <DoubleIconLink label="View release on GitHub" href="https://github.com/livepeer/comfystream/releases/tag/v0.1.0" iconLeft="github" />
  </Update>
</LazyLoad>
