@yeaft/webchat-agent 0.1.853 → 0.1.856

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 (174) hide show
  1. package/bin/yeaft-stats.js +3 -3
  2. package/connection/message-router.js +73 -44
  3. package/context.js +4 -4
  4. package/expert-roles.js +1 -1
  5. package/index.js +1 -1
  6. package/package.json +4 -4
  7. package/service/index.js +1 -1
  8. package/{unify → yeaft}/attachments.js +7 -7
  9. package/{unify → yeaft}/cli.js +4 -4
  10. package/{unify → yeaft}/compact/compactor.js +10 -10
  11. package/{unify → yeaft}/config-api.js +12 -12
  12. package/{unify → yeaft}/config.js +19 -19
  13. package/{unify → yeaft}/conversation/migrate-messages-threadid.js +1 -1
  14. package/{unify → yeaft}/conversation/persist.js +194 -65
  15. package/{unify → yeaft}/conversation/search.js +28 -23
  16. package/{unify → yeaft}/debug-trace.js +1 -1
  17. package/{unify → yeaft}/dream-v2/limits.js +3 -3
  18. package/{unify → yeaft}/dream-v2/runner.js +1 -1
  19. package/{unify → yeaft}/dream-v2/session-wiring.js +2 -2
  20. package/{unify → yeaft}/effort.js +2 -2
  21. package/{unify → yeaft}/engine.js +12 -14
  22. package/{unify → yeaft}/eval/run-eval.js +11 -11
  23. package/{unify → yeaft}/eval/runner.js +1 -1
  24. package/{unify → yeaft}/groups/feature-flag.js +2 -2
  25. package/{unify → yeaft}/groups/index.js +2 -2
  26. package/{unify → yeaft}/groups/pre-flow.js +1 -1
  27. package/{unify → yeaft}/groups/project-doc.js +1 -1
  28. package/{unify → yeaft}/history-compact.js +3 -3
  29. package/{unify → yeaft}/index.js +1 -1
  30. package/{unify → yeaft}/init.js +15 -9
  31. package/{unify → yeaft}/llm/adapter.js +1 -1
  32. package/{unify → yeaft}/llm/anthropic.js +2 -2
  33. package/{unify → yeaft}/llm/models-dev.js +10 -3
  34. package/{unify → yeaft}/llm/openai-responses.js +2 -2
  35. package/{unify → yeaft}/llm/router.js +1 -1
  36. package/{unify → yeaft}/mcp.js +1 -1
  37. package/{unify → yeaft}/memory/ams-registry.js +1 -1
  38. package/{unify → yeaft}/memory/seed-backfill.js +1 -1
  39. package/{unify → yeaft}/memory/store-v2.js +1 -1
  40. package/{unify → yeaft}/models.js +3 -3
  41. package/{unify → yeaft}/pair-sanitize.js +2 -2
  42. package/{unify → yeaft}/personas.js +1 -1
  43. package/{unify → yeaft}/prompts.js +1 -1
  44. package/{unify → yeaft}/routing/index.js +1 -1
  45. package/{unify → yeaft}/routing/router.js +1 -1
  46. package/{unify → yeaft}/session.js +8 -8
  47. package/{unify → yeaft}/skills.js +2 -2
  48. package/{unify → yeaft}/stats/format.js +1 -1
  49. package/{unify → yeaft}/stop-hooks.js +1 -1
  50. package/{unify → yeaft}/sub-agent/runner.js +1 -1
  51. package/{unify → yeaft}/tools/ask-user.js +2 -2
  52. package/{unify → yeaft}/tools/enter-worktree.js +1 -1
  53. package/{unify → yeaft}/tools/exit-worktree.js +1 -1
  54. package/{unify → yeaft}/tools/mcp-tools.js +1 -1
  55. package/{unify → yeaft}/tools/registry.js +2 -2
  56. package/{unify → yeaft}/tools/skill.js +1 -1
  57. package/{unify → yeaft}/tools/start-plan.js +1 -1
  58. package/{unify → yeaft}/tools/types.js +3 -3
  59. package/{unify → yeaft}/tools/web-search.js +1 -1
  60. package/{unify → yeaft}/turn-utils.js +1 -1
  61. package/{unify → yeaft}/vp/index.js +1 -1
  62. package/{unify → yeaft}/vp/registry.js +1 -1
  63. package/{unify → yeaft}/vp/vp-bridge.js +8 -8
  64. package/{unify → yeaft}/web-bridge.js +239 -238
  65. /package/{unify → yeaft}/archive/tool-results.js +0 -0
  66. /package/{unify → yeaft}/archive/trace.js +0 -0
  67. /package/{unify → yeaft}/archive/turn-archive.js +0 -0
  68. /package/{unify → yeaft}/compact/decisions-log.js +0 -0
  69. /package/{unify → yeaft}/compact/orchestrator.js +0 -0
  70. /package/{unify → yeaft}/compact/triggers.js +0 -0
  71. /package/{unify → yeaft}/compact/turn-group.js +0 -0
  72. /package/{unify → yeaft}/dream-v2/apply.js +0 -0
  73. /package/{unify → yeaft}/dream-v2/merge.js +0 -0
  74. /package/{unify → yeaft}/dream-v2/prompts/create.md +0 -0
  75. /package/{unify → yeaft}/dream-v2/prompts/extract-group.md +0 -0
  76. /package/{unify → yeaft}/dream-v2/prompts/extract-topic.md +0 -0
  77. /package/{unify → yeaft}/dream-v2/prompts/extract-user.md +0 -0
  78. /package/{unify → yeaft}/dream-v2/prompts/extract-vp.md +0 -0
  79. /package/{unify → yeaft}/dream-v2/prompts/index.js +0 -0
  80. /package/{unify → yeaft}/dream-v2/prompts/summarize-scope.md +0 -0
  81. /package/{unify → yeaft}/dream-v2/prompts/triage-pass1.md +0 -0
  82. /package/{unify → yeaft}/dream-v2/prompts/triage-pass2.md +0 -0
  83. /package/{unify → yeaft}/dream-v2/prompts/update.md +0 -0
  84. /package/{unify → yeaft}/dream-v2/schedule.js +0 -0
  85. /package/{unify → yeaft}/dream-v2/segment.js +0 -0
  86. /package/{unify → yeaft}/dream-v2/snapshot.js +0 -0
  87. /package/{unify → yeaft}/dream-v2/state.js +0 -0
  88. /package/{unify → yeaft}/dream-v2/triage.js +0 -0
  89. /package/{unify → yeaft}/eval/cases/e2e.js +0 -0
  90. /package/{unify → yeaft}/eval/cases/memory.js +0 -0
  91. /package/{unify → yeaft}/eval/cases/skills.js +0 -0
  92. /package/{unify → yeaft}/eval/cases/tool-use.js +0 -0
  93. /package/{unify → yeaft}/groups/coordinator.js +0 -0
  94. /package/{unify → yeaft}/groups/group-config.js +0 -0
  95. /package/{unify → yeaft}/groups/group-crud.js +0 -0
  96. /package/{unify → yeaft}/groups/group-store.js +0 -0
  97. /package/{unify → yeaft}/groups/ids.js +0 -0
  98. /package/{unify → yeaft}/groups/roster.js +0 -0
  99. /package/{unify → yeaft}/groups/seed-default.js +0 -0
  100. /package/{unify → yeaft}/llm/credentials/github-copilot.js +0 -0
  101. /package/{unify → yeaft}/llm/credentials/index.js +0 -0
  102. /package/{unify → yeaft}/memory/adjust.js +0 -0
  103. /package/{unify → yeaft}/memory/ams.js +0 -0
  104. /package/{unify → yeaft}/memory/budget.js +0 -0
  105. /package/{unify → yeaft}/memory/consolidate.js +0 -0
  106. /package/{unify → yeaft}/memory/index-db.js +0 -0
  107. /package/{unify → yeaft}/memory/keywords.js +0 -0
  108. /package/{unify → yeaft}/memory/preflow.js +0 -0
  109. /package/{unify → yeaft}/memory/segment-store.js +0 -0
  110. /package/{unify → yeaft}/memory/segment-sync.js +0 -0
  111. /package/{unify → yeaft}/memory/segment.js +0 -0
  112. /package/{unify → yeaft}/memory/summary-store.js +0 -0
  113. /package/{unify → yeaft}/router/continuity.js +0 -0
  114. /package/{unify → yeaft}/router/thinking.js +0 -0
  115. /package/{unify → yeaft}/routing/loop-guard.js +0 -0
  116. /package/{unify → yeaft}/stats/tool-usage.js +0 -0
  117. /package/{unify → yeaft}/storage/atomic.js +0 -0
  118. /package/{unify → yeaft}/storage/compact.js +0 -0
  119. /package/{unify → yeaft}/storage/index.js +0 -0
  120. /package/{unify → yeaft}/storage/jsonl-index.js +0 -0
  121. /package/{unify → yeaft}/storage/jsonl-log.js +0 -0
  122. /package/{unify → yeaft}/storage/shard-index.js +0 -0
  123. /package/{unify → yeaft}/storage/shard-store.js +0 -0
  124. /package/{unify → yeaft}/sub-agent/spawned-prompt.js +0 -0
  125. /package/{unify → yeaft}/templates/base.md +0 -0
  126. /package/{unify → yeaft}/templates/common-rules.md +0 -0
  127. /package/{unify → yeaft}/templates/harness/router-handoff.md +0 -0
  128. /package/{unify → yeaft}/templates/harness/router-shape.md +0 -0
  129. /package/{unify → yeaft}/templates/harness/worker-shape.md +0 -0
  130. /package/{unify → yeaft}/templates/identity-yeaft.md +0 -0
  131. /package/{unify → yeaft}/templates/mode-dream.md +0 -0
  132. /package/{unify → yeaft}/templates/mode-unified.md +0 -0
  133. /package/{unify → yeaft}/templates/personas/explorer.md +0 -0
  134. /package/{unify → yeaft}/templates/personas/implementer.md +0 -0
  135. /package/{unify → yeaft}/templates/personas/researcher.md +0 -0
  136. /package/{unify → yeaft}/templates/personas/reviewer.md +0 -0
  137. /package/{unify → yeaft}/templates/plan-instruction.md +0 -0
  138. /package/{unify → yeaft}/templates/tool-guidance.md +0 -0
  139. /package/{unify → yeaft}/tool-folding/exec-log.js +0 -0
  140. /package/{unify → yeaft}/tool-folding/fallback-stub.js +0 -0
  141. /package/{unify → yeaft}/tool-folding/index.js +0 -0
  142. /package/{unify → yeaft}/tool-folding/reflection-prompt.js +0 -0
  143. /package/{unify → yeaft}/tool-folding/t1-reflector.js +0 -0
  144. /package/{unify → yeaft}/tool-folding/t2-reflector.js +0 -0
  145. /package/{unify → yeaft}/tools/agent.js +0 -0
  146. /package/{unify → yeaft}/tools/apply-patch.js +0 -0
  147. /package/{unify → yeaft}/tools/bash.js +0 -0
  148. /package/{unify → yeaft}/tools/close-agent.js +0 -0
  149. /package/{unify → yeaft}/tools/file-edit.js +0 -0
  150. /package/{unify → yeaft}/tools/file-read.js +0 -0
  151. /package/{unify → yeaft}/tools/file-write.js +0 -0
  152. /package/{unify → yeaft}/tools/glob.js +0 -0
  153. /package/{unify → yeaft}/tools/grep.js +0 -0
  154. /package/{unify → yeaft}/tools/history-search.js +0 -0
  155. /package/{unify → yeaft}/tools/image-generation.js +0 -0
  156. /package/{unify → yeaft}/tools/index.js +0 -0
  157. /package/{unify → yeaft}/tools/js-repl.js +0 -0
  158. /package/{unify → yeaft}/tools/list-agents.js +0 -0
  159. /package/{unify → yeaft}/tools/list-dir.js +0 -0
  160. /package/{unify → yeaft}/tools/notebook-edit.js +0 -0
  161. /package/{unify → yeaft}/tools/route-forward.js +0 -0
  162. /package/{unify → yeaft}/tools/send-message.js +0 -0
  163. /package/{unify → yeaft}/tools/todo-write.js +0 -0
  164. /package/{unify → yeaft}/tools/view-image.js +0 -0
  165. /package/{unify → yeaft}/tools/wait-agent.js +0 -0
  166. /package/{unify → yeaft}/tools/web-fetch.js +0 -0
  167. /package/{unify → yeaft}/vp/seed-defaults.js +0 -0
  168. /package/{unify → yeaft}/vp/seed-topup.js +0 -0
  169. /package/{unify → yeaft}/vp/stock-ids.js +0 -0
  170. /package/{unify → yeaft}/vp/thread-classifier.js +0 -0
  171. /package/{unify → yeaft}/vp/vp-crud.js +0 -0
  172. /package/{unify → yeaft}/vp/vp-loader.js +0 -0
  173. /package/{unify → yeaft}/vp/vp-store.js +0 -0
  174. /package/{unify → yeaft}/vp-status-broker.js +0 -0
@@ -2,46 +2,48 @@
2
2
  * search.js — Conversation history search
3
3
  *
4
4
  * Simple keyword search across hot and cold messages.
5
- * Reference: yeaft-unify-core-systems.md §4.3
6
5
  */
7
6
 
8
7
  import { existsSync, readdirSync, readFileSync } from 'fs';
9
8
  import { join } from 'path';
10
- import { parseMessage } from './persist.js';
9
+ import { parseMessage, parseSeqFromId } from './persist.js';
11
10
 
12
11
  /**
13
12
  * Search messages in a directory for a keyword.
14
13
  *
15
14
  * @param {string} dir — messages directory
16
15
  * @param {string} keyword — search term (case-insensitive)
17
- * @param {number} limit — max results
18
16
  * @returns {object[]} — matching messages
19
17
  */
20
- function searchDir(dir, keyword, limit) {
18
+ function searchDir(dir, keyword) {
21
19
  if (!existsSync(dir)) return [];
22
20
 
23
21
  const lowerKeyword = keyword.toLowerCase();
24
22
  const files = readdirSync(dir)
25
23
  .filter(f => f.endsWith('.md'))
26
24
  .sort()
27
- .reverse(); // newest first
25
+ .reverse(); // newest first within one directory
28
26
 
29
27
  const results = [];
30
28
  for (const file of files) {
31
- if (results.length >= limit) break;
32
-
33
29
  const raw = readFileSync(join(dir, file), 'utf8');
34
- if (raw.toLowerCase().includes(lowerKeyword)) {
35
- const msg = parseMessage(raw);
36
- if (msg) results.push(msg);
37
- }
38
- }
30
+ if (!raw.toLowerCase().includes(lowerKeyword)) continue;
39
31
 
32
+ const msg = parseMessage(raw);
33
+ if (msg) results.push(msg);
34
+ }
40
35
  return results;
41
36
  }
42
37
 
38
+ function compareNewestFirst(a, b) {
39
+ const sa = parseSeqFromId(a?.id);
40
+ const sb = parseSeqFromId(b?.id);
41
+ if (Number.isFinite(sa) && Number.isFinite(sb) && sa !== sb) return sb - sa;
42
+ return String(b?.time || '').localeCompare(String(a?.time || ''));
43
+ }
44
+
43
45
  /**
44
- * Search conversation history (hot + cold) for a keyword.
46
+ * Search Yeaft history (chat + group + legacy conversation) for a keyword.
45
47
  *
46
48
  * @param {string} dir — Yeaft root directory (e.g. ~/.yeaft)
47
49
  * @param {string} keyword — search term
@@ -51,15 +53,18 @@ function searchDir(dir, keyword, limit) {
51
53
  export function searchMessages(dir, keyword, limit = 20) {
52
54
  if (!keyword || !keyword.trim()) return [];
53
55
 
54
- const msgDir = join(dir, 'conversation', 'messages');
55
- const coldDir = join(dir, 'conversation', 'cold');
56
-
57
- // Search hot first (more recent), then cold
58
- const hotResults = searchDir(msgDir, keyword, limit);
59
- const remaining = limit - hotResults.length;
60
- const coldResults = remaining > 0
61
- ? searchDir(coldDir, keyword, remaining)
62
- : [];
56
+ const dirs = [
57
+ join(dir, 'chat', 'messages'),
58
+ join(dir, 'chat', 'cold'),
59
+ join(dir, 'group', 'messages'),
60
+ join(dir, 'group', 'cold'),
61
+ // Compatibility for profiles created before chat/group split.
62
+ join(dir, 'conversation', 'messages'),
63
+ join(dir, 'conversation', 'cold'),
64
+ ];
63
65
 
64
- return [...hotResults, ...coldResults];
66
+ return dirs
67
+ .flatMap(d => searchDir(d, keyword))
68
+ .sort(compareNewestFirst)
69
+ .slice(0, limit);
65
70
  }
@@ -401,7 +401,7 @@ export class DebugTrace {
401
401
  }
402
402
 
403
403
  /**
404
- * Fetch the recent debug history for the UnifyDebugPanel. Returns one
404
+ * Fetch the recent debug history for the YeaftDebugPanel. Returns one
405
405
  * record per LLM loop (ordered oldest → newest) with the structured
406
406
  * fields the panel expects. JSON columns are parsed; truncated /
407
407
  * malformed payloads degrade to null instead of failing the call.
@@ -6,7 +6,7 @@
6
6
  * callers that want to override one knob without restating the rest.
7
7
  *
8
8
  * `loadLimitsFromConfig(config)` merges a `~/.yeaft/config.json`
9
- * `unify.dream` block on top of defaults; unknown keys are ignored,
9
+ * `yeaft.dream` block on top of defaults; unknown keys are ignored,
10
10
  * malformed values fall back to default.
11
11
  */
12
12
 
@@ -35,12 +35,12 @@ export const DEFAULT_LIMITS = Object.freeze({
35
35
  });
36
36
 
37
37
  /**
38
- * Merge a config object's `unify.dream` block on top of defaults.
38
+ * Merge a config object's `yeaft.dream` block on top of defaults.
39
39
  * @param {object} [config]
40
40
  */
41
41
  export function loadLimitsFromConfig(config) {
42
42
  const out = { ...DEFAULT_LIMITS };
43
- const ud = config && config.unify && config.unify.dream;
43
+ const ud = config && config.yeaft && config.yeaft.dream;
44
44
  if (!ud || typeof ud !== 'object') return out;
45
45
  for (const k of Object.keys(out)) {
46
46
  if (Object.prototype.hasOwnProperty.call(ud, k)) {
@@ -29,7 +29,7 @@
29
29
  * pruneOldSnapshots()
30
30
  *
31
31
  * onProgress emits dream_progress events that the web bridge forwards
32
- * as `unify_output` messages so the debug panel can render live state
32
+ * as `yeaft_output` messages so the debug panel can render live state
33
33
  * . All events flow through the same channel; no new
34
34
  * WebSocket message type is introduced.
35
35
  *
@@ -9,7 +9,7 @@
9
9
  * retired (task-710) — the wiring is unconditional.
10
10
  *
11
11
  * ─────────────────────────────────────────────────────────────────────
12
- * Wire contract — DreamEvent (consumed by web/components/UnifyDebugPanel.js)
12
+ * Wire contract — DreamEvent (consumed by web/components/YeaftDebugPanel.js)
13
13
  * ─────────────────────────────────────────────────────────────────────
14
14
  * The events persisted to trace_events with these event_type values are
15
15
  * load-bearing for the debug panel. Renaming a field on this side
@@ -282,7 +282,7 @@ function persistDreamTrace(session, eventType, eventData) {
282
282
  /**
283
283
  * Create a v2 dream scheduler bound to a session and wire its progress
284
284
  * events into the engine's sub-agent event sink (web-bridge translates
285
- * `dream_progress` into `unify_output` for the debug panel).
285
+ * `dream_progress` into `yeaft_output` for the debug panel).
286
286
  *
287
287
  * @param {Object} session
288
288
  * @returns {Object} — scheduler (start/stop/triggerNow)
@@ -1,5 +1,5 @@
1
1
  /**
2
- * effort.js — Scenario → effort decision tree for Unify
2
+ * effort.js — Scenario → effort decision tree for Yeaft
3
3
  *
4
4
  * task-327b: given a per-query context (scenario tag, tool-loop depth,
5
5
  * user override), pick the thinking/reasoning effort level that should be
@@ -14,7 +14,7 @@
14
14
  *
15
15
  * Red lines:
16
16
  * • Never error on unknown scenario — default to 'max'.
17
- * • Feature flag UNIFY_THINKING_V1 is enforced at the adapter/router
17
+ * • Feature flag YEAFT_THINKING_V1 is enforced at the adapter/router
18
18
  * layer; this module just computes the intended value. If the flag
19
19
  * is off, adapters drop it anyway.
20
20
  * • Unsupported models silently drop effort at the router — this
@@ -14,7 +14,7 @@
14
14
  *
15
15
  * Pattern derived from Claude Code's query loop (src/query.ts).
16
16
  *
17
- * Reference: yeaft-unify-implementation-plan.md §3.1, §4 (Phase 2)
17
+ * Reference: yeaft-yeaft-implementation-plan.md §3.1, §4 (Phase 2)
18
18
  */
19
19
 
20
20
  import { randomUUID } from 'crypto';
@@ -60,7 +60,7 @@ import {
60
60
  * task-324 — Turn cap removed.
61
61
  *
62
62
  * Previously MAX_TURNS=25 broke the query loop out of long tool-driven
63
- * conversations (user report: Unify loop errored at the cap). The engine
63
+ * conversations (user report: Yeaft loop errored at the cap). The engine
64
64
  * now runs until the LLM itself returns stopReason='end_turn' or a
65
65
  * non-retryable error surfaces. Real runaway loops are still bounded by:
66
66
  * • provider rate limits / context window (LLMContextError → compact)
@@ -81,7 +81,7 @@ const MAX_CONTINUE_TURNS = 3;
81
81
  * Content is passed through verbatim — never truncated. Debug traces must
82
82
  * mirror exactly what we sent to the LLM; a truncated copy is misleading.
83
83
  * If the resulting payload is too large for the client debug store the
84
- * bound is per-loop-count (see `MAX_UNIFY_DEBUG_LOOPS` in
84
+ * bound is per-loop-count (see `MAX_YEAFT_DEBUG_LOOPS` in
85
85
  * `web/stores/chat.js`), not per-payload mutilation here.
86
86
  *
87
87
  * Pure function — no side effects on the input message.
@@ -790,7 +790,7 @@ export class Engine {
790
790
  // Worker-shape harness is descriptive metadata for human inspection;
791
791
  // production prompts skip it to save tokens. Re-enable via env when
792
792
  // diagnosing prompt structure issues.
793
- includeShape: process.env.UNIFY_PROMPT_INCLUDE_SHAPE === '1',
793
+ includeShape: process.env.YEAFT_PROMPT_INCLUDE_SHAPE === '1',
794
794
  });
795
795
  }
796
796
 
@@ -888,9 +888,9 @@ export class Engine {
888
888
  // ViewImage (task-333b PR-B rev-3 P1-A): expose size cap + allowlist
889
889
  // via tool ctx so hosts can override via ~/.yeaft/config.json without
890
890
  // touching the tool impl.
891
- maxImageBytes: this.#config?.unify?.maxImageBytes,
892
- imageAllowlist: Array.isArray(this.#config?.unify?.imageAllowlist)
893
- ? this.#config.unify.imageAllowlist
891
+ maxImageBytes: this.#config?.yeaft?.maxImageBytes,
892
+ imageAllowlist: Array.isArray(this.#config?.yeaft?.imageAllowlist)
893
+ ? this.#config.yeaft.imageAllowlist
894
894
  : [],
895
895
  // Bug 4 fix — VP / routing context for RouteForward (and any other
896
896
  // VP-aware tool). Undefined when running in non-group / no-VP flows.
@@ -991,14 +991,12 @@ export class Engine {
991
991
  #getCompactSummary() {
992
992
  if (!this.#conversationStore) return '';
993
993
  // Per-(group, vp) scoping: when this engine is bound to a fan-out VP,
994
- // read its own summary file. On a miss (empty scoped file) we fall
995
- // through to the legacy global file so pre-PR sessions whose only
996
- // summary lives in compact.md still surface their context — matches
997
- // the OR-fallback in web-bridge's `hasCompactSummary` flag.
994
+ // read ONLY its own summary file. Falling back to legacy compact.md here
995
+ // leaks another group/VP's summary into every new group turn after one
996
+ // post-turn compact writes the session-global file.
998
997
  if (this.#groupId && this.#vpId
999
998
  && typeof this.#conversationStore.readCompactSummaryFor === 'function') {
1000
- const scoped = this.#conversationStore.readCompactSummaryFor(this.#groupId, this.#vpId);
1001
- if (scoped) return scoped;
999
+ return this.#conversationStore.readCompactSummaryFor(this.#groupId, this.#vpId);
1002
1000
  }
1003
1001
  return this.#conversationStore.readCompactSummary();
1004
1002
  }
@@ -2737,7 +2735,7 @@ export class Engine {
2737
2735
  /**
2738
2736
  * Run a one-shot fast-model call to produce a compact summary.
2739
2737
  * Used by the web bridge's in-memory history compactor
2740
- * (`agent/unify/history-compact.js`) — kept on the engine so callers
2738
+ * (`agent/yeaft/history-compact.js`) — kept on the engine so callers
2741
2739
  * don't reach into the private adapter field.
2742
2740
  *
2743
2741
  * @param {{system: string, prompt: string, maxTokens?: number}} args
@@ -5,22 +5,22 @@
5
5
  *
6
6
  * Usage:
7
7
  * # Run all evals against default model (requires API key)
8
- * node agent/unify/eval/run-eval.js
8
+ * node agent/yeaft/eval/run-eval.js
9
9
  *
10
10
  * # Run specific suite
11
- * node agent/unify/eval/run-eval.js --suite tools
11
+ * node agent/yeaft/eval/run-eval.js --suite tools
12
12
  *
13
13
  * # Compare multiple models
14
- * node agent/unify/eval/run-eval.js --models claude-sonnet-4-20250514,gpt-5
14
+ * node agent/yeaft/eval/run-eval.js --models claude-sonnet-4-20250514,gpt-5
15
15
  *
16
16
  * # Save baseline
17
- * node agent/unify/eval/run-eval.js --save-baseline initial
17
+ * node agent/yeaft/eval/run-eval.js --save-baseline initial
18
18
  *
19
19
  * # Compare against baseline
20
- * node agent/unify/eval/run-eval.js --compare-baseline baselines/initial.json
20
+ * node agent/yeaft/eval/run-eval.js --compare-baseline baselines/initial.json
21
21
  *
22
22
  * # Dry run (MockAdapter, no API calls)
23
- * node agent/unify/eval/run-eval.js --dry-run
23
+ * node agent/yeaft/eval/run-eval.js --dry-run
24
24
  *
25
25
  * Environment:
26
26
  * YEAFT_API_KEY — Anthropic API key
@@ -62,7 +62,7 @@ if (args.help) {
62
62
  Yeaft Eval Runner
63
63
 
64
64
  Usage:
65
- node agent/unify/eval/run-eval.js [options]
65
+ node agent/yeaft/eval/run-eval.js [options]
66
66
 
67
67
  Options:
68
68
  -s, --suite <name> Run specific suite: tools, memory, skills, e2e, all (default: all)
@@ -78,16 +78,16 @@ Environment:
78
78
 
79
79
  Examples:
80
80
  # Quick dry run to verify harness works
81
- node agent/unify/eval/run-eval.js --dry-run
81
+ node agent/yeaft/eval/run-eval.js --dry-run
82
82
 
83
83
  # Run tool evals against Claude Sonnet
84
- node agent/unify/eval/run-eval.js --suite tools --models claude-sonnet-4-20250514
84
+ node agent/yeaft/eval/run-eval.js --suite tools --models claude-sonnet-4-20250514
85
85
 
86
86
  # Full eval, save baseline
87
- node agent/unify/eval/run-eval.js --save-baseline v0.1.411
87
+ node agent/yeaft/eval/run-eval.js --save-baseline v0.1.411
88
88
 
89
89
  # Check for regressions
90
- node agent/unify/eval/run-eval.js --compare-baseline baselines/v0.1.411.json
90
+ node agent/yeaft/eval/run-eval.js --compare-baseline baselines/v0.1.411.json
91
91
  `);
92
92
  process.exit(0);
93
93
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * eval/runner.js — Eval harness for Yeaft Unify
2
+ * eval/runner.js — Eval harness for Yeaft Yeaft
3
3
  *
4
4
  * Runs eval cases against one or more models and produces scored results.
5
5
  * Each eval case defines:
@@ -1,5 +1,5 @@
1
1
  /**
2
- * feature-flag.js — Reads `config.unify.multiVp.enabled` from ~/.yeaft/config.json.
2
+ * feature-flag.js — Reads `config.yeaft.multiVp.enabled` from ~/.yeaft/config.json.
3
3
  *
4
4
  * Per architecture §11: multi-VP group mode is opt-in for MVP. The flag
5
5
  * gates UI entry points and (later) migration. This module returns a plain
@@ -14,7 +14,7 @@ import { join } from 'path';
14
14
  import { writeAtomic } from '../storage/index.js';
15
15
 
16
16
  const CONFIG_FILE = 'config.json';
17
- const FLAG_PATH = ['unify', 'multiVp', 'enabled'];
17
+ const FLAG_PATH = ['yeaft', 'multiVp', 'enabled'];
18
18
 
19
19
  function readConfig(yeaftDir) {
20
20
  const path = join(yeaftDir, CONFIG_FILE);
@@ -6,10 +6,10 @@
6
6
  * - Roster mutation helpers
7
7
  * - Coordinator that parses @-mentions on USER messages and dispatches to
8
8
  * target RoleInstances via a caller-supplied `deliver(vpId, envelope)`.
9
- * - Feature flag reader for `unify.multiVp.enabled`
9
+ * - Feature flag reader for `yeaft.multiVp.enabled`
10
10
  * - First-boot default group seeder
11
11
  *
12
- * See agent/unify/groups/coordinator.js for the dispatch contract.
12
+ * See agent/yeaft/groups/coordinator.js for the dispatch contract.
13
13
  */
14
14
 
15
15
  export {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * groups/pre-flow.js — explicit pre-flow stage for Unify.
2
+ * groups/pre-flow.js — explicit pre-flow stage for Yeaft.
3
3
  *
4
4
  * Pre-flow is the "before any VP runs" stage. It owns:
5
5
  *
@@ -140,7 +140,7 @@ export function readProjectDoc(workDir, opts = {}) {
140
140
  const text = buffer.toString('utf8', 0, useBytes).trim();
141
141
  if (truncated) {
142
142
  console.warn(
143
- `[unify/project-doc] ${picked.path} exceeds ${maxBytes} bytes — truncated.`,
143
+ `[yeaft/project-doc] ${picked.path} exceeds ${maxBytes} bytes — truncated.`,
144
144
  );
145
145
  }
146
146
  if (!text) return null;
@@ -1,15 +1,15 @@
1
1
  /**
2
2
  * history-compact.js — In-memory conversation history compaction for the
3
- * Unify group-chat fan-out path.
3
+ * Yeaft group-chat fan-out path.
4
4
  *
5
5
  * Problem this solves:
6
- * `agent/unify/web-bridge.js` keeps a flat module-level array
6
+ * `agent/yeaft/web-bridge.js` keeps a flat module-level array
7
7
  * `conversationMessages` that grows unbounded across the lifetime of the
8
8
  * agent process. Every fan-out turn snapshots the whole thing into
9
9
  * `baseSnapshot` and feeds it to `engine.query` for every VP. Without a
10
10
  * cap, prompt size and token cost grow linearly with conversation length.
11
11
  *
12
- * Existing infrastructure (`agent/unify/compact/orchestrator.js`,
12
+ * Existing infrastructure (`agent/yeaft/compact/orchestrator.js`,
13
13
  * `engine.js#runOrchestratorCompact`) compacts the on-disk
14
14
  * `conversationStore` — a different surface. This helper compacts the
15
15
  * in-memory array that actually gets passed to the LLM.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * index.js — Yeaft Unify module entry point
2
+ * index.js — Yeaft Yeaft module entry point
3
3
  *
4
4
  * Re-exports all public APIs for external consumption.
5
5
  */
@@ -2,7 +2,7 @@
2
2
  * init.js — Yeaft directory structure initialization
3
3
  *
4
4
  * Ensures ~/.yeaft/ and all required subdirectories exist.
5
- * Creates default config.md, MEMORY.md, and conversation/index.md if missing.
5
+ * Creates default config.md, MEMORY.md, chat/index.md, and group/index.md if missing.
6
6
  */
7
7
 
8
8
  import { existsSync, mkdirSync, writeFileSync, accessSync, constants } from 'fs';
@@ -74,9 +74,13 @@ export const DEFAULT_YEAFT_DIR = join(homedir(), '.yeaft');
74
74
 
75
75
  /** Subdirectories that must exist inside the Yeaft data directory. */
76
76
  const SUBDIRS = [
77
- 'conversation/messages',
78
- 'conversation/cold',
79
- 'conversation/blobs',
77
+ 'chat/messages',
78
+ 'chat/cold',
79
+ 'chat/blobs',
80
+ 'group/messages',
81
+ 'group/cold',
82
+ 'group/blobs',
83
+ 'group/compact',
80
84
  'memory/entries',
81
85
  'tasks',
82
86
  'skills',
@@ -144,7 +148,7 @@ totalMessages: 0
144
148
 
145
149
  # Conversation Index
146
150
 
147
- This file tracks the conversation state for the "one eternal conversation" model.
151
+ This file tracks one Yeaft message-history mode.
148
152
  `;
149
153
 
150
154
  /**
@@ -196,10 +200,12 @@ export function initYeaftDir(dir) {
196
200
  created.push(memoryPath);
197
201
  }
198
202
 
199
- const indexPath = join(root, 'conversation', 'index.md');
200
- if (!existsSync(indexPath)) {
201
- safeWriteFile(indexPath, DEFAULT_CONVERSATION_INDEX, warnings);
202
- created.push(indexPath);
203
+ for (const mode of ['chat', 'group']) {
204
+ const indexPath = join(root, mode, 'index.md');
205
+ if (!existsSync(indexPath)) {
206
+ safeWriteFile(indexPath, DEFAULT_CONVERSATION_INDEX, warnings);
207
+ created.push(indexPath);
208
+ }
203
209
  }
204
210
 
205
211
  // mcp.json.example — reference template for MCP server configuration
@@ -120,7 +120,7 @@ export class LLMAbortError extends Error {
120
120
  * sent to the LLM. A truncated copy is worse than useless — it lies about
121
121
  * what the model saw. If the resulting payload is too large for the debug
122
122
  * store, the fix is to bound retention (drop oldest turns), not to mutilate
123
- * individual payloads. See `MAX_UNIFY_DEBUG_LOOPS` in `web/stores/chat.js`.
123
+ * individual payloads. See `MAX_YEAFT_DEBUG_LOOPS` in `web/stores/chat.js`.
124
124
  *
125
125
  * @param {{ url: string, method: string, headers: object, body: any }} req
126
126
  * @returns {{ url: string, method: string, headers: object, body: any }}
@@ -24,10 +24,10 @@ import {
24
24
 
25
25
  /**
26
26
  * task-327a: feature-flag accessor. thinkingV1 is OFF by default; set
27
- * env UNIFY_THINKING_V1=1 to enable. Read lazily so tests can flip.
27
+ * env YEAFT_THINKING_V1=1 to enable. Read lazily so tests can flip.
28
28
  */
29
29
  function thinkingV1Enabled() {
30
- return process.env.UNIFY_THINKING_V1 === '1';
30
+ return process.env.YEAFT_THINKING_V1 === '1';
31
31
  }
32
32
 
33
33
  const DEFAULT_BASE_URL = 'https://api.anthropic.com';
@@ -25,6 +25,7 @@ const NETWORK_TIMEOUT_MS = 15000;
25
25
  const STALE_GRACE_MS = 5 * 60 * 1000; // 5 minutes when serving stale-after-failure
26
26
 
27
27
  let _memCache = null;
28
+ let _memCachePath = null;
28
29
  let _memCacheTime = 0;
29
30
 
30
31
  function getCachePath(yeaftDir) {
@@ -71,8 +72,10 @@ async function saveDiskCache(yeaftDir, data) {
71
72
  * @returns {Promise<object>} provider-id → provider entry; {} on total failure.
72
73
  */
73
74
  export async function fetchModelsDev({ forceRefresh = false, yeaftDir = null } = {}) {
75
+ const cachePath = getCachePath(yeaftDir);
76
+
74
77
  // Stage 1: in-memory cache.
75
- if (!forceRefresh && _memCache && Date.now() - _memCacheTime < CACHE_TTL_MS) {
78
+ if (!forceRefresh && _memCache && _memCachePath === cachePath && Date.now() - _memCacheTime < CACHE_TTL_MS) {
76
79
  return _memCache;
77
80
  }
78
81
 
@@ -83,6 +86,7 @@ export async function fetchModelsDev({ forceRefresh = false, yeaftDir = null } =
83
86
  const data = await loadDiskCache(yeaftDir);
84
87
  if (data && typeof data === 'object') {
85
88
  _memCache = data;
89
+ _memCachePath = cachePath;
86
90
  _memCacheTime = Date.now() - age;
87
91
  return _memCache;
88
92
  }
@@ -99,6 +103,7 @@ export async function fetchModelsDev({ forceRefresh = false, yeaftDir = null } =
99
103
  const data = await res.json();
100
104
  if (data && typeof data === 'object') {
101
105
  _memCache = data;
106
+ _memCachePath = cachePath;
102
107
  _memCacheTime = Date.now();
103
108
  await saveDiskCache(yeaftDir, data);
104
109
  return data;
@@ -111,15 +116,16 @@ export async function fetchModelsDev({ forceRefresh = false, yeaftDir = null } =
111
116
  }
112
117
 
113
118
  // Stage 4: stale disk cache fallback with short grace TTL so we retry soon.
114
- if (!_memCache) {
119
+ if (!_memCache || _memCachePath !== cachePath) {
115
120
  const data = await loadDiskCache(yeaftDir);
116
121
  if (data && typeof data === 'object') {
117
122
  _memCache = data;
123
+ _memCachePath = cachePath;
118
124
  _memCacheTime = Date.now() - CACHE_TTL_MS + STALE_GRACE_MS;
119
125
  }
120
126
  }
121
127
 
122
- return _memCache || {};
128
+ return _memCachePath === cachePath ? (_memCache || {}) : {};
123
129
  }
124
130
 
125
131
  /**
@@ -156,5 +162,6 @@ export async function listProviderModels(providerId, { yeaftDir = null } = {}) {
156
162
  */
157
163
  export function _resetMemCache() {
158
164
  _memCache = null;
165
+ _memCachePath = null;
159
166
  _memCacheTime = 0;
160
167
  }
@@ -43,12 +43,12 @@ import {
43
43
  const DEFAULT_BASE_URL = 'https://api.openai.com/v1';
44
44
 
45
45
  /**
46
- * Feature-flag accessor mirroring anthropic.js. UNIFY_THINKING_V1 is OFF by
46
+ * Feature-flag accessor mirroring anthropic.js. YEAFT_THINKING_V1 is OFF by
47
47
  * default; set env to '1' to enable thinking-mode field translation. Read
48
48
  * lazily so tests can flip the flag between calls.
49
49
  */
50
50
  function thinkingV1Enabled() {
51
- return process.env.UNIFY_THINKING_V1 === '1';
51
+ return process.env.YEAFT_THINKING_V1 === '1';
52
52
  }
53
53
 
54
54
  /**
@@ -78,7 +78,7 @@ export function inferProtocolFromModelId(modelId) {
78
78
  * task-327a: feature-flag accessor. Read lazily so tests can flip.
79
79
  */
80
80
  function thinkingV1Enabled() {
81
- return process.env.UNIFY_THINKING_V1 === '1';
81
+ return process.env.YEAFT_THINKING_V1 === '1';
82
82
  }
83
83
 
84
84
  /**
@@ -19,7 +19,7 @@
19
19
  *
20
20
  * Each MCP server communicates via stdio JSON-RPC (MCP protocol).
21
21
  *
22
- * Reference: yeaft-unify-design.md §8, yeaft-unify-core-systems.md §3.2
22
+ * Reference: yeaft-yeaft-design.md §8, yeaft-yeaft-core-systems.md §3.2
23
23
  */
24
24
 
25
25
  import { spawn } from 'child_process';
@@ -24,7 +24,7 @@
24
24
  * the next time the group is opened. Resident layer is derived state
25
25
  * (rebuilt every turn from `<scope>/summary.md`) — never persisted.
26
26
  *
27
- * For the single-VP Unify path (no group), the registry uses the literal
27
+ * For the single-VP Yeaft path (no group), the registry uses the literal
28
28
  * key `"default"` so there's still a stable home for AMS state.
29
29
  */
30
30
 
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * memory/seed-backfill.js — Run-once backfill of `summary.md` for VPs and
3
3
  * groups that were created BEFORE the create-time seed was added (PR
4
- * "fix-unify-context-and-memory"). Without backfill, an existing user's
4
+ * "fix-yeaft-context-and-memory"). Without backfill, an existing user's
5
5
  * `grp_claude` group and `steve` VP never get a Layer-A resident summary —
6
6
  * `engine.#prepareAms` then renders an empty memory section every turn,
7
7
  * which is the user-visible Bug #2.
@@ -37,7 +37,7 @@
37
37
  * by `dream-v2/state.js`, not here.
38
38
  * - No LLM calls, no extraction, no summarisation. Pure I/O.
39
39
  *
40
- * Reference: agent/unify/memory/DESIGN-H2-AMS.md.
40
+ * Reference: agent/yeaft/memory/DESIGN-H2-AMS.md.
41
41
  */
42
42
 
43
43
  import {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * models.js — Model ID registry for Yeaft Unify
2
+ * models.js — Model ID registry for Yeaft Yeaft
3
3
  *
4
4
  * Maps model IDs (e.g. "gpt-5", "claude-sonnet-4-20250514") to their
5
5
  * adapter type, API base URL, and capabilities.
@@ -305,7 +305,7 @@ export function parseModelRef(ref) {
305
305
  // ─── task-327a: thinking / reasoning capability ─────────────────
306
306
 
307
307
  /**
308
- * Valid effort levels accepted by Unify adapters.
308
+ * Valid effort levels accepted by Yeaft adapters.
309
309
  * @typedef {'low' | 'medium' | 'high' | 'max'} Effort
310
310
  */
311
311
 
@@ -325,7 +325,7 @@ export const ANTHROPIC_THINKING_BUDGETS = {
325
325
  };
326
326
 
327
327
  /**
328
- * Map a Unify effort level to the OpenAI reasoning.effort enum. OpenAI does
328
+ * Map a Yeaft effort level to the OpenAI reasoning.effort enum. OpenAI does
329
329
  * not expose a 'max' level — callers that pass 'max' get 'high' (the highest
330
330
  * available on that protocol). The router/engine should log this downgrade
331
331
  * but the adapter MUST NOT error.
@@ -3,8 +3,8 @@
3
3
  * slice so it can be safely fed to the LLM adapter.
4
4
  *
5
5
  * Why this exists:
6
- * `agent/unify/conversation/persist.js#loadRecentByGroup` and
7
- * `agent/unify/history-compact.js#compactHistory` both produce
6
+ * `agent/yeaft/conversation/persist.js#loadRecentByGroup` and
7
+ * `agent/yeaft/history-compact.js#compactHistory` both produce
8
8
  * sub-slices of a longer message stream. Both paths can — depending on
9
9
  * where the cut lands — produce one of two illegal shapes:
10
10
  * 1. A `role: 'tool'` message whose owning assistant `tool_use` is
@@ -5,7 +5,7 @@
5
5
  * model tier it runs on, and what system prompt it carries.
6
6
  *
7
7
  * Presets live as markdown files with YAML frontmatter in
8
- * `agent/unify/templates/personas/*.md`.
8
+ * `agent/yeaft/templates/personas/*.md`.
9
9
  */
10
10
 
11
11
  import { readFileSync, readdirSync } from 'fs';