Commit Graph

2404 Commits

Author SHA1 Message Date
YeonGyu-Kim
aad0c3644b fix(test): fix sync continuation test mock leaking across sessions
The messages() mock in 'session_id with background=false' test did not
filter by session ID, causing resolveParentContext's SDK calls for
parent-session to increment messagesCallCount. This inflated
anchorMessageCount to 4 (matching total messages), so the poll loop
could never detect new messages and always hit MAX_POLL_TIME_MS.

Fix: filter messages() mock by path.id so only target session
(ses_continue_test) increments the counter. Restore MAX_POLL_TIME_MS
from 8000 back to 2000.
2026-02-16 16:13:40 +09:00
YeonGyu-Kim
96a67e2d4e fix(test): increase timeouts for CI-flaky polling tests
- runner.test.ts: waitForEventProcessorShutdown timeout 50ms → 500ms
  (50ms was consistently too tight for CI runners)
- tools.test.ts: MAX_POLL_TIME_MS 2000ms → 8000ms
  (polling timed out at ~2009ms on CI due to resource contention)
2026-02-16 16:13:40 +09:00
YeonGyu-Kim
11586445cf fix: make sessionExists() async with SDK verification on SQLite
sessionExists() previously returned unconditional true on SQLite,
preventing ralph-loop orphaned-session cleanup from triggering.
Now uses sdkClient.session.messages() to verify session actually
exists. Callers updated to await the async result.

Addresses Cubic review feedback on PR #1837.
2026-02-16 16:13:40 +09:00
YeonGyu-Kim
3bbe0cbb1d feat: implement SDK/HTTP pruning for deduplication and tool-output truncation on SQLite
- executeDeduplication: now async, reads messages from SDK on SQLite via
  client.session.messages() instead of JSON file reads
- truncateToolOutputsByCallId: now async, uses truncateToolResultAsync()
  HTTP PATCH on SQLite instead of file-based truncateToolResult()
- deduplication-recovery: passes client through to both functions
- recovery-hook: passes ctx.client to attemptDeduplicationRecovery

Removes the last intentional feature gap on SQLite backend — dynamic
context pruning (dedup + tool-output truncation) now works on both
JSON and SQLite storage backends.
2026-02-16 16:13:40 +09:00
YeonGyu-Kim
a25b35c380 fix: make sessionExists() SQLite-aware for session_read tool
sessionExists() relied on JSON message directories which don't exist on
SQLite. Return true on SQLite and let readSessionMessages() handle lookup.
Also add empty-messages fallback in session_read for graceful not-found.
2026-02-16 16:13:40 +09:00
YeonGyu-Kim
52161ef69f fix: add SDK readParts fallback for recoverToolResultMissing on SQLite
On SQLite backend, readParts() returns [] since JSON files don't exist.
Add isSqliteBackend() branch that reads parts from SDK via
client.session.messages() when failedAssistantMsg.parts is empty.
2026-02-16 16:13:40 +09:00
YeonGyu-Kim
62e4e57455 feat: wire context-window-recovery callers to async SDK/HTTP variants on SQLite
- empty-content-recovery: isSqliteBackend() branch delegating to extracted
  empty-content-recovery-sdk.ts with SDK message scanning
- message-builder: sanitizeEmptyMessagesBeforeSummarize now async with SDK path
  using replaceEmptyTextPartsAsync/injectTextPartAsync
- target-token-truncation: truncateUntilTargetTokens now async with SDK path
  using findToolResultsBySizeFromSDK/truncateToolResultAsync
- aggressive-truncation-strategy: passes client to truncateUntilTargetTokens
- summarize-retry-strategy: await sanitizeEmptyMessagesBeforeSummarize
- client.ts: derive Client from PluginInput['client'] instead of manual defs
- executor.test.ts: .mockReturnValue() → .mockResolvedValue() for async fns
- storage.test.ts: add await for async truncateUntilTargetTokens
2026-02-16 16:13:40 +09:00
YeonGyu-Kim
dff3a551d8 feat: wire session-recovery callers to async SDK/HTTP variants on SQLite
- recover-thinking-disabled-violation: isSqliteBackend() branch using
  stripThinkingPartsAsync() with SDK message enumeration
- recover-thinking-block-order: isSqliteBackend() branch using
  prependThinkingPartAsync() with SDK orphan thinking detection
- recover-empty-content-message: isSqliteBackend() branch delegating to
  extracted recover-empty-content-message-sdk.ts (200 LOC limit)
- storage.ts barrel: add async variant exports for all SDK functions
2026-02-16 16:13:40 +09:00
YeonGyu-Kim
0a085adcd6 fix(test): rewrite SDK reader tests to use mock client objects instead of mock.module 2026-02-16 16:13:40 +09:00
YeonGyu-Kim
291a3edc71 feat: migrate tool callers to SDK message finders on SQLite backend 2026-02-16 16:13:40 +09:00
YeonGyu-Kim
553817c1a0 feat: migrate call-omo-agent tool callers to SDK message finders 2026-02-16 16:13:40 +09:00
YeonGyu-Kim
2bf8b15f24 feat: migrate hook callers to SDK message finders on SQLite backend 2026-02-16 16:13:40 +09:00
YeonGyu-Kim
af8de2eaa2 feat: add SDK read paths for session-recovery parts/messages readers 2026-02-16 16:13:40 +09:00
YeonGyu-Kim
1197f919af feat: add SDK/HTTP paths for tool-result-storage truncation 2026-02-16 16:13:40 +09:00
YeonGyu-Kim
808de5836d feat: implement SQLite backend for replaceEmptyTextParts via HTTP PATCH 2026-02-16 16:13:40 +09:00
YeonGyu-Kim
f69820e76e feat: implement SQLite backend for prependThinkingPart via HTTP PATCH 2026-02-16 16:13:40 +09:00
YeonGyu-Kim
c771eb5acd feat: implement SQLite backend for injectTextPart via HTTP PATCH 2026-02-16 16:13:40 +09:00
YeonGyu-Kim
049a259332 feat: implement SQLite backend for stripThinkingParts via HTTP DELETE 2026-02-16 16:13:40 +09:00
YeonGyu-Kim
3fe0e0c7ae docs: clarify injectHookMessage degradation log on SQLite backend 2026-02-16 16:13:40 +09:00
YeonGyu-Kim
d414f6daba fix: add explicit isSqliteBackend guards to pruning modules 2026-02-16 16:13:40 +09:00
YeonGyu-Kim
0c6fe3873c feat: add SDK path for getMessageIds in context-window recovery 2026-02-16 16:13:40 +09:00
YeonGyu-Kim
450a5bf954 feat: add opencode HTTP API helpers for part PATCH/DELETE 2026-02-16 16:13:40 +09:00
YeonGyu-Kim
7727e51e5a fix(test): eliminate mock.module pollution between shared test files
Rewrite opencode-message-dir.test.ts to use real temp directories instead
of mocking node:fs/node:path. Rewrite opencode-storage-detection.test.ts
to inline isSqliteBackend logic, avoiding cross-file mock pollution.

Resolves all 195 bun test failures (195 → 0). Full suite: 2707 pass.
2026-02-16 16:13:40 +09:00
YeonGyu-Kim
2a7535bb48 fix(test): mock isSqliteBackend in prometheus-md-only tests for SQLite environments
On machines running OpenCode beta (v1.1.53+) with SQLite backend,
getMessageDir() returns null because isSqliteBackend() returns true.
This caused all 15 message-storage-dependent tests to fail.

Fix: mock opencode-storage-detection to force JSON mode, and use
ses_ prefixed session IDs to match getMessageDir's validation.
2026-02-16 16:13:40 +09:00
YeonGyu-Kim
4cf3bc431b refactor(shared): unify MESSAGE_STORAGE/PART_STORAGE constants into single source
- Create src/shared/opencode-storage-paths.ts with all 4 constants
- Update 4 previous declaration sites to import from shared file
- Update additional OPENCODE_STORAGE usages for consistency
- Re-export from src/shared/index.ts
- No duplicate constant declarations remain
2026-02-16 16:13:40 +09:00
YeonGyu-Kim
068831f79e refactor: cleanup shared constants and add async SDK support for isCallerOrchestrator
- Use shared OPENCODE_STORAGE, MESSAGE_STORAGE, PART_STORAGE constants
- Make isCallerOrchestrator async with SDK fallback for beta
- Fix cache implementation using Symbol sentinel
- Update atlas hooks and sisyphus-junior-notepad to use async isCallerOrchestrator
2026-02-16 16:13:40 +09:00
YeonGyu-Kim
1bb5a3a037 fix: prefer id matching when deleting todos (Cubic feedback)
- When deleting tasks, prefer matching by id if present

- Fall back to content matching only when todo has no id

- Prevents deleting unrelated todos with same subject
2026-02-16 16:13:40 +09:00
YeonGyu-Kim
02e0534615 fix: handle deleted tasks in todo-sync (Cubic feedback)
- When task is deleted (syncTaskToTodo returns null), filter by content

- Prevents stale todos from remaining after task deletion
2026-02-16 16:13:40 +09:00
YeonGyu-Kim
4b2410d0a2 fix: address remaining Cubic review comments (P2 issues)
- Add content-based fallback matching for todos without ids

- Add TODO comment for exported but unused SDK functions

- Add resetStorageClient() for test isolation

- Fixes todo duplication risk on beta (SQLite backend)
2026-02-16 16:13:40 +09:00
YeonGyu-Kim
07da116671 fix: address Cubic review comments (P2/P3 issues)
- Fix empty catch block in opencode-message-dir.ts (P2)

- Add log deduplication for truncateToolResult to prevent spam (P3)
2026-02-16 16:13:40 +09:00
YeonGyu-Kim
49dafd3c91 feat(storage): gate JSON write operations on OpenCode beta, document degraded features
- Gate session-recovery writes: injectTextPart, prependThinkingPart, replaceEmptyTextParts, stripThinkingParts

- Gate context-window-recovery writes: truncateToolResult

- Add isSqliteBackend() checks with log warnings

- Create beta-degraded-features.md documentation
2026-02-16 16:13:40 +09:00
YeonGyu-Kim
e34fbd08a9 feat(context-window-recovery): gate JSON writes on OpenCode beta 2026-02-16 16:13:40 +09:00
YeonGyu-Kim
b0944b7fd1 feat(session-manager): add version-gated SDK read path for OpenCode beta
- Add SDK client injection via setStorageClient()

- Version-gate getMainSessions(), getAllSessions(), readSessionMessages(), readSessionTodos()

- Add comprehensive tests for SDK path (beta mode)

- Maintain backward compatibility with JSON fallback
2026-02-16 16:13:40 +09:00
YeonGyu-Kim
5eebef953b refactor(shared): unify MESSAGE_STORAGE/PART_STORAGE constants into single source
- Add src/shared/opencode-storage-paths.ts with consolidated constants

- Update imports in hook-message-injector and session-manager

- Add src/shared/opencode-storage-detection.ts with isSqliteBackend()

- Add OPENCODE_SQLITE_VERSION constant

- Export all from shared/index.ts
2026-02-16 16:13:40 +09:00
YeonGyu-Kim
c9c02e0525 refactor(shared): consolidate 13+ getMessageDir copies into single shared function 2026-02-16 16:13:39 +09:00
YeonGyu-Kim
e90734d6d9 fix(todo): make Todo id field optional for OpenCode beta compatibility
- Make id field optional in all Todo interfaces (TodoInfo, Todo, TodoItem)
- Fix null-unsafe comparisons in todo-sync.ts to handle missing ids
- Add test case for todos without id field preservation
- All tests pass and typecheck clean
2026-02-16 16:13:39 +09:00
YeonGyu-Kim
cb4a165c76 Merge pull request #1882 from code-yeongyu/fix/resume-completion-timer-cleanup
fix: cancel completion timer on resume and prevent silent notification drop
2026-02-16 16:09:02 +09:00
YeonGyu-Kim
d3574a392f fix: cancel completion timer on resume and prevent silent notification drop 2026-02-16 16:06:36 +09:00
YeonGyu-Kim
0ef682965f fix: detect interrupted/error/cancelled status in unstable-agent-task polling loop
The polling loop in executeUnstableAgentTask only checked session status
and message stability, never checking if the background task itself had
been interrupted. This caused the tool call to hang until MAX_POLL_TIME_MS
(10 minutes) when a task was interrupted by prompt errors.

Add manager.getTask() check at each poll iteration to break immediately
on terminal statuses (interrupt, error, cancelled), returning a clear
failure message instead of hanging.
2026-02-16 15:56:52 +09:00
YeonGyu-Kim
dd11d5df1b refactor: compress plan template while recovering lost specificity guidelines
Reduce plan-template from 541 to 335 lines by removing redundant verbose
examples while recovering 3 lost context items: tool-type mapping table in
QA Policy, scenario specificity requirements (selectors/data/assertions/
timing/negative) in TODO template, and structured output format hints for
each Final Verification agent.
2026-02-16 15:46:00 +09:00
YeonGyu-Kim
130aaaf910 enhance: enforce mandatory per-task QA scenarios and add Final Verification Wave
Strengthen TODO template to make QA scenarios non-optional with explicit
rejection warning. Add Final Verification Wave with 4 parallel review
agents: oracle (plan compliance audit), unspecified-high (code quality),
unspecified-high (real manual QA), deep (scope fidelity check) — each
with detailed verification steps and structured output format.
2026-02-16 15:46:00 +09:00
YeonGyu-Kim
7e6982c8d8 Merge pull request #1878 from code-yeongyu/fix/1806-todo-enforcer-cooldown
fix: apply cooldown on injection failure and add max retry limit (#1806)
2026-02-16 15:42:24 +09:00
YeonGyu-Kim
2a4009e692 fix: add post-max-failure recovery window for todo continuation 2026-02-16 15:27:00 +09:00
YeonGyu-Kim
2b7ef43619 Merge pull request #1879 from code-yeongyu/fix/cli-installer-provider-config-1876
fix: run auth plugins and provider config for all providers, not just gemini
2026-02-16 15:26:55 +09:00
YeonGyu-Kim
5c9ef7bb1c fix: run auth plugins and provider config for all providers, not just gemini
Closes #1876
2026-02-16 15:23:22 +09:00
YeonGyu-Kim
67efe2d7af test: verify provider setup runs for openai/copilot without gemini 2026-02-16 15:23:22 +09:00
YeonGyu-Kim
abfab1a78a enhance: calibrate Prometheus plan granularity to 5-8 parallel tasks per wave
Add Maximum Parallelism Principle as a top-level constraint and replace
small-scale plan template examples (6 tasks, 3 waves) with production-scale
examples (24 tasks, 4 waves, max 7 concurrent) to steer the model toward
generating fine-grained, dependency-minimized plans by default.
2026-02-16 15:14:25 +09:00
YeonGyu-Kim
24ea3627ad Merge pull request #1877 from code-yeongyu/fix/1752-compaction-race
fix: cancel pending compaction timer on session.idle and add error logging (#1752)
2026-02-16 15:11:30 +09:00
YeonGyu-Kim
c2f22cd6e5 fix: apply cooldown on injection failure and cap retries 2026-02-16 15:00:41 +09:00
YeonGyu-Kim
6a90182503 fix: prevent duplicate compaction race and log preemptive failures 2026-02-16 14:58:59 +09:00