chore: remove all remaining mini-swe-agent references
Complete cleanup after dropping the mini-swe-agent submodule (PR #2804): - Remove MSWEA_SILENT_STARTUP and MSWEA_GLOBAL_CONFIG_DIR env var settings from cli.py, run_agent.py, hermes_cli/main.py, doctor.py - Remove mini-swe-agent health check from hermes doctor - Remove 'minisweagent' from logger suppression lists - Remove litellm/typer/platformdirs from requirements.txt - Remove mini-swe-agent install steps from install.ps1 (Windows) - Remove mini-swe-agent install steps from website docs - Update all stale comments/docstrings referencing mini-swe-agent in terminal_tool.py, tools/__init__.py, code_execution_tool.py, environments/README.md, environments/agent_loop.py - Remove mini_swe_runner from pyproject.toml py-modules (still exists as standalone script for RL training use) - Shrink test_minisweagent_path.py to empty stub The orphaned mini-swe-agent/ directory on disk needs manual removal: rm -rf mini-swe-agent/
This commit is contained in:
parent
e2c81c6e2f
commit
ad1bf16f28
16 changed files with 21 additions and 73 deletions
5
cli.py
5
cli.py
|
|
@ -31,7 +31,6 @@ from typing import List, Dict, Any, Optional
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
# Suppress startup messages for clean CLI experience
|
# Suppress startup messages for clean CLI experience
|
||||||
os.environ["MSWEA_SILENT_STARTUP"] = "1" # suppress mini-swe-agent startup noise if installed
|
|
||||||
os.environ["HERMES_QUIET"] = "1" # Our own modules
|
os.environ["HERMES_QUIET"] = "1" # Our own modules
|
||||||
|
|
||||||
import yaml
|
import yaml
|
||||||
|
|
@ -78,8 +77,6 @@ _hermes_home = Path(os.getenv("HERMES_HOME", Path.home() / ".hermes"))
|
||||||
_project_env = Path(__file__).parent / '.env'
|
_project_env = Path(__file__).parent / '.env'
|
||||||
load_hermes_dotenv(hermes_home=_hermes_home, project_env=_project_env)
|
load_hermes_dotenv(hermes_home=_hermes_home, project_env=_project_env)
|
||||||
|
|
||||||
# Point mini-swe-agent at ~/.hermes/ if installed (RL training use)
|
|
||||||
os.environ.setdefault("MSWEA_GLOBAL_CONFIG_DIR", str(_hermes_home))
|
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# Configuration Loading
|
# Configuration Loading
|
||||||
|
|
@ -4444,7 +4441,7 @@ class HermesCLI:
|
||||||
logging.getLogger(noisy).setLevel(logging.WARNING)
|
logging.getLogger(noisy).setLevel(logging.WARNING)
|
||||||
else:
|
else:
|
||||||
logging.getLogger().setLevel(logging.INFO)
|
logging.getLogger().setLevel(logging.INFO)
|
||||||
for quiet_logger in ('tools', 'minisweagent', 'run_agent', 'trajectory_compressor', 'cron', 'hermes_cli'):
|
for quiet_logger in ('tools', 'run_agent', 'trajectory_compressor', 'cron', 'hermes_cli'):
|
||||||
logging.getLogger(quiet_logger).setLevel(logging.ERROR)
|
logging.getLogger(quiet_logger).setLevel(logging.ERROR)
|
||||||
|
|
||||||
def _show_insights(self, command: str = "/insights"):
|
def _show_insights(self, command: str = "/insights"):
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,7 @@ Available methods:
|
||||||
|
|
||||||
### Patches (`patches.py`)
|
### Patches (`patches.py`)
|
||||||
|
|
||||||
**Problem**: Some hermes-agent tools use `asyncio.run()` internally (e.g., mini-swe-agent's Modal backend via SWE-ReX). This crashes when called from inside Atropos's event loop because `asyncio.run()` cannot be nested.
|
**Problem**: Some hermes-agent tools use `asyncio.run()` internally (e.g., the Modal backend via SWE-ReX). This crashes when called from inside Atropos's event loop because `asyncio.run()` cannot be nested.
|
||||||
|
|
||||||
**Solution**: `patches.py` monkey-patches `SwerexModalEnvironment` to use a dedicated background thread (`_AsyncWorker`) with its own event loop. The calling code sees the same sync interface, but internally the async work happens on a separate thread that doesn't conflict with Atropos's loop.
|
**Solution**: `patches.py` monkey-patches `SwerexModalEnvironment` to use a dedicated background thread (`_AsyncWorker`) with its own event loop. The calling code sees the same sync interface, but internally the async work happens on a separate thread that doesn't conflict with Atropos's loop.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ from typing import Any, Dict, List, Optional, Set
|
||||||
from model_tools import handle_function_call
|
from model_tools import handle_function_call
|
||||||
|
|
||||||
# Thread pool for running sync tool calls that internally use asyncio.run()
|
# Thread pool for running sync tool calls that internally use asyncio.run()
|
||||||
# (e.g., mini-swe-agent's modal/docker/daytona backends). Running them in a separate
|
# (e.g., the Modal/Docker/Daytona terminal backends). Running them in a separate
|
||||||
# thread gives them a clean event loop so they don't deadlock inside Atropos's loop.
|
# thread gives them a clean event loop so they don't deadlock inside Atropos's loop.
|
||||||
# Size must be large enough for concurrent eval tasks (e.g., 89 TB2 tasks all
|
# Size must be large enough for concurrent eval tasks (e.g., 89 TB2 tasks all
|
||||||
# making tool calls). Too small = thread pool starvation, tasks queue for minutes.
|
# making tool calls). Too small = thread pool starvation, tasks queue for minutes.
|
||||||
|
|
|
||||||
|
|
@ -26,10 +26,6 @@ if _env_path.exists():
|
||||||
# Also try project .env as dev fallback
|
# Also try project .env as dev fallback
|
||||||
load_dotenv(PROJECT_ROOT / ".env", override=False, encoding="utf-8")
|
load_dotenv(PROJECT_ROOT / ".env", override=False, encoding="utf-8")
|
||||||
|
|
||||||
# Point mini-swe-agent at ~/.hermes/ so it shares our config
|
|
||||||
os.environ.setdefault("MSWEA_GLOBAL_CONFIG_DIR", str(HERMES_HOME))
|
|
||||||
os.environ.setdefault("MSWEA_SILENT_STARTUP", "1")
|
|
||||||
|
|
||||||
from hermes_cli.colors import Colors, color
|
from hermes_cli.colors import Colors, color
|
||||||
from hermes_constants import OPENROUTER_MODELS_URL
|
from hermes_constants import OPENROUTER_MODELS_URL
|
||||||
|
|
||||||
|
|
@ -618,18 +614,6 @@ def run_doctor(args):
|
||||||
print()
|
print()
|
||||||
print(color("◆ Submodules", Colors.CYAN, Colors.BOLD))
|
print(color("◆ Submodules", Colors.CYAN, Colors.BOLD))
|
||||||
|
|
||||||
# mini-swe-agent (terminal tool backend)
|
|
||||||
mini_swe_dir = PROJECT_ROOT / "mini-swe-agent"
|
|
||||||
if mini_swe_dir.exists() and (mini_swe_dir / "pyproject.toml").exists():
|
|
||||||
try:
|
|
||||||
__import__("minisweagent")
|
|
||||||
check_ok("mini-swe-agent", "(terminal backend)")
|
|
||||||
except ImportError:
|
|
||||||
check_warn("mini-swe-agent found but not installed", "(run: uv pip install -e ./mini-swe-agent)")
|
|
||||||
issues.append("Install mini-swe-agent: uv pip install -e ./mini-swe-agent")
|
|
||||||
else:
|
|
||||||
check_warn("mini-swe-agent not found", "(run: git submodule update --init --recursive)")
|
|
||||||
|
|
||||||
# tinker-atropos (RL training backend)
|
# tinker-atropos (RL training backend)
|
||||||
tinker_dir = PROJECT_ROOT / "tinker-atropos"
|
tinker_dir = PROJECT_ROOT / "tinker-atropos"
|
||||||
if tinker_dir.exists() and (tinker_dir / "pyproject.toml").exists():
|
if tinker_dir.exists() and (tinker_dir / "pyproject.toml").exists():
|
||||||
|
|
|
||||||
|
|
@ -60,9 +60,6 @@ from hermes_cli.config import get_hermes_home
|
||||||
from hermes_cli.env_loader import load_hermes_dotenv
|
from hermes_cli.env_loader import load_hermes_dotenv
|
||||||
load_hermes_dotenv(project_env=PROJECT_ROOT / '.env')
|
load_hermes_dotenv(project_env=PROJECT_ROOT / '.env')
|
||||||
|
|
||||||
# Point mini-swe-agent at ~/.hermes/ so it shares our config
|
|
||||||
os.environ.setdefault("MSWEA_GLOBAL_CONFIG_DIR", str(get_hermes_home()))
|
|
||||||
os.environ.setdefault("MSWEA_SILENT_STARTUP", "1")
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import time as _time
|
import time as _time
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,7 @@ hermes-agent = "run_agent:main"
|
||||||
hermes-acp = "acp_adapter.entry:main"
|
hermes-acp = "acp_adapter.entry:main"
|
||||||
|
|
||||||
[tool.setuptools]
|
[tool.setuptools]
|
||||||
py-modules = ["run_agent", "model_tools", "toolsets", "batch_runner", "trajectory_compressor", "toolset_distributions", "cli", "hermes_constants", "hermes_state", "hermes_time", "mini_swe_runner", "rl_cli", "utils"]
|
py-modules = ["run_agent", "model_tools", "toolsets", "batch_runner", "trajectory_compressor", "toolset_distributions", "cli", "hermes_constants", "hermes_state", "hermes_time", "rl_cli", "utils"]
|
||||||
|
|
||||||
[tool.setuptools.packages.find]
|
[tool.setuptools.packages.find]
|
||||||
include = ["agent", "tools", "tools.*", "hermes_cli", "gateway", "gateway.*", "cron", "honcho_integration", "acp_adapter"]
|
include = ["agent", "tools", "tools.*", "hermes_cli", "gateway", "gateway.*", "cron", "honcho_integration", "acp_adapter"]
|
||||||
|
|
|
||||||
|
|
@ -23,12 +23,6 @@ parallel-web>=0.4.2
|
||||||
# Image generation
|
# Image generation
|
||||||
fal-client
|
fal-client
|
||||||
|
|
||||||
# mini-swe-agent dependencies (for terminal tool)
|
|
||||||
# Note: Install mini-swe-agent itself with: pip install -e ./mini-swe-agent
|
|
||||||
litellm>=1.75.5
|
|
||||||
typer
|
|
||||||
platformdirs
|
|
||||||
|
|
||||||
# Text-to-speech (Edge TTS is free, no API key needed)
|
# Text-to-speech (Edge TTS is free, no API key needed)
|
||||||
edge-tts
|
edge-tts
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -58,9 +58,6 @@ if _loaded_env_paths:
|
||||||
else:
|
else:
|
||||||
logger.info("No .env file found. Using system environment variables.")
|
logger.info("No .env file found. Using system environment variables.")
|
||||||
|
|
||||||
# Point mini-swe-agent at ~/.hermes/ if installed (RL training use)
|
|
||||||
os.environ.setdefault("MSWEA_GLOBAL_CONFIG_DIR", str(_hermes_home))
|
|
||||||
os.environ.setdefault("MSWEA_SILENT_STARTUP", "1")
|
|
||||||
|
|
||||||
# Import our tool system
|
# Import our tool system
|
||||||
from model_tools import get_tool_definitions, handle_function_call, check_toolset_requirements
|
from model_tools import get_tool_definitions, handle_function_call, check_toolset_requirements
|
||||||
|
|
@ -661,7 +658,7 @@ class AIAgent:
|
||||||
# INFO/WARNING messages just clutter it.
|
# INFO/WARNING messages just clutter it.
|
||||||
for quiet_logger in [
|
for quiet_logger in [
|
||||||
'tools', # all tools.* (terminal, browser, web, file, etc.)
|
'tools', # all tools.* (terminal, browser, web, file, etc.)
|
||||||
'minisweagent', # mini-swe-agent execution backend
|
|
||||||
'run_agent', # agent runner internals
|
'run_agent', # agent runner internals
|
||||||
'trajectory_compressor',
|
'trajectory_compressor',
|
||||||
'cron', # scheduler (only relevant in daemon mode)
|
'cron', # scheduler (only relevant in daemon mode)
|
||||||
|
|
|
||||||
|
|
@ -505,7 +505,7 @@ function Install-Repository {
|
||||||
git -c windows.appendAtomically=false config windows.appendAtomically false 2>$null
|
git -c windows.appendAtomically=false config windows.appendAtomically false 2>$null
|
||||||
|
|
||||||
# Ensure submodules are initialized and updated
|
# Ensure submodules are initialized and updated
|
||||||
Write-Info "Initializing submodules (mini-swe-agent, tinker-atropos)..."
|
Write-Info "Initializing submodules..."
|
||||||
git -c windows.appendAtomically=false submodule update --init --recursive 2>$null
|
git -c windows.appendAtomically=false submodule update --init --recursive 2>$null
|
||||||
if ($LASTEXITCODE -ne 0) {
|
if ($LASTEXITCODE -ne 0) {
|
||||||
Write-Warn "Submodule init failed (terminal/RL tools may need manual setup)"
|
Write-Warn "Submodule init failed (terminal/RL tools may need manual setup)"
|
||||||
|
|
@ -559,19 +559,7 @@ function Install-Dependencies {
|
||||||
|
|
||||||
Write-Success "Main package installed"
|
Write-Success "Main package installed"
|
||||||
|
|
||||||
# Install submodules
|
# Install optional submodules
|
||||||
Write-Info "Installing mini-swe-agent (terminal tool backend)..."
|
|
||||||
if (Test-Path "mini-swe-agent\pyproject.toml") {
|
|
||||||
try {
|
|
||||||
& $UvCmd pip install -e ".\mini-swe-agent" 2>&1 | Out-Null
|
|
||||||
Write-Success "mini-swe-agent installed"
|
|
||||||
} catch {
|
|
||||||
Write-Warn "mini-swe-agent install failed (terminal tools may not work)"
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Write-Warn "mini-swe-agent not found (run: git submodule update --init)"
|
|
||||||
}
|
|
||||||
|
|
||||||
Write-Info "Installing tinker-atropos (RL training backend)..."
|
Write-Info "Installing tinker-atropos (RL training backend)..."
|
||||||
if (Test-Path "tinker-atropos\pyproject.toml") {
|
if (Test-Path "tinker-atropos\pyproject.toml") {
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,2 @@
|
||||||
"""Tests for minisweagent_path.py — REMOVED.
|
# This file intentionally left empty.
|
||||||
|
# minisweagent_path.py was removed — see PR #2804.
|
||||||
minisweagent_path.py was removed as part of dropping the mini-swe-agent
|
|
||||||
dependency. These tests are no longer applicable.
|
|
||||||
"""
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ This package contains all the specific tool implementations for the Hermes Agent
|
||||||
Each module provides specialized functionality for different capabilities:
|
Each module provides specialized functionality for different capabilities:
|
||||||
|
|
||||||
- web_tools: Web search, content extraction, and crawling
|
- web_tools: Web search, content extraction, and crawling
|
||||||
- terminal_tool: Command execution using mini-swe-agent (local/docker/modal/daytona backends)
|
- terminal_tool: Command execution (local/docker/modal/daytona/ssh/singularity backends)
|
||||||
- vision_tools: Image analysis and understanding
|
- vision_tools: Image analysis and understanding
|
||||||
- mixture_of_agents_tool: Multi-model collaborative reasoning
|
- mixture_of_agents_tool: Multi-model collaborative reasoning
|
||||||
- image_generation_tool: Text-to-image generation with upscaling
|
- image_generation_tool: Text-to-image generation with upscaling
|
||||||
|
|
@ -23,7 +23,7 @@ from .web_tools import (
|
||||||
check_firecrawl_api_key
|
check_firecrawl_api_key
|
||||||
)
|
)
|
||||||
|
|
||||||
# Primary terminal tool (mini-swe-agent backend: local/docker/singularity/modal/daytona)
|
# Primary terminal tool (local/docker/singularity/modal/daytona/ssh)
|
||||||
from .terminal_tool import (
|
from .terminal_tool import (
|
||||||
terminal_tool,
|
terminal_tool,
|
||||||
check_terminal_requirements,
|
check_terminal_requirements,
|
||||||
|
|
@ -166,7 +166,7 @@ __all__ = [
|
||||||
'web_extract_tool',
|
'web_extract_tool',
|
||||||
'web_crawl_tool',
|
'web_crawl_tool',
|
||||||
'check_firecrawl_api_key',
|
'check_firecrawl_api_key',
|
||||||
# Terminal tools (mini-swe-agent backend)
|
# Terminal tools
|
||||||
'terminal_tool',
|
'terminal_tool',
|
||||||
'check_terminal_requirements',
|
'check_terminal_requirements',
|
||||||
'cleanup_vm',
|
'cleanup_vm',
|
||||||
|
|
|
||||||
|
|
@ -442,7 +442,7 @@ def execute_code(
|
||||||
child_env["HERMES_RPC_SOCKET"] = sock_path
|
child_env["HERMES_RPC_SOCKET"] = sock_path
|
||||||
child_env["PYTHONDONTWRITEBYTECODE"] = "1"
|
child_env["PYTHONDONTWRITEBYTECODE"] = "1"
|
||||||
# Ensure the hermes-agent root is importable in the sandbox so
|
# Ensure the hermes-agent root is importable in the sandbox so
|
||||||
# modules like minisweagent_path are available to child scripts.
|
# repo-root modules are available to child scripts.
|
||||||
_hermes_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
_hermes_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
_existing_pp = child_env.get("PYTHONPATH", "")
|
_existing_pp = child_env.get("PYTHONPATH", "")
|
||||||
child_env["PYTHONPATH"] = _hermes_root + (os.pathsep + _existing_pp if _existing_pp else "")
|
child_env["PYTHONPATH"] = _hermes_root + (os.pathsep + _existing_pp if _existing_pp else "")
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
"""
|
"""
|
||||||
Terminal Tool Module (mini-swe-agent backend)
|
Terminal Tool Module
|
||||||
|
|
||||||
A terminal tool that executes commands using mini-swe-agent's execution environments.
|
A terminal tool that executes commands in local, Docker, Modal, SSH, Singularity, and Daytona environments.
|
||||||
Supports local execution, Docker containers, and Modal cloud sandboxes.
|
Supports local execution, Docker containers, and Modal cloud sandboxes.
|
||||||
|
|
||||||
Environment Selection (via TERMINAL_ENV environment variable):
|
Environment Selection (via TERMINAL_ENV environment variable):
|
||||||
|
|
@ -532,7 +532,7 @@ def _create_environment(env_type: str, image: str, cwd: str, timeout: int,
|
||||||
task_id: str = "default",
|
task_id: str = "default",
|
||||||
host_cwd: str = None):
|
host_cwd: str = None):
|
||||||
"""
|
"""
|
||||||
Create an execution environment from mini-swe-agent.
|
Create an execution environment for sandboxed command execution.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
env_type: One of "local", "docker", "singularity", "modal", "daytona", "ssh"
|
env_type: One of "local", "docker", "singularity", "modal", "daytona", "ssh"
|
||||||
|
|
@ -847,7 +847,7 @@ def terminal_tool(
|
||||||
pty: bool = False,
|
pty: bool = False,
|
||||||
) -> str:
|
) -> str:
|
||||||
"""
|
"""
|
||||||
Execute a command using mini-swe-agent's execution environments.
|
Execute a command in the configured terminal environment.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
command: The command to execute
|
command: The command to execute
|
||||||
|
|
@ -982,7 +982,7 @@ def terminal_tool(
|
||||||
return json.dumps({
|
return json.dumps({
|
||||||
"output": "",
|
"output": "",
|
||||||
"exit_code": -1,
|
"exit_code": -1,
|
||||||
"error": f"Terminal tool disabled: mini-swe-agent not available ({e})",
|
"error": f"Terminal tool disabled: environment creation failed ({e})",
|
||||||
"status": "disabled"
|
"status": "disabled"
|
||||||
}, ensure_ascii=False)
|
}, ensure_ascii=False)
|
||||||
|
|
||||||
|
|
@ -1267,7 +1267,7 @@ if __name__ == "__main__":
|
||||||
|
|
||||||
print("\n✅ All requirements met!")
|
print("\n✅ All requirements met!")
|
||||||
print("\nAvailable Tool:")
|
print("\nAvailable Tool:")
|
||||||
print(" - terminal_tool: Execute commands using mini-swe-agent environments")
|
print(" - terminal_tool: Execute commands in sandboxed environments")
|
||||||
|
|
||||||
print("\nUsage Examples:")
|
print("\nUsage Examples:")
|
||||||
print(" # Execute a command")
|
print(" # Execute a command")
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,6 @@ export VIRTUAL_ENV="$(pwd)/venv"
|
||||||
|
|
||||||
# Install with all extras (messaging, cron, CLI menus, dev tools)
|
# Install with all extras (messaging, cron, CLI menus, dev tools)
|
||||||
uv pip install -e ".[all,dev]"
|
uv pip install -e ".[all,dev]"
|
||||||
uv pip install -e "./mini-swe-agent"
|
|
||||||
uv pip install -e "./tinker-atropos"
|
uv pip install -e "./tinker-atropos"
|
||||||
|
|
||||||
# Optional: browser tools
|
# Optional: browser tools
|
||||||
|
|
|
||||||
|
|
@ -132,13 +132,10 @@ You can combine extras: `uv pip install -e ".[messaging,cron]"`
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
### Step 4: Install Submodule Packages
|
### Step 4: Install Optional Submodules (if needed)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Terminal tool backend (required for terminal/command-execution)
|
# RL training backend (optional)
|
||||||
uv pip install -e "./mini-swe-agent"
|
|
||||||
|
|
||||||
# RL training backend
|
|
||||||
uv pip install -e "./tinker-atropos"
|
uv pip install -e "./tinker-atropos"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -238,7 +235,6 @@ export VIRTUAL_ENV="$(pwd)/venv"
|
||||||
|
|
||||||
# Install everything
|
# Install everything
|
||||||
uv pip install -e ".[all]"
|
uv pip install -e ".[all]"
|
||||||
uv pip install -e "./mini-swe-agent"
|
|
||||||
uv pip install -e "./tinker-atropos"
|
uv pip install -e "./tinker-atropos"
|
||||||
npm install # optional, for browser tools and WhatsApp
|
npm install # optional, for browser tools and WhatsApp
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,6 @@ git submodule update --init --recursive
|
||||||
|
|
||||||
# Reinstall (picks up new dependencies)
|
# Reinstall (picks up new dependencies)
|
||||||
uv pip install -e ".[all]"
|
uv pip install -e ".[all]"
|
||||||
uv pip install -e "./mini-swe-agent"
|
|
||||||
uv pip install -e "./tinker-atropos"
|
uv pip install -e "./tinker-atropos"
|
||||||
|
|
||||||
# Check for new config options
|
# Check for new config options
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue