Skip to content

Commit 3de9601

Browse files
authored
fix(chat_structured): send structured data info back to the LLM (#203)
* Close #191: send structured data info back to the LLM * Update changelog
1 parent 66c02c0 commit 3de9601

File tree

6 files changed

+18
-7
lines changed

6 files changed

+18
-7
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3131
### Bug fixes
3232

3333
* `.set_model_params()` now works correctly for `.*_async()` methods. (#198)
34+
* `.chat_structured()` results are now included correctly into the multi-turn conversation history. (#203)
3435

3536
## [0.13.2] - 2025-10-02
3637

chatlas/_provider_anthropic.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,8 @@ def _as_content_block(content: Content) -> "ContentBlockParam":
526526
if isinstance(content, ContentText):
527527
return {"text": content.text, "type": "text"}
528528
elif isinstance(content, ContentJson):
529-
return {"text": "<structured data/>", "type": "text"}
529+
text = orjson.dumps(content.value).decode("utf-8")
530+
return {"text": text, "type": "text"}
530531
elif isinstance(content, ContentPDF):
531532
return {
532533
"type": "document",

chatlas/_provider_google.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,8 @@ def _as_part_type(self, content: Content) -> "Part":
442442
if isinstance(content, ContentText):
443443
return Part.from_text(text=content.text)
444444
elif isinstance(content, ContentJson):
445-
return Part.from_text(text="<structured data/>")
445+
text = orjson.dumps(content.value).decode("utf-8")
446+
return Part.from_text(text=text)
446447
elif isinstance(content, ContentPDF):
447448
from google.genai.types import Blob
448449

chatlas/_provider_openai_completions.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -245,9 +245,8 @@ def _turns_as_inputs(turns: list[Turn]) -> list["ChatCompletionMessageParam"]:
245245
if isinstance(x, ContentText):
246246
content_parts.append({"type": "text", "text": x.text})
247247
elif isinstance(x, ContentJson):
248-
content_parts.append(
249-
{"type": "text", "text": "<structured data/>"}
250-
)
248+
text = orjson.dumps(x.value).decode("utf-8")
249+
content_parts.append({"type": "text", "text": text})
251250
elif isinstance(x, ContentToolRequest):
252251
tool_calls.append(
253252
{
@@ -286,7 +285,8 @@ def _turns_as_inputs(turns: list[Turn]) -> list["ChatCompletionMessageParam"]:
286285
if isinstance(x, ContentText):
287286
contents.append({"type": "text", "text": x.text})
288287
elif isinstance(x, ContentJson):
289-
contents.append({"type": "text", "text": "<structured data/>"})
288+
text = orjson.dumps(x.value).decode("utf-8")
289+
contents.append({"type": "text", "text": text})
290290
elif isinstance(x, ContentPDF):
291291
contents.append(
292292
{

chatlas/_provider_snowflake.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,8 @@ def _as_request_messages(self, turns: list[Turn]):
511511
}
512512
)
513513
elif isinstance(x, ContentJson):
514-
req.content = req.content or "<structured data/>"
514+
text = orjson.dumps(x.value).decode("utf-8")
515+
req.content = req.content or text
515516

516517
res.append(req)
517518
return res

tests/conftest.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,13 @@ def assert_data_extraction(chat_fun: ChatFun):
221221
assert data2.author == "Hadley Wickham"
222222
assert data2.title.lower() == "apples are tasty"
223223

224+
class Person(BaseModel):
225+
name: str
226+
age: int
227+
data = chat.chat_structured("Generate the name and age of a random person.", data_model=Person)
228+
response = chat.chat("What is the name of the person?")
229+
assert data.name in str(response)
230+
224231

225232
def assert_images_inline(chat_fun: ChatFun, stream: bool = True):
226233
img = Image.new("RGB", (60, 30), color="red")

0 commit comments

Comments
 (0)