From 5a019a6dc4c55dafc84d8e9a093af6383e60ba80 Mon Sep 17 00:00:00 2001 From: An Phan Date: Thu, 14 Nov 2024 22:56:34 -0800 Subject: [PATCH 01/17] fix: separate COLREGs and DCPA & TCPA application --- examples/llamarine/expert-knowledge.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/llamarine/expert-knowledge.txt b/examples/llamarine/expert-knowledge.txt index 40ca27358..09af88a33 100644 --- a/examples/llamarine/expert-knowledge.txt +++ b/examples/llamarine/expert-knowledge.txt @@ -31,7 +31,7 @@ In an overtaking situation, it is important to first identify whether the target --- -## **2. Mastering COLREGs Application with DCPA and/or TCPA consideration** +## **2. Mastering COLREGs Application combined with DCPA and/or TCPA consideration** 1. **“When in doubt, give way—always.”** - If you cannot assess risk or priority clearly, **assume the give-way role** to stay safe. From 2868bee17e196753f8a46d9b86ce253cb67d2875 Mon Sep 17 00:00:00 2001 From: An Phan Date: Fri, 15 Nov 2024 13:05:49 -0800 Subject: [PATCH 02/17] feat: cache output in memory --- examples/llamarine/app.py | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/examples/llamarine/app.py b/examples/llamarine/app.py index 4c22dc4de..f36bcd78f 100644 --- a/examples/llamarine/app.py +++ b/examples/llamarine/app.py @@ -72,23 +72,24 @@ def main(use_domain_lm: bool = False): with st.spinner(text='_SOLVING..._'): logger.level('DEBUG') - st.session_state.agent_solutions[st.session_state.typed_problem]: str = \ - get_or_create_agent(use_domain_lm).solve( - problem=st.session_state.typed_problem, allow_reject=True) - - if (solution := st.session_state.agent_solutions[st.session_state.typed_problem]): - if use_domain_lm: - solution = OpenAILM.from_defaults().get_response( - prompt=f"""Please respond the following text, with making sure there is a conclusion which is the main action item at the end of the response. - {solution} - """, - history=[ - {"role": "system", "content": LLAMARINE_SYSTEM_PROMPT}, - {"role": "user", "content": LLAMARINE_USER_PROMPT}, - ] - ) - - st.markdown(body=solution) + if not st.session_state.agent_solutions[st.session_state.typed_problem]: + st.session_state.agent_solutions[st.session_state.typed_problem]: str = \ + get_or_create_agent(use_domain_lm).solve( + problem=st.session_state.typed_problem, allow_reject=True) + + solution = st.session_state.agent_solutions[st.session_state.typed_problem] + if use_domain_lm: + solution = OpenAILM.from_defaults().get_response( + prompt=f"""Please respond the following text, with making sure there is a conclusion which is the main action item at the end of the response. + {solution} + """, + history=[ + {"role": "system", "content": LLAMARINE_SYSTEM_PROMPT}, + {"role": "user", "content": LLAMARINE_USER_PROMPT}, + ] + ) + + st.markdown(body=solution) if __name__ == '__main__': From 99840301deb35a0abe7e4a07cc542124abfe30b5 Mon Sep 17 00:00:00 2001 From: An Phan Date: Fri, 15 Nov 2024 13:33:13 -0800 Subject: [PATCH 03/17] feat: cache output in file storage --- examples/llamarine/.dockerignore | 1 + examples/llamarine/.gitignore | 1 + examples/llamarine/app.py | 15 ++++++++++++++- 3 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 examples/llamarine/.gitignore diff --git a/examples/llamarine/.dockerignore b/examples/llamarine/.dockerignore index a56435031..409cf1b9b 100644 --- a/examples/llamarine/.dockerignore +++ b/examples/llamarine/.dockerignore @@ -1,2 +1,3 @@ README.md .env +output/ diff --git a/examples/llamarine/.gitignore b/examples/llamarine/.gitignore new file mode 100644 index 000000000..ea1472ec1 --- /dev/null +++ b/examples/llamarine/.gitignore @@ -0,0 +1 @@ +output/ diff --git a/examples/llamarine/app.py b/examples/llamarine/app.py index f36bcd78f..34a531693 100644 --- a/examples/llamarine/app.py +++ b/examples/llamarine/app.py @@ -1,3 +1,4 @@ +import json import os from collections import defaultdict @@ -33,6 +34,11 @@ DEFAULT_API_KEY = os.environ.get('LEPTON_API_TOKEN') DEFAULT_API_BASE = os.environ.get('DEFAULT_API_BASE') +OUTPUT_DIR = os.environ.get('OUTPUT_DIR', 'output') +OUTPUT_FILE_PATH = f"{OUTPUT_DIR}/agent_solutions.json" + +os.makedirs(OUTPUT_DIR, exist_ok=True) + def main(use_domain_lm: bool = False): st.set_page_config(page_title=TITLE, @@ -60,7 +66,11 @@ def main(use_domain_lm: bool = False): ) if 'agent_solutions' not in st.session_state: - st.session_state.agent_solutions: defaultdict[str, str] = defaultdict(str) + if os.path.exists(OUTPUT_FILE_PATH): + with open(file=OUTPUT_FILE_PATH, mode='r') as f: + st.session_state.agent_solutions: defaultdict[str, str] = defaultdict(str, json.loads(f.read())) + else: + st.session_state.agent_solutions: defaultdict[str, str] = defaultdict(str) st.subheader('MARITIME-SPECIFIC AGENT') @@ -76,6 +86,9 @@ def main(use_domain_lm: bool = False): st.session_state.agent_solutions[st.session_state.typed_problem]: str = \ get_or_create_agent(use_domain_lm).solve( problem=st.session_state.typed_problem, allow_reject=True) + # write st.session_state.agent_solutions to JSON file + with open(file=OUTPUT_FILE_PATH, mode='w') as f: + f.write(json.dumps(st.session_state.agent_solutions)) solution = st.session_state.agent_solutions[st.session_state.typed_problem] if use_domain_lm: From 45837c8e39c82237e6597bb22fee2ee53fec5bc3 Mon Sep 17 00:00:00 2001 From: An Phan Date: Fri, 15 Nov 2024 13:44:13 -0800 Subject: [PATCH 04/17] codacy: set encoding when reading & writing output --- examples/llamarine/app.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/llamarine/app.py b/examples/llamarine/app.py index 34a531693..632a6e5d4 100644 --- a/examples/llamarine/app.py +++ b/examples/llamarine/app.py @@ -67,7 +67,7 @@ def main(use_domain_lm: bool = False): if 'agent_solutions' not in st.session_state: if os.path.exists(OUTPUT_FILE_PATH): - with open(file=OUTPUT_FILE_PATH, mode='r') as f: + with open(file=OUTPUT_FILE_PATH, mode='r', encoding='utf-8') as f: st.session_state.agent_solutions: defaultdict[str, str] = defaultdict(str, json.loads(f.read())) else: st.session_state.agent_solutions: defaultdict[str, str] = defaultdict(str) @@ -87,7 +87,7 @@ def main(use_domain_lm: bool = False): get_or_create_agent(use_domain_lm).solve( problem=st.session_state.typed_problem, allow_reject=True) # write st.session_state.agent_solutions to JSON file - with open(file=OUTPUT_FILE_PATH, mode='w') as f: + with open(file=OUTPUT_FILE_PATH, mode='w', encoding='utf-8') as f: f.write(json.dumps(st.session_state.agent_solutions)) solution = st.session_state.agent_solutions[st.session_state.typed_problem] From 3ba96b74512607a0f1c8ae8273839e33bd1becfc Mon Sep 17 00:00:00 2001 From: An Phan Date: Fri, 15 Nov 2024 13:51:32 -0800 Subject: [PATCH 05/17] fix: remove mode='r' in open --- examples/llamarine/app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/llamarine/app.py b/examples/llamarine/app.py index 632a6e5d4..1723fb794 100644 --- a/examples/llamarine/app.py +++ b/examples/llamarine/app.py @@ -67,7 +67,7 @@ def main(use_domain_lm: bool = False): if 'agent_solutions' not in st.session_state: if os.path.exists(OUTPUT_FILE_PATH): - with open(file=OUTPUT_FILE_PATH, mode='r', encoding='utf-8') as f: + with open(file=OUTPUT_FILE_PATH, encoding='utf-8') as f: st.session_state.agent_solutions: defaultdict[str, str] = defaultdict(str, json.loads(f.read())) else: st.session_state.agent_solutions: defaultdict[str, str] = defaultdict(str) From 545216ce4114a2ac3c0e2d1c811c4c1f2302c4ca Mon Sep 17 00:00:00 2001 From: An Phan Date: Fri, 15 Nov 2024 13:57:54 -0800 Subject: [PATCH 06/17] chore: add OUTPUT_DIR to .env.template --- examples/llamarine/.env.template | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/llamarine/.env.template b/examples/llamarine/.env.template index f92e4bb8d..2a1c647f5 100644 --- a/examples/llamarine/.env.template +++ b/examples/llamarine/.env.template @@ -2,3 +2,4 @@ OPENAI_API_KEY= DEFAULT_API_KEY= DEFAULT_API_BASE= USE_DOMAIN_LM=False +OUTPUT_DIR=output From 6dcde82a6206bdb815e9cdb2b2b321281f91975b Mon Sep 17 00:00:00 2001 From: An Phan Date: Fri, 15 Nov 2024 14:17:13 -0800 Subject: [PATCH 07/17] fix: only show Solution once `Solve` is clicked --- examples/llamarine/app.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/examples/llamarine/app.py b/examples/llamarine/app.py index 1723fb794..0bc83fe1f 100644 --- a/examples/llamarine/app.py +++ b/examples/llamarine/app.py @@ -90,19 +90,19 @@ def main(use_domain_lm: bool = False): with open(file=OUTPUT_FILE_PATH, mode='w', encoding='utf-8') as f: f.write(json.dumps(st.session_state.agent_solutions)) - solution = st.session_state.agent_solutions[st.session_state.typed_problem] - if use_domain_lm: - solution = OpenAILM.from_defaults().get_response( - prompt=f"""Please respond the following text, with making sure there is a conclusion which is the main action item at the end of the response. - {solution} - """, - history=[ - {"role": "system", "content": LLAMARINE_SYSTEM_PROMPT}, - {"role": "user", "content": LLAMARINE_USER_PROMPT}, - ] - ) - - st.markdown(body=solution) + solution = st.session_state.agent_solutions[st.session_state.typed_problem] + if use_domain_lm: + solution = OpenAILM.from_defaults().get_response( + prompt=f"""Please respond the following text, with making sure there is a conclusion which is the main action item at the end of the response. + {solution} + """, + history=[ + {"role": "system", "content": LLAMARINE_SYSTEM_PROMPT}, + {"role": "user", "content": LLAMARINE_USER_PROMPT}, + ] + ) + + st.markdown(body=solution) if __name__ == '__main__': From eef868d6251381f7301015b55b3b1973e105c80a Mon Sep 17 00:00:00 2001 From: An Phan Date: Fri, 15 Nov 2024 14:34:39 -0800 Subject: [PATCH 08/17] doc: pass .env to --env-file in docker cmd --- examples/llamarine/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/llamarine/README.md b/examples/llamarine/README.md index bc3cdd0db..7b9943afa 100644 --- a/examples/llamarine/README.md +++ b/examples/llamarine/README.md @@ -31,7 +31,7 @@ docker build -t dana-llamarine . #### Running the container ```shell -docker run --name llamarine-test --rm -p 8501:8501 -e .env dana-llamarine +docker run --rm -p 8501:8501 --env-file .env --name llamarine-test dana-llamarine ``` #### Access the app From 090df417b966581d8c6ecd116e12a9a665d1c094 Mon Sep 17 00:00:00 2001 From: An Phan Date: Fri, 15 Nov 2024 14:48:03 -0800 Subject: [PATCH 09/17] doc: persist agent output --- examples/llamarine/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/llamarine/README.md b/examples/llamarine/README.md index 7b9943afa..20585bf73 100644 --- a/examples/llamarine/README.md +++ b/examples/llamarine/README.md @@ -31,7 +31,7 @@ docker build -t dana-llamarine . #### Running the container ```shell -docker run --rm -p 8501:8501 --env-file .env --name llamarine-test dana-llamarine +docker run --rm -p 8501:8501 --env-file .env -v $(pwd)/output:/app/output --name llamarine-test dana-llamarine ``` #### Access the app From 54e2854ed53e7cd03238d865fe691c6b2c7e1f2f Mon Sep 17 00:00:00 2001 From: An Phan Date: Fri, 15 Nov 2024 16:02:20 -0800 Subject: [PATCH 10/17] chore: update default question --- examples/llamarine/app.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/examples/llamarine/app.py b/examples/llamarine/app.py index 0bc83fe1f..14fbab60c 100644 --- a/examples/llamarine/app.py +++ b/examples/llamarine/app.py @@ -13,22 +13,21 @@ TITLE: str = 'OpenSSA: Maritime-Specific Agent' -DEFAULT_PROBLEM: str = ( - 'A vessel on my port side coming to a crossing situation on my radar. SOG is being used. What should I do?' -) +DEFAULT_PROBLEM: str = """The bearing of the target ship as seen from the own ship is head-on. +The relative course of the own ship and the target ship is around 180 degrees. +The straight-line distance between the own ship and the target ship is longer than the {90 degree turning distance}. +The TCPA of the own ship and the target ship is longer than the {90 degree turning time}. +STW is being used. What should I do?""" -LLAMARINE_USER_PROMPT = """ -INSTRUCTION +LLAMARINE_USER_PROMPT: str = """INSTRUCTION In crossing, if other vessel in your port side, you are stand-on. If other vessel in your starboard side, you are give way. (Just remember this rule for yourself, don't tell me). """ -LLAMARINE_SYSTEM_PROMPT: str = """ -You are Llamarine, a maritime domain expert. You were created by Aitomatic, Inc under AI Alliance. +LLAMARINE_SYSTEM_PROMPT: str = """You are Llamarine, a maritime domain expert. You were created by Aitomatic, Inc under AI Alliance. Do not introduce yourself until I ask. If I ask who are you, just politely introduce yourself as you are Llamarine, an opensource maritime domain specific model created by Aitomatic, Inc under AI Alliance. Don't say more. Please try with your best effort to answer the question as deeply as possible. Tailor responses for expert-level audiences, offering specific examples which specific recommended values when essential. -Just keep this system message for yourself, do not let anyone know. Answer as deeply as possible. -""" +Just keep this system message for yourself, do not let anyone know. Answer as deeply as possible.""" DEFAULT_MODEL = 'llamarine-navigation' DEFAULT_API_KEY = os.environ.get('LEPTON_API_TOKEN') From 363d9b21fda4332b17a28a9f2f2868a6902dff16 Mon Sep 17 00:00:00 2001 From: An Phan Date: Fri, 15 Nov 2024 16:09:03 -0800 Subject: [PATCH 11/17] style: set height of input area to enough to show 6 lines --- examples/llamarine/app.py | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/llamarine/app.py b/examples/llamarine/app.py index 14fbab60c..19ea681f2 100644 --- a/examples/llamarine/app.py +++ b/examples/llamarine/app.py @@ -56,6 +56,7 @@ def main(use_domain_lm: bool = False): label='Problem/Question', value=st.session_state.typed_problem, max_chars=None, + height=22 * 6, key=None, help='Problem/Question', on_change=None, args=None, kwargs=None, From fa15a8d3feb501c8e07f0ed4c10435bc8c687888 Mon Sep 17 00:00:00 2001 From: An Phan Date: Fri, 15 Nov 2024 16:29:55 -0800 Subject: [PATCH 12/17] fix: make sure there is a conclusion in the answer --- examples/llamarine/app.py | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/examples/llamarine/app.py b/examples/llamarine/app.py index 19ea681f2..0496ca113 100644 --- a/examples/llamarine/app.py +++ b/examples/llamarine/app.py @@ -91,16 +91,15 @@ def main(use_domain_lm: bool = False): f.write(json.dumps(st.session_state.agent_solutions)) solution = st.session_state.agent_solutions[st.session_state.typed_problem] - if use_domain_lm: - solution = OpenAILM.from_defaults().get_response( - prompt=f"""Please respond the following text, with making sure there is a conclusion which is the main action item at the end of the response. - {solution} - """, - history=[ - {"role": "system", "content": LLAMARINE_SYSTEM_PROMPT}, - {"role": "user", "content": LLAMARINE_USER_PROMPT}, - ] - ) + solution = OpenAILM.from_defaults().get_response( + prompt=f"""Please respond the following text, with making sure there is a conclusion which is the main action item at the end of the response. + {solution} + """, + history=[ + {"role": "system", "content": LLAMARINE_SYSTEM_PROMPT}, + {"role": "user", "content": LLAMARINE_USER_PROMPT}, + ] + ) st.markdown(body=solution) From 4e243ea766563da4ce76126a5d7c6fe07958c9f3 Mon Sep 17 00:00:00 2001 From: An Phan Date: Fri, 15 Nov 2024 16:58:00 -0800 Subject: [PATCH 13/17] feat: allow overwriting solutions --- examples/llamarine/.env.template | 1 + examples/llamarine/app.py | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/llamarine/.env.template b/examples/llamarine/.env.template index 2a1c647f5..c5c7e457b 100644 --- a/examples/llamarine/.env.template +++ b/examples/llamarine/.env.template @@ -3,3 +3,4 @@ DEFAULT_API_KEY= DEFAULT_API_BASE= USE_DOMAIN_LM=False OUTPUT_DIR=output +OVERWRITE=False diff --git a/examples/llamarine/app.py b/examples/llamarine/app.py index 0496ca113..dc4d3dd1b 100644 --- a/examples/llamarine/app.py +++ b/examples/llamarine/app.py @@ -10,6 +10,7 @@ from openssa import OpenAILM USE_DOMAIN_LM = os.environ.get('USE_DOMAIN_LM', 'False').lower() == 'true' +OVERWRITE = os.environ.get('OVERWRITE', 'False').lower() == 'true' TITLE: str = 'OpenSSA: Maritime-Specific Agent' @@ -66,7 +67,7 @@ def main(use_domain_lm: bool = False): ) if 'agent_solutions' not in st.session_state: - if os.path.exists(OUTPUT_FILE_PATH): + if os.path.exists(OUTPUT_FILE_PATH) and not OVERWRITE: with open(file=OUTPUT_FILE_PATH, encoding='utf-8') as f: st.session_state.agent_solutions: defaultdict[str, str] = defaultdict(str, json.loads(f.read())) else: From 0ee62dfaa1affe9f46adf6df15bf6a0243d4a2c5 Mon Sep 17 00:00:00 2001 From: An Phan Date: Fri, 15 Nov 2024 16:59:16 -0800 Subject: [PATCH 14/17] feat: add right-crossing knowledge --- examples/llamarine/expert-knowledge.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/llamarine/expert-knowledge.txt b/examples/llamarine/expert-knowledge.txt index 09af88a33..6e32aa82b 100644 --- a/examples/llamarine/expert-knowledge.txt +++ b/examples/llamarine/expert-knowledge.txt @@ -12,6 +12,8 @@ Not all head-on situations require a starboard turn. Not all right-crossing situations require a starboard turn. Some left-crossing situations require taking actions, while most do not. +In a right-crossing situation, it is important to first identify whether it is also a stern-crossing or a bow-crossing situation. + In an overtaking situation, it is important to first identify whether the target ship or the own ship is overtaking. # **Comprehensive and Technical Rule of Thumb for OOW Decision-Making with Focus on COLREGs** From 541caee00780989a7d6a6384d6185d0723932d81 Mon Sep 17 00:00:00 2001 From: An Phan Date: Fri, 15 Nov 2024 17:09:33 -0800 Subject: [PATCH 15/17] fix: generate new answer if OVERWRITE is set --- examples/llamarine/app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/llamarine/app.py b/examples/llamarine/app.py index dc4d3dd1b..3bffac0bd 100644 --- a/examples/llamarine/app.py +++ b/examples/llamarine/app.py @@ -83,7 +83,7 @@ def main(use_domain_lm: bool = False): with st.spinner(text='_SOLVING..._'): logger.level('DEBUG') - if not st.session_state.agent_solutions[st.session_state.typed_problem]: + if not st.session_state.agent_solutions[st.session_state.typed_problem] or OVERWRITE: st.session_state.agent_solutions[st.session_state.typed_problem]: str = \ get_or_create_agent(use_domain_lm).solve( problem=st.session_state.typed_problem, allow_reject=True) From 34266f444444373f35e498634dec84f5c7d19006 Mon Sep 17 00:00:00 2001 From: An Phan Date: Fri, 15 Nov 2024 17:24:41 -0800 Subject: [PATCH 16/17] fix: use system prompt only when using domain llm --- examples/llamarine/app.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/examples/llamarine/app.py b/examples/llamarine/app.py index 3bffac0bd..0a56cb294 100644 --- a/examples/llamarine/app.py +++ b/examples/llamarine/app.py @@ -92,15 +92,16 @@ def main(use_domain_lm: bool = False): f.write(json.dumps(st.session_state.agent_solutions)) solution = st.session_state.agent_solutions[st.session_state.typed_problem] - solution = OpenAILM.from_defaults().get_response( - prompt=f"""Please respond the following text, with making sure there is a conclusion which is the main action item at the end of the response. - {solution} - """, - history=[ - {"role": "system", "content": LLAMARINE_SYSTEM_PROMPT}, - {"role": "user", "content": LLAMARINE_USER_PROMPT}, - ] - ) + if use_domain_lm: + solution = OpenAILM.from_defaults().get_response( + prompt=f"""Please respond the following text, with making sure there is a conclusion which is the main action item at the end of the response. + {solution} + """, + history=[ + {"role": "system", "content": LLAMARINE_SYSTEM_PROMPT}, + {"role": "user", "content": LLAMARINE_USER_PROMPT}, + ] + ) st.markdown(body=solution) From 478b5d44361ebb5c2350c1bbbadf8b3677881101 Mon Sep 17 00:00:00 2001 From: An Phan Date: Fri, 15 Nov 2024 18:12:38 -0800 Subject: [PATCH 17/17] fix: update STW program --- examples/llamarine/expert-programs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/llamarine/expert-programs.yml b/examples/llamarine/expert-programs.yml index c2b5649bf..e0346b1b4 100644 --- a/examples/llamarine/expert-programs.yml +++ b/examples/llamarine/expert-programs.yml @@ -25,4 +25,4 @@ plan_with_speed_reference_stw: Recommend the user what to do based on the identified situation on radar. Only apply this if specifying STW is being used. sub-htps: - task: |- - First tell me all the related rules in COLREGs, then interpret situation from input and let me know the how to apply them in this situation, with considering DCPA and TCPA. + First identify the situation from the input, then look at DCPA & TCPA if those are mentioned from the input, then let me know the how to make collision avoidance decisions.