Metadata-Version: 2.4
Name: intent-score
Version: 0.1.0
Summary: Score social posts 0-100 for buying intent with transparent regex rules, plus an optional LLM prompt template.
Author: Prospy
License-Expression: MIT
Project-URL: Homepage, https://prospy.io
Project-URL: Repository, https://codeberg.org/prospy/intent-score
Project-URL: Issues, https://codeberg.org/prospy/intent-score/issues
Keywords: buying-intent,lead-generation,social-listening,nlp,classification
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Text Processing :: Linguistic
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# intent-score

Score a social post 0–100 for **buying intent** with transparent, editable regex rules. There's also an optional LLM prompt template for posts the rules can't call.

```
$ intent-score "Is there a tool that finds people asking for a CRM on forums? Need one for my startup asap."
 75 high   Is there a tool that finds people asking for a CRM on forums? Need one for my startup asap.
           +25 asks whether a tool exists; +25 states a need; +10 business context; +10 urgency; +5 asks a question
```

- Pure Python, no dependencies, no network calls.
- Every point in a score comes with a reason, so you can see why a post scored the way it did.
- Ships with a static, in-browser demo (`space/`) that uses the exact same rules.
- The example posts in `examples/` are made up. No real user posts are included.

## Install

```bash
pip install intent-score     # once published
# or from a checkout:
pip install .
```

## Usage

```bash
# Score text directly
intent-score "Can anyone recommend a simple invoicing app?"

# Score a JSON-lines file, keep only strong signals, emit JSON
intent-score --jsonl examples/sample_posts.jsonl --min 60 --json

# Plain text on stdin, one post per line
cat posts.txt | intent-score

# Combine with a watcher, e.g. hn-keyword-watch or bsky-keyword-watch
hn-keyword-watch "alternative to" --json | intent-score --jsonl - --field title,text --min 25
```

In Python:

```python
from intent_score import score, IntentScorer, load_rules

r = score("Looking for an alternative to our help desk, budget is flexible")
print(r.score, r.label, r.reasons)   # 85 high ['+30 asks for a solution', ...]

custom = IntentScorer(load_rules("my_rules.json"))
```

### How scoring works

`src/intent_score/rules.json` holds a list of `{id, pattern, weight, reason}` rules. Each rule that matches adds its weight once. Negative weights cover self-promotion, job posts, promo codes and "not looking for...". The total is clamped to 0–100 and labelled `high` (≥60), `medium` (≥25) or `low`. Copy the file and tune it for your niche with `--rules my_rules.json`.

### Optional LLM step

intent-score never calls an LLM. If you want a second opinion on borderline posts, build a prompt and send it to whichever model you already use:

```python
from intent_score import build_prompt, parse_llm_response

prompt = build_prompt(post_text, product="a social listening tool for agencies")
reply = my_llm(prompt)                 # your own client
print(parse_llm_response(reply))       # {'score': 82, 'label': 'high', 'reason': '...'}
```

Or print prompts from the CLI with `intent-score --prompt "a CRM for agencies" "post text"`.

## Static demo (Hugging Face Space ready)

`space/` is a plain HTML/JS page (`index.html`, `scorer.js`, `rules.js`) with Space front-matter in `space/README.md` (`sdk: static`). Open `space/index.html` locally or upload the folder as a static Space. After you edit `rules.json`, run `python scripts/build_space.py` to regenerate `space/rules.js`. A test checks that the JS and Python scorers agree.

## Limits

- It matches English keywords. It won't catch sarcasm or context, and it doesn't know about other languages. Treat the score as a first filter, not a verdict.
- The default weights were tuned on a small set of made-up examples. Check them against your own data.
- When you score posts from a public platform, follow that platform's API terms and rate limits, and don't contact people in bulk based on a score.

If you'd rather not run this yourself, [Prospy](https://prospy.io) does social listening and AI lead generation across X/Twitter, Reddit, Bluesky and Hacker News, surfacing buying-intent posts.

## Development

```bash
PYTHONPATH=src python -m unittest discover -s tests -v
```

## License

MIT
