Metadata-Version: 2.4
Name: prompt-complexity-analyzer
Version: 0.1.1
Summary: ML-powered prompt complexity analyzer for LLM routing
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Requires-Dist: scikit-learn>=1.3
Requires-Dist: numpy>=1.24
Requires-Dist: joblib>=1.3
Requires-Dist: sentence-transformers>=2.2
Requires-Dist: aiohttp>=3.9

# prompt-complexity-analyzer

ML-powered prompt complexity analyzer for LLM routing. Scores any prompt 1–10 and recommends the right model tier — no API calls, runs locally.

## Install

```bash
pip install prompt-complexity-analyzer
```

## Quick start

```python
from prompt_complexity_analyzer import complexity

r = complexity("prove P≠NP")
print(r.score)    # 9.2
print(r.tier)     # capable
print(r.model)    # claude-opus-4-6
print(r)          # Score 9.2/10 | Tier: capable | Model: claude-opus-4-6 | Backend: ml
r.explain()       # full breakdown with dimension scores
```

## Score tiers

| Score | Tier | Models |
|---|---|---|
| 1.0 – 3.5 | `fast` | claude-haiku-4-5 · gpt-4o-mini · gemini-2.0-flash |
| 3.6 – 6.5 | `balanced` | claude-sonnet-4-6 · gpt-4o · gemini-2.0-pro |
| 6.6 – 10.0 | `capable` | claude-opus-4-6 · o1 · gemini-2.5-pro |

## Providers

```python
r = complexity("your prompt", provider="openai")    # gpt-4o-mini / gpt-4o / o1
r = complexity("your prompt", provider="google")    # gemini-2.0-flash / pro / 2.5-pro
r = complexity("your prompt", provider="ollama")    # qwen3:1.7b / 14b / 32b
r = complexity("your prompt", provider="anthropic") # default
```

## Result object

```python
r = complexity("Compare ECDH vs RSA for TLS 1.3")

r.score          # float 1–10
r.tier           # "fast" | "balanced" | "capable"
r.model          # recommended model string for the chosen provider
r.label          # "Fast / Lightweight" | "Balanced" | "High Capability"
r.backend        # "ml" | "heuristic"
r.dimensions     # {"Reasoning Depth": 8.5, "Domain Specificity": 9.0, ...}
r.flags          # advisory messages, e.g. ["⚠ Very high complexity"]

# Fuzzy key access — substring matches dimension names
r["reasoning"]   # Reasoning Depth score
r["domain"]      # Domain Specificity score
r["multi"]       # Multi-part score
r["ambiguity"]   # Ambiguity score
r["output"]      # Output Complexity score

# Serialization
r.to_dict()      # plain dict
r.to_json()      # JSON string
```

## explain() output

```
  ────────────────────────────────────────────────────────────
  Score        8.1 / 10
  Tier         High Capability
  Model        claude-opus-4-6  [anthropic]
  Backend      ml
  Use when     Complex research, deep reasoning, ambiguous high-stakes tasks
  ────────────────────────────────────────────────────────────

  Dimension                Bar               Score
  ──────────────────────────────────────────────────────────
  Vocabulary               ████░░░░░░░░░░     4.5
  Multi-part               ████████░░░░░░     7.0
  Reasoning Depth          █████████░░░░░     8.5
  Domain Specificity       █████████░░░░░     9.0
  Ambiguity                ███░░░░░░░░░░░     2.0
  Output Complexity        █████░░░░░░░░░     4.5
```

## CLI

```bash
# Full breakdown
prompt_complexity_analyzer -p "your prompt"

# Single field
prompt_complexity_analyzer --only score -p "your prompt"
prompt_complexity_analyzer --only tier -p "your prompt"
prompt_complexity_analyzer --only model -p "your prompt"
prompt_complexity_analyzer --only reasoning -p "your prompt"

# Provider
prompt_complexity_analyzer --provider openai -p "your prompt"

# JSON output
prompt_complexity_analyzer --json -p "your prompt"

# Stdin
echo "your prompt" | prompt_complexity_analyzer
```

## Load a custom ML model

```python
from prompt_complexity_analyzer import set_model, complexity

set_model("./my_model.joblib")   # call once at startup
r = complexity("your prompt")
print(r.backend)  # ml

# Or per-call
r = complexity("your prompt", model_path="./my_model.joblib")
```

## Semantic embeddings

The package uses `sentence-transformers` (all-MiniLM-L6-v2) for higher-accuracy scoring. The embedding model loads automatically on import if `sentence-transformers` is installed (it is — it's a hard dependency). The first run downloads ~80MB, cached locally after that.

```python
from prompt_complexity_analyzer import load_embedding_model, complexity

load_embedding_model()   # explicit load — optional, auto-loads on import
r = complexity("your prompt")
```

## Feature dimensions

| Dimension | What it measures |
|---|---|
| Vocabulary | Technical word length (binned) |
| Multi-part | Subtask signals — "also", "furthermore", numbered steps |
| Reasoning Depth | Keywords: analyze, prove, deduce, evaluate, compare… |
| Domain Specificity | Math · Code · Security · Medical · Legal · Finance · Science |
| Ambiguity | Vague qualifiers: "something", "maybe", "kind of"… |
| Output Complexity | Structured output signals: JSON, essay, table, code block |
