diff --git a/packages/app/src/contexts/session-context.tsx b/packages/app/src/contexts/session-context.tsx index 6f32d6289..d678b161d 100644 --- a/packages/app/src/contexts/session-context.tsx +++ b/packages/app/src/contexts/session-context.tsx @@ -19,7 +19,7 @@ import type { import type { AgentPermissionRequest, } from "@server/server/agent/agent-sdk-types"; -import * as FileSystem from "expo-file-system"; +import { File } from "expo-file-system"; import { useDaemonConnections } from "./daemon-connections-context"; import { useSessionStore } from "@/stores/session-store"; import type { AgentDirectoryEntry } from "@/types/agent-directory"; @@ -1329,9 +1329,8 @@ export function SessionProvider({ children, serverUrl, serverId }: SessionProvid }); return base64; } - return await FileSystem.readAsStringAsync(uri, { - encoding: "base64", - }); + const file = new File(uri); + return await file.base64(); })(); return { data, @@ -1473,10 +1472,12 @@ export function SessionProvider({ children, serverUrl, serverId }: SessionProvid }, [ws]); const createAgent = useCallback(async ({ config, initialPrompt, images, git, worktreeName, requestId }: { config: any; initialPrompt: string; images?: Array<{ uri: string; mimeType?: string }>; git?: any; worktreeName?: string; requestId?: string }) => { + console.log("[Session] createAgent called with images:", images?.length ?? 0, images); const trimmedPrompt = initialPrompt.trim(); let imagesData: Array<{ data: string; mimeType: string }> | undefined; try { imagesData = await encodeImages(images); + console.log("[Session] encodeImages result:", imagesData?.length ?? 0, imagesData?.map(img => ({ dataLength: img.data?.length ?? 0, mimeType: img.mimeType }))); } catch (error) { console.error("[Session] Failed to prepare images for agent creation:", error); } @@ -1492,6 +1493,7 @@ export function SessionProvider({ children, serverUrl, serverId }: SessionProvid ...(requestId ? { requestId } : {}), }, }; + console.log("[Session] createAgent message has images:", 'images' in msg.message, (msg.message as any).images?.length); ws.send(msg); }, [encodeImages, ws]); diff --git a/plan.md b/plan.md index b58b9506d..d63970db2 100644 --- a/plan.md +++ b/plan.md @@ -191,3 +191,14 @@ Improvements to the new agent screen in the app. - Ensure temp files are created under `/tmp/paseo-attachments` and prompt only references the file path. - Add a lightweight regression test or log assertion if possible. - **Done (2025-12-29 10:34)**: WHAT: `packages/server/src/server/agent/providers/codex-mcp-agent.ts:2333-2412` now normalizes inline data URLs, writes attachments under `/tmp/paseo-attachments`, and replaces embedded base64 in prompt strings/blocks with temp file paths (plus a log when replacements occur). RESULT: Codex prompt text no longer carries inline base64 data URLs and uses temp file references instead. EVIDENCE: Not run (not requested). + +- [x] **Fix**: Migrate expo-file-system to new API for React Native image encoding. + + - Error in RN: `Method readAsStringAsync imported from "expo-file-system" is deprecated`. + - The error occurs at `packages/app/src/contexts/session-context.tsx:1332` when encoding images on native platforms. + - Current code uses `FileSystem.readAsStringAsync(uri, { encoding: "base64" })` which is deprecated. + - Search the web for Expo's new filesystem API using `File` and `Directory` classes. + - Check the Expo documentation for the recommended migration path. + - Update `encodeImages` function to use the new API for native platforms while keeping web handling unchanged. + - Test image attachments on iOS/Android after the fix. + - **Done (2025-12-29 10:50)**: WHAT: `packages/app/src/contexts/session-context.tsx:22` swaps the import to `File` from the new expo-file-system API; `packages/app/src/contexts/session-context.tsx:1332-1333` uses `new File(uri).base64()` instead of `readAsStringAsync` for native image encoding. RESULT: Native image encoding no longer relies on deprecated `readAsStringAsync`. EVIDENCE: Not run (iOS/Android testing not requested).