Spaces:
Running
Running
bump to 0.2.0
Browse files- agent.py +23 -23
- requirements.txt +1 -1
- st_app.py +18 -11
agent.py
CHANGED
@@ -6,12 +6,12 @@ from typing import Tuple, List
|
|
6 |
|
7 |
from omegaconf import OmegaConf
|
8 |
|
9 |
-
from typing import Optional
|
10 |
from pydantic import Field, BaseModel
|
11 |
|
12 |
from vectara_agentic.agent import Agent
|
|
|
13 |
from vectara_agentic.tools import ToolsFactory, VectaraToolFactory
|
14 |
-
from vectara_agentic.tools_catalog import
|
15 |
|
16 |
from dotenv import load_dotenv
|
17 |
load_dotenv(override=True)
|
@@ -34,7 +34,7 @@ def extract_components_from_citation(citation: str) -> dict:
|
|
34 |
|
35 |
return {'volume': int(volume_num), 'reporter': reporter, 'first_page': int(first_page)}
|
36 |
|
37 |
-
def create_assistant_tools(cfg):
|
38 |
|
39 |
def get_opinion_text(
|
40 |
case_citation: str = Field(description = citation_description),
|
@@ -52,6 +52,7 @@ def create_assistant_tools(cfg):
|
|
52 |
citation_dict = extract_components_from_citation(case_citation)
|
53 |
if not citation_dict:
|
54 |
return f"Citation is invalid: {case_citation}."
|
|
|
55 |
reporter = citation_dict['reporter']
|
56 |
volume_num = citation_dict['volume']
|
57 |
first_page = citation_dict['first_page']
|
@@ -168,9 +169,8 @@ def create_assistant_tools(cfg):
|
|
168 |
class QueryCaselawArgs(BaseModel):
|
169 |
query: str = Field(..., description="The user query.")
|
170 |
|
171 |
-
vec_factory = VectaraToolFactory(vectara_api_key=cfg.api_key,
|
172 |
-
|
173 |
-
vectara_corpus_id=cfg.corpus_id)
|
174 |
summarizer = 'vectara-experimental-summary-ext-2023-12-11-med-omni'
|
175 |
|
176 |
ask_caselaw = vec_factory.create_rag_tool(
|
@@ -188,14 +188,14 @@ def create_assistant_tools(cfg):
|
|
188 |
"diversity_bias": 0.1
|
189 |
},
|
190 |
{
|
191 |
-
"type": "
|
192 |
"user_function": "max(1000 * get('$.score') - hours(seconds(to_unix_timestamp(now()) - to_unix_timestamp(datetime_parse(get('$.document_metadata.decision_date'), 'yyyy-MM-dd')))) / 24 / 365, 0)"
|
193 |
}
|
194 |
],
|
195 |
n_sentences_before = 2, n_sentences_after = 2, lambda_val = 0.005,
|
196 |
summary_num_results = 15,
|
197 |
vectara_summarizer = summarizer,
|
198 |
-
include_citations =
|
199 |
)
|
200 |
|
201 |
tools_factory = ToolsFactory()
|
@@ -213,8 +213,6 @@ def create_assistant_tools(cfg):
|
|
213 |
|
214 |
def get_agent_config() -> OmegaConf:
|
215 |
cfg = OmegaConf.create({
|
216 |
-
'customer_id': str(os.environ['VECTARA_CUSTOMER_ID']),
|
217 |
-
'corpus_id': str(os.environ['VECTARA_CORPUS_ID']),
|
218 |
'corpus_key': str(os.environ['VECTARA_CORPUS_KEY']),
|
219 |
'api_key': str(os.environ['VECTARA_API_KEY']),
|
220 |
'examples': os.environ.get('QUERY_EXAMPLES', None),
|
@@ -228,37 +226,39 @@ def initialize_agent(_cfg, agent_progress_callback=None):
|
|
228 |
|
229 |
legal_assistant_instructions = """
|
230 |
- You are a helpful legal assistant, with expertise in case law for the state of Alaska.
|
231 |
-
- The ask_caselaw tool is your primary
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
- If the ask_caselaw tool returns a response along with a ist of references mentioned in its response (in [N] format),
|
236 |
Format your response to focus on the main response, and use the metadata (such as citations, decision date, or case name)
|
237 |
in each relevant reference to provide more context in your response.
|
|
|
|
|
238 |
- Citations include 3 components: volume number, reporter, and first page.
|
239 |
Here are some examples: '253 P.2d 136', '10 Alaska 11', '6 C.M.A. 3'
|
240 |
- Never use your internal knowledge to guess citations. Only use citations information provided by a tool or the user.
|
|
|
|
|
|
|
|
|
|
|
241 |
- If two cases have conflicting rulings, assume that the case with the more current ruling date is correct.
|
242 |
- If the response is based on cases that are older than 5 years, make sure to inform the user that the information may be outdated,
|
243 |
since some case opinions may no longer apply in law.
|
244 |
- To summarize the case, use the get_opinion_text with summarize=True.
|
245 |
- Use get_opinion_text with summarize=False only when full text is needed. Consider summarizing the text when possible to make things run faster.
|
246 |
-
-
|
247 |
-
If this is unsuccessful, call the get_case_document_page tool instead.
|
248 |
-
The text displayed with this URL should be the name_abbreviation of the case (DON'T just say the info can be found here).
|
249 |
-
Don't call the get_case_document_page tool until after you have tried the get_case_document_pdf tool.
|
250 |
-
Don't provide URLs from any other tools. Do not generate URLs yourself.
|
251 |
-
- When presenting a URL in your response, use the validate_url tool.
|
252 |
- If a user wants to test their argument, use the ask_caselaw tool to gather information about cases related to their argument
|
253 |
and the critique_as_judge tool to determine whether their argument is sound or has issues that must be corrected.
|
254 |
- Never discuss politics, and always respond politely.
|
255 |
"""
|
256 |
-
|
257 |
agent = Agent(
|
258 |
-
tools=create_assistant_tools(_cfg),
|
259 |
topic="Case law in Alaska",
|
260 |
custom_instructions=legal_assistant_instructions,
|
261 |
agent_progress_callback=agent_progress_callback,
|
|
|
262 |
)
|
263 |
agent.report()
|
264 |
return agent
|
|
|
6 |
|
7 |
from omegaconf import OmegaConf
|
8 |
|
|
|
9 |
from pydantic import Field, BaseModel
|
10 |
|
11 |
from vectara_agentic.agent import Agent
|
12 |
+
from vectara_agentic.agent_config import AgentConfig
|
13 |
from vectara_agentic.tools import ToolsFactory, VectaraToolFactory
|
14 |
+
from vectara_agentic.tools_catalog import ToolsCatalog
|
15 |
|
16 |
from dotenv import load_dotenv
|
17 |
load_dotenv(override=True)
|
|
|
34 |
|
35 |
return {'volume': int(volume_num), 'reporter': reporter, 'first_page': int(first_page)}
|
36 |
|
37 |
+
def create_assistant_tools(cfg, agent_config):
|
38 |
|
39 |
def get_opinion_text(
|
40 |
case_citation: str = Field(description = citation_description),
|
|
|
52 |
citation_dict = extract_components_from_citation(case_citation)
|
53 |
if not citation_dict:
|
54 |
return f"Citation is invalid: {case_citation}."
|
55 |
+
summarize_text = ToolsCatalog(agent_config).summarize_text
|
56 |
reporter = citation_dict['reporter']
|
57 |
volume_num = citation_dict['volume']
|
58 |
first_page = citation_dict['first_page']
|
|
|
169 |
class QueryCaselawArgs(BaseModel):
|
170 |
query: str = Field(..., description="The user query.")
|
171 |
|
172 |
+
vec_factory = VectaraToolFactory(vectara_api_key=cfg.api_key,
|
173 |
+
vectara_corpus_key=cfg.corpus_key)
|
|
|
174 |
summarizer = 'vectara-experimental-summary-ext-2023-12-11-med-omni'
|
175 |
|
176 |
ask_caselaw = vec_factory.create_rag_tool(
|
|
|
188 |
"diversity_bias": 0.1
|
189 |
},
|
190 |
{
|
191 |
+
"type": "userfn",
|
192 |
"user_function": "max(1000 * get('$.score') - hours(seconds(to_unix_timestamp(now()) - to_unix_timestamp(datetime_parse(get('$.document_metadata.decision_date'), 'yyyy-MM-dd')))) / 24 / 365, 0)"
|
193 |
}
|
194 |
],
|
195 |
n_sentences_before = 2, n_sentences_after = 2, lambda_val = 0.005,
|
196 |
summary_num_results = 15,
|
197 |
vectara_summarizer = summarizer,
|
198 |
+
include_citations = True,
|
199 |
)
|
200 |
|
201 |
tools_factory = ToolsFactory()
|
|
|
213 |
|
214 |
def get_agent_config() -> OmegaConf:
|
215 |
cfg = OmegaConf.create({
|
|
|
|
|
216 |
'corpus_key': str(os.environ['VECTARA_CORPUS_KEY']),
|
217 |
'api_key': str(os.environ['VECTARA_API_KEY']),
|
218 |
'examples': os.environ.get('QUERY_EXAMPLES', None),
|
|
|
226 |
|
227 |
legal_assistant_instructions = """
|
228 |
- You are a helpful legal assistant, with expertise in case law for the state of Alaska.
|
229 |
+
- The ask_caselaw tool is your primary tool for answering user questions. Do not use your own knowledge to answer questions.
|
230 |
+
- If the ask_caselaw tool responds that it does not have enough information to answer the question,
|
231 |
+
try to rephrase the query or break it down into multiple sub-questions, and use the tool again.
|
232 |
+
- If the ask_caselaw tool returns a response along with a list of references mentioned in its response (in [N] format),
|
|
|
233 |
Format your response to focus on the main response, and use the metadata (such as citations, decision date, or case name)
|
234 |
in each relevant reference to provide more context in your response.
|
235 |
+
- If the ask_caselaw tool returns references with case citations, use the `get_case_document_pdf` tool to get a valid URL for the case.
|
236 |
+
and then use that link in your response to provide a clickable link to the case.
|
237 |
- Citations include 3 components: volume number, reporter, and first page.
|
238 |
Here are some examples: '253 P.2d 136', '10 Alaska 11', '6 C.M.A. 3'
|
239 |
- Never use your internal knowledge to guess citations. Only use citations information provided by a tool or the user.
|
240 |
+
- If you need a valid URL of the full case PDF, call the get_case_document_pdf tool.
|
241 |
+
- If you need a valid URL of the case information page, call the get_case_document_page tool.
|
242 |
+
The text displayed with this URL should be the name_abbreviation of the case (DON'T just say the info can be found here).
|
243 |
+
Don't call the get_case_document_page tool until after you have tried the get_case_document_pdf tool.
|
244 |
+
Don't provide URLs from any other tools. Do not generate URLs yourself.
|
245 |
- If two cases have conflicting rulings, assume that the case with the more current ruling date is correct.
|
246 |
- If the response is based on cases that are older than 5 years, make sure to inform the user that the information may be outdated,
|
247 |
since some case opinions may no longer apply in law.
|
248 |
- To summarize the case, use the get_opinion_text with summarize=True.
|
249 |
- Use get_opinion_text with summarize=False only when full text is needed. Consider summarizing the text when possible to make things run faster.
|
250 |
+
- When presenting a URL in your response, use the 'validate_url' tool.
|
|
|
|
|
|
|
|
|
|
|
251 |
- If a user wants to test their argument, use the ask_caselaw tool to gather information about cases related to their argument
|
252 |
and the critique_as_judge tool to determine whether their argument is sound or has issues that must be corrected.
|
253 |
- Never discuss politics, and always respond politely.
|
254 |
"""
|
255 |
+
agent_config = AgentConfig()
|
256 |
agent = Agent(
|
257 |
+
tools=create_assistant_tools(_cfg, agent_config=agent_config),
|
258 |
topic="Case law in Alaska",
|
259 |
custom_instructions=legal_assistant_instructions,
|
260 |
agent_progress_callback=agent_progress_callback,
|
261 |
+
agent_config=agent_config
|
262 |
)
|
263 |
agent.report()
|
264 |
return agent
|
requirements.txt
CHANGED
@@ -6,4 +6,4 @@ streamlit-feedback==0.1.3
|
|
6 |
uuid==1.30
|
7 |
langdetect==1.0.9
|
8 |
langcodes==3.4.0
|
9 |
-
vectara-agentic==0.
|
|
|
6 |
uuid==1.30
|
7 |
langdetect==1.0.9
|
8 |
langcodes==3.4.0
|
9 |
+
vectara-agentic==0.2.0
|
st_app.py
CHANGED
@@ -13,15 +13,6 @@ from agent import initialize_agent, get_agent_config
|
|
13 |
|
14 |
initial_prompt = "How can I help you today?"
|
15 |
|
16 |
-
def show_example_questions():
|
17 |
-
if len(st.session_state.example_messages) > 0 and st.session_state.first_turn:
|
18 |
-
selected_example = pills("Queries to Try:", st.session_state.example_messages, index=None)
|
19 |
-
if selected_example:
|
20 |
-
st.session_state.ex_prompt = selected_example
|
21 |
-
st.session_state.first_turn = False
|
22 |
-
return True
|
23 |
-
return False
|
24 |
-
|
25 |
def format_log_msg(log_msg: str):
|
26 |
max_log_msg_size = 500
|
27 |
return log_msg if len(log_msg) <= max_log_msg_size else log_msg[:max_log_msg_size]+'...'
|
@@ -37,7 +28,13 @@ def agent_progress_callback(status_type: AgentStatusType, msg: str):
|
|
37 |
latest_message = f"Calling tool {tool_name}..."
|
38 |
elif status_type == AgentStatusType.TOOL_OUTPUT:
|
39 |
latest_message = "Analyzing tool output..."
|
|
|
|
|
|
|
|
|
|
|
40 |
else:
|
|
|
41 |
return
|
42 |
|
43 |
st.session_state.status.update(label=latest_message)
|
@@ -46,6 +43,16 @@ def agent_progress_callback(status_type: AgentStatusType, msg: str):
|
|
46 |
for log_msg in st.session_state.log_messages:
|
47 |
st.markdown(format_log_msg(log_msg), unsafe_allow_html=True)
|
48 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
49 |
@st.dialog(title="Agent logs", width='large')
|
50 |
def show_modal():
|
51 |
for log_msg in st.session_state.log_messages:
|
@@ -132,8 +139,8 @@ async def launch_bot():
|
|
132 |
if st.session_state.prompt:
|
133 |
with st.chat_message("assistant", avatar='🤖'):
|
134 |
st.session_state.status = st.status('Processing...', expanded=False)
|
135 |
-
|
136 |
-
res = escape_dollars_outside_latex(
|
137 |
message = {"role": "assistant", "content": res, "avatar": '🤖'}
|
138 |
st.session_state.messages.append(message)
|
139 |
st.markdown(res)
|
|
|
13 |
|
14 |
initial_prompt = "How can I help you today?"
|
15 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
def format_log_msg(log_msg: str):
|
17 |
max_log_msg_size = 500
|
18 |
return log_msg if len(log_msg) <= max_log_msg_size else log_msg[:max_log_msg_size]+'...'
|
|
|
28 |
latest_message = f"Calling tool {tool_name}..."
|
29 |
elif status_type == AgentStatusType.TOOL_OUTPUT:
|
30 |
latest_message = "Analyzing tool output..."
|
31 |
+
elif status_type == AgentStatusType.AGENT_UPDATE:
|
32 |
+
if "Thought:" in msg:
|
33 |
+
latest_message = "Thinking..."
|
34 |
+
else:
|
35 |
+
latest_message = "Updating agent..."
|
36 |
else:
|
37 |
+
print(f"callback with {status_type} and {msg}")
|
38 |
return
|
39 |
|
40 |
st.session_state.status.update(label=latest_message)
|
|
|
43 |
for log_msg in st.session_state.log_messages:
|
44 |
st.markdown(format_log_msg(log_msg), unsafe_allow_html=True)
|
45 |
|
46 |
+
|
47 |
+
def show_example_questions():
|
48 |
+
if len(st.session_state.example_messages) > 0 and st.session_state.first_turn:
|
49 |
+
selected_example = pills("Queries to Try:", st.session_state.example_messages, index=None)
|
50 |
+
if selected_example:
|
51 |
+
st.session_state.ex_prompt = selected_example
|
52 |
+
st.session_state.first_turn = False
|
53 |
+
return True
|
54 |
+
return False
|
55 |
+
|
56 |
@st.dialog(title="Agent logs", width='large')
|
57 |
def show_modal():
|
58 |
for log_msg in st.session_state.log_messages:
|
|
|
139 |
if st.session_state.prompt:
|
140 |
with st.chat_message("assistant", avatar='🤖'):
|
141 |
st.session_state.status = st.status('Processing...', expanded=False)
|
142 |
+
response = st.session_state.agent.chat(st.session_state.prompt)
|
143 |
+
res = escape_dollars_outside_latex(response.response)
|
144 |
message = {"role": "assistant", "content": res, "avatar": '🤖'}
|
145 |
st.session_state.messages.append(message)
|
146 |
st.markdown(res)
|