{
  "components": {
    "schemas": {
      "AgendaItem": {
        "description": "Одна строка ленты: событие календаря ИЛИ поручение со сроком.\n\n``kind`` — дискриминатор. Он появился раньше самого наложения намеренно: клиенты писались\nпротив него, и добавление второй ветки стало ровно тем аддитивным изменением, которым и\nзадумывалось.",
        "properties": {
          "all_day": {
            "default": false,
            "title": "All Day",
            "type": "boolean"
          },
          "conflict": {
            "default": false,
            "title": "Conflict",
            "type": "boolean"
          },
          "day": {
            "title": "Day",
            "type": "string"
          },
          "day_label": {
            "default": "",
            "title": "Day Label",
            "type": "string"
          },
          "ends_at": {
            "format": "date-time",
            "title": "Ends At",
            "type": "string"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "kind": {
            "default": "event",
            "title": "Kind",
            "type": "string"
          },
          "location": {
            "default": "",
            "title": "Location",
            "type": "string"
          },
          "number": {
            "title": "Number",
            "type": "integer"
          },
          "occurrence_at": {
            "format": "date-time",
            "title": "Occurrence At",
            "type": "string"
          },
          "past": {
            "default": false,
            "title": "Past",
            "type": "boolean"
          },
          "recurrence_label": {
            "default": "",
            "title": "Recurrence Label",
            "type": "string"
          },
          "recurring": {
            "default": false,
            "title": "Recurring",
            "type": "boolean"
          },
          "reminders": {
            "items": {
              "type": "integer"
            },
            "title": "Reminders",
            "type": "array"
          },
          "starts_at": {
            "format": "date-time",
            "title": "Starts At",
            "type": "string"
          },
          "task": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/AgendaTask"
              },
              {
                "type": "null"
              }
            ]
          },
          "title": {
            "title": "Title",
            "type": "string"
          },
          "weekday": {
            "title": "Weekday",
            "type": "string"
          }
        },
        "required": [
          "id",
          "number",
          "title",
          "starts_at",
          "ends_at",
          "occurrence_at",
          "day",
          "weekday"
        ],
        "title": "AgendaItem",
        "type": "object"
      },
      "AgendaOut": {
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/AgendaItem"
            },
            "title": "Items",
            "type": "array"
          },
          "reminder_note": {
            "default": "",
            "title": "Reminder Note",
            "type": "string"
          },
          "since": {
            "format": "date-time",
            "title": "Since",
            "type": "string"
          },
          "today": {
            "default": 0,
            "title": "Today",
            "type": "integer"
          },
          "truncated": {
            "default": false,
            "title": "Truncated",
            "type": "boolean"
          },
          "tz": {
            "title": "Tz",
            "type": "string"
          },
          "until": {
            "format": "date-time",
            "title": "Until",
            "type": "string"
          },
          "upcoming": {
            "default": 0,
            "title": "Upcoming",
            "type": "integer"
          }
        },
        "required": [
          "items",
          "since",
          "until",
          "tz"
        ],
        "title": "AgendaOut",
        "type": "object"
      },
      "AgendaTask": {
        "description": "Поручение, наложенное на ленту. Вложено ЦЕЛИКОМ, а не размазано по полям события.\n\nТак клиент переиспользует свою готовую строку поручения дословно, а не собирает третью\nеё версию из чужих полей — и «закрыть» из ленты бьёт в тот же ``PATCH /v1/tasks/{id}``.",
        "properties": {
          "assignee": {
            "default": "",
            "title": "Assignee",
            "type": "string"
          },
          "due_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Due At"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "number": {
            "title": "Number",
            "type": "integer"
          },
          "overdue": {
            "default": false,
            "title": "Overdue",
            "type": "boolean"
          },
          "status": {
            "default": "open",
            "title": "Status",
            "type": "string"
          },
          "title": {
            "title": "Title",
            "type": "string"
          }
        },
        "required": [
          "id",
          "number",
          "title"
        ],
        "title": "AgendaTask",
        "type": "object"
      },
      "AgentActivateOut": {
        "properties": {
          "active": {
            "title": "Active",
            "type": "string"
          },
          "name": {
            "title": "Name",
            "type": "string"
          }
        },
        "required": [
          "active",
          "name"
        ],
        "title": "AgentActivateOut",
        "type": "object"
      },
      "AgentCatalogOut": {
        "properties": {
          "active": {
            "title": "Active",
            "type": "string"
          },
          "can_create_custom": {
            "default": true,
            "title": "Can Create Custom",
            "type": "boolean"
          },
          "custom_limit": {
            "default": 0,
            "title": "Custom Limit",
            "type": "integer"
          },
          "icons": {
            "items": {
              "type": "string"
            },
            "title": "Icons",
            "type": "array"
          },
          "items": {
            "items": {
              "$ref": "#/components/schemas/AgentProfileOut"
            },
            "title": "Items",
            "type": "array"
          },
          "presets": {
            "items": {
              "$ref": "#/components/schemas/PresetOut"
            },
            "title": "Presets",
            "type": "array"
          },
          "toolsets": {
            "items": {
              "$ref": "#/components/schemas/ToolsetOut"
            },
            "title": "Toolsets",
            "type": "array"
          }
        },
        "required": [
          "items",
          "active"
        ],
        "title": "AgentCatalogOut",
        "type": "object"
      },
      "AgentChatRequest": {
        "additionalProperties": false,
        "properties": {
          "agent_slug": {
            "anyOf": [
              {
                "maxLength": 64,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Agent Slug"
          },
          "attachment_ids": {
            "items": {
              "format": "uuid",
              "type": "string"
            },
            "maxItems": 5,
            "title": "Attachment Ids",
            "type": "array"
          },
          "channel_chat_id": {
            "default": 0,
            "title": "Channel Chat Id",
            "type": "integer"
          },
          "channel_members": {
            "items": {
              "$ref": "#/components/schemas/ChannelMemberIn"
            },
            "maxItems": 200,
            "title": "Channel Members",
            "type": "array"
          },
          "channel_user_id": {
            "default": 0,
            "title": "Channel User Id",
            "type": "integer"
          },
          "collection_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Collection Id"
          },
          "history": {
            "items": {
              "$ref": "#/components/schemas/AskTurnIn"
            },
            "maxItems": 50,
            "title": "History",
            "type": "array"
          },
          "include_subfolders": {
            "default": true,
            "title": "Include Subfolders",
            "type": "boolean"
          },
          "inline_attachments": {
            "items": {
              "$ref": "#/components/schemas/InlineAttachmentIn"
            },
            "maxItems": 5,
            "title": "Inline Attachments",
            "type": "array"
          },
          "query": {
            "maxLength": 8000,
            "minLength": 1,
            "title": "Query",
            "type": "string"
          },
          "scope_object_ids": {
            "items": {
              "format": "uuid",
              "type": "string"
            },
            "maxItems": 25,
            "title": "Scope Object Ids",
            "type": "array"
          },
          "session_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Session Id"
          },
          "web_search": {
            "default": true,
            "title": "Web Search",
            "type": "boolean"
          }
        },
        "required": [
          "query"
        ],
        "title": "AgentChatRequest",
        "type": "object"
      },
      "AgentContinueRequest": {
        "additionalProperties": false,
        "properties": {
          "agent_slug": {
            "anyOf": [
              {
                "maxLength": 64,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Agent Slug"
          },
          "decisions": {
            "items": {
              "$ref": "#/components/schemas/AgentDecision"
            },
            "minItems": 1,
            "title": "Decisions",
            "type": "array"
          },
          "run_id": {
            "title": "Run Id",
            "type": "string"
          },
          "session_id": {
            "title": "Session Id",
            "type": "string"
          },
          "web_search": {
            "default": true,
            "title": "Web Search",
            "type": "boolean"
          }
        },
        "required": [
          "run_id",
          "session_id",
          "decisions"
        ],
        "title": "AgentContinueRequest",
        "type": "object"
      },
      "AgentDecision": {
        "properties": {
          "confirmed": {
            "title": "Confirmed",
            "type": "boolean"
          },
          "tool_call_id": {
            "title": "Tool Call Id",
            "type": "string"
          }
        },
        "required": [
          "tool_call_id",
          "confirmed"
        ],
        "title": "AgentDecision",
        "type": "object"
      },
      "AgentProfileIn": {
        "description": "Своя роль на создание. Слаг задаётся один раз и потом не меняется.",
        "properties": {
          "description": {
            "default": "",
            "maxLength": 200,
            "title": "Description",
            "type": "string"
          },
          "icon": {
            "default": "sparkles",
            "title": "Icon",
            "type": "string"
          },
          "name": {
            "maxLength": 60,
            "minLength": 1,
            "title": "Name",
            "type": "string"
          },
          "persona": {
            "maxLength": 4000,
            "minLength": 1,
            "title": "Persona",
            "type": "string"
          },
          "slug": {
            "maxLength": 40,
            "minLength": 2,
            "title": "Slug",
            "type": "string"
          },
          "toolsets": {
            "items": {
              "type": "string"
            },
            "title": "Toolsets",
            "type": "array"
          }
        },
        "required": [
          "slug",
          "name",
          "persona"
        ],
        "title": "AgentProfileIn",
        "type": "object"
      },
      "AgentProfileOut": {
        "description": "Карточка роли для экрана «Главная».",
        "properties": {
          "description": {
            "title": "Description",
            "type": "string"
          },
          "icon": {
            "title": "Icon",
            "type": "string"
          },
          "is_active": {
            "title": "Is Active",
            "type": "boolean"
          },
          "locked": {
            "default": false,
            "title": "Locked",
            "type": "boolean"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "persona": {
            "default": "",
            "title": "Persona",
            "type": "string"
          },
          "plan_min": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Plan Min"
          },
          "slug": {
            "title": "Slug",
            "type": "string"
          },
          "source": {
            "title": "Source",
            "type": "string"
          },
          "toolsets": {
            "items": {
              "type": "string"
            },
            "title": "Toolsets",
            "type": "array"
          }
        },
        "required": [
          "slug",
          "name",
          "description",
          "icon",
          "source",
          "is_active"
        ],
        "title": "AgentProfileOut",
        "type": "object"
      },
      "AgentProfileUpdateIn": {
        "description": "Правка своей роли. ``None`` — поле не трогаем (частичное обновление).",
        "properties": {
          "description": {
            "anyOf": [
              {
                "maxLength": 200,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "icon": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Icon"
          },
          "name": {
            "anyOf": [
              {
                "maxLength": 60,
                "minLength": 1,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name"
          },
          "persona": {
            "anyOf": [
              {
                "maxLength": 4000,
                "minLength": 1,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Persona"
          },
          "toolsets": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Toolsets"
          }
        },
        "title": "AgentProfileUpdateIn",
        "type": "object"
      },
      "AgentStatus": {
        "properties": {
          "enabled": {
            "title": "Enabled",
            "type": "boolean"
          },
          "memory": {
            "title": "Memory",
            "type": "boolean"
          },
          "model": {
            "default": "",
            "title": "Model",
            "type": "string"
          }
        },
        "required": [
          "enabled",
          "memory"
        ],
        "title": "AgentStatus",
        "type": "object"
      },
      "AgentTaskStatus": {
        "description": "Ответ ``GET /agent/task/{task_id}`` в форме события ``task_done`` из SSE-контракта:\nклиент кладёт его в тот же обработчик, что и кадр из стрима.\n\n``done`` — единственное поле сверх контракта, и оно обязательно: без него «ещё выполняется»\nи «выполнилось с ошибкой» неотличимы (оба ok=false), и клиент либо покажет ошибку раньше\nвремени, либо будет опрашивать вечно.",
        "properties": {
          "done": {
            "default": false,
            "title": "Done",
            "type": "boolean"
          },
          "filename": {
            "default": "",
            "title": "Filename",
            "type": "string"
          },
          "note": {
            "default": "",
            "title": "Note",
            "type": "string"
          },
          "object_id": {
            "default": "",
            "title": "Object Id",
            "type": "string"
          },
          "ok": {
            "default": false,
            "title": "Ok",
            "type": "boolean"
          },
          "stage": {
            "default": "",
            "title": "Stage",
            "type": "string"
          },
          "step": {
            "default": 0,
            "title": "Step",
            "type": "integer"
          },
          "steps": {
            "default": 0,
            "title": "Steps",
            "type": "integer"
          },
          "task_id": {
            "title": "Task Id",
            "type": "string"
          },
          "type": {
            "default": "task_done",
            "title": "Type",
            "type": "string"
          }
        },
        "required": [
          "task_id"
        ],
        "title": "AgentTaskStatus",
        "type": "object"
      },
      "ArchiveAccepted": {
        "description": "Распаковка zip принята: ``created`` файлов заведены отдельными объектами (Celery).",
        "properties": {
          "created": {
            "default": 0,
            "title": "Created",
            "type": "integer"
          },
          "duplicates": {
            "default": 0,
            "title": "Duplicates",
            "type": "integer"
          },
          "status": {
            "default": "accepted",
            "title": "Status",
            "type": "string"
          }
        },
        "title": "ArchiveAccepted",
        "type": "object"
      },
      "AskCitation": {
        "properties": {
          "char_end": {
            "default": 0,
            "title": "Char End",
            "type": "integer"
          },
          "char_start": {
            "default": 0,
            "title": "Char Start",
            "type": "integer"
          },
          "doc_type": {
            "default": "",
            "title": "Doc Type",
            "type": "string"
          },
          "filename": {
            "default": "",
            "title": "Filename",
            "type": "string"
          },
          "index": {
            "default": 0,
            "title": "Index",
            "type": "integer"
          },
          "object_id": {
            "format": "uuid",
            "title": "Object Id",
            "type": "string"
          },
          "ord": {
            "title": "Ord",
            "type": "integer"
          },
          "snippet": {
            "default": "",
            "title": "Snippet",
            "type": "string"
          },
          "title": {
            "default": "",
            "title": "Title",
            "type": "string"
          }
        },
        "required": [
          "object_id",
          "ord"
        ],
        "title": "AskCitation",
        "type": "object"
      },
      "AskRequest": {
        "properties": {
          "doc_type": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Doc Type"
          },
          "history": {
            "items": {
              "$ref": "#/components/schemas/AskTurnIn"
            },
            "title": "History",
            "type": "array"
          },
          "include_hidden": {
            "default": false,
            "title": "Include Hidden",
            "type": "boolean"
          },
          "model": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Model"
          },
          "object_ids": {
            "anyOf": [
              {
                "items": {
                  "format": "uuid",
                  "type": "string"
                },
                "maxItems": 100,
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Object Ids"
          },
          "query": {
            "maxLength": 2000,
            "minLength": 1,
            "title": "Query",
            "type": "string"
          },
          "session_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Session Id"
          },
          "top_k": {
            "anyOf": [
              {
                "maximum": 50.0,
                "minimum": 1.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Top K"
          },
          "use_memory": {
            "default": true,
            "title": "Use Memory",
            "type": "boolean"
          },
          "web_search": {
            "default": true,
            "title": "Web Search",
            "type": "boolean"
          }
        },
        "required": [
          "query"
        ],
        "title": "AskRequest",
        "type": "object"
      },
      "AskResponse": {
        "properties": {
          "answer": {
            "title": "Answer",
            "type": "string"
          },
          "citations": {
            "items": {
              "$ref": "#/components/schemas/AskCitation"
            },
            "title": "Citations",
            "type": "array"
          },
          "cost_rub": {
            "default": 0.0,
            "title": "Cost Rub",
            "type": "number"
          },
          "primary": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/AskCitation"
              },
              {
                "type": "null"
              }
            ]
          },
          "session_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Session Id"
          },
          "used_context": {
            "default": false,
            "title": "Used Context",
            "type": "boolean"
          }
        },
        "required": [
          "answer"
        ],
        "title": "AskResponse",
        "type": "object"
      },
      "AskTurnIn": {
        "properties": {
          "content": {
            "title": "Content",
            "type": "string"
          },
          "role": {
            "title": "Role",
            "type": "string"
          }
        },
        "required": [
          "role",
          "content"
        ],
        "title": "AskTurnIn",
        "type": "object"
      },
      "AssembleAccepted": {
        "description": "Сборка принята: результат появится НОВЫМ объектом-PDF в списке (Celery).",
        "properties": {
          "count": {
            "default": 0,
            "title": "Count",
            "type": "integer"
          },
          "status": {
            "default": "accepted",
            "title": "Status",
            "type": "string"
          }
        },
        "title": "AssembleAccepted",
        "type": "object"
      },
      "AssembleRequest": {
        "description": "Сборка выбранных объектов в один PDF. ``sort``: ``date`` (по created_at) или\n``order`` (порядок переданного списка).",
        "properties": {
          "name": {
            "anyOf": [
              {
                "maxLength": 255,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name"
          },
          "object_ids": {
            "items": {
              "format": "uuid",
              "type": "string"
            },
            "maxItems": 200,
            "minItems": 1,
            "title": "Object Ids",
            "type": "array"
          },
          "sort": {
            "default": "date",
            "enum": [
              "date",
              "order"
            ],
            "title": "Sort",
            "type": "string"
          }
        },
        "required": [
          "object_ids"
        ],
        "title": "AssembleRequest",
        "type": "object"
      },
      "Body_extract_attachment_v1_chat_attachment_post": {
        "properties": {
          "file": {
            "contentMediaType": "application/octet-stream",
            "title": "File",
            "type": "string"
          }
        },
        "required": [
          "file"
        ],
        "title": "Body_extract_attachment_v1_chat_attachment_post",
        "type": "object"
      },
      "Body_import_ics_v1_calendar_feeds_import_post": {
        "properties": {
          "file": {
            "contentMediaType": "application/octet-stream",
            "title": "File",
            "type": "string"
          }
        },
        "required": [
          "file"
        ],
        "title": "Body_import_ics_v1_calendar_feeds_import_post",
        "type": "object"
      },
      "Body_share_upload_v1_share__token__upload_post": {
        "properties": {
          "file": {
            "anyOf": [
              {
                "contentMediaType": "application/octet-stream",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "File"
          }
        },
        "title": "Body_share_upload_v1_share__token__upload_post",
        "type": "object"
      },
      "Body_transcribe_v1_transcribe_post": {
        "properties": {
          "file": {
            "anyOf": [
              {
                "contentMediaType": "application/octet-stream",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "File"
          }
        },
        "title": "Body_transcribe_v1_transcribe_post",
        "type": "object"
      },
      "Body_upload_archive_v1_objects_archive_post": {
        "properties": {
          "file": {
            "anyOf": [
              {
                "contentMediaType": "application/octet-stream",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "File"
          }
        },
        "title": "Body_upload_archive_v1_objects_archive_post",
        "type": "object"
      },
      "Body_upload_v1_objects_post": {
        "properties": {
          "file": {
            "anyOf": [
              {
                "contentMediaType": "application/octet-stream",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "File"
          }
        },
        "title": "Body_upload_v1_objects_post",
        "type": "object"
      },
      "BotChatDetailOut": {
        "properties": {
          "chat_id": {
            "title": "Chat Id",
            "type": "integer"
          },
          "collection_id": {
            "default": "",
            "title": "Collection Id",
            "type": "string"
          },
          "description": {
            "default": "",
            "title": "Description",
            "type": "string"
          },
          "known_count": {
            "default": 0,
            "title": "Known Count",
            "type": "integer"
          },
          "last_seen_at": {
            "default": "",
            "title": "Last Seen At",
            "type": "string"
          },
          "member_count": {
            "default": 0,
            "title": "Member Count",
            "type": "integer"
          },
          "members": {
            "items": {
              "$ref": "#/components/schemas/BotChatMemberOut"
            },
            "title": "Members",
            "type": "array"
          },
          "note_object_id": {
            "default": "",
            "title": "Note Object Id",
            "type": "string"
          },
          "proactive_allowed": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Proactive Allowed"
          },
          "synced_at": {
            "default": "",
            "title": "Synced At",
            "type": "string"
          },
          "title": {
            "title": "Title",
            "type": "string"
          }
        },
        "required": [
          "chat_id",
          "title"
        ],
        "title": "BotChatDetailOut",
        "type": "object"
      },
      "BotChatListOut": {
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/BotChatOut"
            },
            "title": "Items",
            "type": "array"
          }
        },
        "title": "BotChatListOut",
        "type": "object"
      },
      "BotChatMemberOut": {
        "description": "Человек из группы. ``source`` не косметика: у админа может не быть ни одной реплики,\nи пустое ``last_seen_at`` у него означает «мы его не слышали», а не «давно не заходил».",
        "properties": {
          "display_name": {
            "default": "",
            "title": "Display Name",
            "type": "string"
          },
          "is_admin": {
            "default": false,
            "title": "Is Admin",
            "type": "boolean"
          },
          "last_seen_at": {
            "default": "",
            "title": "Last Seen At",
            "type": "string"
          },
          "role": {
            "default": "",
            "title": "Role",
            "type": "string"
          },
          "source": {
            "default": "spoke",
            "title": "Source",
            "type": "string"
          },
          "tg_user_id": {
            "title": "Tg User Id",
            "type": "integer"
          },
          "username": {
            "default": "",
            "title": "Username",
            "type": "string"
          }
        },
        "required": [
          "tg_user_id"
        ],
        "title": "BotChatMemberOut",
        "type": "object"
      },
      "BotChatMemberUpdateIn": {
        "description": "Чем человек занимается. Пустая строка — снять роль: убрать неверную пометку так же\nнужно, как поставить верную.",
        "properties": {
          "role": {
            "default": "",
            "maxLength": 200,
            "title": "Role",
            "type": "string"
          }
        },
        "title": "BotChatMemberUpdateIn",
        "type": "object"
      },
      "BotChatOut": {
        "description": "Карточка группы для экрана владельца.\n\n``member_count`` и ``known_count`` идут ПАРОЙ намеренно. Состав группы Telegram боту не\nотдаёт (есть только getChatAdministrators и getChatMember по уже известному id), поэтому\nреестр неполон всегда. Одно ``known_count`` выдало бы четверых известных за всю группу —\nинтерфейс обязан показывать «знаем 4 из 12», а не «4 участника».",
        "properties": {
          "chat_id": {
            "title": "Chat Id",
            "type": "integer"
          },
          "collection_id": {
            "default": "",
            "title": "Collection Id",
            "type": "string"
          },
          "description": {
            "default": "",
            "title": "Description",
            "type": "string"
          },
          "known_count": {
            "default": 0,
            "title": "Known Count",
            "type": "integer"
          },
          "last_seen_at": {
            "default": "",
            "title": "Last Seen At",
            "type": "string"
          },
          "member_count": {
            "default": 0,
            "title": "Member Count",
            "type": "integer"
          },
          "note_object_id": {
            "default": "",
            "title": "Note Object Id",
            "type": "string"
          },
          "proactive_allowed": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Proactive Allowed"
          },
          "synced_at": {
            "default": "",
            "title": "Synced At",
            "type": "string"
          },
          "title": {
            "title": "Title",
            "type": "string"
          }
        },
        "required": [
          "chat_id",
          "title"
        ],
        "title": "BotChatOut",
        "type": "object"
      },
      "BotChatUpdateIn": {
        "description": "Правка карточки группы владельцем. Все поля необязательные — присланные меняются.",
        "properties": {
          "proactive_allowed": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Proactive Allowed"
          }
        },
        "title": "BotChatUpdateIn",
        "type": "object"
      },
      "BotCreateIn": {
        "description": "Создание бота: токен @BotFather + выбранный пресет.",
        "properties": {
          "agent_slug": {
            "default": "assistant",
            "maxLength": 64,
            "title": "Agent Slug",
            "type": "string"
          },
          "title": {
            "default": "",
            "maxLength": 120,
            "title": "Title",
            "type": "string"
          },
          "token": {
            "maxLength": 200,
            "minLength": 20,
            "title": "Token",
            "type": "string"
          }
        },
        "required": [
          "token"
        ],
        "title": "BotCreateIn",
        "type": "object"
      },
      "BotCreatedOut": {
        "description": "Ответ на создание: карточка + подсказка, если вебхук не зарегистрировался.",
        "properties": {
          "agent_slug": {
            "title": "Agent Slug",
            "type": "string"
          },
          "allowlist_count": {
            "default": 0,
            "title": "Allowlist Count",
            "type": "integer"
          },
          "can_read_all_messages": {
            "default": false,
            "title": "Can Read All Messages",
            "type": "boolean"
          },
          "created_at": {
            "default": "",
            "title": "Created At",
            "type": "string"
          },
          "deep_link": {
            "default": "",
            "title": "Deep Link",
            "type": "string"
          },
          "enabled": {
            "title": "Enabled",
            "type": "boolean"
          },
          "id": {
            "title": "Id",
            "type": "string"
          },
          "owner_bound": {
            "title": "Owner Bound",
            "type": "boolean"
          },
          "provider": {
            "title": "Provider",
            "type": "string"
          },
          "title": {
            "title": "Title",
            "type": "string"
          },
          "username": {
            "title": "Username",
            "type": "string"
          },
          "webhook_note": {
            "default": "",
            "title": "Webhook Note",
            "type": "string"
          },
          "webhook_set": {
            "title": "Webhook Set",
            "type": "boolean"
          }
        },
        "required": [
          "id",
          "provider",
          "username",
          "title",
          "agent_slug",
          "enabled",
          "webhook_set",
          "owner_bound"
        ],
        "title": "BotCreatedOut",
        "type": "object"
      },
      "BotListOut": {
        "properties": {
          "can_create": {
            "default": true,
            "title": "Can Create",
            "type": "boolean"
          },
          "items": {
            "items": {
              "$ref": "#/components/schemas/BotOut"
            },
            "title": "Items",
            "type": "array"
          },
          "limit": {
            "default": 0,
            "title": "Limit",
            "type": "integer"
          }
        },
        "title": "BotListOut",
        "type": "object"
      },
      "BotOut": {
        "description": "Карточка бота для экрана «Боты» и мастера.",
        "properties": {
          "agent_slug": {
            "title": "Agent Slug",
            "type": "string"
          },
          "allowlist_count": {
            "default": 0,
            "title": "Allowlist Count",
            "type": "integer"
          },
          "can_read_all_messages": {
            "default": false,
            "title": "Can Read All Messages",
            "type": "boolean"
          },
          "created_at": {
            "default": "",
            "title": "Created At",
            "type": "string"
          },
          "deep_link": {
            "default": "",
            "title": "Deep Link",
            "type": "string"
          },
          "enabled": {
            "title": "Enabled",
            "type": "boolean"
          },
          "id": {
            "title": "Id",
            "type": "string"
          },
          "owner_bound": {
            "title": "Owner Bound",
            "type": "boolean"
          },
          "provider": {
            "title": "Provider",
            "type": "string"
          },
          "title": {
            "title": "Title",
            "type": "string"
          },
          "username": {
            "title": "Username",
            "type": "string"
          },
          "webhook_set": {
            "title": "Webhook Set",
            "type": "boolean"
          }
        },
        "required": [
          "id",
          "provider",
          "username",
          "title",
          "agent_slug",
          "enabled",
          "webhook_set",
          "owner_bound"
        ],
        "title": "BotOut",
        "type": "object"
      },
      "BotSubscriberListOut": {
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/BotSubscriberOut"
            },
            "title": "Items",
            "type": "array"
          }
        },
        "title": "BotSubscriberListOut",
        "type": "object"
      },
      "BotSubscriberOut": {
        "description": "Исполнитель, открывший личку с ботом, — то есть тот, до кого уведомление доедет.\n\n``blocked`` показывать ОБЯЗАТЕЛЬНО. Без него владелец видит человека в списке и считает,\nчто поручения к нему уходят; на деле Telegram отвечает 403, и «поручил и забыл»\nпревращается в «поручил в пустоту». Это единственное состояние экрана, о котором нельзя\nпромолчать.",
        "properties": {
          "blocked": {
            "default": false,
            "title": "Blocked",
            "type": "boolean"
          },
          "display_name": {
            "default": "",
            "title": "Display Name",
            "type": "string"
          },
          "source": {
            "default": "member",
            "title": "Source",
            "type": "string"
          },
          "subscribed_at": {
            "default": "",
            "title": "Subscribed At",
            "type": "string"
          },
          "tg_user_id": {
            "title": "Tg User Id",
            "type": "integer"
          },
          "username": {
            "default": "",
            "title": "Username",
            "type": "string"
          }
        },
        "required": [
          "tg_user_id"
        ],
        "title": "BotSubscriberOut",
        "type": "object"
      },
      "BotUpdateIn": {
        "description": "Правка бота. ``None`` — поле не трогаем (частичное обновление).",
        "properties": {
          "agent_slug": {
            "anyOf": [
              {
                "maxLength": 64,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Agent Slug"
          },
          "allowlist": {
            "anyOf": [
              {
                "items": {
                  "type": "integer"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Allowlist"
          },
          "enabled": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Enabled"
          },
          "title": {
            "anyOf": [
              {
                "maxLength": 120,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Title"
          }
        },
        "title": "BotUpdateIn",
        "type": "object"
      },
      "ChannelMemberIn": {
        "description": "Один участник канала: адрес плюс то, как его зовут и окликают.",
        "properties": {
          "display_name": {
            "default": "",
            "maxLength": 200,
            "title": "Display Name",
            "type": "string"
          },
          "role": {
            "default": "",
            "maxLength": 200,
            "title": "Role",
            "type": "string"
          },
          "user_id": {
            "title": "User Id",
            "type": "integer"
          },
          "username": {
            "default": "",
            "maxLength": 64,
            "title": "Username",
            "type": "string"
          }
        },
        "required": [
          "user_id"
        ],
        "title": "ChannelMemberIn",
        "type": "object"
      },
      "ChatAttachmentOut": {
        "description": "Файл, приложенный пользователем к сообщению. ``filename`` — снимок на момент вопроса:\nфайл могли переименовать или удалить, а показать нужно то, с чем шёл разговор.",
        "properties": {
          "filename": {
            "default": "",
            "title": "Filename",
            "type": "string"
          },
          "object_id": {
            "format": "uuid",
            "title": "Object Id",
            "type": "string"
          }
        },
        "required": [
          "object_id"
        ],
        "title": "ChatAttachmentOut",
        "type": "object"
      },
      "ChatDetail": {
        "properties": {
          "collection_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Collection Id"
          },
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "kind": {
            "default": "ask",
            "title": "Kind",
            "type": "string"
          },
          "messages": {
            "items": {
              "$ref": "#/components/schemas/ChatMessageOut"
            },
            "title": "Messages",
            "type": "array"
          },
          "pinned": {
            "default": false,
            "title": "Pinned",
            "type": "boolean"
          },
          "title": {
            "title": "Title",
            "type": "string"
          },
          "updated_at": {
            "format": "date-time",
            "title": "Updated At",
            "type": "string"
          }
        },
        "required": [
          "id",
          "title",
          "created_at",
          "updated_at"
        ],
        "title": "ChatDetail",
        "type": "object"
      },
      "ChatMessageOut": {
        "properties": {
          "attachments": {
            "items": {
              "$ref": "#/components/schemas/ChatAttachmentOut"
            },
            "title": "Attachments",
            "type": "array"
          },
          "citations": {
            "items": {
              "$ref": "#/components/schemas/AskCitation"
            },
            "title": "Citations",
            "type": "array"
          },
          "content": {
            "title": "Content",
            "type": "string"
          },
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "objects": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/ChatAttachmentOut"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Objects"
          },
          "role": {
            "title": "Role",
            "type": "string"
          },
          "steps": {
            "anyOf": [
              {
                "items": {
                  "additionalProperties": true,
                  "type": "object"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Steps"
          }
        },
        "required": [
          "id",
          "role",
          "content",
          "created_at"
        ],
        "title": "ChatMessageOut",
        "type": "object"
      },
      "ChatPatch": {
        "description": "Частичная правка сессии: незаданное поле не трогаем. Пустой заголовок не принимаем —\nпереименование на пустое смысла не имеет; закрепление — независимый флаг.\n\n``collection_id`` — перенести чат в проект (папку). У него NULL значащий («без проекта»),\nпоэтому «снять проект» нельзя выразить тем же ``None``, что и «не трогать»: для снятия\nзаведён отдельный флаг ``clear_collection``.",
        "properties": {
          "clear_collection": {
            "default": false,
            "title": "Clear Collection",
            "type": "boolean"
          },
          "collection_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Collection Id"
          },
          "pinned": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Pinned"
          },
          "title": {
            "anyOf": [
              {
                "maxLength": 200,
                "minLength": 1,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Title"
          }
        },
        "title": "ChatPatch",
        "type": "object"
      },
      "ChatRequest": {
        "properties": {
          "attachment_ids": {
            "items": {
              "format": "uuid",
              "type": "string"
            },
            "title": "Attachment Ids",
            "type": "array"
          },
          "history": {
            "items": {
              "$ref": "#/components/schemas/ChatTurnIn"
            },
            "title": "History",
            "type": "array"
          },
          "inline_attachments": {
            "items": {
              "$ref": "#/components/schemas/InlineAttachmentIn"
            },
            "maxItems": 5,
            "title": "Inline Attachments",
            "type": "array"
          },
          "model": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Model"
          },
          "query": {
            "maxLength": 4000,
            "minLength": 1,
            "title": "Query",
            "type": "string"
          },
          "session_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Session Id"
          },
          "use_memory": {
            "default": true,
            "title": "Use Memory",
            "type": "boolean"
          },
          "web_search": {
            "default": true,
            "title": "Web Search",
            "type": "boolean"
          }
        },
        "required": [
          "query"
        ],
        "title": "ChatRequest",
        "type": "object"
      },
      "ChatResponse": {
        "properties": {
          "answer": {
            "title": "Answer",
            "type": "string"
          },
          "cost_rub": {
            "default": 0.0,
            "title": "Cost Rub",
            "type": "number"
          },
          "session_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Session Id"
          }
        },
        "required": [
          "answer"
        ],
        "title": "ChatResponse",
        "type": "object"
      },
      "ChatSessionList": {
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/ChatSessionOut"
            },
            "title": "Items",
            "type": "array"
          },
          "total": {
            "default": 0,
            "title": "Total",
            "type": "integer"
          }
        },
        "title": "ChatSessionList",
        "type": "object"
      },
      "ChatSessionOut": {
        "properties": {
          "collection_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Collection Id"
          },
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "kind": {
            "default": "ask",
            "title": "Kind",
            "type": "string"
          },
          "last_file": {
            "default": "",
            "title": "Last File",
            "type": "string"
          },
          "pinned": {
            "default": false,
            "title": "Pinned",
            "type": "boolean"
          },
          "preview": {
            "default": "",
            "title": "Preview",
            "type": "string"
          },
          "title": {
            "title": "Title",
            "type": "string"
          },
          "updated_at": {
            "format": "date-time",
            "title": "Updated At",
            "type": "string"
          }
        },
        "required": [
          "id",
          "title",
          "created_at",
          "updated_at"
        ],
        "title": "ChatSessionOut",
        "type": "object"
      },
      "ChatTurnIn": {
        "properties": {
          "content": {
            "title": "Content",
            "type": "string"
          },
          "role": {
            "title": "Role",
            "type": "string"
          }
        },
        "required": [
          "role",
          "content"
        ],
        "title": "ChatTurnIn",
        "type": "object"
      },
      "CollectionCreate": {
        "properties": {
          "icon": {
            "default": "",
            "maxLength": 32,
            "title": "Icon",
            "type": "string"
          },
          "is_hidden": {
            "default": false,
            "title": "Is Hidden",
            "type": "boolean"
          },
          "name": {
            "maxLength": 200,
            "minLength": 1,
            "title": "Name",
            "type": "string"
          },
          "parent_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Parent Id"
          },
          "theme_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Theme Id"
          }
        },
        "required": [
          "name"
        ],
        "title": "CollectionCreate",
        "type": "object"
      },
      "CollectionList": {
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/CollectionOut"
            },
            "title": "Items",
            "type": "array"
          },
          "total": {
            "default": 0,
            "title": "Total",
            "type": "integer"
          }
        },
        "title": "CollectionList",
        "type": "object"
      },
      "CollectionOut": {
        "properties": {
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "has_note": {
            "default": false,
            "title": "Has Note",
            "type": "boolean"
          },
          "icon": {
            "default": "",
            "title": "Icon",
            "type": "string"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "is_hidden": {
            "default": false,
            "title": "Is Hidden",
            "type": "boolean"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "name_mode": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name Mode"
          },
          "object_count": {
            "default": 0,
            "title": "Object Count",
            "type": "integer"
          },
          "parent_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Parent Id"
          },
          "theme_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Theme Id"
          }
        },
        "required": [
          "id",
          "name",
          "created_at"
        ],
        "title": "CollectionOut",
        "type": "object"
      },
      "CollectionUpdate": {
        "properties": {
          "icon": {
            "anyOf": [
              {
                "maxLength": 32,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Icon"
          },
          "is_hidden": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Is Hidden"
          },
          "name": {
            "anyOf": [
              {
                "maxLength": 200,
                "minLength": 1,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name"
          },
          "name_mode": {
            "anyOf": [
              {
                "maxLength": 16,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name Mode"
          },
          "parent_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Parent Id"
          },
          "theme_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Theme Id"
          }
        },
        "title": "CollectionUpdate",
        "type": "object"
      },
      "CommandRequest": {
        "description": "Свободная команда пользователя — обычно распознанный текст голосового ввода.",
        "properties": {
          "text": {
            "maxLength": 1000,
            "minLength": 1,
            "title": "Text",
            "type": "string"
          }
        },
        "required": [
          "text"
        ],
        "title": "CommandRequest",
        "type": "object"
      },
      "CommandResponse": {
        "description": "Результат команды.\n\nДля выполненного convert: ``action='convert'``, ``executed=true``, заполнены\n``object_id``/``filename``/``fmt`` (целевой формат), а ``reply`` — готовая фраза для чата\n(«Конвертирую …»). Если convert поняли, но файл не нашли/не конвертируется — ``executed=false``\nи ``reply`` с причиной. Для остальных намерений — только классификация (``action`` +\n``target``/``lang``/``fmt``), которую маршрутизирует клиент.",
        "properties": {
          "action": {
            "title": "Action",
            "type": "string"
          },
          "executed": {
            "default": false,
            "title": "Executed",
            "type": "boolean"
          },
          "filename": {
            "default": "",
            "title": "Filename",
            "type": "string"
          },
          "fmt": {
            "default": "",
            "title": "Fmt",
            "type": "string"
          },
          "lang": {
            "default": "",
            "title": "Lang",
            "type": "string"
          },
          "object_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Object Id"
          },
          "op": {
            "default": "",
            "title": "Op",
            "type": "string"
          },
          "reply": {
            "default": "",
            "title": "Reply",
            "type": "string"
          },
          "target": {
            "default": "",
            "title": "Target",
            "type": "string"
          }
        },
        "required": [
          "action"
        ],
        "title": "CommandResponse",
        "type": "object"
      },
      "CompareOut": {
        "description": "Результат сравнения: расхождения + сводка по ВСЕМУ тексту.\n\n``blocks`` обрезается потолком показа, счётчики — нет: «изменено 3» при трёх сотнях\nправок ввело бы в заблуждение сильнее, чем длинный список. ``truncated`` про это и говорит.\n``similarity`` — доля совпавших абзацев (0..1).",
        "properties": {
          "added": {
            "default": 0,
            "title": "Added",
            "type": "integer"
          },
          "blocks": {
            "items": {
              "$ref": "#/components/schemas/DiffBlockOut"
            },
            "title": "Blocks",
            "type": "array"
          },
          "changed": {
            "default": 0,
            "title": "Changed",
            "type": "integer"
          },
          "identical": {
            "default": false,
            "title": "Identical",
            "type": "boolean"
          },
          "left_label": {
            "title": "Left Label",
            "type": "string"
          },
          "removed": {
            "default": 0,
            "title": "Removed",
            "type": "integer"
          },
          "right_label": {
            "title": "Right Label",
            "type": "string"
          },
          "similarity": {
            "default": 0.0,
            "title": "Similarity",
            "type": "number"
          },
          "truncated": {
            "default": false,
            "title": "Truncated",
            "type": "boolean"
          },
          "unchanged": {
            "default": 0,
            "title": "Unchanged",
            "type": "integer"
          }
        },
        "required": [
          "left_label",
          "right_label"
        ],
        "title": "CompareOut",
        "type": "object"
      },
      "CompareRequest": {
        "description": "С чем сравнивать файл. Ровно ОДИН источник: другой файл либо своя прошлая версия.\n\nОба поля разом — ошибка клиента, а не повод молча выбрать один: «сравни с версией 3»\nи «сравни с этим файлом» — разные вопросы, и угадывать, какой из них имелся в виду,\nзначит показать человеку не тот диф. Ни одного — берём последнюю ревизию (частый случай\n«что изменилось с прошлого раза»).",
        "properties": {
          "other_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Other Id"
          },
          "version": {
            "anyOf": [
              {
                "minimum": 1.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Version"
          }
        },
        "title": "CompareRequest",
        "type": "object"
      },
      "ConnectOut": {
        "properties": {
          "url": {
            "title": "Url",
            "type": "string"
          }
        },
        "required": [
          "url"
        ],
        "title": "ConnectOut",
        "type": "object"
      },
      "ContentSaveStatus": {
        "description": "Статус фоновой пересборки docx/pdf. ``error`` — терминальная причина отказа задачи\n(``version_conflict`` — файл успели изменить в другом сеансе, правка НЕ применена);\nпри нём ``object_id`` пуст, и клиент обязан показать конфликт, а не «сохранено».",
        "properties": {
          "done": {
            "default": false,
            "title": "Done",
            "type": "boolean"
          },
          "error": {
            "default": "",
            "title": "Error",
            "type": "string"
          },
          "filename": {
            "default": "",
            "title": "Filename",
            "type": "string"
          },
          "object_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Object Id"
          },
          "state": {
            "title": "State",
            "type": "string"
          }
        },
        "required": [
          "state"
        ],
        "title": "ContentSaveStatus",
        "type": "object"
      },
      "ContentUrl": {
        "properties": {
          "expires_in": {
            "title": "Expires In",
            "type": "integer"
          },
          "url": {
            "title": "Url",
            "type": "string"
          }
        },
        "required": [
          "url",
          "expires_in"
        ],
        "title": "ContentUrl",
        "type": "object"
      },
      "ConvertAccepted": {
        "description": "Конвертация принята: результат появится НОВЫМ объектом в списке (Celery).\n\n``task_id`` — id Celery-задачи; по нему клиент опрашивает ``/convert-status``,\nчтобы показать готовый файл карточкой сразу, как он создан.",
        "properties": {
          "status": {
            "default": "accepted",
            "title": "Status",
            "type": "string"
          },
          "task_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Task Id"
          },
          "to": {
            "default": "pdf",
            "title": "To",
            "type": "string"
          }
        },
        "title": "ConvertAccepted",
        "type": "object"
      },
      "ConvertByQueryAccepted": {
        "description": "Найден файл и поставлена конвертация: результат появится НОВЫМ объектом (Celery).",
        "properties": {
          "filename": {
            "default": "",
            "title": "Filename",
            "type": "string"
          },
          "object_id": {
            "format": "uuid",
            "title": "Object Id",
            "type": "string"
          },
          "status": {
            "default": "accepted",
            "title": "Status",
            "type": "string"
          },
          "to": {
            "default": "pdf",
            "title": "To",
            "type": "string"
          }
        },
        "required": [
          "object_id"
        ],
        "title": "ConvertByQueryAccepted",
        "type": "object"
      },
      "ConvertByQueryRequest": {
        "description": "Найти файл по фразе и сконвертировать (C1): чинит «команда конвертации не сработала».\n\n``query`` — поисковая фраза («паспорт», «договор аренды»); ``to`` — целевой формат как\nназвал пользователь («word», «pdf», «docx»...), нормализуется на сервере.",
        "properties": {
          "query": {
            "maxLength": 500,
            "minLength": 1,
            "title": "Query",
            "type": "string"
          },
          "to": {
            "default": "pdf",
            "title": "To",
            "type": "string"
          }
        },
        "required": [
          "query"
        ],
        "title": "ConvertByQueryRequest",
        "type": "object"
      },
      "ConvertRequest": {
        "properties": {
          "to": {
            "default": "pdf",
            "title": "To",
            "type": "string"
          }
        },
        "title": "ConvertRequest",
        "type": "object"
      },
      "ConvertStatus": {
        "description": "Статус конвертации (для карточки готового файла в чате). Читается из Celery\nAsyncResult: SUCCESS → id/имя нового объекта.",
        "properties": {
          "done": {
            "default": false,
            "title": "Done",
            "type": "boolean"
          },
          "duplicate": {
            "default": false,
            "title": "Duplicate",
            "type": "boolean"
          },
          "filename": {
            "default": "",
            "title": "Filename",
            "type": "string"
          },
          "object_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Object Id"
          },
          "state": {
            "title": "State",
            "type": "string"
          }
        },
        "required": [
          "state"
        ],
        "title": "ConvertStatus",
        "type": "object"
      },
      "ConvertTargets": {
        "description": "Доступные целевые форматы конвертации для файла (по расширению источника).\n\nПустой список — файл не конвертируется. Клиент показывает эти форматы в\nвыпадающем списке на странице конвертации.",
        "properties": {
          "source_ext": {
            "default": "",
            "title": "Source Ext",
            "type": "string"
          },
          "targets": {
            "items": {
              "type": "string"
            },
            "title": "Targets",
            "type": "array"
          }
        },
        "title": "ConvertTargets",
        "type": "object"
      },
      "CorrectionCreate": {
        "description": "Правка файла (scope=file): create+apply одним вызовом.",
        "properties": {
          "confidence": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Confidence"
          },
          "criticality": {
            "default": "normal",
            "enum": [
              "low",
              "normal",
              "high"
            ],
            "title": "Criticality",
            "type": "string"
          },
          "field": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Field"
          },
          "kind": {
            "enum": [
              "reclassify",
              "rename",
              "redescribe",
              "retag",
              "exclude",
              "pin",
              "rule"
            ],
            "title": "Kind",
            "type": "string"
          },
          "new_value": {
            "anyOf": [
              {},
              {
                "type": "null"
              }
            ],
            "title": "New Value"
          },
          "note": {
            "default": "",
            "maxLength": 2000,
            "title": "Note",
            "type": "string"
          },
          "source_message_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Source Message Id"
          },
          "source_session_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Source Session Id"
          }
        },
        "required": [
          "kind"
        ],
        "title": "CorrectionCreate",
        "type": "object"
      },
      "CorrectionList": {
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/CorrectionOut"
            },
            "title": "Items",
            "type": "array"
          },
          "total": {
            "title": "Total",
            "type": "integer"
          }
        },
        "required": [
          "items",
          "total"
        ],
        "title": "CorrectionList",
        "type": "object"
      },
      "CorrectionOut": {
        "properties": {
          "actor": {
            "default": "",
            "title": "Actor",
            "type": "string"
          },
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "criticality": {
            "default": "normal",
            "title": "Criticality",
            "type": "string"
          },
          "field": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Field"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "kind": {
            "title": "Kind",
            "type": "string"
          },
          "new_value": {
            "anyOf": [
              {},
              {
                "type": "null"
              }
            ],
            "title": "New Value"
          },
          "note": {
            "default": "",
            "title": "Note",
            "type": "string"
          },
          "object_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Object Id"
          },
          "scope": {
            "title": "Scope",
            "type": "string"
          },
          "status": {
            "default": "applied",
            "title": "Status",
            "type": "string"
          }
        },
        "required": [
          "id",
          "scope",
          "kind",
          "created_at"
        ],
        "title": "CorrectionOut",
        "type": "object"
      },
      "DeepHealthOut": {
        "description": "Состояние зависимостей. ``degraded`` едет вместе с кодом 503 — и это ответ, а не сбой:\nради перечня в ``checks`` ручку и зовут, поэтому у неё есть тело даже в плохом случае.",
        "properties": {
          "checks": {
            "additionalProperties": {
              "type": "string"
            },
            "title": "Checks",
            "type": "object"
          },
          "status": {
            "title": "Status",
            "type": "string"
          }
        },
        "required": [
          "status",
          "checks"
        ],
        "title": "DeepHealthOut",
        "type": "object"
      },
      "DiarizationResult": {
        "description": "Результат диаризации для UI. ``ready=False`` — разметки ещё нет (не запускали или в\nобработке). Служебные эмбеддинги (self-enrollment) наружу НЕ отдаём.",
        "properties": {
          "object_id": {
            "format": "uuid",
            "title": "Object Id",
            "type": "string"
          },
          "ready": {
            "default": false,
            "title": "Ready",
            "type": "boolean"
          },
          "segments": {
            "default": [],
            "items": {
              "$ref": "#/components/schemas/DiarizationSegment"
            },
            "title": "Segments",
            "type": "array"
          },
          "speakers": {
            "additionalProperties": {
              "type": "string"
            },
            "default": {},
            "title": "Speakers",
            "type": "object"
          },
          "text": {
            "default": "",
            "title": "Text",
            "type": "string"
          }
        },
        "required": [
          "object_id"
        ],
        "title": "DiarizationResult",
        "type": "object"
      },
      "DiarizationSegment": {
        "properties": {
          "end": {
            "title": "End",
            "type": "number"
          },
          "speaker": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Speaker"
          },
          "start": {
            "title": "Start",
            "type": "number"
          },
          "text": {
            "title": "Text",
            "type": "string"
          },
          "uncertain": {
            "default": false,
            "title": "Uncertain",
            "type": "boolean"
          }
        },
        "required": [
          "start",
          "end",
          "text"
        ],
        "title": "DiarizationSegment",
        "type": "object"
      },
      "DiarizeAccepted": {
        "properties": {
          "object_id": {
            "format": "uuid",
            "title": "Object Id",
            "type": "string"
          },
          "status": {
            "default": "accepted",
            "title": "Status",
            "type": "string"
          },
          "task_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Task Id"
          }
        },
        "required": [
          "object_id"
        ],
        "title": "DiarizeAccepted",
        "type": "object"
      },
      "DiarizeStatus": {
        "description": "Статус фоновой диаризации по task_id (как convert-status): done → ok=SUCCESS.",
        "properties": {
          "done": {
            "default": false,
            "title": "Done",
            "type": "boolean"
          },
          "ok": {
            "default": false,
            "title": "Ok",
            "type": "boolean"
          },
          "state": {
            "title": "State",
            "type": "string"
          }
        },
        "required": [
          "state"
        ],
        "title": "DiarizeStatus",
        "type": "object"
      },
      "DiarizedOut": {
        "properties": {
          "object_id": {
            "format": "uuid",
            "title": "Object Id",
            "type": "string"
          },
          "speakers": {
            "additionalProperties": {
              "type": "string"
            },
            "title": "Speakers",
            "type": "object"
          },
          "text": {
            "title": "Text",
            "type": "string"
          }
        },
        "required": [
          "object_id",
          "speakers",
          "text"
        ],
        "title": "DiarizedOut",
        "type": "object"
      },
      "DiffBlockOut": {
        "description": "Одно расхождение. Номера абзацев 1-based, ``0`` — «на той стороне такого абзаца нет».",
        "properties": {
          "left": {
            "default": "",
            "title": "Left",
            "type": "string"
          },
          "left_no": {
            "default": 0,
            "title": "Left No",
            "type": "integer"
          },
          "op": {
            "enum": [
              "added",
              "removed",
              "changed"
            ],
            "title": "Op",
            "type": "string"
          },
          "right": {
            "default": "",
            "title": "Right",
            "type": "string"
          },
          "right_no": {
            "default": 0,
            "title": "Right No",
            "type": "integer"
          }
        },
        "required": [
          "op"
        ],
        "title": "DiffBlockOut",
        "type": "object"
      },
      "DocGenAccepted": {
        "description": "Генерация принята: результат появится НОВЫМ объектом (Celery). ``task_id`` — для\nопроса ``/documents/status``.",
        "properties": {
          "status": {
            "default": "accepted",
            "title": "Status",
            "type": "string"
          },
          "task_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Task Id"
          },
          "to": {
            "default": "docx",
            "title": "To",
            "type": "string"
          }
        },
        "title": "DocGenAccepted",
        "type": "object"
      },
      "DocGenRequest": {
        "description": "Запрос на генерацию документа. ``kind`` — тип по смыслу (letter/report/contract/memo/doc);\n``to`` — формат результата (docx по умолчанию или pdf); ``title`` — заголовок (опц.).",
        "properties": {
          "kind": {
            "default": "doc",
            "maxLength": 20,
            "title": "Kind",
            "type": "string"
          },
          "prompt": {
            "maxLength": 4000,
            "minLength": 1,
            "title": "Prompt",
            "type": "string"
          },
          "title": {
            "default": "",
            "maxLength": 255,
            "title": "Title",
            "type": "string"
          },
          "to": {
            "default": "docx",
            "maxLength": 8,
            "title": "To",
            "type": "string"
          }
        },
        "required": [
          "prompt"
        ],
        "title": "DocGenRequest",
        "type": "object"
      },
      "DocGenStatus": {
        "description": "Статус генерации (для карточки готового файла в чате). Читается из Celery AsyncResult:\nSUCCESS → id/имя нового объекта.\n\n``stage``/``step``/``steps`` — текущий этап: генерация текста моделью идёт десятками секунд,\nи без этапа интерфейс неотличим от зависшего запроса.",
        "properties": {
          "detail": {
            "default": "",
            "title": "Detail",
            "type": "string"
          },
          "done": {
            "default": false,
            "title": "Done",
            "type": "boolean"
          },
          "duplicate": {
            "default": false,
            "title": "Duplicate",
            "type": "boolean"
          },
          "filename": {
            "default": "",
            "title": "Filename",
            "type": "string"
          },
          "object_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Object Id"
          },
          "stage": {
            "default": "",
            "title": "Stage",
            "type": "string"
          },
          "state": {
            "title": "State",
            "type": "string"
          },
          "step": {
            "default": 0,
            "title": "Step",
            "type": "integer"
          },
          "steps": {
            "default": 0,
            "title": "Steps",
            "type": "integer"
          }
        },
        "required": [
          "state"
        ],
        "title": "DocGenStatus",
        "type": "object"
      },
      "DraftOut": {
        "description": "Черновик пользователя по файлу. Отсутствие черновика — 404, а не пустой объект.",
        "properties": {
          "base_version": {
            "default": 1,
            "title": "Base Version",
            "type": "integer"
          },
          "text": {
            "default": "",
            "title": "Text",
            "type": "string"
          },
          "updated_at": {
            "format": "date-time",
            "title": "Updated At",
            "type": "string"
          }
        },
        "required": [
          "updated_at"
        ],
        "title": "DraftOut",
        "type": "object"
      },
      "DraftUpdate": {
        "description": "Автосохранение черновика редактора: текст не публикуется (S3/индекс не трогаем),\n``base_version`` — версия файла, поверх которой правили (нужна для 412 при публикации).",
        "properties": {
          "base_version": {
            "minimum": 1.0,
            "title": "Base Version",
            "type": "integer"
          },
          "text": {
            "maxLength": 5000000,
            "title": "Text",
            "type": "string"
          }
        },
        "required": [
          "text",
          "base_version"
        ],
        "title": "DraftUpdate",
        "type": "object"
      },
      "EmptyTrashResult": {
        "properties": {
          "removed": {
            "default": 0,
            "title": "Removed",
            "type": "integer"
          }
        },
        "title": "EmptyTrashResult",
        "type": "object"
      },
      "EnrichmentOut": {
        "properties": {
          "description": {
            "default": "",
            "title": "Description",
            "type": "string"
          },
          "doc_type": {
            "default": "other",
            "title": "Doc Type",
            "type": "string"
          },
          "entities": {
            "additionalProperties": true,
            "title": "Entities",
            "type": "object"
          },
          "keywords": {
            "items": {
              "type": "string"
            },
            "title": "Keywords",
            "type": "array"
          },
          "language": {
            "default": "",
            "title": "Language",
            "type": "string"
          },
          "model": {
            "default": "",
            "title": "Model",
            "type": "string"
          },
          "summary": {
            "default": "",
            "title": "Summary",
            "type": "string"
          },
          "title": {
            "default": "",
            "title": "Title",
            "type": "string"
          }
        },
        "title": "EnrichmentOut",
        "type": "object"
      },
      "EnrichmentUpdateRequest": {
        "description": "Ручная правка обогащения (теги/описание/заголовок). summary и авто-поля read-only.",
        "properties": {
          "description": {
            "anyOf": [
              {
                "maxLength": 5000,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "keywords": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "maxItems": 64,
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Keywords"
          },
          "title": {
            "anyOf": [
              {
                "maxLength": 500,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Title"
          }
        },
        "title": "EnrichmentUpdateRequest",
        "type": "object"
      },
      "EventCreate": {
        "properties": {
          "description": {
            "default": "",
            "title": "Description",
            "type": "string"
          },
          "ends_at": {
            "default": "",
            "title": "Ends At",
            "type": "string"
          },
          "location": {
            "default": "",
            "title": "Location",
            "type": "string"
          },
          "reminders": {
            "items": {
              "type": "integer"
            },
            "title": "Reminders",
            "type": "array"
          },
          "rrule": {
            "default": "",
            "title": "Rrule",
            "type": "string"
          },
          "starts_at": {
            "title": "Starts At",
            "type": "string"
          },
          "title": {
            "title": "Title",
            "type": "string"
          }
        },
        "required": [
          "title",
          "starts_at"
        ],
        "title": "EventCreate",
        "type": "object"
      },
      "EventIn": {
        "properties": {
          "event": {
            "maxLength": 64,
            "title": "Event",
            "type": "string"
          },
          "props": {
            "additionalProperties": true,
            "title": "Props",
            "type": "object"
          }
        },
        "required": [
          "event"
        ],
        "title": "EventIn",
        "type": "object"
      },
      "EventList": {
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/EventOut"
            },
            "title": "Items",
            "type": "array"
          }
        },
        "required": [
          "items"
        ],
        "title": "EventList",
        "type": "object"
      },
      "EventOut": {
        "properties": {
          "all_day": {
            "default": false,
            "title": "All Day",
            "type": "boolean"
          },
          "description": {
            "default": "",
            "title": "Description",
            "type": "string"
          },
          "ends_at": {
            "format": "date-time",
            "title": "Ends At",
            "type": "string"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "location": {
            "default": "",
            "title": "Location",
            "type": "string"
          },
          "number": {
            "title": "Number",
            "type": "integer"
          },
          "recurrence_label": {
            "default": "",
            "title": "Recurrence Label",
            "type": "string"
          },
          "reminders": {
            "items": {
              "type": "integer"
            },
            "title": "Reminders",
            "type": "array"
          },
          "rrule": {
            "default": "",
            "title": "Rrule",
            "type": "string"
          },
          "starts_at": {
            "format": "date-time",
            "title": "Starts At",
            "type": "string"
          },
          "status": {
            "default": "confirmed",
            "title": "Status",
            "type": "string"
          },
          "title": {
            "title": "Title",
            "type": "string"
          },
          "tz": {
            "title": "Tz",
            "type": "string"
          }
        },
        "required": [
          "id",
          "number",
          "title",
          "starts_at",
          "ends_at",
          "tz"
        ],
        "title": "EventOut",
        "type": "object"
      },
      "EventUpdate": {
        "description": "Частичная правка: ``None`` — «не трогать».\n\n``status`` сюда НЕ входит намеренно: у отмены ровно один путь записи — DELETE. Два способа\nотменить встречу означали бы два места, где можно забыть про exdates.",
        "properties": {
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "ends_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Ends At"
          },
          "location": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Location"
          },
          "reminders": {
            "anyOf": [
              {
                "items": {
                  "type": "integer"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reminders"
          },
          "rrule": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Rrule"
          },
          "starts_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Starts At"
          },
          "title": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Title"
          }
        },
        "title": "EventUpdate",
        "type": "object"
      },
      "EventsAck": {
        "properties": {
          "recorded": {
            "title": "Recorded",
            "type": "integer"
          }
        },
        "required": [
          "recorded"
        ],
        "title": "EventsAck",
        "type": "object"
      },
      "EventsBatch": {
        "properties": {
          "events": {
            "items": {
              "$ref": "#/components/schemas/EventIn"
            },
            "maxItems": 50,
            "title": "Events",
            "type": "array"
          }
        },
        "title": "EventsBatch",
        "type": "object"
      },
      "ExtractedAttachmentOut": {
        "description": "Ответ ``POST /chat/attachment``: извлечённый текст локального файла. В облаке НИЧЕГО не\nсохранено — клиент шлёт этот текст обратно как ``inline_attachments`` к вопросам.\n\nИмя НЕ ``ChatAttachmentOut``: так называется схема вложения сообщения в\n``schemas/chats.py``, и два одноимённых класса заставляли FastAPI разводить их в\nOpenAPI полными путями модулей — генераторы клиентов получали тип с именем\n``backend__app__api__routers__chat__ChatAttachmentOut``. Схемы разные по смыслу\n(текст без файла против ссылки на файл), поэтому и имена разные.",
        "properties": {
          "filename": {
            "title": "Filename",
            "type": "string"
          },
          "text": {
            "title": "Text",
            "type": "string"
          },
          "truncated": {
            "default": false,
            "title": "Truncated",
            "type": "boolean"
          }
        },
        "required": [
          "filename",
          "text"
        ],
        "title": "ExtractedAttachmentOut",
        "type": "object"
      },
      "FactCreate": {
        "description": "Факт «Что ИИ о вас знает», добавленный человеком руками.\n\nПоля ``kind`` тут нет НАМЕРЕННО: вид фиксирован сервисом. Иначе факт можно было бы создать\nобщим ``POST /v1/corrections`` в обход ``remember_fact`` — мимо дедупа, вытеснения по\nсубъекту и отсева секретов, которые живут только там.",
        "properties": {
          "fact": {
            "maxLength": 2000,
            "minLength": 1,
            "title": "Fact",
            "type": "string"
          },
          "object_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Object Id"
          },
          "subject": {
            "default": "",
            "maxLength": 64,
            "title": "Subject",
            "type": "string"
          }
        },
        "required": [
          "fact"
        ],
        "title": "FactCreate",
        "type": "object"
      },
      "FeedCreate": {
        "properties": {
          "name": {
            "default": "",
            "title": "Name",
            "type": "string"
          },
          "ttl_days": {
            "default": 365,
            "maximum": 1095.0,
            "minimum": 1.0,
            "title": "Ttl Days",
            "type": "integer"
          }
        },
        "title": "FeedCreate",
        "type": "object"
      },
      "FeedList": {
        "properties": {
          "enabled": {
            "default": false,
            "title": "Enabled",
            "type": "boolean"
          },
          "items": {
            "items": {
              "$ref": "#/components/schemas/FeedOut"
            },
            "title": "Items",
            "type": "array"
          }
        },
        "required": [
          "items"
        ],
        "title": "FeedList",
        "type": "object"
      },
      "FeedOut": {
        "properties": {
          "access_count": {
            "default": 0,
            "title": "Access Count",
            "type": "integer"
          },
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "expires_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Expires At"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "last_access_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Access At"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "url": {
            "default": "",
            "title": "Url",
            "type": "string"
          },
          "webcal_url": {
            "default": "",
            "title": "Webcal Url",
            "type": "string"
          }
        },
        "required": [
          "id",
          "name",
          "created_at"
        ],
        "title": "FeedOut",
        "type": "object"
      },
      "FolderNoteOut": {
        "description": "Заметка-знания папки (KNOWLEDGE): id объекта-заметки для открытия в редакторе.",
        "properties": {
          "object_id": {
            "format": "uuid",
            "title": "Object Id",
            "type": "string"
          }
        },
        "required": [
          "object_id"
        ],
        "title": "FolderNoteOut",
        "type": "object"
      },
      "GoogleStatus": {
        "description": "Состояние связи. Токенов здесь нет и быть не может — наружу они не уходят никогда.",
        "properties": {
          "account_email": {
            "default": "",
            "title": "Account Email",
            "type": "string"
          },
          "connected": {
            "default": false,
            "title": "Connected",
            "type": "boolean"
          },
          "enabled": {
            "default": false,
            "title": "Enabled",
            "type": "boolean"
          },
          "last_error": {
            "default": "",
            "title": "Last Error",
            "type": "string"
          },
          "synced_at": {
            "default": "",
            "title": "Synced At",
            "type": "string"
          }
        },
        "title": "GoogleStatus",
        "type": "object"
      },
      "HTTPValidationError": {
        "properties": {
          "detail": {
            "items": {
              "$ref": "#/components/schemas/ValidationError"
            },
            "title": "Detail",
            "type": "array"
          }
        },
        "title": "HTTPValidationError",
        "type": "object"
      },
      "HealthOut": {
        "description": "Живо ли приложение. ``ok`` — единственное значение: ответ отдаёт сам процесс.",
        "properties": {
          "status": {
            "default": "ok",
            "title": "Status",
            "type": "string"
          }
        },
        "title": "HealthOut",
        "type": "object"
      },
      "ImageOpAccepted": {
        "description": "Операция над изображением принята: результат перезапишет исходный объект (Celery).\n``task_id`` — для опроса ``/image-status``.",
        "properties": {
          "op": {
            "default": "",
            "title": "Op",
            "type": "string"
          },
          "status": {
            "default": "accepted",
            "title": "Status",
            "type": "string"
          },
          "task_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Task Id"
          }
        },
        "title": "ImageOpAccepted",
        "type": "object"
      },
      "ImageOpRequest": {
        "description": "Параметры операции над изображением (сама операция — в пути ``/image/{op}``). Поля\nопциональны, нужны по операции: ``quality`` — compress/resize (для jpg/webp); ``max_side`` —\nresize (длинная сторона, px); ``angle`` — rotate (90/180/270); ``mode`` — flip («h»/«v»);\n``box`` — crop (нормализованная рамка ``[left, top, right, bottom]`` в долях 0..1).",
        "properties": {
          "angle": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Angle"
          },
          "box": {
            "anyOf": [
              {
                "items": {
                  "type": "number"
                },
                "maxItems": 4,
                "minItems": 4,
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Box"
          },
          "max_side": {
            "anyOf": [
              {
                "maximum": 10000.0,
                "minimum": 16.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Max Side"
          },
          "mode": {
            "default": "",
            "maxLength": 1,
            "title": "Mode",
            "type": "string"
          },
          "quality": {
            "anyOf": [
              {
                "maximum": 100.0,
                "minimum": 10.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Quality"
          }
        },
        "title": "ImageOpRequest",
        "type": "object"
      },
      "ImageOpStatus": {
        "description": "Статус операции над изображением. SUCCESS → id/имя обновлённого объекта. Читается\nиз Celery AsyncResult.",
        "properties": {
          "count": {
            "default": 1,
            "title": "Count",
            "type": "integer"
          },
          "done": {
            "default": false,
            "title": "Done",
            "type": "boolean"
          },
          "duplicate": {
            "default": false,
            "title": "Duplicate",
            "type": "boolean"
          },
          "filename": {
            "default": "",
            "title": "Filename",
            "type": "string"
          },
          "object_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Object Id"
          },
          "state": {
            "title": "State",
            "type": "string"
          }
        },
        "required": [
          "state"
        ],
        "title": "ImageOpStatus",
        "type": "object"
      },
      "ImportOut": {
        "description": "Квитанция импорта. Показывает, что реально произошло, а не «готово».",
        "properties": {
          "imported": {
            "default": 0,
            "title": "Imported",
            "type": "integer"
          },
          "notes": {
            "items": {
              "type": "string"
            },
            "title": "Notes",
            "type": "array"
          },
          "skipped": {
            "default": 0,
            "title": "Skipped",
            "type": "integer"
          }
        },
        "title": "ImportOut",
        "type": "object"
      },
      "InlineAttachmentIn": {
        "description": "Разовое вложение: имя файла + УЖЕ извлечённый текст. Файла в облаке нет и не будет —\nэто контекст, который живёт только в запросе (и в истории чата как имя).",
        "properties": {
          "filename": {
            "default": "",
            "maxLength": 255,
            "title": "Filename",
            "type": "string"
          },
          "text": {
            "maxLength": 50000,
            "minLength": 1,
            "title": "Text",
            "type": "string"
          }
        },
        "required": [
          "text"
        ],
        "title": "InlineAttachmentIn",
        "type": "object"
      },
      "IntegrationOut": {
        "description": "Карточка одного подключения (llm или s3).",
        "properties": {
          "checked_at": {
            "default": "",
            "title": "Checked At",
            "type": "string"
          },
          "config": {
            "additionalProperties": true,
            "title": "Config",
            "type": "object"
          },
          "configured": {
            "title": "Configured",
            "type": "boolean"
          },
          "enabled": {
            "title": "Enabled",
            "type": "boolean"
          },
          "kind": {
            "title": "Kind",
            "type": "string"
          },
          "last_error": {
            "default": "",
            "title": "Last Error",
            "type": "string"
          },
          "migration": {
            "additionalProperties": true,
            "title": "Migration",
            "type": "object"
          },
          "secret_hint": {
            "default": "",
            "title": "Secret Hint",
            "type": "string"
          },
          "status": {
            "title": "Status",
            "type": "string"
          }
        },
        "required": [
          "kind",
          "configured",
          "enabled",
          "status"
        ],
        "title": "IntegrationOut",
        "type": "object"
      },
      "IntegrationToggleIn": {
        "properties": {
          "enabled": {
            "title": "Enabled",
            "type": "boolean"
          }
        },
        "required": [
          "enabled"
        ],
        "title": "IntegrationToggleIn",
        "type": "object"
      },
      "IntegrationsOut": {
        "properties": {
          "available": {
            "default": true,
            "title": "Available",
            "type": "boolean"
          },
          "items": {
            "items": {
              "$ref": "#/components/schemas/IntegrationOut"
            },
            "title": "Items",
            "type": "array"
          },
          "unavailable_reason": {
            "default": "",
            "title": "Unavailable Reason",
            "type": "string"
          }
        },
        "title": "IntegrationsOut",
        "type": "object"
      },
      "IntentRequest": {
        "properties": {
          "query": {
            "title": "Query",
            "type": "string"
          }
        },
        "required": [
          "query"
        ],
        "title": "IntentRequest",
        "type": "object"
      },
      "IntentResponse": {
        "properties": {
          "action": {
            "title": "Action",
            "type": "string"
          },
          "fmt": {
            "default": "",
            "title": "Fmt",
            "type": "string"
          },
          "lang": {
            "default": "",
            "title": "Lang",
            "type": "string"
          },
          "target": {
            "title": "Target",
            "type": "string"
          }
        },
        "required": [
          "action",
          "target"
        ],
        "title": "IntentResponse",
        "type": "object"
      },
      "LinkAccepted": {
        "description": "Ответ на добавление ссылки. Веб-страница обрабатывается сразу (есть ``object_id``);\nвидео-ссылка скачивается/транскрибируется фоном (``status='processing'``, объект появится позже).",
        "properties": {
          "duplicate": {
            "default": false,
            "title": "Duplicate",
            "type": "boolean"
          },
          "object_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Object Id"
          },
          "status": {
            "title": "Status",
            "type": "string"
          }
        },
        "required": [
          "status"
        ],
        "title": "LinkAccepted",
        "type": "object"
      },
      "LinkRequest": {
        "description": "Добавление веб-ссылки как объекта (v4): страница скачивается и индексируется.",
        "properties": {
          "url": {
            "maxLength": 2048,
            "minLength": 1,
            "title": "Url",
            "type": "string"
          }
        },
        "required": [
          "url"
        ],
        "title": "LinkRequest",
        "type": "object"
      },
      "LlmModelsIn": {
        "description": "Слаги моделей у ЭТОГО эндпойнта. Пусто в роли → шлём слаг, который выбрал бы наш код.",
        "properties": {
          "audio": {
            "default": "",
            "maxLength": 200,
            "title": "Audio",
            "type": "string"
          },
          "chat": {
            "default": "",
            "maxLength": 200,
            "title": "Chat",
            "type": "string"
          },
          "translate": {
            "default": "",
            "maxLength": 200,
            "title": "Translate",
            "type": "string"
          },
          "vision": {
            "default": "",
            "maxLength": 200,
            "title": "Vision",
            "type": "string"
          }
        },
        "title": "LlmModelsIn",
        "type": "object"
      },
      "LlmSaveIn": {
        "description": "Сохранение своего подключения к модели (OpenAI-совместимый эндпойнт).",
        "properties": {
          "api_key": {
            "anyOf": [
              {
                "maxLength": 400,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Api Key"
          },
          "base_url": {
            "default": "",
            "maxLength": 500,
            "title": "Base Url",
            "type": "string"
          },
          "models": {
            "$ref": "#/components/schemas/LlmModelsIn"
          },
          "use_proxy": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Use Proxy"
          }
        },
        "title": "LlmSaveIn",
        "type": "object"
      },
      "MemoryItem": {
        "properties": {
          "input": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Input"
          },
          "memory": {
            "title": "Memory",
            "type": "string"
          },
          "memory_id": {
            "title": "Memory Id",
            "type": "string"
          },
          "topics": {
            "items": {
              "type": "string"
            },
            "title": "Topics",
            "type": "array"
          },
          "updated_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Updated At"
          }
        },
        "required": [
          "memory_id",
          "memory"
        ],
        "title": "MemoryItem",
        "type": "object"
      },
      "MemoryList": {
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/MemoryItem"
            },
            "title": "Items",
            "type": "array"
          }
        },
        "required": [
          "items"
        ],
        "title": "MemoryList",
        "type": "object"
      },
      "MemorySuggestionOut": {
        "properties": {
          "detail": {
            "title": "Detail",
            "type": "string"
          },
          "kind": {
            "title": "Kind",
            "type": "string"
          },
          "object_ids": {
            "default": [],
            "items": {
              "format": "uuid",
              "type": "string"
            },
            "title": "Object Ids",
            "type": "array"
          },
          "title": {
            "title": "Title",
            "type": "string"
          }
        },
        "required": [
          "kind",
          "title",
          "detail"
        ],
        "title": "MemorySuggestionOut",
        "type": "object"
      },
      "MemorySuggestionsList": {
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/MemorySuggestionOut"
            },
            "title": "Items",
            "type": "array"
          }
        },
        "required": [
          "items"
        ],
        "title": "MemorySuggestionsList",
        "type": "object"
      },
      "MeterCost": {
        "properties": {
          "audio_seconds": {
            "default": 0,
            "title": "Audio Seconds",
            "type": "integer"
          },
          "calls": {
            "default": 0,
            "title": "Calls",
            "type": "integer"
          },
          "cost_rub": {
            "title": "Cost Rub",
            "type": "number"
          },
          "meter": {
            "title": "Meter",
            "type": "string"
          },
          "prompt_tokens": {
            "default": 0,
            "title": "Prompt Tokens",
            "type": "integer"
          },
          "total_tokens": {
            "default": 0,
            "title": "Total Tokens",
            "type": "integer"
          }
        },
        "required": [
          "meter",
          "cost_rub"
        ],
        "title": "MeterCost",
        "type": "object"
      },
      "ModelInfo": {
        "properties": {
          "available": {
            "default": false,
            "title": "Available",
            "type": "boolean"
          },
          "default": {
            "default": false,
            "title": "Default",
            "type": "boolean"
          },
          "id": {
            "title": "Id",
            "type": "string"
          },
          "label": {
            "title": "Label",
            "type": "string"
          },
          "provider": {
            "title": "Provider",
            "type": "string"
          }
        },
        "required": [
          "id",
          "label",
          "provider"
        ],
        "title": "ModelInfo",
        "type": "object"
      },
      "ModelList": {
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/ModelInfo"
            },
            "title": "Items",
            "type": "array"
          }
        },
        "title": "ModelList",
        "type": "object"
      },
      "NotificationList": {
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/NotificationOut"
            },
            "title": "Items",
            "type": "array"
          },
          "unread": {
            "default": 0,
            "title": "Unread",
            "type": "integer"
          }
        },
        "required": [
          "items"
        ],
        "title": "NotificationList",
        "type": "object"
      },
      "NotificationOut": {
        "properties": {
          "body": {
            "default": "",
            "title": "Body",
            "type": "string"
          },
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "kind": {
            "title": "Kind",
            "type": "string"
          },
          "payload": {
            "additionalProperties": true,
            "default": {},
            "title": "Payload",
            "type": "object"
          },
          "read_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Read At"
          },
          "title": {
            "title": "Title",
            "type": "string"
          }
        },
        "required": [
          "id",
          "kind",
          "title",
          "created_at"
        ],
        "title": "NotificationOut",
        "type": "object"
      },
      "NotificationsRead": {
        "properties": {
          "ids": {
            "items": {
              "format": "uuid",
              "type": "string"
            },
            "title": "Ids",
            "type": "array"
          }
        },
        "title": "NotificationsRead",
        "type": "object"
      },
      "ObjectAccepted": {
        "properties": {
          "duplicate": {
            "default": false,
            "title": "Duplicate",
            "type": "boolean"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "status": {
            "title": "Status",
            "type": "string"
          }
        },
        "required": [
          "id",
          "status"
        ],
        "title": "ObjectAccepted",
        "type": "object"
      },
      "ObjectContentSaved": {
        "description": "Итог сохранения правки. ``status``: saved (текст записан сразу) | accepted (docx/pdf\nпересобирается фоном — следить по ``task_id`` через ``/content-status``).",
        "properties": {
          "object_id": {
            "format": "uuid",
            "title": "Object Id",
            "type": "string"
          },
          "status": {
            "title": "Status",
            "type": "string"
          },
          "task_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Task Id"
          }
        },
        "required": [
          "status",
          "object_id"
        ],
        "title": "ObjectContentSaved",
        "type": "object"
      },
      "ObjectContentUpdate": {
        "description": "Правка содержимого файла. ``base_version`` — версия объекта, поверх которой правили\n(оптимистичная блокировка E0): если файл успели изменить в другой вкладке/сеансе, сервер\nответит 412, а не молча затрёт чужую правку. ``None`` — проверку не делаем (легаси-клиенты\nи агентский путь продолжают работать как раньше).",
        "properties": {
          "base_version": {
            "anyOf": [
              {
                "minimum": 1.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Base Version"
          },
          "text": {
            "maxLength": 5000000,
            "title": "Text",
            "type": "string"
          }
        },
        "required": [
          "text"
        ],
        "title": "ObjectContentUpdate",
        "type": "object"
      },
      "ObjectDetail": {
        "properties": {
          "ai_name": {
            "default": "",
            "title": "Ai Name",
            "type": "string"
          },
          "categories": {
            "items": {
              "type": "string"
            },
            "title": "Categories",
            "type": "array"
          },
          "content_hash": {
            "title": "Content Hash",
            "type": "string"
          },
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "display_name": {
            "default": "",
            "title": "Display Name",
            "type": "string"
          },
          "editor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Editor"
          },
          "enrichment": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/EnrichmentOut"
              },
              {
                "type": "null"
              }
            ]
          },
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Error"
          },
          "filename": {
            "title": "Filename",
            "type": "string"
          },
          "has_corrections": {
            "default": false,
            "title": "Has Corrections",
            "type": "boolean"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "image_editable": {
            "default": false,
            "title": "Image Editable",
            "type": "boolean"
          },
          "is_hidden": {
            "default": false,
            "title": "Is Hidden",
            "type": "boolean"
          },
          "kind": {
            "title": "Kind",
            "type": "string"
          },
          "mime": {
            "title": "Mime",
            "type": "string"
          },
          "name_locked": {
            "default": false,
            "title": "Name Locked",
            "type": "boolean"
          },
          "name_source": {
            "default": "original",
            "title": "Name Source",
            "type": "string"
          },
          "needs_manual": {
            "default": false,
            "title": "Needs Manual",
            "type": "boolean"
          },
          "original_name": {
            "default": "",
            "title": "Original Name",
            "type": "string"
          },
          "pdf_tools": {
            "default": false,
            "title": "Pdf Tools",
            "type": "boolean"
          },
          "size": {
            "title": "Size",
            "type": "integer"
          },
          "source_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Source Url"
          },
          "status": {
            "title": "Status",
            "type": "string"
          },
          "suggested_collection_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Suggested Collection Id"
          },
          "suggested_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Suggested Name"
          },
          "suggested_reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Suggested Reason"
          },
          "text_fallback": {
            "default": false,
            "title": "Text Fallback",
            "type": "boolean"
          },
          "text_view": {
            "default": false,
            "title": "Text View",
            "type": "boolean"
          },
          "updated_at": {
            "format": "date-time",
            "title": "Updated At",
            "type": "string"
          },
          "version": {
            "default": 1,
            "title": "Version",
            "type": "integer"
          }
        },
        "required": [
          "id",
          "filename",
          "mime",
          "size",
          "kind",
          "status",
          "content_hash",
          "created_at",
          "updated_at"
        ],
        "title": "ObjectDetail",
        "type": "object"
      },
      "ObjectList": {
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/ObjectListItem"
            },
            "title": "Items",
            "type": "array"
          },
          "total": {
            "default": 0,
            "title": "Total",
            "type": "integer"
          }
        },
        "title": "ObjectList",
        "type": "object"
      },
      "ObjectListItem": {
        "properties": {
          "categories": {
            "items": {
              "type": "string"
            },
            "title": "Categories",
            "type": "array"
          },
          "collection_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Collection Id"
          },
          "collection_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Collection Name"
          },
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "deleted_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Deleted At"
          },
          "display_name": {
            "default": "",
            "title": "Display Name",
            "type": "string"
          },
          "doc_type": {
            "default": "other",
            "title": "Doc Type",
            "type": "string"
          },
          "editor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Editor"
          },
          "filename": {
            "title": "Filename",
            "type": "string"
          },
          "has_corrections": {
            "default": false,
            "title": "Has Corrections",
            "type": "boolean"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "image_editable": {
            "default": false,
            "title": "Image Editable",
            "type": "boolean"
          },
          "is_hidden": {
            "default": false,
            "title": "Is Hidden",
            "type": "boolean"
          },
          "kind": {
            "title": "Kind",
            "type": "string"
          },
          "meeting_date": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Meeting Date"
          },
          "name_source": {
            "default": "original",
            "title": "Name Source",
            "type": "string"
          },
          "needs_manual": {
            "default": false,
            "title": "Needs Manual",
            "type": "boolean"
          },
          "pdf_tools": {
            "default": false,
            "title": "Pdf Tools",
            "type": "boolean"
          },
          "size": {
            "default": 0,
            "title": "Size",
            "type": "integer"
          },
          "source_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Source Url"
          },
          "status": {
            "title": "Status",
            "type": "string"
          },
          "suggested_collection_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Suggested Collection Id"
          },
          "suggested_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Suggested Name"
          },
          "summary": {
            "default": "",
            "title": "Summary",
            "type": "string"
          },
          "text_fallback": {
            "default": false,
            "title": "Text Fallback",
            "type": "boolean"
          },
          "text_view": {
            "default": false,
            "title": "Text View",
            "type": "boolean"
          },
          "title": {
            "default": "",
            "title": "Title",
            "type": "string"
          },
          "version": {
            "default": 1,
            "title": "Version",
            "type": "integer"
          }
        },
        "required": [
          "id",
          "filename",
          "kind",
          "status",
          "created_at"
        ],
        "title": "ObjectListItem",
        "type": "object"
      },
      "ObjectUpdateRequest": {
        "description": "Правка объекта пользователем (переименование, скрытие).",
        "properties": {
          "filename": {
            "anyOf": [
              {
                "maxLength": 255,
                "minLength": 1,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Filename"
          },
          "is_hidden": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Is Hidden"
          }
        },
        "title": "ObjectUpdateRequest",
        "type": "object"
      },
      "OfficeConfigOut": {
        "description": "Конфиг офисного редактора для фронта.\n\n``enabled=False`` — не ошибка, а штатный ответ: кил-свич выключен, движок не настроен\nили формат не офисный. Фронт в этом случае показывает ``reason`` и откатывается на\n«правку как текст».",
        "properties": {
          "config": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Config"
          },
          "document_server_url": {
            "default": "",
            "title": "Document Server Url",
            "type": "string"
          },
          "enabled": {
            "default": false,
            "title": "Enabled",
            "type": "boolean"
          },
          "reason": {
            "default": "",
            "title": "Reason",
            "type": "string"
          }
        },
        "title": "OfficeConfigOut",
        "type": "object"
      },
      "OkOut": {
        "description": "Ответ «сделано/не сделано» там, где отдавать нечего.\n\nЗаведён общим не ради экономии строк: без ``response_model`` эти ручки уходили в\nOpenAPI как безымянный ``object``, и генератор клиента получал из них ``any``. Форма\nответа при этом не меняется — она и была ``{\"ok\": …}``.",
        "properties": {
          "ok": {
            "default": true,
            "title": "Ok",
            "type": "boolean"
          }
        },
        "title": "OkOut",
        "type": "object"
      },
      "OwnerRuleCreate": {
        "description": "Owner-правило (kind=rule) или пин файла (kind=pin, нужен object_id).",
        "properties": {
          "criticality": {
            "default": "normal",
            "enum": [
              "low",
              "normal",
              "high"
            ],
            "title": "Criticality",
            "type": "string"
          },
          "kind": {
            "default": "rule",
            "enum": [
              "rule",
              "pin"
            ],
            "title": "Kind",
            "type": "string"
          },
          "new_value": {
            "anyOf": [
              {},
              {
                "type": "null"
              }
            ],
            "title": "New Value"
          },
          "note": {
            "default": "",
            "maxLength": 2000,
            "title": "Note",
            "type": "string"
          },
          "object_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Object Id"
          }
        },
        "title": "OwnerRuleCreate",
        "type": "object"
      },
      "OwnerUsage": {
        "properties": {
          "by_meter": {
            "default": [],
            "items": {
              "$ref": "#/components/schemas/MeterCost"
            },
            "title": "By Meter",
            "type": "array"
          },
          "owner_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Owner Id"
          },
          "total_cost_rub": {
            "default": 0.0,
            "title": "Total Cost Rub",
            "type": "number"
          }
        },
        "title": "OwnerUsage",
        "type": "object"
      },
      "PdfAnnotation": {
        "description": "Аннотация на странице PDF в нормализованных [0..1] координатах (0,0 — верхний левый).\n``type`` — ``highlight`` (заливка), ``rect`` (рамка) или ``text`` (текст в рамке);\n``color`` — hex (#RRGGBB); ``text`` — для ``type='text'``.",
        "properties": {
          "color": {
            "default": "#FDE047",
            "maxLength": 9,
            "title": "Color",
            "type": "string"
          },
          "page": {
            "maximum": 5001.0,
            "minimum": 1.0,
            "title": "Page",
            "type": "integer"
          },
          "text": {
            "default": "",
            "maxLength": 500,
            "title": "Text",
            "type": "string"
          },
          "type": {
            "default": "highlight",
            "enum": [
              "highlight",
              "rect",
              "text"
            ],
            "title": "Type",
            "type": "string"
          },
          "x0": {
            "maximum": 1.0,
            "minimum": 0.0,
            "title": "X0",
            "type": "number"
          },
          "x1": {
            "maximum": 1.0,
            "minimum": 0.0,
            "title": "X1",
            "type": "number"
          },
          "y0": {
            "maximum": 1.0,
            "minimum": 0.0,
            "title": "Y0",
            "type": "number"
          },
          "y1": {
            "maximum": 1.0,
            "minimum": 0.0,
            "title": "Y1",
            "type": "number"
          }
        },
        "required": [
          "page",
          "x0",
          "y0",
          "x1",
          "y1"
        ],
        "title": "PdfAnnotation",
        "type": "object"
      },
      "PdfInfo": {
        "description": "Служебная инфа о PDF для приложения: число страниц (навигатор + разметка redact).",
        "properties": {
          "pages": {
            "default": 0,
            "title": "Pages",
            "type": "integer"
          }
        },
        "title": "PdfInfo",
        "type": "object"
      },
      "PdfOpAccepted": {
        "description": "PDF-операция принята: результат появится НОВЫМ объектом(-ами) (Celery). ``task_id`` —\nдля опроса ``/pdf-status``.",
        "properties": {
          "op": {
            "default": "",
            "title": "Op",
            "type": "string"
          },
          "status": {
            "default": "accepted",
            "title": "Status",
            "type": "string"
          },
          "task_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Task Id"
          }
        },
        "title": "PdfOpAccepted",
        "type": "object"
      },
      "PdfOpRequest": {
        "description": "Параметры PDF-операции (сама операция — в пути ``/pdf/{op}``). Поля опциональны,\nнужны по операции: ``pages`` — delete/rotate/replace («5-7,2»); ``angle`` — rotate\n(90/180/270) или наклон watermark; ``password`` — protect/unlock; ``size``/``ranges`` —\nsplit; ``order`` — reorder; ``text``/``opacity``/``font_size`` — watermark;\n``source_object_id``/``at`` — insert (``at`` — позиция вставки, 1-индексная);\n``source_object_id``/``pages`` — replace; ``title``/``author``/``subject``/``keywords`` —\nproperties.",
        "properties": {
          "angle": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Angle"
          },
          "annotations": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/PdfAnnotation"
                },
                "maxItems": 500,
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Annotations"
          },
          "at": {
            "anyOf": [
              {
                "maximum": 5001.0,
                "minimum": 1.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "At"
          },
          "author": {
            "default": "",
            "maxLength": 255,
            "title": "Author",
            "type": "string"
          },
          "boxes": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/RedactBox"
                },
                "maxItems": 1000,
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Boxes"
          },
          "font_size": {
            "anyOf": [
              {
                "maximum": 200.0,
                "minimum": 6.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Font Size"
          },
          "keywords": {
            "default": "",
            "maxLength": 255,
            "title": "Keywords",
            "type": "string"
          },
          "opacity": {
            "anyOf": [
              {
                "maximum": 1.0,
                "minimum": 0.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Opacity"
          },
          "order": {
            "anyOf": [
              {
                "items": {
                  "type": "integer"
                },
                "maxItems": 5000,
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Order"
          },
          "pages": {
            "default": "",
            "maxLength": 200,
            "title": "Pages",
            "type": "string"
          },
          "password": {
            "default": "",
            "maxLength": 256,
            "title": "Password",
            "type": "string"
          },
          "ranges": {
            "anyOf": [
              {
                "items": {
                  "maxItems": 2,
                  "minItems": 2,
                  "prefixItems": [
                    {
                      "type": "integer"
                    },
                    {
                      "type": "integer"
                    }
                  ],
                  "type": "array"
                },
                "maxItems": 1000,
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Ranges"
          },
          "size": {
            "default": 1,
            "maximum": 1000.0,
            "minimum": 1.0,
            "title": "Size",
            "type": "integer"
          },
          "source_object_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Source Object Id"
          },
          "subject": {
            "default": "",
            "maxLength": 255,
            "title": "Subject",
            "type": "string"
          },
          "text": {
            "default": "",
            "maxLength": 120,
            "title": "Text",
            "type": "string"
          },
          "title": {
            "default": "",
            "maxLength": 255,
            "title": "Title",
            "type": "string"
          }
        },
        "title": "PdfOpRequest",
        "type": "object"
      },
      "PdfOpStatus": {
        "description": "Статус PDF-операции. SUCCESS → id/имя ПЕРВОГО нового объекта и ``count`` созданных\n(для split — число частей). Читается из Celery AsyncResult.",
        "properties": {
          "count": {
            "default": 0,
            "title": "Count",
            "type": "integer"
          },
          "done": {
            "default": false,
            "title": "Done",
            "type": "boolean"
          },
          "duplicate": {
            "default": false,
            "title": "Duplicate",
            "type": "boolean"
          },
          "filename": {
            "default": "",
            "title": "Filename",
            "type": "string"
          },
          "object_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Object Id"
          },
          "state": {
            "title": "State",
            "type": "string"
          }
        },
        "required": [
          "state"
        ],
        "title": "PdfOpStatus",
        "type": "object"
      },
      "PinSetRequest": {
        "properties": {
          "old_pin": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Old Pin"
          },
          "pin": {
            "maxLength": 12,
            "minLength": 4,
            "title": "Pin",
            "type": "string"
          }
        },
        "required": [
          "pin"
        ],
        "title": "PinSetRequest",
        "type": "object"
      },
      "PinStatus": {
        "properties": {
          "enabled": {
            "title": "Enabled",
            "type": "boolean"
          }
        },
        "required": [
          "enabled"
        ],
        "title": "PinStatus",
        "type": "object"
      },
      "PinUnlockOut": {
        "properties": {
          "expires_in": {
            "title": "Expires In",
            "type": "integer"
          },
          "token": {
            "title": "Token",
            "type": "string"
          }
        },
        "required": [
          "token",
          "expires_in"
        ],
        "title": "PinUnlockOut",
        "type": "object"
      },
      "PinVerifyRequest": {
        "properties": {
          "pin": {
            "maxLength": 12,
            "minLength": 1,
            "title": "Pin",
            "type": "string"
          }
        },
        "required": [
          "pin"
        ],
        "title": "PinVerifyRequest",
        "type": "object"
      },
      "PresetOut": {
        "description": "Пресет-шаблон роли для формы «+ Своя роль»: заготовка с готовой персоной и scoped-набором\nинструментов (min-privilege под роль). Клиент подставляет в форму, человек правит.",
        "properties": {
          "description": {
            "title": "Description",
            "type": "string"
          },
          "icon": {
            "title": "Icon",
            "type": "string"
          },
          "key": {
            "title": "Key",
            "type": "string"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "persona": {
            "title": "Persona",
            "type": "string"
          },
          "toolsets": {
            "items": {
              "type": "string"
            },
            "title": "Toolsets",
            "type": "array"
          }
        },
        "required": [
          "key",
          "name",
          "description",
          "icon",
          "persona",
          "toolsets"
        ],
        "title": "PresetOut",
        "type": "object"
      },
      "ProtocolAccepted": {
        "properties": {
          "object_id": {
            "format": "uuid",
            "title": "Object Id",
            "type": "string"
          },
          "status": {
            "default": "accepted",
            "title": "Status",
            "type": "string"
          },
          "task_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Task Id"
          }
        },
        "required": [
          "object_id"
        ],
        "title": "ProtocolAccepted",
        "type": "object"
      },
      "ProtocolQuestionsOut": {
        "description": "Готовность к умному протоколу + уточняющие вопросы по недостающим полям (C3).",
        "properties": {
          "questions": {
            "items": {
              "type": "string"
            },
            "title": "Questions",
            "type": "array"
          },
          "ready": {
            "default": false,
            "title": "Ready",
            "type": "boolean"
          }
        },
        "title": "ProtocolQuestionsOut",
        "type": "object"
      },
      "ProtocolRequest": {
        "description": "Заявка на протокол ДОКУМЕНТОМ. Параллель агентному ``make_protocol``, но из интерфейса.",
        "properties": {
          "attachments": {
            "items": {
              "format": "uuid",
              "type": "string"
            },
            "maxItems": 5,
            "title": "Attachments",
            "type": "array"
          },
          "context": {
            "default": "",
            "maxLength": 2000,
            "title": "Context",
            "type": "string"
          },
          "fmt": {
            "default": "docx",
            "title": "Fmt",
            "type": "string"
          },
          "type": {
            "default": "protocol",
            "title": "Type",
            "type": "string"
          }
        },
        "title": "ProtocolRequest",
        "type": "object"
      },
      "ProtocolStatus": {
        "description": "Статус сборки протокола (как convert-status) + id готового файла, когда он появился.\n\n``stage``/``step``/``steps`` — текущий этап для полосы прогресса. Сборка по двухчасовой\nвстрече идёт минутами, и без этапа интерфейс неотличим от зависшего запроса.",
        "properties": {
          "detail": {
            "default": "",
            "title": "Detail",
            "type": "string"
          },
          "done": {
            "default": false,
            "title": "Done",
            "type": "boolean"
          },
          "filename": {
            "default": "",
            "title": "Filename",
            "type": "string"
          },
          "object_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Object Id"
          },
          "ok": {
            "default": false,
            "title": "Ok",
            "type": "boolean"
          },
          "stage": {
            "default": "",
            "title": "Stage",
            "type": "string"
          },
          "state": {
            "title": "State",
            "type": "string"
          },
          "step": {
            "default": 0,
            "title": "Step",
            "type": "integer"
          },
          "steps": {
            "default": 0,
            "title": "Steps",
            "type": "integer"
          }
        },
        "required": [
          "state"
        ],
        "title": "ProtocolStatus",
        "type": "object"
      },
      "QuotaOut": {
        "description": "Данные «кольца использования» (B2): месячные лимиты и остаток по плану.",
        "properties": {
          "audio_minutes": {
            "$ref": "#/components/schemas/QuotaResource"
          },
          "documents": {
            "$ref": "#/components/schemas/QuotaResource"
          },
          "period": {
            "default": "month",
            "title": "Period",
            "type": "string"
          },
          "plan": {
            "default": "free",
            "title": "Plan",
            "type": "string"
          }
        },
        "required": [
          "documents",
          "audio_minutes"
        ],
        "title": "QuotaOut",
        "type": "object"
      },
      "QuotaResource": {
        "description": "Остаток по ресурсу за месяц (B2). ``limit=None`` — безлимит (fair-use).",
        "properties": {
          "limit": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Limit"
          },
          "remaining": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Remaining"
          },
          "used": {
            "default": 0,
            "title": "Used",
            "type": "integer"
          }
        },
        "title": "QuotaResource",
        "type": "object"
      },
      "RecentQueryList": {
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/RecentQueryOut"
            },
            "title": "Items",
            "type": "array"
          },
          "total": {
            "default": 0,
            "title": "Total",
            "type": "integer"
          }
        },
        "title": "RecentQueryList",
        "type": "object"
      },
      "RecentQueryOut": {
        "description": "Последний запрос пользователя (25§6) — выводится из истории чатов.",
        "properties": {
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "query": {
            "title": "Query",
            "type": "string"
          },
          "session_id": {
            "format": "uuid",
            "title": "Session Id",
            "type": "string"
          },
          "title": {
            "default": "",
            "title": "Title",
            "type": "string"
          }
        },
        "required": [
          "query",
          "created_at",
          "session_id"
        ],
        "title": "RecentQueryOut",
        "type": "object"
      },
      "RedactBox": {
        "description": "Область для скрытия (redact) в нормализованных [0..1] координатах от размера страницы\n(0,0 — верхний левый угол). ``page`` — 1-индексный номер страницы.",
        "properties": {
          "page": {
            "maximum": 5001.0,
            "minimum": 1.0,
            "title": "Page",
            "type": "integer"
          },
          "x0": {
            "maximum": 1.0,
            "minimum": 0.0,
            "title": "X0",
            "type": "number"
          },
          "x1": {
            "maximum": 1.0,
            "minimum": 0.0,
            "title": "X1",
            "type": "number"
          },
          "y0": {
            "maximum": 1.0,
            "minimum": 0.0,
            "title": "Y0",
            "type": "number"
          },
          "y1": {
            "maximum": 1.0,
            "minimum": 0.0,
            "title": "Y1",
            "type": "number"
          }
        },
        "required": [
          "page",
          "x0",
          "y0",
          "x1",
          "y1"
        ],
        "title": "RedactBox",
        "type": "object"
      },
      "ReferralApply": {
        "properties": {
          "code": {
            "maxLength": 16,
            "minLength": 1,
            "title": "Code",
            "type": "string"
          }
        },
        "required": [
          "code"
        ],
        "title": "ReferralApply",
        "type": "object"
      },
      "ReferralApplyOut": {
        "properties": {
          "applied": {
            "title": "Applied",
            "type": "boolean"
          }
        },
        "required": [
          "applied"
        ],
        "title": "ReferralApplyOut",
        "type": "object"
      },
      "ReferralOut": {
        "properties": {
          "code": {
            "title": "Code",
            "type": "string"
          },
          "joined": {
            "default": 0,
            "title": "Joined",
            "type": "integer"
          }
        },
        "required": [
          "code"
        ],
        "title": "ReferralOut",
        "type": "object"
      },
      "ReorganizeAccepted": {
        "description": "Перераспределение принято (Celery): файлы «переедут» — видно живым опросом списка.",
        "properties": {
          "force": {
            "default": false,
            "title": "Force",
            "type": "boolean"
          },
          "status": {
            "default": "accepted",
            "title": "Status",
            "type": "string"
          },
          "task_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Task Id"
          }
        },
        "title": "ReorganizeAccepted",
        "type": "object"
      },
      "ReorganizeRequest": {
        "description": "AI-перераспределение по смыслу (29-12). ``force=False`` — только файлы без папки;\n``force=True`` — переразложить всё (дороже, под потолком ``reorganize_max_objects``).\n\n``reset=True`` («разложить всё заново», STORAGE_REDESIGN) — сначала снести ИИ-папки/темы и\nавто-связи, затем разложить с нуля. Ручные и расшаренные папки сохраняются. Имеет приоритет\nнад ``force`` (после сброса раскладываются все файлы без папки).",
        "properties": {
          "force": {
            "default": false,
            "title": "Force",
            "type": "boolean"
          },
          "reset": {
            "default": false,
            "title": "Reset",
            "type": "boolean"
          }
        },
        "title": "ReorganizeRequest",
        "type": "object"
      },
      "ReorganizeStatus": {
        "description": "Прогресс перераскладки (для индикатора «X из N»). Читается из Celery AsyncResult.",
        "properties": {
          "created_folders": {
            "default": 0,
            "title": "Created Folders",
            "type": "integer"
          },
          "created_themes": {
            "default": 0,
            "title": "Created Themes",
            "type": "integer"
          },
          "done": {
            "default": false,
            "title": "Done",
            "type": "boolean"
          },
          "moved": {
            "default": 0,
            "title": "Moved",
            "type": "integer"
          },
          "phase": {
            "default": "",
            "title": "Phase",
            "type": "string"
          },
          "processed": {
            "default": 0,
            "title": "Processed",
            "type": "integer"
          },
          "skipped": {
            "default": 0,
            "title": "Skipped",
            "type": "integer"
          },
          "state": {
            "title": "State",
            "type": "string"
          },
          "total": {
            "default": 0,
            "title": "Total",
            "type": "integer"
          }
        },
        "required": [
          "state"
        ],
        "title": "ReorganizeStatus",
        "type": "object"
      },
      "RevisionList": {
        "description": "История версий файла, новые первыми.",
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/RevisionOut"
            },
            "title": "Items",
            "type": "array"
          }
        },
        "title": "RevisionList",
        "type": "object"
      },
      "RevisionOut": {
        "description": "Ревизия содержимого файла (E0) — иммутабельный снимок прежних байтов в S3.\n\nРевизия снимается ПЕРЕД каждой перезаписью, поэтому хранит состояние ДО правки.\n``author`` — owner_id того, кто сохранил (``None`` — система/агент/конвейер).\n``is_current``=True — содержимое снимка совпадает с текущим содержимым файла\n(так подсвечивается точка, в которую только что откатились).",
        "properties": {
          "author": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Author"
          },
          "content_hash": {
            "default": "",
            "title": "Content Hash",
            "type": "string"
          },
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "filename": {
            "default": "",
            "title": "Filename",
            "type": "string"
          },
          "is_current": {
            "default": false,
            "title": "Is Current",
            "type": "boolean"
          },
          "size": {
            "default": 0,
            "title": "Size",
            "type": "integer"
          },
          "version": {
            "title": "Version",
            "type": "integer"
          }
        },
        "required": [
          "version",
          "created_at"
        ],
        "title": "RevisionOut",
        "type": "object"
      },
      "RewriteOut": {
        "properties": {
          "mode": {
            "title": "Mode",
            "type": "string"
          },
          "text": {
            "title": "Text",
            "type": "string"
          }
        },
        "required": [
          "mode",
          "text"
        ],
        "title": "RewriteOut",
        "type": "object"
      },
      "RewriteRequest": {
        "description": "Переписать/форматировать текст по пресету (см. ``services.rewrite.REWRITE_MODES``).",
        "properties": {
          "mode": {
            "default": "shorter",
            "title": "Mode",
            "type": "string"
          },
          "model": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Model"
          },
          "text": {
            "maxLength": 20000,
            "minLength": 1,
            "title": "Text",
            "type": "string"
          }
        },
        "required": [
          "text"
        ],
        "title": "RewriteRequest",
        "type": "object"
      },
      "S3SaveIn": {
        "description": "Сохранение своего S3-совместимого хранилища.",
        "properties": {
          "access_key": {
            "anyOf": [
              {
                "maxLength": 200,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Access Key"
          },
          "addressing": {
            "default": "path",
            "maxLength": 16,
            "title": "Addressing",
            "type": "string"
          },
          "bucket": {
            "maxLength": 200,
            "title": "Bucket",
            "type": "string"
          },
          "endpoint_url": {
            "maxLength": 500,
            "title": "Endpoint Url",
            "type": "string"
          },
          "region": {
            "default": "",
            "maxLength": 64,
            "title": "Region",
            "type": "string"
          },
          "secret_key": {
            "anyOf": [
              {
                "maxLength": 400,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Secret Key"
          }
        },
        "required": [
          "endpoint_url",
          "bucket"
        ],
        "title": "S3SaveIn",
        "type": "object"
      },
      "SearchHit": {
        "properties": {
          "doc_type": {
            "default": "other",
            "title": "Doc Type",
            "type": "string"
          },
          "filename": {
            "default": "",
            "title": "Filename",
            "type": "string"
          },
          "object_id": {
            "format": "uuid",
            "title": "Object Id",
            "type": "string"
          },
          "score": {
            "default": 0.0,
            "title": "Score",
            "type": "number"
          },
          "snippet": {
            "default": "",
            "title": "Snippet",
            "type": "string"
          },
          "summary": {
            "default": "",
            "title": "Summary",
            "type": "string"
          },
          "title": {
            "default": "",
            "title": "Title",
            "type": "string"
          }
        },
        "required": [
          "object_id"
        ],
        "title": "SearchHit",
        "type": "object"
      },
      "SearchResponse": {
        "properties": {
          "hits": {
            "items": {
              "$ref": "#/components/schemas/SearchHit"
            },
            "title": "Hits",
            "type": "array"
          },
          "query": {
            "title": "Query",
            "type": "string"
          }
        },
        "required": [
          "query"
        ],
        "title": "SearchResponse",
        "type": "object"
      },
      "SettingsOut": {
        "properties": {
          "auto_rename_mode": {
            "default": "dont_rename",
            "title": "Auto Rename Mode",
            "type": "string"
          },
          "calendar_reminders_telegram": {
            "default": false,
            "title": "Calendar Reminders Telegram",
            "type": "boolean"
          },
          "chat_memory": {
            "default": true,
            "title": "Chat Memory",
            "type": "boolean"
          },
          "prefs": {
            "additionalProperties": true,
            "default": {},
            "title": "Prefs",
            "type": "object"
          },
          "proactive": {
            "default": false,
            "title": "Proactive",
            "type": "boolean"
          },
          "timezone": {
            "default": "",
            "title": "Timezone",
            "type": "string"
          },
          "ui": {
            "additionalProperties": true,
            "default": {},
            "title": "Ui",
            "type": "object"
          }
        },
        "title": "SettingsOut",
        "type": "object"
      },
      "SettingsUpdate": {
        "properties": {
          "auto_rename_mode": {
            "anyOf": [
              {
                "enum": [
                  "auto",
                  "dont_rename",
                  "manual"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Auto Rename Mode"
          },
          "calendar_reminders_telegram": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Calendar Reminders Telegram"
          },
          "chat_memory": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Chat Memory"
          },
          "proactive": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Proactive"
          },
          "timezone": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Timezone"
          },
          "ui": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Ui"
          }
        },
        "title": "SettingsUpdate",
        "type": "object"
      },
      "ShareCreate": {
        "properties": {
          "expires_in_days": {
            "anyOf": [
              {
                "maximum": 3650.0,
                "minimum": 1.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Expires In Days"
          },
          "kind": {
            "enum": [
              "folder",
              "file"
            ],
            "title": "Kind",
            "type": "string"
          },
          "name": {
            "default": "",
            "maxLength": 200,
            "title": "Name",
            "type": "string"
          },
          "password": {
            "anyOf": [
              {
                "maxLength": 128,
                "minLength": 6,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Password"
          },
          "resource_id": {
            "format": "uuid",
            "title": "Resource Id",
            "type": "string"
          },
          "role": {
            "default": "viewer",
            "enum": [
              "viewer",
              "contributor"
            ],
            "title": "Role",
            "type": "string"
          }
        },
        "required": [
          "kind",
          "resource_id"
        ],
        "title": "ShareCreate",
        "type": "object"
      },
      "ShareLinkOut": {
        "properties": {
          "access_count": {
            "default": 0,
            "title": "Access Count",
            "type": "integer"
          },
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "expires_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Expires At"
          },
          "has_password": {
            "default": false,
            "title": "Has Password",
            "type": "boolean"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "kind": {
            "enum": [
              "folder",
              "file"
            ],
            "title": "Kind",
            "type": "string"
          },
          "prefix": {
            "default": "",
            "title": "Prefix",
            "type": "string"
          },
          "resource_id": {
            "format": "uuid",
            "title": "Resource Id",
            "type": "string"
          },
          "resource_name": {
            "default": "",
            "title": "Resource Name",
            "type": "string"
          },
          "revoked_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Revoked At"
          },
          "role": {
            "default": "viewer",
            "enum": [
              "viewer",
              "contributor"
            ],
            "title": "Role",
            "type": "string"
          },
          "token": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Token"
          },
          "upload_count": {
            "default": 0,
            "title": "Upload Count",
            "type": "integer"
          },
          "url": {
            "default": "",
            "title": "Url",
            "type": "string"
          }
        },
        "required": [
          "id",
          "kind",
          "resource_id",
          "created_at"
        ],
        "title": "ShareLinkOut",
        "type": "object"
      },
      "ShareList": {
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/ShareLinkOut"
            },
            "title": "Items",
            "type": "array"
          },
          "total": {
            "default": 0,
            "title": "Total",
            "type": "integer"
          }
        },
        "title": "ShareList",
        "type": "object"
      },
      "ShareMeta": {
        "description": "Метаданные ссылки для публичной страницы. При защите паролём без верного пароля\nконтент (список/имя) не раскрывается — только ``needs_password``.",
        "properties": {
          "can_upload": {
            "default": false,
            "title": "Can Upload",
            "type": "boolean"
          },
          "count": {
            "default": 0,
            "title": "Count",
            "type": "integer"
          },
          "kind": {
            "enum": [
              "folder",
              "file"
            ],
            "title": "Kind",
            "type": "string"
          },
          "name": {
            "default": "",
            "title": "Name",
            "type": "string"
          },
          "needs_password": {
            "default": false,
            "title": "Needs Password",
            "type": "boolean"
          },
          "object": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SharePublicObject"
              },
              {
                "type": "null"
              }
            ]
          },
          "object_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Object Id"
          },
          "role": {
            "default": "viewer",
            "enum": [
              "viewer",
              "contributor"
            ],
            "title": "Role",
            "type": "string"
          }
        },
        "required": [
          "kind"
        ],
        "title": "ShareMeta",
        "type": "object"
      },
      "SharePublicList": {
        "properties": {
          "can_upload": {
            "default": false,
            "title": "Can Upload",
            "type": "boolean"
          },
          "folder_name": {
            "default": "",
            "title": "Folder Name",
            "type": "string"
          },
          "items": {
            "items": {
              "$ref": "#/components/schemas/SharePublicObject"
            },
            "title": "Items",
            "type": "array"
          },
          "total": {
            "default": 0,
            "title": "Total",
            "type": "integer"
          }
        },
        "title": "SharePublicList",
        "type": "object"
      },
      "SharePublicObject": {
        "description": "Лёгкое представление файла для публичной страницы (без внутренних подсказок/полей).",
        "properties": {
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "display_name": {
            "default": "",
            "title": "Display Name",
            "type": "string"
          },
          "doc_type": {
            "default": "other",
            "title": "Doc Type",
            "type": "string"
          },
          "filename": {
            "default": "",
            "title": "Filename",
            "type": "string"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "kind": {
            "default": "",
            "title": "Kind",
            "type": "string"
          },
          "mime": {
            "default": "",
            "title": "Mime",
            "type": "string"
          },
          "size": {
            "default": 0,
            "title": "Size",
            "type": "integer"
          },
          "status": {
            "default": "",
            "title": "Status",
            "type": "string"
          },
          "text_view": {
            "default": false,
            "title": "Text View",
            "type": "boolean"
          }
        },
        "required": [
          "id",
          "created_at"
        ],
        "title": "SharePublicObject",
        "type": "object"
      },
      "ShareUploadOut": {
        "properties": {
          "duplicate": {
            "default": false,
            "title": "Duplicate",
            "type": "boolean"
          },
          "filename": {
            "default": "",
            "title": "Filename",
            "type": "string"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "status": {
            "default": "",
            "title": "Status",
            "type": "string"
          }
        },
        "required": [
          "id"
        ],
        "title": "ShareUploadOut",
        "type": "object"
      },
      "SpeakerRenames": {
        "properties": {
          "names": {
            "additionalProperties": {
              "type": "string"
            },
            "title": "Names",
            "type": "object"
          }
        },
        "required": [
          "names"
        ],
        "title": "SpeakerRenames",
        "type": "object"
      },
      "StorageMigrationOut": {
        "description": "Состояние переноса уже загруженных файлов в свой бакет.",
        "properties": {
          "error": {
            "default": "",
            "title": "Error",
            "type": "string"
          },
          "failed": {
            "default": 0,
            "title": "Failed",
            "type": "integer"
          },
          "finished_at": {
            "default": "",
            "title": "Finished At",
            "type": "string"
          },
          "moved": {
            "default": 0,
            "title": "Moved",
            "type": "integer"
          },
          "remaining": {
            "default": 0,
            "title": "Remaining",
            "type": "integer"
          },
          "started_at": {
            "default": "",
            "title": "Started At",
            "type": "string"
          },
          "status": {
            "title": "Status",
            "type": "string"
          },
          "total": {
            "default": 0,
            "title": "Total",
            "type": "integer"
          }
        },
        "required": [
          "status"
        ],
        "title": "StorageMigrationOut",
        "type": "object"
      },
      "SuggestedQuestionsOut": {
        "description": "Предлагаемые вопросы по документу (Ф2): UI показывает кликабельными подсказками над чатом.",
        "properties": {
          "object_id": {
            "format": "uuid",
            "title": "Object Id",
            "type": "string"
          },
          "questions": {
            "items": {
              "type": "string"
            },
            "title": "Questions",
            "type": "array"
          }
        },
        "required": [
          "object_id"
        ],
        "title": "SuggestedQuestionsOut",
        "type": "object"
      },
      "SummarizeRequest": {
        "description": "Конспект нужного типа (C4/§3.4). ``context`` — уточнения для умного протокола (C3).",
        "properties": {
          "context": {
            "default": "",
            "maxLength": 2000,
            "title": "Context",
            "type": "string"
          },
          "model": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Model"
          },
          "type": {
            "default": "short",
            "enum": [
              "short",
              "detailed",
              "tasks",
              "protocol",
              "meeting",
              "lecture",
              "consultation",
              "standup"
            ],
            "title": "Type",
            "type": "string"
          }
        },
        "title": "SummarizeRequest",
        "type": "object"
      },
      "SummaryOut": {
        "description": "Карточка содержания объекта (Ф9, B1): метаданные из ``Enrichment`` без LLM-затрат.\n\n``status`` отдаётся всегда; при ``pending/processing/failed`` поля обогащения пусты\n(объект ещё не обработан) — клиент показывает статус, а не падает.",
        "properties": {
          "description": {
            "default": "",
            "title": "Description",
            "type": "string"
          },
          "doc_type": {
            "default": "other",
            "title": "Doc Type",
            "type": "string"
          },
          "entities": {
            "additionalProperties": true,
            "title": "Entities",
            "type": "object"
          },
          "filename": {
            "default": "",
            "title": "Filename",
            "type": "string"
          },
          "keywords": {
            "items": {
              "type": "string"
            },
            "title": "Keywords",
            "type": "array"
          },
          "language": {
            "default": "",
            "title": "Language",
            "type": "string"
          },
          "object_id": {
            "format": "uuid",
            "title": "Object Id",
            "type": "string"
          },
          "status": {
            "title": "Status",
            "type": "string"
          },
          "summary": {
            "default": "",
            "title": "Summary",
            "type": "string"
          },
          "title": {
            "default": "",
            "title": "Title",
            "type": "string"
          }
        },
        "required": [
          "object_id",
          "status"
        ],
        "title": "SummaryOut",
        "type": "object"
      },
      "SummaryTextOut": {
        "properties": {
          "text": {
            "title": "Text",
            "type": "string"
          },
          "type": {
            "title": "Type",
            "type": "string"
          }
        },
        "required": [
          "type",
          "text"
        ],
        "title": "SummaryTextOut",
        "type": "object"
      },
      "TaskList": {
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/TaskOut"
            },
            "title": "Items",
            "type": "array"
          },
          "open": {
            "default": 0,
            "title": "Open",
            "type": "integer"
          },
          "overdue": {
            "default": 0,
            "title": "Overdue",
            "type": "integer"
          }
        },
        "required": [
          "items"
        ],
        "title": "TaskList",
        "type": "object"
      },
      "TaskOut": {
        "properties": {
          "assignee": {
            "default": "",
            "title": "Assignee",
            "type": "string"
          },
          "done_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Done At"
          },
          "due_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Due At"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "number": {
            "title": "Number",
            "type": "integer"
          },
          "overdue": {
            "default": false,
            "title": "Overdue",
            "type": "boolean"
          },
          "source_object_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Source Object Id"
          },
          "status": {
            "title": "Status",
            "type": "string"
          },
          "title": {
            "title": "Title",
            "type": "string"
          }
        },
        "required": [
          "id",
          "number",
          "title",
          "status"
        ],
        "title": "TaskOut",
        "type": "object"
      },
      "TaskUpdate": {
        "properties": {
          "status": {
            "pattern": "^(open|done)$",
            "title": "Status",
            "type": "string"
          }
        },
        "required": [
          "status"
        ],
        "title": "TaskUpdate",
        "type": "object"
      },
      "TelegramBindRequest": {
        "properties": {
          "code": {
            "title": "Code",
            "type": "string"
          },
          "tg_id": {
            "title": "Tg Id",
            "type": "integer"
          },
          "username": {
            "default": "",
            "title": "Username",
            "type": "string"
          }
        },
        "required": [
          "code",
          "tg_id"
        ],
        "title": "TelegramBindRequest",
        "type": "object"
      },
      "TextContentOut": {
        "description": "Редактируемый текст файла для встроенного редактора.\n\n``editable``=False — формат нельзя редактировать «как текст» (медиа/картинка/архив).\n``format`` — как трактовать текст в редакторе (markdown|plain|html); для docx/pdf это\nизвлечённый текст (markdown), правки пересобираются в исходный формат при сохранении.",
        "properties": {
          "editable": {
            "default": false,
            "title": "Editable",
            "type": "boolean"
          },
          "filename": {
            "default": "",
            "title": "Filename",
            "type": "string"
          },
          "format": {
            "default": "plain",
            "title": "Format",
            "type": "string"
          },
          "reason": {
            "default": "",
            "title": "Reason",
            "type": "string"
          },
          "text": {
            "default": "",
            "title": "Text",
            "type": "string"
          },
          "version": {
            "default": 1,
            "title": "Version",
            "type": "integer"
          }
        },
        "title": "TextContentOut",
        "type": "object"
      },
      "ThemeCreate": {
        "properties": {
          "icon": {
            "default": "",
            "maxLength": 32,
            "title": "Icon",
            "type": "string"
          },
          "is_hidden": {
            "default": false,
            "title": "Is Hidden",
            "type": "boolean"
          },
          "name": {
            "maxLength": 200,
            "minLength": 1,
            "title": "Name",
            "type": "string"
          }
        },
        "required": [
          "name"
        ],
        "title": "ThemeCreate",
        "type": "object"
      },
      "ThemeList": {
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/ThemeOut"
            },
            "title": "Items",
            "type": "array"
          },
          "total": {
            "default": 0,
            "title": "Total",
            "type": "integer"
          }
        },
        "title": "ThemeList",
        "type": "object"
      },
      "ThemeOut": {
        "properties": {
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "folder_count": {
            "default": 0,
            "title": "Folder Count",
            "type": "integer"
          },
          "icon": {
            "default": "",
            "title": "Icon",
            "type": "string"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "is_hidden": {
            "default": false,
            "title": "Is Hidden",
            "type": "boolean"
          },
          "name": {
            "title": "Name",
            "type": "string"
          }
        },
        "required": [
          "id",
          "name",
          "created_at"
        ],
        "title": "ThemeOut",
        "type": "object"
      },
      "ThemeUpdate": {
        "properties": {
          "icon": {
            "anyOf": [
              {
                "maxLength": 32,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Icon"
          },
          "is_hidden": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Is Hidden"
          },
          "name": {
            "anyOf": [
              {
                "maxLength": 200,
                "minLength": 1,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name"
          }
        },
        "title": "ThemeUpdate",
        "type": "object"
      },
      "TokenUsage": {
        "description": "Расход одного API-ключа.\n\n``token_id=None`` — строка-остаток: работа в приложении, фоновые задачи и всё, что\nзаписано до появления учёта по ключам. Не «неизвестный ключ», а «не через ключ», и\nбез этой строки сумма разбивки не сошлась бы с общим расходом.",
        "properties": {
          "calls": {
            "default": 0,
            "title": "Calls",
            "type": "integer"
          },
          "cost_rub": {
            "default": 0.0,
            "title": "Cost Rub",
            "type": "number"
          },
          "name": {
            "default": "",
            "title": "Name",
            "type": "string"
          },
          "prefix": {
            "default": "",
            "title": "Prefix",
            "type": "string"
          },
          "revoked": {
            "default": false,
            "title": "Revoked",
            "type": "boolean"
          },
          "token_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Token Id"
          }
        },
        "title": "TokenUsage",
        "type": "object"
      },
      "TokenUsageList": {
        "properties": {
          "days": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Days"
          },
          "items": {
            "default": [],
            "items": {
              "$ref": "#/components/schemas/TokenUsage"
            },
            "title": "Items",
            "type": "array"
          },
          "total_cost_rub": {
            "default": 0.0,
            "title": "Total Cost Rub",
            "type": "number"
          }
        },
        "title": "TokenUsageList",
        "type": "object"
      },
      "ToolsetOut": {
        "description": "Группа инструментов для конструктора: что человек отмечает галочкой.",
        "properties": {
          "description": {
            "title": "Description",
            "type": "string"
          },
          "key": {
            "title": "Key",
            "type": "string"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "tools": {
            "title": "Tools",
            "type": "integer"
          }
        },
        "required": [
          "key",
          "name",
          "description",
          "tools"
        ],
        "title": "ToolsetOut",
        "type": "object"
      },
      "TranscriptOut": {
        "properties": {
          "chars": {
            "default": 0,
            "title": "Chars",
            "type": "integer"
          },
          "diarized": {
            "default": false,
            "title": "Diarized",
            "type": "boolean"
          },
          "object_id": {
            "format": "uuid",
            "title": "Object Id",
            "type": "string"
          },
          "ready": {
            "default": false,
            "title": "Ready",
            "type": "boolean"
          },
          "text": {
            "default": "",
            "title": "Text",
            "type": "string"
          }
        },
        "required": [
          "object_id"
        ],
        "title": "TranscriptOut",
        "type": "object"
      },
      "TranscriptResponse": {
        "properties": {
          "text": {
            "title": "Text",
            "type": "string"
          }
        },
        "required": [
          "text"
        ],
        "title": "TranscriptResponse",
        "type": "object"
      },
      "TranslateAccepted": {
        "properties": {
          "duplicate": {
            "default": false,
            "title": "Duplicate",
            "type": "boolean"
          },
          "object_id": {
            "format": "uuid",
            "title": "Object Id",
            "type": "string"
          },
          "status": {
            "title": "Status",
            "type": "string"
          }
        },
        "required": [
          "object_id",
          "status"
        ],
        "title": "TranslateAccepted",
        "type": "object"
      },
      "TranslateRequest": {
        "properties": {
          "target_lang": {
            "maxLength": 40,
            "minLength": 1,
            "title": "Target Lang",
            "type": "string"
          }
        },
        "required": [
          "target_lang"
        ],
        "title": "TranslateRequest",
        "type": "object"
      },
      "UsageBreakdown": {
        "properties": {
          "days": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Days"
          },
          "owners": {
            "default": [],
            "items": {
              "$ref": "#/components/schemas/OwnerUsage"
            },
            "title": "Owners",
            "type": "array"
          },
          "total_cost_rub": {
            "default": 0.0,
            "title": "Total Cost Rub",
            "type": "number"
          }
        },
        "title": "UsageBreakdown",
        "type": "object"
      },
      "UsagePoint": {
        "description": "Точка дневного графика расхода (Ф7): дата + ₽ + токены + вызовы за день.",
        "properties": {
          "calls": {
            "default": 0,
            "title": "Calls",
            "type": "integer"
          },
          "cost_rub": {
            "default": 0.0,
            "title": "Cost Rub",
            "type": "number"
          },
          "date": {
            "title": "Date",
            "type": "string"
          },
          "total_tokens": {
            "default": 0,
            "title": "Total Tokens",
            "type": "integer"
          }
        },
        "required": [
          "date"
        ],
        "title": "UsagePoint",
        "type": "object"
      },
      "UsageSummary": {
        "properties": {
          "by_meter": {
            "default": [],
            "items": {
              "$ref": "#/components/schemas/MeterCost"
            },
            "title": "By Meter",
            "type": "array"
          },
          "days": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Days"
          },
          "owner_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Owner Id"
          },
          "total_cost_rub": {
            "default": 0.0,
            "title": "Total Cost Rub",
            "type": "number"
          }
        },
        "title": "UsageSummary",
        "type": "object"
      },
      "ValidationError": {
        "properties": {
          "ctx": {
            "title": "Context",
            "type": "object"
          },
          "input": {
            "title": "Input"
          },
          "loc": {
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "integer"
                }
              ]
            },
            "title": "Location",
            "type": "array"
          },
          "msg": {
            "title": "Message",
            "type": "string"
          },
          "type": {
            "title": "Error Type",
            "type": "string"
          }
        },
        "required": [
          "loc",
          "msg",
          "type"
        ],
        "title": "ValidationError",
        "type": "object"
      },
      "VoiceProfileOut": {
        "properties": {
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "samples": {
            "title": "Samples",
            "type": "integer"
          }
        },
        "required": [
          "id",
          "name",
          "samples"
        ],
        "title": "VoiceProfileOut",
        "type": "object"
      },
      "ZipAccepted": {
        "description": "Архивация принята: результат появится НОВЫМ объектом-ZIP в списке (Celery).",
        "properties": {
          "collection_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Collection Id"
          },
          "count": {
            "default": 0,
            "title": "Count",
            "type": "integer"
          },
          "status": {
            "default": "accepted",
            "title": "Status",
            "type": "string"
          }
        },
        "title": "ZipAccepted",
        "type": "object"
      },
      "ZipRequest": {
        "description": "Архивация выбранных объектов в один ZIP-файл.",
        "properties": {
          "name": {
            "anyOf": [
              {
                "maxLength": 255,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name"
          },
          "object_ids": {
            "items": {
              "format": "uuid",
              "type": "string"
            },
            "maxItems": 500,
            "minItems": 1,
            "title": "Object Ids",
            "type": "array"
          }
        },
        "required": [
          "object_ids"
        ],
        "title": "ZipRequest",
        "type": "object"
      }
    },
    "securitySchemes": {
      "bearerAuth": {
        "description": "Токен `ak_…` из приложения [app.agentums.ru](https://app.agentums.ru): **Настройки → API-токены → Создать**. Показывается один раз; скомпрометированный — отозвать там же.",
        "scheme": "bearer",
        "type": "http"
      }
    }
  },
  "info": {
    "description": "REST-контракт умного облака: загрузка документов, поиск по смыслу, ответы с цитатами,\nпреобразования файлов и агент с инструментами.\n\n* Авторизация — `Authorization: Bearer ak_…`. Токен выпускается в приложении и видит только\n  файлы своего аккаунта.\n* Загрузка **асинхронна**: объект отвечает `status=\"pending\"`, пока не обработан. Искать по\n  содержимому сразу после загрузки бесполезно — дождитесь готовности.\n* Тяжёлые операции возвращают `task_id`; готовность спрашивается у соответствующего\n  `*/status`-маршрута.\n\nГотовый клиент на Python — `pip install agentum-cloud-sdk`.",
    "title": "Agentum Cloud API",
    "version": "1.0.590"
  },
  "openapi": "3.1.0",
  "paths": {
    "/health": {
      "get": {
        "description": "Живо ли приложение. Отвечает сам процесс, зависимости не опрашивает — поэтому `ok`\nздесь не означает, что запросы будут работать; для этого есть `/health/deep`.",
        "operationId": "health_health_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HealthOut"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "security": [],
        "summary": "Health",
        "tags": [
          "health"
        ]
      }
    },
    "/health/deep": {
      "get": {
        "description": "Состояние зависимостей: база, кэш, векторный индекс, хранилище, модель.\n\nТребует токен — в отличие от `/health`: перечень внутренних сервисов не для анонимного\nчитателя. `503` тут штатный ответ, а не сбой: он приходит с телом, и именно ради\nразбора `checks` ручку и зовут.",
        "operationId": "health_deep_health_deep_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeepHealthOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Health Deep",
        "tags": [
          "health"
        ]
      }
    },
    "/v1/agent/chat": {
      "post": {
        "description": "Агент с инструментами: сам решает, что сделать с файлами, и стримит ход работы.\n\nВ отличие от `/chat` агент действует: ищет, конвертирует, переводит, собирает PDF,\nзаводит поручения. Ответ — поток SSE-событий: `start`, `token` (кусочки текста),\n`tool_start` / `tool_end`, `paused`, `error`, `done`.\n\nФорма потока — два правила, которые легко нарушить, и оба стоят потерянных данных:\n\n* **`paused` — конец потока.** `done` за ним НЕ придёт: агент упёрся в опасный\n  инструмент (перезапись файла, необратимое действие) и ждёт решения. Продолжают ран\n  через `POST /agent/continue`, передавая решения по ВСЕМ инструментам из события одним\n  вызовом — не упомянутый инструмент молча не выполнится.\n* **`error` — не конец потока.** За кадром с ошибкой могут прийти ещё токены и `done`.\n  Выйти из цикла по `error` значит потерять хвост ответа.\n\n`session_id` из `start`/`done` продолжает разговор следующим вызовом. `collection_id`\nограничивает работу папкой, `scope_object_ids` (до 25) — конкретными файлами: это\nсужение поиска инструментов, а не выдача доступа. `web_search` — политика «можно ли\nвообще», решение идти в сеть принимает сам агент.\n\nОшибки приходят до потока, обычным ответом: `503` — агентный режим выключен на сервере,\n`402` — исчерпан месячный лимит.",
        "operationId": "agent_chat_v1_agent_chat_post",
        "parameters": [
          {
            "in": "header",
            "name": "x-hidden-token",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Hidden-Token"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AgentChatRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              },
              "text/event-stream": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "description": "Поток событий SSE: кадры data: {...} с полем type (start|token|tool_start|tool_end|paused|error|done). paused — терминальный кадр (ран ждёт /agent/continue), error — НЕ терминальный: за ним ещё могут прийти токены и done."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Agent Chat",
        "tags": [
          "agent"
        ]
      }
    },
    "/v1/agent/continue": {
      "post": {
        "description": "Продолжить приостановленный ран (HITL): применить решения по опасным инструментам и стримить.",
        "operationId": "agent_continue_v1_agent_continue_post",
        "parameters": [
          {
            "in": "header",
            "name": "x-hidden-token",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Hidden-Token"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AgentContinueRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              },
              "text/event-stream": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "description": "Поток событий SSE: кадры data: {...} с полем type (start|token|tool_start|tool_end|paused|error|done). paused — терминальный кадр (ран ждёт /agent/continue), error — НЕ терминальный: за ним ещё могут прийти токены и done."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Agent Continue",
        "tags": [
          "agent"
        ]
      }
    },
    "/v1/agent/memory": {
      "delete": {
        "description": "Стереть всю память пользователя (только его).",
        "operationId": "clear_memory_v1_agent_memory_delete",
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Clear Memory",
        "tags": [
          "agent"
        ]
      },
      "get": {
        "description": "Что ИИ запомнил о пользователе (только его память — scoped по owner_id).",
        "operationId": "list_memory_v1_agent_memory_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemoryList"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Memory",
        "tags": [
          "agent"
        ]
      }
    },
    "/v1/agent/memory/{memory_id}": {
      "delete": {
        "description": "Удалить один выученный факт (scoped: чужой факт не тронется).",
        "operationId": "delete_memory_v1_agent_memory__memory_id__delete",
        "parameters": [
          {
            "in": "path",
            "name": "memory_id",
            "required": true,
            "schema": {
              "title": "Memory Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Delete Memory",
        "tags": [
          "agent"
        ]
      }
    },
    "/v1/agent/proactive": {
      "get": {
        "description": "Проактивные подсказки владельцу (Ф4) — только при agent_proactive_enabled И opt-in владельца.\n\nДёшево (метаданные, без LLM). Пусто, если проактивность выключена глобально или владельцем.",
        "operationId": "proactive_v1_agent_proactive_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemorySuggestionsList"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Proactive",
        "tags": [
          "agent"
        ]
      }
    },
    "/v1/agent/status": {
      "get": {
        "description": "Capability-флаги: доступен ли агентный режим, память и какая модель (фронт по ним решает UI).",
        "operationId": "agent_status_v1_agent_status_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgentStatus"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "security": [],
        "summary": "Agent Status",
        "tags": [
          "agent"
        ]
      }
    },
    "/v1/agent/task/{task_id}": {
      "get": {
        "description": "Чем кончилась фоновая задача, ``task_id`` которой уехал в кадре ``tool_end``.\n\n``require_key``, а не ``rate_limit()``: эндпоинт опросный (клиент дёргает его раз в\nсекунду до готовности), и лимитер выключил бы ровно тот сценарий, ради которого он есть.\nРазбор состояния — общий с ``/objects/pdf-status`` и ``/objects/content-status``\n(``services.task_status``), третьей копии правил «что считать завершённым» не заводим.\n\nБЕЗОПАСНОСТЬ. ``task_id`` не несёт владельца: любой аутентифицированный пользователь может\nподставить сюда чужой id (и подобрать — это uuid4 задачи Celery). Поэтому наружу уходит\nровно два вида сведений:\n  * ``ok`` — булев исход. По нему злоумышленник узнаёт только то, что какая-то задача с\n    таким id завершилась успешно; ни файла, ни владельца, ни операции в этом нет;\n  * ``note`` — человеческая подпись. Имя файла в неё попадает ТОЛЬКО если объект из\n    результата задачи принадлежит спрашивающему (``_resolve_filename`` скоупит запрос по\n    tenant+owner). Чужой файл даёт нейтральное «Готово» — то есть по чужому task_id нельзя\n    достать ни имя файла, ни его id.\nСоседние ``/pdf-status``/``/content-status`` отдают ``object_id`` и ``filename`` любому\nаутентифицированному по task_id и оправдываются тем, что открытие файла всё равно\nпроверяет владельца; имя файла — уже само по себе содержимое, и повторять это здесь\nнезачем: агентному клиенту хватает ``ok`` и подписи.",
        "operationId": "agent_task_status_v1_agent_task__task_id__get",
        "parameters": [
          {
            "in": "path",
            "name": "task_id",
            "required": true,
            "schema": {
              "title": "Task Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgentTaskStatus"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Agent Task Status",
        "tags": [
          "agent"
        ]
      }
    },
    "/v1/agents": {
      "get": {
        "description": "Каталог ролей: что есть, что закрыто тарифом, кто сейчас активен.\n\n``active`` отдаём из ``resolve``, а не из сырых настроек: если оплаченный когда-то профиль\nзакрылся после истечения тарифа, клиент обязан увидеть тот, с которым РЕАЛЬНО пойдёт ран,\nиначе экран будет показывать «Секретарь», а отвечать будет обычный ассистент.",
        "operationId": "list_agents_v1_agents_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgentCatalogOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Agents",
        "tags": [
          "agents"
        ]
      }
    },
    "/v1/agents/custom": {
      "post": {
        "description": "Завести свою роль. Активной она при этом НЕ становится — включение отдельным действием.",
        "operationId": "create_custom_agent_v1_agents_custom_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AgentProfileIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgentProfileOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Create Custom Agent",
        "tags": [
          "agents"
        ]
      }
    },
    "/v1/agents/custom/{slug}": {
      "delete": {
        "description": "Удалить свою роль. Если она была активной, активной станет «Помощник».",
        "operationId": "delete_custom_agent_v1_agents_custom__slug__delete",
        "parameters": [
          {
            "in": "path",
            "name": "slug",
            "required": true,
            "schema": {
              "title": "Slug",
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Delete Custom Agent",
        "tags": [
          "agents"
        ]
      },
      "patch": {
        "description": "Поправить свою роль. Изменённая персона подхватывается следующим ходом.\n\nОтдельного сброса кэша сборок не нужно: он ключуется отпечатком персоны и набора\n(``routers/agent._profile_fingerprint``), поэтому правка сама даёт другой ключ.",
        "operationId": "update_custom_agent_v1_agents_custom__slug__patch",
        "parameters": [
          {
            "in": "path",
            "name": "slug",
            "required": true,
            "schema": {
              "title": "Slug",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AgentProfileUpdateIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgentProfileOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Update Custom Agent",
        "tags": [
          "agents"
        ]
      }
    },
    "/v1/agents/{slug}/activate": {
      "post": {
        "description": "Сделать роль активной.\n\nГейт по тарифу проверяется ЗДЕСЬ, а не только при выдаче каталога: пометка ``locked`` в\nсписке — подсказка интерфейсу, а не защита, и прямой POST мимо экрана её не увидит.",
        "operationId": "activate_agent_v1_agents__slug__activate_post",
        "parameters": [
          {
            "in": "path",
            "name": "slug",
            "required": true,
            "schema": {
              "title": "Slug",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgentActivateOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Activate Agent",
        "tags": [
          "agents"
        ]
      }
    },
    "/v1/ask": {
      "post": {
        "description": "Ответить по содержимому своих файлов, с цитатами на источники.\n\nСервер сам подбирает подходящие фрагменты и синтезирует ответ. `citations` — куски,\nна которых ответ построен; `primary` — файл, закреплённый под запрос целиком («найди\nдоговор с Ромашкой» → вот он), и он бывает нужнее самого текста ответа.\n`used_context=false` означает, что в файлах ничего не нашлось и ответ построен без них.\n\n`session_id` продолжает разговор: верните полученный из ответа идентификатор в\nследующий запрос, иначе «а подробнее?» уйдёт отдельным диалогом и будет отвечено с\nнуля. `object_ids` (до 100) сужает вопрос до конкретных файлов — надёжнее, чем\nнадеяться, что подбор выберет те же самые.\n\n`use_memory=false` отвечает вообще без обращения к документам. `web_search` — это\nПОЛИТИКА, а не команда: он разрешает дополнить ответ сведениями из сети, а решение\nидти туда сервер принимает сам — по формулировке вопроса или потому, что в файлах\nответа не нашлось.\n\nСкрытые документы в ответ не попадают, пока зона не разблокирована: `include_hidden`\nработает только вместе с заголовком `X-Hidden-Token`, иначе гасится молча.\n\nДолгий запрос обрывается по дедлайну с `504`; повторять его тем же текстом бесполезно\n— это предел сервера, а не сетевой сбой. `cost_rub` возвращает стоимость этого вызова.",
        "operationId": "ask_v1_ask_post",
        "parameters": [
          {
            "in": "header",
            "name": "x-hidden-token",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Hidden-Token"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AskRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AskResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Ask",
        "tags": [
          "ask"
        ]
      }
    },
    "/v1/assistant/command": {
      "post": {
        "description": "Выполнить свободную команду. Для convert — сразу поиск файла + конвертация.",
        "operationId": "assistant_command_v1_assistant_command_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CommandRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CommandResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Assistant Command",
        "tags": [
          "assistant"
        ]
      }
    },
    "/v1/bots": {
      "get": {
        "description": "Боты владельца + флаг «можно ли завести ещё» (для кнопки «+»).",
        "operationId": "list_bots_v1_bots_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BotListOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Bots",
        "tags": [
          "bots"
        ]
      },
      "post": {
        "description": "Создаёт бота по токену @BotFather и пресету. Валидирует токен, ставит вебхук.",
        "operationId": "create_bot_v1_bots_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BotCreateIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BotCreatedOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Create Bot",
        "tags": [
          "bots"
        ]
      }
    },
    "/v1/bots/{bot_id}": {
      "delete": {
        "description": "Удалить бота вместе с его токеном. Необратимо; файлы, которые через него пришли в\nоблако, остаются на месте. Чтобы просто выключить — `PATCH` с `enabled=false`.",
        "operationId": "delete_bot_v1_bots__bot_id__delete",
        "parameters": [
          {
            "in": "path",
            "name": "bot_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Bot Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Delete Bot",
        "tags": [
          "bots"
        ]
      },
      "get": {
        "description": "Карточка своего Telegram-бота: имя, пресет роли, включён ли, состояние подключения.\n\nТокен BotFather наружу не отдаётся никогда — он хранится зашифрованным.",
        "operationId": "get_bot_v1_bots__bot_id__get",
        "parameters": [
          {
            "in": "path",
            "name": "bot_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Bot Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BotOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get Bot",
        "tags": [
          "bots"
        ]
      },
      "patch": {
        "description": "Настроить бота: роль ассистента (`agent_slug`), название, включение и список\nдопущенных.\n\n`enabled=false` не удаляет бота и не отзывает токен — он просто перестаёт отвечать,\nи это обратимо. Незаданные поля не трогаются.",
        "operationId": "update_bot_v1_bots__bot_id__patch",
        "parameters": [
          {
            "in": "path",
            "name": "bot_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Bot Id",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BotUpdateIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BotOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Update Bot",
        "tags": [
          "bots"
        ]
      }
    },
    "/v1/bots/{bot_id}/chats": {
      "get": {
        "description": "Группы, в которых живёт бот. Наполняются сами из апдейтов — список чатов Telegram не отдаёт.",
        "operationId": "list_bot_chats_v1_bots__bot_id__chats_get",
        "parameters": [
          {
            "in": "path",
            "name": "bot_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Bot Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BotChatListOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Bot Chats",
        "tags": [
          "bots"
        ]
      }
    },
    "/v1/bots/{bot_id}/chats/{chat_id}": {
      "get": {
        "description": "Карточка группы: паспорт + те, кого знаем поимённо.\n\n``known_count`` меньше ``member_count`` — это НЕ ошибка выдачи, а честное состояние:\nмолчунов бот не видит в принципе.",
        "operationId": "get_bot_chat_v1_bots__bot_id__chats__chat_id__get",
        "parameters": [
          {
            "in": "path",
            "name": "bot_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Bot Id",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "chat_id",
            "required": true,
            "schema": {
              "title": "Chat Id",
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BotChatDetailOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get Bot Chat",
        "tags": [
          "bots"
        ]
      },
      "patch": {
        "description": "Пока правится только согласие писать в чат первым — и давать его может ТОЛЬКО владелец:\nэто его бот и его репутация в чужом чате.",
        "operationId": "update_bot_chat_v1_bots__bot_id__chats__chat_id__patch",
        "parameters": [
          {
            "in": "path",
            "name": "bot_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Bot Id",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "chat_id",
            "required": true,
            "schema": {
              "title": "Chat Id",
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BotChatUpdateIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BotChatOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Update Bot Chat",
        "tags": [
          "bots"
        ]
      }
    },
    "/v1/bots/{bot_id}/chats/{chat_id}/folder": {
      "post": {
        "description": "Завести папку этой группы (или вернуть уже заведённую) — идемпотентно.\n\nКнопкой, а не автоматически при первом появлении бота в чате: бота приводят в группу по\nчужому приглашению, и у человека с пятью рабочими чатами в облаке иначе появилось бы пять\nпапок, о которых он не просил. Заводит папку ВЛАДЕЛЕЦ, поэтому она и создаётся здесь, где\nесть его ``Principal``, — рантайм бота потом только читает связь.\n\nДальше папка живёт как обычная: её можно переименовать, перенести, расшарить и открыть ей\nзнания — связь держит ``collection_id``, а не имя.",
        "operationId": "create_bot_chat_folder_v1_bots__bot_id__chats__chat_id__folder_post",
        "parameters": [
          {
            "in": "path",
            "name": "bot_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Bot Id",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "chat_id",
            "required": true,
            "schema": {
              "title": "Chat Id",
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BotChatOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Create Bot Chat Folder",
        "tags": [
          "bots"
        ]
      }
    },
    "/v1/bots/{bot_id}/chats/{chat_id}/members/{tg_user_id}": {
      "patch": {
        "description": "Чем человек в группе занимается. По этому полю агент выбирает исполнителя поручения,\nпоэтому пишет его ВЛАДЕЛЕЦ, а не сам участник: иначе «я тут главный» стало бы правом.",
        "operationId": "update_bot_chat_member_v1_bots__bot_id__chats__chat_id__members__tg_user_id__patch",
        "parameters": [
          {
            "in": "path",
            "name": "bot_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Bot Id",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "chat_id",
            "required": true,
            "schema": {
              "title": "Chat Id",
              "type": "integer"
            }
          },
          {
            "in": "path",
            "name": "tg_user_id",
            "required": true,
            "schema": {
              "title": "Tg User Id",
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BotChatMemberUpdateIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BotChatMemberOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Update Bot Chat Member",
        "tags": [
          "bots"
        ]
      }
    },
    "/v1/bots/{bot_id}/chats/{chat_id}/sync": {
      "post": {
        "description": "Перечитать паспорт чата у Telegram прямо сейчас, не дожидаясь TTL.\n\nРучка нужна именно потому, что автообновление ленивое: владелец добавил людей и хочет\nувидеть это немедленно, а не через двенадцать часов. Сбой Telegram не ошибка запроса —\nотдаём карточку как есть, просто без свежих данных.",
        "operationId": "sync_bot_chat_v1_bots__bot_id__chats__chat_id__sync_post",
        "parameters": [
          {
            "in": "path",
            "name": "bot_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Bot Id",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "chat_id",
            "required": true,
            "schema": {
              "title": "Chat Id",
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BotChatDetailOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Sync Bot Chat",
        "tags": [
          "bots"
        ]
      }
    },
    "/v1/bots/{bot_id}/subscribers": {
      "get": {
        "description": "Кому бот вправе написать первым — то есть до кого поручение реально доедет.\n\nОтдельный список, а не флажок в составе группы, и разница не косметическая. Состав группы\nотвечает на вопрос «кто здесь», подписка — на вопрос «кому дойдёт». Второе не следует из\nпервого: Telegram запрещает боту начинать разговор, поэтому участник группы, не открывший\nличку, для уведомлений недостижим, — и владельцу надо видеть именно этот разрыв.",
        "operationId": "list_bot_subscribers_v1_bots__bot_id__subscribers_get",
        "parameters": [
          {
            "in": "path",
            "name": "bot_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Bot Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BotSubscriberListOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Bot Subscribers",
        "tags": [
          "bots"
        ]
      }
    },
    "/v1/calendar/agenda": {
      "get": {
        "description": "Лента вхождений: серия здесь раскрыта, каждая встреча отдельной строкой.\n\nСоюз считается на СЕРВЕРЕ (поле ``kind``), а не собирается клиентом: бот и SDK не повторят\nни сортировку, ни раскладку по дням, а API — это и есть продукт.\n\nГраницы окна разбирает ``parse_when``, а НЕ pydantic через тип ``datetime``. Причина не в\nкрасоте: pydantic превращает ``2026-07-27`` в НАИВНЫЙ момент, тот встречается с aware-``now``\nниже по стеку, и сравнение падает TypeError-ом — весь экран «Месяц» отвечал 500. Даже если\nнаивность чинить на месте, оставалось бы второе: голая дата — это дата В ПОЯСЕ ВЛАДЕЛЬЦА,\nа не в UTC, и приклеенный UTC сдвигал бы окно на смещение зоны, пряча ранние встречи.",
        "operationId": "get_agenda_v1_calendar_agenda_get",
        "parameters": [
          {
            "description": "ГГГГ-ММ-ДД или ГГГГ-ММ-ДДTЧЧ:ММ — местное время",
            "in": "query",
            "name": "since",
            "required": false,
            "schema": {
              "default": "",
              "description": "ГГГГ-ММ-ДД или ГГГГ-ММ-ДДTЧЧ:ММ — местное время",
              "title": "Since",
              "type": "string"
            }
          },
          {
            "description": "То же; голая дата включает день целиком",
            "in": "query",
            "name": "until",
            "required": false,
            "schema": {
              "default": "",
              "description": "То же; голая дата включает день целиком",
              "title": "Until",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "include",
            "required": false,
            "schema": {
              "default": "events,tasks",
              "pattern": "^(events|tasks|events,tasks)$",
              "title": "Include",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgendaOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get Agenda",
        "tags": [
          "calendar"
        ]
      }
    },
    "/v1/calendar/events": {
      "get": {
        "description": "Сами записи (не вхождения): серия здесь одна строка, а не сорок повторов.",
        "operationId": "list_events_v1_calendar_events_get",
        "parameters": [
          {
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "default": "confirmed",
              "pattern": "^(confirmed|cancelled|all)$",
              "title": "Status",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 100,
              "maximum": 500,
              "minimum": 1,
              "title": "Limit",
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventList"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Events",
        "tags": [
          "calendar"
        ]
      },
      "post": {
        "description": "Завести встречу.\n\nВремя разбирается **в часовом поясе владельца**: `2026-09-01T15:00` — это три часа дня\nу него, а не UTC. Дата без времени заводит событие на весь день.\n\n`rrule` делает встречу повторяющейся (`FREQ=WEEKLY;BYDAY=MO`), `reminders` — за сколько\nминут напомнить. Отдельных строк на каждое вхождение серии не создаётся: серия хранится\nправилом и раскрывается при чтении.",
        "operationId": "create_event_v1_calendar_events_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EventCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Create Event",
        "tags": [
          "calendar"
        ]
      }
    },
    "/v1/calendar/events/{event_id}": {
      "delete": {
        "description": "Отменяет всю серию или одно вхождение (``?occurrence_at=``). Отмена мягкая.",
        "operationId": "cancel_event_v1_calendar_events__event_id__delete",
        "parameters": [
          {
            "in": "path",
            "name": "event_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Event Id",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "occurrence_at",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "date-time",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Occurrence At"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Cancel Event",
        "tags": [
          "calendar"
        ]
      },
      "get": {
        "description": "Одна встреча по идентификатору. Для серии возвращается её правило, а не вхождение —\nразвёрнутые вхождения даёт лента (`GET /calendar/agenda`).",
        "operationId": "get_event_v1_calendar_events__event_id__get",
        "parameters": [
          {
            "in": "path",
            "name": "event_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Event Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get Event",
        "tags": [
          "calendar"
        ]
      },
      "patch": {
        "description": "Изменить встречу. Незаданные поля не трогаются; время — в поясе владельца.\n\nПравка серии меняет **всю** серию: отдельного «изменить только это вхождение» здесь\nнет. Отменить одно вхождение можно удалением с `?occurrence_at=`.",
        "operationId": "update_event_v1_calendar_events__event_id__patch",
        "parameters": [
          {
            "in": "path",
            "name": "event_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Event Id",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EventUpdate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Update Event",
        "tags": [
          "calendar"
        ]
      }
    },
    "/v1/calendar/feeds": {
      "get": {
        "description": "Выданные ICS-подписки на календарь.\n\n`enabled=false` означает, что фича выключена на сервере, — это не то же самое, что\nпустой список подписок, и показывать пользователю нужно разное.",
        "operationId": "list_feeds_v1_calendar_feeds_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FeedList"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Feeds",
        "tags": [
          "calendar"
        ]
      },
      "post": {
        "description": "Выдать ссылку-подписку для календарного приложения (Яндекс, Apple, Outlook).\n\nСсылка **публична по построению**: календарные клиенты не умеют слать заголовок\nавторизации, поэтому право доступа несёт токен в самом URL. Отсюда и `ttl_days` —\nограничить срок жизни ссылки, которую нельзя защитить ничем другим. Утекла — отзывайте.",
        "operationId": "create_feed_v1_calendar_feeds_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FeedCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FeedOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Create Feed",
        "tags": [
          "calendar"
        ]
      }
    },
    "/v1/calendar/feeds/import": {
      "post": {
        "description": "Разовый импорт .ics. Файл читается ЦЕЛИКОМ в память, поэтому размер режется первым.\n\nДедуп — по ``UID``: повторный импорт того же файла не плодит копии. Своего столбца под\nчужой UID в схеме нет намеренно (см. 0048), поэтому сопоставляем по названию и началу —\nэтого хватает, чтобы «залил ещё раз» не удваивало расписание.",
        "operationId": "import_ics_v1_calendar_feeds_import_post",
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/Body_import_ics_v1_calendar_feeds_import_post"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ImportOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Import Ics",
        "tags": [
          "calendar"
        ]
      }
    },
    "/v1/calendar/feeds/{feed_id}": {
      "delete": {
        "description": "Отозвать подписку: ссылка сразу перестаёт работать у всех, кому она попала.",
        "operationId": "revoke_feed_v1_calendar_feeds__feed_id__delete",
        "parameters": [
          {
            "in": "path",
            "name": "feed_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Feed Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Revoke Feed",
        "tags": [
          "calendar"
        ]
      }
    },
    "/v1/chat": {
      "post": {
        "description": "Разговор с ассистентом, у которого есть доступ к вашим файлам.\n\nОтличие от `/ask` в том, что здесь ассистент отвечает всегда. `/ask` — строгий RAG:\nнет подходящих документов — нет ответа. Здесь контекст из файлов (явно приложенных\nчерез `attachment_ids` и подобранных поиском) лишь дополняет обычного помощника, а без\nконтекста он отвечает как обычный помощник.\n\nИнструментов у этого маршрута нет: он ничего не конвертирует, не создаёт и не удаляет.\nЭто `/agent/chat`.\n\n`session_id` продолжает разговор и общий с `/ask`: оба маршрута пишут в одну историю\nчатов. Пустой `query` возвращает пустой ответ, а не ошибку.",
        "operationId": "chat_v1_chat_post",
        "parameters": [
          {
            "in": "header",
            "name": "x-hidden-token",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Hidden-Token"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChatRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChatResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Chat",
        "tags": [
          "chat"
        ]
      }
    },
    "/v1/chat/attachment": {
      "post": {
        "description": "Извлекает текст из ЛОКАЛЬНОГО файла для разового контекста чата — НИЧЕГО не сохраняя.\n\nВ отличие от ``POST /objects`` (загрузка в облако) здесь нет ни S3, ни строки в БД: только\nизвлечение текста и возврат клиенту. Файла в облаке пользователя не появляется. Скоуп/лимит —\nкак у остальных дорогих ручек (``rate_limit``); размер режем ДО чтения всего файла в память.",
        "operationId": "extract_attachment_v1_chat_attachment_post",
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/Body_extract_attachment_v1_chat_attachment_post"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExtractedAttachmentOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Extract Attachment",
        "tags": [
          "chat"
        ]
      }
    },
    "/v1/chats": {
      "get": {
        "description": "История разговоров: `/ask`, `/chat` и агент пишут в неё общий список.\n\n`kind` показывает, чем сессия велась; у агентных (`kind == \"agent\"`) идентификатор\nможно вернуть в `/agent/chat` как `session_id` и продолжить с того же места.\nПревью последней реплики вторично: если оно не собралось, список всё равно придёт —\nпросто без превью.",
        "operationId": "list_chats_v1_chats_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChatSessionList"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Chats",
        "tags": [
          "chats"
        ]
      }
    },
    "/v1/chats/{chat_id}": {
      "delete": {
        "description": "Удалить сессию вместе с её репликами. Необратимо; на файлы не влияет.\n\nИдентификатор после этого мёртв: передать его в `/ask` или `/agent/chat` как\n`session_id` уже нельзя.",
        "operationId": "delete_chat_v1_chats__chat_id__delete",
        "parameters": [
          {
            "in": "path",
            "name": "chat_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Chat Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Delete Chat",
        "tags": [
          "chats"
        ]
      },
      "get": {
        "description": "Сессия целиком: реплики по порядку, закреплённость, проект и вид сессии.",
        "operationId": "get_chat_v1_chats__chat_id__get",
        "parameters": [
          {
            "in": "path",
            "name": "chat_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Chat Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChatDetail"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get Chat",
        "tags": [
          "chats"
        ]
      },
      "patch": {
        "description": "Правка сессии: переименование, закрепление и/или перенос в проект (папку).\n\nНезаданные поля не трогаем. Владение папкой проверяем ЗДЕСЬ: без этого чужой ``collection_id``\nзаписался бы в строку чата — сама ``svc.update`` папку не знает и проверить её не может.",
        "operationId": "patch_chat_v1_chats__chat_id__patch",
        "parameters": [
          {
            "in": "path",
            "name": "chat_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Chat Id",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChatPatch"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChatSessionOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Patch Chat",
        "tags": [
          "chats"
        ]
      }
    },
    "/v1/chats/{chat_id}/messages/{message_id}": {
      "delete": {
        "description": "Удалить одну реплику треда (свой вопрос или ответ бота). Скоуп — по владельцу сессии.",
        "operationId": "delete_message_v1_chats__chat_id__messages__message_id__delete",
        "parameters": [
          {
            "in": "path",
            "name": "chat_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Chat Id",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "message_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Message Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Delete Message",
        "tags": [
          "chats"
        ]
      }
    },
    "/v1/collections": {
      "get": {
        "description": "Плоский список папок владельца со счётчиками файлов (дерево клиент строит по\n``parent_id``/``theme_id``). Счётчики — одним GROUP BY (без N+1). Скрытые папки\nпо умолчанию исключены (29-13); ``include_hidden=true`` отдаёт и их.",
        "operationId": "list_collections_v1_collections_get",
        "parameters": [
          {
            "in": "query",
            "name": "include_hidden",
            "required": false,
            "schema": {
              "default": false,
              "title": "Include Hidden",
              "type": "boolean"
            }
          },
          {
            "in": "header",
            "name": "x-hidden-token",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Hidden-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CollectionList"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Collections",
        "tags": [
          "collections"
        ]
      },
      "post": {
        "description": "Создать папку. `parent_id` вкладывает её в другую, `theme_id` относит к теме.\n\n`is_hidden=true` заводит папку сразу в зоне «Скрытые»: её содержимое не попадёт ни в\nсписки, ни в поиск, ни в ответы, пока зона не разблокирована по PIN.",
        "operationId": "create_collection_v1_collections_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CollectionCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CollectionOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Create Collection",
        "tags": [
          "collections"
        ]
      }
    },
    "/v1/collections/{collection_id}": {
      "delete": {
        "description": "Удалить папку. **Файлы при этом не удаляются.**\n\nОни теряют связь с этой папкой и остаются в остальных, а тем, для кого удаляемая была\nосновной, основная переизбирается из оставшихся (или обнуляется). Вложенные папки не\nудаляются — всплывают в корень. Заметка-знания проекта уходит в корзину, откуда её\nможно вернуть.",
        "operationId": "delete_collection_v1_collections__collection_id__delete",
        "parameters": [
          {
            "in": "path",
            "name": "collection_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Collection Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Delete Collection",
        "tags": [
          "collections"
        ]
      },
      "patch": {
        "description": "Переименовать папку, перевесить её в другую (`parent_id`) или в другую тему.\n\n`parent_id` и `theme_id` меняются только если поле **явно передано** — в том числе\nзначением `null` (вынести в корень / убрать из темы). Не передали поле — оно осталось\nкак было; это разные вещи, и обнулить их случайным неполным телом нельзя.\n\nПапку нельзя сделать потомком самой себя или своего потомка — сервер откажет.",
        "operationId": "update_collection_v1_collections__collection_id__patch",
        "parameters": [
          {
            "in": "path",
            "name": "collection_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Collection Id",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CollectionUpdate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CollectionOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Update Collection",
        "tags": [
          "collections"
        ]
      }
    },
    "/v1/collections/{collection_id}/note": {
      "get": {
        "description": "Заметка-знания папки (KNOWLEDGE): создаёт «знания.md» при первом обращении и возвращает\nеё ``object_id`` — клиент открывает её в обычном редакторе. Чужая папка → 404.",
        "operationId": "folder_note_v1_collections__collection_id__note_get",
        "parameters": [
          {
            "in": "path",
            "name": "collection_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Collection Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FolderNoteOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Folder Note",
        "tags": [
          "collections"
        ]
      }
    },
    "/v1/collections/{collection_id}/objects/{object_id}": {
      "delete": {
        "description": "Убрать файл из папки (M:N). Файл остаётся в других папках; основная переизберётся.",
        "operationId": "unlink_object_from_collection_v1_collections__collection_id__objects__object_id__delete",
        "parameters": [
          {
            "in": "path",
            "name": "collection_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Collection Id",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Unlink Object From Collection",
        "tags": [
          "collections"
        ]
      },
      "post": {
        "description": "Добавить файл в папку (M:N) и сделать её основной. Файл остаётся и в прежних папках.",
        "operationId": "move_object_v1_collections__collection_id__objects__object_id__post",
        "parameters": [
          {
            "in": "path",
            "name": "collection_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Collection Id",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Move Object",
        "tags": [
          "collections"
        ]
      }
    },
    "/v1/collections/{collection_id}/objects/{object_id}/primary": {
      "post": {
        "description": "Сделать папку основной для файла (свяжет, если ещё не связан).",
        "operationId": "set_primary_folder_v1_collections__collection_id__objects__object_id__primary_post",
        "parameters": [
          {
            "in": "path",
            "name": "collection_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Collection Id",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Set Primary Folder",
        "tags": [
          "collections"
        ]
      }
    },
    "/v1/corrections": {
      "get": {
        "description": "Owner-правила и пины владельца.",
        "operationId": "list_owner_rules_v1_corrections_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CorrectionList"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Owner Rules",
        "tags": [
          "corrections"
        ]
      },
      "post": {
        "description": "Owner-правило (учитывается в ответах) или пин файла (буст в поиске).",
        "operationId": "create_owner_rule_v1_corrections_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OwnerRuleCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CorrectionOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Create Owner Rule",
        "tags": [
          "corrections"
        ]
      }
    },
    "/v1/corrections/{correction_id}/revert": {
      "post": {
        "description": "Откатить исправление (восстановить старое значение + пересчитать флаги).",
        "operationId": "revert_correction_v1_corrections__correction_id__revert_post",
        "parameters": [
          {
            "in": "path",
            "name": "correction_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Correction Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CorrectionOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Revert Correction",
        "tags": [
          "corrections"
        ]
      }
    },
    "/v1/documents/generate": {
      "post": {
        "description": "Сгенерировать документ по запросу (docx по умолчанию, либо pdf).\n\nСтавит Celery-задачу ``docgen.run``; результат появится НОВЫМ объектом-файлом, когда\nобработается (опрос ``/documents/status``). Неизвестный формат → docx.",
        "operationId": "generate_document_v1_documents_generate_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DocGenRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocGenAccepted"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Generate Document",
        "tags": [
          "documents"
        ]
      }
    },
    "/v1/documents/status/{task_id}": {
      "get": {
        "description": "Статус генерации по task_id: SUCCESS → id/имя нового объекта. Открытие файла всё равно\nпроверяет владельца, поэтому по task_id утечки доступа нет.",
        "operationId": "generate_status_v1_documents_status__task_id__get",
        "parameters": [
          {
            "in": "path",
            "name": "task_id",
            "required": true,
            "schema": {
              "title": "Task Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocGenStatus"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Generate Status",
        "tags": [
          "documents"
        ]
      }
    },
    "/v1/events": {
      "post": {
        "description": "Записать батч продуктовых событий. Незнакомые события отбрасываются (белый список).",
        "operationId": "post_events_v1_events_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EventsBatch"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventsAck"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Post Events",
        "tags": [
          "analytics"
        ]
      }
    },
    "/v1/facts": {
      "delete": {
        "description": "Забыть ВСЕ факты пользователя (только его).",
        "operationId": "clear_facts_v1_facts_delete",
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Clear Facts",
        "tags": [
          "corrections"
        ]
      },
      "get": {
        "description": "Активные факты, которые ИИ запомнил о пользователе (только его — scoped по owner_id).",
        "operationId": "list_facts_v1_facts_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CorrectionList"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Facts",
        "tags": [
          "corrections"
        ]
      },
      "post": {
        "description": "Добавить факт о себе руками — раздел «Знания» умел только читать и удалять.\n\nПишем ЧЕРЕЗ ``svc.remember_fact``, а не INSERT'ом: там живут дедуп полного дубля,\nвытеснение по субъекту, потолок длины и детерминированный отсев секретов (номер карты,\nпароль). Ручной путь обязан получать те же рубежи, что инструмент агента и авто-захват, —\nиначе через форму в вечную память уедет то, что оба других пути не пропускают.\n\nТочный дубль возвращает УЖЕ существующий факт с тем же 201: копий не плодим, а сообщать об\nошибке там, где пользователь получил ровно то, чего хотел, незачем.",
        "operationId": "create_fact_v1_facts_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FactCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CorrectionOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Create Fact",
        "tags": [
          "corrections"
        ]
      }
    },
    "/v1/facts/{fact_id}": {
      "delete": {
        "description": "Забыть один факт (scoped по владельцу; expected_kind='fact' — чужую правку не откатит).",
        "operationId": "forget_fact_v1_facts__fact_id__delete",
        "parameters": [
          {
            "in": "path",
            "name": "fact_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Fact Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Forget Fact",
        "tags": [
          "corrections"
        ]
      }
    },
    "/v1/hidden-pin": {
      "get": {
        "description": "Установлен ли у владельца PIN скрытых (фронт выбирает «создать» или «ввести»).",
        "operationId": "pin_status_v1_hidden_pin_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PinStatus"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Pin Status",
        "tags": [
          "hidden"
        ]
      },
      "post": {
        "description": "Установить PIN (смена — только со старым PIN). Сразу возвращает unlock-токен.",
        "operationId": "pin_set_v1_hidden_pin_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PinSetRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PinUnlockOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Pin Set",
        "tags": [
          "hidden"
        ]
      }
    },
    "/v1/hidden-pin/disable": {
      "post": {
        "description": "Снять PIN — только зная текущий. «Сброс» без PIN намеренно невозможен (T29):\nзабытый PIN снимает администратор.",
        "operationId": "pin_disable_v1_hidden_pin_disable_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PinVerifyRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Pin Disable",
        "tags": [
          "hidden"
        ]
      }
    },
    "/v1/hidden-pin/verify": {
      "post": {
        "description": "Проверить PIN → unlock-токен для ``X-Hidden-Token`` (30 мин).",
        "operationId": "pin_verify_v1_hidden_pin_verify_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PinVerifyRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PinUnlockOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Pin Verify",
        "tags": [
          "hidden"
        ]
      }
    },
    "/v1/integrations": {
      "get": {
        "description": "Обе карточки (llm и s3) + доступна ли фича на этом контуре.",
        "operationId": "list_integrations_v1_integrations_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IntegrationsOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Integrations",
        "tags": [
          "integrations"
        ]
      }
    },
    "/v1/integrations/google": {
      "delete": {
        "description": "Отключает синхронизацию. Календарь в аккаунте Google НЕ удаляет — это уже его данные.",
        "operationId": "disconnect_v1_integrations_google_delete",
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Disconnect",
        "tags": [
          "google-calendar"
        ]
      }
    },
    "/v1/integrations/google/connect": {
      "post": {
        "description": "Ссылка на экран согласия Google. Сам переход делает браузер, а не мы.",
        "operationId": "connect_v1_integrations_google_connect_post",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConnectOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Connect",
        "tags": [
          "google-calendar"
        ]
      }
    },
    "/v1/integrations/google/status": {
      "get": {
        "description": "Подключён ли Google-календарь и когда синхронизировался последний раз.\n\nТри разных состояния, которые нельзя смешивать: `enabled=false` — фича выключена на\nсервере; `enabled=true, connected=false` — не подключён этим владельцем;\nподключён — тогда приходят почта аккаунта, время синхронизации и последняя ошибка,\nесли она была. Само подключение идёт через браузерный OAuth и вне SDK.",
        "operationId": "status_of_v1_integrations_google_status_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GoogleStatus"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Status Of",
        "tags": [
          "google-calendar"
        ]
      }
    },
    "/v1/integrations/llm": {
      "put": {
        "description": "Подключить/поправить свой ключ модели. ``api_key=null`` — оставить ранее введённый.",
        "operationId": "save_llm_v1_integrations_llm_put",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LlmSaveIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IntegrationOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Save Llm",
        "tags": [
          "integrations"
        ]
      }
    },
    "/v1/integrations/s3": {
      "put": {
        "description": "Подключить/поправить своё хранилище. Ключи доступа — обе строки сразу либо ни одной.",
        "operationId": "save_s3_v1_integrations_s3_put",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/S3SaveIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IntegrationOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Save S3",
        "tags": [
          "integrations"
        ]
      }
    },
    "/v1/integrations/s3/migration": {
      "get": {
        "description": "Прогресс переноса + СКОЛЬКО ЕЩЁ лежит у нас (пересчёт, а не только запомненный итог).",
        "operationId": "migration_status_v1_integrations_s3_migration_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StorageMigrationOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Migration Status",
        "tags": [
          "integrations"
        ]
      },
      "post": {
        "description": "Запустить перенос всех файлов владельца в его бакет (фоном).\n\nИдемпотентно: повторный запуск подберёт то, что не доехало. Уже идущий перенос НЕ\nдублируем — иначе две задачи гоняли бы одни и те же байты и мешали друг другу удалением\nисточников.",
        "operationId": "start_migration_v1_integrations_s3_migration_post",
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StorageMigrationOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Start Migration",
        "tags": [
          "integrations"
        ]
      }
    },
    "/v1/integrations/{kind}": {
      "delete": {
        "description": "Удалить подключение вместе с секретами. Файлы в чужом бакете НЕ трогаем — они его.",
        "operationId": "delete_integration_v1_integrations__kind__delete",
        "parameters": [
          {
            "in": "path",
            "name": "kind",
            "required": true,
            "schema": {
              "title": "Kind",
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Delete Integration",
        "tags": [
          "integrations"
        ]
      },
      "patch": {
        "description": "Включить/выключить подключение, не теряя настроек.\n\nДля хранилища это НЕ возврат файлов: уже уехавшие в свой бакет читаются по отметке объекта\nи остаются там. Выключение влияет только на новые записи.",
        "operationId": "toggle_v1_integrations__kind__patch",
        "parameters": [
          {
            "in": "path",
            "name": "kind",
            "required": true,
            "schema": {
              "title": "Kind",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/IntegrationToggleIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IntegrationOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Toggle",
        "tags": [
          "integrations"
        ]
      }
    },
    "/v1/integrations/{kind}/test": {
      "post": {
        "description": "Проверить связь по сохранённым настройкам и запомнить вердикт.\n\nХодит в сеть (у модели спрашивает список моделей, у бакета пишет и удаляет пробный объект),\nпоэтому под общим rate-limit — как остальные дорогие ручки.",
        "operationId": "test_connection_v1_integrations__kind__test_post",
        "parameters": [
          {
            "in": "path",
            "name": "kind",
            "required": true,
            "schema": {
              "title": "Kind",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IntegrationOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Test Connection",
        "tags": [
          "integrations"
        ]
      }
    },
    "/v1/intent": {
      "post": {
        "description": "Понять, чего человек хочет от свободной фразы: `{action, target}`.\n\nНужно клиентам с одним полем ввода — боту, виджету, — чтобы отличить «пришли мне\nдоговор» (выдать файл) от «что в договоре» (ответить по содержимому) до того, как\nзвать дорогие маршруты. Сам ничего не ищет и не отвечает: только классифицирует.\n\nМодель недоступна — `503`; в этом случае разумно откатиться на обычный `/ask`.",
        "operationId": "route_intent_v1_intent_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/IntentRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IntentResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Route Intent",
        "tags": [
          "intent"
        ]
      }
    },
    "/v1/memory/suggestions": {
      "get": {
        "description": "Проактивные подсказки по памяти владельца (конфликты/разметка/раскладка).\n\nСкрытые документы в подсказки попадают только при разблокированной зоне (валидный\n``X-Hidden-Token``) — как в списке объектов, поиске и ``/ask``. Без него карточка\n«Несколько документов „паспорт“» подтверждала бы существование скрытого паспорта.",
        "operationId": "get_memory_suggestions_v1_memory_suggestions_get",
        "parameters": [
          {
            "in": "header",
            "name": "x-hidden-token",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Hidden-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemorySuggestionsList"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get Memory Suggestions",
        "tags": [
          "memory"
        ]
      }
    },
    "/v1/models": {
      "get": {
        "description": "Доступные модели: их `id` передаётся в `/ask` параметром `model`.\n\nКаталог зависит от развёртывания и настроек аккаунта, поэтому зашивать идентификатор в\nклиент не стоит. Неизвестный или недоступный `model` в `/ask` не ошибка — запрос молча\nуходит на модель по умолчанию.",
        "operationId": "list_models_v1_models_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ModelList"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Models",
        "tags": [
          "models"
        ]
      }
    },
    "/v1/notifications": {
      "get": {
        "description": "Уведомления владельца; `unread=true` — только непрочитанные.\n\nPush-канала у API нет: клиент забирает уведомления опросом. Ответ несёт счётчик\nнепрочитанных, поэтому бейдж рисуется без второго запроса.",
        "operationId": "list_notifications_v1_notifications_get",
        "parameters": [
          {
            "in": "query",
            "name": "unread",
            "required": false,
            "schema": {
              "default": false,
              "title": "Unread",
              "type": "boolean"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 50,
              "maximum": 100,
              "minimum": 1,
              "title": "Limit",
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotificationList"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Notifications",
        "tags": [
          "notifications"
        ]
      }
    },
    "/v1/notifications/read": {
      "post": {
        "description": "Гасит перечисленные уведомления; пустой список — все. Отдаёт свежий список со счётчиком,\nчтобы клиенту не приходилось делать второй запрос ради бейджа.",
        "operationId": "mark_notifications_read_v1_notifications_read_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NotificationsRead"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotificationList"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Mark Notifications Read",
        "tags": [
          "notifications"
        ]
      }
    },
    "/v1/notifications/{notification_id}": {
      "delete": {
        "description": "Убрать уведомление совсем. Отличается от `POST /notifications/read`: то гасит\nнепрочитанность, оставляя запись в списке, а это удаляет её.",
        "operationId": "delete_notification_v1_notifications__notification_id__delete",
        "parameters": [
          {
            "in": "path",
            "name": "notification_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Notification Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Delete Notification",
        "tags": [
          "notifications"
        ]
      }
    },
    "/v1/objects": {
      "get": {
        "description": "Список объектов владельца (новые сверху). Скоуп tenant+owner; опц. фильтры\n``doc_type`` и ``collection_id`` (папка). ``uncategorized=true`` — только файлы БЕЗ\nпапки («Все файлы» показывает несортированные, файлы в папках туда не попадают).\nСкрытые по умолчанию исключены (29-13): ``include_hidden`` / ``hidden_only``; при\nустановленном PIN (T29) выдача скрытых требует unlock-токен ``X-Hidden-Token``\n(``hidden_only`` без него → 403, ``include_hidden`` молча деградирует до обычной).\nКорзина: по умолчанию удалённые исключены; ``trashed=true`` — ТОЛЬКО корзина.",
        "operationId": "list_objects_v1_objects_get",
        "parameters": [
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 20,
              "maximum": 100,
              "minimum": 1,
              "title": "Limit",
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "offset",
            "required": false,
            "schema": {
              "default": 0,
              "minimum": 0,
              "title": "Offset",
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "doc_type",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Doc Type"
            }
          },
          {
            "in": "query",
            "name": "kind",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Kind"
            }
          },
          {
            "in": "query",
            "name": "is_link",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "boolean"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Is Link"
            }
          },
          {
            "in": "query",
            "name": "collection_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "uuid",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Collection Id"
            }
          },
          {
            "in": "query",
            "name": "uncategorized",
            "required": false,
            "schema": {
              "default": false,
              "title": "Uncategorized",
              "type": "boolean"
            }
          },
          {
            "in": "query",
            "name": "include_hidden",
            "required": false,
            "schema": {
              "default": false,
              "title": "Include Hidden",
              "type": "boolean"
            }
          },
          {
            "in": "query",
            "name": "hidden_only",
            "required": false,
            "schema": {
              "default": false,
              "title": "Hidden Only",
              "type": "boolean"
            }
          },
          {
            "in": "query",
            "name": "trashed",
            "required": false,
            "schema": {
              "default": false,
              "title": "Trashed",
              "type": "boolean"
            }
          },
          {
            "in": "query",
            "name": "notes_only",
            "required": false,
            "schema": {
              "default": false,
              "title": "Notes Only",
              "type": "boolean"
            }
          },
          {
            "in": "header",
            "name": "x-hidden-token",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Hidden-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObjectList"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Objects",
        "tags": [
          "objects"
        ]
      },
      "post": {
        "description": "``chat_only=true`` — вложение чата (📎): файл обрабатывается как обычно, но живёт только\nв чате (вне сетки файлов/счётчиков), пока не нажмут «Сохранить в облако».\n\n``collection_id`` (опционально) — сразу положить файл в эту папку владельца (один файл —\nодна папка). Чужая/несуществующая папка → 404. Для вложений чата папка игнорируется.",
        "operationId": "upload_v1_objects_post",
        "parameters": [
          {
            "in": "query",
            "name": "chat_only",
            "required": false,
            "schema": {
              "default": false,
              "title": "Chat Only",
              "type": "boolean"
            }
          },
          {
            "in": "query",
            "name": "collection_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "uuid",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Collection Id"
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/Body_upload_v1_objects_post"
              }
            }
          }
        },
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObjectAccepted"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Upload",
        "tags": [
          "objects"
        ]
      }
    },
    "/v1/objects/archive": {
      "post": {
        "description": "Загрузить zip — каждый файл внутри заводится отдельным объектом и индексируется (v4).\n\nЗащита от zip-бомбы/path traversal в ``unpack_zip``; оригинал архива сохраняется в\nпапку «Заархивированные».",
        "operationId": "upload_archive_v1_objects_archive_post",
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/Body_upload_archive_v1_objects_archive_post"
              }
            }
          }
        },
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ArchiveAccepted"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Upload Archive",
        "tags": [
          "objects"
        ]
      }
    },
    "/v1/objects/assemble": {
      "post": {
        "description": "Сборка нескольких объектов в один PDF новым объектом (Celery).\n\nВсе ``object_ids`` должны принадлежать владельцу (иначе 404). Разные форматы\nвнутри (pdf/docx/xlsx/pptx/картинки) приводятся к PDF-страницам; неконвертируемые\n(txt/аудио/видео) пропускаются. Порядок страниц — ``sort`` (date|order). Результат\nпоявится новым объектом в списке, когда соберётся (как ``/convert``).\n\nСкрытый файл собирается только при разблокированной зоне (``X-Hidden-Token``): иначе\nего id — «не найден». Результат создаётся ОБЫЧНЫМ объектом, поэтому без гейта сборка\nбыла бы штатным способом вынести содержимое из зоны «Скрытые» мимо PIN.",
        "operationId": "assemble_v1_objects_assemble_post",
        "parameters": [
          {
            "in": "header",
            "name": "x-hidden-token",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Hidden-Token"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AssembleRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AssembleAccepted"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Assemble",
        "tags": [
          "objects"
        ]
      }
    },
    "/v1/objects/content-status/{task_id}": {
      "get": {
        "description": "Статус пересборки docx/pdf по task_id: SUCCESS → id/имя обновлённого объекта.\nОткрытие файла всё равно проверяет владельца — по task_id утечки доступа нет.\n\n``error='version_conflict'`` — задача отработала, но правку НЕ применила: файл успели\nизменить в другом сеансе (тот же смысл, что 412 у синхронного пути).",
        "operationId": "content_save_status_v1_objects_content_status__task_id__get",
        "parameters": [
          {
            "in": "path",
            "name": "task_id",
            "required": true,
            "schema": {
              "title": "Task Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContentSaveStatus"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Content Save Status",
        "tags": [
          "objects"
        ]
      }
    },
    "/v1/objects/convert-by-query": {
      "post": {
        "description": "Найти файл по фразе и сконвертировать его (C1).\n\nЧинит демо-баг «команда конвертации не сработала»: раньше роутер намерений не знал\nдействия convert, и «конвертируй паспорт в Word» не доходило до конвертера. Теперь один\nвызов делает поиск (``hybrid_search``) → выбор первого КОНВЕРТИРУЕМОГО в целевой формат\nфайла → постановку той же Celery-задачи ``convert.run``. Результат появится новым объектом.",
        "operationId": "convert_by_query_v1_objects_convert_by_query_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ConvertByQueryRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConvertByQueryAccepted"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Convert By Query",
        "tags": [
          "objects"
        ]
      }
    },
    "/v1/objects/convert-status/{task_id}": {
      "get": {
        "description": "Статус конвертации по task_id: SUCCESS → id/имя нового объекта (клиент\nпоказывает готовый файл карточкой в чате). Открытие файла всё равно проверяет\nвладельца, поэтому по task_id утечки доступа нет.",
        "operationId": "convert_status_v1_objects_convert_status__task_id__get",
        "parameters": [
          {
            "in": "path",
            "name": "task_id",
            "required": true,
            "schema": {
              "title": "Task Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConvertStatus"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Convert Status",
        "tags": [
          "objects"
        ]
      }
    },
    "/v1/objects/image-status/{task_id}": {
      "get": {
        "description": "Статус операции над изображением по task_id: SUCCESS → id/имя обновлённого объекта.\nОткрытие файла всё равно проверяет владельца — по task_id утечки доступа нет.",
        "operationId": "image_op_status_v1_objects_image_status__task_id__get",
        "parameters": [
          {
            "in": "path",
            "name": "task_id",
            "required": true,
            "schema": {
              "title": "Task Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ImageOpStatus"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Image Op Status",
        "tags": [
          "objects"
        ]
      }
    },
    "/v1/objects/link": {
      "post": {
        "description": "Добавить ссылку как объект (v4). Веб-страница → текст извлекается и индексируется сразу.\nВидео-ссылка (YouTube и т.п.) → аудиодорожка скачивается и транскрибируется фоном (yt-dlp).\n``source_url`` хранит исходный URL. SSRF-проверка хоста до любого забора.",
        "operationId": "add_link_v1_objects_link_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LinkRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LinkAccepted"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Add Link",
        "tags": [
          "objects"
        ]
      }
    },
    "/v1/objects/pdf-status/{task_id}": {
      "get": {
        "description": "Статус PDF-операции по task_id: SUCCESS → id/имя первого нового объекта и число созданных\n(для split). Открытие файла всё равно проверяет владельца — по task_id утечки доступа нет.",
        "operationId": "pdf_op_status_v1_objects_pdf_status__task_id__get",
        "parameters": [
          {
            "in": "path",
            "name": "task_id",
            "required": true,
            "schema": {
              "title": "Task Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PdfOpStatus"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Pdf Op Status",
        "tags": [
          "objects"
        ]
      }
    },
    "/v1/objects/protocol-status/{task_id}": {
      "get": {
        "description": "Статус сборки протокола. В отличие от convert-status отдаёт ещё и id готового файла —\nклиенту нужно на что-то сослаться кнопками «Открыть» и «Скачать».",
        "operationId": "protocol_status_v1_objects_protocol_status__task_id__get",
        "parameters": [
          {
            "in": "path",
            "name": "task_id",
            "required": true,
            "schema": {
              "title": "Task Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProtocolStatus"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Protocol Status",
        "tags": [
          "objects"
        ]
      }
    },
    "/v1/objects/reorganize": {
      "post": {
        "description": "AI-перераспределение файлов по папкам ПО СМЫСЛУ (29-12). Ручной запуск, асинхронно.\n\nПо умолчанию (``force=False``) раскладывает только файлы без папки; ``force=True`` —\nпереразложить всё (под потолком ``reorganize_max_objects``, контроль стоимости).\n``reset=True`` («разложить всё заново») — сначала снести ИИ-папки/темы и авто-связи, затем\nразложить с нуля (ручные и расшаренные папки сохраняются). Скрытые (29-13) не трогаем.\nРезультат виден живым опросом списка — файлы «переедут» по папкам.",
        "operationId": "reorganize_objects_v1_objects_reorganize_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReorganizeRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReorganizeAccepted"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Reorganize Objects",
        "tags": [
          "objects"
        ]
      }
    },
    "/v1/objects/reorganize/{task_id}": {
      "get": {
        "description": "Прогресс перераскладки (29-12): состояние Celery-задачи + счётчики «X из N».\n\nPROGRESS → meta из update_state; SUCCESS → итоговая сводка (``candidates`` = total).",
        "operationId": "reorganize_status_v1_objects_reorganize__task_id__get",
        "parameters": [
          {
            "in": "path",
            "name": "task_id",
            "required": true,
            "schema": {
              "title": "Task Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReorganizeStatus"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Reorganize Status",
        "tags": [
          "objects"
        ]
      }
    },
    "/v1/objects/trash/empty": {
      "post": {
        "description": "Очистить корзину: окончательно удалить все объекты владельца, лежащие в корзине.",
        "operationId": "empty_trash_v1_objects_trash_empty_post",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmptyTrashResult"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Empty Trash",
        "tags": [
          "objects"
        ]
      }
    },
    "/v1/objects/zip": {
      "post": {
        "description": "Архивация выбранных объектов в один ZIP новым объектом (Celery).\n\nВсе ``object_ids`` должны принадлежать владельцу (иначе 404). Каждый файл кладётся в\nархив под своим именем (дубликаты разводятся суффиксом); ссылки пропускаются. Результат\nпоявится новым объектом-архивом в списке, когда соберётся (как ``/assemble``).\n\nСкрытый файл архивируется только при разблокированной зоне (``X-Hidden-Token``) — довод\nтот же, что у ``/assemble``: архив создаётся обычным объектом в папке «Заархивированные».",
        "operationId": "zip_objects_v1_objects_zip_post",
        "parameters": [
          {
            "in": "header",
            "name": "x-hidden-token",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Hidden-Token"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ZipRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ZipAccepted"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Zip Objects",
        "tags": [
          "objects"
        ]
      }
    },
    "/v1/objects/{object_id}": {
      "delete": {
        "description": "Переместить объект в корзину (soft-delete): исчезает из списков/поиска/чата, но не\nудаляется физически. Через 14 дней — окончательная чистка (фоновая задача). Восстановить —\nPOST /{id}/restore; снести сразу — DELETE /{id}/permanent.",
        "operationId": "delete_object_v1_objects__object_id__delete",
        "parameters": [
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-hidden-token",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Hidden-Token"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Delete Object",
        "tags": [
          "objects"
        ]
      },
      "get": {
        "description": "Карточка файла: имя, тип, статус обработки и ИИ-обогащение (заголовок, суть, теги).\n\nПока `status=\"pending\"`, обогащения ещё нет и поиск по содержимому этого файла ничего\nне найдёт — обработка идёт фоном после загрузки. Файл из «Скрытых» отдаётся только с\nзаголовком `X-Hidden-Token`, иначе `404`: ответ «нет такого» вместо «нет доступа» здесь\nнамеренный.",
        "operationId": "get_object_v1_objects__object_id__get",
        "parameters": [
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-hidden-token",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Hidden-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObjectDetail"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get Object",
        "tags": [
          "objects"
        ]
      },
      "patch": {
        "description": "Правка объекта пользователем (переименование). Скоуп tenant+owner.",
        "operationId": "update_object_v1_objects__object_id__patch",
        "parameters": [
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-hidden-token",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Hidden-Token"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ObjectUpdateRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObjectDetail"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Update Object",
        "tags": [
          "objects"
        ]
      }
    },
    "/v1/objects/{object_id}/accept-folder": {
      "post": {
        "description": "Принять предложенную папку (v4, автораспределение): кладёт объект в предложенную коллекцию,\nсоздавая её при необходимости (если предложено новое имя). После принятия подсказка снимается.",
        "operationId": "accept_folder_v1_objects__object_id__accept_folder_post",
        "parameters": [
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-hidden-token",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Hidden-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObjectDetail"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Accept Folder",
        "tags": [
          "objects"
        ]
      }
    },
    "/v1/objects/{object_id}/apply-ai-name": {
      "post": {
        "description": "Применить AI-имя (Enrichment.title) как отображаемое имя файла (если не залочено).",
        "operationId": "apply_ai_name_endpoint_v1_objects__object_id__apply_ai_name_post",
        "parameters": [
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-hidden-token",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Hidden-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObjectDetail"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Apply Ai Name Endpoint",
        "tags": [
          "objects"
        ]
      }
    },
    "/v1/objects/{object_id}/compare": {
      "post": {
        "description": "Что изменилось: файл против другого файла ИЛИ против своей прошлой версии.\n\nСравнение идёт по абзацам; регистр и лишние пробелы правкой не считаются (см.\n``services/compare``). Файл в запросе — ПРАВАЯ сторона («что стало»), источник из тела —\nлевая («что было»), поэтому «добавлено» читается относительно текущего состояния файла.\n\nБез тела берётся последняя ревизия — частый вопрос «что изменилось с прошлого раза».\n``other_id`` проходит ту же проверку владения и тот же PIN скрытой зоны, что и сам файл:\nиначе сравнение стало бы обходным чтением чужого (и скрытого) содержимого.\n\n404 — файла/версии нет либо истории ещё нет. 422 — заданы оба источника разом, или\nсравнивать нечего (нераспознанный скан, картинка, файл ещё в обработке).",
        "operationId": "compare_object_v1_objects__object_id__compare_post",
        "parameters": [
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-hidden-token",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Hidden-Token"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CompareRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompareOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Compare Object",
        "tags": [
          "objects"
        ]
      }
    },
    "/v1/objects/{object_id}/content": {
      "get": {
        "description": "Временная ссылка на скачивание файла из хранилища.\n\nСсылка подписана и живёт `expires_in` секунд — её выдают человеку или отдают в\nзагрузчик, но не сохраняют. Она ведёт напрямую в хранилище, поэтому наших CORS-заголовков\nна ней нет: браузерному коду нужен `/objects/{id}/raw`, а тексту для модели —\n`/objects/{id}/text-content`.",
        "operationId": "get_content_v1_objects__object_id__content_get",
        "parameters": [
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-hidden-token",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Hidden-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContentUrl"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get Content",
        "tags": [
          "objects"
        ]
      },
      "put": {
        "description": "Сохранить правку содержимого файла (редактор «как текст»).\n\nПрямой текст (txt/md/код/разметка) — записываем байты СРАЗУ (``overwrite_object_bytes``),\nобъект пере-обогащается по новому содержимому. docx/pdf — пересобираем фоном из markdown\n(Celery ``doc_edit.run``); следить за готовностью по ``/content-status/{task_id}``.\n\n``base_version`` (опционально) — оптимистичная блокировка (E0): правка применяется, только\nесли версия файла не изменилась с момента открытия редактора, иначе 412. Прежние байты\nснимаются ревизией перед перезаписью, автор правки — владелец ключа.",
        "operationId": "save_text_content_v1_objects__object_id__content_put",
        "parameters": [
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-hidden-token",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Hidden-Token"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ObjectContentUpdate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObjectContentSaved"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Save Text Content",
        "tags": [
          "objects"
        ]
      }
    },
    "/v1/objects/{object_id}/convert": {
      "post": {
        "description": "Конвертация объекта в другой формат (docx/xlsx/pptx/pdf/картинки → pdf/docx/txt/\ncsv/png/jpg/webp — по возможностям источника, см. converter.targets_for).\n\nСтавит Celery-задачу: результат сохраняется НОВЫМ объектом и проходит обычный\ningest — он появится в списке владельца, когда обработается.",
        "operationId": "convert_object_v1_objects__object_id__convert_post",
        "parameters": [
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-hidden-token",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Hidden-Token"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ConvertRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConvertAccepted"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Convert Object",
        "tags": [
          "objects"
        ]
      }
    },
    "/v1/objects/{object_id}/convert-targets": {
      "get": {
        "description": "Доступные целевые форматы конвертации для файла (по расширению источника).\n\nПитает выпадающий список форматов на странице конвертации: пустой список —\nфайл не конвертируется, и клиент прячет действие.",
        "operationId": "convert_targets_v1_objects__object_id__convert_targets_get",
        "parameters": [
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-hidden-token",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Hidden-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConvertTargets"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Convert Targets",
        "tags": [
          "objects"
        ]
      }
    },
    "/v1/objects/{object_id}/corrections": {
      "get": {
        "description": "История исправлений файла (для панели «уточнения» на детали).",
        "operationId": "list_object_corrections_v1_objects__object_id__corrections_get",
        "parameters": [
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CorrectionList"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Object Corrections",
        "tags": [
          "corrections"
        ]
      },
      "post": {
        "description": "Создать и применить исправление файла (метка «изменялся/есть уточнение» появится сразу).",
        "operationId": "create_object_correction_v1_objects__object_id__corrections_post",
        "parameters": [
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CorrectionCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CorrectionOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Create Object Correction",
        "tags": [
          "corrections"
        ]
      }
    },
    "/v1/objects/{object_id}/diarization": {
      "get": {
        "description": "Результат диаризации записи для UI (спикеры + сегменты + готовый транскрипт). ``ready=False``,\nпока разметки нет (не запускали или ещё считается) — клиент поллит этот GET после запуска.\nЭмбеддинги self-enrollment из ответа исключены (``from_json`` их не читает).",
        "operationId": "get_diarization_v1_objects__object_id__diarization_get",
        "parameters": [
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-hidden-token",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Hidden-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DiarizationResult"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get Diarization",
        "tags": [
          "objects"
        ]
      }
    },
    "/v1/objects/{object_id}/diarize": {
      "post": {
        "description": "Ставит фоновую диаризацию записи (критерий «Спикеры»). Нужен поднятый диар-воркер\n(``DIARIZATION_ENABLED``). После обработки текст и протокол получат реальных спикеров, а\nнеуверенные фрагменты — пометку (честная атрибуция).",
        "operationId": "diarize_object_v1_objects__object_id__diarize_post",
        "parameters": [
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-hidden-token",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Hidden-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DiarizeAccepted"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Diarize Object",
        "tags": [
          "objects"
        ]
      }
    },
    "/v1/objects/{object_id}/diarize-status/{task_id}": {
      "get": {
        "description": "Статус фоновой диаризации по task_id (как convert-status). Данных не отдаёт — только\nсостояние, поэтому доступа не раскрывает; результат клиент забирает GET /diarization.",
        "operationId": "diarize_status_v1_objects__object_id__diarize_status__task_id__get",
        "parameters": [
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "task_id",
            "required": true,
            "schema": {
              "title": "Task Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DiarizeStatus"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Diarize Status",
        "tags": [
          "objects"
        ]
      }
    },
    "/v1/objects/{object_id}/draft": {
      "delete": {
        "description": "Удалить черновик («отменить правки»). Идемпотентно: без черновика тоже 204.",
        "operationId": "delete_object_draft_v1_objects__object_id__draft_delete",
        "parameters": [
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-hidden-token",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Hidden-Token"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Delete Object Draft",
        "tags": [
          "objects"
        ]
      },
      "get": {
        "description": "Черновик редактора по файлу (E0): несохранённый текст владельца. Нет черновика → 404.",
        "operationId": "get_object_draft_v1_objects__object_id__draft_get",
        "parameters": [
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-hidden-token",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Hidden-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DraftOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get Object Draft",
        "tags": [
          "objects"
        ]
      },
      "put": {
        "description": "Автосохранение черновика редактора (E0): у владельца один черновик на файл (upsert).\n\nПубликацией НЕ является: байты в S3 не меняются, ``content_hash`` не трогаем, повторное\nобогащение/индексацию не запускаем. ``base_version`` запоминаем, чтобы при публикации\nпоймать чужую правку (412).",
        "operationId": "save_object_draft_v1_objects__object_id__draft_put",
        "parameters": [
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-hidden-token",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Hidden-Token"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DraftUpdate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DraftOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Save Object Draft",
        "tags": [
          "objects"
        ]
      }
    },
    "/v1/objects/{object_id}/enrichment": {
      "patch": {
        "description": "Ручная правка тегов/описания/заголовка. ``tsv`` (FTS) пересчитается сам; Qdrant —\nиз ``extracted_text`` (его не трогаем), поэтому векторы не рассинхронятся.",
        "operationId": "update_enrichment_v1_objects__object_id__enrichment_patch",
        "parameters": [
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-hidden-token",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Hidden-Token"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EnrichmentUpdateRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObjectDetail"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Update Enrichment",
        "tags": [
          "objects"
        ]
      }
    },
    "/v1/objects/{object_id}/image/{op}": {
      "post": {
        "description": "Операция над изображением: compress|resize|rotate|flip|crop. Параметры — в теле\n(``quality``/``max_side``/``angle``/``mode``/``box``, нужны по операции). Доступно только\nдля картинок (jpg/png/webp). Ставит Celery-задачу ``image_ops.run``; результат перезапишет\nисходный объект. Валидацию параметров делает ``image_ops.build_params`` (422 при ошибке).",
        "operationId": "image_op_v1_objects__object_id__image__op__post",
        "parameters": [
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "op",
            "required": true,
            "schema": {
              "title": "Op",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-hidden-token",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Hidden-Token"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ImageOpRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ImageOpAccepted"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Image Op",
        "tags": [
          "objects"
        ]
      }
    },
    "/v1/objects/{object_id}/lock-name": {
      "post": {
        "description": "Зафиксировать «не переименовывать» без смены имени (name_locked=true).",
        "operationId": "lock_name_endpoint_v1_objects__object_id__lock_name_post",
        "parameters": [
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-hidden-token",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Hidden-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObjectDetail"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Lock Name Endpoint",
        "tags": [
          "objects"
        ]
      }
    },
    "/v1/objects/{object_id}/page-image": {
      "get": {
        "description": "PNG указанной страницы PDF — для превью и разметки областей redact в приложении.\n\nРендер тот же (pypdfium2), что и у операции redact → нормализованные координаты боксов,\nнарисованных поверх этой картинки, точно ложатся при скрытии. Только для PDF.",
        "operationId": "pdf_page_image_v1_objects__object_id__page_image_get",
        "parameters": [
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "page",
            "required": false,
            "schema": {
              "default": 1,
              "maximum": 5001,
              "minimum": 1,
              "title": "Page",
              "type": "integer"
            }
          },
          {
            "in": "header",
            "name": "x-hidden-token",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Hidden-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Pdf Page Image",
        "tags": [
          "objects"
        ]
      }
    },
    "/v1/objects/{object_id}/pdf-info": {
      "get": {
        "description": "Число страниц PDF — приложению для навигатора страниц и разметки redact. Только для PDF.",
        "operationId": "pdf_info_v1_objects__object_id__pdf_info_get",
        "parameters": [
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-hidden-token",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Hidden-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PdfInfo"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Pdf Info",
        "tags": [
          "objects"
        ]
      }
    },
    "/v1/objects/{object_id}/pdf/{op}": {
      "post": {
        "description": "PDF-операция над объектом: compress|split|delete|rotate|reorder|protect|unlock.\n\nПараметры — в теле (``pages``/``angle``/``password``/``size``/``order``/``ranges``, нужны по\nоперации). Доступно только для PDF. Ставит Celery-задачу ``pdf_ops.run``; результат появится\nНОВЫМ объектом(-ами) и пройдёт обычный ingest (как ``/convert``). Валидацию параметров делает\n``pdf_ops.build_params`` (понятная 422-ошибка при нехватке/некорректности).",
        "operationId": "pdf_op_v1_objects__object_id__pdf__op__post",
        "parameters": [
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "op",
            "required": true,
            "schema": {
              "title": "Op",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-hidden-token",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Hidden-Token"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PdfOpRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PdfOpAccepted"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Pdf Op",
        "tags": [
          "objects"
        ]
      }
    },
    "/v1/objects/{object_id}/permanent": {
      "delete": {
        "description": "Окончательно удалить объект (из корзины или напрямую): строки БД + Qdrant + S3.",
        "operationId": "delete_object_permanent_v1_objects__object_id__permanent_delete",
        "parameters": [
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-hidden-token",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Hidden-Token"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Delete Object Permanent",
        "tags": [
          "objects"
        ]
      }
    },
    "/v1/objects/{object_id}/protocol": {
      "post": {
        "description": "Собирает протокол по записи ОТДЕЛЬНЫМ ФАЙЛОМ и кладёт его в облако.\n\nЧем отличается от ``/summarize``: тот отдаёт ТЕКСТ в панель, и текст исчезает вместе с\nкарточкой. Здесь появляется документ, который остаётся, ищется и отправляется дальше —\nровно то, зачем протокол и нужен.\n\nПриложения работают в две стороны: их текст участвует в сборке, а сами файлы попадают в\nраздел «Приложения» готового документа (фото — картинкой). Чужие id отсеет сама таска,\nно проверяем и здесь: молча собрать протокол с чужим документом внутри нельзя.",
        "operationId": "make_protocol_file_v1_objects__object_id__protocol_post",
        "parameters": [
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-hidden-token",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Hidden-Token"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProtocolRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProtocolAccepted"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Make Protocol File",
        "tags": [
          "objects"
        ]
      }
    },
    "/v1/objects/{object_id}/protocol/questions": {
      "get": {
        "description": "Уточняющие вопросы перед умным протоколом (C3/§6): чего не хватает — участники/дата/проект.\n\nИзвестное берём из обогащения (участники из ``entities.people``, дата встречи) и папки-проекта.\n``ready=true`` — данных достаточно, можно сразу звать ``/summarize?type=protocol``.",
        "operationId": "protocol_questions_v1_objects__object_id__protocol_questions_get",
        "parameters": [
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-hidden-token",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Hidden-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProtocolQuestionsOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Protocol Questions",
        "tags": [
          "objects"
        ]
      }
    },
    "/v1/objects/{object_id}/questions": {
      "get": {
        "description": "Предлагаемые вопросы по документу (Ф2, «как в Acrobat AI Assistant»): 3–5 кратких\nвопросов по извлечённому тексту — UI показывает их кликабельными подсказками над чатом.",
        "operationId": "object_questions_v1_objects__object_id__questions_get",
        "parameters": [
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-hidden-token",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Hidden-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SuggestedQuestionsOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Object Questions",
        "tags": [
          "objects"
        ]
      }
    },
    "/v1/objects/{object_id}/raw": {
      "get": {
        "description": "Сырые байты файла ЧЕРЕЗ наш API (а не presigned S3).\n\nНужно для превью в вебе: Flutter CanvasKit не может отрисовать картинку с S3 Timeweb\n(нет ``Access-Control-Allow-Origin``), а на этот эндпоинт наш CORSMiddleware (app_origins)\nзаголовки ставит — фронт читает байты по dio и рисует ``Image.memory`` / blob-iframe.",
        "operationId": "get_raw_v1_objects__object_id__raw_get",
        "parameters": [
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-hidden-token",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Hidden-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get Raw",
        "tags": [
          "objects"
        ]
      }
    },
    "/v1/objects/{object_id}/reprocess": {
      "post": {
        "description": "Проанализировать файл нейросетью ЗАНОВО (STORAGE_REDESIGN): сброс статуса → повторный\ningest (извлечение, авто-название/описание, категоризация, эмбеддинги). Для застрявших\n(failed/needs_manual) и для «перепрогнать свежей моделью». Разложенный вручную файл\nостаётся в своей папке. Идемпотентно: если файл уже в обработке — второй прогон не ставим.",
        "operationId": "reprocess_object_endpoint_v1_objects__object_id__reprocess_post",
        "parameters": [
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObjectAccepted"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Reprocess Object Endpoint",
        "tags": [
          "objects"
        ]
      }
    },
    "/v1/objects/{object_id}/restore": {
      "post": {
        "description": "Восстановить объект из корзины (deleted_at → NULL) — снова в списках/поиске.\n\nВозвращаем 204 (без тела): клиент тело не использует, а сериализация ObjectDetail после\nкоммита могла давать 500 при уже выполненном восстановлении («ошибка, но файл вернулся»).",
        "operationId": "restore_object_v1_objects__object_id__restore_post",
        "parameters": [
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-hidden-token",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Hidden-Token"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Restore Object",
        "tags": [
          "objects"
        ]
      }
    },
    "/v1/objects/{object_id}/restore-name": {
      "post": {
        "description": "Вернуть исходное имя файла (original_name) и снять лок.",
        "operationId": "restore_name_endpoint_v1_objects__object_id__restore_name_post",
        "parameters": [
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-hidden-token",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Hidden-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObjectDetail"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Restore Name Endpoint",
        "tags": [
          "objects"
        ]
      }
    },
    "/v1/objects/{object_id}/revisions": {
      "get": {
        "description": "История версий содержимого файла (E0), новые первыми.\n\nКаждая ревизия — снимок байтов ДО очередной правки; хранится последние\n``settings.revision_retention`` штук. Скоуп tenant+owner (чужой объект → 404).",
        "operationId": "object_revisions_v1_objects__object_id__revisions_get",
        "parameters": [
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-hidden-token",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Hidden-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RevisionList"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Object Revisions",
        "tags": [
          "objects"
        ]
      }
    },
    "/v1/objects/{object_id}/revisions/{version}/restore": {
      "post": {
        "description": "Откатить содержимое файла к ревизии.\n\nОткат сам по себе обратим: текущие байты снимаются НОВОЙ ревизией до восстановления,\nпоэтому «отменить отмену» — это просто откат к предыдущей версии.\n\n404 — такой версии нет (или её снимок утрачен). 409 — версия есть и видна в\n``GET /revisions``, но её содержимое уже занято ДРУГИМ файлом владельца: две принципиально\nразные причины, схлопывать их в одно «Версия не найдена» нельзя.\n\nСервис сообщает исход словом: ``ok`` | ``not_found`` | ``conflict``.",
        "operationId": "restore_object_revision_v1_objects__object_id__revisions__version__restore_post",
        "parameters": [
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "version",
            "required": true,
            "schema": {
              "title": "Version",
              "type": "integer"
            }
          },
          {
            "in": "header",
            "name": "x-hidden-token",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Hidden-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObjectContentSaved"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Restore Object Revision",
        "tags": [
          "objects"
        ]
      }
    },
    "/v1/objects/{object_id}/save-to-cloud": {
      "post": {
        "description": "Вложение чата (📎) → обычный файл: chat_only=false, файл появляется в сетке/счётчиках.",
        "operationId": "save_to_cloud_v1_objects__object_id__save_to_cloud_post",
        "parameters": [
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-hidden-token",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Hidden-Token"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Save To Cloud",
        "tags": [
          "objects"
        ]
      }
    },
    "/v1/objects/{object_id}/speakers": {
      "patch": {
        "description": "Ручная коррекция спикеров («это говорил Дмитрий Никулин»): переименовать метки и\nперерисовать транскрипт (его подхватит протокол). Ключ — текущая подпись «Спикер N» или\nметка движка (``SPEAKER_00``). Правка сохраняется в записи.",
        "operationId": "rename_speakers_v1_objects__object_id__speakers_patch",
        "parameters": [
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-hidden-token",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Hidden-Token"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SpeakerRenames"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DiarizedOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Rename Speakers",
        "tags": [
          "objects"
        ]
      }
    },
    "/v1/objects/{object_id}/summarize": {
      "post": {
        "description": "Конспект нужного типа по требованию (C4/§3.4): short | detailed | tasks | protocol.\n\nДля «protocol» ``context`` можно заполнить ответами на уточняющие вопросы (C3), чтобы\nумный протокол учёл участников/роли/проект/формат.",
        "operationId": "summarize_object_v1_objects__object_id__summarize_post",
        "parameters": [
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-hidden-token",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Hidden-Token"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SummarizeRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SummaryTextOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Summarize Object",
        "tags": [
          "objects"
        ]
      }
    },
    "/v1/objects/{object_id}/summary": {
      "get": {
        "description": "Содержание объекта из готовых метаданных. ``pending/processing`` — статус, не 500.",
        "operationId": "get_summary_v1_objects__object_id__summary_get",
        "parameters": [
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-hidden-token",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Hidden-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SummaryOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get Summary",
        "tags": [
          "content"
        ]
      }
    },
    "/v1/objects/{object_id}/text-content": {
      "get": {
        "description": "Редактируемый текст файла для встроенного редактора.\n\nПрямой текст (txt/md/код/разметка) — сами байты; docx/pdf — извлечённый текст (правится\nкак markdown, при сохранении пересобирается в исходный формат). Прочее — ``editable=False``.\n\nИзвлечение текста и вердикт «правится ли как текст» — общее ядро с инструментом агента\n(``services/text_content.load_text_content``), чтобы редактор и ``read_document``/\n``edit_document`` видели файл ОДИНАКОВО. Текст нередактируемых форматов (xlsx/pptx) ядро\nотдаёт агенту для чтения, но редактору он не нужен — здесь его отбрасываем (``editable``).\n\n``version`` — текущая версия содержимого: редактор запоминает её при открытии и возвращает\nкак ``base_version`` при сохранении/автосохранении (оптимистичная блокировка E0).",
        "operationId": "get_text_content_v1_objects__object_id__text_content_get",
        "parameters": [
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-hidden-token",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Hidden-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TextContentOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get Text Content",
        "tags": [
          "objects"
        ]
      }
    },
    "/v1/objects/{object_id}/thumbnail": {
      "get": {
        "description": "PNG-скриншот первой страницы (pdf/офис) — по запросу, с кешем в S3.\n\nЛёгкая альтернатива iframe/WebView для превью документов на всех платформах: фронт рисует\nкартинку, по клику открывает оригинал. Форматы без страниц (аудио/видео/картинки/сырой\nтекст) → 404, фронт показывает иконку (или саму картинку для изображений).",
        "operationId": "get_thumbnail_v1_objects__object_id__thumbnail_get",
        "parameters": [
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-hidden-token",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Hidden-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get Thumbnail",
        "tags": [
          "objects"
        ]
      }
    },
    "/v1/objects/{object_id}/transcript": {
      "get": {
        "description": "Сырая расшифровка записи как есть — без LLM, без диаризации, без затрат.\n\nДырка в UX, которую это закрывает: аудио и видео расшифровываются прямо при загрузке\n(ingest), текст лежит в ``extracted_text`` и участвует в поиске — но посмотреть его было\nнегде. Ближайшая вкладка «Спикеры» тянет за собой тяжёлый диар-воркер и время, сравнимое с\nдлительностью записи, ради того, что уже готово.\n\n``diarized`` говорит, размечен ли текст по спикерам: после диаризации ``extracted_text``\nПЕРЕЗАПИСЫВАЕТСЯ строками «Спикер N: …», и клиент должен показывать это как есть, а не\nвыдавать за исходную расшифровку.",
        "operationId": "get_transcript_v1_objects__object_id__transcript_get",
        "parameters": [
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-hidden-token",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Hidden-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TranscriptOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get Transcript",
        "tags": [
          "objects"
        ]
      }
    },
    "/v1/objects/{object_id}/translate": {
      "post": {
        "description": "Перевод объекта на ``target_lang`` → новый искомый ``.md``-объект.",
        "operationId": "translate_v1_objects__object_id__translate_post",
        "parameters": [
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TranslateRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TranslateAccepted"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Translate",
        "tags": [
          "content"
        ]
      }
    },
    "/v1/office/config/{object_id}": {
      "get": {
        "description": "Подписанный конфиг офисного редактора для файла владельца.\n\nНедоступность движка — не ошибка: отдаём ``enabled=false`` с причиной, фронт по ней\nпоказывает правку «как текст». 404 остаётся только за чужим/несуществующим объектом —\nи за скрытым, когда задан PIN, а валидного ``X-Hidden-Token`` в запросе нет: иначе\nподписанный конфиг стал бы обходом зоны «Скрытые» вместе с ``/office/file``.",
        "operationId": "office_config_v1_office_config__object_id__get",
        "parameters": [
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-hidden-token",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Hidden-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OfficeConfigOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Office Config",
        "tags": [
          "office"
        ]
      }
    },
    "/v1/recent-queries": {
      "get": {
        "description": "О чём владелец спрашивал за последние `days` дней — для подсказок и повтора.\n\nОтдельного журнала запросов нет: список выводится из истории чатов, поэтому сюда\nпопадает только то, что задавалось через `/ask`, `/chat` и агента.",
        "operationId": "recent_queries_v1_recent_queries_get",
        "parameters": [
          {
            "in": "query",
            "name": "days",
            "required": false,
            "schema": {
              "default": 30,
              "maximum": 365,
              "minimum": 1,
              "title": "Days",
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 50,
              "maximum": 200,
              "minimum": 1,
              "title": "Limit",
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecentQueryList"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Recent Queries",
        "tags": [
          "recent"
        ]
      }
    },
    "/v1/referral": {
      "get": {
        "description": "Код приглашения владельца + число присоединившихся по нему.",
        "operationId": "my_referral_v1_referral_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReferralOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "My Referral",
        "tags": [
          "referral"
        ]
      }
    },
    "/v1/referral/apply": {
      "post": {
        "description": "Применить код реферера (один раз, не свой). Возвращает, зачтён ли реферал.",
        "operationId": "apply_referral_v1_referral_apply_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReferralApply"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReferralApplyOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Apply Referral",
        "tags": [
          "referral"
        ]
      }
    },
    "/v1/rewrite": {
      "post": {
        "description": "Переписать/форматировать текст по пресету: shorter/longer/formal/casual/simpler/\nemail/report/bullets/takeaways.",
        "operationId": "rewrite_v1_rewrite_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RewriteRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RewriteOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Rewrite",
        "tags": [
          "rewrite"
        ]
      }
    },
    "/v1/search": {
      "get": {
        "description": "Найти файлы: вектор, полнотекст и имя с расширением одной выдачей.\n\nТри способа ищут разное и объединяются ранжированием, поэтому запрос вида `договор\nаренды` и запрос вида `акт-2024.pdf` работают оба. Пустой `q` возвращает пустую\nвыдачу, а не ошибку.\n\n`doc_type` (`contract`, `invoice`, `passport`, `meeting_minutes` и др.) сужает поиск\nпо типу документа и работает дешевле и точнее свободной формулировки.\n\n`top_k` ограничен сверху настройкой сервера: запрошенное большее число молча\nурезается — рассчитывать на выдачу произвольного размера нельзя.\n\nФайлы из «Скрытых» в выдачу не попадают, пока зона не разблокирована: нужен\n`include_hidden=true` вместе с заголовком `X-Hidden-Token`, который выдаёт разблокировка\nпо PIN. Без токена флаг гасится молча — иначе разница в ответах выдавала бы сам факт\nсуществования скрытого файла.\n\nОтвет — совпадения с оценкой; содержимое файла отдают `/objects/{id}/text-content`\n(текст) и `/objects/{id}/content` (временная ссылка на скачивание).",
        "operationId": "search_v1_search_get",
        "parameters": [
          {
            "in": "query",
            "name": "q",
            "required": false,
            "schema": {
              "default": "",
              "maxLength": 2000,
              "title": "Q",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "doc_type",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Doc Type"
            }
          },
          {
            "in": "query",
            "name": "top_k",
            "required": false,
            "schema": {
              "default": 0,
              "minimum": 0,
              "title": "Top K",
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "include_hidden",
            "required": false,
            "schema": {
              "default": false,
              "title": "Include Hidden",
              "type": "boolean"
            }
          },
          {
            "in": "header",
            "name": "x-hidden-token",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Hidden-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SearchResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Search",
        "tags": [
          "search"
        ]
      }
    },
    "/v1/settings": {
      "get": {
        "description": "Настройки владельца: часовой пояс, режим автопереименования, напоминания, `ui`.\n\n`ui` — свободный объект под нужды клиента: сервер в него не заглядывает и хранит как\nесть. Секретные значения (ключи чужих интеграций) сюда не попадают.",
        "operationId": "get_settings_v1_settings_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SettingsOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get Settings",
        "tags": [
          "settings"
        ]
      },
      "put": {
        "description": "Изменить настройки. Несмотря на `PUT`, тело **частичное**: незаданные поля\nсохраняются, а не обнуляются. Размер `ui` ограничен — превышение даёт `400`.",
        "operationId": "update_settings_v1_settings_put",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SettingsUpdate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SettingsOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Update Settings",
        "tags": [
          "settings"
        ]
      }
    },
    "/v1/settings/chat-memory": {
      "delete": {
        "description": "Стереть всю память о прошлых чатах (только этого владельца). Тумблер при этом не трогаем —\nотключение и очистка независимы (можно очистить, оставив память включённой на будущее).",
        "operationId": "clear_chat_memory_v1_settings_chat_memory_delete",
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Clear Chat Memory",
        "tags": [
          "settings"
        ]
      }
    },
    "/v1/share/{token}": {
      "get": {
        "description": "Метаданные ссылки для публичной страницы. Без верного пароля контент не раскрываем.",
        "operationId": "share_meta_v1_share__token__get",
        "parameters": [
          {
            "in": "path",
            "name": "token",
            "required": true,
            "schema": {
              "title": "Token",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-share-password",
            "required": false,
            "schema": {
              "default": "",
              "title": "X-Share-Password",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ShareMeta"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "security": [],
        "summary": "Share Meta",
        "tags": [
          "public-share"
        ]
      }
    },
    "/v1/share/{token}/objects": {
      "get": {
        "description": "Файлы общей папки (её под-дерева). Только для folder-ссылки.",
        "operationId": "share_objects_v1_share__token__objects_get",
        "parameters": [
          {
            "in": "path",
            "name": "token",
            "required": true,
            "schema": {
              "title": "Token",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 200,
              "maximum": 500,
              "minimum": 1,
              "title": "Limit",
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "offset",
            "required": false,
            "schema": {
              "default": 0,
              "minimum": 0,
              "title": "Offset",
              "type": "integer"
            }
          },
          {
            "in": "header",
            "name": "x-share-password",
            "required": false,
            "schema": {
              "default": "",
              "title": "X-Share-Password",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SharePublicList"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "security": [],
        "summary": "Share Objects",
        "tags": [
          "public-share"
        ]
      }
    },
    "/v1/share/{token}/objects/{object_id}/content": {
      "get": {
        "description": "Presigned-URL для скачивания файла (offload на S3).",
        "operationId": "share_content_v1_share__token__objects__object_id__content_get",
        "parameters": [
          {
            "in": "path",
            "name": "token",
            "required": true,
            "schema": {
              "title": "Token",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-share-password",
            "required": false,
            "schema": {
              "default": "",
              "title": "X-Share-Password",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContentUrl"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "security": [],
        "summary": "Share Content",
        "tags": [
          "public-share"
        ]
      }
    },
    "/v1/share/{token}/objects/{object_id}/page-image": {
      "get": {
        "description": "Страница PDF картинкой (PNG) — постраничный просмотр без скачивания файла.\n\nНумерация с единицы. Рендер идёт на сервере и стоит времени, поэтому ответ\nзакэширован; листать документ целиком через него дороже, чем отдать файл.",
        "operationId": "share_page_image_v1_share__token__objects__object_id__page_image_get",
        "parameters": [
          {
            "in": "path",
            "name": "token",
            "required": true,
            "schema": {
              "title": "Token",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "page",
            "required": false,
            "schema": {
              "default": 1,
              "maximum": 5001,
              "minimum": 1,
              "title": "Page",
              "type": "integer"
            }
          },
          {
            "in": "header",
            "name": "x-share-password",
            "required": false,
            "schema": {
              "default": "",
              "title": "X-Share-Password",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "security": [],
        "summary": "Share Page Image",
        "tags": [
          "public-share"
        ]
      }
    },
    "/v1/share/{token}/objects/{object_id}/pdf-info": {
      "get": {
        "description": "Сколько страниц в PDF, открытом по публичной ссылке.\n\nТокена в пути достаточно — авторизация здесь и есть ссылка; ключ аккаунта не\nнужен. Ссылка под паролем требует заголовок `X-Share-Password`. Не PDF — `415`.",
        "operationId": "share_pdf_info_v1_share__token__objects__object_id__pdf_info_get",
        "parameters": [
          {
            "in": "path",
            "name": "token",
            "required": true,
            "schema": {
              "title": "Token",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-share-password",
            "required": false,
            "schema": {
              "default": "",
              "title": "X-Share-Password",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PdfInfo"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "security": [],
        "summary": "Share Pdf Info",
        "tags": [
          "public-share"
        ]
      }
    },
    "/v1/share/{token}/objects/{object_id}/raw": {
      "get": {
        "description": "Сырые байты файла ЧЕРЕЗ наш API (CORS-friendly превью), как авторизованный /raw.",
        "operationId": "share_raw_v1_share__token__objects__object_id__raw_get",
        "parameters": [
          {
            "in": "path",
            "name": "token",
            "required": true,
            "schema": {
              "title": "Token",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-share-password",
            "required": false,
            "schema": {
              "default": "",
              "title": "X-Share-Password",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "security": [],
        "summary": "Share Raw",
        "tags": [
          "public-share"
        ]
      }
    },
    "/v1/share/{token}/objects/{object_id}/thumbnail": {
      "get": {
        "description": "PNG-превью первой страницы (кеш в S3, owner-agnostic).",
        "operationId": "share_thumbnail_v1_share__token__objects__object_id__thumbnail_get",
        "parameters": [
          {
            "in": "path",
            "name": "token",
            "required": true,
            "schema": {
              "title": "Token",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "object_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Object Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-share-password",
            "required": false,
            "schema": {
              "default": "",
              "title": "X-Share-Password",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "security": [],
        "summary": "Share Thumbnail",
        "tags": [
          "public-share"
        ]
      }
    },
    "/v1/share/{token}/upload": {
      "post": {
        "description": "Анонимная загрузка файла в общую папку (contributor). Файл ложится под owner'ом\nВЛАДЕЛЬЦА ссылки и в общую папку — появляется в его списке. Каппировано по размеру и числу.",
        "operationId": "share_upload_v1_share__token__upload_post",
        "parameters": [
          {
            "in": "path",
            "name": "token",
            "required": true,
            "schema": {
              "title": "Token",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-share-password",
            "required": false,
            "schema": {
              "default": "",
              "title": "X-Share-Password",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/Body_share_upload_v1_share__token__upload_post"
              }
            }
          }
        },
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ShareUploadOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "security": [],
        "summary": "Share Upload",
        "tags": [
          "public-share"
        ]
      }
    },
    "/v1/shares": {
      "get": {
        "description": "Мои активные ссылки (новые сверху). Возвращаем полный URL, чтобы владелец мог\nскопировать активную ссылку повторно (см. ShareLink.token_plain).",
        "operationId": "list_shares_v1_shares_get",
        "parameters": [
          {
            "in": "query",
            "name": "kind",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Kind"
            }
          },
          {
            "in": "query",
            "name": "resource_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "uuid",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Resource Id"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ShareList"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Shares",
        "tags": [
          "shares"
        ]
      },
      "post": {
        "description": "Создать ссылку на папку (kind=folder) или файл (kind=file). Токен — в ответе ОДИН раз.",
        "operationId": "create_share_v1_shares_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ShareCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ShareLinkOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Create Share",
        "tags": [
          "shares"
        ]
      }
    },
    "/v1/shares/{link_id}": {
      "delete": {
        "description": "Отозвать ссылку — доступ по ней сразу перестаёт работать.",
        "operationId": "revoke_share_v1_shares__link_id__delete",
        "parameters": [
          {
            "in": "path",
            "name": "link_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Link Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Revoke Share",
        "tags": [
          "shares"
        ]
      }
    },
    "/v1/tasks": {
      "get": {
        "description": "Поручения владельца: `open` (по умолчанию), `done` или `all`.\n\nСчётчики открытых и просроченных сервер считает по **всем** поручениям, а не по\nвыданной странице, — по ним можно рисовать бейдж, не вычитывая список целиком.\nСроки отдаются в часовом поясе владельца.\n\nЗаводит поручения агент (например, из протокола встречи); ручного создания здесь нет.",
        "operationId": "list_tasks_v1_tasks_get",
        "parameters": [
          {
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "default": "open",
              "pattern": "^(open|done|all)$",
              "title": "Status",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 50,
              "maximum": 200,
              "minimum": 1,
              "title": "Limit",
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaskList"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Tasks",
        "tags": [
          "tasks"
        ]
      }
    },
    "/v1/tasks/{task_id}": {
      "patch": {
        "description": "Отметить поручение сделанным или вернуть в работу (`status`).\n\nЧужой или несуществующий идентификатор отвечает одинаково — `404`.",
        "operationId": "update_task_v1_tasks__task_id__patch",
        "parameters": [
          {
            "in": "path",
            "name": "task_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Task Id",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TaskUpdate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaskOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Update Task",
        "tags": [
          "tasks"
        ]
      }
    },
    "/v1/telegram/bind": {
      "post": {
        "description": "Погасить код привязки Telegram: аккаунт приложения и tg-пользователь становятся\nодним владельцем, и файлы из бота видны в приложении.\n\nТолько для **сервисного** ключа инсталляции: код гасит рантайм бота, а не клиентский\nкод. Обычный `ak_`-токен получит здесь `403`, и это не ошибка настройки — сам код\nвыдаёт приложение владельцу (`POST /account/telegram/link-code`).",
        "operationId": "bind_v1_telegram_bind_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TelegramBindRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OkOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Bind",
        "tags": [
          "telegram"
        ]
      }
    },
    "/v1/themes": {
      "get": {
        "description": "Темы владельца со счётчиком папок (GROUP BY). Скрытые — только при include_hidden.",
        "operationId": "list_themes_v1_themes_get",
        "parameters": [
          {
            "in": "query",
            "name": "include_hidden",
            "required": false,
            "schema": {
              "default": false,
              "title": "Include Hidden",
              "type": "boolean"
            }
          },
          {
            "in": "header",
            "name": "x-hidden-token",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Hidden-Token"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ThemeList"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Themes",
        "tags": [
          "themes"
        ]
      },
      "post": {
        "description": "Создать тему — верхний ярус организации: тема содержит папки, папки содержат файлы.",
        "operationId": "create_theme_v1_themes_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ThemeCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ThemeOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Create Theme",
        "tags": [
          "themes"
        ]
      }
    },
    "/v1/themes/{theme_id}": {
      "delete": {
        "description": "Удалить тему. Папки и файлы остаются — папки просто становятся «без темы».",
        "operationId": "delete_theme_v1_themes__theme_id__delete",
        "parameters": [
          {
            "in": "path",
            "name": "theme_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Theme Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Delete Theme",
        "tags": [
          "themes"
        ]
      },
      "patch": {
        "description": "Переименовать тему, сменить значок или спрятать её целиком.\n\n`is_hidden` **каскадит**: вслед за темой в зону «Скрытые» уходят все её папки и все\nфайлы в них — и так же возвращаются обратно. Это единственная операция здесь с\nпоследствиями за пределами самой темы.",
        "operationId": "update_theme_v1_themes__theme_id__patch",
        "parameters": [
          {
            "in": "path",
            "name": "theme_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Theme Id",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ThemeUpdate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ThemeOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Update Theme",
        "tags": [
          "themes"
        ]
      }
    },
    "/v1/transcribe": {
      "post": {
        "description": "Распознать речь из аудио. Файл в облаке **не сохраняется** и не индексируется.\n\nЭто разовое распознавание — для голосовой команды или диктовки. Чтобы получить\nрасшифровку с разделением по говорящим и хранением, загрузите файл обычным\n`POST /objects` и запустите диаризацию.\n\nРазмер ограничен настройкой сервера; превышение — `413`, неподдерживаемый\nформат — `415`.",
        "operationId": "transcribe_v1_transcribe_post",
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/Body_transcribe_v1_transcribe_post"
              }
            }
          }
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TranscriptResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Transcribe",
        "tags": [
          "transcribe"
        ]
      }
    },
    "/v1/usage": {
      "get": {
        "description": "Сколько потрачено в рублях: суммарно и по статьям расхода.\n\n`days=0` (умолчание) — за всё время, иначе за последние N дней. Считается по фактически\nвыполненным операциям, поэтому сумма отстаёт от только что запущенной фоновой задачи:\nрасход появится, когда задача доработает. Остаток по тарифу — отдельно, в `/usage/quota`.",
        "operationId": "my_usage_v1_usage_get",
        "parameters": [
          {
            "in": "query",
            "name": "days",
            "required": false,
            "schema": {
              "default": 0,
              "maximum": 365,
              "minimum": 0,
              "title": "Days",
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UsageSummary"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "My Usage",
        "tags": [
          "usage"
        ]
      }
    },
    "/v1/usage/breakdown": {
      "get": {
        "description": "Сводный расход по всем юзерам — только супер-админ (``ADMIN_OWNERS``, ``require_superadmin``).",
        "operationId": "usage_breakdown_v1_usage_breakdown_get",
        "parameters": [
          {
            "in": "query",
            "name": "days",
            "required": false,
            "schema": {
              "default": 0,
              "maximum": 365,
              "minimum": 0,
              "title": "Days",
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UsageBreakdown"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Usage Breakdown",
        "tags": [
          "usage"
        ]
      }
    },
    "/v1/usage/history": {
      "get": {
        "description": "Дневной график расхода текущего юзера за последние N дней (для вкладки «Расходы»).",
        "operationId": "usage_history_v1_usage_history_get",
        "parameters": [
          {
            "in": "query",
            "name": "days",
            "required": false,
            "schema": {
              "default": 30,
              "maximum": 365,
              "minimum": 1,
              "title": "Days",
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/UsagePoint"
                  },
                  "title": "Response Usage History V1 Usage History Get",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Usage History",
        "tags": [
          "usage"
        ]
      }
    },
    "/v1/usage/quota": {
      "get": {
        "description": "Остаток месячного лимита (B2, «кольцо использования»): документы + минуты аудио.\n\nПлан берём из активной подписки (иначе free). Расход — за текущий календарный месяц.\nЧат лимитами не ограничивается (протокол §6.1): здесь только загрузки/аудио.",
        "operationId": "usage_quota_v1_usage_quota_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuotaOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Usage Quota",
        "tags": [
          "usage"
        ]
      }
    },
    "/v1/usage/tokens": {
      "get": {
        "description": "Расход в разрезе API-ключей: какой ключ сколько потратил.\n\nОтвечает на вопрос, который не разрешить общей суммой: интеграция разогналась или это\nработа в приложении. Строка с `token_id=null` — как раз «не через ключ»: приложение,\nфоновые задачи и всё, записанное до появления этого учёта. Без неё разбивка не сошлась\nбы с `GET /usage`.\n\nОтозванный ключ из выдачи не пропадает (`revoked=true`): потраченное им остаётся в\nистории, иначе сумма за прошлый месяц менялась бы задним числом при уборке ключей.",
        "operationId": "usage_by_token_v1_usage_tokens_get",
        "parameters": [
          {
            "in": "query",
            "name": "days",
            "required": false,
            "schema": {
              "default": 0,
              "maximum": 365,
              "minimum": 0,
              "title": "Days",
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TokenUsageList"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Usage By Token",
        "tags": [
          "usage"
        ]
      }
    },
    "/v1/voice-profiles": {
      "get": {
        "description": "Голосовые профили владельца (для панели «участники»).",
        "operationId": "list_voice_profiles_v1_voice_profiles_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/VoiceProfileOut"
                  },
                  "title": "Response List Voice Profiles V1 Voice Profiles Get",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Voice Profiles",
        "tags": [
          "voice"
        ]
      }
    },
    "/v1/voice-profiles/{profile_id}": {
      "delete": {
        "description": "Удаляет голосовой профиль (чужой/несуществующий → ok=false).",
        "operationId": "delete_voice_profile_v1_voice_profiles__profile_id__delete",
        "parameters": [
          {
            "in": "path",
            "name": "profile_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Profile Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OkOut"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Delete Voice Profile",
        "tags": [
          "voice"
        ]
      }
    }
  },
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "servers": [
    {
      "description": "Прод",
      "url": "https://api.cloud.agentums.ru"
    }
  ]
}
