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 <[email protected]>
- 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)
|