diff --git a/.changeset/free-pots-peel.md b/.changeset/free-pots-peel.md new file mode 100644 index 000000000..309d4f457 --- /dev/null +++ b/.changeset/free-pots-peel.md @@ -0,0 +1,5 @@ +--- +"@adobe/alloy": patch +--- + +Added support for configuring Brand Concierge `conversation.voiceEnabled` so the SDK routes requests differently based on the voiceEnabled configuration. Included unit test coverage for config validation and voice subpath routing behavior. diff --git a/packages/core/src/components/BrandConcierge/configValidators.js b/packages/core/src/components/BrandConcierge/configValidators.js index 4fc4fdf1f..5c47d0d48 100644 --- a/packages/core/src/components/BrandConcierge/configValidators.js +++ b/packages/core/src/components/BrandConcierge/configValidators.js @@ -14,12 +14,14 @@ import { number, objectOf, boolean } from "../../utils/validation/index.js"; export default objectOf({ conversation: objectOf({ + voiceEnabled: boolean().default(false), stickyConversationSession: boolean().default(false), streamTimeout: number() .integer() .minimum(STREAM_START_TIMEOUT_MS) .default(STREAM_START_TIMEOUT_MS), }).default({ + voiceEnabled: false, stickyConversationSession: false, streamTimeout: STREAM_START_TIMEOUT_MS, }), diff --git a/packages/core/src/components/BrandConcierge/createConversationServiceRequest.js b/packages/core/src/components/BrandConcierge/createConversationServiceRequest.js index 69d36c1ed..4b835ff9d 100644 --- a/packages/core/src/components/BrandConcierge/createConversationServiceRequest.js +++ b/packages/core/src/components/BrandConcierge/createConversationServiceRequest.js @@ -11,10 +11,22 @@ governing permissions and limitations under the License. */ import { createRequest } from "../../utils/request/index.js"; -export default ({ payload, action = "conversations", sessionId }) => { +const BRAND_CONCIERGE_PATH = "/brand-concierge"; +const VOICE_BRAND_CONCIERGE_PATH = "/brand-concierge-voice"; + +export default ({ + payload, + action = "conversations", + sessionId, + voiceEnabled = false, +}) => { + const edgeSubPath = voiceEnabled + ? VOICE_BRAND_CONCIERGE_PATH + : BRAND_CONCIERGE_PATH; + return createRequest({ payload: payload, - edgeSubPath: "/brand-concierge", + edgeSubPath, requestParams: { sessionId }, getAction() { return action; diff --git a/packages/core/src/components/BrandConcierge/createSendConversationEvent.js b/packages/core/src/components/BrandConcierge/createSendConversationEvent.js index de5368f01..0fb047916 100644 --- a/packages/core/src/components/BrandConcierge/createSendConversationEvent.js +++ b/packages/core/src/components/BrandConcierge/createSendConversationEvent.js @@ -36,6 +36,7 @@ export default ({ onBeforeEventSend, conversation, } = config; + const { voiceEnabled } = conversation; return (options) => { let streamingEnabled = false; @@ -46,6 +47,7 @@ export default ({ const request = createConversationServiceRequest({ payload, sessionId: sessionId, + voiceEnabled, }); const event = eventManager.createEvent(); diff --git a/packages/core/test/unit/specs/components/BrandConcierge/createConversationServiceRequest.spec.js b/packages/core/test/unit/specs/components/BrandConcierge/createConversationServiceRequest.spec.js index 03cd10282..2e4e92aa6 100644 --- a/packages/core/test/unit/specs/components/BrandConcierge/createConversationServiceRequest.spec.js +++ b/packages/core/test/unit/specs/components/BrandConcierge/createConversationServiceRequest.spec.js @@ -85,7 +85,7 @@ describe("createConversationServiceRequest", () => { }); }); - it("uses correct edge subpath", () => { + it("uses default edge subpath when voice is disabled", () => { const request = createConversationServiceRequest({ payload: mockPayload, sessionId: mockSessionId, @@ -93,4 +93,14 @@ describe("createConversationServiceRequest", () => { expect(request.getEdgeSubPath()).toBe("/brand-concierge"); }); + + it("uses voice edge subpath when voice is enabled", () => { + const request = createConversationServiceRequest({ + payload: mockPayload, + sessionId: mockSessionId, + voiceEnabled: true, + }); + + expect(request.getEdgeSubPath()).toBe("/brand-concierge-voice"); + }); }); diff --git a/packages/core/test/unit/specs/components/BrandConcierge/index.spec.js b/packages/core/test/unit/specs/components/BrandConcierge/index.spec.js index 81d14360a..d0690eea1 100644 --- a/packages/core/test/unit/specs/components/BrandConcierge/index.spec.js +++ b/packages/core/test/unit/specs/components/BrandConcierge/index.spec.js @@ -139,16 +139,24 @@ describe("BrandConcierge config validators", () => { testConfigValidators({ configValidators: createConciergeComponent.configValidators, validConfigurations: [ + { conversation: { voiceEnabled: true } }, + { conversation: { voiceEnabled: false } }, { conversation: { stickyConversationSession: true } }, { conversation: { stickyConversationSession: false } }, { conversation: { streamTimeout: 10000 } }, { conversation: { streamTimeout: 20000 } }, { - conversation: { stickyConversationSession: true, streamTimeout: 10000 }, + conversation: { + voiceEnabled: true, + stickyConversationSession: true, + streamTimeout: 10000, + }, }, {}, ], invalidConfigurations: [ + { conversation: { voiceEnabled: "true" } }, + { conversation: { voiceEnabled: 123 } }, { conversation: { stickyConversationSession: "invalid" } }, { conversation: { stickyConversationSession: 123 } }, { conversation: { streamTimeout: "invalid" } }, @@ -159,6 +167,7 @@ describe("BrandConcierge config validators", () => { }); it("provides default values for concierge configuration", () => { const config = createConciergeComponent.configValidators({}); + expect(config.conversation.voiceEnabled).toBe(false); expect(config.conversation.stickyConversationSession).toBe(false); expect(config.conversation.streamTimeout).toBe(10000); });