mirror of
https://github.com/agentscope-ai/ReMe.git
synced 2026-10-13 04:01:35 +00:00
* fix(dsh): support DeepSeek Harness 0.1.7-rc.2 * fix(dsh): preserve settings and validate live configuration * fix(dsh): recognize legacy ReMe guidance on resumed sessions * fix(dsh): keep live settings schema browser compatible * fix(dsh): preserve exact host validation with serializable forms
176 lines
5.3 KiB
JavaScript
176 lines
5.3 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import test from "node:test";
|
|
import { Context } from "@deepseek-ai/cordis";
|
|
import Loader from "@deepseek-ai/cordis-plugin-loader";
|
|
import z from "@deepseek-ai/schemastery";
|
|
import { Config, resolveConfig } from "../dist/config.js";
|
|
|
|
test("resolves the established ReMe host and port environment", () => {
|
|
const config = resolveConfig(
|
|
{},
|
|
{ REME_HOST: "memory.local", REME_PORT: "2444" },
|
|
);
|
|
assert.equal(config.endpoint, "http://memory.local:2444");
|
|
assert.equal(config.autoMemoryInterval, 5);
|
|
assert.equal(config.dreamCron, "0 23 * * *");
|
|
});
|
|
|
|
test("exports a Cordis schema that rejects invalid configuration", async () => {
|
|
const result = await Config["~standard"].validate({
|
|
autoMemoryInterval: "five",
|
|
});
|
|
assert.ok(result.issues?.length);
|
|
|
|
const valid = await Config["~standard"].validate({ language: "zh" });
|
|
assert.equal(valid.issues, undefined);
|
|
assert.equal(valid.value.autoMemoryInterval.get(), 5);
|
|
assert.equal(valid.value.shutdownTimeoutMs.get(), 5000);
|
|
assert.equal(resolveConfig(valid.value).language, "zh");
|
|
|
|
for (const input of [
|
|
{ endpoint: "not-a-url" },
|
|
{ endpoint: "http://localhost:bad-port" },
|
|
{ endpoint: "http://localhost:65536" },
|
|
{ endpoint: "http://[:::]" },
|
|
{ endpoint: "http://999.0.0.1" },
|
|
{ dreamCron: "every night" },
|
|
{ timezone: "Mars/Olympus" },
|
|
]) {
|
|
assert.throws(() => Config["~standard"].validate(input));
|
|
}
|
|
|
|
for (const timezone of [
|
|
"US/Pacific",
|
|
"US/Eastern",
|
|
"Etc/GMT+8",
|
|
"Etc/GMT-8",
|
|
]) {
|
|
const result = Config["~standard"].validate({ timezone });
|
|
assert.equal(result.issues, undefined);
|
|
assert.equal(result.value.timezone.get(), timezone);
|
|
}
|
|
});
|
|
|
|
test("volatile settings survive Host projection and browser schema rehydration", () => {
|
|
const fields = Object.entries(Config.dict).flatMap(([name, schema]) => {
|
|
if (!schema.meta.volatile) return [];
|
|
const plain = new z(schema.toJSON());
|
|
delete plain.meta.volatile;
|
|
return [[name, plain]];
|
|
});
|
|
const hostForm = z.object(Object.fromEntries(fields));
|
|
const browserForm = new z(JSON.parse(JSON.stringify(hostForm.toJSON())));
|
|
const defaults = Config["~standard"].validate({}).value;
|
|
const values = Object.fromEntries(
|
|
fields.map(([name]) => [name, defaults[name].get()]),
|
|
);
|
|
assert.equal(browserForm["~standard"].validate(values).issues, undefined);
|
|
assert.equal(
|
|
browserForm["~standard"].validate({ ...values, timezone: "US/Pacific" })
|
|
.issues,
|
|
undefined,
|
|
);
|
|
});
|
|
|
|
test("rejects unknown options and invalid IANA timezones", () => {
|
|
assert.throws(
|
|
() => resolveConfig({ autoMemoryIntervl: 3 }, {}),
|
|
/Unknown ReMe config option/,
|
|
);
|
|
assert.throws(
|
|
() => resolveConfig({ timezone: "Mars/Olympus" }, {}),
|
|
/Invalid ReMe timezone/,
|
|
);
|
|
assert.throws(
|
|
() => resolveConfig({ apiKey: "unsupported" }, {}),
|
|
/Unknown ReMe config option/,
|
|
);
|
|
});
|
|
|
|
test("normalizes bounded plugin configuration", () => {
|
|
const config = resolveConfig(
|
|
{
|
|
endpoint: "http://localhost:2333///",
|
|
language: "zh",
|
|
autoMemoryInterval: 0,
|
|
searchLimit: 100,
|
|
rootAgentsOnly: false,
|
|
},
|
|
{},
|
|
);
|
|
assert.equal(config.endpoint, "http://localhost:2333");
|
|
assert.equal(config.language, "zh");
|
|
assert.equal(config.autoMemoryInterval, 1);
|
|
assert.equal(config.searchLimit, 50);
|
|
assert.equal(config.rootAgentsOnly, false);
|
|
});
|
|
|
|
test("rejects settings that cannot be scheduled or reached", () => {
|
|
assert.throws(
|
|
() => resolveConfig({ endpoint: "file:///tmp/reme" }),
|
|
/absolute http/,
|
|
);
|
|
assert.throws(
|
|
() => resolveConfig({ dreamCron: "every night" }),
|
|
/daily form/,
|
|
);
|
|
});
|
|
|
|
test("Loader keeps the previous live values when an update fails schema validation", async () => {
|
|
const ctx = new Context();
|
|
let live;
|
|
try {
|
|
await ctx.plugin(Loader);
|
|
ctx.loader.builtins.remeTest = {
|
|
name: "reme-test",
|
|
Config,
|
|
apply(_owner, input) {
|
|
live = input;
|
|
},
|
|
};
|
|
const id = await ctx.loader.create({
|
|
id: "reme-memory",
|
|
name: "cordis:remeTest",
|
|
config: {
|
|
endpoint: "http://valid.test",
|
|
autoMemoryEnabled: false,
|
|
autoDreamEnabled: false,
|
|
timezone: "US/Pacific",
|
|
},
|
|
});
|
|
const entry = ctx.loader.resolve(id);
|
|
await entry.fiber.await();
|
|
for (const patch of [
|
|
{ endpoint: "not-a-url" },
|
|
{ endpoint: "http://localhost:65536" },
|
|
{ endpoint: "http://999.0.0.1" },
|
|
{ dreamCron: "every night" },
|
|
{ timezone: "Mars/Olympus" },
|
|
]) {
|
|
await entry.update({
|
|
config: {
|
|
endpoint: "http://valid.test",
|
|
autoMemoryEnabled: true,
|
|
autoDreamEnabled: false,
|
|
timezone: "US/Pacific",
|
|
...patch,
|
|
},
|
|
});
|
|
assert.equal(live.endpoint.get(), "http://valid.test");
|
|
assert.equal(live.autoMemoryEnabled.get(), false);
|
|
assert.equal(live.dreamCron.get(), "0 23 * * *");
|
|
assert.equal(live.timezone.get(), "US/Pacific");
|
|
}
|
|
await entry.update({
|
|
config: {
|
|
endpoint: "http://updated.test",
|
|
autoMemoryEnabled: false,
|
|
autoDreamEnabled: false,
|
|
timezone: "US/Pacific",
|
|
},
|
|
});
|
|
assert.equal(live.endpoint.get(), "http://updated.test");
|
|
} finally {
|
|
await ctx.fiber.dispose();
|
|
}
|
|
});
|