# elsai ARMS — GitHub Copilot Instructions

# elsai ARMS

You are an expert in **elsai ARMS** (`elsai-arms`) — Agent Resource Management System for monitoring LLM usage, cost, latency, RAG, OCR, embeddings, and agent traces.

Pick **SaaS or on-prem** correctly: different package indexes, versions, and env vars.

## Installation

```bash
# SaaS
pip install \
  --extra-index-url https://arms-packages.elsaifoundry.ai/root/elsai-arms-sass/ \
  elsai-arms==1.3.4

# On-Prem
pip install \
  --index-url https://arms-packages.elsaifoundry.ai/root/elsai-arms/ \
  --extra-index-url https://pypi.org/simple \
  elsai-arms==2.3.0

# On-prem + Agentkit monitoring
pip install --extra-index-url https://arms-packages.elsaifoundry.ai/root/elsai-arms/ 'elsai-arms[elsai-agents]'
```

## Environment variables

| Variable | SaaS | On-Prem |
|---|---|---|
| `ELSAI_ARMS_API_KEY` | Required | Required |
| `API_BASE_URL` | Not needed | Required |
| `ARMS_MASTER_KEY` | Not needed | Required (license) |
| Database (`MONGO_*`, DynamoDB, ClickHouse, or `SQLITE_DB_PATH`) | Not needed | Choose one backend |

```bash
# SaaS
export ELSAI_ARMS_API_KEY=your-api-key-here

# On-Prem (MongoDB example)
export ELSAI_ARMS_API_KEY=arms-...
export API_BASE_URL=http://localhost:8001
export ARMS_MASTER_KEY=your-master-key
export MONGO_URI=mongodb://localhost:27017
export MONGO_DB_NAME=elsai_arms_db
```

Dashboard: SaaS → https://arms.elsaifoundry.ai/dashboard

## Package entry point

```python
from elsai_arms.elsai_arms import ElsaiARMS

arms = ElsaiARMS("Project_Name")
# or: ElsaiARMS(project_name="my-project")
```

Always finish a run with `arms.end_run()` and `arms.flush()` (and optionally `arms.export()`).

## Decorators (single-call metrics)

```python
@arms.monitor_llm_call
def get_response(prompt: str):
    return llm.invoke(prompt)

@arms.monitor_llm_astream
async def run_astream(prompt, llm):
    return llm.astream_events(...)

@arms.monitor_ocr_call(model_name="EasyOCR")
def run_ocr(image_path):
    ...

@arms.monitor_embedding_call
def get_embedding(text):
    ...

@arms.monitor_rag_call
def retrieve_documents(query, docs, top_k=2):
    ...

arms.log_custom_metric("Number of response", 1)
arms.info("Run completed")
arms.warning("…")
arms.error("…")
```

## Agent monitoring — pick one path per app

| Approach | API | Use when |
|---|---|---|
| Agentkit hook | `arms.elsai_agents_hook` | elsai `Agent` / Graph / Swarm (**on-prem** + `[elsai-agents]`) |
| LangChain callback | `arms.langchain_callback` | LangChain / LangGraph |
| LLM decorator | `@arms.monitor_llm_call` | Single LLM calls only (no full agent tree) |

**Do not** mix the Agentkit hook and LangChain callback in the same run.

### LangChain / LangGraph

```python
graph.invoke(
    {"messages": messages},
    config={"callbacks": [arms.langchain_callback]},
)
```

### Agentkit (on-prem)

Register the hook on the **manager / orchestrator only** — nested agents inherit it:

```python
from elsai import Agent
from elsai.agent import AgentConfig
from elsai_arms.elsai_arms import ElsaiARMS

arms = ElsaiARMS(project_name="my-project")

agent = Agent(
    model=model,
    tools=[...],
    config=AgentConfig(
        name="demo-agent",
        hooks=[arms.elsai_agents_hook],
    ),
)

result = await agent.invoke_async("Hello from ARMS")
arms.end_run()
arms.flush()
```

## Do / don't

- **Do** use `from elsai_arms.elsai_arms import ElsaiARMS`
- **Do** set SaaS vs on-prem env vars correctly (SaaS needs only the API key)
- **Do** call `end_run()` + `flush()` after work
- **Don't** invent dashboard REST clients when the SDK covers monitoring
- **Don't** use `elsai_agents_hook` on SaaS or without the `[elsai-agents]` extra
- **Don't** register the hook on every nested agent — manager only

## Docs

- Overview: `/arms/overview`
- Installation: `/arms/get-started/installation`
- Configuration: `/arms/get-started/configuration`
- Tutorial: `/arms/guides/tutorial`
- Agent monitoring: `/arms/guides/agent-monitoring/`
- SaaS: `/arms/product/saas`
- On-prem: `/arms/product/on-prem`

