11import os
2+ from typing import Optional , Union
3+ from pathlib import Path
24
35import openai
46from openai .api_resources .engine import Engine
810from binaryninja .mediumlevelil import MediumLevelILFunction
911from binaryninja .highlevelil import HighLevelILFunction
1012
11- from typing import Optional
12-
1313from .exceptions import InvalidEngineException
1414
1515
@@ -20,25 +20,20 @@ class Agent:
2020 It is in Binary Ninja's IL_FORM. What does this function do?
2121 '''
2222
23- # The maximum number of tokens that can be submitted to the engine.
24- # See: https://beta.openai.com/docs/models/codex
25- codex_limits : dict [str , int ] = {
26- 'code-davinci-002' : 8_000 ,
27- 'code-cushman-001' : 2_048
28- }
29-
3023 # A mapping of IL forms to their names.
3124 il_name : dict [type , str ] = {
3225 LowLevelILFunction : 'Low Level Intermediate Language' ,
3326 MediumLevelILFunction : 'Medium Level Intermediate Language' ,
3427 HighLevelILFunction : 'High Level Intermediate Language'
3528 }
3629
37- def __init__ (self , function : LowLevelILFunction | MediumLevelILFunction |
38- HighLevelILFunction , engine : str ) -> None :
30+ def __init__ (self ,
31+ function : Union [LowLevelILFunction , MediumLevelILFunction , HighLevelILFunction ],
32+ engine : str ,
33+ path_to_api_key : Optional [Path ]= None ) -> None :
3934
4035 # Read the API key from the environment variable.
41- openai .api_key = self .read_api_key ('/Users/sean/.openai/api_key' )
36+ openai .api_key = self .read_api_key (path_to_api_key )
4237
4338 # Ensure that a function type was passed in.
4439 if not isinstance (
@@ -59,20 +54,20 @@ def __init__(self, function: LowLevelILFunction | MediumLevelILFunction |
5954 self .function = function
6055 self .engine = engine
6156
62- def read_api_key (self , filename : Optional [str ]= None ) -> str :
57+ def read_api_key (self , filename : Optional [Path ]= None ) -> str :
6358 if os .getenv ('OPENAI_API_KEY' ):
6459 return os .getenv ('OPENAI_API_KEY' )
65- elif filename :
66- with open (filename , 'r ' ) as api_key_file :
60+ if filename :
61+ with open (filename , mode = 'r' , encoding = 'ascii ' ) as api_key_file :
6762 return api_key_file .read ()
6863 else :
6964 raise APIError ('No API key found. Please set the environment '
7065 'variable OPENAI_API_KEY to your API key.' )
7166
7267
73- def instruction_list (self , function : LowLevelILFunction |
74- MediumLevelILFunction |
75- HighLevelILFunction ) -> list [str ]:
68+ def instruction_list (self , function : Union [ LowLevelILFunction ,
69+ MediumLevelILFunction ,
70+ HighLevelILFunction ] ) -> list [str ]:
7671 '''Generates a list of instructions in string representation given a
7772 BNIL function.
7873 '''
@@ -81,9 +76,9 @@ def instruction_list(self, function: LowLevelILFunction |
8176 instructions .append (str (instruction ))
8277 return instructions
8378
84- def generate_query (self , function : LowLevelILFunction |
85- MediumLevelILFunction |
86- HighLevelILFunction ) -> str :
79+ def generate_query (self , function : Union [ LowLevelILFunction ,
80+ MediumLevelILFunction ,
81+ HighLevelILFunction ] ) -> str :
8782 '''Generates a query string given a BNIL function. Reads the file
8883 prompt.txt and replaces the IL form with the name of the IL form.
8984 '''
@@ -95,3 +90,13 @@ def generate_query(self, function: LowLevelILFunction |
9590 # Add the instructions to the prompt.
9691 prompt += '\n ' .join (self .instruction_list (function ))
9792 return prompt
93+
94+ def send_query (self , query : str ) -> str :
95+ '''Sends a query to the engine and returns the response.'''
96+ response : str = openai .Completion .create (
97+ model = self .engine ,
98+ prompt = query ,
99+ max_tokens = 2_048
100+ )
101+ return response .choices [0 ].text
102+
0 commit comments