mirror of
https://github.com/hackertron/LucidLoanMachine.git
synced 2026-01-09 04:28:03 -05:00
TLSN proof agent (#7)
* plugin prompts * init : make separate agent for plugin. * init plugin description agent * prompt to check the tlsn proof that user will upload, need to work on the actual skill to accomplish that
This commit is contained in:
86
plugin_agent/plugin_agent_gen.py
Normal file
86
plugin_agent/plugin_agent_gen.py
Normal file
@@ -0,0 +1,86 @@
|
||||
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()
|
||||
233
plugin_agent/plugin_prompts.py
Normal file
233
plugin_agent/plugin_prompts.py
Normal file
@@ -0,0 +1,233 @@
|
||||
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}
|
||||
"""
|
||||
@@ -13,14 +13,22 @@ 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
|
||||
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
|
||||
h11==0.14.0
|
||||
httpcore==1.0.5
|
||||
httpx==0.27.0
|
||||
@@ -48,6 +56,7 @@ 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
|
||||
@@ -63,6 +72,7 @@ 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
|
||||
@@ -77,6 +87,7 @@ 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
|
||||
@@ -94,6 +105,8 @@ 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
|
||||
@@ -106,5 +119,6 @@ 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
|
||||
|
||||
@@ -21,4 +21,12 @@ account number, bank balance.
|
||||
Ensure the details match with the bank.json file.
|
||||
Add additional keys to the bank.json file and save it.
|
||||
If there are any errors in processing the PDF, inform the user and ask for a different PDF.
|
||||
"""
|
||||
|
||||
verify_tlsn_proof_prompt = """
|
||||
Ask user to paste the tlsn proof in the terminal and you will save that proof in a file called tlsn_proof.json. it will be a json file.
|
||||
Remember the json contents and you will use verify_tlsn_proof skill to upload the proof to explorer.tlsn.org. Once we get the confirmation
|
||||
that the proof is valid and it contains the correct details that user have provided we can proceed to give out loans. The information we are
|
||||
looking for are name and country. If possible account number too but name and country is enough of a proof.
|
||||
Once we get the proof we can give out loans.
|
||||
"""
|
||||
0
verify_tlsn_proof.py
Normal file
0
verify_tlsn_proof.py
Normal file
Reference in New Issue
Block a user