@oh-my-pi/pi-coding-agent 16.2.2 → 16.2.4
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 +60 -0
- package/dist/cli.js +3682 -3615
- package/dist/types/advisor/__tests__/config.test.d.ts +1 -0
- package/dist/types/advisor/advise-tool.d.ts +8 -4
- package/dist/types/advisor/config.d.ts +88 -0
- package/dist/types/advisor/index.d.ts +1 -0
- package/dist/types/advisor/transcript-recorder.d.ts +13 -2
- package/dist/types/advisor/watchdog.d.ts +20 -0
- package/dist/types/cli/update-cli.d.ts +15 -0
- package/dist/types/collab/guest.d.ts +29 -0
- package/dist/types/collab/replication-shrink.d.ts +39 -0
- package/dist/types/config/provider-globals.d.ts +7 -0
- package/dist/types/config/settings-schema.d.ts +81 -0
- package/dist/types/debug/log-viewer.d.ts +1 -0
- package/dist/types/debug/raw-sse.d.ts +1 -0
- package/dist/types/edit/hashline/diff.d.ts +0 -11
- package/dist/types/extensibility/tool-event-input.d.ts +7 -0
- package/dist/types/extensibility/utils.d.ts +12 -0
- package/dist/types/mcp/transports/index.d.ts +1 -0
- package/dist/types/mcp/transports/sse.d.ts +20 -0
- package/dist/types/memories/index.d.ts +20 -1
- package/dist/types/modes/components/advisor-config.d.ts +59 -0
- package/dist/types/modes/components/index.d.ts +1 -0
- package/dist/types/modes/components/model-selector.d.ts +9 -1
- package/dist/types/modes/components/settings-selector.d.ts +1 -0
- package/dist/types/modes/components/status-line/component.d.ts +35 -1
- package/dist/types/modes/components/status-line/types.d.ts +13 -1
- package/dist/types/modes/controllers/command-controller.d.ts +3 -3
- package/dist/types/modes/controllers/selector-controller.d.ts +1 -0
- package/dist/types/modes/interactive-mode.d.ts +11 -4
- package/dist/types/modes/skill-command.d.ts +32 -0
- package/dist/types/modes/types.d.ts +9 -3
- package/dist/types/session/agent-session.d.ts +58 -10
- package/dist/types/session/indexed-session-storage.d.ts +7 -1
- package/dist/types/session/messages.d.ts +26 -0
- package/dist/types/session/messages.test.d.ts +1 -0
- package/dist/types/session/session-entries.d.ts +31 -3
- package/dist/types/session/session-history-format.d.ts +6 -0
- package/dist/types/session/session-loader.d.ts +9 -1
- package/dist/types/session/session-manager.d.ts +8 -7
- package/dist/types/session/session-storage.d.ts +11 -0
- package/dist/types/session/session-title-slot.d.ts +19 -0
- package/dist/types/ssh/connection-manager.d.ts +47 -0
- package/dist/types/ssh/utils.d.ts +16 -0
- package/dist/types/task/executor.d.ts +3 -16
- package/dist/types/task/render.d.ts +0 -5
- package/dist/types/task/renderer.d.ts +13 -0
- package/dist/types/task/types.d.ts +16 -0
- package/dist/types/task/yield-assembly.d.ts +28 -0
- package/dist/types/tiny/text.d.ts +8 -0
- package/dist/types/tools/render-utils.d.ts +2 -0
- package/dist/types/tools/review.d.ts +6 -4
- package/dist/types/tools/ssh.d.ts +1 -1
- package/dist/types/tools/todo.d.ts +6 -0
- package/dist/types/tools/yield.d.ts +8 -3
- package/dist/types/utils/thinking-display.d.ts +4 -0
- package/package.json +12 -12
- package/src/advisor/__tests__/advisor.test.ts +242 -10
- package/src/advisor/__tests__/config.test.ts +173 -0
- package/src/advisor/advise-tool.ts +11 -6
- package/src/advisor/config.ts +256 -0
- package/src/advisor/index.ts +1 -0
- package/src/advisor/runtime.ts +12 -2
- package/src/advisor/transcript-recorder.ts +25 -2
- package/src/advisor/watchdog.ts +57 -31
- package/src/autolearn/controller.ts +13 -22
- package/src/autoresearch/index.ts +7 -2
- package/src/cli/gc-cli.ts +17 -10
- package/src/cli/update-cli.ts +254 -0
- package/src/collab/guest.ts +43 -7
- package/src/collab/host.ts +13 -8
- package/src/collab/replication-shrink.ts +111 -0
- package/src/config/model-registry.ts +80 -18
- package/src/config/provider-globals.ts +25 -0
- package/src/config/settings-schema.ts +77 -0
- package/src/debug/index.ts +32 -7
- package/src/debug/log-viewer.ts +111 -53
- package/src/debug/raw-sse.ts +68 -48
- package/src/discovery/codex.ts +13 -5
- package/src/edit/hashline/diff.ts +57 -4
- package/src/eval/__tests__/julia-prelude.test.ts +2 -2
- package/src/eval/js/shared/local-module-loader.ts +23 -1
- package/src/export/html/template.js +13 -7
- package/src/extensibility/extensions/loader.ts +5 -3
- package/src/extensibility/extensions/wrapper.ts +9 -3
- package/src/extensibility/hooks/loader.ts +3 -3
- package/src/extensibility/hooks/tool-wrapper.ts +13 -4
- package/src/extensibility/plugins/manager.ts +2 -1
- package/src/extensibility/tool-event-input.ts +23 -0
- package/src/extensibility/utils.ts +74 -0
- package/src/internal-urls/docs-index.generated.txt +1 -1
- package/src/mcp/client.ts +3 -1
- package/src/mcp/manager.ts +12 -5
- package/src/mcp/transports/index.ts +1 -0
- package/src/mcp/transports/sse.ts +377 -0
- package/src/memories/index.ts +130 -15
- package/src/memory-backend/local-backend.ts +5 -3
- package/src/modes/components/advisor-config.ts +555 -0
- package/src/modes/components/advisor-message.ts +9 -2
- package/src/modes/components/agent-hub.ts +9 -4
- package/src/modes/components/index.ts +2 -0
- package/src/modes/components/model-selector.ts +79 -48
- package/src/modes/components/settings-selector.ts +1 -0
- package/src/modes/components/status-line/component.ts +150 -5
- package/src/modes/components/status-line/segments.ts +46 -21
- package/src/modes/components/status-line/types.ts +13 -1
- package/src/modes/components/tool-execution.ts +47 -6
- package/src/modes/controllers/command-controller.ts +27 -36
- package/src/modes/controllers/event-controller.ts +113 -1
- package/src/modes/controllers/extension-ui-controller.ts +1 -1
- package/src/modes/controllers/input-controller.ts +61 -61
- package/src/modes/controllers/selector-controller.ts +100 -9
- package/src/modes/interactive-mode.ts +74 -25
- package/src/modes/skill-command.ts +116 -0
- package/src/modes/types.ts +9 -3
- package/src/modes/utils/ui-helpers.ts +41 -23
- package/src/prompts/agents/reviewer.md +11 -10
- package/src/prompts/goals/goal-todo-context.md +12 -0
- package/src/prompts/review-custom-request.md +1 -2
- package/src/prompts/review-request.md +1 -2
- package/src/prompts/system/interrupted-thinking.md +7 -0
- package/src/prompts/system/recap-user.md +9 -0
- package/src/prompts/system/subagent-system-prompt.md +8 -5
- package/src/prompts/system/subagent-yield-reminder.md +6 -5
- package/src/prompts/system/system-prompt.md +0 -1
- package/src/prompts/tools/irc.md +2 -2
- package/src/prompts/tools/read.md +2 -2
- package/src/sdk.ts +28 -24
- package/src/session/agent-session.ts +899 -429
- package/src/session/indexed-session-storage.ts +86 -13
- package/src/session/messages.test.ts +125 -0
- package/src/session/messages.ts +172 -9
- package/src/session/redis-session-storage.ts +49 -2
- package/src/session/session-entries.ts +39 -2
- package/src/session/session-history-format.ts +29 -2
- package/src/session/session-listing.ts +54 -24
- package/src/session/session-loader.ts +66 -3
- package/src/session/session-manager.ts +115 -22
- package/src/session/session-persistence.ts +95 -1
- package/src/session/session-storage.ts +36 -0
- package/src/session/session-title-slot.ts +141 -0
- package/src/session/sql-session-storage.ts +71 -11
- package/src/slash-commands/builtin-registry.ts +23 -24
- package/src/ssh/__tests__/connection-manager-args.test.ts +123 -1
- package/src/ssh/__tests__/file-transfer-posix-guard.test.ts +55 -18
- package/src/ssh/connection-manager.ts +139 -12
- package/src/ssh/file-transfer.ts +23 -18
- package/src/ssh/ssh-executor.ts +2 -13
- package/src/ssh/utils.ts +19 -0
- package/src/task/executor.ts +21 -23
- package/src/task/render.ts +162 -20
- package/src/task/renderer.ts +14 -0
- package/src/task/types.ts +17 -0
- package/src/task/yield-assembly.ts +207 -0
- package/src/tiny/text.ts +23 -0
- package/src/tools/ask.ts +55 -4
- package/src/tools/render-utils.ts +2 -0
- package/src/tools/renderers.ts +8 -2
- package/src/tools/review.ts +17 -7
- package/src/tools/ssh.ts +8 -4
- package/src/tools/todo.ts +17 -1
- package/src/tools/yield.ts +140 -31
- package/src/utils/thinking-display.ts +15 -0
- package/src/prompts/system/autolearn-nudge.md +0 -5
|
@@ -34,6 +34,7 @@ export interface StatusLinePreviewSettings {
|
|
|
34
34
|
separator?: StatusLineSeparatorStyle;
|
|
35
35
|
sessionAccent?: boolean;
|
|
36
36
|
transparent?: boolean;
|
|
37
|
+
compactThinkingLevel?: boolean;
|
|
37
38
|
}
|
|
38
39
|
export interface SettingsCallbacks {
|
|
39
40
|
/** Called when any setting value changes */
|
|
@@ -14,9 +14,43 @@ export declare class StatusLineComponent implements Component {
|
|
|
14
14
|
getEffectiveSettingsForTest(): EffectiveStatusLineSettings;
|
|
15
15
|
setAutoCompactEnabled(enabled: boolean): void;
|
|
16
16
|
setSubagentCount(count: number): void;
|
|
17
|
+
/**
|
|
18
|
+
* Compatibility shim for callers predating the simplified subagent badge.
|
|
19
|
+
* The status line now intentionally shows only the active count.
|
|
20
|
+
*/
|
|
21
|
+
setSubagentHubHint(_hint: string | undefined): void;
|
|
17
22
|
/** Active subagent count as currently displayed (collab state mirroring). */
|
|
18
23
|
get subagentCount(): number;
|
|
19
|
-
|
|
24
|
+
/**
|
|
25
|
+
* Reset the currently-attached session's active-time accumulators so
|
|
26
|
+
* the `time_spent` segment starts from zero. Called from `/clear`,
|
|
27
|
+
* fresh-session, and joined-collab paths; both the completed
|
|
28
|
+
* accumulator and any in-flight window are dropped, so a reset
|
|
29
|
+
* mid-turn ignores the running window (the matching `markActivityEnd`
|
|
30
|
+
* will see an idle meter and no-op).
|
|
31
|
+
*/
|
|
32
|
+
resetActiveTime(): void;
|
|
33
|
+
/**
|
|
34
|
+
* Mark the currently-attached session as having started a unit of
|
|
35
|
+
* active processing. Idempotent: a second start while a window is
|
|
36
|
+
* already open is a no-op, so reentrant `agent_start` events (e.g.
|
|
37
|
+
* nested auto-compaction loops, focus-controller mid-turn attach onto
|
|
38
|
+
* an already-running window) do not double-count.
|
|
39
|
+
*/
|
|
40
|
+
markActivityStart(): void;
|
|
41
|
+
/**
|
|
42
|
+
* Close the currently-attached session's open active-processing
|
|
43
|
+
* window, folding its elapsed time into the accumulator. Idempotent
|
|
44
|
+
* when the meter is already idle so callers can fire it on every
|
|
45
|
+
* `agent_end` without guarding.
|
|
46
|
+
*/
|
|
47
|
+
markActivityEnd(): void;
|
|
48
|
+
/**
|
|
49
|
+
* Snapshot of total active-processing time for the currently-attached
|
|
50
|
+
* session, including any in-flight window. Exposed for the segment
|
|
51
|
+
* context builder; tests assert against this too.
|
|
52
|
+
*/
|
|
53
|
+
getActiveMs(): number;
|
|
20
54
|
setPlanModeStatus(status: {
|
|
21
55
|
enabled: boolean;
|
|
22
56
|
paused: boolean;
|
|
@@ -41,6 +41,9 @@ export interface StatusLineSettings {
|
|
|
41
41
|
/** Drop the theme's `statusLineBg` fill and powerline caps so the bar
|
|
42
42
|
* inherits the terminal's default background. */
|
|
43
43
|
transparent?: boolean;
|
|
44
|
+
/** Replace the model-segment icon with the thinking-level glyph and drop the
|
|
45
|
+
* " · <level>" suffix, so the thinking level reads as a single compact icon. */
|
|
46
|
+
compactThinkingLevel?: boolean;
|
|
44
47
|
}
|
|
45
48
|
export type EffectiveStatusLineSettings = Required<Pick<StatusLineSettings, "leftSegments" | "rightSegments" | "separator" | "segmentOptions">> & StatusLineSettings;
|
|
46
49
|
export type RGB = readonly [number, number, number];
|
|
@@ -51,6 +54,8 @@ export interface SegmentContext {
|
|
|
51
54
|
activeRepo: ActiveRepoContext | null;
|
|
52
55
|
width: number;
|
|
53
56
|
options: StatusLineSegmentOptions;
|
|
57
|
+
/** Render the model segment's thinking level as a compact leading glyph. */
|
|
58
|
+
compactThinkingLevel: boolean;
|
|
54
59
|
planMode: {
|
|
55
60
|
enabled: boolean;
|
|
56
61
|
paused: boolean;
|
|
@@ -78,7 +83,14 @@ export interface SegmentContext {
|
|
|
78
83
|
contextWindow: number;
|
|
79
84
|
autoCompactEnabled: boolean;
|
|
80
85
|
subagentCount: number;
|
|
81
|
-
|
|
86
|
+
/**
|
|
87
|
+
* Active processing time accumulated this session, in ms — the union of
|
|
88
|
+
* every `agent_start`→`agent_end` window plus the currently-streaming
|
|
89
|
+
* window if the agent is running. Idle wall-clock never contributes, so
|
|
90
|
+
* this is what {@link StatusLineSegmentId.time_spent} renders instead of
|
|
91
|
+
* `Date.now() - sessionStart`.
|
|
92
|
+
*/
|
|
93
|
+
activeMs: number;
|
|
82
94
|
git: {
|
|
83
95
|
branch: string | null;
|
|
84
96
|
status: {
|
|
@@ -30,13 +30,13 @@ export declare class CommandController {
|
|
|
30
30
|
handleDropCommand(): Promise<void>;
|
|
31
31
|
handleForkCommand(): Promise<void>;
|
|
32
32
|
/**
|
|
33
|
-
* `/move` —
|
|
33
|
+
* `/move` — relocate the current session to a different directory.
|
|
34
34
|
*
|
|
35
35
|
* With no `targetPath` (TUI only), opens an autocomplete overlay so the user
|
|
36
36
|
* can pick or type a directory. With a `targetPath`, resolves it directly.
|
|
37
37
|
* If the target directory does not exist, the user is asked whether to create
|
|
38
|
-
* it.
|
|
39
|
-
*
|
|
38
|
+
* it. The active session file and artifacts are moved into the target
|
|
39
|
+
* directory's session bucket so `/resume` from that directory can find it.
|
|
40
40
|
*/
|
|
41
41
|
handleMoveCommand(targetPath?: string): Promise<void>;
|
|
42
42
|
handleRenameCommand(title: string): Promise<void>;
|
|
@@ -83,6 +83,7 @@ export declare class InteractiveMode implements InteractiveModeContext {
|
|
|
83
83
|
chatContainer: TranscriptContainer;
|
|
84
84
|
pendingMessagesContainer: Container;
|
|
85
85
|
statusContainer: Container;
|
|
86
|
+
todoReminderContainer: Container;
|
|
86
87
|
todoContainer: Container;
|
|
87
88
|
subagentContainer: Container;
|
|
88
89
|
btwContainer: Container;
|
|
@@ -109,11 +110,16 @@ export declare class InteractiveMode implements InteractiveModeContext {
|
|
|
109
110
|
loopLimit: LoopLimitRuntime | undefined;
|
|
110
111
|
todoPhases: TodoPhase[];
|
|
111
112
|
hideThinkingBlock: boolean;
|
|
113
|
+
/** Whether the visible session has produced thinking content the user can reveal. */
|
|
114
|
+
get hasDisplayableThinkingContent(): boolean;
|
|
115
|
+
/** Record received reasoning content so Ctrl+T can reveal it even when model metadata says thinking is off. */
|
|
116
|
+
noteDisplayableThinkingContent(message: AgentMessage): boolean;
|
|
112
117
|
/**
|
|
113
|
-
* Effective thinking-block visibility: hidden when the user's setting is on
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
118
|
+
* Effective thinking-block visibility: hidden when the user's setting is on,
|
|
119
|
+
* or while thinking is "off" before the session has actually produced
|
|
120
|
+
* displayable thinking content. Some providers return thinking blocks without
|
|
121
|
+
* advertising reasoning support, so observed content unlocks the visibility
|
|
122
|
+
* toggle.
|
|
117
123
|
*/
|
|
118
124
|
get effectiveHideThinkingBlock(): boolean;
|
|
119
125
|
proseOnlyThinking: boolean;
|
|
@@ -319,6 +325,7 @@ export declare class InteractiveMode implements InteractiveModeContext {
|
|
|
319
325
|
executeCompaction(customInstructionsOrOptions?: string | CompactOptions, isAuto?: boolean): Promise<CompactionOutcome>;
|
|
320
326
|
openInBrowser(urlOrPath: string): void;
|
|
321
327
|
showSettingsSelector(): void;
|
|
328
|
+
showAdvisorConfigure(): void;
|
|
322
329
|
showHistorySearch(): void;
|
|
323
330
|
showExtensionsDashboard(): void;
|
|
324
331
|
showAgentsDashboard(): void;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { ImageContent, TextContent } from "@oh-my-pi/pi-ai";
|
|
2
|
+
import { type CustomMessage, SKILL_PROMPT_MESSAGE_TYPE, type SkillPromptDetails } from "../session/messages";
|
|
3
|
+
import type { InteractiveModeContext } from "./types";
|
|
4
|
+
type SkillCommandHost = Pick<InteractiveModeContext, "skillCommands" | "session" | "showError">;
|
|
5
|
+
type SkillPromptMessage = Pick<CustomMessage<SkillPromptDetails>, "customType" | "content" | "display" | "details" | "attribution"> & {
|
|
6
|
+
customType: typeof SKILL_PROMPT_MESSAGE_TYPE;
|
|
7
|
+
content: string | (TextContent | ImageContent)[];
|
|
8
|
+
display: true;
|
|
9
|
+
details: SkillPromptDetails;
|
|
10
|
+
attribution: "user";
|
|
11
|
+
};
|
|
12
|
+
type SkillPromptOptions = {
|
|
13
|
+
streamingBehavior: "steer" | "followUp";
|
|
14
|
+
queueChipText: string;
|
|
15
|
+
};
|
|
16
|
+
interface InvokeSkillCommandOptions {
|
|
17
|
+
propagateErrors?: boolean;
|
|
18
|
+
queueOnly?: boolean;
|
|
19
|
+
images?: ImageContent[];
|
|
20
|
+
}
|
|
21
|
+
/** Built custom-message payload and delivery options for a `/skill:` command. */
|
|
22
|
+
export interface BuiltSkillCommandPrompt {
|
|
23
|
+
message: SkillPromptMessage;
|
|
24
|
+
options: SkillPromptOptions;
|
|
25
|
+
}
|
|
26
|
+
/** Return true when `text` names a registered `/skill:<name>` command. */
|
|
27
|
+
export declare function isKnownSkillCommand(ctx: SkillCommandHost, text: string): boolean;
|
|
28
|
+
/** Build the user-attributed custom message for a registered `/skill:<name>` command. */
|
|
29
|
+
export declare function buildSkillCommandPrompt(ctx: SkillCommandHost, text: string, streamingBehavior: "steer" | "followUp", images?: ImageContent[]): Promise<BuiltSkillCommandPrompt | undefined>;
|
|
30
|
+
/** Invoke a registered `/skill:<name>` command as a user-attributed custom message. */
|
|
31
|
+
export declare function invokeSkillCommandFromText(ctx: SkillCommandHost, text: string, streamingBehavior: "steer" | "followUp", options?: InvokeSkillCommandOptions): Promise<boolean>;
|
|
32
|
+
export {};
|
|
@@ -81,6 +81,7 @@ export interface InteractiveModeContext {
|
|
|
81
81
|
chatContainer: TranscriptContainer;
|
|
82
82
|
pendingMessagesContainer: Container;
|
|
83
83
|
statusContainer: Container;
|
|
84
|
+
todoReminderContainer: Container;
|
|
84
85
|
todoContainer: Container;
|
|
85
86
|
subagentContainer: Container;
|
|
86
87
|
btwContainer: Container;
|
|
@@ -104,7 +105,7 @@ export interface InteractiveModeContext {
|
|
|
104
105
|
focusParentSession(): Promise<void>;
|
|
105
106
|
/** Return the view to the main session (delegates to SessionFocusController.unfocus). */
|
|
106
107
|
unfocusSession(): Promise<void>;
|
|
107
|
-
/** Clear loader,
|
|
108
|
+
/** Clear loader, transient HUD/pending containers, streaming state, and pending tools. */
|
|
108
109
|
clearTransientSessionUi(): void;
|
|
109
110
|
settings: Settings;
|
|
110
111
|
keybindings: KeybindingsManager;
|
|
@@ -142,10 +143,14 @@ export interface InteractiveModeContext {
|
|
|
142
143
|
hideThinkingBlock: boolean;
|
|
143
144
|
/**
|
|
144
145
|
* Effective thinking-block visibility: true when hidden by user setting OR
|
|
145
|
-
* thinking level is "off"
|
|
146
|
-
*
|
|
146
|
+
* thinking level is "off" before the session has produced displayable
|
|
147
|
+
* thinking content.
|
|
147
148
|
*/
|
|
148
149
|
readonly effectiveHideThinkingBlock: boolean;
|
|
150
|
+
/** Whether this visible session has produced thinking content the user can reveal. */
|
|
151
|
+
readonly hasDisplayableThinkingContent: boolean;
|
|
152
|
+
/** Record a message whose thinking content makes Ctrl+T meaningful even at thinking level "off"; returns true on first observation. */
|
|
153
|
+
noteDisplayableThinkingContent(message: AgentMessage): boolean;
|
|
149
154
|
proseOnlyThinking: boolean;
|
|
150
155
|
compactionQueuedMessages: CompactionQueuedMessage[];
|
|
151
156
|
pendingTools: Map<string, ToolExecutionHandle>;
|
|
@@ -316,6 +321,7 @@ export interface InteractiveModeContext {
|
|
|
316
321
|
refreshSlashCommandState(cwd?: string): Promise<void>;
|
|
317
322
|
applyCwdChange(newCwd: string): Promise<void>;
|
|
318
323
|
showSettingsSelector(): void;
|
|
324
|
+
showAdvisorConfigure(): void;
|
|
319
325
|
showHistorySearch(): void;
|
|
320
326
|
showExtensionsDashboard(): void;
|
|
321
327
|
showAgentsDashboard(): void;
|
|
@@ -17,6 +17,7 @@ import { Agent, type AgentEvent, type AgentMessage, type AgentState, type AgentT
|
|
|
17
17
|
import { type CompactionResult, type ShakeConfig } from "@oh-my-pi/pi-agent-core/compaction";
|
|
18
18
|
import type { AssistantMessage, Context, ImageContent, Message, MessageAttribution, Model, ProviderSessionState, ResetCreditAccountStatus, ResetCreditRedeemOutcome, ResetCreditTarget, ServiceTier, SimpleStreamOptions, TextContent, ToolChoice, UsageReport } from "@oh-my-pi/pi-ai";
|
|
19
19
|
import { Effort } from "@oh-my-pi/pi-ai";
|
|
20
|
+
import { type AdvisorConfig } from "../advisor";
|
|
20
21
|
import { type AsyncJob, type AsyncJobDeliveryState, AsyncJobManager } from "../async";
|
|
21
22
|
import type { Rule } from "../capability/rule";
|
|
22
23
|
import type { ModelRegistry } from "../config/model-registry";
|
|
@@ -247,20 +248,29 @@ export interface AgentSessionConfig {
|
|
|
247
248
|
*/
|
|
248
249
|
providerSessionId?: string;
|
|
249
250
|
/**
|
|
250
|
-
*
|
|
251
|
-
*
|
|
252
|
-
* advisor's
|
|
253
|
-
*
|
|
251
|
+
* Full advisor toolset, pre-built in `createAgentSession` against a distinct,
|
|
252
|
+
* advisor-scoped `ToolSession` (its own `-advisor` session/agent id) so the
|
|
253
|
+
* advisor's tool state stays isolated from the primary. The advisor is a full
|
|
254
|
+
* agent; its config `tools` selects a subset (default read/grep/glob). Undefined
|
|
255
|
+
* when the advisor is disabled.
|
|
254
256
|
*/
|
|
255
|
-
|
|
257
|
+
advisorTools?: AgentTool[];
|
|
256
258
|
/** Preloaded watchdog prompt content for the advisor. */
|
|
257
259
|
advisorWatchdogPrompt?: string;
|
|
260
|
+
/** Preloaded YAML top-level `instructions` shared baseline, kept separate from
|
|
261
|
+
* `advisorWatchdogPrompt` so `/advisor configure` can swap it live. */
|
|
262
|
+
advisorSharedInstructions?: string;
|
|
258
263
|
/**
|
|
259
264
|
* Preloaded project context files (AGENTS.md, etc.) rendered as a system-prompt
|
|
260
265
|
* block for the advisor — the same standing instructions the primary agent
|
|
261
266
|
* receives, so the reviewer holds the agent to them.
|
|
262
267
|
*/
|
|
263
268
|
advisorContextPrompt?: string;
|
|
269
|
+
/**
|
|
270
|
+
* Advisors discovered from `WATCHDOG.yml`. Empty/undefined runs a single
|
|
271
|
+
* legacy advisor on the `advisor` role (byte-for-byte the pre-config path).
|
|
272
|
+
*/
|
|
273
|
+
advisorConfigs?: AdvisorConfig[];
|
|
264
274
|
/**
|
|
265
275
|
* Strip tool descriptions from provider-bound tool specs on side requests
|
|
266
276
|
* (handoff). Must match the session-start value used to build the system
|
|
@@ -356,6 +366,7 @@ export interface SessionStats {
|
|
|
356
366
|
tokens: {
|
|
357
367
|
input: number;
|
|
358
368
|
output: number;
|
|
369
|
+
reasoning: number;
|
|
359
370
|
cacheRead: number;
|
|
360
371
|
cacheWrite: number;
|
|
361
372
|
total: number;
|
|
@@ -373,6 +384,7 @@ export interface AdvisorStats {
|
|
|
373
384
|
tokens: {
|
|
374
385
|
input: number;
|
|
375
386
|
output: number;
|
|
387
|
+
reasoning: number;
|
|
376
388
|
cacheRead: number;
|
|
377
389
|
cacheWrite: number;
|
|
378
390
|
total: number;
|
|
@@ -383,6 +395,18 @@ export interface AdvisorStats {
|
|
|
383
395
|
assistant: number;
|
|
384
396
|
total: number;
|
|
385
397
|
};
|
|
398
|
+
/** Per-advisor breakdown; one entry per active advisor (single-advisor sessions have one). */
|
|
399
|
+
advisors: PerAdvisorStat[];
|
|
400
|
+
}
|
|
401
|
+
/** One advisor's slice of {@link AdvisorStats}, surfaced for the multi-advisor status panel. */
|
|
402
|
+
export interface PerAdvisorStat {
|
|
403
|
+
name: string;
|
|
404
|
+
model: Model;
|
|
405
|
+
contextWindow: number;
|
|
406
|
+
contextTokens: number;
|
|
407
|
+
tokens: AdvisorStats["tokens"];
|
|
408
|
+
cost: number;
|
|
409
|
+
messages: AdvisorStats["messages"];
|
|
386
410
|
}
|
|
387
411
|
export interface FreshSessionResult {
|
|
388
412
|
previousSessionId: string;
|
|
@@ -394,6 +418,7 @@ export type RestoredQueuedMessage = {
|
|
|
394
418
|
text: string;
|
|
395
419
|
images?: ImageContent[];
|
|
396
420
|
};
|
|
421
|
+
type SessionNameTrigger = "replan";
|
|
397
422
|
export declare class AgentSession {
|
|
398
423
|
#private;
|
|
399
424
|
readonly agent: Agent;
|
|
@@ -698,6 +723,7 @@ export declare class AgentSession {
|
|
|
698
723
|
prompt(text: string, options?: PromptOptions): Promise<boolean>;
|
|
699
724
|
promptCustomMessage<T = unknown>(message: Pick<CustomMessage<T>, "customType" | "content" | "display" | "details" | "attribution">, options?: Pick<PromptOptions, "streamingBehavior" | "toolChoice"> & {
|
|
700
725
|
queueChipText?: string;
|
|
726
|
+
queueOnly?: boolean;
|
|
701
727
|
}): Promise<void>;
|
|
702
728
|
/**
|
|
703
729
|
* Queue a steering message to interrupt the agent mid-run.
|
|
@@ -797,7 +823,7 @@ export declare class AgentSession {
|
|
|
797
823
|
/**
|
|
798
824
|
* Set a display name for the current session.
|
|
799
825
|
*/
|
|
800
|
-
setSessionName(name: string, source?: "auto" | "user"): Promise<boolean>;
|
|
826
|
+
setSessionName(name: string, source?: "auto" | "user", trigger?: SessionNameTrigger): Promise<boolean>;
|
|
801
827
|
/**
|
|
802
828
|
* Fork the current session, creating a new session file with the exact same state.
|
|
803
829
|
* Copies all entries and artifacts to the new session.
|
|
@@ -808,16 +834,22 @@ export declare class AgentSession {
|
|
|
808
834
|
/**
|
|
809
835
|
* Set model directly.
|
|
810
836
|
* Validates that a credential source is configured (synchronously, without
|
|
811
|
-
* refreshing OAuth or running command-backed key programs)
|
|
812
|
-
*
|
|
813
|
-
*
|
|
837
|
+
* refreshing OAuth or running command-backed key programs). The active
|
|
838
|
+
* session switches by default; when `currentContextTokens` is provided and
|
|
839
|
+
* exceeds the refreshed candidate's context window, the live switch is
|
|
840
|
+
* skipped while role persistence still runs. Returns whether the active
|
|
841
|
+
* model actually switched, computed against the refreshed metadata so
|
|
842
|
+
* dynamic providers (e.g. llama.cpp) honor their post-load contextWindow.
|
|
814
843
|
* @throws Error if no API key available for the model
|
|
815
844
|
*/
|
|
816
845
|
setModel(model: Model, role?: string, options?: {
|
|
817
846
|
selector?: string;
|
|
818
847
|
thinkingLevel?: ThinkingLevel;
|
|
819
848
|
persist?: boolean;
|
|
820
|
-
|
|
849
|
+
currentContextTokens?: number;
|
|
850
|
+
}): Promise<{
|
|
851
|
+
switched: boolean;
|
|
852
|
+
}>;
|
|
821
853
|
/**
|
|
822
854
|
* Set model temporarily (for this session only).
|
|
823
855
|
* Validates that a credential source is configured (synchronously, without
|
|
@@ -1258,6 +1290,15 @@ export declare class AgentSession {
|
|
|
1258
1290
|
* @returns true when the advisor is actively running after the call.
|
|
1259
1291
|
*/
|
|
1260
1292
|
toggleAdvisorEnabled(): boolean;
|
|
1293
|
+
/**
|
|
1294
|
+
* Replace the live advisor roster from an edited `WATCHDOG.yml` (the `/advisor
|
|
1295
|
+
* configure` save path). Swaps the configs + shared baseline, then rebuilds the
|
|
1296
|
+
* runtimes in place so the change applies without a restart. When the advisor is
|
|
1297
|
+
* disabled the new configs are simply stored for the next enable.
|
|
1298
|
+
*
|
|
1299
|
+
* @returns the number of advisors active after the rebuild.
|
|
1300
|
+
*/
|
|
1301
|
+
applyAdvisorConfigs(advisors: AdvisorConfig[], sharedInstructions: string | undefined): number;
|
|
1261
1302
|
/**
|
|
1262
1303
|
* Whether the advisor setting is enabled for this session.
|
|
1263
1304
|
*/
|
|
@@ -1269,6 +1310,13 @@ export declare class AgentSession {
|
|
|
1269
1310
|
* not merely the setting. Drives the status-line badge and `/dump advisor`.
|
|
1270
1311
|
*/
|
|
1271
1312
|
isAdvisorActive(): boolean;
|
|
1313
|
+
/**
|
|
1314
|
+
* The names of the tools available to advisors this session (the pool a
|
|
1315
|
+
* `/advisor configure` editor lists). The advisor is a full agent, so this is the
|
|
1316
|
+
* full built tool set; a tool whose optional factory returns null (e.g. lsp with
|
|
1317
|
+
* no servers) is absent.
|
|
1318
|
+
*/
|
|
1319
|
+
getAdvisorAvailableToolNames(): string[];
|
|
1272
1320
|
/**
|
|
1273
1321
|
* The live advisor `Agent`, or `undefined` when no advisor runtime is
|
|
1274
1322
|
* attached. Surfaced for diagnostics (`/dump advisor` already serializes
|
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
import type { SessionStorage, SessionStorageStat, SessionStorageWriter } from "./session-storage";
|
|
2
|
+
import { type SessionTitleUpdate } from "./session-title-slot";
|
|
2
3
|
export interface SessionStorageIndexEntry {
|
|
3
4
|
path: string;
|
|
4
5
|
size: number;
|
|
5
6
|
mtimeMs: number;
|
|
7
|
+
title?: string;
|
|
8
|
+
titleSource?: SessionTitleUpdate["source"];
|
|
9
|
+
titleUpdatedAt?: string;
|
|
6
10
|
}
|
|
7
11
|
export interface SessionStorageBackend {
|
|
8
12
|
init(): Promise<void>;
|
|
9
13
|
loadIndex(): Promise<Iterable<SessionStorageIndexEntry>>;
|
|
10
14
|
readFull(path: string): Promise<string | null>;
|
|
11
15
|
readSlices(path: string, prefixBytes: number, suffixBytes: number): Promise<[string, string]>;
|
|
12
|
-
writeFull(path: string, content: string, mtimeMs: number): Promise<void>;
|
|
16
|
+
writeFull(path: string, content: string, mtimeMs: number, title?: SessionTitleUpdate): Promise<void>;
|
|
13
17
|
append(path: string, line: string, mtimeMs: number): Promise<void>;
|
|
18
|
+
updateSessionTitle(path: string, title: SessionTitleUpdate, mtimeMs: number): Promise<void>;
|
|
14
19
|
truncate(path: string, mtimeMs: number): Promise<void>;
|
|
15
20
|
remove(paths: string[]): Promise<void>;
|
|
16
21
|
move(src: string, dst: string, mtimeMs: number): Promise<void>;
|
|
@@ -24,6 +29,7 @@ export declare class IndexedSessionStorage implements SessionStorage {
|
|
|
24
29
|
ensureDirSync(_dir: string): void;
|
|
25
30
|
existsSync(path: string): boolean;
|
|
26
31
|
writeTextSync(path: string, content: string): void;
|
|
32
|
+
updateSessionTitle(path: string, title: SessionTitleUpdate): Promise<void>;
|
|
27
33
|
statSync(path: string): SessionStorageStat;
|
|
28
34
|
listFilesSync(dir: string, pattern: string): string[];
|
|
29
35
|
exists(path: string): Promise<boolean>;
|
|
@@ -12,6 +12,32 @@ import type { OutputMeta } from "../tools/output-meta";
|
|
|
12
12
|
export declare const SKILL_PROMPT_MESSAGE_TYPE = "skill-prompt";
|
|
13
13
|
export declare const LSP_LATE_DIAGNOSTIC_MESSAGE_TYPE = "lsp-late-diagnostic";
|
|
14
14
|
export declare const BACKGROUND_TAN_DISPATCH_MESSAGE_TYPE = "background-tan-dispatch";
|
|
15
|
+
/** Custom message type for hidden interrupted-thinking continuity context. */
|
|
16
|
+
export declare const INTERRUPTED_THINKING_MESSAGE_TYPE = "interrupted-thinking";
|
|
17
|
+
/** Metadata persisted with a hidden interrupted-thinking continuity message. */
|
|
18
|
+
export interface InterruptedThinkingDetails {
|
|
19
|
+
interruptedAt: number;
|
|
20
|
+
provider: AssistantMessage["provider"];
|
|
21
|
+
model: string;
|
|
22
|
+
blockCount: number;
|
|
23
|
+
}
|
|
24
|
+
/** Pure helper result for persisting interrupted thinking outside the assistant turn. */
|
|
25
|
+
export interface DemotedInterruptedThinking {
|
|
26
|
+
reasoning: string;
|
|
27
|
+
strippedContent: AssistantMessage["content"];
|
|
28
|
+
blockCount: number;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Demote a trailing run of *incomplete* interrupted-thinking from an assistant
|
|
32
|
+
* message — reasoning that was still streaming when the user aborted.
|
|
33
|
+
*
|
|
34
|
+
* A block joins the run only when it is a non-empty `thinking` block with no
|
|
35
|
+
* `thinkingSignature`. A signed/complete thinking block (Anthropic signature,
|
|
36
|
+
* OpenAI reasoning item id) is safely replayable, so it ends the run and stays
|
|
37
|
+
* in place — as do `redactedThinking` encrypted blobs, text, tool calls,
|
|
38
|
+
* empty-thinking blocks, and trailing empty text placeholders.
|
|
39
|
+
*/
|
|
40
|
+
export declare function demoteInterruptedThinking(message: Pick<AssistantMessage, "content">): DemotedInterruptedThinking | undefined;
|
|
15
41
|
/** Details persisted on a `/tan` background-dispatch breadcrumb. */
|
|
16
42
|
export interface BackgroundTanDispatchDetails {
|
|
17
43
|
jobId: string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,13 +1,26 @@
|
|
|
1
1
|
import type { AgentMessage } from "@oh-my-pi/pi-agent-core";
|
|
2
2
|
import type { ImageContent, MessageAttribution, ServiceTier, TextContent } from "@oh-my-pi/pi-ai";
|
|
3
3
|
export declare const CURRENT_SESSION_VERSION = 3;
|
|
4
|
+
export declare const SESSION_TITLE_SLOT_BYTES = 256;
|
|
5
|
+
export declare const SESSION_TITLE_SLOT_ENTRY_TYPE = "title";
|
|
6
|
+
export declare const TITLE_CHANGE_ENTRY_TYPE = "title_change";
|
|
7
|
+
export type SessionTitleSource = "auto" | "user";
|
|
8
|
+
/** Fixed-width first-line slot carrying the mutable current session title. */
|
|
9
|
+
export interface SessionTitleSlotEntry {
|
|
10
|
+
type: typeof SESSION_TITLE_SLOT_ENTRY_TYPE;
|
|
11
|
+
v: 1;
|
|
12
|
+
title: string;
|
|
13
|
+
source?: SessionTitleSource;
|
|
14
|
+
updatedAt: string;
|
|
15
|
+
pad: string;
|
|
16
|
+
}
|
|
4
17
|
export declare const EPHEMERAL_MODEL_CHANGE_ROLE = "fallback";
|
|
5
18
|
export interface SessionHeader {
|
|
6
19
|
type: "session";
|
|
7
20
|
version?: number;
|
|
8
21
|
id: string;
|
|
9
22
|
title?: string;
|
|
10
|
-
titleSource?:
|
|
23
|
+
titleSource?: SessionTitleSource;
|
|
11
24
|
timestamp: string;
|
|
12
25
|
cwd: string;
|
|
13
26
|
parentSession?: string;
|
|
@@ -91,6 +104,19 @@ export interface LabelEntry extends SessionEntryBase {
|
|
|
91
104
|
targetId: string;
|
|
92
105
|
label: string | undefined;
|
|
93
106
|
}
|
|
107
|
+
/** Append-only audit entry recording a session title change. */
|
|
108
|
+
export interface TitleChangeEntry extends SessionEntryBase {
|
|
109
|
+
type: typeof TITLE_CHANGE_ENTRY_TYPE;
|
|
110
|
+
title: string;
|
|
111
|
+
previousTitle?: string;
|
|
112
|
+
source: SessionTitleSource;
|
|
113
|
+
trigger?: string;
|
|
114
|
+
}
|
|
115
|
+
declare module "@oh-my-pi/pi-agent-core/compaction/entries" {
|
|
116
|
+
interface CustomCompactionSessionEntries {
|
|
117
|
+
titleChange: TitleChangeEntry;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
94
120
|
/** TTSR injection entry - tracks which time-traveling rules have been injected this session. */
|
|
95
121
|
export interface TtsrInjectionEntry extends SessionEntryBase {
|
|
96
122
|
type: "ttsr_injection";
|
|
@@ -149,9 +175,11 @@ export interface CustomMessageEntry<T = unknown> extends SessionEntryBase {
|
|
|
149
175
|
attribution?: MessageAttribution;
|
|
150
176
|
}
|
|
151
177
|
/** Session entry - has id/parentId for tree structure (returned by "read" methods in SessionManager) */
|
|
152
|
-
export type SessionEntry = SessionMessageEntry | ThinkingLevelChangeEntry | ModelChangeEntry | ServiceTierChangeEntry | CompactionEntry | BranchSummaryEntry | CustomEntry | CustomMessageEntry | LabelEntry | TtsrInjectionEntry | MCPToolSelectionEntry | SessionInitEntry | ModeChangeEntry;
|
|
153
|
-
/** Raw file entry
|
|
178
|
+
export type SessionEntry = SessionMessageEntry | ThinkingLevelChangeEntry | ModelChangeEntry | ServiceTierChangeEntry | CompactionEntry | BranchSummaryEntry | CustomEntry | CustomMessageEntry | LabelEntry | TitleChangeEntry | TtsrInjectionEntry | MCPToolSelectionEntry | SessionInitEntry | ModeChangeEntry;
|
|
179
|
+
/** Raw logical file entry after loaders strip any fixed-width title slot. */
|
|
154
180
|
export type FileEntry = SessionHeader | SessionEntry;
|
|
181
|
+
/** Physical JSONL entry before slot-aware loaders fold the title slot. */
|
|
182
|
+
export type RawFileEntry = SessionTitleSlotEntry | FileEntry;
|
|
155
183
|
/** Tree node for getTree() - defensive copy of session structure */
|
|
156
184
|
export interface SessionTreeNode {
|
|
157
185
|
entry: SessionEntry;
|
|
@@ -18,6 +18,12 @@ export interface HistoryFormatOptions {
|
|
|
18
18
|
* still collapse to a one-liner.
|
|
19
19
|
*/
|
|
20
20
|
expandPrimaryContext?: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Append the full unified diff (from a tool result's `details.diff`) below
|
|
23
|
+
* edit/apply_patch tool lines, instead of just the path. The advisor sets
|
|
24
|
+
* this so it sees what changed without re-reading the file.
|
|
25
|
+
*/
|
|
26
|
+
expandEditDiffs?: boolean;
|
|
21
27
|
}
|
|
22
28
|
/**
|
|
23
29
|
* Hidden custom messages that inject the primary agent's operative *constraints*
|
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
import type { AgentMessage } from "@oh-my-pi/pi-agent-core";
|
|
2
2
|
import { BlobStore } from "./blob-store";
|
|
3
|
-
import type
|
|
3
|
+
import { type FileEntry, type SessionTitleSlotEntry } from "./session-entries";
|
|
4
4
|
import { type SessionStorage } from "./session-storage";
|
|
5
|
+
import { type SessionTitleUpdate } from "./session-title-slot";
|
|
6
|
+
/** Parse session JSONL while stripping and folding the optional fixed title slot. */
|
|
7
|
+
export declare function parseSessionContent(content: string): {
|
|
8
|
+
entries: FileEntry[];
|
|
9
|
+
titleSlot: SessionTitleUpdate | undefined;
|
|
10
|
+
};
|
|
11
|
+
/** Read only the fixed-size head window to detect a physical title slot. */
|
|
12
|
+
export declare function readTitleSlotFromFile(filePath: string, storage?: SessionStorage): Promise<SessionTitleSlotEntry | undefined>;
|
|
5
13
|
/** Exported for compaction.test.ts */
|
|
6
14
|
export declare function parseSessionEntries(content: string): FileEntry[];
|
|
7
15
|
/** Exported for testing */
|
|
@@ -3,7 +3,7 @@ import { ArtifactManager } from "./artifacts";
|
|
|
3
3
|
import { type BlobPutOptions, type BlobPutResult } from "./blob-store";
|
|
4
4
|
import { type BashExecutionMessage, type CustomMessage, type FileMentionMessage, type HookMessage, type PythonExecutionMessage } from "./messages";
|
|
5
5
|
import { type BuildSessionContextOptions, type SessionContext } from "./session-context";
|
|
6
|
-
import { type NewSessionOptions, type SessionEntry, type SessionHeader, type SessionTreeNode, type UsageStatistics } from "./session-entries";
|
|
6
|
+
import { type NewSessionOptions, type SessionEntry, type SessionHeader, type SessionTitleSource, type SessionTreeNode, type UsageStatistics } from "./session-entries";
|
|
7
7
|
import { type SessionInfo } from "./session-listing";
|
|
8
8
|
import { type SessionStorage } from "./session-storage";
|
|
9
9
|
export type ReadonlySessionManager = Pick<SessionManager, "getCwd" | "getSessionDir" | "getSessionId" | "getSessionFile" | "getSessionName" | "getArtifactsDir" | "getArtifactManager" | "allocateArtifactPath" | "saveArtifact" | "getArtifactPath" | "getLeafId" | "getLeafEntry" | "getEntry" | "getLabel" | "getBranch" | "getHeader" | "getEntries" | "getTree" | "getUsageStatistics" | "putBlob" | "putBlobSync">;
|
|
@@ -12,8 +12,10 @@ interface SessionManagerStateSnapshot {
|
|
|
12
12
|
sessionDir: string;
|
|
13
13
|
sessionId: string;
|
|
14
14
|
sessionName: string | undefined;
|
|
15
|
-
titleSource:
|
|
15
|
+
titleSource: SessionTitleSource | undefined;
|
|
16
16
|
sessionFile: string | undefined;
|
|
17
|
+
titleUpdatedAt: string;
|
|
18
|
+
hasTitleSlot: boolean;
|
|
17
19
|
onDisk: boolean;
|
|
18
20
|
needsRewrite: boolean;
|
|
19
21
|
header: SessionHeader;
|
|
@@ -109,7 +111,7 @@ export declare class SessionManager {
|
|
|
109
111
|
saveDraft(text: string): Promise<void>;
|
|
110
112
|
consumeDraft(): Promise<string | null>;
|
|
111
113
|
/** The source that set the session name: "user" (manual/RPC) or "auto" (generated title). */
|
|
112
|
-
get titleSource():
|
|
114
|
+
get titleSource(): SessionTitleSource | undefined;
|
|
113
115
|
getSessionName(): string | undefined;
|
|
114
116
|
onSessionNameChanged(cb: () => void): () => void;
|
|
115
117
|
/**
|
|
@@ -117,7 +119,7 @@ export declare class SessionManager {
|
|
|
117
119
|
* @param source "user" for explicit renames; "auto" for generated titles.
|
|
118
120
|
* Auto titles are ignored once the user has set a name.
|
|
119
121
|
*/
|
|
120
|
-
setSessionName(name: string, source?:
|
|
122
|
+
setSessionName(name: string, source?: SessionTitleSource, trigger?: string): Promise<boolean>;
|
|
121
123
|
/**
|
|
122
124
|
* Append a foreign (host-authored) entry verbatim, preserving its
|
|
123
125
|
* `id`/`parentId`. Used by collab guests to mirror the host session.
|
|
@@ -240,9 +242,8 @@ export declare class SessionManager {
|
|
|
240
242
|
/**
|
|
241
243
|
* Create a fresh empty session file in the default session directory for
|
|
242
244
|
* `cwd`, writing only the session header. The returned path can be passed to
|
|
243
|
-
* `setSessionFile` / `AgentSession.switchSession`
|
|
244
|
-
*
|
|
245
|
-
* dragging the current conversation along.
|
|
245
|
+
* `setSessionFile` / `AgentSession.switchSession` when a caller explicitly
|
|
246
|
+
* needs a brand-new persisted session at a cwd-derived path.
|
|
246
247
|
*/
|
|
247
248
|
static createEmptySessionFile(cwd: string, storage?: SessionStorage): string;
|
|
248
249
|
/**
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type SessionTitleUpdate } from "./session-title-slot";
|
|
1
2
|
export interface SessionStorageStat {
|
|
2
3
|
size: number;
|
|
3
4
|
mtimeMs: number;
|
|
@@ -22,6 +23,14 @@ export interface SessionStorage {
|
|
|
22
23
|
ensureDirSync(dir: string): void;
|
|
23
24
|
existsSync(path: string): boolean;
|
|
24
25
|
writeTextSync(path: string, content: string): void;
|
|
26
|
+
/**
|
|
27
|
+
* Update the current session title through the storage backend.
|
|
28
|
+
*
|
|
29
|
+
* File-like backends rewrite the fixed-width JSONL title slot; indexed
|
|
30
|
+
* backends can store the semantic title fields and synthesize the slot when
|
|
31
|
+
* reading.
|
|
32
|
+
*/
|
|
33
|
+
updateSessionTitle(path: string, update: SessionTitleUpdate): Promise<void>;
|
|
25
34
|
statSync(path: string): SessionStorageStat;
|
|
26
35
|
listFilesSync(dir: string, pattern: string): string[];
|
|
27
36
|
exists(path: string): Promise<boolean>;
|
|
@@ -43,6 +52,7 @@ export declare class FileSessionStorage implements SessionStorage {
|
|
|
43
52
|
ensureDirSync(dir: string): void;
|
|
44
53
|
existsSync(path: string): boolean;
|
|
45
54
|
writeTextSync(fpath: string, content: string): void;
|
|
55
|
+
updateSessionTitle(fpath: string, update: SessionTitleUpdate): Promise<void>;
|
|
46
56
|
statSync(path: string): SessionStorageStat;
|
|
47
57
|
listFilesSync(dir: string, pattern: string): string[];
|
|
48
58
|
exists(path: string): Promise<boolean>;
|
|
@@ -67,6 +77,7 @@ export declare class MemorySessionStorage implements SessionStorage {
|
|
|
67
77
|
ensureDirSync(_dir: string): void;
|
|
68
78
|
existsSync(path: string): boolean;
|
|
69
79
|
writeTextSync(path: string, content: string): void;
|
|
80
|
+
updateSessionTitle(path: string, update: SessionTitleUpdate): Promise<void>;
|
|
70
81
|
/**
|
|
71
82
|
* Internal O(1) append used by {@link MemorySessionStorageWriter}. Lazily
|
|
72
83
|
* creates the entry. External callers should go through `openWriter()`
|