kestrel-feature-visual
Visual identity for Kestrel Sovereign agents — avatar generation, selfies, and LoRA training for character consistency. Uses Replicate for image generation with optional LoRA training for consistent visual identity across generated images.
Installation
uv pip install kestrel-feature-visual
The feature is auto-discovered by Kestrel Sovereign via the kestrel_sovereign.features entry point — install it alongside kestrel-sovereign and the VisualIdentityFeature registers itself at startup.
Configuration
| Variable | Description |
|---|---|
REPLICATE_API_TOKEN |
Replicate API token for image generation (required for avatar/selfie tools) |
Tools provided
generate_avatar— Create a portrait avatar from a descriptiongenerate_selfie— Generate a selfie in various scenes (casual, portrait, glamour, flirty, cozy, adventure, mysterious, romantic, playful, dreamy, confident)train_lora— Kick off LoRA training for character consistency (requireskestrel-feature-loraor another training provider installed alongside)
Canonical LoRA selfie specification
Queue-backed providers must use resolve_lora_selfie_spec() when a selfie is
quoted and bind_lora_selfie_spec() immediately before dispatch. Both paths
produce the same content-free spec_sha256 over the final prompt hash,
generation parameters, and immutable promoted-LoRA identity. The plaintext
prompt remains transient and is never part of the persisted evidence object.
scene and style are caller-owned. This package normalizes them (whitespace
collapsed, lowercased) and bounds their length, but never rejects one for failing to
appear in its own tables — frinz forwards both unvalidated from an HTTP body and from
LLM tool arguments, and deliberately supports free-form prose scenes such as
stargazing at night with aurora borealis.
SELFIE_SCENE_PROMPTS and the style prefixes therefore govern only the descriptive
prompt text: an unrecognized scene contributes no description rather than silently
rendering as casual, and an unrecognized style adds no prefix. The scene reads the
same on the resolved prompt, the generation config, the returned result, and
spec_sha256, so two different scenes can never share a digest.
An absent scene or style — None, "", or whitespace — means "use the default"
(casual / photorealistic), not "fail". frinz forwards style completely raw from
both an unvalidated body field and an LLM tool argument.
On the no-LoRA reference route, when there is neither a custom prompt nor a known
scene description this package sends no prompt override, so the catalog worker's
own scene template is used instead of a subjectless stub. Otherwise the route uses
prompt_without_trigger(), which derives the trigger-free text from the resolved
prompt itself — rebuilding it in the caller silently dropped the style prefix.
The public ResolvedSelfiePrompt object carries the exact values that must be
sent to the image worker, including seed, dimensions, inference steps, and
guidance scale. Providers must reject a reconstructed digest that differs from
the accepted quote.
The object re-validates its own invariants on construction, not only inside
resolve_selfie_prompt(), because downstream consumers treat the type itself
as the trust boundary. It therefore carries the plaintext trigger_word
alongside trigger_word_sha256 and verifies that the digest matches the
trigger and that prompt binds that trigger exactly once as a whole token.
A directly constructed instance attesting a trigger the prompt never binds — or
binds twice — is rejected, so a valid spec_sha256 can never describe a prompt
that does not match it. Carrying the trigger in plaintext discloses nothing
further: it is already contained verbatim in prompt.
Dependencies
kestrel-sovereign-sdk>=0.25.0,<1— baseFeature,tool, andToolCategoryinterfacesreplicate>=1.0.4— Replicate API clienthttpx>=0.27.0— HTTP transport
Development
uv pip install -e '.[test]'
uv run pytest
License
Apache-2.0
Metadata
Release files for kestrel-feature-visual 0.4.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| kestrel_feature_visual-0.4.0.tar.gz | 48.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| kestrel_feature_visual-0.4.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 98.7 kB
Release files / kestrel_feature_visual-0.4.0.tar.gz
| Download URL | kestrel_feature_visual-0.4.0.tar.gz |
|---|---|
| Size | 48.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a08f7cbdb5effa0f6bd8d68aa824bbbe03468361d7e83df5df7c22e112d48cd0
|
|
BLAKE2b-256 checksum How to use checksums |
b84d4b709d7c0299367f5f75bf7810e64b5835648f04735071b34dca898466be
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 4, 2026.
Transparency logRelease files / kestrel_feature_visual-0.4.0-py3-none-any.whl
| Download URL | kestrel_feature_visual-0.4.0-py3-none-any.whl |
|---|---|
| Size | 50.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c7de99a8f66deaa006db8f638d53cc90ae930b004964b8e4720bc079d61a5b6b
|
|
BLAKE2b-256 checksum How to use checksums |
545c1a383adeaf77fcbbf2fde2479dad957cd6b768ec61423ae3a218e6c62b2a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 4, 2026.
Transparency log