Skip to content

fix: Agent infrastructure critical issues (C3, C4, H1-H5) - #162

Merged
ULookup merged 5 commits into
mainfrom
worktree-fix+agent-infra-critical-fixes
Jun 19, 2026
Merged

ULookup merged 5 commits into
mainfrom
worktree-fix+agent-infra-critical-fixes

Conversation

@ULookup

@ULookup ULookup commented Jun 19, 2026

Copy link
Copy Markdown
Owner

Summary

  • C3: Add read_mutex_ to JsonRpcClient::read_message() to serialize concurrent reads from std::async tasks sharing the same stdout pipe
  • H4: Add 30s timeout wrapper in send_request() to prevent indefinite blocking on hung child process
  • C4: Change AgentLoop::run()/resume() return type from std::future<AgentResponse> to AgentResponse (all callers immediately .get() — async added no benefit but created dangling reference risk)
  • H1: Delete AgentLoop move constructor/assignment (the object holds this in async paths)
  • H2: Serialize actual tool call data and pipeline stats in checkpoint instead of hardcoded empty strings; track last_compaction_text_ for recovery
  • H3: Replace [this] capture in init_runtime with explicit SubRunDeps struct (matching PipelineManager::Dependencies DI pattern)
  • H5: Default-initialize PlanInput::on_escalate to []{} to prevent std::bad_function_call

Files Changed

  • libs/core/include/merak/json_rpc_client.hpp — C3: add read_mutex_
  • libs/core/src/json_rpc_client.cpp — C3: lock read_message + H4: 30s timeout
  • libs/loop/include/merak/agent_loop.hpp — C4: sync return + H1: delete move + H2: last_compaction_text_
  • libs/loop/src/agent_loop.cpp — C4: sync bodies + H2: checkpoint serialization + compaction tracking
  • libs/app/src/application.cpp — C4: remove .get() + H3: SubRunDeps DI
  • libs/loop/src/sub_agent_runner.cpp — C4: remove .get()
  • libs/app/include/merak/app/application.hpp — H3: SubRunDeps struct + static execute_sub_run
  • libs/core/include/merak/pipeline_types.hpp — H5: default init

Test plan

  • CI passes
  • Verify JSON-RPC requests no longer race on stdout pipe
  • Verify hung child process is detected within 30s
  • Verify AgentLoop checkpoint serializes real data
  • Verify no dangling references in sub-agent execution paths
  • Verify on_escalate no longer throws std::bad_function_call

ULookup added 5 commits June 19, 2026 18:14
Add read_mutex_ to serialize concurrent read_message calls from std::async
tasks sharing the same stdout pipe. Add 30s timeout wrapper via wait_for
to prevent indefinite blocking if the child process hangs.
- Change run()/resume() return type from future to direct AgentResponse
  (all callers immediately .get(), async added no benefit)
- Delete move constructor/assignment (AgentLoop holds this in async paths)
- Track last compaction summary for checkpoint recovery
- Serialize actual tool calls and pipeline stats in checkpoint
  instead of hardcoded empty strings
Prevents std::bad_function_call when callers invoke without checking.
Existing callers already guard with operator bool(); this is defense-in-depth.
Replace [this] capture in init_runtime with explicit SubRunDeps struct,
matching the PipelineManager::Dependencies DI pattern. execute_sub_run
is now a static method taking explicit dependencies. This eliminates
the hidden lifetime dependency on Application member declaration order.
@ULookup
ULookup merged commit 829fbcd into main Jun 19, 2026
0 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant