fix(coding-agent): fail fast when RPC startup exits early
This commit is contained in:
@@ -1,17 +1,15 @@
|
||||
# Changelog
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Changed
|
||||
|
||||
- Implemented time-budget-based retry strategy for Google Gemini rate limits (429 errors), allowing retries within a 5-minute window instead of a fixed attempt cap
|
||||
- Set default `maxRetries` to 5 for Anthropic, Azure OpenAI, and OpenAI client configurations to improve resilience against transient failures
|
||||
|
||||
### Fixed
|
||||
|
||||
- Improved error messages for OAuth token refresh failures by including detailed error information from the provider
|
||||
- Separated rate limit and usage limit error handling to provide distinct user-friendly messages for ChatGPT rate limits vs subscription usage limits
|
||||
- Changed 429 retry strategy for OpenAI Codex to use a 5-minute time budget when the server provides a retry delay, instead of a fixed 5-attempt cap
|
||||
|
||||
### Changed
|
||||
|
||||
- Increased SDK retry attempts to 5 for OpenAI, Azure OpenAI, and Anthropic clients (was SDK default of 2)
|
||||
- Changed 429 retry strategy for OpenAI Codex and Google Gemini CLI to use a 5-minute time budget when the server provides a retry delay, instead of a fixed attempt cap
|
||||
|
||||
## [12.14.0] - 2026-02-19
|
||||
### Added
|
||||
|
||||
@@ -134,15 +134,11 @@ export class RpcClient {
|
||||
// Wait a moment for process to initialize
|
||||
await Bun.sleep(100);
|
||||
|
||||
try {
|
||||
const exitCode = await Promise.race([this.#process.exited, Bun.sleep(500).then(() => null)]);
|
||||
if (exitCode !== null) {
|
||||
throw new Error(
|
||||
`Agent process exited immediately with code ${exitCode}. Stderr: ${this.#process.peekStderr()}`,
|
||||
);
|
||||
}
|
||||
} catch {
|
||||
// Process still running, which is what we want
|
||||
const exitCode = await Promise.race([this.#process.exited, Bun.sleep(500).then(() => null)]);
|
||||
if (exitCode !== null) {
|
||||
throw new Error(
|
||||
`Agent process exited immediately with code ${exitCode}. Stderr: ${this.#process.peekStderr()}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import * as path from "node:path";
|
||||
import { RpcClient } from "@oh-my-pi/pi-coding-agent/modes/rpc/rpc-client";
|
||||
|
||||
describe("RpcClient.start", () => {
|
||||
test("rejects when RPC process exits immediately", async () => {
|
||||
using client = new RpcClient({
|
||||
cliPath: path.join(import.meta.dir, "..", "src", "cli.ts"),
|
||||
cwd: path.join(import.meta.dir, ".."),
|
||||
provider: "__missing_provider__",
|
||||
model: "claude-sonnet-4-5",
|
||||
env: { PI_NO_TITLE: "1" },
|
||||
});
|
||||
|
||||
await expect(client.start()).rejects.toThrow('Unknown provider "__missing_provider__"');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user