@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.
- package/bin/yeaft-stats.js +3 -3
- package/connection/message-router.js +73 -44
- package/context.js +4 -4
- package/expert-roles.js +1 -1
- package/index.js +1 -1
- package/package.json +4 -4
- package/service/index.js +1 -1
- package/{unify → yeaft}/attachments.js +7 -7
- package/{unify → yeaft}/cli.js +4 -4
- package/{unify → yeaft}/compact/compactor.js +10 -10
- package/{unify → yeaft}/config-api.js +12 -12
- package/{unify → yeaft}/config.js +19 -19
- package/{unify → yeaft}/conversation/migrate-messages-threadid.js +1 -1
- package/{unify → yeaft}/conversation/persist.js +194 -65
- package/{unify → yeaft}/conversation/search.js +28 -23
- package/{unify → yeaft}/debug-trace.js +1 -1
- package/{unify → yeaft}/dream-v2/limits.js +3 -3
- package/{unify → yeaft}/dream-v2/runner.js +1 -1
- package/{unify → yeaft}/dream-v2/session-wiring.js +2 -2
- package/{unify → yeaft}/effort.js +2 -2
- package/{unify → yeaft}/engine.js +12 -14
- package/{unify → yeaft}/eval/run-eval.js +11 -11
- package/{unify → yeaft}/eval/runner.js +1 -1
- package/{unify → yeaft}/groups/feature-flag.js +2 -2
- package/{unify → yeaft}/groups/index.js +2 -2
- package/{unify → yeaft}/groups/pre-flow.js +1 -1
- package/{unify → yeaft}/groups/project-doc.js +1 -1
- package/{unify → yeaft}/history-compact.js +3 -3
- package/{unify → yeaft}/index.js +1 -1
- package/{unify → yeaft}/init.js +15 -9
- package/{unify → yeaft}/llm/adapter.js +1 -1
- package/{unify → yeaft}/llm/anthropic.js +2 -2
- package/{unify → yeaft}/llm/models-dev.js +10 -3
- package/{unify → yeaft}/llm/openai-responses.js +2 -2
- package/{unify → yeaft}/llm/router.js +1 -1
- package/{unify → yeaft}/mcp.js +1 -1
- package/{unify → yeaft}/memory/ams-registry.js +1 -1
- package/{unify → yeaft}/memory/seed-backfill.js +1 -1
- package/{unify → yeaft}/memory/store-v2.js +1 -1
- package/{unify → yeaft}/models.js +3 -3
- package/{unify → yeaft}/pair-sanitize.js +2 -2
- package/{unify → yeaft}/personas.js +1 -1
- package/{unify → yeaft}/prompts.js +1 -1
- package/{unify → yeaft}/routing/index.js +1 -1
- package/{unify → yeaft}/routing/router.js +1 -1
- package/{unify → yeaft}/session.js +8 -8
- package/{unify → yeaft}/skills.js +2 -2
- package/{unify → yeaft}/stats/format.js +1 -1
- package/{unify → yeaft}/stop-hooks.js +1 -1
- package/{unify → yeaft}/sub-agent/runner.js +1 -1
- package/{unify → yeaft}/tools/ask-user.js +2 -2
- package/{unify → yeaft}/tools/enter-worktree.js +1 -1
- package/{unify → yeaft}/tools/exit-worktree.js +1 -1
- package/{unify → yeaft}/tools/mcp-tools.js +1 -1
- package/{unify → yeaft}/tools/registry.js +2 -2
- package/{unify → yeaft}/tools/skill.js +1 -1
- package/{unify → yeaft}/tools/start-plan.js +1 -1
- package/{unify → yeaft}/tools/types.js +3 -3
- package/{unify → yeaft}/tools/web-search.js +1 -1
- package/{unify → yeaft}/turn-utils.js +1 -1
- package/{unify → yeaft}/vp/index.js +1 -1
- package/{unify → yeaft}/vp/registry.js +1 -1
- package/{unify → yeaft}/vp/vp-bridge.js +8 -8
- package/{unify → yeaft}/web-bridge.js +239 -238
- /package/{unify → yeaft}/archive/tool-results.js +0 -0
- /package/{unify → yeaft}/archive/trace.js +0 -0
- /package/{unify → yeaft}/archive/turn-archive.js +0 -0
- /package/{unify → yeaft}/compact/decisions-log.js +0 -0
- /package/{unify → yeaft}/compact/orchestrator.js +0 -0
- /package/{unify → yeaft}/compact/triggers.js +0 -0
- /package/{unify → yeaft}/compact/turn-group.js +0 -0
- /package/{unify → yeaft}/dream-v2/apply.js +0 -0
- /package/{unify → yeaft}/dream-v2/merge.js +0 -0
- /package/{unify → yeaft}/dream-v2/prompts/create.md +0 -0
- /package/{unify → yeaft}/dream-v2/prompts/extract-group.md +0 -0
- /package/{unify → yeaft}/dream-v2/prompts/extract-topic.md +0 -0
- /package/{unify → yeaft}/dream-v2/prompts/extract-user.md +0 -0
- /package/{unify → yeaft}/dream-v2/prompts/extract-vp.md +0 -0
- /package/{unify → yeaft}/dream-v2/prompts/index.js +0 -0
- /package/{unify → yeaft}/dream-v2/prompts/summarize-scope.md +0 -0
- /package/{unify → yeaft}/dream-v2/prompts/triage-pass1.md +0 -0
- /package/{unify → yeaft}/dream-v2/prompts/triage-pass2.md +0 -0
- /package/{unify → yeaft}/dream-v2/prompts/update.md +0 -0
- /package/{unify → yeaft}/dream-v2/schedule.js +0 -0
- /package/{unify → yeaft}/dream-v2/segment.js +0 -0
- /package/{unify → yeaft}/dream-v2/snapshot.js +0 -0
- /package/{unify → yeaft}/dream-v2/state.js +0 -0
- /package/{unify → yeaft}/dream-v2/triage.js +0 -0
- /package/{unify → yeaft}/eval/cases/e2e.js +0 -0
- /package/{unify → yeaft}/eval/cases/memory.js +0 -0
- /package/{unify → yeaft}/eval/cases/skills.js +0 -0
- /package/{unify → yeaft}/eval/cases/tool-use.js +0 -0
- /package/{unify → yeaft}/groups/coordinator.js +0 -0
- /package/{unify → yeaft}/groups/group-config.js +0 -0
- /package/{unify → yeaft}/groups/group-crud.js +0 -0
- /package/{unify → yeaft}/groups/group-store.js +0 -0
- /package/{unify → yeaft}/groups/ids.js +0 -0
- /package/{unify → yeaft}/groups/roster.js +0 -0
- /package/{unify → yeaft}/groups/seed-default.js +0 -0
- /package/{unify → yeaft}/llm/credentials/github-copilot.js +0 -0
- /package/{unify → yeaft}/llm/credentials/index.js +0 -0
- /package/{unify → yeaft}/memory/adjust.js +0 -0
- /package/{unify → yeaft}/memory/ams.js +0 -0
- /package/{unify → yeaft}/memory/budget.js +0 -0
- /package/{unify → yeaft}/memory/consolidate.js +0 -0
- /package/{unify → yeaft}/memory/index-db.js +0 -0
- /package/{unify → yeaft}/memory/keywords.js +0 -0
- /package/{unify → yeaft}/memory/preflow.js +0 -0
- /package/{unify → yeaft}/memory/segment-store.js +0 -0
- /package/{unify → yeaft}/memory/segment-sync.js +0 -0
- /package/{unify → yeaft}/memory/segment.js +0 -0
- /package/{unify → yeaft}/memory/summary-store.js +0 -0
- /package/{unify → yeaft}/router/continuity.js +0 -0
- /package/{unify → yeaft}/router/thinking.js +0 -0
- /package/{unify → yeaft}/routing/loop-guard.js +0 -0
- /package/{unify → yeaft}/stats/tool-usage.js +0 -0
- /package/{unify → yeaft}/storage/atomic.js +0 -0
- /package/{unify → yeaft}/storage/compact.js +0 -0
- /package/{unify → yeaft}/storage/index.js +0 -0
- /package/{unify → yeaft}/storage/jsonl-index.js +0 -0
- /package/{unify → yeaft}/storage/jsonl-log.js +0 -0
- /package/{unify → yeaft}/storage/shard-index.js +0 -0
- /package/{unify → yeaft}/storage/shard-store.js +0 -0
- /package/{unify → yeaft}/sub-agent/spawned-prompt.js +0 -0
- /package/{unify → yeaft}/templates/base.md +0 -0
- /package/{unify → yeaft}/templates/common-rules.md +0 -0
- /package/{unify → yeaft}/templates/harness/router-handoff.md +0 -0
- /package/{unify → yeaft}/templates/harness/router-shape.md +0 -0
- /package/{unify → yeaft}/templates/harness/worker-shape.md +0 -0
- /package/{unify → yeaft}/templates/identity-yeaft.md +0 -0
- /package/{unify → yeaft}/templates/mode-dream.md +0 -0
- /package/{unify → yeaft}/templates/mode-unified.md +0 -0
- /package/{unify → yeaft}/templates/personas/explorer.md +0 -0
- /package/{unify → yeaft}/templates/personas/implementer.md +0 -0
- /package/{unify → yeaft}/templates/personas/researcher.md +0 -0
- /package/{unify → yeaft}/templates/personas/reviewer.md +0 -0
- /package/{unify → yeaft}/templates/plan-instruction.md +0 -0
- /package/{unify → yeaft}/templates/tool-guidance.md +0 -0
- /package/{unify → yeaft}/tool-folding/exec-log.js +0 -0
- /package/{unify → yeaft}/tool-folding/fallback-stub.js +0 -0
- /package/{unify → yeaft}/tool-folding/index.js +0 -0
- /package/{unify → yeaft}/tool-folding/reflection-prompt.js +0 -0
- /package/{unify → yeaft}/tool-folding/t1-reflector.js +0 -0
- /package/{unify → yeaft}/tool-folding/t2-reflector.js +0 -0
- /package/{unify → yeaft}/tools/agent.js +0 -0
- /package/{unify → yeaft}/tools/apply-patch.js +0 -0
- /package/{unify → yeaft}/tools/bash.js +0 -0
- /package/{unify → yeaft}/tools/close-agent.js +0 -0
- /package/{unify → yeaft}/tools/file-edit.js +0 -0
- /package/{unify → yeaft}/tools/file-read.js +0 -0
- /package/{unify → yeaft}/tools/file-write.js +0 -0
- /package/{unify → yeaft}/tools/glob.js +0 -0
- /package/{unify → yeaft}/tools/grep.js +0 -0
- /package/{unify → yeaft}/tools/history-search.js +0 -0
- /package/{unify → yeaft}/tools/image-generation.js +0 -0
- /package/{unify → yeaft}/tools/index.js +0 -0
- /package/{unify → yeaft}/tools/js-repl.js +0 -0
- /package/{unify → yeaft}/tools/list-agents.js +0 -0
- /package/{unify → yeaft}/tools/list-dir.js +0 -0
- /package/{unify → yeaft}/tools/notebook-edit.js +0 -0
- /package/{unify → yeaft}/tools/route-forward.js +0 -0
- /package/{unify → yeaft}/tools/send-message.js +0 -0
- /package/{unify → yeaft}/tools/todo-write.js +0 -0
- /package/{unify → yeaft}/tools/view-image.js +0 -0
- /package/{unify → yeaft}/tools/wait-agent.js +0 -0
- /package/{unify → yeaft}/tools/web-fetch.js +0 -0
- /package/{unify → yeaft}/vp/seed-defaults.js +0 -0
- /package/{unify → yeaft}/vp/seed-topup.js +0 -0
- /package/{unify → yeaft}/vp/stock-ids.js +0 -0
- /package/{unify → yeaft}/vp/thread-classifier.js +0 -0
- /package/{unify → yeaft}/vp/vp-crud.js +0 -0
- /package/{unify → yeaft}/vp/vp-loader.js +0 -0
- /package/{unify → yeaft}/vp/vp-store.js +0 -0
- /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
|
|
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
|
|
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
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
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
|
|
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
|
|
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
|
-
* `
|
|
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 `
|
|
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.
|
|
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 `
|
|
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/
|
|
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 `
|
|
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
|
|
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
|
|
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-
|
|
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:
|
|
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 `
|
|
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.
|
|
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?.
|
|
892
|
-
imageAllowlist: Array.isArray(this.#config?.
|
|
893
|
-
? this.#config.
|
|
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.
|
|
995
|
-
//
|
|
996
|
-
//
|
|
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
|
-
|
|
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/
|
|
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/
|
|
8
|
+
* node agent/yeaft/eval/run-eval.js
|
|
9
9
|
*
|
|
10
10
|
* # Run specific suite
|
|
11
|
-
* node agent/
|
|
11
|
+
* node agent/yeaft/eval/run-eval.js --suite tools
|
|
12
12
|
*
|
|
13
13
|
* # Compare multiple models
|
|
14
|
-
* node agent/
|
|
14
|
+
* node agent/yeaft/eval/run-eval.js --models claude-sonnet-4-20250514,gpt-5
|
|
15
15
|
*
|
|
16
16
|
* # Save baseline
|
|
17
|
-
* node agent/
|
|
17
|
+
* node agent/yeaft/eval/run-eval.js --save-baseline initial
|
|
18
18
|
*
|
|
19
19
|
* # Compare against baseline
|
|
20
|
-
* node agent/
|
|
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/
|
|
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/
|
|
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/
|
|
81
|
+
node agent/yeaft/eval/run-eval.js --dry-run
|
|
82
82
|
|
|
83
83
|
# Run tool evals against Claude Sonnet
|
|
84
|
-
node agent/
|
|
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/
|
|
87
|
+
node agent/yeaft/eval/run-eval.js --save-baseline v0.1.411
|
|
88
88
|
|
|
89
89
|
# Check for regressions
|
|
90
|
-
node agent/
|
|
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
|
-
* feature-flag.js — Reads `config.
|
|
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 = ['
|
|
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 `
|
|
9
|
+
* - Feature flag reader for `yeaft.multiVp.enabled`
|
|
10
10
|
* - First-boot default group seeder
|
|
11
11
|
*
|
|
12
|
-
* See agent/
|
|
12
|
+
* See agent/yeaft/groups/coordinator.js for the dispatch contract.
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
export {
|
|
@@ -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
|
-
`[
|
|
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
|
-
*
|
|
3
|
+
* Yeaft group-chat fan-out path.
|
|
4
4
|
*
|
|
5
5
|
* Problem this solves:
|
|
6
|
-
* `agent/
|
|
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/
|
|
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.
|
package/{unify → yeaft}/index.js
RENAMED
package/{unify → yeaft}/init.js
RENAMED
|
@@ -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
|
|
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
|
-
'
|
|
78
|
-
'
|
|
79
|
-
'
|
|
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
|
|
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
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
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 `
|
|
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
|
|
27
|
+
* env YEAFT_THINKING_V1=1 to enable. Read lazily so tests can flip.
|
|
28
28
|
*/
|
|
29
29
|
function thinkingV1Enabled() {
|
|
30
|
-
return process.env.
|
|
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.
|
|
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.
|
|
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.
|
|
81
|
+
return process.env.YEAFT_THINKING_V1 === '1';
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
/**
|
package/{unify → yeaft}/mcp.js
RENAMED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
*
|
|
20
20
|
* Each MCP server communicates via stdio JSON-RPC (MCP protocol).
|
|
21
21
|
*
|
|
22
|
-
* Reference: yeaft-
|
|
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
|
|
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-
|
|
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.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* models.js — Model ID registry for Yeaft
|
|
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
|
|
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
|
|
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/
|
|
7
|
-
* `agent/
|
|
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/
|
|
8
|
+
* `agent/yeaft/templates/personas/*.md`.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import { readFileSync, readdirSync } from 'fs';
|