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

# agent

> TradeAgent identity + signed-PnL + AgentOwnerCap pause/resume.

`TradeAgent` is the on-chain identity for an AI trader. Holds name, Walrus strategy blob ref, agent address, human owner, BalanceManager id, TradeCap id, PredictManager id. Tracks reputation via signed PnL and a PLP score.

## Custody surface

<Frame caption="TradeAgent is the on-chain identity. Owner holds AgentOwnerCap; operator holds TradeCap. Neither alone can both trade and withdraw.">
  <img src="https://mintcdn.com/dp-550c5f99/A_4YREAUu9JDQyGi/images/move-agent-custody.png?fit=max&auto=format&n=A_4YREAUu9JDQyGi&q=85&s=ab7a7d479f21c791cdfa74c46c686e01" alt="Move agent custody surface. Owner address holds AgentOwnerCap and uses it for pause / resume and record_outcome on the shared TradeAgent. The shared TradeAgent references the BalanceManager via balance_manager_id. The operator address holds TradeCap and uses it to place orders on the BalanceManager. withdraw_all is Move-gated and runs from the Owner address to the BalanceManager." width="1774" height="887" data-path="images/move-agent-custody.png" />
</Frame>

## TradeAgent

```move theme={"system"}
public struct TradeAgent has key, store {
    id: UID,
    name: String,
    strategy_blob: vector<u8>,             // Walrus blob id
    agent_address: address,                 // operator address
    owner: address,                         // human owner
    balance_manager_id: ID,                 // DeepBook V3 BalanceManager
    trade_cap_id: ID,                       // DeepBook V3 TradeCap
    predict_manager_id: ID,                 // optional; 0 sentinel if absent
    is_active: bool,                        // pause / resume gate
    realized_pnl_abs: u128,                 // signed via two fields
    realized_pnl_sign: bool,
    plp_score: u128,                        // cumulative utilization share
}
```

<Note>
  **Signed-PnL trick.** Sui Move has no native i128. We split the signed quantity into `realized_pnl_abs: u128` + `realized_pnl_sign: bool`. On `record_outcome`, the runtime computes new = old + delta in i128 mentally and writes back the abs+sign.
</Note>

## AgentOwnerCap

```move theme={"system"}
public struct AgentOwnerCap has key, store {
    id: UID,
    agent_id: ID,
}
```

Gates the three owner-only actions:

```move theme={"system"}
public fun pause(agent: &mut TradeAgent, cap: &AgentOwnerCap)
public fun resume(agent: &mut TradeAgent, cap: &AgentOwnerCap)
public fun record_outcome(
    agent: &mut TradeAgent,
    cap: &AgentOwnerCap,
    pnl_delta_abs: u128,
    pnl_delta_sign: bool,
    plp_score_delta: u128,
)
```

All three abort with `ENotOwner` if `cap.agent_id != object::id(agent)`.

## Registration

```move theme={"system"}
public fun register_agent(
    registry: &mut AgentRegistry,
    name: String,
    strategy_blob: vector<u8>,
    agent_address: address,
    balance_manager_id: ID,
    trade_cap_id: ID,
    predict_manager_id: ID,
    ctx: &mut TxContext,
): (TradeAgent, AgentOwnerCap)
```

Wraps `AgentRegistered { agent_id, name, owner, agent_address }` event. Wired via `scripts/register-trade-agent.ts` and the `/agents` Create wizard.

## Pause/resume + indexer

<Warning>
  `pause` and `resume` emit **no events** (verified at `agent.move:215`). The server `paused` column in the `agents` table is stuck at the registration default. **Authoritative source** for an agent's active state is `sui.getObject(TradeAgent).is_active`. Frontend `OwnerControls` and the agent-service tick guard both read it live. Do not trust the API field.
</Warning>

## Tests

No dedicated test file in `tests/`; covered indirectly by `predict_facade_tests` and the per-agent flows.
