diff --git a/dkim_skill.py b/dkim_skill.py deleted file mode 100644 index 86f78d7..0000000 --- a/dkim_skill.py +++ /dev/null @@ -1,32 +0,0 @@ -import dkim -import email -import sys - -def verify_dkim_signature(email_file): - try: - # Open and read the email file - with open(email_file, 'rb') as f: - raw_email = f.read() - - # Parse the email - parsed_email = email.message_from_bytes(raw_email) - - # Extract the headers and body - headers = parsed_email.as_bytes().split(b'\r\n\r\n', 1)[0] - body = parsed_email.get_payload(decode=True) - - # Verify DKIM signature - if dkim.verify(raw_email): - print("DKIM signature is valid.") - else: - print("DKIM signature is invalid.") - except Exception as e: - print(f"An error occurred: {e}") - -if __name__ == "__main__": - if len(sys.argv) != 2: - print("Usage: python verify_dkim.py ") - sys.exit(1) - - email_file = sys.argv[1] - verify_dkim_signature(email_file) diff --git a/main.py b/main.py index 97d294d..f4820b9 100644 --- a/main.py +++ b/main.py @@ -1,26 +1,15 @@ -import autogen -import os -import json -from dotenv import load_dotenv +from autogen import AssistantAgent, UserProxyAgent, config_list_from_json from typing import Annotated import requests -from system_prompts import front_desk_assistant_prompt, email_assistant_prompt, salary_slip_assistant_prompt -from extract_pdf_skill import process_pdf_from_url +from system_prompts import front_desk_assistant_prompt, email_assistant_prompt, verify_tlsn_proof_prompt + -load_dotenv() # take environment variables from .env. -config_list = [ - { - 'model': 'gpt-3.5-turbo', - 'api_key': os.getenv('OPENAI_API_KEY'), - } -] llm_config = { "timeout": 120, "seed": 42, # for caching. once task is run it caches the response, - "config_list": config_list, - "temperature": 0 #lower temperature more standard lesss creative response, higher is more creative - + "config_list": config_list_from_json(env_or_file="OAI_CONFIG_LIST.json"), + "temperature": 0 } def verify_email_with_prove_api(domain :Annotated[str, "The domain name to verify"]) -> Annotated[dict, "The response from the Prove Email API"] | None: @@ -29,34 +18,31 @@ def verify_email_with_prove_api(domain :Annotated[str, "The domain name to verif print("response : ", response) return response.json() if response.status_code == 200 else None - -front_desk_assistant = autogen.AssistantAgent( +front_desk_assistant = AssistantAgent( name="front_desk_assistant", llm_config=llm_config, system_message=front_desk_assistant_prompt, ) -email_assistant = autogen.AssistantAgent( +email_assistant = AssistantAgent( name="email_assistant", llm_config=llm_config, system_message=email_assistant_prompt ) - - -salary_slip_assistant = autogen.AssistantAgent( - name="salary_slip_assistant", +verify_tlsn_proof_assistant = AssistantAgent( + name="verify_tlsn_proof_assistant", llm_config=llm_config, - system_message=salary_slip_assistant_prompt + system_message=verify_tlsn_proof_prompt ) -# assistant = autogen.AssistantAgent( -# name="laon_assistant", +# salary_slip_assistant = AssistantAgent( +# name="salary_slip_assistant", # llm_config=llm_config, -# system_message="checks the bank documents. extract pdf using extract_pdf_skill.", +# system_message=salary_slip_assistant_prompt # ) -user_proxy = autogen.UserProxyAgent( +user_proxy = UserProxyAgent( name="user_proxy", human_input_mode="ALWAYS", max_consecutive_auto_reply=3, @@ -72,18 +58,19 @@ user_proxy = autogen.UserProxyAgent( ) + user_proxy.register_for_llm(name="verify_email_with_prove_api", description="verify email's dkim using prove api verify_email_with_prove_api")(verify_email_with_prove_api) user_proxy.register_for_execution(name="verify_email_with_prove_api")(verify_email_with_prove_api) -user_proxy.register_for_llm(name="process_pdf_from_url", description="process pdf from url using extract_pdf_skill")(process_pdf_from_url) -user_proxy.register_for_execution(name="process_pdf_from_url")(process_pdf_from_url) +#user_proxy.register_for_llm(name="process_pdf_from_url", description="process pdf from url using extract_pdf_skill")(process_pdf_from_url) +#user_proxy.register_for_execution(name="process_pdf_from_url")(process_pdf_from_url) def main(): # Register the verify_email_with_prove_api function for the email_assistant email_assistant.register_function( function_map={ "verify_email_with_prove_api": verify_email_with_prove_api, - "process_pdf_from_url": process_pdf_from_url + #"process_pdf_from_url": process_pdf_from_url } ) chat_results = user_proxy.initiate_chats([ @@ -100,8 +87,8 @@ def main(): "summary_method": "reflection_with_llm" }, { - "recipient": salary_slip_assistant, - "message": "guide user to upload a salary slip in pdf format and call process_pdf_from_url function to verify the pdf", + "recipient": verify_tlsn_proof_assistant, + "message": "guide user to provide the tlsn proof", "silent": False, "summary_method": "reflection_with_llm" } diff --git a/plugin_agent/plugin_agent_gen.py b/plugin_agent/plugin_agent_gen.py deleted file mode 100644 index 35e46f2..0000000 --- a/plugin_agent/plugin_agent_gen.py +++ /dev/null @@ -1,86 +0,0 @@ -import autogen -import os -import json -from dotenv import load_dotenv -from typing import Annotated -import requests -from plugin_prompts import bank_plugin_prompts - - -load_dotenv() # take environment variables from .env. -config_list = [ - { - 'model': 'gpt-3.5-turbo', - 'api_key': os.getenv('OPENAI_API_KEY'), - } -] - -llm_config = { - "timeout": 120, - "seed": 42, # for caching. once task is run it caches the response, - "config_list": config_list, - "temperature": 0 #lower temperature more standard lesss creative response, higher is more creative - -} - -def write_plugin(website_url:Annotated[str, "website url"], plugin_name:Annotated[str, "plugin name"]) -> Annotated[dict, "The response from the plugin"] | None: - api_url = f"https://archive.prove.email/api/key?domain={domain}" - response = requests.get(api_url) - print("response : ", response) - return response.json() if response.status_code == 200 else None - - -plugin_agent = autogen.AssistantAgent( - name="plugin_agent", - llm_config=llm_config, - system_message="""you will write TLSN plugin for the website that the user will provide. - You will ask the user to provide the website url, - API and some web request and response of it and plugin name. - Once you receive the url, use the write_plugin function to write the plugin. - The function will return the response from the plugin. - Analyze the response to gather the following information from the plugin: plugin name, plugin description, plugin author, plugin version, website url. - """, -) - -user_proxy = autogen.UserProxyAgent( - name="user_proxy", - human_input_mode="ALWAYS", - max_consecutive_auto_reply=3, - is_termination_msg=lambda x: x.get("content", "").rstrip().endswith("TERMINATE"), - code_execution_config={ - "last_n_messages": 3, - "work_dir": "code", - "use_docker": False, - }, - llm_config=llm_config, - system_message="""Reply TERMINATE if the task has been solved at full satisfaction - otherwise, reply CONTINUE, or the reason why the task is not solved yet.""" -) - - -user_proxy.register_for_llm(name="write_plugin", description="write TLSN extension plugin for website that user will provide")(write_plugin) -user_proxy.register_for_execution(name="write_plugin")(write_plugin) - -def main(): - # Register the verify_email_with_prove_api function for the email_assistant - plugin_agent.register_function( - function_map={ - "write_plugin": write_plugin, - } - ) - chat_results = user_proxy.initiate_chats([ - { - "recipient": plugin_agent, - "message": "I want to write a TLSN extension plugin for the website that I will provide, please help me", - "silent": False, - "summary_method": "reflection_with_llm" - } - ]) - for i, chat_res in enumerate(chat_results): - print(f"*****{i}th chat*******:") - print(chat_res.summary) - print("Human input in the middle:", chat_res.human_input) - print("Conversation cost: ", chat_res.cost) - print("\n\n") -if __name__ == "__main__": - main() \ No newline at end of file diff --git a/plugin_agent/plugin_prompts.py b/plugin_agent/plugin_prompts.py deleted file mode 100644 index 54baecf..0000000 --- a/plugin_agent/plugin_prompts.py +++ /dev/null @@ -1,233 +0,0 @@ -bank_plugin_prompts = """ -your task is to build tlsn browser extension plugins for the website. I can give you sample code below, that you can refer -to make such plugins. I will give you a task description and you have to build the plugin to do the task. - -You will ask users to give the website url, API link / route, auth method. -Here is the task description: -Ask users to provide the website url, API link. Make sure to ask user if TLSN extension is installed. If not, ask them to install it. - -Ask users to provide the auth method. Make sure to ask user if TLSN extension is installed. If not, ask them to install it. - -Ask users to provide the API link. Make sure to ask user if TLSN extension is installed. If not, ask them to install it. - -Here is the sample code below for twitter profile notarization example -import icon from '../assets/icon.png'; -import config_json from '../config.json'; -import { redirect, notarize, outputJSON, getCookiesByHost, getHeadersByHost } from './utils/hf.js'; - -/** - * Plugin configuration - * This configurations defines the plugin, most importantly: - * * the different steps - * * the user data (headers, cookies) it will access - * * the web requests it will query (or notarize) - */ -export function config() { - outputJSON({ - ...config_json, - icon: icon - }); -} - -function isValidHost(urlString: string) { - const url = new URL(urlString); - return url.hostname === 'twitter.com' || url.hostname === 'x.com'; -} - -/** - * Implementation of the first (start) plugin step - */ -export function start() { - if (!isValidHost(Config.get('tabUrl'))) { - redirect('https://x.com'); - outputJSON(false); - return; - } - outputJSON(true); -} - -/** - * Implementation of step "two". - * This step collects and validates authentication cookies and headers for 'api.x.com'. - * If all required information, it creates the request object. - * Note that the url needs to be specified in the `config` too, otherwise the request will be refused. - */ -export function two() { - const cookies = getCookiesByHost('api.x.com'); - const headers = getHeadersByHost('api.x.com'); - - if ( - !cookies.auth_token || - !cookies.ct0 || - !headers['x-csrf-token'] || - !headers['authorization'] - ) { - outputJSON(false); - return; - } - - outputJSON({ - url: 'https://api.x.com/1.1/account/settings.json', - method: 'GET', - headers: { - 'x-twitter-client-language': 'en', - 'x-csrf-token': headers['x-csrf-token'], - Host: 'api.x.com', - authorization: headers.authorization, - Cookie: `lang=en; auth_token=${cookies.auth_token}; ct0=${cookies.ct0}`, - 'Accept-Encoding': 'identity', - Connection: 'close', - }, - secretHeaders: [ - `x-csrf-token: ${headers['x-csrf-token']}`, - `cookie: lang=en; auth_token=${cookies.auth_token}; ct0=${cookies.ct0}`, - `authorization: ${headers.authorization}`, - ], - }); -} - -/** - * This method is used to parse the Twitter response and specify what information is revealed (i.e. **not** redacted) - * This method is optional in the notarization request. When it is not specified nothing is redacted. - * - * In this example it locates the `screen_name` and excludes that range from the revealed response. - */ -export function parseTwitterResp() { - const bodyString = Host.inputString(); - const params = JSON.parse(bodyString); - - if (params.screen_name) { - const revealed = `"screen_name":"${params.screen_name}"`; - const selectionStart = bodyString.indexOf(revealed); - const selectionEnd = - selectionStart + revealed.length; - const secretResps = [ - bodyString.substring(0, selectionStart), - bodyString.substring(selectionEnd, bodyString.length), - ]; - outputJSON(secretResps); - } else { - outputJSON(false); - } -} - -/** - * Step 3: calls the `notarize` host function - */ -export function three() { - const params = JSON.parse(Host.inputString()); - - if (!params) { - outputJSON(false); - } else { - const id = notarize({ - ...params, - getSecretResponse: 'parseTwitterResp', - }); - outputJSON(id); - } -} - -Below is the sample config.json that above code uses: -{ - "title": "Twitter Profile", - "description": "Notarize ownership of a twitter profile", - "steps": [ - { - "title": "Visit Twitter website", - "cta": "Go to x.com", - "action": "start" - }, - { - "title": "Collect credentials", - "description": "Login to your account if you haven't already", - "cta": "Check cookies", - "action": "two" - }, - { - "title": "Notarize twitter profile", - "cta": "Notarize", - "action": "three", - "prover": true - } - ], - "hostFunctions": [ - "redirect", - "notarize" - ], - "cookies": [ - "api.x.com" - ], - "headers": [ - "api.x.com" - ], - "requests": [ - { - "url": "https://api.x.com/1.1/account/settings.json", - "method": "GET" - } - ] -} - -You need to make the config json for user's use case. You can use the sample config.json as a reference. - -below is the hf.js file that above code uses: -function redirect(url) { - const { redirect } = Host.getFunctions(); - const mem = Memory.fromString(url); - redirect(mem.offset); -} - -function notarize(options) { - const { notarize } = Host.getFunctions(); - const mem = Memory.fromString(JSON.stringify(options)); - const idOffset = notarize(mem.offset); - const id = Memory.find(idOffset).readString(); - return id; -} - -function outputJSON(json) { - Host.outputString( - JSON.stringify(json), - ); -} - -function getCookiesByHost(hostname) { - const cookies = JSON.parse(Config.get('cookies')); - if (!cookies[hostname]) throw new Error(`cannot find cookies for ${hostname}`); - return cookies[hostname]; -} - -function getHeadersByHost(hostname) { - const headers = JSON.parse(Config.get('headers')); - if (!headers[hostname]) throw new Error(`cannot find headers for ${hostname}`); - return headers[hostname]; -} - -module.exports = { - redirect, - notarize, - outputJSON, - getCookiesByHost, - getHeadersByHost, -}; - - -You have to build the plugin to do the task. You can use the sample code as a reference. - -You have to use the following format to build the plugin: - -Plugin Name: {plugin_name} // name will be asked by user -Plugin Description: {plugin_description} -Plugin Code: // you will generate plugin code based on the sample code above -{plugin_code} - -Remember to use the sample code as a reference and not copy and paste it directly. - -Your response should be in the following format: - -Plugin Name: {plugin_name} -Plugin Description: {plugin_description} -Plugin Code: -{plugin_code} -""" \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index b828bd1..dda7e65 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,124 +1,39 @@ -aiohttp==3.9.5 -aiosignal==1.3.1 -altair==5.3.0 +ag2==0.7.6 +aiofiles==24.1.0 annotated-types==0.7.0 -anyio==4.4.0 -attrs==23.2.0 -backoff==2.2.1 -beautifulsoup4==4.12.3 -blinker==1.8.2 -cachetools==5.3.3 -certifi==2024.6.2 -cffi==1.16.0 -chardet==5.2.0 -charset-normalizer==3.3.2 -click==8.1.7 -colorama==0.4.6 -cryptography==42.0.8 -dataclasses-json==0.6.7 -deepdiff==7.0.1 +anyio==4.8.0 +asyncer==0.0.8 +autogen-core==0.4.8 +certifi==2025.1.31 +charset-normalizer==3.4.1 +Deprecated==1.2.18 diskcache==5.6.3 distro==1.9.0 -dkimpy==1.1.8 -dnspython==2.6.1 docker==7.1.0 -emoji==2.12.1 -filetype==1.2.0 -FLAML==2.1.2 -frozenlist==1.4.1 -gitdb==4.0.11 -GitPython==3.1.43 -greenlet==3.0.3 +fast-depends==2.4.12 h11==0.14.0 -httpcore==1.0.5 -httpx==0.27.0 -idna==3.7 -Jinja2==3.1.4 -joblib==1.4.2 -jsonpatch==1.33 -jsonpath-python==1.0.6 -jsonpointer==3.0.0 -jsonschema==4.22.0 -jsonschema-specifications==2023.12.1 -langchain==0.2.4 -langchain-core==0.2.6 -langchain-text-splitters==0.2.1 -langdetect==1.0.9 -langsmith==0.1.77 -lxml==5.2.2 -markdown-it-py==3.0.0 -MarkupSafe==2.1.5 -marshmallow==3.21.3 -mdurl==0.1.2 -multidict==6.0.5 -mypy-extensions==1.0.0 -nest-asyncio==1.6.0 -nltk==3.8.1 -numpy==1.26.4 -ollama==0.2.1 -openai==1.35.7 -opencv-contrib-python==4.10.0.84 -opencv-python==4.10.0.84 -ordered-set==4.1.0 -orjson==3.10.5 -packaging==24.1 -pandas==2.2.2 -pdf2image==1.17.0 -pdfminer==20191125 -pdfminer.six==20231228 -phi==0.6.7 -phidata==2.4.20 -pillow==10.3.0 -pillow_heif==0.16.0 -protobuf==4.25.3 -pyarrow==16.1.0 -pyautogen==0.2.31 -pycparser==2.22 -pycryptodome==3.20.0 -pydantic==2.7.4 -pydantic-settings==2.3.3 -pydantic_core==2.18.4 -pydeck==0.9.1 -Pygments==2.18.0 -pypdf==4.2.0 -PyPDF2==3.0.1 -python-dateutil==2.9.0.post0 +httpcore==1.0.7 +httpx==0.28.1 +idna==3.10 +importlib_metadata==8.5.0 +jiter==0.8.2 +jsonref==1.1.0 +openai==1.65.3 +opentelemetry-api==1.30.0 +packaging==24.2 +pillow==11.1.0 +protobuf==5.29.3 +pyautogen==0.7.6 +pydantic==2.10.6 +pydantic_core==2.27.2 python-dotenv==1.0.1 -python-iso639==2024.4.27 -python-magic==0.4.27 -pytz==2024.1 -pywin32==306 -PyYAML==6.0.1 -rapidfuzz==3.9.3 -referencing==0.35.1 -regex==2024.5.15 +regex==2024.11.6 requests==2.32.3 -requests-toolbelt==1.0.0 -rich==13.7.1 -rpds-py==0.18.1 -shellingham==1.5.4 -six==1.16.0 -smmap==5.0.1 sniffio==1.3.1 -soupsieve==2.5 -SQLAlchemy==2.0.30 -streamlit==1.35.0 -tabulate==0.9.0 -tenacity==8.3.0 -termcolor==2.4.0 -tiktoken==0.7.0 -toml==0.10.2 -tomli==2.0.1 -toolz==0.12.1 -tornado==6.4.1 -tqdm==4.66.4 -typer==0.12.3 -typing-inspect==0.9.0 +termcolor==2.5.0 +tiktoken==0.9.0 +tqdm==4.67.1 typing_extensions==4.12.2 -tzdata==2024.1 -unstructured==0.14.6 -unstructured-client==0.23.3 -urllib3==2.2.1 -watchdog==4.0.1 -wrapt==1.16.0 -yarl==1.9.4 +urllib3==2.3.0 +wrapt==1.17.2 +zipp==3.21.0 diff --git a/system_prompts.py b/system_prompts.py index d594cf7..9399ede 100644 --- a/system_prompts.py +++ b/system_prompts.py @@ -7,7 +7,7 @@ front_desk_assistant_prompt = """You have a personality of monopoly banker. You that json response to a file called bank.json """ -email_assistant_prompt = """You will have access to bank.json from front_desk_assistant. +email_assistant_prompt = """You will have access to bank.json from front_desk_assistant. it's in code folder. You will guide user to paste their raw email. Assume user has desktop and not on their mobile phone. guide user to paste their raw email to you. Tell them to paste raw email in chunks, not the complete email in one go. You will then analyze the email and check if it's valid and details matches with bank.json."""