> ## Documentation Index
> Fetch the complete documentation index at: https://java.agentscope.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Harness Architecture

> What HarnessAgent is, how to choose an invocation style, combine capabilities and persist conversation state

`HarnessAgent` combines reasoning, tools and context management with workspace, long-term memory, skills, subagents and sandboxes. Start with a working conversation in [Quickstart](https://java.agentscope.io/dev/en/docs/quickstart.md), then add capabilities for your application.

`ReActAgent` provides the reasoning loop, tools, permissions and conversation context APIs. Harness composes these capabilities with additional defaults and integrations. Both support `call` and `streamEvents`.

Configure a shared `HarnessAgent.Builder` at startup, build a fresh instance for each direct request, and close it after execution. Stable identity and the same log backend preserve the conversation. See [Instance lifecycle](https://java.agentscope.io/dev/en/docs/building-blocks/agent.md#instance-lifecycle) for code and the shared-instance option. A Durable adapter factory creates native Agents for managed invocations; Runtime owns persistent task scheduling.

## Core working principle

An execution loads the conversation state, builds model input, calls tools as needed and saves its results. Workspace, memory and compaction capabilities take effect during these steps. Applications customize behavior through the builder, tools and middleware.

## Choose an invocation style

* **Get a reply or invoke an Agent within a workflow**: use `call(input, ctx)`.
* **Display live text and tool progress within the current request**: use `streamEvents(input, ctx)`.
* **Run persistent background tasks with queueing, guidance and recovery**: use [DurableRuntime](https://java.agentscope.io/dev/en/docs/harness/durable.md).

Direct calls support ongoing conversations and save state through the default Thread journal and checkpoints. Durable handles persistent admission, Thread queues and interaction association. Harness supplies the same model, tools and middleware capabilities through the AgentScope adapter; it does not own another task scheduler.

Ordinary calls do not create persistent Turns. Local subagents have their own Runs and execution counters, with parent Run/Step references for provenance. They do not inherit parent control objects or recovery positions. Durable manages the corresponding Thread/Turn when persistent tasks, background takeover and cross-process control are required.

See [Agent](https://java.agentscope.io/dev/en/docs/building-blocks/agent.md) for direct calls and [Durable](https://java.agentscope.io/dev/en/docs/harness/durable.md) for background task workflows. Applications with an existing workflow scheduler can continue using direct calls.

## Core components

Configure capabilities and use session operations as your application needs them.

| Capability | What it solves | Configuration or operation | Detail |
| - | - | - | - |
| Workspace-driven persona | Persona, knowledge, subagent specs, skills, MCP allowlist all live as files | `.workspace(path)` | [Workspace](https://java.agentscope.io/dev/en/docs/harness/workspace.md) |
| State and execution history | Full facts, checkpoints, cross-request/node recovery | journal mode by default; override threadJournalStore | [Session logs](https://java.agentscope.io/dev/en/docs/harness/session-log.md) |
| Persistent tasks | Background work, queueing, guidance and recovery | `DurableRuntime` | [Durable](https://java.agentscope.io/dev/en/docs/harness/durable.md) |
| Two-layer long-term memory | Facts in long conversations sediment into `MEMORY.md` | on by default; `.memory(...)` customizes prompts / trigger policy | [Memory](https://java.agentscope.io/dev/en/docs/harness/memory.md) |
| Conversation compaction | History bounded; force-retry on real overflow | `.compaction(...)` | [Context management](https://java.agentscope.io/dev/en/docs/harness/context.md) |
| Large tool-result offloading | >80K-char results moved to disk + placeholder | `.toolResultEviction(...)` | [Context management](https://java.agentscope.io/dev/en/docs/harness/context.md) |
| Subagent orchestration | Delegate to children, sync or background, with auto push-back | `.subagent(...)` or drop spec in `workspace/subagents/` | [Subagent](https://java.agentscope.io/dev/en/docs/harness/subagent.md) |
| Pluggable filesystem | Local + shell / shared store / sandbox without code changes | `.filesystem(...)` | [Filesystem](https://java.agentscope.io/dev/en/docs/harness/filesystem.md) |
| Sandbox isolation | Files and commands isolated; cross-call recovery; multi-replica | `.filesystem(new DockerFilesystemSpec()...)` | [Sandbox](https://java.agentscope.io/dev/en/docs/harness/sandbox.md) |
| Plan Mode | Read-only think-first phase with HITL exit | `.enablePlanMode()` | [Plan Mode](https://java.agentscope.io/dev/en/docs/harness/plan-mode.md) |
| Skill composition | Skills from Git / Nacos / MySQL / classpath / workspace | `.skillRepository(...)` | [Skill](https://java.agentscope.io/dev/en/docs/harness/skill.md) |
| MCP integration & tool allowlist | Declarative MCP servers + allow/deny per tool | `workspace/tools.json` | [Workspace](https://java.agentscope.io/dev/en/docs/harness/workspace.md) |
| Channel routing | Session management, per-session concurrency, multi-agent routing, streaming events | `agent.channel(...)` / `GatewayBootstrap` | [Channel](https://java.agentscope.io/dev/en/docs/harness/channel.md) |

## How state flows

Three layers exist; the framework moves data between them automatically.

* **In-call state** — `AgentState` (conversation context, permission rules, Plan Mode state, tool state) plus `RuntimeContext` (`sessionId`, `userId`, sandbox handle, extras).
* **Cross-call state** — Default recovery uses native checkpoints and applicable facts; full history remains and JSONL is exported only on demand. snapshot mode use AgentStateStore; files, tasks and sandbox metadata retain their own backends.
* **Long-term memory** — accumulated across sessions: `memory/YYYY-MM-DD.md` is append-only, periodically merged into `MEMORY.md` by a throttled background job; `MEMORY.md` loads once per call as reference context, not System instructions.

Three invariants worth remembering:

* Final requests are rebuilt each reasoning step, but workspace files load per call. Edits to AGENTS.md or MEMORY.md take effect on the next call without restarting.
* Compaction, memory distillation, and background maintenance are throttled; they don't run every turn.
* Core manages persistence: journal mode commits checkpoints; snapshot mode save legacy state. Harness selects the default log backend.

## Adding your own middleware

To insert custom behaviour without bypassing Harness's plumbing:

* Use `.middleware(...)` — your middleware runs before all Harness built-ins.
* Read `RuntimeContext` from the agent for the current call's identity (`userId` / `sessionId`).
* For workspace I/O, go through `harnessAgent.getWorkspaceManager()` — it routes correctly under sandbox or remote-store modes. `java.nio.Files` writes to the host disk and will land in the wrong place outside local mode.

## Related pages

* [Session operations, events and recovery](https://java.agentscope.io/dev/en/docs/harness/session-log.md) — background tasks, queues, interaction and continuation
* [Recoverable chat example](https://java.agentscope.io/v2/en/blogs/best-practices/session-chat.md) — a complete application from submission to frontend reconnection
* [Workspace](https://java.agentscope.io/dev/en/docs/harness/workspace.md) — directory layout, instruction and reference sources, `tools.json`
* [Context & AgentState](https://java.agentscope.io/dev/en/docs/building-blocks/context.md) — `AgentState`, `RuntimeContext`, `AgentStateStore` persistence, multi-user isolation
* [Memory](https://java.agentscope.io/dev/en/docs/harness/memory.md) — two-layer memory
* [Context management](https://java.agentscope.io/dev/en/docs/harness/context.md) — build model input, track long-running tasks, summarize history, and offload large results
* [Filesystem](https://java.agentscope.io/dev/en/docs/harness/filesystem.md) — local + shell / shared store / sandbox
* [Sandbox](https://java.agentscope.io/dev/en/docs/harness/sandbox.md) — isolated execution, cross-call recovery, distributed
* [Subagent](https://java.agentscope.io/dev/en/docs/harness/subagent.md) — declarations, sync/background, streaming forwarding
* [Skill](https://java.agentscope.io/dev/en/docs/harness/skill.md) — four-layer composition, self-learning loop
* [Plan Mode](https://java.agentscope.io/dev/en/docs/harness/plan-mode.md) — read-only phase + HITL exit
* [Channel](https://java.agentscope.io/dev/en/docs/harness/channel.md) — session management, multi-agent routing, streaming SSE

## Final model input construction

Harness organizes System, conversation, task state and references at the final model-call boundary. Supply dynamic business information through contextSource. See [Context management](https://java.agentscope.io/dev/en/docs/harness/context.md) for configuration, defaults and limits.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.