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

# Agent

> Open connections to agents with the open() API.

The `open()` function is the main entry point for Thinkwell. It connects to an AI agent (like Claude Code) and returns an `Agent` instance with a fluent API for blending deterministic code with LLM-powered reasoning.

## Opening an Agent

Use `open()` to establish a connection to an AI agent by name.

### Named Agents

Thinkwell provides built-in support for popular AI agents:

```typescript theme={null}
import { open } from "thinkwell";

// Connect to Claude Code
const agent = await open('claude');

// Or connect to other supported agents
const codexAgent = await open('codex');
const geminiAgent = await open('gemini');
```

Supported agent names:

| Name         | Command                                        |
| ------------ | ---------------------------------------------- |
| `'claude'`   | `npx -y @agentclientprotocol/claude-agent-acp` |
| `'codex'`    | `npx -y @zed-industries/codex-acp`             |
| `'gemini'`   | `npx -y @google/gemini-cli --experimental-acp` |
| `'kiro'`     | `kiro-cli acp`                                 |
| `'opencode'` | `opencode acp`                                 |
| `'auggie'`   | `auggie --acp`                                 |

### Custom Commands

You can also connect using any custom command that implements the Agent Client Protocol:

```typescript theme={null}
const agent = await open({ cmd: 'my-custom-agent --acp' });
```

### Connection Options

The `open()` function accepts optional configuration:

```typescript theme={null}
const agent = await open('claude', {
  // Environment variables for the agent process
  env: {
    ANTHROPIC_API_KEY: process.env.MY_API_KEY,
  },
  // Connection timeout in milliseconds
  timeout: 30000,
});
```

### Environment Variable Overrides

`open()` checks two environment variables before resolving the agent:

* `$THINKWELL_AGENT` — an agent name: `THINKWELL_AGENT=opencode thinkwell script.ts`
* `$THINKWELL_AGENT_CMD` — a command string: `THINKWELL_AGENT_CMD="myagent --acp" thinkwell script.ts`

If both are set, `$THINKWELL_AGENT_CMD` takes precedence. Either way, the env override applies regardless of what the script passes to `open()`. This lets you swap agents at runtime without changing code.

## Ephemeral vs Persistent Sessions

Thinkwell supports two patterns for interacting with agents:

### Ephemeral Sessions (Single-Turn)

Use `agent.think()` for one-off prompts that don't need conversation history. Each call creates an ephemeral session that is automatically closed when the prompt completes.

```typescript theme={null}
import { open } from "thinkwell";

/**
 * A summary of content.
 * @JSONSchema
 */
interface Summary {
  title: string;
  points: string[];
}

const agent = await open('claude');

const summary = await agent
  .think(Summary.Schema)
  .text("Summarize this document:")
  .quote(documentContent)
  .run();

console.log(summary.title);
console.log(summary.points);

agent.close();
```

Ephemeral sessions are ideal for:

* Independent, self-contained tasks
* Stateless operations that don't need context
* Parallel processing of multiple prompts

### Persistent Sessions (Multi-Turn)

Use `agent.createSession()` for multi-turn conversations where the agent needs to remember previous interactions.

```typescript theme={null}
import { open } from "thinkwell";

const agent = await open('claude');
const session = await agent.createSession({ cwd: "/my/project" });

// First turn: analyze the codebase
const analysis = await session
  .think(AnalysisSchema)
  .text("Analyze this codebase for potential issues")
  .run();

// Second turn: the agent remembers the analysis
const fixes = await session
  .think(FixesSchema)
  .text("Suggest fixes for the top 3 issues you found")
  .run();

session.close();
agent.close();
```

Persistent sessions are ideal for:

* Multi-step workflows where context matters
* Iterative refinement of results
* Conversations that build on previous responses

## Code Examples

### Basic Prompt with Structured Output

```typescript theme={null}
import { open } from "thinkwell";

/**
 * Sentiment analysis result.
 * @JSONSchema
 */
interface Sentiment {
  /** Overall sentiment: positive, negative, or neutral */
  sentiment: "positive" | "negative" | "neutral";
  /** Confidence score from 0 to 1 */
  confidence: number;
  /** Brief explanation */
  explanation: string;
}

async function analyzeSentiment(text: string) {
  const agent = await open('claude');

  try {
    return await agent
      .think(Sentiment.Schema)
      .text("Analyze the sentiment of this text:")
      .quote(text)
      .run();
  } finally {
    agent.close();
  }
}
```

### Using Custom Tools

```typescript theme={null}
import { open } from "thinkwell";

/**
 * A greeting message.
 * @JSONSchema
 */
interface Greeting {
  message: string;
}

const agent = await open('claude');

const greeting = await agent
  .think(Greeting.Schema)
  .text("Create a greeting appropriate for the current time of day.")
  .tool(
    "current_time",
    "Returns the current date and time.",
    async () => ({
      time: new Date().toLocaleTimeString(),
      date: new Date().toLocaleDateString(),
    })
  )
  .run();

agent.close();
```

### Multi-Turn Session with Working Directory

```typescript theme={null}
import { open } from "thinkwell";

const agent = await open('claude');

// Create a session scoped to a specific project directory
const session = await agent.createSession({
  cwd: "/path/to/project",
  systemPrompt: "You are a helpful code review assistant.",
});

// The agent can access files relative to the working directory
const review = await session
  .think(CodeReviewSchema)
  .text("Review the main entry point of this project")
  .run();

// Follow-up questions maintain context
const details = await session
  .think(DetailSchema)
  .text("Explain more about the third issue you mentioned")
  .run();

session.close();
agent.close();
```

## API Reference

### `open(name, options?)`

Opens a connection to a named agent.

**Parameters:**

| Parameter | Type           | Description                                                                       |
| --------- | -------------- | --------------------------------------------------------------------------------- |
| `name`    | `AgentName`    | Agent name: `'claude'`, `'codex'`, `'gemini'`, `'kiro'`, `'opencode'`, `'auggie'` |
| `options` | `AgentOptions` | Optional connection configuration                                                 |

**Returns:** `Promise<Agent>`

### `open(options)`

Opens a connection using a custom command.

**Parameters:**

| Parameter | Type                 | Description                       |
| --------- | -------------------- | --------------------------------- |
| `options` | `CustomAgentOptions` | Options with required `cmd` field |

**Returns:** `Promise<Agent>`

**AgentOptions:**

| Property  | Type                     | Description                                 |
| --------- | ------------------------ | ------------------------------------------- |
| `env`     | `Record<string, string>` | Environment variables for the agent process |
| `timeout` | `number`                 | Connection timeout in milliseconds          |

**CustomAgentOptions** (extends AgentOptions):

| Property | Type     | Description                                  |
| -------- | -------- | -------------------------------------------- |
| `cmd`    | `string` | The shell command to spawn the agent process |

***

### `agent.think(schema)`

Creates a `Plan` for constructing a single-turn prompt. Each call creates an ephemeral session that is automatically closed when the prompt completes.

**Parameters:**

| Parameter | Type                     | Description                           |
| --------- | ------------------------ | ------------------------------------- |
| `schema`  | `SchemaProvider<Output>` | Defines the expected output structure |

**Returns:** `Plan<Output>`

***

### `agent.createSession(options?)`

Creates a persistent session for multi-turn conversations.

**Parameters:**

| Parameter | Type             | Description                    |
| --------- | ---------------- | ------------------------------ |
| `options` | `SessionOptions` | Optional session configuration |

**Returns:** `Promise<Session>`

**SessionOptions:**

| Property       | Type     | Description                                                     |
| -------------- | -------- | --------------------------------------------------------------- |
| `cwd`          | `string` | Working directory for the session (defaults to `process.cwd()`) |
| `systemPrompt` | `string` | System prompt for the session                                   |

***

### `agent.close()`

Closes the connection to the agent. This shuts down the conductor and invalidates any active sessions.

**Returns:** `void`

## See Also

* [API Overview](/api/overview) - Plan methods and schema providers
* [Sessions](/api/sessions) - Multi-turn conversation sessions
