主世界层直接写正文,转述与旁观改读用户展示输出。

去掉裁决包主路径,让无转述时可直出终稿、有转述时再改写镶壳。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-10 02:18:14 +08:00
co-authored by Cursor
parent d65ebbce8b
commit 3d720f23fe
27 changed files with 290 additions and 216 deletions
+4 -4
View File
@@ -280,14 +280,14 @@ describe("context-order.v1", () => {
template: {
id: "world-simulator",
label: "主世界层",
duty: "裁决",
duty: "写正文",
suggested_context: { static: ["设计.worker集"], dynamic: ["用户.最新输入"] },
},
workerSet: parsed,
});
expect(worker.contextSegments?.some((s) => s.inline?.includes("裁决"))).toBe(
true,
);
expect(
worker.contextSegments?.some((s) => s.inline?.includes("正文")),
).toBe(true);
expect(
worker.contextSegments?.some(
(s) => s.tier === "dynamic" && s.tags.includes("用户.最新输入"),
+13 -3
View File
@@ -5,6 +5,8 @@ import {
parseShellAdaptationFromReplyFormat,
presentFromPlainText,
presentOutputFromFallback,
isPlayFinalVisibleWorker,
isPlayGmBodyWorker,
isPlayPresentWorker,
shellDefaultRegions,
} from "../src/skills/present-packet.js";
@@ -118,16 +120,24 @@ describe("shell adaptation from reply-format", () => {
});
describe("play present worker", () => {
it("recognizes narrator, round-present, and solo gm", () => {
it("structured present only for narrator / round-present", () => {
expect(isPlayPresentWorker("narrator")).toBe(true);
expect(isPlayPresentWorker("round-present")).toBe(true);
expect(isPlayPresentWorker("world-simulator")).toBe(false);
});
it("gm body worker and final visible roles", () => {
expect(isPlayGmBodyWorker("world-simulator")).toBe(true);
expect(isPlayGmBodyWorker("narrator")).toBe(false);
expect(
isPlayPresentWorker("world-simulator", { narratorEnabled: false }),
isPlayFinalVisibleWorker("world-simulator", { narratorEnabled: false }),
).toBe(true);
expect(
isPlayPresentWorker("world-simulator", { narratorEnabled: true }),
isPlayFinalVisibleWorker("world-simulator", { narratorEnabled: true }),
).toBe(false);
expect(
isPlayFinalVisibleWorker("narrator", { narratorEnabled: true }),
).toBe(true);
});
it("fallback packet uses the given shell", () => {
+5 -5
View File
@@ -18,7 +18,7 @@ workers:
- 用户.最新输入
- 运行.事件流
outputs:
- 运行.本轮.裁决
- 输出.用户展示
- 运行.事件流
- ref: narrator
duty: 组装用户可见回复
@@ -30,14 +30,14 @@ workers:
static:
- 叙事.指南.确认稿
dynamic:
- 运行.事件流
- 输出.用户展示
outputs:
- 输出.用户展示
instantiate_hints:
invoke: [opening-generator]
tag_flow:
- "用户.最新输入 → 运行.本轮.裁决"
- "运行.本轮.裁决 → 输出.用户展示"
- "用户.最新输入 → 输出.用户展示"
- "输出.用户展示 → 输出.用户展示(转述终稿)"
`;
describe("formatWorkerSetForUser", () => {
@@ -62,7 +62,7 @@ describe("formatWorkerSetForUser", () => {
false,
);
expect(view.workers[0].context.staticTags[0].tag).toBe("设计.worker集");
expect(view.workers[0].writes).toEqual(["运行.本轮.裁决", "运行.事件流"]);
expect(view.workers[0].writes).toEqual(["输出.用户展示", "运行.事件流"]);
expect(view.workers[0].context.explicit).toBe(true);
expect(view.workers[1].presentation?.[0].label).toBe("语气");
expect(view.tagFlow).toHaveLength(2);