← Back to PRs

#9006: fix: streaming UI, session locks, routing performance, plugin sandboxing

by facundollamas2007 open 2026-02-04 18:53 View on GitHub →
gateway agents
## 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