Implement loading models from specific files.

This commit is contained in:
Eddie Antonio Santos 2018-10-11 15:19:46 -06:00
parent 47580c6af9
commit f7bd16dade
No known key found for this signature in database
GPG key ID: DD411EA4D9509D87
5 changed files with 47 additions and 11 deletions

View file

@ -338,10 +338,12 @@ TODO
- [x] Change `context` to `contexts`.
- [x] Change `contexts` to `context`....
- [] Figure out what a `Context` will be
- [x] Figure out what a `Context` will be
- [x] Implement hack to make `global` inherit from `self`
- [x] Define on `self.registerModel(factory: (c) => Model)` protocol
- [x] Describe `contexts`
- [x] Implement loading a model from a file.
- [ ] Document `suggestions`
- [ ] make simple `index.html` that demos a dummy model
- [ ] make an `error` initialization message.
- [ ] TypeScript!

View file

@ -21,7 +21,7 @@ class LMLayer {
/**
* [async] Waits for the model's initialization.
*/
initialize(_acceptConfiguration) {
initialize({model, configuration }) {
if (this._configuration) {
return Promise.resolve(this._configuration);
}
@ -30,9 +30,11 @@ class LMLayer {
// _onMessage() will resolve this Promise.
return new Promise((resolve, _reject) => {
this._cast('initialize', {
model,
configuration: {
maxLeftContextCodeUnits: 32,
supportsRightContexts: false,
...configuration
}
});
this._resolveInitialized = resolve;

View file

@ -52,7 +52,7 @@ function onMessageWhenUninitialized(event) {
}
// Import the model.
let model = loadModel(configuration.path, configuration);
let model = loadModel(event.data.model, configuration);
transitionToReadyState(model);
// Ready! Send desired configuration.
@ -69,7 +69,7 @@ function transitionToReadyState(model) {
* Responds to `predict` messages with a `suggestions` message.
*/
onMessage = function onMessageWhenReady(event) {
const {message, token} = event.data;
const {message, token, transform, context} = event.data;
if (message !== 'predict') {
throw new Error('invalid message');
@ -82,10 +82,9 @@ function transitionToReadyState(model) {
return;
}
// TODO: rip contexts out of message.
let rawSuggestions = model.predict();
let rawSuggestions = model.predict(context, transform);
// Sort in-place according to weight.
// Sort in-place according to weight, ascending.
rawSuggestions.sort((a, b) => a.weight - b.weight);
// Convert the internal suggestion format to the one required by the keyboard.
@ -114,8 +113,8 @@ function cast(message, parameters) {
/**
* Loads the model from a separate file.
*/
function loadModel(_path /* : string */, configuration /* : Configuration */) {
importScripts('./models/en-x-test-derek.js');
function loadModel(path /* : string */, configuration /* : Configuration */) {
importScripts(path);
/**
* The model MUST call registerModel() which ultimately defines
* createModel() to a function.

View file

@ -0,0 +1,33 @@
/**
* This is a test model that simply returns "teapot" when given the context of
* «I'm a little ».
*/
registerModel(function () {
return {
predict(context, transform) {
return [
{
transform: {
insert: 'teapot',
deleteLeft: transform.insert.length,
deleteRight: 0,
},
displayAs: '🍵',
weight: 0.00,
}
];
/* TODO:
if (context.wordsLeft === ["I'm", "a", "little"] &&
transform.insert === 't') {
}
return [];
*/
},
configuration: {
}
};
});
/*global registerModel*/

View file

@ -11,7 +11,7 @@ test('It provide context to LMLayer', async t => {
const lm = new LMLayer;
// Wait for the language model to initialize and declare its configuration.
let configuration = await lm.initialize({ model: 'en-x-derek' });
let configuration = await lm.initialize({ model: './models/en-x-test-derek.js' });
// The model should as for 32 code units of context to the left of the
// cursor.
t.is(configuration.leftContextCodeUnits, 32);
@ -46,7 +46,7 @@ test('It should reject when predictions crash', async t => {
t.plan(1);
const lm = new LMLayer;
await lm.initialize({ model: 'en-x-derek' });
await lm.initialize({ model: './models/en-x-test-derek.js' });
try {
await lm.predict({