Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions pixelle_video/config/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,15 +112,17 @@ def get_llm_config(self) -> dict:
"api_key": self.config.llm.api_key,
"base_url": self.config.llm.base_url,
"model": self.config.llm.model,
"stream": self.config.llm.stream,
}
def set_llm_config(self, api_key: str, base_url: str, model: str):

def set_llm_config(self, api_key: str, base_url: str, model: str, stream: bool = False):
"""Set LLM configuration"""
self.update({
"llm": {
"api_key": api_key,
"base_url": base_url,
"model": model,
"stream": stream,
}
})

Expand Down
1 change: 1 addition & 0 deletions pixelle_video/config/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class LLMConfig(BaseModel):
api_key: str = Field(default="", description="LLM API Key")
base_url: str = Field(default="", description="LLM API Base URL")
model: str = Field(default="", description="LLM Model Name")
stream: bool = Field(default=False, description="Enable streaming mode for LLM API")


class TTSLocalConfig(BaseModel):
Expand Down
112 changes: 91 additions & 21 deletions pixelle_video/services/llm_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,24 +184,80 @@ class MovieReview(BaseModel):
**kwargs
)
else:
# Standard text output mode
response = await client.chat.completions.create(
model=final_model,
messages=[{"role": "user", "content": prompt}],
temperature=temperature,
max_tokens=max_tokens,
**kwargs
)

result = response.choices[0].message.content
# Check if streaming mode is enabled
use_stream = self._get_config_value("stream", False)

if use_stream:
# Streaming mode - collect chunks
result = await self._call_with_stream(
client=client,
model=final_model,
prompt=prompt,
temperature=temperature,
max_tokens=max_tokens,
**kwargs
)
else:
# Standard text output mode
response = await client.chat.completions.create(
model=final_model,
messages=[{"role": "user", "content": prompt}],
temperature=temperature,
max_tokens=max_tokens,
**kwargs
)

result = response.choices[0].message.content

logger.debug(f"LLM response length: {len(result)} chars")

return result

except Exception as e:
logger.error(f"LLM call error (model={final_model}, base_url={client.base_url}): {e}")
raise

async def _call_with_stream(
self,
client: AsyncOpenAI,
model: str,
prompt: str,
temperature: float,
max_tokens: int,
**kwargs
) -> str:
"""
Call LLM with streaming mode enabled

Collects all chunks and returns the complete response.

Args:
client: OpenAI client
model: Model name
prompt: The prompt
temperature: Sampling temperature
max_tokens: Max tokens
**kwargs: Additional parameters

Returns:
Complete response text
"""
chunks = []
async for chunk in await client.chat.completions.create(
model=model,
messages=[{"role": "user", "content": prompt}],
temperature=temperature,
max_tokens=max_tokens,
stream=True,
**kwargs
):
if chunk.choices and len(chunk.choices) > 0:
delta = chunk.choices[0].delta
if delta and delta.content:
chunks.append(delta.content)

return "".join(chunks)

async def _call_with_structured_output(
self,
client: AsyncOpenAI,
Expand Down Expand Up @@ -233,16 +289,30 @@ async def _call_with_structured_output(
# Build JSON schema instruction and append to prompt
json_schema_instruction = self._get_json_schema_instruction(response_type)
enhanced_prompt = f"{prompt}\n\n{json_schema_instruction}"

# Call LLM with enhanced prompt
response = await client.chat.completions.create(
model=model,
messages=[{"role": "user", "content": enhanced_prompt}],
temperature=temperature,
max_tokens=max_tokens,
**kwargs
)
content = response.choices[0].message.content

# Check if streaming mode is enabled
use_stream = self._get_config_value("stream", False)

if use_stream:
# Streaming mode
content = await self._call_with_stream(
client=client,
model=model,
prompt=enhanced_prompt,
temperature=temperature,
max_tokens=max_tokens,
**kwargs
)
else:
# Call LLM with enhanced prompt
response = await client.chat.completions.create(
model=model,
messages=[{"role": "user", "content": enhanced_prompt}],
temperature=temperature,
max_tokens=max_tokens,
**kwargs
)
content = response.choices[0].message.content

logger.debug(f"Structured output response length: {len(content)} chars")

Expand Down
11 changes: 10 additions & 1 deletion web/components/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,15 @@ def render_advanced_settings():
)
else:
llm_model = selected_model_option

# Stream mode toggle
llm_config = config_manager.get_llm_config()
llm_stream = st.checkbox(
"启用流式输出 (Stream Mode)",
value=llm_config.get("stream", False),
help="某些 API 服务只支持流式返回,勾选此项可兼容这类服务",
key="llm_stream_toggle"
)

# ====================================================================
# Column 2: ComfyUI Settings
Expand Down Expand Up @@ -303,7 +312,7 @@ def render_advanced_settings():
if not (llm_api_key and llm_base_url and llm_model):
st.error(tr("status.llm_config_incomplete"))
else:
config_manager.set_llm_config(llm_api_key, llm_base_url, llm_model)
config_manager.set_llm_config(llm_api_key, llm_base_url, llm_model, llm_stream)

# Save ComfyUI configuration (optional fields, always save what's provided)
# Convert checkbox to instance type: True -> "plus", False -> ""
Expand Down