@yeaft/webchat-agent 0.1.756 → 0.1.758

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.756",
3
+ "version": "0.1.758",
4
4
  "description": "Remote agent for Yeaft WebChat — connects worker machines to the central server",
5
5
  "main": "index.js",
6
6
  "type": "module",
package/unify/prompts.js CHANGED
@@ -301,7 +301,7 @@ export function buildSystemPrompt({
301
301
  // Phase 8 wire-up: when a VP persona is active, the persona body REPLACES
302
302
  // the Yeaft identity block (the LLM is that VP, not Yeaft pretending). When
303
303
  // there is no persona, fall back to the legacy Yeaft identity bundle.
304
- const personaBlock = renderVpPersona(vpPersona, lang);
304
+ const personaBlock = renderVpPersona(vpPersona, lang, effectiveLang);
305
305
  if (personaBlock) {
306
306
  parts.push(personaBlock);
307
307
  // Common rules (output format, code editing, search, frontend) still
@@ -396,17 +396,18 @@ export function buildSystemPrompt({
396
396
  * @param {object} vpPersona
397
397
  * @param {string} vpPersona.displayName
398
398
  * @param {string} [vpPersona.role]
399
+ * @param {string} [vpPersona.roleZh]
399
400
  * @param {string} [vpPersona.persona]
400
401
  * @param {object} lang
402
+ * @param {'en'|'zh'} effectiveLang
401
403
  * @returns {string}
402
404
  */
403
- function renderVpPersona(vpPersona, lang) {
405
+ function renderVpPersona(vpPersona, lang, effectiveLang = 'en') {
404
406
  if (!vpPersona || typeof vpPersona !== 'object') return '';
405
- const name = typeof vpPersona.displayName === 'string'
406
- ? vpPersona.displayName.trim() : '';
407
+ const name = selectVpPersonaName(vpPersona, effectiveLang);
407
408
  if (!name) return '';
408
- const role = typeof vpPersona.role === 'string' ? vpPersona.role.trim() : '';
409
- const body = typeof vpPersona.persona === 'string' ? vpPersona.persona.trim() : '';
409
+ const role = selectVpPersonaRole(vpPersona, effectiveLang);
410
+ const body = selectVpPersonaBody(vpPersona, effectiveLang);
410
411
 
411
412
  // Phase 8 wire-up: persona is now the IDENTITY layer (not an overlay).
412
413
  // Emit a `# <name> — <role>` H1 so the prompt opens with the VP's name,
@@ -419,6 +420,41 @@ function renderVpPersona(vpPersona, lang) {
419
420
  return lines.join('\n');
420
421
  }
421
422
 
423
+ function selectVpPersonaName(vpPersona, effectiveLang) {
424
+ if (effectiveLang === 'zh') {
425
+ const zhName = typeof vpPersona.displayNameZh === 'string'
426
+ ? vpPersona.displayNameZh.trim() : '';
427
+ if (zhName) return zhName;
428
+ }
429
+ return typeof vpPersona.displayName === 'string' ? vpPersona.displayName.trim() : '';
430
+ }
431
+
432
+ function selectVpPersonaRole(vpPersona, effectiveLang) {
433
+ if (effectiveLang === 'zh') {
434
+ const zhRole = typeof vpPersona.roleZh === 'string' ? vpPersona.roleZh.trim() : '';
435
+ if (zhRole) return zhRole;
436
+
437
+ const role = typeof vpPersona.role === 'string' ? vpPersona.role.trim() : '';
438
+ return hasCjk(role) ? role : '';
439
+ }
440
+ return typeof vpPersona.role === 'string' ? vpPersona.role.trim() : '';
441
+ }
442
+
443
+ function selectVpPersonaBody(vpPersona, effectiveLang) {
444
+ const body = typeof vpPersona.persona === 'string' ? vpPersona.persona.trim() : '';
445
+ if (effectiveLang === 'zh') {
446
+ // role.md has one persisted persona body today. If that body is Chinese,
447
+ // keep it. If it is English-only (the default seeded VP shape), do not glue
448
+ // it under a Chinese wrapper and produce a half-translated system prompt.
449
+ return hasCjk(body) ? body : '';
450
+ }
451
+ return body;
452
+ }
453
+
454
+ function hasCjk(text) {
455
+ return /[\u3400-\u9fff\uf900-\ufaff]/u.test(String(text || ''));
456
+ }
457
+
422
458
  const DEFAULT_TASK_MEMORY_TOP = 5;
423
459
  const DEFAULT_RELATED_TASK_TOP = 3;
424
460
  const DEFAULT_RELATED_TASK_MEMORY_TOP = 2;
@@ -112,6 +112,7 @@ export function buildRoleMd(p) {
112
112
  const nameZh = p.displayNameZh != null ? String(p.displayNameZh) : '';
113
113
  const aliases = Array.isArray(p.aliases) ? p.aliases.map(a => String(a)).filter(Boolean) : [];
114
114
  const role = p.role != null ? String(p.role) : '';
115
+ const roleZh = p.roleZh != null ? String(p.roleZh) : '';
115
116
  const traits = Array.isArray(p.traits) ? p.traits.map(t => String(t)).filter(Boolean) : [];
116
117
  const modelHint = p.modelHint === 'primary' || p.modelHint === 'fast' ? p.modelHint : null;
117
118
  const body = typeof p.persona === 'string' ? p.persona : '';
@@ -119,6 +120,7 @@ export function buildRoleMd(p) {
119
120
  const lines = ['---', `id: ${id}`, `name: ${yamlScalar(name)}`];
120
121
  if (nameZh) lines.push(`nameZh: ${yamlScalar(nameZh)}`);
121
122
  lines.push(`role: ${yamlScalar(role)}`);
123
+ if (roleZh) lines.push(`roleZh: ${yamlScalar(roleZh)}`);
122
124
  if (modelHint) lines.push(`modelHint: ${modelHint}`);
123
125
  if (traits.length > 0) {
124
126
  lines.push('traits:');
@@ -287,6 +289,7 @@ export function readVp(vpId, options = {}) {
287
289
  displayNameZh: typeof meta.nameZh === 'string' ? String(meta.nameZh) : '',
288
290
  aliases: Array.isArray(meta.aliases) ? meta.aliases.map(String) : [],
289
291
  role: String(meta.role || ''),
292
+ roleZh: typeof meta.roleZh === 'string' ? String(meta.roleZh) : '',
290
293
  traits: Array.isArray(meta.traits) ? meta.traits.map(String) : [],
291
294
  modelHint,
292
295
  persona: body,
@@ -135,6 +135,7 @@ export function loadVpFromDir(dir) {
135
135
  ? meta.aliases.map(String).map(s => s.trim()).filter(Boolean)
136
136
  : [],
137
137
  role: String(meta.role || ''),
138
+ roleZh: typeof meta.roleZh === 'string' ? String(meta.roleZh) : '',
138
139
  traits: Array.isArray(meta.traits) ? meta.traits.map(String) : [],
139
140
  modelHint,
140
141
  persona: body,
@@ -1850,7 +1850,9 @@ export function buildVpQueryOpts({ vpId, groupCoordinator, groupId, envelope })
1850
1850
  out.vpPersona = {
1851
1851
  vpId: resolvedVpId,
1852
1852
  displayName: vp.displayName || resolvedVpId,
1853
+ displayNameZh: vp.displayNameZh || '',
1853
1854
  role: vp.role || '',
1855
+ roleZh: vp.roleZh || '',
1854
1856
  persona: vp.persona || '',
1855
1857
  };
1856
1858
  }