@livekit/agents-plugin-anam 1.6.4 → 1.7.0

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 CHANGED
@@ -79,8 +79,8 @@ class AvatarSession extends import_agents.voice.AvatarSession {
79
79
  personaId: (_c = this.opts.personaConfig) == null ? void 0 : _c.personaId,
80
80
  apiUrl: apiUrl ?? "(default https://api.anam.ai)",
81
81
  livekitUrl,
82
- avatarParticipantIdentity: this.opts.avatarParticipantIdentity ?? "anam-avatar-agent",
83
- publishOnBehalf: localIdentity
82
+ "lk.pii.avatar_participant_identity": this.opts.avatarParticipantIdentity ?? "anam-avatar-agent",
83
+ "lk.pii.publish_on_behalf": localIdentity
84
84
  },
85
85
  "starting Anam avatar session"
86
86
  );
@@ -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 {\n type APIConnectOptions,\n AnamException,\n type PersonaConfig,\n type SessionOptions,\n} from './types.js';\n\n/** @public */\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\n/** @public */\nexport class AvatarSession extends voice.AvatarSession {\n private sessionId?: string;\n\n constructor(\n private opts: {\n personaConfig: PersonaConfig;\n sessionOptions?: SessionOptions;\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 personaId: this.opts.personaConfig?.personaId,\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: this.opts.personaConfig,\n livekitUrl,\n livekitToken: jwt,\n sessionOptions: this.opts.sessionOptions,\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":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,oBAA2B;AAE3B,sBAA0B;AAC1B,gCAA6C;AAC7C,iBAAwB;AACxB,mBAKO;AAGP,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,sCAAY,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;AAGd,MAAM,sBAAsB,oBAAM,cAAc;AAAA,EAGrD,YACU,MASR;AACA,UAAM;AAVE;AAAA,EAWV;AAAA,EAdQ;AAAA,EAgBR,IAAa,iBAAyB;AACpC,WAAO,KAAK,KAAK,6BAA6B;AAAA,EAChD;AAAA,EAEA,IAAa,WAAmB;AAC9B,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,MACJ,cACA,MACA,QAKA;AA/EJ;AAgFI,UAAM,MAAM,MAAM,cAAc,IAAI;AAEpC,UAAM,aAAS,mBAAI,EAAE,MAAM,EAAE,QAAQ,aAAa,CAAC;AACnD,UAAM,SAAS,KAAK,KAAK,UAAU,QAAQ,IAAI;AAC/C,QAAI,CAAC,OAAQ,OAAM,IAAI,2BAAc,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,2BAAc,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,YAAW,UAAK,KAAK,kBAAV,mBAAyB;AAAA,QACpC,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,mBAAQ,QAAQ,QAAQ,KAAK,KAAK,WAAW;AAC9D,WAAO,MAAM,EAAE,WAAW,GAAG,+BAA+B;AAE5D,UAAM,EAAE,aAAa,IAAI,MAAM,KAAK,mBAAmB;AAAA,MACrD,eAAe,KAAK,KAAK;AAAA,MACzB;AAAA,MACA,cAAc;AAAA,MACd,gBAAgB,KAAK,KAAK;AAAA,IAC5B,CAAC;AACD,WAAO,MAAM,8BAA8B;AAC3C,UAAM,UAAU,MAAM,KAAK,mBAAmB,EAAE,aAAa,CAAC;AAC9D,SAAK,YAAY,QAAQ;AAEzB,iBAAa,OAAO,QAAQ,IAAI,oBAAM,sBAAsB;AAAA,MAC1D;AAAA,MACA,qBAAqB,KAAK;AAAA,MAC1B,iBAAiB,0BAAU;AAAA,IAC7B,CAAC;AAAA,EACH;AACF;","names":[]}
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 {\n type APIConnectOptions,\n AnamException,\n type PersonaConfig,\n type SessionOptions,\n} from './types.js';\n\n/** @public */\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\n/** @public */\nexport class AvatarSession extends voice.AvatarSession {\n private sessionId?: string;\n\n constructor(\n private opts: {\n personaConfig: PersonaConfig;\n sessionOptions?: SessionOptions;\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 personaId: this.opts.personaConfig?.personaId,\n apiUrl: apiUrl ?? '(default https://api.anam.ai)',\n livekitUrl,\n 'lk.pii.avatar_participant_identity':\n this.opts.avatarParticipantIdentity ?? 'anam-avatar-agent',\n 'lk.pii.publish_on_behalf': 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: this.opts.personaConfig,\n livekitUrl,\n livekitToken: jwt,\n sessionOptions: this.opts.sessionOptions,\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":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,oBAA2B;AAE3B,sBAA0B;AAC1B,gCAA6C;AAC7C,iBAAwB;AACxB,mBAKO;AAGP,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,sCAAY,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;AAGd,MAAM,sBAAsB,oBAAM,cAAc;AAAA,EAGrD,YACU,MASR;AACA,UAAM;AAVE;AAAA,EAWV;AAAA,EAdQ;AAAA,EAgBR,IAAa,iBAAyB;AACpC,WAAO,KAAK,KAAK,6BAA6B;AAAA,EAChD;AAAA,EAEA,IAAa,WAAmB;AAC9B,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,MACJ,cACA,MACA,QAKA;AA/EJ;AAgFI,UAAM,MAAM,MAAM,cAAc,IAAI;AAEpC,UAAM,aAAS,mBAAI,EAAE,MAAM,EAAE,QAAQ,aAAa,CAAC;AACnD,UAAM,SAAS,KAAK,KAAK,UAAU,QAAQ,IAAI;AAC/C,QAAI,CAAC,OAAQ,OAAM,IAAI,2BAAc,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,2BAAc,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,YAAW,UAAK,KAAK,kBAAV,mBAAyB;AAAA,QACpC,QAAQ,UAAU;AAAA,QAClB;AAAA,QACA,sCACE,KAAK,KAAK,6BAA6B;AAAA,QACzC,4BAA4B;AAAA,MAC9B;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,mBAAQ,QAAQ,QAAQ,KAAK,KAAK,WAAW;AAC9D,WAAO,MAAM,EAAE,WAAW,GAAG,+BAA+B;AAE5D,UAAM,EAAE,aAAa,IAAI,MAAM,KAAK,mBAAmB;AAAA,MACrD,eAAe,KAAK,KAAK;AAAA,MACzB;AAAA,MACA,cAAc;AAAA,MACd,gBAAgB,KAAK,KAAK;AAAA,IAC5B,CAAC;AACD,WAAO,MAAM,8BAA8B;AAC3C,UAAM,UAAU,MAAM,KAAK,mBAAmB,EAAE,aAAa,CAAC;AAC9D,SAAK,YAAY,QAAQ;AAEzB,iBAAa,OAAO,QAAQ,IAAI,oBAAM,sBAAsB;AAAA,MAC1D;AAAA,MACA,qBAAqB,KAAK;AAAA,MAC1B,iBAAiB,0BAAU;AAAA,IAC7B,CAAC;AAAA,EACH;AACF;","names":[]}
@@ -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,EACL,KAAK,iBAAiB,EAEtB,KAAK,aAAa,EAClB,KAAK,cAAc,EACpB,MAAM,YAAY,CAAC;AAEpB,cAAc;AACd,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,cAAc;AACd,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,cAAc,CAAC,EAAE,cAAc,CAAC;QAChC,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;CA2DJ"}
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,EACL,KAAK,iBAAiB,EAEtB,KAAK,aAAa,EAClB,KAAK,cAAc,EACpB,MAAM,YAAY,CAAC;AAEpB,cAAc;AACd,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,cAAc;AACd,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,cAAc,CAAC,EAAE,cAAc,CAAC;QAChC,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
@@ -57,8 +57,8 @@ class AvatarSession extends voice.AvatarSession {
57
57
  personaId: (_c = this.opts.personaConfig) == null ? void 0 : _c.personaId,
58
58
  apiUrl: apiUrl ?? "(default https://api.anam.ai)",
59
59
  livekitUrl,
60
- avatarParticipantIdentity: this.opts.avatarParticipantIdentity ?? "anam-avatar-agent",
61
- publishOnBehalf: localIdentity
60
+ "lk.pii.avatar_participant_identity": this.opts.avatarParticipantIdentity ?? "anam-avatar-agent",
61
+ "lk.pii.publish_on_behalf": localIdentity
62
62
  },
63
63
  "starting Anam avatar session"
64
64
  );
@@ -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 {\n type APIConnectOptions,\n AnamException,\n type PersonaConfig,\n type SessionOptions,\n} from './types.js';\n\n/** @public */\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\n/** @public */\nexport class AvatarSession extends voice.AvatarSession {\n private sessionId?: string;\n\n constructor(\n private opts: {\n personaConfig: PersonaConfig;\n sessionOptions?: SessionOptions;\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 personaId: this.opts.personaConfig?.personaId,\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: this.opts.personaConfig,\n livekitUrl,\n livekitToken: jwt,\n sessionOptions: this.opts.sessionOptions,\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;AAAA,EAEE;AAAA,OAGK;AAGP,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;AAGd,MAAM,sBAAsB,MAAM,cAAc;AAAA,EAGrD,YACU,MASR;AACA,UAAM;AAVE;AAAA,EAWV;AAAA,EAdQ;AAAA,EAgBR,IAAa,iBAAyB;AACpC,WAAO,KAAK,KAAK,6BAA6B;AAAA,EAChD;AAAA,EAEA,IAAa,WAAmB;AAC9B,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,MACJ,cACA,MACA,QAKA;AA/EJ;AAgFI,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,YAAW,UAAK,KAAK,kBAAV,mBAAyB;AAAA,QACpC,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,KAAK,KAAK;AAAA,MACzB;AAAA,MACA,cAAc;AAAA,MACd,gBAAgB,KAAK,KAAK;AAAA,IAC5B,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":[]}
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 {\n type APIConnectOptions,\n AnamException,\n type PersonaConfig,\n type SessionOptions,\n} from './types.js';\n\n/** @public */\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\n/** @public */\nexport class AvatarSession extends voice.AvatarSession {\n private sessionId?: string;\n\n constructor(\n private opts: {\n personaConfig: PersonaConfig;\n sessionOptions?: SessionOptions;\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 personaId: this.opts.personaConfig?.personaId,\n apiUrl: apiUrl ?? '(default https://api.anam.ai)',\n livekitUrl,\n 'lk.pii.avatar_participant_identity':\n this.opts.avatarParticipantIdentity ?? 'anam-avatar-agent',\n 'lk.pii.publish_on_behalf': 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: this.opts.personaConfig,\n livekitUrl,\n livekitToken: jwt,\n sessionOptions: this.opts.sessionOptions,\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;AAAA,EAEE;AAAA,OAGK;AAGP,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;AAGd,MAAM,sBAAsB,MAAM,cAAc;AAAA,EAGrD,YACU,MASR;AACA,UAAM;AAVE;AAAA,EAWV;AAAA,EAdQ;AAAA,EAgBR,IAAa,iBAAyB;AACpC,WAAO,KAAK,KAAK,6BAA6B;AAAA,EAChD;AAAA,EAEA,IAAa,WAAmB;AAC9B,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,MACJ,cACA,MACA,QAKA;AA/EJ;AAgFI,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,YAAW,UAAK,KAAK,kBAAV,mBAAyB;AAAA,QACpC,QAAQ,UAAU;AAAA,QAClB;AAAA,QACA,sCACE,KAAK,KAAK,6BAA6B;AAAA,QACzC,4BAA4B;AAAA,MAC9B;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,KAAK,KAAK;AAAA,MACzB;AAAA,MACA,cAAc;AAAA,MACd,gBAAgB,KAAK,KAAK;AAAA,IAC5B,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
@@ -23,7 +23,7 @@ class AnamPlugin extends import_agents.Plugin {
23
23
  constructor() {
24
24
  super({
25
25
  title: "anam",
26
- version: "1.6.4",
26
+ version: "1.7.0",
27
27
  package: "@livekit/agents-plugin-anam"
28
28
  });
29
29
  }
package/dist/index.js CHANGED
@@ -6,7 +6,7 @@ class AnamPlugin extends Plugin {
6
6
  constructor() {
7
7
  super({
8
8
  title: "anam",
9
- version: "1.6.4",
9
+ version: "1.7.0",
10
10
  package: "@livekit/agents-plugin-anam"
11
11
  });
12
12
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@livekit/agents-plugin-anam",
3
- "version": "1.6.4",
3
+ "version": "1.7.0",
4
4
  "description": "Anam plugin for LiveKit Node Agents",
5
5
  "main": "dist/index.js",
6
6
  "require": "dist/index.cjs",
@@ -28,22 +28,22 @@
28
28
  "README.md"
29
29
  ],
30
30
  "devDependencies": {
31
- "@livekit/rtc-node": "^0.13.33",
32
- "@microsoft/api-extractor": "^7.35.0",
31
+ "@livekit/rtc-node": "^0.13.34",
32
+ "@microsoft/api-extractor": "^7.58.12",
33
33
  "@types/ws": "^8.5.10",
34
34
  "tsup": "^8.3.5",
35
35
  "typescript": "^5.0.0",
36
- "@livekit/agents": "1.6.4",
37
- "@livekit/agents-plugin-openai": "1.6.4",
38
- "@livekit/agents-plugins-test": "1.6.4"
36
+ "@livekit/agents": "1.7.0",
37
+ "@livekit/agents-plugin-openai": "1.7.0",
38
+ "@livekit/agents-plugins-test": "1.7.0"
39
39
  },
40
40
  "dependencies": {
41
41
  "livekit-server-sdk": "^2.9.2",
42
42
  "ws": "^8.21.0"
43
43
  },
44
44
  "peerDependencies": {
45
- "@livekit/rtc-node": "^0.13.33",
46
- "@livekit/agents": "1.6.4"
45
+ "@livekit/rtc-node": "^0.13.34",
46
+ "@livekit/agents": "1.7.0"
47
47
  },
48
48
  "scripts": {
49
49
  "build": "tsup --onSuccess \"pnpm build:types\"",
package/src/avatar.ts CHANGED
@@ -102,8 +102,9 @@ export class AvatarSession extends voice.AvatarSession {
102
102
  personaId: this.opts.personaConfig?.personaId,
103
103
  apiUrl: apiUrl ?? '(default https://api.anam.ai)',
104
104
  livekitUrl,
105
- avatarParticipantIdentity: this.opts.avatarParticipantIdentity ?? 'anam-avatar-agent',
106
- publishOnBehalf: localIdentity,
105
+ 'lk.pii.avatar_participant_identity':
106
+ this.opts.avatarParticipantIdentity ?? 'anam-avatar-agent',
107
+ 'lk.pii.publish_on_behalf': localIdentity,
107
108
  },
108
109
  'starting Anam avatar session',
109
110
  );