@yeaft/webchat-agent 0.1.604 → 0.1.605

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.604",
3
+ "version": "0.1.605",
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/engine.js CHANGED
@@ -713,7 +713,7 @@ export class Engine {
713
713
  * SCENARIO_EFFORT. Unknown values fall through to 'high'.
714
714
  * @yields {EngineEvent}
715
715
  */
716
- async *query({ prompt, messages = [], signal, userEffort = null, scenario = 'chat', vpPersona, router, senderVpId, inboundEnvelope, taskId, taskMembers, groupId } = {}) {
716
+ async *query({ prompt, messages = [], signal, userEffort = null, scenario = 'chat', vpPersona, router, senderVpId, inboundEnvelope, taskId, taskMembers, groupId, vpPlan } = {}) {
717
717
  if (!prompt || typeof prompt !== 'string' || !prompt.trim()) {
718
718
  yield {
719
719
  type: 'error',
@@ -764,7 +764,7 @@ export class Engine {
764
764
  const runSignal = abortCtrl.signal;
765
765
 
766
766
  try {
767
- yield* this.#runQuery({ prompt: effectivePrompt, messages, signal: runSignal, userEffort: effectiveUserEffort, scenario, vpPersona, router, senderVpId, inboundEnvelope, taskId, taskMembers, groupId });
767
+ yield* this.#runQuery({ prompt: effectivePrompt, messages, signal: runSignal, userEffort: effectiveUserEffort, scenario, vpPersona, router, senderVpId, inboundEnvelope, taskId, taskMembers, groupId, vpPlan });
768
768
  } finally {
769
769
  if (signal) {
770
770
  try { signal.removeEventListener('abort', onExternalAbort); } catch { /* ignore */ }
@@ -782,7 +782,7 @@ export class Engine {
782
782
  * in a try/finally without indenting the whole loop.
783
783
  * @private
784
784
  */
785
- async *#runQuery({ prompt, messages, signal, userEffort = null, scenario = 'chat', vpPersona, router, senderVpId, inboundEnvelope, taskId, taskMembers, groupId }) {
785
+ async *#runQuery({ prompt, messages, signal, userEffort = null, scenario = 'chat', vpPersona, router, senderVpId, inboundEnvelope, taskId, taskMembers, groupId, vpPlan }) {
786
786
 
787
787
  // ─── Pre-query: Memory Injection (task-287) + Compact Summary ──
788
788
  // Two-layer recall:
@@ -902,10 +902,19 @@ export class Engine {
902
902
  if (vpPersona && vpPersona.vpId) {
903
903
  const priorPlan = extractPriorPlan(conversationMessages, vpPersona.vpId);
904
904
  const thinkingCfg = (this.#config && this.#config.thinking) || {};
905
+ // PR-I: live routerPlan.thinking — when the dispatcher passes
906
+ // `vpPlan` for this turn (per-VP plan from the V2 router) and its
907
+ // `vpId` matches the active persona, surface its `thinking` field
908
+ // to resolveThinking. Mismatched vpId means the plan addresses a
909
+ // different VP — ignore it for this VP's thinking decision.
910
+ const liveRouterThinking = (vpPlan && typeof vpPlan === 'object'
911
+ && typeof vpPlan.vpId === 'string' && vpPlan.vpId === vpPersona.vpId
912
+ && (vpPlan.thinking === 'high' || vpPlan.thinking === 'max'))
913
+ ? vpPlan.thinking
914
+ : null;
905
915
  const resolved = resolveThinking({
906
916
  uiOverride: (userEffort === 'max' || userEffort === 'high') ? userEffort : null,
907
- routerPlan: null, // PR-C scope: priorPlan continuity only;
908
- // live router-plan thinking is a follow-up.
917
+ routerPlan: liveRouterThinking,
909
918
  priorPlan: priorPlan && priorPlan.thinking ? priorPlan.thinking : null,
910
919
  vpDefault: typeof vpPersona.thinking === 'string' ? vpPersona.thinking : null,
911
920
  globalDefault: typeof thinkingCfg.default === 'string' ? thinkingCfg.default : null,
@@ -1106,12 +1115,29 @@ export class Engine {
1106
1115
  // assistant message that produced it. Stripped at the wire by
1107
1116
  // stripMetaForWire — pure bookkeeping for priorPlan continuity.
1108
1117
  if (vpPersona && vpPersona.vpId) {
1118
+ // PR-I: when the dispatcher hands us a per-VP plan whose vpId matches
1119
+ // the active persona, persist its `forwardQuery`, `preselect`, and
1120
+ // `thinking` on the assistant message so the next turn's
1121
+ // priorPlan continuity (DESIGN.md §9.15) sees the live router's
1122
+ // decision — not a synthetic stub.
1123
+ const planForThisVp = (vpPlan && typeof vpPlan === 'object'
1124
+ && typeof vpPlan.vpId === 'string' && vpPlan.vpId === vpPersona.vpId)
1125
+ ? vpPlan
1126
+ : null;
1109
1127
  attachRouterPlan(assistantMsg, {
1110
1128
  vpId: vpPersona.vpId,
1111
- forwardQuery: { userOriginal: prompt || '', intent: '' },
1112
- preselect: undefined,
1113
- thinking: null,
1114
- thinkingReason: '',
1129
+ forwardQuery: planForThisVp && planForThisVp.forwardQuery
1130
+ ? planForThisVp.forwardQuery
1131
+ : { userOriginal: prompt || '', intent: '' },
1132
+ preselect: planForThisVp && planForThisVp.preselect
1133
+ ? planForThisVp.preselect
1134
+ : undefined,
1135
+ thinking: planForThisVp && (planForThisVp.thinking === 'high' || planForThisVp.thinking === 'max')
1136
+ ? planForThisVp.thinking
1137
+ : null,
1138
+ thinkingReason: planForThisVp && typeof planForThisVp.thinkingReason === 'string'
1139
+ ? planForThisVp.thinkingReason
1140
+ : '',
1115
1141
  });
1116
1142
  }
1117
1143
  conversationMessages.push(assistantMsg);
@@ -97,7 +97,7 @@ export class EngineInstance {
97
97
  * @param {AbortSignal} [params.signal]
98
98
  * @yields {object} EngineEvent with { ...event, threadId }
99
99
  */
100
- async *query({ prompt, mode, signal, vpPersona, router, senderVpId, inboundEnvelope, taskId, taskMembers, groupId } = {}) {
100
+ async *query({ prompt, mode, signal, vpPersona, router, senderVpId, inboundEnvelope, taskId, taskMembers, groupId, vpPlan } = {}) {
101
101
  if (this.#terminated) {
102
102
  yield {
103
103
  type: 'error',
@@ -173,7 +173,7 @@ export class EngineInstance {
173
173
  curToolResults = [];
174
174
  }
175
175
 
176
- for await (const event of this.#engine.query({ prompt, mode, messages: snapshot, signal, vpPersona, router, senderVpId, inboundEnvelope, taskId, taskMembers, groupId })) {
176
+ for await (const event of this.#engine.query({ prompt, mode, messages: snapshot, signal, vpPersona, router, senderVpId, inboundEnvelope, taskId, taskMembers, groupId, vpPlan })) {
177
177
  // Re-tag every event with the bound threadId. Non-object events
178
178
  // (shouldn't happen — all engine events are objects) are passed
179
179
  // through untouched.