# OpenAI-Compatible Base URL And Reasoning Policy

Date: 2026-06-01

Purpose: record the decision for PR #1 (`feat/openai-compatible-routing`) and future OpenAI-compatible gateway support.

## Decision

AgInTiFlow should incorporate the useful part of PR #1:

- Support `OPENAI_BASE_URL` for OpenAI-compatible gateways.
- Allow project-local env configuration to affect model/provider display.

AgInTiFlow should not incorporate the confusing part as-is:

- Do not add a built-in model named `gpt-5.4-high` as if it were an official OpenAI model.
- Do not encode reasoning effort inside built-in model identity.

The correct internal shape stays:

```text
provider=openai
model=gpt-5.4
reasoning=high
```

For custom gateways that really expose a model string such as `gpt-5.4-high`, users can still set that exact model name manually:

```env
AGENT_PROVIDER=openai
OPENAI_BASE_URL=https://example-gateway.local/v1
OPENAI_DEFAULT_MODEL=gpt-5.4-high
AGINTI_MAIN_REASONING=none
```

That sends the custom model name but omits AgInTiFlow's separate reasoning parameter.

## Rationale

AgInTiFlow's current model design separates three concepts:

- **Provider**: the API surface, such as `openai`, `deepseek`, `openrouter`, `qwen`, `venice`, or future `lazyingrouter`.
- **Model**: the provider model id or gateway alias.
- **Reasoning**: optional effort level, such as `low`, `medium`, `high`, or `xhigh`.

This separation matters because direct OpenAI, OpenRouter, Venice, and LazyingRouter-style gateways may all expose different model ids while AgInTiFlow still needs a consistent role-based routing layer.

Synthetic built-in ids like `gpt-5.4-high` make the UI look simple but blur the contract. They also risk sending an invalid `model` value to a provider that expects `gpt-5.4` plus a separate reasoning option.

## `OPENAI_BASE_URL`

`OPENAI_BASE_URL` should be accepted as an OpenAI-provider-specific base URL.

Recommended precedence:

```text
OPENAI_BASE_URL
LLM_BASE_URL
https://api.openai.com/v1
```

Reason:

- `OPENAI_BASE_URL` is explicit and only affects OpenAI-compatible routing.
- `LLM_BASE_URL` remains a generic fallback.
- The official OpenAI endpoint remains the default.

Accepted local env keys should include:

```env
OPENAI_API_KEY=
OPENAI_BASE_URL=https://api.openai.com/v1
OPENAI_DEFAULT_MODEL=gpt-5.4-mini
```

`OPENAI_BASE_URL` is not a secret, but it belongs in the same local environment mechanism because users often configure it together with `OPENAI_API_KEY`.

## Reasoning "None" Option

Reasoning must be optional. Some OpenAI-compatible gateways encode effort in the model name or do not support reasoning at all.

Recommended user-facing selector label:

```text
Provider default
```

Recommended internal value:

```text
""
```

Accepted CLI/env aliases:

```text
none
off
default
provider-default
provider_default
auto
""
```

All of those should normalize to an empty reasoning value, meaning AgInTiFlow should omit the reasoning option from provider requests.

Why not use `none` internally:

- `none` is a user-facing command word, not a provider value.
- Empty string already means "no explicit reasoning override" in current role config.
- Keeping the runtime value empty avoids accidentally sending `"reasoning": "none"` to providers.

## Selector Behavior

Model selectors should show reasoning as a separate field:

```text
Model: GPT-5.4
Reasoning: Provider default | low | medium | high | xhigh
```

Preset examples:

```text
OpenAI GPT-5.4
provider=openai
model=gpt-5.4
reasoning=medium

OpenAI GPT-5.4 High Reasoning
provider=openai
model=gpt-5.4
reasoning=high

Custom OpenAI-Compatible Gateway Model
provider=openai
model=gpt-5.4-high
reasoning=
```

The last case is a user or project configuration, not a built-in official OpenAI model.

## Incorporation Plan For PR #1

Cherry-pick the useful intent:

1. Add `OPENAI_BASE_URL` to the local env allow-list.
2. Update OpenAI provider defaults to prefer `OPENAI_BASE_URL`.
3. Add `OPENAI_BASE_URL` to `.aginti/.env.example` generated by project initialization.
4. Load project env before `aginti models`, but preserve normal shell-env precedence unless runtime behavior is intentionally changed.
5. Add a `Provider default` reasoning selector option and normalize common aliases to empty string.

Do not cherry-pick:

1. Built-in `PROVIDER_MODEL_CATALOG.openai` entry for `gpt-5.4-high`.
2. Provider dropdown defaulting OpenAI to `gpt-5.4-high`.
3. Examples implying `gpt-5.4-high` is a standard official OpenAI model.

## Tests To Add

Minimum regression tests:

1. `OPENAI_BASE_URL` is used before `LLM_BASE_URL` for provider `openai`.
2. `LLM_BASE_URL` still works when `OPENAI_BASE_URL` is unset.
3. `AGINTI_MAIN_REASONING=none` normalizes to empty reasoning.
4. `AGINTI_MAIN_REASONING=provider-default` normalizes to empty reasoning.
5. Official OpenAI presets keep `model=gpt-5.4` and a separate reasoning value.
6. A custom gateway config can use `OPENAI_DEFAULT_MODEL=gpt-5.4-high` with empty reasoning.

## Future LazyingRouter Alignment

This policy also matches the LazyingRouter design:

```env
AGENT_PROVIDER=lazyingrouter
LAZYINGROUTER_BASE_URL=https://router.lazying.art/v1
LAZYINGROUTER_MODEL=lazying/auto
AGINTI_MAIN_REASONING=provider-default
```

LazyingRouter can route `lazying/auto` internally without AgInTiFlow inventing provider-specific model aliases or leaking upstream routing semantics into the client UI.

