Bixby Developer Center

Guides

2017 March–December

Note

Internal platform changes that are not visible to capsule developers will be communicated via internal status updates.

17X Capsule SDK Release Notes

Access Actions through Endpoints

You must now explicitly declare and access actions as endpoints. You can make your actions accessible as local, remote, and client endpoints.

You create action endpoints through an endpoints.bxb file that defines the action, including the inputs the action will accept and the endpoints that the action will call.

Here is an example endpoints.bxb for a test capsule that allows users to search for shoes:

endpoints {
authorization {
none
}

action-endpoints {

action-endpoint (FindShoe) {
accepted-inputs (name, type, minPrice, maxPrice)
local-endpoint (FindShoe.js)
}

}
}

The corresponding FindShoe.js then includes the external action implementation that returns values back to the capsule:

exports.tests = []

var SHOES = require('./lib/shoes')

exports.function = function (name, type, minPrice, maxPrice) {
var result = SHOES.filter(function (shoe) {
return (
(!name || shoe.name.toUpperCase() == name.toUpperCase()) &&
(!type || shoe.type.toUpperCase() == type.toUpperCase()) &&
(!maxPrice || shoe.price.value <= maxPrice.value) &&
(!minPrice || shoe.price.value >= minPrice.value)
)
})
return result
}

To learn more about endpoints, read Configuring Endpoints.

New Ways to Sort Action Results

In addition to natural-order sorting, you can now sort action results using the sort-orderings, which gives you more control over results that are presented. You can define sort ordering within structures and then use them in actions, or your actions can define specific sort ordering.

Here are examples of how you can define sorting within a structure and an action, respectively:

structure {
...

sort-orderings {
default-ordering (EarliestArrival) {

sorting (somePropertyExprOrBindingPath) {
by (OtherOrderingOfSomePropertyExprStaticType)
}

sorting (somePropertyExprOrBindingPath) {
by (AnotherOrderingOfSomePropertyExprStaticType)
inverted
}

// default order used
sorting (somePropertyExprOrBindingPath)

// inverted default order used
sorting (somePropertyExprOrBindingPath) {
inverted
}

}

ordering (LatestArrival) {
...
}
...
}
}
action (MyAction) {
type (Search)
collect {
input (mySort) {
type (MySortEnum)
}
}
...

output (MyOutputType) {
...
sort {
switch (mySort) {
case (PriceAsc) {
each (r) {
sorting (r.price) {
by (Desc)
inverted
}
// compound in case of a tie
ranking (-1 * r.price)
}
}
case (FooBarBaz) {
each (r) {
sorting (r) {
by (SomeOtherCriteriaDefinedInFlightStatus)
}
}
}
default {
each (r) {
sorting (r) // use natural order of r
}
}
}
}
}
}

To learn more, refer to sort-orderings (structure) and sort (action) within the Reference Guide.

Limits on Capsule Training Examples and Vocabulary

You now have a limit of 2,000 training examples for your capsule. You also are limited to 50,000 vocabulary entries per type.

Limits on Enum Primitives

You are now limited to 512 symbols for each enum. You also cannot extend an enum or add a symbol when you add a concept that is a role-of an enum.

New "never-equivalent" Key

You can now ensure that two primitive types never merge into a single value using the new equivalence child key, never-equivalent.

integer (calculator.Number) {
equivalence {
never-equivalent
}

17V Capsule SDK Release Notes

Replace "value" with "intent" in Inputs

We have standardized using intent within the default-init key (previously the default-value key). As a result, the value key has been deprecated within default-init.

Old:

input (test) {
...
default-init {
value {MyType(...)}
}
}

New:

input (test) {
...
default-init {
intent {goal {MyType} value {MyType(...)}
}
}

Replace "value-template" with "evaluate" in Inputs

To better reflect how the key works, we've renamed the value-template key within actions to evaluate.

Old:

output (test) {
value-template {
...
}
}

New:

output (test) {
evaluate {
...
}
}

Replace "header" Element in Layouts with "content"

To simplify creating layouts, we've removed the <header> element for all layout types and have now consolidated all layout content into the <content> element, which is now interchangeable with <header>.

Old:

<layout type="details">
<match>
Recipe (this)
</match>
<header>
<div class="photo" style="background-image: url({{#try}}{{thumbnail.url}}{{/try}})"></div>
<layout-macro id="title-area">
<title>{{name}}</title>
</layout-macro>
</header>
<content>
<div class="details">
<div class="info-row">
<div>
<h5>Serves</h5>
<span>{{#if exists(servings)}}{{ servings }}{{else}}&mdash;{{/if}}</span>
</div>
...

New:

<layout type="details">
<match>
Recipe (this)
</match>
<content>
<div class="photo" style="background-image: url({{#try}}{{thumbnail.url}}{{/try}})"></div>
<layout-macro id="title-area">
<title>{{name}}</title>
</layout-macro>
<div class="details">
<div class="info-row">
<div>
<h5>Serves</h5>
<span>{{#if exists(servings)}}{{ servings }}{{else}}&mdash;{{/if}}</span>
</div>
<div>
...

Include "requires" Key in "input-group"

To enforce cardinality constraints on input groups, the input-group key must now include a requires child key.

Example:

collect {
input (shape) {
type (ShapeType)
min(Required) max (One)
}

input-group(atLeastOne) {
requires (OneOrMoreOf)

collect {
input (line1) {
type (Line1)
min(Optional) max (One)

validate {
if (exists(line1) && line1 <= 0) {
halt {
dialog {
template("Need a positive length.")
}
}
}
}
}
...

Remove "open-match" within "name" primitives

We've deprecated support for having an open-match declaration within name primitives. Previously, open-match was true by default and was used to restrict the matching of words not present in a vocabulary file. We instead recommend better training and vocabulary data.

Old:

name (SubLocalityOneName) {
extends (AdministrativeDivisionName)
open-match (false)
}