liuhua liuhua commited on
Commit
e9078f4
·
1 Parent(s): 24b9cdf

Add sdk for Agent API (#3220)

Browse files

### What problem does this PR solve?

Add sdk for Agent API

### Type of change

- [x] New Feature (non-breaking change which adds functionality)

---------

Co-authored-by: liuhua <[email protected]>

api/apps/sdk/session.py CHANGED
@@ -74,11 +74,12 @@ def create_agent_session(tenant_id, agent_id):
74
  conv = {
75
  "id": get_uuid(),
76
  "dialog_id": cvs.id,
77
- "user_id": req.get("user_id", ""),
78
  "message": [{"role": "assistant", "content": canvas.get_prologue()}],
79
  "source": "agent"
80
  }
81
  API4ConversationService.save(**conv)
 
82
  return get_result(data=conv)
83
 
84
 
@@ -150,6 +151,25 @@ def completion(tenant_id, chat_id):
150
  conv.reference.append({"chunks": [], "doc_aggs": []})
151
 
152
  def fillin_conv(ans):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
153
  nonlocal conv, message_id
154
  if not conv.reference:
155
  conv.reference.append(ans["reference"])
@@ -179,6 +199,7 @@ def completion(tenant_id, chat_id):
179
  resp.headers.add_header("Connection", "keep-alive")
180
  resp.headers.add_header("X-Accel-Buffering", "no")
181
  resp.headers.add_header("Content-Type", "text/event-stream; charset=utf-8")
 
182
  return resp
183
 
184
  else:
@@ -195,6 +216,7 @@ def completion(tenant_id, chat_id):
195
  @token_required
196
  def agent_completion(tenant_id, agent_id):
197
  req = request.json
 
198
  e, cvs = UserCanvasService.get_by_id(agent_id)
199
  if not e:
200
  return get_error_data_result("Agent not found.")
@@ -202,25 +224,14 @@ def agent_completion(tenant_id, agent_id):
202
  return get_error_data_result(message="You do not own the agent.")
203
  if not isinstance(cvs.dsl, str):
204
  cvs.dsl = json.dumps(cvs.dsl, ensure_ascii=False)
205
-
206
  canvas = Canvas(cvs.dsl, tenant_id)
207
 
208
- msg = []
209
- for m in req["messages"]:
210
- if m["role"] == "system":
211
- continue
212
- if m["role"] == "assistant" and not msg:
213
- continue
214
- msg.append(m)
215
- if not msg[-1].get("id"): msg[-1]["id"] = get_uuid()
216
- message_id = msg[-1]["id"]
217
-
218
  if not req.get("session_id"):
219
  session_id = get_uuid()
220
  conv = {
221
  "id": session_id,
222
  "dialog_id": cvs.id,
223
- "user_id": req.get("user_id", ""),
224
  "message": [{"role": "assistant", "content": canvas.get_prologue()}],
225
  "source": "agent"
226
  }
@@ -232,10 +243,49 @@ def agent_completion(tenant_id, agent_id):
232
  if not e:
233
  return get_error_data_result(message="Session not found!")
234
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
235
  if "quote" not in req: req["quote"] = False
236
  stream = req.get("stream", True)
237
 
238
  def fillin_conv(ans):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
239
  nonlocal conv, message_id
240
  if not conv.reference:
241
  conv.reference.append(ans["reference"])
 
74
  conv = {
75
  "id": get_uuid(),
76
  "dialog_id": cvs.id,
77
+ "user_id": req.get("usr_id",""),
78
  "message": [{"role": "assistant", "content": canvas.get_prologue()}],
79
  "source": "agent"
80
  }
81
  API4ConversationService.save(**conv)
82
+ conv["agent_id"] = conv.pop("dialog_id")
83
  return get_result(data=conv)
84
 
85
 
 
151
  conv.reference.append({"chunks": [], "doc_aggs": []})
152
 
153
  def fillin_conv(ans):
154
+ reference = ans["reference"]
155
+ if "chunks" in reference:
156
+ chunks = reference.get("chunks")
157
+ chunk_list = []
158
+ for chunk in chunks:
159
+ new_chunk = {
160
+ "id": chunk["chunk_id"],
161
+ "content": chunk["content_with_weight"],
162
+ "document_id": chunk["doc_id"],
163
+ "document_name": chunk["docnm_kwd"],
164
+ "dataset_id": chunk["kb_id"],
165
+ "image_id": chunk["img_id"],
166
+ "similarity": chunk["similarity"],
167
+ "vector_similarity": chunk["vector_similarity"],
168
+ "term_similarity": chunk["term_similarity"],
169
+ "positions": chunk["positions"],
170
+ }
171
+ chunk_list.append(new_chunk)
172
+ reference["chunks"] = chunk_list
173
  nonlocal conv, message_id
174
  if not conv.reference:
175
  conv.reference.append(ans["reference"])
 
199
  resp.headers.add_header("Connection", "keep-alive")
200
  resp.headers.add_header("X-Accel-Buffering", "no")
201
  resp.headers.add_header("Content-Type", "text/event-stream; charset=utf-8")
202
+
203
  return resp
204
 
205
  else:
 
216
  @token_required
217
  def agent_completion(tenant_id, agent_id):
218
  req = request.json
219
+
220
  e, cvs = UserCanvasService.get_by_id(agent_id)
221
  if not e:
222
  return get_error_data_result("Agent not found.")
 
224
  return get_error_data_result(message="You do not own the agent.")
225
  if not isinstance(cvs.dsl, str):
226
  cvs.dsl = json.dumps(cvs.dsl, ensure_ascii=False)
 
227
  canvas = Canvas(cvs.dsl, tenant_id)
228
 
 
 
 
 
 
 
 
 
 
 
229
  if not req.get("session_id"):
230
  session_id = get_uuid()
231
  conv = {
232
  "id": session_id,
233
  "dialog_id": cvs.id,
234
+ "user_id": req.get("user_id",""),
235
  "message": [{"role": "assistant", "content": canvas.get_prologue()}],
236
  "source": "agent"
237
  }
 
243
  if not e:
244
  return get_error_data_result(message="Session not found!")
245
 
246
+ messages = conv.message
247
+ question = req.get("question")
248
+ if not question:
249
+ return get_error_data_result("`question` is required.")
250
+ question={
251
+ "role":"user",
252
+ "content":question,
253
+ "id": str(uuid4())
254
+ }
255
+ messages.append(question)
256
+ msg = []
257
+ for m in messages:
258
+ if m["role"] == "system":
259
+ continue
260
+ if m["role"] == "assistant" and not msg:
261
+ continue
262
+ msg.append(m)
263
+ if not msg[-1].get("id"): msg[-1]["id"] = get_uuid()
264
+ message_id = msg[-1]["id"]
265
+
266
  if "quote" not in req: req["quote"] = False
267
  stream = req.get("stream", True)
268
 
269
  def fillin_conv(ans):
270
+ reference = ans["reference"]
271
+ if "chunks" in reference:
272
+ chunks = reference.get("chunks")
273
+ chunk_list = []
274
+ for chunk in chunks:
275
+ new_chunk = {
276
+ "id": chunk["chunk_id"],
277
+ "content": chunk["content_with_weight"],
278
+ "document_id": chunk["doc_id"],
279
+ "document_name": chunk["docnm_kwd"],
280
+ "dataset_id": chunk["kb_id"],
281
+ "image_id": chunk["img_id"],
282
+ "similarity": chunk["similarity"],
283
+ "vector_similarity": chunk["vector_similarity"],
284
+ "term_similarity": chunk["term_similarity"],
285
+ "positions": chunk["positions"],
286
+ }
287
+ chunk_list.append(new_chunk)
288
+ reference["chunks"] = chunk_list
289
  nonlocal conv, message_id
290
  if not conv.reference:
291
  conv.reference.append(ans["reference"])
docs/references/http_api_reference.md CHANGED
@@ -2018,59 +2018,54 @@ curl --request POST \
2018
 
2019
  Success:
2020
 
2021
- ```json
2022
- data: {
2023
  "code": 0,
2024
  "data": {
2025
- "answer": "I am an intelligent assistant designed to help you with your inquiries. I can provide",
2026
  "reference": {},
2027
  "audio_binary": null,
2028
- "id": "d8e5ebb6-6b52-4fd1-bd02-35b52ba3acaa",
2029
- "session_id": "e14344d08d1a11efb6210242ac120004"
2030
  }
2031
  }
2032
-
2033
- data: {
2034
  "code": 0,
2035
  "data": {
2036
- "answer": "I am an intelligent assistant designed to help you with your inquiries. I can provide information, answer questions, and assist with tasks based on the knowledge available to me",
2037
  "reference": {},
2038
  "audio_binary": null,
2039
- "id": "d8e5ebb6-6b52-4fd1-bd02-35b52ba3acaa",
2040
- "session_id": "e14344d08d1a11efb6210242ac120004"
2041
  }
2042
  }
2043
-
2044
- data: {
2045
  "code": 0,
2046
  "data": {
2047
- "answer": "I am an intelligent assistant designed to help you with your inquiries. I can provide information, answer questions, and assist with tasks based on the knowledge available to me. How can I assist you today?",
2048
  "reference": {},
2049
  "audio_binary": null,
2050
- "id": "d8e5ebb6-6b52-4fd1-bd02-35b52ba3acaa",
2051
- "session_id": "e14344d08d1a11efb6210242ac120004"
2052
  }
2053
  }
2054
-
2055
- data: {
2056
  "code": 0,
2057
  "data": {
2058
- "answer": "I am an intelligent assistant designed to help you with your inquiries. I can provide information, answer questions, and assist with tasks based on the knowledge available to me ##0$$. How can I assist you today?",
2059
  "reference": {
2060
- "total": 8,
2061
  "chunks": [
2062
  {
2063
- "chunk_id": "895d34de762e674b43e8613c6fb54c6d",
2064
- "content_ltks": "xxxx\r\n\r\n\"\"\"\r\nyou are an intellig assistant. pleas summar the content of the knowledg base to answer the question. pleas list thedata in the knowledg base and answer in detail. when all knowledg base content is irrelev to the question , your answer must includ the sentenc\"the answer you are lookfor isnot found in the knowledg base!\" answer needto consid chat history.\r\n here is the knowledg base:\r\n{ knowledg}\r\nthe abov is the knowledg base.\r\n\"\"\"\r\n1\r\n 2\r\n 3\r\n 4\r\n 5\r\n 6\r\nxxxx ",
2065
- "content_with_weight": "xxxx\r\n\r\n\"\"\"\r\nYou are an intelligent assistant. Please summarize the content of the knowledge base to answer the question. Please list the data in the knowledge base and answer in detail. When all knowledge base content is irrelevant to the question, your answer must include the sentence \"The answer you are looking for is not found in the knowledge base!\" Answers need to consider chat history.\r\n ",
2066
- "doc_id": "5c5999ec7be811ef9cab0242ac120005",
2067
- "docnm_kwd": "1.txt",
2068
- "kb_id": "c7ee74067a2c11efb21c0242ac120006",
2069
- "important_kwd": [],
2070
- "img_id": "",
2071
- "similarity": 0.4442746624416507,
2072
- "vector_similarity": 0.3843936320913369,
2073
- "term_similarity": 0.4699379611632138,
2074
  "positions": [
2075
  ""
2076
  ]
@@ -2079,17 +2074,16 @@ data: {
2079
  "doc_aggs": [
2080
  {
2081
  "doc_name": "1.txt",
2082
- "doc_id": "5c5999ec7be811ef9cab0242ac120005",
2083
  "count": 1
2084
  }
2085
  ]
2086
  },
2087
- "prompt": "xxxx\r\n\r\n\"\"\"\r\nYou are an intelligent assistant. Please summarize the content of the knowledge base to answer the question. Please list the data in the knowledge base and answer in detail. When all knowledge base content is irrelevant to the question, your answer must include the sentence \"The answer you are looking for is not found in the knowledge base!\" Answers need to consider chat history.\r\n \r\n\"\"\"\r\n1\r\n2\r\n3\r\n4\r\n5\r\n6\r\nxxxx\n\n### Query:\nwho are you,please answer me in English\n\n### Elapsed\n - Retrieval: 332.2 ms\n - LLM: 2972.1 ms",
2088
- "id": "d8e5ebb6-6b52-4fd1-bd02-35b52ba3acaa",
2089
- "session_id": "e14344d08d1a11efb6210242ac120004"
2090
  }
2091
  }
2092
-
2093
  data:{
2094
  "code": 0,
2095
  "data": true
@@ -2103,4 +2097,244 @@ Failure:
2103
  "code": 102,
2104
  "message": "Please input your question."
2105
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2106
  ```
 
2018
 
2019
  Success:
2020
 
2021
+ ```text
2022
+ data:{
2023
  "code": 0,
2024
  "data": {
2025
+ "answer": "I am an intelligent assistant designed to help answer questions by summarizing content from a",
2026
  "reference": {},
2027
  "audio_binary": null,
2028
+ "id": "a84c5dd4-97b4-4624-8c3b-974012c8000d",
2029
+ "session_id": "82b0ab2a9c1911ef9d870242ac120006"
2030
  }
2031
  }
2032
+ data:{
 
2033
  "code": 0,
2034
  "data": {
2035
+ "answer": "I am an intelligent assistant designed to help answer questions by summarizing content from a knowledge base. My responses are based on the information available in the knowledge base and",
2036
  "reference": {},
2037
  "audio_binary": null,
2038
+ "id": "a84c5dd4-97b4-4624-8c3b-974012c8000d",
2039
+ "session_id": "82b0ab2a9c1911ef9d870242ac120006"
2040
  }
2041
  }
2042
+ data:{
 
2043
  "code": 0,
2044
  "data": {
2045
+ "answer": "I am an intelligent assistant designed to help answer questions by summarizing content from a knowledge base. My responses are based on the information available in the knowledge base and any relevant chat history.",
2046
  "reference": {},
2047
  "audio_binary": null,
2048
+ "id": "a84c5dd4-97b4-4624-8c3b-974012c8000d",
2049
+ "session_id": "82b0ab2a9c1911ef9d870242ac120006"
2050
  }
2051
  }
2052
+ data:{
 
2053
  "code": 0,
2054
  "data": {
2055
+ "answer": "I am an intelligent assistant designed to help answer questions by summarizing content from a knowledge base ##0$$. My responses are based on the information available in the knowledge base and any relevant chat history.",
2056
  "reference": {
2057
+ "total": 1,
2058
  "chunks": [
2059
  {
2060
+ "id": "faf26c791128f2d5e821f822671063bd",
2061
+ "content": "xxxxxxxx",
2062
+ "document_id": "dd58f58e888511ef89c90242ac120006",
2063
+ "document_name": "1.txt",
2064
+ "dataset_id": "8e83e57a884611ef9d760242ac120006",
2065
+ "image_id": "",
2066
+ "similarity": 0.7,
2067
+ "vector_similarity": 0.0,
2068
+ "term_similarity": 1.0,
 
 
2069
  "positions": [
2070
  ""
2071
  ]
 
2074
  "doc_aggs": [
2075
  {
2076
  "doc_name": "1.txt",
2077
+ "doc_id": "dd58f58e888511ef89c90242ac120006",
2078
  "count": 1
2079
  }
2080
  ]
2081
  },
2082
+ "prompt": "xxxxxxxxxxx",
2083
+ "id": "a84c5dd4-97b4-4624-8c3b-974012c8000d",
2084
+ "session_id": "82b0ab2a9c1911ef9d870242ac120006"
2085
  }
2086
  }
 
2087
  data:{
2088
  "code": 0,
2089
  "data": true
 
2097
  "code": 102,
2098
  "message": "Please input your question."
2099
  }
2100
+ ```
2101
+
2102
+ ## Create agent session
2103
+
2104
+ **POST** `/api/v1/agents/{agent_id}/sessions`
2105
+
2106
+ Creates an agent session.
2107
+
2108
+ ### Request
2109
+
2110
+ - Method: POST
2111
+ - URL: `/api/v1/agents/{agent_id}/sessions`
2112
+ - Headers:
2113
+ - `'content-Type: application/json'`
2114
+ - `'Authorization: Bearer <YOUR_API_KEY>'`
2115
+ - Body:
2116
+
2117
+ #### Request example
2118
+
2119
+ ```bash
2120
+ curl --request POST \
2121
+ --url http://{address}/api/v1/agents/{agent_id}/sessions \
2122
+ --header 'Content-Type: application/json' \
2123
+ --header 'Authorization: Bearer <YOUR_API_KEY>' \
2124
+ --data '{
2125
+ }'
2126
+ ```
2127
+
2128
+ #### Request parameters
2129
+
2130
+ - `agent_id`: (*Path parameter*)
2131
+ The ID of the associated agent assistant.
2132
+
2133
+ ### Response
2134
+
2135
+ Success:
2136
+
2137
+ ```json
2138
+ {
2139
+ "code": 0,
2140
+ "data": {
2141
+ "agent_id": "2e45b5209c1011efa3e90242ac120006",
2142
+ "id": "7869e9e49c1711ef92840242ac120006",
2143
+ "message": [
2144
+ {
2145
+ "content": "Hello! I am the HR responsible for recruitment at Infineon. I learned that you are an expert in this field, and I took the liberty of reaching out to you. There is an opportunity I would like to share with you. RAGFlow is currently looking for a senior engineer for your position. I was wondering if you might be interested?",
2146
+ "role": "assistant"
2147
+ }
2148
+ ],
2149
+ "source": "agent",
2150
+ "user_id": ""
2151
+ }
2152
+ }
2153
+ ```
2154
+
2155
+ Failure:
2156
+
2157
+ ```json
2158
+ {
2159
+ "code": 102,
2160
+ "message": "Agent not found."
2161
+ }
2162
+ ```
2163
+
2164
+
2165
+
2166
+ ## Converse through agent
2167
+
2168
+ **POST** `/api/v1/agents/{agent_id}/completions`
2169
+ #######
2170
+ Asks a question to start an AI-powered conversation.
2171
+
2172
+ ### Request
2173
+
2174
+ - Method: POST
2175
+ - URL: `/api/v1/agents/{agent_id}/completions`
2176
+ - Headers:
2177
+ - `'content-Type: application/json'`
2178
+ - `'Authorization: Bearer <YOUR_API_KEY>'`
2179
+ - Body:
2180
+ - `"question"`: `string`
2181
+ - `"stream"`: `boolean`
2182
+ - `"session_id"`: `string`
2183
+
2184
+ #### Request example
2185
+
2186
+ ```bash
2187
+ curl --request POST \
2188
+ --url http://{address}/api/v1/agents/{agent_id}/completions \
2189
+ --header 'Content-Type: application/json' \
2190
+ --header 'Authorization: Bearer <YOUR_API_KEY>' \
2191
+ --data-binary '
2192
+ {
2193
+ "question": "What is RAGFlow?",
2194
+ "stream": true
2195
+ }'
2196
+ ```
2197
+
2198
+ #### Request Parameters
2199
+
2200
+ - `agent_id`: (*Path parameter*)
2201
+ The ID of the associated agent assistant.
2202
+ - `"question"`: (*Body Parameter*), `string` *Required*
2203
+ The question to start an AI-powered conversation.
2204
+ - `"stream"`: (*Body Parameter*), `boolean`
2205
+ Indicates whether to output responses in a streaming way:
2206
+ - `true`: Enable streaming.
2207
+ - `false`: Disable streaming (default).
2208
+ - `"session_id"`: (*Body Parameter*)
2209
+ The ID of session. If it is not provided, a new session will be generated.
2210
+
2211
+ ### Response
2212
+
2213
+ Success:
2214
+
2215
+ ```text
2216
+ data:{
2217
+ "code": 0,
2218
+ "message": "",
2219
+ "data": {
2220
+ "answer": "",
2221
+ "reference": [],
2222
+ "id": "7ed5c2e4-aa28-4397-bbed-59664a332aa0",
2223
+ "session_id": "ce1b4fa89c1811ef85720242ac120006"
2224
+ }
2225
+ }
2226
+ data:{
2227
+ "code": 0,
2228
+ "message": "",
2229
+ "data": {
2230
+ "answer": "Hello",
2231
+ "reference": [],
2232
+ "id": "7ed5c2e4-aa28-4397-bbed-59664a332aa0",
2233
+ "session_id": "ce1b4fa89c1811ef85720242ac120006"
2234
+ }
2235
+ }
2236
+ data:{
2237
+ "code": 0,
2238
+ "message": "",
2239
+ "data": {
2240
+ "answer": "Hello!",
2241
+ "reference": [],
2242
+ "id": "7ed5c2e4-aa28-4397-bbed-59664a332aa0",
2243
+ "session_id": "ce1b4fa89c1811ef85720242ac120006"
2244
+ }
2245
+ }
2246
+ data:{
2247
+ "code": 0,
2248
+ "message": "",
2249
+ "data": {
2250
+ "answer": "Hello! How",
2251
+ "reference": [],
2252
+ "id": "7ed5c2e4-aa28-4397-bbed-59664a332aa0",
2253
+ "session_id": "ce1b4fa89c1811ef85720242ac120006"
2254
+ }
2255
+ }
2256
+ data:{
2257
+ "code": 0,
2258
+ "message": "",
2259
+ "data": {
2260
+ "answer": "Hello! How can",
2261
+ "reference": [],
2262
+ "id": "7ed5c2e4-aa28-4397-bbed-59664a332aa0",
2263
+ "session_id": "ce1b4fa89c1811ef85720242ac120006"
2264
+ }
2265
+ }
2266
+ data:{
2267
+ "code": 0,
2268
+ "message": "",
2269
+ "data": {
2270
+ "answer": "Hello! How can I",
2271
+ "reference": [],
2272
+ "id": "7ed5c2e4-aa28-4397-bbed-59664a332aa0",
2273
+ "session_id": "ce1b4fa89c1811ef85720242ac120006"
2274
+ }
2275
+ }
2276
+ data:{
2277
+ "code": 0,
2278
+ "message": "",
2279
+ "data": {
2280
+ "answer": "Hello! How can I assist",
2281
+ "reference": [],
2282
+ "id": "7ed5c2e4-aa28-4397-bbed-59664a332aa0",
2283
+ "session_id": "ce1b4fa89c1811ef85720242ac120006"
2284
+ }
2285
+ }
2286
+ data:{
2287
+ "code": 0,
2288
+ "message": "",
2289
+ "data": {
2290
+ "answer": "Hello! How can I assist you",
2291
+ "reference": [],
2292
+ "id": "7ed5c2e4-aa28-4397-bbed-59664a332aa0",
2293
+ "session_id": "ce1b4fa89c1811ef85720242ac120006"
2294
+ }
2295
+ }
2296
+ data:{
2297
+ "code": 0,
2298
+ "message": "",
2299
+ "data": {
2300
+ "answer": "Hello! How can I assist you today",
2301
+ "reference": [],
2302
+ "id": "7ed5c2e4-aa28-4397-bbed-59664a332aa0",
2303
+ "session_id": "ce1b4fa89c1811ef85720242ac120006"
2304
+ }
2305
+ }
2306
+ data:{
2307
+ "code": 0,
2308
+ "message": "",
2309
+ "data": {
2310
+ "answer": "Hello! How can I assist you today?",
2311
+ "reference": [],
2312
+ "id": "7ed5c2e4-aa28-4397-bbed-59664a332aa0",
2313
+ "session_id": "ce1b4fa89c1811ef85720242ac120006"
2314
+ }
2315
+ }
2316
+ data:{
2317
+ "code": 0,
2318
+ "message": "",
2319
+ "data": {
2320
+ "answer": "Hello! How can I assist you today?",
2321
+ "reference": [],
2322
+ "id": "7ed5c2e4-aa28-4397-bbed-59664a332aa0",
2323
+ "session_id": "ce1b4fa89c1811ef85720242ac120006"
2324
+ }
2325
+ }
2326
+ data:{
2327
+ "code": 0,
2328
+ "message": "",
2329
+ "data": true
2330
+ }
2331
+ ```
2332
+
2333
+ Failure:
2334
+
2335
+ ```json
2336
+ {
2337
+ "code": 102,
2338
+ "message": "`question` is required."
2339
+ }
2340
  ```
docs/references/python_api_reference.md CHANGED
@@ -1387,6 +1387,117 @@ while True:
1387
 
1388
  cont = ""
1389
  for ans in session.ask(question, stream=True):
1390
- print(answer.content[len(cont):], end='', flush=True)
1391
- cont = answer.content
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1392
  ```
 
1387
 
1388
  cont = ""
1389
  for ans in session.ask(question, stream=True):
1390
+ print(ans.content[len(cont):], end='', flush=True)
1391
+ cont = ans.content
1392
+ ```
1393
+ ---
1394
+
1395
+ ## Create agent session
1396
+
1397
+ ```python
1398
+ Agent.create_session(id,rag) -> Session
1399
+ ```
1400
+
1401
+ Creates a agemt session.
1402
+
1403
+ ### Returns
1404
+
1405
+ - Success: A `Session` object containing the following attributes:
1406
+ - `id`: `str` The auto-generated unique identifier of the created session.
1407
+ - `message`: `list[Message]` The messages of the created session assistant. Default: `[{"role": "assistant", "content": "Hi! I am your assistant,can I help you?"}]`
1408
+ - `agnet_id`: `str` The ID of the associated agent assistant.
1409
+ - Failure: `Exception`
1410
+
1411
+ ### Examples
1412
+
1413
+ ```python
1414
+ from ragflow_sdk import RAGFlow
1415
+
1416
+ rag_object = RAGFlow(api_key="<YOUR_API_KEY>", base_url="http://<YOUR_BASE_URL>:9380")
1417
+ AGENT_ID = "AGENT_ID"
1418
+ session = create_session(AGENT_ID,rag_object)
1419
+ ```
1420
+ ---
1421
+
1422
+ ## Converse through agent
1423
+
1424
+ ```python
1425
+ Session.ask(question: str, stream: bool = False) -> Optional[Message, iter[Message]]
1426
+ ```
1427
+
1428
+ Asks a question to start an AI-powered conversation.
1429
+
1430
+ ### Parameters
1431
+
1432
+ #### question: `str` *Required*
1433
+
1434
+ The question to start an AI-powered conversation.
1435
+
1436
+ #### stream: `bool`
1437
+
1438
+ Indicates whether to output responses in a streaming way:
1439
+
1440
+ - `True`: Enable streaming.
1441
+ - `False`: Disable streaming (default).
1442
+
1443
+ ### Returns
1444
+
1445
+ - A `Message` object containing the response to the question if `stream` is set to `False`
1446
+ - An iterator containing multiple `message` objects (`iter[Message]`) if `stream` is set to `True`
1447
+
1448
+ The following shows the attributes of a `Message` object:
1449
+
1450
+ #### id: `str`
1451
+
1452
+ The auto-generated message ID.
1453
+
1454
+ #### content: `str`
1455
+
1456
+ The content of the message. Defaults to `"Hi! I am your assistant, can I help you?"`.
1457
+
1458
+ #### reference: `list[Chunk]`
1459
+
1460
+ A list of `Chunk` objects representing references to the message, each containing the following attributes:
1461
+
1462
+ - `id` `str`
1463
+ The chunk ID.
1464
+ - `content` `str`
1465
+ The content of the chunk.
1466
+ - `image_id` `str`
1467
+ The ID of the snapshot of the chunk. Applicable only when the source of the chunk is an image, PPT, PPTX, or PDF file.
1468
+ - `document_id` `str`
1469
+ The ID of the referenced document.
1470
+ - `document_name` `str`
1471
+ The name of the referenced document.
1472
+ - `position` `list[str]`
1473
+ The location information of the chunk within the referenced document.
1474
+ - `dataset_id` `str`
1475
+ The ID of the dataset to which the referenced document belongs.
1476
+ - `similarity` `float`
1477
+ A composite similarity score of the chunk ranging from `0` to `1`, with a higher value indicating greater similarity. It is the weighted sum of `vector_similarity` and `term_similarity`.
1478
+ - `vector_similarity` `float`
1479
+ A vector similarity score of the chunk ranging from `0` to `1`, with a higher value indicating greater similarity between vector embeddings.
1480
+ - `term_similarity` `float`
1481
+ A keyword similarity score of the chunk ranging from `0` to `1`, with a higher value indicating greater similarity between keywords.
1482
+
1483
+ ### Examples
1484
+
1485
+ ```python
1486
+ from ragflow_sdk import RAGFlow,Agent
1487
+
1488
+ rag_object = RAGFlow(api_key="<YOUR_API_KEY>", base_url="http://<YOUR_BASE_URL>:9380")
1489
+ AGENT_id = "AGENT_ID"
1490
+ session = Agent.create_session(AGENT_id,rag_object)
1491
+
1492
+ print("\n==================== Miss R =====================\n")
1493
+ print("Hello. What can I do for you?")
1494
+
1495
+ while True:
1496
+ question = input("\n==================== User =====================\n> ")
1497
+ print("\n==================== Miss R =====================\n")
1498
+
1499
+ cont = ""
1500
+ for ans in session.ask(question, stream=True):
1501
+ print(ans.content[len(cont):], end='', flush=True)
1502
+ cont = ans.content
1503
  ```
sdk/python/ragflow_sdk/__init__.py CHANGED
@@ -7,4 +7,5 @@ from .modules.dataset import DataSet
7
  from .modules.chat import Chat
8
  from .modules.session import Session
9
  from .modules.document import Document
10
- from .modules.chunk import Chunk
 
 
7
  from .modules.chat import Chat
8
  from .modules.session import Session
9
  from .modules.document import Document
10
+ from .modules.chunk import Chunk
11
+ from .modules.agent import Agent
sdk/python/ragflow_sdk/modules/agent.py ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from .base import Base
2
+ from .session import Session
3
+ import requests
4
+
5
+ class Agent(Base):
6
+ def __init__(self,rag,res_dict):
7
+ self.id = None
8
+ self.avatar = None
9
+ self.canvas_type = None
10
+ self.description = None
11
+ self.dsl = None
12
+ super().__init__(rag, res_dict)
13
+
14
+ class Dsl(Base):
15
+ def __init__(self,rag,res_dict):
16
+ self.answer = []
17
+ self.components = {
18
+ "begin": {
19
+ "downstream": ["Answer:China"],
20
+ "obj": {
21
+ "component_name": "Begin",
22
+ "params": {}
23
+ },
24
+ "upstream": []
25
+ }
26
+ }
27
+ self.graph = {
28
+ "edges": [],
29
+ "nodes": [
30
+ {
31
+ "data": {
32
+ "label": "Begin",
33
+ "name": "begin"
34
+ },
35
+ "id": "begin",
36
+ "position": {
37
+ "x": 50,
38
+ "y": 200
39
+ },
40
+ "sourcePosition": "left",
41
+ "targetPosition": "right",
42
+ "type": "beginNode"
43
+ }
44
+ ]
45
+ }
46
+ self.history = []
47
+ self.messages = []
48
+ self.path = []
49
+ self.reference = []
50
+ super().__init__(rag,res_dict)
51
+
52
+ @staticmethod
53
+ def create_session(id,rag) -> Session:
54
+ res = requests.post(f"http://127.0.0.1:9380/api/v1/agents/{id}/sessions",headers={"Authorization": f"Bearer {rag.user_key}"},json={})
55
+ res = res.json()
56
+ if res.get("code") == 0:
57
+ return Session(rag,res.get("data"))
58
+ raise Exception(res.get("message"))
59
+
sdk/python/ragflow_sdk/modules/session.py CHANGED
@@ -9,14 +9,19 @@ class Session(Base):
9
  self.name = "New session"
10
  self.messages = [{"role": "assistant", "content": "Hi! I am your assistant,can I help you?"}]
11
  self.chat_id = None
 
 
 
 
 
 
12
  super().__init__(rag, res_dict)
13
 
14
- def ask(self, question: str, stream: bool = False):
15
- for message in self.messages:
16
- if "reference" in message:
17
- message.pop("reference")
18
- res = self.post(f"/chats/{self.chat_id}/completions",
19
- {"question": question, "stream": True,"session_id":self.id}, stream=stream)
20
  for line in res.iter_lines():
21
  line = line.decode("utf-8")
22
  if line.startswith("{"):
@@ -33,25 +38,20 @@ class Session(Base):
33
  }
34
  if "chunks" in reference:
35
  chunks = reference["chunks"]
36
- chunk_list = []
37
- for chunk in chunks:
38
- new_chunk = {
39
- "id": chunk["chunk_id"],
40
- "content": chunk["content_with_weight"],
41
- "document_id": chunk["doc_id"],
42
- "document_name": chunk["docnm_kwd"],
43
- "dataset_id": chunk["kb_id"],
44
- "image_id": chunk["img_id"],
45
- "similarity": chunk["similarity"],
46
- "vector_similarity": chunk["vector_similarity"],
47
- "term_similarity": chunk["term_similarity"],
48
- "positions": chunk["positions"],
49
- }
50
- chunk_list.append(new_chunk)
51
- temp_dict["reference"] = chunk_list
52
  message = Message(self.rag, temp_dict)
53
  yield message
54
 
 
 
 
 
 
 
 
 
 
 
55
  def update(self,update_message):
56
  res = self.put(f"/chats/{self.chat_id}/sessions/{self.id}",
57
  update_message)
@@ -66,20 +66,4 @@ class Message(Base):
66
  self.role = "assistant"
67
  self.prompt = None
68
  self.id = None
69
- super().__init__(rag, res_dict)
70
-
71
-
72
- class Chunk(Base):
73
- def __init__(self, rag, res_dict):
74
- self.id = None
75
- self.content = None
76
- self.document_id = ""
77
- self.document_name = ""
78
- self.dataset_id = ""
79
- self.image_id = ""
80
- self.similarity = None
81
- self.vector_similarity = None
82
- self.term_similarity = None
83
- self.positions = None
84
- super().__init__(rag, res_dict)
85
-
 
9
  self.name = "New session"
10
  self.messages = [{"role": "assistant", "content": "Hi! I am your assistant,can I help you?"}]
11
  self.chat_id = None
12
+ self.agent_id = None
13
+ for key,value in res_dict.items():
14
+ if key =="chat_id" and value is not None:
15
+ self.__session_type = "chat"
16
+ if key == "agent_id" and value is not None:
17
+ self.__session_type = "agent"
18
  super().__init__(rag, res_dict)
19
 
20
+ def ask(self, question):
21
+ if self.__session_type == "agent":
22
+ res=self._ask_agent(question)
23
+ elif self.__session_type == "chat":
24
+ res=self._ask_chat(question)
 
25
  for line in res.iter_lines():
26
  line = line.decode("utf-8")
27
  if line.startswith("{"):
 
38
  }
39
  if "chunks" in reference:
40
  chunks = reference["chunks"]
41
+ temp_dict["reference"] = chunks
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  message = Message(self.rag, temp_dict)
43
  yield message
44
 
45
+
46
+ def _ask_chat(self, question: str, stream: bool = False):
47
+ res = self.post(f"/chats/{self.chat_id}/completions",
48
+ {"question": question, "stream": True,"session_id":self.id}, stream=stream)
49
+ return res
50
+ def _ask_agent(self,question:str,stream:bool=False):
51
+ res = self.post(f"/agents/{self.agent_id}/completions",
52
+ {"question": question, "stream": True,"session_id":self.id}, stream=stream)
53
+ return res
54
+
55
  def update(self,update_message):
56
  res = self.put(f"/chats/{self.chat_id}/sessions/{self.id}",
57
  update_message)
 
66
  self.role = "assistant"
67
  self.prompt = None
68
  self.id = None
69
+ super().__init__(rag, res_dict)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
sdk/python/test/t_session.py CHANGED
@@ -1,5 +1,6 @@
1
- from ragflow_sdk import RAGFlow
2
  from common import HOST_ADDRESS
 
3
 
4
 
5
  def test_create_session_with_success(get_api_key_fixture):
@@ -58,6 +59,7 @@ def test_delete_sessions_with_success(get_api_key_fixture):
58
  session = assistant.create_session()
59
  assistant.delete_sessions(ids=[session.id])
60
 
 
61
  def test_update_session_with_name(get_api_key_fixture):
62
  API_KEY = get_api_key_fixture
63
  rag = RAGFlow(API_KEY, HOST_ADDRESS)
@@ -92,4 +94,17 @@ def test_list_sessions_with_success(get_api_key_fixture):
92
  assistant=rag.create_chat("test_list_session", dataset_ids=[kb.id])
93
  assistant.create_session("test_1")
94
  assistant.create_session("test_2")
95
- assistant.list_sessions()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from ragflow_sdk import RAGFlow,Agent
2
  from common import HOST_ADDRESS
3
+ import pytest
4
 
5
 
6
  def test_create_session_with_success(get_api_key_fixture):
 
59
  session = assistant.create_session()
60
  assistant.delete_sessions(ids=[session.id])
61
 
62
+
63
  def test_update_session_with_name(get_api_key_fixture):
64
  API_KEY = get_api_key_fixture
65
  rag = RAGFlow(API_KEY, HOST_ADDRESS)
 
94
  assistant=rag.create_chat("test_list_session", dataset_ids=[kb.id])
95
  assistant.create_session("test_1")
96
  assistant.create_session("test_2")
97
+ assistant.list_sessions()
98
+
99
+ @pytest.mark.skip(reason="")
100
+ def test_create_agent_session_with_success(get_api_key_fixture):
101
+ API_KEY = "ragflow-BkOGNhYjIyN2JiODExZWY5MzVhMDI0Mm"
102
+ rag = RAGFlow(API_KEY,HOST_ADDRESS)
103
+ Agent.create_session("2e45b5209c1011efa3e90242ac120006", rag)
104
+
105
+ @pytest.mark.skip(reason="")
106
+ def test_create_agent_conversation_with_success(get_api_key_fixture):
107
+ API_KEY = "ragflow-BkOGNhYjIyN2JiODExZWY5MzVhMDI0Mm"
108
+ rag = RAGFlow(API_KEY,HOST_ADDRESS)
109
+ session = Agent.create_session("2e45b5209c1011efa3e90242ac120006", rag)
110
+ session.ask("What is this job")