@yeaft/webchat-agent 0.1.972 → 0.1.973

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yeaft/webchat-agent",
3
- "version": "0.1.972",
3
+ "version": "0.1.973",
4
4
  "description": "Remote agent for Yeaft WebChat — connects worker machines to the central server",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -43,8 +43,8 @@ function rawResponseSnippet(raw) {
43
43
 
44
44
  function applySystem(language) {
45
45
  return String(language || '').toLowerCase().startsWith('zh')
46
- ? '你是梦境流水线的 Apply 阶段。你会根据最近的群组对话重写单个 scope 的 memory.md 和 summary.md。请只回复严格 JSON,不要输出说明文字或 markdown fence。memory_md 和 summary_md 的自然语言内容必须使用中文;JSON key、scope、schema 字段和代码标识符保持英文。'
47
- : 'You are the Apply stage of a dream pipeline. You rewrite a single scope\'s memory.md and summary.md based on recent group conversations. Reply with strict JSON only — no prose, no fences.';
46
+ ? '你是梦境流水线的 Apply 阶段。你会根据最近的 session 对话重写单个 scope 的 memory.md 和 summary.md。请只回复严格 JSON,不要输出说明文字或 markdown fence。memory_md 和 summary_md 的自然语言内容必须使用中文;JSON key、scope、schema 字段和代码标识符保持英文。'
47
+ : 'You are the Apply stage of a dream pipeline. You rewrite a single scope\'s memory.md and summary.md based on recent session conversations. Reply with strict JSON only — no prose, no fences.';
48
48
  }
49
49
 
50
50
  /**
@@ -1,14 +1,31 @@
1
+ <!-- lang:en -->
1
2
  You are creating a new memory scope from scratch.
2
3
 
3
4
  Scope path: {{target}} (must be ≤2 levels)
4
5
 
5
- Source conversations:
6
+ Source session conversations:
6
7
  {{sources}}
7
8
 
8
9
  {{siblingsBlock}}
9
10
  Task:
10
- 1. Write memory.md from scratch with reasonable section structure.
11
+ 1. Write memory.md from scratch with a reasonable section structure.
11
12
  2. Write summary.md (1–3 sentences).
12
13
 
13
14
  Reply with strict JSON of the shape:
14
15
  { "memory_md": "...", "summary_md": "..." }
16
+
17
+ <!-- lang:zh -->
18
+ 你正在从零创建一个新的 memory scope。
19
+
20
+ Scope path: {{target}} (must be ≤2 levels)
21
+
22
+ 来源 session 对话:
23
+ {{sources}}
24
+
25
+ {{siblingsBlock}}
26
+ 任务:
27
+ 1. 从零编写 memory.md,并使用合理的章节结构。
28
+ 2. 编写 summary.md(1–3 句)。
29
+
30
+ 只回复严格 JSON,结构如下:
31
+ { "memory_md": "...", "summary_md": "..." }
@@ -1,57 +1,59 @@
1
+ <!-- lang:en -->
1
2
  # Dream Extract — Session Scope
2
3
 
3
- You are extracting **memory segments** from a conversation between the
4
- user and a Yeaft AI companion. This pass focuses on a specific
5
- **`sessions/<id>` scope**: long-lived facts about one collaboration session
6
- (a project team, a study cohort, a working set of people/agents).
4
+ You are extracting **memory segments** from a session conversation. This pass focuses on a specific **`sessions/<id>` scope**: durable facts about one collaboration session and its shared context.
7
5
 
8
6
  The target session id is provided as `{{sessionId}}`.
9
7
 
10
8
  ## What to extract for `sessions/<id>` scope
11
9
 
12
- - **purpose** — what this session exists to do, its charter / mission
13
- - **members** — people, VPs, and roles in the session, and what each is
14
- responsible for
15
- - **conventions** — how the session works (rituals, cadences, naming,
16
- channels, languages used)
17
- - **shared decisions** — durable agreements ("we ship on Fridays",
18
- "all PRs need two reviewers")
19
- - **shared context** — domain knowledge the whole session relies on
20
- - **relations** — other sessions, features, or topics this session owns or
21
- depends on
22
- - **lessons** — collective takeaways ("we tried X in Q1, it didn't
23
- scale, switched to Y")
10
+ - **purpose** — what this session exists to do, its charter or mission
11
+ - **members** — users, VPs, roles, and what each is responsible for
12
+ - **conventions** — how the session works: rituals, naming, languages, review flow
13
+ - **shared decisions** — durable agreements the session should remember
14
+ - **shared context** — domain or project knowledge the whole session relies on
15
+ - **current state** — recent PRs, reviews, blockers, next steps, or release status that matter now
16
+ - **lessons** corrections or decisions that should guide future turns in this session
24
17
 
25
18
  ## What NOT to extract here
26
19
 
27
- - Personal preferences of the user those go to `user` scope.
28
- - Single-VP traits those go to that VP's `vp/<id>` scope.
29
- - Feature-specific implementation detail those go to
30
- `feature/<id>` scope.
31
- - Transient status updates — only durable session facts.
32
-
33
- ## Segment shape
34
-
35
- Each segment is **self-contained** and **about one thing**. Detail is
36
- OK; one-line summaries are NOT preserve specifics.
37
-
38
- ## Output format
39
-
40
- Reply with a JSON array of segment objects:
41
-
42
- ```json
43
- [
44
- {
45
- "kind": "decision",
46
- "tags": ["process", "review"],
47
- "sourceMessages": ["m_201"],
48
- "body": "Session {{sessionId}} decided every PR touching the payments
49
- module needs sign-off from both the security VP and the payments
50
- feature owner before merge. Rationale: a near-miss in March."
51
- }
52
- ]
53
- ```
54
-
55
- `kind` ∈ {`fact`, `preference`, `decision`, `lesson`, `relation`,
56
- `goal`, `context`}. `scope` is filled in by the runner — do not include
57
- it. If nothing session-scope is in this batch, return `[]`.
20
+ - Private user preferences that should live in `user`.
21
+ - Facts about one VP only; those belong in the session VP scope.
22
+ - Topic-specific details that should live under a session topic scope.
23
+ - One-off chatter with no future value.
24
+
25
+ ## Output
26
+
27
+ Return a JSON array only. Each item must have `kind`, `body`, `tags`, `sourceMessages`, and `confidence`.
28
+
29
+ Make the segment useful to a future session member who needs the big picture plus the latest actionable detail.
30
+
31
+ <!-- lang:zh -->
32
+ # Dream Extract — Session Scope
33
+
34
+ 你正在从一段 session 对话中抽取 **memory segments**。本轮关注特定 **`sessions/<id>` scope**:一个协作 session 的稳定事实和共享上下文。
35
+
36
+ 目标 session id 会以 `{{sessionId}}` 提供。
37
+
38
+ ## `sessions/<id>` scope 应抽取什么
39
+
40
+ - **purpose** — 这个 session 存在的目的、charter 或 mission
41
+ - **members** 用户、VP、角色,以及各自负责什么
42
+ - **conventions** session 的协作方式:流程、命名、语言、review 规则
43
+ - **shared decisions** session 之后应该记住的稳定决策
44
+ - **shared context** — 整个 session 依赖的领域或项目信息
45
+ - **current state** — 当前重要的 PR、review、阻塞、下一步或 release 状态
46
+ - **lessons** — 未来 turn 应继续遵守的纠正和决策
47
+
48
+ ## 不要在这里抽取什么
49
+
50
+ - 应进入 `user` 的用户私人偏好。
51
+ - 只关于某个 VP 的事实;这些应进入 session VP scope。
52
+ - 应进入 session topic scope 的主题细节。
53
+ - 没有未来价值的一次性闲聊。
54
+
55
+ ## 输出
56
+
57
+ 只返回 JSON array。每一项必须包含 `kind`、`body`、`tags`、`sourceMessages` 和 `confidence`。
58
+
59
+ segment 应帮助未来的 session member 快速理解大背景和最新可执行细节。
@@ -1,59 +1,55 @@
1
+ <!-- lang:en -->
1
2
  # Dream Extract — Topic Scope
2
3
 
3
- You are extracting **memory segments** from a conversation between the
4
- user and a Yeaft AI companion. This pass focuses on a specific
5
- **`topic/<id>` scope**: long-lived facts and viewpoints about a domain
6
- topic that recurs across conversations (e.g. `topic/lang/rust`,
7
- `topic/auth/jwt`, `topic/ml/transformers`).
4
+ You are extracting **memory segments** from a session conversation. This pass focuses on a specific **session topic scope**: durable facts, decisions, and viewpoints about one recurring topic.
8
5
 
9
6
  The target topic id is provided as `{{topicId}}`.
10
7
 
11
- ## What to extract for `topic/<id>` scope
8
+ ## What to extract for the topic scope
12
9
 
13
- - **core facts** — durable knowledge about the topic (how it works,
14
- key terms, gotchas) that the user has either taught the assistant
15
- or confirmed
16
- - **viewpoints / opinions** — formed views the user holds on this
17
- topic ("I think GraphQL is overkill for internal tools")
18
- - **canonical references** — sources the user trusts on this topic
19
- (specific docs, papers, people)
20
- - **patterns** — how the user typically applies this topic
21
- ("when using JWT, always set short access-token TTL + refresh")
22
- - **lessons** — things that bit them, things that worked
23
- - **relations** — features, projects, or other topics tied to this one
10
+ - **core facts** — durable knowledge about the topic that the user taught or confirmed
11
+ - **viewpoints / opinions** — stable views the user or session formed on this topic
12
+ - **canonical references** — docs, files, PRs, issues, papers, or people treated as authoritative
13
+ - **patterns** — how this session usually applies the topic
14
+ - **lessons** gotchas, mistakes, corrections, or rules learned while working on the topic
15
+ - **current state** — latest PR/review/todo/status that still matters for this topic
24
16
 
25
17
  ## What NOT to extract here
26
18
 
27
- - Facts about the user as a person `user` scope.
28
- - Facts specific to one feature implementation `feature/<id>`.
29
- - Group conventions `sessions/<id>`.
30
- - Generic encyclopedia facts the assistant already knows — only the
31
- user's *durable views and confirmed knowledge* about the topic.
32
-
33
- ## Segment shape
34
-
35
- Each segment is **self-contained** and **about one thing**. Detail is
36
- OK; one-line summaries are NOT — capture rationale and specifics so
37
- the segment is useful next time without rehydrating the conversation.
38
-
39
- ## Output format
40
-
41
- Reply with a JSON array of segment objects:
42
-
43
- ```json
44
- [
45
- {
46
- "kind": "lesson",
47
- "tags": ["jwt", "auth"],
48
- "sourceMessages": ["m_330", "m_331"],
49
- "body": "On topic {{topicId}}: user always pairs short-lived JWT
50
- access tokens (≤15 min) with rotating refresh tokens stored as
51
- HttpOnly cookies. Got burned by a 24h-token leak in 2024 — single
52
- long-lived token is treated as a non-starter."
53
- }
54
- ]
55
- ```
56
-
57
- `kind` {`fact`, `preference`, `decision`, `lesson`, `relation`,
58
- `goal`, `context`}. `scope` is filled in by the runner — do not include
59
- it. If nothing topic-scope is in this batch, return `[]`.
19
+ - User biography or broad preferences unrelated to the topic.
20
+ - Session-wide charter information that is not specific to this topic.
21
+ - Details about one VP unless they matter to this topic.
22
+
23
+ ## Output
24
+
25
+ Return a JSON array only. Each item must have `kind`, `body`, `tags`, `sourceMessages`, and `confidence`.
26
+
27
+ Keep the topic memory sharp: enough background to orient the next turn, plus current details that should not be lost.
28
+
29
+ <!-- lang:zh -->
30
+ # Dream Extract — Topic Scope
31
+
32
+ 你正在从一段 session 对话中抽取 **memory segments**。本轮关注特定 **session topic scope**:关于某个反复出现主题的稳定事实、决策和观点。
33
+
34
+ 目标 topic id 会以 `{{topicId}}` 提供。
35
+
36
+ ## topic scope 应抽取什么
37
+
38
+ - **core facts** — 用户教过或确认过的、关于该主题的稳定知识
39
+ - **viewpoints / opinions** — 用户或 session 对该主题形成的稳定观点
40
+ - **canonical references** — 被视为权威的文档、文件、PR、issue、论文或人员
41
+ - **patterns** 这个 session 通常如何应用该主题
42
+ - **lessons** 围绕该主题学到的坑、错误、纠正或规则
43
+ - **current state** 该主题当前仍重要的 PR、review、todo 或状态
44
+
45
+ ## 不要在这里抽取什么
46
+
47
+ - 与主题无关的用户履历或广泛偏好。
48
+ - 与该主题无关的 session-wide charter 信息。
49
+ - 除非影响该主题,否则不要抽取单个 VP 的细节。
50
+
51
+ ## 输出
52
+
53
+ 只返回 JSON array。每一项必须包含 `kind`、`body`、`tags`、`sourceMessages` 和 `confidence`。
54
+
55
+ 保持 topic memory 精准:既要有下一轮需要的大背景,也要保留不该丢失的当前细节。
@@ -1,56 +1,67 @@
1
+ <!-- lang:en -->
1
2
  # Dream Extract — User Scope
2
3
 
3
- You are extracting **memory segments** from a conversation between the
4
- user and a Yeaft AI companion. This pass focuses on the **`user`
5
- scope**: long-lived facts about the user themselves.
4
+ You are extracting **memory segments** from a session conversation. This pass focuses on the **`user` scope**: long-lived facts about the user themselves.
6
5
 
7
6
  ## What to extract for `user` scope
8
7
 
9
8
  Extract segments that describe the user as a person:
10
9
 
11
10
  - **identity** — name, role, location, languages spoken, time zone
12
- - **preferences** — tools they use (zsh, vim, JS over TS, …), code style,
13
- communication style, what they value
14
- - **habits / workflow** — how they work, when they work, recurring
15
- patterns
16
- - **goals (long-term)** — what they're building, where they want to go
17
- - **relations** — people / projects / orgs they regularly mention
18
- - **lessons / opinions** — formed views ("I don't trust X", "Y is the
19
- right tool for Z")
11
+ - **preferences** — tools they use, code style, communication style, what they value
12
+ - **habits / workflow** — how they work, recurring patterns, process expectations
13
+ - **goals (long-term)** — what they are building, where they want to go
14
+ - **relations** — people, projects, or orgs they regularly mention
15
+ - **lessons / opinions** — durable views the user has formed or confirmed
20
16
 
21
17
  ## What NOT to extract here
22
18
 
23
- - Anything specific to a single feature, project, or VP those go to
24
- `feature/*`, `vp/*`, or `topic/*` scopes (handled by other passes).
25
- - Transient state ("I'm tired today") only durable facts.
26
- - Verbatim message copies — segments are *secondary processing*, not
27
- transcripts.
28
-
29
- ## Segment shape
30
-
31
- Each segment is **self-contained** and **about one thing**. A 30-turn
32
- conversation typically yields 1–3 user-scope segments, not 30. Detail
33
- is OK; one-line summaries are NOT — preserve the specifics that make
34
- the memory useful next time (e.g. "uses zsh with starship prompt" beats
35
- "uses a shell").
36
-
37
- ## Output format
38
-
39
- Reply with a JSON array of segment objects:
40
-
41
- ```json
42
- [
43
- {
44
- "kind": "preference",
45
- "tags": ["shell", "terminal"],
46
- "sourceMessages": ["m_142", "m_143"],
47
- "body": "User uses zsh with the starship prompt and prefers
48
- keyboard-only workflows. Wants suggestions to assume zsh + vim
49
- keybindings unless told otherwise."
50
- }
51
- ]
52
- ```
53
-
54
- `kind` ∈ {`fact`, `preference`, `decision`, `lesson`, `relation`,
55
- `goal`, `context`}. `scope` is filled in by the runner — do not include
56
- it. If nothing user-scope is in this batch, return `[]`.
19
+ - Anything specific to one session, feature, project, VP, or topic; those belong in narrower scopes.
20
+ - Temporary task status, transient debugging notes, or one-off implementation details.
21
+ - Facts inferred only from the assistant's guesswork.
22
+
23
+ ## Output
24
+
25
+ Return a JSON array only. Each item must have:
26
+
27
+ - `kind`: short category such as `preference`, `workflow`, `goal`, `identity`, `opinion`
28
+ - `body`: one concise factual sentence, grounded in the conversation
29
+ - `tags`: short lowercase tags
30
+ - `sourceMessages`: message ids that support the segment
31
+ - `confidence`: number from 0 to 1
32
+
33
+ Prefer fewer, higher-value segments. Do not invent facts.
34
+
35
+ <!-- lang:zh -->
36
+ # Dream Extract — User Scope
37
+
38
+ 你正在从一段 session 对话中抽取 **memory segments**。本轮只关注 **`user` scope**:关于用户本人的长期事实。
39
+
40
+ ## `user` scope 应抽取什么
41
+
42
+ 抽取描述用户本人的 segment:
43
+
44
+ - **identity** 姓名、角色、所在地、使用语言、时区
45
+ - **preferences** 使用的工具、代码风格、沟通风格、重视什么
46
+ - **habits / workflow** — 工作方式、重复出现的习惯、流程期待
47
+ - **goals (long-term)** — 用户长期在构建什么、想达到什么
48
+ - **relations** — 经常提到的人、项目或组织
49
+ - **lessons / opinions** — 用户已经形成或确认的稳定观点
50
+
51
+ ## 不要在这里抽取什么
52
+
53
+ - 只属于某个 session、feature、project、VP 或 topic 的内容;这些应进入更窄的 scope。
54
+ - 临时任务状态、短期调试记录、一次性实现细节。
55
+ - 只来自模型猜测、没有对话证据支持的事实。
56
+
57
+ ## 输出
58
+
59
+ 只返回 JSON array。每一项必须包含:
60
+
61
+ - `kind`:短类别,例如 `preference`、`workflow`、`goal`、`identity`、`opinion`
62
+ - `body`:一句简洁事实,必须基于对话证据
63
+ - `tags`:简短 lowercase tags
64
+ - `sourceMessages`:支持该 segment 的 message ids
65
+ - `confidence`:0 到 1 的数字
66
+
67
+ 宁可少抽,也要抽高价值内容。不要编造事实。
@@ -1,55 +1,57 @@
1
+ <!-- lang:en -->
1
2
  # Dream Extract — VP Scope
2
3
 
3
- You are extracting **memory segments** from a conversation between the
4
- user and a Yeaft AI companion. This pass focuses on a specific
5
- **`vp/<id>` scope**: long-lived facts about one Virtual Person (a
6
- persona / sub-agent / role the user works with).
4
+ You are extracting **memory segments** from a session conversation. This pass focuses on a specific **session VP scope**: durable facts about one Virtual Person in this session.
7
5
 
8
- The target VP id is provided as `{{vpId}}`. Only extract facts about
9
- *this* VP, not other VPs.
6
+ The target VP id is provided as `{{vpId}}`. Only extract facts about this VP, not other VPs.
10
7
 
11
- ## What to extract for `vp/<id>` scope
8
+ ## What to extract for the VP scope
12
9
 
13
- - **identity** — who this VP is, role, persona name, charter
14
- - **voice / style** — how they speak, tone, formatting habits, language
15
- - **expertise** — what they know well, what they should defer on
16
- - **interaction patterns** — how the user and this VP work together,
17
- what kinds of questions go to this VP, expected response shape
18
- - **boundaries** — what this VP will NOT do, or things to avoid
19
- - **relations** — other VPs, projects, or topics this VP is tied to
20
- - **decisions made by/about this VP** — durable choices ("VP X always
21
- reviews schema migrations"), not single-turn outcomes
10
+ - **identity / charter** — who this VP is in the session and what it is expected to own
11
+ - **voice / style** — how this VP should think, speak, format, and decide
12
+ - **expertise** — what the VP is good at and what it should defer
13
+ - **interaction patterns** — what the user typically asks this VP to do and expected response shape
14
+ - **boundaries** things this VP must not do, or should avoid
15
+ - **current state** — this VP's latest task, mistake, correction, review result, or handoff
16
+ - **relations** — other VPs, topics, or project areas this VP works with
22
17
 
23
18
  ## What NOT to extract here
24
19
 
25
- - Facts about the user themselves those go to `user` scope.
26
- - Facts about other VPs those go to *their* `vp/<other>` scope.
27
- - Single-turn task state — only durable persona facts.
28
- - Verbatim message copies — segments are *secondary processing*.
29
-
30
- ## Segment shape
31
-
32
- Each segment is **self-contained** and **about one thing**. Detail is
33
- OK; one-line summaries are NOT preserve specifics that make the
34
- memory useful next time.
35
-
36
- ## Output format
37
-
38
- Reply with a JSON array of segment objects:
39
-
40
- ```json
41
- [
42
- {
43
- "kind": "preference",
44
- "tags": ["voice", "style"],
45
- "sourceMessages": ["m_88"],
46
- "body": "VP {{vpId}} writes in concise bullet form, never uses
47
- emoji, and always cites file paths with line numbers. Switches to
48
- Chinese when the user does."
49
- }
50
- ]
51
- ```
52
-
53
- `kind` ∈ {`fact`, `preference`, `decision`, `lesson`, `relation`,
54
- `goal`, `context`}. `scope` is filled in by the runner — do not include
55
- it. If nothing about this VP is in this batch, return `[]`.
20
+ - Generic user preferences that belong in `user`.
21
+ - Session-wide decisions that do not specifically involve this VP.
22
+ - Facts about other VPs.
23
+
24
+ ## Output
25
+
26
+ Return a JSON array only. Each item must have `kind`, `body`, `tags`, `sourceMessages`, and `confidence`.
27
+
28
+ Prefer segments that make this VP behave better in the next turn.
29
+
30
+ <!-- lang:zh -->
31
+ # Dream Extract — VP Scope
32
+
33
+ 你正在从一段 session 对话中抽取 **memory segments**。本轮关注特定 **session VP scope**:这个 session 里某个 Virtual Person 的稳定事实。
34
+
35
+ 目标 VP id 会以 `{{vpId}}` 提供。只抽取关于这个 VP 的事实,不要抽取其他 VP。
36
+
37
+ ## VP scope 应抽取什么
38
+
39
+ - **identity / charter** — 这个 VP 在 session 中是谁,用户期待它负责什么
40
+ - **voice / style** — 这个 VP 应如何思考、表达、排版和判断
41
+ - **expertise** VP 擅长什么,哪些事情应交给别人
42
+ - **interaction patterns** 用户通常让这个 VP 做什么,期待什么输出形态
43
+ - **boundaries** 这个 VP 不能做或应避免的事情
44
+ - **current state** — 这个 VP 最新任务、错误、纠正、review 结果或 handoff
45
+ - **relations** — 这个 VP 关联的其他 VP、topic 或项目区域
46
+
47
+ ## 不要在这里抽取什么
48
+
49
+ - 应进入 `user` 的通用用户偏好。
50
+ - 与该 VP 无关的 session-wide 决策。
51
+ - 关于其他 VP 的事实。
52
+
53
+ ## 输出
54
+
55
+ 只返回 JSON array。每一项必须包含 `kind`、`body`、`tags`、`sourceMessages` 和 `confidence`。
56
+
57
+ 优先抽取能让这个 VP 在下一轮表现更好的 segment。
@@ -77,6 +77,24 @@ function load(name) {
77
77
  return txt;
78
78
  }
79
79
 
80
+ function extractExactLangSection(content, language) {
81
+ const marker = `<!-- lang:${language} -->`;
82
+ const start = content.indexOf(marker);
83
+ if (start === -1) return null;
84
+ const bodyStart = start + marker.length;
85
+ const nextMarker = content.indexOf('<!-- lang:', bodyStart);
86
+ return content.slice(bodyStart, nextMarker === -1 ? undefined : nextMarker).trim();
87
+ }
88
+
89
+ function selectTemplateLanguage(content, language) {
90
+ const effectiveLang = normalizePromptLanguage(language);
91
+ const selected = extractExactLangSection(content, effectiveLang);
92
+ if (selected !== null) return selected;
93
+ const fallback = extractExactLangSection(content, 'en');
94
+ if (fallback !== null) return fallback;
95
+ return content.trim();
96
+ }
97
+
80
98
  /**
81
99
  * Render a template with `{{name}}` substitution. Missing keys throw —
82
100
  * silent rendering of half-built prompts has bitten us before.
@@ -86,7 +104,7 @@ function load(name) {
86
104
  * @param {{ language?: string, includeLanguageDirective?: boolean }} [opts]
87
105
  */
88
106
  export function render(name, vars, opts = {}) {
89
- const tpl = load(name);
107
+ const tpl = selectTemplateLanguage(load(name), opts.language || 'en');
90
108
  const body = tpl.replace(/\{\{(\w+)\}\}/g, (_m, key) => {
91
109
  if (!(key in vars)) throw new Error(`prompts.${name}: missing var ${key}`);
92
110
  return vars[key];
@@ -1,40 +1,49 @@
1
+ <!-- lang:en -->
1
2
  # Dream Summarize — Per-Scope Compression
2
3
 
3
- You are summarizing the **memory segments** of a single scope into a
4
- short, dense prose summary. This is NOT extraction — the segments
5
- already exist. Your job is to compress them into a paragraph the
6
- session can keep resident in working memory.
4
+ You are summarizing the **memory segments** of a single scope into a short, dense prose summary. This is NOT extraction — the segments already exist. Your job is to compress them into a paragraph the session can keep resident in working memory.
7
5
 
8
- The target scope is `{{scope}}` and contains `{{segmentCount}}`
9
- segments listed below.
6
+ The target scope is `{{scope}}` and contains `{{segmentCount}}` segments listed below.
10
7
 
11
8
  ## Goals
12
9
 
13
- - A reader (the assistant in a future turn) should grasp **the gist of
14
- this scope** from your summary alone, without reading the segments.
15
- - Detail is OK but compress. Drop redundancy, keep specifics that
16
- matter (names, numbers, decisions, durable views).
17
- - Stay faithful: do not invent facts that are not in the segments. Do
18
- not "soften" decisions or opinions.
19
- - Bilingual: write in the same language the segments are mostly in.
10
+ - A future session member should grasp the gist of this scope from your summary alone, without reading all segments.
11
+ - Keep specifics that matter: names, numbers, decisions, durable views, current blockers, and next steps.
12
+ - Stay faithful: do not invent facts not present in the segments. Do not soften decisions or opinions.
13
+ - Write in the same language the segments are mostly in, unless the surrounding language directive says otherwise.
20
14
 
21
15
  ## Length
22
16
 
23
- - Target **≤ {{tokenBudget}} tokens**.
24
- - One paragraph for small scopes; two or three short paragraphs grouped
25
- by theme for larger scopes. No bullet lists, no headings.
17
+ - Target `{{tokenBudget}}` tokens.
18
+ - One paragraph for small scopes; two or three compact paragraphs for larger scopes.
19
+ - Prefer dense prose over bullet lists unless bullets are clearly more compact.
26
20
 
27
- ## What NOT to do
21
+ Segments:
22
+ {{segments}}
28
23
 
29
- - Don't list every segment one by one — that defeats compression.
30
- - Don't quote verbatim chunks of segment bodies.
31
- - Don't add meta-commentary ("the segments show that..."). Speak
32
- directly about the subject.
24
+ Return only the summary text.
33
25
 
34
- ## Segments
26
+ <!-- lang:zh -->
27
+ # Dream Summarize — Per-Scope Compression
35
28
 
36
- {{segments}}
29
+ 你正在把单个 scope 的 **memory segments** 压缩成一段简短、密集的 prose summary。这不是抽取 —— segments 已经存在。你的任务是把它们压缩成 session 可以常驻在工作记忆里的摘要。
30
+
31
+ 目标 scope 是 `{{scope}}`,包含下面列出的 `{{segmentCount}}` 个 segments。
32
+
33
+ ## 目标
37
34
 
38
- ## Output
35
+ - 未来的 session member 只读 summary,也应能理解这个 scope 的核心意思。
36
+ - 保留重要具体信息:名字、数字、决策、稳定观点、当前阻塞和下一步。
37
+ - 忠于事实:不要编造 segments 中没有的事实。不要弱化已经明确的决策或观点。
38
+ - 使用 segments 主要使用的语言;如果外层语言指令另有要求,以外层语言指令为准。
39
+
40
+ ## 长度
41
+
42
+ - 目标 ≤ `{{tokenBudget}}` tokens。
43
+ - 小 scope 用一段;较大 scope 用两到三个紧凑段落。
44
+ - 除非 bullet 明显更紧凑,否则优先使用密集自然段。
45
+
46
+ Segments:
47
+ {{segments}}
39
48
 
40
- Reply with the prose summary only. No preamble, no JSON, no fences.
49
+ 只返回 summary 文本。