Jovo v4.5: Dependency Injection and Intent Scoping
Published by Alex Swetlow & Jan König on Nov 22, 2022.
Jovo v4.5
builds on top of our major v4
release last year. Learn more below.
Introduction
Jovo v4.5
includes the following larger updates:
v4.5
also comes with many other improvements and bugfixes. You can find all releases on GitHub and the Jovo News page.
A huge thank you for everyone who keeps helping to improve Jovo: Mark, Palle, Nico, Florian, David, Pete, Gianluca, and many more who are part of the Jovo community!
New Features
The v4.5
release comes with many improvements and 4 larger additions:
Here are some more pull requests that are part of latest releases:
- Add billingMode option on DynamoDbConfig to allow on-demand mode by Florian
- Allow history items as class instances by Alex
- Add app data + allow app and request data in unit tests by Jan
- Add Alexa Lists feature by Nico
Dependency Injection
Dependency injection is a feature that can be helpful to access instantiated service providers (and values) in components and output classes:
// src/services/OrderService.ts import { Injectable } from '@jovotech/framework'; // ... @Injectable() class OrderService { async performOrder() { // ... } }
They can be added to the app config:
// src/app.ts import { OrderService } from './services/OrderService'; // ... const app = new App({ providers: [ OrderService, // ... ], });
And then accessed in any component our output class using the constructor()
:
// src/components/OrderPizzaComponent.ts @Component() class OrderPizzaComponent extends BaseComponent { constructor( jovo: Jovo, options: UnknownObject | undefined, private readonly orderService: OrderService ) { super(jovo, options); } @Intents('ConfirmOrderIntent') async confirmOrder() { try { await this.orderService.performOrder(); // ... } catch (e) { // ... } } }
This feature is especially helpful if you want to mock API calls in unit testing.
Thank you Palle for contributing this great feature!
Intent Scoping
As part of our goal to make it easier for you to improve NLU performance, we added a feature called intent scoping.
Some NLU services support the ability to prioritize certain intents. This helps if you have a large language model, but want to listen to specific input.
In Jovo, you can now pass a list of intents using the listen
output property:
{ message: `Which city do you want to visit?`, listen: { intents: [ 'CityIntent' ], }, }
This feature currently works with Snips NLU.
Native NLU Data
For more transparency and easier debugging, we added a native
property to the NLU data that gets added to the $input
property. It includes the full API response from the NLU service:
{ type: 'TEXT', text: 'My name is Max', nlu: { intent: 'MyNameIsIntent', entities: { name: { value: 'Max', // ... }, }, native: { // Raw API response from the NLU service }, }, }
Component Inheritance
Components can now inherit handlers from their superclass. This is useful for components that offer similar workflows, like a help handler.
import { BaseComponent } from '@jovotech/framework'; abstract class ComponentWithHelp extends BaseComponent { abstract showHelp(): Promise<void>; async repeatLastResponse() { // ... } @Intents('HelpIntent') async help() { await this.showHelp(); await this.repeatLastResponse(); } } @Component() class YourComponent extends ComponentWithHelp { async showHelp() { // ... } }
Thank you Palle for contributing this great feature!
New Examples
We also added 2 Jovo examples:
Breaking Changes
The dependency injection feature comes with a small breaking change.
It changes the constructor signature for BaseComponent
and BaseOutput
. By changing from options?: TYPE
to options: undefined | TYPE
, subsequent parameters are not required to be optional.
In your constructor()
, make sure to add undefined
as a potential value for options
, for example:
@Component() class OrderPizzaComponent extends BaseComponent { constructor( jovo: Jovo, options: ComponentOptions<UnknownObject> | undefined, private readonly orderService: OrderService ) { super(jovo, options); } @Intents('ConfirmOrderIntent') async confirmOrder() { try { await this.orderService.performOrder(); // ... } catch (e) { // ... } } }
Learn more in its pull request.
Also, in v4.4
, we dropped support for Node v12
.
Getting Started with Jovo
There are several ways how you can get started with Jovo:
- Follow our getting started guide to install the Jovo CLI and create a new project
- Take a look at our examples
- Join our community
Thanks a lot for being part of Jovo!