alpha-avatar-core 0.6.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- alpha_avatar_core-0.6.4/.gitignore +182 -0
- alpha_avatar_core-0.6.4/PKG-INFO +61 -0
- alpha_avatar_core-0.6.4/README.md +38 -0
- alpha_avatar_core-0.6.4/alphaavatar/core/__init__.py +13 -0
- alpha_avatar_core-0.6.4/alphaavatar/core/env/__init__.py +20 -0
- alpha_avatar_core-0.6.4/alphaavatar/core/env/annotation.py +62 -0
- alpha_avatar_core-0.6.4/alphaavatar/core/env/observation.py +205 -0
- alpha_avatar_core-0.6.4/alphaavatar/core/media/__init__.py +26 -0
- alpha_avatar_core-0.6.4/alphaavatar/core/media/formats.py +57 -0
- alpha_avatar_core-0.6.4/alphaavatar/core/media/payload.py +142 -0
- alpha_avatar_core-0.6.4/alphaavatar/core/media/video.py +148 -0
- alpha_avatar_core-0.6.4/alphaavatar/core/perception/__init__.py +38 -0
- alpha_avatar_core-0.6.4/alphaavatar/core/perception/runtime.py +162 -0
- alpha_avatar_core-0.6.4/alphaavatar/core/perception/stream.py +138 -0
- alpha_avatar_core-0.6.4/alphaavatar/core/perception/timeline.py +186 -0
- alpha_avatar_core-0.6.4/alphaavatar/core/perception/window.py +120 -0
- alpha_avatar_core-0.6.4/alphaavatar/core/version.py +14 -0
- alpha_avatar_core-0.6.4/pyproject.toml +55 -0
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
**/.vscode
|
|
2
|
+
**/.DS_Store
|
|
3
|
+
|
|
4
|
+
# Byte-compiled / optimized / DLL files
|
|
5
|
+
__pycache__/
|
|
6
|
+
*.py[cod]
|
|
7
|
+
*$py.class
|
|
8
|
+
|
|
9
|
+
# C extensions
|
|
10
|
+
*.so
|
|
11
|
+
|
|
12
|
+
# Distribution / packaging
|
|
13
|
+
.Python
|
|
14
|
+
build/
|
|
15
|
+
develop-eggs/
|
|
16
|
+
dist/
|
|
17
|
+
downloads/
|
|
18
|
+
eggs/
|
|
19
|
+
.eggs/
|
|
20
|
+
lib/
|
|
21
|
+
lib64/
|
|
22
|
+
parts/
|
|
23
|
+
sdist/
|
|
24
|
+
var/
|
|
25
|
+
wheels/
|
|
26
|
+
share/python-wheels/
|
|
27
|
+
*.egg-info/
|
|
28
|
+
.installed.cfg
|
|
29
|
+
*.egg
|
|
30
|
+
MANIFEST
|
|
31
|
+
KMS
|
|
32
|
+
|
|
33
|
+
# PyInstaller
|
|
34
|
+
# Usually these files are written by a python script from a template
|
|
35
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
36
|
+
*.manifest
|
|
37
|
+
*.spec
|
|
38
|
+
|
|
39
|
+
# Installer logs
|
|
40
|
+
pip-log.txt
|
|
41
|
+
pip-delete-this-directory.txt
|
|
42
|
+
|
|
43
|
+
# Unit test / coverage reports
|
|
44
|
+
htmlcov/
|
|
45
|
+
.tox/
|
|
46
|
+
.nox/
|
|
47
|
+
.coverage
|
|
48
|
+
.coverage.*
|
|
49
|
+
.cache
|
|
50
|
+
nosetests.xml
|
|
51
|
+
coverage.xml
|
|
52
|
+
*.cover
|
|
53
|
+
*.py,cover
|
|
54
|
+
.hypothesis/
|
|
55
|
+
.pytest_cache/
|
|
56
|
+
cover/
|
|
57
|
+
|
|
58
|
+
# Translations
|
|
59
|
+
*.mo
|
|
60
|
+
*.pot
|
|
61
|
+
|
|
62
|
+
# Django stuff:
|
|
63
|
+
*.log
|
|
64
|
+
local_settings.py
|
|
65
|
+
db.sqlite3
|
|
66
|
+
db.sqlite3-journal
|
|
67
|
+
|
|
68
|
+
# Flask stuff:
|
|
69
|
+
instance/
|
|
70
|
+
.webassets-cache
|
|
71
|
+
|
|
72
|
+
# Scrapy stuff:
|
|
73
|
+
.scrapy
|
|
74
|
+
|
|
75
|
+
# Sphinx documentation
|
|
76
|
+
docs/_build/
|
|
77
|
+
|
|
78
|
+
# PyBuilder
|
|
79
|
+
.pybuilder/
|
|
80
|
+
target/
|
|
81
|
+
|
|
82
|
+
# Jupyter Notebook
|
|
83
|
+
.ipynb_checkpoints
|
|
84
|
+
|
|
85
|
+
# IPython
|
|
86
|
+
profile_default/
|
|
87
|
+
ipython_config.py
|
|
88
|
+
|
|
89
|
+
# pyenv
|
|
90
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
91
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
92
|
+
# .python-version
|
|
93
|
+
|
|
94
|
+
# pipenv
|
|
95
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
96
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
97
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
98
|
+
# install all needed dependencies.
|
|
99
|
+
#Pipfile.lock
|
|
100
|
+
|
|
101
|
+
# poetry
|
|
102
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
103
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
104
|
+
# commonly ignored for libraries.
|
|
105
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
106
|
+
#poetry.lock
|
|
107
|
+
|
|
108
|
+
# pdm
|
|
109
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
110
|
+
#pdm.lock
|
|
111
|
+
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
|
112
|
+
# in version control.
|
|
113
|
+
# https://pdm.fming.dev/#use-with-ide
|
|
114
|
+
.pdm.toml
|
|
115
|
+
|
|
116
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
117
|
+
__pypackages__/
|
|
118
|
+
|
|
119
|
+
# Celery stuff
|
|
120
|
+
celerybeat-schedule
|
|
121
|
+
celerybeat.pid
|
|
122
|
+
|
|
123
|
+
# SageMath parsed files
|
|
124
|
+
*.sage.py
|
|
125
|
+
|
|
126
|
+
# Environments
|
|
127
|
+
.env
|
|
128
|
+
.env.dev
|
|
129
|
+
.env.demo
|
|
130
|
+
.env.personal
|
|
131
|
+
.env.prod
|
|
132
|
+
.venv
|
|
133
|
+
venv/
|
|
134
|
+
ENV/
|
|
135
|
+
env.bak/
|
|
136
|
+
venv.bak/
|
|
137
|
+
|
|
138
|
+
# Spyder project settings
|
|
139
|
+
.spyderproject
|
|
140
|
+
.spyproject
|
|
141
|
+
|
|
142
|
+
# Rope project settings
|
|
143
|
+
.ropeproject
|
|
144
|
+
|
|
145
|
+
# mkdocs documentation
|
|
146
|
+
/site
|
|
147
|
+
|
|
148
|
+
# mypy
|
|
149
|
+
.mypy_cache/
|
|
150
|
+
.dmypy.json
|
|
151
|
+
dmypy.json
|
|
152
|
+
|
|
153
|
+
# trunk
|
|
154
|
+
.trunk/
|
|
155
|
+
|
|
156
|
+
# Pyre type checker
|
|
157
|
+
.pyre/
|
|
158
|
+
|
|
159
|
+
# pytype static type analyzer
|
|
160
|
+
.pytype/
|
|
161
|
+
|
|
162
|
+
# Cython debug symbols
|
|
163
|
+
cython_debug/
|
|
164
|
+
|
|
165
|
+
# PyCharm
|
|
166
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
167
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
168
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
169
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
170
|
+
.idea/
|
|
171
|
+
|
|
172
|
+
auth
|
|
173
|
+
node_modules
|
|
174
|
+
|
|
175
|
+
credentials.json
|
|
176
|
+
pyrightconfig.json
|
|
177
|
+
|
|
178
|
+
# Database files
|
|
179
|
+
*.db
|
|
180
|
+
.alphaavatar_workspace
|
|
181
|
+
|
|
182
|
+
docs/releases/.generated/
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: alpha-avatar-core
|
|
3
|
+
Version: 0.6.4
|
|
4
|
+
Summary: Core runtime schemas and transport primitives for AlphaAvatar.
|
|
5
|
+
Project-URL: Source, https://github.com/AlphaAvatar/AlphaAvatar
|
|
6
|
+
License-Expression: Apache-2.0
|
|
7
|
+
Keywords: AI,audio,multimodal,omni,realtime,rtc,runtime,video
|
|
8
|
+
Classifier: Intended Audience :: Developers
|
|
9
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
+
Classifier: Topic :: Multimedia :: Sound/Audio
|
|
14
|
+
Classifier: Topic :: Multimedia :: Video
|
|
15
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
16
|
+
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
|
|
17
|
+
Requires-Python: <3.12,>=3.11
|
|
18
|
+
Provides-Extra: livekit
|
|
19
|
+
Requires-Dist: livekit-api<2,>=1.0.4; extra == 'livekit'
|
|
20
|
+
Requires-Dist: livekit-protocol~=1.0; extra == 'livekit'
|
|
21
|
+
Requires-Dist: livekit<2,>=1.0.12; extra == 'livekit'
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
|
|
24
|
+
# AlphaAvatar Core
|
|
25
|
+
|
|
26
|
+
## 🧩 Introduction
|
|
27
|
+
|
|
28
|
+
`avatar-core` provides the transport-agnostic runtime primitives shared across AlphaAvatar.
|
|
29
|
+
|
|
30
|
+
It defines how multimodal observations are represented, enriched with annotations, published through typed perception streams, aligned on a shared timeline, and selected as consumer-specific windows. The package intentionally remains independent from LiveKit Agents, model providers, and plugin implementations so that RTC adapters, Persona, Memory, Vision, and future multimodal components can evolve without coupling the core runtime to a specific backend.
|
|
31
|
+
|
|
32
|
+
## 📦 Package Structure
|
|
33
|
+
|
|
34
|
+
```text
|
|
35
|
+
avatar-core/
|
|
36
|
+
├── README.md
|
|
37
|
+
├── alphaavatar/
|
|
38
|
+
│ └── core/
|
|
39
|
+
│ ├── __init__.py
|
|
40
|
+
│ ├── env/ # Environment observation envelopes and annotations.
|
|
41
|
+
│ │ ├── __init__.py
|
|
42
|
+
│ │ ├── annotation.py # Structured metadata attached to an observation.
|
|
43
|
+
│ │ └── observation.py # Runtime observation envelope for video, audio, screen, and events.
|
|
44
|
+
│ ├── media/ # Backend-independent multimodal payload representations.
|
|
45
|
+
│ │ ├── __init__.py
|
|
46
|
+
│ │ ├── formats.py # Payload formats and views such as raw, annotated, and derived.
|
|
47
|
+
│ │ ├── payload.py # Thread-safe multi-representation MediaPayload container.
|
|
48
|
+
│ │ └── video.py # Generic video frame buffers and video payload helpers.
|
|
49
|
+
│ ├── perception/ # Full-duplex perception transport, alignment, and windowing.
|
|
50
|
+
│ │ ├── __init__.py
|
|
51
|
+
│ │ ├── runtime.py # PerceptionRuntime entry point and typed stream orchestration.
|
|
52
|
+
│ │ ├── stream.py # Multi-consumer streams with independent cursors and backpressure.
|
|
53
|
+
│ │ ├── timeline.py # Observation–annotation alignment and renderer coordination.
|
|
54
|
+
│ │ └── window.py # Ordered multimodal windows for Memory, Persona, Vision, and routers.
|
|
55
|
+
│ └── version.py # Package version metadata.
|
|
56
|
+
└── pyproject.toml
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## 🔄 Workflow
|
|
60
|
+
|
|
61
|
+
External RTC or device adapters first normalize incoming media into AlphaAvatar-owned payloads. `EnvObservation` wraps each payload with identity, source, timestamp, and metadata before publishing it to `PerceptionRuntime`. Persona and other perception modules can attach annotations and produce annotated payload views without overwriting the raw representation. Consumer-specific windows then provide ordered observations to modules such as ENV Memory, Sampled Frame Vision, routers, and future audio or event processors.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# AlphaAvatar Core
|
|
2
|
+
|
|
3
|
+
## 🧩 Introduction
|
|
4
|
+
|
|
5
|
+
`avatar-core` provides the transport-agnostic runtime primitives shared across AlphaAvatar.
|
|
6
|
+
|
|
7
|
+
It defines how multimodal observations are represented, enriched with annotations, published through typed perception streams, aligned on a shared timeline, and selected as consumer-specific windows. The package intentionally remains independent from LiveKit Agents, model providers, and plugin implementations so that RTC adapters, Persona, Memory, Vision, and future multimodal components can evolve without coupling the core runtime to a specific backend.
|
|
8
|
+
|
|
9
|
+
## 📦 Package Structure
|
|
10
|
+
|
|
11
|
+
```text
|
|
12
|
+
avatar-core/
|
|
13
|
+
├── README.md
|
|
14
|
+
├── alphaavatar/
|
|
15
|
+
│ └── core/
|
|
16
|
+
│ ├── __init__.py
|
|
17
|
+
│ ├── env/ # Environment observation envelopes and annotations.
|
|
18
|
+
│ │ ├── __init__.py
|
|
19
|
+
│ │ ├── annotation.py # Structured metadata attached to an observation.
|
|
20
|
+
│ │ └── observation.py # Runtime observation envelope for video, audio, screen, and events.
|
|
21
|
+
│ ├── media/ # Backend-independent multimodal payload representations.
|
|
22
|
+
│ │ ├── __init__.py
|
|
23
|
+
│ │ ├── formats.py # Payload formats and views such as raw, annotated, and derived.
|
|
24
|
+
│ │ ├── payload.py # Thread-safe multi-representation MediaPayload container.
|
|
25
|
+
│ │ └── video.py # Generic video frame buffers and video payload helpers.
|
|
26
|
+
│ ├── perception/ # Full-duplex perception transport, alignment, and windowing.
|
|
27
|
+
│ │ ├── __init__.py
|
|
28
|
+
│ │ ├── runtime.py # PerceptionRuntime entry point and typed stream orchestration.
|
|
29
|
+
│ │ ├── stream.py # Multi-consumer streams with independent cursors and backpressure.
|
|
30
|
+
│ │ ├── timeline.py # Observation–annotation alignment and renderer coordination.
|
|
31
|
+
│ │ └── window.py # Ordered multimodal windows for Memory, Persona, Vision, and routers.
|
|
32
|
+
│ └── version.py # Package version metadata.
|
|
33
|
+
└── pyproject.toml
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## 🔄 Workflow
|
|
37
|
+
|
|
38
|
+
External RTC or device adapters first normalize incoming media into AlphaAvatar-owned payloads. `EnvObservation` wraps each payload with identity, source, timestamp, and metadata before publishing it to `PerceptionRuntime`. Persona and other perception modules can attach annotations and produce annotated payload views without overwriting the raw representation. Consumer-specific windows then provide ordered observations to modules such as ENV Memory, Sampled Frame Vision, routers, and future audio or event processors.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Copyright 2026 AlphaAvatar project
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Copyright 2026 AlphaAvatar project
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
from .annotation import EnvAnnotation
|
|
15
|
+
from .observation import EnvObservation
|
|
16
|
+
|
|
17
|
+
__all__ = [
|
|
18
|
+
"EnvAnnotation",
|
|
19
|
+
"EnvObservation",
|
|
20
|
+
]
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Copyright 2026 AlphaAvatar project
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
import uuid
|
|
15
|
+
from dataclasses import dataclass, field
|
|
16
|
+
from typing import Any
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@dataclass(slots=True)
|
|
20
|
+
class EnvAnnotation:
|
|
21
|
+
"""
|
|
22
|
+
Lightweight environment annotation attached to an observation or frame.
|
|
23
|
+
|
|
24
|
+
Examples:
|
|
25
|
+
- face boxes from persona.face_stream
|
|
26
|
+
- object boxes from interaction_router
|
|
27
|
+
- gaze/focus regions from avatar vision
|
|
28
|
+
- OCR/screen regions
|
|
29
|
+
- speaker/voice alignment metadata
|
|
30
|
+
|
|
31
|
+
This object must stay LiveKit-independent.
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
source: str
|
|
35
|
+
annotation_type: str
|
|
36
|
+
data: dict[str, Any]
|
|
37
|
+
|
|
38
|
+
# Usually one of these two is enough.
|
|
39
|
+
frame_id: str | None = None
|
|
40
|
+
observation_id: str | None = None
|
|
41
|
+
|
|
42
|
+
timestamp: str | None = None
|
|
43
|
+
annotation_id: str = field(default_factory=lambda: str(uuid.uuid4()))
|
|
44
|
+
|
|
45
|
+
@property
|
|
46
|
+
def target_key(self) -> str | None:
|
|
47
|
+
if self.observation_id:
|
|
48
|
+
return f"observation:{self.observation_id}"
|
|
49
|
+
if self.frame_id:
|
|
50
|
+
return f"frame:{self.frame_id}"
|
|
51
|
+
return None
|
|
52
|
+
|
|
53
|
+
def to_dict(self) -> dict[str, Any]:
|
|
54
|
+
return {
|
|
55
|
+
"annotation_id": self.annotation_id,
|
|
56
|
+
"source": self.source,
|
|
57
|
+
"type": self.annotation_type,
|
|
58
|
+
"timestamp": self.timestamp,
|
|
59
|
+
"frame_id": self.frame_id,
|
|
60
|
+
"observation_id": self.observation_id,
|
|
61
|
+
"data": self.data,
|
|
62
|
+
}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
# Copyright 2026 AlphaAvatar project
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
import uuid
|
|
17
|
+
from dataclasses import dataclass, field
|
|
18
|
+
from typing import Any
|
|
19
|
+
|
|
20
|
+
from alphaavatar.core.media import MediaPayload
|
|
21
|
+
|
|
22
|
+
from .annotation import EnvAnnotation
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@dataclass(slots=True)
|
|
26
|
+
class EnvObservation:
|
|
27
|
+
"""
|
|
28
|
+
Runtime environment observation envelope.
|
|
29
|
+
|
|
30
|
+
payload:
|
|
31
|
+
AlphaAvatar-owned MediaPayload.
|
|
32
|
+
|
|
33
|
+
It must not directly contain:
|
|
34
|
+
- LiveKit rtc.VideoFrame
|
|
35
|
+
- provider-specific content blocks
|
|
36
|
+
- LangChain message objects
|
|
37
|
+
|
|
38
|
+
path:
|
|
39
|
+
Optional persisted evidence path.
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
kind: str
|
|
43
|
+
timestamp: str
|
|
44
|
+
source_id: str
|
|
45
|
+
|
|
46
|
+
observation_id: str = field(default_factory=lambda: str(uuid.uuid4()))
|
|
47
|
+
|
|
48
|
+
path: str | None = None
|
|
49
|
+
mime_type: str | None = None
|
|
50
|
+
|
|
51
|
+
payload: MediaPayload | None = field(
|
|
52
|
+
default=None,
|
|
53
|
+
repr=False,
|
|
54
|
+
compare=False,
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
metadata: dict[str, Any] = field(default_factory=dict)
|
|
58
|
+
annotations: list[EnvAnnotation] = field(default_factory=list)
|
|
59
|
+
|
|
60
|
+
@property
|
|
61
|
+
def frame_id(self) -> str | None:
|
|
62
|
+
metadata_frame_id = self.metadata.get("frame_id")
|
|
63
|
+
if metadata_frame_id:
|
|
64
|
+
return str(metadata_frame_id)
|
|
65
|
+
|
|
66
|
+
payload_frame_id = getattr(self.payload, "frame_id", None)
|
|
67
|
+
if payload_frame_id:
|
|
68
|
+
return str(payload_frame_id)
|
|
69
|
+
|
|
70
|
+
return None
|
|
71
|
+
|
|
72
|
+
@property
|
|
73
|
+
def has_payload(self) -> bool:
|
|
74
|
+
return self.payload is not None and self.payload.has_any
|
|
75
|
+
|
|
76
|
+
@property
|
|
77
|
+
def has_persisted_evidence(self) -> bool:
|
|
78
|
+
return bool(self.path)
|
|
79
|
+
|
|
80
|
+
def add_annotation(self, annotation: EnvAnnotation) -> bool:
|
|
81
|
+
"""
|
|
82
|
+
Add annotation once.
|
|
83
|
+
|
|
84
|
+
Returns True when added and False when it already existed.
|
|
85
|
+
"""
|
|
86
|
+
|
|
87
|
+
for current in self.annotations:
|
|
88
|
+
if current.annotation_id == annotation.annotation_id:
|
|
89
|
+
return False
|
|
90
|
+
|
|
91
|
+
self.annotations.append(annotation)
|
|
92
|
+
return True
|
|
93
|
+
|
|
94
|
+
def clear_payload(self) -> None:
|
|
95
|
+
if self.payload is not None:
|
|
96
|
+
self.payload.clear()
|
|
97
|
+
|
|
98
|
+
self.payload = None
|
|
99
|
+
|
|
100
|
+
def to_evidence_dict(self) -> dict[str, Any]:
|
|
101
|
+
if self.path:
|
|
102
|
+
data: dict[str, Any] = {
|
|
103
|
+
"observation_id": self.observation_id,
|
|
104
|
+
"kind": self.kind,
|
|
105
|
+
"timestamp": self.timestamp,
|
|
106
|
+
"source_id": self.source_id,
|
|
107
|
+
"mime_type": self.mime_type,
|
|
108
|
+
"metadata": self.metadata,
|
|
109
|
+
"annotations": [annotation.to_dict() for annotation in self.annotations],
|
|
110
|
+
"path": self.path,
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return data
|
|
114
|
+
else:
|
|
115
|
+
return {}
|
|
116
|
+
|
|
117
|
+
@classmethod
|
|
118
|
+
def video_frame(
|
|
119
|
+
cls,
|
|
120
|
+
*,
|
|
121
|
+
timestamp: str,
|
|
122
|
+
source_id: str,
|
|
123
|
+
payload: MediaPayload,
|
|
124
|
+
path: str | None = None,
|
|
125
|
+
metadata: dict[str, Any] | None = None,
|
|
126
|
+
annotations: list[EnvAnnotation] | None = None,
|
|
127
|
+
) -> EnvObservation:
|
|
128
|
+
return cls(
|
|
129
|
+
kind="video_frame",
|
|
130
|
+
timestamp=timestamp,
|
|
131
|
+
source_id=source_id,
|
|
132
|
+
path=path,
|
|
133
|
+
mime_type="image/jpeg",
|
|
134
|
+
payload=payload,
|
|
135
|
+
metadata=metadata or {},
|
|
136
|
+
annotations=annotations or [],
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
@classmethod
|
|
140
|
+
def screen_frame(
|
|
141
|
+
cls,
|
|
142
|
+
*,
|
|
143
|
+
timestamp: str,
|
|
144
|
+
source_id: str,
|
|
145
|
+
payload: MediaPayload,
|
|
146
|
+
path: str | None = None,
|
|
147
|
+
metadata: dict[str, Any] | None = None,
|
|
148
|
+
annotations: list[EnvAnnotation] | None = None,
|
|
149
|
+
) -> EnvObservation:
|
|
150
|
+
return cls(
|
|
151
|
+
kind="screen_frame",
|
|
152
|
+
timestamp=timestamp,
|
|
153
|
+
source_id=source_id,
|
|
154
|
+
path=path,
|
|
155
|
+
mime_type="image/jpeg",
|
|
156
|
+
payload=payload,
|
|
157
|
+
metadata=metadata or {},
|
|
158
|
+
annotations=annotations or [],
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
@classmethod
|
|
162
|
+
def video_clip(
|
|
163
|
+
cls,
|
|
164
|
+
*,
|
|
165
|
+
timestamp: str,
|
|
166
|
+
source_id: str,
|
|
167
|
+
payload: MediaPayload | None = None,
|
|
168
|
+
path: str | None = None,
|
|
169
|
+
mime_type: str = "video/mp4",
|
|
170
|
+
metadata: dict[str, Any] | None = None,
|
|
171
|
+
annotations: list[EnvAnnotation] | None = None,
|
|
172
|
+
) -> EnvObservation:
|
|
173
|
+
return cls(
|
|
174
|
+
kind="video_clip",
|
|
175
|
+
timestamp=timestamp,
|
|
176
|
+
source_id=source_id,
|
|
177
|
+
path=path,
|
|
178
|
+
mime_type=mime_type,
|
|
179
|
+
payload=payload,
|
|
180
|
+
metadata=metadata or {},
|
|
181
|
+
annotations=annotations or [],
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
@classmethod
|
|
185
|
+
def audio_segment(
|
|
186
|
+
cls,
|
|
187
|
+
*,
|
|
188
|
+
timestamp: str,
|
|
189
|
+
source_id: str,
|
|
190
|
+
payload: MediaPayload | None = None,
|
|
191
|
+
path: str | None = None,
|
|
192
|
+
mime_type: str = "audio/wav",
|
|
193
|
+
metadata: dict[str, Any] | None = None,
|
|
194
|
+
annotations: list[EnvAnnotation] | None = None,
|
|
195
|
+
) -> EnvObservation:
|
|
196
|
+
return cls(
|
|
197
|
+
kind="audio_segment",
|
|
198
|
+
timestamp=timestamp,
|
|
199
|
+
source_id=source_id,
|
|
200
|
+
path=path,
|
|
201
|
+
mime_type=mime_type,
|
|
202
|
+
payload=payload,
|
|
203
|
+
metadata=metadata or {},
|
|
204
|
+
annotations=annotations or [],
|
|
205
|
+
)
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Copyright 2026 AlphaAvatar project
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
from .formats import PayloadFormat, PayloadView
|
|
15
|
+
from .payload import MediaPayload, PayloadFormatUnavailable
|
|
16
|
+
from .video import PixelFormat, VideoFrame, VideoFramePayload
|
|
17
|
+
|
|
18
|
+
__all__ = [
|
|
19
|
+
"MediaPayload",
|
|
20
|
+
"PayloadFormat",
|
|
21
|
+
"PayloadFormatUnavailable",
|
|
22
|
+
"PayloadView",
|
|
23
|
+
"PixelFormat",
|
|
24
|
+
"VideoFrame",
|
|
25
|
+
"VideoFramePayload",
|
|
26
|
+
]
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Copyright 2026 AlphaAvatar project
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
from enum import StrEnum
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class PayloadView(StrEnum):
|
|
20
|
+
"""
|
|
21
|
+
Logical representation view.
|
|
22
|
+
|
|
23
|
+
RAW:
|
|
24
|
+
Original input representation produced by an input adapter.
|
|
25
|
+
|
|
26
|
+
ANNOTATED:
|
|
27
|
+
Representation containing perception annotations, such as face boxes.
|
|
28
|
+
|
|
29
|
+
DERIVED:
|
|
30
|
+
Other derived representations, such as thumbnails or provider-ready blocks.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
RAW = "raw"
|
|
34
|
+
ANNOTATED = "annotated"
|
|
35
|
+
DERIVED = "derived"
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class PayloadFormat(StrEnum):
|
|
39
|
+
"""
|
|
40
|
+
AlphaAvatar-owned payload formats.
|
|
41
|
+
|
|
42
|
+
Do not add provider-specific or RTC-specific classes here.
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
# Generic video frame owned by AlphaAvatar.
|
|
46
|
+
VIDEO_FRAME = "video.frame"
|
|
47
|
+
|
|
48
|
+
# Encoded visual representations.
|
|
49
|
+
IMAGE_JPEG_BYTES = "image/jpeg.bytes"
|
|
50
|
+
IMAGE_PNG_BYTES = "image/png.bytes"
|
|
51
|
+
|
|
52
|
+
# Reserved for later audio implementation.
|
|
53
|
+
AUDIO_PCM16_BYTES = "audio/pcm16.bytes"
|
|
54
|
+
AUDIO_WAV_BYTES = "audio/wav.bytes"
|
|
55
|
+
|
|
56
|
+
# Reserved for provider adapters.
|
|
57
|
+
PROVIDER_CONTENT_BLOCK = "provider.content_block"
|