refactor(app): introduce attachment storage layer and draft lifecycle management

Replace inline data-URL image handling with a persistent attachment storage service, add draft lifecycle states (active/abandoned/sent) with generation tracking, and update fetchAgent to return project placement alongside agent snapshots.
This commit is contained in:
Mohamed Boudra
2026-02-22 16:22:21 +07:00
parent 2652bdda2e
commit 0c710b09f5
55 changed files with 2381 additions and 350 deletions
@@ -42,6 +42,8 @@ import {
normalizeAgentSnapshot,
} from "@/utils/agent-snapshots";
import { resolveProjectPlacement } from "@/utils/project-placement";
import { buildDraftStoreKey } from "@/stores/draft-keys";
import type { AttachmentMetadata } from "@/attachments/types";
// Re-export types from session-store and draft-store for backward compatibility
export type { DraftInput } from "@/stores/draft-store";
@@ -259,7 +261,7 @@ function SessionProviderInternal({
| ((
agentId: string,
message: string,
images?: Array<{ uri: string; mimeType?: string }>
images?: AttachmentMetadata[]
) => Promise<void>)
| null
>(null);
@@ -1172,7 +1174,9 @@ function SessionProviderInternal({
});
// Remove draft input
clearDraftInput(agentId);
clearDraftInput({
draftKey: buildDraftStoreKey({ serverId, agentId }),
});
setPendingPermissions(serverId, (prev) => {
let changed = false;
@@ -1270,7 +1274,7 @@ function SessionProviderInternal({
async (
agentId: string,
message: string,
images?: Array<{ uri: string; mimeType?: string }>
images?: AttachmentMetadata[]
) => {
const messageId = generateMessageId();
const userMessage: StreamItem = {
@@ -1385,7 +1389,7 @@ function SessionProviderInternal({
}: {
config: any;
initialPrompt: string;
images?: Array<{ uri: string; mimeType?: string }>;
images?: AttachmentMetadata[];
git?: any;
worktreeName?: string;
requestId?: string;