@oh-my-pi/pi-coding-agent 16.1.0 → 16.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/dist/cli.js +1847 -1847
- package/dist/types/config/settings-schema.d.ts +27 -36
- package/dist/types/lsp/types.d.ts +5 -3
- package/dist/types/modes/components/cache-invalidation-marker.d.ts +7 -2
- package/package.json +12 -12
- package/src/config/settings-schema.ts +33 -36
- package/src/config/settings.ts +40 -0
- package/src/lsp/client.ts +9 -9
- package/src/lsp/types.ts +6 -3
- package/src/modes/components/cache-invalidation-marker.ts +12 -2
- package/src/modes/components/settings-defs.ts +7 -0
- package/src/session/agent-session.ts +6 -10
|
@@ -138,44 +138,32 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
138
138
|
readonly description: "Automatically resume the most recent session in the current directory";
|
|
139
139
|
};
|
|
140
140
|
};
|
|
141
|
-
readonly "power.
|
|
142
|
-
readonly type: "
|
|
143
|
-
readonly
|
|
144
|
-
readonly
|
|
145
|
-
readonly tab: "interaction";
|
|
146
|
-
readonly group: "Power (macOS)";
|
|
147
|
-
readonly label: "Prevent Idle Sleep";
|
|
148
|
-
readonly description: "Keep the system awake while a session is open (caffeinate -i)";
|
|
149
|
-
};
|
|
150
|
-
};
|
|
151
|
-
readonly "power.preventSystemSleep": {
|
|
152
|
-
readonly type: "boolean";
|
|
153
|
-
readonly default: false;
|
|
154
|
-
readonly ui: {
|
|
155
|
-
readonly tab: "interaction";
|
|
156
|
-
readonly group: "Power (macOS)";
|
|
157
|
-
readonly label: "Prevent System Sleep on AC";
|
|
158
|
-
readonly description: "Block all system sleep while on AC power (caffeinate -s)";
|
|
159
|
-
};
|
|
160
|
-
};
|
|
161
|
-
readonly "power.declareUserActive": {
|
|
162
|
-
readonly type: "boolean";
|
|
163
|
-
readonly default: false;
|
|
164
|
-
readonly ui: {
|
|
165
|
-
readonly tab: "interaction";
|
|
166
|
-
readonly group: "Power (macOS)";
|
|
167
|
-
readonly label: "Declare User Active";
|
|
168
|
-
readonly description: "Keep the display lit and treat the user as active (caffeinate -u)";
|
|
169
|
-
};
|
|
170
|
-
};
|
|
171
|
-
readonly "power.preventDisplaySleep": {
|
|
172
|
-
readonly type: "boolean";
|
|
173
|
-
readonly default: false;
|
|
141
|
+
readonly "power.sleepPrevention": {
|
|
142
|
+
readonly type: "enum";
|
|
143
|
+
readonly values: readonly ["off", "idle", "display", "system"];
|
|
144
|
+
readonly default: "idle";
|
|
174
145
|
readonly ui: {
|
|
175
146
|
readonly tab: "interaction";
|
|
176
147
|
readonly group: "Power (macOS)";
|
|
177
|
-
readonly label: "
|
|
178
|
-
readonly description: "
|
|
148
|
+
readonly label: "Sleep Prevention";
|
|
149
|
+
readonly description: "Prevent macOS sleep during active sessions. Each level is cumulative — it adds the flags of all lower levels.";
|
|
150
|
+
readonly options: readonly [{
|
|
151
|
+
readonly value: "off";
|
|
152
|
+
readonly label: "Off";
|
|
153
|
+
readonly description: "Do not prevent any sleep";
|
|
154
|
+
}, {
|
|
155
|
+
readonly value: "idle";
|
|
156
|
+
readonly label: "Prevent Idle Sleep";
|
|
157
|
+
readonly description: "Keep the system awake while a session is open (caffeinate -i)";
|
|
158
|
+
}, {
|
|
159
|
+
readonly value: "display";
|
|
160
|
+
readonly label: "Prevent Display Sleep";
|
|
161
|
+
readonly description: "Also keep the display from idle-sleeping (caffeinate -i -d)";
|
|
162
|
+
}, {
|
|
163
|
+
readonly value: "system";
|
|
164
|
+
readonly label: "Prevent System Sleep";
|
|
165
|
+
readonly description: "Also block all system sleep on AC and declare the user active (caffeinate -i -d -s -u)";
|
|
166
|
+
}];
|
|
179
167
|
};
|
|
180
168
|
};
|
|
181
169
|
readonly "advisor.enabled": {
|
|
@@ -196,6 +184,7 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
196
184
|
readonly group: "Advisor";
|
|
197
185
|
readonly label: "Advisor for Subagents";
|
|
198
186
|
readonly description: "Also enable the advisor on spawned task/eval subagents.";
|
|
187
|
+
readonly condition: "advisorEnabled";
|
|
199
188
|
};
|
|
200
189
|
};
|
|
201
190
|
readonly "advisor.syncBacklog": {
|
|
@@ -207,6 +196,7 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
207
196
|
readonly group: "Advisor";
|
|
208
197
|
readonly label: "Advisor Sync Backlog";
|
|
209
198
|
readonly description: "Pause the main agent for up to 30 seconds if the advisor falls behind by this many turns. Off disables catch-up delays.";
|
|
199
|
+
readonly condition: "advisorEnabled";
|
|
210
200
|
};
|
|
211
201
|
};
|
|
212
202
|
readonly "advisor.immuneTurns": {
|
|
@@ -238,6 +228,7 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
238
228
|
readonly value: "5";
|
|
239
229
|
readonly label: "5 turns";
|
|
240
230
|
}];
|
|
231
|
+
readonly condition: "advisorEnabled";
|
|
241
232
|
};
|
|
242
233
|
};
|
|
243
234
|
readonly shellPath: {
|
|
@@ -821,7 +812,7 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
821
812
|
};
|
|
822
813
|
readonly "display.cacheMissMarker": {
|
|
823
814
|
readonly type: "boolean";
|
|
824
|
-
readonly default:
|
|
815
|
+
readonly default: false;
|
|
825
816
|
readonly ui: {
|
|
826
817
|
readonly tab: "appearance";
|
|
827
818
|
readonly group: "Display";
|
|
@@ -259,7 +259,7 @@ export interface LspClient {
|
|
|
259
259
|
diagnostics: Map<string, PublishedDiagnostics>;
|
|
260
260
|
diagnosticsVersion: number;
|
|
261
261
|
openFiles: Map<string, OpenFile>;
|
|
262
|
-
pendingRequests: Map<number, PendingRequest>;
|
|
262
|
+
pendingRequests: Map<number | string, PendingRequest>;
|
|
263
263
|
messageBuffer: Uint8Array;
|
|
264
264
|
isReading: boolean;
|
|
265
265
|
/** Lifecycle state: "connecting" until initialize completes, then "ready"; "error" on init failure or reader death. */
|
|
@@ -275,15 +275,17 @@ export interface LspClient {
|
|
|
275
275
|
/** Call to signal that project loading has completed */
|
|
276
276
|
resolveProjectLoaded: () => void;
|
|
277
277
|
}
|
|
278
|
+
/** JSON-RPC request/response identifier accepted by LSP peers. */
|
|
279
|
+
export type LspJsonRpcId = number | string;
|
|
278
280
|
export interface LspJsonRpcRequest {
|
|
279
281
|
jsonrpc: "2.0";
|
|
280
|
-
id:
|
|
282
|
+
id: LspJsonRpcId;
|
|
281
283
|
method: string;
|
|
282
284
|
params: unknown;
|
|
283
285
|
}
|
|
284
286
|
export interface LspJsonRpcResponse {
|
|
285
287
|
jsonrpc: "2.0";
|
|
286
|
-
id?:
|
|
288
|
+
id?: LspJsonRpcId;
|
|
287
289
|
result?: unknown;
|
|
288
290
|
error?: {
|
|
289
291
|
code: number;
|
|
@@ -13,8 +13,13 @@ export interface CacheInvalidation {
|
|
|
13
13
|
* request reads nothing from cache and re-pays for the whole prompt. We detect
|
|
14
14
|
* that as: the previous turn cached a meaningful prefix, yet this turn's
|
|
15
15
|
* `cacheRead` collapsed to zero while it still reprocessed a non-trivial prompt.
|
|
16
|
-
* Returns `undefined` (no marker) for the first turn, tiny contexts,
|
|
17
|
-
* that reused any cache
|
|
16
|
+
* Returns `undefined` (no marker) for the first turn, tiny contexts, turns
|
|
17
|
+
* that reused any cache, and — crucially — turns on providers with *implicit*
|
|
18
|
+
* best-effort caching. Only an explicit, prefix-controlled cache (Anthropic /
|
|
19
|
+
* Bedrock `cache_control`) re-creates the prefix on a cold turn (`cacheWrite >
|
|
20
|
+
* 0`); implicit caches (Google / OpenAI / Fireworks) report `cacheWrite: 0` and
|
|
21
|
+
* drop `cacheRead` to zero intermittently as routine propagation noise that
|
|
22
|
+
* self-heals the next turn, so flagging it would be a false positive.
|
|
18
23
|
*/
|
|
19
24
|
export declare function detectCacheInvalidation(prev: Usage | undefined, current: Usage): CacheInvalidation | undefined;
|
|
20
25
|
/**
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@oh-my-pi/pi-coding-agent",
|
|
4
|
-
"version": "16.1.
|
|
4
|
+
"version": "16.1.1",
|
|
5
5
|
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
|
6
6
|
"homepage": "https://omp.sh",
|
|
7
7
|
"author": "Can Boluk",
|
|
@@ -48,17 +48,17 @@
|
|
|
48
48
|
"@agentclientprotocol/sdk": "0.25.0",
|
|
49
49
|
"@babel/parser": "^7.29.7",
|
|
50
50
|
"@mozilla/readability": "^0.6.0",
|
|
51
|
-
"@oh-my-pi/hashline": "16.1.
|
|
52
|
-
"@oh-my-pi/omp-stats": "16.1.
|
|
53
|
-
"@oh-my-pi/pi-agent-core": "16.1.
|
|
54
|
-
"@oh-my-pi/pi-ai": "16.1.
|
|
55
|
-
"@oh-my-pi/pi-catalog": "16.1.
|
|
56
|
-
"@oh-my-pi/pi-mnemopi": "16.1.
|
|
57
|
-
"@oh-my-pi/pi-natives": "16.1.
|
|
58
|
-
"@oh-my-pi/pi-tui": "16.1.
|
|
59
|
-
"@oh-my-pi/pi-utils": "16.1.
|
|
60
|
-
"@oh-my-pi/pi-wire": "16.1.
|
|
61
|
-
"@oh-my-pi/snapcompact": "16.1.
|
|
51
|
+
"@oh-my-pi/hashline": "16.1.1",
|
|
52
|
+
"@oh-my-pi/omp-stats": "16.1.1",
|
|
53
|
+
"@oh-my-pi/pi-agent-core": "16.1.1",
|
|
54
|
+
"@oh-my-pi/pi-ai": "16.1.1",
|
|
55
|
+
"@oh-my-pi/pi-catalog": "16.1.1",
|
|
56
|
+
"@oh-my-pi/pi-mnemopi": "16.1.1",
|
|
57
|
+
"@oh-my-pi/pi-natives": "16.1.1",
|
|
58
|
+
"@oh-my-pi/pi-tui": "16.1.1",
|
|
59
|
+
"@oh-my-pi/pi-utils": "16.1.1",
|
|
60
|
+
"@oh-my-pi/pi-wire": "16.1.1",
|
|
61
|
+
"@oh-my-pi/snapcompact": "16.1.1",
|
|
62
62
|
"@opentelemetry/api": "^1.9.1",
|
|
63
63
|
"@opentelemetry/context-async-hooks": "^2.7.1",
|
|
64
64
|
"@opentelemetry/exporter-trace-otlp-proto": "^0.218.0",
|
|
@@ -342,44 +342,38 @@ export const SETTINGS_SCHEMA = {
|
|
|
342
342
|
},
|
|
343
343
|
|
|
344
344
|
// macOS power assertions (caffeinate flags). No-op on other platforms.
|
|
345
|
-
"power.
|
|
346
|
-
type: "
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
tab: "interaction",
|
|
350
|
-
group: "Power (macOS)",
|
|
351
|
-
label: "Prevent Idle Sleep",
|
|
352
|
-
description: "Keep the system awake while a session is open (caffeinate -i)",
|
|
353
|
-
},
|
|
354
|
-
},
|
|
355
|
-
"power.preventSystemSleep": {
|
|
356
|
-
type: "boolean",
|
|
357
|
-
default: false,
|
|
358
|
-
ui: {
|
|
359
|
-
tab: "interaction",
|
|
360
|
-
group: "Power (macOS)",
|
|
361
|
-
label: "Prevent System Sleep on AC",
|
|
362
|
-
description: "Block all system sleep while on AC power (caffeinate -s)",
|
|
363
|
-
},
|
|
364
|
-
},
|
|
365
|
-
"power.declareUserActive": {
|
|
366
|
-
type: "boolean",
|
|
367
|
-
default: false,
|
|
368
|
-
ui: {
|
|
369
|
-
tab: "interaction",
|
|
370
|
-
group: "Power (macOS)",
|
|
371
|
-
label: "Declare User Active",
|
|
372
|
-
description: "Keep the display lit and treat the user as active (caffeinate -u)",
|
|
373
|
-
},
|
|
374
|
-
},
|
|
375
|
-
"power.preventDisplaySleep": {
|
|
376
|
-
type: "boolean",
|
|
377
|
-
default: false,
|
|
345
|
+
"power.sleepPrevention": {
|
|
346
|
+
type: "enum",
|
|
347
|
+
values: ["off", "idle", "display", "system"] as const,
|
|
348
|
+
default: "idle",
|
|
378
349
|
ui: {
|
|
379
350
|
tab: "interaction",
|
|
380
351
|
group: "Power (macOS)",
|
|
381
|
-
label: "
|
|
382
|
-
description:
|
|
352
|
+
label: "Sleep Prevention",
|
|
353
|
+
description:
|
|
354
|
+
"Prevent macOS sleep during active sessions. Each level is cumulative — it adds the flags of all lower levels.",
|
|
355
|
+
options: [
|
|
356
|
+
{
|
|
357
|
+
value: "off",
|
|
358
|
+
label: "Off",
|
|
359
|
+
description: "Do not prevent any sleep",
|
|
360
|
+
},
|
|
361
|
+
{
|
|
362
|
+
value: "idle",
|
|
363
|
+
label: "Prevent Idle Sleep",
|
|
364
|
+
description: "Keep the system awake while a session is open (caffeinate -i)",
|
|
365
|
+
},
|
|
366
|
+
{
|
|
367
|
+
value: "display",
|
|
368
|
+
label: "Prevent Display Sleep",
|
|
369
|
+
description: "Also keep the display from idle-sleeping (caffeinate -i -d)",
|
|
370
|
+
},
|
|
371
|
+
{
|
|
372
|
+
value: "system",
|
|
373
|
+
label: "Prevent System Sleep",
|
|
374
|
+
description: "Also block all system sleep on AC and declare the user active (caffeinate -i -d -s -u)",
|
|
375
|
+
},
|
|
376
|
+
],
|
|
383
377
|
},
|
|
384
378
|
},
|
|
385
379
|
"advisor.enabled": {
|
|
@@ -401,6 +395,7 @@ export const SETTINGS_SCHEMA = {
|
|
|
401
395
|
group: "Advisor",
|
|
402
396
|
label: "Advisor for Subagents",
|
|
403
397
|
description: "Also enable the advisor on spawned task/eval subagents.",
|
|
398
|
+
condition: "advisorEnabled",
|
|
404
399
|
},
|
|
405
400
|
},
|
|
406
401
|
"advisor.syncBacklog": {
|
|
@@ -413,6 +408,7 @@ export const SETTINGS_SCHEMA = {
|
|
|
413
408
|
label: "Advisor Sync Backlog",
|
|
414
409
|
description:
|
|
415
410
|
"Pause the main agent for up to 30 seconds if the advisor falls behind by this many turns. Off disables catch-up delays.",
|
|
411
|
+
condition: "advisorEnabled",
|
|
416
412
|
},
|
|
417
413
|
},
|
|
418
414
|
"advisor.immuneTurns": {
|
|
@@ -432,6 +428,7 @@ export const SETTINGS_SCHEMA = {
|
|
|
432
428
|
{ value: "4", label: "4 turns" },
|
|
433
429
|
{ value: "5", label: "5 turns" },
|
|
434
430
|
],
|
|
431
|
+
condition: "advisorEnabled",
|
|
435
432
|
},
|
|
436
433
|
},
|
|
437
434
|
shellPath: { type: "string", default: undefined },
|
|
@@ -851,7 +848,7 @@ export const SETTINGS_SCHEMA = {
|
|
|
851
848
|
|
|
852
849
|
"display.cacheMissMarker": {
|
|
853
850
|
type: "boolean",
|
|
854
|
-
default:
|
|
851
|
+
default: false,
|
|
855
852
|
ui: {
|
|
856
853
|
tab: "appearance",
|
|
857
854
|
group: "Display",
|
package/src/config/settings.ts
CHANGED
|
@@ -909,6 +909,46 @@ export class Settings {
|
|
|
909
909
|
}
|
|
910
910
|
}
|
|
911
911
|
|
|
912
|
+
// power.preventIdleSleep / power.preventSystemSleep / power.declareUserActive
|
|
913
|
+
// / power.preventDisplaySleep (four booleans) → power.sleepPrevention enum.
|
|
914
|
+
// The enum is cumulative: each level adds the flags of all lower levels.
|
|
915
|
+
// Migration picks the highest level whose condition is met, scanning from
|
|
916
|
+
// most to least aggressive so a single enum value captures the old state.
|
|
917
|
+
if (
|
|
918
|
+
!("sleepPrevention" in ((raw.power as Record<string, unknown>) ?? {})) &&
|
|
919
|
+
raw["power.sleepPrevention"] === undefined
|
|
920
|
+
) {
|
|
921
|
+
const powerObj = raw.power as Record<string, unknown> | undefined;
|
|
922
|
+
const getFlag = (key: string): boolean | undefined => {
|
|
923
|
+
const nested = powerObj?.[key];
|
|
924
|
+
const flat = raw[`power.${key}`];
|
|
925
|
+
const value = nested ?? flat;
|
|
926
|
+
return typeof value === "boolean" ? value : undefined;
|
|
927
|
+
};
|
|
928
|
+
const idle = getFlag("preventIdleSleep");
|
|
929
|
+
const system = getFlag("preventSystemSleep");
|
|
930
|
+
const user = getFlag("declareUserActive");
|
|
931
|
+
const display = getFlag("preventDisplaySleep");
|
|
932
|
+
const anySet = idle !== undefined || system !== undefined || user !== undefined || display !== undefined;
|
|
933
|
+
if (anySet) {
|
|
934
|
+
const mode = system || user ? "system" : display ? "display" : idle !== false ? "idle" : "off";
|
|
935
|
+
const powerRoot = (powerObj ?? {}) as Record<string, unknown>;
|
|
936
|
+
powerRoot.sleepPrevention = mode;
|
|
937
|
+
raw.power = powerRoot;
|
|
938
|
+
}
|
|
939
|
+
// Clean up old keys (nested + flat)
|
|
940
|
+
if (powerObj) {
|
|
941
|
+
delete powerObj.preventIdleSleep;
|
|
942
|
+
delete powerObj.preventSystemSleep;
|
|
943
|
+
delete powerObj.declareUserActive;
|
|
944
|
+
delete powerObj.preventDisplaySleep;
|
|
945
|
+
}
|
|
946
|
+
delete raw["power.preventIdleSleep"];
|
|
947
|
+
delete raw["power.preventSystemSleep"];
|
|
948
|
+
delete raw["power.declareUserActive"];
|
|
949
|
+
delete raw["power.preventDisplaySleep"];
|
|
950
|
+
}
|
|
951
|
+
|
|
912
952
|
return raw;
|
|
913
953
|
}
|
|
914
954
|
|
package/src/lsp/client.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { applyWorkspaceEdit } from "./edits";
|
|
|
5
5
|
import { getLspmuxCommand, isLspmuxSupported } from "./lspmux";
|
|
6
6
|
import type {
|
|
7
7
|
LspClient,
|
|
8
|
+
LspJsonRpcId,
|
|
8
9
|
LspJsonRpcNotification,
|
|
9
10
|
LspJsonRpcRequest,
|
|
10
11
|
LspJsonRpcResponse,
|
|
@@ -416,7 +417,6 @@ function currentWorkspaceFolders(client: LspClient): Array<{ uri: string; name:
|
|
|
416
417
|
* Handle workspace/workspaceFolders requests from the server.
|
|
417
418
|
*/
|
|
418
419
|
async function handleWorkspaceFoldersRequest(client: LspClient, message: LspJsonRpcRequest): Promise<void> {
|
|
419
|
-
if (typeof message.id !== "number") return;
|
|
420
420
|
await sendResponse(client, message.id, currentWorkspaceFolders(client), "workspace/workspaceFolders");
|
|
421
421
|
}
|
|
422
422
|
|
|
@@ -424,7 +424,6 @@ async function handleWorkspaceFoldersRequest(client: LspClient, message: LspJson
|
|
|
424
424
|
* Handle workspace/configuration requests from the server.
|
|
425
425
|
*/
|
|
426
426
|
async function handleConfigurationRequest(client: LspClient, message: LspJsonRpcRequest): Promise<void> {
|
|
427
|
-
if (typeof message.id !== "number") return;
|
|
428
427
|
const params = message.params as { items?: Array<{ section?: string }> };
|
|
429
428
|
const items = params?.items ?? [];
|
|
430
429
|
const result = items.map(item => {
|
|
@@ -438,7 +437,6 @@ async function handleConfigurationRequest(client: LspClient, message: LspJsonRpc
|
|
|
438
437
|
* Handle workspace/applyEdit requests from the server.
|
|
439
438
|
*/
|
|
440
439
|
async function handleApplyEditRequest(client: LspClient, message: LspJsonRpcRequest): Promise<void> {
|
|
441
|
-
if (typeof message.id !== "number") return;
|
|
442
440
|
const params = message.params as { edit?: WorkspaceEdit };
|
|
443
441
|
if (!params?.edit) {
|
|
444
442
|
await sendResponse(
|
|
@@ -475,13 +473,15 @@ async function handleServerRequest(client: LspClient, message: LspJsonRpcRequest
|
|
|
475
473
|
return;
|
|
476
474
|
}
|
|
477
475
|
if (message.method === "window/workDoneProgress/create") {
|
|
478
|
-
// Accept progress token registration from the server
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
476
|
+
// Accept progress token registration from the server.
|
|
477
|
+
await sendResponse(client, message.id, null, message.method);
|
|
478
|
+
return;
|
|
479
|
+
}
|
|
480
|
+
if (message.method === "client/registerCapability" || message.method === "client/unregisterCapability") {
|
|
481
|
+
// Some servers block semantic requests until dynamic registration succeeds.
|
|
482
|
+
await sendResponse(client, message.id, null, message.method);
|
|
482
483
|
return;
|
|
483
484
|
}
|
|
484
|
-
if (typeof message.id !== "number") return;
|
|
485
485
|
await sendResponse(client, message.id, null, message.method, {
|
|
486
486
|
code: -32601,
|
|
487
487
|
message: `Method not found: ${message.method}`,
|
|
@@ -493,7 +493,7 @@ async function handleServerRequest(client: LspClient, message: LspJsonRpcRequest
|
|
|
493
493
|
*/
|
|
494
494
|
async function sendResponse(
|
|
495
495
|
client: LspClient,
|
|
496
|
-
id:
|
|
496
|
+
id: LspJsonRpcId,
|
|
497
497
|
result: unknown,
|
|
498
498
|
method: string,
|
|
499
499
|
error?: { code: number; message: string; data?: unknown },
|
package/src/lsp/types.ts
CHANGED
|
@@ -399,7 +399,7 @@ export interface LspClient {
|
|
|
399
399
|
diagnostics: Map<string, PublishedDiagnostics>;
|
|
400
400
|
diagnosticsVersion: number;
|
|
401
401
|
openFiles: Map<string, OpenFile>;
|
|
402
|
-
pendingRequests: Map<number, PendingRequest>;
|
|
402
|
+
pendingRequests: Map<number | string, PendingRequest>;
|
|
403
403
|
messageBuffer: Uint8Array;
|
|
404
404
|
isReading: boolean;
|
|
405
405
|
/** Lifecycle state: "connecting" until initialize completes, then "ready"; "error" on init failure or reader death. */
|
|
@@ -420,16 +420,19 @@ export interface LspClient {
|
|
|
420
420
|
// JSON-RPC Protocol Types
|
|
421
421
|
// =============================================================================
|
|
422
422
|
|
|
423
|
+
/** JSON-RPC request/response identifier accepted by LSP peers. */
|
|
424
|
+
export type LspJsonRpcId = number | string;
|
|
425
|
+
|
|
423
426
|
export interface LspJsonRpcRequest {
|
|
424
427
|
jsonrpc: "2.0";
|
|
425
|
-
id:
|
|
428
|
+
id: LspJsonRpcId;
|
|
426
429
|
method: string;
|
|
427
430
|
params: unknown;
|
|
428
431
|
}
|
|
429
432
|
|
|
430
433
|
export interface LspJsonRpcResponse {
|
|
431
434
|
jsonrpc: "2.0";
|
|
432
|
-
id?:
|
|
435
|
+
id?: LspJsonRpcId;
|
|
433
436
|
result?: unknown;
|
|
434
437
|
error?: { code: number; message: string; data?: unknown };
|
|
435
438
|
}
|
|
@@ -25,8 +25,13 @@ export interface CacheInvalidation {
|
|
|
25
25
|
* request reads nothing from cache and re-pays for the whole prompt. We detect
|
|
26
26
|
* that as: the previous turn cached a meaningful prefix, yet this turn's
|
|
27
27
|
* `cacheRead` collapsed to zero while it still reprocessed a non-trivial prompt.
|
|
28
|
-
* Returns `undefined` (no marker) for the first turn, tiny contexts,
|
|
29
|
-
* that reused any cache
|
|
28
|
+
* Returns `undefined` (no marker) for the first turn, tiny contexts, turns
|
|
29
|
+
* that reused any cache, and — crucially — turns on providers with *implicit*
|
|
30
|
+
* best-effort caching. Only an explicit, prefix-controlled cache (Anthropic /
|
|
31
|
+
* Bedrock `cache_control`) re-creates the prefix on a cold turn (`cacheWrite >
|
|
32
|
+
* 0`); implicit caches (Google / OpenAI / Fireworks) report `cacheWrite: 0` and
|
|
33
|
+
* drop `cacheRead` to zero intermittently as routine propagation noise that
|
|
34
|
+
* self-heals the next turn, so flagging it would be a false positive.
|
|
30
35
|
*/
|
|
31
36
|
export function detectCacheInvalidation(prev: Usage | undefined, current: Usage): CacheInvalidation | undefined {
|
|
32
37
|
if (!prev) return undefined;
|
|
@@ -34,6 +39,11 @@ export function detectCacheInvalidation(prev: Usage | undefined, current: Usage)
|
|
|
34
39
|
if (prevFootprint < MIN_CACHE_FOOTPRINT) return undefined;
|
|
35
40
|
// Any cache reuse this turn means the prefix survived (at least partly).
|
|
36
41
|
if (current.cacheRead > 0) return undefined;
|
|
42
|
+
// Only an explicit, prefix-controlled cache re-creates the prefix on a cold
|
|
43
|
+
// turn — Anthropic/Bedrock report that as `cacheWrite`. Implicit best-effort
|
|
44
|
+
// caches (Google/OpenAI/Fireworks) report `cacheWrite: 0` and drop `cacheRead`
|
|
45
|
+
// to zero intermittently as propagation noise, not a real invalidation.
|
|
46
|
+
if (current.cacheWrite <= 0) return undefined;
|
|
37
47
|
const reprocessedTokens = current.cacheWrite + current.input;
|
|
38
48
|
if (reprocessedTokens < MIN_CACHE_FOOTPRINT) return undefined;
|
|
39
49
|
return { reprocessedTokens };
|
|
@@ -76,6 +76,13 @@ export type SettingDef = BooleanSettingDef | EnumSettingDef | SubmenuSettingDef
|
|
|
76
76
|
|
|
77
77
|
const CONDITIONS: Record<string, () => boolean> = {
|
|
78
78
|
hasImageProtocol: () => !!TERMINAL.imageProtocol,
|
|
79
|
+
advisorEnabled: () => {
|
|
80
|
+
try {
|
|
81
|
+
return Settings.instance.get("advisor.enabled") === true;
|
|
82
|
+
} catch {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
},
|
|
79
86
|
hindsightActive: () => {
|
|
80
87
|
try {
|
|
81
88
|
return Settings.instance.get("memory.backend") === "hindsight";
|
|
@@ -1344,19 +1344,15 @@ export class AgentSession {
|
|
|
1344
1344
|
if (process.platform !== "darwin") return;
|
|
1345
1345
|
if (isBunTestRuntime()) return;
|
|
1346
1346
|
if (this.#powerAssertion) return;
|
|
1347
|
-
const
|
|
1348
|
-
|
|
1349
|
-
const user = this.settings.get("power.declareUserActive");
|
|
1350
|
-
const display = this.settings.get("power.preventDisplaySleep");
|
|
1351
|
-
// All four off → user opted out; do nothing.
|
|
1352
|
-
if (!idle && !system && !user && !display) return;
|
|
1347
|
+
const mode = this.settings.get("power.sleepPrevention");
|
|
1348
|
+
if (mode === "off") return;
|
|
1353
1349
|
try {
|
|
1354
1350
|
this.#powerAssertion = MacOSPowerAssertion.start({
|
|
1355
1351
|
reason: "Oh My Pi agent session",
|
|
1356
|
-
idle,
|
|
1357
|
-
system,
|
|
1358
|
-
|
|
1359
|
-
|
|
1352
|
+
idle: true,
|
|
1353
|
+
display: mode === "display" || mode === "system",
|
|
1354
|
+
system: mode === "system",
|
|
1355
|
+
user: mode === "system",
|
|
1360
1356
|
});
|
|
1361
1357
|
} catch (error) {
|
|
1362
1358
|
logger.warn("Failed to acquire macOS power assertion", { error: String(error) });
|