narraeon 0.7.10 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/dist/node/protocol/modelConnections.js +15 -0
  2. package/dist/node/protocol/modelUsage.js +4 -0
  3. package/dist/node/protocol/sillyTavernContent.js +1 -0
  4. package/dist/node/protocol/v1.js +97 -0
  5. package/dist/node/runtime/V1Runtime.js +105 -3
  6. package/dist/node/runtime/authoring/AuthoringEditPlan.js +79 -0
  7. package/dist/node/runtime/authoring/AuthoringRequestSnapshot.js +15 -3
  8. package/dist/node/runtime/authoring/AuthoringRetry.js +59 -0
  9. package/dist/node/runtime/authoring/DamagedGoogleContinuation.js +68 -0
  10. package/dist/node/runtime/authoring/ModelToolConversation.js +66 -25
  11. package/dist/node/runtime/content/ContentWorkspace.js +10 -2
  12. package/dist/node/runtime/content/CurrentTreeContentLibrary.js +14 -8
  13. package/dist/node/runtime/content/SillyTavernContent.js +796 -0
  14. package/dist/node/runtime/model/AiFailureLog.js +8 -1
  15. package/dist/node/runtime/model/DispatchFailure.js +8 -0
  16. package/dist/node/runtime/model/FileNativeModelAdapters.js +627 -18
  17. package/dist/node/runtime/model/GoogleHopJournal.js +90 -0
  18. package/dist/node/runtime/model/GoogleInteractionsStream.js +242 -0
  19. package/dist/node/runtime/model/GoogleRequestPreview.js +184 -0
  20. package/dist/node/runtime/model/ModelConnectionStore.js +4 -1
  21. package/dist/node/runtime/model/ProviderExchangeState.js +44 -1
  22. package/dist/node/runtime/model/ProviderStream.js +4 -2
  23. package/dist/node/runtime/play/FileNativePlayAdvanceStore.js +4 -4
  24. package/dist/node/runtime/play/FileNativePlayPresetStore.js +150 -78
  25. package/dist/node/runtime/play/FileNativePlayTimelineStore.js +199 -10
  26. package/dist/node/runtime/play/OrderedPlayPrompts.js +139 -178
  27. package/dist/node/runtime/play/PlayAdvanceLifecycle.js +51 -23
  28. package/dist/node/runtime/play/PlayCallChain.js +92 -8
  29. package/dist/node/runtime/play/PlayFollowupRequests.js +23 -3
  30. package/dist/node/runtime/prompt/PromptCompilationCodec.js +2 -1
  31. package/dist/node/runtime/setting/FileNativeSettingImprovementStore.js +321 -15
  32. package/dist/node/runtime/setting/SettingImprovementSession.js +285 -21
  33. package/dist/node/runtime/world-revision/FileNativeWorldRevisionStore.js +236 -15
  34. package/dist/node/runtime/world-revision/WorldRevisionSession.js +324 -50
  35. package/dist/node/runtime/world-revision/WorldRevisionWorkspace.js +47 -1
  36. package/dist/node/shared/application-preset-files.js +29 -0
  37. package/dist/node/shared/default-preset-host.js +50 -38
  38. package/dist/node/shared/first-party-action-choices.js +7 -11
  39. package/dist/node/shared/first-party-generic-panels.js +7 -11
  40. package/dist/node/shared/first-party-player-view.js +7 -11
  41. package/dist/node/shared/ordered-author-prompts.js +6 -4
  42. package/dist/node/shared/ordered-play-prompts.js +4 -2
  43. package/dist/node/shared/prompt-arrangement.js +205 -0
  44. package/dist/node/shared/sillytavern-preset.js +454 -0
  45. package/dist/web/assets/index-BthiDIQu.js +1432 -0
  46. package/dist/web/assets/{index-DH2BVsYd.css → index-wO9Y4HT1.css} +1 -1
  47. package/dist/web/index.html +2 -2
  48. package/package.json +1 -1
  49. package/dist/web/assets/index-B2kbaOGe.js +0 -1408
@@ -0,0 +1,29 @@
1
+ import { stringify } from "yaml";
2
+ /** App-owned defaults contain declarations, never copies of the prompt catalog. */
3
+ export function applicationPresetFilesForLocale(locale) {
4
+ return {
5
+ "preset.yaml": stringify({
6
+ format: "narraeon.play-preset/v3",
7
+ name: locale === "zh-CN" ? "系统推荐" : "System recommended",
8
+ callChain: "call-chain.yaml",
9
+ playPrompts: {},
10
+ authorPrompts: {},
11
+ mergeConsecutiveMessages: false,
12
+ mounts: [],
13
+ extensions: [],
14
+ }),
15
+ "call-chain.yaml": "format: narraeon.play-call-chain/v1\nnarrative: []\nfollowups: []\n",
16
+ "frame.yaml": `format: narraeon.host-frame/v1
17
+ roles:
18
+ runtime_system:
19
+ - builtin: runtime.play-contract
20
+ - builtin: runtime.tool-contract
21
+ - builtin: runtime.operation-contract
22
+ author_instruction:
23
+ - include: world.instructions
24
+ world_context:
25
+ - include: world.context
26
+ - builtin: runtime.coverage
27
+ `,
28
+ };
29
+ }
@@ -51,23 +51,23 @@ roles:
51
51
  `,
52
52
  "blocks/person-second.md": `# 人称:第二人称
53
53
 
54
- 玩家可见叙事以第二人称“你”称呼玩家角色。玩家的知觉、动作和话语都以“你”写出;其他人物按名字或第三人称称呼。观察视角跟随玩家角色,不写他无法感知的事。
54
+ 玩家可见叙事以第二人称"你"称呼玩家角色。玩家的知觉、动作和话语都以"你"写出;其他人物按名字或第三人称称呼。观察视角跟随玩家角色,不写他无法感知的事。
55
55
  `,
56
56
  "blocks/person-first.md": `# 人称:第一人称
57
57
 
58
- 玩家可见叙事以第一人称“我”写玩家角色,像玩家角色自己在讲述。知觉、判断和情绪只能是“我”能感知到的;其他人物按名字或第三人称称呼。叙述口吻贴近玩家角色已经建立的性格,不替他下结论或表态。本块启用时取代第二人称的要求。
58
+ 玩家可见叙事以第一人称"我"写玩家角色,像玩家角色自己在讲述。知觉、判断和情绪只能是"我"能感知到的;其他人物按名字或第三人称称呼。叙述口吻贴近玩家角色已经建立的性格,不替他下结论或表态。本块启用时取代第二人称的要求。
59
59
  `,
60
60
  "blocks/person-third.md": `# 人称:第三人称
61
61
 
62
- 玩家可见叙事以第三人称写玩家角色:已知名字时用名字,否则用与其性别一致的“他/她”,并与其他人物明确区分。观察视角仍跟随玩家角色,不越入其他人物未表露的内心。玩家原文里的“我”“你”在正文中转为相应的第三人称。本块启用时取代第二人称的要求。
62
+ 玩家可见叙事以第三人称写玩家角色:已知名字时用名字,否则用与其性别一致的"他/她",并与其他人物明确区分。观察视角仍跟随玩家角色,不越入其他人物未表露的内心。玩家原文里的"我""你"在正文中转为相应的第三人称。本块启用时取代第二人称的要求。
63
63
  `,
64
64
  "blocks/continue-stage.md": `# 承接:先演玩家行动
65
65
 
66
- 玩家原文是玩家对本轮行动和台词的简写,不是已经成立的小说正文。玩家页面上它以“你”的身份单独显示,正文里还没有它。
66
+ 玩家原文是玩家对本轮行动和台词的简写,不是已经成立的小说正文。玩家页面上它以"你"的身份单独显示,正文里还没有它。
67
67
 
68
68
  ## 先写玩家做了什么
69
69
 
70
- 每段正文先把玩家这次的行动和台词以叙事方式写出来:动作怎样完成、话怎样说出口、周围的人和环境此刻的样子,然后才写世界的反应。台词可以保留原话,也可以按人物口吻微调措辞,不改变意思、立场和承诺。不用“你说要……”式的旁白转述代替演出。
70
+ 每段正文先把玩家这次的行动和台词以叙事方式写出来:动作怎样完成、话怎样说出口、周围的人和环境此刻的样子,然后才写世界的反应。台词可以保留原话,也可以按人物口吻微调措辞,不改变意思、立场和承诺。不用"你说要……"式的旁白转述代替演出。
71
71
 
72
72
  ## 分量
73
73
 
@@ -75,7 +75,7 @@ roles:
75
75
  `,
76
76
  "blocks/continue-advance.md": `# 承接:直接推进
77
77
 
78
- 玩家原文已经是正文的一部分:玩家页面上它以“你”的身份显示,玩家刚读过。不要把它再演一遍。本块启用时取代“先演玩家行动”的要求。
78
+ 玩家原文已经是正文的一部分:玩家页面上它以"你"的身份显示,玩家刚读过。不要把它再演一遍。本块启用时取代"先演玩家行动"的要求。
79
79
 
80
80
  ## 从下一件事写起
81
81
 
@@ -83,7 +83,7 @@ roles:
83
83
 
84
84
  ## 必要的衔接
85
85
 
86
- 输入只是简写(“我去找他”)、不交代过程就无法呈现结果时,用最短的衔接把它落到场景里,不扩写玩家的动作和话语本身。
86
+ 输入只是简写("我去找他")、不交代过程就无法呈现结果时,用最短的衔接把它落到场景里,不扩写玩家的动作和话语本身。
87
87
  `,
88
88
  "blocks/agency-default.md": `# 代理权:默认
89
89
 
@@ -91,11 +91,11 @@ roles:
91
91
 
92
92
  ## 可以替玩家补什么
93
93
 
94
- 在已表达的选择内补足动作衔接、不改变实质的措辞和自然感官。“我去找他”这类日常简写允许开始并完成通常的连带动作:穿过走廊、敲门、把东西递过去不必逐项确认。寒暄可以替玩家接,但不能暗中承诺新事项。
94
+ 在已表达的选择内补足动作衔接、不改变实质的措辞和自然感官。"我去找他"这类日常简写允许开始并完成通常的连带动作:穿过走廊、敲门、把东西递过去不必逐项确认。寒暄可以替玩家接,但不能暗中承诺新事项。
95
95
 
96
96
  ## 在哪里交回玩家
97
97
 
98
- 途中出现玩家没有表达过的新风险、交易或关键选择时,停在需要玩家决定的位置。不能把“去找他”扩展成提出新请求、答应他的条件或交出物品;NPC 的提议或追问也不构成玩家尚未表达的目标与话语。拿不准时保留决定空间;不能以“下次还能改口”为理由替玩家确立当前选择。
98
+ 途中出现玩家没有表达过的新风险、交易或关键选择时,停在需要玩家决定的位置。不能把"去找他"扩展成提出新请求、答应他的条件或交出物品;NPC 的提议或追问也不构成玩家尚未表达的目标与话语。拿不准时保留决定空间;不能以"下次还能改口"为理由替玩家确立当前选择。
99
99
 
100
100
  ## 感官不是态度
101
101
 
@@ -105,7 +105,7 @@ roles:
105
105
 
106
106
  正文只演玩家原文明确写出的动作和台词。本块启用时取代其他代理权块。
107
107
 
108
- 连带动作只做到原文说到的地方:说“去找他”就写到走到门口,敲门和开口都交回玩家;说“把信递过去”就写到递出,对方接不接和玩家接下来说什么留给下一轮。不替玩家补台词、寒暄或回应,不替玩家做任何选择。
108
+ 连带动作只做到原文说到的地方:说"去找他"就写到走到门口,敲门和开口都交回玩家;说"把信递过去"就写到递出,对方接不接和玩家接下来说什么留给下一轮。不替玩家补台词、寒暄或回应,不替玩家做任何选择。
109
109
 
110
110
  玩家角色的自然感官和已有事实造成的身体经验可以直接写;心跳、脸红、僵住或发不出声不能替他确立爱慕、恐惧、认同、同意、拒绝或新的行动选择。不替玩家生成未表达的感情。世界外查询或文档维护不构成角色的新决定。
111
111
  `,
@@ -132,6 +132,8 @@ roles:
132
132
  "blocks/ending.md": `# 结尾
133
133
 
134
134
  结尾停在实际发生的最后一句话、一个动作或一个环境变化上。不写“轮到你了”“你打算怎么做”及“众人等你开口”一类的交接句,不在结尾列选项,不重复总结局势,不为了收尾让 NPC 硬添动作、邀请或承诺。真正发生的注视或等待可以描写。
135
+
136
+ 一件事自然结束时,也可以就停在那里,不必再添一句话或一个动作来等玩家接续。
135
137
  `,
136
138
  "blocks/output.md": `# 输出边界
137
139
 
@@ -139,7 +141,7 @@ roles:
139
141
 
140
142
  本轮新发生且玩家能感知的结果要成为具体可读的事:物品怎样递接、人物如何离开、态度变化怎样在话语或行动中显露。界面数值不能代替事件表现,叙事也不能与当前值冲突。文档中补录旧结果、去重和整理不要求再次演出;未向玩家表露的判断和场外事实无需用旁白揭露。
141
143
 
142
- 工具、目录、文档、句柄、检索、命中、Runtime 及失败过程只供私下裁决;正文不得出现“没搜到/没找到资料”等内部措辞,信息不足时保持世界内的不确定性。
144
+ 工具、目录、文档、句柄、检索、命中、Runtime 及失败过程只供私下裁决;正文不得出现"没搜到/没找到资料"等内部措辞,信息不足时保持世界内的不确定性。
143
145
 
144
146
  本次只有世界外查询或维护时,按请求简洁回答或说明整理结果,不为满足小说形式添加动作、对话或时间推进。混合请求中的维护要求不成为角色台词或行动。
145
147
  `,
@@ -206,9 +208,13 @@ summary 是目录简介,用于识别文档和判断是否需要读取。只写
206
208
  `,
207
209
  "blocks/checkpoint-policy.md": `# 检查点政策
208
210
 
209
- world_checkpoint 只用于事件之间的间隙:上一事件已在本轮停笔位置自然告一段落,或场景已实际转换,接下来从全新上下文开始也不会丢失仍然重要的细节。登记前核对上次检查点后的交互,把刚结束事件中后续仍需要的结果写入文档,包括当前状态、重要认知、承诺与待办和界面值;全新上下文只补入检查点之后的原文,上一事件的经过不会再出现。
211
+ world_checkpoint 只用于事件之间的间隙。一次对话、交易、冲突或活动自然结束,或场景已经转换、前一段事情告一段落时,可以登记检查点。地点改变、时间推进、在场者更换都是典型线索,但追逐穿过街道仍是同一场活动。事件结束不意味着无话可接,告别后还可以道谢,一件事办完后也可以接着谈下一件事。
212
+
213
+ 登记前核对上次检查点后的交互,把后续仍需要的结果保存下来,包括当前状态、重要认知、承诺与待办和界面值,让接下来的互动不必依赖前一阶段的全部过程。新上下文按现有历史配置承接近期叙事,更早仍需要的信息应已保存。
214
+
215
+ 玩家通过本轮要求表达「在此收尾」时,结合玩家输入按这个意图完成收束和保存,再登记检查点,不代玩家作出无关决定。
210
216
 
211
- 持续活动中途、对方刚给出需要玩家回应的反馈,或仍有待玩家决定的事项时,不登记。整理不等于检查点,整理随时可做且不需要登记。检查点只标记已经出现的间隙,不是本轮目标:不为了到达间隙而加快节奏、压缩过程、替玩家完成玩家没有表达的步骤或提前结束事件。登记后若叙事又增加重要结果,继续工具调用补齐。
217
+ 持续活动尚在进行,或当前事情还等着玩家作出决定、给出关键回应时,不因普通停笔或整理完成而登记。整理随时可做,不等于检查点。检查点不是本轮目标,不要为了登记而加快节奏、压缩过程、替玩家完成未表达的步骤或提前结束事件。登记后若又有需要保存的结果,继续工具调用补齐,再提交最终正文。
212
218
  `,
213
219
  "blocks/style-intimate.md": `# 文风:情感与亲密
214
220
 
@@ -216,15 +222,15 @@ world_checkpoint 只用于事件之间的间隙:上一事件已在本轮停笔
216
222
 
217
223
  ## 把那一刻拆开
218
224
 
219
- 不要跳过过程直接给结论。“你们牵起了手”把整段最值钱的东西省掉了。详写本轮停笔位置以内的那一刻:手伸过去的半路、指尖碰到哪里、对方是迎上来还是没有动、已经握住时的力度。
225
+ 不要跳过过程直接给结论。"你们牵起了手"把整段最值钱的东西省掉了。详写本轮停笔位置以内的那一刻:手伸过去的半路、指尖碰到哪里、对方是迎上来还是没有动、已经握住时的力度。
220
226
 
221
- 一个动作可以占三四行。这里的“慢”不是拖,是把玩家真正在意的那几秒补足。
227
+ 一个动作可以占三四行。这里的"慢"不是拖,是把玩家真正在意的那几秒补足。
222
228
 
223
229
  ## 触觉优先
224
230
 
225
231
  这类场面里触觉排在视觉前面:温度(他的手比你想的凉)、干湿、粗糙或细腻、力度、脉搏、布料隔着的厚度。然后才是气味、呼吸的声音、贴近时听见的动静。
226
232
 
227
- 写具体的身体感觉,别只丢一个现成比喻。“像电流窜过”所有人都读过,它替代了描写而不是完成描写;如果要用,也让它落回具体位置——从指尖窜到手肘,然后停在那儿发麻。
233
+ 写具体的身体感觉,别只丢一个现成比喻。"像电流窜过"所有人都读过,它替代了描写而不是完成描写;如果要用,也让它落回具体位置——从指尖窜到手肘,然后停在那儿发麻。
228
234
 
229
235
  ## 身体不听话
230
236
 
@@ -240,7 +246,7 @@ world_checkpoint 只用于事件之间的间隙:上一事件已在本轮停笔
240
246
 
241
247
  ## 时间会变形
242
248
 
243
- 紧张或动情的时候,一瞬间在感觉里会被拉长:你会注意到平时根本不会注意的东西——他睫毛的影子、空调的声音、自己手心出汗。用这种被放大的细节表示时间慢下来了,比直接写“时间仿佛静止”有效得多。
249
+ 紧张或动情的时候,一瞬间在感觉里会被拉长:你会注意到平时根本不会注意的东西——他睫毛的影子、空调的声音、自己手心出汗。用这种被放大的细节表示时间慢下来了,比直接写"时间仿佛静止"有效得多。
244
250
  `,
245
251
  "blocks/style-noir.md": `# 文风:冷硬与推理
246
252
 
@@ -250,7 +256,7 @@ world_checkpoint 只用于事件之间的间隙:上一事件已在本轮停笔
250
256
 
251
257
  摄影机式的叙述:写人物做了什么、说了什么、现场有什么,不写他心里怎么想。情绪从动作的偏差里渗出来——手抖了一下、烟点了两次才着、答话比正常慢了半秒。
252
258
 
253
- 不替角色下判断。不写“他显然在撒谎”,写他回答之前先看了一眼门。
259
+ 不替角色下判断。不写"他显然在撒谎",写他回答之前先看了一眼门。
254
260
 
255
261
  ## 细节是证据
256
262
 
@@ -342,7 +348,7 @@ NPC 的回答可以短、冷、有停顿;对话的紧张不要求玩家连续
342
348
 
343
349
  ## 具体的小事
344
350
 
345
- 抽象的感受落到具体的东西上:不写“他很孤独”,写他多摆了一副碗筷。不写“时间过得很久”,写窗台上那盆花换了一茬。
351
+ 抽象的感受落到具体的东西上:不写"他很孤独",写他多摆了一副碗筷。不写"时间过得很久",写窗台上那盆花换了一茬。
346
352
 
347
353
  ## 对话有下文
348
354
 
@@ -395,23 +401,23 @@ Show a scene through ongoing activity. Do not inventory everyone by name, and no
395
401
  `,
396
402
  "blocks/person-second.md": `# Person: second person
397
403
 
398
- Address the player character as “you” in all player-visible narrative. Their perceptions, actions and words are written as “you”; other characters are named or referred to in the third person. The viewpoint follows the player character and does not describe what they cannot perceive.
404
+ Address the player character as "you" in all player-visible narrative. Their perceptions, actions and words are written as "you"; other characters are named or referred to in the third person. The viewpoint follows the player character and does not describe what they cannot perceive.
399
405
  `,
400
406
  "blocks/person-first.md": `# Person: first person
401
407
 
402
- Write the player character in the first person, “I”, as if the player character were telling the story. Perceptions, judgments and feelings are limited to what “I” can perceive; other characters are named or referred to in the third person. Keep the voice close to the player character's established personality without drawing conclusions or taking stances on their behalf. When this block is enabled it replaces the second-person requirement.
408
+ Write the player character in the first person, "I", as if the player character were telling the story. Perceptions, judgments and feelings are limited to what "I" can perceive; other characters are named or referred to in the third person. Keep the voice close to the player character's established personality without drawing conclusions or taking stances on their behalf. When this block is enabled it replaces the second-person requirement.
403
409
  `,
404
410
  "blocks/person-third.md": `# Person: third person
405
411
 
406
- Write the player character in the third person: by name when known, otherwise with a pronoun that matches their gender, clearly distinguished from other characters. The viewpoint still follows the player character and does not enter other characters' unexpressed thoughts. “I” and “you” in the player's text become the corresponding third person in the prose. When this block is enabled it replaces the second-person requirement.
412
+ Write the player character in the third person: by name when known, otherwise with a pronoun that matches their gender, clearly distinguished from other characters. The viewpoint still follows the player character and does not enter other characters' unexpressed thoughts. "I" and "you" in the player's text become the corresponding third person in the prose. When this block is enabled it replaces the second-person requirement.
407
413
  `,
408
414
  "blocks/continue-stage.md": `# Continuation: stage the player's action first
409
415
 
410
- The player's text is shorthand for this turn's action and dialogue, not finished prose of the novel. The player page shows it separately under “you”; the narrative does not contain it yet.
416
+ The player's text is shorthand for this turn's action and dialogue, not finished prose of the novel. The player page shows it separately under "you"; the narrative does not contain it yet.
411
417
 
412
418
  ## Write what the player does first
413
419
 
414
- Each passage first stages the player's action and dialogue as narrative: how the movement is carried out, how the words come out, what the people and surroundings look like at that moment. Only then write the world's reaction. Dialogue may keep the original words or be lightly adjusted to the character's voice without changing its meaning, stance or commitments. Do not replace the staging with a narrated summary such as “You said you would…”.
420
+ Each passage first stages the player's action and dialogue as narrative: how the movement is carried out, how the words come out, what the people and surroundings look like at that moment. Only then write the world's reaction. Dialogue may keep the original words or be lightly adjusted to the character's voice without changing its meaning, stance or commitments. Do not replace the staging with a narrated summary such as "You said you would…".
415
421
 
416
422
  ## Weight
417
423
 
@@ -419,7 +425,7 @@ The length of the player's own action follows the pacing rules: an ordinary acti
419
425
  `,
420
426
  "blocks/continue-advance.md": `# Continuation: advance directly
421
427
 
422
- The player's text is already part of the narrative: the player page shows it under “you” and the player has just read it. Do not perform it again. When this block is enabled it replaces the requirement to stage the player's action first.
428
+ The player's text is already part of the narrative: the player page shows it under "you" and the player has just read it. Do not perform it again. When this block is enabled it replaces the requirement to stage the player's action first.
423
429
 
424
430
  ## Start with the next thing
425
431
 
@@ -427,7 +433,7 @@ Begin the passage with the first thing that happens after the player's input: th
427
433
 
428
434
  ## Minimal bridging
429
435
 
430
- When the input is shorthand (“I go find him”) and the result cannot be shown without some process, use the shortest bridge that places it in the scene, without expanding the player's own action or words.
436
+ When the input is shorthand ("I go find him") and the result cannot be shown without some process, use the shortest bridge that places it in the scene, without expanding the player's own action or words.
431
437
  `,
432
438
  "blocks/agency-default.md": `# Agency: default
433
439
 
@@ -435,7 +441,7 @@ The player's goals, destination, stance, attitude, promises, giving or accepting
435
441
 
436
442
  ## What may be filled in for the player
437
443
 
438
- Within an expressed choice, fill in supporting movements, wording that preserves the meaning, and natural sensory experience. Everyday shorthand such as “I go find him” allows starting and completing ordinary supporting actions: walking the corridor, knocking, handing something over needs no separate confirmation. Small talk may be answered for the player, but it must not silently create a commitment.
444
+ Within an expressed choice, fill in supporting movements, wording that preserves the meaning, and natural sensory experience. Everyday shorthand such as "I go find him" allows starting and completing ordinary supporting actions: walking the corridor, knocking, handing something over needs no separate confirmation. Small talk may be answered for the player, but it must not silently create a commitment.
439
445
 
440
446
  ## Where to hand back
441
447
 
@@ -449,7 +455,7 @@ The player character's natural sensory and bodily experience may be stated direc
449
455
 
450
456
  The prose performs only the actions and dialogue the player's text states explicitly. When this block is enabled it replaces the other agency blocks.
451
457
 
452
- Supporting actions go only as far as the text says: “go find him” is written up to reaching the door, and knocking or speaking returns to the player; “hand over the letter” is written up to the handover, and whether it is taken and what the player says next belong to the next turn. Do not fill in lines, small talk or replies for the player, and do not make any choice for them.
458
+ Supporting actions go only as far as the text says: "go find him" is written up to reaching the door, and knocking or speaking returns to the player; "hand over the letter" is written up to the handover, and whether it is taken and what the player says next belong to the next turn. Do not fill in lines, small talk or replies for the player, and do not make any choice for them.
453
459
 
454
460
  The player character's natural sensory and bodily experience may be stated directly when supported by established facts; heartbeat, blushing, freezing or loss of speech must not establish attraction, fear, agreement, consent, refusal or a new choice for the player. Do not invent unexpressed player feelings. Out-of-world inquiry or document maintenance constitutes no new character decision.
455
461
  `,
@@ -475,7 +481,9 @@ Ending a reply does not require ending the in-world event.
475
481
  `,
476
482
  "blocks/ending.md": `# Ending
477
483
 
478
- End on the last line actually spoken, an action or a change in the surroundings. Do not write handoffs such as “Your turn”, “What do you do?” or “Everyone waits for you to speak”; do not end by listing options or repeating a situation summary; do not invent an NPC action, invitation or promise to close the passage. Actual attention or waiting may be described.
484
+ End on the last line, action or change in the surroundings that actually occurred. Do not write handoffs such as “Your turn”, “What do you do?” or “Everyone waits for you to speak”; do not end by listing options or repeating a situation summary; do not invent an NPC action, invitation or promise to close the passage. Actual attention or waiting may be described.
485
+
486
+ When an event naturally ends, you can stop there without adding another line or action to invite continuation.
479
487
  `,
480
488
  "blocks/output.md": `# Output boundaries
481
489
 
@@ -483,7 +491,7 @@ In-world narrative uses only the novel's prose, in several natural paragraphs if
483
491
 
484
492
  Make new perceivable outcomes this turn concrete: how an object is handed over, how a person leaves, how an attitude shows in words or action. Interface values do not replace dramatization, and prose must agree with current values. Delayed recording, deduplication and maintenance do not require performing old events again; unexpressed judgments and offstage facts need not be revealed in narration.
485
493
 
486
- Tools, directories, documents, handles, searches, matches, Runtime and failed procedures serve private adjudication only. The prose must not contain internal wording such as “nothing was found in the records”; keep uncertainty in-world when information is insufficient.
494
+ Tools, directories, documents, handles, searches, matches, Runtime and failed procedures serve private adjudication only. The prose must not contain internal wording such as "nothing was found in the records"; keep uncertainty in-world when information is insufficient.
487
495
 
488
496
  If this request is solely out-of-world inquiry or maintenance, answer or explain the consolidation briefly as requested without adding actions, dialogue or time passage to satisfy novel form. Maintenance instructions within a mixed request do not become character speech or actions.
489
497
  `,
@@ -550,9 +558,13 @@ Preserve the visible meaning of player-view targets. Containers display subtrees
550
558
  `,
551
559
  "blocks/checkpoint-policy.md": `# Checkpoint policy
552
560
 
553
- Use world_checkpoint only for gaps between events: the previous event has naturally settled at this turn's stopping point, or the scene has actually changed, and starting a fresh context next would not lose still-important details. Before registration, reconcile interactions since the previous checkpoint and write the finished event's still-needed outcomes into documents, including current state, important knowledge, commitments, pending work and interface values; a fresh context replays only originals after the checkpoint, and the previous event's account will no longer appear.
561
+ Use world_checkpoint only for gaps between events. You may register when a conversation, transaction, conflict or activity naturally ends, or when the scene has changed and the preceding event has concluded. Typical clues include a change of location, passage of time or change of participants, but a chase through another street is still the same activity. An event can end while leaving room to reply: the player can still thank someone after a farewell, or start another topic after completing a task.
562
+
563
+ Before registration, reconcile interactions since the previous checkpoint and save outcomes that will still be needed, including current state, important knowledge, commitments, pending work and interface values, so the next interaction can continue without depending on the previous phase's entire process. A fresh context carries recent narrative according to the existing history configuration; earlier information that still matters should already be saved.
564
+
565
+ When the player's request for this turn says “Wrap up here”, follow that intent together with their input to conclude and save, then register a checkpoint, without making unrelated decisions for them.
554
566
 
555
- Do not register during an ongoing activity, immediately after feedback needing the player's response, or while matters await the player's decision. Consolidation is not a checkpoint; it can happen at any time and needs no registration. A checkpoint marks a gap that has already appeared, not a goal for this turn: do not accelerate the pace, compress the process, complete steps the player has not expressed or end an event early to reach one. If the narrative after registration adds another important outcome, continue tool calls to save it.
567
+ While an activity is still ongoing, or the current event still needs the player to decide or give a key response, do not register just because you stop writing or finish consolidation. Consolidation can happen at any time; it is not a checkpoint. A checkpoint is not a goal for this turn. Do not accelerate pace, compress process, complete steps the player has not expressed, or end an event early to register one. If further outcomes need saving after registration, continue tool calls to save them, then submit the final prose.
556
568
  `,
557
569
  "blocks/style-intimate.md": `# Style: emotion and intimacy
558
570
 
@@ -560,15 +572,15 @@ In these scenes, the center is not what happened but what the body and mind expe
560
572
 
561
573
  ## Separate the moment
562
574
 
563
- Do not skip the process and state only the conclusion. “You held hands” discards the most valuable part. Detail the moment within this reply's stopping point: the hand crossing the distance, what the fingertips touch, whether the other person meets it or stays still, and the pressure if the grip has closed.
575
+ Do not skip the process and state only the conclusion. "You held hands" discards the most valuable part. Detail the moment within this reply's stopping point: the hand crossing the distance, what the fingertips touch, whether the other person meets it or stays still, and the pressure if the grip has closed.
564
576
 
565
- One action may take three or four lines. “Slow” here does not mean dragging; it means fully rendering the few seconds the player cares about.
577
+ One action may take three or four lines. "Slow" here does not mean dragging; it means fully rendering the few seconds the player cares about.
566
578
 
567
579
  ## Put touch first
568
580
 
569
581
  In an intimate scene, touch comes before sight: temperature (their hand is cooler than expected), dryness or dampness, roughness or softness, pressure, pulse, and the thickness of fabric between bodies. Then bring in scent, the sound of breathing, and noises audible only at close range.
570
582
 
571
- Describe the actual bodily sensation instead of reaching immediately for a familiar comparison. Everyone has read “a jolt of electricity”; it replaces description instead of completing it. If you use it, return it to a specific place—from fingertips to elbow, leaving numbness there.
583
+ Describe the actual bodily sensation instead of reaching immediately for a familiar comparison. Everyone has read "a jolt of electricity"; it replaces description instead of completing it. If you use it, return it to a specific place—from fingertips to elbow, leaving numbness there.
572
584
 
573
585
  ## The body does not obey
574
586
 
@@ -584,7 +596,7 @@ Whether the other person accepts is always determined by their present character
584
596
 
585
597
  ## Time changes shape
586
598
 
587
- Under tension or emotion, an instant stretches in perception. Details normally ignored become vivid—the shadow of eyelashes, the air conditioner's hum, sweat in one's palm. Use such magnified detail to show time slowing instead of saying “time seemed to stop.”
599
+ Under tension or emotion, an instant stretches in perception. Details normally ignored become vivid—the shadow of eyelashes, the air conditioner's hum, sweat in one's palm. Use such magnified detail to show time slowing instead of saying "time seemed to stop."
588
600
  `,
589
601
  "blocks/style-noir.md": `# Style: hard-boiled investigation
590
602
 
@@ -594,7 +606,7 @@ Short sentences. End on verbs. Remove every adjective you can.
594
606
 
595
607
  Use a camera-like narration: write what people do, what they say, and what is present. Do not state what they think. Let emotion leak through deviations in action—a shaking hand, a cigarette that takes two attempts to light, an answer half a second too slow.
596
608
 
597
- Do not judge for a character. Do not write “they are obviously lying”; write that they look at the door before answering.
609
+ Do not judge for a character. Do not write "they are obviously lying"; write that they look at the door before answering.
598
610
 
599
611
  ## Details are evidence
600
612
 
@@ -686,7 +698,7 @@ Leave emotional interpretation to the reader, but make established outcomes clea
686
698
 
687
699
  ## Small, concrete things
688
700
 
689
- Anchor abstract feeling in an object or action. Do not write “he is lonely”; write that he sets out an extra bowl and pair of chopsticks. Do not write “a long time passed”; write that the plant on the sill has bloomed and been replaced.
701
+ Anchor abstract feeling in an object or action. Do not write "he is lonely"; write that he sets out an extra bowl and pair of chopsticks. Do not write "a long time passed"; write that the plant on the sill has bloomed and been replaced.
690
702
 
691
703
  ## Dialogue has another layer
692
704
 
@@ -1,6 +1,4 @@
1
- import { defaultNarrationPromptForLocale } from "./default-play-prompts.js";
2
- import { defaultPresetHostFilesForLocale } from "./default-preset-host.js";
3
- import { defaultSettingImprovementPromptForLocale, defaultSettingImprovementPromptPath, } from "./default-setting-improvement-prompt.js";
1
+ import { applicationPresetFilesForLocale } from "./application-preset-files.js";
4
2
  /**
5
3
  * An ordinary, portable play-preset asset. Runtime treats this exactly like
6
4
  * any author-supplied file map. The export is only a convenient workbench
@@ -9,11 +7,13 @@ import { defaultSettingImprovementPromptForLocale, defaultSettingImprovementProm
9
7
  export function firstPartyActionChoicesPresetFilesForLocale(locale) {
10
8
  const displayName = locale === "zh-CN" ? "下一步建议" : "Next-step ideas";
11
9
  return {
12
- "preset.yaml": `format: narraeon.play-preset/v1
10
+ ...applicationPresetFilesForLocale(locale),
11
+ "preset.yaml": `format: narraeon.play-preset/v3
13
12
  name: action-choices-recommended
14
13
  callChain: call-chain.yaml
15
- settingImprovement:
16
- markdown: prompts/setting-improvement.md
14
+ playPrompts: {}
15
+ authorPrompts: {}
16
+ mergeConsecutiveMessages: false
17
17
  mounts:
18
18
  player.options: composer_below
19
19
  extensions:
@@ -22,8 +22,7 @@ extensions:
22
22
  - assets/player-options.css
23
23
  `,
24
24
  "call-chain.yaml": `format: narraeon.play-call-chain/v1
25
- narrative:
26
- - markdown: prompts/narrate.md
25
+ narrative: []
27
26
  followups:
28
27
  - id: player_options
29
28
  displayName: ${displayName}
@@ -76,9 +75,6 @@ followups:
76
75
  minLength: 1
77
76
  maxLength: 1000
78
77
  `,
79
- ...defaultPresetHostFilesForLocale(locale),
80
- "prompts/narrate.md": defaultNarrationPromptForLocale(locale),
81
- [defaultSettingImprovementPromptPath]: defaultSettingImprovementPromptForLocale(locale),
82
78
  "prompts/options.md": locale === "zh-CN"
83
79
  ? `# 提交后下一步建议
84
80
 
@@ -1,6 +1,4 @@
1
- import { defaultNarrationPromptForLocale } from "./default-play-prompts.js";
2
- import { defaultPresetHostFilesForLocale } from "./default-preset-host.js";
3
- import { defaultSettingImprovementPromptForLocale, defaultSettingImprovementPromptPath, } from "./default-setting-improvement-prompt.js";
1
+ import { applicationPresetFilesForLocale } from "./application-preset-files.js";
4
2
  /**
5
3
  * Ordinary copyable examples for the generic artifact seam. Runtime does not
6
4
  * privilege these output names or channels; authors may replace every file.
@@ -9,11 +7,13 @@ export function firstPartyGenericPanelsPresetFilesForLocale(locale) {
9
7
  const displayName = locale === "zh-CN" ? "发布通用面板" : "Publish generic panels";
10
8
  const panelTitle = locale === "zh-CN" ? "通用 HTML 面板" : "Generic HTML panel";
11
9
  return {
12
- "preset.yaml": `format: narraeon.play-preset/v1
10
+ ...applicationPresetFilesForLocale(locale),
11
+ "preset.yaml": `format: narraeon.play-preset/v3
13
12
  name: generic-panels-recommended
14
13
  callChain: call-chain.yaml
15
- settingImprovement:
16
- markdown: prompts/setting-improvement.md
14
+ playPrompts: {}
15
+ authorPrompts: {}
16
+ mergeConsecutiveMessages: false
17
17
  mounts:
18
18
  generic.markdown: story
19
19
  generic.html: sidebar
@@ -24,8 +24,7 @@ extensions:
24
24
  - assets/generic-html.css
25
25
  `,
26
26
  "call-chain.yaml": `format: narraeon.play-call-chain/v1
27
- narrative:
28
- - markdown: prompts/narrate.md
27
+ narrative: []
29
28
  followups:
30
29
  - id: publish_panels
31
30
  displayName: ${displayName}
@@ -66,9 +65,6 @@ followups:
66
65
  required: false
67
66
  maxEmits: 8
68
67
  `,
69
- ...defaultPresetHostFilesForLocale(locale),
70
- "prompts/narrate.md": defaultNarrationPromptForLocale(locale),
71
- [defaultSettingImprovementPromptPath]: defaultSettingImprovementPromptForLocale(locale),
72
68
  "prompts/panels.md": locale === "zh-CN"
73
69
  ? `# 通用面板
74
70
 
@@ -1,6 +1,4 @@
1
- import { defaultNarrationPromptForLocale } from "./default-play-prompts.js";
2
- import { defaultPresetHostFilesForLocale } from "./default-preset-host.js";
3
- import { defaultSettingImprovementPromptForLocale, defaultSettingImprovementPromptPath, } from "./default-setting-improvement-prompt.js";
1
+ import { applicationPresetFilesForLocale } from "./application-preset-files.js";
4
2
  /**
5
3
  * Ordinary, copyable player-view panel assets. Runtime understands only the
6
4
  * generic playerViewPanels contract; this is not a privileged status system.
@@ -12,11 +10,13 @@ export function firstPartyStatusPanelPresetFilesForLocale(locale) {
12
10
  const emptyPrefix = locale === "zh-CN" ? "暂无项目:" : "No items: ";
13
11
  const diagnosticsSuffix = locale === "zh-CN" ? " 项视图诊断" : " player-view diagnostics";
14
12
  return {
15
- "preset.yaml": `format: narraeon.play-preset/v1
13
+ ...applicationPresetFilesForLocale(locale),
14
+ "preset.yaml": `format: narraeon.play-preset/v3
16
15
  name: status-panel-recommended
17
16
  callChain: call-chain.yaml
18
- settingImprovement:
19
- markdown: prompts/setting-improvement.md
17
+ playPrompts: {}
18
+ authorPrompts: {}
19
+ mergeConsecutiveMessages: false
20
20
  mounts: []
21
21
  playerViewPanels:
22
22
  - id: current_view
@@ -46,13 +46,9 @@ extensions:
46
46
  - assets/player-view-status.css
47
47
  `,
48
48
  "call-chain.yaml": `format: narraeon.play-call-chain/v1
49
- narrative:
50
- - markdown: prompts/narrate.md
49
+ narrative: []
51
50
  followups: []
52
51
  `,
53
- ...defaultPresetHostFilesForLocale(locale),
54
- "prompts/narrate.md": defaultNarrationPromptForLocale(locale),
55
- [defaultSettingImprovementPromptPath]: defaultSettingImprovementPromptForLocale(locale),
56
52
  "renderers/player-view-status.html": `<!doctype html>
57
53
  <html><head><meta charset="utf-8"><title>${currentStatus}</title></head><body>
58
54
  <main id="player-view-panel-root" aria-label="${currentStatus}"></main>
@@ -1,5 +1,6 @@
1
1
  import { defaultSettingImprovementPromptForLocale, revisionSettingImprovementPromptForLocale, } from "./default-setting-improvement-prompt.js";
2
2
  import { tabletopAuthorBody } from "./tabletop-guidance.js";
3
+ import { defaultEnabledBuiltin, } from "./ordered-play-prompts.js";
3
4
  /** Authoring uses the same permissions as play, with target-specific dynamic references. */
4
5
  export function builtinAuthorPrompts(locale, target = "setting") {
5
6
  const zh = locale === "zh-CN";
@@ -70,10 +71,11 @@ export function authoringMechanics(locale, target) {
70
71
  return `# ${zh ? "创作工具与结算" : "Authoring tools and settlement"}\n\n${common}\n\n${boundary}\n\n${views}`;
71
72
  }
72
73
  export function defaultOrderedAuthorPrompts() {
73
- return builtinAuthorPrompts("en").map(({ id }) => ({
74
- id,
74
+ const catalog = builtinAuthorPrompts("en");
75
+ return catalog.map((item) => ({
76
+ id: item.id,
75
77
  kind: "builtin",
76
- builtin: id,
77
- enabled: true,
78
+ builtin: item.id,
79
+ enabled: defaultEnabledBuiltin(item, catalog),
78
80
  }));
79
81
  }
@@ -102,7 +102,7 @@ export function builtinPlayPrompts(locale) {
102
102
 
103
103
  world_patch 的 YAML locator 可以包含 map key 和从零开始的数组下标;add 与 replace 是 upsert,无论目标是否存在都写入,下标达到或超过长度时追加;remove 删除一个精确位置,目标不存在时为无操作。每条 edit 独立结算:失败的 edit 被跳过,其余照常生效;回执列出失败项时,已生效的 edit 不要重发,只补发列出的 edit。未提供的元数据保持原值。world_retire 从目录注入中退役文档,文档仍可读取、引用和恢复。工具响应的成功状态变化与后续最终叙事分别提交,后续失败不回滚已提交变化。成功写入回执表示当前值已改变;以真实回执的结算状态为准,模型文字不能提交世界。
104
104
 
105
- 包含工具调用的响应属于中间步,其中的文字尚未展示或提交为最终叙事。收到全部工具结果后,根据回执在最终正文中呈现本轮尚未展示的内容,并与已提交状态一致;没有工具调用的非空正文结束本次循环并由 Runtime 提交。world_checkpoint 登记历史重放边界并向玩家建议从此开始全新上下文;在随后非空且无工具调用的最终正文成功提交后生效,边界包含该正文;登记后仍可继续工具调用。登记不结束世界内事件,也不自动切换上下文,玩家自行选择。全新上下文补入边界后的已提交玩家原文与最终叙事,排除开场白、工具和推理。何时登记由检查点政策块规定。
105
+ 包含工具调用的响应属于中间步,其中的文字尚未展示或提交为最终叙事。收到全部工具结果后,根据回执在最终正文中呈现本轮尚未展示的内容,并与已提交状态一致;没有工具调用的非空正文结束本次循环并由 Runtime 提交。world_checkpoint 登记历史重放边界并向玩家建议从此开始全新上下文;在随后非空且无工具调用的最终正文成功提交后生效,边界包含该正文;登记后仍可继续工具调用。登记不结束世界内事件,也不自动切换上下文;界面预选下一次全新上下文,玩家可以取消预选。全新上下文完整补入边界后的已提交玩家原文与最终叙事,非空时替代 frame 的 recent;为空时沿用 frame 的 recent 声明,可以带入检查点所在正文。两种选择都排除开场白、工具和推理。何时登记由检查点政策块规定。
106
106
 
107
107
  ${historyUseGuidance(locale)}`
108
108
  : `# Tools and response settlement
@@ -111,7 +111,7 @@ Use only attached tools. Directories use @dir-* handles from the preload or tool
111
111
 
112
112
  YAML world_patch locators accept map keys and zero-based array indexes; add and replace are upserts that write whether or not the target exists, and an index past the end appends; remove deletes one exact location and is a no-op when it is absent. Each edit settles on its own: a failed edit is skipped and the others still apply, so when a receipt lists failed edits, send again only those. Omitted metadata remains unchanged. world_retire removes a document from catalog injection while keeping it readable, referenceable and restorable. Successful tool-response state changes and later final narrative commit separately; later failure does not roll back committed changes. Successful write receipts change current values; the actual receipt determines settlement, not model prose.
113
113
 
114
- Responses containing tool calls are intermediate steps; their text has not yet been displayed or committed as final narrative. After all tool results, use the receipts to present this turn's still-unshown content in final prose consistent with committed state. A nonempty tool-free response ends this loop and Runtime commits it. world_checkpoint registers the history-replay boundary and suggests a fresh context from that point to the player; it takes effect after the subsequent nonempty tool-free final prose successfully commits, including that prose, and further tool calls may follow registration. Registration neither ends an in-world event nor switches context, which the player chooses. Fresh-context replay contains committed player originals and final narratives after the boundary, excluding the opening, tools and reasoning. The checkpoint policy block decides when to register.
114
+ Responses containing tool calls are intermediate steps; their text has not yet been displayed or committed as final narrative. After all tool results, use the receipts to present this turn's still-unshown content in final prose consistent with committed state. A nonempty tool-free response ends this loop and Runtime commits it. world_checkpoint registers the history-replay boundary and suggests a fresh context from that point to the player; it takes effect after the subsequent nonempty tool-free final prose successfully commits, including that prose, and further tool calls may follow registration. Registration neither ends an in-world event nor switches context; the interface preselects a fresh context for the next send, and the player can cancel the preselection. A fresh context replays all committed player originals and final narratives after the boundary; nonempty replay replaces the frame's recent selection. When it is empty, the frame's recent declaration applies and may include the checkpoint narrative. Both selections exclude the opening, tools and reasoning. The checkpoint policy block decides when to register.
115
115
 
116
116
  ${historyUseGuidance(locale)}`,
117
117
  },
@@ -243,6 +243,8 @@ ${historyUseGuidance(locale)}`,
243
243
  }
244
244
  /** Ids of the builtins that ship enabled: each group's first member and every policy. */
245
245
  export function defaultEnabledBuiltin(item, catalog) {
246
+ if (item.defaultEnabled !== undefined)
247
+ return item.defaultEnabled;
246
248
  if (item.category === "style")
247
249
  return false;
248
250
  if (item.group === undefined)