接入AGC后台模型目录与对话模型选择

新增后台 AGC 模型目录、别名、启停和默认项管理

客户端设置页恢复原状,对话框右下角按别名选择模型

服务端按稳定模型标识映射并校验实际模型白名单

修复 AGC 配套后端端口漂移、启动等待和 SpacetimeDB 版本检查

补充迁移、文档、启动与模型选择测试
This commit is contained in:
2026-09-05 19:10:49 +08:00
parent 76f0c8e58e
commit 4f3f0f24ff
52 changed files with 1942 additions and 1544 deletions
+38
View File
@@ -10,6 +10,7 @@ import {
symlinkSync,
writeFileSync,
} from 'node:fs';
import { createServer } from 'node:net';
import { tmpdir } from 'node:os';
import { dirname, join, resolve } from 'node:path';
@@ -18,6 +19,7 @@ import { afterEach, describe, expect, test, vi } from 'vitest';
import {
assertReusableSpacetimeProcessVersionMatchesWorkspace,
assertSpacetimeToolVersionMatchesWorkspace,
assertStandaloneVersionMatchesCli,
buildApiServerProcessEnv,
buildBgfilterWorkerProcessEnv,
buildDevStackSnapshot,
@@ -59,6 +61,42 @@ function workspaceSpacetimeVersionForTest() {
}
describe('dev scheduler argument routing', () => {
test('拒绝 CLI 已升级但 standalone 仍为旧版本的工具链', () => {
expect(() => assertStandaloneVersionMatchesCli('2.8.3', '2.7.0')).toThrow(
'不能只更新 CLI',
);
expect(() =>
assertStandaloneVersionMatchesCli('2.8.3', '2.8.3'),
).not.toThrow();
});
test('backend 模式避开已占用的 worker 端口并同步代理目标', async () => {
const occupied = createServer();
await new Promise<void>((resolveReady) =>
occupied.listen(0, '127.0.0.1', resolveReady),
);
const address = occupied.address();
if (!address || typeof address === 'string')
throw new Error('监听地址无效');
try {
const { command, explicitOptions, options } = parseArgs(['backend'], {});
options.apiPort = 0;
options.bgfilterWorkerPort = address.port;
const runner = new DevRunner(options, {}, explicitOptions);
runner.state.spacetimeReused = true;
await runner.resolvePorts(command);
expect(runner.options.bgfilterWorkerPort).not.toBe(address.port);
expect(runner.options.bgfilterWorkerPort).not.toBe(
runner.options.apiPort,
);
expect(runner.state.bgfilterWorkerTarget).toBe(
`http://127.0.0.1:${runner.options.bgfilterWorkerPort}`,
);
} finally {
await new Promise<void>((resolveClosed) =>
occupied.close(() => resolveClosed()),
);
}
});
const linuxTest = process.platform === 'linux' ? test : test.skip;
test('Windows junction 路径下的直接执行入口也能识别为当前模块', () => {