feat(config): 运行时配置体系①——LLM 多厂商独立组落 models.json + 面板落盘 + 热更新
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled

- runtimeconfig/models.go: models.json 承载 [{id,provider,baseUrl,apiKey,model,fallback?,multimodal?}] 多厂商独立组(首项=生效)
- LoadModels 优先文件/回退env(GroupFromEnv), SaveModels(0600+tmp原子写), Activate/Upsert/MaskedKey脱敏
- 面板 POST /admin/llm 落盘 models.json(取代temporary内存) + GET 列组(脱敏)
- runtime/model/runtime.go: RuntimeLLM(adapter+router) atomic快照可热替换, Reload 重建不中断进行中请求; per-role路由用接口
- wire 用 NewRuntimeLLM(adapter+router), 保留 a.modelAdapter(=runtime stack, 审查模型随热更新)
- .env 退兜底(.env.example注明); apiKey不打印/Config()脱敏/热更新不中断
- 全仓 go build/vet/test 绿(54包)+交叉编译+前端build绿(79模块); api-client v0.15已同步
- 遗留: vision ModelInfo 仍读静态env(后续纳入); 保存组=生效组(第一版语义)
This commit is contained in:
Aska committed 2026-09-07 13:07:58 +08:00
1 parent 8cde0162e6
commit 2d7151f979
16 files changed
+1079 -108

No files matched your search

+9 -10
View File
@@ -18,6 +18,7 @@ import type {
ChannelTestResult,
ChatMessage,
ChatSyncResult,
LlmProviderRequest,
LlmTestRequest,
LlmTestResult,
LoginResult,
@@ -452,16 +453,14 @@ export function adminRunAutomation(id: string): Promise<AutomationRunResult> {
export function adminDeleteAutomation(id: string): Promise<{ id: string; deleted: boolean }> {
return request<{ id: string; deleted: boolean }>(`/admin/automations/${encodeURIComponent(id)}`, { method: "DELETE" });
}
/** POST /api/v1/admin/llm — records a provider for the process lifetime (temporary). */
export function adminAddLlmProvider(req: {
id?: string;
name: string;
baseUrl?: string;
model: string;
multimodal?: boolean;
fallback?: string;
}): Promise<{ provider: AdminLlmProvider; temporary: boolean }> {
return request<{ provider: AdminLlmProvider; temporary: boolean }>("/admin/llm", {
/** POST /api/v1/admin/llm — saves a provider group to models.json and hot-reloads
* the running LLM stack (design/04 §3.1). The provider is the wire protocol. */
export function adminAddLlmProvider(req: LlmProviderRequest): Promise<{
provider: AdminLlmProvider;
persisted: boolean;
path?: string;
}> {
return request<{ provider: AdminLlmProvider; persisted: boolean; path?: string }>("/admin/llm", {
method: "POST",
body: JSON.stringify(req),
});
+9 -4
View File
@@ -272,10 +272,12 @@ export interface AdminUserRecord {
createdAt?: string;
}
/** LLM provider/model configuration (GET/PUT /api/v1/admin/llm, planned M10). */
/** LLM provider/model configuration (GET/PUT /api/v1/admin/llm, design/04 §3.1).
* API key is never returned by the backend; provider is the wire protocol. */
export interface AdminLlmProvider {
id: string;
name: string;
provider: string;
baseUrl: string;
model: string;
multimodal: boolean;
@@ -433,11 +435,14 @@ export interface AutomationRunResult {
output: unknown;
}
/** POST /api/v1/admin/llm body. */
/** POST /api/v1/admin/llm body — saves a provider group to models.json and
* hot-reloads the running LLM stack (persisted + active). */
export interface LlmProviderRequest {
id?: string;
name: string;
baseUrl?: string;
name?: string;
provider?: string;
baseUrl: string;
apiKey?: string;
model: string;
multimodal?: boolean;
fallback?: string;