Something went wrong. Try again.
source dump of claude code forked from oppi.li/claude-code
Something went wrong. Try again.
2.7 kB · 80 lines
TypeScript
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081import type { Base64ImageSource, ContentBlockParam, ImageBlockParam,} from '@anthropic-ai/sdk/resources/messages.mjs'import type { UUID } from 'crypto'import type { SDKMessage } from '../entrypoints/agentSdkTypes.js'import { detectImageFormatFromBase64 } from '../utils/imageResizer.js'
/** * Process an inbound user message from the bridge, extracting content * and UUID for enqueueing. Supports both string content and * ContentBlockParam[] (e.g. messages containing images). * * Normalizes image blocks from bridge clients that may use camelCase * `mediaType` instead of snake_case `media_type` (mobile-apps#5825). * * Returns the extracted fields, or undefined if the message should be * skipped (non-user type, missing/empty content). */export function extractInboundMessageFields( msg: SDKMessage,): | { content: string | Array<ContentBlockParam>; uuid: UUID | undefined } | undefined { if (msg.type !== 'user') return undefined const content = msg.message?.content if (!content) return undefined if (Array.isArray(content) && content.length === 0) return undefined
const uuid = 'uuid' in msg && typeof msg.uuid === 'string' ? (msg.uuid as UUID) : undefined
return { content: Array.isArray(content) ? normalizeImageBlocks(content) : content, uuid, }}
/** * Normalize image content blocks from bridge clients. iOS/web clients may * send `mediaType` (camelCase) instead of `media_type` (snake_case), or * omit the field entirely. Without normalization, the bad block poisons * the session — every subsequent API call fails with * "media_type: Field required". * * Fast-path scan returns the original array reference when no * normalization is needed (zero allocation on the happy path). */export function normalizeImageBlocks( blocks: Array<ContentBlockParam>,): Array<ContentBlockParam> { if (!blocks.some(isMalformedBase64Image)) return blocks
return blocks.map(block => { if (!isMalformedBase64Image(block)) return block const src = block.source as unknown as Record<string, unknown> const mediaType = typeof src.mediaType === 'string' && src.mediaType ? src.mediaType : detectImageFormatFromBase64(block.source.data) return { ...block, source: { type: 'base64' as const, media_type: mediaType as Base64ImageSource['media_type'], data: block.source.data, }, } })}
function isMalformedBase64Image( block: ContentBlockParam,): block is ImageBlockParam & { source: Base64ImageSource } { if (block.type !== 'image' || block.source?.type !== 'base64') return false return !(block.source as unknown as Record<string, unknown>).media_type}