Skip to content

Commit 756b1d8

Browse files
authored
fix(oci): convert image_url to camelCase imageUrl for OCI vision requests (#761)
OCI Generative AI expects camelCase field names. The SDK transforms message roles and content types but passed image_url through as-is, causing 400 errors on Command A Vision with inline images. Added integration test that sends a 1x1 red PNG to Command A Vision and verifies the model correctly identifies the color. Fixes #760
1 parent fc167c1 commit 756b1d8

2 files changed

Lines changed: 34 additions & 0 deletions

File tree

src/cohere/oci_client.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -721,6 +721,9 @@ def transform_request_to_oci(
721721
if isinstance(item, dict) and "type" in item:
722722
transformed_item = item.copy()
723723
transformed_item["type"] = item["type"].upper()
724+
# OCI expects camelCase: image_url → imageUrl
725+
if "image_url" in transformed_item:
726+
transformed_item["imageUrl"] = transformed_item.pop("image_url")
724727
transformed_content.append(transformed_item)
725728
else:
726729
transformed_content.append(item)

tests/test_oci_client.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,37 @@ def test_chat_v2(self):
190190
self.assertIsNotNone(response)
191191
self.assertIsNotNone(response.message)
192192

193+
def test_chat_vision_v2(self):
194+
"""Test vision with inline image on Command A Vision."""
195+
import base64, struct, zlib
196+
197+
# Create a minimal 1x1 red PNG
198+
raw = b'\x00\xff\x00\x00'
199+
compressed = zlib.compress(raw)
200+
def chunk(ctype, data):
201+
c = ctype + data
202+
return struct.pack('>I', len(data)) + c + struct.pack('>I', zlib.crc32(c) & 0xffffffff)
203+
ihdr = struct.pack('>IIBBBBB', 1, 1, 8, 2, 0, 0, 0)
204+
png = b'\x89PNG\r\n\x1a\n' + chunk(b'IHDR', ihdr) + chunk(b'IDAT', compressed) + chunk(b'IEND', b'')
205+
img_b64 = base64.b64encode(png).decode()
206+
207+
response = self.client.chat(
208+
model="command-a-vision",
209+
messages=[{
210+
"role": "user",
211+
"content": [
212+
{"type": "text", "text": "What color is this image? Reply with one word."},
213+
{"type": "image_url", "image_url": {"url": f"data:image/png;base64,{img_b64}"}},
214+
],
215+
}],
216+
)
217+
218+
self.assertIsNotNone(response)
219+
self.assertIsNotNone(response.message)
220+
self.assertTrue(len(response.message.content) > 0)
221+
# The 1x1 red pixel should be identified as red
222+
self.assertIn("red", response.message.content[0].text.lower())
223+
193224
def test_chat_tool_use_v2(self):
194225
"""Test tool use with v2 client on OCI on-demand inference."""
195226
response = self.client.chat(

0 commit comments

Comments
 (0)