@yeaft/webchat-agent 0.1.670 → 0.1.671

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yeaft/webchat-agent",
3
- "version": "0.1.670",
3
+ "version": "0.1.671",
4
4
  "description": "Remote agent for Yeaft WebChat — connects worker machines to the central server",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -805,8 +805,8 @@ export async function handleUnifyChat(msg) {
805
805
  const { prompt, mode } = msg;
806
806
  if (!prompt?.trim()) return;
807
807
  const vpId = typeof msg.vpId === 'string' && msg.vpId.trim() ? msg.vpId.trim() : null;
808
- const groupCoordinator = msg._groupCoordinator || null;
809
- const groupId = typeof msg.groupId === 'string' && msg.groupId.trim() ? msg.groupId.trim() : null;
808
+ let groupCoordinator = msg._groupCoordinator || null;
809
+ let groupId = typeof msg.groupId === 'string' && msg.groupId.trim() ? msg.groupId.trim() : null;
810
810
 
811
811
  if (mode !== undefined && mode !== null) {
812
812
  console.warn('[Unify] unify_chat.mode is deprecated and ignored — Unify now runs in a single unified mode.');
@@ -892,6 +892,48 @@ export async function handleUnifyChat(msg) {
892
892
  const toolCallsAccum = [];
893
893
  const toolResultsAccum = [];
894
894
 
895
+ // Backend safety net: if no coordinator was supplied (legacy
896
+ // `unify_chat` path, or test harness) but we have a yeaft dir, build
897
+ // an ephemeral coordinator over `groupId || grp_default`. This keeps
898
+ // ctx.router always wired so `route_forward` never bombs out with
899
+ // `router_unavailable`. The coordinator is local to this turn — no
900
+ // fan-out, no extra dispatch — it only exists so the per-VP Engine
901
+ // query can hand it to createRouter().
902
+ if (!groupCoordinator) {
903
+ try {
904
+ const yeaftDir = ctx.CONFIG?.yeaftDir;
905
+ if (yeaftDir) {
906
+ const resolvedGroupId = groupId || 'grp_default';
907
+ const { openGroup, loadGroupMeta } = await import('./groups/group-store.js');
908
+ const { join } = await import('node:path');
909
+ const { existsSync } = await import('node:fs');
910
+ const root = join(yeaftDir, 'groups');
911
+ const dir = join(root, resolvedGroupId);
912
+ let groupHandle = null;
913
+ if (existsSync(dir) && loadGroupMeta(dir)) {
914
+ groupHandle = openGroup(root, resolvedGroupId);
915
+ } else if (resolvedGroupId === 'grp_default') {
916
+ const { seedDefaultGroup } = await import('./groups/seed-default.js');
917
+ const seeded = seedDefaultGroup(yeaftDir, {});
918
+ groupHandle = seeded.group;
919
+ } else {
920
+ console.warn('[Unify] handleUnifyChat: groupId %s not found; no router will be wired for this turn', resolvedGroupId);
921
+ }
922
+ if (groupHandle) {
923
+ const { createCoordinator } = await import('./groups/coordinator.js');
924
+ groupCoordinator = createCoordinator(groupHandle, {
925
+ deliver: () => { /* no-op: 1:1 path, no fan-out */ },
926
+ });
927
+ if (!groupId) groupId = resolvedGroupId;
928
+ }
929
+ }
930
+ } catch (err) {
931
+ console.warn('[Unify] handleUnifyChat: ephemeral coordinator build failed', err?.message || err);
932
+ // Non-fatal — buildVpQueryOpts will return without router and
933
+ // route_forward will surface `router_unavailable` for that turn.
934
+ }
935
+ }
936
+
895
937
  // H2.f.5: dispatcher + InputQueue retired. Call engine.query() directly,
896
938
  // passing the flat conversation history as `messages` for context continuity.
897
939
  const queryOpts = buildVpQueryOpts({ vpId, groupCoordinator, groupId });