dawoodkhan82 commited on
Commit
e3e7ab8
·
1 Parent(s): 9cb2bd5
Files changed (5) hide show
  1. .gitignore +157 -0
  2. app.py +163 -6
  3. gradio_ui.py +8 -7
  4. requirements.txt +2 -3
  5. system_prompt.py +19 -0
.gitignore ADDED
@@ -0,0 +1,157 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.pyc
6
+
7
+ # C extensions
8
+ *.so
9
+
10
+ # Distribution / packaging
11
+ .Python
12
+ build/
13
+ develop-eggs/
14
+ dist/
15
+ downloads/
16
+ .eggs/
17
+ .eggs/
18
+ lib/
19
+ lib64/
20
+ parts/
21
+ sdist/
22
+ var/
23
+ wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ *.manifest
31
+ *.spec
32
+
33
+ # Installer logs
34
+ pip-log.txt
35
+ pip-delete-this-directory.txt
36
+
37
+ # Unit test / coverage reports
38
+ htmlcov/
39
+ .tox/
40
+ .nox/
41
+ .coverage
42
+ .coverage.*
43
+ .cache
44
+ nosetests.xml
45
+ coverage.xml
46
+ *.cover
47
+ *.py,cover
48
+ .hypothesis/
49
+ .pytest_cache/
50
+ cover/
51
+
52
+ # Translations
53
+ *.mo
54
+ *.pot
55
+
56
+ # Django stuff:
57
+ *.log
58
+ local_settings.py
59
+ db.sqlite3
60
+ db.sqlite3-journal
61
+
62
+ # Flask stuff:
63
+ instance/
64
+ .webassets-cache
65
+
66
+ # Scrapy stuff:
67
+ .scrapy
68
+
69
+ # Sphinx documentation
70
+ docs/_build/
71
+
72
+ # PyBuilder
73
+ .pybuilder/
74
+ target/
75
+
76
+ # Jupyter Notebook
77
+ .ipynb_checkpoints
78
+
79
+ # IPython
80
+ profile_default/
81
+ ipython_config.py
82
+
83
+ # pyenv
84
+ .python-version
85
+
86
+ # pipenv
87
+ Pipfile.lock
88
+
89
+ # poetry
90
+ poetry.lock
91
+
92
+ # Environments
93
+ .env
94
+ .venv
95
+ env/
96
+ venv/
97
+ ENV/
98
+ env.bak/
99
+ venv.bak/
100
+
101
+ # Spyder project settings
102
+ .spyderproject
103
+ .spyproject
104
+
105
+ # Rope project settings
106
+ .ropeproject
107
+
108
+ # mkdocs documentation
109
+ /site
110
+
111
+ # mypy
112
+ .mypy_cache/
113
+ .dmypy.json
114
+ dmypy.json
115
+
116
+ # Pyre type checker
117
+ .pyre/
118
+
119
+ # pytype static type analyzer
120
+ .pytype/
121
+
122
+ # Cython debug symbols
123
+ cython_debug/
124
+
125
+ # PyCharm
126
+ .idea/
127
+
128
+ # VS Code
129
+ .vscode/
130
+
131
+ # Operating System
132
+ .DS_Store
133
+ .DS_Store?
134
+ ._*
135
+ .Spotlight-V100
136
+ .Trashes
137
+ ehthumbs.db
138
+ Thumbs.db
139
+
140
+ # Temporary files
141
+ *.tmp
142
+ *.temp
143
+
144
+ # Gradio
145
+ .gradio/
146
+
147
+ # Flask instance folder
148
+ instance/
149
+
150
+ # API keys and sensitive data
151
+ *.key
152
+ secrets.json
153
+ config.ini
154
+
155
+ # Log files
156
+ *.log
157
+ logs/
app.py CHANGED
@@ -1,7 +1,164 @@
1
- from smolagents import VisitWebpageTool, InferenceClientModel, CodeAgent, ToolCallingAgent, WebSearchTool
2
- from gradio_ui import GradioUI
 
 
 
 
 
3
 
4
- model = InferenceClientModel(model_id="meta-llama/Llama-3.3-70B-Instruct", provider="hf-inference")
5
- agent = CodeAgent(tools=[VisitWebpageTool(), WebSearchTool()], model=model, additional_authorized_imports=["xml.etree.ElementTree"])
6
- agent.prompt_templates["system_prompt"] = agent.prompt_templates["system_prompt"] + "\nTake the final result and format it as a sms text message to a customer. You are a helpful customer support assistant. Keep your answers to a 30 word limit. You are a sms text box so keep it informal. Dont show your thinking in the final message. When the user mentions a time that works for them for a scheduled appointment, reply with `Great! We can schedule your visit for that time. Please call https://www.ohiocars.com at +1 513-712-8086 to confirm your appointment. Looking forward to seeing you then!'"
7
- GradioUI(agent).launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from smolagents import VisitWebpageTool, InferenceClientModel, CodeAgent, WebSearchTool, tool
2
+ from flask import Flask, request, jsonify
3
+ from crawl4ai import AsyncWebCrawler, CrawlerRunConfig
4
+ from crawl4ai.deep_crawling import BFSDeepCrawlStrategy
5
+ from crawl4ai.content_scraping_strategy import LXMLWebScrapingStrategy
6
+ from system_prompt import get_system_prompt
7
+ import xml.etree.ElementTree as ET
8
 
9
+ app = Flask(__name__)
10
+
11
+ model = InferenceClientModel(model_id="meta-llama/Llama-3.3-70B-Instruct", provider="together")
12
+ crawler_config = CrawlerRunConfig(
13
+ deep_crawl_strategy=BFSDeepCrawlStrategy(
14
+ max_depth=0,
15
+ include_external=False
16
+ ),
17
+ scraping_strategy=LXMLWebScrapingStrategy(),
18
+ verbose=True
19
+ )
20
+
21
+ def extract_vehicle_info_as_string(adf_xml):
22
+ root = ET.fromstring(adf_xml)
23
+
24
+ # Find the vehicle element
25
+ vehicle = root.find('.//vehicle')
26
+
27
+ if vehicle is not None:
28
+ year = vehicle.find('year').text if vehicle.find('year') is not None else ""
29
+ make = vehicle.find('make').text if vehicle.find('make') is not None else ""
30
+ model = vehicle.find('model').text if vehicle.find('model') is not None else ""
31
+ vehicle_info = f"{year} {make} {model}".strip()
32
+
33
+ # Extract first name
34
+ first_name = ""
35
+ name_element = root.find('.//name[@part="first"]')
36
+ if name_element is not None:
37
+ first_name = name_element.text.strip() if name_element.text else ""
38
+ return first_name, vehicle_info
39
+
40
+ def safe_get_attr(obj, attr, default=None):
41
+ try:
42
+ return getattr(obj, attr, default)
43
+ except (AttributeError, TypeError):
44
+ return default
45
+
46
+ @tool
47
+ def custom_site_crawler(website_url: str) -> str:
48
+ """
49
+ Crawl the car gurus site for the specific dealership and return the markdown content or crawl the dealership website and return the markdown content. Use this when the user asks about the car or dealership and cannot be answered by the ADF Lead.
50
+
51
+ Args:
52
+ website_url: The url of the website (car gurus or dealership website) to crawl.
53
+
54
+ Returns:
55
+ A string of markdown content of the website.
56
+ """
57
+ import asyncio
58
+
59
+ async def _crawl_site(url):
60
+ async with AsyncWebCrawler() as crawler:
61
+ try:
62
+ result_container = await crawler.arun(url, config=crawler_config)
63
+
64
+ # Handle different result types from crawler
65
+ if hasattr(result_container, '__iter__') and not isinstance(result_container, str):
66
+ try:
67
+ # Try to get first result if it's a list-like container
68
+ result = next(iter(result_container))
69
+ except (StopIteration, TypeError):
70
+ result = result_container
71
+ else:
72
+ result = result_container
73
+
74
+ markdown_result = safe_get_attr(result, 'markdown', None)
75
+ if markdown_result:
76
+ raw_markdown = safe_get_attr(markdown_result, 'raw_markdown', '')
77
+ return raw_markdown if raw_markdown else ""
78
+ else:
79
+ return ""
80
+ except Exception as e:
81
+ print(f"Error crawling {url}: {e}")
82
+ return ""
83
+
84
+ return asyncio.run(_crawl_site(website_url))
85
+
86
+ agent = CodeAgent(tools=[VisitWebpageTool(), WebSearchTool(), custom_site_crawler], model=model, additional_authorized_imports=["xml.etree.ElementTree"])
87
+
88
+
89
+ dealership_phone = "(513) 800-0805"
90
+ car_gurus_site = "https://www.cargurus.com/Cars/m-Ohio-Cars-sp458596"
91
+ car_site = "https://www.Ohiocars.com"
92
+ adf_lead = "<?xml version=\"1.0\"?><?ADF version=\"1.0\"?><adf><prospect><requestdate>2025-05-12T13:59:30</requestdate><vehicle status=\"used\"><id source=\"CarsForSale.com\">16f3114e-825f-4eb0-8165-ce43fe5143b6</id><year>2016</year><make>Toyota</make><model>Corolla</model><vin>5YFBURHE4GP511115</vin><stock></stock><comments>DP</comments><colorcombination><exteriorcolor>Super White</exteriorcolor></colorcombination><miles>131024.0</miles><price type=\"asking\">9950</price></vehicle><customer><contact><name part=\"first\">Test</name><name part=\"last\">Lead</name><name part=\"full\">Test Lead</name><email>[email protected]</email><phone>2582584568</phone><address><city></city><state></state><postalcode></postalcode></address></contact><comments><![CDATA[I'm interested and want to know more about the 2016 Toyota Corolla S Plus you have listed for $9,950 on Cars For Sale.]]></comments><timeframe><description></description></timeframe></customer><provider><id>19971</id><name part=\"full\">Carsforsale.com</name><service>Carsforsale.com</service><phone>866-388-9778</phone></provider><vendor><id>114483</id><vendorname>Ohio Cars</vendorname></vendor></prospect></adf>"
93
+ first_name, vehicle_info = extract_vehicle_info_as_string(adf_lead)
94
+
95
+ agent.prompt_templates["system_prompt"] = agent.prompt_templates["system_prompt"] + get_system_prompt(car_gurus_site, car_site, adf_lead, dealership_phone)
96
+
97
+ @app.route('/chat', methods=['POST'])
98
+ def chat():
99
+ """
100
+ Main chat endpoint to interact with the agent.
101
+ Expects JSON payload with 'message' field.
102
+ """
103
+ try:
104
+ data = request.get_json()
105
+ if not data or 'message' not in data:
106
+ return jsonify({'error': 'Missing message field in request'}), 400
107
+
108
+ message = data['message']
109
+ response = agent.run(message)
110
+
111
+ return jsonify({
112
+ 'response': response,
113
+ 'status': 'success'
114
+ })
115
+
116
+ except Exception as e:
117
+ return jsonify({
118
+ 'error': str(e),
119
+ 'status': 'error'
120
+ }), 500
121
+
122
+ @app.route('/crawl', methods=['POST'])
123
+ def crawl_website():
124
+ """
125
+ Endpoint to directly crawl a website using the custom site crawler.
126
+ Expects JSON payload with 'url' field.
127
+ """
128
+ try:
129
+ data = request.get_json()
130
+ if not data or 'url' not in data:
131
+ return jsonify({'error': 'Missing url field in request'}), 400
132
+
133
+ url = data['url']
134
+ content = custom_site_crawler(url)
135
+
136
+ return jsonify({
137
+ 'content': content,
138
+ 'url': url,
139
+ 'status': 'success'
140
+ })
141
+
142
+ except Exception as e:
143
+ return jsonify({
144
+ 'error': str(e),
145
+ 'status': 'error'
146
+ }), 500
147
+
148
+ @app.route('/health', methods=['GET'])
149
+ def health_check():
150
+ """Health check endpoint."""
151
+ return jsonify({'status': 'healthy'})
152
+
153
+ if __name__ == '__main__':
154
+ app.run(debug=True, host='0.0.0.0', port=4000)
155
+
156
+
157
+ # "(513) 800-0805"
158
+ # "https://www.cargurus.com/Cars/m-Ohio-Cars-sp458596"
159
+ # "https://www.Ohiocars.com"
160
+ # "<?xml version=\"1.0\"?><?ADF version=\"1.0\"?><adf><prospect><requestdate>2025-05-12T13:59:30</requestdate><vehicle status=\"used\"><id source=\"CarsForSale.com\">16f3114e-825f-4eb0-8165-ce43fe5143b6</id><year>2016</year><make>Toyota</make><model>Corolla</model><vin>5YFBURHE4GP511115</vin><stock></stock><comments>DP</comments><colorcombination><exteriorcolor>Super White</exteriorcolor></colorcombination><miles>131024.0</miles><price type=\"asking\">9950</price></vehicle><customer><contact><name part=\"first\">Test</name><name part=\"last\">Lead</name><name part=\"full\">Test Lead</name><email>[email protected]</email><phone>2582584568</phone><address><city></city><state></state><postalcode></postalcode></address></contact><comments><![CDATA[I'm interested and want to know more about the 2016 Toyota Corolla S Plus you have listed for $9,950 on Cars For Sale.]]></comments><timeframe><description></description></timeframe></customer><provider><id>19971</id><name part=\"full\">Carsforsale.com</name><service>Carsforsale.com</service><phone>866-388-9778</phone></provider><vendor><id>114483</id><vendorname>Ohio Cars</vendorname></vendor></prospect></adf>"
161
+ # "Hi {first_name}! The {vehicle_info} you're interested in is available at [OhioCars.com](https://www.ohiocars.com). Would you like to schedule a visit to check it out? We have appointment slots at 11 AM, 1 PM, or 3 PM. Which time works best for you?"
162
+
163
+
164
+ # first_name, vehicle_info = extract_vehicle_info_as_string(adf_lead.value)
gradio_ui.py CHANGED
@@ -9,7 +9,7 @@ from smolagents.memory import ActionStep, FinalAnswerStep, MemoryStep
9
  from smolagents.models import ChatMessageStreamDelta
10
  from smolagents.utils import _is_package_available
11
  import xml.etree.ElementTree as ET
12
-
13
 
14
  def get_step_footnote_content(step_log: MemoryStep, step_name: str) -> str:
15
  """Get a footnote string for a step log with duration and token information"""
@@ -241,10 +241,9 @@ class GradioUI:
241
  if not self.file_upload_folder.exists():
242
  self.file_upload_folder.mkdir(parents=True, exist_ok=True)
243
 
244
- def interact_with_agent(self, prompt, messages, session_state, car_site, adf_lead):
245
  import gradio as gr
246
- self.agent.prompt_templates["system_prompt"] += f"\n\nWhen answering a customer's question about the dealership or other cars, use the following site to find the information:\n\nDealership Site: {car_site}\n\nWhen answering a customer's question about the specific car use the following ADF Lead:\n\nADF Lead: {adf_lead}"
247
- # Get the agent type from the template agent
248
  if "agent" not in session_state:
249
  session_state["agent"] = self.agent
250
 
@@ -344,8 +343,10 @@ class GradioUI:
344
  )
345
  submit_btn = gr.Button("Submit", variant="primary")
346
  with gr.Accordion("Dealership Info", open=False):
347
- car_site = gr.Textbox(label="Car Gurus Dealership Site", lines=2, value="https://www.cargurus.com/Cars/m-Ohio-Cars-sp458596", interactive=True)
 
348
  adf_lead = gr.Textbox(label="ADF Lead", lines=4, value="<?xml version=\"1.0\"?><?ADF version=\"1.0\"?><adf><prospect><requestdate>2025-05-12T13:59:30</requestdate><vehicle status=\"used\"><id source=\"CarsForSale.com\">16f3114e-825f-4eb0-8165-ce43fe5143b6</id><year>2016</year><make>Toyota</make><model>Corolla</model><vin>5YFBURHE4GP511115</vin><stock></stock><comments>DP</comments><colorcombination><exteriorcolor>Super White</exteriorcolor></colorcombination><miles>131024.0</miles><price type=\"asking\">9950</price></vehicle><customer><contact><name part=\"first\">Test</name><name part=\"last\">Lead</name><name part=\"full\">Test Lead</name><email>[email protected]</email><phone>2582584568</phone><address><city></city><state></state><postalcode></postalcode></address></contact><comments><![CDATA[I'm interested and want to know more about the 2016 Toyota Corolla S Plus you have listed for $9,950 on Cars For Sale.]]></comments><timeframe><description></description></timeframe></customer><provider><id>19971</id><name part=\"full\">Carsforsale.com</name><service>Carsforsale.com</service><phone>866-388-9778</phone></provider><vendor><id>114483</id><vendorname>Ohio Cars</vendorname></vendor></prospect></adf>", interactive=False)
 
349
  # If an upload folder is provided, enable the upload feature
350
  if self.file_upload_folder is not None:
351
  upload_file = gr.File(label="Upload a file")
@@ -376,7 +377,7 @@ class GradioUI:
376
  self.log_user_message,
377
  [text_input, file_uploads_log],
378
  [stored_messages, text_input, submit_btn],
379
- ).then(self.interact_with_agent, [stored_messages, chatbot, session_state, car_site, adf_lead], [chatbot]).then(
380
  lambda: (
381
  gr.Textbox(
382
  interactive=True, placeholder="Enter your prompt here and press Shift+Enter or the button"
@@ -391,7 +392,7 @@ class GradioUI:
391
  self.log_user_message,
392
  [text_input, file_uploads_log],
393
  [stored_messages, text_input, submit_btn],
394
- ).then(self.interact_with_agent, [stored_messages, chatbot, session_state, car_site, adf_lead], [chatbot]).then(
395
  lambda: (
396
  gr.Textbox(
397
  interactive=True, placeholder="Enter your prompt here and press Shift+Enter or the button"
 
9
  from smolagents.models import ChatMessageStreamDelta
10
  from smolagents.utils import _is_package_available
11
  import xml.etree.ElementTree as ET
12
+ from system_prompt import get_system_prompt
13
 
14
  def get_step_footnote_content(step_log: MemoryStep, step_name: str) -> str:
15
  """Get a footnote string for a step log with duration and token information"""
 
241
  if not self.file_upload_folder.exists():
242
  self.file_upload_folder.mkdir(parents=True, exist_ok=True)
243
 
244
+ def interact_with_agent(self, prompt, messages, session_state, car_gurus_site, car_site, adf_lead, dealership_phone):
245
  import gradio as gr
246
+ self.agent.prompt_templates["system_prompt"] = self.agent.prompt_templates["system_prompt"] + get_system_prompt(car_gurus_site, car_site, adf_lead, dealership_phone)
 
247
  if "agent" not in session_state:
248
  session_state["agent"] = self.agent
249
 
 
343
  )
344
  submit_btn = gr.Button("Submit", variant="primary")
345
  with gr.Accordion("Dealership Info", open=False):
346
+ car_gurus_site = gr.Textbox(label="Car Gurus Dealership Site", lines=2, value="https://www.cargurus.com/Cars/m-Ohio-Cars-sp458596", interactive=True)
347
+ car_site = gr.Textbox(label="Dealership Site", lines=2, value="https://www.Ohiocars.com", interactive=True)
348
  adf_lead = gr.Textbox(label="ADF Lead", lines=4, value="<?xml version=\"1.0\"?><?ADF version=\"1.0\"?><adf><prospect><requestdate>2025-05-12T13:59:30</requestdate><vehicle status=\"used\"><id source=\"CarsForSale.com\">16f3114e-825f-4eb0-8165-ce43fe5143b6</id><year>2016</year><make>Toyota</make><model>Corolla</model><vin>5YFBURHE4GP511115</vin><stock></stock><comments>DP</comments><colorcombination><exteriorcolor>Super White</exteriorcolor></colorcombination><miles>131024.0</miles><price type=\"asking\">9950</price></vehicle><customer><contact><name part=\"first\">Test</name><name part=\"last\">Lead</name><name part=\"full\">Test Lead</name><email>[email protected]</email><phone>2582584568</phone><address><city></city><state></state><postalcode></postalcode></address></contact><comments><![CDATA[I'm interested and want to know more about the 2016 Toyota Corolla S Plus you have listed for $9,950 on Cars For Sale.]]></comments><timeframe><description></description></timeframe></customer><provider><id>19971</id><name part=\"full\">Carsforsale.com</name><service>Carsforsale.com</service><phone>866-388-9778</phone></provider><vendor><id>114483</id><vendorname>Ohio Cars</vendorname></vendor></prospect></adf>", interactive=False)
349
+ dealership_phone = gr.Textbox(label="Dealership Phone", lines=2, value="(513) 800-0805", interactive=True)
350
  # If an upload folder is provided, enable the upload feature
351
  if self.file_upload_folder is not None:
352
  upload_file = gr.File(label="Upload a file")
 
377
  self.log_user_message,
378
  [text_input, file_uploads_log],
379
  [stored_messages, text_input, submit_btn],
380
+ ).then(self.interact_with_agent, [stored_messages, chatbot, session_state, car_gurus_site, car_site, adf_lead, dealership_phone], [chatbot]).then(
381
  lambda: (
382
  gr.Textbox(
383
  interactive=True, placeholder="Enter your prompt here and press Shift+Enter or the button"
 
392
  self.log_user_message,
393
  [text_input, file_uploads_log],
394
  [stored_messages, text_input, submit_btn],
395
+ ).then(self.interact_with_agent, [stored_messages, chatbot, session_state, car_gurus_site, car_site, adf_lead, dealership_phone], [chatbot]).then(
396
  lambda: (
397
  gr.Textbox(
398
  interactive=True, placeholder="Enter your prompt here and press Shift+Enter or the button"
requirements.txt CHANGED
@@ -1,5 +1,4 @@
 
1
  smolagents
 
2
  gradio
3
- markdownify
4
- requests
5
- beautifulsoup4
 
1
+ flask>=2.3.0
2
  smolagents
3
+ crawl4ai
4
  gradio
 
 
 
system_prompt.py ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ SYSTEM_PROMPT = """You are a helpful customer support assistant.
2
+ Keep your answers to a 35 word limit. You are a sms text box so keep it informal.
3
+ Take the final result and format it as a sms text message to a customer. Dont show your thinking in the final message.
4
+ When the user mentions a time that works for them for a scheduled appointment, reply with `Great! We can schedule your visit for that time. Please call {car_site} at {dealership_phone} to confirm your appointment. Looking forward to seeing you then!
5
+ When it makes sense, end messages asking if the customer would like to schedule an appointment to visit and check out the vehicle.
6
+ When answering a customer's question about the car (e.g. price, features, mileage, etc.), use this ADF lead: {adf_lead} to find the information.
7
+ If the answer cannot be found, then use the custom_site_crawler tool with this site: {car_gurus_site} to find the information. This site will hold information regarding the dealership inventory, business hours, address, etc.
8
+ If the answer still cannot be found, then use the custom_site_crawler tool with this site: {car_site} to find the information. This is the dealership's website and will hold all up to date information.
9
+ Lastly, if the other sources still don;t have the answer, then use the WebSearchTool to find the information as a final resort.
10
+ If the question from the user is not related to the car, the dealership, or scheduling an appointment, then do not use the WebSearchTool and do not answer the question. Instead reply with `I'm sorry, I can only help with information about the car, the dealership, or scheduling an appointment. Would you like the schedule a visit?`
11
+ """
12
+
13
+ def get_system_prompt(car_gurus_site, car_site, adf_lead, dealership_phone):
14
+ return SYSTEM_PROMPT.format(
15
+ car_gurus_site=car_gurus_site,
16
+ car_site=car_site,
17
+ adf_lead=adf_lead,
18
+ dealership_phone=dealership_phone
19
+ )