Metadata-Version: 2.4
Name: psygen-llm
Version: 0.2.2
Summary: LLM-chained psychological profile generator for fictional characters (Psygen revised).
Author: Stardew AI NPC contributors
License-Expression: MIT
License-File: LICENSE
Keywords: character,llm,npc,profile,psychology,stardew
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: jsonschema>=4.20.0
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.24.0; extra == 'dev'
Requires-Dist: pytest>=8.0.0; extra == 'dev'
Provides-Extra: openai
Requires-Dist: openai>=1.40.0; extra == 'openai'
Description-Content-Type: text/markdown

# psygen-llm

Python package implementing **Psygen Revised**: a three-stage (optional fourth) LLM pipeline that produces a structured psychological profile for a character from a natural-language query.

- **Schema**: JSON Schema for each layer and the merged profile (`package data`).
- **Runner**: `ProfileGenerator` chains axiom → intermediate → emergent calls, validates JSON, merges evidence.
- **Prompt surface**: `to_prompt_string()` emits dialogue-ready text (20 emergent traits + coping style + role identity), capped at 600 characters per the design contract.

## Install and publish (uv)

Requires [uv](https://docs.astral.sh/uv/) and Python **3.10+** (see `requires-python` in `pyproject.toml`). PyPI name **`psygen-llm`**, import **`psygen_llm`**, CLI **`psygen-llm`**.

For **publishing**, the path is: **build with uv**, **publish the artifacts**. For **using** the package from PyPI, install into a **local virtual environment** (for example `uv venv` then activate the `.venv`, or use whatever venv your project already uses) — not system-wide Python.

From the repository root, bump `version` in `pyproject.toml` when publishing a new release, and configure PyPI credentials for Twine (for example `~/.pypirc` or the usual `TWINE_*` environment variables).

**Install dev mode**
```
uv pip install -e .
```

**Build and push** (maintainers):

```bash
uv build
uvx twine upload dist/*
```

**Install into the active venv** (after the release is on PyPI; with that environment selected — no `--system`):

```bash
uv pip install "psygen-llm"
```

Use `uv pip install "psygen-llm[openai]"` for the optional OpenAI dependency. To remove: `uv pip uninstall psygen-llm` (it is fine if nothing is installed). Quote extras so the shell does not treat `[openai]` as a glob.

## OpenAI config

Create a JSON file (e.g. `psygen.json`, keep it private — `chmod 600` — and do not commit it):

```json
{
  "openai": {
    "api_key": "sk-...",
    "model": "gpt-4o-mini",
    "base_url": null
  }
}
```

`openai.api_key` and `openai.model` are required. `openai.base_url` is optional; omit it or set it to `null` for the default OpenAI API URL.

## Quick use

```python
import asyncio
from psygen_llm import ProfileGenerator, OpenAiLlmClient

async def main():
    client = OpenAiLlmClient.from_config_file("psygen.json")
    gen = ProfileGenerator(client)
    profile = await gen.generate("Linus from Stardew Valley")
    print(profile.to_prompt_string())
    print(profile.to_json())

asyncio.run(main())
```

## Custom LLM backend

Implement `psygen_llm.protocols.LlmClient` (`complete(system, user) -> str`) and pass it to `ProfileGenerator`.

## CLI

By default the merged profile JSON is written to `output/<slug>.json` (slug derived from your query; the `output/` directory is created if needed). Use `-o` for another path, or `-o -` to print JSON to stdout.

```bash
psygen-llm --config psygen.json "Linus from Stardew Valley"
psygen-llm --config psygen.json "Linus from Stardew Valley" -o /tmp/linus.json
psygen-llm --config psygen.json "Linus from Stardew Valley" -o -
```

## Design

See [DESIGN.md](./DESIGN.md) and [PLAN.md](./PLAN.md) in this directory.

## License

MIT
