@yeaft/webchat-agent 1.0.574 → 1.0.576
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/connection/message-router.js +8 -22
- package/local-runtime/server/handlers/agent-output.js +12 -34
- package/local-runtime/server/handlers/agent-sync.js +4 -15
- package/local-runtime/server/handlers/client-conversation.js +7 -2
- package/local-runtime/server/handlers/client-misc.js +4 -6
- package/local-runtime/version.json +1 -1
- package/local-runtime/web/app.bundle.js +101 -299
- package/local-runtime/web/app.bundle.js.gz +0 -0
- package/local-runtime/web/index.html +2 -2
- package/local-runtime/web/style.bundle.css +1 -1
- package/local-runtime/web/style.bundle.css.gz +0 -0
- package/package.json +1 -1
- package/yeaft/cli-session-runner.js +2 -2
- package/yeaft/cli.js +1 -1
- package/yeaft/config.js +3 -1
- package/yeaft/debug-trace.js +12 -135
- package/yeaft/init.js +3 -22
- package/yeaft/migrate/sessions.js +52 -47
- package/yeaft/session.js +15 -108
- package/yeaft/sessions/seed-default.js +0 -26
- package/yeaft/sessions/session-crud.js +6 -29
- package/yeaft/sub-agent/runner.js +7 -8
- package/yeaft/web-bridge.js +16 -308
- package/yeaft/work-center/runner.js +2 -98
package/yeaft/session.js
CHANGED
|
@@ -33,29 +33,13 @@ import { TaskManager } from './tasks/manager.js';
|
|
|
33
33
|
// session still exposes a single default Engine; PR #797 adds group VP thread
|
|
34
34
|
// engines in web-bridge runtime state, keyed below the session layer.
|
|
35
35
|
//
|
|
36
|
-
//
|
|
37
|
-
//
|
|
38
|
-
//
|
|
39
|
-
// previous per-scope file reader recall-v2.js has been deleted).
|
|
40
|
-
// The `config.memoryV2` opt-out flag was retired in task-710; wiring is
|
|
41
|
-
// unconditional.
|
|
42
|
-
//
|
|
43
|
-
// When memoryIndex is wired we also open an AmsRegistry. It caches the
|
|
44
|
-
// per-Session ActiveMemorySet object and keeps the version-1 ams.json shape for
|
|
45
|
-
// disk compatibility. Engine rebuilds prompt-facing Resident entries from
|
|
46
|
-
// query-selected canonical content on every turn; persisted segment ids are
|
|
47
|
-
// never rehydrated into the prompt.
|
|
36
|
+
// Dream memory remains archived on disk, but normal Session startup must not
|
|
37
|
+
// open, migrate, reconcile, or inject it. Explicit memory tools own any direct
|
|
38
|
+
// access requested by a user.
|
|
48
39
|
import { ensureDefaultSessionIfEmpty, migrateRegisteredWorkDirSessions } from './sessions/session-crud.js';
|
|
49
40
|
import { seedDefaultVps } from './vp/seed-defaults.js';
|
|
50
41
|
import { topUpDefaultVps } from './vp/seed-topup.js';
|
|
51
|
-
import { archiveLegacyScopes } from './memory/seed-backfill.js';
|
|
52
|
-
// Dream scheduler wiring is intentionally not imported while the runtime path is disabled.
|
|
53
|
-
// import { createV2DreamScheduler, bootInitEmptyGroups, bootCatchUpStaleDream } from './dream/session-wiring.js';
|
|
54
42
|
import { isWorkCenterEnabled } from './work-center/feature.js';
|
|
55
|
-
import { openSegmentIndex } from './memory/index-db.js';
|
|
56
|
-
import { syncAll as syncSegmentIndex } from './memory/segment-sync.js';
|
|
57
|
-
import { backfillCanonicalContent } from './memory/content-backfill.js';
|
|
58
|
-
import { openAmsRegistry } from './memory/ams-registry.js';
|
|
59
43
|
import { join } from 'path';
|
|
60
44
|
import { existsSync as existsSyncSafe, readFileSync as readFileSyncSafe, mkdirSync as mkdirSyncSafe } from 'fs';
|
|
61
45
|
|
|
@@ -139,7 +123,6 @@ export async function loadSession(options = {}) {
|
|
|
139
123
|
extraTools = [],
|
|
140
124
|
configOverrides = {},
|
|
141
125
|
serverMode = false,
|
|
142
|
-
dreamEnabled,
|
|
143
126
|
managedCliReady = null,
|
|
144
127
|
workCenterEnabled,
|
|
145
128
|
} = options;
|
|
@@ -159,7 +142,7 @@ export async function loadSession(options = {}) {
|
|
|
159
142
|
const sessionWorkDir = typeof workDir === 'string' && workDir.trim() ? workDir.trim() : '';
|
|
160
143
|
const configDir = overrides.dir || process.env.YEAFT_DIR || DEFAULT_YEAFT_DIR;
|
|
161
144
|
const yeaftDir = configDir;
|
|
162
|
-
const configInitResult = initYeaftDir(configDir);
|
|
145
|
+
const configInitResult = initYeaftDir(configDir, { migrateMemory: false });
|
|
163
146
|
const storeInitResult = configInitResult;
|
|
164
147
|
overrides.dir = configDir;
|
|
165
148
|
|
|
@@ -174,11 +157,10 @@ export async function loadSession(options = {}) {
|
|
|
174
157
|
// ─── 2. Load config ───────────────────────────────────
|
|
175
158
|
const config = loadConfig(overrides);
|
|
176
159
|
const effectiveWorkCenterEnabled = workCenterEnabled ?? isWorkCenterEnabled(process.env, config);
|
|
177
|
-
// fix/dream-cadence-and-ui-trigger: tag config so the dream scheduler
|
|
178
|
-
// can decide whether to keep its interval timer alive (server) or
|
|
179
|
-
// unref it (CLI / tests). Non-persisted — set per-session by caller.
|
|
180
160
|
if (serverMode) config.serverMode = true;
|
|
181
|
-
|
|
161
|
+
// Dream is disabled at the runtime boundary. Ignore legacy caller/config
|
|
162
|
+
// toggles so an old client cannot re-enable scheduling or loading.
|
|
163
|
+
config.dream = { ...(config.dream || {}), enabled: false };
|
|
182
164
|
|
|
183
165
|
// Propagate the (clamped) cold-start replay window to the conversation
|
|
184
166
|
// store. The default is 10 turns; a user wanting more recall after a
|
|
@@ -260,60 +242,11 @@ export async function loadSession(options = {}) {
|
|
|
260
242
|
// ─── 5. Create stores ──────────────────────────────────
|
|
261
243
|
const conversationStore = new ConversationStore(yeaftDir);
|
|
262
244
|
|
|
263
|
-
//
|
|
264
|
-
//
|
|
265
|
-
//
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
// truth; on boot we reconcile disk → index via syncAll. Failure
|
|
269
|
-
// to open the index is non-fatal: #recallMemory returns an empty
|
|
270
|
-
// result and the turn proceeds without pre-injected memory.
|
|
271
|
-
let memoryIndex = null;
|
|
272
|
-
if (!config._readOnly) {
|
|
273
|
-
try {
|
|
274
|
-
const indexPath = join(yeaftDir, 'memory', 'index.db');
|
|
275
|
-
memoryIndex = openSegmentIndex(indexPath);
|
|
276
|
-
const memoryRoot = join(yeaftDir, 'memory');
|
|
277
|
-
// One-shot migration to the group-isolated memory layout: move any
|
|
278
|
-
// remaining top-level vp/ feature/ topic/ dirs into .legacy/ before
|
|
279
|
-
// we open the FTS index and re-sync from disk.
|
|
280
|
-
try {
|
|
281
|
-
archiveLegacyScopes(memoryRoot);
|
|
282
|
-
} catch (archiveErr) {
|
|
283
|
-
if (config.debug) {
|
|
284
|
-
console.warn(`[Yeaft] legacy scope archive warning: ${archiveErr?.message || archiveErr}`);
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
try {
|
|
288
|
-
backfillCanonicalContent(memoryRoot);
|
|
289
|
-
syncSegmentIndex(memoryRoot, memoryIndex);
|
|
290
|
-
} catch (syncErr) {
|
|
291
|
-
// Sync is best-effort; an empty / partial index just produces
|
|
292
|
-
// empty recall results, never an error.
|
|
293
|
-
if (config.debug) {
|
|
294
|
-
console.warn(`[Yeaft] FTS index sync warning: ${syncErr?.message || syncErr}`);
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
} catch (err) {
|
|
298
|
-
console.warn(`[Yeaft] Failed to open FTS segment index (preflow disabled): ${err?.message || err}`);
|
|
299
|
-
memoryIndex = null;
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
// ─── 5-ams. Session-keyed AMS registry ─────────────────
|
|
304
|
-
// The registry caches one ActiveMemorySet per sessionId and
|
|
305
|
-
// retains version-1 metadata for disk compatibility. Prompt state is
|
|
306
|
-
// rebuilt from selected canonical content each turn; old segment ids are
|
|
307
|
-
// not rehydrated. Without memoryIndex the registry remains disabled.
|
|
308
|
-
let amsRegistry = null;
|
|
309
|
-
if (memoryIndex && !config._readOnly) {
|
|
310
|
-
try {
|
|
311
|
-
amsRegistry = openAmsRegistry({ yeaftDir, memoryIndex, config });
|
|
312
|
-
} catch (err) {
|
|
313
|
-
console.warn(`[Yeaft] Failed to open AMS registry (adjust disabled): ${err?.message || err}`);
|
|
314
|
-
amsRegistry = null;
|
|
315
|
-
}
|
|
316
|
-
}
|
|
245
|
+
// Dream runtime loading is disabled. Keep these compatibility properties
|
|
246
|
+
// null for callers that still pass them through to Engine/sub-agent setup,
|
|
247
|
+
// without touching the archived memory tree or its SQLite index on boot.
|
|
248
|
+
const memoryIndex = null;
|
|
249
|
+
const amsRegistry = null;
|
|
317
250
|
|
|
318
251
|
// ─── 5a. (removed 2026-05-13) Feature store init — Feature system retired.
|
|
319
252
|
|
|
@@ -475,19 +408,8 @@ export async function loadSession(options = {}) {
|
|
|
475
408
|
});
|
|
476
409
|
|
|
477
410
|
|
|
478
|
-
//
|
|
479
|
-
//
|
|
480
|
-
// and persisted data intact, but do not create a scheduler or run boot-time
|
|
481
|
-
// initialization/catch-up while the replacement is evaluated.
|
|
482
|
-
//
|
|
483
|
-
// const partialSession = { yeaftDir, adapter, config, engine, trace };
|
|
484
|
-
// const dreamScheduler = createV2DreamScheduler(partialSession);
|
|
485
|
-
// if (memoryIndex && !config._readOnly) {
|
|
486
|
-
// bootInitEmptyGroups({ yeaftDir, memoryIndex, dreamScheduler, config }).catch(() => {});
|
|
487
|
-
// }
|
|
488
|
-
// if (!config._readOnly) {
|
|
489
|
-
// bootCatchUpStaleDream({ yeaftDir, dreamScheduler, config }).catch(() => {});
|
|
490
|
-
// }
|
|
411
|
+
// Dream implementation and persisted data remain available for explicit
|
|
412
|
+
// tooling, but Session runtime has no scheduler or boot-time Dream hooks.
|
|
491
413
|
const dreamScheduler = null;
|
|
492
414
|
|
|
493
415
|
// H2.f.5 retired the old session-level thread engine registry, input queue,
|
|
@@ -507,13 +429,8 @@ export async function loadSession(options = {}) {
|
|
|
507
429
|
tools: toolRegistry.size,
|
|
508
430
|
};
|
|
509
431
|
|
|
510
|
-
/** Graceful shutdown: disconnect MCP
|
|
432
|
+
/** Graceful shutdown: disconnect MCP and close runtime-owned resources. */
|
|
511
433
|
async function shutdown() {
|
|
512
|
-
try {
|
|
513
|
-
dreamScheduler.shutdown();
|
|
514
|
-
} catch {
|
|
515
|
-
// Best-effort cleanup
|
|
516
|
-
}
|
|
517
434
|
try {
|
|
518
435
|
await mcpManager.disconnectAll();
|
|
519
436
|
} catch {
|
|
@@ -529,16 +446,6 @@ export async function loadSession(options = {}) {
|
|
|
529
446
|
} catch {
|
|
530
447
|
// Performance telemetry is best-effort and must not block shutdown.
|
|
531
448
|
}
|
|
532
|
-
try {
|
|
533
|
-
if (memoryIndex) memoryIndex.close();
|
|
534
|
-
} catch {
|
|
535
|
-
// Best-effort cleanup
|
|
536
|
-
}
|
|
537
|
-
try {
|
|
538
|
-
if (amsRegistry) amsRegistry.persistAll();
|
|
539
|
-
} catch {
|
|
540
|
-
// Best-effort cleanup
|
|
541
|
-
}
|
|
542
449
|
try {
|
|
543
450
|
if (toolStats && typeof toolStats.flush === 'function') {
|
|
544
451
|
await toolStats.flush();
|
|
@@ -14,20 +14,10 @@
|
|
|
14
14
|
|
|
15
15
|
import { existsSync, mkdirSync } from 'fs';
|
|
16
16
|
import { join } from 'path';
|
|
17
|
-
import { homedir } from 'os';
|
|
18
17
|
import { openSession, createSession, loadSessionMeta } from './session-store.js';
|
|
19
|
-
import { seedSummaryIfMissingSync } from '../memory/store.js';
|
|
20
18
|
|
|
21
19
|
export const DEFAULT_SESSION_ID = 'session_default';
|
|
22
20
|
|
|
23
|
-
/**
|
|
24
|
-
* Default memory root used when callers don't pass `options.memoryRoot`.
|
|
25
|
-
* See `sessions/session-crud.js` and `vp/vp-crud.js` for the same default;
|
|
26
|
-
* production code threads `<yeaftDir>/memory` through to keep test/prod
|
|
27
|
-
* isolation honest.
|
|
28
|
-
*/
|
|
29
|
-
const DEFAULT_MEMORY_ROOT = join(homedir(), '.yeaft', 'memory');
|
|
30
|
-
|
|
31
21
|
/**
|
|
32
22
|
* Build the default-session seed summary body. Pulled into a helper so
|
|
33
23
|
* tests can pin the exact format. Mirrors `buildSessionSeedSummary` in
|
|
@@ -54,7 +44,6 @@ export function buildDefaultSessionSeedSummary(spec) {
|
|
|
54
44
|
* @returns {{ group: import('./session-store.js').GroupHandle, created: boolean }}
|
|
55
45
|
*/
|
|
56
46
|
export function seedDefaultSession(yeaftDir, spec = {}) {
|
|
57
|
-
const memoryRoot = spec.memoryRoot || DEFAULT_MEMORY_ROOT;
|
|
58
47
|
const sessionsRoot = join(yeaftDir, 'sessions');
|
|
59
48
|
if (!existsSync(sessionsRoot)) mkdirSync(sessionsRoot, { recursive: true });
|
|
60
49
|
|
|
@@ -76,20 +65,5 @@ export function seedDefaultSession(yeaftDir, spec = {}) {
|
|
|
76
65
|
defaultVpId,
|
|
77
66
|
});
|
|
78
67
|
|
|
79
|
-
// Seed Layer-A resident summary so the very first session — even on a
|
|
80
|
-
// brand-new install where only `session_default` exists — renders a non-
|
|
81
|
-
// empty memory section in the system prompt. No-op once Dream-v2 (or
|
|
82
|
-
// createSessionFromSpec) has already written one. Best-effort: a memory-
|
|
83
|
-
// root permission failure must NOT break the bootstrap flow.
|
|
84
|
-
try {
|
|
85
|
-
seedSummaryIfMissingSync(
|
|
86
|
-
{ kind: 'session', id: DEFAULT_SESSION_ID },
|
|
87
|
-
buildDefaultSessionSeedSummary({ name, roster, defaultVpId }),
|
|
88
|
-
{ root: memoryRoot },
|
|
89
|
-
);
|
|
90
|
-
} catch (err) {
|
|
91
|
-
console.warn(`[seed-default] failed to seed summary.md for ${DEFAULT_SESSION_ID}:`, err?.message || err);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
68
|
return { group, created: true };
|
|
95
69
|
}
|
|
@@ -56,7 +56,7 @@ import { addVp as rosterAdd, removeVp as rosterRemove, setDefaultVp } from './ro
|
|
|
56
56
|
import { seedDefaultSession, DEFAULT_SESSION_ID } from './seed-default.js';
|
|
57
57
|
import { nextSessionId, validateVpId, isReservedVpId } from './ids.js';
|
|
58
58
|
import { scanVpLibrary, DEFAULT_VP_LIB_DIR } from '../vp/vp-store.js';
|
|
59
|
-
import {
|
|
59
|
+
import { removeScopeDirSync } from '../memory/store.js';
|
|
60
60
|
import {
|
|
61
61
|
markConversationDirty,
|
|
62
62
|
removeConversationIndexScope,
|
|
@@ -218,7 +218,8 @@ function ensureSessionManifestReady(yeaftDir) {
|
|
|
218
218
|
registry: readWorkDirRegistry(yeaftDir),
|
|
219
219
|
yeaftDirForWorkDir,
|
|
220
220
|
sessionsRootForYeaftDir: sessionsRoot,
|
|
221
|
-
|
|
221
|
+
// Archived Dream scopes stay at their original data root. Session bootstrap
|
|
222
|
+
// migrates Session metadata/transcripts only and must not read or copy memory.
|
|
222
223
|
unregisterSessionWorkDir: (sessionId) => unregisterSessionWorkDir(yeaftDir, sessionId),
|
|
223
224
|
});
|
|
224
225
|
for (const row of listManifestSessions(yeaftDir)) {
|
|
@@ -237,16 +238,6 @@ function ensureSessionManifestReady(yeaftDir) {
|
|
|
237
238
|
return result;
|
|
238
239
|
}
|
|
239
240
|
|
|
240
|
-
function copySessionExtras(sourceYeaftDir, destYeaftDir, sessionId) {
|
|
241
|
-
for (const family of ['session', 'sessions', 'group']) {
|
|
242
|
-
const src = join(sourceYeaftDir, 'memory', family, sessionId);
|
|
243
|
-
const dst = join(destYeaftDir, 'memory', family, sessionId);
|
|
244
|
-
if (!existsSync(src) || existsSync(dst)) continue;
|
|
245
|
-
mkdirSync(join(dst, '..'), { recursive: true });
|
|
246
|
-
cpSync(src, dst, { recursive: true, errorOnExist: false });
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
|
|
250
241
|
function repairSessionStoreAndManifest(yeaftDir, options = {}) {
|
|
251
242
|
const repaired = repairSessionStore(yeaftDir, options);
|
|
252
243
|
ensureSessionManifestReady(yeaftDir);
|
|
@@ -392,7 +383,9 @@ export function restoreSessionToRegistry(defaultYeaftDir, sessionId, workDir) {
|
|
|
392
383
|
} finally {
|
|
393
384
|
handle.close();
|
|
394
385
|
}
|
|
395
|
-
|
|
386
|
+
// Restore only the explicitly selected Session and its transcript. Archived
|
|
387
|
+
// Dream scopes are owned by their existing data root and are not Session
|
|
388
|
+
// storage extras.
|
|
396
389
|
invalidateSessionConversationIndex(
|
|
397
390
|
[defaultYeaftDir],
|
|
398
391
|
sessionId,
|
|
@@ -477,7 +470,6 @@ function scanSortedVpIds(libDir) {
|
|
|
477
470
|
*/
|
|
478
471
|
export function ensureDefaultSessionIfEmpty(yeaftDir, options = {}) {
|
|
479
472
|
const libDir = options.libDir || DEFAULT_VP_LIB_DIR;
|
|
480
|
-
const memoryRoot = options.memoryRoot || DEFAULT_MEMORY_ROOT;
|
|
481
473
|
repairSessionStoreAndManifest(yeaftDir, {
|
|
482
474
|
defaultRoster: scanSortedVpIds(libDir),
|
|
483
475
|
});
|
|
@@ -496,7 +488,6 @@ export function ensureDefaultSessionIfEmpty(yeaftDir, options = {}) {
|
|
|
496
488
|
name: options.name || 'Default',
|
|
497
489
|
roster: vps,
|
|
498
490
|
defaultVpId,
|
|
499
|
-
memoryRoot,
|
|
500
491
|
});
|
|
501
492
|
const meta = group.getMeta();
|
|
502
493
|
if (meta) addOrUpdateManifestSession(yeaftDir, meta, join(sessionsRoot(yeaftDir), meta.id));
|
|
@@ -524,7 +515,6 @@ export function createSessionFromSpec(yeaftDir, spec, options = {}) {
|
|
|
524
515
|
const workspaceKey = canonicalWorkspaceKey(normalizedWorkDir);
|
|
525
516
|
ensureSessionManifestReady(yeaftDir);
|
|
526
517
|
const groupYeaftDir = yeaftDir;
|
|
527
|
-
const memoryRoot = options.memoryRoot || (groupYeaftDir ? join(groupYeaftDir, 'memory') : DEFAULT_MEMORY_ROOT);
|
|
528
518
|
const libDir = options.libDir || DEFAULT_VP_LIB_DIR;
|
|
529
519
|
const name = String(input.name || '').trim();
|
|
530
520
|
if (!name) throw new SessionCrudError('invalid_name', null, 'group name required');
|
|
@@ -583,19 +573,6 @@ export function createSessionFromSpec(yeaftDir, spec, options = {}) {
|
|
|
583
573
|
console.warn(`[session-crud] failed to seed config.json for ${id}:`, err?.message || err);
|
|
584
574
|
}
|
|
585
575
|
|
|
586
|
-
// Seed Layer-A resident summary so the first session has memory content
|
|
587
|
-
// even before Dream-v2 has run. No-op if a summary.md already exists.
|
|
588
|
-
// Best-effort: a memory-root permission failure must NOT break group create.
|
|
589
|
-
try {
|
|
590
|
-
seedSummaryIfMissingSync(
|
|
591
|
-
{ kind: 'session', id },
|
|
592
|
-
buildSessionSeedSummary({ name, roster, defaultVpId }),
|
|
593
|
-
{ root: memoryRoot },
|
|
594
|
-
);
|
|
595
|
-
} catch (err) {
|
|
596
|
-
console.warn(`[session-crud] failed to seed summary.md for ${id}:`, err?.message || err);
|
|
597
|
-
}
|
|
598
|
-
|
|
599
576
|
return meta;
|
|
600
577
|
}
|
|
601
578
|
|
|
@@ -133,11 +133,10 @@ export function startSubAgent(agent, deps = {}) {
|
|
|
133
133
|
let subEngine = null;
|
|
134
134
|
let outputLog = null;
|
|
135
135
|
try {
|
|
136
|
-
// Build sub-engine wired to the parent's adapter/
|
|
137
|
-
//
|
|
138
|
-
// turns must not pollute the user-facing conversation history.
|
|
139
|
-
//
|
|
140
|
-
// sub-agent (matches parent VP persona memory).
|
|
136
|
+
// Build sub-engine wired to the parent's adapter/config but with a
|
|
137
|
+
// restricted toolset. We DO NOT pass a conversationStore: sub-agent
|
|
138
|
+
// turns must not pollute the user-facing conversation history. Dream
|
|
139
|
+
// runtime recall remains disabled for sub-agents as it is for Sessions.
|
|
141
140
|
agent.budget = resolveSubAgentBudget(agent.budget);
|
|
142
141
|
agent.execution = agent.execution || createExecutionStats();
|
|
143
142
|
const childRegistry = buildChildToolRegistry(deps.parentToolRegistry, { agent });
|
|
@@ -149,9 +148,9 @@ export function startSubAgent(agent, deps = {}) {
|
|
|
149
148
|
_gitReadAlwaysVisible: (agent.personaData || getPersona(agent.persona))?.id === 'reviewer',
|
|
150
149
|
},
|
|
151
150
|
conversationStore: null,
|
|
152
|
-
memoryIndex:
|
|
153
|
-
memoryStore:
|
|
154
|
-
memoryShardStore:
|
|
151
|
+
memoryIndex: null,
|
|
152
|
+
memoryStore: null,
|
|
153
|
+
memoryShardStore: null,
|
|
155
154
|
toolRegistry: childRegistry,
|
|
156
155
|
skillManager: deps.skillManager || null,
|
|
157
156
|
mcpManager: deps.mcpManager || null,
|