From 4b4fa004b8c274d47f41a1b4ba6565264959fef9 Mon Sep 17 00:00:00 2001 From: "typesafe-sdk-spec-sync[bot]" <332563186+typesafe-sdk-spec-sync[bot]@users.noreply.github.com> Date: Sat, 24 Oct 2026 09:42:31 +0000 Subject: [PATCH] Update the vendored TypeSafe OpenAPI specification --- typesafe-ai-core/spec/openapi.json | 538 +++++++++++++++++++++++++++-- 1 file changed, 500 insertions(+), 38 deletions(-) diff --git a/typesafe-ai-core/spec/openapi.json b/typesafe-ai-core/spec/openapi.json index d4aa8d4..add8781 100644 --- a/typesafe-ai-core/spec/openapi.json +++ b/typesafe-ai-core/spec/openapi.json @@ -5,6 +5,7 @@ "description": "An answer whose type matches the corresponding question.", "discriminator": { "mapping": { + "box": "#/components/schemas/BoxAnswer", "choice": "#/components/schemas/ChoiceAnswer", "noul": "#/components/schemas/NoulAnswer", "score": "#/components/schemas/ScoreAnswer" @@ -13,16 +14,187 @@ }, "oneOf": [ { - "$ref": "#/components/schemas/NoulAnswer" + "$ref": "#/components/schemas/NoulAnswer", + "title": "Noul" }, { - "$ref": "#/components/schemas/ScoreAnswer" + "$ref": "#/components/schemas/ChoiceAnswer", + "title": "Choice" }, { - "$ref": "#/components/schemas/ChoiceAnswer" + "$ref": "#/components/schemas/ScoreAnswer", + "title": "Score" + }, + { + "$ref": "#/components/schemas/BoxAnswer", + "title": "Box" } ] }, + "Asset": { + "description": "An image that replaces its placeholder: its bytes in data_base64 with their format, or, in a multipart request, the name of the image part that holds them. Requests with images must send the header TypeSafe-Danger-Zone-Images: true.", + "properties": { + "data_base64": { + "description": "Base64-encoded image data.", + "title": "Data Base64", + "type": "string" + }, + "format": { + "description": "The image format, required with data_base64. The actual format is detected from the bytes.", + "enum": [ + "png", + "jpg", + "jpeg" + ], + "title": "Format", + "type": "string" + }, + "part": { + "description": "In a multipart request, the name of the image part this asset uses. With part, data_base64 is ignored.", + "title": "Part", + "type": "string" + }, + "type": { + "const": "image", + "description": "Identifies an image asset.", + "title": "Type", + "type": "string" + } + }, + "title": "Asset", + "type": "object" + }, + "BoxAnswer": { + "description": "A located box with normalized edge coordinates and confidence.", + "properties": { + "box": { + "$ref": "#/components/schemas/BoxCoordinates", + "description": "The box's edges as fractions of image height and width, from 0 to 1. Each coordinate is the expected value of its edge's predicted position.", + "examples": [ + { + "bottom": 0.66, + "left": 0.19, + "right": 0.68, + "top": 0.2 + } + ] + }, + "confidence": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "description": "Confidence for the given box, from 0 to 1, with 1 being more confident. Null when the model does not provide confidence.", + "examples": [ + null, + 0.9 + ], + "title": "Confidence" + }, + "type": { + "const": "box", + "description": "Identifies a box answer.", + "examples": [ + "box" + ], + "title": "Type", + "type": "string" + } + }, + "required": [ + "type", + "box", + "confidence" + ], + "title": "BoxAnswer", + "type": "object" + }, + "BoxCoordinates": { + "description": "Normalized box edges. Vertical coordinates are measured from the top of the image; horizontal coordinates are measured from the left.", + "properties": { + "bottom": { + "description": "Bottom edge of the box, as a fraction of image height from the top (0-1).", + "examples": [ + 0.66 + ], + "title": "Bottom", + "type": "number" + }, + "left": { + "description": "Left edge of the box, as a fraction of image width from the left (0-1).", + "examples": [ + 0.19 + ], + "title": "Left", + "type": "number" + }, + "right": { + "description": "Right edge of the box, as a fraction of image width from the left (0-1).", + "examples": [ + 0.68 + ], + "title": "Right", + "type": "number" + }, + "top": { + "description": "Top edge of the box, as a fraction of image height from the top (0-1).", + "examples": [ + 0.2 + ], + "title": "Top", + "type": "number" + } + }, + "required": [ + "top", + "bottom", + "left", + "right" + ], + "title": "BoxCoordinates", + "type": "object" + }, + "BoxQuestion": { + "description": "A question that locates what its instructions describe in the request's image. Requests with box questions must send the header TypeSafe-Danger-Zone-Images: true.", + "properties": { + "instructions": { + "anyOf": [ + { + "type": "string" + }, + { + "additionalProperties": true, + "type": "object" + }, + { + "items": {}, + "type": "array" + }, + { + "type": "null" + } + ], + "description": "What to locate in the image.", + "title": "Instructions", + "x-accepts": "string | object | array" + }, + "type": { + "const": "box", + "description": "Identifies a box question.", + "title": "Type", + "type": "string" + } + }, + "required": [ + "type" + ], + "title": "BoxQuestion", + "type": "object" + }, "ChoiceAnswer": { "description": "The selected choice, confidence, and probabilities for a choice question.", "properties": { @@ -68,10 +240,10 @@ } }, "required": [ + "type", "choice", "confidence", - "probabilities", - "type" + "probabilities" ], "title": "ChoiceAnswer", "type": "object" @@ -96,7 +268,8 @@ { "type": "null" } - ] + ], + "x-accepts": "string | object | array" }, "description": "Choice names and descriptions of when each applies. A choice without a description is interpreted by its name alone.", "examples": [ @@ -106,6 +279,8 @@ "excited": "An enthusiastic or eager message" } ], + "maxProperties": 255, + "minProperties": 1, "title": "Criteria", "type": "object" }, @@ -130,7 +305,8 @@ "examples": [ "What is the tone of this message?" ], - "title": "Instructions" + "title": "Instructions", + "x-accepts": "string | object | array" }, "type": { "const": "choice", @@ -143,12 +319,35 @@ } }, "required": [ - "criteria", - "type" + "type", + "criteria" ], "title": "ChoiceQuestion", "type": "object" }, + "HTTPBadRequestError": { + "description": "Application validation failures returned with HTTP status 400.", + "properties": { + "detail": { + "anyOf": [ + { + "type": "string" + }, + { + "additionalProperties": true, + "type": "object" + } + ], + "description": "Explanation of the invalid request. String details and message fields are bounded, with shortened text ending with ….", + "title": "Detail" + } + }, + "required": [ + "detail" + ], + "title": "HTTPBadRequestError", + "type": "object" + }, "HTTPValidationError": { "description": "Request validation failures returned with HTTP status 422.", "properties": { @@ -261,8 +460,8 @@ } }, "required": [ - "noul", - "type" + "type", + "noul" ], "title": "NoulAnswer", "type": "object" @@ -291,7 +490,8 @@ "examples": [ "The message is a legitimate conversation." ], - "title": "False" + "title": "False", + "x-accepts": "string | object | array" }, "true": { "anyOf": [ @@ -314,7 +514,8 @@ "examples": [ "The message is unsolicited advertising." ], - "title": "True" + "title": "True", + "x-accepts": "string | object | array" } }, "title": "NoulCriteria", @@ -365,7 +566,8 @@ "task": "Identify unsolicited advertising." } ], - "title": "Instructions" + "title": "Instructions", + "x-accepts": "string | object | array" }, "type": { "const": "noul", @@ -387,6 +589,7 @@ "description": "A question about the supplied content.", "discriminator": { "mapping": { + "box": "#/components/schemas/BoxQuestion", "choice": "#/components/schemas/ChoiceQuestion", "noul": "#/components/schemas/NoulQuestion", "score": "#/components/schemas/ScoreQuestion" @@ -395,13 +598,20 @@ }, "oneOf": [ { - "$ref": "#/components/schemas/NoulQuestion" + "$ref": "#/components/schemas/NoulQuestion", + "title": "Noul" }, { - "$ref": "#/components/schemas/ChoiceQuestion" + "$ref": "#/components/schemas/ChoiceQuestion", + "title": "Choice" }, { - "$ref": "#/components/schemas/ScoreQuestion" + "$ref": "#/components/schemas/ScoreQuestion", + "title": "Score" + }, + { + "$ref": "#/components/schemas/BoxQuestion", + "title": "Box" } ] }, @@ -430,7 +640,8 @@ "items": {}, "type": "array" } - ] + ], + "x-accepts": "string | object | array" }, "description": "The requested criteria mapped to their score levels, so you can interpret the score.", "examples": [ @@ -477,11 +688,11 @@ } }, "required": [ + "type", "score", "confidence", "legend", - "probabilities", - "type" + "probabilities" ], "title": "ScoreAnswer", "type": "object" @@ -511,8 +722,10 @@ "items": {}, "type": "array" } - ] + ], + "x-accepts": "string | object | array" }, + "maxItems": 10, "minItems": 1, "title": "Criteria", "type": "array" @@ -538,7 +751,8 @@ "examples": [ "How urgent is this message?" ], - "title": "Instructions" + "title": "Instructions", + "x-accepts": "string | object | array" }, "type": { "const": "score", @@ -551,8 +765,8 @@ } }, "required": [ - "criteria", - "type" + "type", + "criteria" ], "title": "ScoreQuestion", "type": "object" @@ -560,6 +774,15 @@ "SystemOneRequest": { "description": "Content and named questions to evaluate together using a TypeSafe model.", "properties": { + "assets": { + "additionalProperties": { + "$ref": "#/components/schemas/Asset" + }, + "description": "Media assets keyed by an opaque placeholder (recommend a per-image UUID). Each placeholder, wherever it appears as or inside a string in state, question instructions, or criteria, is replaced with the asset. Image assets require a vision-language model.", + "minProperties": 1, + "title": "Assets", + "type": "object" + }, "model": { "description": "Name or alias of the model to use. Available names are returned by GET /v1/models.", "examples": [ @@ -607,13 +830,14 @@ "subject": "Duplicate charge" } ], - "title": "State" + "title": "State", + "x-accepts": "string | object | array" } }, "required": [ "model", - "questions", - "state" + "state", + "questions" ], "title": "SystemOneRequest", "type": "object" @@ -696,7 +920,7 @@ "description": "A request validation error at a specific field or array element.", "properties": { "ctx": { - "description": "Additional context used to explain the validation failure.", + "description": "Additional context used to explain the validation failure. Entries may be omitted or shortened.", "examples": [ { "min_length": 1 @@ -706,16 +930,15 @@ "type": "object" }, "input": { - "description": "The input value that failed validation.", + "description": "Text preview of the rejected input. May be shortened with ….", "examples": [ - { - "type": "score" - } + "{\"type\":\"score\"}" ], - "title": "Input" + "title": "Input", + "type": "string" }, "loc": { - "description": "Path to the invalid value: the request location followed by field names and array indices.", + "description": "Path to the invalid value: the request location followed by field names and array indices. May be empty.", "examples": [ [ "body", @@ -739,7 +962,7 @@ "type": "array" }, "msg": { - "description": "Human-readable explanation of the validation failure.", + "description": "Human-readable explanation of the validation failure. May be shortened with ….", "examples": [ "Field required" ], @@ -793,6 +1016,16 @@ }, "description": "Successful Response" }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPBadRequestError" + } + } + }, + "description": "Bad Request" + }, "422": { "content": { "application/json": { @@ -809,19 +1042,144 @@ "HTTPBearer": [] } ], - "summary": "Models V1" + "summary": "List models" } }, "/v1/systemone": { "post": { "description": "Answer one or more questions about the content supplied in `state`.\n\nYou can mix question types in one request. Answers use the same names as the\nquestions, so you can match each result to its question. The response also includes\nthe model used and token usage.", "operationId": "systemone_v1_systemone_post", + "parameters": [ + { + "description": "Set to true to use assets or box questions.", + "example": "true", + "in": "header", + "name": "TypeSafe-Danger-Zone-Images", + "schema": { + "enum": [ + "true" + ], + "type": "string" + } + }, + { + "description": "Set to true to use long context.", + "example": "true", + "in": "header", + "name": "TypeSafe-Danger-Zone-Long-Context", + "schema": { + "enum": [ + "true" + ], + "type": "string" + } + } + ], "requestBody": { "content": { "application/json": { + "examples": { + "box": { + "summary": "Box (requires TypeSafe-Danger-Zone-Images: true)", + "value": { + "assets": { + "photo": { + "data_base64": "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAHElEQVR4nGP4TyJgoKcGBgbsaFQDfTUQB4aDBgDAen2fpitsVAAAAABJRU5ErkJggg==", + "format": "png", + "type": "image" + } + }, + "model": "jev-preview", + "questions": { + "red_rectangle": { + "instructions": "Locate the red rectangle.", + "type": "box" + } + }, + "state": "photo" + } + }, + "choice": { + "summary": "Choice", + "value": { + "model": "jev-latest", + "questions": { + "tone": { + "criteria": { + "angry": "An upset or hostile message", + "calm": "A neutral or polite message", + "excited": "An enthusiastic or eager message" + }, + "instructions": "What is the tone of this message?", + "type": "choice" + } + }, + "state": "I was charged twice for my subscription this month. Please refund the extra charge." + } + }, + "noul": { + "summary": "Noul", + "value": { + "model": "jev-latest", + "questions": { + "billing": { + "instructions": "Is this message about billing?", + "type": "noul" + } + }, + "state": "I was charged twice for my subscription this month. Please refund the extra charge." + } + }, + "score": { + "summary": "Score", + "value": { + "model": "jev-latest", + "questions": { + "urgency": { + "criteria": [ + "Can wait", + "Needs attention this week", + "Needs attention today" + ], + "instructions": "How urgent is this message?", + "type": "score" + } + }, + "state": "I was charged twice for my subscription this month. Please refund the extra charge." + } + } + }, "schema": { "$ref": "#/components/schemas/SystemOneRequest" } + }, + "multipart/form-data": { + "encoding": { + "request": { + "contentType": "application/json" + } + }, + "schema": { + "additionalProperties": { + "contentMediaType": "image/*", + "description": "An image, named by the asset part that uses it.", + "type": "string" + }, + "description": "The JSON request as the first part, named request, then each image as its own part. Every image part needs a unique, non-empty name and must be used by exactly one asset's part.", + "properties": { + "request": { + "contentMediaType": "application/json", + "contentSchema": { + "$ref": "#/components/schemas/SystemOneRequest" + }, + "description": "The JSON request, as the first part." + } + }, + "required": [ + "request" + ], + "type": "object" + } } }, "required": true @@ -830,6 +1188,95 @@ "200": { "content": { "application/json": { + "examples": { + "box": { + "summary": "Box", + "value": { + "answers": { + "red_rectangle": { + "box": { + "bottom": 0.66, + "left": 0.19, + "right": 0.68, + "top": 0.2 + }, + "confidence": null, + "type": "box" + } + }, + "model": "jev-preview", + "usage": { + "input_tokens": 285, + "output_tokens": 20 + } + } + }, + "choice": { + "summary": "Choice", + "value": { + "answers": { + "tone": { + "choice": "calm", + "confidence": 0.7, + "probabilities": { + "angry": 0.15, + "calm": 0.8, + "excited": 0.05 + }, + "type": "choice" + } + }, + "model": "jev-latest", + "usage": { + "input_tokens": 120, + "output_tokens": 12 + } + } + }, + "noul": { + "summary": "Noul", + "value": { + "answers": { + "billing": { + "noul": 0.98, + "type": "noul" + } + }, + "model": "jev-latest", + "usage": { + "input_tokens": 120, + "output_tokens": 12 + } + } + }, + "score": { + "summary": "Score", + "value": { + "answers": { + "urgency": { + "confidence": 0.55, + "legend": { + "0": "Can wait", + "1": "Needs attention this week", + "2": "Needs attention today" + }, + "probabilities": { + "0": 0.1, + "1": 0.1, + "2": 0.8 + }, + "score": 1.7, + "type": "score" + } + }, + "model": "jev-latest", + "usage": { + "input_tokens": 120, + "output_tokens": 12 + } + } + } + }, "schema": { "$ref": "#/components/schemas/SystemOneResponse" } @@ -837,6 +1284,16 @@ }, "description": "Successful Response" }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPBadRequestError" + } + } + }, + "description": "Bad Request" + }, "422": { "content": { "application/json": { @@ -853,8 +1310,13 @@ "HTTPBearer": [] } ], - "summary": "Systemone" + "summary": "System One" } } - } + }, + "servers": [ + { + "url": "https://api.typesafe.ai" + } + ] }