Fix the SDK smoke check for an SMS integration
Your task
An AI agent wired a third party SMS provider's SDK into your notification service, from docs it remembered. The code compiles and reads well, but an agent can invent method names and response fields. Before production, your smoke check compares the surface the code assumes (the methods and fields it touches) with the surface the installed SDK really has.
An assistant wrote sdk_contract_gaps(assumed_surface, real_surface). It is in the editor. It has a bug. Find it and fix it.
Input and output:
assumed_surface: what the integration code uses, one string per symbol, in the form"kind|name|shape", like"method|client.messages.create|to,body,from"or"field|response.sid|string". The kind is normallymethodorfield. The shape is the parameter list or the type the code depends on.real_surface: the same format, dumped from the installed SDK.- Return the list of gaps.
Rules the tests check:
- Split each entry on
|. Skip an entry with fewer than 3 parts. Parts after the third are ignored. - Trim whitespace at both ends of the kind, the name and the shape. Skip an entry whose kind or name is empty after trimming. An empty shape is fine.
- A symbol is a kind plus a name. Kinds, names and shapes compare exactly, and case matters.
- When
real_surfacelists a symbol more than once, its first entry counts. - Check each symbol in
assumed_surfaceonce, using its first entry. Skip later entries for a symbol you already checked. - For each assumed symbol, add
"missing:<kind>.<name>", with the trimmed kind and name, when the real surface does not have it. Add"shape_mismatch:<kind>.<name>"when it has it with a different shape, soto,bodyandbody,todiffer. Add nothing when the shapes are equal. - Symbols that only
real_surfacehas add nothing. - Return the gaps sorted in ascending order by character code, as a default string sort does.
Examples
sdk_contract_gaps(assumed_surface: list[str], real_surface: list[str]) -> list[str]Example 1
Input
sdk_contract_gaps(["method|client.messages.create|to,body,from", "field|response.messageId|string", "field|response.error.code|string"], ["method|client.messages.create|to,body,from", "field|response.sid|string", "field|response.status|string"])Output
["missing:field.response.error.code", "missing:field.response.messageId"]Example 2
Input
sdk_contract_gaps(["method|client.messages.create|body,to"], ["method|client.messages.create|to,body"])Output
["shape_mismatch:method.client.messages.create"]Example 3
Input
sdk_contract_gaps(["method|client.messages.create|to,body", "field|response.sid|string"], ["method|client.messages.create|to,body", "field|response.sid|string", "method|client.messages.list|limit"])Output
[]