@yeaft/webchat-agent 0.1.556 → 0.1.557
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/web-bridge.js +61 -35
package/package.json
CHANGED
package/unify/web-bridge.js
CHANGED
|
@@ -963,76 +963,102 @@ export async function handleUnifyGroupChat(msg) {
|
|
|
963
963
|
if (!text?.trim()) return;
|
|
964
964
|
const mentions = Array.isArray(msg.mentions) ? msg.mentions : [];
|
|
965
965
|
|
|
966
|
-
//
|
|
967
|
-
//
|
|
968
|
-
|
|
966
|
+
// Fallback path #1 (PM red-line): no groupId on payload → skip group
|
|
967
|
+
// resolution entirely and hand the text to the legacy single-agent
|
|
968
|
+
// dispatcher. Ensures backward-compat with old clients that never learned
|
|
969
|
+
// about groups.
|
|
970
|
+
if (!groupId) {
|
|
971
|
+
await handleUnifyChat({ ...msg, prompt: text });
|
|
972
|
+
return;
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
// Open the group handle (meta + jsonl log). Unresolvable groups take the
|
|
976
|
+
// legacy fallback — never silently drop the send.
|
|
977
|
+
let groupHandle = null;
|
|
969
978
|
try {
|
|
970
979
|
const yeaftDir = ctx.CONFIG?.yeaftDir;
|
|
971
|
-
if (yeaftDir
|
|
980
|
+
if (yeaftDir) {
|
|
972
981
|
const { openGroup, loadGroupMeta } = await import('./groups/group-store.js');
|
|
973
982
|
const { join } = await import('node:path');
|
|
974
983
|
const { existsSync } = await import('node:fs');
|
|
975
984
|
const root = join(yeaftDir, 'groups');
|
|
976
985
|
const dir = join(root, groupId);
|
|
977
986
|
if (existsSync(dir) && loadGroupMeta(dir)) {
|
|
978
|
-
|
|
979
|
-
meta = handle.getMeta();
|
|
987
|
+
groupHandle = openGroup(root, groupId);
|
|
980
988
|
}
|
|
981
989
|
}
|
|
982
990
|
} catch (err) {
|
|
983
|
-
console.warn('[Unify] unify_group_chat: group
|
|
991
|
+
console.warn('[Unify] unify_group_chat: group open failed', err?.message || err);
|
|
984
992
|
}
|
|
985
993
|
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
if (mentions.length > 0) {
|
|
990
|
-
// Intersect mentions with roster. Unknown mentions are ignored (not
|
|
991
|
-
// dispatched) — coordinator §6 "not_in_roster" semantics.
|
|
992
|
-
targets = mentions.filter((v) => roster.includes(v));
|
|
993
|
-
}
|
|
994
|
-
if (targets.length === 0 && meta?.defaultVpId && roster.includes(meta.defaultVpId)) {
|
|
995
|
-
targets = [meta.defaultVpId];
|
|
994
|
+
if (!groupHandle) {
|
|
995
|
+
await handleUnifyChat({ ...msg, prompt: text });
|
|
996
|
+
return;
|
|
996
997
|
}
|
|
997
998
|
|
|
998
|
-
//
|
|
999
|
-
//
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
999
|
+
// Adapter layer (PM red-line: do NOT modify coordinator to fit this
|
|
1000
|
+
// consumer). We drive `createCoordinator()` with a capturing `deliver`
|
|
1001
|
+
// callback, collect its dispatched/fallback report, then translate each
|
|
1002
|
+
// target into (a) a per-VP `group_message` event for the UI and (b) a
|
|
1003
|
+
// per-VP prompt dispatched through the legacy `handleUnifyChat` path.
|
|
1004
|
+
//
|
|
1005
|
+
// Source of truth for mentions is the PAYLOAD (ChatInput parsed them
|
|
1006
|
+
// once). We pass them through the coordinator's `input.meta` so the
|
|
1007
|
+
// appended log carries the authoritative set — the coordinator will also
|
|
1008
|
+
// run its own parse over `text` for routing, which matches the payload by
|
|
1009
|
+
// construction (ChatInput's `parseMentions` is the same regex).
|
|
1010
|
+
const { createCoordinator } = await import('./groups/coordinator.js');
|
|
1011
|
+
const captured = [];
|
|
1012
|
+
const coord = createCoordinator(groupHandle, {
|
|
1013
|
+
deliver: (vpId, envelope) => { captured.push({ vpId, envelope }); },
|
|
1014
|
+
});
|
|
1015
|
+
|
|
1016
|
+
let report;
|
|
1017
|
+
try {
|
|
1018
|
+
report = coord.ingest({
|
|
1019
|
+
from: 'user',
|
|
1020
|
+
role: 'user',
|
|
1021
|
+
text,
|
|
1022
|
+
meta: { mentions },
|
|
1004
1023
|
});
|
|
1024
|
+
} catch (err) {
|
|
1025
|
+
console.warn('[Unify] unify_group_chat: coord.ingest failed', err?.message || err);
|
|
1026
|
+
await handleUnifyChat({ ...msg, prompt: text });
|
|
1005
1027
|
return;
|
|
1006
1028
|
}
|
|
1007
1029
|
|
|
1008
|
-
//
|
|
1009
|
-
//
|
|
1010
|
-
|
|
1030
|
+
// Fallback path #2: coordinator resolved no targets and no default VP.
|
|
1031
|
+
// Hand off to the legacy single-agent path so the text still runs.
|
|
1032
|
+
const dispatchedIds = Array.isArray(report?.dispatched) ? report.dispatched : [];
|
|
1033
|
+
if (dispatchedIds.length === 0 && !report?.fallback) {
|
|
1034
|
+
await handleUnifyChat({ ...msg, prompt: text });
|
|
1035
|
+
return;
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
// Per target: emit `group_message` tagged with `speakerVpId` (the VP
|
|
1039
|
+
// being addressed — F3's GroupSelector binding consumes this) + dispatch
|
|
1040
|
+
// through the Engine via handleUnifyChat with an `@vp-<id>` prompt prefix.
|
|
1041
|
+
for (const { vpId, envelope } of captured) {
|
|
1011
1042
|
try {
|
|
1012
1043
|
sendUnifyEvent({
|
|
1013
1044
|
type: 'group_message',
|
|
1014
1045
|
groupId,
|
|
1015
1046
|
vpId,
|
|
1047
|
+
speakerVpId: vpId,
|
|
1016
1048
|
text,
|
|
1017
1049
|
mentions,
|
|
1018
|
-
trigger:
|
|
1050
|
+
trigger: envelope?.trigger || 'fallback',
|
|
1019
1051
|
ts: Date.now(),
|
|
1020
1052
|
});
|
|
1021
1053
|
} catch { /* never crash WS pipeline */ }
|
|
1022
|
-
}
|
|
1023
1054
|
|
|
1024
|
-
// For each target, dispatch into the engine via handleUnifyChat. We prepend
|
|
1025
|
-
// an `@vp-<id>` tag on the prompt so the Dispatcher can route per-VP when
|
|
1026
|
-
// VP-bound Engine wiring lands (task-338-F2/F5); today handleUnifyChat
|
|
1027
|
-
// still runs a single shared Engine, which preserves legacy behaviour.
|
|
1028
|
-
for (const vpId of targets) {
|
|
1029
|
-
const scoped = `@vp-${vpId} ${text}`;
|
|
1030
1055
|
try {
|
|
1031
1056
|
await handleUnifyChat({
|
|
1032
1057
|
...msg,
|
|
1033
|
-
prompt:
|
|
1058
|
+
prompt: `@vp-${vpId} ${text}`,
|
|
1034
1059
|
groupId,
|
|
1035
1060
|
vpId,
|
|
1061
|
+
speakerVpId: vpId,
|
|
1036
1062
|
});
|
|
1037
1063
|
} catch (err) {
|
|
1038
1064
|
console.warn('[Unify] unify_group_chat: per-vp dispatch failed', vpId, err?.message || err);
|