Skip to content

feat(shadcn): add useExpression hook - #1415

Open
theomonnom wants to merge 11 commits into
mainfrom
theo/agent-expression-aura
Open

feat(shadcn): add useExpression hook#1415
theomonnom wants to merge 11 commits into
mainfrom
theo/agent-expression-aura

Conversation

@theomonnom

Copy link
Copy Markdown
Member

No description provided.

@vercel

vercel Bot commented Aug 4, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
components-js-storybook-5kld Ready Ready Preview Aug 6, 2026 1:43pm

Request Review

@changeset-bot

changeset-bot Bot commented Aug 4, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 48f0551

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 6 packages
Name Type
@livekit/components-react Patch
@livekit/agents-ui Patch
@livekit/component-example-next Patch
@livekit/components-js-docs Patch
@livekit/component-docs-storybook Patch
@livekit/components-docs-gen Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@CLAassistant

CLAassistant commented Aug 4, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@thomasyuill-livekit thomasyuill-livekit left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great @theomonnom

We should include a storybook example for testing and evaluate the behaviour with an agent that has expression enabled

And we should add tests for the hooks

I'm happy to contribute these to the PR if that's helpful

@theomonnom
theomonnom force-pushed the theo/agent-expression-aura branch from a18ce27 to 8a2ac0e Compare August 4, 2026 21:42
@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

Path Size
LiveKitRoom only 7.89 KB (0%)
LiveKitRoom with VideoConference 32.48 KB (0%)
All exports 44.47 KB (+0.68% 🔺)

@theomonnom
theomonnom force-pushed the theo/agent-expression-aura branch from 8a2ac0e to 85a4e75 Compare August 4, 2026 21:47
@theomonnom
theomonnom force-pushed the theo/agent-expression-aura branch from c0fecc8 to 654645a Compare August 4, 2026 22:18
@theomonnom
theomonnom force-pushed the theo/agent-expression-aura branch from 654645a to 6471c3c Compare August 4, 2026 22:30
@theomonnom
theomonnom force-pushed the theo/agent-expression-aura branch from 6471c3c to 026db07 Compare August 4, 2026 22:37
@theomonnom
theomonnom force-pushed the theo/agent-expression-aura branch from 026db07 to 94c3baf Compare August 4, 2026 22:45
@theomonnom theomonnom changed the title feat(shadcn): add AgentExpressionAura feat(shadcn): add useExpression hook Aug 4, 2026
@theomonnom
theomonnom force-pushed the theo/agent-expression-aura branch from 94c3baf to 0e2d557 Compare August 4, 2026 22:50
@theomonnom
theomonnom force-pushed the theo/agent-expression-aura branch from 0e2d557 to b93668c Compare August 4, 2026 22:53
@theomonnom
theomonnom force-pushed the theo/agent-expression-aura branch from b93668c to 061a12f Compare August 4, 2026 22:59
Comment thread packages/shadcn/hooks/agents-ui/use-expression.ts Outdated

@thomasyuill-livekit thomasyuill-livekit left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe we should add the useExpression hook to JS SDK and not Shadcn so it can be used by any React project.

our Shadcn Agents-UI library should be primarily concerned with presentation
since all the visualizers all ready support a color prop, I don't believe that Agents UI needs to be extended to support expressions.

We should not be including opionated "glue" code into our presentational components because that will make them brittle and less extensible. We should instead provide examples of how to glue these pieces together in our docs and starter templates

@thomasyuill-livekit thomasyuill-livekit left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally LGTM

just a few questions and suggestions

Also, looks like there's a linting error tripping up the tests

Would love @1egoman to give it a look too

Comment thread packages/react/src/hooks/useExpression.ts Outdated
Comment thread packages/react/src/hooks/useExpression.ts Outdated
Comment on lines +137 to +147
for (const segment of segments) {
const parsed = parseExpression(segment);
if (parsed) {
current = parsed;
speaker = segment.participantInfo.identity;
turnsSince = 0;
} else if (current && segment.participantInfo.identity === speaker) {
// only the expressing participant's own later turns age the mood
turnsSince++;
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

again couldn't we do this in reverse order?

Suggested change
for (const segment of segments) {
const parsed = parseExpression(segment);
if (parsed) {
current = parsed;
speaker = segment.participantInfo.identity;
turnsSince = 0;
} else if (current && segment.participantInfo.identity === speaker) {
// only the expressing participant's own later turns age the mood
turnsSince++;
}
}
turnsSince = 0;
for (const segment of segments.reverse()) {
turnsSince++;
const parsed = parseExpression(segment);
if (parsed) {
current = parsed;
speaker = segment.participantInfo.identity;
continue;
}
}

Comment thread packages/react/src/hooks/useSessionMessages.ts
let ticks = 0;
const id = setInterval(() => {
setSettled((previous) => {
const latest = segments.reduce<string | null>(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wouldn't it be faster to go backwards and find the first match?

@1egoman 1egoman left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally makes sense to me, just noticed a few nitpicks.

A higher level question - is useExpression a good name given how general "expression" is as a term (ie, somebody could think this relates to a mathematical expression, etc) ? Maybe useAgentExpression could be better?

Comment on lines +5 to +6
/** Published per transcript segment by Expressive Mode: the segment's leading delivery tag. */
export const EXPRESSION_ATTRIBUTE = 'lk.expression';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: Put this in here instead:

export enum ParticipantAgentAttributes {

All the agent attributes constants are centralized in that enum.


try {
const parsed = JSON.parse(raw) as { expression?: string; mood?: AgentMood };
const expression = parsed.expression?.trim() || null;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: You likely want ?? here instead of ||:

Suggested change
const expression = parsed.expression?.trim() || null;
const expression = parsed.expression?.trim() ?? null;

@1egoman 1egoman left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, meant to approve

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants