reverse-engineering-assistant 1.0.0__tar.gz → 1.0.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. reverse-engineering-assistant-1.0.3/PKG-INFO +191 -0
  2. reverse-engineering-assistant-1.0.3/README.md +170 -0
  3. {reverse-engineering-assistant-1.0.0 → reverse-engineering-assistant-1.0.3}/pyproject.toml +3 -1
  4. reverse-engineering-assistant-1.0.3/reverse_engineering_assistant/api_server_tools/llm_tools.py +67 -0
  5. reverse-engineering-assistant-1.0.3/reverse_engineering_assistant/api_server_tools/re_tools.py +311 -0
  6. {reverse-engineering-assistant-1.0.0 → reverse-engineering-assistant-1.0.3}/reverse_engineering_assistant/assistant.py +74 -63
  7. {reverse-engineering-assistant-1.0.0 → reverse-engineering-assistant-1.0.3}/reverse_engineering_assistant/assistant_api_server.py +48 -34
  8. {reverse-engineering-assistant-1.0.0 → reverse-engineering-assistant-1.0.3}/reverse_engineering_assistant/model.py +8 -41
  9. {reverse-engineering-assistant-1.0.0 → reverse-engineering-assistant-1.0.3}/reverse_engineering_assistant/reva_exceptions.py +7 -1
  10. {reverse-engineering-assistant-1.0.0 → reverse-engineering-assistant-1.0.3}/reverse_engineering_assistant/tool_protocol.py +174 -30
  11. reverse-engineering-assistant-1.0.3/reverse_engineering_assistant.egg-info/PKG-INFO +191 -0
  12. {reverse-engineering-assistant-1.0.0 → reverse-engineering-assistant-1.0.3}/reverse_engineering_assistant.egg-info/SOURCES.txt +2 -1
  13. {reverse-engineering-assistant-1.0.0 → reverse-engineering-assistant-1.0.3}/reverse_engineering_assistant.egg-info/requires.txt +2 -0
  14. reverse-engineering-assistant-1.0.0/PKG-INFO +0 -152
  15. reverse-engineering-assistant-1.0.0/README.md +0 -133
  16. reverse-engineering-assistant-1.0.0/reverse_engineering_assistant/api_server_tools/function_tools.py +0 -122
  17. reverse-engineering-assistant-1.0.0/reverse_engineering_assistant.egg-info/PKG-INFO +0 -152
  18. {reverse-engineering-assistant-1.0.0 → reverse-engineering-assistant-1.0.3}/reverse_engineering_assistant/__init__.py +0 -0
  19. {reverse-engineering-assistant-1.0.0 → reverse-engineering-assistant-1.0.3}/reverse_engineering_assistant/api_server_tools/__init__.py +0 -0
  20. {reverse-engineering-assistant-1.0.0 → reverse-engineering-assistant-1.0.3}/reverse_engineering_assistant/configuration.py +0 -0
  21. {reverse-engineering-assistant-1.0.0 → reverse-engineering-assistant-1.0.3}/reverse_engineering_assistant/documents.py +0 -0
  22. {reverse-engineering-assistant-1.0.0 → reverse-engineering-assistant-1.0.3}/reverse_engineering_assistant/tool.py +0 -0
  23. {reverse-engineering-assistant-1.0.0 → reverse-engineering-assistant-1.0.3}/reverse_engineering_assistant.egg-info/dependency_links.txt +0 -0
  24. {reverse-engineering-assistant-1.0.0 → reverse-engineering-assistant-1.0.3}/reverse_engineering_assistant.egg-info/entry_points.txt +0 -0
  25. {reverse-engineering-assistant-1.0.0 → reverse-engineering-assistant-1.0.3}/reverse_engineering_assistant.egg-info/top_level.txt +0 -0
  26. {reverse-engineering-assistant-1.0.0 → reverse-engineering-assistant-1.0.3}/setup.cfg +0 -0
@@ -0,0 +1,191 @@
1
+ Metadata-Version: 2.1
2
+ Name: reverse-engineering-assistant
3
+ Version: 1.0.3
4
+ Summary: An AI assistant for reverse engineering tasks
5
+ Author: サイバーカイダ (cyberkaida)
6
+ Classifier: License :: OSI Approved :: Apache Software License
7
+ Classifier: Natural Language :: English
8
+ Classifier: Operating System :: OS Independent
9
+ Classifier: Programming Language :: Python
10
+ Description-Content-Type: text/markdown
11
+ Requires-Dist: langchain
12
+ Requires-Dist: langchain-core
13
+ Requires-Dist: langchain-openai
14
+ Requires-Dist: llama-cpp-python
15
+ Requires-Dist: prompt_toolkit
16
+ Requires-Dist: sentence_transformers
17
+ Requires-Dist: PyYAML
18
+ Requires-Dist: pydantic
19
+ Requires-Dist: rich
20
+ Requires-Dist: Flask
21
+
22
+ # ReVA - Reverse Engineering Assistant
23
+
24
+ [✨ An (old) quick demo! ✨](https://asciinema.org/a/626197)
25
+
26
+ The reverse engineering assistant (ReVA) is a project to build a disassembler agnostic AI assistant for
27
+ reverse engineering tasks. This includes both _offline_ and online inference and a simple architecture.
28
+
29
+ ReVa is different from other efforts at building AI assistants for RE tasks because it uses a _tool driven approach_.
30
+ ReVa aims to provide a variety of small tools to the LLM, just as your RE environment provides a set of small tools
31
+ to you. ReVa combines this approach with chain-of-reasoning techniques to empower the LLM to complete complex tasks.
32
+
33
+ Each of the tools given to the LLM are constructed to be easy for the LLM to use and to tolerate a variety of inputs
34
+ and to reduce hallucination by the LLM. We do this by providing the LLM with a schema but tolerating other input,
35
+ including descriptions that guide the LLM,and redirecting correctable mistakes back to the LLM, and including extra
36
+ output to guide the next decision by the LLM.
37
+
38
+ For example, when the LLM requests decompilation from your RE tool, we will accept a raw address in hex, a raw address
39
+ in base 10, a symbol name with a namespace, or a symbol. If the LLM gives us bad input we report this to the LLM along
40
+ with instructions to correct the input (maybe encouraging it to use the function list for example). To encourage exploration
41
+ as a human would, we report additional context like the namespace and cross references along with the decompilation, this
42
+ is a small nudge to make the LLM explore the binary in the same way a human would.
43
+
44
+ Using this technique you can ask general questions and get relevant answers. The model prioritises
45
+ information from the tools, but when there is no information it can still respond to generic
46
+ questions from its training.
47
+
48
+ You can ask questions like:
49
+ - Does this program use encryption? Write a markdown report on the encryption and where it is used.
50
+ - Draw a class diagram using plantuml syntax.
51
+ - Start from main, examine the program in detail. Rename variables as you go and provide a summary of the program.
52
+ - Explain the purpose of the `__mod_init` segment.
53
+ - What does `mmap` return?
54
+ - What does the function at address 0x80000 do?
55
+ - This is a CTF problem. Start at main, examine the program in detail and write a pwntools script to get the flag.
56
+
57
+ An important part of reverse engineering is the process. Many other tools simply ask a single question of the LLM,
58
+ this means it is difficult to determine _why_ a thing happened. In ReVa we break all actions down into small parts
59
+ and include the LLMs thoughts in the output. This allows the analyst to monitor the LLMs actions and reasoning, aborting
60
+ and changing the prompt if required.
61
+
62
+ ## Large Language Model Support
63
+
64
+ RevA is based on [langchain](https://langchain.com),
65
+ which supports a number of models.
66
+
67
+ Built in support is provided for:
68
+ - [OpenAI](https://platform.openai.com/overview) for online inference and easy setup (Needs an OpenAI API key)
69
+ - [Ollama](https://ollama.ai) and any model it supports for local on-device inference or connecting to a self hosted remote inference server.
70
+
71
+ Limited support is provided for:
72
+ - [llama-cpp](https://llama-cpp-python.readthedocs.io/en/latest/) and any model it supports for local on-device inference
73
+ - [text-generation-webui](https://github.com/oobabooga/text-generation-webui) and any model it supports for self-hosted remote inference
74
+
75
+ Adding additional inference servers is easy if it is supported by langchain.
76
+
77
+ See the configuration section for more information about setting the model.
78
+
79
+ ## Configuration
80
+
81
+ Configuration for the reverse engineering assistant is stored at
82
+ `~/.config/reverse-engineering-assistant/config.yaml`. If this
83
+ is not present on first start, a default configuration using
84
+ OpenAI for inference and the `OPENAI_API_TOKEN` environment
85
+ variable will be used.
86
+
87
+ The most important setting is the `type` top level setting.
88
+ This controls what inference service you use. These are the
89
+ same as the configuration keys, for example to use Ollama,
90
+ set type to `ollama` and configure the settings in the `ollama:`
91
+ section.
92
+
93
+ The configuration also contains the prompts used for the models.
94
+ If you use Ollama or OpenAI these will be processed to fit the
95
+ model specific prompt pattern (placing the system prompt in the
96
+ correct tags, etc).
97
+
98
+ For `llama-cpp` and `text-generation-webui` these may need to be
99
+ configured for your specific model. For this reason Ollama is
100
+ preferred for self hosting.
101
+
102
+ ## Workflow
103
+
104
+ RevA has a two step workflow.
105
+ 1. Open your RE tool and the program you want to examine
106
+ 2. Open the chat session.
107
+
108
+ ReVa uses an extension for your RE tool to perform analysis.
109
+ See [Ghidra Support](#ghidra-support) and [BinaryNinja Support](#binary-ninja-support) below.
110
+
111
+ Once open the RE tool will try to connect to ReVa's REST API on localhost.
112
+
113
+ A project cache is created in `~/.cache/reverse-engineering-assistant/projects`. This contains your chat log and other
114
+ cache data. This can be deleted at any time and ReVa will re-generate the data as needed.
115
+
116
+ To ask questions and run the inference a command line tool is provided. Run `revassistant --project ${NAME_OF_YOUR_FILE}` to begin the chat session.
117
+
118
+ > Note: In the future `--project` will refer to a _project_ in Ghidra and allow inference across multiple files.
119
+ > I am waiting for BinaryNinja's project feature to make this change, if this takes too long I will rework this argument.
120
+
121
+ `revassistant` provides a chat window and runs the command API to talk with the RE tool.
122
+
123
+ > Note: Right now only one `revassistant` can run at a time (as we start a server on a well known port)
124
+ > In the future we will share the server between chat clients and RE tool connections.
125
+
126
+ ## Installation
127
+
128
+ To install the particular extension for your disassembler see:
129
+ - [Ghidra Support](#ghidra-support)
130
+ - [Binary Ninja Support](#binary-ninja-support)
131
+
132
+ To install the chat component you can do the following:
133
+
134
+ ```sh
135
+ python3 -m pip install ./reverse-engineering-assistant
136
+ ```
137
+
138
+ The chat can be started with:
139
+
140
+ ```sh
141
+ revassistant --project ${NAME_OF_YOUR_PROJECT}
142
+ ```
143
+
144
+ # Ghidra Support
145
+
146
+ ## Usage
147
+
148
+ The [ghidra-assistant](ghidra-assistant/README.md) plugin must be installed first.
149
+
150
+ After installation, enable the `ReVaPlugin` extension in the CodeBrowser tool (Open a file and click: File -> Configure -> Miscellaneous).
151
+
152
+ If you want ReVa enabled by default, click File -> Save Tool to save the configuration.
153
+
154
+ To start the inference side, open Help -> About ${program name}. In this popup you will see details about your open file.
155
+ The `Program Name:` field is the name you need to pass to `revassistant --project` to start the inference server. In some
156
+ cases this is different to the name in the project view.
157
+
158
+ ## Undo
159
+
160
+ Whenever ReVa performs an action it will create an undo point for each action. If ReVa renames 5 variables, this will be
161
+ one undo.
162
+
163
+ ## Menus
164
+
165
+ ReVa adds some elements to the Ghidra UI. You can either ask ReVa to do something in the chat window,
166
+ "Examine the variable usage in `main` in detail, rename the variables with more descriptive names.",
167
+ or use the menu system.
168
+
169
+ For example you can right click a variable in the decompilation, select Reva -> Rename variable and ReVa
170
+ will perform the action.
171
+
172
+ Note this uses the same system as chatting with ReVa, this means you can monitor ReVas thoughts in the chat
173
+ window while the action is performed.
174
+
175
+ # Binary Ninja Support
176
+
177
+ > Note: Binary Ninja support is currently on hold while the basic functions are implemented in the Ghidra plugin.
178
+ > This is because plugin development for Binary Ninja is easier as we have Python3. I will resume development soon!
179
+
180
+ Install the ReVA BinaryNinja plugin by opening your BinaryNinja plugin directory (Plugins -> Open Plugin Folder)
181
+ and copying or symbolic linking the [binary-ninja-assistant](./binary-ninja-assistant) directory into the plugin
182
+ directory.
183
+
184
+ Restart Binary Ninja and "ReVA Push" will be available in the Plugin menu.
185
+ Press this to push data from BinaryNinja to ReVA, then follow the instructions in the [Workflow section](#workflow).
186
+ The project name will be the name of the current open file.
187
+
188
+ # Support
189
+
190
+ Do you like my work? Want to support this project and others? Interested in how this project was designed and built?
191
+ This project and many others are built live on my stream at https://twitch.tv/cyberkaida !
@@ -0,0 +1,170 @@
1
+ # ReVA - Reverse Engineering Assistant
2
+
3
+ [✨ An (old) quick demo! ✨](https://asciinema.org/a/626197)
4
+
5
+ The reverse engineering assistant (ReVA) is a project to build a disassembler agnostic AI assistant for
6
+ reverse engineering tasks. This includes both _offline_ and online inference and a simple architecture.
7
+
8
+ ReVa is different from other efforts at building AI assistants for RE tasks because it uses a _tool driven approach_.
9
+ ReVa aims to provide a variety of small tools to the LLM, just as your RE environment provides a set of small tools
10
+ to you. ReVa combines this approach with chain-of-reasoning techniques to empower the LLM to complete complex tasks.
11
+
12
+ Each of the tools given to the LLM are constructed to be easy for the LLM to use and to tolerate a variety of inputs
13
+ and to reduce hallucination by the LLM. We do this by providing the LLM with a schema but tolerating other input,
14
+ including descriptions that guide the LLM,and redirecting correctable mistakes back to the LLM, and including extra
15
+ output to guide the next decision by the LLM.
16
+
17
+ For example, when the LLM requests decompilation from your RE tool, we will accept a raw address in hex, a raw address
18
+ in base 10, a symbol name with a namespace, or a symbol. If the LLM gives us bad input we report this to the LLM along
19
+ with instructions to correct the input (maybe encouraging it to use the function list for example). To encourage exploration
20
+ as a human would, we report additional context like the namespace and cross references along with the decompilation, this
21
+ is a small nudge to make the LLM explore the binary in the same way a human would.
22
+
23
+ Using this technique you can ask general questions and get relevant answers. The model prioritises
24
+ information from the tools, but when there is no information it can still respond to generic
25
+ questions from its training.
26
+
27
+ You can ask questions like:
28
+ - Does this program use encryption? Write a markdown report on the encryption and where it is used.
29
+ - Draw a class diagram using plantuml syntax.
30
+ - Start from main, examine the program in detail. Rename variables as you go and provide a summary of the program.
31
+ - Explain the purpose of the `__mod_init` segment.
32
+ - What does `mmap` return?
33
+ - What does the function at address 0x80000 do?
34
+ - This is a CTF problem. Start at main, examine the program in detail and write a pwntools script to get the flag.
35
+
36
+ An important part of reverse engineering is the process. Many other tools simply ask a single question of the LLM,
37
+ this means it is difficult to determine _why_ a thing happened. In ReVa we break all actions down into small parts
38
+ and include the LLMs thoughts in the output. This allows the analyst to monitor the LLMs actions and reasoning, aborting
39
+ and changing the prompt if required.
40
+
41
+ ## Large Language Model Support
42
+
43
+ RevA is based on [langchain](https://langchain.com),
44
+ which supports a number of models.
45
+
46
+ Built in support is provided for:
47
+ - [OpenAI](https://platform.openai.com/overview) for online inference and easy setup (Needs an OpenAI API key)
48
+ - [Ollama](https://ollama.ai) and any model it supports for local on-device inference or connecting to a self hosted remote inference server.
49
+
50
+ Limited support is provided for:
51
+ - [llama-cpp](https://llama-cpp-python.readthedocs.io/en/latest/) and any model it supports for local on-device inference
52
+ - [text-generation-webui](https://github.com/oobabooga/text-generation-webui) and any model it supports for self-hosted remote inference
53
+
54
+ Adding additional inference servers is easy if it is supported by langchain.
55
+
56
+ See the configuration section for more information about setting the model.
57
+
58
+ ## Configuration
59
+
60
+ Configuration for the reverse engineering assistant is stored at
61
+ `~/.config/reverse-engineering-assistant/config.yaml`. If this
62
+ is not present on first start, a default configuration using
63
+ OpenAI for inference and the `OPENAI_API_TOKEN` environment
64
+ variable will be used.
65
+
66
+ The most important setting is the `type` top level setting.
67
+ This controls what inference service you use. These are the
68
+ same as the configuration keys, for example to use Ollama,
69
+ set type to `ollama` and configure the settings in the `ollama:`
70
+ section.
71
+
72
+ The configuration also contains the prompts used for the models.
73
+ If you use Ollama or OpenAI these will be processed to fit the
74
+ model specific prompt pattern (placing the system prompt in the
75
+ correct tags, etc).
76
+
77
+ For `llama-cpp` and `text-generation-webui` these may need to be
78
+ configured for your specific model. For this reason Ollama is
79
+ preferred for self hosting.
80
+
81
+ ## Workflow
82
+
83
+ RevA has a two step workflow.
84
+ 1. Open your RE tool and the program you want to examine
85
+ 2. Open the chat session.
86
+
87
+ ReVa uses an extension for your RE tool to perform analysis.
88
+ See [Ghidra Support](#ghidra-support) and [BinaryNinja Support](#binary-ninja-support) below.
89
+
90
+ Once open the RE tool will try to connect to ReVa's REST API on localhost.
91
+
92
+ A project cache is created in `~/.cache/reverse-engineering-assistant/projects`. This contains your chat log and other
93
+ cache data. This can be deleted at any time and ReVa will re-generate the data as needed.
94
+
95
+ To ask questions and run the inference a command line tool is provided. Run `revassistant --project ${NAME_OF_YOUR_FILE}` to begin the chat session.
96
+
97
+ > Note: In the future `--project` will refer to a _project_ in Ghidra and allow inference across multiple files.
98
+ > I am waiting for BinaryNinja's project feature to make this change, if this takes too long I will rework this argument.
99
+
100
+ `revassistant` provides a chat window and runs the command API to talk with the RE tool.
101
+
102
+ > Note: Right now only one `revassistant` can run at a time (as we start a server on a well known port)
103
+ > In the future we will share the server between chat clients and RE tool connections.
104
+
105
+ ## Installation
106
+
107
+ To install the particular extension for your disassembler see:
108
+ - [Ghidra Support](#ghidra-support)
109
+ - [Binary Ninja Support](#binary-ninja-support)
110
+
111
+ To install the chat component you can do the following:
112
+
113
+ ```sh
114
+ python3 -m pip install ./reverse-engineering-assistant
115
+ ```
116
+
117
+ The chat can be started with:
118
+
119
+ ```sh
120
+ revassistant --project ${NAME_OF_YOUR_PROJECT}
121
+ ```
122
+
123
+ # Ghidra Support
124
+
125
+ ## Usage
126
+
127
+ The [ghidra-assistant](ghidra-assistant/README.md) plugin must be installed first.
128
+
129
+ After installation, enable the `ReVaPlugin` extension in the CodeBrowser tool (Open a file and click: File -> Configure -> Miscellaneous).
130
+
131
+ If you want ReVa enabled by default, click File -> Save Tool to save the configuration.
132
+
133
+ To start the inference side, open Help -> About ${program name}. In this popup you will see details about your open file.
134
+ The `Program Name:` field is the name you need to pass to `revassistant --project` to start the inference server. In some
135
+ cases this is different to the name in the project view.
136
+
137
+ ## Undo
138
+
139
+ Whenever ReVa performs an action it will create an undo point for each action. If ReVa renames 5 variables, this will be
140
+ one undo.
141
+
142
+ ## Menus
143
+
144
+ ReVa adds some elements to the Ghidra UI. You can either ask ReVa to do something in the chat window,
145
+ "Examine the variable usage in `main` in detail, rename the variables with more descriptive names.",
146
+ or use the menu system.
147
+
148
+ For example you can right click a variable in the decompilation, select Reva -> Rename variable and ReVa
149
+ will perform the action.
150
+
151
+ Note this uses the same system as chatting with ReVa, this means you can monitor ReVas thoughts in the chat
152
+ window while the action is performed.
153
+
154
+ # Binary Ninja Support
155
+
156
+ > Note: Binary Ninja support is currently on hold while the basic functions are implemented in the Ghidra plugin.
157
+ > This is because plugin development for Binary Ninja is easier as we have Python3. I will resume development soon!
158
+
159
+ Install the ReVA BinaryNinja plugin by opening your BinaryNinja plugin directory (Plugins -> Open Plugin Folder)
160
+ and copying or symbolic linking the [binary-ninja-assistant](./binary-ninja-assistant) directory into the plugin
161
+ directory.
162
+
163
+ Restart Binary Ninja and "ReVA Push" will be available in the Plugin menu.
164
+ Press this to push data from BinaryNinja to ReVA, then follow the instructions in the [Workflow section](#workflow).
165
+ The project name will be the name of the current open file.
166
+
167
+ # Support
168
+
169
+ Do you like my work? Want to support this project and others? Interested in how this project was designed and built?
170
+ This project and many others are built live on my stream at https://twitch.tv/cyberkaida !
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
5
5
  [project]
6
6
  name = "reverse-engineering-assistant"
7
7
  readme = "README.md"
8
- version = "1.0.0"
8
+ version = "1.0.3"
9
9
  authors = [
10
10
  {name="サイバーカイダ (cyberkaida)"},
11
11
  ]
@@ -18,6 +18,8 @@ classifiers = [
18
18
  ]
19
19
  dependencies = [
20
20
  "langchain",
21
+ "langchain-core",
22
+ "langchain-openai",
21
23
  "llama-cpp-python",
22
24
  "prompt_toolkit",
23
25
  "sentence_transformers",
@@ -0,0 +1,67 @@
1
+ from typing import Dict, List, Optional
2
+ from ..assistant_api_server import register_message_handler, RevaMessageHandler, RevaCallbackHandler
3
+ from ..tool_protocol import (
4
+ RevaExplain,
5
+ RevaGetNewVariableName,
6
+ RevaGetNewVariableNameResponse,
7
+ RevaGetNewSymbolName,
8
+ RevaGetNewSymbolNameResponse,
9
+ RevaExplain,
10
+ RevaExplainResponse,
11
+ RevaLocation,
12
+ )
13
+
14
+ from ..reva_exceptions import RevaToolException
15
+ import threading
16
+ import logging
17
+
18
+
19
+ @register_message_handler
20
+ class HandleGetNewVariableName(RevaMessageHandler):
21
+ handles_type = RevaGetNewVariableName
22
+ def run(self, callback_handler: RevaCallbackHandler) -> RevaGetNewVariableNameResponse:
23
+ # Extract the content and ask the LLM what it thinks...
24
+ assert isinstance(callback_handler.message, RevaGetNewVariableName)
25
+ message: RevaGetNewVariableName = callback_handler.message
26
+ question = f"""
27
+ Examine the function {message.function_name} in detail and rename the following variable:
28
+ {message.variable}
29
+ """
30
+ # Block until ReVa finishes analysis.
31
+ _ = self.assistant.query(question)
32
+ response = RevaGetNewVariableNameResponse(response_to=message.message_id)
33
+ return response
34
+
35
+ @register_message_handler
36
+ class HandleGetNewSymbolName(RevaMessageHandler):
37
+ handles_type = RevaGetNewSymbolName
38
+ def run(self, callback_handler: RevaCallbackHandler) -> RevaGetNewSymbolNameResponse:
39
+ # Extract the content and ask the LLM what it thinks...
40
+ assert isinstance(callback_handler.message, RevaGetNewSymbolName)
41
+ message: RevaGetNewSymbolName = callback_handler.message
42
+ question = f"""
43
+ Examine {message.symbol_name} and rename it to something descriptive using the `set_sybmol_name` function.
44
+ """
45
+ # Block until ReVa finishes analysis.
46
+ _ = self.assistant.query(question)
47
+ response = RevaGetNewSymbolNameResponse(response_to=message.message_id)
48
+ return response
49
+
50
+ @register_message_handler
51
+ class HandleExplain(RevaMessageHandler):
52
+ handles_type = RevaExplain
53
+ def run(self, callback_handler: RevaCallbackHandler) -> RevaExplainResponse:
54
+ # Extract the content and ask the LLM what it thinks...
55
+ assert isinstance(callback_handler.message, RevaExplain)
56
+ message: RevaExplain = callback_handler.message
57
+ question = f"""
58
+ Explain the following location in detail, leave comments as needed.
59
+ """
60
+
61
+ location: RevaLocation = message.location
62
+
63
+ if message.location is not None:
64
+ question += f"\n{message.location}"
65
+ # Block until ReVa finishes analysis.
66
+ threading.Thread(target=self.assistant.query, args=(question,)).start()
67
+ return RevaExplainResponse(response_to=message.message_id)