@bedrockio/ai 0.7.0 → 0.7.2

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,11 @@
1
+ ## 0.7.2
2
+
3
+ - Handling long filenames.
4
+
5
+ ## 0.7.1
6
+
7
+ - Better model listing.
8
+
1
9
  ## 0.7.0
2
10
 
3
11
  - Allow getting the template source.
@@ -193,19 +193,13 @@ class BaseClient {
193
193
  };
194
194
  }
195
195
  normalizeInput(options) {
196
- let { input = '' } = options;
197
- if (!input) {
198
- input = [];
199
- }
200
- else if (typeof input === 'string') {
201
- input = [
202
- {
203
- role: 'user',
204
- content: input,
205
- },
206
- ];
207
- }
208
- return input;
196
+ const { input = '' } = options;
197
+ return [
198
+ {
199
+ role: 'user',
200
+ content: input,
201
+ },
202
+ ];
209
203
  }
210
204
  normalizeSchema(options) {
211
205
  let { schema } = options;
@@ -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
+ }
@@ -191,19 +191,13 @@ export default class BaseClient {
191
191
  };
192
192
  }
193
193
  normalizeInput(options) {
194
- let { input = '' } = options;
195
- if (!input) {
196
- input = [];
197
- }
198
- else if (typeof input === 'string') {
199
- input = [
200
- {
201
- role: 'user',
202
- content: input,
203
- },
204
- ];
205
- }
206
- return input;
194
+ const { input = '' } = options;
195
+ return [
196
+ {
197
+ role: 'user',
198
+ content: input,
199
+ },
200
+ ];
207
201
  }
208
202
  normalizeSchema(options) {
209
203
  let { schema } = options;
@@ -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.2",
4
4
  "description": "Bedrock wrapper for common AI chatbots.",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -36,7 +36,7 @@
36
36
  },
37
37
  "dependencies": {
38
38
  "@anthropic-ai/sdk": "^0.66.0",
39
- "@bedrockio/templates": "^0.3.0",
39
+ "@bedrockio/templates": "^0.3.1",
40
40
  "@google/generative-ai": "^0.21.0",
41
41
  "openai": "^6.3.0",
42
42
  "partial-json": "^0.1.7"
@@ -45,7 +45,10 @@ export default class BaseClient {
45
45
  system: string;
46
46
  messages: any[];
47
47
  };
48
- normalizeInput(options: any): any;
48
+ normalizeInput(options: any): {
49
+ role: string;
50
+ content: any;
51
+ }[];
49
52
  normalizeSchema(options: any): {
50
53
  schema: any;
51
54
  hasWrappedSchema: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"BaseClient.d.ts","sourceRoot":"","sources":["../src/BaseClient.js"],"names":[],"mappings":"AAKA;IACE,0BASC;IARC,aAIC;IACD,2BAEE;IAKJ;;;;;OAKG;IACH,gBAFW,aAAa,gBAuCvB;IAED;;;;;OAKG;IACH,gBAHW,aAAa,GAAG,aAAa,gCAsDvC;IAED;;;;OAIG;IACH,wBAFW,MAAM,OAIhB;IAID,8BAGC;IAED,8BAGC;IAED,qCAGC;IAED;;OAEG;IACH,0CAGC;IAED;;OAEG;IACH,oDAGC;IAED;;OAEG;IACH,sCAGC;IAID;;OAEG;IACH,oCAOC;IAED;;;MAsCC;IAED,kCAeC;IAED;;;MA4BC;IAED,uDAWC;IAED,oCAMC;CACF;;;;;WAIa,MAAM,GAAC,aAAa,EAAE;;;;YACtB,MAAM;;;;YACN,OAAO;;;;;;;;aAEP,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,UAAU;;;;;;;;;;;sBAOpC,MAAM;;;UAKN,QAAQ,GAAG,MAAM,GAAG,WAAW;aAC/B,MAAM;;iCA3Ta,sBAAsB"}
1
+ {"version":3,"file":"BaseClient.d.ts","sourceRoot":"","sources":["../src/BaseClient.js"],"names":[],"mappings":"AAKA;IACE,0BASC;IARC,aAIC;IACD,2BAEE;IAKJ;;;;;OAKG;IACH,gBAFW,aAAa,gBAuCvB;IAED;;;;;OAKG;IACH,gBAHW,aAAa,GAAG,aAAa,gCAsDvC;IAED;;;;OAIG;IACH,wBAFW,MAAM,OAIhB;IAID,8BAGC;IAED,8BAGC;IAED,qCAGC;IAED;;OAEG;IACH,0CAGC;IAED;;OAEG;IACH,oDAGC;IAED;;OAEG;IACH,sCAGC;IAID;;OAEG;IACH,oCAOC;IAED;;;MAuCC;IAED;;;QAQC;IAED;;;MA4BC;IAED,uDAWC;IAED,oCAMC;CACF;;;;;WAIa,MAAM,GAAC,aAAa,EAAE;;;;YACtB,MAAM;;;;YACN,OAAO;;;;;;;;aAEP,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,UAAU;;;;;;;;;;;sBAOpC,MAAM;;;UAKN,QAAQ,GAAG,MAAM,GAAG,WAAW;aAC/B,MAAM;;iCArTa,sBAAsB"}
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"}