Skip to content
Open
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
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,18 @@ async with client.connect(session_options=session_options) as session:

Currently, only `"high"` or `"auto"` are supported `video_quality` values.

### AI avatar disclosure

Anam applies the AI avatar disclosure automatically when required. When
enabled, it remains visible throughout the session. To request it explicitly:

```python
session_options = SessionOptions(show_ai_avatar_disclosure=True)
```

Eligible plans can set `show_ai_avatar_disclosure=False` when the application
provides its own disclosure. Leave it unset to use Anam's default.

## Direct Egress (Daily)

> [!WARNING]
Expand Down
5 changes: 5 additions & 0 deletions src/anam/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,13 +208,16 @@ class SessionOptions:
video_width: Requested video output width. Must be provided with video_height.
video_height: Requested video output height. Must be provided with video_width.
egress: Optional direct egress to a third-party transport (e.g. Daily). See :class:`EgressOptions`.
show_ai_avatar_disclosure: Show the AI avatar disclosure throughout the session.
Omit to use Anam's default. Explicit False requires an eligible plan.
"""

enable_session_replay: bool = True
video_quality: Literal["high", "auto"] = "high"
video_width: int | None = None
video_height: int | None = None
egress: EgressOptions | None = None
show_ai_avatar_disclosure: bool | None = None
Comment thread
cubic-dev-ai[bot] marked this conversation as resolved.

def __post_init__(self) -> None:
self._session_replay = SessionReplayOptions(
Expand Down Expand Up @@ -243,6 +246,8 @@ def to_dict(self) -> dict[str, Any]:
result["videoHeight"] = self.video_height
if self.egress is not None:
result["egress"] = self.egress.to_dict()
if self.show_ai_avatar_disclosure is not None:
result["showAiAvatarDisclosure"] = self.show_ai_avatar_disclosure
return result


Expand Down
29 changes: 29 additions & 0 deletions tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
AnamEvent,
ClientOptions,
DirectorNotes,
EgressDailyOptions,
EgressOptions,
MessageRole,
MessageStreamEvent,
PersonaConfig,
Expand Down Expand Up @@ -283,6 +285,33 @@ def test_to_dict_with_video_dimensions(self) -> None:
"videoHeight": 768,
}

@pytest.mark.parametrize("value", [True, False])
def test_to_dict_with_ai_avatar_disclosure(self, value: bool) -> None:
options = SessionOptions(show_ai_avatar_disclosure=value)

assert options.to_dict()["showAiAvatarDisclosure"] is value

def test_to_dict_omits_ai_avatar_disclosure_by_default(self) -> None:
assert "showAiAvatarDisclosure" not in SessionOptions().to_dict()

def test_ai_avatar_disclosure_preserves_positional_egress_argument(self) -> None:
egress = EgressOptions(
mode="daily",
daily=EgressDailyOptions(room_url="https://example.daily.co/room"),
)
options = SessionOptions(True, "high", None, None, egress, True)

assert options.egress is egress
assert options.show_ai_avatar_disclosure is True
result = options.to_dict()
assert result["egress"]["mode"] == "daily"
assert list(result) == [
"sessionReplay",
"videoQuality",
"egress",
"showAiAvatarDisclosure",
]

def test_invalid_video_quality_raises_value_error(self) -> None:
with pytest.raises(ValueError, match='video_quality must be either "high" or "auto"'):
SessionOptions(video_quality="medium") # type: ignore[arg-type]
Expand Down
Loading