feat: add director notes support (initial config + runtime cues) - #63
feat: add director notes support (initial config + runtime cues)#63sebvanleuven wants to merge 1 commit into
Conversation
Add DirectorNotes to PersonaConfig for session-start delivery-style defaults, and Session.send_director_note_cue() to send turn-scoped director-note cues over the data channel. at_seconds/in_seconds are validated as finite client-side (non-finite values would serialize to invalid JSON and break the engine parser); all other cue semantics are validated by the backend. Includes unit tests and README documentation. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
3 issues found across 6 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/anam/client.py">
<violation number="1" location="src/anam/client.py:596">
P2: Static type checking will fail on this new helper because `_ensure_data_channel_open` has no return annotation while mypy disallows untyped defs. Adding `-> StreamingClient` matches the returned object and keeps the file consistent with the project config.</violation>
</file>
<file name="src/anam/types.py">
<violation number="1" location="src/anam/types.py:74">
P2: Session startup can still send invalid JSON when `DirectorNotes(expressivity=nan/inf)` is used, because this float is serialized without the same finiteness guard added for runtime director-note cues. Consider validating `expressivity` with `math.isfinite` before adding it to `directorNotes`.</violation>
</file>
<file name="README.md">
<violation number="1" location="README.md:342">
P3: The markdown heading for `Runtime Director Note Cues` uses `#####` (h5), but since it's a peer section to `#### Initial Director Notes`, it should use `####` (h4). Using `#####` makes it appear as a sub-subsection of `Initial` rather than a sibling section under `### Director Notes`.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Fix all with cubic | Re-trigger cubic
| if not streaming.send_data_message(json.dumps(payload)): | ||
| raise SessionError("Failed to send director note cue over data channel") | ||
|
|
||
| async def _ensure_data_channel_open(self): |
There was a problem hiding this comment.
P2: Static type checking will fail on this new helper because _ensure_data_channel_open has no return annotation while mypy disallows untyped defs. Adding -> StreamingClient matches the returned object and keeps the file consistent with the project config.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/anam/client.py, line 596:
<comment>Static type checking will fail on this new helper because `_ensure_data_channel_open` has no return annotation while mypy disallows untyped defs. Adding `-> StreamingClient` matches the returned object and keeps the file consistent with the project config.</comment>
<file context>
@@ -560,17 +553,57 @@ async def interrupt(self) -> None:
+ if not streaming.send_data_message(json.dumps(payload)):
+ raise SessionError("Failed to send director note cue over data channel")
+
+ async def _ensure_data_channel_open(self):
+ """Return the streaming client once the data channel is ready."""
if not self._client._streaming_client:
</file context>
| async def _ensure_data_channel_open(self): | |
| async def _ensure_data_channel_open(self) -> StreamingClient: |
| if self.overlay_model_name_on_output is not None: | ||
| result["overlayModelNameOnOutput"] = self.overlay_model_name_on_output | ||
| if self.expressivity is not None: | ||
| result["expressivity"] = self.expressivity |
There was a problem hiding this comment.
P2: Session startup can still send invalid JSON when DirectorNotes(expressivity=nan/inf) is used, because this float is serialized without the same finiteness guard added for runtime director-note cues. Consider validating expressivity with math.isfinite before adding it to directorNotes.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/anam/types.py, line 74:
<comment>Session startup can still send invalid JSON when `DirectorNotes(expressivity=nan/inf)` is used, because this float is serialized without the same finiteness guard added for runtime director-note cues. Consider validating `expressivity` with `math.isfinite` before adding it to `directorNotes`.</comment>
<file context>
@@ -47,6 +47,34 @@ class MessageRole(str, Enum):
+ if self.overlay_model_name_on_output is not None:
+ result["overlayModelNameOnOutput"] = self.overlay_model_name_on_output
+ if self.expressivity is not None:
+ result["expressivity"] = self.expressivity
+ return result
+
</file context>
| ``` | ||
| The initial director notes are the avatar's default presence for the session. | ||
|
|
||
| ##### Runtime Director Note Cues |
There was a problem hiding this comment.
P3: The markdown heading for Runtime Director Note Cues uses ##### (h5), but since it's a peer section to #### Initial Director Notes, it should use #### (h4). Using ##### makes it appear as a sub-subsection of Initial rather than a sibling section under ### Director Notes.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At README.md, line 342:
<comment>The markdown heading for `Runtime Director Note Cues` uses `#####` (h5), but since it's a peer section to `#### Initial Director Notes`, it should use `####` (h4). Using `#####` makes it appear as a sub-subsection of `Initial` rather than a sibling section under `### Director Notes`.</comment>
<file context>
@@ -310,6 +317,43 @@ async with client.connect() as session:
+```
+The initial director notes are the avatar's default presence for the session.
+
+##### Runtime Director Note Cues
+
+Use `session.send_director_note_cue(...)` to adjust delivery style during the active turn.
</file context>
| ##### Runtime Director Note Cues | |
| #### Runtime Director Note Cues |
Withdrawn.