Imported skill main from langchain
Scanned 9/11/2026
Install to Claude Code
npx -y skills add bitwikiorg/skills.md --skill main --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Main?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/bitwikiorg-main-skills-md)More formats (shields.io, HTML) on the badges page.
---
description: Imported skill main from langchain
name: main
signature: 275c656ef1d7ebdc95a8906eb73cb7617391f8e7e46b4d4958710f05f939c920
source: /a0/tmp/skills_research/langchain/libs/deepagents-cli/deepagents_cli/main.py
---
"""Main entry point and CLI loop for deepagents."""
# ruff: noqa: T201, E402, BLE001, PLR0912, PLR0915
# Suppress deprecation warnings from langchain_core (e.g., Pydantic V1 on Python 3.14+)
# ruff: noqa: E402
import warnings
warnings.filterwarnings("ignore", module="langchain_core._api.deprecation")
import argparse
import asyncio
import contextlib
import os
import sys
import warnings
from pathlib import Path
# Suppress Pydantic v1 compatibility warnings from langchain on Python 3.14+
warnings.filterwarnings("ignore", message=".*Pydantic V1.*", category=UserWarning)
from rich.text import Text
from deepagents_cli._version import __version__
# Now safe to import agent (which imports LangChain modules)
from deepagents_cli.agent import create_cli_agent, list_agents, reset_agent
# CRITICAL: Import config FIRST to set LANGSMITH_PROJECT before LangChain loads
from deepagents_cli.config import (
console,
create_model,
settings,
)
from deepagents_cli.integrations.sandbox_factory import create_sandbox
from deepagents_cli.sessions import (
delete_thread_command,
generate_thread_id,
get_checkpointer,
get_most_recent,
get_thread_agent,
list_threads_command,
thread_exists,
)
from deepagents_cli.skills import execute_skills_command, setup_skills_parser
from deepagents_cli.tools import fetch_url, http_request, web_search
from deepagents_cli.ui import show_help
def check_cli_dependencies() -> None:
"""Check if CLI optional dependencies are installed."""
missing = []
try:
import requests # noqa: F401
except ImportError:
missing.append("requests")
try:
import dotenv # noqa: F401
except ImportError:
missing.append("python-dotenv")
try:
import tavily # noqa: F401
except ImportError:
missing.append("tavily-python")
try:
import textual # noqa: F401
except ImportError:
missing.append("textual")
if missing:
print("\n❌ Missing required CLI dependencies!")
print("\nThe following packages are required to use the deepagents CLI:")
for pkg in missing:
print(f" - {pkg}")
print("\nPlease install them with:")
print(" pip install deepagents[cli]")
print("\nOr install all dependencies:")
print(" pip install 'deepagents[cli]'")
sys.exit(1)
def parse_args() -> argparse.Namespace:
"""Parse command line arguments."""
parser = argparse.ArgumentParser(
description="DeepAgents - AI Coding Assistant",
formatter_class=argparse.RawDescriptionHelpFormatter,
add_help=False,
)
parser.add_argument(
"--version",
action="version",
version=f"deepagents {__version__}",
)
subparsers = parser.add_subparsers(dest="command", help="Command to run")
# List command
subparsers.add_parser("list", help="List all available agents")
# Help command
subparsers.add_parser("help", help="Show help information")
# Reset command
reset_parser = subparsers.add_parser("reset", help="Reset an agent")
reset_parser.add_argument("--agent", required=True, help="Name of agent to reset")
reset_parser.add_argument(
"--target", dest="source_agent", help="Copy prompt from another agent"
)
# Skills command - setup delegated to skills module
setup_skills_parser(subparsers)
# Threads command
threads_parser = subparsers.add_parser("threads", help="Manage conversation threads")
threads_sub = threads_parser.add_subparsers(dest="threads_command")
# threads list
threads_list = threads_sub.add_parser("list", help="List threads")
threads_list.add_argument(
"--agent", default=None, help="Filter by agent name (default: show all)"
)
threads_list.add_argument("--limit", type=int, default=20, help="Max threads (default: 20)")
# threads delete
threads_delete = threads_sub.add_parser("delete", help="Delete a thread")
threads_delete.add_argument("thread_id", help="Thread ID to delete")
# Default interactive mode
parser.add_argument(
"--agent",
default="agent",
help="Agent identifier for separate memory stores (default: agent).",
)
# Thread resume argument - matches PR #638: -r for most recent, -r <ID> for specific
parser.add_argument(
"-r",
"--resume",
dest="resume_thread",
nargs="?",
const="__MOST_RECENT__",
default=None,
help="Resume thread: -r for most recent, -r <ID> for specific thread",
)
# Initial prompt - auto-submit when session starts
parser.add_argument(
"-m",
"--message",
dest="initial_prompt",
help="Initial prompt to auto-submit when session starts",
)
parser.add_argument(
"--model",
help="Model to use (e.g., claude-sonnet-4-5-20250929, gpt-5-mini). "
"Provider is auto-detected from model name.",
)
parser.add_argument(
"--auto-approve",
action="store_true",
help="Auto-approve tool usage without prompting (disables human-in-the-loop)",
)
parser.add_argument(
"--sandbox",
choices=["none", "modal", "daytona", "runloop"],
default="none",
help="Remote sandbox for code execution (default: none - local only)",
)
parser.add_argument(
"--sandbox-id",
help="Existing sandbox ID to reuse (skips creation and cleanup)",
)
parser.add_argument(
"--sandbox-setup",
help="Path to setup script to run in sandbox after creation",
)
return parser.parse_args()
async def run_textual_cli_async(
assistant_id: str,
*,
auto_approve: bool = False,
sandbox_type: str = "none",
sandbox_id: str | None = None,
model_name: str | None = None,
thread_id: str | None = None,
is_resumed: bool = False,
initial_prompt: str | None = None,
) -> None:
"""Run the Textual CLI interface (async version).
Args:
assistant_id: Agent identifier for memory storage
auto_approve: Whether to auto-approve tool usage
sandbox_type: Type of sandbox ("none", "modal", "runloop", "daytona")
sandbox_id: Optional existing sandbox ID to reuse
model_name: Optional model name to use
thread_id: Thread ID to use (new or resumed)
is_resumed: Whether this is a resumed session
initial_prompt: Optional prompt to auto-submit when session starts
"""
from deepagents_cli.app import run_textual_app
model = create_model(model_name)
# Show thread info
if is_resumed:
console.print(f"[green]Resuming thread:[/green] {thread_id}")
else:
console.print(f"[dim]Thread: {thread_id}[/dim]")
# Use async context manager for checkpointer
async with get_checkpointer() as checkpointer:
# Create agent with conditional tools
tools = [http_request, fetch_url]
if settings.has_tavily:
tools.append(web_search)
# Handle sandbox mode
sandbox_backend = None
sandbox_cm = None
if sandbox_type != "none":
try:
# Create sandbox context manager but keep it open
sandbox_cm = create_sandbox(sandbox_type, sandbox_id=sandbox_id)
sandbox_backend = sandbox_cm.__enter__()
except (ImportError, ValueError, RuntimeError, NotImplementedError) as e:
console.print()
console.print("[red]❌ Sandbox creation failed[/red]")
console.print(Text(str(e), style="dim"))
sys.exit(1)
try:
agent, composite_backend = create_cli_agent(
model=model,
assistant_id=assistant_id,
tools=tools,
sandbox=sandbox_backend,
sandbox_type=sandbox_type if sandbox_type != "none" else None,
auto_approve=auto_approve,
checkpointer=checkpointer,
)
# Run Textual app
await run_textual_app(
agent=agent,
assistant_id=assistant_id,
backend=composite_backend,
auto_approve=auto_approve,
cwd=Path.cwd(),
thread_id=thread_id,
initial_prompt=initial_prompt,
)
except Exception as e:
error_text = Text("❌ Failed to create agent: ", style="red")
error_text.append(str(e))
console.print(error_text)
sys.exit(1)
finally:
# Clean up sandbox if we created one
if sandbox_cm is not None:
with contextlib.suppress(Exception):
sandbox_cm.__exit__(None, None, None)
def cli_main() -> None:
"""Entry point for console script."""
# Fix for gRPC fork issue on macOS
# https://github.com/grpc/grpc/issues/37642
if sys.platform == "darwin":
os.environ["GRPC_ENABLE_FORK_SUPPORT"] = "0"
# Note: LANGSMITH_PROJECT is already overridden in config.py (before LangChain imports)
# This ensures agent traces → DEEPAGENTS_LANGSMITH_PROJECT
# Shell commands → user's original LANGSMITH_PROJECT (via ShellMiddleware env)
# Check dependencies first
check_cli_dependencies()
try:
args = parse_args()
if args.command == "help":
show_help()
elif args.command == "list":
list_agents()
elif args.command == "reset":
reset_agent(args.agent, args.source_agent)
elif args.command == "skills":
execute_skills_command(args)
elif args.command == "threads":
if args.threads_command == "list":
asyncio.run(
list_threads_command(
agent_name=getattr(args, "agent", None),
limit=getattr(args, "limit", 20),
)
)
elif args.threads_command == "delete":
asyncio.run(delete_thread_command(args.thread_id))
else:
console.print("[yellow]Usage: deepagents threads <list|delete>[/yellow]")
else:
# Interactive mode - handle thread resume
thread_id = None
is_resumed = False
if args.resume_thread == "__MOST_RECENT__":
# -r (no ID): Get most recent thread
# If --agent specified, filter by that agent; otherwise get most recent overall
agent_filter = args.agent if args.agent != "agent" else None
thread_id = asyncio.run(get_most_recent(agent_filter))
if thread_id:
is_resumed = True
agent_name = asyncio.run(get_thread_agent(thread_id))
if agent_name:
args.agent = agent_name
else:
if agent_filter:
msg = Text("No previous thread for '", style="yellow")
msg.append(args.agent)
msg.append("', starting new.", style="yellow")
else:
msg = Text("No previous threads, starting new.", style="yellow")
console.print(msg)
elif args.resume_thread:
# -r <ID>: Resume specific thread
if asyncio.run(thread_exists(args.resume_thread)):
thread_id = args.resume_thread
is_resumed = True
if args.agent == "agent":
agent_name = asyncio.run(get_thread_agent(thread_id))
if agent_name:
args.agent = agent_name
else:
error_msg = Text("Thread '", style="red")
error_msg.append(args.resume_thread)
error_msg.append("' not found.", style="red")
console.print(error_msg)
console.print(
"[dim]Use 'deepagents threads list' to see available threads.[/dim]"
)
sys.exit(1)
# Generate new thread ID if not resuming
if thread_id is None:
thread_id = generate_thread_id()
# Run Textual CLI
asyncio.run(
run_textual_cli_async(
assistant_id=args.agent,
auto_approve=args.auto_approve,
sandbox_type=args.sandbox,
sandbox_id=args.sandbox_id,
model_name=getattr(args, "model", None),
thread_id=thread_id,
is_resumed=is_resumed,
initial_prompt=getattr(args, "initial_prompt", None),
)
)
except KeyboardInterrupt:
# Clean exit on Ctrl+C - suppress ugly traceback
console.print("\n\n[yellow]Interrupted[/yellow]")
sys.exit(0)
if __name__ == "__main__":
cli_main()
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!