@yeaft/webchat-agent 1.0.597 → 1.0.599

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": "1.0.597",
3
+ "version": "1.0.599",
4
4
  "description": "Remote worker agent for Yeaft Web Code Agent — connects the native Yeaft engine, CLI providers, and workbench tools",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -64,7 +64,9 @@ export function createPersonBridge({
64
64
  // Driver/provider messages can include credential-bearing URLs. Never relay them.
65
65
  const safeErrors = {
66
66
  BUSY: 'The digital person is busy; wait or cancel before trying again',
67
- INVALID_REQUEST: 'Invalid digital person input (maximum 8192 UTF-8 bytes)',
67
+ INVALID_REQUEST: response.op === 'settings'
68
+ ? 'Invalid digital person settings; use a non-empty name of at most 160 UTF-8 bytes and valid settings fields'
69
+ : 'Invalid digital person request',
68
70
  INVALID_ATTACHMENT: 'Invalid digital person attachment',
69
71
  UNSUPPORTED_ATTACHMENT: 'Use PNG/JPEG/WebP/GIF images or UTF-8 text; PDF and binary files are not supported',
70
72
  ATTACHMENT_LIMIT: 'Maximum 4 attachments, 5 MiB each, 10 MiB total; text plus extracted content must fit 24 KiB',
@@ -420,10 +420,11 @@ export class MongoPersonRepository {
420
420
  if (p.activeEpisodeId) fail('BUSY'); // No implicit background API or deferred control effects.
421
421
  const { name, ...patch } = settings;
422
422
  if (Object.hasOwn(settings, 'name')) p.name = personName(name);
423
- const next = { ...settingsView(p.settings), ...patch };
423
+ // A partial update must preserve durable fields omitted from the public view.
424
+ const next = { ...p.settings, ...patch };
424
425
  await this.collections.persons.updateOne(scope, { $set: { settings: next, name: p.name }, $inc: { controlVersion: 1, writeSerial: 1 } }, { session });
425
- if (Object.keys(settings).length) await this.trace(session, p, null, 'settings', { settings: next, ...(name !== undefined ? { name: p.name } : {}) });
426
- return { settings: next, person: this.personView({ ...p, settings: next }) };
426
+ if (Object.keys(settings).length) await this.trace(session, p, null, 'settings', { settings: settingsView(next), ...(name !== undefined ? { name: p.name } : {}) });
427
+ return { settings: settingsView(next), person: this.personView({ ...p, settings: next }) };
427
428
  });
428
429
  }
429
430
  async inspect(ownerId, options) {
@@ -54,9 +54,9 @@ export function createPersonService(options = {}) {
54
54
  if (typeof op !== 'string') fail('INVALID_REQUEST');
55
55
  if (op === 'status') {
56
56
  object(payload, []);
57
- if (!configured) return { configured: false, storage, reason: 'Digital person storage configuration is missing.', storageReady: false, modelReady: false };
57
+ if (!configured) return { renameSupported: true, configured: false, storage, reason: 'Digital person storage configuration is missing.', storageReady: false, modelReady: false };
58
58
  try { await repository.init(); }
59
- catch (error) { return { configured: true, storage, reason: safeError(error).message, storageReady: false, modelReady: false }; }
59
+ catch (error) { return { renameSupported: true, configured: true, storage, reason: safeError(error).message, storageReady: false, modelReady: false }; }
60
60
  let modelCandidates = [];
61
61
  try { modelCandidates = (await repository.getPerson(ownerId)).settings.modelCandidates ?? []; }
62
62
  catch (error) { if (error.code !== 'NOT_OPEN') throw error; }
@@ -67,10 +67,10 @@ export function createPersonService(options = {}) {
67
67
  validateModelCandidates(modelCandidates);
68
68
  if (modelCandidates.some(ref => !provider.availableModels.some(model => model.id === ref))) modelReady = false;
69
69
  } catch { modelReady = false; }
70
- return { configured: true, storage, reason: modelReady ? null : 'Saved model candidates are unavailable; choose models or reset to Agent defaults.',
70
+ return { renameSupported: true, configured: true, storage, reason: modelReady ? null : 'Saved model candidates are unavailable; choose models or reset to Agent defaults.',
71
71
  storageReady: true, modelReady, models: provider.availableModels, availableModels: provider.availableModels,
72
72
  availableModelsTruncated: provider.availableModelsTruncated, modelCandidates, autonomySupported: false };
73
- } catch { return { configured: true, storage, reason: 'No permitted native model is configured for digital person.', storageReady: true, modelReady: false, models: [], availableModels: [], modelCandidates }; }
73
+ } catch { return { renameSupported: true, configured: true, storage, reason: 'No permitted native model is configured for digital person.', storageReady: true, modelReady: false, models: [], availableModels: [], modelCandidates }; }
74
74
  }
75
75
  if (!configured) fail('NOT_CONFIGURED');
76
76
  switch (op) {
@@ -387,8 +387,9 @@ export class SqlitePersonStore {
387
387
  if (p.activeEpisodeId) fail('BUSY');
388
388
  const { name, ...patch } = settings;
389
389
  if (Object.hasOwn(settings, 'name')) p.name = personName(name);
390
- p.settings = { ...settingsView(p.settings), ...patch }; p.controlVersion++; p.writeSerial++; this.put('persons', p);
391
- if (Object.keys(settings).length) this.trace(ownerId, null, 'settings', { settings: p.settings, ...(name !== undefined ? { name: p.name } : {}) });
390
+ // A partial update must preserve durable fields omitted from the public view.
391
+ p.settings = { ...p.settings, ...patch }; p.controlVersion++; p.writeSerial++; this.put('persons', p);
392
+ if (Object.keys(settings).length) this.trace(ownerId, null, 'settings', { settings: settingsView(p.settings), ...(name !== undefined ? { name: p.name } : {}) });
392
393
  return { settings: settingsView(p.settings), person: this.personView(p) };
393
394
  }
394
395
  inspect(ownerId, options) {