# elsai Prompt Manager — Claude Code Instructions

# elsai Prompt Manager

You are an expert in the **elsai Prompt Manager SDK** (`elsai-prompts`). Use it to fetch versioned prompts at runtime — do not hardcode production prompts in application code when the SDK is available.

## Installation

```bash
# SaaS
pip install --extra-index-url https://elsai-core-package.optisolbusiness.com/root/elsai-prompts-sass/ elsai-prompts==2.0.0

# On-Prem
pip install --extra-index-url https://elsai-core-package.optisolbusiness.com/root/elsai-prompts/ elsai-prompts==2.0.0
```

Requires Python **3.10–3.12**. Pin the version in production.

## Package layout

```
elsai_prompts.prompt_manager
├── PromptManager          # client — construct once per process
├── PromptContent          # returned by get_active_prompt_version*
└── PromptNotReleasedInEnvironmentError
```

## Initialize

```python
import os
from dotenv import load_dotenv
from elsai_prompts.prompt_manager import PromptManager

load_dotenv()

pm = PromptManager(
    api_key=os.environ["ELSAI_API_KEY"],
    project_id=os.environ["ELSAI_PROJECT_ID"],
    environment=os.environ["ELSAI_ENVIRONMENT"],  # development | testing | production
    # base_url=os.environ.get("PROMPT_MANAGER_API_URL"),  # on-prem only
    timeout=20,
)
```

### Required credentials

| Argument / env | Required | Notes |
|---|---|---|
| `api_key` / `ELSAI_API_KEY` | Yes | Console API key (`elsai_…`) |
| `project_id` / `ELSAI_PROJECT_ID` | Yes | Project UUID from console URL |
| `environment` / `ELSAI_ENVIRONMENT` | Yes | Runtime env of *this code* |
| `base_url` / `PROMPT_MANAGER_API_URL` | On-prem only | SaaS build hardcodes the host |

Construct **one** `PromptManager` per process (or per project). It is thread-safe.

## Fetch and render

```python
prompt = pm.get_active_prompt_version("welcome_email")
print(prompt.kind)           # instruction | f_string | chat | structured
print(prompt.version_label)
print(prompt.environments)

# Substitute {{variable}} placeholders (kind-aware)
rendered = prompt.render({"name": "Ada"})
```

Per-call environment override:

```python
prod = pm.get_active_prompt_version_for_environment(
    "welcome_email",
    environment="production",
)
```

Kinds and `render()` return types:

| Kind | `render(vars)` returns |
|---|---|
| `instruction` | `str` (no substitution) |
| `f_string` | `str` with `{{vars}}` filled |
| `chat` | `list[{role, content}]` |
| `structured` | `dict` with `base` + `response_schema` |

Missing `{{vars}}` become empty strings. Extra keys are ignored. Use `prompt.variables` as the canonical variable list.

## Error handling

```python
from elsai_prompts.prompt_manager import PromptNotReleasedInEnvironmentError

try:
    prompt = pm.get_active_prompt_version("welcome_email")
except PromptNotReleasedInEnvironmentError as e:
    # Active version exists but is not released to this environment
    print(e.prompt_name, e.requested_environment, e.available_environments)
    raise
```

Also handle `requests.exceptions.HTTPError` (e.g. 404), `RequestException` (network/timeout), and constructor `ValueError` for missing args.

## Do / don't

- **Do** fetch prompts by name via `PromptManager`; keep prompts in the registry
- **Do** load credentials from env / `.env` — never commit API keys
- **Do** use exact environment strings that match release tags (`development` ≠ `testing`)
- **Don't** invent REST clients or mock `PromptManager` APIs
- **Don't** hardcode SaaS vs on-prem hosts incorrectly — SaaS omits `base_url`; on-prem requires it
- **Don't** silently swallow `PromptNotReleasedInEnvironmentError` in production

## Docs

- Overview: `/prompt-manager/overview`
- Installation: `/prompt-manager/get-started/installation`
- Configuration: `/prompt-manager/get-started/configuration`
- SDK overview: `/prompt-manager/sdk/overview`
- SaaS console: https://promptmanager-new.elsaifoundry.ai/

