diff --git a/graph-renderer.js b/graph-renderer.js index c8b6a9b..6754398 100644 --- a/graph-renderer.js +++ b/graph-renderer.js @@ -55,12 +55,23 @@ function layoutKeysFromForceConfig(fc) { } function roundRectPath(ctx, x, y, w, h, r) { - const radius = Math.min(r, w / 2, h / 2); + const W = Math.max(0, Number(w) || 0); + const H = Math.max(0, Number(h) || 0); + const rr = Math.max(0, Number(r) || 0); + const radius = Math.min(rr, W / 2, H / 2); + if (W < 1 || H < 1) { + ctx.rect(x, y, Math.max(1, W), Math.max(1, H)); + return; + } + if (radius < 1e-6) { + ctx.rect(x, y, W, H); + return; + } ctx.moveTo(x + radius, y); - ctx.arcTo(x + w, y, x + w, y + h, radius); - ctx.arcTo(x + w, y + h, x, y + h, radius); - ctx.arcTo(x, y + h, x, y, radius); - ctx.arcTo(x, y, x + w, y, radius); + ctx.arcTo(x + W, y, x + W, y + H, radius); + ctx.arcTo(x + W, y + H, x, y + H, radius); + ctx.arcTo(x, y + H, x, y, radius); + ctx.arcTo(x, y, x + W, y, radius); ctx.closePath(); } @@ -272,8 +283,11 @@ export class GraphRenderer { const objectivePanel = { x: pad, y: pad + 6, - w: (hasRight ? splitX : W) - pad * 2 - (hasRight ? gutter / 2 : 0), - h: H - pad * 2 - 6, + w: Math.max( + 0, + (hasRight ? splitX : W) - pad * 2 - (hasRight ? gutter / 2 : 0), + ), + h: Math.max(0, H - pad * 2 - 6), label: '客观层', tint: 'rgba(26, 35, 50, 0.42)', key: 'objective', @@ -283,15 +297,15 @@ export class GraphRenderer { const innerObjective = { x: objectivePanel.x + 10, y: objectivePanel.y + topPad, - w: objectivePanel.w - 20, - h: objectivePanel.h - topPad - 10, + w: Math.max(1, objectivePanel.w - 20), + h: Math.max(1, objectivePanel.h - topPad - 10), }; for (const n of objective) n.regionRect = innerObjective; if (!hasRight) return panels; const rightX = splitX + gutter / 2; - const rightW = W - pad - rightX; + const rightW = Math.max(0, W - pad - rightX); const yBottom = H - pad; let yTop = pad + 6; @@ -315,8 +329,8 @@ export class GraphRenderer { const innerU = { x: rightX + 10, y: yTop + topPad, - w: rightW - 20, - h: fullH - topPad - 8, + w: Math.max(1, rightW - 20), + h: Math.max(1, fullH - topPad - 8), }; for (const n of userPov) n.regionRect = innerU; return panels; @@ -349,8 +363,8 @@ export class GraphRenderer { const inner = { x: rightX + 10, y: yc + topPad, - w: rightW - 20, - h: ph - topPad - 8, + w: Math.max(1, rightW - 20), + h: Math.max(1, ph - topPad - 8), }; for (const n of arr) n.regionRect = inner; yc += ph + gap; @@ -370,8 +384,8 @@ export class GraphRenderer { const innerU = { x: rightX + 10, y: uy + topPad, - w: rightW - 20, - h: userStripH - topPad - 8, + w: Math.max(1, rightW - 20), + h: Math.max(1, userStripH - topPad - 8), }; for (const n of userPov) n.regionRect = innerU; } @@ -536,8 +550,11 @@ export class GraphRenderer { _drawRegionPanels(ctx) { for (const p of this._regionPanels) { + const pw = Number(p.w) || 0; + const ph = Number(p.h) || 0; + if (pw < 2 || ph < 2) continue; ctx.beginPath(); - roundRectPath(ctx, p.x, p.y, p.w, p.h, 12); + roundRectPath(ctx, p.x, p.y, pw, ph, 12); ctx.fillStyle = p.tint; ctx.fill(); ctx.strokeStyle = 'rgba(87, 199, 255, 0.12)'; diff --git a/index.js b/index.js index 88ad621..87849ce 100644 --- a/index.js +++ b/index.js @@ -1791,6 +1791,9 @@ function ensurePersistedRecallRecordForGeneration({ }, ); + // #region agent log + {fetch('http://127.0.0.1:7433/ingest/799bfe5d-077f-41ac-bcda-da9f93fe5a85',{method:'POST',headers:{'Content-Type':'application/json','X-Debug-Session-Id':'b6ba57'},body:JSON.stringify({sessionId:'b6ba57',location:'index.js:ensurePersistedRecallRecordForGeneration',message:'target resolved',data:{targetUserMessageIndex,chatLen:chat.length,isUser:chat[targetUserMessageIndex]?.is_user,generationType,hookName:String(hookName||''),injectionTextLen:injectionText?.length||0},timestamp:Date.now()})}).catch(()=>{});} + // #endregion if ( !Number.isFinite(targetUserMessageIndex) || !chat[targetUserMessageIndex]?.is_user @@ -2547,6 +2550,9 @@ function refreshPersistedRecallMessageUi() { skippedNonUserIndices: [], }; + // #region agent log + {const _latestUserIdx=chat.reduce((a,m,i)=>m?.is_user?i:a,-1);const _domKeys=[...messageElementMap.keys()];const _hasRecord=_latestUserIdx>=0&&!!readPersistedRecallFromUserMessage(chat,_latestUserIdx);const _hasDom=_latestUserIdx>=0&&messageElementMap.has(_latestUserIdx);fetch('http://127.0.0.1:7433/ingest/799bfe5d-077f-41ac-bcda-da9f93fe5a85',{method:'POST',headers:{'Content-Type':'application/json','X-Debug-Session-Id':'b6ba57'},body:JSON.stringify({sessionId:'b6ba57',location:'index.js:refreshPersistedRecallMessageUi:loop-start',message:'refresh loop entry',data:{chatLen:chat.length,domElementCount:_domKeys.length,domKeys:_domKeys.slice(-6),latestUserIdx:_latestUserIdx,hasRecordForLatest:_hasRecord,hasDomForLatest:_hasDom},timestamp:Date.now()})}).catch(()=>{});} + // #endregion for (let messageIndex = 0; messageIndex < chat.length; messageIndex++) { const message = chat[messageIndex]; const messageElement = messageElementMap.get(messageIndex) || null; @@ -2578,6 +2584,9 @@ function refreshPersistedRecallMessageUi() { } const record = readPersistedRecallFromUserMessage(chat, messageIndex); + // #region agent log + if(message?.is_user){const _isLatestUser=messageIndex===chat.reduce((a,m,i)=>m?.is_user?i:a,-1);if(_isLatestUser){fetch('http://127.0.0.1:7433/ingest/799bfe5d-077f-41ac-bcda-da9f93fe5a85',{method:'POST',headers:{'Content-Type':'application/json','X-Debug-Session-Id':'b6ba57'},body:JSON.stringify({sessionId:'b6ba57',location:'index.js:refreshPersistedRecallMessageUi:latest-user-check',message:'latest user msg detail',data:{messageIndex,hasRecord:!!record?.injectionText,hasDom:!!messageElement,hasExistingCard:!!existingCard,domMesid:messageElement?.getAttribute?.('mesid'),domDataMesid:messageElement?.getAttribute?.('data-mesid'),domClasses:messageElement?.className?.slice(0,80)||''},timestamp:Date.now()})}).catch(()=>{});}} + // #endregion if (!record?.injectionText) { if (messageElement) { restoreRecallCardUserInputDisplay(messageElement); @@ -2645,6 +2654,9 @@ function refreshPersistedRecallMessageUi() { recallCardUserInputDisplayMode, ); summary.renderedCount += 1; + // #region agent log + {const _isLatestUser2=messageIndex===chat.reduce((a,m,i)=>m?.is_user?i:a,-1);if(_isLatestUser2){fetch('http://127.0.0.1:7433/ingest/799bfe5d-077f-41ac-bcda-da9f93fe5a85',{method:'POST',headers:{'Content-Type':'application/json','X-Debug-Session-Id':'b6ba57'},body:JSON.stringify({sessionId:'b6ba57',location:'index.js:refreshPersistedRecallMessageUi:card-mounted',message:'card mounted for latest user',data:{messageIndex,hadExistingCard:!!currentCard,cardInDom:!!messageElement.querySelector('.bme-recall-card')},timestamp:Date.now()})}).catch(()=>{});}} + // #endregion } summary.status = summarizePersistedRecallRefreshStatus(summary); @@ -2661,6 +2673,9 @@ function refreshPersistedRecallMessageUi() { `rendered:${summary.renderedCount}`, ); } + // #region agent log + fetch('http://127.0.0.1:7433/ingest/799bfe5d-077f-41ac-bcda-da9f93fe5a85',{method:'POST',headers:{'Content-Type':'application/json','X-Debug-Session-Id':'b6ba57'},body:JSON.stringify({sessionId:'b6ba57',location:'index.js:refreshPersistedRecallMessageUi:summary',message:'refresh complete',data:{status:summary.status,renderedCount:summary.renderedCount,persistedRecordCount:summary.persistedRecordCount,waitingDom:summary.waitingMessageIndices,anchorFail:summary.anchorFailureIndices},timestamp:Date.now()})}).catch(()=>{}); + // #endregion return summary; } @@ -2752,6 +2767,9 @@ function armPersistedRecallMessageUiObserver(sessionId, runAttempt) { } function schedulePersistedRecallMessageUiRefresh(delayMs = 0) { + // #region agent log + {const _prevSession=persistedRecallUiRefreshSession;const _caller=new Error().stack?.split('\n')?.[2]?.trim()?.slice(0,120)||'';fetch('http://127.0.0.1:7433/ingest/799bfe5d-077f-41ac-bcda-da9f93fe5a85',{method:'POST',headers:{'Content-Type':'application/json','X-Debug-Session-Id':'b6ba57'},body:JSON.stringify({sessionId:'b6ba57',location:'index.js:schedulePersistedRecallMessageUiRefresh',message:'schedule called',data:{delayMs,prevSession:_prevSession,nextSession:_prevSession+1,caller:_caller},timestamp:Date.now()})}).catch(()=>{});} + // #endregion clearTimeout(persistedRecallUiRefreshTimer); clearPersistedRecallMessageUiObserver();