Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
lint:
timeout-minutes: 10
name: lint
runs-on: ${{ github.repository == 'stainless-sdks/luma-agents-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
runs-on: ${{ startsWith(github.repository, 'stainless-sdks/') && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
if: (github.event_name == 'push' || github.event.pull_request.head.repo.fork) && (github.event_name != 'push' || github.event.head_commit.message != 'codegen metadata')
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
Expand All @@ -44,7 +44,7 @@ jobs:
permissions:
contents: read
id-token: write
runs-on: ${{ github.repository == 'stainless-sdks/luma-agents-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
runs-on: ${{ startsWith(github.repository, 'stainless-sdks/') && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

Expand Down Expand Up @@ -84,7 +84,7 @@ jobs:
test:
timeout-minutes: 10
name: test
runs-on: ${{ github.repository == 'stainless-sdks/luma-agents-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
runs-on: ${{ startsWith(github.repository, 'stainless-sdks/') && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
if: github.event_name == 'push' || github.event.pull_request.head.repo.fork
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
Expand Down
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "0.4.0"
".": "0.5.0"
}
4 changes: 2 additions & 2 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
configured_endpoints: 7
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/luma-ai-karanganesan/luma-agents-97a8aef0de4fd193e5eef598041e2faf1bf46e86eb0c88ae54a35a2caa6aff79.yml
openapi_spec_hash: 5ddbbb17402e16c48a87d8e8b1f89e34
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/luma-ai-karanganesan/luma-agents-8c5b06cd9d673015a5a9c1790d7fee4ce93fd10b2d9e3ee27cf29fbc03d1f829.yml
openapi_spec_hash: 9c99c38e4976acbd2ebcb09fac7cd8bf
config_hash: cc17190a7b86cf4c8868ec2f674b5221
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# Changelog

## 0.5.0 (2026-08-04)

Full Changelog: [v0.4.0...v0.5.0](https://github.com/lumalabs/luma-agents-python/compare/v0.4.0...v0.5.0)

### Features

* **api:** add layering parameter, type enum, Layer/Layering models to generations ([6206d27](https://github.com/lumalabs/luma-agents-python/commit/6206d274b27c2fce8faeb7f1824ca9a782d1a517))
* **stlc:** configurable CI runner and private-production-repo support in workflow templates ([8bb3cfc](https://github.com/lumalabs/luma-agents-python/commit/8bb3cfcd6c1c1541b7e0170d4d4934d95713bea3))

## 0.4.0 (2026-06-23)

Full Changelog: [v0.3.0...v0.4.0](https://github.com/lumalabs/luma-agents-python/compare/v0.3.0...v0.4.0)
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,9 @@ client = Luma()

generation = client.generations.create(
prompt="A glass of iced coffee on a marble countertop, morning light streaming through a window",
source={},
layering={},
)
print(generation.source)
print(generation.layering)
```

## Handling errors
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "luma-agents"
version = "0.4.0"
version = "0.5.0"
description = "The official Python library for the luma API"
dynamic = ["readme"]
license = "Apache-2.0"
Expand Down
2 changes: 1 addition & 1 deletion src/luma_agents/_version.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.

__title__ = "luma_agents"
__version__ = "0.4.0" # x-release-please-version
__version__ = "0.5.0" # x-release-please-version
16 changes: 14 additions & 2 deletions src/luma_agents/resources/generations.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,12 @@ def create(
]
| Omit = omit,
image_ref: Iterable[ImageRefParam] | Omit = omit,
layering: Optional[generation_create_params.Layering] | Omit = omit,
model: Model | Omit = omit,
output_format: Optional[Literal["png", "jpeg"]] | Omit = omit,
source: Optional[ImageRefParam] | Omit = omit,
style: Literal["auto", "manga"] | Omit = omit,
type: Literal["image", "image_edit", "video", "video_edit", "video_reframe"] | Omit = omit,
type: Literal["image", "image_edit", "video", "video_edit", "video_reframe", "layering"] | Omit = omit,
user_id: Optional[str] | Omit = omit,
video: Optional[VideoOptionsParam] | Omit = omit,
web_search: bool | Omit = omit,
Expand All @@ -85,6 +86,10 @@ def create(
image_ref: Reference images for style/content guidance. Up to 9 for type 'image', up to 8
for type 'image_edit'.

layering: Layer-extraction options for type=layering (model uni-1). The image to decompose
rides body.source; body.prompt optionally guides how to split it (max 500
characters). The server plans the layers automatically before generating.

model: Model identifier. `uni-1` is the default image tier; `uni-1-max` produces
higher-quality output than `uni-1` at a higher per-image price. `ray-3.2` is the
public video model for text-to-video, image-to-video, and video-to-video
Expand Down Expand Up @@ -132,6 +137,7 @@ def create(
"prompt": prompt,
"aspect_ratio": aspect_ratio,
"image_ref": image_ref,
"layering": layering,
"model": model,
"output_format": output_format,
"source": source,
Expand Down Expand Up @@ -214,11 +220,12 @@ async def create(
]
| Omit = omit,
image_ref: Iterable[ImageRefParam] | Omit = omit,
layering: Optional[generation_create_params.Layering] | Omit = omit,
model: Model | Omit = omit,
output_format: Optional[Literal["png", "jpeg"]] | Omit = omit,
source: Optional[ImageRefParam] | Omit = omit,
style: Literal["auto", "manga"] | Omit = omit,
type: Literal["image", "image_edit", "video", "video_edit", "video_reframe"] | Omit = omit,
type: Literal["image", "image_edit", "video", "video_edit", "video_reframe", "layering"] | Omit = omit,
user_id: Optional[str] | Omit = omit,
video: Optional[VideoOptionsParam] | Omit = omit,
web_search: bool | Omit = omit,
Expand All @@ -243,6 +250,10 @@ async def create(
image_ref: Reference images for style/content guidance. Up to 9 for type 'image', up to 8
for type 'image_edit'.

layering: Layer-extraction options for type=layering (model uni-1). The image to decompose
rides body.source; body.prompt optionally guides how to split it (max 500
characters). The server plans the layers automatically before generating.

model: Model identifier. `uni-1` is the default image tier; `uni-1-max` produces
higher-quality output than `uni-1` at a higher per-image price. `ray-3.2` is the
public video model for text-to-video, image-to-video, and video-to-video
Expand Down Expand Up @@ -290,6 +301,7 @@ async def create(
"prompt": prompt,
"aspect_ratio": aspect_ratio,
"image_ref": image_ref,
"layering": layering,
"model": model,
"output_format": output_format,
"source": source,
Expand Down
2 changes: 1 addition & 1 deletion src/luma_agents/types/generation.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class Generation(BaseModel):
state: Literal["queued", "processing", "completed", "failed"]
"""Current state of the generation"""

type: Literal["image", "image_edit", "video", "video_edit", "video_reframe"]
type: Literal["image", "image_edit", "video", "video_edit", "video_reframe", "layering"]
"""The kind of generation to perform"""

failure_code: Optional[GenerationFailureCode] = None
Expand Down
26 changes: 24 additions & 2 deletions src/luma_agents/types/generation_create_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from .image_ref_param import ImageRefParam
from .video_options_param import VideoOptionsParam

__all__ = ["GenerationCreateParams"]
__all__ = ["GenerationCreateParams", "Layering"]


class GenerationCreateParams(TypedDict, total=False):
Expand All @@ -31,6 +31,14 @@ class GenerationCreateParams(TypedDict, total=False):
Up to 9 for type 'image', up to 8 for type 'image_edit'.
"""

layering: Optional[Layering]
"""Layer-extraction options for type=layering (model uni-1).

The image to decompose rides body.source; body.prompt optionally guides how to
split it (max 500 characters). The server plans the layers automatically before
generating.
"""

model: Model
"""Model identifier.

Expand All @@ -57,7 +65,7 @@ class GenerationCreateParams(TypedDict, total=False):
style: Literal["auto", "manga"]
"""Style preset (auto, manga)"""

type: Literal["image", "image_edit", "video", "video_edit", "video_reframe"]
type: Literal["image", "image_edit", "video", "video_edit", "video_reframe", "layering"]
"""The kind of generation to perform"""

user_id: Optional[str]
Expand All @@ -82,3 +90,17 @@ class GenerationCreateParams(TypedDict, total=False):
Enable web search grounding — the agent can search the web and download
reference images before generating.
"""


class Layering(TypedDict, total=False):
"""Layer-extraction options for type=layering (model uni-1).

The image to decompose rides body.source; body.prompt optionally guides how to split it (max 500 characters). The server plans the layers automatically before generating.
"""

resolution: Literal["1k", "2k"]
"""Output resolution for every extracted layer.

1k is faster and lower cost; 2k re-renders each layer at higher quality (priced
higher, per layer).
"""
26 changes: 25 additions & 1 deletion src/luma_agents/types/generation_output.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,29 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.

from typing import Optional

from .._models import BaseModel

__all__ = ["GenerationOutput"]
__all__ = ["GenerationOutput", "Layer"]


class Layer(BaseModel):
"""Per-layer semantics for a type=layering output"""

alpha_hint: str
"""
Edge treatment of the layer's transparency — soft (hair/fur/glass), hard (solid
edges), or none (the opaque background)
"""

description: str
"""Complete-element caption for the layer's content"""

index: int
"""Layer position, front-to-back; the last layer is the background"""

label: str
"""Short (1-2 word) layer name"""


class GenerationOutput(BaseModel):
Expand All @@ -13,3 +34,6 @@ class GenerationOutput(BaseModel):

url: str
"""Presigned URL (1hr expiry)"""

layer: Optional[Layer] = None
"""Per-layer semantics for a type=layering output"""
2 changes: 2 additions & 0 deletions tests/api_resources/test_generations.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ def test_method_create_with_all_params(self, client: Luma) -> None:
"url": "url",
}
],
layering={"resolution": "1k"},
model="uni-1",
output_format="png",
source={
Expand Down Expand Up @@ -213,6 +214,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncLuma) -> N
"url": "url",
}
],
layering={"resolution": "1k"},
model="uni-1",
output_format="png",
source={
Expand Down