@yeaft/webchat-agent 0.1.518 → 0.1.519
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 +7 -1
- package/package.json +1 -1
- package/unify/vp/vp-bridge.js +102 -0
- package/unify/web-bridge.js +10 -0
|
@@ -36,7 +36,7 @@ import { sendToServer, flushMessageBuffer } from './buffer.js';
|
|
|
36
36
|
import { handleRestartAgent, handleUpgradeAgent } from './upgrade.js';
|
|
37
37
|
import { loadMcpServers, updateMcpConfig } from '../mcp.js';
|
|
38
38
|
import { getLlmConfig, updateLlmConfig, getUnifySettings, updateUnifySettings } from '../unify/config-api.js';
|
|
39
|
-
import { handleUnifyChat, handleUnifyModeSwitch, handleUnifyModelSwitch, resetUnifySession, handleUnifyLoadHistory, handleUnifyMergeThread, handleUnifyForkThread, handleUnifyAbortThread, handleUnifyAbortAll } from '../unify/web-bridge.js';
|
|
39
|
+
import { handleUnifyChat, handleUnifyModeSwitch, handleUnifyModelSwitch, resetUnifySession, handleUnifyLoadHistory, handleUnifyMergeThread, handleUnifyForkThread, handleUnifyAbortThread, handleUnifyAbortAll, handleUnifyVpSubscribe } from '../unify/web-bridge.js';
|
|
40
40
|
|
|
41
41
|
export async function handleMessage(msg) {
|
|
42
42
|
switch (msg.type) {
|
|
@@ -397,6 +397,12 @@ export async function handleMessage(msg) {
|
|
|
397
397
|
handleUnifyAbortAll();
|
|
398
398
|
break;
|
|
399
399
|
|
|
400
|
+
// task-334-ui-a: VP library subscribe — replies with one-shot
|
|
401
|
+
// vp_snapshot event. Live diff (vp_updated/vp_removed) deferred to 334h.
|
|
402
|
+
case 'unify_vp_subscribe':
|
|
403
|
+
handleUnifyVpSubscribe(msg);
|
|
404
|
+
break;
|
|
405
|
+
|
|
400
406
|
// Expert roles definition (for ExpertPanel detail view)
|
|
401
407
|
case 'get_expert_roles': {
|
|
402
408
|
const { getExpertRolesDefinition } = await import('../expert-roles.js');
|
package/package.json
CHANGED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* vp-bridge.js — task-334-ui-a snapshot-only WS adapter.
|
|
3
|
+
*
|
|
4
|
+
* Per ruling .crew/context/task-334-ui-a-ruling.md §3 (D3 = mixed):
|
|
5
|
+
* • snapshot path lives here (this slice, in-scope)
|
|
6
|
+
* • live diff (vp_updated / vp_removed) deferred to 334h — see TODO below
|
|
7
|
+
*
|
|
8
|
+
* This module is the SOLE serialiser for the wire-format VP shape.
|
|
9
|
+
* Per ruling §1 (D1 = (b) web-bridge boundary rename), the entity layer
|
|
10
|
+
* (`vp-store.js` / `registry.js`) keeps `id` / `name`; here we map to
|
|
11
|
+
* `vpId` / `displayName` per the spec (§2.1) / architecture §R6.11.
|
|
12
|
+
*
|
|
13
|
+
* Per ruling §2 (D2):
|
|
14
|
+
* • subtitle → agent emits `vp.role` directly
|
|
15
|
+
* • personaHash → agent emits `vp.personaHash` (added by dev-1's
|
|
16
|
+
* 334a-followup patch). Until that lands, this serialiser falls back
|
|
17
|
+
* to undefined and the web layer simply omits the field.
|
|
18
|
+
* • color / avatar → web-derived, NOT emitted here
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
import { defaultRegistry } from './registry.js';
|
|
22
|
+
import { VpLoader } from './vp-loader.js';
|
|
23
|
+
|
|
24
|
+
/** Process-singleton VpLoader; lazily started on first subscribe. */
|
|
25
|
+
let _loaderStarted = false;
|
|
26
|
+
let _loader = null;
|
|
27
|
+
|
|
28
|
+
function ensureLoader() {
|
|
29
|
+
if (_loaderStarted) return _loader;
|
|
30
|
+
_loaderStarted = true;
|
|
31
|
+
try {
|
|
32
|
+
_loader = new VpLoader({ registry: defaultRegistry });
|
|
33
|
+
_loader.start();
|
|
34
|
+
} catch {
|
|
35
|
+
// Hot-reload optional; subscribe still returns whatever scan loaded.
|
|
36
|
+
_loader = null;
|
|
37
|
+
}
|
|
38
|
+
return _loader;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Serialise a VP (entity layer shape) to the wire-format the web layer
|
|
43
|
+
* expects (spec §2.1). Pure; no IO.
|
|
44
|
+
*
|
|
45
|
+
* @param {{id:string,name:string,role:string,traits?:string[],modelHint?:string,personaHash?:string}} vp
|
|
46
|
+
* @returns {{vpId:string,displayName:string,subtitle:string,role:string,traits:string[],modelHint:?string,personaHash:?string}}
|
|
47
|
+
*/
|
|
48
|
+
export function serializeVpForWire(vp) {
|
|
49
|
+
return {
|
|
50
|
+
vpId: vp.id,
|
|
51
|
+
displayName: vp.name,
|
|
52
|
+
role: vp.role || '',
|
|
53
|
+
subtitle: vp.role || '',
|
|
54
|
+
traits: Array.isArray(vp.traits) ? vp.traits.slice() : [],
|
|
55
|
+
modelHint: vp.modelHint ?? null,
|
|
56
|
+
personaHash: vp.personaHash ?? null,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Build a vp_snapshot event payload from the registry.
|
|
62
|
+
* @param {import('./registry.js').Registry} [registry]
|
|
63
|
+
* @returns {{type:'vp_snapshot', vps:Array, emptyLibrary:boolean}}
|
|
64
|
+
*/
|
|
65
|
+
export function buildVpSnapshot(registry = defaultRegistry) {
|
|
66
|
+
const vps = registry.listVps().map(serializeVpForWire);
|
|
67
|
+
return {
|
|
68
|
+
type: 'vp_snapshot',
|
|
69
|
+
vps,
|
|
70
|
+
emptyLibrary: vps.length === 0,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Handle an `unify_vp_subscribe` request from the web client.
|
|
76
|
+
* Lazily starts the VpLoader on first call (debounced rescan watchers).
|
|
77
|
+
*
|
|
78
|
+
* @param {(event: object) => void} sendUnifyEvent — emit fn (web-bridge wires this)
|
|
79
|
+
* @param {import('./registry.js').Registry} [registry]
|
|
80
|
+
*/
|
|
81
|
+
export function handleVpSubscribe(sendUnifyEvent, registry = defaultRegistry) {
|
|
82
|
+
ensureLoader();
|
|
83
|
+
try {
|
|
84
|
+
sendUnifyEvent(buildVpSnapshot(registry));
|
|
85
|
+
} catch {
|
|
86
|
+
// Never crash the WS pipeline from snapshot serialisation.
|
|
87
|
+
}
|
|
88
|
+
// TODO(334h): vp_updated / vp_removed live broadcast.
|
|
89
|
+
// Wire VpLoader.onChange → emit per-vp `vp_updated` and `vp_removed`
|
|
90
|
+
// events using serializeVpForWire(). Out of scope for 334-ui-a.
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Test seam: reset the lazy loader (for vitest).
|
|
95
|
+
*/
|
|
96
|
+
export function _resetVpBridgeForTest() {
|
|
97
|
+
if (_loader) {
|
|
98
|
+
try { _loader.stop(); } catch { /* ignore */ }
|
|
99
|
+
}
|
|
100
|
+
_loader = null;
|
|
101
|
+
_loaderStarted = false;
|
|
102
|
+
}
|
package/unify/web-bridge.js
CHANGED
|
@@ -26,6 +26,7 @@ import { loadSession } from './session.js';
|
|
|
26
26
|
import { sendToServer } from '../connection/buffer.js';
|
|
27
27
|
import ctx from '../context.js';
|
|
28
28
|
import { getThreadStore, MAIN_THREAD_ID } from './threads/store.js';
|
|
29
|
+
import { handleVpSubscribe } from './vp/vp-bridge.js';
|
|
29
30
|
|
|
30
31
|
/** @type {import('./session.js').Session | null} */
|
|
31
32
|
let session = null;
|
|
@@ -103,6 +104,15 @@ function sendUnifyEvent(event) {
|
|
|
103
104
|
});
|
|
104
105
|
}
|
|
105
106
|
|
|
107
|
+
/**
|
|
108
|
+
* task-334-ui-a: respond to `unify_vp_subscribe` from the web client by
|
|
109
|
+
* pushing a one-shot `vp_snapshot` event. Live diff (vp_updated /
|
|
110
|
+
* vp_removed) is intentionally deferred to 334h per ruling §3.
|
|
111
|
+
*/
|
|
112
|
+
export function handleUnifyVpSubscribe(_msg) {
|
|
113
|
+
handleVpSubscribe(sendUnifyEvent);
|
|
114
|
+
}
|
|
115
|
+
|
|
106
116
|
/**
|
|
107
117
|
* task-318 rev-1 fix: install live-setter bridge between the session's
|
|
108
118
|
* runtime handles (engineRegistry + threadStore) and `ctx.unifyRuntimeSettings`,
|