Skip to main content
Octop Harness

Octop Harness

A production-grade agent runtime engineered from the Harness Engineering philosophy.

Python 3.12+ License: MIT PyPI Code Style: Ruff GitHub stars

What is Octop Harness? · Why Octop Harness? · How to Use · Documentation

English · 中文


octop-harness is a production-grade agent runtime built on the harness engineering theory. At its core it is a thin, battle-tested encapsulation and engineering layer around deepagents — we take the elegant create_deep_agent primitive from deepagents and package it with everything you need to run agents in production: multi-provider model routing, persistent memory, browser/search tools, a multi-agent registry, pluggable storage backends, and a terminal CLI.

💜 A tribute to deepagents. octop-harness stands on the shoulders of deepagents (by the LangChain team). Our HarnessAgent ultimately delegates to deepagents.create_deep_agent, and everything else — model routing, backends, tiered memory, the agent registry, CLI, and ACP — is the engineering we added on top. deepagents gives us the agentic foundation; Harness gives it a home for production.

What is Octop Harness?

Feature Description
🧩 Built on deepagents A faithful, production-focused facade over deepagents.create_deep_agent — kudos to the deepagents project
🔀 Model routing ChatModelFactory with OpenAI, Anthropic, AWS Bedrock, and 17 editable provider presets
🧠 Persistent memory octop-memory middleware with tiered L0→L3 distillation
🛠️ Rich toolset Browser automation, web search, file ops, sub-agents, and MCP tools out of the box
🗂️ Multi-agent registry AgentManager runs many isolated agents in one process
💾 Pluggable backends Local disk, S3, COS, or PostgreSQL as the agent workspace
🔌 ACP integration A stdio ACP server so IDE / terminal AIs can drive your agent
🔒 Safety built-in Tool guardrails, filesystem permissions, and PII redaction
💬 Teams Peer inbox; peer_invoke_mode selects sync / async / both
⌨️ Terminal CLI Interactive chat, provider/skill config, and agent management

Why Octop Harness?

octop-harness is a library (not an app) that turns deepagents into a deployable runtime. A single HarnessAgentManager owns a registry of agents; each agent wires together a model, a set of tools/skills, a memory backend, and a LangGraph checkpoint — all assembled through the harness layering discipline (L0 I/O helpers → L1 workspace facade → L2 business logic → L3 assembly).

Harness Agent's design goal: let you build a production-grade agent from deepagents in a few lines of code, while keeping model choice, memory, storage, and safety swappable without rewriting your agent.

Core Technology

Layer Technology
Language Python 3.12+
Agent core deepagents (create_deep_agent)
Graph runtime LangGraph + SQLite checkpoint
Model routing ChatModelFactory (OpenAI / Anthropic / Bedrock + 17 presets)
Memory octop-memory middleware
Browser / search octop-browser + web search
Workspaces BackendWorkspace: local / S3 / COS / PostgreSQL
ACP agent-client-protocol
Build / quality hatchling · ruff · mypy · pytest

Features

Agent runtime

  • HarnessAgentManager — a registry that creates, lists, and streams many agents in one process.
  • HarnessAgent — exposes call, stream, stream_events, aget_history, aappend_messages, and cancel.
  • Checkpointing via LangGraph AsyncSqliteSaver (or a octop-memory saver) for resumable chats.

Model routing & providers

  • ChatModelFactory resolves a model name to the right client.
  • First-class providers: OpenAI (incl. OpenAI-compatible via base_url), Anthropic, and AWS Bedrock (optional [bedrock] extra).
  • 17 user-editable provider presets, including Hunyuan, Kimi, GLM, DeepSeek, MiniMax, and Moonshot.

Memory (tiered)

  • MEMORY.md (strong memory) and USER.md (profile) are snapshotted once per session and reused from the checkpoint. Edits apply to new sessions. With structured memory on, the user maintains both files, agent file tools are read-only, and remember requests use memory_save. With structured memory off, the agent edits both files directly; delete and move stay blocked. manual_document_policy defaults to auto and follows that switch; user keeps the files owner-maintained, and agent allows edits even while structured memory is on. The compiled system prompt owns this policy and overrides older rules left in workspace AGENTS.md.
  • Workspace context loading, session snapshots, prompt formatting and cache breakpoints use deepagents' native MemoryMiddleware. Template updates do not overwrite existing user documents.
  • Ordinary saves and automatic promotions check current owner documents through BackendWorkspace, without refreshing the chat snapshot. Proven conflicts retire the old atom and create a replacement review candidate, retaining evidence. memory_save reports conflicts or incomplete checks. Duplicates remain stored and are suppressed against matching session context. Uncertain checks leave facts active. File-tool guards complement the host's shell/OS permissions.
  • Remember requests use memory_save(content, topic) to persist directly through octop-memory; memory_search / memory_get retrieve additional history.
  • Eligible conversation content is captured as L0 raw events, then distilled asynchronously into L2 atoms (AtomCards) and L3 entity pages. Runtime failures are excluded; normal troubleshooting knowledge and explicit remember requests remain eligible.
  • Model failures raise after retries; retry eligibility follows LangChain's defaults, with the existing retry budget and backoff settings. Callers must handle exceptions from call() / streaming. Checkpoints retain failed tasks without adding a synthetic assistant reply. Hosts display errors separately; automatic team failure notifications use configurable.octop_memory_capture_exclude=true to keep diagnostics out of memory.
  • Powered by the octop-memory middleware; memory travels with the workspace.
  • Recall is frozen once per user turn as a quoted historical reference appended after the original user text and attachments, with explicit source/role markers. This keeps the shared request prefix intact through the current user input. The system policy forbids treating recalled questions as new requests. The system prompt stays stable across turns and old v1 snapshots replay exactly; history and capture retain the original user text. Tool continuations and later turns reuse each historical snapshot instead of refreshing earlier recall.
  • For recall diagnostics, enable DEBUG on octop_harness.middleware.memory. recall_inject logs query_chars and query_sha256 (the first 16 hex digits of SHA-256 over the complete UTF-8 query passed to recall, after stripping outer whitespace). Compute the same fingerprint from a suspected query to search and correlate logs; long queries are not truncated before hashing, and raw query text is not logged. Set memory_recall_inject_enabled=False on HarnessAgentConfig to disable fresh automatic recall while retaining memory tools and exact replay of old turns.

Memory extraction can be configured independently of main chat: memory_extract_max_tokens sets the candidate/episode output budget (default 2048), while memory_aux_light_timeout_s / memory_aux_heavy_timeout_s set per-request timeouts (30–3600 seconds). memory_aux_max_retries defaults to 2 extra attempts per model and accepts 0–10; memory_aux_retry_backoff_s defaults to 1 second and doubles up to 60 seconds. Only transport/transient HTTP failures are retried. SDK retries are disabled on separate cached model instances, so main-chat retry settings are unaffected. ChatModelFactory.get_chat_model(ref, max_retries=0) exposes that isolated construction path.

memory_aux_thinking="auto" or "off" disables thinking for known Qwen3/QwQ chat-template models; unsupported models keep their defaults. "on" keeps the model default. memory_aux_extra_body can supply vendor-specific settings such as reasoning_effort; these apply only to the first selected OpenAI-compatible model, never to fallback models. Fallback options are rebuilt for each target, and output budgets respect the target model's configured output limit. Retries, model fallback, and multiple extraction stages can extend total extraction time beyond a single request timeout.

Host-owned memory restore

Hosts can use MemoryMiddleware.pause_background(timeout=120) as a context manager after pausing graph admission. It drains capture, extraction and maintenance workers for that middleware only, skips new background submissions while paused, and resumes admission on exit or timeout. Keep it held while closing and recreating the memory runtime; other experts remain independent.

Ordinary memory runtime shutdown stops accepting background work immediately and returns without waiting. The runtime retains its shared database claim until all accepted workers finish, including workers from middleware replaced during configuration changes. With no pending work, resources are released immediately. MemoryMiddleware.shutdown(on_idle=callback) lets resource owners receive the same completion signal; the callback runs once outside the worker lock, immediately when idle or on the last worker's thread. Shutdown does not keep the process alive; hosts that need to await workers should drain them before exiting.

Tools & skills

  • Built-in tools: browser (octop-browser), web search, files, ask_user_question for respond-only human decisions, optional provider-neutral image/video generation, sub-agents, and MCP tools. Set ask_user_enabled=False for unattended agents.
  • Skills come from the deepagents skills middleware; manage them per agent via the CLI.
  • Optional system_files_path (e.g. .octop) keeps skills, sessions, .env, and sqlite under a workspace subdir while persona markdown stays at the root.

Enable provider-neutral generate_image and generate_video tools with Volcengine Ark:

from octop_harness import HarnessAgentConfig, MediaGenerationConfig

config = HarnessAgentConfig(
    # ...providers/default_model...
    media_generation=MediaGenerationConfig(api_key_env="ARK_API_KEY"),
)

Generated files are stored under generated/images/ and generated/videos/ in the agent workspace. The tools are deferred by default and become visible through the configured tool-search strategy only when needed. Expected provider failures return a structured, model-visible error envelope with retry guidance instead of terminating the agent stream.

For separate image and video routes, configure named providers. Built-in adapters cover Volcengine Ark (Seedream/Seedance), Alibaba Cloud Model Studio (Wan), and MiniMax (image-01/H3):

from octop_harness import HarnessAgentConfig, MediaGenerationConfig, MediaProviderConfig

config = HarnessAgentConfig(
    # ...providers/default_model...
    media_generation=MediaGenerationConfig(
        providers=[
            MediaProviderConfig(
                id="ark-images",
                provider="volcengine",
                api_key_env="ARK_API_KEY",
                video_enabled=False,
            ),
            MediaProviderConfig(
                id="minimax-videos",
                provider="minimax",
                api_key_env="MINIMAX_API_KEY",
                image_enabled=False,
            ),
        ],
        default_image_provider="ark-images",
        default_video_provider="minimax-videos",
    ),
)

Advanced hosts can inject a MediaManager into build_media_generation_tools and register a constrained custom adapter without adding arbitrary protocol or authentication fields to declarative configuration.

Multi-agent & collaboration

  • Multiple isolated agents per process via AgentManager + registry.
  • Teams peer inbox for agent-to-agent messaging. peer_invoke_mode selects the ask_agent surface (sync / async / both); request-scoped overrides may tighten it but cannot add background dispatch.
  • ACP stdio server so external IDE / terminal AIs can invoke your agent.

Safety

  • SecurityPolicy with tool guardrails, filesystem permissions (FilesystemPermission), and PII redaction middleware.
  • PII detection covers provider API keys, mainland China mobile numbers (common 13-19 prefixes, optional +86 / 0086), and 18-character resident IDs with a known province code, 1900-2099 date, and checksum. Existing pii_strategy and pii_surfaces apply; legacy 15-digit IDs and other countries' numbers are out of scope.

CLI

octop-harness provides: init, chat, agent, config (e.g. config provider add), skill, and update.

How to Use

Current release: 1.0.8. See the release notes.

Prerequisites

  • Python 3.12+
  • A model provider API key (OpenAI / Anthropic / Bedrock / compatible)

1. Install

# Core SDK — agent runtime, model routing, tools, skills, backends
pip install octop-harness

# With the terminal CLI — interactive chat, config, skill management
pip install octop-harness[cli]

# Multiple extras — comma-separated inside one pair of brackets (quote for the shell):
pip install 'octop-harness[object-storage,desktop]'
pip install 'octop-harness[cli,all]'

Optional dependency extras (install only what you need; missing extras fail at use-time with an install hint):

Extra What it adds
cli Terminal CLI (octop-harness)
bedrock AWS Bedrock provider
object-storage Tencent COS + Alibaba OSS + Huawei OBS SDKs
desktop Desktop screenshot / input (mss, pynput, pillow)
web-search-all Optional web-search SDKs (Tavily / Brave / Google). DeepSeek uses core HTTP support.
remote-backends Postgres workspace backend (psycopg). S3 uses the bundled boto3 backend.
observability Langfuse
acp ACP agent runner
all All library feature extras above (excludes cli; use [cli,all] for both)

2. Initialize & configure

octop-harness init
octop-harness config provider add   # choose a provider and paste your key

3. Chat

octop-harness chat

Programmatic use

from octop_harness import HarnessAgentManager, HarnessAgentConfig, ProviderConfig, ChatRequest

manager = HarnessAgentManager()
agent: HarnessAgentConfig = manager.create_agent(
    name="assistant",
    provider=ProviderConfig(name="openai", api_key="sk-..."),
    model="gpt-4o",
)
request = ChatRequest(message="Summarize the Harness theory in one paragraph.")
async for chunk in agent.stream(request):
    print(chunk.delta, end="")

Progressive tool loading

Large, low-frequency tool sets can be hidden until the model needs them. The default client mode registers an ordinary tool_search function, so it works with any Chat Completions-compatible model that supports function calling. A deferred tool remains visible by its real name and short description, while its parameter schema is replaced by a lightweight reference. A search result is appended to the conversation, the matched full schemas replace their references on the next model step, and the loaded set persists for the thread. The selected tool is still called by its real name through the normal DeepAgents ToolNode, security guard, and interrupt policy.

from octop_harness import HarnessAgentConfig, ProviderConfig

provider = ProviderConfig(
    id="openai",
    base_url="https://openai-compatible.example/v1",
    api_key="sk-...",
    protocol="openai",
)

config = HarnessAgentConfig(
    providers=[provider],
    default_model="openai/your-function-calling-model",
    tools=[generate_image, generate_video, generate_3d_asset],
    deferred_tools=frozenset(
        {"generate_image", "generate_video", "generate_3d_asset"},
    ),
    defer_mcp_tools=True,
    tool_search_mode="client",  # default; no Responses API required
)

Set tool_search_mode="native" to use OpenAI Responses hosted tool_search or Anthropic hosted defer_loading / tool_reference. Native mode additionally requires ModelConfig.native_tool_search=True; unsupported routed models use the configured tool_search_fallback. Set the mode to eager to disable progressive loading.

For OpenAI-compatible providers, each model can set api_mode to "chat_completions" (default) or "responses". The choice is explicit for official and compatible endpoints alike. Native OpenAI tool search requires Responses. Models using Responses may also opt in to api_fallback="chat_completions". The fallback is disabled by default and is used only for clear unsupported-endpoint/model errors, before any streamed output. It does not apply to native tool search or other Responses-only request features, and never masks authentication, rate-limit, timeout, or server errors.

HITL resume_hitl(thread_id, decisions) retains the paused stream's user, tool selections and other request configuration across nested approvals. The host must authorize the resume caller. This context is process-local, isolated by thread, and released when the resumed stream finishes or the agent closes.

Documentation

CLI reference

Command Description
octop-harness init Bootstrap a workspace and config
octop-harness chat Interactive chat with an agent
octop-harness agent Create, list, and manage agents
octop-harness config Provider / model configuration (config provider add)
octop-harness skill Enable / disable per-agent skills
octop-harness update Check for and install updates

Project layout

src/octop_harness/
  agent.py          facade over deepagents.create_deep_agent
  manager.py        AgentManager — multi-agent registry
  config/           configs, provider & model presets
  llm/factory.py    ChatModelFactory — model routing
  backends/         BackendWorkspace — local / S3 / COS / Postgres
  builtin/          tools + skills + seed files
  middleware/       model_router, skill_filter, tool_guard, memory, pii, ...
  memory/           MemoryRuntime (octop-memory wrapper)
  protocols/        langgraph / openai / mcp streaming
  acp/             ACP stdio server
  teams/           peer inbox
  cli/             terminal CLI

Development

Prerequisites: Python 3.12+, uv

make install          # pip install -e ".[cli,dev]"
make all              # lint + typecheck + test

🤝 Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Run make all before submitting
  4. Open a Pull Request against main

Module boundaries and coding conventions: AGENTS.md.

See CONTRIBUTING.md for branching, PR, and release details (release/* → main auto-publishes to PyPI).

Project Description
deepagents The agentic foundation Harness Agent wraps — ❤️ tribute
octop-memory Memory system behind the tiered recall
octop-browser CDP browser automation used by the agent
octop-gateway Multi-platform IM channel bridge
Octop The self-hosted assistant that composes the Harness stack

📄 License

This project is licensed under the MIT License.

✨ Contributors

Thanks to all contributors:

Channel plugins

A kind: channel manifest may register a channel class with ctx.channel("acme", AcmeChannel, label="Acme IM", fields=[...]). The class must inherit the hosts gateway BaseChannel; factories are not accepted. Harness stores metadata without importing the gateway. The host registers implementations before constructing persisted channels. Plugin IDs own their kinds: updates replace the same plugin, and conflicting owners are rejected. Hosts must stop affected live instances before replacing or removing registrations. Installing this library alone does not add channels to a host that has not implemented the bridge.

Persistent MCP sessions

Use ManagedMCPClient when tools keep state across calls, such as a design brief. The client owns its transport in one task and serializes concurrent callers. It returns original MCP SDK results, including structured content and errors.

from octop_harness import ManagedMCPClient

async with ManagedMCPClient({"transport": "stdio", "command": "my-mcp", "args": []}) as client:
    definitions = await client.get_tools()
    result = await client.call_tool("collect", {"title": "Demo"})
    resources = await client.list_resources()
    resource = await client.read_resource("example://design")

Explicit await client.aclose() is also supported. Closed or disconnected clients must be replaced; writes are never retried automatically. Default MCP tool loading remains stateless.

Metadata

Release files for octop-harness 1.0.8

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for octop-harness 1.0.8
File Size Uploaded Provenance Actions
octop_harness-1.0.8.tar.gz 1.0 MB Without provenance Details for octop_harness-1.0.8.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for octop-harness 1.0.8
File Interpreter ABI Platform Actions
octop_harness-1.0.8-py3-none-any.whl Python 3 none any Details for octop_harness-1.0.8-py3-none-any.whl

Total release size: 2.2 MB

Release files / octop_harness-1.0.8.tar.gz

Download URL octop_harness-1.0.8.tar.gz
Size 1.0 MB
Tags Source
SHA-256 checksum
How to use checksums
fa586d69952eda010452a431093e46ad7685b55189e651c2a5810d2af340b83b
BLAKE2b-256 checksum
How to use checksums
b1305ec8fa8250c9c3f7c973dc35f70625b8a35037808c8b9f2aa2aac0f19fa9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Release files / octop_harness-1.0.8-py3-none-any.whl

Download URL octop_harness-1.0.8-py3-none-any.whl
Size 1.2 MB
Tags Python 3
SHA-256 checksum
How to use checksums
3b7b40063d5cebbe4d47ee3a94f2c392d2cff8b4554c2208fbb5c51cdb77b94c
BLAKE2b-256 checksum
How to use checksums
f988186c8fdca2ba2d37a28e3800e401c660bdd945dbe2d0ca5a585cba2420f1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Security for octop-harness 1.0.8

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page