Files
AI-Video/reelforge/capabilities/llm.py
2025-11-07 16:59:11 +08:00

112 lines
3.5 KiB
Python

"""
LLM Capabilities using OpenAI SDK
All LLM providers that follow OpenAI SDK protocol are supported:
- OpenAI (gpt-4o, gpt-4o-mini, gpt-3.5-turbo)
- Alibaba Qwen (qwen-max, qwen-plus, qwen-turbo)
- Anthropic Claude (claude-sonnet-4-5, claude-opus-4, claude-haiku-4)
- DeepSeek (deepseek-chat)
- Moonshot Kimi (moonshot-v1-8k, moonshot-v1-32k, moonshot-v1-128k)
- Ollama (llama3.2, qwen2.5, mistral, codellama) - FREE & LOCAL!
- Any custom provider with OpenAI-compatible API
Convention: Unified llm_call tool for all providers
"""
from openai import AsyncOpenAI
from loguru import logger
from pydantic import Field
from reelforge.core.mcp_server import reelforge_mcp
@reelforge_mcp.tool(
description="Generate text using any OpenAI SDK compatible LLM",
meta={
"reelforge": {
"display_name": "LLM (OpenAI SDK)",
"description": "Unified interface for all OpenAI SDK compatible LLMs",
"is_default": True,
}
},
)
async def llm_call(
prompt: str = Field(description="The prompt to generate from"),
api_key: str = Field(description="API key for the LLM provider"),
base_url: str = Field(description="Base URL for the LLM API"),
model: str = Field(description="Model name to use"),
temperature: float = Field(default=0.7, description="Sampling temperature"),
max_tokens: int = Field(default=2000, description="Maximum tokens to generate"),
) -> str:
"""
Generate text using any OpenAI SDK compatible LLM
This is a unified interface that works with any LLM provider
following the OpenAI SDK protocol.
Example:
# OpenAI
result = await llm_call(
prompt="Explain quantum physics",
api_key="sk-xxx",
base_url="https://api.openai.com/v1",
model="gpt-4o"
)
# Qwen
result = await llm_call(
prompt="解释量子物理",
api_key="sk-xxx",
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
model="qwen-max"
)
# Anthropic Claude
result = await llm_call(
prompt="Explain reasoning step by step",
api_key="sk-ant-xxx",
base_url="https://api.anthropic.com/v1/",
model="claude-sonnet-4-5"
)
# DeepSeek
result = await llm_call(
prompt="Explain AI",
api_key="sk-xxx",
base_url="https://api.deepseek.com",
model="deepseek-chat"
)
# Ollama (Local - FREE & PRIVATE!)
result = await llm_call(
prompt="Write a Python function to sort a list",
api_key="ollama", # Required but unused
base_url="http://localhost:11434/v1",
model="llama3.2"
)
"""
logger.debug(f"LLM call: model={model}, base_url={base_url}")
try:
client = AsyncOpenAI(
api_key=api_key,
base_url=base_url,
)
response = await client.chat.completions.create(
model=model,
messages=[{"role": "user", "content": prompt}],
temperature=temperature,
max_tokens=max_tokens,
)
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={model}, base_url={base_url}): {e}")
raise