Skip to main content

Indent Langchain Quickstart

Learn how to add approvals to your LangChain application using the Indent Python SDK.

Prerequisites

1. Install

Start by installing the Indent Approval Kit for Python:

pip install approvals

We're going to use the LangChain Human-in-the-loop Tool Validation docs page as a starting point.

pip install langchain
agent.py
from langchain.callbacks import HumanApprovalCallbackHandler
from langchain.tools import ShellTool

tool = ShellTool(callbacks=[HumanApprovalCallbackHandler()])
print(tool.run("echo Hello World!"))

2. Get your API Key

First, you'll need an Indent space and API token which you can find here: indent.com/api-keys

Current User
Sign in to get API key
  • Can take actions on your behalf
  • Appears in audit log as you
Indent Space
Access Token
Note: this token is short lived and will expire soon
.env
INDENT_SPACE=
INDENT_API_TOKEN=************************************************************************************

The INDENT_SPACE is the Indent account you want to use for requests and an INDENT_API_TOKEN which is used for authentication. There are two kinds of API tokens: short-lived user access tokens and long-lived service account tokens. Read more about API authentication.

3. Add await approval

Since we're using a LangChain Tool with Callbacks, we can import HumanApprovalCallbackHandler from approvals.using.langchain to request approval for the tool:

agent.py
from approvals.using.langchain import HumanApprovalCallbackHandler
from langchain.tools import ShellTool

tool = ShellTool(callbacks=[HumanApprovalCallbackHandler()])
print(tool.run("ls /usr"))
Want to build approvals into your tool directly instead of using callbacks?

If we were implementing the tool ourselves, we could use the approval function instead:

tool.py
import asyncio
import platform
import warnings
from approvals import approval
from typing import Any, List, Optional, Type, Union
from langchain.pydantic_v1 import BaseModel
from langchain.tools.base import BaseTool
from langchain.callbacks.manager import (
AsyncCallbackManagerForToolRun,
CallbackManagerForToolRun,
)

class ShellTool(BaseTool):
def _run(
self,
commands: Union[str, List[str]],
run_manager: Optional[CallbackManagerForToolRun] = None,
) -> str:
"""Run commands and return final output."""
return self.process.run(commands)

async def _arun(
self,
commands: Union[str, List[str]],
run_manager: Optional[AsyncCallbackManagerForToolRun] = None,
) -> str:
await approval({
"reason": "Agent needs to run commands",
"resources": [
{
"kind": "exec-shell",
"id": f"commands={commands}"
},
],
})

"""Run commands asynchronously and return final output."""
return await asyncio.get_event_loop().run_in_executor(
None, self.process.run, commands
)

3. Try it for yourself

Configure the following environment variables:

.env
INDENT_SPACE=acmecorp
INDENT_API_TOKEN=s38...65e # Copy from indent.com/api-keys

Run the tool and you'll see a link to approve the request:

$ python tool.py

✳︎ Requesting approval for: ls /usr
⏵ Requested approval #acmecorp/aec1b116-42b3-11ee-824e-42010aac000d
↳ Waiting for approval... (2s elapsed)
↳ Waiting for approval... (4s elapsed)
↳ Waiting for approval... (8s elapsed)
✅ Granted

X11
X11R6
bin
lib
libexec
sbin
share
standalone