fix(rpc): address fast-mode review feedback

This commit is contained in:
Frederico Luz
2026-07-29 19:47:56 +01:00
parent 4dc0c08a1d
commit 7b8001e5c4
4 changed files with 103 additions and 1 deletions
+58
View File
@@ -124,6 +124,7 @@ Important edge behavior from runtime:
### State
- `{ id?, type: "get_state" }`
- `{ id?, type: "set_fast_mode", enabled: boolean }`
- `{ id?, type: "get_available_commands" }`
- `{ id?, type: "set_todos", phases: TodoPhase[] }`
- `{ id?, type: "set_host_tools", tools: RpcHostToolDefinition[] }`
@@ -231,6 +232,10 @@ Local-only slash commands may emit `command_output` frames before completing via
### `get_state` payload
`tokensPerSecond` is a number when output throughput is available and `null`
otherwise. `fastModeEnabled` reports the session setting, while
`fastModeActive` reports whether the current model realizes fast mode.
```json
{
"model": { "provider": "...", "id": "..." },
@@ -243,6 +248,9 @@ Local-only slash commands may emit `command_output` frames before completing via
"sessionFile": "...",
"sessionId": "...",
"sessionName": "...",
"fastModeEnabled": false,
"tokensPerSecond": null,
"fastModeActive": false,
"autoCompactionEnabled": true,
"messageCount": 0,
"queuedMessageCount": 0,
@@ -275,6 +283,56 @@ Local-only slash commands may emit `command_output` frames before completing via
}
```
### `set_fast_mode` payload
`set_fast_mode` changes whether fast mode is enabled for the session. The
request is:
```json
{ "id": "req_fast_on", "type": "set_fast_mode", "enabled": true }
```
On success, `data` always contains both `enabled` and `active`. `enabled`
reports the session setting; `active` reports whether fast mode is realized by
the current model:
```json
{
"id": "req_fast_on",
"type": "response",
"command": "set_fast_mode",
"success": true,
"data": { "enabled": true, "active": true }
}
```
Enabling fast mode on a model without a service-tier family fails with the
exact error below:
```json
{
"id": "req_fast_on",
"type": "response",
"command": "set_fast_mode",
"success": false,
"error": "Fast mode is unavailable for the current model."
}
```
Disabling fast mode is idempotent, including on an unsupported model. It
succeeds as an off/no-op result and leaves `get_state.fastModeEnabled` and
`get_state.fastModeActive` false:
```json
{
"id": "req_fast_off",
"type": "response",
"command": "set_fast_mode",
"success": true,
"data": { "enabled": false, "active": false }
}
```
### `set_todos` payload
Replaces the in-memory todo state for the current session and returns the normalized phase list:
+2
View File
@@ -5,6 +5,8 @@
### Added
- Added tokens-per-second throughput to RPC `get_state` responses for non-TUI clients.
- Added the RPC `set_fast_mode` command for live fast-mode control.
- Added `fastModeEnabled` and `fastModeActive` to RPC `get_state` responses.
## [17.1.8] - 2026-07-28
@@ -1104,7 +1104,8 @@ export async function runRpcMode(
}
case "set_fast_mode": {
if (!session.setFastMode(command.enabled)) {
const supported = session.setFastMode(command.enabled);
if (command.enabled && !supported) {
return error(id, "set_fast_mode", "Fast mode is unavailable for the current model.");
}
return success(id, "set_fast_mode", {
+41
View File
@@ -315,3 +315,44 @@ describe.skipIf(!e2eApiKey("ANTHROPIC_API_KEY"))("RPC mode", () => {
expect(text).toContain("test123");
}, 90000);
});
describe("RPC fast mode with unsupported model", () => {
let client: RpcClient;
let sessionDir: string;
beforeEach(() => {
sessionDir = path.join(os.tmpdir(), `omp-rpc-fast-mode-test-${Snowflake.next()}`);
client = new RpcClient({
cliPath: path.join(import.meta.dir, "..", "src", "cli.ts"),
cwd: path.join(import.meta.dir, ".."),
env: {
PI_CODING_AGENT_DIR: sessionDir,
FIREWORKS_API_KEY: "test-fireworks-key",
},
provider: "fireworks",
model: "deepseek-v4-flash",
});
});
afterEach(async () => {
await client.stop();
if (sessionDir && fs.existsSync(sessionDir)) {
removeSyncWithRetries(sessionDir);
}
});
test("rejects enable but idempotently accepts disable", async () => {
await client.start();
await expect(client.setFastMode(true)).rejects.toMatchObject({
message: "Fast mode is unavailable for the current model.",
});
const disabled = await client.setFastMode(false);
expect(disabled).toEqual({ enabled: false, active: false });
const state = await client.getState();
expect(state.fastModeEnabled).toBe(false);
expect(state.fastModeActive).toBe(false);
}, 30000);
});