├── .circleci └── config.yml ├── .eslintrc ├── .gitignore ├── .npmignore ├── .prettierrc ├── .vscode ├── extensions.json └── settings.json ├── CHANGELOG.md ├── LICENSE ├── README.md ├── docs ├── assets │ ├── css │ │ └── main.css │ ├── images │ │ ├── icons.png │ │ ├── icons@2x.png │ │ ├── widgets.png │ │ └── widgets@2x.png │ └── js │ │ ├── main.js │ │ └── search.json ├── classes │ ├── _hostedmodel_.hostedmodel.html │ ├── _httperrors_.invalidargumenterror.html │ ├── _httperrors_.invlaidurlerror.html │ ├── _httperrors_.modelerror.html │ ├── _httperrors_.networkerror.html │ ├── _httperrors_.notfounderror.html │ ├── _httperrors_.permissiondeniederror.html │ └── _httperrors_.unexpectederror.html ├── globals.html ├── index.html ├── interfaces │ └── _hostedmodel_.hostedmodelconfig.html └── modules │ ├── _hostedmodel_.html │ └── _httperrors_.html ├── examples ├── browser.html ├── node.js └── ts-node.ts ├── package-lock.json ├── package.json ├── secrets.txt ├── src ├── HTTPErrors.ts ├── HostedModel.ts ├── index.ts └── utils.ts └── tsconfig.json /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2.1 2 | jobs: 3 | publish: 4 | docker: 5 | - image: circleci/node:12 6 | steps: 7 | - checkout 8 | - run: sudo apt-get install jq 9 | - restore_cache: 10 | key: dependency-cache-{{ checksum "package-lock.json" }} 11 | - run: npm install 12 | - run: 13 | name: Download awssecret2env 14 | command: | 15 | wget https://awssecret2env.s3.amazonaws.com/latest/awssecret2env-linux64 16 | chmod +x awssecret2env-linux64 && mv awssecret2env-linux64 awssecret2env 17 | - run: 18 | name: Add .env 19 | command: ./awssecret2env --export --output .env secrets.txt 20 | - run: 21 | name: Publish If New Version 22 | command: | 23 | NPM_VERSION=$(npm view @runwayml/hosted-models versions --json | jq -r '.[-1]') 24 | LOCAL_VERSION=$(jq -r .version package.json) 25 | if [[ "$NPM_VERSION" != "$LOCAL_VERSION" ]]; then 26 | source .env 27 | echo "Local version $LOCAL_VERSION doesn't match npm version $NPM_VERSION" 28 | echo "Publishing a new release!" 29 | echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > .npmrc 30 | npm publish --access public 31 | else 32 | echo "Local version $LOCAL_VERSION matches npm version $NPM_VERSION" 33 | echo "Not publishing a new release." 34 | fi 35 | - save_cache: 36 | paths: 37 | - node_modules 38 | key: dependency-cache-{{ checksum "package-lock.json" }} 39 | workflows: 40 | version: 2 41 | publish: 42 | jobs: 43 | - publish: 44 | filters: 45 | branches: 46 | only: master 47 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "ignorePatterns": ["node_modules/"], 3 | "parserOptions": { 4 | "sourceType": "module" 5 | }, 6 | "env": { 7 | "node": true, 8 | "es6": true 9 | }, 10 | "extends": [ 11 | "eslint:recommended", 12 | "plugin:@typescript-eslint/eslint-recommended", 13 | "plugin:@typescript-eslint/recommended", 14 | // Uses eslint-config-prettier to disable ESLint rules from @typescript-eslint/eslint-plugin that would conflict with prettier. 15 | "prettier/@typescript-eslint", 16 | // Enables eslint-plugin-prettier and eslint-config-prettier. 17 | // This will display prettier errors as ESLint errors. 18 | // Make sure this is always the last configuration in the extends array. 19 | "plugin:prettier/recommended" 20 | ], 21 | "plugins": ["@typescript-eslint", "prettier", "simple-import-sort"], 22 | "rules": { 23 | "simple-import-sort/sort": "error", 24 | "no-empty": "off", 25 | "no-case-declarations": "off", 26 | "no-prototype-builtins": "off", 27 | "no-constant-condition": "off", 28 | "@typescript-eslint/explicit-function-return-type": "off", 29 | "@typescript-eslint/ban-ts-ignore": "off", 30 | "@typescript-eslint/no-explicit-any": "off", 31 | "@typescript-eslint/camelcase": "off", 32 | "@typescript-eslint/no-use-before-define": "off", 33 | "@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "_" }] 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | build/ 4 | dist/ 5 | .eslintcache 6 | .cache/ 7 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .vscode/ 2 | .cache/ 3 | .eslintcache 4 | secrets.txt 5 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "es5", 3 | "singleQuote": true, 4 | "semi": true, 5 | "endOfLine": "lf", 6 | "arrowParens": "avoid" 7 | } 8 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["esbenp.prettier-vscode"] 3 | } 4 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.defaultFormatter": "esbenp.prettier-vscode", 3 | "[javascript]": { 4 | "editor.defaultFormatter": "esbenp.prettier-vscode" 5 | }, 6 | "[typescript]": { 7 | "editor.defaultFormatter": "esbenp.prettier-vscode" 8 | }, 9 | "editor.formatOnSave": true, 10 | "eslint.format.enable": true, 11 | "editor.codeActionsOnSave": { 12 | "source.fixAll.eslint": true 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## v0.3.0 4 | 5 | - Add usage section in README. 6 | - More descriptive error message for `NotFoundError`. 7 | - Wake up model during `HostedModel` construction. 8 | - Add optional `pollIntervalMillis` parameter to `HostedModel.waitUntilAwake()` method. 9 | 10 | ## v0.2.0 11 | 12 | - Add CI/CD releases via CircleCI 13 | - Fix infinite loop with `npm run build`. 14 | - Add inline documentation with TypeDoc, generated in `docs/`. 15 | - Add `InvalidArgumentError` type and throw it when invalid arguments are passed to public methods. 16 | 17 | ## v0.1.0 18 | 19 | Initial release. 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Runway 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Hosted Models JavaScript SDK 2 | 3 | [![Runway Hosted Models JavaScript SDK Image](https://runway-static-assets.s3.amazonaws.com/github/hosted-models-js-sdk.jpg)](https://runwayml.com) 4 | 5 | A small library for interfacing with RunwayML [Hosted Models](https://learn.runwayml.com/#/how-to/hosted-models) using only a few lines of code. Works in both Node.js and the Browser. 6 | 7 | ## Benefits 8 | 9 | This library is a thin wrapper around the Hosted Models [HTTP API](https://learn.runwayml.com/#/how-to/hosted-models?id=http-api). It provides a few benefits: 10 | 11 | - Abstracts the HTTP requests to the Hosted Model, so you don't have to make them directly. 12 | - Simplifies authorization for private models, just provide your `token` in the `new HostedModels({ url, token })` constructor. 13 | - Automatically retries failed requests if they timed out while the model wakes up or are blocked due to rate-limiting. 14 | - Includes friendly error reporting with messages for humans, so you can better understand why something went wrong. 15 | 16 | If your project is written in JavaScript, we encourage you to use this library! 17 | 18 | ## Examples 19 | 20 | See the [`examples/`](examples) directory for a full list of examples. 21 | 22 | ### Node.js / Module Syntax 23 | 24 | If you are using Node.js or packaging your front-end code via a bundler, you can install the module using `npm`. 25 | 26 | ```bash 27 | npm install --save @runwayml/hosted-models 28 | ``` 29 | 30 | ```javascript 31 | const { HostedModel } = require('@runwayml/hosted-models'); 32 | 33 | const model = new HostedModel({ 34 | url: 'https://my-model.hosted-models.runwayml.cloud/v1', 35 | token: 'my-private-hosted-model-token', 36 | }); 37 | 38 | const prompt = 'Hey text generation model, finish my sentence'; 39 | model.query({ prompt }).then(result => console.log(result)); 40 | ``` 41 | 42 | ### Browser 43 | 44 | If you prefer to access the library in the Browser using a ` 48 | ``` 49 | 50 | This injects the library into the window and exposes it via the `rw` namespace. 51 | 52 | ```javascript 53 | const model = new rw.HostedModel({ 54 | url: 'https://my-model.hosted-models.runwayml.cloud/v1', 55 | token: 'my-private-hosted-model-token', 56 | }); 57 | 58 | const prompt = 'Hey text generation model, finish my sentence'; 59 | model.query({ prompt }).then(result => console.log(result)); 60 | ``` 61 | 62 | ## Usage 63 | 64 | This library is super simple to use; It exposes a single `HostedModels` class with only four methods: 65 | 66 | - [`HostedModel`](#hostedmodels-constructor) 67 | - [`.info()`](#info-method) 68 | - [`.query()`](#query-method) 69 | - [`.isAwake()`](#isAwake-method) 70 | - [`.waitUntilAwake()`](#waitUntilAwake-method) 71 | 72 | > Note: Be sure to use `rw.HostedModel()` if you are including the library via a ` 533 | 534 | 535 | -------------------------------------------------------------------------------- /docs/classes/_httperrors_.invalidargumenterror.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | InvalidArgumentError | @runwayml/hosted-models 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 65 |

Class InvalidArgumentError

66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |

Thrown when arguments to function or constructors are invalid.

76 |
77 |
78 |
79 |
80 |

Hierarchy

81 |
    82 |
  • 83 | Error 84 |
      85 |
    • 86 | InvalidArgumentError 87 |
    • 88 |
    89 |
  • 90 |
91 |
92 |
93 |

Index

94 |
95 |
96 |
97 |

Constructors

98 | 101 |
102 |
103 |

Properties

104 | 110 |
111 |
112 |
113 |
114 |
115 |

Constructors

116 |
117 | 118 |

constructor

119 | 122 | 138 |
139 |
140 |
141 |

Properties

142 |
143 | 144 |

message

145 |
message: string
146 | 152 |
153 |
154 | 155 |

name

156 |
name: string
157 | 163 |
164 |
165 | 166 |

Optional stack

167 |
stack: string
168 | 174 |
175 |
176 | 177 |

Static Error

178 |
Error: ErrorConstructor
179 | 184 |
185 |
186 |
187 | 248 |
249 |
250 | 270 |
271 |

Generated using TypeDoc

272 |
273 |
274 | 275 | 276 | 277 | -------------------------------------------------------------------------------- /docs/classes/_httperrors_.invlaidurlerror.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | InvlaidURLError | @runwayml/hosted-models 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 65 |

Class InvlaidURLError

66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |

Thrown by HostedModel if the url provided during construction is in an invalid 76 | format.

77 |
78 |
79 |
80 |
81 |

Hierarchy

82 |
    83 |
  • 84 | Error 85 |
      86 |
    • 87 | InvlaidURLError 88 |
    • 89 |
    90 |
  • 91 |
92 |
93 |
94 |

Index

95 |
96 |
97 |
98 |

Constructors

99 | 102 |
103 |
104 |

Properties

105 | 111 |
112 |
113 |
114 |
115 |
116 |

Constructors

117 |
118 | 119 |

constructor

120 | 123 | 133 |
134 |
135 |
136 |

Properties

137 |
138 | 139 |

message

140 |
message: string
141 | 147 |
148 |
149 | 150 |

name

151 |
name: string
152 | 158 |
159 |
160 | 161 |

Optional stack

162 |
stack: string
163 | 169 |
170 |
171 | 172 |

Static Error

173 |
Error: ErrorConstructor
174 | 179 |
180 |
181 |
182 | 243 |
244 |
245 | 265 |
266 |

Generated using TypeDoc

267 |
268 |
269 | 270 | 271 | 272 | -------------------------------------------------------------------------------- /docs/classes/_httperrors_.modelerror.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | ModelError | @runwayml/hosted-models 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 65 |

Class ModelError

66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |

Thrown by HostedModel.query if the underlying hosted model experienced an error, 76 | likely due to malformed input.

77 |
78 |
79 |
80 |
81 |

Hierarchy

82 |
    83 |
  • 84 | Error 85 |
      86 |
    • 87 | ModelError 88 |
    • 89 |
    90 |
  • 91 |
92 |
93 |
94 |

Index

95 |
96 |
97 |
98 |

Constructors

99 | 102 |
103 |
104 |

Properties

105 | 111 |
112 |
113 |
114 |
115 |
116 |

Constructors

117 |
118 | 119 |

constructor

120 | 123 | 133 |
134 |
135 |
136 |

Properties

137 |
138 | 139 |

message

140 |
message: string
141 | 147 |
148 |
149 | 150 |

name

151 |
name: string
152 | 158 |
159 |
160 | 161 |

Optional stack

162 |
stack: string
163 | 169 |
170 |
171 | 172 |

Static Error

173 |
Error: ErrorConstructor
174 | 179 |
180 |
181 |
182 | 243 |
244 |
245 | 265 |
266 |

Generated using TypeDoc

267 |
268 |
269 | 270 | 271 | 272 | -------------------------------------------------------------------------------- /docs/classes/_httperrors_.networkerror.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | NetworkError | @runwayml/hosted-models 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 65 |

Class NetworkError

66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |

Thrown by HostedModel's methods if an underlying network error occurred while 76 | making an HTTP request. This likely indicates an error related to your internet 77 | connection or configuration.

78 |
79 |
80 |
81 |
82 |

Hierarchy

83 |
    84 |
  • 85 | Error 86 |
      87 |
    • 88 | NetworkError 89 |
    • 90 |
    91 |
  • 92 |
93 |
94 |
95 |

Index

96 |
97 |
98 |
99 |

Constructors

100 | 103 |
104 |
105 |

Properties

106 | 112 |
113 |
114 |
115 |
116 |
117 |

Constructors

118 |
119 | 120 |

constructor

121 | 124 |
    125 |
  • 126 | 131 |

    Parameters

    132 |
      133 |
    • 134 |
      code: string
      135 |
    • 136 |
    137 |

    Returns NetworkError

    138 |
  • 139 |
140 |
141 |
142 |
143 |

Properties

144 |
145 | 146 |

message

147 |
message: string
148 | 154 |
155 |
156 | 157 |

name

158 |
name: string
159 | 165 |
166 |
167 | 168 |

Optional stack

169 |
stack: string
170 | 176 |
177 |
178 | 179 |

Static Error

180 |
Error: ErrorConstructor
181 | 186 |
187 |
188 |
189 | 250 |
251 |
252 | 272 |
273 |

Generated using TypeDoc

274 |
275 |
276 | 277 | 278 | 279 | -------------------------------------------------------------------------------- /docs/classes/_httperrors_.notfounderror.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | NotFoundError | @runwayml/hosted-models 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 65 |

Class NotFoundError

66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |

Thrown by HostedModel methods if the url doesn't match a model, or if that model is 76 | not currently "active".

77 |
78 |
79 |
80 |
81 |

Hierarchy

82 |
    83 |
  • 84 | Error 85 |
      86 |
    • 87 | NotFoundError 88 |
    • 89 |
    90 |
  • 91 |
92 |
93 |
94 |

Index

95 |
96 |
97 |
98 |

Constructors

99 | 102 |
103 |
104 |

Properties

105 | 111 |
112 |
113 |
114 |
115 |
116 |

Constructors

117 |
118 | 119 |

constructor

120 | 123 | 133 |
134 |
135 |
136 |

Properties

137 |
138 | 139 |

message

140 |
message: string
141 | 147 |
148 |
149 | 150 |

name

151 |
name: string
152 | 158 |
159 |
160 | 161 |

Optional stack

162 |
stack: string
163 | 169 |
170 |
171 | 172 |

Static Error

173 |
Error: ErrorConstructor
174 | 179 |
180 |
181 |
182 | 243 |
244 |
245 | 265 |
266 |

Generated using TypeDoc

267 |
268 |
269 | 270 | 271 | 272 | -------------------------------------------------------------------------------- /docs/classes/_httperrors_.permissiondeniederror.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | PermissionDeniedError | @runwayml/hosted-models 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 65 |

Class PermissionDeniedError

66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |

Thrown by HostedModel methods if it is a private model and no token was provided 76 | during construction, or if the token is invalid.

77 |
78 |
79 |
80 |
81 |

Hierarchy

82 |
    83 |
  • 84 | Error 85 |
      86 |
    • 87 | PermissionDeniedError 88 |
    • 89 |
    90 |
  • 91 |
92 |
93 |
94 |

Index

95 |
96 |
97 |
98 |

Constructors

99 | 102 |
103 |
104 |

Properties

105 | 111 |
112 |
113 |
114 |
115 |
116 |

Constructors

117 |
118 | 119 |

constructor

120 | 123 | 133 |
134 |
135 |
136 |

Properties

137 |
138 | 139 |

message

140 |
message: string
141 | 147 |
148 |
149 | 150 |

name

151 |
name: string
152 | 158 |
159 |
160 | 161 |

Optional stack

162 |
stack: string
163 | 169 |
170 |
171 | 172 |

Static Error

173 |
Error: ErrorConstructor
174 | 179 |
180 |
181 |
182 | 243 |
244 |
245 | 265 |
266 |

Generated using TypeDoc

267 |
268 |
269 | 270 | 271 | 272 | -------------------------------------------------------------------------------- /docs/classes/_httperrors_.unexpectederror.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | UnexpectedError | @runwayml/hosted-models 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 65 |

Class UnexpectedError

66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |

Thrown whenever an unexpected error occurs. If you experience this error, try again 76 | later or contact support.

77 |
78 |
79 |
80 |
81 |

Hierarchy

82 |
    83 |
  • 84 | Error 85 |
      86 |
    • 87 | UnexpectedError 88 |
    • 89 |
    90 |
  • 91 |
92 |
93 |
94 |

Index

95 |
96 |
97 |
98 |

Constructors

99 | 102 |
103 |
104 |

Properties

105 | 111 |
112 |
113 |
114 |
115 |
116 |

Constructors

117 |
118 | 119 |

constructor

120 | 123 | 133 |
134 |
135 |
136 |

Properties

137 |
138 | 139 |

message

140 |
message: string
141 | 147 |
148 |
149 | 150 |

name

151 |
name: string
152 | 158 |
159 |
160 | 161 |

Optional stack

162 |
stack: string
163 | 169 |
170 |
171 | 172 |

Static Error

173 |
Error: ErrorConstructor
174 | 179 |
180 |
181 |
182 | 243 |
244 |
245 | 265 |
266 |

Generated using TypeDoc

267 |
268 |
269 | 270 | 271 | 272 | -------------------------------------------------------------------------------- /docs/globals.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | @runwayml/hosted-models 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 59 |

@runwayml/hosted-models

60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |

Index

68 |
69 |
70 |
71 |

Modules

72 | 76 |
77 |
78 |
79 |
80 |
81 | 100 |
101 |
102 | 115 |
116 |

Generated using TypeDoc

117 |
118 |
119 | 120 | 121 | 122 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | @runwayml/hosted-models 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 59 |

@runwayml/hosted-models

60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 | 68 |

Hosted Models JavaScript SDK

69 |
70 |

A small library for interfacing with RunwayML Hosted Models using only a few lines of code. Works in both Node.js and the Browser.

71 | 72 |

Benefits

73 |
74 |

This library is a thin wrapper around the Hosted Models HTTP API. It provides a few benefits:

75 |
    76 |
  • Abstracts the HTTP requests to the Hosted Model, so you don't have to make them directly.
  • 77 |
  • Simplifies authorization for private models, just provide your token in the new HostedModels({ url, token }) constructor.
  • 78 |
  • Automatically retries failed requests if they timed out while the model wakes up or are blocked due to rate-limiting.
  • 79 |
  • Includes friendly error reporting with messages for humans, so you can better understand why something went wrong.
  • 80 |
81 |

If your project is written in JavaScript, we encourage you to use this library!

82 | 83 |

Examples

84 |
85 |

See the examples/ directory for a full list of examples.

86 | 87 |

Node.js / Module Syntax

88 |
89 |

If you are using Node.js or packaging your front-end code via a bundler, you can install the module using npm.

90 |
npm install --save @runwayml/hosted-models
91 |
const { HostedModel } = require('@runwayml/hosted-models');
 92 | 
 93 | const model = new HostedModel({
 94 |   url: 'https://my-model.hosted-models.runwayml.cloud/v1',
 95 |   token: 'my-private-hosted-model-token',
 96 | });
 97 | 
 98 | const prompt = 'Hey text generation model, finish my sentence';
 99 | model.query({ prompt }).then(result => console.log(result));
100 | 101 |

Browser

102 |
103 |

If you prefer to access the library in the Browser using a <script> tag, you can include the code snippet below in your HTML files. Replace hosted-models.js with hosted-models.min.js if you prefer a minified build for production environments.

104 |
<script src="https://cdn.jsdelivr.net/npm/@runwayml/hosted-models@latest/dist/hosted-models.js"></script>
105 |

This injects the library into the window and exposes it via the rw namespace.

106 |
const model = new rw.HostedModel({
107 |   url: 'https://my-model.hosted-models.runwayml.cloud/v1',
108 |   token: 'my-private-hosted-model-token',
109 | });
110 | 
111 | const prompt = 'Hey text generation model, finish my sentence';
112 | model.query({ prompt }).then(result => console.log(result));
113 | 114 |

Usage

115 |
116 |

This library is super simple to use; It exposes a single HostedModels class with only four methods:

117 | 126 |
127 |

Note: Be sure to use rw.HostedModel() if you are including the library via a <script> in the Browser.

128 |
129 | 130 |

HostedModels Constructor

131 |
132 |

The HostedModel constructor takes a configuration object with two properties, url and token (required only if the model is private).

133 |
const model = new HostedModel({
134 |   url: 'https://example-text-generator.hosted-models.runwayml.cloud/v1',
135 |   token: 'my-private-hosted-model-token', // not required for public models
136 | });
137 | 138 |

.info() Method

139 |
140 |

This method returns the input/output spec expected by this model's query() method.

141 |
const info = await model.info();
142 | console.log(info);
143 | //// Note: These values will be different for each model
144 | // {
145 | //   "description": "Generate text conditioned on prompt",
146 | //   "name": "generate_batch",
147 | //   "inputs": [
148 | //     {
149 | //       "default": "",
150 | //       "description": null,
151 | //       "minLength": 0,
152 | //       "name": "prompt",
153 | //       "type": "text"
154 | //     },
155 | //     ...
156 | //   ],
157 | //   "outputs": [
158 | //     {
159 | //       "default": "",
160 | //       "description": null,
161 | //       "minLength": 0,
162 | //       "name": "generated_text",
163 | //       "type": "text"
164 | //     },
165 | //     ...
166 | //   ]
167 | // }
168 | 169 |

.query() Method

170 |
171 |

query() is used to trigger the model to process input, and return output.

172 |
const result = await model.query({
173 |   prompt: 'Hey text generation model, finish my sentence',
174 | });
175 | console.log(result);
176 | //// Note: These values will be different for each model
177 | // {
178 | //   generated_text: 'Hey text generation model, finish my sentence please.',
179 | //   encountered_end: true
180 | // }
181 | 182 |

.isAwake() Method

183 |
184 |

The isAwake() method returns true if the model is already awake and processing requests quickly, or false if it is still waking up. A model that is waking up can still process all requests (e.g. info() and query()), they just might take a bit longer to respond. Learn more about Hosted Model states here.

185 |
if (!model.isAwake()) {
186 |   showLoadingScreen(); // this is a fake function for demonstration
187 | }
188 | 
189 | // A model doesn't have to be awake for you to make requests to it
190 | await model.query(input);
191 |
192 |

Note: A model that is waking up can still process all requests (e.g. info() and query()), they just might take a bit longer to respond. Learn more about Hosted Model states here.

193 |
194 | 195 |

.waitUntilAwake() Method

196 |
197 |

The .waitUntilAwake() method returns a promise that will resolve as soon as the model is awake. This is useful if you'd prefer to wait to perform some action until after the model can be expected to process them quickly.

198 |
setLoading(true); // this is a fake function for demonstration
199 | await model.waitUntilAwake();
200 | setLoading(false);
201 | 
202 | setProcessing(true); // this is also a fake function for demonstration
203 | await model.query(input);
204 | setProcessing(false);
205 |
206 |

Note: A model that is waking up can still process all requests (e.g. info() and query()), they just might take a bit longer to respond. Learn more about Hosted Model states here.

207 |
208 | 209 |

License

210 |
211 |

This library is released under the terms of the MIT license.

212 | 213 |

CHANGELOG

214 |
215 |

You can view a list of changes here.

216 |
217 |
218 | 237 |
238 |
239 | 252 |
253 |

Generated using TypeDoc

254 |
255 |
256 | 257 | 258 | 259 | -------------------------------------------------------------------------------- /docs/interfaces/_hostedmodel_.hostedmodelconfig.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | HostedModelConfig | @runwayml/hosted-models 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 65 |

Interface HostedModelConfig

66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |

The config object used to construct a new HostedModel.

76 |
77 |
// For private models...
 78 | {
 79 |   url: 'https://my-model.hosted-models.runwayml.cloud/v1',
 80 |   token: 'kN5PB/GGgL5IcXxViegzUA==', // this is a fake token, use your own
 81 | }
 82 | 
 83 | // For public models...
 84 | {
 85 |   url: 'https://my-model.hosted-models.runwayml.cloud/v1',
 86 | }
87 |
88 |
89 |
90 |

Hierarchy

91 |
    92 |
  • 93 | HostedModelConfig 94 |
  • 95 |
96 |
97 |
98 |

Index

99 |
100 |
101 |
102 |

Properties

103 | 107 |
108 |
109 |
110 |
111 |
112 |

Properties

113 |
114 | 115 |

Optional token

116 |
token: string
117 | 122 |
123 |
124 |

The secret token associated with this model. Only required if this model is private.

125 |
126 |
127 |
128 |
129 | 130 |

url

131 |
url: string
132 | 137 |
138 |
139 |

The full URL of your hosted model in the format https://my-model.hosted-models.runwayml.cloud/v1

140 |
141 |
142 |
143 |
144 |
145 | 182 |
183 |
184 | 198 |
199 |

Generated using TypeDoc

200 |
201 |
202 | 203 | 204 | 205 | -------------------------------------------------------------------------------- /docs/modules/_hostedmodel_.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | "HostedModel" | @runwayml/hosted-models 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 62 |

Module "HostedModel"

63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |

Index

71 |
72 |
73 |
74 |

Classes

75 | 78 |
79 |
80 |

Interfaces

81 | 84 |
85 |
86 |
87 |
88 |
89 | 114 |
115 |
116 | 129 |
130 |

Generated using TypeDoc

131 |
132 |
133 | 134 | 135 | 136 | -------------------------------------------------------------------------------- /docs/modules/_httperrors_.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | "HTTPErrors" | @runwayml/hosted-models 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 62 |

Module "HTTPErrors"

63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |

A collection of Error objects which can be thrown by HostedModel's methods.

73 |
74 |
75 |
76 |
77 |

Index

78 |
79 |
80 |
81 |

Classes

82 | 91 |
92 |
93 |
94 |
95 |
96 | 136 |
137 |
138 | 151 |
152 |

Generated using TypeDoc

153 |
154 |
155 | 156 | 157 | 158 | -------------------------------------------------------------------------------- /examples/browser.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Basic Example 5 | 6 | 7 |

Open the developer's console

8 | 9 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /examples/node.js: -------------------------------------------------------------------------------- 1 | const { HostedModel } = require('@runwayml/hosted-models'); 2 | 3 | async function main() { 4 | const model = new HostedModel({ 5 | url: 'https://my-model.hosted-models.runwayml.cloud/v1', 6 | token: 'my-private-hosted-model-token', 7 | }); 8 | const result = await model.query({ 9 | prompt: 'Hey text generation model, finish my sentence', 10 | }); 11 | console.log(result.generated_text); 12 | } 13 | 14 | main().catch(err => console.error(err)); 15 | -------------------------------------------------------------------------------- /examples/ts-node.ts: -------------------------------------------------------------------------------- 1 | import { HostedModel } from '../src/HostedModel'; 2 | 3 | async function main() { 4 | const model = new HostedModel({ 5 | url: 'https://lotr.hosted-models.runwayml.cloud/v1/', 6 | }); 7 | const result = await model.query({ 8 | prompt: 'The one ring to', 9 | max_characters: 180, 10 | }); 11 | console.log(result.generated_text); 12 | } 13 | 14 | main().catch(err => console.error(err)); 15 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@runwayml/hosted-models", 3 | "version": "0.3.0", 4 | "description": "Interact with Runway Hosted Models with only a few lines of code!", 5 | "main": "build/index.js", 6 | "scripts": { 7 | "prepublishOnly": "npm run build", 8 | "build": "concurrently \"npm run compile && npm run bundle && npm run minify\" \"npm run docs\"", 9 | "docs": "typedoc --stripInternal --out docs src", 10 | "compile": "tsc", 11 | "bundle": "browserify build/index.js --standalone rw -o dist/hosted-models.js", 12 | "minify": "terser --compress --output dist/hosted-models.min.js -- dist/hosted-models.js", 13 | "lint": "eslint . --cache --ext=.ts --fix", 14 | "prettier": "pretty-quick --staged --pattern \"**/*.+(js|jsx|ts|tsx)\"", 15 | "test": "echo \"Error: no test specified\" && exit 1" 16 | }, 17 | "repository": { 18 | "type": "git", 19 | "url": "git+https://github.com/runwayml/hosted-models.git" 20 | }, 21 | "author": "Runway AI, Inc", 22 | "license": "MIT", 23 | "bugs": { 24 | "url": "https://github.com/runwayml/hosted-models/issues" 25 | }, 26 | "keywords": [ 27 | "runway", 28 | "runwayml", 29 | "hosted models", 30 | "machine learning", 31 | "artificial intelligence" 32 | ], 33 | "homepage": "https://github.com/runwayml/hosted-models#readme", 34 | "devDependencies": { 35 | "@types/node": "^13.13.4", 36 | "@typescript-eslint/eslint-plugin": "^2.24.0", 37 | "@typescript-eslint/parser": "^2.24.0", 38 | "browserify": "^16.5.1", 39 | "concurrently": "^5.2.0", 40 | "eslint": "^6.8.0", 41 | "eslint-config-prettier": "^6.10.0", 42 | "eslint-plugin-prettier": "^3.1.2", 43 | "eslint-plugin-simple-import-sort": "^5.0.2", 44 | "husky": "^4.2.3", 45 | "prettier": "^1.19.1", 46 | "pretty-quick": "^2.0.1", 47 | "terser": "^4.6.12", 48 | "ts-node": "^8.7.0", 49 | "typedoc": "^0.17.6", 50 | "typescript": "^3.8.3" 51 | }, 52 | "dependencies": { 53 | "axios": "^0.19.2" 54 | }, 55 | "husky": { 56 | "hooks": { 57 | "pre-commit": "concurrently \"npm run prettier\" \"npm run build\" \"npm run lint\"" 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /secrets.txt: -------------------------------------------------------------------------------- 1 | NPM_TOKEN=npm/runway-admin/AUTH_TOKEN 2 | -------------------------------------------------------------------------------- /src/HTTPErrors.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * A collection of Error objects which can be thrown by [[HostedModel]]'s methods. 3 | */ 4 | 5 | /** 6 | * Thrown by [[HostedModel]] methods if it is a private model and no token was provided 7 | * during construction, or if the token is invalid. 8 | */ 9 | export class PermissionDeniedError extends Error { 10 | constructor() { 11 | super( 12 | `Permission denied, this model is private. Did you include the correct token?` 13 | ); 14 | } 15 | } 16 | 17 | /** 18 | * Thrown by [[HostedModel]] methods if the url doesn't match a model, or if that model is 19 | * not currently "active". 20 | */ 21 | export class NotFoundError extends Error { 22 | constructor() { 23 | super( 24 | `Model not found. Make sure the url is correct and that the model is "active".` 25 | ); 26 | } 27 | } 28 | 29 | /** 30 | * Thrown by [[HostedModel.query]] if the underlying hosted model experienced an error, 31 | * likely due to malformed input. 32 | */ 33 | export class ModelError extends Error { 34 | constructor() { 35 | super( 36 | `The model experienced an error while processing your input. ` + 37 | `Double-check that you are sending properly formed input parameters in HostedModel.query(). ` + 38 | `You can use the HostedModel.info() method to check the input parameters the model expects. ` + 39 | `If the error persists, contact support (https://support.runwayml.com).` 40 | ); 41 | } 42 | } 43 | 44 | /** 45 | * Thrown by [[HostedModel]] if the url provided during construction is in an invalid 46 | * format. 47 | */ 48 | export class InvlaidURLError extends Error { 49 | constructor() { 50 | super( 51 | `The url you've provided is not valid. Your Hosted Model your must be in the format https://my-model.hosted-models.runwayml.cloud/v1.` 52 | ); 53 | } 54 | } 55 | 56 | /** 57 | * Thrown when arguments to function or constructors are invalid. 58 | */ 59 | export class InvalidArgumentError extends Error { 60 | constructor(argumentName: string) { 61 | super(`The required argument "${argumentName}" is invalid.`); 62 | } 63 | } 64 | 65 | /** 66 | * Thrown by [[HostedModel]]'s methods if an underlying network error occurred while 67 | * making an HTTP request. This likely indicates an error related to your internet 68 | * connection or configuration. 69 | */ 70 | export class NetworkError extends Error { 71 | constructor(code: string) { 72 | super( 73 | `A network error has ocurred${ 74 | code ? `: ${code}` : `` 75 | }. Please check your internet connection is working properly and try again.` 76 | ); 77 | } 78 | } 79 | 80 | /** 81 | * Thrown whenever an unexpected error occurs. If you experience this error, try again 82 | * later or [contact support](https://support.runwayml.com). 83 | */ 84 | export class UnexpectedError extends Error { 85 | constructor() { 86 | super( 87 | `An unexpected error has ocurred. Please try again later or contact support (https://support.runwayml.com).` 88 | ); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/HostedModel.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * A module for interfacing with Runway Hosted Models. 3 | */ 4 | import { AxiosRequestConfig, AxiosResponse } from 'axios'; 5 | 6 | import { 7 | InvalidArgumentError, 8 | InvlaidURLError, 9 | ModelError, 10 | NetworkError, 11 | NotFoundError, 12 | PermissionDeniedError, 13 | UnexpectedError, 14 | } from './HTTPErrors'; 15 | import { delay, requestWithRetry } from './utils'; 16 | 17 | /** 18 | * The config object used to construct a new [[HostedModel]]. 19 | * 20 | * ```typescript 21 | * // For private models... 22 | * { 23 | * url: 'https://my-model.hosted-models.runwayml.cloud/v1', 24 | * token: 'kN5PB/GGgL5IcXxViegzUA==', // this is a fake token, use your own 25 | * } 26 | * 27 | * // For public models... 28 | * { 29 | * url: 'https://my-model.hosted-models.runwayml.cloud/v1', 30 | * } 31 | * ``` 32 | */ 33 | export interface HostedModelConfig { 34 | /** 35 | * The full URL of your hosted model in the format `https://my-model.hosted-models.runwayml.cloud/v1` 36 | */ 37 | url: string; 38 | /** 39 | * The secret token associated with this model. Only required if this model is private. 40 | */ 41 | token?: string; 42 | } 43 | 44 | /** 45 | * A class representing a Runway Hosted Model. This is the main interface provided by 46 | * this package. Exposes two main methods for interfacing with a model. 47 | * 48 | * - `info()` 49 | * - `query(input)` 50 | * 51 | * Exposes two helper methods for checking the "awake" status of a hosted model. 52 | * 53 | * - `isAwake()` 54 | * - `waitUntilAwake()` 55 | */ 56 | export class HostedModel { 57 | private url: string; 58 | private token: string; 59 | private headers: { [name: string]: string }; 60 | private responseCodesToRetry: number[]; 61 | 62 | /** 63 | * ```typescript 64 | * const model = new HostedModel({ 65 | * url: 'https://my-model.hosted-models.runwayml.cloud/v1', 66 | * token: 'my-secret-token', # token is only required for private models 67 | * }) 68 | * ``` 69 | */ 70 | constructor(config: HostedModelConfig) { 71 | if (typeof config !== 'object') throw new InvalidArgumentError('config'); 72 | this.url = config.url; 73 | this.token = config.token || null; 74 | this.headers = { 75 | Accept: 'application/json', 76 | 'Content-Type': 'application/json', 77 | }; 78 | if (this.token) this.headers['Authorization'] = `Bearer ${this.token}`; 79 | this.responseCodesToRetry = [502, 429]; 80 | if (!this.isValidV1URL(this.url)) throw new InvlaidURLError(); 81 | // Wake up the model during construction because it will probably be used soon 82 | this.root() 83 | .then(result => result) 84 | .catch(err => err); 85 | } 86 | 87 | /** 88 | * Return info about the input/output spec provided by the model. Makes a GET request 89 | * to the /v1/info route of a hosted model under the hood. 90 | */ 91 | async info() { 92 | return this.requestHostedModel({ 93 | url: `${this.url}/info`, 94 | method: 'GET', 95 | headers: this.headers, 96 | }); 97 | } 98 | 99 | /** 100 | * Run the model on your input and produce an output. This is how you "run" the model. 101 | * @param input An object containing input parameters to be sent to the model. 102 | * Use the [[info]] method to get the correct format for this object, as each model 103 | * expects different inputs. 104 | */ 105 | async query(input: any) { 106 | if (typeof input !== 'object') throw new InvalidArgumentError('input'); 107 | return this.requestHostedModel({ 108 | url: `${this.url}/query`, 109 | method: 'POST', 110 | headers: this.headers, 111 | data: input, 112 | }); 113 | } 114 | 115 | /** 116 | * Returns `true` if this model is awake, `false` if it is still waking up. 117 | * See Awake, Awakening, and Awake in the 118 | * [Hosted Models docs](https://learn.runwayml.com/#/how-to/hosted-models?id=asleep-awakening-and-awake-states). 119 | */ 120 | async isAwake() { 121 | const root = await this.root(); 122 | return root.status === 'running'; 123 | } 124 | 125 | /** 126 | * Returns a promise that will resolve once the model is awake. This method is never 127 | * required, as [[info]] and [[query]] will always return results eventually, but it can be 128 | * useful for managing UI if you want to postpone making [[info]] and [[query]] requests 129 | * until you know that they will resolve more quickly. 130 | * 131 | * ```typescript 132 | * // This is pseudo code 133 | * const model = new HostedModel({ 134 | * url: 'https://my-model.hosted-models.runwayml.cloud/v1', 135 | * token: 'my-secret-token', # token is only required for private models 136 | * }) 137 | * // Enter some loading state in the UI. 138 | * loading(true) 139 | * await model.waitUntilAwake() // This method is never required, but can sometimes be useful 140 | * loading(false) 141 | * 142 | * while (true) { 143 | * const input = getSomeInput() 144 | * const output = await model.query(input) 145 | * doSomething(output) 146 | * } 147 | * ``` 148 | * 149 | * @param pollIntervalMillis [[waitUntilAwake]] The rate that this function will poll 150 | * the hosted model endpoint to check if it is awake yet. 151 | */ 152 | async waitUntilAwake(pollIntervalMillis = 1000): Promise { 153 | return new Promise((resolve, reject) => { 154 | (async () => { 155 | try { 156 | while (true) { 157 | const awake = await this.isAwake(); 158 | if (awake) { 159 | resolve(); 160 | return; 161 | } 162 | await delay(pollIntervalMillis); 163 | } 164 | } catch (err) { 165 | reject(err); 166 | } 167 | })(); 168 | }); 169 | } 170 | 171 | private async root() { 172 | return this.requestHostedModel({ 173 | url: `${this.url}/`, 174 | method: 'GET', 175 | headers: this.headers, 176 | }); 177 | } 178 | 179 | private async requestHostedModel(config: AxiosRequestConfig) { 180 | let result: AxiosResponse; 181 | try { 182 | result = await requestWithRetry(this.responseCodesToRetry, config); 183 | } catch (err) { 184 | throw new NetworkError(err.code); 185 | } 186 | if (this.isHostedModelResponseError(result)) { 187 | if (result.status === 401) throw new PermissionDeniedError(); 188 | else if (result.status === 404) throw new NotFoundError(); 189 | else if (result.status === 500) throw new ModelError(); 190 | throw new UnexpectedError(); 191 | } 192 | return result.data; 193 | } 194 | 195 | private isHostedModelResponseError(response: AxiosResponse) { 196 | return ( 197 | !response.headers['content-type'].includes('application/json') || 198 | !(response.status >= 200 && response.status < 300) 199 | ); 200 | } 201 | 202 | private isValidV1URL(url: string) { 203 | return /^https{0,1}:\/\/.+\.runwayml\.cloud\/v1/.test(url); 204 | } 205 | } 206 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | /** @ignore */ /** */ 2 | // Ignore index from generated docs ^ 3 | import { HostedModel, HostedModelConfig } from './HostedModel'; 4 | 5 | export { HostedModel, HostedModelConfig }; 6 | -------------------------------------------------------------------------------- /src/utils.ts: -------------------------------------------------------------------------------- 1 | /** @ignore */ /** */ 2 | // Ignore utils from generated docs ^ 3 | import axios, { AxiosRequestConfig } from 'axios'; 4 | 5 | export function delay(millis: number) { 6 | return new Promise(resolve => setTimeout(resolve, millis)); 7 | } 8 | 9 | export async function requestWithRetry( 10 | responseCodesToRetry: number[], 11 | config: AxiosRequestConfig 12 | ) { 13 | if (responseCodesToRetry.length < 1) { 14 | throw Error(`responseCodesToRetry must include at least one status code`); 15 | } 16 | while (true) { 17 | const result = await axios.request({ ...config, validateStatus: null }); 18 | if (!responseCodesToRetry.includes(result.status)) return result; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowUnreachableCode": false, 4 | "alwaysStrict": true, 5 | "declaration": false, 6 | "diagnostics": false, 7 | "module": "CommonJS", 8 | "noFallthroughCasesInSwitch": true, 9 | "noImplicitAny": true, 10 | "noImplicitReturns": true, 11 | "noImplicitThis": true, 12 | "noUnusedLocals": true, 13 | "noUnusedParameters": true, 14 | "preserveConstEnums": true, 15 | "pretty": true, 16 | "sourceMap": true, 17 | "target": "ES5", 18 | "outDir": "./build", 19 | "emitDecoratorMetadata": true, 20 | "experimentalDecorators": true, 21 | "rootDir": "./src" 22 | }, 23 | "include": ["./src/**/*.ts"], 24 | "exclude": ["build", "dist", "node_modules"] 25 | } 26 | --------------------------------------------------------------------------------