add first commit

This commit is contained in:
2026-07-21 15:43:39 +08:00
commit 482f8df508
19 changed files with 521 additions and 0 deletions
+39
View File
@@ -0,0 +1,39 @@
"""
豆包视觉理解 Worker 插件
"""
import os
from volcenginesdkarkruntime import AsyncArk
from chongming_worker import create_workers as _create_workers
from chongming_worker import auto_bind_models
from .global_var import set_ark_client, cleanup_ark_client
from .router import *
# 自动绑定 gen_models 生成的 Pydantic 模型
auto_bind_models("doubao")
async def create_workers(session, config, count=1, worker_manager=None):
"""
工厂函数:由 app 生命周期调用,创建 Worker 协程。
"""
# 从配置或环境变量获取 API Key
api_key = config.get("api_key") or os.environ.get("VOLC_ACCESSKEY")
if not api_key:
raise ValueError("缺少 API_KEY,请在配置中设置 api_key 或环境变量 VOLC_ACCESSKEY")
base_url = config.get("base_url", "https://ark.cn-beijing.volces.com/api/v3")
model = config.get("model", "doubao-seed-evolving")
# 将模型名存入环境变量,供 router 使用
os.environ["DOUBAO_MODEL"] = model
# 创建全局客户端
client = AsyncArk(base_url=base_url, api_key=api_key)
set_ark_client(client)
# 委托给通用运行时创建 Worker 任务
return _create_workers(session, config, count, worker_manager)
async def cleanup(worker_item: str):
"""清理资源"""
cleanup_ark_client()
print(f"{worker_item} 清理完毕")
+17
View File
@@ -0,0 +1,17 @@
from typing import Optional
from volcenginesdkarkruntime import AsyncArk
_ark_client: Optional[AsyncArk] = None
def set_ark_client(client: AsyncArk):
global _ark_client
_ark_client = client
def get_ark_client() -> Optional[AsyncArk]:
return _ark_client
def cleanup_ark_client():
global _ark_client
if _ark_client:
# AsyncArk 无显式 close,但可设为 None
_ark_client = None
+14
View File
@@ -0,0 +1,14 @@
"""
模型导出 — doubao
自动生成,请勿手动修改
"""
from .pydantic import AnalyzePostRequest
from .pydantic import AnalyzePostResponse
from .pydantic import DoubaoResponse
__all__ = [
"AnalyzePostRequest",
"AnalyzePostResponse",
"DoubaoResponse",
]
+23
View File
@@ -0,0 +1,23 @@
"""
自动生成的 Pydantic 模型 — doubao
来源: config/workers/doubao/
"""
from __future__ import annotations
from typing import Any, Optional
from pydantic import BaseModel, Field
class AnalyzePostRequest(BaseModel):
"""分析图片内容 — 请求体"""
image_base64: str = Field(...)
prompt: str = Field(...)
class AnalyzePostResponse(BaseModel):
"""分析图片内容 — 响应体"""
result: str = Field(...)
error: Optional[str] = Field(default='')
# 所有响应模型的联合类型
DoubaoResponse = AnalyzePostResponse
+3
View File
@@ -0,0 +1,3 @@
from .analyze import analyze
__all__ = ["analyze"]
+48
View File
@@ -0,0 +1,48 @@
import os
from chongming_worker import rpc_method
from ..models.pydantic import AnalyzePostRequest, AnalyzePostResponse
from ..global_var import get_ark_client
@rpc_method(
subject="doubao.analyze",
method="POST",
summary="Analyze image via Doubao vision model",
response_model=AnalyzePostResponse,
)
async def analyze(request: AnalyzePostRequest) -> AnalyzePostResponse:
print(f"[DEBUG] analyze called with prompt={request.prompt}, image_base64 length={len(request.image_base64)}")
client = get_ark_client()
if client is None:
return AnalyzePostResponse(result="", error="客户端未初始化")
# 获取图片数据
image_base64 = request.image_base64
if not image_base64:
return AnalyzePostResponse(result="", error="未提供图片数据(image_base64或image_path)")
if image_base64.startswith('data:image/'):
image_base64 = image_base64.split(',', 1)[1]
mime_type = "image/png"
prompt = request.prompt or ""
try:
response = await client.chat.completions.create(
model=os.getenv("DOUBAO_MODEL", "doubao-seed-evolving"),
messages=[
{
"role": "user",
"content": [
{"type": "image_url", "image_url": f"data:{mime_type};base64,{image_base64}"},
{"type": "text", "text": prompt}
]
} # type: ignore
],
thinking={"type": "disabled"}
)
result = response.choices[0].message.content # type: ignore
return AnalyzePostResponse(result=result) # type: ignore
except Exception as e:
return AnalyzePostResponse(result="", error=f"调用豆包API失败: {str(e)}")