• Stefy Lanza (nextime / spora )'s avatar
    characters/voices: accept /v1/files paths and sha256 upload ids as media · be1ecdf4
    Stefy Lanza (nextime / spora ) authored
    Motus request 3. The character and voice extractors decoded media with their own
    helpers, which took base64, data: URIs and http(s) URLs but not the
    /v1/files/... paths compose accepts — so a client had to inline every source clip
    as base64 (a third larger) even when the server already held the file it had
    uploaded minutes earlier.
    
    - codai/compose/media.py: one resolver for every accepted reference —
      blob_path() for a sha256: upload id, local_path() for that or a /v1/files path
      (traversal-checked), fetch_bytes() for the endpoints that want bytes; a file we
      hold is read from disk, never fetched over the loopback.
    - characters._decode_source and voice_clone._decode_b64_or_url now delegate to
      it, which also gives POST /v1/characters and PATCH add_images the same
      references (they only base64-decoded before), and _decode_audio takes the
      stored extension from the CONTENT rather than the caller's claim (a
      data:audio/mpeg URI holding a wav was written as .mpeg).
    - uploads.find_blob() reuses media.blob_path so there is one lookup, not two.
    - A bare server path stays refused; a missing blob is a 400 naming the problem.
    - docs/video-compose.md lists the endpoints that share the resolver;
      tests/test_compose.py +2 (every reference form, and a character saved from an
      upload id).
    Co-Authored-By: 's avatarClaude Opus 5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01B7EnDW6RSd2nhEPZMzMkqi
    be1ecdf4
voice_clone.py 36.4 KB