88from binaryninja .mediumlevelil import MediumLevelILFunction
99from binaryninja .highlevelil import HighLevelILFunction
1010
11+ from typing import Optional
12+
1113from .exceptions import InvalidEngineException
1214
1315
1416class Agent :
1517
16- def ___init__ (self , function : LowLevelILFunction | MediumLevelILFunction |
18+ # The maximum number of tokens that can be submitted to the engine.
19+ # See: https://beta.openai.com/docs/models/codex
20+ codex_limits : dict [str , int ] = {
21+ 'code-davinci-002' : 8_000 ,
22+ 'code-cushman-001' : 2_048
23+ }
24+
25+ # A mapping of IL forms to their names.
26+ il_name : dict [type , str ] = {
27+ LowLevelILFunction : 'Low Level Intermediate Language' ,
28+ MediumLevelILFunction : 'Medium Level Intermediate Language' ,
29+ HighLevelILFunction : 'High Level Intermediate Language'
30+ }
31+
32+ def __init__ (self , function : LowLevelILFunction | MediumLevelILFunction |
1733 HighLevelILFunction , engine : str ) -> None :
1834
1935 # Read the API key from the environment variable.
20- openai .api_key = os .getenv ('OPENAI_API_KEY' )
21- if openai .api_key is None :
22- raise APIError ('No API key found. Please set the environment '
23- 'variable OPENAI_API_KEY to your API key.' )
36+ openai .api_key = self .read_api_key ('/Users/sean/.openai/api_key' )
2437
2538 # Ensure that a function type was passed in.
2639 if not isinstance (
@@ -41,6 +54,17 @@ def ___init__(self, function: LowLevelILFunction | MediumLevelILFunction |
4154 self .function = function
4255 self .engine = engine
4356
57+ def read_api_key (self , filename : Optional [str ]= None ) -> str :
58+ if os .getenv ('OPENAI_API_KEY' ):
59+ return os .getenv ('OPENAI_API_KEY' )
60+ elif filename :
61+ with open (filename , 'r' ) as api_key_file :
62+ return api_key_file .read ()
63+ else :
64+ raise APIError ('No API key found. Please set the environment '
65+ 'variable OPENAI_API_KEY to your API key.' )
66+
67+
4468 def instruction_list (self , function : LowLevelILFunction |
4569 MediumLevelILFunction |
4670 HighLevelILFunction ) -> list [str ]:
@@ -51,3 +75,20 @@ def instruction_list(self, function: LowLevelILFunction |
5175 for instruction in function .instructions :
5276 instructions .append (str (instruction ))
5377 return instructions
78+
79+ def generate_query (self , function : LowLevelILFunction |
80+ MediumLevelILFunction |
81+ HighLevelILFunction ) -> str :
82+ '''Generates a query string given a BNIL function. Reads the file
83+ prompt.txt and replaces the IL form with the name of the IL form.
84+ '''
85+ prompt : str = ''
86+ # Read the prompt from the text file.
87+ with open ('prompt.txt' , 'r' ) as prompt_file :
88+ prompt = prompt_file .read ()
89+ prompt .replace ('\{IL FORM\}' , self .il_name [type (function )])
90+ # Add some new lines. Maybe not necessary.
91+ prompt += '\n \n '
92+ # Add the instructions to the prompt.
93+ prompt += '\n ' .join (self .instruction_list (function ))
94+ return prompt
0 commit comments