#20817: feat(process): paced send-keys for PTY sessions
agents
size: S
trusted-contributor
Cluster:
Model Reasoning Fixes
Fixes #20797
## Summary
- add optional `delayMs` to `process send-keys` so callers can pace key-token delivery
- keep existing behavior as default (`delayMs` omitted or `0` still sends in one burst)
- clamp delay to `0..5000ms` to avoid abuse and huge sleeps
- add e2e coverage asserting paced writes apply inter-key delay and still complete expected PTY input
## Why
Issue #20797 reports dropped/out-of-order input with bursty `send-keys` into interactive PTY tools. Pacing gives callers a bounded, opt-in way to serialize key delivery for fragile TUIs without changing existing callers.
## Testing
- `pnpm -s vitest --config vitest.e2e.config.ts run src/agents/bash-tools.process.send-keys.e2e.test.ts`
- `pnpm -s vitest run src/agents/bash-tools.process.poll-timeout.test.ts src/agents/bash-tools.process.supervisor.test.ts`
- `pnpm -s oxlint src/agents/bash-tools.process.ts src/agents/bash-tools.process.send-keys.e2e.test.ts`
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Added optional `delayMs` parameter to `process send-keys` action to pace key-token delivery for PTY sessions. The implementation clamps delay values to 0-5000ms range to prevent abuse, defaults to 0 (burst mode) to maintain backward compatibility, and applies inter-key delays only when `delayMs > 0`. The feature allows callers to serialize key delivery for fragile interactive TUI tools that may drop or reorder input with bursty send-keys.
**Changes:**
- Added `delayMs` optional parameter to process tool schema (lines 72-77)
- Implemented `resolveSendKeysDelayMs()` validation function with 5000ms upper bound (lines 95-108)
- Refactored `send-keys` action to support paced delivery: processes hex/literal prefix first, then iterates through key tokens with delays between them (lines 494-566)
- Added e2e test coverage verifying paced writes apply inter-key delay and complete expected PTY input
**Testing:**
- New e2e test validates timing (3 inter-key waits of 60ms = minimum 130ms elapsed, allowing timer jitter)
- Existing tests for Enter encoding and submit action remain passing
- Test design uses obfuscated string construction to avoid triggering event-based exit conditions
<h3>Confidence Score: 5/5</h3>
- This PR is safe to merge with minimal risk
- The implementation is well-designed with proper input validation, maintains backward compatibility, includes comprehensive e2e test coverage, and follows the repository's coding patterns. The 5000ms upper bound prevents abuse, and the delay logic correctly applies only between key tokens (not after the last one).
- No files require special attention
<sub>Last reviewed commit: 5120098</sub>
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#20798: fix(process): Add delayMs parameter to send-keys for TUI compatibility
by Q00 · 2026-02-19
80.8%
#15996: fix(agents): messages arrive out of order — tool output beats narra...
by yinghaosang · 2026-02-14
68.1%
#20868: fix: resolve {model} responsePrefix vars in non-agent-turn paths
by Operative-001 · 2026-02-19
67.8%
#19632: fix: suppressToolErrors now suppresses exec tool failure notifications
by Gitjay11 · 2026-02-18
66.0%
#12358: fix: Sessions format timestamps in sessions_history using userTimezone
by xialonglee · 2026-02-09
66.0%
#16403: feat: add readable timestamp to inbound_meta.v1 payload
by mcinteerj · 2026-02-14
65.7%
#19412: fix(status): prefer configured contextTokens over session entry
by rafaelipuente · 2026-02-17
65.6%
#16856: feat(agents): add tool execution duration tracking with configurabl...
by EunHyeokJung · 2026-02-15
65.6%
#19339: fix(heartbeat): skip isError payloads when resolving heartbeat reply
by aldoeliacim · 2026-02-17
65.4%
#19624: fix: elevatedDefault should default to off when tools.elevated.enab...
by stakeswky · 2026-02-18
65.3%