#9006: fix: streaming UI, session locks, routing performance, plugin sandboxing
gateway
agents
Cluster:
Session Management and Fixes
## Summary
This PR includes four fixes:
1. **Streaming UI fix** - Reduces throttle from 150ms to 50ms and adds buffer flush before final event. Fixes issue #549 where UI (TUI and webchat) would not update in real-time.
2. **Session write locks auto-release** - Adds `autoReleaseAfterMs` parameter (default: 5 minutes) to prevent indefinite locks when an agent hangs.
3. **Routing O(1) optimization** - Changes O(n) linear scans to O(1) lookups using indexed Maps. ~1000x faster with 1000 bindings.
4. **Plugin sandboxing** - Adds granular permission system for dangerous APIs (`runCommandWithTimeout`, `writeConfigFile`). Plugins are restricted by default and need explicit permissions in config.
## Test plan
- [x] Build passes
- [x] All 207 tests pass
- [x] Manually tested streaming fix - UI updates in real-time now
## Plugin sandboxing usage
```json
{
"plugins": {
"entries": {
"my-plugin": {
"permissions": {
"runCommandWithTimeout": true,
"writeConfigFile": false
}
}
}
}
}
```
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
This PR batches four fixes across gateway, routing, session locking, and plugin infrastructure:
- **Gateway streaming**: lowers delta throttle (150ms → 50ms) and adds a pre-final “flush” of any buffered assistant text before emitting the `final`/`error` event.
- **Session write lock**: adds an `autoReleaseAfterMs` timer (default 5 minutes) so held locks can’t persist forever if a process hangs.
- **Routing**: replaces repeated O(n) binding scans with cached Map-based indexes intended to make route resolution O(1) per lookup.
- **Plugins**: introduces a sandbox policy wrapper for the plugin runtime, gating “dangerous” runtime APIs behind per-plugin config permissions that are normalized from config and passed through the loader into the registry.
The overall direction fits the codebase: `server-chat` continues to own chat event shaping/throttling, `resolve-route` centralizes binding resolution, and plugin API construction in `registry` is the right place to inject a restricted runtime. The main issues to address before merge are correctness regressions in routing (account scoping dropped for peer/guild/team bindings), the streaming flush still being subject to throttling (so the last delta can still be lost), and a sandbox permission naming mismatch that can produce impossible-to-satisfy config guidance.
<h3>Confidence Score: 2/5</h3>
- This PR should not be merged until a few correctness regressions are fixed.
- Score is reduced due to (1) the routing index dropping accountId filtering for peer/guild/team bindings (behavior change in common multi-account configs), (2) the streaming flush still being throttled so the original tail-loss bug can persist, and (3) sandbox policy referring to permission keys that can’t be granted via config (inconsistent enforcement vs docs).
- src/routing/resolve-route.ts, src/gateway/server-chat.ts, src/plugins/sandbox-policy.ts
<!-- greptile_other_comments_section -->
<sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#4878: fix: string/type handling and API fixes (#4537, #4380, #4373, #4547...
by lailoo · 2026-01-30
78.5%
#13881: fix: Address Greptile feedback - test isolation and channel resolution
by trevorgordon981 · 2026-02-11
78.2%
#21463: fix(discord): prevent WebSocket death spiral + fix numeric channel ID…
by akropp · 2026-02-20
78.1%
#14309: fix(ui): resolve chat event session key mismatch
by justonlyforyou · 2026-02-11
77.7%
#9218: Fix Control UI chat resync on gaps and terminal events
by figitaki · 2026-02-05
77.6%
#10745: feat: Security improvements and Windows compatibility fixes
by lluviaoscuradeldoce-design · 2026-02-06
77.4%
#8353: fix(ui): display tool calls during webchat streaming
by MarvinDontPanic · 2026-02-03
77.3%
#14795: fix: skip disabled channel plugins in cross-context messaging checks
by explainanalyze · 2026-02-12
77.1%
#18187: fix: tool summaries silently dropped when reasoningLevel is stream
by ayanesakura · 2026-02-16
77.1%
#23749: fix some issues
by tronpis · 2026-02-22
76.5%