# AutoTeamBuilder

TnsAI.Intelligence generates a configured multi-agent team from a natural-language task. `AutoTeamBuilder` decomposes the task, writes per-agent prompts, picks a formation, and instantiates the agents. Package: `com.tnsai.autoteam`.

## Quick Start

`AutoTeamBuilder.create()` is the entry point. `build(task)` returns an `AutoTeamBuilder.Result` with the constructed `AgentGroup`, the `TeamPlan`, and the individual agents. There is no `builder()`, `toolRegistry()`, `buildTeam()`, or `TeamSpec`.

<!-- java-contract: src/main/java/com/example/tnsai/docs/AutoTeamQuickstartExample.java -->
```java
AutoTeamBuilder.Result result = AutoTeamBuilder.create()
    .llm(llmClient)
    .toolPojos(searchTools)
    .build("Research quantum computing advances and write a summary report");

AgentGroup group = result.group();
TeamPlan plan = result.plan();
```

Register tools as `@Tool` POJOs via `toolPojos(...)`, or as runtime methods via `dynamicTool(...)` / `dynamicTools(...)`.

## How It Works

`build(task)` runs three internal steps, then constructs agents and an `AgentGroup`.

### 1. Task decomposition

An LLM turns the task into a `TeamPlan`: a team name, a list of `GeneratedAgentConfig`s, suggested formation, and an inter-agent dependency map. There is no public `decompose(...)` method and no `SubTask` type.

Call `plan(task)` when you want that blueprint without instantiating agents:

<!-- java-contract: src/main/java/com/example/tnsai/docs/AutoTeamPlanPreviewExample.java -->
```java
TeamPlan preview = AutoTeamBuilder.create()
    .llm(llmClient)
    .toolPojos(searchTools)
    .maxAgents(5)
    .plan("Build a market analysis dashboard");
```

### 2. Agent configuration

Each `GeneratedAgentConfig` carries the fields the builder needs to instantiate one agent:

| Component | Meaning |
|-----------|---------|
| `id()` | Agent identifier |
| `role()` | Human-readable role name |
| `systemPrompt()` | Prompt generated for that role |
| `toolNames()` | Tool names assigned from the builder's pool |
| `capabilities()` | Capability descriptions |
| `parameters()` | Extra knobs (model, `isLead`, ...) |

There is no public `AgentConfig` record.

### 3. Topology selection

`TopologySelector` inspects the plan and returns one of `PARALLEL`, `SEQUENTIAL`, or `HIERARCHICAL`. That name is stored on `TeamPlan.suggestedFormation()`.

| Condition | Formation |
|-----------|-----------|
| One agent | `PARALLEL` |
| Lead plus dependencies | `HIERARCHICAL` |
| Linear dependency chain | `SEQUENTIAL` |
| Dependency depth ≥ 2 | `HIERARCHICAL` |
| Lead, no dependencies | `HIERARCHICAL` |
| No dependencies | `PARALLEL` |
| Otherwise | LLM suggestion, else `PARALLEL` |

There is no `preferredTopology(...)` override.

## Builder Parameters

| Parameter | Default | Description |
|-----------|---------|-------------|
| `llm` | required | `LLMClient` for decomposition and prompt generation |
| `toolPojos` | empty | Objects whose `@Tool` methods become the tool pool |
| `dynamicTool` / `dynamicTools` | empty | Runtime `DynamicToolMethod`s (MCP proxies, etc.) |
| `maxAgents` | `10` | Cap applied after decomposition |
| `temperature` | `0.4` | LLM temperature for planning |
| `agentCustomizer` | unset | `Function<AgentBuilder, AgentBuilder>` applied to each agent |

## Result and TeamPlan

`build(task)` returns `AutoTeamBuilder.Result`:

| Accessor | Type | Meaning |
|----------|------|---------|
| `group()` | `AgentGroup` | Constructed group |
| `plan()` | `TeamPlan` | Plan used to build it |
| `agents()` | `List<Agent>` | Instantiated members |

`TeamPlan` fields:

| Accessor | Meaning |
|----------|---------|
| `taskDescription()` | Original task |
| `teamName()` | Generated name |
| `reasoning()` | LLM rationale |
| `agents()` | `List<GeneratedAgentConfig>` |
| `suggestedFormation()` | `PARALLEL`, `SEQUENTIAL`, or `HIERARCHICAL` |
| `dependencies()` | Agent-id → dependency ids |
| `agentCount()` | Size of `agents()` |
| `hasDependencies()` | Whether the dependency map is non-empty |

`AgentGroup` is not a `Team` and does not expose `execute(String)`. To run the generated members, wrap them in `Team`.

## Run with Team

`Team.builder()` requires a `mission`. Add members with `member(...)`. `Team.execute` returns `TeamResult`.

<!-- java-contract: src/main/java/com/example/tnsai/docs/AutoTeamRunExample.java -->
```java
TeamBuilder teamBuilder = Team.builder()
    .name(plan.teamName())
    .mission(plan.taskDescription())
    .formation(TeamFormation.valueOf(plan.suggestedFormation()));
for (Agent agent : result.agents()) {
    teamBuilder.member(agent, TeamRole.MEMBER);
}
Team team = teamBuilder.build();
team.start();
TeamResult teamResult = team.execute(plan.taskDescription());
```

See [Topologies](topologies.md) for the formation patterns themselves.
