narraeon 0.3.1 → 0.5.0
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.
- package/dist/node/protocol/appPreferences.js +25 -0
- package/dist/node/protocol/conversationObservation.js +67 -0
- package/dist/node/protocol/v1.js +188 -34
- package/dist/node/protocol/worldExtensions.js +16 -0
- package/dist/node/protocol/worldMaintenance.js +77 -0
- package/dist/node/protocol/worldPromptDiagnostics.js +1 -0
- package/dist/node/runtime/ConversationChanges.js +24 -0
- package/dist/node/runtime/V1Runtime.js +447 -121
- package/dist/node/runtime/artifact/FileNativeArtifactStore.js +326 -12
- package/dist/node/runtime/authoring/AuthoringRequestSnapshot.js +63 -0
- package/dist/node/runtime/authoring/ModelToolConversation.js +218 -0
- package/dist/node/runtime/config/AppPreferencesStore.js +46 -17
- package/dist/node/runtime/content/ContentTreeFingerprint.js +13 -0
- package/dist/node/runtime/content/ContentWorkspace.js +43 -13
- package/dist/node/runtime/content/CurrentTreeContentLibrary.js +128 -46
- package/dist/node/runtime/content/FileNativeContentTree.js +28 -10
- package/dist/node/runtime/content/PackageFollowups.js +80 -0
- package/dist/node/runtime/extension/FrontendExtensionBundle.js +19 -14
- package/dist/node/runtime/extension/PackageScriptPermissions.js +70 -0
- package/dist/node/runtime/extension/WorldExtensionControls.js +205 -0
- package/dist/node/runtime/extension/WorldExtensionRequests.js +64 -0
- package/dist/node/runtime/model/FileNativeModelAdapters.js +21 -466
- package/dist/node/runtime/model/ModelConnectionStore.js +44 -10
- package/dist/node/runtime/model/ModelHost.js +31 -1
- package/dist/node/runtime/model/ModelHostStream.js +51 -5
- package/dist/node/runtime/play/FileNativeContinuityCorrection.js +55 -45
- package/dist/node/runtime/play/FileNativePlayPresetStore.js +256 -238
- package/dist/node/runtime/play/FileNativePlayTimelineStore.js +118 -9
- package/dist/node/runtime/play/OrderedFollowups.js +71 -0
- package/dist/node/runtime/play/OrderedPlayPrompts.js +180 -0
- package/dist/node/runtime/play/PlayCallChain.js +814 -61
- package/dist/node/runtime/play/PlayContinuity.js +88 -0
- package/dist/node/runtime/play/PlayDocumentTools.js +205 -287
- package/dist/node/runtime/play/PlayFollowupRequests.js +34 -3
- package/dist/node/runtime/play/PlayPresetWorkbench.js +45 -54
- package/dist/node/runtime/play/PlayPromptRun.js +86 -0
- package/dist/node/runtime/prompt/FileNativePromptCompiler.js +670 -93
- package/dist/node/runtime/prompt/FileNativeToolRegistry.js +37 -21
- package/dist/node/runtime/prompt/PromptCompilationCodec.js +322 -0
- package/dist/node/runtime/prompt/WorldMaintenanceReport.js +251 -0
- package/dist/node/runtime/prompt/WorldMaterialCoverage.js +83 -0
- package/dist/node/runtime/prompt/WorldPromptDiagnostics.js +185 -0
- package/dist/node/runtime/setting/FileNativeSettingImprovementStore.js +1027 -0
- package/dist/node/runtime/setting/SettingAuthoringTransaction.js +1339 -0
- package/dist/node/runtime/setting/SettingImprovementSession.js +714 -0
- package/dist/node/runtime/world/FileNativeAuthorityV3.js +88 -1
- package/dist/node/runtime/world/FileNativeWorldStore.js +292 -27
- package/dist/node/runtime/world/PlayerViewBindings.js +30 -0
- package/dist/node/runtime/world/PlayerViewRenderer.js +27 -34
- package/dist/node/runtime/world/WorldDocumentMaintenance.js +174 -0
- package/dist/node/runtime/world/WorldDocumentStore.js +166 -96
- package/dist/node/runtime/world/WorldOperationCoordinator.js +103 -2
- package/dist/node/runtime/world-revision/FileNativeWorldRevisionStore.js +696 -0
- package/dist/node/runtime/world-revision/WorldRevisionAuthoringTransaction.js +380 -0
- package/dist/node/runtime/world-revision/WorldRevisionSession.js +709 -0
- package/dist/node/runtime/world-revision/WorldRevisionWorkspace.js +494 -0
- package/dist/node/server/ConversationStream.js +109 -0
- package/dist/node/server/createServer.js +5 -1
- package/dist/node/shared/artifact-payload-contract.js +123 -0
- package/dist/node/shared/default-play-prompts.js +25 -45
- package/dist/node/shared/default-preset-host.js +114 -138
- package/dist/node/shared/default-setting-improvement-prompt.js +52 -38
- package/dist/node/shared/display-regex.js +114 -0
- package/dist/node/shared/first-party-action-choices.js +1 -6
- package/dist/node/shared/first-party-player-view.js +1 -6
- package/dist/node/shared/ordered-author-prompts.js +64 -0
- package/dist/node/shared/ordered-followups.js +42 -0
- package/dist/node/shared/ordered-play-prompts.js +73 -0
- package/dist/web/assets/index-BXfelCi9.js +1207 -0
- package/dist/web/assets/index-BYnhUxlk.css +1 -0
- package/dist/web/index.html +2 -2
- package/package.json +1 -1
- package/dist/node/runtime/model/SettingAuthorStream.js +0 -21
- package/dist/node/runtime/setting/DocumentCandidateSettingImprovement.js +0 -1731
- package/dist/web/assets/index-D5VqDvjY.js +0 -1192
- package/dist/web/assets/index-Xa0s35CJ.css +0 -1
|
@@ -1,73 +1,87 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Canonical author-owned guidance for AI-assisted setting improvement.
|
|
3
3
|
*
|
|
4
|
-
* The Runtime tool universe, schemas,
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* The Runtime tool universe, schemas, per-call settlement, persistence and
|
|
5
|
+
* current-tree settlement boundary deliberately do not live here. This text is an ordinary
|
|
6
|
+
* portable preset asset: users may edit it without gaining authority over the
|
|
7
|
+
* mechanical setting-improvement boundary.
|
|
8
8
|
*/
|
|
9
9
|
export const defaultSettingImprovementPromptPath = "prompts/setting-improvement.md";
|
|
10
|
-
export const defaultSettingImprovementPromptZhCN = `#
|
|
10
|
+
export const defaultSettingImprovementPromptZhCN = `# 系统推荐的创作方法
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
以当前编辑目标、已有内容和用户目标为起点。讨论时说明必要判断,落实时定向修改;用户要求审查或重组时,相关结构与重复表达也在范围内。不为填满结构制造内容,无需修改也是合法结果。
|
|
13
13
|
|
|
14
|
-
##
|
|
14
|
+
## 编辑目标与世界起点
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
内容包设定完善定义开场结束处的世界起点,可以包含已有历史、当前状态、持续过程和各人的认知。简单起点足以开玩,普通未定义内容可在游玩中生长;不预写未来必然发生的经历或强制剧情阶段。
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
运行中世界修订维护当前已经演变的世界,按用户要求调整并保留未受影响的事实、经历与认知,不退回初始取值。此分支不读取或修改 opening.md。明确修订不是世界内事件,不需虚构行动解释它。
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
涉及结构、材料发现或更新位置时,先列出编辑目标根目录,完整读取 control/frame.yaml、启用的世界提示块、绑定的当前情境及受影响文档。实际操作遵守本轮工具边界。
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
## 世界信息怎样组织
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
世界文档承载事实与语义:当前值归自然所有者;持续过程记录实际进展与条件;意图、承诺、日程保留主体和已知条件,其目标尚未实现。角色声称、猜测与真实发生的事分开。人物的认知和态度属于各自主体,不随事实变化自动同步,也不互相对称;不代填玩家未表达的感情。
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
重要事件的经过集中承载,需要多人引用、持续追溯或重新解释时安排独立可引用的事件文档。事件记载当时的经过和结果;最新状态、待办与看法留在各自文档,用引用关联,事件不充当滚动状态表。对象保存当前结果,个人保存认知、关系评价与简短依据,引用相关事件而不各抄经过。已经形成的状态和态度也要保存,不能只存事件再让每次游玩重新推算。事件按事情组织,不按回合建档;普通细节可以只留在叙事。
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
这些区别适用于物品、伤病、地点、组织、交易、调查与人物关系,不要求固定目录、字段或数量。独立引用、自身状态或生命周期需要独立文档;小规模信息可集中在合适载体中。当前情境只承接眼前地点、在场者、进行中的事及待回应事项,不承担全部历史或未来分支。
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
- 每项持续信息优先写给它的自然所有者。普通临时对象不必独立建档;只有需要独立引用、转移或追踪生命周期时,才升级为独立文档。
|
|
32
|
-
- 当前情境只保留开场动作和即时反应结束后仍然成立的局面:此刻地点、仍在场的人物、仍在进行的事件,以及首次行动若忽略就会立刻冲突的少量限制。它不是背景摘要、事件日志或未来分支清单。
|
|
33
|
-
- catalog 的摘要要写成足以帮助主持者判断“是否需要继续读取正文”的一句话,而不是“某某的资料”。正文改变后,标题和摘要也要继续准确。
|
|
30
|
+
summary 是目录简介:只写识别文档所需的简短身份、主题或稳定线索,不复述具体状态和事件经过。具体事实放在正文,仅在识别信息改变时更新标题与简介。
|
|
34
31
|
|
|
35
|
-
##
|
|
32
|
+
## 承载与发现一起安排
|
|
36
33
|
|
|
37
|
-
|
|
34
|
+
每项持续信息确定自然所有者、更新位置及实际的发现或注入路径。常用当前值按需全文或节点注入;较长事件通过目录和引用按需读取。重要事件应有实际可用的集中承载位置,不能只有无法创建的目录设想。查看真实 frame 和写后覆盖,不假定所有正文都已进入游玩请求。
|
|
38
35
|
|
|
39
|
-
|
|
36
|
+
同一时点、同一含义的事实尽量只维护一份;过去取值、当前结果和不同主体的理解不按重复删去。当前情境、叙事及界面只承担各自用途,避免重复强化同一概念。
|
|
37
|
+
|
|
38
|
+
world/ 或 state/ 承载虚构事实,control/ 安排本世界的取材、规则运用、保存位置与呈现,不复制当前值。未来游玩参考只代表实际启用的作者块;它不是本轮叙事要求,可选政策也未必始终启用。世界指令补充本世界特有约束,不重复通用规则或工具流程,不擅自改写世界外预设。
|
|
39
|
+
|
|
40
|
+
## 开场与整理
|
|
41
|
+
|
|
42
|
+
仅在内容包分支检查 opening.md:写玩家当时可感知的具体局面,保留尚待回答的请求与必要原话,不替玩家决定行动、台词或内心。独处、安静和等待也可形成开场。开场与文档停在同一时点,将约束首次行动的结果写给自然所有者,无需复制整篇叙事。
|
|
43
|
+
|
|
44
|
+
整理结束已完成或失效的进程、约定和限制,保留仍有意义的成果、后遗影响、经历与引用。补录、去重和归档不让事情再发生。长材料按需发现,软体积提示不授权截断;暂时离场不等于退役,退役也不会移除显式全文槽。
|
|
45
|
+
|
|
46
|
+
检查实际玩家视图选择器。容器会显示子树,隐藏认知不能混进公开节点;重组绑定结构时同步更新选择器。审计先对应概念、时间与主体,再处理重复句子;最后用实际写后覆盖检查发现路径,不默认输出整份内部审计表。
|
|
40
47
|
`;
|
|
41
|
-
export const defaultSettingImprovementPromptEn = `# Recommended
|
|
48
|
+
export const defaultSettingImprovementPromptEn = `# Recommended authoring method
|
|
49
|
+
|
|
50
|
+
Start with the editing target, existing content and the user's goal. Discuss necessary judgments when asked to discuss; apply targeted changes when asked to implement. An audit or restructuring request includes relevant structure and duplicated expression. Do not invent content to fill a structure; no change needed is valid.
|
|
51
|
+
|
|
52
|
+
## Editing target and world starting point
|
|
53
|
+
|
|
54
|
+
Content-package setting improvement defines the world where the opening ends, including established history, current state, ongoing processes and individual knowledge. A simple starting point can be playable and ordinary undefined content can grow during play. Do not prewrite inevitable future experiences or mandatory plot stages.
|
|
55
|
+
|
|
56
|
+
Running-world revision maintains the world as it has evolved: apply requested changes while preserving unaffected facts, events and knowledge instead of resetting initial values. This branch does not read or modify opening.md. Explicit revision is not an in-world event and needs no invented action to explain it.
|
|
57
|
+
|
|
58
|
+
When structure, discovery or update locations are affected, list the editing target's root and completely read control/frame.yaml, enabled world instructions, the bound current situation and affected documents. Follow this request's actual tool boundary.
|
|
42
59
|
|
|
43
|
-
|
|
60
|
+
## Organizing world information
|
|
44
61
|
|
|
45
|
-
|
|
62
|
+
World documents carry facts and semantics. Current values belong to natural owners; ongoing processes retain actual progress and conditions; intentions, promises and schedules retain subjects and known conditions while their goals remain unrealized. Separate claims and guesses from what actually happened. Knowledge and attitudes belong to their holders, do not automatically follow world changes, and need not be mutual. Do not invent unexpressed player feelings.
|
|
46
63
|
|
|
47
|
-
|
|
64
|
+
Keep important event accounts in one place, using independently referenceable event documents for shared reference, continued retrieval or reinterpretation. Events record what happened and the outcomes at that time; latest states, pending work and views stay in their own documents, connected by references rather than copied into a rolling event-state table. Objects retain current outcomes; people retain knowledge, relationship appraisals and a brief basis, linking relevant events instead of copying their accounts. Persist formed states and attitudes too, rather than saving only events and asking each play request to infer everything again. Organize events by what happened, not by turn; ordinary details may remain narrative-only.
|
|
48
65
|
|
|
49
|
-
|
|
66
|
+
These distinctions apply to objects, injuries, places, organizations, trades, investigations and personal relationships without fixed directories, fields or counts. Independent reference, evolving state or lifecycle tracking warrants a separate document; smaller records may share a suitable home. The current situation holds the immediate location, people present, ongoing matters and unanswered requests, not all history or future branches.
|
|
50
67
|
|
|
51
|
-
|
|
68
|
+
summary is a catalog description: include only a brief identity, topic or stable clue needed to identify the document, not detailed state or event accounts. Concrete facts belong in the body. Update titles and descriptions only when identifying information changes.
|
|
52
69
|
|
|
53
|
-
|
|
70
|
+
## Arrange storage and discovery together
|
|
54
71
|
|
|
55
|
-
|
|
72
|
+
Give each durable fact a natural owner, update location and actual discovery or injection path. Inject frequently needed current values as bodies or nodes when appropriate; retrieve longer event accounts through catalogs and references. Important events need a usable central home, not merely an imagined directory that play cannot create. Check the real frame and post-write coverage instead of assuming every body enters play requests.
|
|
56
73
|
|
|
57
|
-
|
|
74
|
+
Prefer one maintained home for facts with the same meaning at the same time. Past values, current outcomes and different subjects' interpretations are not duplicates. Let the current situation, prose and interface serve their own purposes without repeatedly overweighting one concept.
|
|
58
75
|
|
|
59
|
-
|
|
76
|
+
world/ or state/ carries fictional facts. control/ arranges world-specific material selection, rule use, save locations and presentation without copying current values. Future-play reference reflects only enabled author blocks: it is not this request's narrative instruction, and optional policies may not stay enabled. World instructions add world-specific constraints without repeating general rules or tool procedures or rewriting an external preset.
|
|
60
77
|
|
|
61
|
-
|
|
62
|
-
- Write each durable piece of information to its natural owner first. Ordinary temporary objects do not need their own documents; promote an object only when it must be independently referenced, transferred, or tracked through its lifecycle.
|
|
63
|
-
- The current situation contains only what remains true after the opening action and immediate reactions finish: the present location, characters still present, events still in progress, and the few constraints whose omission would immediately conflict with the first action. It is not a background summary, event log, or list of future branches.
|
|
64
|
-
- Catalog summaries must be informative enough for the host to decide whether to read the full body, rather than saying only “information about X.” Titles and summaries must remain accurate after the body changes.
|
|
78
|
+
## Opening and consolidation
|
|
65
79
|
|
|
66
|
-
|
|
80
|
+
Inspect opening.md only in the content-package branch. Show a concrete situation the player can perceive, retaining unanswered requests and consequential wording without choosing player action, speech or inner thoughts. Solitude, quiet and waiting can also open a story. Documents and opening stop at the same moment; give outcomes constraining the first action to natural owners without copying the whole narrative.
|
|
67
81
|
|
|
68
|
-
|
|
82
|
+
Consolidation closes completed or expired processes, commitments and restrictions while retaining meaningful results, lasting effects, events and references. Recording, deduplication and archiving do not perform events again. Keep long material discoverable on demand; advisory size limits do not authorize truncation. Temporary absence is not retirement, and retirement does not remove explicit full-document slots.
|
|
69
83
|
|
|
70
|
-
|
|
84
|
+
Check actual player-view selectors. Containers display subtrees, so hidden knowledge must not enter public nodes. Update selectors with any restructuring of bound content. Audit concepts, time and subjects before removing repeated sentences; finish by checking discovery against real post-write coverage without printing a full internal audit by default.
|
|
71
85
|
`;
|
|
72
86
|
export const defaultSettingImprovementPrompt = defaultSettingImprovementPromptEn;
|
|
73
87
|
export function defaultSettingImprovementPromptForLocale(locale) {
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { parseDocument, visit, isAlias, isNode } from "yaml";
|
|
2
|
+
export function parseDisplayRegex(source, path = "regex/inline.yaml") {
|
|
3
|
+
const document = parseDocument(source, {
|
|
4
|
+
schema: "core",
|
|
5
|
+
uniqueKeys: true,
|
|
6
|
+
strict: true,
|
|
7
|
+
});
|
|
8
|
+
if (document.errors.length > 0 || document.warnings.length > 0)
|
|
9
|
+
invalid("regex_asset_invalid", `Regex-resource YAML is invalid: ${path}`, path);
|
|
10
|
+
let unsafe = false;
|
|
11
|
+
visit(document, (_, node) => {
|
|
12
|
+
if (isAlias(node) ||
|
|
13
|
+
(isNode(node) &&
|
|
14
|
+
(node.tag !== undefined || ("anchor" in node && Boolean(node.anchor)))))
|
|
15
|
+
unsafe = true;
|
|
16
|
+
});
|
|
17
|
+
if (unsafe)
|
|
18
|
+
invalid("regex_asset_invalid", "Regex YAML aliases, tags and anchors are not supported", path);
|
|
19
|
+
const value = document.toJS({ maxAliasCount: 0 });
|
|
20
|
+
if (isRecord(value))
|
|
21
|
+
assertKnownKeys(value, ["rules"], path);
|
|
22
|
+
const rules = Array.isArray(value)
|
|
23
|
+
? value
|
|
24
|
+
: isRecord(value) && Array.isArray(value.rules)
|
|
25
|
+
? value.rules
|
|
26
|
+
: null;
|
|
27
|
+
if (rules === null || rules.length > 256)
|
|
28
|
+
invalid("regex_rules_invalid", `A regex resource may contain at most 256 rules: ${path}`, path);
|
|
29
|
+
const orders = new Set();
|
|
30
|
+
const parsed = rules.map((raw, index) => {
|
|
31
|
+
const location = `${path}#rules[${index}]`;
|
|
32
|
+
if (!isRecord(raw))
|
|
33
|
+
invalid("regex_rule_invalid", "A regex rule must be a map", location);
|
|
34
|
+
assertKnownKeys(raw, [
|
|
35
|
+
"order",
|
|
36
|
+
"scope",
|
|
37
|
+
"pattern",
|
|
38
|
+
"flags",
|
|
39
|
+
"replace",
|
|
40
|
+
"maxMatches",
|
|
41
|
+
"errorPolicy",
|
|
42
|
+
"enabled",
|
|
43
|
+
], location);
|
|
44
|
+
if (raw.enabled !== undefined && typeof raw.enabled !== "boolean")
|
|
45
|
+
invalid("regex_enabled_invalid", "Rule enabled must be a boolean", location);
|
|
46
|
+
const order = raw.order;
|
|
47
|
+
if (!Number.isSafeInteger(order) || order < 0)
|
|
48
|
+
invalid("regex_order_invalid", "A regex rule must declare a non-negative integer order", location);
|
|
49
|
+
if (orders.has(order))
|
|
50
|
+
invalid("regex_order_duplicate", "Regex rule order cannot be duplicated", location);
|
|
51
|
+
orders.add(order);
|
|
52
|
+
const scope = raw.scope;
|
|
53
|
+
if (scope !== "raw_text" &&
|
|
54
|
+
scope !== "markdown_html" &&
|
|
55
|
+
scope !== "structured_payload")
|
|
56
|
+
invalid("regex_scope_invalid", "A regex rule must declare raw_text, markdown_html, or structured_payload scope", location);
|
|
57
|
+
const pattern = raw.pattern;
|
|
58
|
+
if (typeof pattern !== "string" ||
|
|
59
|
+
pattern.length === 0 ||
|
|
60
|
+
pattern.length > 4_096)
|
|
61
|
+
invalid("regex_pattern_invalid", "Regex pattern must be a bounded non-empty string", location);
|
|
62
|
+
const flags = raw.flags === undefined ? "" : raw.flags;
|
|
63
|
+
if (typeof flags !== "string" || flags.length > 16)
|
|
64
|
+
invalid("regex_flags_invalid", "Regex flags are invalid", location);
|
|
65
|
+
try {
|
|
66
|
+
new RegExp(pattern, flags);
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
invalid("regex_pattern_invalid", "Regex pattern could not be compiled", location);
|
|
70
|
+
}
|
|
71
|
+
if (typeof raw.replace !== "string")
|
|
72
|
+
invalid("regex_replace_invalid", "Regex replace must be text", location);
|
|
73
|
+
const maxMatches = raw.maxMatches ?? 1;
|
|
74
|
+
if (!Number.isSafeInteger(maxMatches) ||
|
|
75
|
+
maxMatches < 1 ||
|
|
76
|
+
maxMatches > 1_024)
|
|
77
|
+
invalid("regex_limit_invalid", "Regex replacement count must be a bounded positive integer", location);
|
|
78
|
+
const errorPolicy = raw.errorPolicy;
|
|
79
|
+
if (errorPolicy !== "fallback" &&
|
|
80
|
+
errorPolicy !== "skip" &&
|
|
81
|
+
errorPolicy !== "fail")
|
|
82
|
+
invalid("regex_error_policy_invalid", "A regex rule must declare fallback, skip, or fail errorPolicy", location);
|
|
83
|
+
return {
|
|
84
|
+
...(raw.enabled === undefined ? {} : { enabled: raw.enabled }),
|
|
85
|
+
order: order,
|
|
86
|
+
scope,
|
|
87
|
+
pattern,
|
|
88
|
+
flags,
|
|
89
|
+
replace: raw.replace,
|
|
90
|
+
maxMatches: maxMatches,
|
|
91
|
+
errorPolicy,
|
|
92
|
+
};
|
|
93
|
+
});
|
|
94
|
+
return parsed.sort((left, right) => left.order - right.order);
|
|
95
|
+
}
|
|
96
|
+
export class DisplayRegexError extends Error {
|
|
97
|
+
code;
|
|
98
|
+
constructor(code, message) {
|
|
99
|
+
super(message);
|
|
100
|
+
this.code = code;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
function invalid(code, message, _location) {
|
|
104
|
+
void _location;
|
|
105
|
+
throw new DisplayRegexError(code, message);
|
|
106
|
+
}
|
|
107
|
+
function isRecord(value) {
|
|
108
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
109
|
+
}
|
|
110
|
+
function assertKnownKeys(value, allowed, location) {
|
|
111
|
+
const unknown = Object.keys(value).find((key) => !allowed.includes(key));
|
|
112
|
+
if (unknown !== undefined)
|
|
113
|
+
invalid("unsupported_field", `The current play format does not support field: ${unknown}`, location);
|
|
114
|
+
}
|
|
@@ -100,12 +100,7 @@ Use only information the player can already know, and suggest only actions the p
|
|
|
100
100
|
"scripts/player-options.js": `(function () {
|
|
101
101
|
var root = document.getElementById("player-options-root");
|
|
102
102
|
var pending = new Map();
|
|
103
|
-
|
|
104
|
-
if (typeof styleSource === "string") {
|
|
105
|
-
var style = document.createElement("style");
|
|
106
|
-
style.textContent = styleSource;
|
|
107
|
-
document.head.append(style);
|
|
108
|
-
}
|
|
103
|
+
|
|
109
104
|
function post(command, payload) {
|
|
110
105
|
var requestId = "draft-" + Math.random().toString(36).slice(2);
|
|
111
106
|
parent.postMessage({
|
|
@@ -60,12 +60,7 @@ followups: []
|
|
|
60
60
|
`,
|
|
61
61
|
"scripts/player-view-status.js": `(function () {
|
|
62
62
|
var root = document.getElementById("player-view-panel-root");
|
|
63
|
-
|
|
64
|
-
if (typeof styleSource === "string") {
|
|
65
|
-
var style = document.createElement("style");
|
|
66
|
-
style.textContent = styleSource;
|
|
67
|
-
document.head.append(style);
|
|
68
|
-
}
|
|
63
|
+
|
|
69
64
|
function valueNode(value) {
|
|
70
65
|
if (value === null || value === undefined) return document.createTextNode("—");
|
|
71
66
|
if (typeof value === "object") {
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { defaultSettingImprovementPromptForLocale } from "./default-setting-improvement-prompt.js";
|
|
2
|
+
/** Authoring uses the same permissions as play, with target-specific dynamic references. */
|
|
3
|
+
export function builtinAuthorPrompts(locale) {
|
|
4
|
+
const zh = locale === "zh-CN";
|
|
5
|
+
return [
|
|
6
|
+
{
|
|
7
|
+
id: "author.mechanics",
|
|
8
|
+
name: zh
|
|
9
|
+
? "创作工具与结算(必选)"
|
|
10
|
+
: "Authoring tools and settlement (required)",
|
|
11
|
+
required: true,
|
|
12
|
+
body: authoringMechanics(locale, "setting"),
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
id: "author.guidance",
|
|
16
|
+
name: zh ? "创作建议" : "Authoring guidance",
|
|
17
|
+
required: false,
|
|
18
|
+
body: defaultSettingImprovementPromptForLocale(locale),
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
id: "author.target",
|
|
22
|
+
name: zh
|
|
23
|
+
? "创作目标与读取授权(动态必选)"
|
|
24
|
+
: "Target and read authorization (required, dynamic)",
|
|
25
|
+
required: true,
|
|
26
|
+
body: zh
|
|
27
|
+
? "实际请求在此显示内容包或修订世界身份及当前树边界。世界修订保留独占 epoch;跨 epoch 继续时在用户消息前显式通知并清空读取授权。文件正文只通过工具按需读取,不预注入整棵树。"
|
|
28
|
+
: "The actual request shows the content package or revision world identity and current-tree boundary here. World revision retains its exclusive epoch; continuing across epochs announces the transition before the user message and clears read authorization. Files are read on demand through tools, never injected as a whole tree.",
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
id: "author.play-reference",
|
|
32
|
+
name: zh ? "未来游玩参考(动态)" : "Future play reference (dynamic)",
|
|
33
|
+
required: false,
|
|
34
|
+
body: zh
|
|
35
|
+
? "在此展开当前预设已启用的游玩编排,明确标为未来游玩参考,不是本轮叙事要求。内容包及世界正文仍通过创作工具读取。"
|
|
36
|
+
: "Expands the current preset's enabled play arrangement as future-play reference, not narrative instructions for this conversation. Actual package and world content remains behind authoring tools.",
|
|
37
|
+
},
|
|
38
|
+
];
|
|
39
|
+
}
|
|
40
|
+
export function authoringMechanics(locale, target) {
|
|
41
|
+
const zh = locale === "zh-CN";
|
|
42
|
+
const common = zh
|
|
43
|
+
? `只使用请求随附的工具及其参数契约。含工具调用的响应是中间步;收到全部工具结果后继续,非空且无工具调用的响应结束本次发送。完整工具响应按调用顺序结算,失败调用不撤销成功同级调用。修改既有文件前必须完整读取;cursor 只属于产生它的树 revision;本事务自身成功修改后的完整读取授权由 Runtime 承接。外部树变化或跨 epoch 后旧授权失效,需要重新读取。工具返回逻辑路径,不能访问宿主文件。文档引用使用返回的 @ref;YAML 整文档引用为单键 {$ref: "@ref"},locator 使用 map key 或从零开始的数组下标。成功回执决定当前值,模型文字不构成提交。`
|
|
44
|
+
: `Use only the attached tools and their parameter contracts. Responses with tool calls are intermediate steps; continue after all results. A nonempty tool-free response ends this send. Complete tool responses settle calls in order; a failed call does not undo successful siblings. Completely read existing files before writing. Cursors belong to their producing tree revision. Runtime carries complete-read authorization through this transaction’s own successful changes. External tree changes or an epoch transition invalidate old authorization and require new reads. Tools expose logical paths, never host files. Use returned @refs for documents; YAML whole-document references are single-key {$ref: "@ref"} maps, and locators use map keys or zero-based array indexes. Actual receipts determine current values; model prose cannot commit changes.`;
|
|
45
|
+
const boundary = target === "setting"
|
|
46
|
+
? zh
|
|
47
|
+
? "内容包工具的成功变化在完整响应结算时原子发布到当前树,无需应用。setting_create 建立新文档身份;删除仅在无绑定与引用阻挡时接受。"
|
|
48
|
+
: "Successful content-package changes publish atomically to the current tree when the complete response settles, with no Apply step. setting_create establishes new document identities; deletion is accepted only without binding or reference blockers."
|
|
49
|
+
: zh
|
|
50
|
+
? "世界修订工具只修改持久独占 epoch 的 state/* 与 control/* 工作树。opening.md 不可读取或修改,既有状态文档不可删除或移动。只有玩家应用或放弃才结束 epoch;应用提交世界,放弃不改变世界。跨 epoch 全部旧读取授权失效。"
|
|
51
|
+
: "World-revision tools modify only state/* and control/* in the durably locked exclusive epoch. opening.md cannot be read or changed; existing state documents cannot be deleted or moved. Only player Apply or Discard ends the epoch; Apply commits the world, Discard leaves it unchanged. Every old read authorization expires across epochs.";
|
|
52
|
+
const views = zh
|
|
53
|
+
? 'control/player-views.yaml 的 format 为 narraeon.player-views/v1;views 中每项有 id、title 和 items,items 中每项有 id、label、select。精确选择一个 YAML 字段使用 select: {document: "@ref", locator: {yaml: [字段名]}};Markdown 小节使用 locator: {markdown: [标题]}。document 必须来自实际返回的引用,locator 必须对应已读正文;省略 locator 会展示整份文档,选择容器会递归展示子树。'
|
|
54
|
+
: 'control/player-views.yaml uses format: narraeon.player-views/v1. Each views entry has id, title and items; each item has id, label and select. Select one YAML field with select: {document: "@ref", locator: {yaml: [field]}}; select a Markdown section with locator: {markdown: [heading]}. Use a returned document reference and a locator from the actual read body. Omitting locator displays the whole document; selecting a container recursively displays its subtree.';
|
|
55
|
+
return `# ${zh ? "创作工具与结算" : "Authoring tools and settlement"}\n\n${common}\n\n${boundary}\n\n${views}`;
|
|
56
|
+
}
|
|
57
|
+
export function defaultOrderedAuthorPrompts() {
|
|
58
|
+
return builtinAuthorPrompts("en").map(({ id }) => ({
|
|
59
|
+
id,
|
|
60
|
+
kind: "builtin",
|
|
61
|
+
builtin: id,
|
|
62
|
+
enabled: true,
|
|
63
|
+
}));
|
|
64
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export function defaultFollowupItems(definitions) {
|
|
2
|
+
return [
|
|
3
|
+
...definitions.map(({ id }) => ({
|
|
4
|
+
id,
|
|
5
|
+
kind: "user",
|
|
6
|
+
enabled: true,
|
|
7
|
+
})),
|
|
8
|
+
{ id: "builtin:summary", kind: "builtin", enabled: false },
|
|
9
|
+
{ id: "package:followups", kind: "content-package", enabled: true },
|
|
10
|
+
];
|
|
11
|
+
}
|
|
12
|
+
/** A current application example; snapshots freeze the compiled text, never this reference. */
|
|
13
|
+
export function builtinFollowupExample(locale) {
|
|
14
|
+
const zh = locale === "zh-CN";
|
|
15
|
+
return {
|
|
16
|
+
body: zh
|
|
17
|
+
? "主叙事已完成。仅根据已向玩家呈现的叙事与明确可见事实整理简短场景回顾,通过 artifact_emit 输出 recap。不要从工具材料、未表露认知或场外状态补全幕后原因,不补写剧情或引入新事实。回顾只是显示产物,不替代状态维护、检查点或历史恢复。"
|
|
18
|
+
: "The main narrative has settled. Emit a brief scene recap as recap using artifact_emit, using only narrative already shown to the player and explicitly visible facts. Do not fill in backstage causes from tool material, unexpressed knowledge or offstage state. Do not continue the story or introduce new facts. This display artifact does not replace state maintenance, checkpoints or history recovery.",
|
|
19
|
+
definition: {
|
|
20
|
+
id: "builtin:summary",
|
|
21
|
+
displayName: zh ? "场景回顾(系统示例)" : "Scene recap (system example)",
|
|
22
|
+
prompt: {
|
|
23
|
+
role: "author_instruction",
|
|
24
|
+
path: "builtin:followup-summary",
|
|
25
|
+
},
|
|
26
|
+
artifacts: [
|
|
27
|
+
{
|
|
28
|
+
name: "recap",
|
|
29
|
+
channel: "builtin:summary",
|
|
30
|
+
strategy: "replace",
|
|
31
|
+
contentType: "text/markdown",
|
|
32
|
+
rendererMode: "document",
|
|
33
|
+
save: "commit",
|
|
34
|
+
invalidation: "explicit_clear",
|
|
35
|
+
required: true,
|
|
36
|
+
maxEmits: 1,
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
maxArtifactBytes: 32_768,
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { defaultNarrationPromptForLocale } from "./default-play-prompts.js";
|
|
2
|
+
import { defaultPresetHostFilesForLocale } from "./default-preset-host.js";
|
|
3
|
+
/** Application-owned references. Persist references; freeze resolved text in requests. */
|
|
4
|
+
export function builtinPlayPrompts(locale) {
|
|
5
|
+
const zh = locale === "zh-CN";
|
|
6
|
+
const host = defaultPresetHostFilesForLocale(locale);
|
|
7
|
+
return [
|
|
8
|
+
{
|
|
9
|
+
id: "play.mechanics",
|
|
10
|
+
name: zh
|
|
11
|
+
? "工具与响应结算(必选)"
|
|
12
|
+
: "Tools and response settlement (required)",
|
|
13
|
+
required: true,
|
|
14
|
+
body: zh
|
|
15
|
+
? `# 工具与响应结算
|
|
16
|
+
|
|
17
|
+
只可调用请求随附的工具。目录使用 Runtime 返回的 @dir-*;文档和历史使用返回的 @句柄。工具结果标明读取范围、完整性及 cursor;目录摘要不等于正文。材料覆盖中完整正文与精确读取授予对应范围的写入资格,界面绑定标注不授予额外权限。同一原生对话刷新提示时,仅在当前状态与旧读取凭据完全匹配时承接原精确范围,并合并本次注入授权;全新上下文不继承旧对话授权。
|
|
18
|
+
|
|
19
|
+
world_patch 的 YAML locator 可以包含 map key 和从零开始的数组下标;remove 删除一个精确位置。未提供的元数据保持原值。world_retire 从目录注入中退役文档,文档仍可读取、引用和恢复。工具响应的成功状态变化与后续最终叙事分别提交,后续失败不回滚已提交变化。成功写入回执表示当前值已改变;以真实回执的结算状态为准,模型文字不能提交世界。
|
|
20
|
+
|
|
21
|
+
包含工具调用的响应属于中间步,正文不作为最终叙事提交。收到全部工具结果后继续;没有工具调用的非空正文结束本次循环并由 Runtime 提交叙事。world_checkpoint 登记在随后最终叙事成功提交后生效,边界包含该叙事;登记后仍可继续工具调用。全新上下文的历史补充只包含检查点后的已提交玩家原文与最终叙事,排除开场白、工具和推理。`
|
|
22
|
+
: `# Tools and response settlement
|
|
23
|
+
|
|
24
|
+
Use only attached tools. Directories use returned @dir-* handles; documents and history use returned @handles. Results identify read scope, completeness and cursor; directory summaries are not document bodies. Complete injected bodies and exact reads authorize writes within their corresponding scopes; player-view annotations grant no additional authority. Refreshing the same native conversation retains prior exact scopes only when the current state matches their proof, merging them with current injected authorization. A fresh context does not inherit old conversation authorization.
|
|
25
|
+
|
|
26
|
+
YAML world_patch locators accept map keys and zero-based array indexes; remove deletes one exact location. 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.
|
|
27
|
+
|
|
28
|
+
Responses containing tool calls are intermediate steps; their text is not committed as final narrative. Continue after all tool results. A nonempty tool-free response ends this loop and Runtime commits its narrative. world_checkpoint takes effect after the subsequent final narrative commits, including that narrative in its boundary; further tool calls may follow registration. Fresh-context replay contains committed player originals and final narratives after the checkpoint, excluding the opening, tools and reasoning.`,
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
id: "play.style",
|
|
32
|
+
name: zh ? "通用文风" : "General style",
|
|
33
|
+
body: host["blocks/style.md"],
|
|
34
|
+
required: false,
|
|
35
|
+
},
|
|
36
|
+
...["adjudication", "state"].map((id) => ({
|
|
37
|
+
id: `play.${id}`,
|
|
38
|
+
name: zh
|
|
39
|
+
? id === "state"
|
|
40
|
+
? "状态维护建议"
|
|
41
|
+
: "裁判与玩家代理权"
|
|
42
|
+
: id === "state"
|
|
43
|
+
? "State maintenance"
|
|
44
|
+
: "Adjudication and player agency",
|
|
45
|
+
body: host[`blocks/${id}.md`],
|
|
46
|
+
required: false,
|
|
47
|
+
})),
|
|
48
|
+
{
|
|
49
|
+
id: "play.narrative",
|
|
50
|
+
name: zh ? "叙事建议" : "Narrative guidance",
|
|
51
|
+
body: defaultNarrationPromptForLocale(locale),
|
|
52
|
+
required: false,
|
|
53
|
+
},
|
|
54
|
+
...Object.entries(host)
|
|
55
|
+
.filter(([path]) => path.startsWith("blocks/style-"))
|
|
56
|
+
.map(([path, body]) => ({
|
|
57
|
+
id: `play.${path.slice(7, -3)}`,
|
|
58
|
+
name: /^#\s+(.+)$/mu.exec(body)?.[1] ?? path,
|
|
59
|
+
body,
|
|
60
|
+
required: false,
|
|
61
|
+
})),
|
|
62
|
+
];
|
|
63
|
+
}
|
|
64
|
+
export function defaultOrderedPlayPrompts() {
|
|
65
|
+
return builtinPlayPrompts("en")
|
|
66
|
+
.map(({ id }) => ({
|
|
67
|
+
id,
|
|
68
|
+
kind: "builtin",
|
|
69
|
+
builtin: id,
|
|
70
|
+
enabled: !id.startsWith("play.style-"),
|
|
71
|
+
}))
|
|
72
|
+
.concat([{ id: "world", kind: "world" }]);
|
|
73
|
+
}
|