Commit Graph

42 Commits

Author SHA1 Message Date
Eyejoker
3d36e15f67 Fix recurring Codex unavailable in paired rooms (#212)
* fix: avoid codex leases for claude readonly sessions

* fix: restore codex lease quality budget

* fix: preserve owner finalization on codex failure

* fix: wake owner after arbiter codex failure

* chore: format readonly codex lease fix
2026-06-03 01:14:39 +08:00
ejclaw
5648b61075 fix: stop Codex pool retry loops 2026-06-02 05:30:04 +09:00
ejclaw
03d4c81192 fix: recover Codex rotation auth failures
- mark Codex bearer/refresh failures as terminal auth-expired states

- sync refreshed session auth back to rotation slots and revive refreshed dead_auth slots

- stop paired arbiter retry loops when Codex accounts are unavailable

- add regression coverage for rotation leases, follow-up suppression, and arbiter closure
2026-06-02 00:21:53 +09:00
Eyejoker
fb87e94c5a refactor: centralize EJClaw runtime env names (#192) 2026-05-29 22:00:15 +09:00
Eyejoker
5c8def0674 fix: pass room role to Codex MCP tools (#185) 2026-05-29 06:14:08 +09:00
Eyejoker
fd3145e2a7 feat: refresh dashboard settings UX and Codex feature toggles (#153)
* feat: refresh dashboard settings UX and Codex feature toggles

Improve settings/tasks mobile layout, model effort validation by agent type, and preset models for GPT 5.5 and Opus 4.7. Store Codex fast mode and goals in config.toml with Claude fastMode session sync and updated docs for Codex 0.133.

Co-authored-by: Cursor <cursoragent@cursor.com>

* style: apply pre-commit formatting after dashboard settings commit

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-23 12:18:42 +09:00
Eyejoker
0a8decde8c Apply room skill overrides to runner spawn 2026-05-04 16:13:24 +09:00
Eyejoker
7576bcd3ff Update agent SDKs and add gated Codex goals support (#114)
* add gated codex goals support

* sync README SDK versions

* bump claude agent sdk

* add codex goals settings toggle
2026-05-02 01:42:04 +09:00
ejclaw
4dcd4037f1 chore: clear low-risk lint warnings 2026-04-29 13:31:11 +09:00
ejclaw
e458382d3d runtime: canonicalize Claude token env names 2026-04-11 14:32:43 +09:00
ejclaw
4650abbd10 Rename readonly reviewer runtime remnants 2026-04-06 17:27:16 +09:00
ejclaw
994e957767 Enable unsafe host paired runtime 2026-04-06 02:40:15 +09:00
Eyejoker
e9c400424d Add reviewer host evidence and verification shims 2026-04-04 20:51:24 +09:00
Eyejoker
54abb5bb4e Apply formatter after local memory refactor 2026-04-04 03:52:28 +09:00
Eyejoker
3dd772c229 Refactor local memory and role-fixed runtime routing 2026-04-04 03:50:28 +09:00
Eyejoker
c76126bd58 refactor: replace Memento MCP with local memory 2026-03-31 23:22:50 +09:00
Eyejoker
509e4c24a3 refactor: cut over room mode from paired legacy 2026-03-31 14:47:59 +09:00
Eyejoker
4a5edaceb6 refactor: remove SERVICE_AGENT_TYPE legacy constant
SERVICE_AGENT_TYPE was always 'claude-code' in the unified service,
making it a misleading constant. Each group already has its own
agentType field.

- Removed SERVICE_AGENT_TYPE from config.ts
- Session functions now accept agentType parameter (default: 'claude-code')
- Task scheduler uses task-level agent_type for token rotation decisions
- All fallback defaults changed to 'claude-code' literal
- Logging uses 'unified' instead of the misleading type
2026-03-30 23:10:48 +09:00
Eyejoker
a043f2b79a feat: implement MAGI 3-agent arbiter system for deadlock resolution
Introduces a third agent role (arbiter) that is summoned on-demand
when owner and reviewer reach a deadlock (same verdict 3+ rounds).

Architecture:
- 3 Discord bots: owner (codex), reviewer (claude), arbiter (claude/codex)
- Arbiter is NOT always-on — only invoked when deadlock detected
- Arbiter renders binding verdict: PROCEED/REVISE/RESET/ESCALATE
- Non-escalate verdicts reset round_trip_count and resume ping-pong
- Backward compatible: ARBITER_AGENT_TYPE unset = existing 2-agent mode

Changes across 13 source files + 7 test files:
- types.ts: PairedRoomRole += 'arbiter', new statuses, ArbiterVerdict type
- config.ts: ARBITER_AGENT_TYPE, ARBITER_SERVICE_ID, ARBITER_DEADLOCK_THRESHOLD
- db.ts: schema migration (arbiter columns in channel_owner + paired_tasks)
- service-routing.ts: arbiter_service_id in lease
- room-role-context.ts: arbiter role detection
- paired-execution-context.ts: deadlock->arbiter, verdict handling
- message-runtime.ts: arbiter turn routing, cursor, sender labeling
- message-agent-executor.ts: arbiter mode, failover
- agent-runner.ts + environment.ts: arbiter container mode
- platform-prompts.ts: arbiter prompt loading

New files:
- prompts/arbiter-paired-room.md: arbiter system prompt
- src/arbiter-context.ts: builds conversation context for arbiter judgment
2026-03-30 22:20:42 +09:00
Eyejoker
8e9975aa2b fix: add log for container CLAUDE.md injection verification 2026-03-30 03:24:07 +09:00
Eyejoker
1031cd44dd refactor: SSOT for paired room prompts, remove 4 duplicate files
All reviewers (claude, codex-review, codex-review-failover) now use
claude-paired-room.md. All owners use owner-common-paired-room.md.

Removed: codex-paired-room.md, codex-review-paired-room.md,
codex-review-failover-paired-room.md, codex-review-platform.md

10 prompt files → 6.
2026-03-30 02:39:04 +09:00
Eyejoker
691be0dc86 refactor: streamline paired room prompts and fix role separation
Prompts:
- Remove model-specific names (클코, Codex) — use owner/reviewer only
- Compress duplicated sections (communication, stagnation, consensus)
  while preserving 4 ontological questions and verdict protocol intact
- Remove verdict examples (redundant with status descriptions)
- claude-platform.md: strip SDK defaults, keep only send_message rules

Code:
- Remove reviewer paired room prompt from owner CLAUDE.md
  (was causing role confusion — owner got "You are the reviewer")
- Remove "Provide feedback or approve" from review turn prompt
  (conflicted with CLAUDE.md verdict protocol)

187 lines → 100 lines across 4 prompt files.
2026-03-30 02:31:04 +09:00
Eyejoker
d024b763f0 fix: prepare CLAUDE.md and roomRoleContext for container reviewer
Container reviewer was running without prompts because the container
path in agent-runner.ts skipped prepareGroupEnvironment() entirely.
This meant no CLAUDE.md (platform + paired room prompts + memory
briefing) and no roomRoleContext were passed to the container.

- Add prepareContainerSessionEnvironment() to write CLAUDE.md, sync
  skills, and ensure settings.json for the reviewer session directory
- Pass roomRoleContext through ReviewerContainerInput so the runner
  can prepend the [ROOM_ROLE] header
- Add roomRoleContext field to ReviewerContainerInput interface
2026-03-30 01:12:47 +09:00
Eyejoker
3899271b9a fix: sync Codex skills to ~/.agents/skills/ instead of .codex/skills/
Codex CLI reads skills from ~/.agents/skills/ (user-level) and
{workDir}/.agents/skills/ (project-level), not from .codex/skills/.
Skills were being copied to the wrong path and never discovered.
2026-03-30 00:26:12 +09:00
Eyejoker
772fea45df refactor: share owner prompts and tighten silent output guidance 2026-03-28 07:46:13 +09:00
Eyejoker
e1fdc47552 style: sync pre-commit formatting fallout 2026-03-28 05:41:16 +09:00
Eyejoker
ba9f6871b6 feat: add codex review failover and suppress output hardening 2026-03-28 05:40:38 +09:00
Eyejoker
7b63ba859d fix: deduplicate CI watchers and remove task ID from watcher prompts
Prevent duplicate CI completion notifications in paired rooms by checking
for existing active watchers with the same channel+provider+metadata before
creating a new one. Remove Task ID from watcher prompt construction to
avoid router secret redaction (task- IDs contain sk- pattern), passing
EJCLAW_RUNTIME_TASK_ID via env var instead and making cancel_task
auto-resolve when task_id is omitted.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 20:57:59 +09:00
Eyejoker
5620301024 fix: pass EJCLAW_HOST_IPC_DIR to MCP server env for both runners
Watcher tasks get task-scoped IPC dirs (data/ipc/{group}/tasks/{taskId}/),
but the MCP server used HOST_IPC_DIR to write IPC files. Without
EJCLAW_HOST_IPC_DIR, it fell back to the task-scoped path, writing
cancel_task/send_message files to nested dirs the IPC watcher never scans.

This caused 11 zombie watchers stuck in infinite loops — self-cancel
calls silently failed with ~4000 stranded IPC files accumulating.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 21:05:22 +09:00
Eyejoker
00ffde7623 fix: remove Codex API key auth path, add secret redaction and d7 auto-rotation
- Remove OPENAI_API_KEY from .env and Codex child process env to prevent
  API billing when subscription quota is exhausted
- Remove writeCodexApiKeyAuth entirely — Codex now uses OAuth only
- Add 9-pattern secret redaction in formatOutbound() to prevent key leaks
- Fix Codex usage bucket aggregation: use 'codex' bucket only instead of
  max across all buckets (bengalfox = Codex Spark, not needed)
- Add d7≥100% auto-rotation in updateCodexAccountUsage to skip exhausted
  accounts and prevent API billing fallback
- Add findNextCodexAvailable that checks both rate-limits and d7 usage
- Clean stale apikey auth.json files from all session directories
- Update tests: OAuth-only auth, d7 auto-skip (3 new tests), dashboard

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 10:39:42 +09:00
Eyejoker
5ea3439c5f refactor: extract shared utilities, protocol constants, and retry loop
Phase 3: provider-retry.ts — shared Claude rotation loop (SSOT)
  - retryClaudeWithRotation extracted from message-agent-executor + task-scheduler
  - ~200 lines of duplicated retry logic removed

Phase 4: types.ts — AgentOutputPhase + VisiblePhase unified
Phase 5: types.ts — AgentConfig extended with claudeThinking/claudeThinkingBudget

Utilities (utils.ts):
  - getErrorMessage: 14 occurrences of instanceof Error pattern → 1 function
  - readJsonFile/writeJsonFile: 19 occurrences of JSON+fs pattern → 2 functions
  - fetchWithTimeout: 3 occurrences of AbortController pattern → 1 function
  - formatElapsedKorean: deduplicated from task-watch-status + message-turn-controller

Protocol (agent-protocol.ts):
  - OUTPUT_START/END_MARKER centralized (runners keep local copies with SSOT reference)
  - IMAGE_TAG_RE, IPC constants documented

Runner: show "대화 요약 중..." progress message during auto-compact

Net: -137 lines, 354/354 tests passing
2026-03-25 04:59:49 +09:00
Eyejoker
744e2ce6e2 style: format agent rotation updates 2026-03-24 17:09:17 +09:00
Eyejoker
8b2c46b89e fix: harden agent shutdown and auth rotation 2026-03-24 17:08:48 +09:00
Eyejoker
0724914a43 merge: integrate remote token rotation + memory pipeline
Merge remote main (token rotation, usage API, dashboard fixes)
with local memory pipeline changes. Smart quote encoding fixed.
Test alignment pending.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 03:53:15 +09:00
Eyejoker
3467e245d5 feat: auto memory pipeline — host-driven Memento recall/reflect
Add automatic memory integration so EJClaw host directly calls Memento
MCP for recall at session start and reflect on compact, removing
reliance on agent voluntary tool use.

Stage 1: New sessions get room memory briefing injected into system
prompt (CLAUDE.md / AGENTS.md) via host-side MCP client.

Stage 2: PreCompact hook automatically calls reflect + remember to
persist session summaries as room-memory fragments.

Also restores missing source files (token-rotation, codex-token-rotation,
claude-usage exports) to fix full build from source.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 03:48:36 +09:00
Eyejoker
120f16e9e1 fix: Claude token rotation, usage-exhausted fallback, and usage API caching
- Fix token rotation not taking effect: getCurrentToken() was shadowed
  by static .env CLAUDE_CODE_OAUTH_TOKEN value in agent environment
- Don't fall back to Kimi on usage-exhausted (only on transient 429/network)
- Add disk cache for Claude usage API data (survives restarts, 429s)
- Rate-limit usage API calls to 1 per token per 5 minutes
- Add ignoreRateLimits option to rotateToken() for exhausted recovery
- Rotate to next token in getActiveProvider() when current is exhausted
- Add isUsageExhausted() helper to provider-fallback
2026-03-24 03:40:51 +09:00
Eyejoker
c51d80bd07 style: prettier formatting 2026-03-24 01:37:14 +09:00
Eyejoker
816b0a39cc feat: Codex account rotation + fix rate-limit detection
- New codex-token-rotation module: rotates between multiple
  ~/.codex-accounts/{n}/auth.json on rate-limit
- Copies active account auth to session dir before each spawn
- Fix detectFallbackTrigger to match "usage limit" / "hit your limit"
- Fix streamed error detection: remove claude-only guard so codex
  rate-limit errors are caught even when output.status is "success"
- Add rotation in both task-scheduler and message-agent-executor
2026-03-23 23:06:17 +09:00
Eyejoker
d378598f2e feat: Claude OAuth token rotation on rate-limit
- New token-rotation module: stores multiple tokens from
  CLAUDE_CODE_OAUTH_TOKENS env var (comma-separated)
- On rate-limit, rotates to next healthy token before falling
  back to Kimi provider
- Also fixes: intermediate text routes to progress message
  when no subagents active (prevents message flooding)
2026-03-23 22:01:06 +09:00
Eyejoker
42d721a9ec fix claude turn teardown and start CI watchers immediately 2026-03-23 08:55:48 +09:00
Eyejoker
d28b6151a8 chore: rebrand runtime and docs to EJClaw 2026-03-23 08:09:15 +09:00
Eyejoker
f42234bc65 refactor: split runner env and slim dashboard facade 2026-03-23 07:30:55 +09:00