Fork assistant turns into new drafts (#1788)
* feat(chat): fork assistant turns into new drafts Builds chat-history attachments on the daemon and routes them into draft composers so users can continue an assistant turn in an existing workspace tab or New Workspace. * fix(chat): clean up fork draft handling * fix(chat): address fork draft review feedback * fix(server): build fork context from bounded timeline * fix(app): restore assistant turn footer in streams * fix(app): preserve fork draft setup * fix(app): tighten assistant fork footers * fix(app): lock active fork draft handoff * fix(app): preserve attachment-only draft retries * fix(app): unify composer attachment scopes * fix(app): align chat history attachment labels * fix(app): centralize attachment pill content * fix(app): trim fork context for workspace naming
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
import type { AgentAttachment } from "@getpaseo/protocol/messages";
|
||||
|
||||
function isLikelyWindowsPath(path: string): boolean {
|
||||
return /^[a-zA-Z]:\//.test(path);
|
||||
}
|
||||
|
||||
function isChatHistoryTextAttachment(attachment: AgentAttachment): boolean {
|
||||
return attachment.type === "text" && attachment.contextKind === "chat_history";
|
||||
}
|
||||
|
||||
export function getWorkspaceNamingAttachments(
|
||||
attachments: readonly AgentAttachment[],
|
||||
): AgentAttachment[] {
|
||||
return attachments.filter((attachment) => !isChatHistoryTextAttachment(attachment));
|
||||
}
|
||||
|
||||
export function remapDraftCwdToWorkspace(input: {
|
||||
cwd: string;
|
||||
sourceDirectory?: string | null;
|
||||
workspaceDirectory: string;
|
||||
}): string {
|
||||
const cwd = input.cwd.trim();
|
||||
const sourceDirectory = input.sourceDirectory?.trim();
|
||||
const workspaceDirectory = input.workspaceDirectory.trim();
|
||||
if (!cwd || !sourceDirectory) {
|
||||
return workspaceDirectory;
|
||||
}
|
||||
const normalizedCwd = cwd.replace(/\\/g, "/").replace(/\/+$/, "");
|
||||
const normalizedSource = sourceDirectory.replace(/\\/g, "/").replace(/\/+$/, "");
|
||||
const compareCaseInsensitively =
|
||||
isLikelyWindowsPath(normalizedCwd) || isLikelyWindowsPath(normalizedSource);
|
||||
const comparableCwd = compareCaseInsensitively ? normalizedCwd.toLowerCase() : normalizedCwd;
|
||||
const comparableSource = compareCaseInsensitively
|
||||
? normalizedSource.toLowerCase()
|
||||
: normalizedSource;
|
||||
if (comparableCwd === comparableSource) {
|
||||
return workspaceDirectory;
|
||||
}
|
||||
const relativePath = comparableCwd.startsWith(`${comparableSource}/`)
|
||||
? normalizedCwd.slice(normalizedSource.length + 1)
|
||||
: "";
|
||||
if (!relativePath) {
|
||||
return workspaceDirectory;
|
||||
}
|
||||
const separator =
|
||||
workspaceDirectory.includes("\\") && !workspaceDirectory.includes("/") ? "\\" : "/";
|
||||
return [workspaceDirectory.replace(/[\\/]+$/, ""), ...relativePath.split("/")]
|
||||
.filter(Boolean)
|
||||
.join(separator);
|
||||
}
|
||||
Reference in New Issue
Block a user