接入AGC后台模型目录与对话模型选择
新增后台 AGC 模型目录、别名、启停和默认项管理 客户端设置页恢复原状,对话框右下角按别名选择模型 服务端按稳定模型标识映射并校验实际模型白名单 修复 AGC 配套后端端口漂移、启动等待和 SpacetimeDB 版本检查 补充迁移、文档、启动与模型选择测试
This commit is contained in:
@@ -649,9 +649,30 @@ function readSpacetimeToolProvenance() {
|
||||
if (!version) {
|
||||
throw new Error(`无法解析 spacetime 版本输出: ${trimPreview(output)}`);
|
||||
}
|
||||
const standalone = spawnSync('spacetimedb-standalone', ['--version'], {
|
||||
cwd: repoRoot,
|
||||
encoding: 'utf8',
|
||||
timeout: 5000,
|
||||
shell: process.platform === 'win32',
|
||||
});
|
||||
// Some installations keep the host inside the version manager rather than PATH.
|
||||
if (!standalone.error && standalone.status === 0) {
|
||||
const standaloneVersion = parseSpacetimeToolVersion(
|
||||
`${standalone.stdout ?? ''}\n${standalone.stderr ?? ''}`,
|
||||
);
|
||||
assertStandaloneVersionMatchesCli(version, standaloneVersion);
|
||||
}
|
||||
return { version, commit: parseSpacetimeToolCommit(output) };
|
||||
}
|
||||
|
||||
function assertStandaloneVersionMatchesCli(cliVersion, standaloneVersion) {
|
||||
if (!standaloneVersion || standaloneVersion !== cliVersion) {
|
||||
throw new Error(
|
||||
`spacetime CLI 为 ${cliVersion},但 PATH 中的 spacetimedb-standalone 为 ${standaloneVersion || 'unknown'};请同时更新宿主可执行文件或软链接后重试,不能只更新 CLI。`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function assertSpacetimeToolVersionMatchesWorkspace({
|
||||
toolVersion,
|
||||
toolCommit = '',
|
||||
@@ -1438,6 +1459,7 @@ class DevRunner {
|
||||
|
||||
if (
|
||||
command === 'all' ||
|
||||
command === 'backend' ||
|
||||
command === 'api-server' ||
|
||||
command === 'bgfilter-worker'
|
||||
) {
|
||||
@@ -3460,6 +3482,7 @@ export {
|
||||
applyLocalFfmpegEnv,
|
||||
assertReusableSpacetimeProcessVersionMatchesWorkspace,
|
||||
assertSpacetimeToolVersionMatchesWorkspace,
|
||||
assertStandaloneVersionMatchesCli,
|
||||
buildApiServerProcessEnv,
|
||||
buildBgfilterWorkerProcessEnv,
|
||||
buildDevStackSnapshot,
|
||||
|
||||
@@ -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 路径下的直接执行入口也能识别为当前模块', () => {
|
||||
|
||||
Reference in New Issue
Block a user