Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,11 @@ async def async_main():
args = parser.parse_args()

if os.path.exists(args.logs_path):
os.remove(args.logs_path)
try:
os.remove(args.logs_path)
except PermissionError:
# File is in use, just continue
pass
logger_for_agent_logs = logging.getLogger("agent_logs")
logger_for_agent_logs.setLevel(logging.DEBUG)
# Prevent propagation to root logger to avoid duplicate logs
Expand Down
2 changes: 1 addition & 1 deletion frontend/components/question-input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ const QuestionInput = ({

<div className="flex items-center gap-x-2">
<Tooltip>
<TooltipTrigger>
<TooltipTrigger asChild>
<Button
variant="ghost"
size="icon"
Expand Down
31 changes: 12 additions & 19 deletions frontend/yarn.lock
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zinzied Could you remove changes of yarn.lock file?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah sure

Original file line number Diff line number Diff line change
Expand Up @@ -123,17 +123,10 @@
resolved "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.2.tgz"
integrity sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==

"@img/sharp-darwin-arm64@0.33.5":
"@img/sharp-win32-x64@0.33.5":
version "0.33.5"
resolved "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz"
integrity sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==
optionalDependencies:
"@img/sharp-libvips-darwin-arm64" "1.0.4"

"@img/sharp-libvips-darwin-arm64@1.0.4":
version "1.0.4"
resolved "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.4.tgz"
integrity sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==
resolved "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz"
integrity sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==

"@monaco-editor/loader@^1.5.0":
version "1.5.0"
Expand Down Expand Up @@ -161,10 +154,10 @@
dependencies:
fast-glob "3.3.1"

"@next/swc-darwin-arm64@15.2.0":
"@next/swc-win32-x64-msvc@15.2.0":
version "15.2.0"
resolved "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.2.0.tgz"
integrity sha512-rlp22GZwNJjFCyL7h5wz9vtpBVuCt3ZYjFWpEPBGzG712/uL1bbSkS675rVAUCRZ4hjoTJ26Q7IKhr5DfJrHDA==
resolved "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.2.0.tgz"
integrity sha512-8+4Z3Z7xa13NdUuUAcpVNA6o76lNPniBd9Xbo02bwXQXnZgFvEopwY2at5+z7yHl47X9qbZpvwatZ2BRo3EdZw==

"@nodelib/fs.scandir@2.1.5":
version "2.1.5"
Expand Down Expand Up @@ -513,10 +506,10 @@
jiti "^2.4.2"
tailwindcss "4.0.9"

"@tailwindcss/oxide-darwin-arm64@4.0.9":
"@tailwindcss/oxide-win32-x64-msvc@4.0.9":
version "4.0.9"
resolved "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.0.9.tgz"
integrity sha512-pWdl4J2dIHXALgy2jVkwKBmtEb73kqIfMpYmcgESr7oPQ+lbcQ4+tlPeVXaSAmang+vglAfFpXQCOvs/aGSqlw==
resolved "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.0.9.tgz"
integrity sha512-dpc05mSlqkwVNOUjGu/ZXd5U1XNch1kHFJ4/cHkZFvaW1RzbHmRt24gvM8/HC6IirMxNarzVw4IXVtvrOoZtxA==

"@tailwindcss/oxide@4.0.9":
version "4.0.9"
Expand Down Expand Up @@ -2367,10 +2360,10 @@ levn@^0.4.1:
prelude-ls "^1.2.1"
type-check "~0.4.0"

lightningcss-darwin-arm64@1.29.1:
lightningcss-win32-x64-msvc@1.29.1:
version "1.29.1"
resolved "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.29.1.tgz"
integrity sha512-HtR5XJ5A0lvCqYAoSv2QdZZyoHNttBpa5EP9aNuzBQeKGfbyH5+UipLWvVzpP4Uml5ej4BYs5I9Lco9u1fECqw==
resolved "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.29.1.tgz"
integrity sha512-NygcbThNBe4JElP+olyTI/doBNGJvLs3bFCRPdvuCcxZCcCZ71B858IHpdm7L1btZex0FvCmM17FK98Y9MRy1Q==

lightningcss@^1.29.1:
version "1.29.1"
Expand Down
48 changes: 30 additions & 18 deletions src/ii_agent/tools/bash_tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,39 @@

from pathlib import Path
from typing import Any, Dict, List, Optional

import pexpect
import platform
import re
from abc import ABC, abstractmethod

from ii_agent.llm.message_history import MessageHistory
from ii_agent.tools.base import LLMTool, ToolImplOutput

# Import the appropriate expect module based on platform
if platform.system() == "Windows":
import wexpect
import subprocess
else:
import pexpect


def start_persistent_shell(timeout: int):
# Start a new Bash shell
child = pexpect.spawn("/bin/bash", encoding="utf-8", echo=False, timeout=timeout)
# Set a known, unique prompt
# We use a random string that is unlikely to appear otherwise
# so we can detect the prompt reliably.
custom_prompt = "PEXPECT_PROMPT>> "
child.sendline("stty -onlcr")
child.sendline("unset PROMPT_COMMAND")
child.sendline(f"PS1='{custom_prompt}'")
# Force an initial read until the newly set prompt shows up
child.expect(custom_prompt)
# Start a new shell (bash on Unix, cmd on Windows)
if platform.system() == "Windows":
child = wexpect.spawn("cmd.exe", encoding="utf-8", timeout=timeout)
custom_prompt = "PEXPECT_PROMPT>> "
child.sendline(f"prompt {custom_prompt}")
child.expect(custom_prompt)
else:
child = pexpect.spawn("/bin/bash", encoding="utf-8", echo=False, timeout=timeout)
# Set a known, unique prompt
# We use a random string that is unlikely to appear otherwise
# so we can detect the prompt reliably.
custom_prompt = "PEXPECT_PROMPT>> "
child.sendline("stty -onlcr")
child.sendline("unset PROMPT_COMMAND")
child.sendline(f"PS1='{custom_prompt}'")
# Force an initial read until the newly set prompt shows up
child.expect(custom_prompt)
return child, custom_prompt


Expand Down Expand Up @@ -164,7 +176,7 @@ def filter_command(self, command: str) -> str:


class BashTool(LLMTool):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, thanks for the PR! For running commands on Windows (cmd), I think it would be cleaner to separate the logic into a dedicated tool (e.g., CmdTool) rather than mixing it into the existing implementation.

In the future, when we add sandbox support, we'll only need to support Linux, so keeping the platforms decoupled now will make things easier to maintain.

"""A tool for executing bash commands.
"""A tool for executing shell commands.

This tool allows the agent to run shell commands and get their output.
Commands are executed in a controlled environment with appropriate safeguards.
Expand All @@ -173,14 +185,14 @@ class BashTool(LLMTool):

name = "bash"
description = """\
Run commands in a bash shell
Run commands in a shell (bash on Unix/Linux, cmd on Windows)
* When invoking this tool, the contents of the \"command\" parameter does NOT need to be XML-escaped.
* You don't have access to the internet via this tool.
* You do have access to a mirror of common linux and python packages via apt and pip.
* State is persistent across command calls and discussions with the user.
* To inspect a particular line range of a file, e.g. lines 10-25, try 'sed -n 10,25p /path/to/the/file'.
* On Windows, use Windows commands (dir, type, etc.). On Unix/Linux, use standard commands (ls, cat, etc.).
* To inspect a particular line range of a file on Unix, try 'sed -n 10,25p /path/to/the/file'. On Windows, use 'more +10 file.txt' or similar.
* Please avoid commands that may produce a very large amount of output.
* Please run long lived commands in the background, e.g. 'sleep 10 &' or start a server in the background."""
* Please run long lived commands in the background when possible."""

input_schema = {
"type": "object",
Expand Down