mirror of
https://github.com/merlinhu1/codex-game-studio.git
synced 2026-08-25 07:54:34 +02:00
* feat: add deterministic model tier routing Define Sol, Terra, and Luna policies with fixed fallbacks, explicit surface assignments, runtime precedence, and Luna escalation. Validate generated metadata and expose tier overrides across role, task, and orchestration commands. * fix: infer model tiers from surface models * fix: rebalance prompt model routing * fix: decouple prompt effort routing --------- Co-authored-by: MerlinH <merlinh221@gmail.com>
98 lines
5.3 KiB
TypeScript
98 lines
5.3 KiB
TypeScript
import { describe, test } from "node:test";
|
|
import { expect } from "expect";
|
|
import {
|
|
isCodexModelName,
|
|
modelPolicyForTier,
|
|
modelTierForModel,
|
|
parsePromptSurfaceFrontmatter,
|
|
resolveModelRoute,
|
|
validateAgentDescriptionQuality,
|
|
validateModelPolicy,
|
|
validateSkillDescriptionQuality,
|
|
validateWorkflowArgumentHintQuality
|
|
} from "../src/prompt-surface-metadata.js";
|
|
|
|
describe("prompt surface metadata", () => {
|
|
test("maps stable model tiers to primary and safe fallback defaults", () => {
|
|
expect(modelPolicyForTier("sol")).toEqual({
|
|
tier: "sol",
|
|
primary: { model: "gpt-5.6-sol", effort: "high" },
|
|
fallback: { model: "gpt-5.5", effort: "high" }
|
|
});
|
|
expect(modelPolicyForTier("terra")).toEqual({
|
|
tier: "terra",
|
|
primary: { model: "gpt-5.6-terra", effort: "medium" },
|
|
fallback: { model: "gpt-5.4", effort: "medium" }
|
|
});
|
|
expect(modelPolicyForTier("luna")).toEqual({
|
|
tier: "luna",
|
|
primary: { model: "gpt-5.6-luna", effort: "low" },
|
|
fallback: { model: "gpt-5.4-mini", effort: "low" }
|
|
});
|
|
});
|
|
|
|
test("infers surface tiers while preserving per-surface reasoning effort", () => {
|
|
expect(resolveModelRoute({ surfaceModel: "gpt-5.6-terra", surfaceEffort: "low" })).toMatchObject({ tier: "terra", source: "surface", primary: { model: "gpt-5.6-terra", effort: "low" }, fallback: { model: "gpt-5.4", effort: "low" } });
|
|
expect(resolveModelRoute({ surfaceModel: "gpt-5.6-luna", surfaceEffort: "medium", requestedTier: "sol" })).toMatchObject({ tier: "sol", source: "explicit-tier", primary: { model: "gpt-5.6-sol", effort: "medium" } });
|
|
expect(modelTierForModel("gpt-5.5")).toBe("sol");
|
|
expect(modelTierForModel("gpt-5.4")).toBe("terra");
|
|
expect(modelTierForModel("gpt-5.4-mini")).toBe("luna");
|
|
});
|
|
|
|
test("rejects unregistered models and invalid reasoning effort values without coupling the two", () => {
|
|
for (const valid of ["gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna", "gpt-5.5", "gpt-5.4", "gpt-5.4-mini"]) expect(isCodexModelName(valid)).toBe(true);
|
|
for (const invalid of ["sonnet", "haiku", "opus", "claude-3.5-sonnet", "complex", "moderate", "simple", "gpt5.5"]) {
|
|
expect(isCodexModelName(invalid)).toBe(false);
|
|
expect(validateModelPolicy({ model: invalid, model_reasoning_effort: "high" }).valid).toBe(false);
|
|
}
|
|
expect(validateModelPolicy({ model: "gpt-5.6-sol", model_reasoning_effort: "medium" }).valid).toBe(true);
|
|
expect(validateModelPolicy({ model: "gpt-5.6-luna", model_reasoning_effort: "high" }).valid).toBe(true);
|
|
expect(validateModelPolicy({ model: "gpt-5.6-sol" }).issues).toContain("missing reasoning effort");
|
|
expect(validateModelPolicy({ model: "gpt-5.6-sol", model_reasoning_effort: "extreme" }).issues).toContain("invalid reasoning effort: extreme");
|
|
});
|
|
|
|
test("parses markdown frontmatter", () => {
|
|
const parsed = parsePromptSurfaceFrontmatter(`---\nname: cgs-prototype\nmodel: gpt-5.6-sol\nmodel_reasoning_effort: high\nrelated-agents: [producer, qa-playtester]\n---\n\n# Body`);
|
|
expect(parsed.frontmatter.model_tier).toBeUndefined();
|
|
expect(parsed.frontmatter.model).toBe("gpt-5.6-sol");
|
|
expect(parsed.frontmatter.model_reasoning_effort).toBe("high");
|
|
expect(parsed.body).toContain("# Body");
|
|
});
|
|
|
|
test("flags generic agent descriptions and accepts selection-oriented ownership metadata", () => {
|
|
const generic = validateAgentDescriptionQuality("Game development Game Designer agent for game-designer tasks in this template repository.", "game-designer");
|
|
expect(generic.valid).toBe(false);
|
|
expect(generic.diagnostics.map((diagnostic) => diagnostic.id)).toContain("prompt.discovery.agent.generic_description");
|
|
|
|
const specific = validateAgentDescriptionQuality(
|
|
"Owns implementable gameplay mechanics, tuning values, edge cases, and player-facing acceptance criteria for bounded feature design; hand off production scope or QA evidence decisions.",
|
|
"game-designer"
|
|
);
|
|
expect(specific.valid).toBe(true);
|
|
});
|
|
|
|
test("flags non-actionable skill descriptions and accepts trigger/outcome metadata", () => {
|
|
const generic = validateSkillDescriptionQuality("Use for Codex Game Studio prototype work.", "cgs-prototype");
|
|
expect(generic.valid).toBe(false);
|
|
expect(generic.diagnostics.map((diagnostic) => diagnostic.id)).toContain("prompt.discovery.skill.vague_description");
|
|
|
|
const specific = validateSkillDescriptionQuality(
|
|
"Use for prototype experiments: define a falsifiable gameplay hypothesis, throwaway boundary, success signal, cleanup plan, and verification evidence.",
|
|
"cgs-prototype"
|
|
);
|
|
expect(specific.valid).toBe(true);
|
|
});
|
|
|
|
test("flags generic workflow argument hints and accepts workflow-specific input guidance", () => {
|
|
const generic = validateWorkflowArgumentHintQuality("Describe the vertical-slice goal, target milestone/files, constraints, and required evidence.", "vertical-slice");
|
|
expect(generic.valid).toBe(false);
|
|
expect(generic.diagnostics.map((diagnostic) => diagnostic.id)).toContain("prompt.discovery.workflow.generic_argument_hint");
|
|
|
|
const specific = validateWorkflowArgumentHintQuality(
|
|
"Provide the playable slice goal, milestone target, involved scenes/assets/code paths, scope constraints, acceptance gates, and required build or playtest evidence.",
|
|
"vertical-slice"
|
|
);
|
|
expect(specific.valid).toBe(true);
|
|
});
|
|
});
|