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

# Model Selection

`query()` offers two model-selection modes:

* **Fixed model (default)**: the entire session uses one model.
* **Dynamic selection**: a callback is called before every LLM request to return the model. You can route by purpose (main conversation, sub-agent, context compaction, etc.) or return a BYOK credential to use your own API key.

The two modes are mutually exclusive: passing the callback switches to dynamic-selection mode and the fixed-model setting is ignored.

<div id="fixed-model" />

## Fixed model

Specify it via the model option; omit to use the account default:

```typescript theme={null}
import { qodercliAuth, query } from '@qoder-ai/qoder-agent-sdk';

const q = query({
  prompt: 'Analyze this code',
  options: {
    auth: qodercliAuth(),
    model: 'performance',
  },
});
```

<div id="dynamic-selection" />

## Dynamic selection

Provide a callback function that is invoked before every LLM request:

```typescript theme={null}
import { qodercliAuth, query, type ModelPolicyProvider } from '@qoder-ai/qoder-agent-sdk';

const resolveModel: ModelPolicyProvider = (context) => {
  return { model: 'performance' };
};

const q = query({
  prompt: 'Analyze this code',
  options: {
    auth: qodercliAuth(),
    resolveModel,
  },
});
```

The callback receives the request's purpose, session info, and the list of currently available models.

<div id="routing-by-purpose" />

### Routing by purpose

Use a different model per purpose:

```typescript theme={null}
const resolveModel: ModelPolicyProvider = (context) => {
  switch (context.purpose) {
    case 'main':       return { model: 'performance' };
    case 'subagent':   return { model: 'efficient' };
    case 'compact':    return { model: 'lite' };
    default:           return { model: 'auto' };
  }
};
```

Purposes cover scenarios like main conversation, sub-agent, context compaction, WebFetch, and image generation. For the full list, see [SDK References](/en/cli/sdk/references).

<div id="returning-model-parameters" />

### Returning model parameters

Return `parameters` with the selected model to override the context window and thinking depth for that LLM request. These keys are camelCase at the SDK control boundary:

```typescript theme={null}
const resolveModel: ModelPolicyProvider = (context) => {
  return {
    model: 'ultimate',
    parameters: {
      contextWindow: 200000,
      reasoningEffort: 'high',
    },
  };
};
```

Choose values supported by the selected model. The available context-window and thinking-effort metadata is exposed on `context.availableModels` through `ModelInfo.context_config` and `ModelInfo.thinking_config`.

<div id="timeout" />

### Timeout

The callback has a default timeout (in milliseconds). Increase it when the callback performs remote I/O:

```typescript theme={null}
{ resolveModel, resolveModelTimeoutMs: 800 }
```

<div id="byok-use-your-own-api-key" />

### BYOK: use your own API key

The callback can also return a BYOK credential object — that request will be routed to a third-party provider:

```typescript theme={null}
const resolveModel: ModelPolicyProvider = () => ({
  model: {
    provider: 'bailian',
    model: 'qwen3.5-plus-cp',
    api_key: process.env.MY_API_KEY!,
  },
});
```

The available provider/model catalog can be fetched at runtime, so the front-end can render selectors and an API-key input.

<div id="runtime-operations" />

## Runtime operations

While a session is running you can fetch the account's currently available model list:

```typescript theme={null}
import { qodercliAuth, query } from '@qoder-ai/qoder-agent-sdk';

const q = query({
  prompt: '...',
  options: { auth: qodercliAuth() },
});

const models = await q.getAvailableModels();
for (const m of models) {
  console.log(`${m.value}\t${m.displayName}\t${m.isEnabled ?? true}`);
}
```

You can also switch the current model in fixed-model mode, or fetch the BYOK provider catalog. For specific method signatures, see [SDK References](/en/cli/sdk/references).

<div id="error-handling" />

## Error handling

Dynamic-selection mode has **no automatic fallback** — a callback that times out, throws, or returns an empty model causes the query to fail. Handle errors inside the callback:

```typescript theme={null}
const resolveModel: ModelPolicyProvider = async (context) => {
  try {
    const policy = await fetchRemotePolicy(context);
    return { model: policy.model };
  } catch {
    return { model: 'auto' };   // fallback, must be non-empty
  }
};
```

For full field and type definitions, see [SDK References](/en/cli/sdk/references).
