Metadata-Version: 2.5
Name: deep-worker
Version: 0.0.19
Summary: Terminal interface for Deep Worker - interactive AI agent with file operations, shell access, and sub-agent capabilities.
Project-URL: Homepage, https://github.com/rr-develop/deep-worker
Project-URL: Source, https://github.com/rr-develop/deep-worker
Project-URL: Repository, https://github.com/rr-develop/deep-worker
Project-URL: Issues, https://github.com/rr-develop/deep-worker/issues
License-Expression: MIT
License-File: LICENSE
Keywords: agents,ai,cli,deep-agent,langchain,langgraph,llm,terminal
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Terminals
Requires-Python: <4.0,>=3.11
Requires-Dist: aiosqlite<1.0.0,>=0.19.0
Requires-Dist: daytona<1.0.0,>=0.113.0
Requires-Dist: grpcio<1.77,>=1.76
Requires-Dist: langchain-anthropic==1.3.2
Requires-Dist: langchain-core==1.2.9
Requires-Dist: langchain-deepseek==1.0.1
Requires-Dist: langchain-google-genai==4.2.0
Requires-Dist: langchain-openai==1.1.7
Requires-Dist: langchain==1.2.9
Requires-Dist: langgraph-checkpoint-sqlite==3.0.3
Requires-Dist: langgraph-prebuilt==1.0.7
Requires-Dist: langgraph==1.0.8
Requires-Dist: langsmith<0.7,>=0.6.6
Requires-Dist: markdownify<2.0.0,>=0.13.0
Requires-Dist: mcp==1.17.0
Requires-Dist: modal<2.0.0,>=0.65.0
Requires-Dist: pillow<13.0.0,>=10.0.0
Requires-Dist: prompt-toolkit<4.0.0,>=3.0.52
Requires-Dist: pyperclip<2.0.0,>=1.11.0
Requires-Dist: python-dotenv<2.0.0,>=1.0.0
Requires-Dist: pyyaml>=6.0.0
Requires-Dist: requests<3.0.0,>=2.0.0
Requires-Dist: rich<15.0.0,>=14.0.0
Requires-Dist: rpyc-async>=1.0.0
Requires-Dist: runloop-api-client>=0.69.0
Requires-Dist: starlette>=0.27.0
Requires-Dist: tavily-python<1.0.0,>=0.7.21
Requires-Dist: textual-autocomplete<5.0.0,>=3.0.0
Requires-Dist: textual<8.0.0,>=6.0.0
Requires-Dist: uvicorn>=0.24.0
Requires-Dist: watchfiles<2.0,>=1.1
Requires-Dist: wcmatch<11.0.0,>=8.5.0
Provides-Extra: a2a
Requires-Dist: a2a-sdk[http-server]>=1.1.0; extra == 'a2a'
Provides-Extra: semantic-search
Requires-Dist: lancedb>=0.20.0; extra == 'semantic-search'
Requires-Dist: llama-index-core>=0.10.0; extra == 'semantic-search'
Requires-Dist: llama-index-embeddings-huggingface>=0.4.0; extra == 'semantic-search'
Requires-Dist: llama-index-vector-stores-lancedb>=0.4.0; extra == 'semantic-search'
Requires-Dist: pandas>=2.0.0; extra == 'semantic-search'
Requires-Dist: tree-sitter-language-pack>=0.13.0; extra == 'semantic-search'
Provides-Extra: vertexai
Requires-Dist: langchain-google-vertexai<4.0.0,>=3.0.0; extra == 'vertexai'
Description-Content-Type: text/markdown

# Deep Worker CLI

`deep-worker` is a Python package that runs LangChain agents as background
daemon processes and exposes them to the interactive `dwcli` client.

This is a fork of [LangChain's `deepagents-cli`](https://github.com/langchain-ai/deepagents),
renamed to `deep-worker` and extended with additional providers, tools, and
infrastructure (see the root [README](../../README.md) for the component map).

## Quick Install

There are two supported ways to use `deep-worker`:

**1. From a source checkout (recommended for development)** — no `pip install`:

```bash
# Point the launchers into your PATH (project policy: no virtual environments)
ln -sf /path/to/checkout/deep_worker/deep_worker_cli/deep-worker ~/.local/bin/deep-worker
ln -sf /path/to/checkout/deep_worker/deep_worker_cli/dwcli ~/.local/bin/dwcli
```

**2. From a built wheel (`pip install deep-worker`)** — for consuming the
package without the source tree. See
[`docs/BUILD_INSTALL_GUIDE.md`](docs/BUILD_INSTALL_GUIDE.md) for build,
check, and install instructions. Note the wheel's limitations
(`--import-claude` is unavailable; `deepagents` is vendored, so the official
PyPI `deepagents` must not be co-installed).

See [`deep_worker/README.md`](../../deep_worker/README.md) for the no-venv
runtime model.

## Providers & Capabilities (installed wheel)

The wheel ships its five provider packages **inside** the `deep_worker`
namespace — never as top-level packages (avoids collisions with real PyPI
distributions such as `claude-code-provider` / `semantic-search`):

```python
from deep_worker.providers.claude_code_provider import ClaudeCodeChatModel
from deep_worker.providers.semantic_search import SemanticSearchIndexer
```

Optional capabilities are gated behind extras and reported with actionable
`CapabilityError` remedies when missing:

| Extra / capability | Install | When missing |
|---|---|---|
| Vertex AI | `pip install "deep-worker[vertexai]"` | `pip install deep-worker[vertexai]` |
| Semantic search | `pip install "deep-worker[semantic-search]"` | `pip install deep-worker[semantic-search]` |
| A2A protocol | `pip install "deep-worker[a2a]"` | `pip install deep-worker[a2a]` |
| Claude Code / web-search delegation | SDK **fork** via `CLAUDE_AGENT_SDK_SRC` | set `CLAUDE_AGENT_SDK_SRC`; official SDK → `sdk_incompatible` |

The universal `web_search` delegation tool works with any LLM provider
(tri-state policy): default `auto` skips it with a single warning when the SDK
fork is absent; `--enable-web-search` fails loudly; `--disable-web-search`
never touches the SDK. `DEEP_WORKER_SOURCE_ROOT` / `DEEP_WORKER_PROVIDER_SOURCE`
force source-checkout provider resolution (development). Full details:
[`docs/BUILD_INSTALL_GUIDE.md`](docs/BUILD_INSTALL_GUIDE.md).

## Key Features

- 🚀 **Background Agent Processes**: Run agents as daemon processes with `deep-worker`
- 💬 **Interactive CLI**: Connect to running agents with `dwcli`
- 🧹 **Clean History**: Start agents with fresh state using `--clean` option
- 🔧 **Customizable**: Support for custom prompts, skills, and configurations
- 📊 **Session Management**: Conversation history and thread management with `-rm`, `--history`, `--remove-before`
- 💾 **Flexible Storage**: Choose between persistent SQLite or in-memory storage

## 🔒 Security Notice

**⚠️ IMPORTANT: deep-worker-cli is designed for LOCAL TRUSTED ENVIRONMENTS ONLY**

- All network services bind to **localhost (127.0.0.1) only**
- **NO external network access** - ports are not exposed outside your machine
- No authentication/authorization - relies on localhost isolation
- Suitable for personal development, NOT for production servers
- See [SECURITY.md](SECURITY.md) for detailed security requirements

**Never expose deep-worker ports to external networks!**

## 🤔 What is this?

Using an LLM to call tools in a loop is the simplest form of an agent. This architecture, however, can yield agents that are "shallow" and fail to plan and act over longer, more complex tasks.

Applications like "Deep Research", "Manus", and "Claude Code" have gotten around this limitation by implementing a combination of four things: a **planning tool**, **sub agents**, access to a **file system**, and a **detailed prompt**.

`deep-worker` implements these in a general purpose way so that you can easily create a Deep Agent for your application.

**Acknowledgements: This project was primarily inspired by Claude Code, and initially was largely an attempt to see what made Claude Code general purpose, and make it even more so.**

## 💾 Storage Options

By default, agents persist conversation history to SQLite database. You can control storage behavior:

```bash
# Default: SQLite persistence (production)
deep-worker my_agent

# Temporary in-memory storage (no persistence)
deep-worker --memory-only temp_agent

# Force SQLite even in test environment
deep-worker --use-sqlite test_agent
```

**List all conversation threads:**
```bash
# List all threads
deep-worker --list

# List with message counts (slower)
deep-worker --list --with-counts

# Filter by agent name
deep-worker --list --agent my_agent

# JSON output
deep-worker --list --format json
```

**Thread management commands:**
```bash
# Remove a specific thread
deep-worker -rm thread_id

# Dry run (preview without deleting)
deep-worker -rm thread_id --dry-run

# View thread history (works offline)
deep-worker --history thread_id

# View history as JSON
deep-worker --history thread_id --format json

# ⚠️ DANGER: --remove-before is GLOBAL and DESTRUCTIVE.
# It sweeps every sessions_*.db under ~/.deepagents/ AND every
# ~/.deep_worker/<agent>/summaries/<thread>.md across ALL agents for the
# current $HOME. NEVER run this command from an ad-hoc shell / integration
# test without first isolating $HOME to a temp directory (see the
# isolated_home / fake_home fixtures under tests/).
#
# Safety guard: if DATE resolves to a future timestamp, the command
# refuses by default (exit code 2) and requires --force to proceed.
# Future cutoffs match every row and are almost always bugs.
#
# Always start with --dry-run.

# Remove old conversation data (threads AND offloaded summary sections)
# before a specific date. See the Summarization storage section below
# for what "summary sections" means.
deep-worker --remove-before 2026-01-01

# Remove data older than 30 days
deep-worker --remove-before 30d

# Other relative formats: 7d, 2w, 3m, 1y
deep-worker --remove-before 1y --dry-run
```

**Summarization storage — find and manage offloaded conversation history:**

When the model's context fills up, `SummarizationMiddleware` evicts older
messages and writes them to an on-disk file so the agent can later refer
back to them. Files live at:

```
~/.deep_worker/<agent_name>/summaries/<thread_id>.md
```

Each file is an append-only log with one `## Summarized at <ISO-timestamp>`
section per summarization event. The path quoted in the synthetic summary
message injected into the agent's history is exactly this absolute path —
you can `cat`/`grep`/`less` it directly. See
`deep_worker/docs/DESIGN_SUMMARIZATION_PERSISTENT_STORAGE.md`.

```bash
# List all offloaded summaries (text table)
deep-worker --list-summaries

# Filter by agent
deep-worker --list-summaries --agent my_agent

# Machine-readable JSON output
deep-worker --list-summaries --format json
```

The `--remove-before DATE` command also prunes summary files:
- If **every** section in a summary file is older than DATE → the file is
  deleted.
- If **some** are older and **some** are newer → the file is atomically
  rewritten (via `<file>.tmp` + `os.replace`) keeping only the newer
  sections.
- If **all** are newer → the file is untouched.

**Note:** Tests automatically use in-memory storage by default for faster execution and test isolation.

## 🏁 Turn-ending tools

Some tools *are* the agent's answer for a turn: once they succeed there is
nothing useful left for the model to say, and calling it again only produces
filler text. `send_message_to_agent` works this way out of the box — an
outgoing inter-agent message is the agent's response for that turn.

Any tool can be given the same behavior by declaring it explicitly:

```python
from deep_worker_cli.agent import create_cli_agent
from deep_worker_cli.middleware import TurnEndingTool

agent, backend = create_cli_agent(
    model="anthropic:claude-sonnet-4-5-20250929",
    assistant_id="extractor-42",
    project_memory_dir=work_dir,
    tools=[submit_fragments_tool],
    turn_ending_tools=[
        TurnEndingTool(
            tool_name="submit_fragments",
            is_success=lambda result: result.get("document_closed") is True,
            echo_field=None,
        ),
    ],
)
```

`TurnEndingTool` fields:

| Field | Default | Meaning |
| --- | --- | --- |
| `tool_name` | — | Exact tool name, compared with `==` against `ToolMessage.name`. |
| `is_success` | `result["success"]` is truthy | Predicate over the parsed tool result deciding whether this call ends the turn. |
| `echo_field` | `"delivered_content"` | Field whose non-empty string value becomes the final assistant message. `None` ends the turn without emitting any message. |

Notes:

- **Registration is explicit — a tool never becomes turn-ending because of its
  name.** There is no naming convention and no prefix matching, so an MCP
  server cannot alter an agent's control flow by choosing a suggestive tool
  name.
- `send_message_to_agent` is registered automatically; re-declaring it (or any
  name twice) raises `DuplicateTurnEndingToolError` at startup rather than
  being silently ignored.
- With `echo_field=None` the turn ends on the tool result itself and no
  assistant message is created — appropriate when the tool's output is not
  conversational. Use `echo_field` when the caller should see an answer.
- If the model made **parallel** tool calls, the turn is not ended, so it can
  see every result — including any sibling failure.
- A failing `is_success` predicate is treated as "not successful" and logged;
  it never stalls the agent.

See [`docs/DESIGN_TOOL_COMPLETION_MIDDLEWARE.md`](docs/DESIGN_TOOL_COMPLETION_MIDDLEWARE.md)
for the full contract.

## 📖 Resources

- Root [README](../../README.md) — component map and quick start
- [docs/](../../docs/README.md) — documentation index
- [SECURITY.md](SECURITY.md) — security model
- [Upstream](https://github.com/langchain-ai/deepagents) — the `deepagents-cli` project this is forked from
