> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ag2.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Tools with Secrets

### Introduction to Dependency Injection

Secrets such as password, tokens, or personal information needs to be protected from capture. AG2 provides dependency injection as a way to secure this sensitive information while still allowing agents to perform their tasks effectively, even when working with large language models (LLMs).

Benefits of dependency injection:

* **Enhanced Security**: Your sensitive data is never directly exposed to the LLM or telemetry.
* **Simplified Development**: Secure data can be seamlessly accessed by functions without requiring complex configurations.
* **Unmatched Flexibility**: Supports safe integration of diverse workflows, allowing you to scale and adapt with ease.

In this walk-through we'll show how you could support 3rd party system credentials using specific agents and their respective tools and dependency injection.

```python theme={null}
# Imports and an LLM configuration for all agents
import os
from typing import Annotated, Literal

from pydantic import BaseModel

from autogen import GroupChat, GroupChatManager, LLMConfig
from autogen.agentchat import ConversableAgent, UserProxyAgent
from autogen.tools.dependency_injection import BaseContext, Depends

llm_config = LLMConfig(api_type="openai", model="gpt-4o-mini", api_key=os.environ["OPENAI_API_KEY"])
```

### Setting Up Third-Party Systems

We have 2 external systems and have 2 related login credentials. We don't want or need the LLM to be aware of these credentials.

#### Mock third party systems

Here are two functions which, we'll assume, are accessing a third party system using a username and password.

We have `username` and `password` going into the functions, but we don't want to have that information stored in our messages, sent to the LLM, or tracked through telemetry.

Soon we'll see how dependency injection can help.

```python theme={null}
# Mock functions accessing 3rd party systems

def weather_api_call(username: str, password: str, location: str) -> str:
    print(f"Accessing third party Weather System using username {username}")
    return "It's sunny and 40 degrees Celsius in Sydney, Australia."

def my_ticketing_system_availability(username: str, password: str, concert: str) -> bool:
    print(f"Accessing third party Ticketing System using username {username}")
    return False
```

#### Our credentials structure

Here we define a `BaseContext` class for account credentials. This will act as the base structure for dependency injection with information in these not being exposed to the LLM.

```python theme={null}
# Credentials class based on BaseContext
class ThirdPartyCredentials(BaseContext, BaseModel):
    username: str
    password: str
```

#### Agents for each system

An agent is created for each 3rd party system.

```python theme={null}
with llm_config:
    # Our two 3rd party system accessing agents
    weather_agent = ConversableAgent(
        name="weather_agent",
        system_message="You are a Weather Agent, you can only get the weather.",
        description="Weather Agent solely used for getting weather.",
    )

    ticket_agent = ConversableAgent(
        name="ticket_agent",
        system_message="You are a Ticketing Agent, you can only get ticket availability.",
        description="Ticketing Agent solely used for getting ticket availability.",
    )

# Our user proxy agent, used to execute the tools
user_proxy = UserProxyAgent(
    name="user_proxy",
    human_input_mode="NEVER",
    llm_config=False,
)
```

### Implementing Secure Tools

#### Creating credentials and tools with dependency injection

For each 3rd party system we create the credentials and a tool.

Take note that we are setting the credentials parameter as a `ThirdPartyCredential` and are injecting the respective credentials, e.g. `Depends(weather_account)`.

The `credentials` parameters will not be visible to the LLM, it'll be completely unaware of it.

```python theme={null}
# Weather API
weather_account = ThirdPartyCredentials(username="ag2weather", password="wbkvEehV1A")

@user_proxy.register_for_execution()
@weather_agent.register_for_llm(description="Get the weather for a location")
def get_weather(
    location: str,
    credentials: Annotated[ThirdPartyCredentials, Depends(weather_account)],
) -> str:
    # Access the Weather API using the credentials
    return weather_api_call(username=credentials.username, password=credentials.password, location=location)

# Ticketing System API
ticket_system_account = ThirdPartyCredentials(username="ag2tickets", password="EZRIVeVWvA")

@user_proxy.register_for_execution()
@ticket_agent.register_for_llm(description="Get the availability of tickets for a concert")
def tickets_available(
    concert_name: str,
    credentials: Annotated[ThirdPartyCredentials, Depends(ticket_system_account)],
) -> bool:
    return my_ticketing_system_availability(
        username=credentials.username, password=credentials.password, concert=concert_name
    )
```

#### Create Group Chat and run

```python theme={null}
# Create a GroupChat
groupchat = GroupChat(agents=[user_proxy, weather_agent, ticket_agent], messages=[], max_round=5)
manager = GroupChatManager(groupchat=groupchat, llm_config=llm_config)

# Here's our task for our LLM to help with
message = (
    "Start by getting the weather for Sydney, Australia, and follow that up by checking "
    "if there are tickets for the 'AG2 Live' concert."
)
user_proxy.initiate_chat(manager, message=message, max_turns=1)
```

Below is the output of the chat, broken up so we can understand what's happening.

```console theme={null}
user_proxy (to chat_manager):

Start by getting the weather for Sydney, Australia, and follow that up by checking if there are tickets for the 'AG2 Live' concert.

--------------------------------------------------------------------------------

Next speaker: weather_agent

>>>>>>>> USING AUTO REPLY...
weather_agent (to chat_manager):

***** Suggested tool call (call_4ZWdbwuuojMxGXoxQDPzXpRl): get_weather *****
Arguments:
{"location": "Sydney, Australia"}
****************************************************************************
```

We can see that the LLM has suggested a tool call for `get_weather` and it only has `location`, `credentials` is not part of the LLM request or response.

```console theme={null}
--------------------------------------------------------------------------------

Next speaker: user_proxy

>>>>>>>> EXECUTING FUNCTION get_weather...
Call ID: call_4ZWdbwuuojMxGXoxQDPzXpRl
Input arguments: {'location': 'Sydney, Australia'}
Accessing third party Weather System using username ag2weather
user_proxy (to chat_manager):

***** Response from calling tool (call_4ZWdbwuuojMxGXoxQDPzXpRl) *****
It's sunny and 40 degrees Celsius in Sydney, Australia.
**********************************************************************
```

Similarly, when the tool's function is called we can see that our view of it shows only the `location` parameter, with the `credentials` being injected automatically. Our function is printing out the username to prove that credentials are being passed in.

```console theme={null}
--------------------------------------------------------------------------------

Next speaker: ticket_agent

>>>>>>>> USING AUTO REPLY...
ticket_agent (to chat_manager):

***** Suggested tool call (call_MQVDpFTDcdNdKxH7LsikfR1z): tickets_available *****
Arguments:
{"concert_name":"AG2 Live"}
**********************************************************************************

--------------------------------------------------------------------------------

Next speaker: user_proxy

>>>>>>>> EXECUTING FUNCTION tickets_available...
Call ID: call_MQVDpFTDcdNdKxH7LsikfR1z
Input arguments: {'concert_name': 'AG2 Live'}
Accessing third party Ticketing System using username ag2tickets
user_proxy (to chat_manager):

***** Response from calling tool (call_MQVDpFTDcdNdKxH7LsikfR1z) *****
false
**********************************************************************

--------------------------------------------------------------------------------
```

The same occurred for the other 3rd party tool and function, with all credentials silently injected.

### More Tool with Dependency Injection examples

See the [Tools with Dependency Injection](/docs/use-cases/notebooks/notebooks/tools_dependency_injection) notebook.

### API

* [BaseContext](/docs/api-reference/autogen/tools/BaseContext)
* [Depends](/docs/api-reference/autogen/tools/Depends)

<div className="edit-url-container">
  <a className="edit-url" href="https://github.com/ag2ai/ag2/edit/main/website/docs/user-guide/advanced-concepts/tools/tools-with-secrets.mdx" target="_blank"><Icon icon="pen" iconType="solid" size="13px" /> Edit this page</a>
</div>
