feat: added macOS power assertion module to prevent idle-sleep during sessions
- Added MacOSPowerAssertion native module to prevent idle-sleep on macOS during active sessions. - Integrated power assertion lifecycle management into coding-agent session with automatic start/stop. - Implemented N-API bindings for macOS IOKit power assertions with RAII cleanup and cross-platform no-op fallback. - Reformatted indentation from spaces to tabs across Rust chunk module for consistency.
This commit is contained in:
@@ -22,6 +22,7 @@
|
||||
|
||||
### Changed
|
||||
|
||||
- Agent sessions now hold a macOS power assertion for their lifetime so the host stays awake during active coding-agent runs
|
||||
- Updated chunk edit prompt documentation to use ellipsis (…) instead of ellipsis (...) for consistency in operation examples
|
||||
- Modified chunk path parsing to preserve raw selector strings and extract CRC separately, enabling accurate chunk reference round-tripping in read/edit workflows
|
||||
- Changed chunk edit behavior to auto-accept stale CRC checksums for subsequent operations on the same chunk within a batch, improving usability when applying multiple edits to the same target
|
||||
|
||||
@@ -49,7 +49,7 @@ import {
|
||||
modelsAreEqual,
|
||||
parseRateLimitReason,
|
||||
} from "@oh-my-pi/pi-ai";
|
||||
import type { SearchDb } from "@oh-my-pi/pi-natives";
|
||||
import { MacOSPowerAssertion, type SearchDb } from "@oh-my-pi/pi-natives";
|
||||
import { abortableSleep, getAgentDbPath, isEnoent, logger } from "@oh-my-pi/pi-utils";
|
||||
import type { AsyncJob, AsyncJobManager } from "../async";
|
||||
import type { Rule } from "../capability/rule";
|
||||
@@ -396,6 +396,9 @@ export class AgentSession {
|
||||
readonly sessionManager: SessionManager;
|
||||
readonly settings: Settings;
|
||||
readonly searchDb: SearchDb | undefined;
|
||||
|
||||
#powerAssertion: MacOSPowerAssertion | undefined;
|
||||
|
||||
readonly configWarnings: string[] = [];
|
||||
|
||||
#asyncJobManager: AsyncJobManager | undefined = undefined;
|
||||
@@ -507,11 +510,36 @@ export class AgentSession {
|
||||
#promptGeneration = 0;
|
||||
#providerSessionState = new Map<string, ProviderSessionState>();
|
||||
|
||||
#startPowerAssertion(): void {
|
||||
if (process.platform !== "darwin") {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
this.#powerAssertion = MacOSPowerAssertion.start({ reason: "Oh My Pi agent session" });
|
||||
} catch (error) {
|
||||
logger.warn("Failed to acquire macOS power assertion", { error: String(error) });
|
||||
}
|
||||
}
|
||||
|
||||
#stopPowerAssertion(): void {
|
||||
const assertion = this.#powerAssertion;
|
||||
this.#powerAssertion = undefined;
|
||||
if (!assertion) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
assertion.stop();
|
||||
} catch (error) {
|
||||
logger.warn("Failed to release macOS power assertion", { error: String(error) });
|
||||
}
|
||||
}
|
||||
|
||||
constructor(config: AgentSessionConfig) {
|
||||
this.agent = config.agent;
|
||||
this.sessionManager = config.sessionManager;
|
||||
this.settings = config.settings;
|
||||
this.searchDb = config.searchDb;
|
||||
this.#startPowerAssertion();
|
||||
this.#asyncJobManager = config.asyncJobManager;
|
||||
this.#scopedModels = config.scopedModels ?? [];
|
||||
this.#thinkingLevel = config.thinkingLevel;
|
||||
@@ -1673,6 +1701,7 @@ export class AgentSession {
|
||||
if (drained === false && deliveryState) {
|
||||
logger.warn("Async job completion deliveries still pending during dispose", { ...deliveryState });
|
||||
}
|
||||
this.#stopPowerAssertion();
|
||||
await this.sessionManager.close();
|
||||
this.#closeAllProviderSessions("dispose");
|
||||
this.#unsubscribePendingActionPush?.();
|
||||
|
||||
Reference in New Issue
Block a user