chore: import upstream snapshot with attribution
CodeQL / Analyze (python) (push) Has been cancelled
Update Platform Components Table / update (push) Has been cancelled
Docker image release / Build base image (push) Has been cancelled
Sync docs with Docusaurus / sync (push) Has been cancelled
Tests / Check if changed (push) Has been cancelled
Tests / format (push) Has been cancelled
Tests / check-imports (push) Has been cancelled
Tests / Unit / macos-latest (push) Has been cancelled
Tests / Unit / ubuntu-latest (push) Has been cancelled
Tests / Unit / windows-latest (push) Has been cancelled
Tests / mypy (push) Has been cancelled
Tests / Integration / ubuntu-latest (push) Has been cancelled
Tests / Integration / macos-latest (push) Has been cancelled
Tests / Integration / windows-latest (push) Has been cancelled
Tests / notify-slack-on-failure (push) Has been cancelled
Tests / Mark tests as completed (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Update Platform Components Table / update (push) Has been cancelled
Docker image release / Build base image (push) Has been cancelled
Sync docs with Docusaurus / sync (push) Has been cancelled
Tests / Check if changed (push) Has been cancelled
Tests / format (push) Has been cancelled
Tests / check-imports (push) Has been cancelled
Tests / Unit / macos-latest (push) Has been cancelled
Tests / Unit / ubuntu-latest (push) Has been cancelled
Tests / Unit / windows-latest (push) Has been cancelled
Tests / mypy (push) Has been cancelled
Tests / Integration / ubuntu-latest (push) Has been cancelled
Tests / Integration / macos-latest (push) Has been cancelled
Tests / Integration / windows-latest (push) Has been cancelled
Tests / notify-slack-on-failure (push) Has been cancelled
Tests / Mark tests as completed (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,161 @@
|
||||
---
|
||||
title: "E2BToolset"
|
||||
id: e2btoolset
|
||||
slug: "/e2btoolset"
|
||||
description: "A Toolset that gives Agents access to a live E2B cloud sandbox for executing bash commands and managing files."
|
||||
---
|
||||
|
||||
# E2BToolset
|
||||
|
||||
A Toolset that gives Agents access to a live [E2B](https://e2b.dev/) cloud sandbox for executing bash commands and managing files.
|
||||
|
||||
<div className="key-value-table">
|
||||
|
||||
| | |
|
||||
| --- | --- |
|
||||
| **Mandatory init variables** | `api_key`: E2B API key. Can be set with `E2B_API_KEY` env var. |
|
||||
| **API reference** | [E2B](/reference/integrations-e2b) |
|
||||
| **GitHub link** | https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/e2b |
|
||||
| **Package name** | `e2b-haystack` |
|
||||
|
||||
</div>
|
||||
|
||||
## Overview
|
||||
|
||||
`E2BToolset` bundles four tools that operate inside the same [E2B](https://e2b.dev/) cloud sandbox, giving an Agent a secure, isolated Linux environment to execute code and manipulate files:
|
||||
|
||||
- **`run_bash_command`** (`RunBashCommandTool`): Runs a bash command and returns the combined `exit_code`, `stdout`, and `stderr`. Use it for shell scripts, package installation, code compilation, or any system-level operation.
|
||||
- **`read_file`** (`ReadFileTool`): Reads the text content of a file from the sandbox filesystem.
|
||||
- **`write_file`** (`WriteFileTool`): Writes text content to a file in the sandbox. Parent directories are created automatically and existing files are overwritten.
|
||||
- **`list_directory`** (`ListDirectoryTool`): Lists files and subdirectories at a given path.
|
||||
|
||||
All four tools share a single `E2BSandbox` instance, so a file written by `write_file` is immediately available to `run_bash_command` and `read_file` in the same Agent run. The toolset owns the sandbox lifecycle: `warm_up()` starts the sandbox, `close()` shuts it down, and YAML serialization round-trips preserve the shared-sandbox relationship.
|
||||
|
||||
### Parameters
|
||||
|
||||
- `api_key` is _mandatory_ and must be an E2B API key. The default setting uses the environment variable `E2B_API_KEY`. Get a key at [e2b.dev](https://e2b.dev/).
|
||||
- `sandbox_template` is _optional_ and defaults to `"base"`. Sets the E2B sandbox template to use.
|
||||
- `timeout` is _optional_ and defaults to `120`. Sets the sandbox inactivity timeout in seconds.
|
||||
- `environment_vars` is _optional_ and lets you inject environment variables into the sandbox process.
|
||||
|
||||
## Usage
|
||||
|
||||
Install the E2B integration to use `E2BToolset`:
|
||||
|
||||
```shell
|
||||
pip install e2b-haystack
|
||||
```
|
||||
|
||||
Set your E2B API key:
|
||||
|
||||
```shell
|
||||
export E2B_API_KEY="your-e2b-api-key"
|
||||
```
|
||||
|
||||
### With an Agent
|
||||
|
||||
You can use `E2BToolset` with the [Agent](../../pipeline-components/agents-1/agent.mdx) component. The Agent will automatically start the sandbox, invoke the tools to write, run, and inspect code, and let the LLM chain calls together inside the same sandbox process.
|
||||
|
||||
```python
|
||||
from haystack.components.agents import Agent
|
||||
from haystack.components.generators.chat import OpenAIChatGenerator
|
||||
from haystack.dataclasses import ChatMessage
|
||||
|
||||
from haystack_integrations.tools.e2b import E2BToolset
|
||||
|
||||
agent = Agent(
|
||||
chat_generator=OpenAIChatGenerator(model="gpt-4o-mini"),
|
||||
tools=E2BToolset(),
|
||||
system_prompt=(
|
||||
"You are a helpful coding assistant with access to a live Linux sandbox. "
|
||||
"Use the available tools freely to explore, write files, and run commands. "
|
||||
"All tools operate inside the same sandbox environment, so files written "
|
||||
"with write_file are immediately available to run_bash_command and read_file."
|
||||
),
|
||||
max_agent_steps=15,
|
||||
)
|
||||
|
||||
response = agent.run(
|
||||
messages=[
|
||||
ChatMessage.from_user(
|
||||
"Write a Python script to /tmp/primes.py that prints all prime numbers "
|
||||
"up to 50, run it, and then read the file back so I can see both the "
|
||||
"script and its output.",
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
print(response["last_message"].text)
|
||||
```
|
||||
|
||||
### Using individual tools
|
||||
|
||||
If you only need a subset of the tools, you can instantiate them directly and pass them a shared `E2BSandbox`:
|
||||
|
||||
```python
|
||||
from haystack.components.agents import Agent
|
||||
from haystack.components.generators.chat import OpenAIChatGenerator
|
||||
|
||||
from haystack_integrations.tools.e2b import (
|
||||
E2BSandbox,
|
||||
ListDirectoryTool,
|
||||
ReadFileTool,
|
||||
RunBashCommandTool,
|
||||
WriteFileTool,
|
||||
)
|
||||
|
||||
sandbox = E2BSandbox(sandbox_template="base", timeout=300)
|
||||
|
||||
agent = Agent(
|
||||
chat_generator=OpenAIChatGenerator(model="gpt-4o-mini"),
|
||||
tools=[
|
||||
RunBashCommandTool(sandbox=sandbox),
|
||||
ReadFileTool(sandbox=sandbox),
|
||||
WriteFileTool(sandbox=sandbox),
|
||||
ListDirectoryTool(sandbox=sandbox),
|
||||
],
|
||||
)
|
||||
```
|
||||
|
||||
When using the tools standalone (outside an Agent or Pipeline), call `sandbox.warm_up()` before the first invocation and `sandbox.close()` when you are done to release the cloud resources.
|
||||
|
||||
### In a Pipeline
|
||||
|
||||
`E2BToolset` is fully serializable, so you can wrap an Agent that uses it in a Pipeline and save the Pipeline to YAML:
|
||||
|
||||
```python
|
||||
from haystack.components.agents import Agent
|
||||
from haystack.components.generators.chat import OpenAIChatGenerator
|
||||
from haystack.core.pipeline import Pipeline
|
||||
from haystack.dataclasses import ChatMessage
|
||||
|
||||
from haystack_integrations.tools.e2b import E2BToolset
|
||||
|
||||
agent = Agent(
|
||||
chat_generator=OpenAIChatGenerator(model="gpt-4o-mini"),
|
||||
tools=E2BToolset(sandbox_template="base", timeout=120),
|
||||
system_prompt="You are a helpful coding assistant with access to a live Linux sandbox.",
|
||||
max_agent_steps=10,
|
||||
)
|
||||
|
||||
pipeline = Pipeline()
|
||||
pipeline.add_component("agent", agent)
|
||||
|
||||
# Serialize and restore - all four tools still share the same E2BSandbox after the round-trip.
|
||||
yaml_str = pipeline.dumps()
|
||||
restored = Pipeline.loads(yaml_str)
|
||||
|
||||
result = restored.run(
|
||||
data={
|
||||
"agent": {
|
||||
"messages": [
|
||||
ChatMessage.from_user(
|
||||
"Write a Python one-liner to /tmp/hello.py that prints "
|
||||
"'Hello from E2B!', run it, then show me the output.",
|
||||
),
|
||||
],
|
||||
},
|
||||
},
|
||||
)
|
||||
print(result["agent"]["last_message"].text)
|
||||
```
|
||||
@@ -0,0 +1,114 @@
|
||||
---
|
||||
title: "GitHubFileEditorTool"
|
||||
id: githubfileeditortool
|
||||
slug: "/githubfileeditortool"
|
||||
description: "A Tool that allows Agents and ToolInvokers to edit files in GitHub repositories."
|
||||
---
|
||||
|
||||
# GitHubFileEditorTool
|
||||
|
||||
A Tool that allows Agents and ToolInvokers to edit files in GitHub repositories.
|
||||
|
||||
<div className="key-value-table">
|
||||
|
||||
| | |
|
||||
| --- | --- |
|
||||
| **Mandatory init variables** | `github_token`: GitHub personal access token. Can be set with `GITHUB_TOKEN` env var. |
|
||||
| **API reference** | [Tools](/reference/tools-api) |
|
||||
| **GitHub link** | https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/github |
|
||||
| **Package name** | `github-haystack` |
|
||||
|
||||
</div>
|
||||
|
||||
## Overview
|
||||
|
||||
`GitHubFileEditorTool` wraps the [`GitHubFileEditor`](../../pipeline-components/connectors/githubfileeditor.mdx) component, providing a tool interface for use in agent workflows and tool-based pipelines.
|
||||
|
||||
The tool supports multiple file operations including editing existing files, creating new files, deleting files, and undoing recent changes. It supports four main commands:
|
||||
|
||||
- **EDIT**: Edit an existing file by replacing specific content
|
||||
- **CREATE**: Create a new file with specified content
|
||||
- **DELETE**: Delete an existing file
|
||||
- **UNDO**: Revert the last commit if made by the same user
|
||||
|
||||
### Parameters
|
||||
|
||||
- `name` is _optional_ and defaults to "file_editor". Specifies the name of the tool.
|
||||
- `description` is _optional_ and provides context to the LLM about what the tool does.
|
||||
- `github_token` is _mandatory_ and must be a GitHub personal access token for API authentication. The default setting uses the environment variable `GITHUB_TOKEN`.
|
||||
- `repo` is _optional_ and sets a default repository in owner/repo format.
|
||||
- `branch` is _optional_ and defaults to "main". Sets the default branch to work with.
|
||||
- `raise_on_failure` is _optional_ and defaults to `True`. If False, errors are returned instead of raising exceptions.
|
||||
|
||||
## Usage
|
||||
|
||||
Install the GitHub integration to use the `GitHubFileEditorTool`:
|
||||
|
||||
```shell
|
||||
pip install github-haystack
|
||||
```
|
||||
|
||||
:::info[Repository Placeholder]
|
||||
|
||||
To run the following code snippets, you need to replace the `owner/repo` with your own GitHub repository name.
|
||||
:::
|
||||
|
||||
### On its own
|
||||
|
||||
Basic usage to edit a file:
|
||||
|
||||
```python
|
||||
from haystack_integrations.tools.github import GitHubFileEditorTool
|
||||
|
||||
tool = GitHubFileEditorTool()
|
||||
result = tool.invoke(
|
||||
command="edit",
|
||||
payload={
|
||||
"path": "src/example.py",
|
||||
"original": "def old_function():",
|
||||
"replacement": "def new_function():",
|
||||
"message": "Renamed function for clarity",
|
||||
},
|
||||
repo="owner/repo",
|
||||
branch="main",
|
||||
)
|
||||
|
||||
print(result)
|
||||
```
|
||||
|
||||
```bash
|
||||
{'result': 'Edit successful'}
|
||||
```
|
||||
|
||||
### With an Agent
|
||||
|
||||
You can use `GitHubFileEditorTool` with the [Agent](../../pipeline-components/agents-1/agent.mdx) component. The Agent will automatically invoke the tool when needed to edit files in GitHub repositories.
|
||||
|
||||
```python
|
||||
from haystack.components.generators.chat import OpenAIChatGenerator
|
||||
from haystack.dataclasses import ChatMessage
|
||||
from haystack.components.agents import Agent
|
||||
from haystack_integrations.tools.github import GitHubFileEditorTool
|
||||
|
||||
editor_tool = GitHubFileEditorTool(repo="owner/repo")
|
||||
|
||||
agent = Agent(
|
||||
chat_generator=OpenAIChatGenerator(),
|
||||
tools=[editor_tool],
|
||||
exit_conditions=["text"],
|
||||
)
|
||||
|
||||
response = agent.run(
|
||||
messages=[
|
||||
ChatMessage.from_user(
|
||||
"Edit the file README.md in the repository \"owner/repo\" and replace the original string 'tpyo' with the replacement 'typo'. This is all context you need.",
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
print(response["last_message"].text)
|
||||
```
|
||||
|
||||
```bash
|
||||
The file `README.md` has been successfully edited to correct the spelling of 'tpyo' to 'typo'.
|
||||
```
|
||||
@@ -0,0 +1,101 @@
|
||||
---
|
||||
title: "GitHubIssueCommenterTool"
|
||||
id: githubissuecommentertool
|
||||
slug: "/githubissuecommentertool"
|
||||
description: "A Tool that allows Agents and ToolInvokers to post comments to GitHub issues."
|
||||
---
|
||||
|
||||
# GitHubIssueCommenterTool
|
||||
|
||||
A Tool that allows Agents and ToolInvokers to post comments to GitHub issues.
|
||||
|
||||
<div className="key-value-table">
|
||||
|
||||
| | |
|
||||
| --- | --- |
|
||||
| **Mandatory init variables** | `github_token`: GitHub personal access token. Can be set with `GITHUB_TOKEN` env var. |
|
||||
| **API reference** | [Tools](/reference/tools-api) |
|
||||
| **GitHub link** | https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/github |
|
||||
| **Package name** | `github-haystack` |
|
||||
|
||||
</div>
|
||||
|
||||
## Overview
|
||||
|
||||
`GitHubIssueCommenterTool` wraps the [`GitHubIssueCommenter`](../../pipeline-components/connectors/githubissuecommenter.mdx) component, providing a tool interface for use in agent workflows and tool-based pipelines.
|
||||
|
||||
The tool takes a GitHub issue URL and comment text, then posts the comment to the specified issue using the GitHub API. This requires authentication since posting comments is an authenticated operation.
|
||||
|
||||
### Parameters
|
||||
|
||||
- `name` is _optional_ and defaults to "issue_commenter". Specifies the name of the tool.
|
||||
- `description` is _optional_ and provides context to the LLM about what the tool does.
|
||||
- `github_token` is _mandatory_ and must be a GitHub personal access token for API authentication. The default setting uses the environment variable `GITHUB_TOKEN`.
|
||||
- `raise_on_failure` is _optional_ and defaults to `True`. If False, errors are returned instead of raising exceptions.
|
||||
- `retry_attempts` is _optional_ and defaults to `2`. Number of retry attempts for failed requests.
|
||||
|
||||
## Usage
|
||||
|
||||
Install the GitHub integration to use the `GitHubIssueCommenterTool`:
|
||||
|
||||
```shell
|
||||
pip install github-haystack
|
||||
```
|
||||
|
||||
:::info[Repository Placeholder]
|
||||
|
||||
To run the following code snippets, you need to replace the `owner/repo` with your own GitHub repository name.
|
||||
:::
|
||||
|
||||
### On its own
|
||||
|
||||
Basic usage to comment on an issue:
|
||||
|
||||
```python
|
||||
from haystack_integrations.tools.github import GitHubIssueCommenterTool
|
||||
|
||||
tool = GitHubIssueCommenterTool()
|
||||
result = tool.invoke(
|
||||
url="https://github.com/owner/repo/issues/123",
|
||||
comment="Thanks for reporting this issue! We'll look into it.",
|
||||
)
|
||||
|
||||
print(result)
|
||||
```
|
||||
|
||||
```bash
|
||||
{'success': True}
|
||||
```
|
||||
|
||||
### With an Agent
|
||||
|
||||
You can use `GitHubIssueCommenterTool` with the [Agent](../../pipeline-components/agents-1/agent.mdx) component. The Agent will automatically invoke the tool when needed to post comments on GitHub issues.
|
||||
|
||||
```python
|
||||
from haystack.components.generators.chat import OpenAIChatGenerator
|
||||
from haystack.dataclasses import ChatMessage
|
||||
from haystack.components.agents import Agent
|
||||
from haystack_integrations.tools.github import GitHubIssueCommenterTool
|
||||
|
||||
comment_tool = GitHubIssueCommenterTool(name="github_issue_commenter")
|
||||
|
||||
agent = Agent(
|
||||
chat_generator=OpenAIChatGenerator(),
|
||||
tools=[comment_tool],
|
||||
exit_conditions=["text"],
|
||||
)
|
||||
|
||||
response = agent.run(
|
||||
messages=[
|
||||
ChatMessage.from_user(
|
||||
"Please post a helpful comment on this GitHub issue: https://github.com/owner/repo/issues/123 acknowledging the bug report and mentioning that we're investigating",
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
print(response["last_message"].text)
|
||||
```
|
||||
|
||||
```bash
|
||||
I have posted the comment on the GitHub issue, acknowledging the bug report and mentioning that the team is investigating the problem. If you need anything else, feel free to ask!
|
||||
```
|
||||
@@ -0,0 +1,109 @@
|
||||
---
|
||||
title: "GitHubIssueViewerTool"
|
||||
id: githubissueviewertool
|
||||
slug: "/githubissueviewertool"
|
||||
description: "A Tool that allows Agents and ToolInvokers to fetch and parse GitHub issues into documents."
|
||||
---
|
||||
|
||||
# GitHubIssueViewerTool
|
||||
|
||||
A Tool that allows Agents and ToolInvokers to fetch and parse GitHub issues into documents.
|
||||
|
||||
<div className="key-value-table">
|
||||
|
||||
| | |
|
||||
| --- | --- |
|
||||
| **API reference** | [Tools](/reference/tools-api) |
|
||||
| **GitHub link** | https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/github |
|
||||
| **Package name** | `github-haystack` |
|
||||
|
||||
</div>
|
||||
|
||||
## Overview
|
||||
|
||||
`GitHubIssueViewerTool` wraps the [`GitHubIssueViewer`](../../pipeline-components/connectors/githubissueviewer.mdx) component, providing a tool interface for use in agent workflows and tool-based pipelines.
|
||||
|
||||
The tool takes a GitHub issue URL and returns a list of documents where:
|
||||
|
||||
- The first document contains the main issue content,
|
||||
- Subsequent documents contain the issue comments (if any).
|
||||
|
||||
Each document includes rich metadata such as the issue title, number, state, creation date, author, and more.
|
||||
|
||||
### Parameters
|
||||
|
||||
- `name` is _optional_ and defaults to "issue_viewer". Specifies the name of the tool.
|
||||
- `description` is _optional_ and provides context to the LLM about what the tool does.
|
||||
- `github_token` is _optional_ but recommended for private repositories or to avoid rate limiting.
|
||||
- `raise_on_failure` is _optional_ and defaults to `True`. If False, errors are returned as documents instead of raising exceptions.
|
||||
- `retry_attempts` is _optional_ and defaults to `2`. Number of retry attempts for failed requests.
|
||||
|
||||
## Usage
|
||||
|
||||
Install the GitHub integration to use the `GitHubIssueViewerTool`:
|
||||
|
||||
```shell
|
||||
pip install github-haystack
|
||||
```
|
||||
|
||||
:::info[Repository Placeholder]
|
||||
|
||||
To run the following code snippets, you need to replace the `owner/repo` with your own GitHub repository name.
|
||||
:::
|
||||
|
||||
### On its own
|
||||
|
||||
```python
|
||||
from haystack_integrations.tools.github import GitHubIssueViewerTool
|
||||
|
||||
tool = GitHubIssueViewerTool()
|
||||
result = tool.invoke(url="https://github.com/deepset-ai/haystack/issues/123")
|
||||
|
||||
print(result)
|
||||
```
|
||||
|
||||
```bash
|
||||
{'documents': [Document(id=3989459bbd8c2a8420a9ba7f3cd3cf79bb41d78bd0738882e57d509e1293c67a, content: 'sentence-transformers = 0.2.6.1
|
||||
haystack = latest
|
||||
farm = 0.4.3 latest branch
|
||||
|
||||
In the call to Emb...', meta: {'type': 'issue', 'title': 'SentenceTransformer no longer accepts \'gpu" as argument', 'number': 123, 'state': 'closed', 'created_at': '2020-05-28T04:49:31Z', 'updated_at': '2020-05-28T07:11:43Z', 'author': 'predoctech', 'url': 'https://github.com/deepset-ai/haystack/issues/123'}), Document(id=a8a56b9ad119244678804d5873b13da0784587773d8f839e07f644c4d02c167a, content: 'Thanks for reporting!
|
||||
Fixed with #124 ', meta: {'type': 'comment', 'issue_number': 123, 'created_at': '2020-05-28T07:11:42Z', 'updated_at': '2020-05-28T07:11:42Z', 'author': 'tholor', 'url': 'https://github.com/deepset-ai/haystack/issues/123#issuecomment-635153940'})]}
|
||||
```
|
||||
|
||||
### With an Agent
|
||||
|
||||
You can use `GitHubIssueViewerTool` with the [Agent](../../pipeline-components/agents-1/agent.mdx) component. The Agent will automatically invoke the tool when needed to fetch GitHub issue information.
|
||||
|
||||
```python
|
||||
from haystack.components.generators.chat import OpenAIChatGenerator
|
||||
from haystack.dataclasses import ChatMessage
|
||||
from haystack.components.agents import Agent
|
||||
from haystack_integrations.tools.github import GitHubIssueViewerTool
|
||||
|
||||
issue_tool = GitHubIssueViewerTool(name="github_issue_viewer")
|
||||
|
||||
agent = Agent(
|
||||
chat_generator=OpenAIChatGenerator(),
|
||||
tools=[issue_tool],
|
||||
exit_conditions=["text"],
|
||||
)
|
||||
|
||||
response = agent.run(
|
||||
messages=[
|
||||
ChatMessage.from_user(
|
||||
"Please analyze this GitHub issue and summarize the main problem: https://github.com/deepset-ai/haystack/issues/123",
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
print(response["last_message"].text)
|
||||
```
|
||||
|
||||
```bash
|
||||
The GitHub issue titled "SentenceTransformer no longer accepts 'gpu' as argument" (issue \#123) discusses a problem encountered when using the `EmbeddingRetriever()` function. The user reports that passing the argument `gpu=True` now causes an error because the method that processes this argument does not accept "gpu" anymore; instead, it previously accepted "cuda" without issues.
|
||||
|
||||
The user indicates that this change is problematic since it prevents users from instantiating the embedding model with GPU support, forcing them to default to using only the CPU for model execution.
|
||||
|
||||
The issue was later closed with a comment indicating it was fixed in another pull request (#124).
|
||||
```
|
||||
@@ -0,0 +1,103 @@
|
||||
---
|
||||
title: "GitHubPRCreatorTool"
|
||||
id: githubprcreatortool
|
||||
slug: "/githubprcreatortool"
|
||||
description: "A Tool that allows Agents and ToolInvokers to create pull requests from a fork back to the original repository."
|
||||
---
|
||||
|
||||
# GitHubPRCreatorTool
|
||||
|
||||
A Tool that allows Agents and ToolInvokers to create pull requests from a fork back to the original repository.
|
||||
|
||||
<div className="key-value-table">
|
||||
|
||||
| | |
|
||||
| --- | --- |
|
||||
| **Mandatory init variables** | `github_token`: GitHub personal access token. Can be set with `GITHUB_TOKEN` env var. |
|
||||
| **API reference** | [Tools](/reference/tools-api) |
|
||||
| **GitHub link** | https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/github |
|
||||
| **Package name** | `github-haystack` |
|
||||
|
||||
</div>
|
||||
|
||||
## Overview
|
||||
|
||||
`GitHubPRCreatorTool` wraps the [`GitHubPRCreator`](../../pipeline-components/connectors/githubprcreator.mdx) component, providing a tool interface for use in agent workflows and tool-based pipelines.
|
||||
|
||||
The tool takes a GitHub issue URL and creates a pull request from your fork to the original repository, automatically linking it to the specified issue. It's designed to work with existing forks and assumes you have already made changes in a branch.
|
||||
|
||||
### Parameters
|
||||
|
||||
- `name` is _optional_ and defaults to "pr_creator". Specifies the name of the tool.
|
||||
- `description` is _optional_ and provides context to the LLM about what the tool does.
|
||||
- `github_token` is _mandatory_ and must be a GitHub personal access token from the fork owner. The default setting uses the environment variable `GITHUB_TOKEN`.
|
||||
- `raise_on_failure` is _optional_ and defaults to `True`. If False, errors are returned instead of raising exceptions.
|
||||
|
||||
## Usage
|
||||
|
||||
Install the GitHub integration to use the `GitHubPRCreatorTool`:
|
||||
|
||||
```shell
|
||||
pip install github-haystack
|
||||
```
|
||||
|
||||
:::info[Repository Placeholder]
|
||||
|
||||
To run the following code snippets, you need to replace the `owner/repo` with your own GitHub repository name.
|
||||
:::
|
||||
|
||||
### On its own
|
||||
|
||||
Basic usage to create a pull request:
|
||||
|
||||
```python
|
||||
from haystack_integrations.tools.github import GitHubPRCreatorTool
|
||||
|
||||
tool = GitHubPRCreatorTool()
|
||||
result = tool.invoke(
|
||||
issue_url="https://github.com/owner/repo/issues/123",
|
||||
title="Fix issue #123",
|
||||
body="This PR addresses issue #123 by implementing the requested changes.",
|
||||
branch="fix-123", # Branch in your fork with the changes
|
||||
base="main", # Branch in original repo to merge into
|
||||
)
|
||||
|
||||
print(result)
|
||||
```
|
||||
|
||||
```bash
|
||||
{'result': 'Pull request #16 created successfully and linked to issue #4'}
|
||||
```
|
||||
|
||||
### With an Agent
|
||||
|
||||
You can use `GitHubPRCreatorTool` with the [Agent](../../pipeline-components/agents-1/agent.mdx) component. The Agent will automatically invoke the tool when needed to create pull requests.
|
||||
|
||||
```python
|
||||
from haystack.components.generators.chat import OpenAIChatGenerator
|
||||
from haystack.dataclasses import ChatMessage
|
||||
from haystack.components.agents import Agent
|
||||
from haystack_integrations.tools.github import GitHubPRCreatorTool
|
||||
|
||||
pr_tool = GitHubPRCreatorTool(name="github_pr_creator")
|
||||
|
||||
agent = Agent(
|
||||
chat_generator=OpenAIChatGenerator(),
|
||||
tools=[pr_tool],
|
||||
exit_conditions=["text"],
|
||||
)
|
||||
|
||||
response = agent.run(
|
||||
messages=[
|
||||
ChatMessage.from_user(
|
||||
"Create a pull request for issue https://github.com/owner/repo/issues/4 with title 'Fix authentication bug' and empty body using my fix-4 branch and main as target branch",
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
print(response["last_message"].text)
|
||||
```
|
||||
|
||||
```bash
|
||||
The pull request titled "Fix authentication bug" has been created successfully and linked to issue [#123](https://github.com/owner/repo/issues/4).
|
||||
```
|
||||
@@ -0,0 +1,137 @@
|
||||
---
|
||||
title: "GitHubRepoViewerTool"
|
||||
id: githubrepoviewertool
|
||||
slug: "/githubrepoviewertool"
|
||||
description: "A Tool that allows Agents and ToolInvokers to navigate and fetch content from GitHub repositories."
|
||||
---
|
||||
|
||||
# GitHubRepoViewerTool
|
||||
|
||||
A Tool that allows Agents and ToolInvokers to navigate and fetch content from GitHub repositories.
|
||||
|
||||
<div className="key-value-table">
|
||||
|
||||
| | |
|
||||
| --- | --- |
|
||||
| **API reference** | [Tools](/reference/tools-api) |
|
||||
| **GitHub link** | https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/github |
|
||||
| **Package name** | `github-haystack` |
|
||||
|
||||
</div>
|
||||
|
||||
## Overview
|
||||
|
||||
`GitHubRepoViewerTool` wraps the [`GitHubRepoViewer`](../../pipeline-components/connectors/githubrepoviewer.mdx) component, providing a tool interface for use in agent workflows and tool-based pipelines.
|
||||
|
||||
The tool provides different behavior based on the path type:
|
||||
|
||||
- **For directories**: Returns a list of documents, one for each item (files and subdirectories),
|
||||
- **For files**: Returns a single document containing the file content.
|
||||
|
||||
Each document includes rich metadata such as the path, type, size, and URL.
|
||||
|
||||
### Parameters
|
||||
|
||||
- `name` is _optional_ and defaults to "repo_viewer". Specifies the name of the tool.
|
||||
- `description` is _optional_ and provides context to the LLM about what the tool does.
|
||||
- `github_token` is _optional_ but recommended for private repositories or to avoid rate limiting.
|
||||
- `repo` is _optional_ and sets a default repository in owner/repo format.
|
||||
- `branch` is _optional_ and defaults to "main". Sets the default branch to work with.
|
||||
- `raise_on_failure` is _optional_ and defaults to `True`. If False, errors are returned as documents instead of raising exceptions.
|
||||
- `max_file_size` is _optional_ and defaults to `1,000,000` bytes (1MB). Maximum file size to fetch.
|
||||
|
||||
## Usage
|
||||
|
||||
Install the GitHub integration to use the `GitHubRepoViewerTool`:
|
||||
|
||||
```shell
|
||||
pip install github-haystack
|
||||
```
|
||||
|
||||
:::info[Repository Placeholder]
|
||||
|
||||
To run the following code snippets, you need to replace the `owner/repo` with your own GitHub repository name.
|
||||
:::
|
||||
|
||||
### On its own
|
||||
|
||||
Basic usage to view repository contents:
|
||||
|
||||
```python
|
||||
from haystack_integrations.tools.github import GitHubRepoViewerTool
|
||||
|
||||
tool = GitHubRepoViewerTool()
|
||||
result = tool.invoke(
|
||||
repo="deepset-ai/haystack",
|
||||
path="haystack/components",
|
||||
branch="main",
|
||||
)
|
||||
|
||||
print(result)
|
||||
```
|
||||
|
||||
```bash
|
||||
{'documents': [Document(id=..., content: 'agents', meta: {'path': 'haystack/components/agents', 'type': 'dir', 'size': 0, 'url': 'https://github.com/deepset-ai/haystack/tree/main/haystack/components/agents'}), Document(id=..., content: 'audio', meta: {'path': 'haystack/components/audio', 'type': 'dir', 'size': 0, 'url': 'https://github.com/deepset-ai/haystack/tree/main/haystack/components/audio'}),...]}
|
||||
```
|
||||
|
||||
### With an Agent
|
||||
|
||||
You can use `GitHubRepoViewerTool` with the [Agent](../../pipeline-components/agents-1/agent.mdx) component. The Agent will automatically invoke the tool when needed to explore repository structure and read files.
|
||||
|
||||
Note that we set the Agent's `state_schema` parameter in this code example so that the GitHubRepoViewerTool can write documents to the state.
|
||||
|
||||
```python
|
||||
from typing import List
|
||||
|
||||
from haystack.components.generators.chat import OpenAIChatGenerator
|
||||
from haystack.dataclasses import ChatMessage, Document
|
||||
from haystack.components.agents import Agent
|
||||
from haystack_integrations.tools.github import GitHubRepoViewerTool
|
||||
|
||||
repo_tool = GitHubRepoViewerTool(name="github_repo_viewer")
|
||||
|
||||
agent = Agent(
|
||||
chat_generator=OpenAIChatGenerator(),
|
||||
tools=[repo_tool],
|
||||
exit_conditions=["text"],
|
||||
state_schema={"documents": {"type": List[Document]}},
|
||||
)
|
||||
|
||||
response = agent.run(
|
||||
messages=[
|
||||
ChatMessage.from_user(
|
||||
"Can you analyze the structure of the deepset-ai/haystack repository and tell me about the main components?",
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
print(response["last_message"].text)
|
||||
```
|
||||
|
||||
```bash
|
||||
The `deepset-ai/haystack` repository has a structured layout that includes several important components. Here's an overview of its main parts:
|
||||
|
||||
1. **Directories**:
|
||||
- **`.github`**: Contains GitHub-specific configuration files and workflows.
|
||||
- **`docker`**: Likely includes Docker-related files for containerization of the Haystack application.
|
||||
- **`docs`**: Contains documentation for the Haystack project. This could include guides, API documentation, and other related resources.
|
||||
- **`e2e`**: This likely stands for "end-to-end", possibly containing tests or examples related to end-to-end functionality of the Haystack framework.
|
||||
- **`examples`**: Includes example scripts or notebooks demonstrating how to use Haystack.
|
||||
- **`haystack`**: This is likely the core source code of the Haystack framework itself, containing the main functionality and classes.
|
||||
- **`proposals`**: A directory that may contain proposals for new features or changes to the Haystack project.
|
||||
- **`releasenotes`**: Contains notes about various releases, including changes and improvements.
|
||||
- **`test`**: This directory likely contains unit tests and other testing utilities to ensure code quality and functionality.
|
||||
|
||||
2. **Files**:
|
||||
- **`.gitignore`**: Specifies files and directories that should be ignored by Git.
|
||||
- **`.pre-commit-config.yaml`**: Configuration file for pre-commit hooks to automate code quality checks.
|
||||
- **`CITATION.cff`**: Might include information on how to cite the repository in academic work.
|
||||
- **`code_of_conduct.txt`**: Contains the code of conduct for contributors and users of the repository.
|
||||
- **`CONTRIBUTING.md`**: Guidelines for contributing to the repository.
|
||||
- **`LICENSE`**: The license under which the project is distributed.
|
||||
- **`VERSION.txt`**: Contains versioning information for the project.
|
||||
- **`README.md`**: A markdown file that usually provides an overview of the project, installation instructions, and usage examples.
|
||||
- **`SECURITY.md`**: Contains information about the security policy of the repository.
|
||||
|
||||
This structure indicates a well-organized repository that follows common conventions in open-source projects, with a focus on documentation, contribution guidelines, and testing. The core functionalities are likely housed in the `haystack` directory, with additional resources provided in the other directories.
|
||||
```
|
||||
@@ -0,0 +1,170 @@
|
||||
---
|
||||
title: "Mem0 Memory Tools"
|
||||
id: mem0memorytools
|
||||
slug: "/mem0memorytools"
|
||||
description: "Tools that allow Agents to retrieve and store long-term memories with Mem0."
|
||||
---
|
||||
|
||||
# Mem0 Memory Tools
|
||||
|
||||
The Mem0 integration provides two ready-made Tools for Agent memory workflows:
|
||||
|
||||
- **`retrieve_memories`** (`Mem0MemoryRetrieverTool`) searches long-term memories, or returns all scoped memories when no query is provided.
|
||||
- **`store_memory`** (`Mem0MemoryWriterTool`) stores durable facts, preferences, and context as long-term memories.
|
||||
|
||||
<div className="key-value-table">
|
||||
|
||||
| | |
|
||||
| --- | --- |
|
||||
| **Mandatory init variables** | `memory_store`: A `Mem0MemoryStore` instance. |
|
||||
| **Environment variables** | `MEM0_API_KEY`: Your Mem0 cloud API key. |
|
||||
| **Mem0 API docs** | [Search Memories](https://docs.mem0.ai/api-reference/memory/search-memories), [Add Memories](https://docs.mem0.ai/api-reference/memory/add-memories) |
|
||||
| **API reference** | [Mem0](/reference/integrations-mem0) |
|
||||
| **GitHub link** | https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/mem0 |
|
||||
| **Package name** | `mem0-haystack` |
|
||||
|
||||
</div>
|
||||
|
||||
## Overview
|
||||
|
||||
Use these tools when an [Agent](../../pipeline-components/agents-1/agent.mdx) needs persistent memory across conversations. The retriever tool gives the Agent access to memories stored in Mem0, and the writer tool lets the Agent save new information that should be useful in future runs.
|
||||
|
||||
Both tools use a shared `Mem0MemoryStore`. By default, they inject `user_id` from [Agent State](../../pipeline-components/agents-1/state.mdx) through `inputs_from_state`, so one Agent instance can serve multiple users without exposing user IDs to the LLM as tool-call parameters.
|
||||
|
||||
`Mem0MemoryRetrieverTool` exposes `query` and `top_k` to the LLM. If the Agent omits `query` or passes `null`, the tool returns all memories in the injected scope. This is useful when the Agent needs to inspect known context before deciding whether a more specific memory search is necessary.
|
||||
|
||||
`Mem0MemoryWriterTool` exposes `text` and `infer` to the LLM. The writer tool uses `infer=False` by default so the Agent stores exactly the memory text it chose. Use `infer=True` when you want Mem0 to extract memories from longer text, such as a conversation transcript.
|
||||
|
||||
### Parameters
|
||||
|
||||
`Mem0MemoryRetrieverTool`:
|
||||
|
||||
- `memory_store` is _mandatory_. It is the `Mem0MemoryStore` instance to query.
|
||||
- `top_k` is _optional_ and defaults to `5`. It sets the default maximum number of memories returned for query searches.
|
||||
- `name` is _optional_ and defaults to `"retrieve_memories"`.
|
||||
- `description` is _optional_ and describes the tool to the LLM.
|
||||
- `parameters` is _optional_ and lets you override the JSON schema exposed to the LLM.
|
||||
- `inputs_from_state` is _optional_ and defaults to `{"user_id": "user_id"}`.
|
||||
|
||||
`Mem0MemoryWriterTool`:
|
||||
|
||||
- `memory_store` is _mandatory_. It is the `Mem0MemoryStore` instance to write to.
|
||||
- `name` is _optional_ and defaults to `"store_memory"`.
|
||||
- `description` is _optional_ and describes the tool to the LLM.
|
||||
- `parameters` is _optional_ and lets you override the JSON schema exposed to the LLM.
|
||||
- `inputs_from_state` is _optional_ and defaults to `{"user_id": "user_id"}`.
|
||||
|
||||
To pass more Mem0 entity IDs at runtime, add the fields to the Agent's `state_schema` and map those State keys to the tool parameters with `inputs_from_state`. For example, `{"user_id": "user_id", "session_id": "run_id"}` passes `state["session_id"]` to the tool's `run_id` parameter.
|
||||
|
||||
At least one Mem0 scope must be available when retrieving or storing memories. Use `user_id` for the common per-user case, or add `run_id`, `agent_id`, or `app_id` when your application needs a narrower scope.
|
||||
|
||||
## Usage
|
||||
|
||||
Install the Mem0 integration:
|
||||
|
||||
```shell
|
||||
pip install mem0-haystack
|
||||
```
|
||||
|
||||
Set your Mem0 API key:
|
||||
|
||||
```shell
|
||||
export MEM0_API_KEY="your-mem0-api-key"
|
||||
```
|
||||
|
||||
### With an Agent
|
||||
|
||||
You can use both tools with an Agent to read memories at the beginning of a turn and write new durable memories before the final answer.
|
||||
|
||||
```python
|
||||
from haystack.components.agents import Agent
|
||||
from haystack.components.generators.chat import OpenAIChatGenerator
|
||||
from haystack.components.generators.utils import print_streaming_chunk
|
||||
from haystack.dataclasses import ChatMessage
|
||||
|
||||
from haystack_integrations.memory_stores.mem0 import Mem0MemoryStore
|
||||
from haystack_integrations.tools.mem0 import (
|
||||
Mem0MemoryRetrieverTool,
|
||||
Mem0MemoryWriterTool,
|
||||
)
|
||||
|
||||
store = Mem0MemoryStore()
|
||||
|
||||
retrieve_memories = Mem0MemoryRetrieverTool(memory_store=store, top_k=10)
|
||||
store_memory = Mem0MemoryWriterTool(memory_store=store)
|
||||
|
||||
agent = Agent(
|
||||
chat_generator=OpenAIChatGenerator(model="gpt-5.4"),
|
||||
tools=[retrieve_memories, store_memory],
|
||||
system_prompt="""You are a helpful assistant with long-term memory.
|
||||
|
||||
At the beginning of each turn, call retrieve_memories without a query to inspect known memories.
|
||||
Use store_memory only for new durable user-specific facts, preferences, or project context.
|
||||
Before storing, compare the proposed memory with retrieved memories and avoid duplicates.
|
||||
Do not store transient requests that are only useful in the current conversation.
|
||||
""",
|
||||
streaming_callback=print_streaming_chunk,
|
||||
state_schema={"user_id": {"type": str}},
|
||||
)
|
||||
|
||||
result = agent.run(
|
||||
messages=[
|
||||
ChatMessage.from_user(
|
||||
"My name is Alice. Please remember that I prefer concise Python examples.",
|
||||
),
|
||||
],
|
||||
user_id="alice",
|
||||
)
|
||||
```
|
||||
|
||||
### Pass more IDs through State
|
||||
|
||||
Mem0 supports scoping memories with `user_id`, `run_id`, `agent_id`, and `app_id`. The tools expose only `user_id` by default, but you can inject more IDs through Agent State without adding them to the LLM-facing parameter schema.
|
||||
|
||||
```python
|
||||
from haystack.components.agents import Agent
|
||||
from haystack.components.generators.chat import OpenAIChatGenerator
|
||||
from haystack.components.generators.utils import print_streaming_chunk
|
||||
from haystack_integrations.memory_stores.mem0 import Mem0MemoryStore
|
||||
from haystack_integrations.tools.mem0 import (
|
||||
Mem0MemoryRetrieverTool,
|
||||
Mem0MemoryWriterTool,
|
||||
)
|
||||
|
||||
store = Mem0MemoryStore()
|
||||
|
||||
inputs_from_state = {
|
||||
"user_id": "user_id",
|
||||
# Map the Agent State key "conversation_id" to the tool's "run_id" parameter.
|
||||
"conversation_id": "run_id",
|
||||
}
|
||||
|
||||
retrieve_memories = Mem0MemoryRetrieverTool(
|
||||
memory_store=store,
|
||||
inputs_from_state=inputs_from_state,
|
||||
)
|
||||
store_memory = Mem0MemoryWriterTool(
|
||||
memory_store=store,
|
||||
inputs_from_state=inputs_from_state,
|
||||
)
|
||||
|
||||
agent = Agent(
|
||||
chat_generator=OpenAIChatGenerator(model="gpt-5.4"),
|
||||
tools=[retrieve_memories, store_memory],
|
||||
state_schema={
|
||||
"user_id": {"type": str},
|
||||
"conversation_id": {"type": str},
|
||||
},
|
||||
streaming_callback=print_streaming_chunk,
|
||||
)
|
||||
|
||||
result = agent.run(
|
||||
messages=[
|
||||
ChatMessage.from_user(
|
||||
"Remember that this conversation is about the docs assistant prototype.",
|
||||
),
|
||||
],
|
||||
user_id="alice",
|
||||
conversation_id="docs-assistant-prototype",
|
||||
)
|
||||
```
|
||||
@@ -0,0 +1,172 @@
|
||||
---
|
||||
title: "MirageShellTool"
|
||||
id: mirageshelltool
|
||||
slug: "/mirageshelltool"
|
||||
description: "A Tool that gives Agents a bash shell over a Mirage unified virtual filesystem, mounting backends like S3, Google Drive, and Postgres as one file tree."
|
||||
---
|
||||
|
||||
# MirageShellTool
|
||||
|
||||
A Tool that gives Agents a bash shell over a [Mirage](https://github.com/strukto-ai/mirage) unified virtual filesystem, mounting backends like S3, Google Drive, and Postgres as one file tree.
|
||||
|
||||
<div className="key-value-table">
|
||||
|
||||
| | |
|
||||
| --- | --- |
|
||||
| **Mandatory init variables** | `workspace`: A `MirageWorkspace` describing the mount tree the Agent can access. |
|
||||
| **API reference** | [Mirage](/reference/integrations-mirage) |
|
||||
| **GitHub link** | https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/mirage |
|
||||
| **Package name** | `mirage-haystack` |
|
||||
|
||||
</div>
|
||||
|
||||
## Overview
|
||||
|
||||
`MirageShellTool` hands an [Agent](../../pipeline-components/agents-1/agent.mdx) a single shell over a [Mirage](https://github.com/strukto-ai/mirage) *unified virtual filesystem*: one directory tree that mounts heterogeneous backends — object storage, databases, SaaS apps, and local disk — side by side. Instead of pre-loading file contents into the prompt, the Agent explores the mounted data itself by running ordinary bash commands (`ls`, `cat`, `grep`, `wc`, …). Command output is normalized to text and truncated before it reaches the model.
|
||||
|
||||
The tool is backed by two serializable helpers you compose the workspace with:
|
||||
|
||||
- **`MirageWorkspace`**: A description of the mount tree that lazily builds a live Mirage workspace. It is the shared backend behind the tool, and you can also use it directly — without an Agent — through its `run()` / `run_async()` methods.
|
||||
- **`MirageMount`**: A declarative description of a single backend: *where* it is mounted (`path`), *which* backend it is (`resource`, a Mirage registry name such as `"s3"`, `"gdrive"`, `"postgres"`, `"disk"`, or `"ram"`), and *how* it is configured (`config`). Credentials can be passed as Haystack `Secret`s and are resolved only when the live workspace is built.
|
||||
|
||||
Because every backend is mounted the same way, one tool gives the Agent uniform access to S3, Google Drive, Slack, Gmail, Redis, Postgres, local disk, and more — swap a `MirageMount` and the Agent's commands stay the same. Mirage never shells out to the host, so the Agent's blast radius is confined to the mounts you attach (see [Security model](#security-model)).
|
||||
|
||||
### Parameters
|
||||
|
||||
- `workspace` is _mandatory_ and must be a `MirageWorkspace` describing the mounts the Agent can access.
|
||||
- `name` is _optional_ and defaults to `"mirage_shell"`. Sets the tool name exposed to the LLM.
|
||||
- `description` is _optional_. A custom tool description; when not set, one is generated from the mount tree.
|
||||
- `invocation_timeout` is _optional_ and defaults to `60.0`. Maximum seconds to wait for a command to finish.
|
||||
- `max_output_chars` is _optional_ and defaults to `20000`. Command output is truncated to this many characters before being returned to the model.
|
||||
- `allowed_commands` is _optional_. If set, only these command names may run (for example `["ls", "cat", "grep"]`). See [Security model](#security-model).
|
||||
- `denied_paths` is _optional_. If set, any command referencing one of these path substrings is rejected.
|
||||
|
||||
## Usage
|
||||
|
||||
Install the Mirage integration to use `MirageShellTool`:
|
||||
|
||||
```shell
|
||||
pip install mirage-haystack
|
||||
```
|
||||
|
||||
### With an Agent
|
||||
|
||||
You can use `MirageShellTool` with the [Agent](../../pipeline-components/agents-1/agent.mdx) component. The Agent starts the workspace on `warm_up()`, then drives the tool with bash to answer questions by exploring the mounted files itself.
|
||||
|
||||
The example below builds a small "log triage" Agent. A directory of log files is mounted read-only, and the Agent inspects it with bash to answer a question. It uses a local `disk` mount so it is fully self-contained; swap the `MirageMount` for `s3`, `gdrive`, `postgres`, … to point the same Agent at a different backend.
|
||||
|
||||
```python
|
||||
import os
|
||||
import tempfile
|
||||
|
||||
from haystack.components.agents import Agent
|
||||
from haystack.components.generators.chat import OpenAIChatGenerator
|
||||
from haystack.dataclasses import ChatMessage
|
||||
|
||||
from haystack_integrations.tools.mirage import (
|
||||
MirageMount,
|
||||
MirageShellTool,
|
||||
MirageWorkspace,
|
||||
)
|
||||
|
||||
# Create some sample data on disk (in a real setup this already exists).
|
||||
data_dir = tempfile.mkdtemp(prefix="mirage-logs-")
|
||||
with open(os.path.join(data_dir, "api.log"), "w") as fh:
|
||||
fh.write(
|
||||
"INFO request /health 200\nERROR db connection timeout\nERROR db connection timeout\n",
|
||||
)
|
||||
with open(os.path.join(data_dir, "worker.log"), "w") as fh:
|
||||
fh.write("INFO job 41 done\nERROR job 42 failed: OutOfMemory\n")
|
||||
|
||||
# Describe the workspace. The read-only mount is the authoritative write boundary:
|
||||
# Mirage refuses any write to it regardless of the command the model chooses.
|
||||
workspace = MirageWorkspace(
|
||||
mounts=[
|
||||
MirageMount(
|
||||
path="/logs",
|
||||
resource="disk",
|
||||
config={"root": data_dir},
|
||||
read_only=True,
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
tool = MirageShellTool(workspace, allowed_commands=["ls", "cat", "grep", "head", "wc"])
|
||||
|
||||
agent = Agent(
|
||||
chat_generator=OpenAIChatGenerator(model="gpt-4o-mini"),
|
||||
tools=[tool],
|
||||
system_prompt=(
|
||||
"You are a log-triage assistant. A virtual filesystem is available through the `mirage_shell` "
|
||||
"tool. Use bash commands (ls, cat, grep, wc, ...) to inspect the mounted files under /logs before "
|
||||
"answering. Base your answer only on what the files actually show."
|
||||
),
|
||||
)
|
||||
|
||||
response = agent.run(
|
||||
messages=[
|
||||
ChatMessage.from_user(
|
||||
"Across all files in /logs, what is the single most common ERROR message, "
|
||||
"and how many times does it occur?",
|
||||
),
|
||||
],
|
||||
)
|
||||
print(response["last_message"].text)
|
||||
|
||||
tool.close()
|
||||
```
|
||||
|
||||
### Running commands without an Agent
|
||||
|
||||
`MirageWorkspace` can be used on its own, which is handy for testing a mount tree or building non-agentic pipelines. When using it standalone, call `warm_up()` before the first invocation (or let the first `run()` build it lazily) and `close()` when you are done to release resources.
|
||||
|
||||
```python
|
||||
from haystack_integrations.tools.mirage import MirageMount, MirageWorkspace
|
||||
|
||||
workspace = MirageWorkspace(
|
||||
mounts=[
|
||||
MirageMount(path="/data", resource="ram"), # in-memory scratch space
|
||||
MirageMount(
|
||||
path="/s3",
|
||||
resource="s3",
|
||||
config={"bucket": "my-bucket"},
|
||||
read_only=True,
|
||||
),
|
||||
],
|
||||
)
|
||||
print(workspace.run("ls /s3"))
|
||||
print(workspace.run("grep -r alert /s3/logs | wc -l"))
|
||||
workspace.close()
|
||||
```
|
||||
|
||||
### Mounting credentialed backends
|
||||
|
||||
Backends that need credentials take them through `config`. Pass secrets as Haystack `Secret`s so they are resolved only when the live workspace is built and are never serialized in plaintext:
|
||||
|
||||
```python
|
||||
from haystack.utils import Secret
|
||||
from haystack_integrations.tools.mirage import MirageMount
|
||||
|
||||
MirageMount(path="/data", resource="ram") # in-memory scratch
|
||||
MirageMount(path="/local", resource="disk", config={"root": "/srv/data"}) # local disk
|
||||
MirageMount(path="/s3", resource="s3", config={"bucket": "my-bucket"}, read_only=True)
|
||||
MirageMount(
|
||||
path="/drive",
|
||||
resource="gdrive",
|
||||
config={
|
||||
"client_id": "...",
|
||||
"refresh_token": Secret.from_env_var("GDRIVE_REFRESH_TOKEN"),
|
||||
},
|
||||
read_only=True,
|
||||
)
|
||||
```
|
||||
|
||||
Discover the backend names available in your Mirage install with `MirageMount.available_resources()`; the config keys each backend expects come from that backend's Mirage config class.
|
||||
|
||||
## Security model
|
||||
|
||||
Mirage never shells out to the host: every command runs inside Mirage's own virtual-filesystem interpreter, so an Agent's blast radius is confined to the mounts you attach. Two controls shape what an Agent can do:
|
||||
|
||||
- **Per-mount read-only mode** (`MirageMount(..., read_only=True)`) is the authoritative write boundary. Mirage refuses any write to a read-only mount regardless of the command used — this is how you prevent modification or deletion. Mount anything the Agent should not change as read-only.
|
||||
- **The command allowlist** (`allowed_commands`) restricts *which* commands may run. It is enforced against every command Mirage would execute, including commands nested inside `$(...)`, backticks, `<(...)`, and subshells, so `ls "$(rm x)"` is rejected unless `rm` is also allowed. Treat it as a best-effort filter to steer the Agent, not a sandbox: allowing a command that itself runs other commands (`eval`, `bash`, `sh`, `source`, `xargs`, `timeout`) effectively allows anything, so do not list those for untrusted or hosted use.
|
||||
- **`denied_paths`** rejects any command whose text references one of the given path substrings.
|
||||
Reference in New Issue
Block a user