@nghyane/arcane 0.1.29 → 0.1.30
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/package.json +4 -4
- package/src/cli/config-cli.ts +1 -1
- package/src/config/settings-schema.ts +19 -27
- package/src/config/settings.ts +3 -4
- package/src/extensibility/custom-tools/types.ts +0 -12
- package/src/extensibility/extensions/index.ts +0 -5
- package/src/extensibility/extensions/runner.ts +6 -26
- package/src/extensibility/extensions/types.ts +1 -77
- package/src/extensibility/hooks/runner.ts +5 -24
- package/src/extensibility/hooks/types.ts +1 -77
- package/src/index.ts +2 -13
- package/src/modes/components/footer.ts +4 -11
- package/src/modes/components/index.ts +0 -1
- package/src/modes/components/status-line/segments.ts +1 -2
- package/src/modes/components/status-line/types.ts +0 -1
- package/src/modes/components/status-line.ts +0 -6
- package/src/modes/components/tree-selector.ts +0 -8
- package/src/modes/controllers/command-controller.ts +2 -98
- package/src/modes/controllers/event-controller.ts +46 -52
- package/src/modes/controllers/extension-ui-controller.ts +0 -42
- package/src/modes/controllers/input-controller.ts +0 -23
- package/src/modes/controllers/selector-controller.ts +0 -5
- package/src/modes/interactive-mode.ts +3 -24
- package/src/modes/print-mode.ts +0 -16
- package/src/modes/rpc/rpc-client.ts +0 -16
- package/src/modes/rpc/rpc-mode.ts +0 -32
- package/src/modes/rpc/rpc-types.ts +0 -9
- package/src/modes/types.ts +1 -13
- package/src/modes/utils/ui-helpers.ts +2 -118
- package/src/sdk.ts +0 -15
- package/src/session/agent-session.ts +89 -650
- package/src/session/compaction/branch-summarization.ts +5 -13
- package/src/session/compaction/index.ts +0 -1
- package/src/session/compaction/utils.ts +94 -2
- package/src/session/messages.ts +0 -37
- package/src/session/retry-utils.ts +1 -1
- package/src/session/session-manager.ts +8 -108
- package/src/session/session-types.ts +4 -25
- package/src/session/stats.ts +2 -39
- package/src/slash-commands/builtin-registry.ts +0 -11
- package/src/task/executor.ts +0 -8
- package/examples/hooks/custom-compaction.ts +0 -116
- package/src/modes/components/compaction-summary-message.ts +0 -59
- package/src/prompts/compaction/compaction-short-summary.md +0 -9
- package/src/prompts/compaction/compaction-summary-context.md +0 -5
- package/src/prompts/compaction/compaction-summary.md +0 -41
- package/src/prompts/compaction/compaction-turn-prefix.md +0 -17
- package/src/prompts/compaction/compaction-update-summary.md +0 -45
- package/src/session/compaction/compaction.ts +0 -864
- package/src/session/compaction/pruning.ts +0 -91
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@nghyane/arcane",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.30",
|
|
5
5
|
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
|
6
6
|
"homepage": "https://github.com/nghyane/arcane",
|
|
7
7
|
"author": "Can Bölük",
|
|
@@ -44,9 +44,9 @@
|
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"@mozilla/readability": "0.6.0",
|
|
47
|
-
"@nghyane/arcane-stats": "^0.1.
|
|
48
|
-
"@nghyane/arcane-agent": "^0.1.
|
|
49
|
-
"@nghyane/arcane-ai": "^0.1.
|
|
47
|
+
"@nghyane/arcane-stats": "^0.1.15",
|
|
48
|
+
"@nghyane/arcane-agent": "^0.1.19",
|
|
49
|
+
"@nghyane/arcane-ai": "^0.1.15",
|
|
50
50
|
"@nghyane/arcane-natives": "^0.1.11",
|
|
51
51
|
"@nghyane/arcane-tui": "^0.1.15",
|
|
52
52
|
"@nghyane/arcane-utils": "^0.1.8",
|
package/src/cli/config-cli.ts
CHANGED
|
@@ -346,7 +346,7 @@ ${chalk.bold("Examples:")}
|
|
|
346
346
|
${APP_NAME} config list
|
|
347
347
|
${APP_NAME} config get theme
|
|
348
348
|
${APP_NAME} config set theme catppuccin-mocha
|
|
349
|
-
${APP_NAME} config set
|
|
349
|
+
${APP_NAME} config set retry.enabled false
|
|
350
350
|
${APP_NAME} config set defaultThinkingLevel medium
|
|
351
351
|
${APP_NAME} config reset steeringMode
|
|
352
352
|
${APP_NAME} config list --json
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* - Optional UI metadata (label, description, tab)
|
|
7
7
|
*
|
|
8
8
|
* The Settings singleton provides type-safe path-based access:
|
|
9
|
-
* settings.get("
|
|
9
|
+
* settings.get("retry.enabled") // => boolean
|
|
10
10
|
* settings.set("theme.dark", "titanium") // sync, saves in background
|
|
11
11
|
*/
|
|
12
12
|
|
|
@@ -296,10 +296,22 @@ export const SETTINGS_SCHEMA = {
|
|
|
296
296
|
ui: {
|
|
297
297
|
tab: "agent",
|
|
298
298
|
label: "Auto-promote context",
|
|
299
|
-
description: "Promote to a larger-context model on context overflow
|
|
299
|
+
description: "Promote to a larger-context model on context overflow",
|
|
300
300
|
},
|
|
301
301
|
},
|
|
302
302
|
|
|
303
|
+
"autoHandoff.enabled": {
|
|
304
|
+
type: "boolean",
|
|
305
|
+
default: true,
|
|
306
|
+
ui: {
|
|
307
|
+
tab: "agent",
|
|
308
|
+
label: "Auto-handoff",
|
|
309
|
+
description: "Automatically hand off to a new session when context window is nearly full",
|
|
310
|
+
},
|
|
311
|
+
},
|
|
312
|
+
"autoHandoff.warningThreshold": { type: "number", default: 80 },
|
|
313
|
+
"autoHandoff.handoffThreshold": { type: "number", default: 95 },
|
|
314
|
+
|
|
303
315
|
// ─────────────────────────────────────────────────────────────────────────
|
|
304
316
|
// Secrets settings
|
|
305
317
|
// ─────────────────────────────────────────────────────────────────────────
|
|
@@ -309,23 +321,6 @@ export const SETTINGS_SCHEMA = {
|
|
|
309
321
|
ui: { tab: "config", label: "Hide secrets", description: "Obfuscate secrets before sending to AI providers" },
|
|
310
322
|
},
|
|
311
323
|
|
|
312
|
-
// ─────────────────────────────────────────────────────────────────────────
|
|
313
|
-
// Compaction settings
|
|
314
|
-
// ─────────────────────────────────────────────────────────────────────────
|
|
315
|
-
"compaction.enabled": {
|
|
316
|
-
type: "boolean",
|
|
317
|
-
default: true,
|
|
318
|
-
ui: {
|
|
319
|
-
tab: "agent",
|
|
320
|
-
label: "Auto-compact",
|
|
321
|
-
description: "Automatically compact context when it gets too large",
|
|
322
|
-
},
|
|
323
|
-
},
|
|
324
|
-
"compaction.reserveTokens": { type: "number", default: 16384 },
|
|
325
|
-
"compaction.keepRecentTokens": { type: "number", default: 20000 },
|
|
326
|
-
"compaction.autoContinue": { type: "boolean", default: true },
|
|
327
|
-
"compaction.remoteEndpoint": { type: "string", default: undefined },
|
|
328
|
-
|
|
329
324
|
// ─────────────────────────────────────────────────────────────────────────
|
|
330
325
|
// Branch summary settings
|
|
331
326
|
// ─────────────────────────────────────────────────────────────────────────
|
|
@@ -997,16 +992,13 @@ export type StatusLineSeparatorStyle = SettingValue<"statusLine.separator">;
|
|
|
997
992
|
// Typed Group Definitions
|
|
998
993
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
999
994
|
|
|
1000
|
-
export interface
|
|
995
|
+
export interface ContextPromotionSettings {
|
|
1001
996
|
enabled: boolean;
|
|
1002
|
-
reserveTokens: number;
|
|
1003
|
-
keepRecentTokens: number;
|
|
1004
|
-
autoContinue: boolean;
|
|
1005
|
-
remoteEndpoint: string | undefined;
|
|
1006
997
|
}
|
|
1007
|
-
|
|
1008
|
-
export interface ContextPromotionSettings {
|
|
998
|
+
export interface AutoHandoffSettings {
|
|
1009
999
|
enabled: boolean;
|
|
1000
|
+
warningThreshold: number;
|
|
1001
|
+
handoffThreshold: number;
|
|
1010
1002
|
}
|
|
1011
1003
|
export interface RetrySettings {
|
|
1012
1004
|
enabled: boolean;
|
|
@@ -1080,8 +1072,8 @@ export interface BashInterceptorRule {
|
|
|
1080
1072
|
|
|
1081
1073
|
/** Map group prefix -> typed settings interface */
|
|
1082
1074
|
export interface GroupTypeMap {
|
|
1083
|
-
compaction: CompactionSettings;
|
|
1084
1075
|
contextPromotion: ContextPromotionSettings;
|
|
1076
|
+
autoHandoff: AutoHandoffSettings;
|
|
1085
1077
|
retry: RetrySettings;
|
|
1086
1078
|
branchSummary: BranchSummarySettings;
|
|
1087
1079
|
skills: SkillsSettings;
|
package/src/config/settings.ts
CHANGED
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
* Usage:
|
|
5
5
|
* import { settings } from "./settings";
|
|
6
6
|
*
|
|
7
|
-
* const enabled = settings.get("
|
|
7
|
+
* const enabled = settings.get("retry.enabled"); // sync read
|
|
8
8
|
* settings.set("theme.dark", "titanium"); // sync write, saves in background
|
|
9
9
|
*
|
|
10
10
|
* For tests:
|
|
11
|
-
* const isolated = Settings.isolated({ "
|
|
11
|
+
* const isolated = Settings.isolated({ "retry.enabled": false });
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
import * as fs from "node:fs";
|
|
@@ -37,7 +37,6 @@ import {
|
|
|
37
37
|
export type {
|
|
38
38
|
BashInterceptorRule,
|
|
39
39
|
BranchSummarySettings,
|
|
40
|
-
CompactionSettings,
|
|
41
40
|
ContextPromotionSettings,
|
|
42
41
|
ExaSettings,
|
|
43
42
|
GroupPrefix,
|
|
@@ -79,7 +78,7 @@ export interface SettingsOptions {
|
|
|
79
78
|
|
|
80
79
|
/**
|
|
81
80
|
* Parse a dotted path into segments.
|
|
82
|
-
* "
|
|
81
|
+
* "retry.enabled" → ["retry", "enabled"]
|
|
83
82
|
* "theme.dark" → ["theme", "dark"]
|
|
84
83
|
*/
|
|
85
84
|
function parsePath(path: string): string[] {
|
|
@@ -12,7 +12,6 @@ import type { Rule } from "../../capability/rule";
|
|
|
12
12
|
import type { ModelRegistry } from "../../config/model-registry";
|
|
13
13
|
import type { ExecOptions, ExecResult } from "../../exec/exec";
|
|
14
14
|
import type { HookUIContext } from "../../extensibility/hooks/types";
|
|
15
|
-
import type { CompactionResult } from "../../session/compaction";
|
|
16
15
|
import type { ReadonlySessionManager } from "../../session/session-manager";
|
|
17
16
|
import type { Theme } from "../../theme/theme";
|
|
18
17
|
import type { TodoItem } from "../../tools/todo-write";
|
|
@@ -71,17 +70,6 @@ export type CustomToolSessionEvent =
|
|
|
71
70
|
/** Previous session file path, or undefined for "start" and "shutdown" */
|
|
72
71
|
previousSessionFile: string | undefined;
|
|
73
72
|
}
|
|
74
|
-
| {
|
|
75
|
-
reason: "auto_compaction_start";
|
|
76
|
-
trigger: "threshold" | "overflow";
|
|
77
|
-
}
|
|
78
|
-
| {
|
|
79
|
-
reason: "auto_compaction_end";
|
|
80
|
-
result: CompactionResult | undefined;
|
|
81
|
-
aborted: boolean;
|
|
82
|
-
willRetry: boolean;
|
|
83
|
-
errorMessage?: string;
|
|
84
|
-
}
|
|
85
73
|
| {
|
|
86
74
|
reason: "auto_retry_start";
|
|
87
75
|
attempt: number;
|
|
@@ -89,16 +89,11 @@ export type {
|
|
|
89
89
|
SendUserMessageHandler,
|
|
90
90
|
SessionBeforeBranchEvent,
|
|
91
91
|
SessionBeforeBranchResult,
|
|
92
|
-
SessionBeforeCompactEvent,
|
|
93
|
-
SessionBeforeCompactResult,
|
|
94
92
|
SessionBeforeSwitchEvent,
|
|
95
93
|
SessionBeforeSwitchResult,
|
|
96
94
|
SessionBeforeTreeEvent,
|
|
97
95
|
SessionBeforeTreeResult,
|
|
98
96
|
SessionBranchEvent,
|
|
99
|
-
SessionCompactEvent,
|
|
100
|
-
SessionCompactingEvent,
|
|
101
|
-
SessionCompactingResult,
|
|
102
97
|
SessionEvent,
|
|
103
98
|
SessionShutdownEvent,
|
|
104
99
|
// Events - Session
|
|
@@ -11,7 +11,6 @@ import { type Theme, theme } from "../../theme/theme";
|
|
|
11
11
|
import type {
|
|
12
12
|
BeforeAgentStartEvent,
|
|
13
13
|
BeforeAgentStartEventResult,
|
|
14
|
-
CompactOptions,
|
|
15
14
|
ContextEvent,
|
|
16
15
|
ContextEventResult,
|
|
17
16
|
ContextUsage,
|
|
@@ -35,10 +34,8 @@ import type {
|
|
|
35
34
|
ResourcesDiscoverEvent,
|
|
36
35
|
ResourcesDiscoverResult,
|
|
37
36
|
SessionBeforeBranchResult,
|
|
38
|
-
SessionBeforeCompactResult,
|
|
39
37
|
SessionBeforeSwitchResult,
|
|
40
38
|
SessionBeforeTreeResult,
|
|
41
|
-
SessionCompactingResult,
|
|
42
39
|
ToolCallEvent,
|
|
43
40
|
ToolCallEventResult,
|
|
44
41
|
ToolResultEvent,
|
|
@@ -74,26 +71,18 @@ type RunnerEmitEvent = Exclude<
|
|
|
74
71
|
|
|
75
72
|
type SessionBeforeEvent = Extract<
|
|
76
73
|
RunnerEmitEvent,
|
|
77
|
-
{ type: "session_before_switch" | "session_before_branch" | "
|
|
74
|
+
{ type: "session_before_switch" | "session_before_branch" | "session_before_tree" }
|
|
78
75
|
>;
|
|
79
76
|
|
|
80
|
-
type SessionBeforeEventResult =
|
|
81
|
-
| SessionBeforeSwitchResult
|
|
82
|
-
| SessionBeforeBranchResult
|
|
83
|
-
| SessionBeforeCompactResult
|
|
84
|
-
| SessionBeforeTreeResult;
|
|
77
|
+
type SessionBeforeEventResult = SessionBeforeSwitchResult | SessionBeforeBranchResult | SessionBeforeTreeResult;
|
|
85
78
|
|
|
86
79
|
type RunnerEmitResult<TEvent extends RunnerEmitEvent> = TEvent extends { type: "session_before_switch" }
|
|
87
80
|
? SessionBeforeSwitchResult | undefined
|
|
88
81
|
: TEvent extends { type: "session_before_branch" }
|
|
89
82
|
? SessionBeforeBranchResult | undefined
|
|
90
|
-
: TEvent extends { type: "
|
|
91
|
-
?
|
|
92
|
-
:
|
|
93
|
-
? SessionBeforeTreeResult | undefined
|
|
94
|
-
: TEvent extends { type: "session.compacting" }
|
|
95
|
-
? SessionCompactingResult | undefined
|
|
96
|
-
: undefined;
|
|
83
|
+
: TEvent extends { type: "session_before_tree" }
|
|
84
|
+
? SessionBeforeTreeResult | undefined
|
|
85
|
+
: undefined;
|
|
97
86
|
|
|
98
87
|
export type NewSessionHandler = (options?: {
|
|
99
88
|
parentSession?: string;
|
|
@@ -162,7 +151,6 @@ export class ExtensionRunner {
|
|
|
162
151
|
#abortFn: () => void = () => {};
|
|
163
152
|
#hasPendingMessagesFn: () => boolean = () => false;
|
|
164
153
|
#getContextUsageFn: () => ContextUsage | undefined = () => undefined;
|
|
165
|
-
#compactFn: (instructionsOrOptions?: string | CompactOptions) => Promise<void> = async () => {};
|
|
166
154
|
#getSystemPromptFn: () => string = () => "";
|
|
167
155
|
#newSessionHandler: NewSessionHandler = async () => ({ cancelled: false });
|
|
168
156
|
#branchHandler: BranchHandler = async () => ({ cancelled: false });
|
|
@@ -217,7 +205,6 @@ export class ExtensionRunner {
|
|
|
217
205
|
this.#switchSessionHandler = commandContextActions.switchSession;
|
|
218
206
|
this.#reloadHandler = commandContextActions.reload;
|
|
219
207
|
this.#getContextUsageFn = commandContextActions.getContextUsage;
|
|
220
|
-
this.#compactFn = commandContextActions.compact;
|
|
221
208
|
}
|
|
222
209
|
|
|
223
210
|
this.#uiContext = uiContext ?? noOpUIContext;
|
|
@@ -376,7 +363,6 @@ export class ExtensionRunner {
|
|
|
376
363
|
return {
|
|
377
364
|
ui: this.#uiContext,
|
|
378
365
|
getContextUsage: () => this.#getContextUsageFn(),
|
|
379
|
-
compact: instructionsOrOptions => this.#compactFn(instructionsOrOptions),
|
|
380
366
|
hasUI: this.hasUI(),
|
|
381
367
|
cwd: this.cwd,
|
|
382
368
|
sessionManager: this.sessionManager,
|
|
@@ -410,7 +396,6 @@ export class ExtensionRunner {
|
|
|
410
396
|
navigateTree: (targetId, options) => this.#navigateTreeHandler(targetId, options),
|
|
411
397
|
switchSession: sessionPath => this.#switchSessionHandler(sessionPath),
|
|
412
398
|
reload: () => this.#reloadHandler(),
|
|
413
|
-
compact: instructionsOrOptions => this.#compactFn(instructionsOrOptions),
|
|
414
399
|
};
|
|
415
400
|
}
|
|
416
401
|
|
|
@@ -418,14 +403,13 @@ export class ExtensionRunner {
|
|
|
418
403
|
return (
|
|
419
404
|
event.type === "session_before_switch" ||
|
|
420
405
|
event.type === "session_before_branch" ||
|
|
421
|
-
event.type === "session_before_compact" ||
|
|
422
406
|
event.type === "session_before_tree"
|
|
423
407
|
);
|
|
424
408
|
}
|
|
425
409
|
|
|
426
410
|
async emit<TEvent extends RunnerEmitEvent>(event: TEvent): Promise<RunnerEmitResult<TEvent>> {
|
|
427
411
|
const ctx = this.createContext();
|
|
428
|
-
let result: SessionBeforeEventResult |
|
|
412
|
+
let result: SessionBeforeEventResult | undefined;
|
|
429
413
|
|
|
430
414
|
for (const ext of this.extensions) {
|
|
431
415
|
const handlers = ext.handlers.get(event.type);
|
|
@@ -441,10 +425,6 @@ export class ExtensionRunner {
|
|
|
441
425
|
return result as RunnerEmitResult<TEvent>;
|
|
442
426
|
}
|
|
443
427
|
}
|
|
444
|
-
|
|
445
|
-
if (event.type === "session.compacting" && handlerResult) {
|
|
446
|
-
result = handlerResult as SessionCompactingResult;
|
|
447
|
-
}
|
|
448
428
|
} catch (err) {
|
|
449
429
|
const message = err instanceof Error ? err.message : String(err);
|
|
450
430
|
const stack = err instanceof Error ? err.stack : undefined;
|
|
@@ -32,11 +32,9 @@ import type { BashResult } from "../../exec/bash-executor";
|
|
|
32
32
|
import type { ExecOptions, ExecResult } from "../../exec/exec";
|
|
33
33
|
import type { PythonResult } from "../../ipy/executor";
|
|
34
34
|
import type { EditToolDetails } from "../../patch";
|
|
35
|
-
import type { CompactionPreparation, CompactionResult } from "../../session/compaction";
|
|
36
35
|
import type { CustomMessage } from "../../session/messages";
|
|
37
36
|
import type {
|
|
38
37
|
BranchSummaryEntry,
|
|
39
|
-
CompactionEntry,
|
|
40
38
|
ReadonlySessionManager,
|
|
41
39
|
SessionEntry,
|
|
42
40
|
SessionManager,
|
|
@@ -176,18 +174,13 @@ export interface ExtensionUIContext {
|
|
|
176
174
|
// ============================================================================
|
|
177
175
|
|
|
178
176
|
export interface ContextUsage {
|
|
179
|
-
/** Estimated context tokens, or null if unknown
|
|
177
|
+
/** Estimated context tokens, or null if unknown. */
|
|
180
178
|
tokens: number | null;
|
|
181
179
|
contextWindow: number;
|
|
182
180
|
/** Context usage as percentage of context window, or null if tokens is unknown. */
|
|
183
181
|
percent: number | null;
|
|
184
182
|
}
|
|
185
183
|
|
|
186
|
-
export interface CompactOptions {
|
|
187
|
-
onComplete?: (result: CompactionResult) => void;
|
|
188
|
-
onError?: (error: Error) => void;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
184
|
/**
|
|
192
185
|
* Context passed to extension event handlers.
|
|
193
186
|
*/
|
|
@@ -196,8 +189,6 @@ export interface ExtensionContext {
|
|
|
196
189
|
ui: ExtensionUIContext;
|
|
197
190
|
/** Get current context usage for the active model. */
|
|
198
191
|
getContextUsage(): ContextUsage | undefined;
|
|
199
|
-
/** Compact the session context (interactive mode shows UI). */
|
|
200
|
-
compact(instructionsOrOptions?: string | CompactOptions): Promise<void>;
|
|
201
192
|
/** Whether UI is available (false in print/RPC mode) */
|
|
202
193
|
hasUI: boolean;
|
|
203
194
|
/** Current working directory */
|
|
@@ -250,9 +241,6 @@ export interface ExtensionCommandContext extends ExtensionContext {
|
|
|
250
241
|
|
|
251
242
|
/** Reload the current session/runtime state. */
|
|
252
243
|
reload(): Promise<void>;
|
|
253
|
-
|
|
254
|
-
/** Compact the session context (interactive mode shows UI). */
|
|
255
|
-
compact(instructionsOrOptions?: string | CompactOptions): Promise<void>;
|
|
256
244
|
}
|
|
257
245
|
|
|
258
246
|
// ============================================================================
|
|
@@ -369,29 +357,6 @@ export interface SessionBranchEvent {
|
|
|
369
357
|
previousSessionFile: string | undefined;
|
|
370
358
|
}
|
|
371
359
|
|
|
372
|
-
/** Fired before context compaction (can be cancelled or customized) */
|
|
373
|
-
export interface SessionBeforeCompactEvent {
|
|
374
|
-
type: "session_before_compact";
|
|
375
|
-
preparation: CompactionPreparation;
|
|
376
|
-
branchEntries: SessionEntry[];
|
|
377
|
-
customInstructions?: string;
|
|
378
|
-
signal: AbortSignal;
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
/** Fired before compaction summarization to customize prompts/context */
|
|
382
|
-
export interface SessionCompactingEvent {
|
|
383
|
-
type: "session.compacting";
|
|
384
|
-
sessionId: string;
|
|
385
|
-
messages: AgentMessage[];
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
/** Fired after context compaction */
|
|
389
|
-
export interface SessionCompactEvent {
|
|
390
|
-
type: "session_compact";
|
|
391
|
-
compactionEntry: CompactionEntry;
|
|
392
|
-
fromExtension: boolean;
|
|
393
|
-
}
|
|
394
|
-
|
|
395
360
|
/** Fired on process exit */
|
|
396
361
|
export interface SessionShutdownEvent {
|
|
397
362
|
type: "session_shutdown";
|
|
@@ -428,9 +393,6 @@ export type SessionEvent =
|
|
|
428
393
|
| SessionSwitchEvent
|
|
429
394
|
| SessionBeforeBranchEvent
|
|
430
395
|
| SessionBranchEvent
|
|
431
|
-
| SessionBeforeCompactEvent
|
|
432
|
-
| SessionCompactingEvent
|
|
433
|
-
| SessionCompactEvent
|
|
434
396
|
| SessionShutdownEvent
|
|
435
397
|
| SessionBeforeTreeEvent
|
|
436
398
|
| SessionTreeEvent;
|
|
@@ -525,21 +487,6 @@ export interface ToolExecutionEndEvent {
|
|
|
525
487
|
isError: boolean;
|
|
526
488
|
}
|
|
527
489
|
|
|
528
|
-
/** Fired when auto-compaction starts */
|
|
529
|
-
export interface AutoCompactionStartEvent {
|
|
530
|
-
type: "auto_compaction_start";
|
|
531
|
-
reason: "threshold" | "overflow";
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
/** Fired when auto-compaction ends */
|
|
535
|
-
export interface AutoCompactionEndEvent {
|
|
536
|
-
type: "auto_compaction_end";
|
|
537
|
-
result: CompactionResult | undefined;
|
|
538
|
-
aborted: boolean;
|
|
539
|
-
willRetry: boolean;
|
|
540
|
-
errorMessage?: string;
|
|
541
|
-
}
|
|
542
|
-
|
|
543
490
|
/** Fired when auto-retry starts */
|
|
544
491
|
export interface AutoRetryStartEvent {
|
|
545
492
|
type: "auto_retry_start";
|
|
@@ -770,8 +717,6 @@ export type ExtensionEvent =
|
|
|
770
717
|
| ToolExecutionStartEvent
|
|
771
718
|
| ToolExecutionUpdateEvent
|
|
772
719
|
| ToolExecutionEndEvent
|
|
773
|
-
| AutoCompactionStartEvent
|
|
774
|
-
| AutoCompactionEndEvent
|
|
775
720
|
| AutoRetryStartEvent
|
|
776
721
|
| AutoRetryEndEvent
|
|
777
722
|
| TtsrTriggeredEvent
|
|
@@ -838,17 +783,6 @@ export interface SessionBeforeBranchResult {
|
|
|
838
783
|
skipConversationRestore?: boolean;
|
|
839
784
|
}
|
|
840
785
|
|
|
841
|
-
export interface SessionBeforeCompactResult {
|
|
842
|
-
cancel?: boolean;
|
|
843
|
-
compaction?: CompactionResult;
|
|
844
|
-
}
|
|
845
|
-
|
|
846
|
-
export interface SessionCompactingResult {
|
|
847
|
-
context?: string[];
|
|
848
|
-
prompt?: string;
|
|
849
|
-
preserveData?: Record<string, unknown>;
|
|
850
|
-
}
|
|
851
|
-
|
|
852
786
|
export interface SessionBeforeTreeResult {
|
|
853
787
|
cancel?: boolean;
|
|
854
788
|
summary?: {
|
|
@@ -923,12 +857,6 @@ export interface ExtensionAPI {
|
|
|
923
857
|
handler: ExtensionHandler<SessionBeforeBranchEvent, SessionBeforeBranchResult>,
|
|
924
858
|
): void;
|
|
925
859
|
on(event: "session_branch", handler: ExtensionHandler<SessionBranchEvent>): void;
|
|
926
|
-
on(
|
|
927
|
-
event: "session_before_compact",
|
|
928
|
-
handler: ExtensionHandler<SessionBeforeCompactEvent, SessionBeforeCompactResult>,
|
|
929
|
-
): void;
|
|
930
|
-
on(event: "session.compacting", handler: ExtensionHandler<SessionCompactingEvent, SessionCompactingResult>): void;
|
|
931
|
-
on(event: "session_compact", handler: ExtensionHandler<SessionCompactEvent>): void;
|
|
932
860
|
on(event: "session_shutdown", handler: ExtensionHandler<SessionShutdownEvent>): void;
|
|
933
861
|
on(event: "session_before_tree", handler: ExtensionHandler<SessionBeforeTreeEvent, SessionBeforeTreeResult>): void;
|
|
934
862
|
on(event: "session_tree", handler: ExtensionHandler<SessionTreeEvent>): void;
|
|
@@ -944,8 +872,6 @@ export interface ExtensionAPI {
|
|
|
944
872
|
on(event: "tool_execution_start", handler: ExtensionHandler<ToolExecutionStartEvent>): void;
|
|
945
873
|
on(event: "tool_execution_update", handler: ExtensionHandler<ToolExecutionUpdateEvent>): void;
|
|
946
874
|
on(event: "tool_execution_end", handler: ExtensionHandler<ToolExecutionEndEvent>): void;
|
|
947
|
-
on(event: "auto_compaction_start", handler: ExtensionHandler<AutoCompactionStartEvent>): void;
|
|
948
|
-
on(event: "auto_compaction_end", handler: ExtensionHandler<AutoCompactionEndEvent>): void;
|
|
949
875
|
on(event: "auto_retry_start", handler: ExtensionHandler<AutoRetryStartEvent>): void;
|
|
950
876
|
on(event: "auto_retry_end", handler: ExtensionHandler<AutoRetryEndEvent>): void;
|
|
951
877
|
on(event: "ttsr_triggered", handler: ExtensionHandler<TtsrTriggeredEvent>): void;
|
|
@@ -1239,7 +1165,6 @@ export interface ExtensionContextActions {
|
|
|
1239
1165
|
hasPendingMessages: () => boolean;
|
|
1240
1166
|
shutdown: () => void;
|
|
1241
1167
|
getContextUsage: () => ContextUsage | undefined;
|
|
1242
|
-
compact: (instructionsOrOptions?: string | CompactOptions) => Promise<void>;
|
|
1243
1168
|
getSystemPrompt: () => string;
|
|
1244
1169
|
}
|
|
1245
1170
|
|
|
@@ -1253,7 +1178,6 @@ export interface ExtensionCommandContextActions {
|
|
|
1253
1178
|
}) => Promise<{ cancelled: boolean }>;
|
|
1254
1179
|
branch: (entryId: string) => Promise<{ cancelled: boolean }>;
|
|
1255
1180
|
navigateTree: (targetId: string, options?: { summarize?: boolean }) => Promise<{ cancelled: boolean }>;
|
|
1256
|
-
compact: (instructionsOrOptions?: string | CompactOptions) => Promise<void>;
|
|
1257
1181
|
switchSession: (sessionPath: string) => Promise<{ cancelled: boolean }>;
|
|
1258
1182
|
reload: () => Promise<void>;
|
|
1259
1183
|
}
|
|
@@ -26,9 +26,7 @@ import type {
|
|
|
26
26
|
HookMessageRenderer,
|
|
27
27
|
HookUIContext,
|
|
28
28
|
RegisteredCommand,
|
|
29
|
-
SessionBeforeCompactResult,
|
|
30
29
|
SessionBeforeTreeResult,
|
|
31
|
-
SessionCompactingResult,
|
|
32
30
|
ToolCallEvent,
|
|
33
31
|
ToolCallEventResult,
|
|
34
32
|
ToolResultEventResult,
|
|
@@ -270,31 +268,17 @@ export class HookRunner {
|
|
|
270
268
|
*/
|
|
271
269
|
#isSessionBeforeEvent(
|
|
272
270
|
type: string,
|
|
273
|
-
): type is "session_before_switch" | "session_before_branch" | "
|
|
274
|
-
return
|
|
275
|
-
type === "session_before_switch" ||
|
|
276
|
-
type === "session_before_branch" ||
|
|
277
|
-
type === "session_before_compact" ||
|
|
278
|
-
type === "session_before_tree"
|
|
279
|
-
);
|
|
271
|
+
): type is "session_before_switch" | "session_before_branch" | "session_before_tree" {
|
|
272
|
+
return type === "session_before_switch" || type === "session_before_branch" || type === "session_before_tree";
|
|
280
273
|
}
|
|
281
274
|
|
|
282
275
|
/**
|
|
283
276
|
* Emit an event to all hooks.
|
|
284
277
|
* Returns the result from session before_* / tool_result events (if any handler returns one).
|
|
285
278
|
*/
|
|
286
|
-
async emit(
|
|
287
|
-
event: HookEvent,
|
|
288
|
-
): Promise<
|
|
289
|
-
SessionBeforeCompactResult | SessionBeforeTreeResult | SessionCompactingResult | ToolResultEventResult | undefined
|
|
290
|
-
> {
|
|
279
|
+
async emit(event: HookEvent): Promise<SessionBeforeTreeResult | ToolResultEventResult | undefined> {
|
|
291
280
|
const ctx = this.#createContext();
|
|
292
|
-
let result:
|
|
293
|
-
| SessionBeforeCompactResult
|
|
294
|
-
| SessionBeforeTreeResult
|
|
295
|
-
| SessionCompactingResult
|
|
296
|
-
| ToolResultEventResult
|
|
297
|
-
| undefined;
|
|
281
|
+
let result: SessionBeforeTreeResult | ToolResultEventResult | undefined;
|
|
298
282
|
|
|
299
283
|
for (const hook of this.hooks) {
|
|
300
284
|
const handlers = hook.handlers.get(event.type);
|
|
@@ -306,7 +290,7 @@ export class HookRunner {
|
|
|
306
290
|
|
|
307
291
|
// For session before_* events, capture the result (for cancellation)
|
|
308
292
|
if (this.#isSessionBeforeEvent(event.type) && handlerResult) {
|
|
309
|
-
result = handlerResult as
|
|
293
|
+
result = handlerResult as SessionBeforeTreeResult;
|
|
310
294
|
// If cancelled, stop processing further hooks
|
|
311
295
|
if (result.cancel) {
|
|
312
296
|
return result;
|
|
@@ -317,9 +301,6 @@ export class HookRunner {
|
|
|
317
301
|
if (event.type === "tool_result" && handlerResult) {
|
|
318
302
|
result = handlerResult as ToolResultEventResult;
|
|
319
303
|
}
|
|
320
|
-
if (event.type === "session.compacting" && handlerResult) {
|
|
321
|
-
result = handlerResult as SessionCompactingResult;
|
|
322
|
-
}
|
|
323
304
|
} catch (err) {
|
|
324
305
|
const message = err instanceof Error ? err.message : String(err);
|
|
325
306
|
this.emitError({
|
|
@@ -11,11 +11,9 @@ import type { Rule } from "../../capability/rule";
|
|
|
11
11
|
import type { ModelRegistry } from "../../config/model-registry";
|
|
12
12
|
import type { ExecOptions, ExecResult } from "../../exec/exec";
|
|
13
13
|
import type { EditToolDetails } from "../../patch";
|
|
14
|
-
import type { CompactionPreparation, CompactionResult } from "../../session/compaction";
|
|
15
14
|
import type { HookMessage } from "../../session/messages";
|
|
16
15
|
import type {
|
|
17
16
|
BranchSummaryEntry,
|
|
18
|
-
CompactionEntry,
|
|
19
17
|
ReadonlySessionManager,
|
|
20
18
|
SessionEntry,
|
|
21
19
|
SessionManager,
|
|
@@ -249,34 +247,6 @@ export interface SessionBranchEvent {
|
|
|
249
247
|
previousSessionFile: string | undefined;
|
|
250
248
|
}
|
|
251
249
|
|
|
252
|
-
/** Fired before context compaction (can be cancelled) */
|
|
253
|
-
export interface SessionBeforeCompactEvent {
|
|
254
|
-
type: "session_before_compact";
|
|
255
|
-
/** Compaction preparation with messages to summarize, file ops, previous summary, etc. */
|
|
256
|
-
preparation: CompactionPreparation;
|
|
257
|
-
/** Branch entries (root to current leaf). Use to inspect custom state or previous compactions. */
|
|
258
|
-
branchEntries: SessionEntry[];
|
|
259
|
-
/** Optional user-provided instructions for the summary */
|
|
260
|
-
customInstructions?: string;
|
|
261
|
-
/** Abort signal - hooks should pass this to LLM calls and check it periodically */
|
|
262
|
-
signal: AbortSignal;
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
/** Fired before compaction summarization to customize prompts/context */
|
|
266
|
-
export interface SessionCompactingEvent {
|
|
267
|
-
type: "session.compacting";
|
|
268
|
-
sessionId: string;
|
|
269
|
-
messages: AgentMessage[];
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
/** Fired after context compaction */
|
|
273
|
-
export interface SessionCompactEvent {
|
|
274
|
-
type: "session_compact";
|
|
275
|
-
compactionEntry: CompactionEntry;
|
|
276
|
-
/** Whether the compaction entry was provided by a hook */
|
|
277
|
-
fromExtension: boolean;
|
|
278
|
-
}
|
|
279
|
-
|
|
280
250
|
/** Fired on process exit (SIGINT/SIGTERM) */
|
|
281
251
|
export interface SessionShutdownEvent {
|
|
282
252
|
type: "session_shutdown";
|
|
@@ -290,7 +260,7 @@ export interface TreePreparation {
|
|
|
290
260
|
oldLeafId: string | null;
|
|
291
261
|
/** Common ancestor of target and old leaf, null if no common ancestor */
|
|
292
262
|
commonAncestorId: string | null;
|
|
293
|
-
/** Entries to summarize (old leaf back to common ancestor
|
|
263
|
+
/** Entries to summarize (old leaf back to common ancestor) */
|
|
294
264
|
entriesToSummarize: SessionEntry[];
|
|
295
265
|
/** Whether user chose to summarize */
|
|
296
266
|
userWantsSummary: boolean;
|
|
@@ -325,9 +295,6 @@ export type SessionEvent =
|
|
|
325
295
|
| SessionSwitchEvent
|
|
326
296
|
| SessionBeforeBranchEvent
|
|
327
297
|
| SessionBranchEvent
|
|
328
|
-
| SessionBeforeCompactEvent
|
|
329
|
-
| SessionCompactingEvent
|
|
330
|
-
| SessionCompactEvent
|
|
331
298
|
| SessionShutdownEvent
|
|
332
299
|
| SessionBeforeTreeEvent
|
|
333
300
|
| SessionTreeEvent;
|
|
@@ -391,21 +358,6 @@ export interface TurnEndEvent {
|
|
|
391
358
|
toolResults: ToolResultMessage[];
|
|
392
359
|
}
|
|
393
360
|
|
|
394
|
-
/** Event data for auto_compaction_start event. */
|
|
395
|
-
export interface AutoCompactionStartEvent {
|
|
396
|
-
type: "auto_compaction_start";
|
|
397
|
-
reason: "threshold" | "overflow";
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
/** Event data for auto_compaction_end event. */
|
|
401
|
-
export interface AutoCompactionEndEvent {
|
|
402
|
-
type: "auto_compaction_end";
|
|
403
|
-
result: CompactionResult | undefined;
|
|
404
|
-
aborted: boolean;
|
|
405
|
-
willRetry: boolean;
|
|
406
|
-
errorMessage?: string;
|
|
407
|
-
}
|
|
408
|
-
|
|
409
361
|
/** Event data for auto_retry_start event. */
|
|
410
362
|
export interface AutoRetryStartEvent {
|
|
411
363
|
type: "auto_retry_start";
|
|
@@ -533,8 +485,6 @@ export type HookEvent =
|
|
|
533
485
|
| AgentEndEvent
|
|
534
486
|
| TurnStartEvent
|
|
535
487
|
| TurnEndEvent
|
|
536
|
-
| AutoCompactionStartEvent
|
|
537
|
-
| AutoCompactionEndEvent
|
|
538
488
|
| AutoRetryStartEvent
|
|
539
489
|
| AutoRetryEndEvent
|
|
540
490
|
| TtsrTriggeredEvent
|
|
@@ -616,24 +566,6 @@ export interface SessionBeforeBranchResult {
|
|
|
616
566
|
skipConversationRestore?: boolean;
|
|
617
567
|
}
|
|
618
568
|
|
|
619
|
-
/** Return type for session_before_compact handlers */
|
|
620
|
-
export interface SessionBeforeCompactResult {
|
|
621
|
-
/** If true, cancel the compaction */
|
|
622
|
-
cancel?: boolean;
|
|
623
|
-
/** Custom compaction result - SessionManager adds id/parentId */
|
|
624
|
-
compaction?: CompactionResult;
|
|
625
|
-
}
|
|
626
|
-
|
|
627
|
-
/** Return type for session.compacting handlers */
|
|
628
|
-
export interface SessionCompactingResult {
|
|
629
|
-
/** Additional context lines to include in summary */
|
|
630
|
-
context?: string[];
|
|
631
|
-
/** Override the default compaction prompt */
|
|
632
|
-
prompt?: string;
|
|
633
|
-
/** Custom data to store in compaction entry */
|
|
634
|
-
preserveData?: Record<string, unknown>;
|
|
635
|
-
}
|
|
636
|
-
|
|
637
569
|
/** Return type for session_before_tree handlers */
|
|
638
570
|
export interface SessionBeforeTreeResult {
|
|
639
571
|
/** If true, cancel the navigation entirely */
|
|
@@ -695,12 +627,6 @@ export interface HookAPI {
|
|
|
695
627
|
on(event: "session_switch", handler: HookHandler<SessionSwitchEvent>): void;
|
|
696
628
|
on(event: "session_before_branch", handler: HookHandler<SessionBeforeBranchEvent, SessionBeforeBranchResult>): void;
|
|
697
629
|
on(event: "session_branch", handler: HookHandler<SessionBranchEvent>): void;
|
|
698
|
-
on(
|
|
699
|
-
event: "session_before_compact",
|
|
700
|
-
handler: HookHandler<SessionBeforeCompactEvent, SessionBeforeCompactResult>,
|
|
701
|
-
): void;
|
|
702
|
-
on(event: "session.compacting", handler: HookHandler<SessionCompactingEvent, SessionCompactingResult>): void;
|
|
703
|
-
on(event: "session_compact", handler: HookHandler<SessionCompactEvent>): void;
|
|
704
630
|
on(event: "session_shutdown", handler: HookHandler<SessionShutdownEvent>): void;
|
|
705
631
|
on(event: "session_before_tree", handler: HookHandler<SessionBeforeTreeEvent, SessionBeforeTreeResult>): void;
|
|
706
632
|
on(event: "session_tree", handler: HookHandler<SessionTreeEvent>): void;
|
|
@@ -712,8 +638,6 @@ export interface HookAPI {
|
|
|
712
638
|
on(event: "agent_end", handler: HookHandler<AgentEndEvent>): void;
|
|
713
639
|
on(event: "turn_start", handler: HookHandler<TurnStartEvent>): void;
|
|
714
640
|
on(event: "turn_end", handler: HookHandler<TurnEndEvent>): void;
|
|
715
|
-
on(event: "auto_compaction_start", handler: HookHandler<AutoCompactionStartEvent>): void;
|
|
716
|
-
on(event: "auto_compaction_end", handler: HookHandler<AutoCompactionEndEvent>): void;
|
|
717
641
|
on(event: "auto_retry_start", handler: HookHandler<AutoRetryStartEvent>): void;
|
|
718
642
|
on(event: "auto_retry_end", handler: HookHandler<AutoRetryEndEvent>): void;
|
|
719
643
|
on(event: "ttsr_triggered", handler: HookHandler<TtsrTriggeredEvent>): void;
|