From 300338d5d3257969d62dcd44a1bc1cbc7b2aea5a Mon Sep 17 00:00:00 2001 From: Variet Worker Date: Fri, 10 Apr 2026 16:52:12 +0900 Subject: [PATCH] fix(extension): bypass 10-item limit of GetAllCascadeTrajectories by utilizing GetDiagnostics --- .agents/references/known-issues.md | 5 ++++ docs/devlog/2026-04-10.md | 1 + docs/devlog/entries/20260410-005.md | 14 ++++++++++ extension/src/http-bridge.ts | 16 +++++++++++ extension/src/step-probe.ts | 42 ++++++++++++++++++++++++++--- 5 files changed, 74 insertions(+), 4 deletions(-) create mode 100644 docs/devlog/entries/20260410-005.md diff --git a/.agents/references/known-issues.md b/.agents/references/known-issues.md index d55d916..cee9256 100644 --- a/.agents/references/known-issues.md +++ b/.agents/references/known-issues.md @@ -224,3 +224,8 @@ - **원인**: ot.py의 chat_snapshot_scanner에서 파일을 순회 파싱할 때 내부의 .unlink() 과정에서 발생하는 예외나 discord.Embed 생성 예외 등을 루프 안에서 잡아주지 못함. 첫 에러 파일(poison pill)을 만나는 순간 루프 전체가 폭파되어 뒤쪽의 정상 파일들도 영원히 처리되지 않고 다음 폴 스케줄에서 다시 첫 파일에 막힘. - **해결**: 루프 내부에 except Exception을 추가하여 전역 예외를 잡아 방어. 실패한 파일은 glob에서 반복 시도되지 않게 .json.failed로 우회(rename)시켜 큐를 비워줌. - **주의**: 폴링/스캐너 or 루프 내부에서는 개별 아이템 파싱 단계에서 발생 가능한 모든 예외 상태에 대한 Defensive Catch 및 Continue(우회) 로직이 필수임. +### [2026-04-10] [Extension] GetAllCascadeTrajectories 10-Item Hard Limit Bypass (Signal Drop) +- ****: ۼߴ { limit: 30 } ĶͰ LS 鿣忡 õǾ ֽ 10 ѿ ɷ ߷. (Discord ޽ ڵ Ѿ). +- ****: GetAllCascadeTrajectories pagination ɼ ϰų 10 ɸ. +- **ذ**: step-probe.ts ⺻ GetAllCascadeTrajectories Ҿ Ʈ丮 ϴ GetDiagnostics API ȣϰ Ͽ ֽ Session ID ġ ʰ ϰ . +- ****: LS Backend RPC Ѱ Argument ȸ Ƿ, GetDiagnostics 鵵 ͸ Ȱ . diff --git a/docs/devlog/2026-04-10.md b/docs/devlog/2026-04-10.md index b39e4ff..e97dff9 100644 --- a/docs/devlog/2026-04-10.md +++ b/docs/devlog/2026-04-10.md @@ -8,3 +8,4 @@ | 002 | 16:05 | Gravity Bridge 빠른 응답 누락 오류 해결 (IDLE-to-IDLE 패스 로직 완화) | TBD | ✅ || 003 | 16:12 | [Bridge] DOM Observer Ž (PATS Ȱȭ) ڵ ˸ | TBD | ? | | 004 | 16:31 | [Bot] chat_snapshot_scanner 미처리 예외 큐 막힘 현상 해결 및 Hermes Gateway 재시작 | TBD | ✅ | +| 005 | 16:50 | [Extension] GetAllCascadeTrajectories 10-Item Limit ȸ GetDiagnostics ȸ ġ | TBD | ? | diff --git a/docs/devlog/entries/20260410-005.md b/docs/devlog/entries/20260410-005.md new file mode 100644 index 0000000..481a5ab --- /dev/null +++ b/docs/devlog/entries/20260410-005.md @@ -0,0 +1,14 @@ +# GetAllCascadeTrajectories 10-Item Hard Limit Bypass + +- **시간**: 2026-04-10 +- **Commit**: TBD +- **Vikunja**: TBD + +## 결정 사항 +- `GetAllCascadeTrajectories` LS API의 `limit` 등 페이지네이션 파라미터가 백엔드에서 무시되어 최신 세션이 10개 제한에 잘려나가는 문제를 확인. +- `DOM observer`가 더 이상 작동하지 않는 상태(Empty 보디 이슈로 비활성화됨)에서, `step-probe.ts`마저 이 10개 한도 밖으로 밀려난 현재 세션(`activeSessionId`)을 발견하지 못해, 발생한 모든 채팅 이벤트 파일이 작성되지 않는 문제("단 한글자도 안 날아옴")의 근본 원인을 특정함. +- `GetDiagnostics` API를 사용하여 내부적으로 저장된 `recentTrajectories` 덤프 전체를 불러와, 기존 `GetAllCascadeTrajectories`의 결과를 병합/보완하도록 변경. +- 이를 통해 아무리 많은 수의 세션이 열려 있어도 현재 사용 중인 세션 ID를 식별 가능. + +## 미완료 +- 없음. diff --git a/extension/src/http-bridge.ts b/extension/src/http-bridge.ts index ee5e4f4..2f44aea 100644 --- a/extension/src/http-bridge.ts +++ b/extension/src/http-bridge.ts @@ -126,6 +126,22 @@ export function startHttpBridge(ctx: HttpBridgeContext, sdk: any): Promise rpcBody += c); + req.on('end', async () => { + try { + const params = JSON.parse(rpcBody); + const result = await sdk.ls.rawRPC(params.method, params.args || {}); + res.writeHead(200, {'Content-Type': 'application/json'}); + res.end(typeof result === 'string' ? result : JSON.stringify(result)); + } catch(e: any) { + res.writeHead(500); res.end(e.message); + } + }); + return; + } + // GET /ping — health check if (url.pathname === '/ping') { res.writeHead(200); res.end('pong'); diff --git a/extension/src/step-probe.ts b/extension/src/step-probe.ts index 65ce960..5050f51 100644 --- a/extension/src/step-probe.ts +++ b/extension/src/step-probe.ts @@ -208,10 +208,44 @@ function setupMonitor() { ctx.logToFile(`[POLL#${pollCount}] alive`); } try { - // Fix (v0.5.14): Reverted 100-limit DoS but restored descending: true with a safe limit of 30 - const allTraj = await ctx.sdk.ls.rawRPC('GetAllCascadeTrajectories', { limit: 30, descending: true }); - if (!allTraj?.trajectorySummaries) { - if (pollCount <= 3) ctx.logToFile('[POLL] no trajectorySummaries'); + // Fix (v0.5.15): Bypass 10-Item Hard Limit of GetAllCascadeTrajectories. + // We fetch GetDiagnostics to discover ALL recent sessions regardless of pagination. + let allTraj: any = { trajectorySummaries: {} }; + try { + // Primary: Try fetching 100 trajectories (backend might ignore this and give 10) + const apiResult = await ctx.sdk.ls.rawRPC('GetAllCascadeTrajectories', { limit: 100, maxResults: 100, pageSize: 100, page_size: 100, descending: true }); + if (apiResult?.trajectorySummaries) { + allTraj.trajectorySummaries = { ...apiResult.trajectorySummaries }; + } + } catch (e: any) { + if (pollCount <= 3) ctx.logToFile(`[POLL] GetAllCascadeTrajectories failed: ${e.message}`); + } + + try { + // Fallback / Augment: GetDiagnostics provides ALL recent sessions bypassing the hard limit + const diagRaw = await ctx.sdk.ls.rawRPC('GetDiagnostics', {}); + const diag = typeof diagRaw === 'string' ? JSON.parse(diagRaw) : diagRaw; + const recent = diag.recentTrajectories || []; + for (const entry of recent) { + const sid = entry.googleAgentId; + if (sid && !allTraj.trajectorySummaries[sid]) { + allTraj.trajectorySummaries[sid] = { + status: entry.status || '', + stepCount: entry.lastStepIndex || 0, + lastModifiedTime: entry.lastModifiedTime || '', + summary: entry.summary || 'Untitled', + trajectoryMetadata: entry.trajectoryMetadata || { + workspaces: [{ workspaceFolderAbsoluteUri: entry.workspaceUri || '' }] + } + }; + } + } + } catch (e: any) { + if (pollCount <= 3) ctx.logToFile(`[POLL] GetDiagnostics fallback failed: ${e.message}`); + } + + if (!allTraj?.trajectorySummaries || Object.keys(allTraj.trajectorySummaries).length === 0) { + if (pollCount <= 3) ctx.logToFile('[POLL] no trajectorySummaries found from any source'); return; }