-
Notifications
You must be signed in to change notification settings - Fork 5.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Code executors #1405
Code executors #1405
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1405 +/- ##
===========================================
+ Coverage 35.03% 69.93% +34.89%
===========================================
Files 44 50 +6
Lines 5383 5677 +294
Branches 1247 1381 +134
===========================================
+ Hits 1886 3970 +2084
+ Misses 3342 1342 -2000
- Partials 155 365 +210
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
I like this idea very much. Given that we use the markdown header to specify language, should be allow executor to be a dictionary?
|
I'm not sure why with the recent 0.2.8 change why we need to default to using docker. I thought the default was to not use docker. |
Running in Docker was always our recommendation -- it's so much safer when dealing with the arbitrary code these agents write. Previously, we printed a prominent warning to console when Docker wasn't explicitly disabled with The change in 0.2.8 is to elevate the recommendation to a default. But, you can easily opt-out setting use_docker to false or setting the global environment variable. |
Thanks. This is actually an interesting idea that the dictionary entry could be an instance of an executor to achieve customization. Though currently we assume the code executor is supposed to be language agnostic -- as the LLM could produce code in multiple languages and we assume those will be executed in the same environment. So, the code executor is more about the environment in which the code runs. E.g., a command line environment which supports command utilities, an ipython environment that only supports ipython commands (python code and stuff like We can also introduce Google Code Lab environment and .NET interactive (shout out to @LittleLittleCloud @colombod) in the future. For now, I am expecting mostly community contributions on these cases. Each executor can put in their configuration parameters inside the {"executor": "ipython",
"ipython": {
"timeout": 50,
"preload_modules": ["numpy", "pandas", ...],
}
} |
That makes sense. Another question: Right now the default assistant prompt is heavily tuned to suggesting sh and python code, and heavily instructed to making sure the codeblocks "stand alone". Are you imagining that the executors might also contain suggested meta-prompts, or descriptions, that can make this a little more integrated? |
You are thinking what I am thinking. I just updated the PR description. In short: agent = ConversableAgent("agent", ...)
user_proxy.code_executor.user_capability.add_to_agent(agent) |
This is actually not quite true. Running in docker doesn't mean running in a separate docker container which would be a much safer way of doing it. It also means running in the same docker container if autogen is already running in a docker container. I discovered that yesterday and thought it was a bug (#1396) while implementing some missing tests, but apparently, it is not. |
Yes. There is a difference between use_docker=True with autogen hosted outside, and running everything in Docker (in which case use_docker is effectively ignored). The former is more secure than the latter. We should definitely distinguish this, and I would be happy to discuss this in another thread. |
@IANTHEREAL I have resolved everything else except regarding the functionality to update producer agent's description field. Please see my comments. |
@abhijithnair1 You can take a look at the PR description about a notebook executor that runs inside a JupyterNote book. There is also an ipython executor that runs in a separate IPython Kernel which is stateful. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
* code executor * test * revert to main conversable agent * prepare for pr * kernel * run open ai tests only when it's out of draft status * update workflow file * revert workflow changes * ipython executor * check kernel installed; fix tests * fix tests * fix tests * update system prompt * Update notebook, more tests * notebook * raise instead of return None * allow user provided code executor. * fixing types * wip * refactoring * polishing * fixed failing tests * resolved merge conflict * fixing failing test * wip * local command line executor and embedded ipython executor * revert notebook * fix format * fix merged error * fix lmm test * fix lmm test * move warning * name and description should be part of the agent protocol, reset is not as it is only used for ConversableAgent; removing accidentally commited file * version for dependency * Update autogen/agentchat/conversable_agent.py Co-authored-by: Jack Gerrits <[email protected]> * ordering of protocol * description * fix tests * make ipython executor dependency optional * update document optional dependencies * Remove exclude from Agent protocol * Make ConversableAgent consistent with Agent * fix tests * add doc string * add doc string * fix notebook * fix interface * merge and update agents * disable config usage in reply function * description field setter * customize system message update * update doc --------- Co-authored-by: Davor Runje <[email protected]> Co-authored-by: Jack Gerrits <[email protected]> Co-authored-by: Aaron <[email protected]> Co-authored-by: Chi Wang <[email protected]>
Why are these changes needed?
The default code execution is done in a command line environment in a docker container. This has following limitations:
This is why we introduce code executors to allow users to select and configure the code execution environment, and at the same time making it easy for people to write their own code executors.
This requires changes to the schema of
code_execution_config
configuration -- those changes will be backward compatible so existing code will be using the legacy code execution module with no change in behavior.Here is an example of specifying
ipython-embedded
code executor for a user proxy.Or the local command line code executor:
In some cases, the user of the code executing agent needs to know how to use the code executor. E.g., the agent needs to know that it is interacting with an IPython notebook to make use of the notebook related features such as
display
, preloaded modules, and! pip install ...
, and expecting rich messages like formatted tables and plots. This requires the user agent to be equipped with a capability. This can be accomplished as following:Here the
user_capability
is anAgentCapability
type that modifiesagent
's system message to add instructions related to usage of Ipython code executor.User-defined code executor.
It is also possible to use user-supplied code executor. So advanced user can use their own executor without modifying the framework. Here is an example of a customized notebook executor that execute LLM generated code within the same notebook it is running on.
Documentation
Documentation will be in a future PR once the user-defined module work is completed. See #1421 .
Backward compatibility
For backward compatibility, existing code that uses either setting
code_execution_config
to a dictionary (without the key "executor") will still be using the legacy code execution module, and subclasses that overridesrun_code
andexecute_code_blocks
will still have their overriding methods used in those classes.Once we have finished the other tasks in the code execution roadmap (#1421), a deprecation warning will be displayed when they do that, encouraging the developer to switch from subclassing when it comes to customizing code execution.
To turn off code execution, set
code_execution_config=False
. This is consistent with the current behavior.Additional changes
Per PEP544 protocol is for supporting structured sub-typing aka interface in Python. So we don't have to declare subclass of a protocol, rather we can rely on static type checker or @runtime_checkable on the protocol to check of type. e.g.,
We make
Agent
andLLMAgent
protocols, this allows external code to create their own agent classes without subclassing ourConversableAgent
and inherit all the underlying methods and variables, yet we can use them in our code likeGroupChat
for example.Related issue number
#1336
#1396
#1095
Checks