Severity: High — create() raises ValidationError on real tool-call responses
to_interfaze re-validates the whole completion through a strict typed model:
# src/interfaze/_chat.pyreturnInterfazeChatCompletion.model_validate(data)
InterfazeChatCompletion.precontext is Optional[List[Precontext]] and Precontext.name is required. But the server appends raw model tool-calls to precontext whenever the final model calls a tool (user-defined tools, or internal action tools like run_code):
src/helpers/response.ts:105 → internalToolUsedToBeShownToUser = [...prev, ...toolCalls] where toolCalls are raw AI-SDK objects {toolCallId, toolName, input} — no name, no result.ModifyToolResponsesForUser (src/utils/messaging.ts:17) sets name from a lookup map, so an unmapped tool yields name: undefined too.
Reproduction (verified)
frominterfaze._chatimportto_interfazefromopenai.types.chatimportChatCompletionraw= {
"id":"r","object":"chat.completion","created":1,"model":"interfaze-beta",
"choices":[{"index":0,"message":{"role":"assistant","content":"hi","refusal":None},
"finish_reason":"stop","logprobs":None}],
"usage":{"prompt_tokens":5,"completion_tokens":3,"total_tokens":8},
"vcache":False,
"precontext":[{"name":"ocr","result":{}},
{"toolCallId":"call_1","toolName":"run_code","input":{}}],
}
to_interfaze(ChatCompletion.model_construct(**raw), strip_fence=False)
# pydantic ValidationError: precontext.1.name Field requiredAny function-calling / run_code turn therefore crashes the non-streaming create(). This is the exact "strong types break precontext" failure mode the SDK exists to avoid — reintroduced by re-validating the response. The openai SDK's own rule is type strongly, validate loosely, preserve everything (it uses model_construct, extra="allow").
Fix options
- Parse leniently:
InterfazeChatCompletion.model_construct(**data) (mirrors openai-python), or - Loosen the field:
precontext: Optional[List[Union[Precontext, Dict[str, Any]]]], or - Don't re-run full validation in
to_interfaze.
Add a fixture/test with a mixed precontext (one {name,result} + one raw {toolCallId,toolName,input}) — current fixtures never cover this (TOOL_CALL has no precontext).
Severity: High —
create()raisesValidationErroron real tool-call responsesto_interfazere-validates the whole completion through a strict typed model:InterfazeChatCompletion.precontextisOptional[List[Precontext]]andPrecontext.nameis required. But the server appends raw model tool-calls toprecontextwhenever the final model calls a tool (user-defined tools, or internal action tools likerun_code):src/helpers/response.ts:105→internalToolUsedToBeShownToUser = [...prev, ...toolCalls]wheretoolCallsare raw AI-SDK objects{toolCallId, toolName, input}— noname, noresult.ModifyToolResponsesForUser(src/utils/messaging.ts:17) setsnamefrom a lookup map, so an unmapped tool yieldsname: undefinedtoo.Reproduction (verified)
Any function-calling /
run_codeturn therefore crashes the non-streamingcreate(). This is the exact "strong types break precontext" failure mode the SDK exists to avoid — reintroduced by re-validating the response. TheopenaiSDK's own rule is type strongly, validate loosely, preserve everything (it usesmodel_construct,extra="allow").Fix options
InterfazeChatCompletion.model_construct(**data)(mirrors openai-python), orprecontext: Optional[List[Union[Precontext, Dict[str, Any]]]], orto_interfaze.Add a fixture/test with a mixed
precontext(one{name,result}+ one raw{toolCallId,toolName,input}) — current fixtures never cover this (TOOL_CALLhas no precontext).