feat(core): AI 生成 Agent 化 — 多模型流式脚本 agent + 可插拔 Provider + gpt-image-2 参考图 + 模特库
- 后端·可插拔 Provider 层:通用 OpenAICompatibleProvider(tokenssr 等中转站,base_url+api_key,零改代码换站)+ ModelProvider.api_key - 后端·脚本 agent:结构化 ScriptDraft 契约 + 加载电商 skill + 出稿/改稿一体对话 agent(3模式/多模型)+ 流式 SSE 端点(DRF SSE renderer) - 后端·图像:gpt-image-2 参考图出图 + 故事板 @图1@图2@图3 多锚点合成(锁脸锁商品);Seedance 打开 generate_audio - 后端·模特库:gpt-image-2 生成器(9:16氛围图→16:9白底三视图)+ seed_demo_models 管理命令 - DB·迁移:tokenssr 中转站 + 多模型 seed(豆包/GPT-5.5/Gemini + gpt-image-2);ScriptSegment 结构化字段 - 前端·脚本趴:接真 SSE(工具卡 + 思考流)+ 模型下拉 + 3模式 + 改稿;agentScriptStream - skills/ecommerce-video-script 电商脚本技能(运行时依赖) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
a0ffb6fc8e
commit
6464001f84
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.1.15 on 2026-06-16 17:50
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('ai', '0004_seed_tts_model'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='modelprovider',
|
||||
name='api_key',
|
||||
field=models.CharField(blank=True, max_length=255),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,82 @@
|
||||
"""Seed tokenssr 中转站 provider + 多模型(文本 GPT-5.5 / Gemini-3-Pro,图像 gpt-image-2 支持参考图)。
|
||||
|
||||
可插拔:tokenssr provider 的 base_url 存 DB(换站改这里),api_key 留空 → 运行时回退 settings.PROVIDER_KEYS(.env)。
|
||||
图像主力切到 tokenssr:gpt-image-2(images/edits 多图参考),停用只能纯文生图的 yunqi:gpt-image-2。
|
||||
幂等:全部 get_or_create / update_or_create,可重复 apply。
|
||||
"""
|
||||
from django.db import migrations
|
||||
|
||||
TOKENSSR_BASE_URL = "https://king.tokenssr.com/v1"
|
||||
|
||||
TEXT_MODELS = [
|
||||
# name, display_name, metadata
|
||||
("gpt-5.5", "GPT-5.5", {"family": "gpt", "recommended": True}),
|
||||
("gemini-3-pro-preview", "Gemini 3 Pro", {"family": "gemini"}),
|
||||
]
|
||||
IMAGE_MODELS = [
|
||||
("gpt-image-2", "GPT-Image-2(参考图)", {"family": "gpt", "supports_reference": True, "recommended": True}),
|
||||
("gemini-2.5-flash-image", "Gemini 2.5 Flash Image", {"family": "gemini", "supports_reference": True}),
|
||||
]
|
||||
|
||||
|
||||
def seed(apps, schema_editor):
|
||||
ModelProvider = apps.get_model("ai", "ModelProvider")
|
||||
ModelConfig = apps.get_model("ai", "ModelConfig")
|
||||
|
||||
tokenssr, _ = ModelProvider.objects.get_or_create(
|
||||
name="tokenssr",
|
||||
defaults={
|
||||
"display_name": "tokenssr 中转站",
|
||||
"status": "active",
|
||||
"base_url": TOKENSSR_BASE_URL,
|
||||
"api_key": "", # 留空:运行时从 .env(PROVIDER_KEYS)解析,密钥不进库
|
||||
"metadata": {"kind": "relay", "note": "一把 key 通吃 ~90 模型"},
|
||||
},
|
||||
)
|
||||
if not tokenssr.base_url:
|
||||
tokenssr.base_url = TOKENSSR_BASE_URL
|
||||
tokenssr.save(update_fields=["base_url"])
|
||||
|
||||
for name, display, meta in TEXT_MODELS:
|
||||
ModelConfig.objects.update_or_create(
|
||||
provider=tokenssr,
|
||||
name=name,
|
||||
capability="text",
|
||||
defaults={
|
||||
"display_name": display,
|
||||
"endpoint": "chat/completions",
|
||||
"unit_price": "1.0000",
|
||||
"status": "active",
|
||||
"metadata": meta,
|
||||
},
|
||||
)
|
||||
for name, display, meta in IMAGE_MODELS:
|
||||
ModelConfig.objects.update_or_create(
|
||||
provider=tokenssr,
|
||||
name=name,
|
||||
capability="image",
|
||||
defaults={
|
||||
"display_name": display,
|
||||
"endpoint": "images/generations",
|
||||
"unit_price": "2.0000",
|
||||
"status": "active" if name == "gpt-image-2" else "disabled",
|
||||
"metadata": meta,
|
||||
},
|
||||
)
|
||||
|
||||
# 图像主力切到 tokenssr:gpt-image-2;停用只能纯文生图的 yunqi:gpt-image-2(参考图分镜要靠 tokenssr)
|
||||
ModelConfig.objects.filter(provider__name="yunqi", capability="image").update(status="disabled")
|
||||
|
||||
|
||||
def unseed(apps, schema_editor):
|
||||
# 反向:停用 tokenssr 模型并复活 yunqi 图像(不删数据,保守)
|
||||
ModelProvider = apps.get_model("ai", "ModelProvider")
|
||||
ModelConfig = apps.get_model("ai", "ModelConfig")
|
||||
ModelConfig.objects.filter(provider__name="tokenssr").update(status="disabled")
|
||||
ModelConfig.objects.filter(provider__name="yunqi", capability="image").update(status="active")
|
||||
ModelProvider.objects.filter(name="tokenssr").update(status="disabled")
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [("ai", "0005_modelprovider_api_key")]
|
||||
operations = [migrations.RunPython(seed, unseed)]
|
||||
Reference in New Issue
Block a user