MitchelHsu commited on
Commit
1586436
1 Parent(s): be41d24

Upload folder using huggingface_hub

Browse files
Files changed (6) hide show
  1. app/agent.py +4 -3
  2. app/app.py +36 -11
  3. app/models.py +2 -2
  4. app/ui.py +24 -25
  5. app/utils.py +9 -1
  6. requirements.txt +2 -1
app/agent.py CHANGED
@@ -1,3 +1,4 @@
 
1
  from langchain_openai import ChatOpenAI
2
  from config import examples, example_template, template_v2
3
  from langchain_core.prompts import PromptTemplate, FewShotPromptTemplate
@@ -25,13 +26,13 @@ class Agent:
25
  self.logs = None
26
  self.response = None
27
 
28
- def process_request(self, question, logs):
29
  self.question = question
30
- self.logs = logs
31
 
32
  prompt_formatted = self.prompt.format(
33
  question=question,
34
- logs=logs
35
  )
36
 
37
  self.response = self.llm.predict(prompt_formatted)
 
1
+ from utils import preprocess_logs
2
  from langchain_openai import ChatOpenAI
3
  from config import examples, example_template, template_v2
4
  from langchain_core.prompts import PromptTemplate, FewShotPromptTemplate
 
26
  self.logs = None
27
  self.response = None
28
 
29
+ def summarize(self, question, logs):
30
  self.question = question
31
+ self.logs = preprocess_logs(logs)
32
 
33
  prompt_formatted = self.prompt.format(
34
  question=question,
35
+ logs=self.logs
36
  )
37
 
38
  self.response = self.llm.predict(prompt_formatted)
app/app.py CHANGED
@@ -1,8 +1,7 @@
1
- import time
2
  from agent import Agent
3
  from config import MODEL
4
  from flask import Flask, jsonify, request
5
- from utils import read_documents, preprocess_logs
6
  from models import GetQuestionAndFactsResponse, SubmitQuestionAndDocumentsResponse, SubmitQuestionAndDocumentRequest
7
 
8
  app = Flask(__name__)
@@ -15,16 +14,16 @@ submitted_data = None
15
  def get_response():
16
  global submitted_data, processing, agent
17
 
18
- print(submitted_data)
19
-
20
  if not submitted_data:
21
  response = GetQuestionAndFactsResponse(
22
  question='',
23
  facts=[],
24
- status='No data found.'
25
  )
26
  return jsonify(response.dict()), 200
27
 
 
28
  if processing:
29
  response = GetQuestionAndFactsResponse(
30
  question=submitted_data.question,
@@ -33,6 +32,7 @@ def get_response():
33
  )
34
  return jsonify(response.dict()), 200
35
 
 
36
  response = GetQuestionAndFactsResponse(
37
  question=submitted_data.question,
38
  facts=agent.get_response_list(),
@@ -47,18 +47,43 @@ def submit_question():
47
  global submitted_data, processing, agent
48
  processing = True
49
  request_content = request.get_json()
50
- submitted_data = SubmitQuestionAndDocumentRequest(**request_content)
51
 
52
- logs = read_documents(submitted_data.urls)
53
- processed_logs = preprocess_logs(logs)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
 
55
- agent.process_request(
 
56
  question=submitted_data.question,
57
- logs=processed_logs
58
  )
59
 
60
  processing = False
61
- response = SubmitQuestionAndDocumentsResponse()
62
  return jsonify(response.dict()), 200
63
 
64
 
 
 
1
  from agent import Agent
2
  from config import MODEL
3
  from flask import Flask, jsonify, request
4
+ from utils import read_documents, validate_request_logs
5
  from models import GetQuestionAndFactsResponse, SubmitQuestionAndDocumentsResponse, SubmitQuestionAndDocumentRequest
6
 
7
  app = Flask(__name__)
 
14
  def get_response():
15
  global submitted_data, processing, agent
16
 
17
+ # If no data found
 
18
  if not submitted_data:
19
  response = GetQuestionAndFactsResponse(
20
  question='',
21
  facts=[],
22
+ status='No data found, please submit data'
23
  )
24
  return jsonify(response.dict()), 200
25
 
26
+ # If still processing request
27
  if processing:
28
  response = GetQuestionAndFactsResponse(
29
  question=submitted_data.question,
 
32
  )
33
  return jsonify(response.dict()), 200
34
 
35
+ # Request processed, create response with Agent summarization
36
  response = GetQuestionAndFactsResponse(
37
  question=submitted_data.question,
38
  facts=agent.get_response_list(),
 
47
  global submitted_data, processing, agent
48
  processing = True
49
  request_content = request.get_json()
 
50
 
51
+ # Submit payload read and validation
52
+ try:
53
+ submitted_data = SubmitQuestionAndDocumentRequest(**request_content)
54
+ except ValueError as e:
55
+ response = SubmitQuestionAndDocumentsResponse(status=f'Request payload does not match expected schema: {str(e)}')
56
+ return jsonify(response.dict()), 200
57
+
58
+ # Validate request URLS formats
59
+ try:
60
+ validate_request_logs(submitted_data.documents)
61
+ except ValueError as e:
62
+ # Respond with URL validation failed error
63
+ response = SubmitQuestionAndDocumentsResponse(status=f'URL validation failed: {e}')
64
+ return jsonify(response.dict()), 200
65
+
66
+ # Try loading documents
67
+ try:
68
+ logs = read_documents(submitted_data.documents)
69
+ except Exception as e:
70
+ # Respond with URL read fail if URL read error
71
+ response = SubmitQuestionAndDocumentsResponse(status=f'URL read failed: {e}')
72
+ return jsonify(response.dict()), 200
73
+
74
+ # If no data found
75
+ if len(logs) == 0:
76
+ response = SubmitQuestionAndDocumentsResponse(status=f'No data found in the URLs')
77
+ return jsonify(response.dict()), 200
78
 
79
+ # Call agent to summarize logs
80
+ agent.summarize(
81
  question=submitted_data.question,
82
+ logs=logs
83
  )
84
 
85
  processing = False
86
+ response = SubmitQuestionAndDocumentsResponse(status='success')
87
  return jsonify(response.dict()), 200
88
 
89
 
app/models.py CHANGED
@@ -9,9 +9,9 @@ class GetQuestionAndFactsResponse(BaseModel):
9
 
10
 
11
  class SubmitQuestionAndDocumentsResponse(BaseModel):
12
- pass
13
 
14
 
15
  class SubmitQuestionAndDocumentRequest(BaseModel):
16
  question: str
17
- urls: List[str]
 
9
 
10
 
11
  class SubmitQuestionAndDocumentsResponse(BaseModel):
12
+ status: str
13
 
14
 
15
  class SubmitQuestionAndDocumentRequest(BaseModel):
16
  question: str
17
+ documents: List[str]
app/ui.py CHANGED
@@ -2,36 +2,40 @@ import time
2
  import requests
3
  import gradio as gr
4
  from utils import get_url_list
5
- from models import SubmitQuestionAndDocumentRequest, GetQuestionAndFactsResponse
6
 
7
- base_url = 'https://cleric-agent-ad76f992e8d8.herokuapp.com/'
 
8
 
9
 
10
  def fetch_facts(question, call_log_urls):
 
 
 
 
 
 
11
  urls = get_url_list(call_log_urls)
12
  payload = SubmitQuestionAndDocumentRequest(
13
  question=question,
14
- urls=urls
15
  ).dict()
 
16
  response = requests.post(f"{base_url}/submit_question_and_documents", json=payload)
 
 
 
17
 
18
  start_time = time.time()
19
  while True:
20
  response = requests.get(f"{base_url}/get_question_and_facts")
21
  if response.status_code != 200:
22
- # st.error(f"Unexpected status code when getting question and facts: {response.status_code}")
23
- return None
24
- try:
25
- data = GetQuestionAndFactsResponse(**response.json())
26
- except ValueError as e:
27
- # st.error(f"The response data does not match the expected schema: {str(e)}")
28
- # st.write(response.json()) # Print the invalid data for debugging
29
- return None
30
 
 
31
  if data.status == "done":
32
  break
33
- elif time.time() - start_time > 300: # 5 minutes timeout
34
- # st.error("Timeout: Facts not ready after 5 minutes")
35
  return None
36
  time.sleep(1)
37
 
@@ -42,29 +46,24 @@ with gr.Blocks() as demo:
42
  gr.Markdown("""
43
  # Cleric Call Logs Summarize Agent
44
 
45
- Please place the URLs in the Call Logs URLs text box, separated by new line.
46
- Place your question to this call logs, then submit!
 
 
47
  """)
48
  error_box = gr.Textbox(label="Error", visible=False)
49
  with gr.Row(equal_height=True):
50
- call_logs_box = gr.Textbox(label='Call Logs URLs', scale=2)
51
- facts_box = gr.Textbox(label='Extracted Facts', scale=2)
52
 
53
  question_box = gr.Textbox(label='Question')
54
  submit_btn = gr.Button("Submit")
55
 
56
  submit_btn.click(
57
  fetch_facts,
58
- inputs=[call_logs_box, question_box],
59
  outputs=facts_box
60
  )
61
 
62
- # iface = gr.Interface(
63
- # fn=fetch_facts,
64
- # inputs=["text", "text"],
65
- # outputs="text",
66
- # allow_flagging="never",
67
- # title="Cleric Call Logs Summarize Agent"
68
- # )
69
  demo.launch()
70
 
 
2
  import requests
3
  import gradio as gr
4
  from utils import get_url_list
5
+ from models import SubmitQuestionAndDocumentRequest, GetQuestionAndFactsResponse, SubmitQuestionAndDocumentsResponse
6
 
7
+ base_url = 'https://cleric-agent-api-untxx3isja-uc.a.run.app'
8
+ # base_url = 'http://localhost:8000'
9
 
10
 
11
  def fetch_facts(question, call_log_urls):
12
+ if len(call_log_urls) == 0:
13
+ raise gr.Error('Please input call log.')
14
+
15
+ if len(question) == 0:
16
+ raise gr.Error('Please input question.')
17
+
18
  urls = get_url_list(call_log_urls)
19
  payload = SubmitQuestionAndDocumentRequest(
20
  question=question,
21
+ documents=urls
22
  ).dict()
23
+
24
  response = requests.post(f"{base_url}/submit_question_and_documents", json=payload)
25
+ response = SubmitQuestionAndDocumentsResponse(**response.json())
26
+ if response.status != 'success':
27
+ raise gr.Error('Input error: ' + response.status)
28
 
29
  start_time = time.time()
30
  while True:
31
  response = requests.get(f"{base_url}/get_question_and_facts")
32
  if response.status_code != 200:
33
+ raise gr.Error('Server response error.')
 
 
 
 
 
 
 
34
 
35
+ data = GetQuestionAndFactsResponse(**response.json())
36
  if data.status == "done":
37
  break
38
+ elif time.time() - start_time > 300:
 
39
  return None
40
  time.sleep(1)
41
 
 
46
  gr.Markdown("""
47
  # Cleric Call Logs Summarize Agent
48
 
49
+ ### Instructions:
50
+ 1. Enter the URLs in the "Call Log URLs" text box, separating each URL with a new line.
51
+ 2. Add your question related to these call logs.
52
+ 3. Click the "Submit" button to proceed.
53
  """)
54
  error_box = gr.Textbox(label="Error", visible=False)
55
  with gr.Row(equal_height=True):
56
+ call_logs_box = gr.Textbox(label='Call Log URLs', lines=10)
57
+ facts_box = gr.Textbox(label='Extracted Facts', lines=10)
58
 
59
  question_box = gr.Textbox(label='Question')
60
  submit_btn = gr.Button("Submit")
61
 
62
  submit_btn.click(
63
  fetch_facts,
64
+ inputs=[question_box, call_logs_box],
65
  outputs=facts_box
66
  )
67
 
 
 
 
 
 
 
 
68
  demo.launch()
69
 
app/utils.py CHANGED
@@ -1,4 +1,5 @@
1
  import requests
 
2
  from typing import List
3
 
4
 
@@ -19,10 +20,17 @@ def read_documents(documents: List[str]) -> List[str]:
19
  logs = []
20
  for url in documents:
21
  response = requests.get(url)
 
22
  logs.append(response.text)
23
 
24
  return logs
25
 
26
 
27
- def preprocess_logs(logs: List[str]):
28
  return '\n'.join(logs)
 
 
 
 
 
 
 
1
  import requests
2
+ import validators
3
  from typing import List
4
 
5
 
 
20
  logs = []
21
  for url in documents:
22
  response = requests.get(url)
23
+ response.raise_for_status()
24
  logs.append(response.text)
25
 
26
  return logs
27
 
28
 
29
+ def preprocess_logs(logs: List[str]) -> str:
30
  return '\n'.join(logs)
31
+
32
+
33
+ def validate_request_logs(urls: List[str]):
34
+ for url in urls:
35
+ if not validators.url(url):
36
+ raise ValueError(f'The following URL is invalid: {url}')
requirements.txt CHANGED
@@ -4,4 +4,5 @@ pydantic
4
  langchain
5
  langchain-openai
6
  pydantic
7
- gunicorn
 
 
4
  langchain
5
  langchain-openai
6
  pydantic
7
+ gunicorn
8
+ validators