Metadata-Version: 2.4
Name: concinno-skills-media
Version: 0.1.0
Summary: Media + smart-home agent skills (OpenAI image generation / Replicate any-model / Home Assistant state + service) for Concinno.
Project-URL: Homepage, https://github.com/aiking931931/concinno
Project-URL: Issues, https://github.com/aiking931931/concinno/issues
Project-URL: Changelog, https://github.com/aiking931931/concinno/blob/main/projects/concinno-skills-media/CHANGELOG.md
Author-email: "AI King (Chen-Xuan Wang)" <me@ai-king.dev>
License-Expression: Apache-2.0
Keywords: agent,concinno,dall-e,flux,home-assistant,image-generation,media,replicate,sdxl,skills,smart-home
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software 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: Topic :: Home Automation
Classifier: Topic :: Multimedia :: Graphics
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Requires-Dist: concinno>=2.15.1
Requires-Dist: httpx>=0.27
Requires-Dist: openai>=1.50
Requires-Dist: replicate>=1.0
Provides-Extra: dev
Requires-Dist: mypy>=1.10; extra == 'dev'
Requires-Dist: pytest-cov>=5; extra == 'dev'
Requires-Dist: pytest>=8; extra == 'dev'
Requires-Dist: ruff>=0.7; extra == 'dev'
Description-Content-Type: text/markdown

# concinno-skills-media

Media + smart-home agent skills for [Concinno](https://pypi.org/project/concinno/)
— OpenAI image generation, Replicate any-model dispatch, and Home
Assistant state + service control via REST.

## Status

MVP (0.1.0) — four tools, three upstream services. Fifth sub-package in
the `concinno-skills-*` ecosystem (after `-google`, `-chat`, `-content`,
`-video`), built to the same entry-points + Tool-protocol pattern.

## Tools

| Tool | Action(s) | Upstream | Paid | Concurrency-safe |
|---|---|---|---|---|
| `ImageGenerate` | `create` | OpenAI `images.generate` (`dall-e-3` / `gpt-image-1`) | Yes | False |
| `ReplicateRun` | `run` | `replicate.Client.run` (any model) | Yes | False |
| `HomeAssistantState` | `get` / `set` | HA REST `/api/states/<entity_id>` | No | False |
| `HomeAssistantService` | `call` | HA REST `/api/services/<domain>/<service>` | No | False |

## Install

```bash
pip install concinno-skills-media
```

Deps pulled transitively: `openai>=1.50`, `replicate>=1.0`, `httpx>=0.27`,
`concinno>=2.15.1`.

## Credentials

All four tools read via `concinno.core.credentials.CredentialStore`
(four-source precedence: runtime override > env var > `~/.concinno/credentials.json`
> `None`). Keys:

| Key | Env alias | Required by |
|---|---|---|
| `openai_api_key` | `CONCINNO_CRED_OPENAI_API_KEY` | `ImageGenerate` |
| `replicate_api_token` | `CONCINNO_CRED_REPLICATE_API_TOKEN` | `ReplicateRun` |
| `homeassistant_url` | `CONCINNO_CRED_HOMEASSISTANT_URL` | `HomeAssistantState`, `HomeAssistantService` |
| `homeassistant_token` | `CONCINNO_CRED_HOMEASSISTANT_TOKEN` | `HomeAssistantState`, `HomeAssistantService` |

### `~/.concinno/credentials.json` example

```json
{
  "openai_api_key": "sk-...",
  "replicate_api_token": "r8_...",
  "homeassistant_url": "http://ha.local:8123",
  "homeassistant_token": "eyJhbGci..."
}
```

The HA token is a
[Long-Lived Access Token](https://www.home-assistant.io/docs/authentication/#your-account-profile)
minted from your HA profile → Security page.

## Cost warnings

`ImageGenerate` and `ReplicateRun` hit paid APIs. Every call logs a
`logger.warning` line so `CostTracker` (if running in the host) can
reconcile against billing:

- DALL-E 3: ~$0.04/image standard, ~$0.08 hd (1024² / 1792×1024)
- `gpt-image-1`: see [OpenAI pricing](https://platform.openai.com/docs/pricing)
- Replicate: see the per-model pricing card on replicate.com

No local free-tier fallback is provided — use
[`concinno-skills-content`](https://pypi.org/project/concinno-skills-content/)'s
`KeywordExtract` (local KeyBERT) if you want a free alternative for the
text side.

## Usage via Concinno `ToolRegistry`

When the consumer sets `CONCINNO_LOAD_PLUGINS=1`, the default registry
auto-mounts all four tools:

```python
import os
os.environ["CONCINNO_LOAD_PLUGINS"] = "1"

from concinno.tools.registry import get_default_registry

reg = get_default_registry()
names = set(reg.list_deferred())
assert {"ImageGenerate", "ReplicateRun",
        "HomeAssistantState", "HomeAssistantService"} <= names

img = reg.get("ImageGenerate")
out = img.call(
    action="create",
    prompt="a cozy cat on a windowsill, sunset",
    model="dall-e-3",
    size="1024x1024",
    quality="standard",
    n=1,
)
print(out["urls"][0])
```

## Direct Python usage

```python
from concinno_skills_media import (
    ImageGenerate, ReplicateRun,
    HomeAssistantState, HomeAssistantService,
)

# 1) Generate an image via DALL-E 3.
img = ImageGenerate().call(
    action="create",
    prompt="a 1990s anime cityscape at night",
    model="dall-e-3",
    size="1792x1024",
    quality="hd",
)
if img["ok"]:
    print(img["urls"][0])

# 2) Any Replicate model (Flux, SDXL, Wan, music, video, voice...)
flux = ReplicateRun().call(
    action="run",
    model="black-forest-labs/flux-schnell",
    input={"prompt": "an iguana on the beach, photorealistic"},
)
print(flux["output"])  # single URL or list of URLs depending on model

# 3) Home Assistant — read a light's state.
st = HomeAssistantState().call(
    action="get", entity_id="light.living_room"
)
print(st["state"], st["attributes"])

# 4) Home Assistant — turn that light on.
svc = HomeAssistantService().call(
    action="call",
    domain="light",
    service="turn_on",
    target={"entity_id": "light.living_room"},
    data={"brightness": 200, "color_name": "warm_white"},
)
print(svc["ok"], len(svc["changed"]))
```

All tools return either a structured `{"ok": True, ...}` dict or
`{"ok": False, "error": "..."}` — never raise. Matches the rest of the
Concinno tool ecosystem.

## Safety notes

### `HomeAssistantService` dangerous calls

Certain HA services mutate the installation itself or destroy history:

- `homeassistant.restart` — drops the HA process mid-work
- `homeassistant.stop` — shuts HA down entirely
- `recorder.purge` / `recorder.purge_entities` — drops historical data

The tool **warns** via `logger.warning` when these are invoked but does
**not** block them — this is a power-user tool. If you want hard blocks,
wrap in a custom guard / `PreToolUse` hook at the Concinno layer.

### `ImageGenerate` safety rails

- `n` capped to 4 regardless of model (OpenAI itself caps DALL-E 3 at 1).
- `size` / `quality` validated against the published per-model enum;
  invalid values return `{"ok": False, "error": ...}` before any HTTP.
- Prompt capped at 4000 chars (DALL-E 3 limit — `gpt-image-1` accepts
  much longer, but we keep the guard symmetric).

## License

Apache-2.0. See `LICENSE` in the Concinno monorepo.
