# Migrating from 0.23.0 to 0.23.1

0.23.1 is backward-compatible for `iModel()` and `Branch` usage. Import paths for
provider internals changed.

---

## Breaking: Provider import paths

The monolithic `service/connections/providers/` and `service/third_party/` modules are
replaced by a per-company, per-endpoint layout under `lionagi/providers/`.

```bash
grep -rn "from lionagi.service.connections.providers\|from lionagi.service.third_party" \
     --include="*.py" .
```

| Old import | New import |
|---|---|
| `from lionagi.service.connections.providers.oai_ import OpenaiChatEndpoint` | `from lionagi.providers.openai.chat.endpoint import OpenaiChatEndpoint` |
| `from lionagi.service.connections.providers.oai_ import OpenaiResponseEndpoint` | `from lionagi.providers.openai.response.endpoint import OpenaiResponseEndpoint` |
| `from lionagi.service.connections.providers.oai_ import OpenrouterChatEndpoint` | `from lionagi.providers.openrouter.chat.endpoint import OpenrouterChatEndpoint` |
| `from lionagi.service.connections.providers.oai_ import GroqChatEndpoint` | `from lionagi.providers.groq.chat.endpoint import GroqChatEndpoint` |
| `from lionagi.service.connections.providers.oai_ import GeminiChatEndpoint` | `from lionagi.providers.google.chat.endpoint import GeminiChatEndpoint` |
| `from lionagi.service.connections.providers.oai_ import DeepseekChatEndpoint` | `from lionagi.providers.deepseek.chat.endpoint import DeepseekChatEndpoint` |
| `from lionagi.service.connections.providers.anthropic_ import AnthropicMessagesEndpoint` | `from lionagi.providers.anthropic.messages.endpoint import AnthropicMessagesEndpoint` |
| `from lionagi.service.connections.providers.ollama_ import OllamaChatEndpoint` | `from lionagi.providers.ollama.chat.endpoint import OllamaChatEndpoint` |
| `from lionagi.service.connections.providers.perplexity_ import PerplexityChatEndpoint` | `from lionagi.providers.perplexity.chat.endpoint import PerplexityChatEndpoint` |
| `from lionagi.service.connections.providers.exa_ import ExaSearchEndpoint` | `from lionagi.providers.exa.search.endpoint import ExaSearchEndpoint` |
| `from lionagi.service.connections.providers.tavily_ import TavilySearchEndpoint` | `from lionagi.providers.tavily.search.endpoint import TavilySearchEndpoint` |
| `from lionagi.service.connections.providers.firecrawl_ import FirecrawlScrapeEndpoint` | `from lionagi.providers.firecrawl.scrape.endpoint import FirecrawlScrapeEndpoint` |
| `from lionagi.service.third_party.openai_models import OpenAIChatCompletionsRequest` | `from lionagi.providers.openai.chat.models import OpenAIChatCompletionsRequest` |
| `from lionagi.service.third_party.anthropic_models import CreateMessageRequest` | `from lionagi.providers.anthropic.messages.models import CreateMessageRequest` |
| `from lionagi.service.third_party.exa_models import ExaSearchRequest` | `from lionagi.providers.exa.search.models import ExaSearchRequest` |
| `from lionagi.service.third_party.deepseek_models import DeepseekChatRequest` | `from lionagi.providers.deepseek.chat.models import DeepseekChatRequest` |
| `from lionagi.service.third_party.pplx_models import PerplexityChatRequest` | `from lionagi.providers.perplexity.chat.models import PerplexityChatRequest` |
| `from lionagi.service.third_party.tavily_models import TavilySearchRequest` | `from lionagi.providers.tavily.search.models import TavilySearchRequest` |
| `from lionagi.service.third_party.firecrawl_models import FirecrawlScrapeRequest` | `from lionagi.providers.firecrawl.scrape.models import FirecrawlScrapeRequest` |

Pattern: `lionagi.service.connections.providers.{slug}` → `lionagi.providers.{company}.{endpoint}.endpoint`
and `lionagi.service.third_party.{slug}_models` → `lionagi.providers.{company}.{endpoint}.models`.

---

## New: Provider registry

`EndpointRegistry` replaces the internal lookup table in `match_endpoint.py`. Endpoints
self-register via decorator at import time.

```python
from lionagi.service.connections.registry import EndpointRegistry, register_endpoint

@register_endpoint(provider="acme", endpoint="chat", base_url="https://api.acme.io/v1")
class AcmeChatEndpoint(Endpoint):
    ...
```

`match_endpoint()` still works and delegates to the registry — no call-site changes needed
unless you were monkey-patching the old lookup dict.

---

## New: AgenticEndpoint (renamed from CLIEndpoint)

`CLIEndpoint` is now `AgenticEndpoint`. The old name is kept as an alias in
`cli_endpoint.py` but will be removed in a future release.

```bash
grep -rn "CLIEndpoint" --include="*.py" .
```

```python
# before
from lionagi.service.connections import CLIEndpoint

# after
from lionagi.service.connections import AgenticEndpoint
```

Both names resolve to the same class today. Migrate at your convenience.

---

## New: Note model

Lightweight nested-dict wrapper used internally by flow operations.

```python
from lionagi.models.note import Note

n = Note(content={"a": {"b": 1}})
n["a", "b"]          # 1
n["a", "b"] = 2
n.pop(("a", "b"))
```

Opt-in for user code. No existing APIs changed.

---

## New: AG2 GroupChat (optional dependency)

```bash
pip install lionagi[ag2]
```

```python
from lionagi.providers.ag2.groupchat.endpoint import AG2GroupChatEndpoint

ep = AG2GroupChatEndpoint(agents=[...], max_round=10)
```

Only installed when the `ag2` extra is requested.

---

## New: nested utilities

```python
from lionagi.libs.nested import nget, nset, npop, flatten, unflatten, deep_update

data = {"a": {"b": [1, 2, 3]}}
nget(data, ["a", "b", 0])          # 1
nset(data, ["a", "c"], 42)
npop(data, ["a", "b"])
flat = flatten(data)               # {"a|b": ..., "a|c": 42}
deep_update(data, {"a": {"d": 0}}) # merges, does not overwrite siblings
```

---

## Changelog

Full details: [`../../CHANGELOG.md`](../../CHANGELOG.md) — `[0.23.1]` entry.
