@fleetagent/pi-coding-agent 0.0.1 → 0.0.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 +32 -0
- package/dist/core/agent-session.d.ts +32 -7
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +225 -12
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/compaction/branch-summarization.d.ts +2 -2
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +2 -2
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +1 -1
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +3 -3
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +5 -5
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +15 -8
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/footer-data-provider.d.ts +1 -1
- package/dist/core/footer-data-provider.d.ts.map +1 -1
- package/dist/core/footer-data-provider.js +1 -1
- package/dist/core/footer-data-provider.js.map +1 -1
- package/dist/core/messages.d.ts +1 -0
- package/dist/core/messages.d.ts.map +1 -1
- package/dist/core/messages.js +4 -0
- package/dist/core/messages.js.map +1 -1
- package/dist/core/pi-agent.d.ts +5 -3
- package/dist/core/pi-agent.d.ts.map +1 -1
- package/dist/core/pi-agent.js +64 -18
- package/dist/core/pi-agent.js.map +1 -1
- package/dist/core/session/in-memory-session-manager.d.ts.map +1 -1
- package/dist/core/session/in-memory-session-manager.js +5 -7
- package/dist/core/session/in-memory-session-manager.js.map +1 -1
- package/dist/core/session/in-memory-session.d.ts +3 -1
- package/dist/core/session/in-memory-session.d.ts.map +1 -1
- package/dist/core/session/in-memory-session.js +5 -2
- package/dist/core/session/in-memory-session.js.map +1 -1
- package/dist/core/session/index.d.ts +2 -2
- package/dist/core/session/index.d.ts.map +1 -1
- package/dist/core/session/index.js.map +1 -1
- package/dist/core/session/jsonl-helpers.d.ts.map +1 -1
- package/dist/core/session/jsonl-helpers.js +4 -4
- package/dist/core/session/jsonl-helpers.js.map +1 -1
- package/dist/core/session/local-session-manager.d.ts.map +1 -1
- package/dist/core/session/local-session-manager.js +12 -11
- package/dist/core/session/local-session-manager.js.map +1 -1
- package/dist/core/session/local-session.d.ts +3 -1
- package/dist/core/session/local-session.d.ts.map +1 -1
- package/dist/core/session/local-session.js +7 -2
- package/dist/core/session/local-session.js.map +1 -1
- package/dist/core/session/remote-session-client.d.ts +6 -1
- package/dist/core/session/remote-session-client.d.ts.map +1 -1
- package/dist/core/session/remote-session-client.js.map +1 -1
- package/dist/core/session/remote-session-manager.d.ts.map +1 -1
- package/dist/core/session/remote-session-manager.js +28 -7
- package/dist/core/session/remote-session-manager.js.map +1 -1
- package/dist/core/session/remote-session.d.ts +3 -0
- package/dist/core/session/remote-session.d.ts.map +1 -1
- package/dist/core/session/remote-session.js +4 -1
- package/dist/core/session/remote-session.js.map +1 -1
- package/dist/core/session/session.d.ts +9 -3
- package/dist/core/session/session.d.ts.map +1 -1
- package/dist/core/session/session.js +64 -10
- package/dist/core/session/session.js.map +1 -1
- package/dist/core/session/stores/in-memory-session-store.d.ts +6 -14
- package/dist/core/session/stores/in-memory-session-store.d.ts.map +1 -1
- package/dist/core/session/stores/in-memory-session-store.js +8 -34
- package/dist/core/session/stores/in-memory-session-store.js.map +1 -1
- package/dist/core/session/stores/jsonl-session-store.d.ts +14 -14
- package/dist/core/session/stores/jsonl-session-store.d.ts.map +1 -1
- package/dist/core/session/stores/jsonl-session-store.js +153 -162
- package/dist/core/session/stores/jsonl-session-store.js.map +1 -1
- package/dist/core/session/stores/remote-session-store.d.ts +4 -6
- package/dist/core/session/stores/remote-session-store.d.ts.map +1 -1
- package/dist/core/session/stores/remote-session-store.js +18 -30
- package/dist/core/session/stores/remote-session-store.js.map +1 -1
- package/dist/core/session/stores/session-store.d.ts +1 -15
- package/dist/core/session/stores/session-store.d.ts.map +1 -1
- package/dist/core/session/stores/session-store.js.map +1 -1
- package/dist/core/session-cwd.d.ts +2 -2
- package/dist/core/session-cwd.d.ts.map +1 -1
- package/dist/core/session-cwd.js +5 -5
- package/dist/core/session-cwd.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +39 -37
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/docs/extensions.md +35 -32
- package/docs/index.md +1 -1
- package/docs/sdk.md +2 -0
- package/docs/session-format.md +21 -21
- package/docs/sessions.md +2 -2
- package/docs/tui.md +1 -1
- package/examples/README.md +3 -0
- package/examples/extensions/README.md +1 -1
- package/examples/extensions/auto-commit-on-exit.ts +1 -1
- package/examples/extensions/bookmark.ts +3 -3
- package/examples/extensions/confirm-destructive.ts +1 -1
- package/examples/extensions/custom-compaction.ts +1 -1
- package/examples/extensions/custom-footer.ts +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/git-checkpoint.ts +1 -1
- package/examples/extensions/handoff.ts +2 -2
- package/examples/extensions/plan-mode/index.ts +1 -1
- package/examples/extensions/preset.ts +1 -1
- package/examples/extensions/qna.ts +1 -1
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/snake.ts +1 -1
- package/examples/extensions/space-invaders.ts +1 -1
- package/examples/extensions/summarize.ts +1 -1
- package/examples/extensions/tic-tac-toe.ts +1 -1
- package/examples/extensions/todo.ts +1 -1
- package/examples/extensions/tools.ts +1 -1
- package/examples/extensions/with-deps/package.json +1 -1
- package/examples/remote-session-server/README.md +66 -0
- package/examples/remote-session-server/server.ts +359 -0
- package/examples/sdk/11-sessions.ts +3 -3
- package/examples/sdk/13-session-runtime.ts +6 -6
- package/npm-shrinkwrap.json +12 -12
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/core/messages.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,MAAM,CAAC,MAAM,yBAAyB,GAAG;;;CAGxC,CAAC;AAEF,MAAM,CAAC,MAAM,yBAAyB,GAAG;WAC9B,CAAC;AAEZ,MAAM,CAAC,MAAM,qBAAqB,GAAG;;;CAGpC,CAAC;AAEF,MAAM,CAAC,MAAM,qBAAqB,GAAG,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/core/messages.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Custom message types and transformers for the coding agent.\n *\n * Extends the base AgentMessage type with coding-agent specific message types,\n * and provides a transformer to convert them to LLM-compatible messages.\n */\n\nimport type { AgentMessage } from \"@fleetagent/pi-agent-core\";\nimport type { ImageContent, Message, TextContent } from \"@fleetagent/pi-ai\";\n\nexport const COMPACTION_SUMMARY_PREFIX = `The conversation history before this point was compacted into the following summary:\n\n<summary>\n`;\n\nexport const COMPACTION_SUMMARY_SUFFIX = `\n</summary>`;\n\nexport const BRANCH_SUMMARY_PREFIX = `The following is a summary of a branch that this conversation came back from:\n\n<summary>\n`;\n\nexport const BRANCH_SUMMARY_SUFFIX = `</summary>`;\n\nexport const STRUCTURED_RESPONSE_INTERNAL_CUSTOM_TYPE = \"structured_response_internal\";\n\n/**\n * Message type for bash executions via the ! command.\n */\nexport interface BashExecutionMessage {\n\trole: \"bashExecution\";\n\tcommand: string;\n\toutput: string;\n\texitCode: number | undefined;\n\tcancelled: boolean;\n\ttruncated: boolean;\n\tfullOutputPath?: string;\n\ttimestamp: number;\n\t/** If true, this message is excluded from LLM context (!! prefix) */\n\texcludeFromContext?: boolean;\n}\n\n/**\n * Message type for extension-injected messages via sendMessage().\n * These are custom messages that extensions can inject into the conversation.\n */\nexport interface CustomMessage<T = unknown> {\n\trole: \"custom\";\n\tcustomType: string;\n\tcontent: string | (TextContent | ImageContent)[];\n\tdisplay: boolean;\n\tdetails?: T;\n\ttimestamp: number;\n}\n\nexport interface BranchSummaryMessage {\n\trole: \"branchSummary\";\n\tsummary: string;\n\tfromId: string;\n\ttimestamp: number;\n}\n\nexport interface CompactionSummaryMessage {\n\trole: \"compactionSummary\";\n\tsummary: string;\n\ttokensBefore: number;\n\ttimestamp: number;\n}\n\n// Extend CustomAgentMessages via declaration merging\ndeclare module \"@fleetagent/pi-agent-core\" {\n\tinterface CustomAgentMessages {\n\t\tbashExecution: BashExecutionMessage;\n\t\tcustom: CustomMessage;\n\t\tbranchSummary: BranchSummaryMessage;\n\t\tcompactionSummary: CompactionSummaryMessage;\n\t}\n}\n\n/**\n * Convert a BashExecutionMessage to user message text for LLM context.\n */\nexport function bashExecutionToText(msg: BashExecutionMessage): string {\n\tlet text = `Ran \\`${msg.command}\\`\\n`;\n\tif (msg.output) {\n\t\ttext += `\\`\\`\\`\\n${msg.output}\\n\\`\\`\\``;\n\t} else {\n\t\ttext += \"(no output)\";\n\t}\n\tif (msg.cancelled) {\n\t\ttext += \"\\n\\n(command cancelled)\";\n\t} else if (msg.exitCode !== null && msg.exitCode !== undefined && msg.exitCode !== 0) {\n\t\ttext += `\\n\\nCommand exited with code ${msg.exitCode}`;\n\t}\n\tif (msg.truncated && msg.fullOutputPath) {\n\t\ttext += `\\n\\n[Output truncated. Full output: ${msg.fullOutputPath}]`;\n\t}\n\treturn text;\n}\n\nexport function createBranchSummaryMessage(summary: string, fromId: string, timestamp: string): BranchSummaryMessage {\n\treturn {\n\t\trole: \"branchSummary\",\n\t\tsummary,\n\t\tfromId,\n\t\ttimestamp: new Date(timestamp).getTime(),\n\t};\n}\n\nexport function createCompactionSummaryMessage(\n\tsummary: string,\n\ttokensBefore: number,\n\ttimestamp: string,\n): CompactionSummaryMessage {\n\treturn {\n\t\trole: \"compactionSummary\",\n\t\tsummary: summary,\n\t\ttokensBefore,\n\t\ttimestamp: new Date(timestamp).getTime(),\n\t};\n}\n\n/** Convert CustomMessageEntry to AgentMessage format */\nexport function createCustomMessage(\n\tcustomType: string,\n\tcontent: string | (TextContent | ImageContent)[],\n\tdisplay: boolean,\n\tdetails: unknown | undefined,\n\ttimestamp: string,\n): CustomMessage {\n\treturn {\n\t\trole: \"custom\",\n\t\tcustomType,\n\t\tcontent,\n\t\tdisplay,\n\t\tdetails,\n\t\ttimestamp: new Date(timestamp).getTime(),\n\t};\n}\n\n/**\n * Transform AgentMessages (including custom types) to LLM-compatible Messages.\n *\n * This is used by:\n * - Agent's transormToLlm option (for prompt calls and queued messages)\n * - Compaction's generateSummary (for summarization)\n * - Custom extensions and tools\n */\nexport function convertToLlm(messages: AgentMessage[]): Message[] {\n\treturn messages\n\t\t.map((m): Message | undefined => {\n\t\t\tswitch (m.role) {\n\t\t\t\tcase \"bashExecution\":\n\t\t\t\t\t// Skip messages excluded from context (!! prefix)\n\t\t\t\t\tif (m.excludeFromContext) {\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\t\t\t\t\treturn {\n\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\tcontent: [{ type: \"text\", text: bashExecutionToText(m) }],\n\t\t\t\t\t\ttimestamp: m.timestamp,\n\t\t\t\t\t};\n\t\t\t\tcase \"custom\": {\n\t\t\t\t\tif (m.customType === STRUCTURED_RESPONSE_INTERNAL_CUSTOM_TYPE) {\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\t\t\t\t\tconst content = typeof m.content === \"string\" ? [{ type: \"text\" as const, text: m.content }] : m.content;\n\t\t\t\t\treturn {\n\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\tcontent,\n\t\t\t\t\t\ttimestamp: m.timestamp,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tcase \"branchSummary\":\n\t\t\t\t\treturn {\n\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\tcontent: [{ type: \"text\" as const, text: BRANCH_SUMMARY_PREFIX + m.summary + BRANCH_SUMMARY_SUFFIX }],\n\t\t\t\t\t\ttimestamp: m.timestamp,\n\t\t\t\t\t};\n\t\t\t\tcase \"compactionSummary\":\n\t\t\t\t\treturn {\n\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t{ type: \"text\" as const, text: COMPACTION_SUMMARY_PREFIX + m.summary + COMPACTION_SUMMARY_SUFFIX },\n\t\t\t\t\t\t],\n\t\t\t\t\t\ttimestamp: m.timestamp,\n\t\t\t\t\t};\n\t\t\t\tcase \"user\":\n\t\t\t\tcase \"assistant\":\n\t\t\t\tcase \"toolResult\":\n\t\t\t\t\treturn m;\n\t\t\t\tdefault:\n\t\t\t\t\t// biome-ignore lint/correctness/noSwitchDeclarations: fine\n\t\t\t\t\tconst _exhaustiveCheck: never = m;\n\t\t\t\t\treturn undefined;\n\t\t\t}\n\t\t})\n\t\t.filter((m) => m !== undefined);\n}\n"]}
|
package/dist/core/pi-agent.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { AuthStorage } from "./auth-storage.ts";
|
|
|
5
5
|
import type { ReplacedSessionContext, SessionStartEvent, ToolDefinition } from "./extensions/index.ts";
|
|
6
6
|
import { ModelRegistry } from "./model-registry.ts";
|
|
7
7
|
import { type DefaultResourceLoaderOptions, type ResourceLoader } from "./resource-loader.ts";
|
|
8
|
-
import { type Session, type SessionInfo, type SessionManager } from "./session-manager.ts";
|
|
8
|
+
import { type Session, type SessionInfo, type SessionListProgress, type SessionManager } from "./session-manager.ts";
|
|
9
9
|
import { SettingsManager } from "./settings-manager.ts";
|
|
10
10
|
export interface PiAgentDiagnostic {
|
|
11
11
|
type: "info" | "warning" | "error";
|
|
@@ -101,6 +101,8 @@ export interface PiAgentRuntimeHost {
|
|
|
101
101
|
importFromJsonl(inputPath: string, cwdOverride?: string): Promise<{
|
|
102
102
|
cancelled: boolean;
|
|
103
103
|
}>;
|
|
104
|
+
listSessions(onProgress?: SessionListProgress): Promise<SessionInfo[]>;
|
|
105
|
+
listAllSessions(onProgress?: SessionListProgress): Promise<SessionInfo[]>;
|
|
104
106
|
dispose(): Promise<void>;
|
|
105
107
|
}
|
|
106
108
|
export declare class SessionImportFileNotFoundError extends Error {
|
|
@@ -184,8 +186,8 @@ export declare class PiAgent {
|
|
|
184
186
|
openSessionReference(reference: string): Session | Promise<Session>;
|
|
185
187
|
continueRecentSession(): Session | Promise<Session>;
|
|
186
188
|
forkSessionFrom(reference: string): Session | Promise<Session>;
|
|
187
|
-
listSessions(): Promise<SessionInfo[]>;
|
|
188
|
-
listAllSessions(): Promise<SessionInfo[]>;
|
|
189
|
+
listSessions(onProgress?: SessionListProgress): Promise<SessionInfo[]>;
|
|
190
|
+
listAllSessions(onProgress?: SessionListProgress): Promise<SessionInfo[]>;
|
|
189
191
|
dispose(): Promise<void>;
|
|
190
192
|
}
|
|
191
193
|
//# sourceMappingURL=pi-agent.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pi-agent.d.ts","sourceRoot":"","sources":["../../src/core/pi-agent.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync } from \"node:fs\";\nimport { join, resolve } from \"node:path\";\nimport { Agent, type AgentMessage, type ThinkingLevel } from \"@fleetagent/pi-agent-core\";\nimport { clampThinkingLevel, type ImageContent, type Message, type Model, streamSimple } from \"@fleetagent/pi-ai\";\nimport chalk from \"chalk\";\nimport { getAgentDir } from \"../config.ts\";\nimport { InteractiveMode, runPrintMode, runRpcMode } from \"../modes/index.ts\";\nimport { stopThemeWatcher } from \"../modes/interactive/theme/theme.ts\";\nimport { AgentSession } from \"./agent-session.ts\";\nimport { formatNoModelsAvailableMessage } from \"./auth-guidance.ts\";\nimport { AuthStorage } from \"./auth-storage.ts\";\nimport { DEFAULT_THINKING_LEVEL } from \"./defaults.ts\";\nimport type {\n\tExtensionRunner,\n\tReplacedSessionContext,\n\tSessionShutdownEvent,\n\tSessionStartEvent,\n\tToolDefinition,\n} from \"./extensions/index.ts\";\nimport { emitSessionShutdownEvent } from \"./extensions/runner.ts\";\nimport { convertToLlm } from \"./messages.ts\";\nimport { ModelRegistry } from \"./model-registry.ts\";\nimport { findInitialModel } from \"./model-resolver.ts\";\nimport { restoreStdout, takeOverStdout } from \"./output-guard.ts\";\nimport { DefaultResourceLoader, type DefaultResourceLoaderOptions, type ResourceLoader } from \"./resource-loader.ts\";\nimport { assertSessionCwdExists } from \"./session-cwd.ts\";\nimport {\n\tgetDefaultSessionDir,\n\tLocalSessionManager,\n\ttype Session,\n\ttype SessionInfo,\n\ttype SessionManager,\n} from \"./session-manager.ts\";\nimport { SettingsManager } from \"./settings-manager.ts\";\nimport { isInstallTelemetryEnabled } from \"./telemetry.ts\";\nimport { printTimings, time } from \"./timings.ts\";\nimport type { ToolName } from \"./tools/index.ts\";\n\nexport interface PiAgentDiagnostic {\n\ttype: \"info\" | \"warning\" | \"error\";\n\tmessage: string;\n}\n\nexport interface PiAgentServices {\n\tcwd: string;\n\tagentDir: string;\n\tauthStorage: AuthStorage;\n\tsettingsManager: SettingsManager;\n\tmodelRegistry: ModelRegistry;\n\tresourceLoader: ResourceLoader;\n\tdiagnostics: PiAgentDiagnostic[];\n}\n\nexport interface PiAgentSessionOptions {\n\tmodel?: Model<any>;\n\tthinkingLevel?: ThinkingLevel;\n\tscopedModels?: Array<{ model: Model<any>; thinkingLevel?: ThinkingLevel }>;\n\ttools?: string[];\n\tnoTools?: \"all\" | \"builtin\";\n\tcustomTools?: ToolDefinition[];\n}\n\nexport interface ResolvePiAgentSessionOptionsContext {\n\tservices: PiAgentServices;\n\tsession: Session;\n\tsessionStartEvent?: SessionStartEvent;\n}\n\nexport interface ResolvePiAgentSessionOptionsResult extends PiAgentSessionOptions {\n\tdiagnostics?: PiAgentDiagnostic[];\n}\n\nexport interface CreatePiAgentOptions extends PiAgentSessionOptions {\n\t/** Runtime mode. Default: embedded SDK usage. */\n\tmode?: PiAgentAppMode;\n\tcwd?: string;\n\tagentDir?: string;\n\t/** Session lifecycle/discovery backend. Default: local JSONL sessions for cwd. */\n\tsessionManager?: SessionManager;\n\t/** Shared auth storage reused across runtime recreation. */\n\tauthStorage?: AuthStorage;\n\tsettingsManager?: SettingsManager;\n\tmodelRegistry?: ModelRegistry;\n\textensionFlagValues?: Map<string, boolean | string>;\n\tresourceLoader?: ResourceLoader;\n\tresourceLoaderOptions?: Omit<DefaultResourceLoaderOptions, \"cwd\" | \"agentDir\" | \"settingsManager\">;\n\tresolveSessionOptions?: (\n\t\tcontext: ResolvePiAgentSessionOptionsContext,\n\t) => Promise<ResolvePiAgentSessionOptionsResult> | ResolvePiAgentSessionOptionsResult;\n}\n\nexport interface CreatePiAgentSessionOptions {\n\t/** Initial active conversation state. Default: sessionManager.create(). */\n\tsession?: Session;\n\tsessionStartEvent?: SessionStartEvent;\n}\n\nexport type PiAgentAppMode = \"embedded\" | \"interactive\" | \"print\" | \"json\" | \"rpc\";\n\nexport interface RunPiAgentModeOptions {\n\tmode?: PiAgentAppMode;\n\tmigratedProviders?: string[];\n\tinitialMessage?: string;\n\tinitialImages?: ImageContent[];\n\tinitialMessages?: string[];\n\tverbose?: boolean;\n\tstartupBenchmark?: boolean;\n}\n\nexport interface PiAgentRuntimeHost {\n\treadonly services: PiAgentServices;\n\treadonly session: AgentSession;\n\treadonly diagnostics: readonly PiAgentDiagnostic[];\n\treadonly modelFallbackMessage: string | undefined;\n\tsetRebindSession(rebindSession?: (session: AgentSession) => Promise<void>): void;\n\tsetBeforeSessionInvalidate(beforeSessionInvalidate?: () => void): void;\n\tswitchSession(\n\t\tsessionPath: string,\n\t\toptions?: { cwdOverride?: string; withSession?: (ctx: ReplacedSessionContext) => Promise<void> },\n\t): Promise<{ cancelled: boolean }>;\n\tnewSession(options?: {\n\t\tid?: string;\n\t\tparentSession?: string;\n\t\tsetup?: (session: Session) => Promise<void>;\n\t\twithSession?: (ctx: ReplacedSessionContext) => Promise<void>;\n\t}): Promise<{ cancelled: boolean }>;\n\tfork(\n\t\tentryId: string,\n\t\toptions?: { position?: \"before\" | \"at\"; withSession?: (ctx: ReplacedSessionContext) => Promise<void> },\n\t): Promise<{ cancelled: boolean; selectedText?: string }>;\n\timportFromJsonl(inputPath: string, cwdOverride?: string): Promise<{ cancelled: boolean }>;\n\tdispose(): Promise<void>;\n}\n\nexport class SessionImportFileNotFoundError extends Error {\n\treadonly filePath: string;\n\n\tconstructor(filePath: string) {\n\t\tsuper(`File not found: ${filePath}`);\n\t\tthis.name = \"SessionImportFileNotFoundError\";\n\t\tthis.filePath = filePath;\n\t}\n}\n\nfunction extractUserMessageText(content: string | Array<{ type: string; text?: string }>): string {\n\tif (typeof content === \"string\") {\n\t\treturn content;\n\t}\n\n\treturn content\n\t\t.filter((part): part is { type: \"text\"; text: string } => part.type === \"text\" && typeof part.text === \"string\")\n\t\t.map((part) => part.text)\n\t\t.join(\"\");\n}\n\nfunction getAttributionHeaders(\n\tmodel: Model<any>,\n\tsettingsManager: SettingsManager,\n): Record<string, string> | undefined {\n\tif (!isInstallTelemetryEnabled(settingsManager)) {\n\t\treturn undefined;\n\t}\n\n\tif (model.provider === \"openrouter\" || model.baseUrl.includes(\"openrouter.ai\")) {\n\t\treturn {\n\t\t\t\"HTTP-Referer\": \"https://pi.dev\",\n\t\t\t\"X-OpenRouter-Title\": \"pi\",\n\t\t\t\"X-OpenRouter-Categories\": \"cli-agent\",\n\t\t};\n\t}\n\n\tif (\n\t\tmodel.provider === \"cloudflare-workers-ai\" ||\n\t\tmodel.provider === \"cloudflare-ai-gateway\" ||\n\t\tmodel.baseUrl.includes(\"api.cloudflare.com\") ||\n\t\tmodel.baseUrl.includes(\"gateway.ai.cloudflare.com\")\n\t) {\n\t\treturn {\n\t\t\t\"User-Agent\": \"pi-coding-agent\",\n\t\t};\n\t}\n\n\treturn undefined;\n}\n\nfunction applyExtensionFlagValues(\n\tresourceLoader: ResourceLoader,\n\textensionFlagValues: Map<string, boolean | string> | undefined,\n): PiAgentDiagnostic[] {\n\tif (!extensionFlagValues) {\n\t\treturn [];\n\t}\n\n\tconst diagnostics: PiAgentDiagnostic[] = [];\n\tconst extensionsResult = resourceLoader.getExtensions();\n\tconst registeredFlags = new Map<string, { type: \"boolean\" | \"string\" }>();\n\tfor (const extension of extensionsResult.extensions) {\n\t\tfor (const [name, flag] of extension.flags) {\n\t\t\tregisteredFlags.set(name, { type: flag.type });\n\t\t}\n\t}\n\n\tconst unknownFlags: string[] = [];\n\tfor (const [name, value] of extensionFlagValues) {\n\t\tconst flag = registeredFlags.get(name);\n\t\tif (!flag) {\n\t\t\tunknownFlags.push(name);\n\t\t\tcontinue;\n\t\t}\n\t\tif (flag.type === \"boolean\") {\n\t\t\textensionsResult.runtime.flagValues.set(name, true);\n\t\t\tcontinue;\n\t\t}\n\t\tif (typeof value === \"string\") {\n\t\t\textensionsResult.runtime.flagValues.set(name, value);\n\t\t\tcontinue;\n\t\t}\n\t\tdiagnostics.push({\n\t\t\ttype: \"error\",\n\t\t\tmessage: `Extension flag \"--${name}\" requires a value`,\n\t\t});\n\t}\n\n\tif (unknownFlags.length > 0) {\n\t\tdiagnostics.push({\n\t\t\ttype: \"error\",\n\t\t\tmessage: `Unknown option${unknownFlags.length === 1 ? \"\" : \"s\"}: ${unknownFlags.map((name) => `--${name}`).join(\", \")}`,\n\t\t});\n\t}\n\n\treturn diagnostics;\n}\n\n/**\n * Application-level composition root for pi's coding agent runtime.\n *\n * PiAgent owns common app services, the session lifecycle backend, and the\n * current active AgentSession. Conversation behavior stays in AgentSession;\n * session lifecycle/discovery stays in SessionManager implementations.\n */\nexport class PiAgent {\n\tprivate readonly initialCwd: string;\n\treadonly agentDir: string;\n\treadonly sessionManager: SessionManager;\n\treadonly authStorage: AuthStorage;\n\n\tprivate readonly options: CreatePiAgentOptions;\n\tprivate _mode: PiAgentAppMode;\n\tprivate _session?: AgentSession;\n\tprivate _services?: PiAgentServices;\n\tprivate _diagnostics: PiAgentDiagnostic[] = [];\n\tprivate _modelFallbackMessage?: string;\n\tprivate rebindSession?: (session: AgentSession) => Promise<void>;\n\tprivate beforeSessionInvalidate?: () => void;\n\n\tprivate constructor(\n\t\toptions: CreatePiAgentOptions,\n\t\tresolved: {\n\t\t\tcwd: string;\n\t\t\tagentDir: string;\n\t\t\tsessionManager: SessionManager;\n\t\t\tauthStorage: AuthStorage;\n\t\t},\n\t) {\n\t\tthis.options = options;\n\t\tthis._mode = options.mode ?? \"embedded\";\n\t\tthis.initialCwd = resolved.cwd;\n\t\tthis.agentDir = resolved.agentDir;\n\t\tthis.sessionManager = resolved.sessionManager;\n\t\tthis.authStorage = resolved.authStorage;\n\t}\n\n\tstatic setupStdio(options: { mode: PiAgentAppMode }): void {\n\t\tif (options.mode !== \"embedded\" && options.mode !== \"interactive\") {\n\t\t\ttakeOverStdout();\n\t\t}\n\t}\n\n\tstatic async create(options: CreatePiAgentOptions = {}): Promise<PiAgent> {\n\t\tconst cwd = options.cwd ?? process.cwd();\n\t\tconst agentDir = options.agentDir ?? getAgentDir();\n\t\tconst sessionManager =\n\t\t\toptions.sessionManager ?? new LocalSessionManager({ cwd, sessionDir: getDefaultSessionDir(cwd, agentDir) });\n\t\tconst authStorage = options.authStorage ?? AuthStorage.create(join(agentDir, \"auth.json\"));\n\t\treturn new PiAgent(options, { cwd, agentDir, sessionManager, authStorage });\n\t}\n\n\tget mode(): PiAgentAppMode {\n\t\treturn this._mode;\n\t}\n\n\tget cwd(): string {\n\t\treturn this._services?.cwd ?? this.initialCwd;\n\t}\n\n\tasync readPipedStdin(): Promise<string | undefined> {\n\t\tif (this._mode === \"embedded\" || this._mode === \"rpc\" || process.stdin.isTTY) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst stdinContent = await new Promise<string | undefined>((resolve) => {\n\t\t\tlet data = \"\";\n\t\t\tprocess.stdin.setEncoding(\"utf8\");\n\t\t\tprocess.stdin.on(\"data\", (chunk) => {\n\t\t\t\tdata += chunk;\n\t\t\t});\n\t\t\tprocess.stdin.on(\"end\", () => {\n\t\t\t\tresolve(data.trim() || undefined);\n\t\t\t});\n\t\t\tprocess.stdin.resume();\n\t\t});\n\n\t\tif (stdinContent !== undefined && this._mode === \"interactive\") {\n\t\t\tthis._mode = \"print\";\n\t\t}\n\t\treturn stdinContent;\n\t}\n\n\tprivate async createServices(cwd: string): Promise<PiAgentServices> {\n\t\tconst settingsManager = this.options.settingsManager ?? SettingsManager.create(cwd, this.agentDir);\n\t\tconst modelRegistry =\n\t\t\tthis.options.modelRegistry ?? ModelRegistry.create(this.authStorage, join(this.agentDir, \"models.json\"));\n\t\tconst resourceLoader =\n\t\t\tthis.options.resourceLoader ??\n\t\t\tnew DefaultResourceLoader({\n\t\t\t\t...(this.options.resourceLoaderOptions ?? {}),\n\t\t\t\tcwd,\n\t\t\t\tagentDir: this.agentDir,\n\t\t\t\tsettingsManager,\n\t\t\t});\n\t\tawait resourceLoader.reload();\n\n\t\tconst diagnostics: PiAgentDiagnostic[] = [];\n\t\tconst extensionsResult = resourceLoader.getExtensions();\n\t\tfor (const { name, config, extensionPath } of extensionsResult.runtime.pendingProviderRegistrations) {\n\t\t\ttry {\n\t\t\t\tmodelRegistry.registerProvider(name, config);\n\t\t\t} catch (error) {\n\t\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\t\tdiagnostics.push({\n\t\t\t\t\ttype: \"error\",\n\t\t\t\t\tmessage: `Extension \"${extensionPath}\" error: ${message}`,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\textensionsResult.runtime.pendingProviderRegistrations = [];\n\t\tdiagnostics.push(...applyExtensionFlagValues(resourceLoader, this.options.extensionFlagValues));\n\n\t\treturn {\n\t\t\tcwd,\n\t\t\tagentDir: this.agentDir,\n\t\t\tauthStorage: this.authStorage,\n\t\t\tsettingsManager,\n\t\t\tmodelRegistry,\n\t\t\tresourceLoader,\n\t\t\tdiagnostics,\n\t\t};\n\t}\n\n\tprivate async buildAgentSession(\n\t\tactiveSession: Session,\n\t\tsessionStartEvent?: SessionStartEvent,\n\t): Promise<{\n\t\tsession: AgentSession;\n\t\tservices: PiAgentServices;\n\t\tdiagnostics: PiAgentDiagnostic[];\n\t\tmodelFallbackMessage?: string;\n\t}> {\n\t\tconst services = await this.createServices(activeSession.getCwd());\n\t\tconst diagnostics: PiAgentDiagnostic[] = [\n\t\t\t...services.diagnostics,\n\t\t\t...services.resourceLoader.getExtensions().errors.map(({ path, error }) => ({\n\t\t\t\ttype: \"error\" as const,\n\t\t\t\tmessage: `Failed to load extension \"${path}\": ${error}`,\n\t\t\t})),\n\t\t];\n\t\tconst resolvedOptions =\n\t\t\t(await this.options.resolveSessionOptions?.({ services, session: activeSession, sessionStartEvent })) ?? {};\n\t\tdiagnostics.push(...(resolvedOptions.diagnostics ?? []));\n\t\tconst sessionOptions: PiAgentSessionOptions = {\n\t\t\tmodel: resolvedOptions.model ?? this.options.model,\n\t\t\tthinkingLevel: resolvedOptions.thinkingLevel ?? this.options.thinkingLevel,\n\t\t\tscopedModels: resolvedOptions.scopedModels ?? this.options.scopedModels,\n\t\t\ttools: resolvedOptions.tools ?? this.options.tools,\n\t\t\tnoTools: resolvedOptions.noTools ?? this.options.noTools,\n\t\t\tcustomTools: resolvedOptions.customTools ?? this.options.customTools,\n\t\t};\n\n\t\tconst existingSession = activeSession.buildSessionContext();\n\t\tconst hasExistingSession = existingSession.messages.length > 0;\n\t\tconst hasThinkingEntry = activeSession.getBranch().some((entry) => entry.type === \"thinking_level_change\");\n\n\t\tlet model = sessionOptions.model;\n\t\tlet modelFallbackMessage: string | undefined;\n\n\t\tif (model) {\n\t\t\tmodel = services.modelRegistry.find(model.provider, model.id) ?? model;\n\t\t}\n\n\t\tif (!model && hasExistingSession && existingSession.model) {\n\t\t\tconst restoredModel = services.modelRegistry.find(\n\t\t\t\texistingSession.model.provider,\n\t\t\t\texistingSession.model.modelId,\n\t\t\t);\n\t\t\tif (restoredModel && services.modelRegistry.hasConfiguredAuth(restoredModel)) {\n\t\t\t\tmodel = restoredModel;\n\t\t\t}\n\t\t\tif (!model) {\n\t\t\t\tmodelFallbackMessage = `Could not restore model ${existingSession.model.provider}/${existingSession.model.modelId}`;\n\t\t\t}\n\t\t}\n\n\t\tif (!model) {\n\t\t\tconst result = await findInitialModel({\n\t\t\t\tscopedModels: [],\n\t\t\t\tisContinuing: hasExistingSession,\n\t\t\t\tdefaultProvider: services.settingsManager.getDefaultProvider(),\n\t\t\t\tdefaultModelId: services.settingsManager.getDefaultModel(),\n\t\t\t\tdefaultThinkingLevel: services.settingsManager.getDefaultThinkingLevel(),\n\t\t\t\tmodelRegistry: services.modelRegistry,\n\t\t\t});\n\t\t\tmodel = result.model;\n\t\t\tif (!model) {\n\t\t\t\tmodelFallbackMessage = formatNoModelsAvailableMessage();\n\t\t\t} else if (modelFallbackMessage) {\n\t\t\t\tmodelFallbackMessage += `. Using ${model.provider}/${model.id}`;\n\t\t\t}\n\t\t}\n\n\t\tlet thinkingLevel = sessionOptions.thinkingLevel;\n\t\tif (thinkingLevel === undefined && hasExistingSession) {\n\t\t\tthinkingLevel = hasThinkingEntry\n\t\t\t\t? (existingSession.thinkingLevel as ThinkingLevel)\n\t\t\t\t: (services.settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL);\n\t\t}\n\t\tif (thinkingLevel === undefined) {\n\t\t\tthinkingLevel = services.settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL;\n\t\t}\n\t\tthinkingLevel = model ? (clampThinkingLevel(model, thinkingLevel) as ThinkingLevel) : \"off\";\n\n\t\tconst defaultActiveToolNames: ToolName[] = [\"read\", \"bash\", \"edit\", \"write\"];\n\t\tconst allowedToolNames = sessionOptions.tools ?? (sessionOptions.noTools === \"all\" ? [] : undefined);\n\t\tconst initialActiveToolNames: string[] = sessionOptions.tools\n\t\t\t? [...sessionOptions.tools]\n\t\t\t: sessionOptions.noTools\n\t\t\t\t? []\n\t\t\t\t: defaultActiveToolNames;\n\n\t\tconst extensionRunnerRef: { current?: ExtensionRunner } = {};\n\t\tconst convertToLlmWithBlockImages = (messages: AgentMessage[]): Message[] => {\n\t\t\tconst converted = convertToLlm(messages);\n\t\t\tif (!services.settingsManager.getBlockImages()) {\n\t\t\t\treturn converted;\n\t\t\t}\n\t\t\treturn converted.map((msg) => {\n\t\t\t\tif (msg.role === \"user\" || msg.role === \"toolResult\") {\n\t\t\t\t\tconst content = msg.content;\n\t\t\t\t\tif (Array.isArray(content)) {\n\t\t\t\t\t\tconst hasImages = content.some((c) => c.type === \"image\");\n\t\t\t\t\t\tif (hasImages) {\n\t\t\t\t\t\t\tconst filteredContent = content\n\t\t\t\t\t\t\t\t.map((c) =>\n\t\t\t\t\t\t\t\t\tc.type === \"image\" ? { type: \"text\" as const, text: \"Image reading is disabled.\" } : c,\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t.filter(\n\t\t\t\t\t\t\t\t\t(c, i, arr) =>\n\t\t\t\t\t\t\t\t\t\t!(\n\t\t\t\t\t\t\t\t\t\t\tc.type === \"text\" &&\n\t\t\t\t\t\t\t\t\t\t\tc.text === \"Image reading is disabled.\" &&\n\t\t\t\t\t\t\t\t\t\t\ti > 0 &&\n\t\t\t\t\t\t\t\t\t\t\tarr[i - 1].type === \"text\" &&\n\t\t\t\t\t\t\t\t\t\t\t(arr[i - 1] as { type: \"text\"; text: string }).text === \"Image reading is disabled.\"\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\treturn { ...msg, content: filteredContent };\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn msg;\n\t\t\t});\n\t\t};\n\n\t\tconst agent = new Agent({\n\t\t\tinitialState: {\n\t\t\t\tsystemPrompt: \"\",\n\t\t\t\tmodel,\n\t\t\t\tthinkingLevel,\n\t\t\t\ttools: [],\n\t\t\t},\n\t\t\tconvertToLlm: convertToLlmWithBlockImages,\n\t\t\tstreamFn: async (model, context, options) => {\n\t\t\t\tconst auth = await services.modelRegistry.getApiKeyAndHeaders(model);\n\t\t\t\tif (!auth.ok) {\n\t\t\t\t\tthrow new Error(auth.error);\n\t\t\t\t}\n\t\t\t\tconst providerRetrySettings = services.settingsManager.getProviderRetrySettings();\n\t\t\t\tconst attributionHeaders = getAttributionHeaders(model, services.settingsManager);\n\t\t\t\treturn streamSimple(model, context, {\n\t\t\t\t\t...options,\n\t\t\t\t\tapiKey: auth.apiKey,\n\t\t\t\t\ttimeoutMs: options?.timeoutMs ?? providerRetrySettings.timeoutMs,\n\t\t\t\t\tmaxRetries: options?.maxRetries ?? providerRetrySettings.maxRetries,\n\t\t\t\t\tmaxRetryDelayMs: options?.maxRetryDelayMs ?? providerRetrySettings.maxRetryDelayMs,\n\t\t\t\t\theaders:\n\t\t\t\t\t\tattributionHeaders || auth.headers || options?.headers\n\t\t\t\t\t\t\t? { ...attributionHeaders, ...auth.headers, ...options?.headers }\n\t\t\t\t\t\t\t: undefined,\n\t\t\t\t});\n\t\t\t},\n\t\t\tonPayload: async (payload) => {\n\t\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\t\tif (!runner?.hasHandlers(\"before_provider_request\")) {\n\t\t\t\t\treturn payload;\n\t\t\t\t}\n\t\t\t\treturn runner.emitBeforeProviderRequest(payload);\n\t\t\t},\n\t\t\tonResponse: async (response) => {\n\t\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\t\tif (!runner?.hasHandlers(\"after_provider_response\")) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tawait runner.emit({\n\t\t\t\t\ttype: \"after_provider_response\",\n\t\t\t\t\tstatus: response.status,\n\t\t\t\t\theaders: response.headers,\n\t\t\t\t});\n\t\t\t},\n\t\t\tsessionId: activeSession.getSessionId(),\n\t\t\ttransformContext: async (messages) => {\n\t\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\t\treturn runner ? runner.emitContext(messages) : messages;\n\t\t\t},\n\t\t\tsteeringMode: services.settingsManager.getSteeringMode(),\n\t\t\tfollowUpMode: services.settingsManager.getFollowUpMode(),\n\t\t\ttransport: services.settingsManager.getTransport(),\n\t\t\tthinkingBudgets: services.settingsManager.getThinkingBudgets(),\n\t\t\tmaxRetryDelayMs: services.settingsManager.getProviderRetrySettings().maxRetryDelayMs,\n\t\t});\n\n\t\tif (hasExistingSession) {\n\t\t\tagent.state.messages = existingSession.messages;\n\t\t\tif (!hasThinkingEntry) {\n\t\t\t\tactiveSession.appendThinkingLevelChange(thinkingLevel);\n\t\t\t}\n\t\t} else {\n\t\t\tif (model) {\n\t\t\t\tactiveSession.appendModelChange(model.provider, model.id);\n\t\t\t}\n\t\t\tactiveSession.appendThinkingLevelChange(thinkingLevel);\n\t\t}\n\n\t\treturn {\n\t\t\tsession: new AgentSession({\n\t\t\t\tagent,\n\t\t\t\tsession: activeSession,\n\t\t\t\tsettingsManager: services.settingsManager,\n\t\t\t\tcwd: services.cwd,\n\t\t\t\tscopedModels: sessionOptions.scopedModels,\n\t\t\t\tresourceLoader: services.resourceLoader,\n\t\t\t\tcustomTools: sessionOptions.customTools,\n\t\t\t\tmodelRegistry: services.modelRegistry,\n\t\t\t\tinitialActiveToolNames,\n\t\t\t\tallowedToolNames,\n\t\t\t\textensionRunnerRef,\n\t\t\t\tsessionStartEvent,\n\t\t\t}),\n\t\t\tservices,\n\t\t\tdiagnostics,\n\t\t\tmodelFallbackMessage,\n\t\t};\n\t}\n\n\tprivate apply(result: {\n\t\tsession: AgentSession;\n\t\tservices: PiAgentServices;\n\t\tdiagnostics: PiAgentDiagnostic[];\n\t\tmodelFallbackMessage?: string;\n\t}): void {\n\t\tthis._session = result.session;\n\t\tthis._services = result.services;\n\t\tthis._diagnostics = result.diagnostics;\n\t\tthis._modelFallbackMessage = result.modelFallbackMessage;\n\t}\n\n\tasync createAgentSession(options: CreatePiAgentSessionOptions = {}): Promise<AgentSession> {\n\t\tconst initialSession = options.session ?? (await this.sessionManager.create());\n\t\tassertSessionCwdExists(initialSession, initialSession.getCwd());\n\t\tthis.apply(await this.buildAgentSession(initialSession, options.sessionStartEvent));\n\t\treturn this.session;\n\t}\n\n\tget runtime(): PiAgent {\n\t\tif (!this._session) {\n\t\t\tthrow new Error(\"PiAgent session has not been created. Call createAgentSession() first.\");\n\t\t}\n\t\treturn this;\n\t}\n\n\tget services(): PiAgentServices {\n\t\tif (!this._services) {\n\t\t\tthrow new Error(\"PiAgent services have not been created. Call createAgentSession() first.\");\n\t\t}\n\t\treturn this._services;\n\t}\n\n\tget session(): AgentSession {\n\t\tif (!this._session) {\n\t\t\tthrow new Error(\"PiAgent session has not been created. Call createAgentSession() first.\");\n\t\t}\n\t\treturn this._session;\n\t}\n\n\tget modelFallbackMessage(): string | undefined {\n\t\treturn this._modelFallbackMessage;\n\t}\n\n\tget settingsManager(): SettingsManager {\n\t\treturn this.services.settingsManager;\n\t}\n\n\tget modelRegistry(): ModelRegistry {\n\t\treturn this.services.modelRegistry;\n\t}\n\n\tget resourceLoader(): ResourceLoader {\n\t\treturn this.services.resourceLoader;\n\t}\n\n\tget diagnostics(): readonly PiAgentDiagnostic[] {\n\t\treturn this._diagnostics;\n\t}\n\n\tget currentCwd(): string {\n\t\treturn this.services.cwd;\n\t}\n\n\tsetRebindSession(rebindSession?: (session: AgentSession) => Promise<void>): void {\n\t\tthis.rebindSession = rebindSession;\n\t}\n\n\tsetBeforeSessionInvalidate(beforeSessionInvalidate?: () => void): void {\n\t\tthis.beforeSessionInvalidate = beforeSessionInvalidate;\n\t}\n\n\tprivate async emitBeforeSwitch(\n\t\treason: \"new\" | \"resume\",\n\t\ttargetSessionFile?: string,\n\t): Promise<{ cancelled: boolean }> {\n\t\tconst runner = this.session.extensionRunner;\n\t\tif (!runner.hasHandlers(\"session_before_switch\")) {\n\t\t\treturn { cancelled: false };\n\t\t}\n\n\t\tconst result = await runner.emit({\n\t\t\ttype: \"session_before_switch\",\n\t\t\treason,\n\t\t\ttargetSessionFile,\n\t\t});\n\t\treturn { cancelled: result?.cancel === true };\n\t}\n\n\tprivate async emitBeforeFork(\n\t\tentryId: string,\n\t\toptions: { position: \"before\" | \"at\" },\n\t): Promise<{ cancelled: boolean }> {\n\t\tconst runner = this.session.extensionRunner;\n\t\tif (!runner.hasHandlers(\"session_before_fork\")) {\n\t\t\treturn { cancelled: false };\n\t\t}\n\n\t\tconst result = await runner.emit({\n\t\t\ttype: \"session_before_fork\",\n\t\t\tentryId,\n\t\t\t...options,\n\t\t});\n\t\treturn { cancelled: result?.cancel === true };\n\t}\n\n\tprivate async flushActiveSession(): Promise<void> {\n\t\tconst flushPendingSync = (this.session.session as { flushPendingSync?: () => Promise<void> }).flushPendingSync;\n\t\tif (flushPendingSync) {\n\t\t\tawait flushPendingSync.call(this.session.session);\n\t\t}\n\t}\n\n\tprivate async teardownCurrent(reason: SessionShutdownEvent[\"reason\"], targetSessionFile?: string): Promise<void> {\n\t\tawait emitSessionShutdownEvent(this.session.extensionRunner, {\n\t\t\ttype: \"session_shutdown\",\n\t\t\treason,\n\t\t\ttargetSessionFile,\n\t\t});\n\t\tawait this.flushActiveSession();\n\t\tthis.beforeSessionInvalidate?.();\n\t\tthis.session.dispose();\n\t}\n\n\tprivate async finishSessionReplacement(withSession?: (ctx: ReplacedSessionContext) => Promise<void>): Promise<void> {\n\t\tif (this.rebindSession) {\n\t\t\tawait this.rebindSession(this.session);\n\t\t}\n\t\tif (withSession) {\n\t\t\tawait withSession(this.session.createReplacedSessionContext());\n\t\t}\n\t}\n\n\tasync switchSession(\n\t\tsessionPath: string,\n\t\toptions?: { cwdOverride?: string; withSession?: (ctx: ReplacedSessionContext) => Promise<void> },\n\t): Promise<{ cancelled: boolean }> {\n\t\tconst beforeResult = await this.emitBeforeSwitch(\"resume\", sessionPath);\n\t\tif (beforeResult.cancelled) {\n\t\t\treturn beforeResult;\n\t\t}\n\n\t\tconst previousSessionFile = this.session.sessionFile;\n\t\tconst nextSession = await this.sessionManager.openReference(sessionPath, { cwdOverride: options?.cwdOverride });\n\t\tassertSessionCwdExists(nextSession, this.services.cwd);\n\t\tawait this.teardownCurrent(\"resume\", nextSession.getSessionReference());\n\t\tthis.apply(\n\t\t\tawait this.buildAgentSession(nextSession, { type: \"session_start\", reason: \"resume\", previousSessionFile }),\n\t\t);\n\t\tawait this.finishSessionReplacement(options?.withSession);\n\t\treturn { cancelled: false };\n\t}\n\n\tasync newSession(options?: {\n\t\tid?: string;\n\t\tparentSession?: string;\n\t\tsetup?: (session: Session) => Promise<void>;\n\t\twithSession?: (ctx: ReplacedSessionContext) => Promise<void>;\n\t}): Promise<{ cancelled: boolean }> {\n\t\tconst beforeResult = await this.emitBeforeSwitch(\"new\");\n\t\tif (beforeResult.cancelled) {\n\t\t\treturn beforeResult;\n\t\t}\n\n\t\tconst previousSessionFile = this.session.sessionFile;\n\t\tconst nextSession = await this.sessionManager.create({ id: options?.id, parentSession: options?.parentSession });\n\n\t\tawait this.teardownCurrent(\"new\", nextSession.getSessionReference());\n\t\tthis.apply(\n\t\t\tawait this.buildAgentSession(nextSession, { type: \"session_start\", reason: \"new\", previousSessionFile }),\n\t\t);\n\t\tif (options?.setup) {\n\t\t\tawait options.setup(this.session.session);\n\t\t\tthis.session.agent.state.messages = this.session.session.buildSessionContext().messages;\n\t\t}\n\t\tawait this.finishSessionReplacement(options?.withSession);\n\t\treturn { cancelled: false };\n\t}\n\n\tasync fork(\n\t\tentryId: string,\n\t\toptions?: { position?: \"before\" | \"at\"; withSession?: (ctx: ReplacedSessionContext) => Promise<void> },\n\t): Promise<{ cancelled: boolean; selectedText?: string }> {\n\t\tconst position = options?.position ?? \"before\";\n\t\tconst beforeResult = await this.emitBeforeFork(entryId, { position });\n\t\tif (beforeResult.cancelled) {\n\t\t\treturn { cancelled: true };\n\t\t}\n\t\tlet targetLeafId: string | null;\n\t\tlet selectedText: string | undefined;\n\n\t\tconst selectedEntry = this.session.session.getEntry(entryId);\n\t\tif (!selectedEntry) {\n\t\t\tthrow new Error(\"Invalid entry ID for forking\");\n\t\t}\n\n\t\tif (position === \"at\") {\n\t\t\ttargetLeafId = selectedEntry.id;\n\t\t} else {\n\t\t\tif (selectedEntry.type !== \"message\" || selectedEntry.message.role !== \"user\") {\n\t\t\t\tthrow new Error(\"Invalid entry ID for forking\");\n\t\t\t}\n\t\t\ttargetLeafId = selectedEntry.parentId;\n\t\t\tselectedText = extractUserMessageText(selectedEntry.message.content);\n\t\t}\n\n\t\tconst previousSessionFile = this.session.sessionFile;\n\t\tconst nextSession = await this.sessionManager.forkSession(this.session.session, targetLeafId);\n\t\tawait this.teardownCurrent(\"fork\", nextSession.getSessionReference());\n\t\tthis.apply(\n\t\t\tawait this.buildAgentSession(nextSession, { type: \"session_start\", reason: \"fork\", previousSessionFile }),\n\t\t);\n\t\tawait this.finishSessionReplacement(options?.withSession);\n\t\treturn { cancelled: false, selectedText };\n\t}\n\n\tasync importFromJsonl(inputPath: string, cwdOverride?: string): Promise<{ cancelled: boolean }> {\n\t\tconst resolvedPath = resolve(inputPath);\n\t\tif (!existsSync(resolvedPath)) {\n\t\t\tthrow new SessionImportFileNotFoundError(resolvedPath);\n\t\t}\n\n\t\tconst beforeResult = await this.emitBeforeSwitch(\"resume\", resolvedPath);\n\t\tif (beforeResult.cancelled) {\n\t\t\treturn beforeResult;\n\t\t}\n\n\t\tconst previousSessionFile = this.session.sessionFile;\n\t\tconst nextSession = await this.sessionManager.importJsonl(resolvedPath, { cwdOverride: cwdOverride });\n\t\tassertSessionCwdExists(nextSession, this.services.cwd);\n\t\tawait this.teardownCurrent(\"resume\", nextSession.getSessionReference());\n\t\tthis.apply(\n\t\t\tawait this.buildAgentSession(nextSession, { type: \"session_start\", reason: \"resume\", previousSessionFile }),\n\t\t);\n\t\tawait this.finishSessionReplacement();\n\t\treturn { cancelled: false };\n\t}\n\n\tasync runMode(options: RunPiAgentModeOptions = {}): Promise<void> {\n\t\tconst mode = options.mode ?? this._mode;\n\t\tif (mode === \"embedded\") {\n\t\t\treturn;\n\t\t}\n\n\t\tif (mode !== \"interactive\" && !this.session.model) {\n\t\t\tconsole.error(chalk.red(formatNoModelsAvailableMessage()));\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\tif (options.startupBenchmark && mode !== \"interactive\") {\n\t\t\tconsole.error(chalk.red(\"Error: PI_STARTUP_BENCHMARK only supports interactive mode\"));\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\tif (mode === \"rpc\") {\n\t\t\tprintTimings();\n\t\t\tawait runRpcMode(this);\n\t\t\treturn;\n\t\t}\n\n\t\tif (mode === \"interactive\") {\n\t\t\tconst interactiveMode = new InteractiveMode(this, {\n\t\t\t\tmigratedProviders: options.migratedProviders,\n\t\t\t\tmodelFallbackMessage: this.modelFallbackMessage,\n\t\t\t\tinitialMessage: options.initialMessage,\n\t\t\t\tinitialImages: options.initialImages,\n\t\t\t\tinitialMessages: options.initialMessages,\n\t\t\t\tverbose: options.verbose,\n\t\t\t});\n\t\t\tif (options.startupBenchmark) {\n\t\t\t\tawait interactiveMode.init();\n\t\t\t\ttime(\"interactiveMode.init\");\n\t\t\t\tprintTimings();\n\t\t\t\tinteractiveMode.stop();\n\t\t\t\tstopThemeWatcher();\n\t\t\t\tif (process.stdout.writableLength > 0) {\n\t\t\t\t\tawait new Promise<void>((resolve) => process.stdout.once(\"drain\", resolve));\n\t\t\t\t}\n\t\t\t\tif (process.stderr.writableLength > 0) {\n\t\t\t\t\tawait new Promise<void>((resolve) => process.stderr.once(\"drain\", resolve));\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tprintTimings();\n\t\t\tawait interactiveMode.run();\n\t\t\treturn;\n\t\t}\n\n\t\tprintTimings();\n\t\tconst exitCode = await runPrintMode(this, {\n\t\t\tmode: mode === \"json\" ? \"json\" : \"text\",\n\t\t\tmessages: options.initialMessages,\n\t\t\tinitialMessage: options.initialMessage,\n\t\t\tinitialImages: options.initialImages,\n\t\t});\n\t\tstopThemeWatcher();\n\t\trestoreStdout();\n\t\tif (exitCode !== 0) {\n\t\t\tprocess.exitCode = exitCode;\n\t\t}\n\t}\n\n\tcreateSession(): Session | Promise<Session> {\n\t\treturn this.sessionManager.create();\n\t}\n\n\topenSessionReference(reference: string): Session | Promise<Session> {\n\t\treturn this.sessionManager.openReference(reference);\n\t}\n\n\tcontinueRecentSession(): Session | Promise<Session> {\n\t\treturn this.sessionManager.continueRecent();\n\t}\n\n\tforkSessionFrom(reference: string): Session | Promise<Session> {\n\t\treturn this.sessionManager.forkFrom(reference);\n\t}\n\n\tasync listSessions(): Promise<SessionInfo[]> {\n\t\treturn this.sessionManager.list();\n\t}\n\n\tasync listAllSessions(): Promise<SessionInfo[]> {\n\t\treturn this.sessionManager.listAll();\n\t}\n\n\tasync dispose(): Promise<void> {\n\t\tif (!this._session) {\n\t\t\treturn;\n\t\t}\n\t\tawait emitSessionShutdownEvent(this.session.extensionRunner, {\n\t\t\ttype: \"session_shutdown\",\n\t\t\treason: \"quit\",\n\t\t});\n\t\tawait this.flushActiveSession();\n\t\tthis.beforeSessionInvalidate?.();\n\t\tthis.session.dispose();\n\t\tthis._session = undefined;\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"pi-agent.d.ts","sourceRoot":"","sources":["../../src/core/pi-agent.ts"],"names":[],"mappings":"AAEA,OAAO,EAA4B,KAAK,aAAa,EAAE,MAAM,2BAA2B,CAAC;AACzF,OAAO,EAAsB,KAAK,YAAY,EAAgB,KAAK,KAAK,EAAgB,MAAM,mBAAmB,CAAC;AAKlH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,KAAK,EAEX,sBAAsB,EAEtB,iBAAiB,EACjB,cAAc,EACd,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGpD,OAAO,EAAyB,KAAK,4BAA4B,EAAE,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAErH,OAAO,EAGN,KAAK,OAAO,EACZ,KAAK,WAAW,EAChB,KAAK,mBAAmB,EACxB,KAAK,cAAc,EACnB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAKxD,MAAM,WAAW,iBAAiB;IACjC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;IACnC,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,WAAW,CAAC;IACzB,eAAe,EAAE,eAAe,CAAC;IACjC,aAAa,EAAE,aAAa,CAAC;IAC7B,cAAc,EAAE,cAAc,CAAC;IAC/B,WAAW,EAAE,iBAAiB,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,qBAAqB;IACrC,KAAK,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,YAAY,CAAC,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;QAAC,aAAa,CAAC,EAAE,aAAa,CAAA;KAAE,CAAC,CAAC;IAC3E,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,CAAC,EAAE,KAAK,GAAG,SAAS,CAAC;IAC5B,WAAW,CAAC,EAAE,cAAc,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,mCAAmC;IACnD,QAAQ,EAAE,eAAe,CAAC;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;CACtC;AAED,MAAM,WAAW,kCAAmC,SAAQ,qBAAqB;IAChF,WAAW,CAAC,EAAE,iBAAiB,EAAE,CAAC;CAClC;AAED,MAAM,WAAW,oBAAqB,SAAQ,qBAAqB;IAClE,iDAAiD;IACjD,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kFAAkF;IAClF,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,4DAA4D;IAC5D,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,mBAAmB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC,CAAC;IACpD,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,qBAAqB,CAAC,EAAE,IAAI,CAAC,4BAA4B,EAAE,KAAK,GAAG,UAAU,GAAG,iBAAiB,CAAC,CAAC;IACnG,qBAAqB,CAAC,EAAE,CACvB,OAAO,EAAE,mCAAmC,KACxC,OAAO,CAAC,kCAAkC,CAAC,GAAG,kCAAkC,CAAC;CACtF;AAED,MAAM,WAAW,2BAA2B;IAC3C,2EAA2E;IAC3E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;CACtC;AAED,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,aAAa,GAAG,OAAO,GAAG,MAAM,GAAG,KAAK,CAAC;AAEnF,MAAM,WAAW,qBAAqB;IACrC,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,YAAY,EAAE,CAAC;IAC/B,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC;IACnC,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;IAC/B,QAAQ,CAAC,WAAW,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACnD,QAAQ,CAAC,oBAAoB,EAAE,MAAM,GAAG,SAAS,CAAC;IAClD,gBAAgB,CAAC,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACjF,0BAA0B,CAAC,uBAAuB,CAAC,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IACvE,aAAa,CACZ,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,sBAAsB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;KAAE,GAC9F,OAAO,CAAC;QAAE,SAAS,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IACnC,UAAU,CAAC,OAAO,CAAC,EAAE;QACpB,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QAC5C,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,sBAAsB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KAC7D,GAAG,OAAO,CAAC;QAAE,SAAS,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IACpC,IAAI,CACH,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC;QAAC,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,sBAAsB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;KAAE,GACpG,OAAO,CAAC;QAAE,SAAS,EAAE,OAAO,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC1D,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,SAAS,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAC1F,YAAY,CAAC,UAAU,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IACvE,eAAe,CAAC,UAAU,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IAC1E,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB;AAED,qBAAa,8BAA+B,SAAQ,KAAK;IACxD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B,YAAY,QAAQ,EAAE,MAAM,EAI3B;CACD;AA2FD;;;;;;GAMG;AACH,qBAAa,OAAO;IACnB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;IACxC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAElC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuB;IAC/C,OAAO,CAAC,KAAK,CAAiB;IAC9B,OAAO,CAAC,QAAQ,CAAC,CAAe;IAChC,OAAO,CAAC,SAAS,CAAC,CAAkB;IACpC,OAAO,CAAC,YAAY,CAA2B;IAC/C,OAAO,CAAC,qBAAqB,CAAC,CAAS;IACvC,OAAO,CAAC,aAAa,CAAC,CAA2C;IACjE,OAAO,CAAC,uBAAuB,CAAC,CAAa;IAE7C,OAAO,eAeN;IAED,MAAM,CAAC,UAAU,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,cAAc,CAAA;KAAE,GAAG,IAAI,CAIzD;IAED,OAAa,MAAM,CAAC,OAAO,GAAE,oBAAyB,GAAG,OAAO,CAAC,OAAO,CAAC,CAOxE;IAED,IAAI,IAAI,IAAI,cAAc,CAEzB;IAED,IAAI,GAAG,IAAI,MAAM,CAEhB;IAEK,cAAc,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAqBlD;YAEa,cAAc;YAyCd,iBAAiB;IAqN/B,OAAO,CAAC,KAAK;IAYP,kBAAkB,CAAC,OAAO,GAAE,2BAAgC,GAAG,OAAO,CAAC,YAAY,CAAC,CAKzF;IAED,IAAI,OAAO,IAAI,OAAO,CAKrB;IAED,IAAI,QAAQ,IAAI,eAAe,CAK9B;IAED,IAAI,OAAO,IAAI,YAAY,CAK1B;IAED,IAAI,oBAAoB,IAAI,MAAM,GAAG,SAAS,CAE7C;IAED,IAAI,eAAe,IAAI,eAAe,CAErC;IAED,IAAI,aAAa,IAAI,aAAa,CAEjC;IAED,IAAI,cAAc,IAAI,cAAc,CAEnC;IAED,IAAI,WAAW,IAAI,SAAS,iBAAiB,EAAE,CAE9C;IAED,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED,gBAAgB,CAAC,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAE/E;IAED,0BAA0B,CAAC,uBAAuB,CAAC,EAAE,MAAM,IAAI,GAAG,IAAI,CAErE;YAEa,gBAAgB;YAkBhB,cAAc;YAiBd,kBAAkB;YAOlB,eAAe;YAef,wBAAwB;IAShC,aAAa,CAClB,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,sBAAsB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;KAAE,GAC9F,OAAO,CAAC;QAAE,SAAS,EAAE,OAAO,CAAA;KAAE,CAAC,CAoBjC;IAEK,UAAU,CAAC,OAAO,CAAC,EAAE;QAC1B,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QAC5C,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,sBAAsB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KAC7D,GAAG,OAAO,CAAC;QAAE,SAAS,EAAE,OAAO,CAAA;KAAE,CAAC,CAqClC;IAEK,IAAI,CACT,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC;QAAC,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,sBAAsB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;KAAE,GACpG,OAAO,CAAC;QAAE,SAAS,EAAE,OAAO,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CA8CxD;IAEK,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,SAAS,EAAE,OAAO,CAAA;KAAE,CAAC,CAyB9F;IAEK,OAAO,CAAC,OAAO,GAAE,qBAA0B,GAAG,OAAO,CAAC,IAAI,CAAC,CA+DhE;IAED,aAAa,IAAI,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAE1C;IAED,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAElE;IAED,qBAAqB,IAAI,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAElD;IAED,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAE7D;IAEK,YAAY,CAAC,UAAU,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAE3E;IAEK,eAAe,CAAC,UAAU,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAE9E;IAEK,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAY7B;CACD","sourcesContent":["import { existsSync } from \"node:fs\";\nimport { join, resolve } from \"node:path\";\nimport { Agent, type AgentMessage, type ThinkingLevel } from \"@fleetagent/pi-agent-core\";\nimport { clampThinkingLevel, type ImageContent, type Message, type Model, streamSimple } from \"@fleetagent/pi-ai\";\nimport chalk from \"chalk\";\nimport { getAgentDir } from \"../config.ts\";\nimport { InteractiveMode, runPrintMode, runRpcMode } from \"../modes/index.ts\";\nimport { stopThemeWatcher } from \"../modes/interactive/theme/theme.ts\";\nimport { AgentSession } from \"./agent-session.ts\";\nimport { formatNoModelsAvailableMessage } from \"./auth-guidance.ts\";\nimport { AuthStorage } from \"./auth-storage.ts\";\nimport { DEFAULT_THINKING_LEVEL } from \"./defaults.ts\";\nimport type {\n\tExtensionRunner,\n\tReplacedSessionContext,\n\tSessionShutdownEvent,\n\tSessionStartEvent,\n\tToolDefinition,\n} from \"./extensions/index.ts\";\nimport { emitSessionShutdownEvent } from \"./extensions/runner.ts\";\nimport { convertToLlm } from \"./messages.ts\";\nimport { ModelRegistry } from \"./model-registry.ts\";\nimport { findInitialModel } from \"./model-resolver.ts\";\nimport { restoreStdout, takeOverStdout } from \"./output-guard.ts\";\nimport { DefaultResourceLoader, type DefaultResourceLoaderOptions, type ResourceLoader } from \"./resource-loader.ts\";\nimport { assertSessionCwdExists } from \"./session-cwd.ts\";\nimport {\n\tgetDefaultSessionDir,\n\tLocalSessionManager,\n\ttype Session,\n\ttype SessionInfo,\n\ttype SessionListProgress,\n\ttype SessionManager,\n} from \"./session-manager.ts\";\nimport { SettingsManager } from \"./settings-manager.ts\";\nimport { isInstallTelemetryEnabled } from \"./telemetry.ts\";\nimport { printTimings, time } from \"./timings.ts\";\nimport type { ToolName } from \"./tools/index.ts\";\n\nexport interface PiAgentDiagnostic {\n\ttype: \"info\" | \"warning\" | \"error\";\n\tmessage: string;\n}\n\nexport interface PiAgentServices {\n\tcwd: string;\n\tagentDir: string;\n\tauthStorage: AuthStorage;\n\tsettingsManager: SettingsManager;\n\tmodelRegistry: ModelRegistry;\n\tresourceLoader: ResourceLoader;\n\tdiagnostics: PiAgentDiagnostic[];\n}\n\nexport interface PiAgentSessionOptions {\n\tmodel?: Model<any>;\n\tthinkingLevel?: ThinkingLevel;\n\tscopedModels?: Array<{ model: Model<any>; thinkingLevel?: ThinkingLevel }>;\n\ttools?: string[];\n\tnoTools?: \"all\" | \"builtin\";\n\tcustomTools?: ToolDefinition[];\n}\n\nexport interface ResolvePiAgentSessionOptionsContext {\n\tservices: PiAgentServices;\n\tsession: Session;\n\tsessionStartEvent?: SessionStartEvent;\n}\n\nexport interface ResolvePiAgentSessionOptionsResult extends PiAgentSessionOptions {\n\tdiagnostics?: PiAgentDiagnostic[];\n}\n\nexport interface CreatePiAgentOptions extends PiAgentSessionOptions {\n\t/** Runtime mode. Default: embedded SDK usage. */\n\tmode?: PiAgentAppMode;\n\tcwd?: string;\n\tagentDir?: string;\n\t/** Session lifecycle/discovery backend. Default: local JSONL sessions for cwd. */\n\tsessionManager?: SessionManager;\n\t/** Shared auth storage reused across runtime recreation. */\n\tauthStorage?: AuthStorage;\n\tsettingsManager?: SettingsManager;\n\tmodelRegistry?: ModelRegistry;\n\textensionFlagValues?: Map<string, boolean | string>;\n\tresourceLoader?: ResourceLoader;\n\tresourceLoaderOptions?: Omit<DefaultResourceLoaderOptions, \"cwd\" | \"agentDir\" | \"settingsManager\">;\n\tresolveSessionOptions?: (\n\t\tcontext: ResolvePiAgentSessionOptionsContext,\n\t) => Promise<ResolvePiAgentSessionOptionsResult> | ResolvePiAgentSessionOptionsResult;\n}\n\nexport interface CreatePiAgentSessionOptions {\n\t/** Initial active conversation state. Default: sessionManager.create(). */\n\tsession?: Session;\n\tsessionStartEvent?: SessionStartEvent;\n}\n\nexport type PiAgentAppMode = \"embedded\" | \"interactive\" | \"print\" | \"json\" | \"rpc\";\n\nexport interface RunPiAgentModeOptions {\n\tmode?: PiAgentAppMode;\n\tmigratedProviders?: string[];\n\tinitialMessage?: string;\n\tinitialImages?: ImageContent[];\n\tinitialMessages?: string[];\n\tverbose?: boolean;\n\tstartupBenchmark?: boolean;\n}\n\nexport interface PiAgentRuntimeHost {\n\treadonly services: PiAgentServices;\n\treadonly session: AgentSession;\n\treadonly diagnostics: readonly PiAgentDiagnostic[];\n\treadonly modelFallbackMessage: string | undefined;\n\tsetRebindSession(rebindSession?: (session: AgentSession) => Promise<void>): void;\n\tsetBeforeSessionInvalidate(beforeSessionInvalidate?: () => void): void;\n\tswitchSession(\n\t\tsessionPath: string,\n\t\toptions?: { cwdOverride?: string; withSession?: (ctx: ReplacedSessionContext) => Promise<void> },\n\t): Promise<{ cancelled: boolean }>;\n\tnewSession(options?: {\n\t\tid?: string;\n\t\tparentSession?: string;\n\t\tsetup?: (session: Session) => Promise<void>;\n\t\twithSession?: (ctx: ReplacedSessionContext) => Promise<void>;\n\t}): Promise<{ cancelled: boolean }>;\n\tfork(\n\t\tentryId: string,\n\t\toptions?: { position?: \"before\" | \"at\"; withSession?: (ctx: ReplacedSessionContext) => Promise<void> },\n\t): Promise<{ cancelled: boolean; selectedText?: string }>;\n\timportFromJsonl(inputPath: string, cwdOverride?: string): Promise<{ cancelled: boolean }>;\n\tlistSessions(onProgress?: SessionListProgress): Promise<SessionInfo[]>;\n\tlistAllSessions(onProgress?: SessionListProgress): Promise<SessionInfo[]>;\n\tdispose(): Promise<void>;\n}\n\nexport class SessionImportFileNotFoundError extends Error {\n\treadonly filePath: string;\n\n\tconstructor(filePath: string) {\n\t\tsuper(`File not found: ${filePath}`);\n\t\tthis.name = \"SessionImportFileNotFoundError\";\n\t\tthis.filePath = filePath;\n\t}\n}\n\nfunction extractUserMessageText(content: string | Array<{ type: string; text?: string }>): string {\n\tif (typeof content === \"string\") {\n\t\treturn content;\n\t}\n\n\treturn content\n\t\t.filter((part): part is { type: \"text\"; text: string } => part.type === \"text\" && typeof part.text === \"string\")\n\t\t.map((part) => part.text)\n\t\t.join(\"\");\n}\n\nfunction getAttributionHeaders(\n\tmodel: Model<any>,\n\tsettingsManager: SettingsManager,\n): Record<string, string> | undefined {\n\tif (!isInstallTelemetryEnabled(settingsManager)) {\n\t\treturn undefined;\n\t}\n\n\tif (model.provider === \"openrouter\" || model.baseUrl.includes(\"openrouter.ai\")) {\n\t\treturn {\n\t\t\t\"HTTP-Referer\": \"https://pi.dev\",\n\t\t\t\"X-OpenRouter-Title\": \"pi\",\n\t\t\t\"X-OpenRouter-Categories\": \"cli-agent\",\n\t\t};\n\t}\n\n\tif (\n\t\tmodel.provider === \"cloudflare-workers-ai\" ||\n\t\tmodel.provider === \"cloudflare-ai-gateway\" ||\n\t\tmodel.baseUrl.includes(\"api.cloudflare.com\") ||\n\t\tmodel.baseUrl.includes(\"gateway.ai.cloudflare.com\")\n\t) {\n\t\treturn {\n\t\t\t\"User-Agent\": \"pi-coding-agent\",\n\t\t};\n\t}\n\n\treturn undefined;\n}\n\nfunction applyExtensionFlagValues(\n\tresourceLoader: ResourceLoader,\n\textensionFlagValues: Map<string, boolean | string> | undefined,\n): PiAgentDiagnostic[] {\n\tif (!extensionFlagValues) {\n\t\treturn [];\n\t}\n\n\tconst diagnostics: PiAgentDiagnostic[] = [];\n\tconst extensionsResult = resourceLoader.getExtensions();\n\tconst registeredFlags = new Map<string, { type: \"boolean\" | \"string\" }>();\n\tfor (const extension of extensionsResult.extensions) {\n\t\tfor (const [name, flag] of extension.flags) {\n\t\t\tregisteredFlags.set(name, { type: flag.type });\n\t\t}\n\t}\n\n\tconst unknownFlags: string[] = [];\n\tfor (const [name, value] of extensionFlagValues) {\n\t\tconst flag = registeredFlags.get(name);\n\t\tif (!flag) {\n\t\t\tunknownFlags.push(name);\n\t\t\tcontinue;\n\t\t}\n\t\tif (flag.type === \"boolean\") {\n\t\t\textensionsResult.runtime.flagValues.set(name, true);\n\t\t\tcontinue;\n\t\t}\n\t\tif (typeof value === \"string\") {\n\t\t\textensionsResult.runtime.flagValues.set(name, value);\n\t\t\tcontinue;\n\t\t}\n\t\tdiagnostics.push({\n\t\t\ttype: \"error\",\n\t\t\tmessage: `Extension flag \"--${name}\" requires a value`,\n\t\t});\n\t}\n\n\tif (unknownFlags.length > 0) {\n\t\tdiagnostics.push({\n\t\t\ttype: \"error\",\n\t\t\tmessage: `Unknown option${unknownFlags.length === 1 ? \"\" : \"s\"}: ${unknownFlags.map((name) => `--${name}`).join(\", \")}`,\n\t\t});\n\t}\n\n\treturn diagnostics;\n}\n\n/**\n * Application-level composition root for pi's coding agent runtime.\n *\n * PiAgent owns common app services, the session lifecycle backend, and the\n * current active AgentSession. Conversation behavior stays in AgentSession;\n * session lifecycle/discovery stays in SessionManager implementations.\n */\nexport class PiAgent {\n\tprivate readonly initialCwd: string;\n\treadonly agentDir: string;\n\treadonly sessionManager: SessionManager;\n\treadonly authStorage: AuthStorage;\n\n\tprivate readonly options: CreatePiAgentOptions;\n\tprivate _mode: PiAgentAppMode;\n\tprivate _session?: AgentSession;\n\tprivate _services?: PiAgentServices;\n\tprivate _diagnostics: PiAgentDiagnostic[] = [];\n\tprivate _modelFallbackMessage?: string;\n\tprivate rebindSession?: (session: AgentSession) => Promise<void>;\n\tprivate beforeSessionInvalidate?: () => void;\n\n\tprivate constructor(\n\t\toptions: CreatePiAgentOptions,\n\t\tresolved: {\n\t\t\tcwd: string;\n\t\t\tagentDir: string;\n\t\t\tsessionManager: SessionManager;\n\t\t\tauthStorage: AuthStorage;\n\t\t},\n\t) {\n\t\tthis.options = options;\n\t\tthis._mode = options.mode ?? \"embedded\";\n\t\tthis.initialCwd = resolved.cwd;\n\t\tthis.agentDir = resolved.agentDir;\n\t\tthis.sessionManager = resolved.sessionManager;\n\t\tthis.authStorage = resolved.authStorage;\n\t}\n\n\tstatic setupStdio(options: { mode: PiAgentAppMode }): void {\n\t\tif (options.mode !== \"embedded\" && options.mode !== \"interactive\") {\n\t\t\ttakeOverStdout();\n\t\t}\n\t}\n\n\tstatic async create(options: CreatePiAgentOptions = {}): Promise<PiAgent> {\n\t\tconst cwd = options.cwd ?? process.cwd();\n\t\tconst agentDir = options.agentDir ?? getAgentDir();\n\t\tconst sessionManager =\n\t\t\toptions.sessionManager ?? new LocalSessionManager({ cwd, sessionDir: getDefaultSessionDir(cwd, agentDir) });\n\t\tconst authStorage = options.authStorage ?? AuthStorage.create(join(agentDir, \"auth.json\"));\n\t\treturn new PiAgent(options, { cwd, agentDir, sessionManager, authStorage });\n\t}\n\n\tget mode(): PiAgentAppMode {\n\t\treturn this._mode;\n\t}\n\n\tget cwd(): string {\n\t\treturn this._services?.cwd ?? this.initialCwd;\n\t}\n\n\tasync readPipedStdin(): Promise<string | undefined> {\n\t\tif (this._mode === \"embedded\" || this._mode === \"rpc\" || process.stdin.isTTY) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst stdinContent = await new Promise<string | undefined>((resolve) => {\n\t\t\tlet data = \"\";\n\t\t\tprocess.stdin.setEncoding(\"utf8\");\n\t\t\tprocess.stdin.on(\"data\", (chunk) => {\n\t\t\t\tdata += chunk;\n\t\t\t});\n\t\t\tprocess.stdin.on(\"end\", () => {\n\t\t\t\tresolve(data.trim() || undefined);\n\t\t\t});\n\t\t\tprocess.stdin.resume();\n\t\t});\n\n\t\tif (stdinContent !== undefined && this._mode === \"interactive\") {\n\t\t\tthis._mode = \"print\";\n\t\t}\n\t\treturn stdinContent;\n\t}\n\n\tprivate async createServices(cwd: string): Promise<PiAgentServices> {\n\t\tconst settingsManager = this.options.settingsManager ?? SettingsManager.create(cwd, this.agentDir);\n\t\tconst modelRegistry =\n\t\t\tthis.options.modelRegistry ?? ModelRegistry.create(this.authStorage, join(this.agentDir, \"models.json\"));\n\t\tconst resourceLoader =\n\t\t\tthis.options.resourceLoader ??\n\t\t\tnew DefaultResourceLoader({\n\t\t\t\t...(this.options.resourceLoaderOptions ?? {}),\n\t\t\t\tcwd,\n\t\t\t\tagentDir: this.agentDir,\n\t\t\t\tsettingsManager,\n\t\t\t});\n\t\tawait resourceLoader.reload();\n\n\t\tconst diagnostics: PiAgentDiagnostic[] = [];\n\t\tconst extensionsResult = resourceLoader.getExtensions();\n\t\tfor (const { name, config, extensionPath } of extensionsResult.runtime.pendingProviderRegistrations) {\n\t\t\ttry {\n\t\t\t\tmodelRegistry.registerProvider(name, config);\n\t\t\t} catch (error) {\n\t\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\t\tdiagnostics.push({\n\t\t\t\t\ttype: \"error\",\n\t\t\t\t\tmessage: `Extension \"${extensionPath}\" error: ${message}`,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\textensionsResult.runtime.pendingProviderRegistrations = [];\n\t\tdiagnostics.push(...applyExtensionFlagValues(resourceLoader, this.options.extensionFlagValues));\n\n\t\treturn {\n\t\t\tcwd,\n\t\t\tagentDir: this.agentDir,\n\t\t\tauthStorage: this.authStorage,\n\t\t\tsettingsManager,\n\t\t\tmodelRegistry,\n\t\t\tresourceLoader,\n\t\t\tdiagnostics,\n\t\t};\n\t}\n\n\tprivate async buildAgentSession(\n\t\tactiveSession: Session,\n\t\tsessionStartEvent?: SessionStartEvent,\n\t): Promise<{\n\t\tsession: AgentSession;\n\t\tservices: PiAgentServices;\n\t\tdiagnostics: PiAgentDiagnostic[];\n\t\tmodelFallbackMessage?: string;\n\t}> {\n\t\tconst services = await this.createServices(activeSession.getCwd());\n\t\tconst diagnostics: PiAgentDiagnostic[] = [\n\t\t\t...services.diagnostics,\n\t\t\t...services.resourceLoader.getExtensions().errors.map(({ path, error }) => ({\n\t\t\t\ttype: \"error\" as const,\n\t\t\t\tmessage: `Failed to load extension \"${path}\": ${error}`,\n\t\t\t})),\n\t\t];\n\t\tconst resolvedOptions =\n\t\t\t(await this.options.resolveSessionOptions?.({ services, session: activeSession, sessionStartEvent })) ?? {};\n\t\tdiagnostics.push(...(resolvedOptions.diagnostics ?? []));\n\t\tconst sessionOptions: PiAgentSessionOptions = {\n\t\t\tmodel: resolvedOptions.model ?? this.options.model,\n\t\t\tthinkingLevel: resolvedOptions.thinkingLevel ?? this.options.thinkingLevel,\n\t\t\tscopedModels: resolvedOptions.scopedModels ?? this.options.scopedModels,\n\t\t\ttools: resolvedOptions.tools ?? this.options.tools,\n\t\t\tnoTools: resolvedOptions.noTools ?? this.options.noTools,\n\t\t\tcustomTools: resolvedOptions.customTools ?? this.options.customTools,\n\t\t};\n\n\t\tconst existingSession = activeSession.buildSessionContext();\n\t\tconst hasExistingSession = existingSession.messages.length > 0;\n\t\tconst hasThinkingEntry = activeSession.getBranch().some((entry) => entry.type === \"thinking_level_change\");\n\n\t\tlet model = sessionOptions.model;\n\t\tlet modelFallbackMessage: string | undefined;\n\n\t\tif (model) {\n\t\t\tmodel = services.modelRegistry.find(model.provider, model.id) ?? model;\n\t\t}\n\n\t\tif (!model && hasExistingSession && existingSession.model) {\n\t\t\tconst restoredModel = services.modelRegistry.find(\n\t\t\t\texistingSession.model.provider,\n\t\t\t\texistingSession.model.modelId,\n\t\t\t);\n\t\t\tif (restoredModel && services.modelRegistry.hasConfiguredAuth(restoredModel)) {\n\t\t\t\tmodel = restoredModel;\n\t\t\t}\n\t\t\tif (!model) {\n\t\t\t\tmodelFallbackMessage = `Could not restore model ${existingSession.model.provider}/${existingSession.model.modelId}`;\n\t\t\t}\n\t\t}\n\n\t\tif (!model) {\n\t\t\tconst result = await findInitialModel({\n\t\t\t\tscopedModels: [],\n\t\t\t\tisContinuing: hasExistingSession,\n\t\t\t\tdefaultProvider: services.settingsManager.getDefaultProvider(),\n\t\t\t\tdefaultModelId: services.settingsManager.getDefaultModel(),\n\t\t\t\tdefaultThinkingLevel: services.settingsManager.getDefaultThinkingLevel(),\n\t\t\t\tmodelRegistry: services.modelRegistry,\n\t\t\t});\n\t\t\tmodel = result.model;\n\t\t\tif (!model) {\n\t\t\t\tmodelFallbackMessage = formatNoModelsAvailableMessage();\n\t\t\t} else if (modelFallbackMessage) {\n\t\t\t\tmodelFallbackMessage += `. Using ${model.provider}/${model.id}`;\n\t\t\t}\n\t\t}\n\n\t\tlet thinkingLevel = sessionOptions.thinkingLevel;\n\t\tif (thinkingLevel === undefined && hasExistingSession) {\n\t\t\tthinkingLevel = hasThinkingEntry\n\t\t\t\t? (existingSession.thinkingLevel as ThinkingLevel)\n\t\t\t\t: (services.settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL);\n\t\t}\n\t\tif (thinkingLevel === undefined) {\n\t\t\tthinkingLevel = services.settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL;\n\t\t}\n\t\tthinkingLevel = model ? (clampThinkingLevel(model, thinkingLevel) as ThinkingLevel) : \"off\";\n\n\t\tconst defaultActiveToolNames: ToolName[] = [\"read\", \"bash\", \"edit\", \"write\"];\n\t\tconst allowedToolNames = sessionOptions.tools ?? (sessionOptions.noTools === \"all\" ? [] : undefined);\n\t\tconst initialActiveToolNames: string[] = sessionOptions.tools\n\t\t\t? [...sessionOptions.tools]\n\t\t\t: sessionOptions.noTools\n\t\t\t\t? []\n\t\t\t\t: defaultActiveToolNames;\n\n\t\tconst extensionRunnerRef: { current?: ExtensionRunner } = {};\n\t\tconst convertToLlmWithBlockImages = (messages: AgentMessage[]): Message[] => {\n\t\t\tconst converted = convertToLlm(messages);\n\t\t\tif (!services.settingsManager.getBlockImages()) {\n\t\t\t\treturn converted;\n\t\t\t}\n\t\t\treturn converted.map((msg) => {\n\t\t\t\tif (msg.role === \"user\" || msg.role === \"toolResult\") {\n\t\t\t\t\tconst content = msg.content;\n\t\t\t\t\tif (Array.isArray(content)) {\n\t\t\t\t\t\tconst hasImages = content.some((c) => c.type === \"image\");\n\t\t\t\t\t\tif (hasImages) {\n\t\t\t\t\t\t\tconst filteredContent = content\n\t\t\t\t\t\t\t\t.map((c) =>\n\t\t\t\t\t\t\t\t\tc.type === \"image\" ? { type: \"text\" as const, text: \"Image reading is disabled.\" } : c,\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t.filter(\n\t\t\t\t\t\t\t\t\t(c, i, arr) =>\n\t\t\t\t\t\t\t\t\t\t!(\n\t\t\t\t\t\t\t\t\t\t\tc.type === \"text\" &&\n\t\t\t\t\t\t\t\t\t\t\tc.text === \"Image reading is disabled.\" &&\n\t\t\t\t\t\t\t\t\t\t\ti > 0 &&\n\t\t\t\t\t\t\t\t\t\t\tarr[i - 1].type === \"text\" &&\n\t\t\t\t\t\t\t\t\t\t\t(arr[i - 1] as { type: \"text\"; text: string }).text === \"Image reading is disabled.\"\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\treturn { ...msg, content: filteredContent };\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn msg;\n\t\t\t});\n\t\t};\n\n\t\tconst agent = new Agent({\n\t\t\tinitialState: {\n\t\t\t\tsystemPrompt: \"\",\n\t\t\t\tmodel,\n\t\t\t\tthinkingLevel,\n\t\t\t\ttools: [],\n\t\t\t},\n\t\t\tconvertToLlm: convertToLlmWithBlockImages,\n\t\t\tstreamFn: async (model, context, options) => {\n\t\t\t\tconst auth = await services.modelRegistry.getApiKeyAndHeaders(model);\n\t\t\t\tif (!auth.ok) {\n\t\t\t\t\tthrow new Error(auth.error);\n\t\t\t\t}\n\t\t\t\tconst providerRetrySettings = services.settingsManager.getProviderRetrySettings();\n\t\t\t\tconst attributionHeaders = getAttributionHeaders(model, services.settingsManager);\n\t\t\t\treturn streamSimple(model, context, {\n\t\t\t\t\t...options,\n\t\t\t\t\tapiKey: auth.apiKey,\n\t\t\t\t\ttimeoutMs: options?.timeoutMs ?? providerRetrySettings.timeoutMs,\n\t\t\t\t\tmaxRetries: options?.maxRetries ?? providerRetrySettings.maxRetries,\n\t\t\t\t\tmaxRetryDelayMs: options?.maxRetryDelayMs ?? providerRetrySettings.maxRetryDelayMs,\n\t\t\t\t\theaders:\n\t\t\t\t\t\tattributionHeaders || auth.headers || options?.headers\n\t\t\t\t\t\t\t? { ...attributionHeaders, ...auth.headers, ...options?.headers }\n\t\t\t\t\t\t\t: undefined,\n\t\t\t\t});\n\t\t\t},\n\t\t\tonPayload: async (payload) => {\n\t\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\t\tif (!runner?.hasHandlers(\"before_provider_request\")) {\n\t\t\t\t\treturn payload;\n\t\t\t\t}\n\t\t\t\treturn runner.emitBeforeProviderRequest(payload);\n\t\t\t},\n\t\t\tonResponse: async (response) => {\n\t\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\t\tif (!runner?.hasHandlers(\"after_provider_response\")) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tawait runner.emit({\n\t\t\t\t\ttype: \"after_provider_response\",\n\t\t\t\t\tstatus: response.status,\n\t\t\t\t\theaders: response.headers,\n\t\t\t\t});\n\t\t\t},\n\t\t\tsessionId: activeSession.getSessionId(),\n\t\t\ttransformContext: async (messages) => {\n\t\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\t\treturn runner ? runner.emitContext(messages) : messages;\n\t\t\t},\n\t\t\tsteeringMode: services.settingsManager.getSteeringMode(),\n\t\t\tfollowUpMode: services.settingsManager.getFollowUpMode(),\n\t\t\ttransport: services.settingsManager.getTransport(),\n\t\t\tthinkingBudgets: services.settingsManager.getThinkingBudgets(),\n\t\t\tmaxRetryDelayMs: services.settingsManager.getProviderRetrySettings().maxRetryDelayMs,\n\t\t});\n\n\t\tif (hasExistingSession) {\n\t\t\tagent.state.messages = existingSession.messages;\n\t\t\tif (!hasThinkingEntry) {\n\t\t\t\tactiveSession.appendThinkingLevelChange(thinkingLevel);\n\t\t\t}\n\t\t} else {\n\t\t\tif (model) {\n\t\t\t\tactiveSession.appendModelChange(model.provider, model.id);\n\t\t\t}\n\t\t\tactiveSession.appendThinkingLevelChange(thinkingLevel);\n\t\t}\n\n\t\treturn {\n\t\t\tsession: new AgentSession({\n\t\t\t\tagent,\n\t\t\t\tsession: activeSession,\n\t\t\t\tsettingsManager: services.settingsManager,\n\t\t\t\tcwd: services.cwd,\n\t\t\t\tscopedModels: sessionOptions.scopedModels,\n\t\t\t\tresourceLoader: services.resourceLoader,\n\t\t\t\tcustomTools: sessionOptions.customTools,\n\t\t\t\tmodelRegistry: services.modelRegistry,\n\t\t\t\tinitialActiveToolNames,\n\t\t\t\tallowedToolNames,\n\t\t\t\textensionRunnerRef,\n\t\t\t\tsessionStartEvent,\n\t\t\t}),\n\t\t\tservices,\n\t\t\tdiagnostics,\n\t\t\tmodelFallbackMessage,\n\t\t};\n\t}\n\n\tprivate apply(result: {\n\t\tsession: AgentSession;\n\t\tservices: PiAgentServices;\n\t\tdiagnostics: PiAgentDiagnostic[];\n\t\tmodelFallbackMessage?: string;\n\t}): void {\n\t\tthis._session = result.session;\n\t\tthis._services = result.services;\n\t\tthis._diagnostics = result.diagnostics;\n\t\tthis._modelFallbackMessage = result.modelFallbackMessage;\n\t}\n\n\tasync createAgentSession(options: CreatePiAgentSessionOptions = {}): Promise<AgentSession> {\n\t\tconst initialSession = options.session ?? (await this.sessionManager.create());\n\t\tassertSessionCwdExists(initialSession, initialSession.getCwd());\n\t\tthis.apply(await this.buildAgentSession(initialSession, options.sessionStartEvent));\n\t\treturn this.session;\n\t}\n\n\tget runtime(): PiAgent {\n\t\tif (!this._session) {\n\t\t\tthrow new Error(\"PiAgent session has not been created. Call createAgentSession() first.\");\n\t\t}\n\t\treturn this;\n\t}\n\n\tget services(): PiAgentServices {\n\t\tif (!this._services) {\n\t\t\tthrow new Error(\"PiAgent services have not been created. Call createAgentSession() first.\");\n\t\t}\n\t\treturn this._services;\n\t}\n\n\tget session(): AgentSession {\n\t\tif (!this._session) {\n\t\t\tthrow new Error(\"PiAgent session has not been created. Call createAgentSession() first.\");\n\t\t}\n\t\treturn this._session;\n\t}\n\n\tget modelFallbackMessage(): string | undefined {\n\t\treturn this._modelFallbackMessage;\n\t}\n\n\tget settingsManager(): SettingsManager {\n\t\treturn this.services.settingsManager;\n\t}\n\n\tget modelRegistry(): ModelRegistry {\n\t\treturn this.services.modelRegistry;\n\t}\n\n\tget resourceLoader(): ResourceLoader {\n\t\treturn this.services.resourceLoader;\n\t}\n\n\tget diagnostics(): readonly PiAgentDiagnostic[] {\n\t\treturn this._diagnostics;\n\t}\n\n\tget currentCwd(): string {\n\t\treturn this.services.cwd;\n\t}\n\n\tsetRebindSession(rebindSession?: (session: AgentSession) => Promise<void>): void {\n\t\tthis.rebindSession = rebindSession;\n\t}\n\n\tsetBeforeSessionInvalidate(beforeSessionInvalidate?: () => void): void {\n\t\tthis.beforeSessionInvalidate = beforeSessionInvalidate;\n\t}\n\n\tprivate async emitBeforeSwitch(\n\t\treason: \"new\" | \"resume\",\n\t\ttargetSessionReference?: string,\n\t): Promise<{ cancelled: boolean }> {\n\t\tconst runner = this.session.extensionRunner;\n\t\tif (!runner.hasHandlers(\"session_before_switch\")) {\n\t\t\treturn { cancelled: false };\n\t\t}\n\n\t\tconst result = await runner.emit({\n\t\t\ttype: \"session_before_switch\",\n\t\t\treason,\n\t\t\ttargetSessionReference,\n\t\t\ttargetSessionFile: targetSessionReference,\n\t\t});\n\t\treturn { cancelled: result?.cancel === true };\n\t}\n\n\tprivate async emitBeforeFork(\n\t\tentryId: string,\n\t\toptions: { position: \"before\" | \"at\" },\n\t): Promise<{ cancelled: boolean }> {\n\t\tconst runner = this.session.extensionRunner;\n\t\tif (!runner.hasHandlers(\"session_before_fork\")) {\n\t\t\treturn { cancelled: false };\n\t\t}\n\n\t\tconst result = await runner.emit({\n\t\t\ttype: \"session_before_fork\",\n\t\t\tentryId,\n\t\t\t...options,\n\t\t});\n\t\treturn { cancelled: result?.cancel === true };\n\t}\n\n\tprivate async flushActiveSession(): Promise<void> {\n\t\tconst flushPendingSync = (this.session.session as { flushPendingSync?: () => Promise<void> }).flushPendingSync;\n\t\tif (flushPendingSync) {\n\t\t\tawait flushPendingSync.call(this.session.session);\n\t\t}\n\t}\n\n\tprivate async teardownCurrent(\n\t\treason: SessionShutdownEvent[\"reason\"],\n\t\ttargetSessionReference?: string,\n\t): Promise<void> {\n\t\tawait emitSessionShutdownEvent(this.session.extensionRunner, {\n\t\t\ttype: \"session_shutdown\",\n\t\t\treason,\n\t\t\ttargetSessionReference,\n\t\t\ttargetSessionFile: targetSessionReference,\n\t\t});\n\t\tawait this.flushActiveSession();\n\t\tthis.beforeSessionInvalidate?.();\n\t\tthis.session.dispose();\n\t}\n\n\tprivate async finishSessionReplacement(withSession?: (ctx: ReplacedSessionContext) => Promise<void>): Promise<void> {\n\t\tif (this.rebindSession) {\n\t\t\tawait this.rebindSession(this.session);\n\t\t}\n\t\tif (withSession) {\n\t\t\tawait withSession(this.session.createReplacedSessionContext());\n\t\t}\n\t}\n\n\tasync switchSession(\n\t\tsessionPath: string,\n\t\toptions?: { cwdOverride?: string; withSession?: (ctx: ReplacedSessionContext) => Promise<void> },\n\t): Promise<{ cancelled: boolean }> {\n\t\tconst beforeResult = await this.emitBeforeSwitch(\"resume\", sessionPath);\n\t\tif (beforeResult.cancelled) {\n\t\t\treturn beforeResult;\n\t\t}\n\n\t\tconst previousSessionReference = this.session.sessionReference;\n\t\tconst nextSession = await this.sessionManager.openReference(sessionPath, { cwdOverride: options?.cwdOverride });\n\t\tassertSessionCwdExists(nextSession, this.services.cwd);\n\t\tawait this.teardownCurrent(\"resume\", nextSession.getSessionReference());\n\t\tthis.apply(\n\t\t\tawait this.buildAgentSession(nextSession, {\n\t\t\t\ttype: \"session_start\",\n\t\t\t\treason: \"resume\",\n\t\t\t\tpreviousSessionReference,\n\t\t\t\tpreviousSessionFile: previousSessionReference,\n\t\t\t}),\n\t\t);\n\t\tawait this.finishSessionReplacement(options?.withSession);\n\t\treturn { cancelled: false };\n\t}\n\n\tasync newSession(options?: {\n\t\tid?: string;\n\t\tparentSession?: string;\n\t\tsetup?: (session: Session) => Promise<void>;\n\t\twithSession?: (ctx: ReplacedSessionContext) => Promise<void>;\n\t}): Promise<{ cancelled: boolean }> {\n\t\tconst beforeResult = await this.emitBeforeSwitch(\"new\");\n\t\tif (beforeResult.cancelled) {\n\t\t\treturn beforeResult;\n\t\t}\n\n\t\tconst previousSessionReference = this.session.sessionReference;\n\t\tconst activeSession = this.session.session;\n\t\tconst newSessionOptions = {\n\t\t\tid: options?.id,\n\t\t\tparentSession: options?.parentSession ?? activeSession.getSessionReference(),\n\t\t};\n\t\tlet nextSession: Session;\n\t\ttry {\n\t\t\tnextSession = await activeSession.createSubSession(newSessionOptions);\n\t\t} catch (error) {\n\t\t\tif (!(error instanceof Error && error.message === \"Session manager unavailable\")) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tnextSession = await this.sessionManager.create(newSessionOptions);\n\t\t}\n\n\t\tawait this.teardownCurrent(\"new\", nextSession.getSessionReference());\n\t\tthis.apply(\n\t\t\tawait this.buildAgentSession(nextSession, {\n\t\t\t\ttype: \"session_start\",\n\t\t\t\treason: \"new\",\n\t\t\t\tpreviousSessionReference,\n\t\t\t\tpreviousSessionFile: previousSessionReference,\n\t\t\t}),\n\t\t);\n\t\tif (options?.setup) {\n\t\t\tawait options.setup(this.session.session);\n\t\t\tthis.session.agent.state.messages = this.session.session.buildSessionContext().messages;\n\t\t}\n\t\tawait this.finishSessionReplacement(options?.withSession);\n\t\treturn { cancelled: false };\n\t}\n\n\tasync fork(\n\t\tentryId: string,\n\t\toptions?: { position?: \"before\" | \"at\"; withSession?: (ctx: ReplacedSessionContext) => Promise<void> },\n\t): Promise<{ cancelled: boolean; selectedText?: string }> {\n\t\tconst position = options?.position ?? \"before\";\n\t\tconst beforeResult = await this.emitBeforeFork(entryId, { position });\n\t\tif (beforeResult.cancelled) {\n\t\t\treturn { cancelled: true };\n\t\t}\n\t\tlet targetLeafId: string | null;\n\t\tlet selectedText: string | undefined;\n\n\t\tconst selectedEntry = this.session.session.getEntry(entryId);\n\t\tif (!selectedEntry) {\n\t\t\tthrow new Error(\"Invalid entry ID for forking\");\n\t\t}\n\n\t\tif (position === \"at\") {\n\t\t\ttargetLeafId = selectedEntry.id;\n\t\t} else {\n\t\t\tif (selectedEntry.type !== \"message\" || selectedEntry.message.role !== \"user\") {\n\t\t\t\tthrow new Error(\"Invalid entry ID for forking\");\n\t\t\t}\n\t\t\ttargetLeafId = selectedEntry.parentId;\n\t\t\tselectedText = extractUserMessageText(selectedEntry.message.content);\n\t\t}\n\n\t\tconst previousSessionReference = this.session.sessionReference;\n\t\tconst activeSession = this.session.session;\n\t\tlet nextSession: Session;\n\t\ttry {\n\t\t\tnextSession = await activeSession.forkSubSession(targetLeafId);\n\t\t} catch (error) {\n\t\t\tif (!(error instanceof Error && error.message === \"Session manager unavailable\")) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tnextSession = await this.sessionManager.forkSession(activeSession, targetLeafId);\n\t\t}\n\t\tawait this.teardownCurrent(\"fork\", nextSession.getSessionReference());\n\t\tthis.apply(\n\t\t\tawait this.buildAgentSession(nextSession, {\n\t\t\t\ttype: \"session_start\",\n\t\t\t\treason: \"fork\",\n\t\t\t\tpreviousSessionReference,\n\t\t\t\tpreviousSessionFile: previousSessionReference,\n\t\t\t}),\n\t\t);\n\t\tawait this.finishSessionReplacement(options?.withSession);\n\t\treturn { cancelled: false, selectedText };\n\t}\n\n\tasync importFromJsonl(inputPath: string, cwdOverride?: string): Promise<{ cancelled: boolean }> {\n\t\tconst resolvedPath = resolve(inputPath);\n\t\tif (!existsSync(resolvedPath)) {\n\t\t\tthrow new SessionImportFileNotFoundError(resolvedPath);\n\t\t}\n\n\t\tconst beforeResult = await this.emitBeforeSwitch(\"resume\", resolvedPath);\n\t\tif (beforeResult.cancelled) {\n\t\t\treturn beforeResult;\n\t\t}\n\n\t\tconst previousSessionReference = this.session.sessionReference;\n\t\tconst nextSession = await this.sessionManager.importJsonl(resolvedPath, { cwdOverride: cwdOverride });\n\t\tassertSessionCwdExists(nextSession, this.services.cwd);\n\t\tawait this.teardownCurrent(\"resume\", nextSession.getSessionReference());\n\t\tthis.apply(\n\t\t\tawait this.buildAgentSession(nextSession, {\n\t\t\t\ttype: \"session_start\",\n\t\t\t\treason: \"resume\",\n\t\t\t\tpreviousSessionReference,\n\t\t\t\tpreviousSessionFile: previousSessionReference,\n\t\t\t}),\n\t\t);\n\t\tawait this.finishSessionReplacement();\n\t\treturn { cancelled: false };\n\t}\n\n\tasync runMode(options: RunPiAgentModeOptions = {}): Promise<void> {\n\t\tconst mode = options.mode ?? this._mode;\n\t\tif (mode === \"embedded\") {\n\t\t\treturn;\n\t\t}\n\n\t\tif (mode !== \"interactive\" && !this.session.model) {\n\t\t\tconsole.error(chalk.red(formatNoModelsAvailableMessage()));\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\tif (options.startupBenchmark && mode !== \"interactive\") {\n\t\t\tconsole.error(chalk.red(\"Error: PI_STARTUP_BENCHMARK only supports interactive mode\"));\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\tif (mode === \"rpc\") {\n\t\t\tprintTimings();\n\t\t\tawait runRpcMode(this);\n\t\t\treturn;\n\t\t}\n\n\t\tif (mode === \"interactive\") {\n\t\t\tconst interactiveMode = new InteractiveMode(this, {\n\t\t\t\tmigratedProviders: options.migratedProviders,\n\t\t\t\tmodelFallbackMessage: this.modelFallbackMessage,\n\t\t\t\tinitialMessage: options.initialMessage,\n\t\t\t\tinitialImages: options.initialImages,\n\t\t\t\tinitialMessages: options.initialMessages,\n\t\t\t\tverbose: options.verbose,\n\t\t\t});\n\t\t\tif (options.startupBenchmark) {\n\t\t\t\tawait interactiveMode.init();\n\t\t\t\ttime(\"interactiveMode.init\");\n\t\t\t\tprintTimings();\n\t\t\t\tinteractiveMode.stop();\n\t\t\t\tstopThemeWatcher();\n\t\t\t\tif (process.stdout.writableLength > 0) {\n\t\t\t\t\tawait new Promise<void>((resolve) => process.stdout.once(\"drain\", resolve));\n\t\t\t\t}\n\t\t\t\tif (process.stderr.writableLength > 0) {\n\t\t\t\t\tawait new Promise<void>((resolve) => process.stderr.once(\"drain\", resolve));\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tprintTimings();\n\t\t\tawait interactiveMode.run();\n\t\t\treturn;\n\t\t}\n\n\t\tprintTimings();\n\t\tconst exitCode = await runPrintMode(this, {\n\t\t\tmode: mode === \"json\" ? \"json\" : \"text\",\n\t\t\tmessages: options.initialMessages,\n\t\t\tinitialMessage: options.initialMessage,\n\t\t\tinitialImages: options.initialImages,\n\t\t});\n\t\tstopThemeWatcher();\n\t\trestoreStdout();\n\t\tif (exitCode !== 0) {\n\t\t\tprocess.exitCode = exitCode;\n\t\t}\n\t}\n\n\tcreateSession(): Session | Promise<Session> {\n\t\treturn this.sessionManager.create();\n\t}\n\n\topenSessionReference(reference: string): Session | Promise<Session> {\n\t\treturn this.sessionManager.openReference(reference);\n\t}\n\n\tcontinueRecentSession(): Session | Promise<Session> {\n\t\treturn this.sessionManager.continueRecent();\n\t}\n\n\tforkSessionFrom(reference: string): Session | Promise<Session> {\n\t\treturn this.sessionManager.forkFrom(reference);\n\t}\n\n\tasync listSessions(onProgress?: SessionListProgress): Promise<SessionInfo[]> {\n\t\treturn this.sessionManager.list(onProgress);\n\t}\n\n\tasync listAllSessions(onProgress?: SessionListProgress): Promise<SessionInfo[]> {\n\t\treturn this.sessionManager.listAll(onProgress);\n\t}\n\n\tasync dispose(): Promise<void> {\n\t\tif (!this._session) {\n\t\t\treturn;\n\t\t}\n\t\tawait emitSessionShutdownEvent(this.session.extensionRunner, {\n\t\t\ttype: \"session_shutdown\",\n\t\t\treason: \"quit\",\n\t\t});\n\t\tawait this.flushActiveSession();\n\t\tthis.beforeSessionInvalidate?.();\n\t\tthis.session.dispose();\n\t\tthis._session = undefined;\n\t}\n}\n"]}
|
package/dist/core/pi-agent.js
CHANGED
|
@@ -439,7 +439,7 @@ export class PiAgent {
|
|
|
439
439
|
setBeforeSessionInvalidate(beforeSessionInvalidate) {
|
|
440
440
|
this.beforeSessionInvalidate = beforeSessionInvalidate;
|
|
441
441
|
}
|
|
442
|
-
async emitBeforeSwitch(reason,
|
|
442
|
+
async emitBeforeSwitch(reason, targetSessionReference) {
|
|
443
443
|
const runner = this.session.extensionRunner;
|
|
444
444
|
if (!runner.hasHandlers("session_before_switch")) {
|
|
445
445
|
return { cancelled: false };
|
|
@@ -447,7 +447,8 @@ export class PiAgent {
|
|
|
447
447
|
const result = await runner.emit({
|
|
448
448
|
type: "session_before_switch",
|
|
449
449
|
reason,
|
|
450
|
-
|
|
450
|
+
targetSessionReference,
|
|
451
|
+
targetSessionFile: targetSessionReference,
|
|
451
452
|
});
|
|
452
453
|
return { cancelled: result?.cancel === true };
|
|
453
454
|
}
|
|
@@ -469,11 +470,12 @@ export class PiAgent {
|
|
|
469
470
|
await flushPendingSync.call(this.session.session);
|
|
470
471
|
}
|
|
471
472
|
}
|
|
472
|
-
async teardownCurrent(reason,
|
|
473
|
+
async teardownCurrent(reason, targetSessionReference) {
|
|
473
474
|
await emitSessionShutdownEvent(this.session.extensionRunner, {
|
|
474
475
|
type: "session_shutdown",
|
|
475
476
|
reason,
|
|
476
|
-
|
|
477
|
+
targetSessionReference,
|
|
478
|
+
targetSessionFile: targetSessionReference,
|
|
477
479
|
});
|
|
478
480
|
await this.flushActiveSession();
|
|
479
481
|
this.beforeSessionInvalidate?.();
|
|
@@ -492,11 +494,16 @@ export class PiAgent {
|
|
|
492
494
|
if (beforeResult.cancelled) {
|
|
493
495
|
return beforeResult;
|
|
494
496
|
}
|
|
495
|
-
const
|
|
497
|
+
const previousSessionReference = this.session.sessionReference;
|
|
496
498
|
const nextSession = await this.sessionManager.openReference(sessionPath, { cwdOverride: options?.cwdOverride });
|
|
497
499
|
assertSessionCwdExists(nextSession, this.services.cwd);
|
|
498
500
|
await this.teardownCurrent("resume", nextSession.getSessionReference());
|
|
499
|
-
this.apply(await this.buildAgentSession(nextSession, {
|
|
501
|
+
this.apply(await this.buildAgentSession(nextSession, {
|
|
502
|
+
type: "session_start",
|
|
503
|
+
reason: "resume",
|
|
504
|
+
previousSessionReference,
|
|
505
|
+
previousSessionFile: previousSessionReference,
|
|
506
|
+
}));
|
|
500
507
|
await this.finishSessionReplacement(options?.withSession);
|
|
501
508
|
return { cancelled: false };
|
|
502
509
|
}
|
|
@@ -505,10 +512,29 @@ export class PiAgent {
|
|
|
505
512
|
if (beforeResult.cancelled) {
|
|
506
513
|
return beforeResult;
|
|
507
514
|
}
|
|
508
|
-
const
|
|
509
|
-
const
|
|
515
|
+
const previousSessionReference = this.session.sessionReference;
|
|
516
|
+
const activeSession = this.session.session;
|
|
517
|
+
const newSessionOptions = {
|
|
518
|
+
id: options?.id,
|
|
519
|
+
parentSession: options?.parentSession ?? activeSession.getSessionReference(),
|
|
520
|
+
};
|
|
521
|
+
let nextSession;
|
|
522
|
+
try {
|
|
523
|
+
nextSession = await activeSession.createSubSession(newSessionOptions);
|
|
524
|
+
}
|
|
525
|
+
catch (error) {
|
|
526
|
+
if (!(error instanceof Error && error.message === "Session manager unavailable")) {
|
|
527
|
+
throw error;
|
|
528
|
+
}
|
|
529
|
+
nextSession = await this.sessionManager.create(newSessionOptions);
|
|
530
|
+
}
|
|
510
531
|
await this.teardownCurrent("new", nextSession.getSessionReference());
|
|
511
|
-
this.apply(await this.buildAgentSession(nextSession, {
|
|
532
|
+
this.apply(await this.buildAgentSession(nextSession, {
|
|
533
|
+
type: "session_start",
|
|
534
|
+
reason: "new",
|
|
535
|
+
previousSessionReference,
|
|
536
|
+
previousSessionFile: previousSessionReference,
|
|
537
|
+
}));
|
|
512
538
|
if (options?.setup) {
|
|
513
539
|
await options.setup(this.session.session);
|
|
514
540
|
this.session.agent.state.messages = this.session.session.buildSessionContext().messages;
|
|
@@ -538,10 +564,25 @@ export class PiAgent {
|
|
|
538
564
|
targetLeafId = selectedEntry.parentId;
|
|
539
565
|
selectedText = extractUserMessageText(selectedEntry.message.content);
|
|
540
566
|
}
|
|
541
|
-
const
|
|
542
|
-
const
|
|
567
|
+
const previousSessionReference = this.session.sessionReference;
|
|
568
|
+
const activeSession = this.session.session;
|
|
569
|
+
let nextSession;
|
|
570
|
+
try {
|
|
571
|
+
nextSession = await activeSession.forkSubSession(targetLeafId);
|
|
572
|
+
}
|
|
573
|
+
catch (error) {
|
|
574
|
+
if (!(error instanceof Error && error.message === "Session manager unavailable")) {
|
|
575
|
+
throw error;
|
|
576
|
+
}
|
|
577
|
+
nextSession = await this.sessionManager.forkSession(activeSession, targetLeafId);
|
|
578
|
+
}
|
|
543
579
|
await this.teardownCurrent("fork", nextSession.getSessionReference());
|
|
544
|
-
this.apply(await this.buildAgentSession(nextSession, {
|
|
580
|
+
this.apply(await this.buildAgentSession(nextSession, {
|
|
581
|
+
type: "session_start",
|
|
582
|
+
reason: "fork",
|
|
583
|
+
previousSessionReference,
|
|
584
|
+
previousSessionFile: previousSessionReference,
|
|
585
|
+
}));
|
|
545
586
|
await this.finishSessionReplacement(options?.withSession);
|
|
546
587
|
return { cancelled: false, selectedText };
|
|
547
588
|
}
|
|
@@ -554,11 +595,16 @@ export class PiAgent {
|
|
|
554
595
|
if (beforeResult.cancelled) {
|
|
555
596
|
return beforeResult;
|
|
556
597
|
}
|
|
557
|
-
const
|
|
598
|
+
const previousSessionReference = this.session.sessionReference;
|
|
558
599
|
const nextSession = await this.sessionManager.importJsonl(resolvedPath, { cwdOverride: cwdOverride });
|
|
559
600
|
assertSessionCwdExists(nextSession, this.services.cwd);
|
|
560
601
|
await this.teardownCurrent("resume", nextSession.getSessionReference());
|
|
561
|
-
this.apply(await this.buildAgentSession(nextSession, {
|
|
602
|
+
this.apply(await this.buildAgentSession(nextSession, {
|
|
603
|
+
type: "session_start",
|
|
604
|
+
reason: "resume",
|
|
605
|
+
previousSessionReference,
|
|
606
|
+
previousSessionFile: previousSessionReference,
|
|
607
|
+
}));
|
|
562
608
|
await this.finishSessionReplacement();
|
|
563
609
|
return { cancelled: false };
|
|
564
610
|
}
|
|
@@ -632,11 +678,11 @@ export class PiAgent {
|
|
|
632
678
|
forkSessionFrom(reference) {
|
|
633
679
|
return this.sessionManager.forkFrom(reference);
|
|
634
680
|
}
|
|
635
|
-
async listSessions() {
|
|
636
|
-
return this.sessionManager.list();
|
|
681
|
+
async listSessions(onProgress) {
|
|
682
|
+
return this.sessionManager.list(onProgress);
|
|
637
683
|
}
|
|
638
|
-
async listAllSessions() {
|
|
639
|
-
return this.sessionManager.listAll();
|
|
684
|
+
async listAllSessions(onProgress) {
|
|
685
|
+
return this.sessionManager.listAll(onProgress);
|
|
640
686
|
}
|
|
641
687
|
async dispose() {
|
|
642
688
|
if (!this._session) {
|