@bedrockio/ai 0.7.0 → 0.7.1

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/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## 0.7.1
2
+
3
+ - Better model listing.
4
+
1
5
  ## 0.7.0
2
6
 
3
7
  - Allow getting the template source.
@@ -14,11 +14,33 @@ class OpenAiClient extends BaseClient_js_1.default {
14
14
  }
15
15
  /**
16
16
  * Lists available models.
17
+ * @param {OpenAICategory} category
17
18
  * {@link https://platform.openai.com/docs/models Documentation}
18
19
  */
19
- async models() {
20
+ async models(category = 'general') {
20
21
  const { data } = await this.client.models.list();
21
- return data.map((o) => o.id);
22
+ const names = [];
23
+ for (let entry of data) {
24
+ const model = {
25
+ ...entry,
26
+ category: getModelCategory(entry),
27
+ };
28
+ if (isMatch(model, category)) {
29
+ names.push(model.id);
30
+ }
31
+ }
32
+ names.sort((a, b) => {
33
+ // If one is a prefix of the other, the shorter one comes first
34
+ if (a.startsWith(b)) {
35
+ return 1;
36
+ }
37
+ else if (b.startsWith(a)) {
38
+ return -1;
39
+ }
40
+ // Otherwise sort alphabetically
41
+ return b.localeCompare(a);
42
+ });
43
+ return names;
22
44
  }
23
45
  async runPrompt(options) {
24
46
  const { model, tools, verbosity, temperature, prevResponseId, messages: input, system: instructions, tool_choice = 'auto', stream = false, } = options;
@@ -136,3 +158,47 @@ class OpenAiClient extends BaseClient_js_1.default {
136
158
  }
137
159
  }
138
160
  exports.OpenAiClient = OpenAiClient;
161
+ // Categories
162
+ const DATE_REG = /\d{4}-\d{2}-\d{2}$|\d{4}/;
163
+ /**
164
+ * @typedef {
165
+ * | "all"
166
+ * | "general"
167
+ * | "reasoning"
168
+ * | "lightweight"
169
+ * | "moderation"
170
+ * | "embedding"
171
+ * | "speech"
172
+ * | "audio"
173
+ * | "image"
174
+ * | "code"
175
+ * | "legacy"
176
+ * } OpenAICategory
177
+ */
178
+ const MODEL_CATEGORIES = [
179
+ { name: 'code', reg: /codex/ },
180
+ { name: 'image', reg: /(dall-e|image|sora)/ },
181
+ { name: 'audio', reg: /(audio|realtime)/ },
182
+ { name: 'speech', reg: /(transcribe|tts)/ },
183
+ { name: 'embedding', reg: /embedding/ },
184
+ { name: 'moderation', reg: /moderation/ },
185
+ { name: 'lightweight', reg: /(mini|nano|small)/ },
186
+ { name: 'reasoning', reg: /(^o\d|deep-research)/ },
187
+ { name: 'legacy', reg: /(davinci|babbage|curie|ada)/ },
188
+ { name: 'general', reg: /^gpt/ },
189
+ ];
190
+ function getModelCategory(model) {
191
+ const category = MODEL_CATEGORIES.find((category) => {
192
+ return category.reg.test(model.id);
193
+ });
194
+ return category?.name || 'none';
195
+ }
196
+ function isMatch(model, category) {
197
+ if (model.owned_by === 'openai-internal') {
198
+ return false;
199
+ }
200
+ else if (DATE_REG.test(model.id)) {
201
+ return false;
202
+ }
203
+ return category === 'all' || model.category === category;
204
+ }
@@ -8,11 +8,33 @@ export class OpenAiClient extends BaseClient {
8
8
  }
9
9
  /**
10
10
  * Lists available models.
11
+ * @param {OpenAICategory} category
11
12
  * {@link https://platform.openai.com/docs/models Documentation}
12
13
  */
13
- async models() {
14
+ async models(category = 'general') {
14
15
  const { data } = await this.client.models.list();
15
- return data.map((o) => o.id);
16
+ const names = [];
17
+ for (let entry of data) {
18
+ const model = {
19
+ ...entry,
20
+ category: getModelCategory(entry),
21
+ };
22
+ if (isMatch(model, category)) {
23
+ names.push(model.id);
24
+ }
25
+ }
26
+ names.sort((a, b) => {
27
+ // If one is a prefix of the other, the shorter one comes first
28
+ if (a.startsWith(b)) {
29
+ return 1;
30
+ }
31
+ else if (b.startsWith(a)) {
32
+ return -1;
33
+ }
34
+ // Otherwise sort alphabetically
35
+ return b.localeCompare(a);
36
+ });
37
+ return names;
16
38
  }
17
39
  async runPrompt(options) {
18
40
  const { model, tools, verbosity, temperature, prevResponseId, messages: input, system: instructions, tool_choice = 'auto', stream = false, } = options;
@@ -129,3 +151,47 @@ export class OpenAiClient extends BaseClient {
129
151
  }
130
152
  }
131
153
  }
154
+ // Categories
155
+ const DATE_REG = /\d{4}-\d{2}-\d{2}$|\d{4}/;
156
+ /**
157
+ * @typedef {
158
+ * | "all"
159
+ * | "general"
160
+ * | "reasoning"
161
+ * | "lightweight"
162
+ * | "moderation"
163
+ * | "embedding"
164
+ * | "speech"
165
+ * | "audio"
166
+ * | "image"
167
+ * | "code"
168
+ * | "legacy"
169
+ * } OpenAICategory
170
+ */
171
+ const MODEL_CATEGORIES = [
172
+ { name: 'code', reg: /codex/ },
173
+ { name: 'image', reg: /(dall-e|image|sora)/ },
174
+ { name: 'audio', reg: /(audio|realtime)/ },
175
+ { name: 'speech', reg: /(transcribe|tts)/ },
176
+ { name: 'embedding', reg: /embedding/ },
177
+ { name: 'moderation', reg: /moderation/ },
178
+ { name: 'lightweight', reg: /(mini|nano|small)/ },
179
+ { name: 'reasoning', reg: /(^o\d|deep-research)/ },
180
+ { name: 'legacy', reg: /(davinci|babbage|curie|ada)/ },
181
+ { name: 'general', reg: /^gpt/ },
182
+ ];
183
+ function getModelCategory(model) {
184
+ const category = MODEL_CATEGORIES.find((category) => {
185
+ return category.reg.test(model.id);
186
+ });
187
+ return category?.name || 'none';
188
+ }
189
+ function isMatch(model, category) {
190
+ if (model.owned_by === 'openai-internal') {
191
+ return false;
192
+ }
193
+ else if (DATE_REG.test(model.id)) {
194
+ return false;
195
+ }
196
+ return category === 'all' || model.category === category;
197
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bedrockio/ai",
3
- "version": "0.7.0",
3
+ "version": "0.7.1",
4
4
  "description": "Bedrock wrapper for common AI chatbots.",
5
5
  "type": "module",
6
6
  "scripts": {
package/types/openai.d.ts CHANGED
@@ -3,9 +3,10 @@ export class OpenAiClient extends BaseClient {
3
3
  client: OpenAI;
4
4
  /**
5
5
  * Lists available models.
6
+ * @param {OpenAICategory} category
6
7
  * {@link https://platform.openai.com/docs/models Documentation}
7
8
  */
8
- models(): Promise<string[]>;
9
+ models(category?: OpenAICategory): Promise<string[]>;
9
10
  runPrompt(options: any): Promise<OpenAI.Responses.Response & {
10
11
  _request_id?: string | null;
11
12
  } & import("openai/core/streaming.js").Stream<OpenAI.Responses.ResponseStreamEvent>>;
@@ -54,6 +55,7 @@ export class OpenAiClient extends BaseClient {
54
55
  delta?: undefined;
55
56
  };
56
57
  }
58
+ export type OpenAICategory = any | "all" | "general" | "reasoning" | "lightweight" | "moderation" | "embedding" | "speech" | "audio" | "image" | "code" | "legacy";
57
59
  import BaseClient from './BaseClient.js';
58
60
  import OpenAI from 'openai';
59
61
  //# sourceMappingURL=openai.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../src/openai.js"],"names":[],"mappings":"AAIA;IACE,6BAAoC;IAIlC,eAAiC;IAGnC;;;OAGG;IACH,4BAGC;IAED;;yFAiCC;IAED;;yFAKC;IAED,oCAEC;IAwBD;;;MAcC;IAID;;;;;;;;;;MAmBC;IAED;;;;;;;;;;;;;;;;;;;;;;;;MAyBC;CACF;uBAxJsB,iBAAiB;mBAFrB,QAAQ"}
1
+ {"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../src/openai.js"],"names":[],"mappings":"AAIA;IACE,6BAAoC;IAIlC,eAAiC;IAGnC;;;;OAIG;IACH,kBAHW,cAAc,qBAgCxB;IAED;;yFAiCC;IAED;;yFAKC;IAED,oCAEC;IAwBD;;;MAcC;IAID;;;;;;;;;;MAmBC;IAED;;;;;;;;;;;;;;;;;;;;;;;;MAyBC;CACF;6BAQA,GAAC,GAAK,KAAK,GACL,SAAS,GACT,WAAW,GACX,aAAa,GACb,YAAY,GACZ,WAAW,GACX,QAAQ,GACR,OAAO,GACP,OAAO,GACP,MAAM,GACN,QAAQ;uBArMQ,iBAAiB;mBAFrB,QAAQ"}