@lexwdex-org/opencode-dcp 3.4.13 → 3.5.0
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/README.md +23 -15
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +573 -81
- package/dist/index.js.map +1 -1
- package/dist/lib/auto-prune.d.ts.map +1 -1
- package/dist/lib/config.d.ts +14 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/hooks.d.ts +24 -5
- package/dist/lib/hooks.d.ts.map +1 -1
- package/dist/lib/prune-service.d.ts +104 -0
- package/dist/lib/prune-service.d.ts.map +1 -0
- package/dist/lib/prune-tool.d.ts +2 -4
- package/dist/lib/prune-tool.d.ts.map +1 -1
- package/dist/lib/session-boundary.d.ts +90 -0
- package/dist/lib/session-boundary.d.ts.map +1 -0
- package/dist/lib/summarize.d.ts +3 -0
- package/dist/lib/summarize.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auto-prune.d.ts","sourceRoot":"","sources":["../../lib/auto-prune.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAE/C,MAAM,MAAM,WAAW,GAAG,aAAa,GAAG,QAAQ,GAAG,UAAU,CAAA;AAE/D,MAAM,WAAW,aAAa;IAC1B,OAAO,EAAE,WAAW,EAAE,CAAA;CACzB;AAUD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAiBlD;AAED,wBAAgB,OAAO,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,CAO9D;
|
|
1
|
+
{"version":3,"file":"auto-prune.d.ts","sourceRoot":"","sources":["../../lib/auto-prune.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAE/C,MAAM,MAAM,WAAW,GAAG,aAAa,GAAG,QAAQ,GAAG,UAAU,CAAA;AAE/D,MAAM,WAAW,aAAa;IAC1B,OAAO,EAAE,WAAW,EAAE,CAAA;CACzB;AAUD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAiBlD;AAED,wBAAgB,OAAO,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,CAO9D;AAwBD,qBAAa,UAAU;IAKf,OAAO,CAAC,QAAQ,CAAC,MAAM;IAJ3B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkC;IAC3D,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAc;gBAGb,MAAM,EAAE,eAAe,EACxC,GAAG,CAAC,EAAE,MAAM,MAAM;IAKtB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,SAAa,GAAG,aAAa;IAoBvF,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,SAAa,GAAG,WAAW,EAAE,GAAG,IAAI;IAUxE,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,SAAa,GAAG,IAAI;IASpD,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAIpC,OAAO,CAAC,QAAQ;IA8BhB,OAAO,CAAC,KAAK;CAYhB"}
|
package/dist/lib/config.d.ts
CHANGED
|
@@ -8,8 +8,15 @@ export interface ExperimentalConfig {
|
|
|
8
8
|
export interface SummarizeConfig {
|
|
9
9
|
failureCooldownMs: number;
|
|
10
10
|
}
|
|
11
|
+
export interface AutoPruneSignals {
|
|
12
|
+
topicDrift: boolean;
|
|
13
|
+
volume: boolean;
|
|
14
|
+
idleGap: boolean;
|
|
15
|
+
}
|
|
11
16
|
export interface AutoPruneConfig {
|
|
12
17
|
enabled: boolean;
|
|
18
|
+
/** Per-signal switches; only topic changes are enabled by default (LD1). */
|
|
19
|
+
signals: AutoPruneSignals;
|
|
13
20
|
minMessages: number;
|
|
14
21
|
volumeThreshold: number;
|
|
15
22
|
driftThreshold: number;
|
|
@@ -42,6 +49,13 @@ interface ValidationError {
|
|
|
42
49
|
actual: string;
|
|
43
50
|
}
|
|
44
51
|
export declare function validateConfigTypes(config: Record<string, any>): ValidationError[];
|
|
52
|
+
/**
|
|
53
|
+
* SR1 migration hint condition: auto prune is on but the user config predates
|
|
54
|
+
* the per-signal switches. The hint fires on every config load where this
|
|
55
|
+
* holds (same always-fires, stateless mechanism as the compress.* hints — no
|
|
56
|
+
* persistent "one-time" flag).
|
|
57
|
+
*/
|
|
58
|
+
export declare function needsSignalsMigrationHint(configData: Record<string, any>): boolean;
|
|
45
59
|
export declare function getConfig(ctx: PluginInput): PluginConfig;
|
|
46
60
|
export {};
|
|
47
61
|
//# sourceMappingURL=config.d.ts.map
|
package/dist/lib/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../lib/config.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAEtD,MAAM,WAAW,QAAQ;IACrB,OAAO,EAAE,OAAO,CAAA;CACnB;AAED,MAAM,WAAW,kBAAkB;IAC/B,aAAa,EAAE,OAAO,CAAA;CACzB;AAED,MAAM,WAAW,eAAe;IAC5B,iBAAiB,EAAE,MAAM,CAAA;CAC5B;AAED,MAAM,WAAW,eAAe;IAC5B,OAAO,EAAE,OAAO,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,eAAe,EAAE,MAAM,CAAA;IACvB,cAAc,EAAE,MAAM,CAAA;IACtB,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,UAAU;IACvB,OAAO,EAAE,OAAO,CAAA;CACnB;AAED,MAAM,MAAM,WAAW,GAAG,IAAI,GAAG,IAAI,CAAA;AAErC,MAAM,WAAW,YAAY;IACzB,OAAO,EAAE,OAAO,CAAA;IAChB,UAAU,EAAE,OAAO,CAAA;IACnB,KAAK,EAAE,OAAO,CAAA;IACd,QAAQ,EAAE,WAAW,CAAA;IACrB,QAAQ,EAAE,QAAQ,CAAA;IAClB,YAAY,EAAE,kBAAkB,CAAA;IAChC,SAAS,EAAE,eAAe,CAAA;IAC1B,SAAS,EAAE,eAAe,CAAA;IAC1B,IAAI,EAAE,UAAU,CAAA;CACnB;AAID,eAAO,MAAM,kBAAkB,EAAE,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../lib/config.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAEtD,MAAM,WAAW,QAAQ;IACrB,OAAO,EAAE,OAAO,CAAA;CACnB;AAED,MAAM,WAAW,kBAAkB;IAC/B,aAAa,EAAE,OAAO,CAAA;CACzB;AAED,MAAM,WAAW,eAAe;IAC5B,iBAAiB,EAAE,MAAM,CAAA;CAC5B;AAED,MAAM,WAAW,gBAAgB;IAC7B,UAAU,EAAE,OAAO,CAAA;IACnB,MAAM,EAAE,OAAO,CAAA;IACf,OAAO,EAAE,OAAO,CAAA;CACnB;AAED,MAAM,WAAW,eAAe;IAC5B,OAAO,EAAE,OAAO,CAAA;IAChB,4EAA4E;IAC5E,OAAO,EAAE,gBAAgB,CAAA;IACzB,WAAW,EAAE,MAAM,CAAA;IACnB,eAAe,EAAE,MAAM,CAAA;IACvB,cAAc,EAAE,MAAM,CAAA;IACtB,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,UAAU;IACvB,OAAO,EAAE,OAAO,CAAA;CACnB;AAED,MAAM,MAAM,WAAW,GAAG,IAAI,GAAG,IAAI,CAAA;AAErC,MAAM,WAAW,YAAY;IACzB,OAAO,EAAE,OAAO,CAAA;IAChB,UAAU,EAAE,OAAO,CAAA;IACnB,KAAK,EAAE,OAAO,CAAA;IACd,QAAQ,EAAE,WAAW,CAAA;IACrB,QAAQ,EAAE,QAAQ,CAAA;IAClB,YAAY,EAAE,kBAAkB,CAAA;IAChC,SAAS,EAAE,eAAe,CAAA;IAC1B,SAAS,EAAE,eAAe,CAAA;IAC1B,IAAI,EAAE,UAAU,CAAA;CACnB;AAID,eAAO,MAAM,kBAAkB,EAAE,eAQhC,CAAA;AAED,eAAO,MAAM,iBAAiB,aAyB5B,CAAA;AAKF,eAAO,MAAM,sBAAsB,aA0CjC,CAAA;AAeF,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,EAAE,CAEjF;AAED,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,EAAE,CAI9E;AAED,UAAU,eAAe;IACrB,GAAG,EAAE,MAAM,CAAA;IACX,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;CACjB;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,eAAe,EAAE,CA4KlF;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CASlF;AA2UD,wBAAgB,SAAS,CAAC,GAAG,EAAE,WAAW,GAAG,YAAY,CAsCxD"}
|
package/dist/lib/hooks.d.ts
CHANGED
|
@@ -3,7 +3,8 @@ import type { Logger } from "./logger";
|
|
|
3
3
|
import type { OpenCodeClient } from "./opencode-client";
|
|
4
4
|
import type { PromptStore } from "./prompts/store";
|
|
5
5
|
import type { AutoPruner } from "./auto-prune";
|
|
6
|
-
import type {
|
|
6
|
+
import type { PruneService } from "./prune-service";
|
|
7
|
+
import type { RestFireReason } from "./session-boundary";
|
|
7
8
|
interface CompactionOutput {
|
|
8
9
|
context: string[];
|
|
9
10
|
prompt?: string;
|
|
@@ -15,19 +16,37 @@ export declare function createChatMessageHandler(autoPruner: AutoPruner): (input
|
|
|
15
16
|
sessionID: string;
|
|
16
17
|
}, _output?: unknown) => Promise<void>;
|
|
17
18
|
export interface EventHandlerDeps {
|
|
18
|
-
|
|
19
|
-
summarize: SummarizeCoordinator;
|
|
19
|
+
prune: PruneService;
|
|
20
20
|
autoPruner: AutoPruner;
|
|
21
|
-
config: AutoPruneConfig;
|
|
22
21
|
logger: Logger;
|
|
23
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* Every host event feeds the PruneService first: `session.status` / legacy
|
|
25
|
+
* `session.idle` observations go to the boundary tracker, which classifies
|
|
26
|
+
* at-rest boundaries (quiet window + live probe) and drives both the
|
|
27
|
+
* deferred-prune drain and the at-rest auto-prune listener. This handler only
|
|
28
|
+
* keeps the heuristic pruner's own lifecycle state in sync.
|
|
29
|
+
*/
|
|
24
30
|
export declare function createEventHandler(deps: EventHandlerDeps): (input: {
|
|
25
31
|
event: {
|
|
26
32
|
type: string;
|
|
27
33
|
properties?: Record<string, any>;
|
|
28
34
|
};
|
|
29
35
|
}) => Promise<void>;
|
|
30
|
-
export
|
|
36
|
+
export interface AtRestAutoPruneDeps {
|
|
37
|
+
client: OpenCodeClient;
|
|
38
|
+
prune: PruneService;
|
|
39
|
+
autoPruner: AutoPruner;
|
|
40
|
+
config: AutoPruneConfig;
|
|
41
|
+
logger: Logger;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* At-rest listener #2: the heuristic auto prune. The `enabled` gate stays at
|
|
45
|
+
* this mount point — a tool-only configuration (auto prune disabled) never
|
|
46
|
+
* registers the listener, so it gains no auto-prune behavior.
|
|
47
|
+
*/
|
|
48
|
+
export declare function createAtRestAutoPruneListener(deps: AtRestAutoPruneDeps): (sessionID: string, _reason: RestFireReason) => Promise<void>;
|
|
49
|
+
export declare function createCommandExecuteHandler(client: OpenCodeClient, prune: PruneService, logger: Logger): (input: {
|
|
31
50
|
command: string;
|
|
32
51
|
sessionID: string;
|
|
33
52
|
arguments: string;
|
package/dist/lib/hooks.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../lib/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAC/C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAClD,OAAO,KAAK,EAAe,UAAU,EAAE,MAAM,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../lib/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAC/C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAClD,OAAO,KAAK,EAAe,UAAU,EAAE,MAAM,cAAc,CAAA;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAGxD,UAAU,gBAAgB;IACtB,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,IACjE,OAAO;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,EAAE,QAAQ,gBAAgB,KAAG,OAAO,CAAC,IAAI,CAAC,CAiBvF;AAeD,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,UAAU,IAC7C,OAAO;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,EAAE,UAAU,OAAO,KAAG,OAAO,CAAC,IAAI,CAAC,CAIhF;AAQD,MAAM,WAAW,gBAAgB;IAC7B,KAAK,EAAE,YAAY,CAAA;IACnB,UAAU,EAAE,UAAU,CAAA;IACtB,MAAM,EAAE,MAAM,CAAA;CACjB;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,gBAAgB,IACvC,OAAO;IAAE,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;KAAE,CAAA;CAAE,mBAoBrF;AAoDD,MAAM,WAAW,mBAAmB;IAChC,MAAM,EAAE,cAAc,CAAA;IACtB,KAAK,EAAE,YAAY,CAAA;IACnB,UAAU,EAAE,UAAU,CAAA;IACtB,MAAM,EAAE,eAAe,CAAA;IACvB,MAAM,EAAE,MAAM,CAAA;CACjB;AAED;;;;GAIG;AACH,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,mBAAmB,IACrD,WAAW,MAAM,EAAE,SAAS,cAAc,KAAG,OAAO,CAAC,IAAI,CAAC,CAK3E;AAED,wBAAgB,2BAA2B,CACvC,MAAM,EAAE,cAAc,EACtB,KAAK,EAAE,YAAY,EACnB,MAAM,EAAE,MAAM,IAGV,OAAO;IACH,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;CACpB,EACD,UAAU;IAAE,KAAK,EAAE,OAAO,EAAE,CAAA;CAAE,KAC/B,OAAO,CAAC,IAAI,CAAC,CAuDnB"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import type { Logger } from "./logger";
|
|
2
|
+
import type { OpenCodeClient } from "./opencode-client";
|
|
3
|
+
import { SessionBoundaryTracker } from "./session-boundary";
|
|
4
|
+
import type { SummarizeCoordinator } from "./summarize";
|
|
5
|
+
export { eventSessionID, retrySeconds } from "./session-boundary";
|
|
6
|
+
/**
|
|
7
|
+
* How a trigger surface wants the service to react when the session is (or may
|
|
8
|
+
* be) mid-turn:
|
|
9
|
+
* - `"defer"`: compaction must never interrupt a running turn. Queue the prune
|
|
10
|
+
* and execute it at the next confirmed at-rest boundary. Used by the
|
|
11
|
+
* model-invokable tool, which by definition executes mid-turn.
|
|
12
|
+
* - `"proceed"`: fire at turn boundaries anyway; only stand down on positive
|
|
13
|
+
* busy evidence. Used by at-rest-driven auto prune and the manual command.
|
|
14
|
+
*/
|
|
15
|
+
export type PruneBusyPolicy = "defer" | "proceed";
|
|
16
|
+
export type PruneOutcome = {
|
|
17
|
+
status: "succeeded";
|
|
18
|
+
} | {
|
|
19
|
+
status: "deferred";
|
|
20
|
+
} | {
|
|
21
|
+
status: "busy";
|
|
22
|
+
} | {
|
|
23
|
+
status: "no-model";
|
|
24
|
+
} | {
|
|
25
|
+
status: "cooldown";
|
|
26
|
+
retryAfterMs: number;
|
|
27
|
+
} | {
|
|
28
|
+
status: "failed";
|
|
29
|
+
error: string;
|
|
30
|
+
};
|
|
31
|
+
export interface PruneRequest {
|
|
32
|
+
sessionID: string;
|
|
33
|
+
onBusy: PruneBusyPolicy;
|
|
34
|
+
}
|
|
35
|
+
export interface PruneServiceDeps {
|
|
36
|
+
client: OpenCodeClient;
|
|
37
|
+
summarize: SummarizeCoordinator;
|
|
38
|
+
logger: Logger;
|
|
39
|
+
/** Injectable clock/timers (tests). BOUNDARY_QUIET_MS stays a code constant. */
|
|
40
|
+
now?: () => number;
|
|
41
|
+
setTimer?: (fn: () => void, ms: number) => unknown;
|
|
42
|
+
clearTimer?: (t: unknown) => void;
|
|
43
|
+
/** Injectable probe deadline (tests only; defaults to PROBE_TIMEOUT_MS). */
|
|
44
|
+
probeTimeoutMs?: number;
|
|
45
|
+
}
|
|
46
|
+
/** Host event names this service derives safety decisions from. */
|
|
47
|
+
export type PruneEventName = "session.idle" | "session.status" | "session.compacted" | "session.deleted" | (string & {});
|
|
48
|
+
/**
|
|
49
|
+
* The single compression entry point. Every trigger surface (model tool,
|
|
50
|
+
* heuristic auto prune, manual command) goes through `request`; the service
|
|
51
|
+
* owns everything a caller must not have to know: session busy state, the
|
|
52
|
+
* never-interrupt-a-running-turn invariant, deferral to the next confirmed
|
|
53
|
+
* at-rest boundary, session model resolution, and delegation to the native
|
|
54
|
+
* summarize coordinator (single-flight + failure cooldown).
|
|
55
|
+
*
|
|
56
|
+
* `request` never rejects: every failure mode is a `PruneOutcome`.
|
|
57
|
+
*/
|
|
58
|
+
export declare class PruneService {
|
|
59
|
+
private readonly deferred;
|
|
60
|
+
private readonly client;
|
|
61
|
+
private readonly summarize;
|
|
62
|
+
private readonly logger;
|
|
63
|
+
private readonly probeTimeoutMs;
|
|
64
|
+
/** THE single busy/idle event state machine (absorbed the former
|
|
65
|
+
* SessionActivityTracker — no second busy cache may exist). */
|
|
66
|
+
readonly boundary: SessionBoundaryTracker;
|
|
67
|
+
constructor(deps: PruneServiceDeps);
|
|
68
|
+
/**
|
|
69
|
+
* Feed every host event through here. `session.status` and legacy
|
|
70
|
+
* `session.idle` feed the boundary tracker (quiet window + expiry probe);
|
|
71
|
+
* the deferral queue drains at the confirmed at-rest classification, and
|
|
72
|
+
* queued prunes are forgotten once a compaction (or the session itself)
|
|
73
|
+
* is gone.
|
|
74
|
+
*/
|
|
75
|
+
observeEvent(type: PruneEventName, properties?: Record<string, any>): void;
|
|
76
|
+
request(request: PruneRequest): Promise<PruneOutcome>;
|
|
77
|
+
/** One admission check; `null` means the request may proceed. */
|
|
78
|
+
private gate;
|
|
79
|
+
/**
|
|
80
|
+
* Executes a queued prune at the confirmed at-rest boundary. The tool
|
|
81
|
+
* already promised its caller this prune would run; losing the busy race
|
|
82
|
+
* must not silently break that promise, so a busy outcome re-queues for
|
|
83
|
+
* the next at-rest boundary. Every other outcome is terminal: it is
|
|
84
|
+
* logged and never retried — new prune demand arrives through new
|
|
85
|
+
* triggers only. Execution is re-guarded on every attempt, so re-queueing
|
|
86
|
+
* never violates the never-interrupt invariant.
|
|
87
|
+
*/
|
|
88
|
+
private drainQueued;
|
|
89
|
+
/**
|
|
90
|
+
* Turns an admission decision into a terminal outcome, or `null` when the
|
|
91
|
+
* request may proceed. Deferral additionally enqueues the session.
|
|
92
|
+
*/
|
|
93
|
+
private outcomeFor;
|
|
94
|
+
private admit;
|
|
95
|
+
/**
|
|
96
|
+
* THE single live busy probe, reused verbatim by the boundary tracker's
|
|
97
|
+
* expiry check. Bounded by a finite deadline: a never-returning probe
|
|
98
|
+
* resolves `null` within the timeout (fail-open). Returns `null` when the
|
|
99
|
+
* answer is unknown (endpoint or SDK method missing, request failed,
|
|
100
|
+
* timeout) — callers must fail open in that case.
|
|
101
|
+
*/
|
|
102
|
+
probeBusy(sessionID: string): Promise<boolean | null>;
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=prune-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prune-service.d.ts","sourceRoot":"","sources":["../../lib/prune-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAEvD,OAAO,EAEH,sBAAsB,EAGzB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAEvD,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAEjE;;;;;;;;GAQG;AACH,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,SAAS,CAAA;AAEjD,MAAM,MAAM,YAAY,GAClB;IAAE,MAAM,EAAE,WAAW,CAAA;CAAE,GACvB;IAAE,MAAM,EAAE,UAAU,CAAA;CAAE,GACtB;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,GAClB;IAAE,MAAM,EAAE,UAAU,CAAA;CAAE,GACtB;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAC5C;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAA;AAEzC,MAAM,WAAW,YAAY;IACzB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,eAAe,CAAA;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAC7B,MAAM,EAAE,cAAc,CAAA;IACtB,SAAS,EAAE,oBAAoB,CAAA;IAC/B,MAAM,EAAE,MAAM,CAAA;IACd,gFAAgF;IAChF,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,IAAI,EAAE,EAAE,EAAE,MAAM,KAAK,OAAO,CAAA;IAClD,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;IACjC,4EAA4E;IAC5E,cAAc,CAAC,EAAE,MAAM,CAAA;CAC1B;AAID,mEAAmE;AACnE,MAAM,MAAM,cAAc,GACpB,cAAc,GACd,gBAAgB,GAChB,mBAAmB,GACnB,iBAAiB,GACjB,CAAC,MAAM,GAAG,EAAE,CAAC,CAAA;AAEnB;;;;;;;;;GASG;AACH,qBAAa,YAAY;IACrB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAoB;IAC7C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAsB;IAChD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;IAC/B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAQ;IACvC;mEAC+D;IAC/D,QAAQ,CAAC,QAAQ,EAAE,sBAAsB,CAAA;gBAE7B,IAAI,EAAE,gBAAgB;IAqBlC;;;;;;OAMG;IACH,YAAY,CAAC,IAAI,EAAE,cAAc,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI;IAwBpE,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;IAmC3D,iEAAiE;IACjE,OAAO,CAAC,IAAI;IAIZ;;;;;;;;OAQG;YACW,WAAW;IAqBzB;;;OAGG;YACW,UAAU;IAaxB,OAAO,CAAC,KAAK;IAUb;;;;;;OAMG;IACG,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;CAqB9D"}
|
package/dist/lib/prune-tool.d.ts
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import type { Logger } from "./logger";
|
|
2
|
-
import type {
|
|
3
|
-
import type { SummarizeCoordinator } from "./summarize";
|
|
2
|
+
import type { PruneService } from "./prune-service";
|
|
4
3
|
export declare const PRUNE_TOOL_NAME = "dcp_prune";
|
|
5
4
|
export interface PruneToolDeps {
|
|
6
|
-
|
|
7
|
-
summarize: SummarizeCoordinator;
|
|
5
|
+
prune: PruneService;
|
|
8
6
|
logger: Logger;
|
|
9
7
|
}
|
|
10
8
|
export declare function createPruneTool(deps: PruneToolDeps): {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prune-tool.d.ts","sourceRoot":"","sources":["../../lib/prune-tool.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACtC,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"prune-tool.d.ts","sourceRoot":"","sources":["../../lib/prune-tool.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACtC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAGnD,eAAO,MAAM,eAAe,cAAc,CAAA;AAU1C,MAAM,WAAW,aAAa;IAC1B,KAAK,EAAE,YAAY,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;CACjB;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,aAAa;;;;EA6BlD"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import type { Logger } from "./logger";
|
|
2
|
+
/**
|
|
3
|
+
* Per-session boundary phase. The compression boundary is NOT the raw
|
|
4
|
+
* `session.idle` instant: an idle observation opens a quiet window, and only
|
|
5
|
+
* a window that survives its full duration plus a live status probe is
|
|
6
|
+
* classified as AT-REST. Busy/retry evidence at any point cancels the window.
|
|
7
|
+
*/
|
|
8
|
+
export type BoundaryPhase = "unknown" | "busy" | "pending-rest" | "at-rest";
|
|
9
|
+
/** Why an at-rest classification fired. `probe-failopen` covers a missing
|
|
10
|
+
* endpoint, an HTTP error, and a timed-out probe — all fail open. */
|
|
11
|
+
export type RestFireReason = "window-expired" | "probe-failopen";
|
|
12
|
+
export type AtRestListener = (sessionID: string, reason: RestFireReason) => void | Promise<void>;
|
|
13
|
+
/** Internal constants — deliberately NOT config: safety semantics, not user
|
|
14
|
+
* preference (design ADR-0004). Clock and timers are injectable for tests. */
|
|
15
|
+
export declare const BOUNDARY_QUIET_MS = 2000;
|
|
16
|
+
export declare const PROBE_TIMEOUT_MS = 2000;
|
|
17
|
+
export interface SessionBoundaryDeps {
|
|
18
|
+
/** THE single busy probe (PruneService.probeBusy), injected — never
|
|
19
|
+
* imported, so this module never depends on prune-service. */
|
|
20
|
+
probeBusy: (sessionID: string) => Promise<boolean | null>;
|
|
21
|
+
logger: Logger;
|
|
22
|
+
now?: () => number;
|
|
23
|
+
setTimer?: (fn: () => void, ms: number) => unknown;
|
|
24
|
+
clearTimer?: (t: unknown) => void;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Classifies turn boundaries as AT-REST or relay-idle. Owns the ONLY
|
|
28
|
+
* per-session busy/idle event state machine (it absorbed the former
|
|
29
|
+
* SessionActivityTracker): exactly one entry per session, LRU-bounded.
|
|
30
|
+
*
|
|
31
|
+
* State model per session:
|
|
32
|
+
* - unknown no evidence (fresh, TTL-decayed, or post-lifecycle); fail-open
|
|
33
|
+
* - busy busy/retry evidence cached; TTL-decays to unknown
|
|
34
|
+
* - pending-rest quiet window armed (BOUNDARY_QUIET_MS); busy/retry cancels
|
|
35
|
+
* - at-rest rest confirmed; onAtRest fired once
|
|
36
|
+
*
|
|
37
|
+
* Idle handling: `pending-rest` + idle -> ignore (dual-publish second leg).
|
|
38
|
+
* `at-rest` + idle -> ignore on status-capable hosts (T1/T2: a real next turn
|
|
39
|
+
* is preceded by a busy/retry status that exits at-rest first). In degrade
|
|
40
|
+
* mode (T3: no status observation ever received) a legacy idle from at-rest
|
|
41
|
+
* RE-ARMS the window — every turn-end idle is a new boundary candidate.
|
|
42
|
+
*/
|
|
43
|
+
export declare class SessionBoundaryTracker {
|
|
44
|
+
private readonly sessions;
|
|
45
|
+
private readonly listeners;
|
|
46
|
+
private readonly probeBusy;
|
|
47
|
+
private readonly logger;
|
|
48
|
+
private readonly now;
|
|
49
|
+
private readonly setTimer;
|
|
50
|
+
private readonly clearTimer;
|
|
51
|
+
constructor(deps: SessionBoundaryDeps);
|
|
52
|
+
/** Register an at-rest listener; listeners fire in registration order
|
|
53
|
+
* (1. deferred drain, 2. heuristic auto prune) and are individually
|
|
54
|
+
* error-isolated: a throw or rejection is warn-logged and never blocks
|
|
55
|
+
* later listeners nor escapes into the timer callback. */
|
|
56
|
+
onAtRest(listener: AtRestListener): void;
|
|
57
|
+
/** Primary input: `session.status` event payload status type. */
|
|
58
|
+
observeStatus(sessionID: string | undefined, statusType: unknown): void;
|
|
59
|
+
/** First-class input: legacy `session.idle`. Absorbed by dedup on hosts
|
|
60
|
+
* that dual-publish; the only boundary signal on status-less hosts (T3). */
|
|
61
|
+
observeLegacyIdle(sessionID: string | undefined): void;
|
|
62
|
+
/** Lifecycle: cancel any pending window and forget the session. */
|
|
63
|
+
observeDeleted(sessionID: string | undefined): void;
|
|
64
|
+
/** Lifecycle: compaction ended; reset to unknown so the next idle opens a
|
|
65
|
+
* fresh window. */
|
|
66
|
+
observeCompacted(sessionID: string | undefined): void;
|
|
67
|
+
/** Absorbed busy-evidence cache: `busy` decays to `unknown` after the TTL;
|
|
68
|
+
* the table is LRU-bounded (pending-rest/at-rest entries have no TTL exit
|
|
69
|
+
* and rely on the cap). */
|
|
70
|
+
state(sessionID: string): BoundaryPhase;
|
|
71
|
+
dispose(sessionID: string): void;
|
|
72
|
+
private observeIdle;
|
|
73
|
+
private armWindow;
|
|
74
|
+
private onWindowExpiry;
|
|
75
|
+
private transition;
|
|
76
|
+
private cancelWindow;
|
|
77
|
+
private fireAtRest;
|
|
78
|
+
private entry;
|
|
79
|
+
private refresh;
|
|
80
|
+
private evictIfNeeded;
|
|
81
|
+
}
|
|
82
|
+
/** Ceil a cooldown to whole seconds for user-facing copy. */
|
|
83
|
+
export declare function retrySeconds(retryAfterMs: number): number;
|
|
84
|
+
/**
|
|
85
|
+
* Resolves the session ID from a host event's properties. Most events carry
|
|
86
|
+
* `sessionID` directly, but some (e.g. `session.deleted`) only carry
|
|
87
|
+
* `info: Session`. Returns `undefined` when neither is a non-empty string.
|
|
88
|
+
*/
|
|
89
|
+
export declare function eventSessionID(properties?: Record<string, any>): string | undefined;
|
|
90
|
+
//# sourceMappingURL=session-boundary.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-boundary.d.ts","sourceRoot":"","sources":["../../lib/session-boundary.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AAEtC;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,MAAM,GAAG,cAAc,GAAG,SAAS,CAAA;AAE3E;qEACqE;AACrE,MAAM,MAAM,cAAc,GAAG,gBAAgB,GAAG,gBAAgB,CAAA;AAEhE,MAAM,MAAM,cAAc,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;AAEhG;8EAC8E;AAC9E,eAAO,MAAM,iBAAiB,OAAQ,CAAA;AACtC,eAAO,MAAM,gBAAgB,OAAQ,CAAA;AAMrC,MAAM,WAAW,mBAAmB;IAChC;kEAC8D;IAC9D,SAAS,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAA;IACzD,MAAM,EAAE,MAAM,CAAA;IACd,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,IAAI,EAAE,EAAE,EAAE,MAAM,KAAK,OAAO,CAAA;IAClD,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;CACpC;AAeD;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,sBAAsB;IAC/B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkC;IAC3D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAuB;IACjD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAgD;IAC1E,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;IAC/B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAc;IAClC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAyC;IAClE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAsB;gBAErC,IAAI,EAAE,mBAAmB;IASrC;;;8DAG0D;IAC1D,QAAQ,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI;IAIxC,iEAAiE;IACjE,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE,UAAU,EAAE,OAAO,GAAG,IAAI;IAkBvE;gFAC4E;IAC5E,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAKtD,mEAAmE;IACnE,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IASnD;uBACmB;IACnB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAgBrD;;+BAE2B;IAC3B,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,aAAa;IAavC,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAIhC,OAAO,CAAC,WAAW;IAyBnB,OAAO,CAAC,SAAS;YAeH,cAAc;IAyC5B,OAAO,CAAC,UAAU;IAelB,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,UAAU;IAqBlB,OAAO,CAAC,KAAK;IAYb,OAAO,CAAC,OAAO;IAMf,OAAO,CAAC,aAAa;CAQxB;AAED,6DAA6D;AAC7D,wBAAgB,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,GAAG,SAAS,CAMnF"}
|
package/dist/lib/summarize.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"summarize.d.ts","sourceRoot":"","sources":["../../lib/summarize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAEvD,MAAM,WAAW,gBAAgB;IAC7B,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE;QACH,UAAU,EAAE,MAAM,CAAA;QAClB,OAAO,EAAE,MAAM,CAAA;KAClB,CAAA;CACJ;AAED,MAAM,MAAM,eAAe,GACrB;IAAE,MAAM,EAAE,WAAW,CAAA;CAAE,GACvB;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACnC;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAAA;AAElD,UAAU,2BAA2B;IACjC,iBAAiB,EAAE,MAAM,CAAA;IACzB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;CACrB;
|
|
1
|
+
{"version":3,"file":"summarize.d.ts","sourceRoot":"","sources":["../../lib/summarize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAEvD,MAAM,WAAW,gBAAgB;IAC7B,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE;QACH,UAAU,EAAE,MAAM,CAAA;QAClB,OAAO,EAAE,MAAM,CAAA;KAClB,CAAA;CACJ;AAED,MAAM,MAAM,eAAe,GACrB;IAAE,MAAM,EAAE,WAAW,CAAA;CAAE,GACvB;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACtC;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACnC;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAAA;AAElD,UAAU,2BAA2B;IACjC,iBAAiB,EAAE,MAAM,CAAA;IACzB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;CACrB;AAwCD,qBAAa,oBAAoB;IAMzB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAP5B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA8C;IACvE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA4B;IACrD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAc;gBAGb,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,2BAA2B;IAKzD,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC;YAsBhD,YAAY;CA8B7B"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
3
|
"name": "@lexwdex-org/opencode-dcp",
|
|
4
|
-
"version": "3.
|
|
4
|
+
"version": "3.5.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Semantic pruning for OpenCode native context compaction",
|
|
7
7
|
"main": "./dist/index.js",
|