@yeaft/webchat-agent 0.1.572 → 0.1.574
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/vp/seed-defaults.js +24 -0
- package/unify/vp/vp-bridge.js +4 -0
- package/unify/vp/vp-crud.js +11 -1
- package/unify/vp/vp-store.js +7 -0
- package/unify/web-bridge.js +23 -0
package/package.json
CHANGED
|
@@ -34,6 +34,8 @@ export const DEFAULT_VPS = Object.freeze([
|
|
|
34
34
|
{
|
|
35
35
|
vpId: 'steve',
|
|
36
36
|
displayName: 'Steve Jobs',
|
|
37
|
+
displayNameZh: '史蒂夫·乔布斯',
|
|
38
|
+
aliases: ['steve', 'jobs', 'shidifu', 'qiaobusi', 'qbs'],
|
|
37
39
|
role: 'Product Strategist',
|
|
38
40
|
traits: ['minimalist', 'uncompromising', 'taste-first'],
|
|
39
41
|
modelHint: 'primary',
|
|
@@ -55,6 +57,8 @@ Bad for: incremental A/B testing, compromise negotiations, anything that rewards
|
|
|
55
57
|
{
|
|
56
58
|
vpId: 'linus',
|
|
57
59
|
displayName: 'Linus Torvalds',
|
|
60
|
+
displayNameZh: '林纳斯·托瓦兹',
|
|
61
|
+
aliases: ['linus', 'torvalds', 'linasi', 'tuowazi', 'lnx'],
|
|
58
62
|
role: 'Systems Engineer',
|
|
59
63
|
traits: ['data-structures-first', 'no-workarounds', 'blunt'],
|
|
60
64
|
modelHint: 'primary',
|
|
@@ -76,6 +80,8 @@ Bad for: soothing egos, PM sync meetings, anything that rewards diplomacy over t
|
|
|
76
80
|
{
|
|
77
81
|
vpId: 'martin',
|
|
78
82
|
displayName: 'Martin Fowler',
|
|
83
|
+
displayNameZh: '马丁·福勒',
|
|
84
|
+
aliases: ['martin', 'fowler', 'mading', 'fule'],
|
|
79
85
|
role: 'Code Reviewer',
|
|
80
86
|
traits: ['refactoring', 'code-smells', 'readability'],
|
|
81
87
|
modelHint: 'primary',
|
|
@@ -97,6 +103,8 @@ Bad for: greenfield scaffolding from zero, raw performance tuning, UI design.`,
|
|
|
97
103
|
{
|
|
98
104
|
vpId: 'dieter',
|
|
99
105
|
displayName: 'Dieter Rams',
|
|
106
|
+
displayNameZh: '迪特·拉姆斯',
|
|
107
|
+
aliases: ['dieter', 'rams', 'dite', 'lamusi'],
|
|
100
108
|
role: 'UX Designer',
|
|
101
109
|
traits: ['less-but-better', 'honest', 'pixel-obsessive'],
|
|
102
110
|
modelHint: 'primary',
|
|
@@ -118,6 +126,8 @@ Bad for: wild brainstorms, marketing sizzle, maximalist visual languages.`,
|
|
|
118
126
|
{
|
|
119
127
|
vpId: 'ada',
|
|
120
128
|
displayName: 'Ada Lovelace',
|
|
129
|
+
displayNameZh: '阿达·洛芙莱斯',
|
|
130
|
+
aliases: ['ada', 'lovelace', 'ada', 'luofulaisi'],
|
|
121
131
|
role: 'Algorithm Specialist',
|
|
122
132
|
traits: ['first-principles', 'rigorous', 'imaginative'],
|
|
123
133
|
modelHint: 'primary',
|
|
@@ -139,6 +149,8 @@ Bad for: production firefighting, ops triage, team-velocity debates.`,
|
|
|
139
149
|
{
|
|
140
150
|
vpId: 'grace',
|
|
141
151
|
displayName: 'Grace Hopper',
|
|
152
|
+
displayNameZh: '葛丽丝·霍普',
|
|
153
|
+
aliases: ['grace', 'hopper', 'gelisi', 'huopu'],
|
|
142
154
|
role: 'Debug Expert',
|
|
143
155
|
traits: ['systems-thinking', 'pragmatic', 'teacher'],
|
|
144
156
|
modelHint: 'primary',
|
|
@@ -160,6 +172,8 @@ Bad for: UI polish, marketing copy, pure-theory derivations.`,
|
|
|
160
172
|
{
|
|
161
173
|
vpId: 'alice',
|
|
162
174
|
displayName: 'Alice Security',
|
|
175
|
+
displayNameZh: '爱丽丝·安全官',
|
|
176
|
+
aliases: ['alice', 'security', 'ailisi', 'anquan'],
|
|
163
177
|
role: 'Security Analyst',
|
|
164
178
|
traits: ['threat-modeling', 'trust-nothing', 'adversarial'],
|
|
165
179
|
modelHint: 'primary',
|
|
@@ -181,6 +195,8 @@ Bad for: greenfield UX explorations, creative copy, cost-optimisation tradeoffs.
|
|
|
181
195
|
{
|
|
182
196
|
vpId: 'ken',
|
|
183
197
|
displayName: 'Ken Thompson',
|
|
198
|
+
displayNameZh: '肯·汤普逊',
|
|
199
|
+
aliases: ['ken', 'thompson', 'ken', 'tangpuxun', 'unix'],
|
|
184
200
|
role: 'Unix Philosopher',
|
|
185
201
|
traits: ['do-one-thing-well', 'composable', 'terse'],
|
|
186
202
|
modelHint: 'primary',
|
|
@@ -202,6 +218,8 @@ Bad for: rich GUIs, stateful sessions, anything that resists the pipeline model.
|
|
|
202
218
|
{
|
|
203
219
|
vpId: 'margaret',
|
|
204
220
|
displayName: 'Margaret Hamilton',
|
|
221
|
+
displayNameZh: '玛格丽特·汉密尔顿',
|
|
222
|
+
aliases: ['margaret', 'hamilton', 'magelite', 'hanmierdun'],
|
|
205
223
|
role: 'QA Lead',
|
|
206
224
|
traits: ['safety-first', 'edge-cases', 'defensive'],
|
|
207
225
|
modelHint: 'primary',
|
|
@@ -223,6 +241,8 @@ Bad for: rapid prototyping where failure is cheap, pixel-hunt design reviews.`,
|
|
|
223
241
|
{
|
|
224
242
|
vpId: 'shannon',
|
|
225
243
|
displayName: 'Shannon',
|
|
244
|
+
displayNameZh: '克劳德·香农',
|
|
245
|
+
aliases: ['shannon', 'claude', 'xiangnong', 'kelaode'],
|
|
226
246
|
role: 'Data Analyst',
|
|
227
247
|
traits: ['information-theory', 'signal-vs-noise', 'probabilistic'],
|
|
228
248
|
modelHint: 'primary',
|
|
@@ -244,6 +264,8 @@ Bad for: qualitative UX research, narrative-first presentations.`,
|
|
|
244
264
|
{
|
|
245
265
|
vpId: 'alan',
|
|
246
266
|
displayName: 'Alan Kay',
|
|
267
|
+
displayNameZh: '艾伦·凯',
|
|
268
|
+
aliases: ['alan', 'kay', 'ailun', 'kai'],
|
|
247
269
|
role: 'Futurist',
|
|
248
270
|
traits: ['paradigm-shift', 'analogies', 'long-view'],
|
|
249
271
|
modelHint: 'primary',
|
|
@@ -265,6 +287,8 @@ Bad for: today's bug, next Tuesday's ship date, conservative refactors.`,
|
|
|
265
287
|
{
|
|
266
288
|
vpId: 'norman',
|
|
267
289
|
displayName: 'Don Norman',
|
|
290
|
+
displayNameZh: '唐纳德·诺曼',
|
|
291
|
+
aliases: ['norman', 'don', 'donald', 'nuoman', 'tangnade'],
|
|
268
292
|
role: 'UX Researcher',
|
|
269
293
|
traits: ['human-centered', 'affordances', 'cognitive-load'],
|
|
270
294
|
modelHint: 'primary',
|
package/unify/vp/vp-bridge.js
CHANGED
|
@@ -182,6 +182,10 @@ export function serializeVpForWire(vp) {
|
|
|
182
182
|
return {
|
|
183
183
|
vpId: vp.id,
|
|
184
184
|
displayName: vp.name,
|
|
185
|
+
// task-fix (5-bugs): carry bilingual name + aliases (incl. pinyin) to
|
|
186
|
+
// the frontend so @ mention matching + localised rendering work.
|
|
187
|
+
displayNameZh: typeof vp.nameZh === 'string' ? vp.nameZh : '',
|
|
188
|
+
aliases: Array.isArray(vp.aliases) ? vp.aliases.slice() : [],
|
|
185
189
|
role: vp.role || '',
|
|
186
190
|
subtitle: vp.role || '',
|
|
187
191
|
traits: Array.isArray(vp.traits) ? vp.traits.slice() : [],
|
package/unify/vp/vp-crud.js
CHANGED
|
@@ -57,17 +57,25 @@ function vpRolePathFor(libDir, vpId) {
|
|
|
57
57
|
export function buildRoleMd(p) {
|
|
58
58
|
const id = String(p.vpId);
|
|
59
59
|
const name = p.displayName != null ? String(p.displayName) : id;
|
|
60
|
+
const nameZh = p.displayNameZh != null ? String(p.displayNameZh) : '';
|
|
61
|
+
const aliases = Array.isArray(p.aliases) ? p.aliases.map(a => String(a)).filter(Boolean) : [];
|
|
60
62
|
const role = p.role != null ? String(p.role) : '';
|
|
61
63
|
const traits = Array.isArray(p.traits) ? p.traits.map(t => String(t)).filter(Boolean) : [];
|
|
62
64
|
const modelHint = p.modelHint === 'primary' || p.modelHint === 'fast' ? p.modelHint : null;
|
|
63
65
|
const body = typeof p.persona === 'string' ? p.persona : '';
|
|
64
66
|
|
|
65
|
-
const lines = ['---', `id: ${id}`, `name: ${yamlScalar(name)}
|
|
67
|
+
const lines = ['---', `id: ${id}`, `name: ${yamlScalar(name)}`];
|
|
68
|
+
if (nameZh) lines.push(`nameZh: ${yamlScalar(nameZh)}`);
|
|
69
|
+
lines.push(`role: ${yamlScalar(role)}`);
|
|
66
70
|
if (modelHint) lines.push(`modelHint: ${modelHint}`);
|
|
67
71
|
if (traits.length > 0) {
|
|
68
72
|
lines.push('traits:');
|
|
69
73
|
for (const t of traits) lines.push(` - ${yamlScalar(t)}`);
|
|
70
74
|
}
|
|
75
|
+
if (aliases.length > 0) {
|
|
76
|
+
lines.push('aliases:');
|
|
77
|
+
for (const a of aliases) lines.push(` - ${yamlScalar(a)}`);
|
|
78
|
+
}
|
|
71
79
|
lines.push('---', '', body.trim(), '');
|
|
72
80
|
return lines.join('\n');
|
|
73
81
|
}
|
|
@@ -193,6 +201,8 @@ export function readVp(vpId, options = {}) {
|
|
|
193
201
|
return {
|
|
194
202
|
vpId: id,
|
|
195
203
|
displayName: String(meta.name || id),
|
|
204
|
+
displayNameZh: typeof meta.nameZh === 'string' ? String(meta.nameZh) : '',
|
|
205
|
+
aliases: Array.isArray(meta.aliases) ? meta.aliases.map(String) : [],
|
|
196
206
|
role: String(meta.role || ''),
|
|
197
207
|
traits: Array.isArray(meta.traits) ? meta.traits.map(String) : [],
|
|
198
208
|
modelHint,
|
package/unify/vp/vp-store.js
CHANGED
|
@@ -127,6 +127,13 @@ export function loadVpFromDir(dir) {
|
|
|
127
127
|
return {
|
|
128
128
|
id,
|
|
129
129
|
name: String(meta.name || id),
|
|
130
|
+
// task-fix (5-bugs): optional localized names + pinyin aliases for
|
|
131
|
+
// bilingual display + @-mention pinyin-prefix matching. Missing fields
|
|
132
|
+
// degrade gracefully to [] / ''.
|
|
133
|
+
nameZh: typeof meta.nameZh === 'string' ? String(meta.nameZh) : '',
|
|
134
|
+
aliases: Array.isArray(meta.aliases)
|
|
135
|
+
? meta.aliases.map(String).map(s => s.trim()).filter(Boolean)
|
|
136
|
+
: [],
|
|
130
137
|
role: String(meta.role || ''),
|
|
131
138
|
traits: Array.isArray(meta.traits) ? meta.traits.map(String) : [],
|
|
132
139
|
modelHint,
|
package/unify/web-bridge.js
CHANGED
|
@@ -1130,6 +1130,11 @@ export async function handleUnifyGroupChat(msg) {
|
|
|
1130
1130
|
// Per target: emit `group_message` tagged with `speakerVpId` (the VP
|
|
1131
1131
|
// being addressed — F3's GroupSelector binding consumes this) + dispatch
|
|
1132
1132
|
// through the Engine via handleUnifyChat with an `@vp-<id>` prompt prefix.
|
|
1133
|
+
//
|
|
1134
|
+
// task-fix: bracket each per-VP dispatch with `vp_typing_start` /
|
|
1135
|
+
// `vp_typing_end` events so the frontend can render a per-speaker typing
|
|
1136
|
+
// dot next to that VP's avatar (matching IM apps). Avoids the old
|
|
1137
|
+
// "one global running cat for N concurrent speakers" ambiguity.
|
|
1133
1138
|
for (const { vpId, envelope } of captured) {
|
|
1134
1139
|
try {
|
|
1135
1140
|
sendUnifyEvent({
|
|
@@ -1144,6 +1149,15 @@ export async function handleUnifyGroupChat(msg) {
|
|
|
1144
1149
|
});
|
|
1145
1150
|
} catch { /* never crash WS pipeline */ }
|
|
1146
1151
|
|
|
1152
|
+
try {
|
|
1153
|
+
sendUnifyEvent({
|
|
1154
|
+
type: 'vp_typing_start',
|
|
1155
|
+
groupId,
|
|
1156
|
+
vpId,
|
|
1157
|
+
ts: Date.now(),
|
|
1158
|
+
});
|
|
1159
|
+
} catch { /* never crash WS pipeline */ }
|
|
1160
|
+
|
|
1147
1161
|
try {
|
|
1148
1162
|
await handleUnifyChat({
|
|
1149
1163
|
...msg,
|
|
@@ -1154,6 +1168,15 @@ export async function handleUnifyGroupChat(msg) {
|
|
|
1154
1168
|
});
|
|
1155
1169
|
} catch (err) {
|
|
1156
1170
|
console.warn('[Unify] unify_group_chat: per-vp dispatch failed', vpId, err?.message || err);
|
|
1171
|
+
} finally {
|
|
1172
|
+
try {
|
|
1173
|
+
sendUnifyEvent({
|
|
1174
|
+
type: 'vp_typing_end',
|
|
1175
|
+
groupId,
|
|
1176
|
+
vpId,
|
|
1177
|
+
ts: Date.now(),
|
|
1178
|
+
});
|
|
1179
|
+
} catch { /* never crash WS pipeline */ }
|
|
1157
1180
|
}
|
|
1158
1181
|
}
|
|
1159
1182
|
}
|