shennian 0.2.89 → 0.2.90
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/dist/assets/wechat-channel/macos/manifest.json +13 -4
- package/dist/assets/wechat-channel/macos/shennian-wechat-channel-helper +0 -0
- package/dist/bin/shennian.js +1 -1
- package/dist/publish-build-manifest.json +548 -0
- package/dist/scripts/wechat-rpa-confirmation.mjs +5 -97
- package/dist/src/agent-env.js +4 -105
- package/dist/src/agents/adapter.js +1 -19
- package/dist/src/agents/claude.js +8 -305
- package/dist/src/agents/codex-control.js +2 -188
- package/dist/src/agents/codex-utils.js +7 -200
- package/dist/src/agents/codex.js +15 -916
- package/dist/src/agents/command-spec.js +2 -413
- package/dist/src/agents/config-status.js +1 -226
- package/dist/src/agents/cursor.js +1 -249
- package/dist/src/agents/custom.js +4 -271
- package/dist/src/agents/detect.js +1 -56
- package/dist/src/agents/external-channel-instructions.js +10 -94
- package/dist/src/agents/gemini.js +1 -173
- package/dist/src/agents/manager.js +13 -157
- package/dist/src/agents/model-registry/cache.js +1 -37
- package/dist/src/agents/model-registry/discovery.js +2 -187
- package/dist/src/agents/model-registry/parsers.js +4 -447
- package/dist/src/agents/model-registry/runner.js +1 -30
- package/dist/src/agents/model-registry/service.js +1 -78
- package/dist/src/agents/model-registry/types.js +1 -8
- package/dist/src/agents/model-registry.js +1 -18
- package/dist/src/agents/openclaw.js +2 -275
- package/dist/src/agents/opencode.js +1 -231
- package/dist/src/agents/pi-context.js +12 -217
- package/dist/src/agents/pi.js +14 -723
- package/dist/src/agents/platform-instructions.js +9 -54
- package/dist/src/channels/base.js +1 -3
- package/dist/src/channels/registry.js +1 -30
- package/dist/src/channels/reply-split.js +10 -89
- package/dist/src/channels/runtime.js +5 -564
- package/dist/src/channels/secret-registry.js +1 -46
- package/dist/src/channels/websocket.js +8 -378
- package/dist/src/channels/wechat-channel/anchor.js +1 -65
- package/dist/src/channels/wechat-channel/client.js +1 -96
- package/dist/src/channels/wechat-channel/cooldown.js +1 -38
- package/dist/src/channels/wechat-channel/fingerprint.js +1 -71
- package/dist/src/channels/wechat-channel/helper-assets.d.ts +10 -1
- package/dist/src/channels/wechat-channel/helper-assets.js +1 -68
- package/dist/src/channels/wechat-channel/helper-client.js +3 -149
- package/dist/src/channels/wechat-channel/helper-protocol.d.ts +1 -1
- package/dist/src/channels/wechat-channel/helper-protocol.js +1 -115
- package/dist/src/channels/wechat-channel/index.d.ts +1 -0
- package/dist/src/channels/wechat-channel/index.js +1 -19
- package/dist/src/channels/wechat-channel/ledger.js +1 -54
- package/dist/src/channels/wechat-channel/media-resolver.js +1 -181
- package/dist/src/channels/wechat-channel/message-key.js +1 -105
- package/dist/src/channels/wechat-channel/observer.js +1 -118
- package/dist/src/channels/wechat-channel/outbound-ledger.d.ts +3 -0
- package/dist/src/channels/wechat-channel/outbound-ledger.js +2 -112
- package/dist/src/channels/wechat-channel/outbound-sender.d.ts +26 -0
- package/dist/src/channels/wechat-channel/outbound-sender.js +1 -0
- package/dist/src/channels/wechat-channel/preflight.js +1 -48
- package/dist/src/channels/wechat-channel/runner.js +1 -84
- package/dist/src/channels/wechat-channel/runtime.js +1 -66
- package/dist/src/channels/wechat-channel/scheduler.d.ts +5 -0
- package/dist/src/channels/wechat-channel/scheduler.js +1 -152
- package/dist/src/channels/wechat-rpa/macos-flow.js +1 -96
- package/dist/src/channels/wechat-rpa/macos.js +6 -48
- package/dist/src/channels/wechat-rpa/normalizer.js +7 -127
- package/dist/src/channels/wechat-rpa.js +6 -1028
- package/dist/src/channels/wecom.js +4 -357
- package/dist/src/commands/agent.js +6 -131
- package/dist/src/commands/daemon-windows.js +8 -48
- package/dist/src/commands/daemon.js +19 -1013
- package/dist/src/commands/external-attachments.js +1 -51
- package/dist/src/commands/external.js +1 -137
- package/dist/src/commands/manager.js +2 -391
- package/dist/src/commands/pair-qr.js +1 -6
- package/dist/src/commands/pair.js +9 -287
- package/dist/src/commands/tools.js +1 -34
- package/dist/src/commands/upgrade.js +1 -198
- package/dist/src/config/index.js +1 -35
- package/dist/src/daemon-log.js +6 -58
- package/dist/src/env-path.js +1 -64
- package/dist/src/fs/boundary.js +1 -126
- package/dist/src/fs/handler.js +1 -130
- package/dist/src/fs/security.js +1 -32
- package/dist/src/fs/text-decoder.js +1 -110
- package/dist/src/index.js +2 -404
- package/dist/src/log-reporter.js +1 -16
- package/dist/src/manager/prompt.js +29 -34
- package/dist/src/manager/registry.js +2 -269
- package/dist/src/manager/runtime.js +19 -1007
- package/dist/src/native-fusion/config.js +1 -5
- package/dist/src/native-fusion/opencode-parser.js +3 -123
- package/dist/src/native-fusion/parser-common.js +8 -264
- package/dist/src/native-fusion/parsers.js +8 -729
- package/dist/src/native-fusion/service.js +2 -225
- package/dist/src/native-fusion/state.js +1 -22
- package/dist/src/native-fusion/types.js +1 -1
- package/dist/src/region.js +1 -88
- package/dist/src/relay/client.js +1 -343
- package/dist/src/session/archive-zip.js +1 -220
- package/dist/src/session/handlers/agent-config.js +1 -150
- package/dist/src/session/handlers/agents.js +1 -55
- package/dist/src/session/handlers/chat.js +2 -751
- package/dist/src/session/handlers/control.js +1 -55
- package/dist/src/session/handlers/fs.js +1 -783
- package/dist/src/session/handlers/session-refresh.js +1 -47
- package/dist/src/session/handlers/skills.js +1 -121
- package/dist/src/session/handlers/title.js +1 -60
- package/dist/src/session/handlers/tool-detail.js +1 -218
- package/dist/src/session/manager.js +1 -319
- package/dist/src/session/projection.js +1 -54
- package/dist/src/session/queue.js +4 -317
- package/dist/src/session/remote-attachments.js +1 -72
- package/dist/src/session/store.js +3 -109
- package/dist/src/session/types.js +1 -4
- package/dist/src/skills/registry.js +15 -148
- package/dist/src/skills/setup.js +1 -101
- package/dist/src/tools/markdown-to-pdf.js +10 -346
- package/dist/src/upgrade/engine.js +3 -347
- package/package.json +3 -2
|
@@ -1,269 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import fs from 'node:fs';
|
|
4
|
-
import path from 'node:path';
|
|
5
|
-
import { randomUUID } from 'node:crypto';
|
|
6
|
-
import { extractPayloadText, isToolPayload } from '@shennian/wire';
|
|
7
|
-
import { resolveShennianPath } from '../config/index.js';
|
|
8
|
-
import { listSessionRecords, readMessages } from '../session/store.js';
|
|
9
|
-
import { listProjectedSessions } from '../session/projection.js';
|
|
10
|
-
const REGISTRY_PATH = resolveShennianPath('manager-registry.json');
|
|
11
|
-
function nowIso() {
|
|
12
|
-
return new Date().toISOString();
|
|
13
|
-
}
|
|
14
|
-
function emptyRegistry() {
|
|
15
|
-
return { managers: {}, workers: {}, replyTargets: {} };
|
|
16
|
-
}
|
|
17
|
-
export class ManagerRegistry {
|
|
18
|
-
load() {
|
|
19
|
-
try {
|
|
20
|
-
const parsed = JSON.parse(fs.readFileSync(REGISTRY_PATH, 'utf-8'));
|
|
21
|
-
return {
|
|
22
|
-
managers: parsed.managers ?? {},
|
|
23
|
-
workers: parsed.workers ?? {},
|
|
24
|
-
replyTargets: parsed.replyTargets ?? {},
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
catch {
|
|
28
|
-
return emptyRegistry();
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
save(registry) {
|
|
32
|
-
fs.mkdirSync(path.dirname(REGISTRY_PATH), { recursive: true });
|
|
33
|
-
fs.writeFileSync(REGISTRY_PATH, JSON.stringify(registry, null, 2));
|
|
34
|
-
}
|
|
35
|
-
upsertManager(input) {
|
|
36
|
-
const registry = this.load();
|
|
37
|
-
const existing = registry.managers[input.sessionId];
|
|
38
|
-
const timestamp = nowIso();
|
|
39
|
-
const record = {
|
|
40
|
-
sessionId: input.sessionId,
|
|
41
|
-
agentSessionId: input.agentSessionId ?? existing?.agentSessionId ?? null,
|
|
42
|
-
workDir: input.workDir,
|
|
43
|
-
machineId: input.machineId ?? existing?.machineId ?? null,
|
|
44
|
-
modelId: input.modelId,
|
|
45
|
-
defaultWorkerAgentType: input.defaultWorkerAgentType ?? existing?.defaultWorkerAgentType ?? null,
|
|
46
|
-
defaultWorkerModelId: input.defaultWorkerModelId ?? existing?.defaultWorkerModelId ?? null,
|
|
47
|
-
status: input.status ?? existing?.status ?? 'idle',
|
|
48
|
-
managedWorkerSessionIds: existing?.managedWorkerSessionIds ?? [],
|
|
49
|
-
attachedExternalChannels: existing?.attachedExternalChannels ?? [],
|
|
50
|
-
createdAt: existing?.createdAt ?? timestamp,
|
|
51
|
-
updatedAt: timestamp,
|
|
52
|
-
};
|
|
53
|
-
registry.managers[input.sessionId] = record;
|
|
54
|
-
this.save(registry);
|
|
55
|
-
return record;
|
|
56
|
-
}
|
|
57
|
-
getManager(sessionId) {
|
|
58
|
-
return this.load().managers[sessionId];
|
|
59
|
-
}
|
|
60
|
-
addWorker(input) {
|
|
61
|
-
const registry = this.load();
|
|
62
|
-
const manager = registry.managers[input.managerSessionId];
|
|
63
|
-
if (!manager)
|
|
64
|
-
throw new Error('Manager runtime is not registered');
|
|
65
|
-
const sessionId = input.sessionId ?? `sess_worker_${randomUUID()}`;
|
|
66
|
-
const timestamp = nowIso();
|
|
67
|
-
const record = {
|
|
68
|
-
sessionId,
|
|
69
|
-
agentType: input.agentType,
|
|
70
|
-
workDir: input.workDir,
|
|
71
|
-
managedBy: input.managerSessionId,
|
|
72
|
-
status: 'running',
|
|
73
|
-
createdAt: timestamp,
|
|
74
|
-
updatedAt: timestamp,
|
|
75
|
-
lastActivityAt: timestamp,
|
|
76
|
-
summary: input.summary ?? null,
|
|
77
|
-
agentSessionId: null,
|
|
78
|
-
runId: null,
|
|
79
|
-
};
|
|
80
|
-
registry.workers[sessionId] = record;
|
|
81
|
-
if (!manager.managedWorkerSessionIds.includes(sessionId)) {
|
|
82
|
-
manager.managedWorkerSessionIds.push(sessionId);
|
|
83
|
-
}
|
|
84
|
-
manager.updatedAt = timestamp;
|
|
85
|
-
this.save(registry);
|
|
86
|
-
return record;
|
|
87
|
-
}
|
|
88
|
-
updateWorker(sessionId, patch) {
|
|
89
|
-
const registry = this.load();
|
|
90
|
-
const existing = registry.workers[sessionId];
|
|
91
|
-
if (!existing)
|
|
92
|
-
return undefined;
|
|
93
|
-
const record = {
|
|
94
|
-
...existing,
|
|
95
|
-
...patch,
|
|
96
|
-
updatedAt: nowIso(),
|
|
97
|
-
};
|
|
98
|
-
registry.workers[sessionId] = record;
|
|
99
|
-
this.save(registry);
|
|
100
|
-
return record;
|
|
101
|
-
}
|
|
102
|
-
listWorkers(managerSessionId, opts = {}) {
|
|
103
|
-
const registry = this.load();
|
|
104
|
-
const manager = registry.managers[managerSessionId];
|
|
105
|
-
if (!manager)
|
|
106
|
-
return [];
|
|
107
|
-
const managedWorkers = Object.values(registry.workers)
|
|
108
|
-
.filter((worker) => worker.workDir === manager.workDir)
|
|
109
|
-
.filter((worker) => opts.includeManagers || worker.agentType !== 'manager')
|
|
110
|
-
.map((worker) => this.decorateManagedWorker(worker, opts.runningSessionIds));
|
|
111
|
-
const managedIds = new Set(managedWorkers.map((worker) => worker.sessionId));
|
|
112
|
-
const projectSessions = listSessionRecords()
|
|
113
|
-
.filter((session) => session.workDir === manager.workDir)
|
|
114
|
-
.filter((session) => opts.includeManagers || session.agentType !== 'manager')
|
|
115
|
-
.filter((session) => !managedIds.has(session.sessionId))
|
|
116
|
-
.map((session) => this.sessionRecordToWorker(session, opts.runningSessionIds));
|
|
117
|
-
const knownIds = new Set([...managedWorkers, ...projectSessions].map((session) => session.sessionId));
|
|
118
|
-
const projectedSource = opts.projectedSessions ?? listProjectedSessions();
|
|
119
|
-
const projectedSessions = projectedSource
|
|
120
|
-
.filter((session) => session.workDir === manager.workDir)
|
|
121
|
-
.filter((session) => opts.includeManagers || session.agentType !== 'manager')
|
|
122
|
-
.filter((session) => !knownIds.has(session.id))
|
|
123
|
-
.map((session) => this.projectedSessionToWorker(session, opts.runningSessionIds));
|
|
124
|
-
return [...managedWorkers, ...projectSessions, ...projectedSessions]
|
|
125
|
-
.sort((a, b) => b.lastActivityAt.localeCompare(a.lastActivityAt));
|
|
126
|
-
}
|
|
127
|
-
getWorkerForManager(managerSessionId, sessionId) {
|
|
128
|
-
const registry = this.load();
|
|
129
|
-
const manager = registry.managers[managerSessionId];
|
|
130
|
-
const worker = registry.workers[sessionId];
|
|
131
|
-
if (!manager)
|
|
132
|
-
return undefined;
|
|
133
|
-
if (worker) {
|
|
134
|
-
if (worker.workDir !== manager.workDir)
|
|
135
|
-
return undefined;
|
|
136
|
-
if (worker.agentType === 'manager')
|
|
137
|
-
return undefined;
|
|
138
|
-
return this.decorateManagedWorker(worker);
|
|
139
|
-
}
|
|
140
|
-
const session = listSessionRecords().find((item) => item.sessionId === sessionId);
|
|
141
|
-
if (!session || session.workDir !== manager.workDir || session.agentType === 'manager')
|
|
142
|
-
return undefined;
|
|
143
|
-
return this.sessionRecordToWorker(session);
|
|
144
|
-
}
|
|
145
|
-
decorateManagedWorker(worker, runningSessionIds) {
|
|
146
|
-
const status = runningSessionIds?.has(worker.sessionId) ? 'running' : worker.status;
|
|
147
|
-
const transcript = this.readTranscriptSummary(worker.sessionId, worker.summary ?? null);
|
|
148
|
-
const lastMessagePreview = transcript.lastMessagePreview ?? worker.lastMessagePreview ?? worker.summary ?? null;
|
|
149
|
-
const userGoal = worker.userGoal ?? transcript.userGoal ?? null;
|
|
150
|
-
return {
|
|
151
|
-
...worker,
|
|
152
|
-
managedBy: worker.managedBy ?? null,
|
|
153
|
-
status,
|
|
154
|
-
title: worker.title ?? userGoal ?? lastMessagePreview ?? worker.summary ?? worker.sessionId,
|
|
155
|
-
userGoal,
|
|
156
|
-
lastMessagePreview,
|
|
157
|
-
summary: worker.summary ?? lastMessagePreview,
|
|
158
|
-
canResume: worker.canResume ?? worker.status !== 'aborted',
|
|
159
|
-
source: worker.source ?? 'manager_registry',
|
|
160
|
-
role: 'managed_worker',
|
|
161
|
-
};
|
|
162
|
-
}
|
|
163
|
-
sessionRecordToWorker(session, runningSessionIds) {
|
|
164
|
-
const transcript = this.readTranscriptSummary(session.sessionId, session.lastMessagePreview ?? null);
|
|
165
|
-
const lastMessagePreview = transcript.lastMessagePreview ?? session.lastMessagePreview ?? null;
|
|
166
|
-
const userGoal = transcript.userGoal;
|
|
167
|
-
const status = runningSessionIds?.has(session.sessionId)
|
|
168
|
-
? 'running'
|
|
169
|
-
: session.status === 'failed'
|
|
170
|
-
? 'error'
|
|
171
|
-
: session.status === 'completed'
|
|
172
|
-
? 'final'
|
|
173
|
-
: 'idle';
|
|
174
|
-
return {
|
|
175
|
-
sessionId: session.sessionId,
|
|
176
|
-
agentType: session.agentType,
|
|
177
|
-
workDir: session.workDir,
|
|
178
|
-
managedBy: null,
|
|
179
|
-
status,
|
|
180
|
-
createdAt: session.createdAt,
|
|
181
|
-
updatedAt: session.updatedAt,
|
|
182
|
-
lastActivityAt: session.lastActivityAt,
|
|
183
|
-
title: userGoal ?? lastMessagePreview ?? session.sessionId,
|
|
184
|
-
userGoal,
|
|
185
|
-
lastMessagePreview,
|
|
186
|
-
summary: lastMessagePreview ?? userGoal ?? null,
|
|
187
|
-
agentSessionId: session.agentSessionId ?? null,
|
|
188
|
-
runId: null,
|
|
189
|
-
canResume: Boolean(session.agentSessionId),
|
|
190
|
-
source: 'local_index',
|
|
191
|
-
role: 'project_session',
|
|
192
|
-
};
|
|
193
|
-
}
|
|
194
|
-
projectedSessionToWorker(session, runningSessionIds) {
|
|
195
|
-
const lastMessagePreview = session.lastMessagePreview ?? null;
|
|
196
|
-
const userGoal = session.title?.trim() || lastMessagePreview;
|
|
197
|
-
const status = runningSessionIds?.has(session.id)
|
|
198
|
-
? 'running'
|
|
199
|
-
: session.status === 'failed'
|
|
200
|
-
? 'error'
|
|
201
|
-
: session.status === 'completed'
|
|
202
|
-
? 'final'
|
|
203
|
-
: 'idle';
|
|
204
|
-
return {
|
|
205
|
-
sessionId: session.id,
|
|
206
|
-
agentType: session.agentType,
|
|
207
|
-
workDir: session.workDir,
|
|
208
|
-
managedBy: null,
|
|
209
|
-
status,
|
|
210
|
-
createdAt: session.createdAt,
|
|
211
|
-
updatedAt: session.updatedAt,
|
|
212
|
-
lastActivityAt: session.lastActivityAt || session.updatedAt,
|
|
213
|
-
title: userGoal ?? session.id,
|
|
214
|
-
userGoal: userGoal ?? null,
|
|
215
|
-
lastMessagePreview,
|
|
216
|
-
summary: lastMessagePreview ?? userGoal ?? null,
|
|
217
|
-
agentSessionId: session.agentSessionId ?? null,
|
|
218
|
-
runId: session.activity?.runId ?? null,
|
|
219
|
-
canResume: true,
|
|
220
|
-
source: 'app_projection',
|
|
221
|
-
role: 'project_session',
|
|
222
|
-
};
|
|
223
|
-
}
|
|
224
|
-
readTranscriptSummary(sessionId, fallbackPreview) {
|
|
225
|
-
const messages = readMessages(sessionId, { limit: 200 });
|
|
226
|
-
if (!messages.length)
|
|
227
|
-
return { userGoal: null, lastMessagePreview: fallbackPreview };
|
|
228
|
-
const chronological = [...messages].sort((a, b) => a.ts - b.ts);
|
|
229
|
-
const firstUser = chronological.find((message) => message.role === 'user');
|
|
230
|
-
const lastReadable = [...chronological].reverse().find((message) => readableText(message));
|
|
231
|
-
return {
|
|
232
|
-
userGoal: firstUser ? clip(readableText(firstUser), 160) : null,
|
|
233
|
-
lastMessagePreview: clip(readableText(lastReadable), 180) ?? fallbackPreview,
|
|
234
|
-
};
|
|
235
|
-
}
|
|
236
|
-
createReplyTarget(input) {
|
|
237
|
-
const registry = this.load();
|
|
238
|
-
const record = {
|
|
239
|
-
replyTarget: `rt_${randomUUID()}`,
|
|
240
|
-
managerSessionId: input.managerSessionId,
|
|
241
|
-
channelId: input.channelId,
|
|
242
|
-
conversationId: input.conversationId,
|
|
243
|
-
messageId: input.messageId ?? null,
|
|
244
|
-
createdAt: nowIso(),
|
|
245
|
-
};
|
|
246
|
-
registry.replyTargets[record.replyTarget] = record;
|
|
247
|
-
this.save(registry);
|
|
248
|
-
return record;
|
|
249
|
-
}
|
|
250
|
-
getReplyTarget(replyTarget) {
|
|
251
|
-
return this.load().replyTargets[replyTarget];
|
|
252
|
-
}
|
|
253
|
-
getLatestReplyTargetForManager(managerSessionId) {
|
|
254
|
-
return Object.values(this.load().replyTargets)
|
|
255
|
-
.filter((target) => target.managerSessionId === managerSessionId)
|
|
256
|
-
.sort((a, b) => b.createdAt.localeCompare(a.createdAt))[0];
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
function readableText(message) {
|
|
260
|
-
if (!message || isToolPayload(message.payload))
|
|
261
|
-
return null;
|
|
262
|
-
const text = extractPayloadText(message.payload).replace(/\r\n/g, '\n').trim();
|
|
263
|
-
return text || null;
|
|
264
|
-
}
|
|
265
|
-
function clip(text, max) {
|
|
266
|
-
if (!text)
|
|
267
|
-
return null;
|
|
268
|
-
return text.length > max ? `${text.slice(0, max)}...` : text;
|
|
269
|
-
}
|
|
1
|
+
import u from"node:fs";import h from"node:path";import{randomUUID as y}from"node:crypto";import{extractPayloadText as k,isToolPayload as T}from"@shennian/wire";import{resolveShennianPath as A}from"../config/index.js";import{listSessionRecords as I,readMessages as w}from"../session/store.js";import{listProjectedSessions as v}from"../session/projection.js";const g=A("manager-registry.json");function l(){return new Date().toISOString()}function M(){return{managers:{},workers:{},replyTargets:{}}}class B{load(){try{const e=JSON.parse(u.readFileSync(g,"utf-8"));return{managers:e.managers??{},workers:e.workers??{},replyTargets:e.replyTargets??{}}}catch{return M()}}save(e){u.mkdirSync(h.dirname(g),{recursive:!0}),u.writeFileSync(g,JSON.stringify(e,null,2))}upsertManager(e){const t=this.load(),r=t.managers[e.sessionId],a=l(),s={sessionId:e.sessionId,agentSessionId:e.agentSessionId??r?.agentSessionId??null,workDir:e.workDir,machineId:e.machineId??r?.machineId??null,modelId:e.modelId,defaultWorkerAgentType:e.defaultWorkerAgentType??r?.defaultWorkerAgentType??null,defaultWorkerModelId:e.defaultWorkerModelId??r?.defaultWorkerModelId??null,status:e.status??r?.status??"idle",managedWorkerSessionIds:r?.managedWorkerSessionIds??[],attachedExternalChannels:r?.attachedExternalChannels??[],createdAt:r?.createdAt??a,updatedAt:a};return t.managers[e.sessionId]=s,this.save(t),s}getManager(e){return this.load().managers[e]}addWorker(e){const t=this.load(),r=t.managers[e.managerSessionId];if(!r)throw new Error("Manager runtime is not registered");const a=e.sessionId??`sess_worker_${y()}`,s=l(),o={sessionId:a,agentType:e.agentType,workDir:e.workDir,managedBy:e.managerSessionId,status:"running",createdAt:s,updatedAt:s,lastActivityAt:s,summary:e.summary??null,agentSessionId:null,runId:null};return t.workers[a]=o,r.managedWorkerSessionIds.includes(a)||r.managedWorkerSessionIds.push(a),r.updatedAt=s,this.save(t),o}updateWorker(e,t){const r=this.load(),a=r.workers[e];if(!a)return;const s={...a,...t,updatedAt:l()};return r.workers[e]=s,this.save(r),s}listWorkers(e,t={}){const r=this.load(),a=r.managers[e];if(!a)return[];const s=Object.values(r.workers).filter(n=>n.workDir===a.workDir).filter(n=>t.includeManagers||n.agentType!=="manager").map(n=>this.decorateManagedWorker(n,t.runningSessionIds)),o=new Set(s.map(n=>n.sessionId)),d=I().filter(n=>n.workDir===a.workDir).filter(n=>t.includeManagers||n.agentType!=="manager").filter(n=>!o.has(n.sessionId)).map(n=>this.sessionRecordToWorker(n,t.runningSessionIds)),c=new Set([...s,...d].map(n=>n.sessionId)),f=(t.projectedSessions??v()).filter(n=>n.workDir===a.workDir).filter(n=>t.includeManagers||n.agentType!=="manager").filter(n=>!c.has(n.id)).map(n=>this.projectedSessionToWorker(n,t.runningSessionIds));return[...s,...d,...f].sort((n,S)=>S.lastActivityAt.localeCompare(n.lastActivityAt))}getWorkerForManager(e,t){const r=this.load(),a=r.managers[e],s=r.workers[t];if(!a)return;if(s)return s.workDir!==a.workDir||s.agentType==="manager"?void 0:this.decorateManagedWorker(s);const o=I().find(d=>d.sessionId===t);if(!(!o||o.workDir!==a.workDir||o.agentType==="manager"))return this.sessionRecordToWorker(o)}decorateManagedWorker(e,t){const r=t?.has(e.sessionId)?"running":e.status,a=this.readTranscriptSummary(e.sessionId,e.summary??null),s=a.lastMessagePreview??e.lastMessagePreview??e.summary??null,o=e.userGoal??a.userGoal??null;return{...e,managedBy:e.managedBy??null,status:r,title:e.title??o??s??e.summary??e.sessionId,userGoal:o,lastMessagePreview:s,summary:e.summary??s,canResume:e.canResume??e.status!=="aborted",source:e.source??"manager_registry",role:"managed_worker"}}sessionRecordToWorker(e,t){const r=this.readTranscriptSummary(e.sessionId,e.lastMessagePreview??null),a=r.lastMessagePreview??e.lastMessagePreview??null,s=r.userGoal,o=t?.has(e.sessionId)?"running":e.status==="failed"?"error":e.status==="completed"?"final":"idle";return{sessionId:e.sessionId,agentType:e.agentType,workDir:e.workDir,managedBy:null,status:o,createdAt:e.createdAt,updatedAt:e.updatedAt,lastActivityAt:e.lastActivityAt,title:s??a??e.sessionId,userGoal:s,lastMessagePreview:a,summary:a??s??null,agentSessionId:e.agentSessionId??null,runId:null,canResume:!!e.agentSessionId,source:"local_index",role:"project_session"}}projectedSessionToWorker(e,t){const r=e.lastMessagePreview??null,a=e.title?.trim()||r,s=t?.has(e.id)?"running":e.status==="failed"?"error":e.status==="completed"?"final":"idle";return{sessionId:e.id,agentType:e.agentType,workDir:e.workDir,managedBy:null,status:s,createdAt:e.createdAt,updatedAt:e.updatedAt,lastActivityAt:e.lastActivityAt||e.updatedAt,title:a??e.id,userGoal:a??null,lastMessagePreview:r,summary:r??a??null,agentSessionId:e.agentSessionId??null,runId:e.activity?.runId??null,canResume:!0,source:"app_projection",role:"project_session"}}readTranscriptSummary(e,t){const r=w(e,{limit:200});if(!r.length)return{userGoal:null,lastMessagePreview:t};const a=[...r].sort((d,c)=>d.ts-c.ts),s=a.find(d=>d.role==="user"),o=[...a].reverse().find(d=>m(d));return{userGoal:s?p(m(s),160):null,lastMessagePreview:p(m(o),180)??t}}createReplyTarget(e){const t=this.load(),r={replyTarget:`rt_${y()}`,managerSessionId:e.managerSessionId,channelId:e.channelId,conversationId:e.conversationId,messageId:e.messageId??null,createdAt:l()};return t.replyTargets[r.replyTarget]=r,this.save(t),r}getReplyTarget(e){return this.load().replyTargets[e]}getLatestReplyTargetForManager(e){return Object.values(this.load().replyTargets).filter(t=>t.managerSessionId===e).sort((t,r)=>r.createdAt.localeCompare(t.createdAt))[0]}}function m(i){return!i||T(i.payload)?null:k(i.payload).replace(/\r\n/g,`
|
|
2
|
+
`).trim()||null}function p(i,e){return i?i.length>e?`${i.slice(0,e)}...`:i:null}export{B as ManagerRegistry};
|