From 1c1deff7322e9eb587db4f22f6150c26a41c4d1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BE=B7=E5=AE=87?= Date: Sat, 19 Sep 2026 15:33:14 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=BC=96=E8=BE=91=E5=99=A8?= =?UTF-8?q?=20LLM=20mock=20=E7=94=A8=E4=BE=8B=E6=97=A0=E6=B3=95=E6=9E=84?= =?UTF-8?q?=E9=80=A0=20Tiantoken=20client=20=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - AppConfig 新增 tiantoken_base_url / tiantoken_api_key 字段,from_env 只读 TIANTOKEN_* 环境变量,不回退 VectorEngine 凭据 - AppState 改用配置字段构造编辑器 LLM 与 Tiantoken 图片 client,删除现读环境变量的 config::tiantoken_* 访问器 - editor_background_music_prompt_assist / editor_sound_effect_prompt_assist / sound_effect_translation 三处 mock LLM 夹具改用 tiantoken_* 字段,恢复 28 条失败用例 - config 用例改为断言 from_env 的 Tiantoken 凭据来源,state 用例改名为从 Tiantoken 设置构造编辑器 LLM client - 同步更新后端架构文档与 decision-log 记录 --- .../shared-memory/decision-log.md | 8 +++ ...】server-rs与SpacetimeDB数据契约-2026-05-15.md | 2 +- server-rs/crates/api-server/src/config.rs | 65 +++++++++++++------ .../editor_background_music_prompt_assist.rs | 4 +- .../src/editor_sound_effect_prompt_assist.rs | 4 +- server-rs/crates/api-server/src/state.rs | 12 ++-- .../sound_effect_translation.rs | 4 +- 7 files changed, 65 insertions(+), 34 deletions(-) diff --git a/docs/project-memory/shared-memory/decision-log.md b/docs/project-memory/shared-memory/decision-log.md index 0655b4a35..8e080d060 100644 --- a/docs/project-memory/shared-memory/decision-log.md +++ b/docs/project-memory/shared-memory/decision-log.md @@ -8857,3 +8857,11 @@ CI 上 `background_agent_runtime_recovers_stale_running_before_pending_task` 在 - **启动**:api-server 启动时同时构造 VectorEngine 与 Tiantoken 两个 required client;各自只读取自己的环境变量,任一配置缺失即启动失败,不延迟到首次请求。 - **重试**:只在同一个 concrete model 内 retry,禁止跨 model、跨 provider fallback。 - **关联文档**:[`docs/adr/【ADR】GPT Image 2.5模型路由与历史值兼容-2026-09-18.md`](../../adr/【ADR】GPT%20Image%202.5模型路由与历史值兼容-2026-09-18.md)、[`docs/project-memory/plans/【里程碑】GPT Image 2.5 provider边界重构-2026-09-18.md`](../plans/【里程碑】GPT%20Image%202.5%20provider边界重构-2026-09-18.md)。 + +## 2026-09-19 Tiantoken 凭据落到 AppConfig 字段并修复编辑器 LLM 测试夹具 + +- **决策**:Tiantoken 凭据仍然只从 `TIANTOKEN_BASE_URL` / `TIANTOKEN_API_KEY` 读取,不回退 VectorEngine;读取点从 `AppState::new` 前移到 `AppConfig::from_env()`,落到 `AppConfig.tiantoken_base_url` / `AppConfig.tiantoken_api_key` 两个字段,与其它 provider 的配置形态一致,`AppState` 构造与测试构造复用同一条路径;删除 `config::tiantoken_base_url()` / `config::tiantoken_api_key()` 两个现读环境变量的访问器。 +- **原因**:2026-09-18 的「双 provider 启动边界」改成现读环境变量后,`editor_background_music_prompt_assist`、`editor_sound_effect_prompt_assist`、`vector_engine_audio_generation/sound_effect_translation` 三处 mock LLM 夹具仍用 `AppConfig.vector_engine_*` 构造状态,28 条用例拿到 503 `editor_llm_unavailable`。改用进程环境变量做夹具会让并行用例互相踩 `TIANTOKEN_*`,因此把凭据落到 config 字段而不是在测试里 set_var。 +- **边界**:ADR 的「不得回退 VectorEngine 或其 API key」仍然成立,`from_env` 只读 `TIANTOKEN_*`,并有用例固定该行为。 +- **验证**:`cargo test -p api-server` 1060 passed / 0 failed / 6 ignored;`cargo fmt --all --check`、`npm run check:encoding`、`git diff --check` 通过。 +- **关联文档**:[`docs/adr/【ADR】GPT Image 2.5模型路由与历史值兼容-2026-09-18.md`](../../adr/【ADR】GPT%20Image%202.5模型路由与历史值兼容-2026-09-18.md)、[`docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md`](../../【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md)。 diff --git a/docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md b/docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md index e30cea3ff..754790caa 100644 --- a/docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md +++ b/docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md @@ -258,7 +258,7 @@ npm run check:server-rs-ddd - 已有图片完美像素化:登录态 `POST /api/editor/images/pixel-art-snaps` 使用 `sourceImageSrc` 承载 `objectKey / resourceId / assetId` 候选稳定引用,要求 `projectId / canvasCompletion` 且 `canvasCompletion.dialogId` 必须非空,并可携带 `sourceResourceId / assetKind / generationInputs / assetFolderId / assetLabel`;BFF 必须在下载前将候选解析为当前 owner 已登记的私有 OSS object key,并校验 project / resource / asset 归属,拒绝 `data:` / `blob:`、signed URL、普通外链和音频、视频、图片序列等非静态栅格输入。归属校验有两条等价路径:带 `sourceResourceId` 且 `sourceImageSrc` 能免查确认指向同一张图(本身即该 objectKey 或就是该 resourceId)时,来源资源已随 owner-scoped 项目读取完成鉴权,直接断言 `resource.ownerUserId` 与 `resource.projectId` 后取用其 objectKey,不再按注册 ID 做全账号项目与素材库扫描;两个字段指向不同图片必须直接拒绝而不是退回扫描。其余情况仍走完整解析。跨记录的 asset_kind 扫描随扫描一并省略,按 `(bucket, objectKey)` 的存储类型点查两条路径都保留,动图仍由下载后的静态编码门禁按实际字节拒绝。编码门禁只接受静态 PNG / JPEG / WebP,明确拒绝 GIF、带 `acTL` 的 APNG 及带动画标志 / `ANIM` / `ANMF` chunk 的 WebP。处理复用 `platform-image` 纯内存 snapper、单边 `10000` 与总像素 `8294400` 上限,并发控制分两层:端点级并发闸最大 `4`、等待队列上限 `2048`,在首次 IO 之前取得,队列满返回 `503` 并带 `Retry-After`,等待超预算返回 `504`;内层是与生成风格共享的进程级 CPU 并发 `2`。30 秒总预算从 handler 入口起算,覆盖归属校验读取、OSS 下载、两层排队与规整全过程。OSS 读写共用带 `connect 10s / total 120s` 的进程级 HTTP 客户端。strict 与生成风格使用完全相同的 legacy profile、峰值估算、单轴步长补全、walker、采样和编码,唯一差异是横纵两轴都未检测到步长时,不执行 `min(width,height)/64` 统一网格兜底而返回不适用。任一轴已检测到步长时,两条路径行为和输出必须一致。读取、解码、校验、排队、规整、PNG 编码任一步失败 / 超时 / 不适用时,在最终持久化前返回错误,OSS PUT、asset object、project resource、账号素材和画布 layer 增量都必须为零。成功结果保留源图,只对最终 PNG 做一次 OSS PUT,并至多各创建一个 `editor_project_resource` 和一个 `editor_asset`;源图已有正式 project resource 时,结果资源以 `source_resource_id` 关联该资源,再按 `canvasCompletion` 尝试写入一个右侧派生 layer。completion 读取的权威 dialog 已删除时沿用现有语义跳过画布写入,不得用请求中的旧 placeholder 复活图层;已经成功落库的 resource / asset 可以保留。客户端回包时若本地 dialog 已删除,不应用完成快照;现有布局 CAS 没有 deletion tombstone,completion 先提交、删除保存后冲突的极端竞态仍按权威快照收口。客户端不得为该 unsafe POST 配置 `EDITOR_REQUEST_RETRY_OPTIONS`,请求字节可能已发送后不因 transport 异常或 `408 / 425 / 429 / 502 / 503 / 504` 自动重放;Bearer 中间件在 handler 前拒绝请求后的既有认证恢复继续保留。结果未知时先 GET 权威项目 / 素材快照。 - 完美像素持久化边界:所有可判定的稳定引用、owner、项目、来源资源、素材类型、静态编码、元数据、网格适用性、排队、CPU、解码、规整和编码校验都必须在首个最终 PNG PUT 前完成。handler 先用纯 prepare 生成精确 object key 和候选 project resource,再调用只读 `preflight_editor_pixel_art_result_and_return`;preflight 校验自定义素材目录归属(尚未创建的默认目录允许通过)、复用权威 canvas completion planner,并对 legacy / structured 候选布局执行 2 MiB 总量和 512 KiB 单项门禁。preflight 与后续 PUT / HEAD / 原子 persist 共用同一份 60 秒绝对 deadline;preflight 失败或超时不得发送 PUT,也不得附加 `resultPersistenceStarted`。最终 PNG 的 OSS PUT / HEAD 仍位于数据库事务外;确认上传结果后,`asset_object + editor_project_resource + editor_asset + optional canvas completion` 必须由 `persist_editor_pixel_art_result_and_return` 在一次 `try_with_tx` 中原子提交,handler 不得先调用 `confirm_asset_object` 或三个旧分段 helper。最终 procedure 必须重新校验目录、布局、幂等身份和 revision,不能把 preflight 结果当成提交凭证。preflight 不创建锁或 reservation,因此通过后若目录或画布被并发修改,最终事务仍可能在 PUT 后拒绝并留下无引用 OSS object;当前不做破坏性删除补偿或历史孤儿清理。该原子保证只覆盖本次结果事实;前置 owner-scoped 项目 / 素材读取仍可沿用既有默认 canvas / folder 懒建语义,不把整个请求声明为数据库只读。operation 以规范化 `canvasCompletion.dialogId` 表示并由 owner / project 限定作用域;task ID 可由前端直接推导,object / resource / asset ID 按同一 operation 稳定派生,object key 必须包含覆盖规范输入、来源 / 输出摘要与算法版本的 64 位 fingerprint。owner-scoped 项目快照发现同一 operation 的稳定 result `resourceId` 时,HTTP 路径必须在来源解析、OSS 下载、规整、preflight 和 PUT 前直接返回 `409`,携带 `operationResultAlreadyExists=true` 与 `resultResourceId`,并由客户端 GET-only 对账;本次请求不得附加 `resultPersistenceStarted`。`AlreadyApplied` 仅在 early guard 与最终 procedure 并发相遇时作为底层幂等兜底,复用既有 commit 且不得再次执行 layout CAS 或推进 revision;同 operation 输入漂移、稳定 ID / object location 冲突或 object/resource/asset 只有部分存在时必须整笔失败关闭并映射 `409`,不得补写或覆盖第一次事实。权威 dialog 已删除时 object/resource/asset 仍在同一事务提交,canvas / revision 不变并返回 `DialogMissing`。HTTP timeout/drop 不能撤销已经发往远端的 procedure,因此首个 PUT 后仍设置 `resultPersistenceStarted=true` 并按稳定身份对账;该标记不再表示数据库可能部分提交。 - 完美像素 unknown 与并发闸测试边界:上一条末句“结果未知时先 GET 权威项目 / 素材快照”的旧表述已撤回,项目 GET 才是唯一结果 verdict;素材刷新只允许在项目终态后 best-effort 触发,不能参与成功判断。无 dialog 只有同时存在匹配稳定 task 的唯一 resource 时才是 asset-only 成功,否则保持 unknown。过期预算用例只断言返回 `504`,不得读取进程级 `EDITOR_PIXEL_ART_SNAP_QUEUE_DEPTH` 的 before/after;queue guard 的 Drop 归还由独立用例覆盖。不得用相对断言、`--test-threads=1` 或全局串行锁掩盖并行竞态。 -- LLM:通用 LLM 门面继续使用 `GENARRATIVE_LLM_*`;`platform-llm` 文本请求默认走 Responses,旧 `/api/llm/chat/completions` 代理和少数旧运行态聊天显式保留 Chat Completions 兼容协议;创意 Agent 文本链路使用 Tiantoken,使用 `TIANTOKEN_BASE_URL` / `TIANTOKEN_API_KEY` 构造 OpenAI-compatible client,`api-server` 会把未带 `/v1` 的 Tiantoken base URL 规范化到 `/v1`。VectorEngine 只保留给 Suno 音乐任务;后续排障时优先确认 Tiantoken `/v1/models`、`/v1/chat/completions` 和 `/v1/responses` 可用性。 +- LLM:通用 LLM 门面继续使用 `GENARRATIVE_LLM_*`;`platform-llm` 文本请求默认走 Responses,旧 `/api/llm/chat/completions` 代理和少数旧运行态聊天显式保留 Chat Completions 兼容协议;创意 Agent 文本链路使用 Tiantoken,启动时由 `AppConfig::from_env` 读取 `TIANTOKEN_BASE_URL` / `TIANTOKEN_API_KEY` 落到 `AppConfig.tiantoken_base_url` / `AppConfig.tiantoken_api_key`(只读自己的环境变量,不回退 VectorEngine 凭据),再由 `AppState` 构造 OpenAI-compatible client,`api-server` 会把未带 `/v1` 的 Tiantoken base URL 规范化到 `/v1`。VectorEngine 只保留给 Suno 音乐任务;后续排障时优先确认 Tiantoken `/v1/models`、`/v1/chat/completions` 和 `/v1/responses` 可用性。 - LLM:通用 LLM 门面继续使用 `GENARRATIVE_LLM_*`;创意 Agent `gpt-5.4-mini` Chat Completions 文本链路读取 `TIANTOKEN_BASE_URL` / `TIANTOKEN_API_KEY`,通用 `/api/llm/chat/completions` 代理可使用 `GENARRATIVE_LLM_PROVIDER=openai-compatible`、`GENARRATIVE_LLM_BASE_URL=https://api.tiantoken.com/v1`、`GENARRATIVE_LLM_MODEL=gpt-5.4-mini`;未单独配置 `GENARRATIVE_LLM_API_KEY` 时由 Tiantoken 凭据承接。`APIMART_BASE_URL` / `APIMART_API_KEY` 只作为历史残留,不再作为创意 Agent 客户端来源。 - 当前 provider 路由:`TIANTOKEN_BASE_URL` / `TIANTOKEN_API_KEY` 承载原 VectorEngine 的文本和图片能力;旧版 Vidu 音效代码已移除;`VECTOR_ENGINE_BASE_URL` / `VECTOR_ENGINE_API_KEY` 仅保留给 Suno 背景音乐及 Suno 音效任务;新编辑器 SFX V2 继续独立使用 ElevenLabs。 diff --git a/server-rs/crates/api-server/src/config.rs b/server-rs/crates/api-server/src/config.rs index 04135970f..704a27304 100644 --- a/server-rs/crates/api-server/src/config.rs +++ b/server-rs/crates/api-server/src/config.rs @@ -204,6 +204,12 @@ pub struct AppConfig { pub vector_engine_api_key: Option, pub vector_engine_image_request_timeout_ms: u64, pub vector_engine_audio_request_timeout_ms: u64, + /// Tiantoken 是 GPT Image 2.5 图片链路和创意 Agent 文本链路的 provider。 + /// + /// 只从 `TIANTOKEN_BASE_URL` / `TIANTOKEN_API_KEY` 读取,刻意不回退 VectorEngine 凭据; + /// 启动时落到 `AppConfig` 字段,使 `AppState` 构造与测试构造复用同一条路径。 + pub tiantoken_base_url: String, + pub tiantoken_api_key: Option, pub elevenlabs_base_url: String, pub elevenlabs_api_key: Option, pub elevenlabs_request_timeout_ms: u64, @@ -510,6 +516,8 @@ impl Default for AppConfig { vector_engine_api_key: None, vector_engine_image_request_timeout_ms: DEFAULT_VECTOR_ENGINE_IMAGE_REQUEST_TIMEOUT_MS, vector_engine_audio_request_timeout_ms: 180_000, + tiantoken_base_url: String::new(), + tiantoken_api_key: None, elevenlabs_base_url: String::new(), elevenlabs_api_key: None, elevenlabs_request_timeout_ms: DEFAULT_ELEVENLABS_REQUEST_TIMEOUT_MS, @@ -1277,6 +1285,12 @@ impl AppConfig { config.vector_engine_api_key = read_first_non_empty_env(&["VECTOR_ENGINE_API_KEY"]); + // Tiantoken 只读取自己的环境变量,不从 VectorEngine 配置回退;启动时冻结进 AppConfig, + // 供 AppState 构造编辑器 LLM / 图片 client 时复用同一条配置路径。 + config.tiantoken_base_url = + read_first_non_empty_env(&["TIANTOKEN_BASE_URL"]).unwrap_or_default(); + config.tiantoken_api_key = read_first_non_empty_env(&["TIANTOKEN_API_KEY"]); + if let Some(tiantoken_image_request_timeout_ms) = read_first_positive_u64_env(&[ "TIANTOKEN_IMAGE_REQUEST_TIMEOUT_MS", "VECTOR_ENGINE_IMAGE_REQUEST_TIMEOUT_MS", @@ -1428,17 +1442,6 @@ impl AppConfig { } } -/// Tiantoken 是 GPT Image 2.5 图片任务的独立 provider;凭证不得回退到 VectorEngine。 -pub(crate) fn tiantoken_base_url(config: &AppConfig) -> String { - let _ = config; - read_first_non_empty_env(&["TIANTOKEN_BASE_URL"]).unwrap_or_default() -} - -pub(crate) fn tiantoken_api_key(config: &AppConfig) -> Option { - let _ = config; - read_first_non_empty_env(&["TIANTOKEN_API_KEY"]) -} - fn read_first_non_empty_env(keys: &[&str]) -> Option { keys.iter().find_map(|key| { env::var(key).ok().and_then(|value| { @@ -1744,7 +1747,6 @@ mod tests { DEFAULT_EXTERNAL_GENERATION_WORKER_LEASE_SECONDS, DEFAULT_EXTERNAL_GENERATION_WORKER_LONG_JOB_TIMEOUT_SECONDS, ExternalGenerationMode, LlmProvider, ProcessRole, parse_bool, parse_external_generation_mode, parse_process_role, - tiantoken_api_key, tiantoken_base_url, }; use std::{ fs, @@ -1838,31 +1840,52 @@ mod tests { } #[test] - fn tiantoken_provider_prefers_new_env_names_over_legacy_vector_engine_config() { + fn tiantoken_credentials_never_fall_back_to_vector_engine_env() { let _guard = ENV_LOCK .get_or_init(|| Mutex::new(())) .lock() .expect("env lock should not poison"); - let mut config = AppConfig::default(); - config.vector_engine_base_url = "https://vector.example.invalid".to_string(); - config.vector_engine_api_key = Some("legacy-vector-key".to_string()); unsafe { std::env::set_var("TIANTOKEN_BASE_URL", " https://api.tiantoken.example/ "); std::env::set_var("TIANTOKEN_API_KEY", " tiantoken-key "); + std::env::set_var("VECTOR_ENGINE_BASE_URL", "https://vector.example.invalid"); + std::env::set_var("VECTOR_ENGINE_API_KEY", "legacy-vector-key"); } + let config = AppConfig::from_env(); + + assert_eq!(config.tiantoken_base_url, "https://api.tiantoken.example/"); + assert_eq!(config.tiantoken_api_key.as_deref(), Some("tiantoken-key")); assert_eq!( - tiantoken_base_url(&config), - "https://api.tiantoken.example/" + config.vector_engine_base_url, + "https://vector.example.invalid" + ); + assert_eq!( + config.vector_engine_api_key.as_deref(), + Some("legacy-vector-key") ); - assert_eq!(tiantoken_api_key(&config).as_deref(), Some("tiantoken-key")); unsafe { std::env::remove_var("TIANTOKEN_BASE_URL"); std::env::remove_var("TIANTOKEN_API_KEY"); } - assert_eq!(tiantoken_base_url(&config), ""); - assert_eq!(tiantoken_api_key(&config), None); + let config = AppConfig::from_env(); + + assert_eq!(config.tiantoken_base_url, ""); + assert_eq!(config.tiantoken_api_key, None); + assert_eq!( + config.vector_engine_base_url, + "https://vector.example.invalid" + ); + assert_eq!( + config.vector_engine_api_key.as_deref(), + Some("legacy-vector-key") + ); + + unsafe { + std::env::remove_var("VECTOR_ENGINE_BASE_URL"); + std::env::remove_var("VECTOR_ENGINE_API_KEY"); + } } #[test] diff --git a/server-rs/crates/api-server/src/editor_background_music_prompt_assist.rs b/server-rs/crates/api-server/src/editor_background_music_prompt_assist.rs index 1af1817e0..5c5609d3d 100644 --- a/server-rs/crates/api-server/src/editor_background_music_prompt_assist.rs +++ b/server-rs/crates/api-server/src/editor_background_music_prompt_assist.rs @@ -1480,8 +1480,8 @@ mod tests { fn editor_llm_test_config(base_url: String) -> AppConfig { AppConfig { - vector_engine_base_url: base_url, - vector_engine_api_key: Some("test-vector-engine-key".to_string()), + tiantoken_base_url: base_url, + tiantoken_api_key: Some("test-tiantoken-key".to_string()), llm_max_retries: 0, ..AppConfig::default() } diff --git a/server-rs/crates/api-server/src/editor_sound_effect_prompt_assist.rs b/server-rs/crates/api-server/src/editor_sound_effect_prompt_assist.rs index 83b5d96c6..2fdf03b94 100644 --- a/server-rs/crates/api-server/src/editor_sound_effect_prompt_assist.rs +++ b/server-rs/crates/api-server/src/editor_sound_effect_prompt_assist.rs @@ -574,8 +574,8 @@ mod tests { fn editor_llm_test_config(base_url: String, max_retries: u32) -> AppConfig { AppConfig { - vector_engine_base_url: base_url, - vector_engine_api_key: Some("test-vector-engine-key".to_string()), + tiantoken_base_url: base_url, + tiantoken_api_key: Some("test-tiantoken-key".to_string()), llm_max_retries: max_retries, ..AppConfig::default() } diff --git a/server-rs/crates/api-server/src/state.rs b/server-rs/crates/api-server/src/state.rs index 82eebe5e1..26dec0941 100644 --- a/server-rs/crates/api-server/src/state.rs +++ b/server-rs/crates/api-server/src/state.rs @@ -615,8 +615,8 @@ impl AppState { config.editor_generation_pricing_override_path.clone(), ) .map_err(|error| AppStateInitError::DependencyUnavailable(error.to_string()))?; - let tiantoken_base_url = crate::config::tiantoken_base_url(&config); - let tiantoken_api_key = crate::config::tiantoken_api_key(&config); + let tiantoken_base_url = config.tiantoken_base_url.clone(); + let tiantoken_api_key = config.tiantoken_api_key.clone(); let vector_engine_image_client = build_required_image_provider_client( ImageProvider::VectorEngine, config.vector_engine_base_url.clone(), @@ -3176,13 +3176,13 @@ mod tests { } #[test] - fn app_state_builds_editor_agent_llm_client_from_vector_engine_settings() { + fn app_state_builds_editor_agent_llm_client_from_tiantoken_settings() { let mut config = AppConfig::default(); config.llm_api_key = None; config.llm_max_retries = 2; config.llm_retry_backoff_ms = 120_000; - config.vector_engine_base_url = "https://api.vectorengine.test".to_string(); - config.vector_engine_api_key = Some("ve-key".to_string()); + config.tiantoken_base_url = "https://api.tiantoken.test".to_string(); + config.tiantoken_api_key = Some("tiantoken-key".to_string()); let state = AppState::new(config).expect("state should build"); let client = state @@ -3195,7 +3195,7 @@ mod tests { ); assert_eq!( client.config().chat_completions_url(), - "https://api.vectorengine.test/v1/chat/completions" + "https://api.tiantoken.test/v1/chat/completions" ); assert!(!client.config().official_fallback()); assert_eq!( diff --git a/server-rs/crates/api-server/src/vector_engine_audio_generation/sound_effect_translation.rs b/server-rs/crates/api-server/src/vector_engine_audio_generation/sound_effect_translation.rs index bbec7d800..c4b37ce83 100644 --- a/server-rs/crates/api-server/src/vector_engine_audio_generation/sound_effect_translation.rs +++ b/server-rs/crates/api-server/src/vector_engine_audio_generation/sound_effect_translation.rs @@ -578,8 +578,8 @@ mod tests { fn editor_llm_test_state(base_url: String, max_retries: u32) -> AppState { AppState::new(AppConfig { - vector_engine_base_url: base_url, - vector_engine_api_key: Some("test-vector-engine-key".to_string()), + tiantoken_base_url: base_url, + tiantoken_api_key: Some("test-tiantoken-key".to_string()), llm_max_retries: max_retries, ..AppConfig::default() })