---
openapi: 3.1.1
info:
  title: Chat Service API
  description:
    Manages the chat functionality for the BookWorm platform, providing
    conversational interactions about books and reading recommendations
  contact:
    name: Nhan Nguyen
    url: https://github.com/foxminchan
    email: nguyenxuannhan407@gmail.com
  license:
    name: MIT
    url: https://opensource.org/licenses/MIT
  version: "1.0"
externalDocs:
  description: Documentation
  url: https://github.com/foxminchan/BookWorm
servers:
  - url: "{protocol}://{environment}.chat.bookworm.com"
    description: Before deploying to production, ensure the environment is set correctly
    variables:
      protocol:
        enum:
          - https
          - http
          - wss
        default: https
      environment:
        enum:
          - dev
          - stg
          - qa
        default: dev
  - url: "{protocol}://chat.bookworm.com"
    description: Production
    variables:
      protocol:
        enum:
          - https
          - wss
        default: https
security:
  - OAuth:
      - chatting
paths:
  "/api/v1/chats":
    post:
      tags:
        - Chat
      summary: Create Chat
      description: Create a new chat in the catalog system
      x-eventcatalog-message-type: command
      operationId: CreateChatEndpoint
      security:
        - OAuth:
            - chatting
      requestBody:
        description: The command to create a chat
        content:
          application/json:
            schema:
              "$ref": "#/components/schemas/CreateChatCommand"
            example:
              name: "Book Recommendations Chat"
        required: true
      responses:
        "201":
          description: Created
          content:
            application/json:
              schema:
                type: string
                format: uuid
                description: The unique identifier of the created chat
                example: "01961f13-64ef-7dbb-84a1-25114e2e0ca4"
          headers:
            Location:
              description: The URI of the created chat
              schema:
                type: string
                format: uri
                example: "/api/v1/chats/01961f13-64ef-7dbb-84a1-25114e2e0ca4"
        "400":
          description: Bad Request
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ProblemDetails"
              examples:
                empty-name:
                  summary: "Chat name is empty"
                  value:
                    type: "https://tools.ietf.org/html/rfc9110#section-15.5.1"
                    title: "Validation failed"
                    status: 400
                    detail: "One or more validation errors has occurred"
                    errors:
                      - propertyName: "name"
                        errorMessage: "'Name' must not be empty."
                        severity: 0
        "401":
          description: Unauthorized - Access token is missing or invalid.
    get:
      tags:
        - Chat
      summary: List Chats
      description: List all chats with optional filtering
      x-eventcatalog-message-type: query
      operationId: ListChatEndpoint
      security:
        - OAuth:
            - chatting
      parameters:
        - name: name
          in: query
          description: The name of the conversation to filter by
          required: false
          schema:
            type: string
            example: "Book Recommendations"
        - name: userId
          in: query
          description: The user ID to filter conversations by (admin only)
          required: false
          schema:
            type: string
            format: uuid
            example: "01961f13-64ef-7dbb-84a1-25114e2e0ca4"
        - name: includeMessages
          in: query
          description: Flag to include messages in the result
          required: false
          schema:
            type: boolean
            default: false
            example: false
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  "$ref": "#/components/schemas/ConversationDto"
              examples:
                chat-empty:
                  summary: "Empty chat list"
                  value: []
                chat-with-messages:
                  summary: "Chat list with messages"
                  value:
                    - id: "01961f13-64ef-7dbb-84a1-25114e2e0ca4"
                      name: "Book Recommendations"
                      userId: "01961f13-64ef-7dbb-84a1-25114e2e0ca4"
                      messages:
                        - id: "01961f13-64ef-7dbb-84a1-25114e2e0ca4"
                          text: "What are the top science fiction books available?"
                          role: "user"
                          parentMessageId: "01961f13-64ef-7dbb-84a1-25114e2e0ca4"
                          createdAt: "2023-10-01T12:00:00Z"
                        - id: "01961f13-64ef-7dbb-84a1-25114e2e0ca4"
                          text: "Here are some recommendations: Dune, Neuromancer, Foundation."
                          role: "assistant"
                          parentMessageId: "01961f13-64ef-7dbb-84a1-25114e2e0ca4"
                          createdAt: "2023-10-01T12:05:00Z"
                chat-without-messages:
                  summary: "Chat list without messages"
                  value:
                    - id: "01961f13-64ef-7dbb-84a1-25114e2e0ca4"
                      name: "Book Recommendations"
                      userId: "01961f13-64ef-7dbb-84a1-25114e2e0ca4"
                      messages: []
        "401":
          description: Unauthorized - Access token is missing or invalid.
    put:
      tags:
        - Chat
      summary: Update Chat
      description: Update an existing chat in the catalog system
      x-eventcatalog-message-type: command
      operationId: UpdateChatEndpoint
      security:
        - OAuth:
            - chatting
      requestBody:
        description: The command to update a chat
        content:
          application/json:
            schema:
              "$ref": "#/components/schemas/UpdateChatCommand"
            example:
              id: "01961f13-64ef-7dbb-84a1-25114e2e0ca4"
              prompt:
                text: "What are the top science fiction books available?"
        required: true
      responses:
        "204":
          description: No Content
        "400":
          description: Bad Request
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ProblemDetails"
              examples:
                empty-id:
                  summary: "Chat ID is empty"
                  value:
                    type: "https://tools.ietf.org/html/rfc9110#section-15.5.1"
                    title: "Validation failed"
                    status: 400
                    detail: "One or more validation errors has occurred"
                    errors:
                      - propertyName: "id"
                        errorMessage: "'Id' must not be empty."
                        severity: 0
                empty-prompt:
                  summary: "Chat prompt is empty"
                  value:
                    type: "https://tools.ietf.org/html/rfc9110#section-15.5.1"
                    title: "Validation failed"
                    status: 400
                    detail: "One or more validation errors has occurred"
                    errors:
                      - propertyName: "prompt"
                        errorMessage: "'Prompt' must not be empty."
                        severity: 0
        "401":
          description: Unauthorized - Access token is missing or invalid.
        "404":
          description: Not Found
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ProblemDetails"
  "/api/v1/chats/{id}":
    get:
      tags:
        - Chat
      summary: Get Chat
      description: Get a chat by its ID
      x-eventcatalog-message-type: query
      operationId: GetChatEndpoint
      security:
        - OAuth:
            - chatting
      parameters:
        - name: id
          in: path
          description: The unique identifier of the chat
          required: true
          schema:
            type: string
            format: uuid
            example: "01961f13-64ef-7dbb-84a1-25114e2e0ca4"
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ConversationDto"
              example:
                id: "01961f13-64ef-7dbb-84a1-25114e2e0ca4"
                name: "Book Recommendations"
                userId: "01961f13-64ef-7dbb-84a1-25114e2e0ca4"
                messages:
                  - id: "01961f13-64ef-7dbb-84a1-25114e2e0ca4"
                    text: "What are the top science fiction books available?"
                    role: "user"
                    parentMessageId: "01961f13-64ef-7dbb-84a1-25114e2e0ca4"
                    createdAt: "2023-10-01T12:00:00Z"
        "404":
          description: Not Found
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ProblemDetails"
              example:
                type: "https://tools.ietf.org/html/rfc9110#section-15.5.5"
                title: "Not Found"
                status: 404
                detail: "Chat with id 01961f13-64ef-7dbb-84a1-25114e2e0ca4 not found."
        "401":
          description: Unauthorized - Access token is missing or invalid.
    delete:
      tags:
        - Chat
      summary: Delete Chat
      description: Delete a chat by its ID
      x-eventcatalog-message-type: command
      operationId: DeleteChatEndpoint
      security:
        - OAuth:
            - chatting
      parameters:
        - name: id
          in: path
          description: The unique identifier of the chat to be deleted
          required: true
          schema:
            type: string
            format: uuid
            example: "01961f13-64ef-7dbb-84a1-25114e2e0ca4"
      responses:
        "204":
          description: No Content
        "404":
          description: Not Found
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/ProblemDetails"
              example:
                type: "https://tools.ietf.org/html/rfc9110#section-15.5.5"
                title: "Not Found"
                status: 404
                detail: "Chat with id 01961f13-64ef-7dbb-84a1-25114e2e0ca4 not found."
        "401":
          description: Unauthorized - Access token is missing or invalid.
  "/api/v1/chats/{id}/cancel":
    delete:
      tags:
        - Chat
      summary: Cancel Chat
      description: Cancel a chat if it exists
      x-eventcatalog-message-type: command
      operationId: CancelChatEndpoint
      security:
        - OAuth:
            - chatting
      parameters:
        - name: id
          in: path
          description: The unique identifier of the chat to be cancelled
          required: true
          schema:
            type: string
            format: uuid
            example: "01961f13-64ef-7dbb-84a1-25114e2e0ca4"
      responses:
        "204":
          description: No Content
        "401":
          description: Unauthorized - Access token is missing or invalid.
  "/api/v1/chats/stream":
    get:
      tags:
        - Chat
      summary: Chat Stream
      x-eventcatalog-message-type: command
      description: SignalR hub endpoint for real-time chat streaming
      operationId: ChatStreamEndpoint
      security:
        - OAuth:
            - chatting
      responses:
        "101":
          description: Switching Protocols - WebSocket connection established
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: string
              example: "Chat stream endpoint is available."
        "401":
          description: Unauthorized - Access token is missing or invalid.
  "/api/v1/agents/summarize/.well-known/agent.json":
    get:
      tags:
        - SummarizeAgent
      summary: Get Summarize Agent Info
      x-eventcatalog-message-type: query
      description: Retrieve information about the Summarize Agent
      responses:
        "200":
          description: OK
  "/api/v1/agents/summarize":
    post:
      tags:
        - SummarizeAgent
      summary: Send Summarize Request
      x-eventcatalog-message-type: command
      description: Send a request to the Summarize Agent
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/JsonRpcRequest"
        required: true
      responses:
        "200":
          description: OK
  "/api/v1/agents/summarize/tasks/{id}":
    get:
      tags:
        - SummarizeAgent
      summary: Get Summarize Task
      x-eventcatalog-message-type: query
      description: Retrieve a specific task from the Summarize Agent
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
        - name: historyLength
          in: query
          schema:
            type: integer
            format: int32
            default: 0
        - name: metadata
          in: query
          schema:
            type: string
            default: null
      responses:
        "200":
          description: OK
  "/api/v1/agents/summarize/tasks/{id}/cancel":
    post:
      tags:
        - SummarizeAgent
      summary: Cancel Summarize Task
      x-eventcatalog-message-type: command
      description: Cancel a specific task from the Summarize Agent
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: OK
  "/api/v1/agents/summarize/send":
    post:
      tags:
        - SummarizeAgent
      summary: Send Summarize Request
      x-eventcatalog-message-type: command
      description: Send a request to the Summarize Agent with optional parameters
      parameters:
        - name: historyLength
          in: query
          schema:
            type: integer
            format: int32
        - name: metadata
          in: query
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/MessageSendParams"
        required: true
      responses:
        "200":
          description: OK
  "/api/v1/agents/summarize/tasks/{id}/send":
    post:
      tags:
        - SummarizeAgent
      summary: Send Summarize Task
      x-eventcatalog-message-type: command
      description: Send a request to the Summarize Agent for a specific task
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
        - name: historyLength
          in: query
          schema:
            type: integer
            format: int32
        - name: metadata
          in: query
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/MessageSendParams"
        required: true
      responses:
        "200":
          description: OK
  "/api/v1/agents/summarize/tasks/{id}/sendSubscribe":
    post:
      tags:
        - SummarizeAgent
      summary: Send Summarize Task with Subscribe
      x-eventcatalog-message-type: command
      description: Send a request to the Summarize Agent for a specific task with subscribe
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
        - name: historyLength
          in: query
          schema:
            type: integer
            format: int32
        - name: metadata
          in: query
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/MessageSendParams"
        required: true
      responses:
        "200":
          description: OK
  "/api/v1/agents/summarize/tasks/{id}/resubscribe":
    post:
      tags:
        - SummarizeAgent
      summary: Resubscribe to Summarize Task
      x-eventcatalog-message-type: command
      description: Resubscribe to a specific task from the Summarize Agent
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: OK
  "/api/v1/agents/summarize/tasks/{id}/pushNotification":
    put:
      tags:
        - SummarizeAgent
      summary: Set Push Notification for Summarize Task
      x-eventcatalog-message-type: command
      description: Set up push notification for a specific task from the Summarize Agent
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PushNotificationConfig"
        required: true
      responses:
        "200":
          description: OK
    get:
      tags:
        - SummarizeAgent
      summary: Get Push Notification for Summarize Task
      x-eventcatalog-message-type: query
      description: Get the push notification settings for a specific task from the Summarize Agent
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: OK
  "/api/v1/agents/sentiment/.well-known/agent.json":
    get:
      tags:
        - SentimentAgent
      summary: Get Sentiment Agent Info
      x-eventcatalog-message-type: query
      description: Get information about the Sentiment Agent
      responses:
        "200":
          description: OK
  "/api/v1/agents/sentiment":
    post:
      tags:
        - SentimentAgent
      summary: Send Sentiment Request
      x-eventcatalog-message-type: command
      description: Send a request to the Sentiment Agent
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/JsonRpcRequest"
        required: true
      responses:
        "200":
          description: OK
  "/api/v1/agents/sentiment/tasks/{id}":
    get:
      tags:
        - SentimentAgent
      summary: Get Sentiment Task
      x-eventcatalog-message-type: query
      description: Get the details of a specific sentiment task
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
        - name: historyLength
          in: query
          schema:
            type: integer
            format: int32
            default: 0
        - name: metadata
          in: query
          schema:
            type: string
            default: null
      responses:
        "200":
          description: OK
  "/api/v1/agents/sentiment/tasks/{id}/cancel":
    post:
      tags:
        - SentimentAgent
      summary: Cancel Sentiment Task
      x-eventcatalog-message-type: command
      description: Cancel a specific sentiment task
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: OK
  "/api/v1/agents/sentiment/send":
    post:
      tags:
        - SentimentAgent
      summary: Send Sentiment Request
      x-eventcatalog-message-type: command
      description: Send a request to the Sentiment Agent
      parameters:
        - name: historyLength
          in: query
          schema:
            type: integer
            format: int32
        - name: metadata
          in: query
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/MessageSendParams"
        required: true
      responses:
        "200":
          description: OK
  "/api/v1/agents/sentiment/tasks/{id}/send":
    post:
      tags:
        - SentimentAgent
      summary: Send Sentiment Task
      x-eventcatalog-message-type: command
      description: Send a request to the Sentiment Agent for a specific task
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
        - name: historyLength
          in: query
          schema:
            type: integer
            format: int32
        - name: metadata
          in: query
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/MessageSendParams"
        required: true
      responses:
        "200":
          description: OK
  "/api/v1/agents/sentiment/tasks/{id}/sendSubscribe":
    post:
      tags:
        - SentimentAgent
      summary: Send Sentiment Task with Subscribe
      x-eventcatalog-message-type: command
      description: Send a request to the Sentiment Agent for a specific task with subscription
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
        - name: historyLength
          in: query
          schema:
            type: integer
            format: int32
        - name: metadata
          in: query
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/MessageSendParams"
        required: true
      responses:
        "200":
          description: OK
  "/api/v1/agents/sentiment/tasks/{id}/resubscribe":
    post:
      tags:
        - SentimentAgent
      summary: Resubscribe to Sentiment Task
      x-eventcatalog-message-type: command
      description: Resubscribe to a specific sentiment task
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: OK
  "/api/v1/agents/sentiment/tasks/{id}/pushNotification":
    put:
      tags:
        - SentimentAgent
      summary: Set Push Notification for Sentiment Task
      x-eventcatalog-message-type: command
      description: Set up push notification for a specific sentiment task
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PushNotificationConfig"
        required: true
      responses:
        "200":
          description: OK
    get:
      tags:
        - SentimentAgent
      summary: Get Push Notification for Sentiment Task
      x-eventcatalog-message-type: query
      description: Get the push notification settings for a specific sentiment task
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: OK
components:
  schemas:
    AuthenticationInfo:
      required:
        - schemes
      type: object
      description: Information about the authentication schemes supported by the agent
      properties:
        schemes:
          type: array
          items:
            type: string
        credentials:
          type: string
    JsonRpcRequest:
      type: object
      properties:
        jsonrpc:
          type: string
        id:
          type: string
        method:
          type: string
        params:
          $ref: "#/components/schemas/NullableOfJsonElement"
    Message:
      required:
        - role
        - parts
        - messageId
      type: object
      properties:
        role:
          $ref: "#/components/schemas/MessageRole"
        parts:
          type: array
          items:
            $ref: "#/components/schemas/Part"
        metadata:
          type: object
        referenceTaskIds:
          type: array
          items:
            type: string
        messageId:
          type:
            - "string"
            - "null"
        taskId:
          type: string
        contextId:
          type: string
        extensions:
          type: array
          items:
            type: string
    MessageRole: {}
    MessageSendConfiguration:
      type: object
      properties:
        acceptedOutputModes:
          type: array
          items:
            type: string
        pushNotification:
          $ref: "#/components/schemas/PushNotificationConfig"
        historyLength:
          type: integer
          format: int32
        blocking:
          type: boolean
    MessageSendParams:
      required:
        - message
      type: object
      properties:
        message:
          $ref: "#/components/schemas/Message"
        configuration:
          $ref: "#/components/schemas/MessageSendConfiguration"
        metadata:
          type: object
    NullableOfJsonElement: {}
    Part:
      required:
        - kind
      type: object
      anyOf:
        - $ref: "#/components/schemas/PartTextPart"
        - $ref: "#/components/schemas/PartFilePart"
        - $ref: "#/components/schemas/PartDataPart"
      discriminator:
        propertyName: kind
        mapping:
          text: "#/components/schemas/PartTextPart"
          file: "#/components/schemas/PartFilePart"
          data: "#/components/schemas/PartDataPart"
    PartDataPart:
      properties:
        kind:
          enum:
            - data
          type: string
        data:
          type: object
        metadata:
          type: object
    PartFilePart:
      properties:
        kind:
          enum:
            - file
          type: string
        file:
          type: object
          properties:
            name:
              type: string
            mimeType:
              type: string
            bytes:
              type: string
            uri:
              type: string
        metadata:
          type: object
    PartTextPart:
      properties:
        kind:
          enum:
            - text
          type: string
        text:
          type: string
        metadata:
          type: object
    Prompt:
      required:
        - text
      type: object
      writeOnly: true
      description: The prompt for creating a chat in the catalog system
      properties:
        text:
          type: string
          description: The text of the prompt
          example: "What is the best book in the world?"
    ProblemDetails:
      type: object
      readOnly: true
      x-scalar-ignore: true
      description: RFC 9110 (https://tools.ietf.org/html/rfc9110)
      properties:
        type:
          type: string
          description: The type of the problem
          example: "https://tools.ietf.org/html/rfc9110#section-15.5.5"
        title:
          type: string
          description: The title of the problem
          example: "Not Found"
        status:
          type: integer
          format: int32
          description: The status code of the problem
          example: 404
        detail:
          type: string
          description: The detail of the problem
          example: "Chat with id 01961f13-64ef-7dbb-84a1-25114e2e0ca4 not found."
    PushNotificationConfig:
      required:
        - url
      type: object
      properties:
        url:
          type: string
        token:
          type: string
        authentication:
          $ref: "#/components/schemas/AuthenticationInfo"
    ConversationDto:
      type: object
      readOnly: true
      description: A conversation in the catalog system
      properties:
        id:
          type: string
          format: uuid
          description: The unique identifier of the conversation
          example: "01961f13-64ef-7dbb-84a1-25114e2e0ca4"
        name:
          type: string
          description: The name of the conversation
          example: "Book Recommendations"
        userId:
          type: string
          format: uuid
          description: The ID of the user who created the conversation
          example: "01961f13-64ef-7dbb-84a1-25114e2e0ca4"
        messages:
          type: array
          items:
            "$ref": "#/components/schemas/MessageDto"
    CreateChatCommand:
      type: object
      required:
        - name
      description: Command to create a chat in the catalog system
      properties:
        name:
          type: string
          description: The name of the chat
          example: "Book Recommendations Chat"
    UpdateChatCommand:
      type: object
      required:
        - id
        - prompt
      description: Command to update a chat in the catalog system
      properties:
        id:
          type: string
          format: uuid
          description: The unique identifier of the chat to be updated
          example: "01961f13-64ef-7dbb-84a1-25114e2e0ca4"
        prompt:
          "$ref": "#/components/schemas/Prompt"
    MessageDto:
      type: object
      readOnly: true
      description: A message in a conversation
      properties:
        id:
          type: string
          format: uuid
          description: The unique identifier of the message
          example: "01961f13-64ef-7dbb-84a1-25114e2e0ca4"
        text:
          type: string
          description: The text of the message
          example: "What are the top science fiction books available?"
        role:
          type: string
          description: The role of the message sender (e.g., user, assistant)
          example: "user"
        parentMessageId:
          type:
            - "string"
            - "null"
          format: uuid
          description: The ID of the parent message, if any
          example: "01961f13-64ef-7dbb-84a1-25114e2e0ca4"
        createdAt:
          type: string
          format: date-time
          description: The timestamp when the message was created
          example: "2023-10-01T12:00:00Z"
  securitySchemes:
    OAuth:
      type: oauth2
      description: OAuth2 security scheme for the BookWorm API
      flows:
        authorizationCode:
          authorizationUrl: "https://auth.bookworm.com/realms/bookworm/protocol/openid-connect/auth"
          tokenUrl: "https://auth.bookworm.com/realms/bookworm/protocol/openid-connect/token"
          scopes:
            chatting: "Chatting API"
tags:
  - name: Chat
    description: Endpoints for handling book-related discussions and user interactions in chat format
  - name: SummarizeAgent
    description: Agent for summarizing book-related content
  - name: SentimentAgent
    description: Agent for analyzing sentiment in book-related discussions
