@yeaft/webchat-agent 0.1.817 → 0.1.820
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/package.json +1 -1
- package/unify/dream-v2/session-wiring.js +72 -8
- package/unify/web-bridge.js +16 -4
package/package.json
CHANGED
|
@@ -110,14 +110,43 @@ function makeLlm(session) {
|
|
|
110
110
|
if (!adapter || typeof adapter.call !== 'function') {
|
|
111
111
|
throw new Error(`dream-v2: no adapter.call available (pass=${pass})`);
|
|
112
112
|
}
|
|
113
|
+
|
|
114
|
+
// Bug 2: emit loop event so the debug panel shows dream LLM API calls.
|
|
115
|
+
const startedMs = Date.now();
|
|
116
|
+
session._dreamLoopCounter = (session._dreamLoopCounter || 0) + 1;
|
|
117
|
+
const loopNumber = session._dreamLoopCounter;
|
|
118
|
+
const turnId = session._dreamTurnId || 'dream';
|
|
119
|
+
const effectiveSystem = system || (String(session.config?.language || '').toLowerCase().startsWith('zh')
|
|
120
|
+
? `你是梦境流水线 — pass: ${pass}。请用中文生成自然语言内容;JSON key 保持英文。`
|
|
121
|
+
: `You are the dream pipeline — pass: ${pass}.`);
|
|
122
|
+
|
|
113
123
|
const r = await adapter.call({
|
|
114
124
|
model,
|
|
115
|
-
system:
|
|
116
|
-
? `你是梦境流水线 — pass: ${pass}。请用中文生成自然语言内容;JSON key 保持英文。`
|
|
117
|
-
: `You are the dream pipeline — pass: ${pass}.`),
|
|
125
|
+
system: effectiveSystem,
|
|
118
126
|
messages: [{ role: 'user', content: prompt }],
|
|
119
127
|
maxTokens: 2048,
|
|
120
128
|
});
|
|
129
|
+
|
|
130
|
+
// Emit complete loop event (request + response) to the debug panel.
|
|
131
|
+
if (typeof session._dreamProgressSink === 'function') {
|
|
132
|
+
session._dreamProgressSink({
|
|
133
|
+
type: 'loop',
|
|
134
|
+
turnId,
|
|
135
|
+
loopNumber,
|
|
136
|
+
model: model || 'unknown',
|
|
137
|
+
systemPrompt: effectiveSystem,
|
|
138
|
+
messages: [{ role: 'user', content: prompt }],
|
|
139
|
+
response: typeof r?.text === 'string' ? r.text : '',
|
|
140
|
+
toolCalls: [],
|
|
141
|
+
usage: r?.usage || { inputTokens: 0, outputTokens: 0, totalTokens: 0 },
|
|
142
|
+
latencyMs: Date.now() - startedMs,
|
|
143
|
+
ttfbMs: null,
|
|
144
|
+
stopReason: 'end_turn',
|
|
145
|
+
rawRequest: null,
|
|
146
|
+
rawResponse: null,
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
|
|
121
150
|
return (r && r.text) ? r.text : '';
|
|
122
151
|
};
|
|
123
152
|
}
|
|
@@ -151,11 +180,46 @@ export function createV2DreamScheduler(session) {
|
|
|
151
180
|
} catch { /* never let progress reporting kill the run */ }
|
|
152
181
|
};
|
|
153
182
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
183
|
+
let dreamTurnCounter = 0;
|
|
184
|
+
|
|
185
|
+
const run = (opts = {}) => {
|
|
186
|
+
// Bug 2: emit turn_open before the dream pass so the debug panel
|
|
187
|
+
// can group all LLM loop events under a single dream "turn".
|
|
188
|
+
dreamTurnCounter += 1;
|
|
189
|
+
const turnId = `dream-${dreamTurnCounter}-${Date.now()}`;
|
|
190
|
+
const startedAt = Date.now();
|
|
191
|
+
session._dreamTurnId = turnId;
|
|
192
|
+
session._dreamLoopCounter = 0;
|
|
193
|
+
|
|
194
|
+
if (typeof session._dreamProgressSink === 'function') {
|
|
195
|
+
session._dreamProgressSink({
|
|
196
|
+
type: 'turn_open',
|
|
197
|
+
turnId,
|
|
198
|
+
userPrompt: '[dream] automatic memory consolidation',
|
|
199
|
+
vpId: null,
|
|
200
|
+
groupId: null,
|
|
201
|
+
at: startedAt,
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
return runDream({
|
|
206
|
+
...buildRunDreamOpts(session, onProgress),
|
|
207
|
+
manual: !!opts.manual,
|
|
208
|
+
scopeFilter: Array.isArray(opts.scopeFilter) ? opts.scopeFilter : undefined,
|
|
209
|
+
}).then((result) => {
|
|
210
|
+
// Bug 2: emit turn_close when the dream pass completes.
|
|
211
|
+
if (typeof session._dreamProgressSink === 'function') {
|
|
212
|
+
session._dreamProgressSink({
|
|
213
|
+
type: 'turn_close',
|
|
214
|
+
turnId,
|
|
215
|
+
totalMs: Date.now() - startedAt,
|
|
216
|
+
totalTokens: 0,
|
|
217
|
+
loopCount: session._dreamLoopCounter || 0,
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
return result;
|
|
221
|
+
});
|
|
222
|
+
};
|
|
159
223
|
|
|
160
224
|
const v2 = createDreamScheduler({
|
|
161
225
|
run,
|
package/unify/web-bridge.js
CHANGED
|
@@ -1597,11 +1597,19 @@ export function installUnifyRuntimeBridge(s) {
|
|
|
1597
1597
|
// `handleUnifyDreamTrigger` wraps THIS sink for the lifetime of the
|
|
1598
1598
|
// trigger to inject `groupId` per-call (see that function below). The
|
|
1599
1599
|
// base sink is intentionally a pure passthrough.
|
|
1600
|
+
//
|
|
1601
|
+
// Bug 2: also forward turn_open / turn_close / loop events emitted by
|
|
1602
|
+
// the dream pipeline so the debug panel shows dream LLM API calls.
|
|
1600
1603
|
s._dreamProgressSink = (evt) => {
|
|
1601
1604
|
try {
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
+
if (evt.type === 'turn_open' || evt.type === 'turn_close' || evt.type === 'loop') {
|
|
1606
|
+
const tag = evt && evt.groupId ? { groupId: evt.groupId } : {};
|
|
1607
|
+
sendUnifyEvent(evt, tag);
|
|
1608
|
+
} else {
|
|
1609
|
+
const out = { type: 'dream_progress', ...evt };
|
|
1610
|
+
const tag = evt && evt.groupId ? { groupId: evt.groupId } : {};
|
|
1611
|
+
sendUnifyEvent(out, tag);
|
|
1612
|
+
}
|
|
1605
1613
|
} catch { /* never let event delivery throw */ }
|
|
1606
1614
|
};
|
|
1607
1615
|
|
|
@@ -2440,6 +2448,7 @@ async function ensureSessionLoaded() {
|
|
|
2440
2448
|
skills: session.status.skills,
|
|
2441
2449
|
mcpServers: session.status.mcpServers,
|
|
2442
2450
|
tools: session.status.tools,
|
|
2451
|
+
yeaftDir: ctx.CONFIG?.yeaftDir || null,
|
|
2443
2452
|
});
|
|
2444
2453
|
sendGroupSnapshotBroadcast();
|
|
2445
2454
|
// vp-status: rebuild frontend status table from authoritative agent
|
|
@@ -3454,6 +3463,7 @@ export async function handleUnifyLoadHistory(msg) {
|
|
|
3454
3463
|
skills: session.status.skills,
|
|
3455
3464
|
mcpServers: session.status.mcpServers,
|
|
3456
3465
|
tools: session.status.tools,
|
|
3466
|
+
yeaftDir: ctx.CONFIG?.yeaftDir || null,
|
|
3457
3467
|
});
|
|
3458
3468
|
sendGroupSnapshotBroadcast();
|
|
3459
3469
|
// vp-status: replay the authoritative table on reconnect so a refreshed
|
|
@@ -3483,7 +3493,7 @@ export async function handleUnifyLoadHistory(msg) {
|
|
|
3483
3493
|
|
|
3484
3494
|
for (const entry of replayEntries) {
|
|
3485
3495
|
if (entry.role === 'user') {
|
|
3486
|
-
sendUnifyOutput({ type: 'user', message: { content: entry.content, id: entry.id || null } }, { groupId: entry.groupId || null });
|
|
3496
|
+
sendUnifyOutput({ type: 'user', message: { content: entry.content, id: entry.id || null }, ts: entry.ts || null }, { groupId: entry.groupId || null });
|
|
3487
3497
|
} else if (entry.role === 'assistant') {
|
|
3488
3498
|
// speakerVpId rides on the envelope so the frontend can route this
|
|
3489
3499
|
// replayed assistant text to the correct VP track. Without it, the
|
|
@@ -3496,6 +3506,7 @@ export async function handleUnifyLoadHistory(msg) {
|
|
|
3496
3506
|
sendUnifyOutput({
|
|
3497
3507
|
type: 'assistant',
|
|
3498
3508
|
message: { id: entry.id || null, content: [{ type: 'text', text: entry.content }] },
|
|
3509
|
+
ts: entry.ts || null,
|
|
3499
3510
|
}, envelopeOpts);
|
|
3500
3511
|
sendUnifyOutput({ type: 'result', result_text: '' }, envelopeOpts);
|
|
3501
3512
|
}
|
|
@@ -3661,6 +3672,7 @@ export async function resetUnifySession() {
|
|
|
3661
3672
|
skills: session.status.skills,
|
|
3662
3673
|
mcpServers: session.status.mcpServers,
|
|
3663
3674
|
tools: session.status.tools,
|
|
3675
|
+
yeaftDir: ctx.CONFIG?.yeaftDir || null,
|
|
3664
3676
|
});
|
|
3665
3677
|
// vp-status: after a forced reset the broker table is still live in
|
|
3666
3678
|
// memory; broadcast so the frontend can rebuild its mirror without
|