# Class LittleGhost::Subagents::Manager

Documentation version: Edge

Canonical HTML: https://littleghostai.org/docs/LittleGhost/Subagents/Manager.html

Manager coordinates delegated conversations without making an application
build its own worker pool or message protocol. It runs bounded concurrent
tasks, queues follow-ups, reports progress, and can restore durable children.

Applications normally enable it through the agent DSL:

    class CustomerSupportAgent < LittleGhost::Agent
      subagent ResearchAgent,
        kind: "research",
        description: "Investigates policies and account history"
    end

LittleGhost then gives `CustomerSupportAgent` tools to spawn, message, check
on, interject, and list research agents. The manager keeps each child identity
stable across follow-up turns. A progress check returns after 30 seconds by
default when the selected subagents are still working; it does not pause or
restart them.

Follow-up messages are FIFO turns and never interject active work. #interject
is the separate synchronous path for delivery at the next model boundary;
delivery does not stop the child, and tool calls from that model response
continue in the child run.

### Durability and cleanup

With a parent session, durable definitions retain only committed compact
transcripts and limited state snapshots. Failed or cancelled turns never
become committed conversation history. Call #close to cancel and join workers
owned by a directly constructed manager. If cooperative fiber cleanup exceeds
the deadline, the manager remains closed to new work and a later #close
retries cleanup.

## Inheritance

`LittleGhost::Subagents::Manager < Object`

## Attributes

<a id="attribute-i-definitions"></a>
### `definitions` (R)

Available definitions, indexed by kind.

## Class methods

<a id="method-c-commit_session_id"></a>
### `.commit_session_id`

```ruby
.commit_session_id(conversation_id, slot)
```

Derives one of the rotating committed-state session IDs.

<a id="method-c-conversation_session_id"></a>
### `.conversation_session_id`

```ruby
.conversation_session_id(conversation_id)
```

Derives the framework-owned transcript session ID.

<a id="method-c-new"></a>
### `.new`

```ruby
.new(definitions,
        runtime: nil,
        max_concurrent: DEFAULT_MAX_CONCURRENT,
        max_identities: DEFAULT_MAX_IDENTITIES,
        max_turns: DEFAULT_MAX_TURNS,
        max_queued_turns_per_identity: DEFAULT_MAX_QUEUED_TURNS_PER_IDENTITY,
        max_message_chars: DEFAULT_MAX_MESSAGE_CHARS,
        max_response_chars: DEFAULT_MAX_RESPONSE_CHARS,
        wait_timeout: DEFAULT_WAIT_TIMEOUT,
        close_timeout: DEFAULT_CLOSE_TIMEOUT,
        cancellation_token: Support::CancellationToken.new,
        deadline: nil,
        observer: nil,
        parent_session: nil,
        parent_agent_path: AgentPath::ROOT)
```

Configures a bounded manager. Durable restoration is enabled only when
`parent_session` is supplied.

<a id="method-c-parent_link"></a>
### `.parent_link`

```ruby
.parent_link(session)
```

Produces a pseudonymous parent-session link for durable metadata.

<a id="method-c-registry_session_id"></a>
### `.registry_session_id`

```ruby
.registry_session_id(session)
```

Derives the framework-owned registry session ID.

## Instance methods

<a id="method-i-close"></a>
### `#close`

```ruby
#close()
```

Cancels queued work, cooperatively stops workers, and closes child agents.
Raises CleanupError if workers do not stop within the bound. A later call
retries unfinished cleanup without accepting new work.

<a id="method-i-interject"></a>
### `#interject`

```ruby
#interject(subagent_id:, message:, cancellation_token: @cancellation_token, deadline: @deadline)
```

Delivers `message` to one currently running turn and waits for the next model
response. The returned `response_disposition` says whether that response also
initiated tool calls; it does not imply the subagent has stopped.

<a id="method-i-list"></a>
### `#list`

```ruby
#list(kind: nil, limit: DEFAULT_LIST_LIMIT, cursor: nil)
```

Lists active and persisted identities newest-first without restoring inactive
agents. Cursors are opaque and must be passed back unchanged.

<a id="method-i-send_message"></a>
### `#send_message`

```ruby
#send_message(subagent_id:, message:, mode:, parent_operation_id: nil, context: nil)
```

Queues a FIFO follow-up for an active or durable identity.

<a id="method-i-spawn"></a>
### `#spawn`

```ruby
#spawn(kind:, task_name:, task:, mode:, parent_operation_id: nil, context: nil)
```

Creates a unique child identity and queues its first task.

`mode` is `"sync"` or `"async"`. Synchronous mode waits
for the turn; asynchronous mode returns a working snapshot for later #wait
calls.

<a id="method-i-tools"></a>
### `#tools`

```ruby
#tools()
```

Builds spawn, follow-up, interject, wait, and list tools bound to this
manager. Closing the first tool closes the shared manager.

<a id="method-i-wait"></a>
### `#wait`

```ruby
#wait(subagent_ids: nil)
```

Long-polls selected identities, or all identities when omitted.
`still_working` is an ordinary timeout result and does not cancel work.
