@livekit/agents-plugin-anam 1.4.2 → 1.4.4
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.
- package/dist/avatar.cjs +8 -2
- package/dist/avatar.cjs.map +1 -1
- package/dist/avatar.d.cts +2 -0
- package/dist/avatar.d.ts +2 -0
- package/dist/avatar.d.ts.map +1 -1
- package/dist/avatar.js +8 -2
- package/dist/avatar.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/package.json +5 -5
- package/src/avatar.ts +10 -2
package/dist/avatar.cjs
CHANGED
|
@@ -52,6 +52,12 @@ class AvatarSession extends import_agents.voice.AvatarSession {
|
|
|
52
52
|
this.opts = opts;
|
|
53
53
|
}
|
|
54
54
|
sessionId;
|
|
55
|
+
get avatarIdentity() {
|
|
56
|
+
return this.opts.avatarParticipantIdentity ?? AVATAR_IDENTITY;
|
|
57
|
+
}
|
|
58
|
+
get provider() {
|
|
59
|
+
return "anam";
|
|
60
|
+
}
|
|
55
61
|
async start(agentSession, room, params) {
|
|
56
62
|
var _a, _b, _c, _d;
|
|
57
63
|
await super.start(agentSession, room);
|
|
@@ -79,7 +85,7 @@ class AvatarSession extends import_agents.voice.AvatarSession {
|
|
|
79
85
|
);
|
|
80
86
|
const jwt = await mintAvatarJoinToken({
|
|
81
87
|
roomName: room.name,
|
|
82
|
-
avatarIdentity: this.
|
|
88
|
+
avatarIdentity: this.avatarIdentity,
|
|
83
89
|
publishOnBehalf: localIdentity,
|
|
84
90
|
apiKey: lkKey,
|
|
85
91
|
apiSecret: lkSecret
|
|
@@ -99,7 +105,7 @@ class AvatarSession extends import_agents.voice.AvatarSession {
|
|
|
99
105
|
this.sessionId = started.sessionId;
|
|
100
106
|
agentSession.output.audio = new import_agents.voice.DataStreamAudioOutput({
|
|
101
107
|
room,
|
|
102
|
-
destinationIdentity: this.
|
|
108
|
+
destinationIdentity: this.avatarIdentity,
|
|
103
109
|
waitRemoteTrack: import_rtc_node.TrackKind.KIND_VIDEO
|
|
104
110
|
});
|
|
105
111
|
}
|
package/dist/avatar.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/avatar.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { log, voice } from '@livekit/agents';\nimport type { Room } from '@livekit/rtc-node';\nimport { TrackKind } from '@livekit/rtc-node';\nimport { AccessToken, type VideoGrant } from 'livekit-server-sdk';\nimport { AnamAPI } from './api.js';\nimport { type APIConnectOptions, AnamException, type PersonaConfig } from './types.js';\n\nexport async function mintAvatarJoinToken({\n roomName,\n avatarIdentity,\n publishOnBehalf,\n apiKey = process.env.LIVEKIT_API_KEY!,\n apiSecret = process.env.LIVEKIT_API_SECRET!,\n ttl = '60s',\n}: {\n roomName: string;\n avatarIdentity: string;\n publishOnBehalf: string;\n apiKey?: string;\n apiSecret?: string;\n ttl?: string | number;\n}): Promise<string> {\n const at = new AccessToken(apiKey, apiSecret);\n at.identity = avatarIdentity;\n at.name = 'Anam Avatar';\n at.kind = 'agent';\n at.ttl = ttl;\n at.attributes = { 'lk.publish_on_behalf': publishOnBehalf };\n\n at.addGrant({ roomJoin: true, room: roomName } as VideoGrant);\n return at.toJwt();\n}\n\nconst AVATAR_IDENTITY = 'anam-avatar-agent';\nconst _AVATAR_NAME = 'anam-avatar-agent';\n\nexport class AvatarSession extends voice.AvatarSession {\n private sessionId?: string;\n\n constructor(\n private opts: {\n personaConfig: PersonaConfig;\n apiUrl?: string;\n apiKey?: string;\n avatarParticipantIdentity?: string;\n avatarParticipantName?: string;\n connOptions?: APIConnectOptions;\n },\n ) {\n super();\n }\n\n async start(\n agentSession: voice.AgentSession,\n room: Room,\n params?: {\n livekitUrl?: string;\n livekitApiKey?: string;\n livekitApiSecret?: string;\n },\n ) {\n await super.start(agentSession, room);\n\n const logger = log().child({ module: 'AnamAvatar' });\n const apiKey = this.opts.apiKey ?? process.env.ANAM_API_KEY;\n if (!apiKey) throw new AnamException('ANAM_API_KEY is required');\n\n const apiUrl = this.opts.apiUrl ?? process.env.ANAM_API_URL;\n const livekitUrl = params?.livekitUrl ?? process.env.LIVEKIT_URL;\n const lkKey = params?.livekitApiKey ?? process.env.LIVEKIT_API_KEY;\n const lkSecret = params?.livekitApiSecret ?? process.env.LIVEKIT_API_SECRET;\n\n if (!livekitUrl || !lkKey || !lkSecret) {\n throw new AnamException('LIVEKIT_URL/API_KEY/API_SECRET must be set');\n }\n\n const localIdentity = (room.localParticipant && room.localParticipant.identity) || 'agent';\n\n logger.debug(\n {\n personaName: this.opts.personaConfig?.name,\n avatarId: this.opts.personaConfig?.avatarId,\n apiUrl: apiUrl ?? '(default https://api.anam.ai)',\n livekitUrl,\n avatarParticipantIdentity: this.opts.avatarParticipantIdentity ?? 'anam-avatar-agent',\n publishOnBehalf: localIdentity,\n },\n 'starting Anam avatar session',\n );\n\n const jwt = await mintAvatarJoinToken({\n roomName: room.name!,\n avatarIdentity: this.
|
|
1
|
+
{"version":3,"sources":["../src/avatar.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { log, voice } from '@livekit/agents';\nimport type { Room } from '@livekit/rtc-node';\nimport { TrackKind } from '@livekit/rtc-node';\nimport { AccessToken, type VideoGrant } from 'livekit-server-sdk';\nimport { AnamAPI } from './api.js';\nimport { type APIConnectOptions, AnamException, type PersonaConfig } from './types.js';\n\nexport async function mintAvatarJoinToken({\n roomName,\n avatarIdentity,\n publishOnBehalf,\n apiKey = process.env.LIVEKIT_API_KEY!,\n apiSecret = process.env.LIVEKIT_API_SECRET!,\n ttl = '60s',\n}: {\n roomName: string;\n avatarIdentity: string;\n publishOnBehalf: string;\n apiKey?: string;\n apiSecret?: string;\n ttl?: string | number;\n}): Promise<string> {\n const at = new AccessToken(apiKey, apiSecret);\n at.identity = avatarIdentity;\n at.name = 'Anam Avatar';\n at.kind = 'agent';\n at.ttl = ttl;\n at.attributes = { 'lk.publish_on_behalf': publishOnBehalf };\n\n at.addGrant({ roomJoin: true, room: roomName } as VideoGrant);\n return at.toJwt();\n}\n\nconst AVATAR_IDENTITY = 'anam-avatar-agent';\nconst _AVATAR_NAME = 'anam-avatar-agent';\n\nexport class AvatarSession extends voice.AvatarSession {\n private sessionId?: string;\n\n constructor(\n private opts: {\n personaConfig: PersonaConfig;\n apiUrl?: string;\n apiKey?: string;\n avatarParticipantIdentity?: string;\n avatarParticipantName?: string;\n connOptions?: APIConnectOptions;\n },\n ) {\n super();\n }\n\n override get avatarIdentity(): string {\n return this.opts.avatarParticipantIdentity ?? AVATAR_IDENTITY;\n }\n\n override get provider(): string {\n return 'anam';\n }\n\n async start(\n agentSession: voice.AgentSession,\n room: Room,\n params?: {\n livekitUrl?: string;\n livekitApiKey?: string;\n livekitApiSecret?: string;\n },\n ) {\n await super.start(agentSession, room);\n\n const logger = log().child({ module: 'AnamAvatar' });\n const apiKey = this.opts.apiKey ?? process.env.ANAM_API_KEY;\n if (!apiKey) throw new AnamException('ANAM_API_KEY is required');\n\n const apiUrl = this.opts.apiUrl ?? process.env.ANAM_API_URL;\n const livekitUrl = params?.livekitUrl ?? process.env.LIVEKIT_URL;\n const lkKey = params?.livekitApiKey ?? process.env.LIVEKIT_API_KEY;\n const lkSecret = params?.livekitApiSecret ?? process.env.LIVEKIT_API_SECRET;\n\n if (!livekitUrl || !lkKey || !lkSecret) {\n throw new AnamException('LIVEKIT_URL/API_KEY/API_SECRET must be set');\n }\n\n const localIdentity = (room.localParticipant && room.localParticipant.identity) || 'agent';\n\n logger.debug(\n {\n personaName: this.opts.personaConfig?.name,\n avatarId: this.opts.personaConfig?.avatarId,\n apiUrl: apiUrl ?? '(default https://api.anam.ai)',\n livekitUrl,\n avatarParticipantIdentity: this.opts.avatarParticipantIdentity ?? 'anam-avatar-agent',\n publishOnBehalf: localIdentity,\n },\n 'starting Anam avatar session',\n );\n\n const jwt = await mintAvatarJoinToken({\n roomName: room.name!,\n avatarIdentity: this.avatarIdentity,\n publishOnBehalf: localIdentity,\n apiKey: lkKey,\n apiSecret: lkSecret,\n });\n\n const anam = new AnamAPI(apiKey, apiUrl, this.opts.connOptions);\n logger.debug({ livekitUrl }, 'requesting Anam session token');\n\n const { sessionToken } = await anam.createSessionToken({\n personaConfig: {\n name: this.opts.personaConfig?.name,\n avatarId: this.opts.personaConfig?.avatarId,\n },\n livekitUrl,\n livekitToken: jwt,\n });\n logger.debug('starting Anam engine session');\n const started = await anam.startEngineSession({ sessionToken });\n this.sessionId = started.sessionId;\n\n agentSession.output.audio = new voice.DataStreamAudioOutput({\n room,\n destinationIdentity: this.avatarIdentity,\n waitRemoteTrack: TrackKind.KIND_VIDEO,\n });\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/avatar.d.cts
CHANGED
|
@@ -20,6 +20,8 @@ export declare class AvatarSession extends voice.AvatarSession {
|
|
|
20
20
|
avatarParticipantName?: string;
|
|
21
21
|
connOptions?: APIConnectOptions;
|
|
22
22
|
});
|
|
23
|
+
get avatarIdentity(): string;
|
|
24
|
+
get provider(): string;
|
|
23
25
|
start(agentSession: voice.AgentSession, room: Room, params?: {
|
|
24
26
|
livekitUrl?: string;
|
|
25
27
|
livekitApiKey?: string;
|
package/dist/avatar.d.ts
CHANGED
|
@@ -20,6 +20,8 @@ export declare class AvatarSession extends voice.AvatarSession {
|
|
|
20
20
|
avatarParticipantName?: string;
|
|
21
21
|
connOptions?: APIConnectOptions;
|
|
22
22
|
});
|
|
23
|
+
get avatarIdentity(): string;
|
|
24
|
+
get provider(): string;
|
|
23
25
|
start(agentSession: voice.AgentSession, room: Room, params?: {
|
|
24
26
|
livekitUrl?: string;
|
|
25
27
|
livekitApiKey?: string;
|
package/dist/avatar.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"avatar.d.ts","sourceRoot":"","sources":["../src/avatar.ts"],"names":[],"mappings":"AAGA,OAAO,EAAO,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAI9C,OAAO,EAAE,KAAK,iBAAiB,EAAiB,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AAEvF,wBAAsB,mBAAmB,CAAC,EACxC,QAAQ,EACR,cAAc,EACd,eAAe,EACf,MAAqC,EACrC,SAA2C,EAC3C,GAAW,GACZ,EAAE;IACD,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACvB,GAAG,OAAO,CAAC,MAAM,CAAC,CAUlB;AAKD,qBAAa,aAAc,SAAQ,KAAK,CAAC,aAAa;IAIlD,OAAO,CAAC,IAAI;IAHd,OAAO,CAAC,SAAS,CAAC,CAAS;gBAGjB,IAAI,EAAE;QACZ,aAAa,EAAE,aAAa,CAAC;QAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,yBAAyB,CAAC,EAAE,MAAM,CAAC;QACnC,qBAAqB,CAAC,EAAE,MAAM,CAAC;QAC/B,WAAW,CAAC,EAAE,iBAAiB,CAAC;KACjC;
|
|
1
|
+
{"version":3,"file":"avatar.d.ts","sourceRoot":"","sources":["../src/avatar.ts"],"names":[],"mappings":"AAGA,OAAO,EAAO,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAI9C,OAAO,EAAE,KAAK,iBAAiB,EAAiB,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AAEvF,wBAAsB,mBAAmB,CAAC,EACxC,QAAQ,EACR,cAAc,EACd,eAAe,EACf,MAAqC,EACrC,SAA2C,EAC3C,GAAW,GACZ,EAAE;IACD,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACvB,GAAG,OAAO,CAAC,MAAM,CAAC,CAUlB;AAKD,qBAAa,aAAc,SAAQ,KAAK,CAAC,aAAa;IAIlD,OAAO,CAAC,IAAI;IAHd,OAAO,CAAC,SAAS,CAAC,CAAS;gBAGjB,IAAI,EAAE;QACZ,aAAa,EAAE,aAAa,CAAC;QAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,yBAAyB,CAAC,EAAE,MAAM,CAAC;QACnC,qBAAqB,CAAC,EAAE,MAAM,CAAC;QAC/B,WAAW,CAAC,EAAE,iBAAiB,CAAC;KACjC;IAKH,IAAa,cAAc,IAAI,MAAM,CAEpC;IAED,IAAa,QAAQ,IAAI,MAAM,CAE9B;IAEK,KAAK,CACT,YAAY,EAAE,KAAK,CAAC,YAAY,EAChC,IAAI,EAAE,IAAI,EACV,MAAM,CAAC,EAAE;QACP,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;KAC3B;CA4DJ"}
|
package/dist/avatar.js
CHANGED
|
@@ -28,6 +28,12 @@ class AvatarSession extends voice.AvatarSession {
|
|
|
28
28
|
this.opts = opts;
|
|
29
29
|
}
|
|
30
30
|
sessionId;
|
|
31
|
+
get avatarIdentity() {
|
|
32
|
+
return this.opts.avatarParticipantIdentity ?? AVATAR_IDENTITY;
|
|
33
|
+
}
|
|
34
|
+
get provider() {
|
|
35
|
+
return "anam";
|
|
36
|
+
}
|
|
31
37
|
async start(agentSession, room, params) {
|
|
32
38
|
var _a, _b, _c, _d;
|
|
33
39
|
await super.start(agentSession, room);
|
|
@@ -55,7 +61,7 @@ class AvatarSession extends voice.AvatarSession {
|
|
|
55
61
|
);
|
|
56
62
|
const jwt = await mintAvatarJoinToken({
|
|
57
63
|
roomName: room.name,
|
|
58
|
-
avatarIdentity: this.
|
|
64
|
+
avatarIdentity: this.avatarIdentity,
|
|
59
65
|
publishOnBehalf: localIdentity,
|
|
60
66
|
apiKey: lkKey,
|
|
61
67
|
apiSecret: lkSecret
|
|
@@ -75,7 +81,7 @@ class AvatarSession extends voice.AvatarSession {
|
|
|
75
81
|
this.sessionId = started.sessionId;
|
|
76
82
|
agentSession.output.audio = new voice.DataStreamAudioOutput({
|
|
77
83
|
room,
|
|
78
|
-
destinationIdentity: this.
|
|
84
|
+
destinationIdentity: this.avatarIdentity,
|
|
79
85
|
waitRemoteTrack: TrackKind.KIND_VIDEO
|
|
80
86
|
});
|
|
81
87
|
}
|
package/dist/avatar.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/avatar.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { log, voice } from '@livekit/agents';\nimport type { Room } from '@livekit/rtc-node';\nimport { TrackKind } from '@livekit/rtc-node';\nimport { AccessToken, type VideoGrant } from 'livekit-server-sdk';\nimport { AnamAPI } from './api.js';\nimport { type APIConnectOptions, AnamException, type PersonaConfig } from './types.js';\n\nexport async function mintAvatarJoinToken({\n roomName,\n avatarIdentity,\n publishOnBehalf,\n apiKey = process.env.LIVEKIT_API_KEY!,\n apiSecret = process.env.LIVEKIT_API_SECRET!,\n ttl = '60s',\n}: {\n roomName: string;\n avatarIdentity: string;\n publishOnBehalf: string;\n apiKey?: string;\n apiSecret?: string;\n ttl?: string | number;\n}): Promise<string> {\n const at = new AccessToken(apiKey, apiSecret);\n at.identity = avatarIdentity;\n at.name = 'Anam Avatar';\n at.kind = 'agent';\n at.ttl = ttl;\n at.attributes = { 'lk.publish_on_behalf': publishOnBehalf };\n\n at.addGrant({ roomJoin: true, room: roomName } as VideoGrant);\n return at.toJwt();\n}\n\nconst AVATAR_IDENTITY = 'anam-avatar-agent';\nconst _AVATAR_NAME = 'anam-avatar-agent';\n\nexport class AvatarSession extends voice.AvatarSession {\n private sessionId?: string;\n\n constructor(\n private opts: {\n personaConfig: PersonaConfig;\n apiUrl?: string;\n apiKey?: string;\n avatarParticipantIdentity?: string;\n avatarParticipantName?: string;\n connOptions?: APIConnectOptions;\n },\n ) {\n super();\n }\n\n async start(\n agentSession: voice.AgentSession,\n room: Room,\n params?: {\n livekitUrl?: string;\n livekitApiKey?: string;\n livekitApiSecret?: string;\n },\n ) {\n await super.start(agentSession, room);\n\n const logger = log().child({ module: 'AnamAvatar' });\n const apiKey = this.opts.apiKey ?? process.env.ANAM_API_KEY;\n if (!apiKey) throw new AnamException('ANAM_API_KEY is required');\n\n const apiUrl = this.opts.apiUrl ?? process.env.ANAM_API_URL;\n const livekitUrl = params?.livekitUrl ?? process.env.LIVEKIT_URL;\n const lkKey = params?.livekitApiKey ?? process.env.LIVEKIT_API_KEY;\n const lkSecret = params?.livekitApiSecret ?? process.env.LIVEKIT_API_SECRET;\n\n if (!livekitUrl || !lkKey || !lkSecret) {\n throw new AnamException('LIVEKIT_URL/API_KEY/API_SECRET must be set');\n }\n\n const localIdentity = (room.localParticipant && room.localParticipant.identity) || 'agent';\n\n logger.debug(\n {\n personaName: this.opts.personaConfig?.name,\n avatarId: this.opts.personaConfig?.avatarId,\n apiUrl: apiUrl ?? '(default https://api.anam.ai)',\n livekitUrl,\n avatarParticipantIdentity: this.opts.avatarParticipantIdentity ?? 'anam-avatar-agent',\n publishOnBehalf: localIdentity,\n },\n 'starting Anam avatar session',\n );\n\n const jwt = await mintAvatarJoinToken({\n roomName: room.name!,\n avatarIdentity: this.
|
|
1
|
+
{"version":3,"sources":["../src/avatar.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { log, voice } from '@livekit/agents';\nimport type { Room } from '@livekit/rtc-node';\nimport { TrackKind } from '@livekit/rtc-node';\nimport { AccessToken, type VideoGrant } from 'livekit-server-sdk';\nimport { AnamAPI } from './api.js';\nimport { type APIConnectOptions, AnamException, type PersonaConfig } from './types.js';\n\nexport async function mintAvatarJoinToken({\n roomName,\n avatarIdentity,\n publishOnBehalf,\n apiKey = process.env.LIVEKIT_API_KEY!,\n apiSecret = process.env.LIVEKIT_API_SECRET!,\n ttl = '60s',\n}: {\n roomName: string;\n avatarIdentity: string;\n publishOnBehalf: string;\n apiKey?: string;\n apiSecret?: string;\n ttl?: string | number;\n}): Promise<string> {\n const at = new AccessToken(apiKey, apiSecret);\n at.identity = avatarIdentity;\n at.name = 'Anam Avatar';\n at.kind = 'agent';\n at.ttl = ttl;\n at.attributes = { 'lk.publish_on_behalf': publishOnBehalf };\n\n at.addGrant({ roomJoin: true, room: roomName } as VideoGrant);\n return at.toJwt();\n}\n\nconst AVATAR_IDENTITY = 'anam-avatar-agent';\nconst _AVATAR_NAME = 'anam-avatar-agent';\n\nexport class AvatarSession extends voice.AvatarSession {\n private sessionId?: string;\n\n constructor(\n private opts: {\n personaConfig: PersonaConfig;\n apiUrl?: string;\n apiKey?: string;\n avatarParticipantIdentity?: string;\n avatarParticipantName?: string;\n connOptions?: APIConnectOptions;\n },\n ) {\n super();\n }\n\n override get avatarIdentity(): string {\n return this.opts.avatarParticipantIdentity ?? AVATAR_IDENTITY;\n }\n\n override get provider(): string {\n return 'anam';\n }\n\n async start(\n agentSession: voice.AgentSession,\n room: Room,\n params?: {\n livekitUrl?: string;\n livekitApiKey?: string;\n livekitApiSecret?: string;\n },\n ) {\n await super.start(agentSession, room);\n\n const logger = log().child({ module: 'AnamAvatar' });\n const apiKey = this.opts.apiKey ?? process.env.ANAM_API_KEY;\n if (!apiKey) throw new AnamException('ANAM_API_KEY is required');\n\n const apiUrl = this.opts.apiUrl ?? process.env.ANAM_API_URL;\n const livekitUrl = params?.livekitUrl ?? process.env.LIVEKIT_URL;\n const lkKey = params?.livekitApiKey ?? process.env.LIVEKIT_API_KEY;\n const lkSecret = params?.livekitApiSecret ?? process.env.LIVEKIT_API_SECRET;\n\n if (!livekitUrl || !lkKey || !lkSecret) {\n throw new AnamException('LIVEKIT_URL/API_KEY/API_SECRET must be set');\n }\n\n const localIdentity = (room.localParticipant && room.localParticipant.identity) || 'agent';\n\n logger.debug(\n {\n personaName: this.opts.personaConfig?.name,\n avatarId: this.opts.personaConfig?.avatarId,\n apiUrl: apiUrl ?? '(default https://api.anam.ai)',\n livekitUrl,\n avatarParticipantIdentity: this.opts.avatarParticipantIdentity ?? 'anam-avatar-agent',\n publishOnBehalf: localIdentity,\n },\n 'starting Anam avatar session',\n );\n\n const jwt = await mintAvatarJoinToken({\n roomName: room.name!,\n avatarIdentity: this.avatarIdentity,\n publishOnBehalf: localIdentity,\n apiKey: lkKey,\n apiSecret: lkSecret,\n });\n\n const anam = new AnamAPI(apiKey, apiUrl, this.opts.connOptions);\n logger.debug({ livekitUrl }, 'requesting Anam session token');\n\n const { sessionToken } = await anam.createSessionToken({\n personaConfig: {\n name: this.opts.personaConfig?.name,\n avatarId: this.opts.personaConfig?.avatarId,\n },\n livekitUrl,\n livekitToken: jwt,\n });\n logger.debug('starting Anam engine session');\n const started = await anam.startEngineSession({ sessionToken });\n this.sessionId = started.sessionId;\n\n agentSession.output.audio = new voice.DataStreamAudioOutput({\n room,\n destinationIdentity: this.avatarIdentity,\n waitRemoteTrack: TrackKind.KIND_VIDEO,\n });\n }\n}\n"],"mappings":"AAGA,SAAS,KAAK,aAAa;AAE3B,SAAS,iBAAiB;AAC1B,SAAS,mBAAoC;AAC7C,SAAS,eAAe;AACxB,SAAiC,qBAAyC;AAE1E,eAAsB,oBAAoB;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAAS,QAAQ,IAAI;AAAA,EACrB,YAAY,QAAQ,IAAI;AAAA,EACxB,MAAM;AACR,GAOoB;AAClB,QAAM,KAAK,IAAI,YAAY,QAAQ,SAAS;AAC5C,KAAG,WAAW;AACd,KAAG,OAAO;AACV,KAAG,OAAO;AACV,KAAG,MAAM;AACT,KAAG,aAAa,EAAE,wBAAwB,gBAAgB;AAE1D,KAAG,SAAS,EAAE,UAAU,MAAM,MAAM,SAAS,CAAe;AAC5D,SAAO,GAAG,MAAM;AAClB;AAEA,MAAM,kBAAkB;AACxB,MAAM,eAAe;AAEd,MAAM,sBAAsB,MAAM,cAAc;AAAA,EAGrD,YACU,MAQR;AACA,UAAM;AATE;AAAA,EAUV;AAAA,EAbQ;AAAA,EAeR,IAAa,iBAAyB;AACpC,WAAO,KAAK,KAAK,6BAA6B;AAAA,EAChD;AAAA,EAEA,IAAa,WAAmB;AAC9B,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,MACJ,cACA,MACA,QAKA;AAvEJ;AAwEI,UAAM,MAAM,MAAM,cAAc,IAAI;AAEpC,UAAM,SAAS,IAAI,EAAE,MAAM,EAAE,QAAQ,aAAa,CAAC;AACnD,UAAM,SAAS,KAAK,KAAK,UAAU,QAAQ,IAAI;AAC/C,QAAI,CAAC,OAAQ,OAAM,IAAI,cAAc,0BAA0B;AAE/D,UAAM,SAAS,KAAK,KAAK,UAAU,QAAQ,IAAI;AAC/C,UAAM,cAAa,iCAAQ,eAAc,QAAQ,IAAI;AACrD,UAAM,SAAQ,iCAAQ,kBAAiB,QAAQ,IAAI;AACnD,UAAM,YAAW,iCAAQ,qBAAoB,QAAQ,IAAI;AAEzD,QAAI,CAAC,cAAc,CAAC,SAAS,CAAC,UAAU;AACtC,YAAM,IAAI,cAAc,4CAA4C;AAAA,IACtE;AAEA,UAAM,gBAAiB,KAAK,oBAAoB,KAAK,iBAAiB,YAAa;AAEnF,WAAO;AAAA,MACL;AAAA,QACE,cAAa,UAAK,KAAK,kBAAV,mBAAyB;AAAA,QACtC,WAAU,UAAK,KAAK,kBAAV,mBAAyB;AAAA,QACnC,QAAQ,UAAU;AAAA,QAClB;AAAA,QACA,2BAA2B,KAAK,KAAK,6BAA6B;AAAA,QAClE,iBAAiB;AAAA,MACnB;AAAA,MACA;AAAA,IACF;AAEA,UAAM,MAAM,MAAM,oBAAoB;AAAA,MACpC,UAAU,KAAK;AAAA,MACf,gBAAgB,KAAK;AAAA,MACrB,iBAAiB;AAAA,MACjB,QAAQ;AAAA,MACR,WAAW;AAAA,IACb,CAAC;AAED,UAAM,OAAO,IAAI,QAAQ,QAAQ,QAAQ,KAAK,KAAK,WAAW;AAC9D,WAAO,MAAM,EAAE,WAAW,GAAG,+BAA+B;AAE5D,UAAM,EAAE,aAAa,IAAI,MAAM,KAAK,mBAAmB;AAAA,MACrD,eAAe;AAAA,QACb,OAAM,UAAK,KAAK,kBAAV,mBAAyB;AAAA,QAC/B,WAAU,UAAK,KAAK,kBAAV,mBAAyB;AAAA,MACrC;AAAA,MACA;AAAA,MACA,cAAc;AAAA,IAChB,CAAC;AACD,WAAO,MAAM,8BAA8B;AAC3C,UAAM,UAAU,MAAM,KAAK,mBAAmB,EAAE,aAAa,CAAC;AAC9D,SAAK,YAAY,QAAQ;AAEzB,iBAAa,OAAO,QAAQ,IAAI,MAAM,sBAAsB;AAAA,MAC1D;AAAA,MACA,qBAAqB,KAAK;AAAA,MAC1B,iBAAiB,UAAU;AAAA,IAC7B,CAAC;AAAA,EACH;AACF;","names":[]}
|
package/dist/index.cjs
CHANGED
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@livekit/agents-plugin-anam",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.4",
|
|
4
4
|
"description": "Anam plugin for LiveKit Node Agents",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"require": "dist/index.cjs",
|
|
@@ -30,9 +30,9 @@
|
|
|
30
30
|
"@types/ws": "^8.5.10",
|
|
31
31
|
"tsup": "^8.3.5",
|
|
32
32
|
"typescript": "^5.0.0",
|
|
33
|
-
"@livekit/agents": "1.4.
|
|
34
|
-
"@livekit/agents-plugin-openai": "1.4.
|
|
35
|
-
"@livekit/agents-plugins-test": "1.4.
|
|
33
|
+
"@livekit/agents": "1.4.4",
|
|
34
|
+
"@livekit/agents-plugin-openai": "1.4.4",
|
|
35
|
+
"@livekit/agents-plugins-test": "1.4.4"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"livekit-server-sdk": "^2.9.2",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
42
|
"@livekit/rtc-node": "^0.13.27",
|
|
43
|
-
"@livekit/agents": "1.4.
|
|
43
|
+
"@livekit/agents": "1.4.4"
|
|
44
44
|
},
|
|
45
45
|
"scripts": {
|
|
46
46
|
"build": "tsup --onSuccess \"pnpm build:types\"",
|
package/src/avatar.ts
CHANGED
|
@@ -53,6 +53,14 @@ export class AvatarSession extends voice.AvatarSession {
|
|
|
53
53
|
super();
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
+
override get avatarIdentity(): string {
|
|
57
|
+
return this.opts.avatarParticipantIdentity ?? AVATAR_IDENTITY;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
override get provider(): string {
|
|
61
|
+
return 'anam';
|
|
62
|
+
}
|
|
63
|
+
|
|
56
64
|
async start(
|
|
57
65
|
agentSession: voice.AgentSession,
|
|
58
66
|
room: Room,
|
|
@@ -93,7 +101,7 @@ export class AvatarSession extends voice.AvatarSession {
|
|
|
93
101
|
|
|
94
102
|
const jwt = await mintAvatarJoinToken({
|
|
95
103
|
roomName: room.name!,
|
|
96
|
-
avatarIdentity: this.
|
|
104
|
+
avatarIdentity: this.avatarIdentity,
|
|
97
105
|
publishOnBehalf: localIdentity,
|
|
98
106
|
apiKey: lkKey,
|
|
99
107
|
apiSecret: lkSecret,
|
|
@@ -116,7 +124,7 @@ export class AvatarSession extends voice.AvatarSession {
|
|
|
116
124
|
|
|
117
125
|
agentSession.output.audio = new voice.DataStreamAudioOutput({
|
|
118
126
|
room,
|
|
119
|
-
destinationIdentity: this.
|
|
127
|
+
destinationIdentity: this.avatarIdentity,
|
|
120
128
|
waitRemoteTrack: TrackKind.KIND_VIDEO,
|
|
121
129
|
});
|
|
122
130
|
}
|