@yeaft/webchat-agent 0.1.603 → 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 +1 -1
- package/unify/engine.js +42 -14
- package/unify/threads/engine-instance.js +2 -2
package/package.json
CHANGED
package/unify/engine.js
CHANGED
|
@@ -537,11 +537,13 @@ export class Engine {
|
|
|
537
537
|
const budget = this.#config.messageTokenBudget || 8192;
|
|
538
538
|
const compactCfg = (this.#config && this.#config.compact) || {};
|
|
539
539
|
|
|
540
|
-
// Phase 8 PR-
|
|
541
|
-
//
|
|
542
|
-
//
|
|
543
|
-
//
|
|
544
|
-
|
|
540
|
+
// Phase 8 PR-H: orchestrator is now the default. The legacy
|
|
541
|
+
// shouldConsolidate / consolidate path remains reachable as an
|
|
542
|
+
// explicit fallback via `config.compact.useLegacy=true` for parity
|
|
543
|
+
// testing during migration. evaluateCompactTriggers (DESIGN §4.1)
|
|
544
|
+
// and runCompact (DESIGN §4.2) own the live path.
|
|
545
|
+
const useLegacy = compactCfg.useLegacy === true || compactCfg.useOrchestrator === false;
|
|
546
|
+
if (!useLegacy) {
|
|
545
547
|
return this.#runOrchestratorCompact(budget, compactCfg);
|
|
546
548
|
}
|
|
547
549
|
|
|
@@ -711,7 +713,7 @@ export class Engine {
|
|
|
711
713
|
* SCENARIO_EFFORT. Unknown values fall through to 'high'.
|
|
712
714
|
* @yields {EngineEvent}
|
|
713
715
|
*/
|
|
714
|
-
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 } = {}) {
|
|
715
717
|
if (!prompt || typeof prompt !== 'string' || !prompt.trim()) {
|
|
716
718
|
yield {
|
|
717
719
|
type: 'error',
|
|
@@ -762,7 +764,7 @@ export class Engine {
|
|
|
762
764
|
const runSignal = abortCtrl.signal;
|
|
763
765
|
|
|
764
766
|
try {
|
|
765
|
-
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 });
|
|
766
768
|
} finally {
|
|
767
769
|
if (signal) {
|
|
768
770
|
try { signal.removeEventListener('abort', onExternalAbort); } catch { /* ignore */ }
|
|
@@ -780,7 +782,7 @@ export class Engine {
|
|
|
780
782
|
* in a try/finally without indenting the whole loop.
|
|
781
783
|
* @private
|
|
782
784
|
*/
|
|
783
|
-
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 }) {
|
|
784
786
|
|
|
785
787
|
// ─── Pre-query: Memory Injection (task-287) + Compact Summary ──
|
|
786
788
|
// Two-layer recall:
|
|
@@ -900,10 +902,19 @@ export class Engine {
|
|
|
900
902
|
if (vpPersona && vpPersona.vpId) {
|
|
901
903
|
const priorPlan = extractPriorPlan(conversationMessages, vpPersona.vpId);
|
|
902
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;
|
|
903
915
|
const resolved = resolveThinking({
|
|
904
916
|
uiOverride: (userEffort === 'max' || userEffort === 'high') ? userEffort : null,
|
|
905
|
-
routerPlan:
|
|
906
|
-
// live router-plan thinking is a follow-up.
|
|
917
|
+
routerPlan: liveRouterThinking,
|
|
907
918
|
priorPlan: priorPlan && priorPlan.thinking ? priorPlan.thinking : null,
|
|
908
919
|
vpDefault: typeof vpPersona.thinking === 'string' ? vpPersona.thinking : null,
|
|
909
920
|
globalDefault: typeof thinkingCfg.default === 'string' ? thinkingCfg.default : null,
|
|
@@ -1104,12 +1115,29 @@ export class Engine {
|
|
|
1104
1115
|
// assistant message that produced it. Stripped at the wire by
|
|
1105
1116
|
// stripMetaForWire — pure bookkeeping for priorPlan continuity.
|
|
1106
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;
|
|
1107
1127
|
attachRouterPlan(assistantMsg, {
|
|
1108
1128
|
vpId: vpPersona.vpId,
|
|
1109
|
-
forwardQuery:
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
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
|
+
: '',
|
|
1113
1141
|
});
|
|
1114
1142
|
}
|
|
1115
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.
|