4234a21eed
- module-runtime:删除写死的初始目录(高质量→gpt-6-astra、快速→gpt-5.6-luna),新增 from_upstream_models:id 用模型名 slug、alias/modelId 用上游原名、默认项取排序后第一项;字段与校验规则不变 - spacetime-module:read_agc_model_catalog 缺行返回 AGC_MODEL_CATALOG_NOT_INITIALIZED,不再返回内置目录 - api-server:新增启动期 ensure_agc_model_catalog_initialized,未初始化时从分组定价列表 GET /api/pricing?group=taonier 生成目录并按存量 revision 写回;拉不到只记录 error、不写替代目录,下次启动重试 - api-server:目录未初始化时 AGC 目录/对话接口与后台目录接口返回 503,不回落任何内置模型名;后台 PUT 同样要求已初始化 - api-server:上游请求 10s 超时、1 MiB 流式上限、禁止重定向、不带凭据;目标校验只校验地址,不再绑定已下线的固定模型哨兵;写回冲突后重读校验既有目录
65 lines
2.3 KiB
Rust
65 lines
2.3 KiB
Rust
use crate::*;
|
|
|
|
#[spacetimedb::table(accessor = agc_model_catalog)]
|
|
pub struct AgcModelCatalogRow {
|
|
#[primary_key]
|
|
pub id: u8,
|
|
pub catalog_json: String,
|
|
pub revision: u64,
|
|
pub updated_at: Timestamp,
|
|
}
|
|
|
|
#[spacetimedb::procedure]
|
|
pub fn read_agc_model_catalog(ctx: &mut ProcedureContext) -> Result<String, String> {
|
|
let caller = ctx.sender();
|
|
ctx.try_with_tx(|tx| {
|
|
crate::editor_project_storage::require_editor_generation_runtime_service_identity(
|
|
tx, caller,
|
|
)?;
|
|
// 目录只有一份事实来源:上游同步或后台保存。缺行时不得返回任何内置目录,
|
|
// 由 api-server 按“未初始化”处理并触发启动期同步。
|
|
tx.db
|
|
.agc_model_catalog()
|
|
.id()
|
|
.find(0)
|
|
.map(|row| row.catalog_json)
|
|
.ok_or_else(|| module_runtime::AGC_MODEL_CATALOG_NOT_INITIALIZED.to_string())
|
|
})
|
|
}
|
|
|
|
#[spacetimedb::procedure]
|
|
pub fn save_agc_model_catalog(
|
|
ctx: &mut ProcedureContext,
|
|
catalog_json: String,
|
|
) -> Result<String, String> {
|
|
let catalog: module_runtime::AgcModelCatalog =
|
|
serde_json::from_str(&catalog_json).map_err(|_| "模型目录格式无效".to_string())?;
|
|
catalog.validate()?;
|
|
let caller = ctx.sender();
|
|
ctx.try_with_tx(|tx| {
|
|
crate::editor_project_storage::require_editor_generation_runtime_service_identity(
|
|
tx, caller,
|
|
)?;
|
|
let mut catalog = catalog.clone();
|
|
let previous = tx.db.agc_model_catalog().id().find(0);
|
|
let revision = previous.as_ref().map(|r| r.revision).unwrap_or(0);
|
|
if catalog.revision != revision {
|
|
return Err(module_runtime::AGC_MODEL_CATALOG_CONFLICT.into());
|
|
}
|
|
catalog.revision = revision.checked_add(1).ok_or("模型目录版本溢出")?;
|
|
let catalog_json = serde_json::to_string(&catalog).map_err(|_| "模型目录序列化失败")?;
|
|
let row = AgcModelCatalogRow {
|
|
id: 0,
|
|
catalog_json: catalog_json.clone(),
|
|
revision: catalog.revision,
|
|
updated_at: tx.timestamp,
|
|
};
|
|
if previous.is_some() {
|
|
tx.db.agc_model_catalog().id().update(row);
|
|
} else {
|
|
tx.db.agc_model_catalog().insert(row);
|
|
}
|
|
Ok(catalog_json)
|
|
})
|
|
}
|