@alwaysai/device-agent 0.0.13 → 0.0.14
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/lib/application-control/backup.js +3 -3
- package/lib/application-control/backup.js.map +1 -1
- package/lib/application-control/index.d.ts +4 -4
- package/lib/application-control/index.d.ts.map +1 -1
- package/lib/application-control/index.js +1 -4
- package/lib/application-control/index.js.map +1 -1
- package/lib/application-control/install.d.ts +1 -1
- package/lib/application-control/install.d.ts.map +1 -1
- package/lib/application-control/install.js +41 -54
- package/lib/application-control/install.js.map +1 -1
- package/lib/application-control/models.d.ts +0 -4
- package/lib/application-control/models.d.ts.map +1 -1
- package/lib/application-control/models.js +13 -22
- package/lib/application-control/models.js.map +1 -1
- package/lib/application-control/status.d.ts +0 -6
- package/lib/application-control/status.d.ts.map +1 -1
- package/lib/application-control/status.js +3 -19
- package/lib/application-control/status.js.map +1 -1
- package/lib/application-control/utils.d.ts +3 -0
- package/lib/application-control/utils.d.ts.map +1 -1
- package/lib/application-control/utils.js +50 -21
- package/lib/application-control/utils.js.map +1 -1
- package/lib/cloud-connection/cmd-status.d.ts +16 -0
- package/lib/cloud-connection/cmd-status.d.ts.map +1 -0
- package/lib/cloud-connection/cmd-status.js +49 -0
- package/lib/cloud-connection/cmd-status.js.map +1 -0
- package/lib/cloud-connection/device-agent-cloud-connection.d.ts +10 -1
- package/lib/cloud-connection/device-agent-cloud-connection.d.ts.map +1 -1
- package/lib/cloud-connection/device-agent-cloud-connection.js +73 -33
- package/lib/cloud-connection/device-agent-cloud-connection.js.map +1 -1
- package/lib/cloud-connection/passthrough-handler.d.ts +11 -0
- package/lib/cloud-connection/passthrough-handler.d.ts.map +1 -0
- package/lib/cloud-connection/passthrough-handler.js +59 -0
- package/lib/cloud-connection/passthrough-handler.js.map +1 -0
- package/lib/cloud-connection/publisher.d.ts +1 -0
- package/lib/cloud-connection/publisher.d.ts.map +1 -1
- package/lib/cloud-connection/publisher.js +14 -0
- package/lib/cloud-connection/publisher.js.map +1 -1
- package/lib/cloud-connection/shadow-handler.d.ts +2 -3
- package/lib/cloud-connection/shadow-handler.d.ts.map +1 -1
- package/lib/cloud-connection/shadow-handler.js +18 -4
- package/lib/cloud-connection/shadow-handler.js.map +1 -1
- package/lib/cloud-connection/shadow-handler.test.d.ts +2 -0
- package/lib/cloud-connection/shadow-handler.test.d.ts.map +1 -0
- package/lib/cloud-connection/shadow-handler.test.js +321 -0
- package/lib/cloud-connection/shadow-handler.test.js.map +1 -0
- package/lib/environment.d.ts +1 -0
- package/lib/environment.d.ts.map +1 -1
- package/lib/environment.js +2 -1
- package/lib/environment.js.map +1 -1
- package/lib/infrastructure/agent-config.d.ts +15 -48
- package/lib/infrastructure/agent-config.d.ts.map +1 -1
- package/lib/infrastructure/agent-config.js.map +1 -1
- package/lib/infrastructure/agent-config.test.js +0 -6
- package/lib/infrastructure/agent-config.test.js.map +1 -1
- package/lib/infrastructure/system-id.js +2 -2
- package/lib/infrastructure/system-id.js.map +1 -1
- package/lib/infrastructure/tokens-and-device-cfg.d.ts.map +1 -1
- package/lib/infrastructure/tokens-and-device-cfg.js +5 -9
- package/lib/infrastructure/tokens-and-device-cfg.js.map +1 -1
- package/lib/local-connection/rabbitmq-connection.d.ts +4 -0
- package/lib/local-connection/rabbitmq-connection.d.ts.map +1 -0
- package/lib/local-connection/rabbitmq-connection.js +58 -0
- package/lib/local-connection/rabbitmq-connection.js.map +1 -0
- package/lib/subcommands/app/app.d.ts +2 -1
- package/lib/subcommands/app/app.d.ts.map +1 -1
- package/lib/subcommands/app/app.js +56 -23
- package/lib/subcommands/app/app.js.map +1 -1
- package/lib/subcommands/device/clean.js +4 -4
- package/lib/subcommands/device/clean.js.map +1 -1
- package/lib/subcommands/device/device.d.ts +1 -1
- package/lib/subcommands/device/device.d.ts.map +1 -1
- package/lib/subcommands/device/device.js +7 -9
- package/lib/subcommands/device/device.js.map +1 -1
- package/lib/subcommands/index.d.ts +0 -1
- package/lib/subcommands/index.d.ts.map +1 -1
- package/lib/subcommands/login.d.ts +0 -1
- package/lib/subcommands/login.d.ts.map +1 -1
- package/lib/subcommands/login.js +1 -9
- package/lib/subcommands/login.js.map +1 -1
- package/lib/util/fetch-with-timeout.d.ts +4 -0
- package/lib/util/fetch-with-timeout.d.ts.map +1 -0
- package/lib/util/fetch-with-timeout.js +15 -0
- package/lib/util/fetch-with-timeout.js.map +1 -0
- package/lib/util/require-logged-in-and-paid-plan.d.ts +2 -0
- package/lib/util/require-logged-in-and-paid-plan.d.ts.map +1 -0
- package/lib/util/require-logged-in-and-paid-plan.js +18 -0
- package/lib/util/require-logged-in-and-paid-plan.js.map +1 -0
- package/lib/util/timer.d.ts +2 -0
- package/lib/util/timer.d.ts.map +1 -0
- package/lib/util/timer.js +6 -0
- package/lib/util/timer.js.map +1 -0
- package/package.json +20 -32
- package/readme.md +100 -89
- package/src/application-control/backup.ts +3 -3
- package/src/application-control/index.ts +0 -6
- package/src/application-control/install.ts +53 -73
- package/src/application-control/models.ts +7 -19
- package/src/application-control/status.ts +3 -19
- package/src/application-control/utils.ts +61 -22
- package/src/cloud-connection/cmd-status.ts +52 -0
- package/src/cloud-connection/device-agent-cloud-connection.ts +94 -47
- package/src/cloud-connection/passthrough-handler.ts +67 -0
- package/src/cloud-connection/publisher.ts +21 -0
- package/src/cloud-connection/shadow-handler.test.ts +361 -0
- package/src/cloud-connection/shadow-handler.ts +28 -7
- package/src/environment.ts +3 -0
- package/src/infrastructure/agent-config.test.ts +0 -7
- package/src/infrastructure/agent-config.ts +24 -2
- package/src/infrastructure/system-id.ts +1 -1
- package/src/infrastructure/tokens-and-device-cfg.ts +8 -13
- package/src/local-connection/rabbitmq-connection.ts +53 -0
- package/src/subcommands/app/app.ts +61 -27
- package/src/subcommands/device/clean.ts +4 -4
- package/src/subcommands/device/device.ts +8 -11
- package/src/subcommands/login.ts +1 -9
- package/src/util/fetch-with-timeout.ts +18 -0
- package/src/util/require-logged-in-and-paid-plan.ts +16 -0
- package/src/util/timer.ts +1 -0
|
@@ -4,15 +4,13 @@ import {
|
|
|
4
4
|
CliStringInput,
|
|
5
5
|
CliTerseError
|
|
6
6
|
} from '@alwaysai/alwayscli';
|
|
7
|
+
import { ClientMessage, keyMirrors } from '@alwaysai/device-agent-schemas';
|
|
7
8
|
import {
|
|
8
|
-
addModel,
|
|
9
9
|
getAllEnvs,
|
|
10
10
|
getAppLogs,
|
|
11
11
|
getAppModels,
|
|
12
12
|
getAppStatus,
|
|
13
|
-
|
|
14
|
-
listAppLatestRelease,
|
|
15
|
-
listAppReleases,
|
|
13
|
+
readAppCfgFile,
|
|
16
14
|
removeModel,
|
|
17
15
|
replaceModels,
|
|
18
16
|
restartApp,
|
|
@@ -23,8 +21,10 @@ import {
|
|
|
23
21
|
uninstallApp,
|
|
24
22
|
updateModels
|
|
25
23
|
} from '../../application-control';
|
|
24
|
+
import { DeviceAgentCloudConnection } from '../../cloud-connection/device-agent-cloud-connection';
|
|
26
25
|
import { AgentConfigFile } from '../../infrastructure/agent-config';
|
|
27
26
|
import { logger } from '../../util/logger';
|
|
27
|
+
import { timer } from '../../util/timer';
|
|
28
28
|
|
|
29
29
|
export const listAppsCliLeaf = CliLeaf({
|
|
30
30
|
name: 'list',
|
|
@@ -45,10 +45,9 @@ export const listAppReleasesCliLeaf = CliLeaf({
|
|
|
45
45
|
required: true
|
|
46
46
|
})
|
|
47
47
|
},
|
|
48
|
+
hidden: true,
|
|
48
49
|
async action(_, opts) {
|
|
49
|
-
|
|
50
|
-
const releaseHistory = await listAppReleases({ projectId: project });
|
|
51
|
-
logger.info(releaseHistory);
|
|
50
|
+
throw new CliTerseError('This command is yet currently implemented!');
|
|
52
51
|
}
|
|
53
52
|
});
|
|
54
53
|
|
|
@@ -61,15 +60,9 @@ export const listAppLatestReleaseCliLeaf = CliLeaf({
|
|
|
61
60
|
required: true
|
|
62
61
|
})
|
|
63
62
|
},
|
|
63
|
+
hidden: true,
|
|
64
64
|
async action(_, opts) {
|
|
65
|
-
|
|
66
|
-
const latestReleaseHash = await listAppLatestRelease({
|
|
67
|
-
projectId: project
|
|
68
|
-
});
|
|
69
|
-
if (latestReleaseHash === undefined) {
|
|
70
|
-
throw new CliTerseError('This application has not been published yet');
|
|
71
|
-
}
|
|
72
|
-
logger.info(latestReleaseHash);
|
|
65
|
+
throw new CliTerseError('This command is yet currently implemented!');
|
|
73
66
|
}
|
|
74
67
|
});
|
|
75
68
|
|
|
@@ -82,19 +75,32 @@ export const installAppCliLeaf = CliLeaf({
|
|
|
82
75
|
required: true
|
|
83
76
|
}),
|
|
84
77
|
releaseHash: CliStringInput({
|
|
85
|
-
description: 'Release Hash'
|
|
78
|
+
description: 'Release Hash',
|
|
79
|
+
required: true
|
|
86
80
|
})
|
|
87
81
|
},
|
|
88
82
|
async action(_, opts) {
|
|
89
|
-
const project = opts
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
83
|
+
const { project, releaseHash } = opts;
|
|
84
|
+
const deviceAgent = new DeviceAgentCloudConnection();
|
|
85
|
+
await deviceAgent.setupHandlers();
|
|
86
|
+
const topic = deviceAgent.getToDeviceTopic();
|
|
87
|
+
const message: ClientMessage = {
|
|
88
|
+
timestamp: '',
|
|
89
|
+
topic,
|
|
90
|
+
payload: {
|
|
91
|
+
messageType: keyMirrors.clientMessageType.app_version_control,
|
|
92
|
+
appVersionControl: {
|
|
93
|
+
baseCommand: keyMirrors.appVersionControl.install,
|
|
94
|
+
projectId: project,
|
|
95
|
+
appReleaseHash: releaseHash
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
await deviceAgent.handleClientMessage({ topic, message });
|
|
100
|
+
while (deviceAgent.getCmdStatus(project) === 'in_progress') {
|
|
101
|
+
await timer(1000);
|
|
93
102
|
}
|
|
94
|
-
|
|
95
|
-
throw new CliTerseError('This application has not been published yet');
|
|
96
|
-
}
|
|
97
|
-
await installApp({ projectId: project, appReleaseHash: releaseHash });
|
|
103
|
+
deviceAgent.stop();
|
|
98
104
|
}
|
|
99
105
|
});
|
|
100
106
|
|
|
@@ -110,7 +116,7 @@ export const getAppStatusCliLeaf = CliLeaf({
|
|
|
110
116
|
async action(_, opts) {
|
|
111
117
|
const { project } = opts;
|
|
112
118
|
const appStatus = await getAppStatus({ projectId: project });
|
|
113
|
-
logger.info(appStatus);
|
|
119
|
+
logger.info(JSON.stringify(appStatus, null, 2));
|
|
114
120
|
}
|
|
115
121
|
});
|
|
116
122
|
|
|
@@ -205,6 +211,7 @@ export const rollbackAppCliLeaf = CliLeaf({
|
|
|
205
211
|
required: true
|
|
206
212
|
})
|
|
207
213
|
},
|
|
214
|
+
hidden: true,
|
|
208
215
|
async action(_, opts) {
|
|
209
216
|
const { project } = opts;
|
|
210
217
|
await rollbackApp({ projectId: project });
|
|
@@ -238,11 +245,38 @@ export const addModelCliLeaf = CliLeaf({
|
|
|
238
245
|
model: CliStringInput({
|
|
239
246
|
description: 'Model ID',
|
|
240
247
|
required: true
|
|
248
|
+
}),
|
|
249
|
+
version: CliStringInput({
|
|
250
|
+
description: 'Model version',
|
|
251
|
+
required: true
|
|
241
252
|
})
|
|
242
253
|
},
|
|
243
254
|
async action(_, opts) {
|
|
244
|
-
const { project, model } = opts;
|
|
245
|
-
|
|
255
|
+
const { project, model, version } = opts;
|
|
256
|
+
const deviceAgent = new DeviceAgentCloudConnection();
|
|
257
|
+
await deviceAgent.setupHandlers();
|
|
258
|
+
|
|
259
|
+
const topic = deviceAgent.getShadowTopics().projects.updateDelta;
|
|
260
|
+
|
|
261
|
+
const newAppCfg = await readAppCfgFile({ projectId: project });
|
|
262
|
+
newAppCfg.models[model] = Number(version);
|
|
263
|
+
|
|
264
|
+
const message = {
|
|
265
|
+
version: 3,
|
|
266
|
+
timestamp: 0,
|
|
267
|
+
state: {
|
|
268
|
+
[project]: {
|
|
269
|
+
appConfig: JSON.stringify(newAppCfg)
|
|
270
|
+
}
|
|
271
|
+
},
|
|
272
|
+
clientToken: 'not-self'
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
await deviceAgent.handleMessage(topic, message);
|
|
276
|
+
while (deviceAgent.getCmdStatus(project) === 'in_progress') {
|
|
277
|
+
await timer(1000);
|
|
278
|
+
}
|
|
279
|
+
deviceAgent.stop();
|
|
246
280
|
}
|
|
247
281
|
});
|
|
248
282
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CliLeaf } from '@alwaysai/alwayscli';
|
|
2
|
-
import
|
|
2
|
+
import { rimraf } from 'rimraf';
|
|
3
3
|
import { LOCAL_CERT_AND_KEY_DIR } from 'alwaysai/lib/constants';
|
|
4
4
|
import { logger } from '../../util/logger';
|
|
5
5
|
import { AgentConfigFile } from '../../infrastructure/agent-config';
|
|
@@ -12,15 +12,15 @@ export const cleanCliLeaf = CliLeaf({
|
|
|
12
12
|
async action(_, opts) {
|
|
13
13
|
logger.info('Cleaning device configuration');
|
|
14
14
|
logger.debug(`Removing ${LOCAL_CERT_AND_KEY_DIR}`);
|
|
15
|
-
rimraf
|
|
15
|
+
await rimraf(LOCAL_CERT_AND_KEY_DIR);
|
|
16
16
|
logger.debug(`Removing ${AgentConfigFile().path}`);
|
|
17
17
|
AgentConfigFile().remove();
|
|
18
18
|
logger.debug(`Removing ${DeviceConfigFile().path}`);
|
|
19
19
|
DeviceConfigFile().remove();
|
|
20
20
|
logger.debug(`Removing ${CREDENTIALS_FILE_PATH}`);
|
|
21
|
-
rimraf
|
|
21
|
+
await rimraf(CREDENTIALS_FILE_PATH);
|
|
22
22
|
logger.debug(`Removing ${APP_ROOT}`);
|
|
23
|
-
rimraf
|
|
23
|
+
await rimraf(APP_ROOT);
|
|
24
24
|
logger.info('Device configuration cleaned');
|
|
25
25
|
}
|
|
26
26
|
});
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { CliLeaf, CliStringInput } from '@alwaysai/alwayscli';
|
|
2
|
-
import { checkUserIsLoggedInComponent } from 'alwaysai/lib/components/user';
|
|
3
2
|
import { getTargetHardwareUuid } from 'alwaysai/lib/core/app';
|
|
4
|
-
import { checkPaidPlan } from 'alwaysai/lib/core/project';
|
|
5
3
|
import { v4 as uuidv4 } from 'uuid';
|
|
6
4
|
import { CliAuthenticationClient } from 'alwaysai/lib/infrastructure';
|
|
7
5
|
import { existsSync } from 'fs';
|
|
@@ -22,6 +20,7 @@ import {
|
|
|
22
20
|
import { writeTokenAndDeviceCfg } from '../../infrastructure/tokens-and-device-cfg';
|
|
23
21
|
import { logger } from '../../util/logger';
|
|
24
22
|
import { DeviceConfigFile } from 'alwaysai/lib/core/device';
|
|
23
|
+
import { requireLoggedInAndPaidPlan } from '../../util/require-logged-in-and-paid-plan';
|
|
25
24
|
|
|
26
25
|
export const initCliLeaf = CliLeaf({
|
|
27
26
|
name: 'init',
|
|
@@ -29,7 +28,7 @@ export const initCliLeaf = CliLeaf({
|
|
|
29
28
|
namedInputs: {
|
|
30
29
|
name: CliStringInput({
|
|
31
30
|
description: 'Device name',
|
|
32
|
-
required:
|
|
31
|
+
required: false
|
|
33
32
|
}),
|
|
34
33
|
description: CliStringInput({
|
|
35
34
|
description: 'Device description',
|
|
@@ -37,19 +36,16 @@ export const initCliLeaf = CliLeaf({
|
|
|
37
36
|
})
|
|
38
37
|
},
|
|
39
38
|
async action(_, opts) {
|
|
40
|
-
|
|
39
|
+
let { name } = opts;
|
|
40
|
+
name = name || uuidv4();
|
|
41
|
+
|
|
41
42
|
if (DeviceConfigFile().exists() || existsSync(getPrivateKeyFilePath())) {
|
|
42
43
|
throw new Error(
|
|
43
44
|
"Device has been previously provisioned. Run 'aai-agent device clean' to re-provision"
|
|
44
45
|
);
|
|
45
46
|
}
|
|
46
47
|
logger.info(`Initializing device ${name}`);
|
|
47
|
-
await
|
|
48
|
-
if (!(await checkPaidPlan())) {
|
|
49
|
-
throw new Error(
|
|
50
|
-
`This action only supported for Enterprise alwaysAI accounts!`
|
|
51
|
-
);
|
|
52
|
-
}
|
|
48
|
+
await requireLoggedInAndPaidPlan();
|
|
53
49
|
const { username } = await CliAuthenticationClient().getInfo();
|
|
54
50
|
const hardwareId = await getTargetHardwareUuid(JsSpawner());
|
|
55
51
|
const device = {
|
|
@@ -60,6 +56,7 @@ export const initCliLeaf = CliLeaf({
|
|
|
60
56
|
friendlyName: name
|
|
61
57
|
};
|
|
62
58
|
|
|
59
|
+
// FIXME: Use JSON schema to validate input
|
|
63
60
|
const response: { deviceUuid: string; claimCertificate: string[] } =
|
|
64
61
|
await microServiceHttpClient(
|
|
65
62
|
'fleet-provision',
|
|
@@ -69,7 +66,7 @@ export const initCliLeaf = CliLeaf({
|
|
|
69
66
|
);
|
|
70
67
|
logger.debug(`addDevice Response: ${JSON.stringify(response, null, 2)}`);
|
|
71
68
|
|
|
72
|
-
if (!
|
|
69
|
+
if (!('claimCertificate' in response)) {
|
|
73
70
|
throw new Error(
|
|
74
71
|
"Device cannot be provisioned. Run 'aai-agent device clean' and retry."
|
|
75
72
|
);
|
package/src/subcommands/login.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { CliLeaf, CliStringInput } from '@alwaysai/alwayscli';
|
|
2
2
|
import { alwaysaiUserLoginYesComponent } from 'alwaysai/lib/components/user';
|
|
3
|
-
import { writeTokenAndDeviceCfg } from '../infrastructure/tokens-and-device-cfg';
|
|
4
3
|
|
|
5
4
|
export const loginCliLeaf = CliLeaf({
|
|
6
5
|
name: 'login',
|
|
@@ -13,21 +12,14 @@ export const loginCliLeaf = CliLeaf({
|
|
|
13
12
|
password: CliStringInput({
|
|
14
13
|
description: 'Account password',
|
|
15
14
|
required: true
|
|
16
|
-
}),
|
|
17
|
-
device: CliStringInput({
|
|
18
|
-
description: 'The device UUID',
|
|
19
|
-
required: false
|
|
20
15
|
})
|
|
21
16
|
},
|
|
22
17
|
async action(_, opts) {
|
|
23
|
-
const { email, password
|
|
18
|
+
const { email, password } = opts;
|
|
24
19
|
|
|
25
20
|
await alwaysaiUserLoginYesComponent({
|
|
26
21
|
alwaysaiUserEmail: email,
|
|
27
22
|
alwaysaiUserPassword: password
|
|
28
23
|
});
|
|
29
|
-
if (device) {
|
|
30
|
-
await writeTokenAndDeviceCfg({ deviceUuid: device });
|
|
31
|
-
}
|
|
32
24
|
}
|
|
33
25
|
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import nodeFetch from 'node-fetch';
|
|
2
|
+
|
|
3
|
+
export async function fetchWithTimeout(
|
|
4
|
+
url: string,
|
|
5
|
+
options: { timeout?: number } = {}
|
|
6
|
+
) {
|
|
7
|
+
//time (ms)
|
|
8
|
+
const { timeout = 60000 } = options;
|
|
9
|
+
|
|
10
|
+
const controller = new AbortController();
|
|
11
|
+
const id = setTimeout(() => controller.abort(), timeout);
|
|
12
|
+
const response = await nodeFetch(url, {
|
|
13
|
+
...options,
|
|
14
|
+
signal: controller.signal
|
|
15
|
+
});
|
|
16
|
+
clearTimeout(id);
|
|
17
|
+
return response;
|
|
18
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { checkPaidPlan } from 'alwaysai/lib/core/project';
|
|
2
|
+
import { CliAuthenticationClient } from 'alwaysai/lib/infrastructure';
|
|
3
|
+
|
|
4
|
+
export async function requireLoggedInAndPaidPlan() {
|
|
5
|
+
// FIXME: Remove this requirement
|
|
6
|
+
if (!CliAuthenticationClient().isSignedIn()) {
|
|
7
|
+
throw new Error('You must be logged in to run this command!');
|
|
8
|
+
}
|
|
9
|
+
// FIXME: This also requires Cognito and should be replaced by a check in
|
|
10
|
+
// microServiceHttpClient()
|
|
11
|
+
if (!(await checkPaidPlan())) {
|
|
12
|
+
throw new Error(
|
|
13
|
+
`This action only supported for Enterprise alwaysAI accounts!`
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const timer = (ms: number) => new Promise((res) => setTimeout(res, ms));
|