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

> ## Agent Instructions
> Phaseo Gateway base URL: https://api.phaseo.app/v1. Send `Authorization: Bearer $PHASEO_API_KEY` with every request.
> Model IDs look like `provider/model`, for example `openai/gpt-6-astra`. Do not guess IDs: list them with `GET /v1/models` or check https://phaseo.app/models. `phaseo/free` routes to an available free model and needs no wallet balance.
> For new text integrations prefer `POST /v1/responses`. `POST /v1/chat/completions` (OpenAI format) and `POST /v1/messages` (Anthropic format) suit existing code.
> The full API contract is https://phaseo.app/docs/openapi/v1/openapi.yaml. Official SDKs: `@phaseo/sdk` (TypeScript) and `phaseo` (Python), plus Go, C#, PHP, Ruby and Rust.
> Search these docs over MCP at https://phaseo.app/docs/mcp, and install Phaseo skills with `npx skills add https://phaseo.app/docs`. If a page is wrong or out of date, report it with the MCP `submit_feedback` tool.
> Manage Phaseo accounts with the `phaseo` CLI (`npm install -g @phaseo/cli`, then `phaseo login` or `phaseo login --device-code`), the `/v1` Management API or the MCP server at `https://mcp.phaseo.app/mcp?access=manage`. Do not send users to the dashboard for account tasks. A person is still needed for sign-up, approving a sign-in, paying the first top-up on the checkout link that `phaseo credits add` returns when no card is saved, confirming each saved-card top-up from the emailed link, and account security (password, MFA, passkeys). Create API keys with `phaseo keys create --name <name> --json`; never guess one. Credit top-ups need `phaseo login --scopes billing:write` first. Task map: https://phaseo.app/docs/v1/developers/manage-from-an-agent.md.

# Fan out local agent tools concurrently

> Use bounded local tool concurrency in the TypeScript Agent SDK so one model turn can gather independent context without serializing every tool call.

Use this recipe when one agent turn can safely call several independent local tools and you want the runtime to execute them concurrently while still preserving deterministic tool-result ordering.

## When to use this

Use `toolExecution.toolConcurrency` when:

* the model can emit multiple local tool calls in one turn
* those tools do not depend on each other’s output
* serial execution would waste worker time
* you still want persisted tool-result messages to stay in the original tool-call order

Do not use high concurrency when one tool mutates shared state or when later tools depend on earlier results.

## Example

```ts theme={null}
import {
  createAgent,
  createGatewayAgentClient,
  defineTool,
} from "@phaseo/agent-sdk";

const fetchDocs = defineTool({
  id: "fetch-docs",
  async execute(input: { slug: string }) {
    return {
      slug: input.slug,
      summary: `Docs summary for ${input.slug}`,
    };
  },
});

const fetchStatus = defineTool({
  id: "fetch-status",
  async execute(input: { component: string }) {
    return {
      component: input.component,
      status: "operational",
    };
  },
});

const fetchIncidents = defineTool({
  id: "fetch-incidents",
  async execute(input: { service: string }) {
    return {
      service: input.service,
      openIncidents: 0,
    };
  },
});

const agent = createAgent({
  id: "parallel-tool-agent",
  model: "phaseo/free",
  instructions:
    "Use the available tools to gather context, then return one concise operational summary.",
  tools: [fetchDocs, fetchStatus, fetchIncidents],
  toolExecution: {
    toolConcurrency: 3,
  },
});

const result = await agent.run({
  input:
    "Fetch the presets docs, the gateway status component, and the async-jobs incident digest, then summarize the current state.",
  client: createGatewayAgentClient({
    clientOptions: {
      apiKey: process.env.PHASEO_API_KEY!,
    },
  }),
});
```

See the packaged version in `packages/sdk/agent-sdk-ts/examples/parallel-tool-agent.ts`.

## What the runtime guarantees

* local tools can execute concurrently up to the configured `toolConcurrency`
* `tool.started` and `tool.completed` events still emit per tool
* persisted tool-result messages stay in the original tool-call order
* checkpointing still happens after the tool phase completes
* tool timeouts still apply per tool through `timeoutMs`

## Operational guidance

* start with a small concurrency value such as `2` or `3`
* keep local tools idempotent and side-effect light
* use `timeoutMs` so one stuck dependency does not waste all worker slots
* only add `store` when your application actually needs resumability or remote coordination

## Validation

After enabling this pattern:

* run the exact agent loop tests that cover multi-tool turns
* confirm the workflow still produces ordered tool-result messages
* confirm operator logs still show the expected `tool.started` and `tool.completed` events


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