WP2: Create AgentSession basic structure + update plan for keep-old-code strategy

This commit is contained in:
Mario Zechner 2025-12-09 00:05:06 +01:00
parent 3f305502cd
commit 29d96ab25a
4 changed files with 204 additions and 88 deletions

View file

@ -0,0 +1,109 @@
/**
* AgentSession - Core abstraction for agent lifecycle and session management.
*
* This class is shared between all run modes (interactive, print, rpc).
* It encapsulates:
* - Agent state access
* - Event subscription with automatic session persistence
* - Model and thinking level management
* - Compaction (manual and auto)
* - Bash execution
* - Session switching and branching
*
* Modes use this class and add their own I/O layer on top.
*/
import type { Agent, AgentState, AppMessage, ThinkingLevel } from "@mariozechner/pi-agent-core";
import type { Model } from "@mariozechner/pi-ai";
import type { SessionManager } from "../session-manager.js";
import type { SettingsManager } from "../settings-manager.js";
import type { FileSlashCommand } from "../slash-commands.js";
// ============================================================================
// Types
// ============================================================================
export interface AgentSessionConfig {
agent: Agent;
sessionManager: SessionManager;
settingsManager: SettingsManager;
/** Models to cycle through with Ctrl+P (from --models flag) */
scopedModels?: Array<{ model: Model<any>; thinkingLevel: ThinkingLevel }>;
/** File-based slash commands for expansion */
fileCommands?: FileSlashCommand[];
}
// ============================================================================
// AgentSession Class
// ============================================================================
export class AgentSession {
readonly agent: Agent;
readonly sessionManager: SessionManager;
readonly settingsManager: SettingsManager;
private _scopedModels: Array<{ model: Model<any>; thinkingLevel: ThinkingLevel }>;
private _fileCommands: FileSlashCommand[];
constructor(config: AgentSessionConfig) {
this.agent = config.agent;
this.sessionManager = config.sessionManager;
this.settingsManager = config.settingsManager;
this._scopedModels = config.scopedModels ?? [];
this._fileCommands = config.fileCommands ?? [];
}
// =========================================================================
// Read-only State Access
// =========================================================================
/** Full agent state */
get state(): AgentState {
return this.agent.state;
}
/** Current model (may be null if not yet selected) */
get model(): Model<any> | null {
return this.agent.state.model;
}
/** Current thinking level */
get thinkingLevel(): ThinkingLevel {
return this.agent.state.thinkingLevel;
}
/** Whether agent is currently streaming a response */
get isStreaming(): boolean {
return this.agent.state.isStreaming;
}
/** All messages including custom types like BashExecutionMessage */
get messages(): AppMessage[] {
return this.agent.state.messages;
}
/** Current queue mode */
get queueMode(): "all" | "one-at-a-time" {
return this.agent.getQueueMode();
}
/** Current session file path */
get sessionFile(): string {
return this.sessionManager.getSessionFile();
}
/** Current session ID */
get sessionId(): string {
return this.sessionManager.getSessionId();
}
/** Scoped models for cycling (from --models flag) */
get scopedModels(): ReadonlyArray<{ model: Model<any>; thinkingLevel: ThinkingLevel }> {
return this._scopedModels;
}
/** File-based slash commands */
get fileCommands(): ReadonlyArray<FileSlashCommand> {
return this._fileCommands;
}
}

View file

@ -35,7 +35,7 @@ export interface BashResult {
cancelled: boolean;
/** Whether the output was truncated */
truncated: boolean;
/** Path to temp file containing full output (if output exceeded threshold) */
/** Path to temp file containing full output (if output exceeded truncation threshold) */
fullOutputPath?: string;
}

View file

@ -2,4 +2,5 @@
* Core modules shared between all run modes.
*/
export { AgentSession, type AgentSessionConfig } from "./agent-session.js";
export { type BashExecutorOptions, type BashResult, executeBash } from "./bash-executor.js";