mirror of
https://github.com/getpaseo/paseo.git
synced 2026-11-10 18:35:17 +00:00
Replay the saved transcript ancestry instead of the compacted model context so older messages retain their native rewind identities and Fork chat boundaries.
158 lines
4.3 KiB
TypeScript
158 lines
4.3 KiB
TypeScript
import type { PiTranscript } from "./transcript.js";
|
|
import type {
|
|
PiModel,
|
|
PiPromptAck,
|
|
PiRpcSlashCommand,
|
|
PiRuntimeEvent,
|
|
PiSessionState,
|
|
PiSessionStats,
|
|
} from "./rpc-types.js";
|
|
import type { ProviderRuntimeSettings } from "../../provider-launch-config.js";
|
|
|
|
export interface PiRuntimeLaunch {
|
|
cwd: string;
|
|
argv: string[];
|
|
env?: Record<string, string>;
|
|
protocolMode?: "rpc" | "rpc-ui";
|
|
model?: string;
|
|
thinkingOptionId?: string;
|
|
modeId?: string;
|
|
session?: string;
|
|
noSession?: boolean;
|
|
mcpConfigPath?: string;
|
|
extensionPaths?: string[];
|
|
extraArgs?: string[];
|
|
}
|
|
|
|
export interface PiStartSessionInput {
|
|
cwd: string;
|
|
signal?: AbortSignal;
|
|
env?: Record<string, string>;
|
|
protocolMode?: "rpc" | "rpc-ui";
|
|
model?: string;
|
|
thinkingOptionId?: string;
|
|
modeId?: string;
|
|
session?: string;
|
|
noSession?: boolean;
|
|
mcpConfigPath?: string;
|
|
extensionPaths?: string[];
|
|
extraArgs?: string[];
|
|
}
|
|
|
|
export interface PiRuntimeSession {
|
|
readonly environment: Record<string, string>;
|
|
onEvent(callback: (event: PiRuntimeEvent) => void): () => void;
|
|
prompt(
|
|
message: string,
|
|
images?: Array<{ type: "image"; data: string; mimeType: string }>,
|
|
): Promise<PiPromptAck>;
|
|
steer(
|
|
message: string,
|
|
images?: Array<{ type: "image"; data: string; mimeType: string }>,
|
|
): Promise<void>;
|
|
clearQueue(): Promise<void>;
|
|
compact(customInstructions?: string): Promise<void>;
|
|
setAutoCompaction(enabled: boolean): Promise<void>;
|
|
abort(): Promise<void>;
|
|
getState(): Promise<PiSessionState>;
|
|
getHistory(): Promise<PiTranscript>;
|
|
getAvailableModels(timeoutMs?: number | null): Promise<PiModel[]>;
|
|
setModel(provider: string, modelId: string): Promise<PiModel>;
|
|
setThinkingLevel(level: string): Promise<void>;
|
|
getSessionStats(): Promise<PiSessionStats>;
|
|
getCommands(): Promise<PiRpcSlashCommand[]>;
|
|
request(
|
|
command: { type: string; [key: string]: unknown },
|
|
timeoutMs?: number | null,
|
|
): Promise<unknown>;
|
|
sendRawFrame(frame: object & { type: string }): void;
|
|
respondToExtensionUiRequest(
|
|
id: string,
|
|
response: { value?: string; confirmed?: boolean; cancelled?: boolean },
|
|
): void;
|
|
cancelExtensionUiRequest(id: string): void;
|
|
close(): Promise<void>;
|
|
}
|
|
|
|
export interface PiRuntime {
|
|
startSession(input: PiStartSessionInput): Promise<PiRuntimeSession>;
|
|
}
|
|
|
|
export function buildPiLaunch(input: {
|
|
command: [string, ...string[]];
|
|
runtimeSettings?: ProviderRuntimeSettings;
|
|
session: PiStartSessionInput;
|
|
}): PiRuntimeLaunch {
|
|
const command =
|
|
input.runtimeSettings?.command?.mode === "replace" && input.runtimeSettings.command.argv[0]
|
|
? input.runtimeSettings.command.argv
|
|
: input.command;
|
|
const argv = [...command];
|
|
|
|
const protocolMode = input.session.protocolMode ?? "rpc";
|
|
appendPiLaunchArgs(argv, input.session, protocolMode);
|
|
|
|
return {
|
|
cwd: input.session.cwd,
|
|
argv,
|
|
env:
|
|
input.runtimeSettings?.env || input.session.env
|
|
? {
|
|
...input.runtimeSettings?.env,
|
|
...input.session.env,
|
|
}
|
|
: undefined,
|
|
model: input.session.model,
|
|
thinkingOptionId: input.session.thinkingOptionId,
|
|
protocolMode,
|
|
modeId: input.session.modeId,
|
|
session: input.session.session,
|
|
noSession: input.session.noSession,
|
|
mcpConfigPath: input.session.mcpConfigPath,
|
|
extensionPaths: input.session.extensionPaths,
|
|
extraArgs: input.session.extraArgs,
|
|
};
|
|
}
|
|
|
|
function appendPiLaunchArgs(
|
|
argv: string[],
|
|
session: PiStartSessionInput,
|
|
protocolMode: "rpc" | "rpc-ui",
|
|
): void {
|
|
if (!hasModeFlag(argv)) {
|
|
argv.push("--mode", protocolMode);
|
|
}
|
|
if (session.extraArgs?.length) {
|
|
argv.push(...session.extraArgs);
|
|
}
|
|
if (session.model) {
|
|
argv.push("--model", session.model);
|
|
}
|
|
if (session.thinkingOptionId) {
|
|
argv.push("--thinking", session.thinkingOptionId);
|
|
}
|
|
if (session.noSession) {
|
|
argv.push("--no-session");
|
|
} else if (session.session) {
|
|
argv.push("--session", session.session);
|
|
}
|
|
if (session.mcpConfigPath) {
|
|
argv.push("--mcp-config", session.mcpConfigPath);
|
|
}
|
|
for (const extensionPath of session.extensionPaths ?? []) {
|
|
argv.push("--extension", extensionPath);
|
|
}
|
|
}
|
|
|
|
function hasModeFlag(argv: string[]): boolean {
|
|
for (let i = 0; i < argv.length; i += 1) {
|
|
if (argv[i] === "--mode") {
|
|
return true;
|
|
}
|
|
if (argv[i]?.startsWith("--mode=")) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|