@yeaft/webchat-agent 0.1.410 → 0.1.412

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.
@@ -0,0 +1,191 @@
1
+ /**
2
+ * session.js — Session orchestrator for Yeaft Unify
3
+ *
4
+ * Single entry point: loadSession(options?) → Session
5
+ *
6
+ * Wires all subsystems together:
7
+ * initYeaftDir → loadConfig → createTrace → createLLMAdapter →
8
+ * ConversationStore → MemoryStore → SkillManager → MCPManager →
9
+ * ToolRegistry → Engine → Session
10
+ *
11
+ * The ~/.yeaft/ directory is the agent's persistent workspace.
12
+ * loadSession() loads (or initializes) this workspace and returns
13
+ * a fully wired Session ready for queries.
14
+ */
15
+
16
+ import { initYeaftDir } from './init.js';
17
+ import { loadConfig, loadMCPConfig } from './config.js';
18
+ import { createTrace } from './debug-trace.js';
19
+ import { createLLMAdapter } from './llm/adapter.js';
20
+ import { ConversationStore } from './conversation/persist.js';
21
+ import { MemoryStore } from './memory/store.js';
22
+ import { SkillManager, createSkillManager } from './skills.js';
23
+ import { MCPManager } from './mcp.js';
24
+ import { createEmptyRegistry } from './tools/registry.js';
25
+ import { Engine } from './engine.js';
26
+ import { join } from 'path';
27
+
28
+ // Built-in tools
29
+ import mcpTools from './tools/mcp-tools.js';
30
+ import skillTool from './tools/skill.js';
31
+ import enterWorktree from './tools/enter-worktree.js';
32
+ import exitWorktree from './tools/exit-worktree.js';
33
+
34
+ /**
35
+ * @typedef {Object} SessionOptions
36
+ * @property {string} [dir] — Yeaft data directory override (default: ~/.yeaft)
37
+ * @property {string} [model] — Model override
38
+ * @property {string} [language] — Language override ('en' | 'zh')
39
+ * @property {boolean} [debug] — Debug mode override
40
+ * @property {boolean} [skipMCP] — Skip MCP server connections (faster startup)
41
+ * @property {boolean} [skipSkills] — Skip skill loading
42
+ * @property {object[]} [extraTools] — Additional ToolDef objects to register
43
+ * @property {object} [configOverrides] — Additional config overrides
44
+ */
45
+
46
+ /**
47
+ * @typedef {Object} Session
48
+ * @property {Engine} engine — The wired engine, ready for .query()
49
+ * @property {object} config — Resolved configuration
50
+ * @property {ConversationStore} conversationStore — Conversation persistence
51
+ * @property {MemoryStore} memoryStore — Memory persistence
52
+ * @property {SkillManager} skillManager — Skill manager
53
+ * @property {MCPManager} mcpManager — MCP manager
54
+ * @property {import('./tools/registry.js').ToolRegistry} toolRegistry — Tool registry
55
+ * @property {import('./debug-trace.js').DebugTrace|import('./debug-trace.js').NullTrace} trace
56
+ * @property {string} yeaftDir — Resolved data directory path
57
+ * @property {{ skills: number, mcpServers: string[], mcpFailed: object[], tools: number }} status
58
+ * @property {() => Promise<void>} shutdown — Graceful shutdown
59
+ */
60
+
61
+ /**
62
+ * Load (or initialize) a Yeaft session.
63
+ *
64
+ * This is the main entry point for using Yeaft programmatically.
65
+ * It creates the directory structure if needed, loads config, connects
66
+ * to services, registers tools, and returns a ready-to-use Session.
67
+ *
68
+ * @param {SessionOptions} [options={}]
69
+ * @returns {Promise<Session>}
70
+ */
71
+ export async function loadSession(options = {}) {
72
+ const {
73
+ dir,
74
+ model,
75
+ language,
76
+ debug,
77
+ skipMCP = false,
78
+ skipSkills = false,
79
+ extraTools = [],
80
+ configOverrides = {},
81
+ } = options;
82
+
83
+ // ─── 1. Load config (determines yeaftDir) ──────────────
84
+ const overrides = { ...configOverrides };
85
+ if (dir) overrides.dir = dir;
86
+ if (model) overrides.model = model;
87
+ if (language) overrides.language = language;
88
+ if (debug !== undefined) overrides.debug = debug;
89
+
90
+ const config = loadConfig(overrides);
91
+ const yeaftDir = config.dir;
92
+
93
+ // ─── 2. Ensure directory structure ─────────────────────
94
+ initYeaftDir(yeaftDir);
95
+
96
+ // ─── 3. Create debug trace ─────────────────────────────
97
+ const trace = createTrace({
98
+ enabled: config.debug,
99
+ dbPath: join(yeaftDir, 'debug.db'),
100
+ });
101
+
102
+ // ─── 4. Create LLM adapter ────────────────────────────
103
+ const adapter = await createLLMAdapter(config);
104
+
105
+ // ─── 5. Create stores ──────────────────────────────────
106
+ const conversationStore = new ConversationStore(yeaftDir);
107
+ const memoryStore = new MemoryStore(yeaftDir);
108
+
109
+ // ─── 6. Load skills ────────────────────────────────────
110
+ let skillManager;
111
+ if (skipSkills) {
112
+ skillManager = new SkillManager(yeaftDir);
113
+ // Don't call .load() — empty skill manager
114
+ } else {
115
+ skillManager = createSkillManager(yeaftDir);
116
+ }
117
+
118
+ // ─── 7. Connect MCP servers ────────────────────────────
119
+ const mcpConfig = loadMCPConfig(yeaftDir);
120
+ const mcpManager = new MCPManager();
121
+ let mcpStatus = { connected: [], failed: [] };
122
+
123
+ if (!skipMCP && mcpConfig.servers.length > 0) {
124
+ mcpStatus = await mcpManager.connectAll(mcpConfig.servers);
125
+ }
126
+
127
+ // ─── 8. Build tool registry ────────────────────────────
128
+ const toolRegistry = createEmptyRegistry();
129
+
130
+ // Register built-in tools
131
+ for (const tool of mcpTools) {
132
+ toolRegistry.register(tool);
133
+ }
134
+ toolRegistry.register(skillTool);
135
+ toolRegistry.register(enterWorktree);
136
+ toolRegistry.register(exitWorktree);
137
+
138
+ // Register any extra tools from caller
139
+ for (const tool of extraTools) {
140
+ toolRegistry.register(tool);
141
+ }
142
+
143
+ // ─── 9. Create engine (wires everything) ───────────────
144
+ const engine = new Engine({
145
+ adapter,
146
+ trace,
147
+ config,
148
+ conversationStore,
149
+ memoryStore,
150
+ toolRegistry,
151
+ skillManager,
152
+ mcpManager,
153
+ yeaftDir,
154
+ });
155
+
156
+ // ─── 10. Build session ─────────────────────────────────
157
+ const status = {
158
+ skills: skillManager.size,
159
+ mcpServers: mcpStatus.connected,
160
+ mcpFailed: mcpStatus.failed,
161
+ tools: toolRegistry.size,
162
+ };
163
+
164
+ /** Graceful shutdown: disconnect MCP, close trace DB. */
165
+ async function shutdown() {
166
+ try {
167
+ await mcpManager.disconnectAll();
168
+ } catch {
169
+ // Best-effort cleanup
170
+ }
171
+ try {
172
+ trace.close();
173
+ } catch {
174
+ // Trace might not have close() (NullTrace)
175
+ }
176
+ }
177
+
178
+ return {
179
+ engine,
180
+ config,
181
+ conversationStore,
182
+ memoryStore,
183
+ skillManager,
184
+ mcpManager,
185
+ toolRegistry,
186
+ trace,
187
+ yeaftDir,
188
+ status,
189
+ shutdown,
190
+ };
191
+ }