liuhua
liuhua
commited on
Commit
·
1f1ca89
1
Parent(s):
8766c6a
Fix bugs in agent api and update api document (#3996)
Browse files### What problem does this PR solve?
Fix bugs in agent api and update api document
### Type of change
- [x] Bug Fix (non-breaking change which fixes an issue)
- [x] New Feature (non-breaking change which adds functionality)
---------
Co-authored-by: liuhua <10215101452@stu.ecun.edu.cn>
- agent/canvas.py +1 -0
- api/apps/sdk/session.py +28 -17
- api/db/services/canvas_service.py +20 -18
- api/db/services/conversation_service.py +2 -1
- docs/references/http_api_reference.md +248 -15
- docs/references/python_api_reference.md +9 -2
- sdk/python/ragflow_sdk/modules/agent.py +30 -1
- sdk/python/ragflow_sdk/modules/session.py +1 -1
- sdk/python/test/test_sdk_api/t_agent.py +12 -2
agent/canvas.py
CHANGED
|
@@ -185,6 +185,7 @@ class Canvas(ABC):
|
|
| 185 |
self.path.append(["begin"])
|
| 186 |
|
| 187 |
self.path.append([])
|
|
|
|
| 188 |
ran = -1
|
| 189 |
waiting = []
|
| 190 |
without_dependent_checking = []
|
|
|
|
| 185 |
self.path.append(["begin"])
|
| 186 |
|
| 187 |
self.path.append([])
|
| 188 |
+
|
| 189 |
ran = -1
|
| 190 |
waiting = []
|
| 191 |
without_dependent_checking = []
|
api/apps/sdk/session.py
CHANGED
|
@@ -73,6 +73,8 @@ def create_agent_session(tenant_id, agent_id):
|
|
| 73 |
cvs.dsl = json.dumps(cvs.dsl, ensure_ascii=False)
|
| 74 |
|
| 75 |
canvas = Canvas(cvs.dsl, tenant_id)
|
|
|
|
|
|
|
| 76 |
conv = {
|
| 77 |
"id": get_uuid(),
|
| 78 |
"dialog_id": cvs.id,
|
|
@@ -112,6 +114,8 @@ def update(tenant_id, chat_id, session_id):
|
|
| 112 |
@token_required
|
| 113 |
def chat_completion(tenant_id, chat_id):
|
| 114 |
req = request.json
|
|
|
|
|
|
|
| 115 |
if not DialogService.query(tenant_id=tenant_id,id=chat_id,status=StatusEnum.VALID.value):
|
| 116 |
return get_error_data_result(f"You don't own the chat {chat_id}")
|
| 117 |
if req.get("session_id"):
|
|
@@ -125,7 +129,6 @@ def chat_completion(tenant_id, chat_id):
|
|
| 125 |
resp.headers.add_header("Content-Type", "text/event-stream; charset=utf-8")
|
| 126 |
|
| 127 |
return resp
|
| 128 |
-
|
| 129 |
else:
|
| 130 |
answer = None
|
| 131 |
for ans in rag_completion(tenant_id, chat_id, **req):
|
|
@@ -137,22 +140,28 @@ def chat_completion(tenant_id, chat_id):
|
|
| 137 |
@manager.route('/agents/<agent_id>/completions', methods=['POST']) # noqa: F821
|
| 138 |
@token_required
|
| 139 |
def agent_completions(tenant_id, agent_id):
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
if
|
| 145 |
-
|
| 146 |
-
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
|
| 150 |
-
|
| 151 |
-
|
| 152 |
-
|
| 153 |
-
|
| 154 |
-
|
| 155 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 156 |
|
| 157 |
|
| 158 |
@manager.route('/chats/<chat_id>/sessions', methods=['GET']) # noqa: F821
|
|
@@ -420,3 +429,5 @@ def agent_bot_completions(agent_id):
|
|
| 420 |
|
| 421 |
for answer in agent_completion(objs[0].tenant_id, agent_id, **req):
|
| 422 |
return get_result(data=answer)
|
|
|
|
|
|
|
|
|
| 73 |
cvs.dsl = json.dumps(cvs.dsl, ensure_ascii=False)
|
| 74 |
|
| 75 |
canvas = Canvas(cvs.dsl, tenant_id)
|
| 76 |
+
if canvas.get_preset_param():
|
| 77 |
+
return get_error_data_result("The agent can't create a session directly")
|
| 78 |
conv = {
|
| 79 |
"id": get_uuid(),
|
| 80 |
"dialog_id": cvs.id,
|
|
|
|
| 114 |
@token_required
|
| 115 |
def chat_completion(tenant_id, chat_id):
|
| 116 |
req = request.json
|
| 117 |
+
if not req or not req.get("session_id"):
|
| 118 |
+
req = {"question":""}
|
| 119 |
if not DialogService.query(tenant_id=tenant_id,id=chat_id,status=StatusEnum.VALID.value):
|
| 120 |
return get_error_data_result(f"You don't own the chat {chat_id}")
|
| 121 |
if req.get("session_id"):
|
|
|
|
| 129 |
resp.headers.add_header("Content-Type", "text/event-stream; charset=utf-8")
|
| 130 |
|
| 131 |
return resp
|
|
|
|
| 132 |
else:
|
| 133 |
answer = None
|
| 134 |
for ans in rag_completion(tenant_id, chat_id, **req):
|
|
|
|
| 140 |
@manager.route('/agents/<agent_id>/completions', methods=['POST']) # noqa: F821
|
| 141 |
@token_required
|
| 142 |
def agent_completions(tenant_id, agent_id):
|
| 143 |
+
req = request.json
|
| 144 |
+
cvs = UserCanvasService.query(user_id=tenant_id, id=agent_id)
|
| 145 |
+
if not cvs:
|
| 146 |
+
return get_error_data_result(f"You don't own the agent {agent_id}")
|
| 147 |
+
if req.get("session_id"):
|
| 148 |
+
conv = API4ConversationService.query(id=req["session_id"], dialog_id=agent_id)
|
| 149 |
+
if not conv:
|
| 150 |
+
return get_error_data_result(f"You don't own the session {req['session_id']}")
|
| 151 |
+
else:
|
| 152 |
+
req["question"]=""
|
| 153 |
+
if req.get("stream", True):
|
| 154 |
+
resp = Response(agent_completion(tenant_id, agent_id, **req), mimetype="text/event-stream")
|
| 155 |
+
resp.headers.add_header("Cache-control", "no-cache")
|
| 156 |
+
resp.headers.add_header("Connection", "keep-alive")
|
| 157 |
+
resp.headers.add_header("X-Accel-Buffering", "no")
|
| 158 |
+
resp.headers.add_header("Content-Type", "text/event-stream; charset=utf-8")
|
| 159 |
+
return resp
|
| 160 |
+
try:
|
| 161 |
+
for answer in agent_completion(tenant_id, agent_id, **req):
|
| 162 |
+
return get_result(data=answer)
|
| 163 |
+
except Exception as e:
|
| 164 |
+
return get_error_data_result(str(e))
|
| 165 |
|
| 166 |
|
| 167 |
@manager.route('/chats/<chat_id>/sessions', methods=['GET']) # noqa: F821
|
|
|
|
| 429 |
|
| 430 |
for answer in agent_completion(objs[0].tenant_id, agent_id, **req):
|
| 431 |
return get_result(data=answer)
|
| 432 |
+
|
| 433 |
+
|
api/db/services/canvas_service.py
CHANGED
|
@@ -55,36 +55,39 @@ def completion(tenant_id, agent_id, question, session_id=None, stream=True, **kw
|
|
| 55 |
e, cvs = UserCanvasService.get_by_id(agent_id)
|
| 56 |
assert e, "Agent not found."
|
| 57 |
assert cvs.user_id == tenant_id, "You do not own the agent."
|
| 58 |
-
|
| 59 |
-
if not isinstance(cvs.dsl, str):
|
| 60 |
cvs.dsl = json.dumps(cvs.dsl, ensure_ascii=False)
|
| 61 |
canvas = Canvas(cvs.dsl, tenant_id)
|
| 62 |
canvas.reset()
|
| 63 |
message_id = str(uuid4())
|
| 64 |
-
|
| 65 |
if not session_id:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 66 |
session_id = get_uuid()
|
| 67 |
conv = {
|
| 68 |
"id": session_id,
|
| 69 |
"dialog_id": cvs.id,
|
| 70 |
"user_id": kwargs.get("user_id", ""),
|
| 71 |
"source": "agent",
|
| 72 |
-
"dsl":
|
| 73 |
}
|
| 74 |
API4ConversationService.save(**conv)
|
| 75 |
-
if canvas.get_preset_param():
|
| 76 |
-
yield "data:" + json.dumps({"code": 0,
|
| 77 |
-
"message": "",
|
| 78 |
-
"data": {
|
| 79 |
-
"session_id": session_id,
|
| 80 |
-
"answer": "",
|
| 81 |
-
"reference": [],
|
| 82 |
-
"param": canvas.get_preset_param()
|
| 83 |
-
}
|
| 84 |
-
},
|
| 85 |
-
ensure_ascii=False) + "\n\n"
|
| 86 |
-
yield "data:" + json.dumps({"code": 0, "message": "", "data": True}, ensure_ascii=False) + "\n\n"
|
| 87 |
-
return
|
| 88 |
conv = API4Conversation(**conv)
|
| 89 |
else:
|
| 90 |
e, conv = API4ConversationService.get_by_id(session_id)
|
|
@@ -104,7 +107,6 @@ def completion(tenant_id, agent_id, question, session_id=None, stream=True, **kw
|
|
| 104 |
conv.reference.append({"chunks": [], "doc_aggs": []})
|
| 105 |
|
| 106 |
final_ans = {"reference": [], "content": ""}
|
| 107 |
-
|
| 108 |
if stream:
|
| 109 |
try:
|
| 110 |
for ans in canvas.run(stream=stream):
|
|
|
|
| 55 |
e, cvs = UserCanvasService.get_by_id(agent_id)
|
| 56 |
assert e, "Agent not found."
|
| 57 |
assert cvs.user_id == tenant_id, "You do not own the agent."
|
| 58 |
+
if not isinstance(cvs.dsl,str):
|
|
|
|
| 59 |
cvs.dsl = json.dumps(cvs.dsl, ensure_ascii=False)
|
| 60 |
canvas = Canvas(cvs.dsl, tenant_id)
|
| 61 |
canvas.reset()
|
| 62 |
message_id = str(uuid4())
|
|
|
|
| 63 |
if not session_id:
|
| 64 |
+
query = canvas.get_preset_param()
|
| 65 |
+
if query:
|
| 66 |
+
for ele in query:
|
| 67 |
+
if not ele["optional"]:
|
| 68 |
+
if not kwargs.get(ele["key"]):
|
| 69 |
+
assert False, f"`{ele['key']}` is required"
|
| 70 |
+
ele["value"] = kwargs[ele["key"]]
|
| 71 |
+
if ele["optional"]:
|
| 72 |
+
if kwargs.get(ele["key"]):
|
| 73 |
+
ele["value"] = kwargs[ele['key']]
|
| 74 |
+
else:
|
| 75 |
+
if "value" in ele:
|
| 76 |
+
ele.pop("value")
|
| 77 |
+
cvs.dsl = json.loads(str(canvas))
|
| 78 |
+
temp_dsl = cvs.dsl
|
| 79 |
+
UserCanvasService.update_by_id(agent_id, cvs.to_dict())
|
| 80 |
+
else:
|
| 81 |
+
temp_dsl = json.loads(cvs.dsl)
|
| 82 |
session_id = get_uuid()
|
| 83 |
conv = {
|
| 84 |
"id": session_id,
|
| 85 |
"dialog_id": cvs.id,
|
| 86 |
"user_id": kwargs.get("user_id", ""),
|
| 87 |
"source": "agent",
|
| 88 |
+
"dsl": temp_dsl
|
| 89 |
}
|
| 90 |
API4ConversationService.save(**conv)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 91 |
conv = API4Conversation(**conv)
|
| 92 |
else:
|
| 93 |
e, conv = API4ConversationService.get_by_id(session_id)
|
|
|
|
| 107 |
conv.reference.append({"chunks": [], "doc_aggs": []})
|
| 108 |
|
| 109 |
final_ans = {"reference": [], "content": ""}
|
|
|
|
| 110 |
if stream:
|
| 111 |
try:
|
| 112 |
for ans in canvas.run(stream=stream):
|
api/db/services/conversation_service.py
CHANGED
|
@@ -86,8 +86,9 @@ def completion(tenant_id, chat_id, question, name="New session", session_id=None
|
|
| 86 |
assert dia, "You do not own the chat."
|
| 87 |
|
| 88 |
if not session_id:
|
|
|
|
| 89 |
conv = {
|
| 90 |
-
"id":
|
| 91 |
"dialog_id": chat_id,
|
| 92 |
"name": name,
|
| 93 |
"message": [{"role": "assistant", "content": dia[0].prompt_config.get("prologue")}]
|
|
|
|
| 86 |
assert dia, "You do not own the chat."
|
| 87 |
|
| 88 |
if not session_id:
|
| 89 |
+
session_id = get_uuid()
|
| 90 |
conv = {
|
| 91 |
+
"id":session_id ,
|
| 92 |
"dialog_id": chat_id,
|
| 93 |
"name": name,
|
| 94 |
"message": [{"role": "assistant", "content": dia[0].prompt_config.get("prologue")}]
|
docs/references/http_api_reference.md
CHANGED
|
@@ -2015,11 +2015,20 @@ curl --request POST \
|
|
| 2015 |
--header 'Authorization: Bearer <YOUR_API_KEY>' \
|
| 2016 |
--data-binary '
|
| 2017 |
{
|
| 2018 |
-
"question": "What is RAGFlow?",
|
| 2019 |
-
"stream": true
|
| 2020 |
}'
|
| 2021 |
```
|
| 2022 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2023 |
#### Request Parameters
|
| 2024 |
|
| 2025 |
- `chat_id`: (*Path parameter*)
|
|
@@ -2034,10 +2043,29 @@ curl --request POST \
|
|
| 2034 |
The ID of session. If it is not provided, a new session will be generated.
|
| 2035 |
|
| 2036 |
### Response
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2037 |
|
| 2038 |
-
Success
|
| 2039 |
|
| 2040 |
-
```
|
| 2041 |
data:{
|
| 2042 |
"code": 0,
|
| 2043 |
"data": {
|
|
@@ -2121,6 +2149,7 @@ Failure:
|
|
| 2121 |
---
|
| 2122 |
|
| 2123 |
## Create session with agent
|
|
|
|
| 2124 |
|
| 2125 |
**POST** `/api/v1/agents/{agent_id}/sessions`
|
| 2126 |
|
|
@@ -2159,16 +2188,101 @@ Success:
|
|
| 2159 |
{
|
| 2160 |
"code": 0,
|
| 2161 |
"data": {
|
| 2162 |
-
"agent_id": "
|
| 2163 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2164 |
"message": [
|
| 2165 |
{
|
| 2166 |
-
"content": "
|
| 2167 |
"role": "assistant"
|
| 2168 |
}
|
| 2169 |
],
|
| 2170 |
"source": "agent",
|
| 2171 |
-
"user_id": ""
|
| 2172 |
}
|
| 2173 |
}
|
| 2174 |
```
|
|
@@ -2216,7 +2330,7 @@ Asks a specified agent a question to start an AI-powered conversation.
|
|
| 2216 |
- `"question"`: `string`
|
| 2217 |
- `"stream"`: `boolean`
|
| 2218 |
- `"session_id"`: `string`
|
| 2219 |
-
|
| 2220 |
#### Request example
|
| 2221 |
|
| 2222 |
```bash
|
|
@@ -2226,11 +2340,33 @@ curl --request POST \
|
|
| 2226 |
--header 'Authorization: Bearer <YOUR_API_KEY>' \
|
| 2227 |
--data-binary '
|
| 2228 |
{
|
| 2229 |
-
|
| 2230 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2231 |
}'
|
| 2232 |
```
|
| 2233 |
|
|
|
|
| 2234 |
#### Request Parameters
|
| 2235 |
|
| 2236 |
- `agent_id`: (*Path parameter*), `string`
|
|
@@ -2243,10 +2379,28 @@ curl --request POST \
|
|
| 2243 |
- `false`: Disable streaming.
|
| 2244 |
- `"session_id"`: (*Body Parameter*)
|
| 2245 |
The ID of the session. If it is not provided, a new session will be generated.
|
| 2246 |
-
|
|
|
|
| 2247 |
### Response
|
| 2248 |
-
|
| 2249 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2250 |
|
| 2251 |
```text
|
| 2252 |
data:{
|
|
@@ -2354,6 +2508,85 @@ data:{
|
|
| 2354 |
"data": true
|
| 2355 |
}
|
| 2356 |
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2357 |
|
| 2358 |
Failure:
|
| 2359 |
|
|
|
|
| 2015 |
--header 'Authorization: Bearer <YOUR_API_KEY>' \
|
| 2016 |
--data-binary '
|
| 2017 |
{
|
|
|
|
|
|
|
| 2018 |
}'
|
| 2019 |
```
|
| 2020 |
+
```bash
|
| 2021 |
+
curl --request POST \
|
| 2022 |
+
--url http://{address}/api/v1/chats/{chat_id}/completions \
|
| 2023 |
+
--header 'Content-Type: application/json' \
|
| 2024 |
+
--header 'Authorization: Bearer <YOUR_API_KEY>' \
|
| 2025 |
+
--data-binary '
|
| 2026 |
+
{
|
| 2027 |
+
"question": "Who are you",
|
| 2028 |
+
"stream": true,
|
| 2029 |
+
"session_id":"9fa7691cb85c11ef9c5f0242ac120005"
|
| 2030 |
+
}'
|
| 2031 |
+
```
|
| 2032 |
#### Request Parameters
|
| 2033 |
|
| 2034 |
- `chat_id`: (*Path parameter*)
|
|
|
|
| 2043 |
The ID of session. If it is not provided, a new session will be generated.
|
| 2044 |
|
| 2045 |
### Response
|
| 2046 |
+
Success without `session_id`:
|
| 2047 |
+
```text
|
| 2048 |
+
data:{
|
| 2049 |
+
"code": 0,
|
| 2050 |
+
"message": "",
|
| 2051 |
+
"data": {
|
| 2052 |
+
"answer": "Hi! I'm your assistant, what can I do for you?",
|
| 2053 |
+
"reference": {},
|
| 2054 |
+
"audio_binary": null,
|
| 2055 |
+
"id": null,
|
| 2056 |
+
"session_id": "b01eed84b85611efa0e90242ac120005"
|
| 2057 |
+
}
|
| 2058 |
+
}
|
| 2059 |
+
data:{
|
| 2060 |
+
"code": 0,
|
| 2061 |
+
"message": "",
|
| 2062 |
+
"data": true
|
| 2063 |
+
}
|
| 2064 |
+
```
|
| 2065 |
|
| 2066 |
+
Success with `session_id`:
|
| 2067 |
|
| 2068 |
+
```text
|
| 2069 |
data:{
|
| 2070 |
"code": 0,
|
| 2071 |
"data": {
|
|
|
|
| 2149 |
---
|
| 2150 |
|
| 2151 |
## Create session with agent
|
| 2152 |
+
*If there are parameters in the `begin` component, the session cannot be created in this way.*
|
| 2153 |
|
| 2154 |
**POST** `/api/v1/agents/{agent_id}/sessions`
|
| 2155 |
|
|
|
|
| 2188 |
{
|
| 2189 |
"code": 0,
|
| 2190 |
"data": {
|
| 2191 |
+
"agent_id": "b4a39922b76611efaa1a0242ac120006",
|
| 2192 |
+
"dsl": {
|
| 2193 |
+
"answer": [],
|
| 2194 |
+
"components": {
|
| 2195 |
+
"Answer:GreenReadersDrum": {
|
| 2196 |
+
"downstream": [],
|
| 2197 |
+
"obj": {
|
| 2198 |
+
"component_name": "Answer",
|
| 2199 |
+
"inputs": [],
|
| 2200 |
+
"output": null,
|
| 2201 |
+
"params": {}
|
| 2202 |
+
},
|
| 2203 |
+
"upstream": []
|
| 2204 |
+
},
|
| 2205 |
+
"begin": {
|
| 2206 |
+
"downstream": [],
|
| 2207 |
+
"obj": {
|
| 2208 |
+
"component_name": "Begin",
|
| 2209 |
+
"inputs": [],
|
| 2210 |
+
"output": {},
|
| 2211 |
+
"params": {}
|
| 2212 |
+
},
|
| 2213 |
+
"upstream": []
|
| 2214 |
+
}
|
| 2215 |
+
},
|
| 2216 |
+
"embed_id": "",
|
| 2217 |
+
"graph": {
|
| 2218 |
+
"edges": [],
|
| 2219 |
+
"nodes": [
|
| 2220 |
+
{
|
| 2221 |
+
"data": {
|
| 2222 |
+
"label": "Begin",
|
| 2223 |
+
"name": "begin"
|
| 2224 |
+
},
|
| 2225 |
+
"dragging": false,
|
| 2226 |
+
"height": 44,
|
| 2227 |
+
"id": "begin",
|
| 2228 |
+
"position": {
|
| 2229 |
+
"x": 53.25688640427177,
|
| 2230 |
+
"y": 198.37155679786412
|
| 2231 |
+
},
|
| 2232 |
+
"positionAbsolute": {
|
| 2233 |
+
"x": 53.25688640427177,
|
| 2234 |
+
"y": 198.37155679786412
|
| 2235 |
+
},
|
| 2236 |
+
"selected": false,
|
| 2237 |
+
"sourcePosition": "left",
|
| 2238 |
+
"targetPosition": "right",
|
| 2239 |
+
"type": "beginNode",
|
| 2240 |
+
"width": 200
|
| 2241 |
+
},
|
| 2242 |
+
{
|
| 2243 |
+
"data": {
|
| 2244 |
+
"form": {},
|
| 2245 |
+
"label": "Answer",
|
| 2246 |
+
"name": "对话_0"
|
| 2247 |
+
},
|
| 2248 |
+
"dragging": false,
|
| 2249 |
+
"height": 44,
|
| 2250 |
+
"id": "Answer:GreenReadersDrum",
|
| 2251 |
+
"position": {
|
| 2252 |
+
"x": 360.43473114516974,
|
| 2253 |
+
"y": 207.29298425089348
|
| 2254 |
+
},
|
| 2255 |
+
"positionAbsolute": {
|
| 2256 |
+
"x": 360.43473114516974,
|
| 2257 |
+
"y": 207.29298425089348
|
| 2258 |
+
},
|
| 2259 |
+
"selected": false,
|
| 2260 |
+
"sourcePosition": "right",
|
| 2261 |
+
"targetPosition": "left",
|
| 2262 |
+
"type": "logicNode",
|
| 2263 |
+
"width": 200
|
| 2264 |
+
}
|
| 2265 |
+
]
|
| 2266 |
+
},
|
| 2267 |
+
"history": [],
|
| 2268 |
+
"messages": [],
|
| 2269 |
+
"path": [
|
| 2270 |
+
[
|
| 2271 |
+
"begin"
|
| 2272 |
+
],
|
| 2273 |
+
[]
|
| 2274 |
+
],
|
| 2275 |
+
"reference": []
|
| 2276 |
+
},
|
| 2277 |
+
"id": "2581031eb7a311efb5200242ac120005",
|
| 2278 |
"message": [
|
| 2279 |
{
|
| 2280 |
+
"content": "Hi! I'm your smart assistant. What can I do for you?",
|
| 2281 |
"role": "assistant"
|
| 2282 |
}
|
| 2283 |
],
|
| 2284 |
"source": "agent",
|
| 2285 |
+
"user_id": "69736c5e723611efb51b0242ac120007"
|
| 2286 |
}
|
| 2287 |
}
|
| 2288 |
```
|
|
|
|
| 2330 |
- `"question"`: `string`
|
| 2331 |
- `"stream"`: `boolean`
|
| 2332 |
- `"session_id"`: `string`
|
| 2333 |
+
- other parameters: `string`
|
| 2334 |
#### Request example
|
| 2335 |
|
| 2336 |
```bash
|
|
|
|
| 2340 |
--header 'Authorization: Bearer <YOUR_API_KEY>' \
|
| 2341 |
--data-binary '
|
| 2342 |
{
|
| 2343 |
+
}'
|
| 2344 |
+
```
|
| 2345 |
+
```bash
|
| 2346 |
+
curl --request POST \
|
| 2347 |
+
--url http://{address}/api/v1/agents/{agent_id}/completions \
|
| 2348 |
+
--header 'Content-Type: application/json' \
|
| 2349 |
+
--header 'Authorization: Bearer <YOUR_API_KEY>' \
|
| 2350 |
+
--data-binary '
|
| 2351 |
+
{
|
| 2352 |
+
"question": "Hello",
|
| 2353 |
+
"stream": true,
|
| 2354 |
+
"session_id": "cb2f385cb86211efa36e0242ac120005"
|
| 2355 |
+
}'
|
| 2356 |
+
```
|
| 2357 |
+
```bash
|
| 2358 |
+
curl --request POST \
|
| 2359 |
+
--url http://{address}/api/v1/agents/{agent_id}/completions \
|
| 2360 |
+
--header 'Content-Type: application/json' \
|
| 2361 |
+
--header 'Authorization: Bearer <YOUR_API_KEY>' \
|
| 2362 |
+
--data-binary '
|
| 2363 |
+
{
|
| 2364 |
+
"lang":"English"
|
| 2365 |
+
"file":"明天天气如何"
|
| 2366 |
}'
|
| 2367 |
```
|
| 2368 |
|
| 2369 |
+
|
| 2370 |
#### Request Parameters
|
| 2371 |
|
| 2372 |
- `agent_id`: (*Path parameter*), `string`
|
|
|
|
| 2379 |
- `false`: Disable streaming.
|
| 2380 |
- `"session_id"`: (*Body Parameter*)
|
| 2381 |
The ID of the session. If it is not provided, a new session will be generated.
|
| 2382 |
+
- Other parameters: (*Body Parameter*)
|
| 2383 |
+
The parameters in the begin component.
|
| 2384 |
### Response
|
| 2385 |
+
success without `session_id` provided and with no parameters in the `begin` component:
|
| 2386 |
+
```text
|
| 2387 |
+
data:{
|
| 2388 |
+
"code": 0,
|
| 2389 |
+
"message": "",
|
| 2390 |
+
"data": {
|
| 2391 |
+
"answer": "Hi! I'm your smart assistant. What can I do for you?",
|
| 2392 |
+
"reference": {},
|
| 2393 |
+
"id": "31e6091d-88d4-441b-ac65-eae1c055be7b",
|
| 2394 |
+
"session_id": "2987ad3eb85f11efb2a70242ac120005"
|
| 2395 |
+
}
|
| 2396 |
+
}
|
| 2397 |
+
data:{
|
| 2398 |
+
"code": 0,
|
| 2399 |
+
"message": "",
|
| 2400 |
+
"data": true
|
| 2401 |
+
}
|
| 2402 |
+
```
|
| 2403 |
+
Success with `session_id` provided and with no parameters in the `begin` component:
|
| 2404 |
|
| 2405 |
```text
|
| 2406 |
data:{
|
|
|
|
| 2508 |
"data": true
|
| 2509 |
}
|
| 2510 |
```
|
| 2511 |
+
Success with parameters in the `begin` component:
|
| 2512 |
+
```text
|
| 2513 |
+
data:{
|
| 2514 |
+
"code": 0,
|
| 2515 |
+
"message": "",
|
| 2516 |
+
"data": {
|
| 2517 |
+
"answer": "How",
|
| 2518 |
+
"reference": {},
|
| 2519 |
+
"id": "0379ac4c-b26b-4a44-8b77-99cebf313fdf",
|
| 2520 |
+
"session_id": "4399c7d0b86311efac5b0242ac120005"
|
| 2521 |
+
}
|
| 2522 |
+
}
|
| 2523 |
+
data:{
|
| 2524 |
+
"code": 0,
|
| 2525 |
+
"message": "",
|
| 2526 |
+
"data": {
|
| 2527 |
+
"answer": "How is",
|
| 2528 |
+
"reference": {},
|
| 2529 |
+
"id": "0379ac4c-b26b-4a44-8b77-99cebf313fdf",
|
| 2530 |
+
"session_id": "4399c7d0b86311efac5b0242ac120005"
|
| 2531 |
+
}
|
| 2532 |
+
}
|
| 2533 |
+
data:{
|
| 2534 |
+
"code": 0,
|
| 2535 |
+
"message": "",
|
| 2536 |
+
"data": {
|
| 2537 |
+
"answer": "How is the",
|
| 2538 |
+
"reference": {},
|
| 2539 |
+
"id": "0379ac4c-b26b-4a44-8b77-99cebf313fdf",
|
| 2540 |
+
"session_id": "4399c7d0b86311efac5b0242ac120005"
|
| 2541 |
+
}
|
| 2542 |
+
}
|
| 2543 |
+
data:{
|
| 2544 |
+
"code": 0,
|
| 2545 |
+
"message": "",
|
| 2546 |
+
"data": {
|
| 2547 |
+
"answer": "How is the weather",
|
| 2548 |
+
"reference": {},
|
| 2549 |
+
"id": "0379ac4c-b26b-4a44-8b77-99cebf313fdf",
|
| 2550 |
+
"session_id": "4399c7d0b86311efac5b0242ac120005"
|
| 2551 |
+
}
|
| 2552 |
+
}
|
| 2553 |
+
data:{
|
| 2554 |
+
"code": 0,
|
| 2555 |
+
"message": "",
|
| 2556 |
+
"data": {
|
| 2557 |
+
"answer": "How is the weather tomorrow",
|
| 2558 |
+
"reference": {},
|
| 2559 |
+
"id": "0379ac4c-b26b-4a44-8b77-99cebf313fdf",
|
| 2560 |
+
"session_id": "4399c7d0b86311efac5b0242ac120005"
|
| 2561 |
+
}
|
| 2562 |
+
}
|
| 2563 |
+
data:{
|
| 2564 |
+
"code": 0,
|
| 2565 |
+
"message": "",
|
| 2566 |
+
"data": {
|
| 2567 |
+
"answer": "How is the weather tomorrow?",
|
| 2568 |
+
"reference": {},
|
| 2569 |
+
"id": "0379ac4c-b26b-4a44-8b77-99cebf313fdf",
|
| 2570 |
+
"session_id": "4399c7d0b86311efac5b0242ac120005"
|
| 2571 |
+
}
|
| 2572 |
+
}
|
| 2573 |
+
data:{
|
| 2574 |
+
"code": 0,
|
| 2575 |
+
"message": "",
|
| 2576 |
+
"data": {
|
| 2577 |
+
"answer": "How is the weather tomorrow?",
|
| 2578 |
+
"reference": {},
|
| 2579 |
+
"id": "0379ac4c-b26b-4a44-8b77-99cebf313fdf",
|
| 2580 |
+
"session_id": "4399c7d0b86311efac5b0242ac120005"
|
| 2581 |
+
}
|
| 2582 |
+
}
|
| 2583 |
+
data:{
|
| 2584 |
+
"code": 0,
|
| 2585 |
+
"message": "",
|
| 2586 |
+
"data": true
|
| 2587 |
+
}
|
| 2588 |
+
```
|
| 2589 |
+
|
| 2590 |
|
| 2591 |
Failure:
|
| 2592 |
|
docs/references/python_api_reference.md
CHANGED
|
@@ -14,6 +14,13 @@ Dataset Management
|
|
| 14 |
:::
|
| 15 |
|
| 16 |
---
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
|
| 18 |
## Create dataset
|
| 19 |
|
|
@@ -1401,7 +1408,7 @@ while True:
|
|
| 1401 |
---
|
| 1402 |
|
| 1403 |
## Create session with agent
|
| 1404 |
-
|
| 1405 |
```python
|
| 1406 |
Agent.create_session(id,rag) -> Session
|
| 1407 |
```
|
|
@@ -1428,7 +1435,7 @@ session = create_session(AGENT_ID,rag_object)
|
|
| 1428 |
|
| 1429 |
---
|
| 1430 |
|
| 1431 |
-
## Converse with agent
|
| 1432 |
|
| 1433 |
```python
|
| 1434 |
Session.ask(question: str, stream: bool = False) -> Optional[Message, iter[Message]]
|
|
|
|
| 14 |
:::
|
| 15 |
|
| 16 |
---
|
| 17 |
+
### Install the RAGFlow SDK
|
| 18 |
+
|
| 19 |
+
To install the RAGFlow SDK, run the following command in your terminal:
|
| 20 |
+
|
| 21 |
+
```bash
|
| 22 |
+
pip install ragflow-sdk
|
| 23 |
+
```
|
| 24 |
|
| 25 |
## Create dataset
|
| 26 |
|
|
|
|
| 1408 |
---
|
| 1409 |
|
| 1410 |
## Create session with agent
|
| 1411 |
+
*If there are parameters in the `begin` component, the session cannot be created in this way.*
|
| 1412 |
```python
|
| 1413 |
Agent.create_session(id,rag) -> Session
|
| 1414 |
```
|
|
|
|
| 1435 |
|
| 1436 |
---
|
| 1437 |
|
| 1438 |
+
## Converse with agent without `begin` component
|
| 1439 |
|
| 1440 |
```python
|
| 1441 |
Session.ask(question: str, stream: bool = False) -> Optional[Message, iter[Message]]
|
sdk/python/ragflow_sdk/modules/agent.py
CHANGED
|
@@ -1,7 +1,9 @@
|
|
| 1 |
from .base import Base
|
| 2 |
-
from .session import Session
|
| 3 |
import requests
|
| 4 |
from typing import List
|
|
|
|
|
|
|
| 5 |
|
| 6 |
class Agent(Base):
|
| 7 |
def __init__(self,rag,res_dict):
|
|
@@ -73,3 +75,30 @@ class Agent(Base):
|
|
| 73 |
result_list.append(temp_agent)
|
| 74 |
return result_list
|
| 75 |
raise Exception(res.get("message"))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
from .base import Base
|
| 2 |
+
from .session import Session,Message
|
| 3 |
import requests
|
| 4 |
from typing import List
|
| 5 |
+
import json
|
| 6 |
+
|
| 7 |
|
| 8 |
class Agent(Base):
|
| 9 |
def __init__(self,rag,res_dict):
|
|
|
|
| 75 |
result_list.append(temp_agent)
|
| 76 |
return result_list
|
| 77 |
raise Exception(res.get("message"))
|
| 78 |
+
|
| 79 |
+
@staticmethod
|
| 80 |
+
def ask(agent_id,rag,stream=True,**kwargs):
|
| 81 |
+
url = f"{rag.api_url}/agents/{agent_id}/completions"
|
| 82 |
+
headers = {"Authorization": f"Bearer {rag.user_key}"}
|
| 83 |
+
res = requests.post(url=url, headers=headers, json=kwargs,stream=stream)
|
| 84 |
+
for line in res.iter_lines():
|
| 85 |
+
line = line.decode("utf-8")
|
| 86 |
+
if line.startswith("{"):
|
| 87 |
+
json_data = json.loads(line)
|
| 88 |
+
raise Exception(json_data["message"])
|
| 89 |
+
if line.startswith("data:"):
|
| 90 |
+
json_data = json.loads(line[5:])
|
| 91 |
+
if json_data["data"] is not True:
|
| 92 |
+
if json_data["data"].get("running_status"):
|
| 93 |
+
continue
|
| 94 |
+
answer = json_data["data"]["answer"]
|
| 95 |
+
reference = json_data["data"]["reference"]
|
| 96 |
+
temp_dict = {
|
| 97 |
+
"content": answer,
|
| 98 |
+
"role": "assistant"
|
| 99 |
+
}
|
| 100 |
+
if "chunks" in reference:
|
| 101 |
+
chunks = reference["chunks"]
|
| 102 |
+
temp_dict["reference"] = chunks
|
| 103 |
+
message = Message(rag, temp_dict)
|
| 104 |
+
yield message
|
sdk/python/ragflow_sdk/modules/session.py
CHANGED
|
@@ -29,7 +29,7 @@ class Session(Base):
|
|
| 29 |
raise Exception(json_data["message"])
|
| 30 |
if line.startswith("data:"):
|
| 31 |
json_data = json.loads(line[5:])
|
| 32 |
-
if
|
| 33 |
answer = json_data["data"]["answer"]
|
| 34 |
reference = json_data["data"]["reference"]
|
| 35 |
temp_dict = {
|
|
|
|
| 29 |
raise Exception(json_data["message"])
|
| 30 |
if line.startswith("data:"):
|
| 31 |
json_data = json.loads(line[5:])
|
| 32 |
+
if json_data["data"] is not True:
|
| 33 |
answer = json_data["data"]["answer"]
|
| 34 |
reference = json_data["data"]["reference"]
|
| 35 |
temp_dict = {
|
sdk/python/test/test_sdk_api/t_agent.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
from ragflow_sdk import RAGFlow
|
| 2 |
from common import HOST_ADDRESS
|
| 3 |
import pytest
|
| 4 |
|
|
@@ -6,4 +6,14 @@ import pytest
|
|
| 6 |
def test_list_agents_with_success(get_api_key_fixture):
|
| 7 |
API_KEY=get_api_key_fixture
|
| 8 |
rag = RAGFlow(API_KEY,HOST_ADDRESS)
|
| 9 |
-
rag.list_agents()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from ragflow_sdk import RAGFlow,Agent
|
| 2 |
from common import HOST_ADDRESS
|
| 3 |
import pytest
|
| 4 |
|
|
|
|
| 6 |
def test_list_agents_with_success(get_api_key_fixture):
|
| 7 |
API_KEY=get_api_key_fixture
|
| 8 |
rag = RAGFlow(API_KEY,HOST_ADDRESS)
|
| 9 |
+
rag.list_agents()
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
@pytest.mark.skip(reason="")
|
| 13 |
+
def test_converse_with_agent_with_success(get_api_key_fixture):
|
| 14 |
+
API_KEY = "ragflow-BkOGNhYjIyN2JiODExZWY5MzVhMDI0Mm"
|
| 15 |
+
agent_id = "ebfada2eb2bc11ef968a0242ac120006"
|
| 16 |
+
rag = RAGFlow(API_KEY,HOST_ADDRESS)
|
| 17 |
+
lang = "Chinese"
|
| 18 |
+
file = "How is the weather tomorrow?"
|
| 19 |
+
Agent.ask(agent_id=agent_id,rag=rag,lang=lang,file=file)
|