Files
WeChat-AI/apps/api/src/shipped-defaults.test.ts
T

125 lines
4.3 KiB
TypeScript

import assert from "node:assert/strict";
import { describe, it } from "node:test";
import { loadConfig } from "./config.js";
import { planInboundMedia, unreadableMediaReply } from "./inbound-media.js";
/**
* Guards the shipped-off state of optional features.
*
* Image understanding costs tokens on every picture and needs a vision endpoint
* that most deployments do not have, so it must stay off unless an operator
* explicitly turns it on. A test is the only way that stays true — a default in
* a 400-line config function is one careless edit away from flipping.
*/
/** Nothing set: exactly what a fresh checkout with no .env gets. */
const bare = () => loadConfig({} as NodeJS.ProcessEnv);
describe("shipped defaults: image understanding is off", () => {
it("visionEnabled is false with no env at all", () => {
assert.equal(bare().visionEnabled, false);
});
it("only the exact string \"true\" enables it", () => {
for (const raw of ["1", "yes", "on", "TRUE", "True", " true", "true "]) {
assert.equal(
loadConfig({ VISION_ENABLED: raw } as NodeJS.ProcessEnv).visionEnabled,
false,
`VISION_ENABLED=${JSON.stringify(raw)} must not enable vision`,
);
}
assert.equal(
loadConfig({ VISION_ENABLED: "true" } as NodeJS.ProcessEnv).visionEnabled,
true,
);
});
it("ships with no vision endpoint or model configured", () => {
const cfg = bare();
assert.equal(cfg.visionModel, "");
assert.equal(cfg.visionBaseUrl, "");
assert.equal(cfg.visionApiKey, "");
});
it("downloads nothing while it is off, whatever arrives", () => {
const refs = [
{ kind: "image" as const, index: 0, encryptQueryParam: "a" },
{ kind: "image" as const, index: 1, encryptQueryParam: "b" },
{ kind: "voice" as const, index: 2, encryptQueryParam: "c" },
{ kind: "video" as const, index: 3, encryptQueryParam: "d" },
{ kind: "file" as const, index: 4, encryptQueryParam: "e" },
];
const cfg = bare();
const plan = planInboundMedia(refs, {
visionEnabled: cfg.visionEnabled,
maxImages: cfg.visionMaxImages,
});
assert.equal(
plan.filter((p) => p.download).length,
0,
"no CDN fetch may happen while vision is off",
);
});
it("answers an image with a canned line, costing no model call", () => {
const reply = unreadableMediaReply([
{ kind: "image", index: 0, encryptQueryParam: "a" },
]);
assert.match(reply, /看不了图片/);
});
it("defaults the mode to caption, so turning it on never needs a vision-capable roleplay model", () => {
// Only matters once someone sets VISION_ENABLED=true, but the safe mode has
// to be the default one — `direct` errors outright on a text-only model.
assert.equal(bare().visionMode, "caption");
});
});
describe("shipped defaults: WeChat's own voice transcript is ON", () => {
it("is enabled with no env at all", () => {
// Deliberately opposite to vision: the transcript arrives inside the inbound
// message, so using it costs nothing and needs no model.
assert.equal(bare().voiceTranscriptEnabled, true);
});
it("only the exact string \"false\" disables it", () => {
for (const raw of ["0", "no", "off", "FALSE", "False", " false"]) {
assert.equal(
loadConfig({ VOICE_TRANSCRIPT_ENABLED: raw } as NodeJS.ProcessEnv)
.voiceTranscriptEnabled,
true,
`VOICE_TRANSCRIPT_ENABLED=${JSON.stringify(raw)} must not disable it`,
);
}
assert.equal(
loadConfig({ VOICE_TRANSCRIPT_ENABLED: "false" } as NodeJS.ProcessEnv)
.voiceTranscriptEnabled,
false,
);
});
it("is independent of the vision switch", () => {
const cfg = bare();
assert.equal(cfg.visionEnabled, false);
assert.equal(cfg.voiceTranscriptEnabled, true);
});
});
describe("shipped defaults: other optional features stay off", () => {
it("proactive outreach is off", () => {
assert.equal(bare().proactiveEnabled, false);
});
it("web search is off", () => {
assert.equal(bare().webSearchEnabled, false);
});
it("the second-pass reply filter is off", () => {
assert.equal(bare().replyFilterEnabled, false);
});
it("unapproved users cannot chat", () => {
assert.equal(bare().allowUnapproved, false);
});
});