import { CodeGroup } from '../code.tsx'
import { Row, Col, Properties, Property, Heading, SubProperty } from '../md.tsx'

# 对话型应用 API

可用于大部分场景的对话型应用，采用一问一答模式与用户持续对话。要开始一个对话请调用 chat-messages 接口，通过继续传入返回的 conversation_id 可持续保持该会话。**[开始前请阅读 !! 什么是 Bearer Token ？](https://swagger.io/docs/specification/authentication/bearer-authentication/)**

<div>
  ### 鉴权

  Dify Service API 使用 `API-Key` 进行鉴权。

  建议开发者把 `API-Key` 放在后端存储，而非分享或者放在客户端存储，以免 `API-Key` 泄露，导致财产损失。

  所有 API 请求都应在 **`Authorization`** HTTP Header 中包含您的 `API-Key`，如下所示：

  <CodeGroup title="Code">
    ```javascript
      Authorization: Bearer {API_KEY}

    ```
  </CodeGroup>
</div>

---

<Heading
  url='/chat-messages'
  method='POST'
  title='发送对话消息'
  name='#Create-Chat-Message'
/>
<Row>
  <Col>
    创建会话消息，或基于此前的对话继续发送消息。

    ### Request Body

    <Properties>
      <Property name='inputs' type='object' key='inputs'>
        （选填）以键值对方式提供用户输入字段，与提示词编排中的变量对应。Key 为变量名称，Value 是参数值。如果字段类型为 Select，传入的 Value 需为预设选项之一。
        <ul>
         {!!props.variables.length && props.variables.map(
            val => (
                <SubProperty name={val.key} type={val.type} key={val.key}>
                  {val.name ? `${val.name}` : ''}
                </SubProperty>
            )
        )}
        </ul>
      </Property>
      <Property name='query' type='string' key='query'>
        用户输入/提问内容
      </Property>
      <Property name='response_mode' type='string' key='response_mode'>
        - blocking 阻塞型，等待执行完毕后返回结果。（请求若流程较长可能会被中断）
        - streaming 流式返回。基于 SSE（**[Server-Sent Events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events)**）实现流式返回。
      </Property>
      <Property name='conversation_id' type='string' key='conversation_id'>
      （必填）<strong>‼️ 会话标识符，首次对话为 conversation_id: "" ‼️</strong>，如果要继续对话请传入上下文返回的 conversation_id
      </Property>
      <Property name='user' type='string' key='user'>
        用户标识，由开发者定义规则，需保证用户标识在应用内唯一。
      </Property>
      <Property name='files' type='array[object]' key='files'>
          上传的文件。
          - `type` 文件类型:目前仅支持 `image`。
          - `transfer_method` 传递方式:
            - `remote_url`: 图片地址。
            - `local_file`: 上传文件。
          - `upload_file_id` 上传文件 ID。`transfer_method` 为 `local_file` 时必填。
          - `url` 图片地址。`transfer_method` 为 `remote_url` 时必填。
      </Property>
    </Properties>
  </Col>
  <Col sticky>

    <CodeGroup title="Request" tag="POST" label="/chat-messages" targetCode={`curl --location --request POST '${props.appDetail.api_base_url}/chat-messages' \\\n--header 'Authorization: Bearer ENTER-YOUR-SECRET-KEY' \\\n--header 'Content-Type: application/json' \\\n--data-raw '{\n    "inputs": ${JSON.stringify(props.inputs)},\n    "query": "eh",\n    "response_mode": "streaming",\n    "conversation_id": "",\n    "user": "abc-123"\n}'\n`}>

    ```bash {{ title: 'cURL' }}
    curl --location --request POST '${props.appDetail.api_base_url}/chat-messages' \
    --header 'Authorization: Bearer ENTER-YOUR-SECRET-KEY' \
    --header 'Content-Type: application/json' \
    --data-raw '{
        "inputs": {},
        "query": "eh",
        "response_mode": "streaming",
        "conversation_id": "",
        "user": "abc-123"
    }'
    ```

    </CodeGroup>
    ### blocking
    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "answer": "Hi, is there anything I can help you?",
      "conversation_id": "45701982-8118-4bc5-8e9b-64562b4555f2",
      "created_at": 1679587005,
      "id": "059f87d9-15c0-473a-870c-fde95cdcc1e4"
    }
    ```
    </CodeGroup>
    ### streaming
    <CodeGroup title="Response">
    ```streaming {{ title: 'Response' }}
      data: {"id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "answer": " I", "created_at": 1679586595}
      data: {"id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "answer": " I", "created_at": 1679586595}
    ```
    </CodeGroup>
  </Col>
</Row>

---

<Heading
  url='/messages/{message_id}/feedbacks'
  method='POST'
  title='消息反馈（点赞）'
  name='#feedbacks'
/>
<Row>
  <Col>
    代表最终用户对返回消息进行评价，可以点赞与点踩，该数据将在“日志与标注”页中可见，并用于后续的模型微调。

    ### Path Params
    <Properties>
      <Property name='message_id' type='string' key='message_id'>
       消息 ID
      </Property>
    </Properties>

    ### Request Body

    <Properties>
      <Property name='rating' type='string' key='rating'>
       like 或 dislike， 空值为撤销
      </Property>
      <Property name='user' type='string' key='user'>
        用户标识，由开发者定义规则，需保证用户标识在应用内唯一。
      </Property>
    </Properties>
  </Col>
  <Col sticky>

    <CodeGroup title="Request" tag="POST" label="/messages/{message_id}/feedbacks" targetCode={`curl --location --request POST '${props.appDetail.api_base_url}/messages/{message_id}/feedbacks \\\n--header 'Authorization: Bearer ENTER-YOUR-SECRET-KEY' \\\n--header 'Content-Type: application/json' \\\n--data-raw '{\n    "rating": "like",\n    "user": "abc-123"\n}'`}>

    ```bash {{ title: 'cURL' }}
    curl --location --request POST '${props.appDetail.api_base_url}/messages/{message_id}/feedbacks' \
    --header 'Authorization: Bearer ENTER-YOUR-SECRET-KEY' \
    --header 'Content-Type: application/json' \
    --data-raw '{
        "rating": "like",
        "user": "abc-123"
    }'
    ```

    </CodeGroup>

    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "has_more": false,
      "data": [
        {
          "id": "WAz8eIbvDR60rouK",
          "username": "FrankMcCallister",
          "phone_number": "1-800-759-3000",
          "avatar_url": "https://assets.protocol.chat/avatars/frank.jpg",
          "display_name": null,
          "conversation_id": "xgQQXg3hrtjh7AvZ",
          "created_at": 692233200
        },
        {
          "id": "hSIhXBhNe8X1d8Et"
          // ...
        }
      ]
    }
    ```
    </CodeGroup>
  </Col>
</Row>

---

<Heading
  url='/messages/{message_id}/suggested'
  method='GET'
  title='消息下一步问题建议'
  name='#suggested'
/>
<Row>
  <Col>
    获取针对当前问题的下一步问题建议

    ### Path Params

    <Properties>
      <Property name='message_id' type='string' key='message_id'>
        消息 ID
      </Property>
    </Properties>
  </Col>
  <Col sticky>

    <CodeGroup title="Request" tag="GET" label="/messages/{message_id}/suggested" targetCode={`curl --location --request GET '${props.appDetail.api_base_url}/messages/{message_id}/suggested' \\\n--header 'Authorization: Bearer ENTER-YOUR-SECRET-KEY' \\\n--header 'Content-Type: application/json'`}>

    ```bash {{ title: 'cURL' }}
    curl --location --request GET '${props.appDetail.api_base_url}/messages/{message_id}/suggested' \
    --header 'Authorization: Bearer ENTER-YOUR-SECRET-KEY' \
    --header 'Content-Type: application/json' \
    ```

    </CodeGroup>

    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "result": "success",
      "data": [
            "a",
            "b",
            "c"
        ]
      ]
    }
    ```
    </CodeGroup>
  </Col>
</Row>

---

<Heading
  url='/messages'
  method='GET'
  title='获取会话历史消息'
  name='#messages'
/>
<Row>
  <Col>
    滚动加载形式返回历史聊天记录，第一页返回最新 `limit` 条，加载更多时，返回 `first_id` 之前的 `limit` 条。

    ### Query

    <Properties>
      <Property name='conversation_id' type='string' key='conversation_id'>
        会话 ID
      </Property>
      <Property name='first_id' type='string' key='first_id'>
        当前页第一条聊天记录的 ID，默认 none
      </Property>
      <Property name='limit' type='int' key='limit'>
        一次请求返回多少条聊天记录
      </Property>
      <Property name='user' type='string' key='user'>
        用户标识，由开发者定义规则，需保证用户标识在应用内唯一。
      </Property>
    </Properties>
  </Col>
  <Col sticky>

    <CodeGroup title="Request" tag="GET" label="/messages" targetCode={`curl --location --request GET '${props.appDetail.api_base_url}/messages?user=abc-123&conversation_id=' \\\n--header 'Authorization: Bearer ENTER-YOUR-SECRET-KEY'`}>

    ```bash {{ title: 'cURL' }}
    curl --location --request GET '${props.appDetail.api_base_url}/messages?user=abc-123&conversation_id='
    --header 'Authorization: Bearer ENTER-YOUR-SECRET-KEY'
    ```

    </CodeGroup>

    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "has_more": false,
      "data": [
        {
          "id": "WAz8eIbvDR60rouK",
          "conversation_id": "xgQQXg3hrtjh7AvZ",
          "inputs": {},
          "query": "...",
          "answer": "...",
          "feedback": "like",
          "created_at": 692233200
        },
        {
          "id": "hSIhXBhNe8X1d8Et"
          // ...
        }
      ]
    }
    ```
    </CodeGroup>
  </Col>
</Row>

---

<Heading
  url='/conversations'
  method='GET'
  title='获取会话列表'
  name='#conversations'
/>
<Row>
  <Col>
    获取当前用户的会话列表，默认返回最近的 20 条。

    ### Query

    <Properties>
      <Property name='last_id' type='string' key='last_id'>
        当前页最后面一条记录的 ID，默认 none
      </Property>
      <Property name='limit' type='int' key='limit'>
        一次请求返回多少条记录
      </Property>
      <Property name='user' type='string' key='user'>
        用户标识，由开发者定义规则，需保证用户标识在应用内唯一。
      </Property>
    </Properties>
  </Col>
  <Col sticky>

    <CodeGroup title="Request" tag="GET" label="/conversations" targetCode={`curl --location --request GET '${props.appDetail.api_base_url}/conversations?user=abc-123&last_id=&limit=20'\\\n--header 'Authorization: Bearer ENTER-YOUR-SECRET-KEY'`}>

    ```bash {{ title: 'cURL' }}
    curl --location --request GET '${props.appDetail.api_base_url}/conversations?user=abc-123&last_id=&limit=20' \
    --header 'Authorization: Bearer ENTER-YOUR-SECRET-KEY'
    ```

    </CodeGroup>

    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "limit": 20,
      "has_more": false,
      "data": [
        {
          "id": "10799fb8-64f7-4296-bbf7-b42bfbe0ae54",
          "name": "New chat",
          "inputs": {
              "book": "book",
              "myName": "Lucy"
          },
          "status": "normal",
          "created_at": 1679667915
        },
        {
          "id": "hSIhXBhNe8X1d8Et"
          // ...
        }
      ]
    }
    ```
    </CodeGroup>
  </Col>
</Row>

---

<Heading
  url='/conversations/{conversation_id}/name'
  method='POST'
  title='会话重命名'
  name='#rename'
/>
<Row>
  <Col>
    对会话进行重命名，会话名称用于显示在支持多会话的客户端上。

    ### Request Body

    <Properties>
      <Property name='name' type='string' key='name'>
        新的名称
      </Property>
      <Property name='user' type='string' key='user'>
        用户标识，由开发者定义规则，需保证用户标识在应用内唯一。
      </Property>
    </Properties>
  </Col>
  <Col sticky>

    <CodeGroup title="Request" tag="POST" label="/conversations/{conversation_id}/name" targetCode={`curl --location --request POST '${props.appDetail.api_base_url}/conversations/name' \\\n--header 'Authorization: Bearer ENTER-YOUR-SECRET-KEY' \\\n--header 'Content-Type: application/json' \\\n--data-raw '{ \n "name": "", \n "user": "abc-123"\n}'`}>

    ```bash {{ title: 'cURL' }}
    curl --location --request POST '${props.appDetail.api_base_url}/conversations/{conversation_id}/name' \
    --header 'Authorization: Bearer ENTER-YOUR-SECRET-KEY' \
    --header 'Content-Type: application/json' \
    --data-raw '{
        "name": "",
        "user": "abc-123"
    }'
    ```

    </CodeGroup>

    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "result": "success"
    }
    ```
    </CodeGroup>
  </Col>
</Row>

---

<Heading
  url='/conversations/{conversation_id}'
  method='DELETE'
  title='删除会话'
  name='#delete'
/>
<Row>
  <Col>
    删除会话。

    ### Request Body

    <Properties>
      <Property name='user' type='string' key='user'>
        用户标识，由开发者定义规则，需保证用户标识在应用内唯一。
      </Property>
    </Properties>
  </Col>
  <Col sticky>

    <CodeGroup title="Request" tag="DELETE" label="/conversations/{conversation_id}" targetCode={`curl --location --request DELETE '${props.appDetail.api_base_url}/conversations/{conversation_id}' \\\n--header 'Authorization: Bearer ENTER-YOUR-SECRET-KEY' \\\n--header 'Content-Type: application/json' \\\n--data-raw '{ \n "user": "abc-123"\n}'`}>

    ```bash {{ title: 'cURL' }}
        curl --location --request DELETE '${props.appDetail.api_base_url}/conversations/{convsation_id}' \
        --header 'Content-Type: application/json' \
        --header 'Accept: application/json' \
        --header 'Authorization: Bearer ENTER-YOUR-SECRET-KEY' \
        --data '{
            "user": "abc-123"
        }'
      ```

    </CodeGroup>

    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "result": "success"
    }
    ```
    </CodeGroup>
  </Col>
</Row>

---

<Heading
  url='/files/upload'
  method='POST'
  title='上传文件'
  name='#files-upload'
/>
<Row>
  <Col>
    上传文件到服务器，供文本生成、对话使用。上传的文件仅供当前终端用户使用。

    ### Request Body
    请求方式为 `multipart/form-data`。
    <Properties>
      <Property name='file' type='file' key='file'>
        要上传的文件。目前支持 png, jpg, jpeg, webp, gif 格式文件。
      </Property>
      <Property name='user' type='string' key='user'>
        用户标识，由开发者定义规则，需保证用户标识在应用内唯一。
      </Property>
    </Properties>
  </Col>
  <Col sticky>

    <CodeGroup title="Request" tag="POST" label="/files/upload" targetCode={`curl --location --request POST '${props.appDetail.api_base_url}/files/upload' \\\n--header 'Authorization: Bearer ENTER-YOUR-SECRET-KEY' \\\n--form 'file=@localfile;type=image/[png|jpeg|jpg|webp|gif] \\\n--form 'user=abc-123'`}>

    ```bash {{ title: 'cURL' }}
    curl --location --request POST '${props.appDetail.api_base_url}/files/upload' \
    --header 'Authorization: Bearer ENTER-YOUR-SECRET-KEY' \
    --form 'file=@"/path/to/file"'
    ```

    </CodeGroup>

    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "id": "72fa9618-8f89-4a37-9b33-7e1178a24a67",  
      "name": "example.png",
      "size": 1024,
      "extension": "png",
      "mime_type": "image/png",
      "created_by": 123,  
      "created_at": 1577836800,
    }
    ```
    </CodeGroup>
  </Col>
</Row>

---

<Heading
  url='/audio-to-text'
  method='POST'
  title='语音转文字'
  name='#audio'
/>
<Row>
  <Col>
    语音转文字，仅支持 openai 模型。

    ### Request Body

    <Properties>
      <Property name='file' type='file' key='file'>
        语音文件。
        文件上传当前限制为 15 MB，并且支持以下输入文件类型：mp3、mp4、mpeg、mpga、m4a、wav 和 webm。
      </Property>
    </Properties>
  </Col>
  <Col sticky>

    <CodeGroup title="Request" tag="POST" label="/audio-to-text" targetCode={`curl --location --request POST '${props.appDetail.api_base_url}/audio-to-text' \\\n--header 'Authorization: Bearer ENTER-YOUR-SECRET-KEY' \\\n--form 'file=@localfile;type=audio/[mp3|mp4|mpeg|mpga|m4a|wav|webm]`}>

    ```bash {{ title: 'cURL' }}
    curl --location --request POST '${props.appDetail.api_base_url}/conversations/name' \
    --header 'Authorization: Bearer ENTER-YOUR-SECRET-KEY' \
    --form 'file=@localfile;type=audio/mp3'
    ```

    </CodeGroup>

    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "text": ""
    }
    ```
    </CodeGroup>
  </Col>
</Row>

---

<Heading
  url='/parameters'
  method='GET'
  title='获取应用配置信息'
  name='#rename'
/>
<Row>
  <Col>
    内容包括：
    1. 已配置的 Input 参数，包括变量名、字段名称、类型与默认值。通常用于客户端加载后显示这些字段的表单或填入默认值。
    2. 上传图片的配置，包括是否开启上传图片，上传图片的数量和上传方式。注意：这个配置只有使用支持多模态的模型时才会生效。

    ### Query

    <Properties>
      <Property name='user' type='string' key='user'>
        用户标识，由开发者定义规则，需保证用户标识在应用内唯一。
      </Property>
    </Properties>
  </Col>
  <Col sticky>

    <CodeGroup title="Request" tag="GET" label="/parameters" targetCode={` curl --location --request GET '${props.appDetail.api_base_url}/parameters'\\\n--header 'Authorization: Bearer ENTER-YOUR-SECRET-KEY'`}>

    ```bash {{ title: 'cURL' }}
    curl --location --request GET '${props.appDetail.api_base_url}/parameters?user=abc-123' \
    --header 'Authorization: Bearer ENTER-YOUR-SECRET-KEY'
    ```

    </CodeGroup>

    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "introduction": "nice to meet you",
      "user_input_form": [
        {
          "text-input": {
            "label": "a",
            "variable": "a",
            "required": true,
            "max_length": 48,
            "default": ""
          }
        }
        {
          // ...
        }
      ],
      "file_upload": {
        "image": {
          "enabled": true,
          "number_limits": 3,
          "transfer_methods": [
            "remote_url",
            "local_file"
          ]
        }
      }
    }
    ```
    </CodeGroup>
  </Col>
</Row>
