ai-functions 0.2.10 → 0.2.13

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.
Files changed (93) hide show
  1. package/db/mongo.ts +3 -3
  2. package/dist/cjs/db/cache.d.ts +1 -0
  3. package/dist/cjs/db/cache.js +12 -0
  4. package/dist/cjs/db/mongo.d.ts +31 -0
  5. package/dist/cjs/db/mongo.js +47 -0
  6. package/dist/cjs/examples/data.d.ts +1105 -0
  7. package/dist/cjs/examples/data.js +1108 -0
  8. package/dist/cjs/functions/ai.d.ts +18 -0
  9. package/dist/cjs/functions/ai.js +99 -0
  10. package/dist/cjs/functions/ai.test.d.ts +1 -0
  11. package/dist/cjs/functions/ai.test.js +40 -0
  12. package/dist/cjs/functions/gpt.d.ts +4 -0
  13. package/dist/cjs/functions/gpt.js +24 -0
  14. package/dist/cjs/functions/list.d.ts +7 -0
  15. package/dist/cjs/functions/list.js +134 -0
  16. package/dist/cjs/index.d.ts +3 -0
  17. package/dist/cjs/index.js +19 -0
  18. package/dist/cjs/package.json +3 -0
  19. package/dist/cjs/queue/kafka.d.ts +0 -0
  20. package/dist/cjs/queue/kafka.js +1 -0
  21. package/dist/cjs/queue/memory.d.ts +0 -0
  22. package/dist/cjs/queue/memory.js +1 -0
  23. package/dist/cjs/queue/mongo.d.ts +30 -0
  24. package/dist/cjs/queue/mongo.js +69 -0
  25. package/dist/cjs/streams/kafka.d.ts +0 -0
  26. package/dist/cjs/streams/kafka.js +1 -0
  27. package/dist/cjs/streams/memory.d.ts +0 -0
  28. package/dist/cjs/streams/memory.js +1 -0
  29. package/dist/cjs/streams/mongo.d.ts +0 -0
  30. package/dist/cjs/streams/mongo.js +1 -0
  31. package/dist/cjs/streams/types.d.ts +0 -0
  32. package/dist/cjs/streams/types.js +1 -0
  33. package/dist/cjs/types.d.ts +11 -0
  34. package/dist/cjs/types.js +2 -0
  35. package/dist/cjs/utils/completion.d.ts +9 -0
  36. package/dist/cjs/utils/completion.js +45 -0
  37. package/dist/cjs/utils/schema.d.ts +10 -0
  38. package/dist/cjs/utils/schema.js +64 -0
  39. package/dist/cjs/utils/schema.test.d.ts +1 -0
  40. package/dist/cjs/utils/schema.test.js +62 -0
  41. package/dist/cjs/utils/state.d.ts +1 -0
  42. package/dist/cjs/utils/state.js +21 -0
  43. package/dist/mjs/db/cache.d.ts +1 -0
  44. package/dist/mjs/db/cache.js +5 -0
  45. package/dist/mjs/db/mongo.d.ts +31 -0
  46. package/dist/mjs/db/mongo.js +48 -0
  47. package/dist/mjs/examples/data.d.ts +1105 -0
  48. package/dist/mjs/examples/data.js +1105 -0
  49. package/dist/mjs/functions/ai.d.ts +18 -0
  50. package/dist/mjs/functions/ai.js +79 -0
  51. package/dist/mjs/functions/ai.test.d.ts +1 -0
  52. package/dist/mjs/functions/ai.test.js +29 -0
  53. package/dist/mjs/functions/gpt.d.ts +4 -0
  54. package/dist/mjs/functions/gpt.js +10 -0
  55. package/dist/mjs/functions/list.d.ts +7 -0
  56. package/dist/mjs/functions/list.js +72 -0
  57. package/dist/mjs/index.d.ts +3 -0
  58. package/dist/mjs/index.js +3 -0
  59. package/dist/mjs/package.json +3 -0
  60. package/dist/mjs/queue/kafka.d.ts +0 -0
  61. package/dist/mjs/queue/kafka.js +1 -0
  62. package/dist/mjs/queue/memory.d.ts +0 -0
  63. package/dist/mjs/queue/memory.js +1 -0
  64. package/dist/mjs/queue/mongo.d.ts +30 -0
  65. package/dist/mjs/queue/mongo.js +42 -0
  66. package/dist/mjs/streams/kafka.d.ts +0 -0
  67. package/dist/mjs/streams/kafka.js +1 -0
  68. package/dist/mjs/streams/memory.d.ts +0 -0
  69. package/dist/mjs/streams/memory.js +1 -0
  70. package/dist/mjs/streams/mongo.d.ts +0 -0
  71. package/dist/mjs/streams/mongo.js +1 -0
  72. package/dist/mjs/streams/types.d.ts +0 -0
  73. package/dist/mjs/streams/types.js +1 -0
  74. package/dist/mjs/types.d.ts +11 -0
  75. package/dist/mjs/types.js +1 -0
  76. package/dist/mjs/utils/completion.d.ts +9 -0
  77. package/dist/mjs/utils/completion.js +20 -0
  78. package/dist/mjs/utils/schema.d.ts +10 -0
  79. package/dist/mjs/utils/schema.js +59 -0
  80. package/dist/mjs/utils/schema.test.d.ts +1 -0
  81. package/dist/mjs/utils/schema.test.js +60 -0
  82. package/dist/mjs/utils/state.d.ts +1 -0
  83. package/dist/mjs/utils/state.js +19 -0
  84. package/fixup +11 -0
  85. package/functions/ai.ts +1 -1
  86. package/functions/list.ts +1 -1
  87. package/package.json +10 -3
  88. package/tsconfig-backup.json +105 -0
  89. package/tsconfig-base.json +26 -0
  90. package/tsconfig-cjs.json +8 -0
  91. package/tsconfig.json +5 -102
  92. package/types.ts +1 -1
  93. package/utils/completion.ts +1 -1
@@ -0,0 +1,18 @@
1
+ import { ClientOptions, OpenAI } from 'openai';
2
+ import { ChatCompletionCreateParamsBase } from 'openai/resources/chat/completions';
3
+ export type AIConfig = ClientOptions & {
4
+ openai?: OpenAI;
5
+ system?: string;
6
+ model?: ChatCompletionCreateParamsBase['model'];
7
+ };
8
+ export type FunctionCallOptions = Omit<ChatCompletionCreateParamsBase, 'messages' | 'stream'> & {
9
+ system?: string;
10
+ meta?: boolean;
11
+ description?: string;
12
+ };
13
+ type AIFunctions<T = Record<string, string>> = Record<string, (returnSchema: T, options?: Partial<FunctionCallOptions>) => (args: string | object, callOptions?: Partial<FunctionCallOptions>) => Promise<T>>;
14
+ export declare const AI: (config?: AIConfig) => {
15
+ ai: AIFunctions<Record<string, string>>;
16
+ openai: OpenAI;
17
+ };
18
+ export {};
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __rest = (this && this.__rest) || function (s, e) {
12
+ var t = {};
13
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
14
+ t[p] = s[p];
15
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
16
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
17
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
18
+ t[p[i]] = s[p[i]];
19
+ }
20
+ return t;
21
+ };
22
+ Object.defineProperty(exports, "__esModule", { value: true });
23
+ exports.AI = void 0;
24
+ const openai_1 = require("openai");
25
+ // import { AIDB, AIDBConfig } from '../db/mongo'
26
+ const js_yaml_1 = require("js-yaml");
27
+ const schema_1 = require("../utils/schema");
28
+ const AI = (config = {}) => {
29
+ var _a;
30
+ const { model = 'gpt-4-1106-preview', system } = config, rest = __rest(config, ["model", "system"]);
31
+ const openai = (_a = config.openai) !== null && _a !== void 0 ? _a : new openai_1.OpenAI(rest);
32
+ // const { client, db, cache, events, queue } = config.db ? AIDB(config.db) : {}
33
+ // const prompt = {
34
+ // model,
35
+ // messages: [{ role: 'user', content: user }],
36
+ // }
37
+ // if (system) prompt.messages.unshift({ role: 'system', content: system })
38
+ // const messages = system ? [{ role: 'system', content: system }] : []
39
+ // const completion = openai.chat.completions.create({
40
+ // model,
41
+ // messages: [{ role: 'user', content: 'hello' }],
42
+ // })
43
+ const ai = new Proxy({}, {
44
+ get: (target, functionName, receiver) => {
45
+ target[functionName] = (returnSchema, options) => (args, callOptions) => __awaiter(void 0, void 0, void 0, function* () {
46
+ var _a;
47
+ console.log((0, schema_1.generateSchema)(returnSchema));
48
+ const _b = Object.assign(Object.assign({}, options), callOptions), { system, description, model = 'gpt-3.5-turbo', meta = false } = _b, rest = __rest(_b, ["system", "description", "model", "meta"]);
49
+ const prompt = Object.assign({ model, messages: [
50
+ {
51
+ role: 'user',
52
+ content: `Call ${functionName} given the context:\n${(0, js_yaml_1.dump)(args)}`,
53
+ }, // \nThere is no additional information, so make assumptions/guesses as necessary` },
54
+ ], tools: [
55
+ {
56
+ type: 'function',
57
+ function: {
58
+ name: functionName,
59
+ description,
60
+ parameters: (0, schema_1.generateSchema)(returnSchema),
61
+ }
62
+ }
63
+ ], tool_choice: {
64
+ type: 'function',
65
+ function: { name: functionName }
66
+ } }, rest);
67
+ if (system)
68
+ prompt.messages.unshift({ role: 'system', content: system });
69
+ const completion = yield openai.chat.completions.create(prompt);
70
+ const schema = (0, schema_1.generateSchema)(returnSchema);
71
+ let data;
72
+ let error;
73
+ const { message } = (_a = completion.choices) === null || _a === void 0 ? void 0 : _a[0];
74
+ console.log({ message });
75
+ prompt.messages.push(message);
76
+ const { content, tool_calls } = message;
77
+ if (tool_calls) {
78
+ try {
79
+ data = JSON.parse(tool_calls[0].function.arguments);
80
+ }
81
+ catch (err) {
82
+ error = err.message;
83
+ }
84
+ }
85
+ const gpt4 = model.includes('gpt-4');
86
+ const cost = completion.usage ?
87
+ Math.round((gpt4
88
+ ? completion.usage.prompt_tokens * 0.003 + completion.usage.completion_tokens * 0.006
89
+ : completion.usage.prompt_tokens * 0.00015 + completion.usage.completion_tokens * 0.0002) * 100000) / 100000 : undefined;
90
+ // completion.usage = camelcaseKeys(completion.usage)
91
+ console.log({ data, content, error, cost, usage: completion.usage });
92
+ return meta ? Object.assign({ prompt, content, data, error, cost }, completion) : data !== null && data !== void 0 ? data : content;
93
+ });
94
+ return target[functionName];
95
+ },
96
+ });
97
+ return { ai, openai }; //, client, db, cache, events, queue }
98
+ };
99
+ exports.AI = AI;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const vitest_1 = require("vitest");
13
+ const ai_1 = require("./ai");
14
+ (0, vitest_1.describe)('AI Functions', () => __awaiter(void 0, void 0, void 0, function* () {
15
+ const { ai } = (0, ai_1.AI)();
16
+ (0, vitest_1.it)('should be initialized', () => {
17
+ (0, vitest_1.expect)(ai).toBeDefined();
18
+ });
19
+ const categorizeWord = ai.categorizeWord({
20
+ type: 'Noun | Verb | Adjective | Adverb | Pronoun | Preposition | Conjunction | Interjection | Other',
21
+ example: 'use the word in a sentence',
22
+ // partOfSpeech: 'Part of speech'
23
+ }, { seed: 1, model: 'gpt-3.5-turbo' });
24
+ (0, vitest_1.it)('should be a function', () => {
25
+ (0, vitest_1.expect)(typeof categorizeWord).toBe('function');
26
+ });
27
+ (0, vitest_1.it)('Destroy should be a verb', () => __awaiter(void 0, void 0, void 0, function* () {
28
+ (0, vitest_1.expect)(yield categorizeWord('destroy')).toMatchObject({ type: 'Verb', example: 'I will destroy the old building.' });
29
+ }));
30
+ (0, vitest_1.it)('Dog should be a Noun', () => __awaiter(void 0, void 0, void 0, function* () {
31
+ const dog = yield categorizeWord({ word: 'dog' });
32
+ (0, vitest_1.expect)(dog).toMatchObject({ type: 'Noun', example: 'I have a dog.' });
33
+ }));
34
+ (0, vitest_1.it)('Large should be an Adjective', () => __awaiter(void 0, void 0, void 0, function* () {
35
+ (0, vitest_1.expect)(yield categorizeWord({ word: 'large' })).toMatchObject({ type: 'Adjective', example: 'She has a large collection of books.' });
36
+ }));
37
+ (0, vitest_1.it)('To should be an Preposition', () => __awaiter(void 0, void 0, void 0, function* () {
38
+ (0, vitest_1.expect)(yield categorizeWord('to')).toMatchObject({ type: 'Preposition', example: "I'm going to the park." });
39
+ }));
40
+ }));
@@ -0,0 +1,4 @@
1
+ import { GPTConfig } from '../types';
2
+ export declare const GPT: (config: GPTConfig) => {
3
+ gpt: (strings: string[], ...values: string[]) => Promise<string | null>;
4
+ };
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.GPT = void 0;
13
+ const completion_1 = require("../utils/completion");
14
+ const GPT = (config) => {
15
+ const gpt = (strings, ...values) => __awaiter(void 0, void 0, void 0, function* () {
16
+ var _a;
17
+ const user = values.map((value, i) => strings[i] + value).join('') + strings[strings.length - 1];
18
+ const completion = yield (0, completion_1.chatCompletion)(Object.assign({ user }, config));
19
+ const content = (_a = completion.choices) === null || _a === void 0 ? void 0 : _a[0].message.content;
20
+ return content;
21
+ });
22
+ return { gpt };
23
+ };
24
+ exports.GPT = GPT;
@@ -0,0 +1,7 @@
1
+ import { GPTConfig } from '../types';
2
+ export declare const List: (config: GPTConfig) => {
3
+ list: (strings: string[], ...values: string[]) => Promise<string[]>;
4
+ };
5
+ export declare const StreamingList: (config: GPTConfig) => {
6
+ list: (strings: string[], ...values: string[]) => AsyncGenerator<string | undefined, void, unknown>;
7
+ };
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __rest = (this && this.__rest) || function (s, e) {
12
+ var t = {};
13
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
14
+ t[p] = s[p];
15
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
16
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
17
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
18
+ t[p[i]] = s[p[i]];
19
+ }
20
+ return t;
21
+ };
22
+ var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
23
+ var __asyncValues = (this && this.__asyncValues) || function (o) {
24
+ if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
25
+ var m = o[Symbol.asyncIterator], i;
26
+ return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
27
+ function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
28
+ function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
29
+ };
30
+ var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
31
+ if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
32
+ var g = generator.apply(thisArg, _arguments || []), i, q = [];
33
+ return i = {}, verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;
34
+ function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }
35
+ function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }
36
+ function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
37
+ function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
38
+ function fulfill(value) { resume("next", value); }
39
+ function reject(value) { resume("throw", value); }
40
+ function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
41
+ };
42
+ Object.defineProperty(exports, "__esModule", { value: true });
43
+ exports.StreamingList = exports.List = void 0;
44
+ const openai_1 = require("openai");
45
+ const completion_1 = require("../utils/completion");
46
+ const List = (config) => {
47
+ const list = (strings, ...values) => __awaiter(void 0, void 0, void 0, function* () {
48
+ var _a;
49
+ const user = values.map((value, i) => strings[i] + value).join('') + strings[strings.length - 1];
50
+ const completion = yield (0, completion_1.chatCompletion)(Object.assign({ user }, config));
51
+ const content = (_a = completion.choices) === null || _a === void 0 ? void 0 : _a[0].message.content;
52
+ return content ? parseList(content) : [];
53
+ });
54
+ return { list };
55
+ };
56
+ exports.List = List;
57
+ function parseList(listStr) {
58
+ // Define a regex pattern to match lines with '1. value', '1) value', '- value', or ' - value'
59
+ const listItemRegex = /^\s*\d+\.\s*(.+)|^\s*\d+\)\s*(.+)|^\s*-\s*(.+)$/gm;
60
+ let match;
61
+ const result = [];
62
+ // Loop over the list string, finding matches with the regex pattern
63
+ while ((match = listItemRegex.exec(listStr)) !== null) {
64
+ // The actual value is in one of the capturing groups (1, 2 or 3)
65
+ const value = match[1] || match[2] || match[3];
66
+ if (value) {
67
+ result.push(value.trim());
68
+ }
69
+ }
70
+ return result;
71
+ }
72
+ const StreamingList = (config) => {
73
+ function list(strings, ...values) {
74
+ var _a, _b, _c;
75
+ return __asyncGenerator(this, arguments, function* list_1() {
76
+ var _d, e_1, _e, _f;
77
+ const user = values.map((value, i) => strings[i] + value).join('') + strings[strings.length - 1];
78
+ const { system, model, db, queue } = config, rest = __rest(config, ["system", "model", "db", "queue"]);
79
+ const openai = (_a = config.openai) !== null && _a !== void 0 ? _a : new openai_1.OpenAI(rest);
80
+ const prompt = {
81
+ model,
82
+ messages: [{ role: 'user', content: user }],
83
+ stream: true,
84
+ };
85
+ if (system)
86
+ prompt.messages.unshift({ role: 'system', content: system });
87
+ const completion = yield __await(openai.chat.completions.create(prompt));
88
+ const stream = yield __await(openai.chat.completions.create(prompt));
89
+ let content = '';
90
+ let seperator;
91
+ let numberedList;
92
+ try {
93
+ for (var _g = true, stream_1 = __asyncValues(stream), stream_1_1; stream_1_1 = yield __await(stream_1.next()), _d = stream_1_1.done, !_d; _g = true) {
94
+ _f = stream_1_1.value;
95
+ _g = false;
96
+ const part = _f;
97
+ const { delta, finish_reason } = part.choices[0];
98
+ content += (delta === null || delta === void 0 ? void 0 : delta.content) || '';
99
+ if (seperator === undefined && content.length > 4) {
100
+ numberedList = content.match(/(\d+\.\s)/g);
101
+ seperator = numberedList ? '\n' : ', ';
102
+ }
103
+ const numberedRegex = /\d+\.\s(?:")?([^"]+)(?:")?/;
104
+ if (seperator && content.includes(seperator)) {
105
+ // get the string before the newline, and modify `content` to be the string after the newline
106
+ // then yield the string before the newline
107
+ const items = content.split(seperator);
108
+ while (items.length > 1) {
109
+ const item = items.shift();
110
+ yield yield __await(numberedList ? (_b = item === null || item === void 0 ? void 0 : item.match(numberedRegex)) === null || _b === void 0 ? void 0 : _b[1] : item);
111
+ }
112
+ content = items[0];
113
+ }
114
+ if (finish_reason) {
115
+ // TODO: Figure out DB saving strategy for streaming
116
+ // if (db) {
117
+ // db.log(prompt, completion as ChatCompletion)
118
+ // }
119
+ yield yield __await(numberedList ? (_c = content.match(numberedRegex)) === null || _c === void 0 ? void 0 : _c[1] : content);
120
+ }
121
+ }
122
+ }
123
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
124
+ finally {
125
+ try {
126
+ if (!_g && !_d && (_e = stream_1.return)) yield __await(_e.call(stream_1));
127
+ }
128
+ finally { if (e_1) throw e_1.error; }
129
+ }
130
+ });
131
+ }
132
+ return { list };
133
+ };
134
+ exports.StreamingList = StreamingList;
@@ -0,0 +1,3 @@
1
+ export * from './functions/ai';
2
+ export * from './functions/gpt';
3
+ export * from './functions/list';
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./functions/ai"), exports);
18
+ __exportStar(require("./functions/gpt"), exports);
19
+ __exportStar(require("./functions/list"), exports);
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "commonjs"
3
+ }
File without changes
@@ -0,0 +1 @@
1
+ "use strict";
File without changes
@@ -0,0 +1 @@
1
+ "use strict";
@@ -0,0 +1,30 @@
1
+ import { AIDB } from '../db/mongo';
2
+ import { CompletionInput } from '../utils/completion';
3
+ import { BSON, ObjectId } from 'mongodb';
4
+ export type QueueConfig = AIDB & {
5
+ batchSize?: number;
6
+ concurrency?: number;
7
+ lockExpiration?: number;
8
+ };
9
+ export type QueueInputMerge = {
10
+ into: string;
11
+ on?: BSON.Document;
12
+ let?: BSON.Document;
13
+ contentAs?: string;
14
+ itemsAs?: string;
15
+ functionDataAs?: string;
16
+ forEachItem?: boolean;
17
+ };
18
+ export type QueueInput = (CompletionInput | ({
19
+ list: string;
20
+ } & Partial<CompletionInput>)) & {
21
+ _id?: ObjectId;
22
+ metadata?: object;
23
+ merge?: string | QueueInputMerge;
24
+ target?: string;
25
+ };
26
+ export type QueueDocument = QueueInput & {
27
+ lockedAt: Date;
28
+ lockedBy: string;
29
+ };
30
+ export declare const startQueue: (config: QueueConfig) => Promise<void>;
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __rest = (this && this.__rest) || function (s, e) {
12
+ var t = {};
13
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
14
+ t[p] = s[p];
15
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
16
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
17
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
18
+ t[p[i]] = s[p[i]];
19
+ }
20
+ return t;
21
+ };
22
+ var __importDefault = (this && this.__importDefault) || function (mod) {
23
+ return (mod && mod.__esModule) ? mod : { "default": mod };
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.startQueue = void 0;
27
+ const p_queue_1 = __importDefault(require("p-queue"));
28
+ const completion_1 = require("../utils/completion");
29
+ let localQueue;
30
+ const startQueue = (config) => __awaiter(void 0, void 0, void 0, function* () {
31
+ const { concurrency = 10, batchSize = 100, lockExpiration = 3600 } = config, db = __rest(config, ["concurrency", "batchSize", "lockExpiration"]);
32
+ const instance = Math.random().toString(36).substring(2, 6);
33
+ const queue = new p_queue_1.default({ concurrency });
34
+ const clearExpiredLocks = () => db.queue.updateMany({ lockedAt: { $lt: new Date(Date.now() - lockExpiration * 1000) } }, { $unset: { lockedAt: '', lockedBy: '' } });
35
+ const lockBatch = () => db.queue.aggregate([
36
+ { $match: { lockedAt: { $exists: false } } },
37
+ { $limit: batchSize },
38
+ { $set: { lockedAt: new Date(), lockedBy: instance } },
39
+ { $merge: { into: 'queue', on: '_id', whenMatched: 'replace' } }, // TODO: Change the `into` to the name of the `queue` collection
40
+ ]).toArray();
41
+ db.queue.watch([
42
+ { $match: { lockedBy: instance } },
43
+ ]).on('change', (change) => __awaiter(void 0, void 0, void 0, function* () {
44
+ const _a = change.fullDocument, { _id, metadata, merge, target } = _a, input = __rest(_a, ["_id", "metadata", "merge", "target"]); // TODO: Move input to child object not catchall spread
45
+ const completion = yield queue.add(() => (0, completion_1.chatCompletion)(input));
46
+ if (merge) {
47
+ const coll = typeof merge === 'string' ? merge : merge.into;
48
+ const match = typeof merge === 'string' ? undefined : merge.on;
49
+ // TODO: Add support to make completion optional, and specify field names for content, items, and functionData
50
+ const mergeResult = match
51
+ ? yield db.db.collection(coll).updateOne(match, { $set: Object.assign({ completion }, metadata !== null && metadata !== void 0 ? metadata : {}) })
52
+ : yield db.db.collection(coll).insertOne(Object.assign({ completion }, metadata !== null && metadata !== void 0 ? metadata : {}));
53
+ if (mergeResult.acknowledged && (mergeResult.modifiedCount ||
54
+ mergeResult.insertedId)) {
55
+ // TODO: We may want to store the merge result in the Events collection to link the queue input to the merge result
56
+ yield db.queue.deleteOne({ _id });
57
+ }
58
+ }
59
+ }));
60
+ queue.on('idle', () => __awaiter(void 0, void 0, void 0, function* () {
61
+ yield clearExpiredLocks();
62
+ yield lockBatch();
63
+ }));
64
+ queue.start();
65
+ // TODO: Add Find() and Watch() for Actors collection
66
+ // TODO: For each actor, create a state machine and start it
67
+ // TODO: Figure out how to create new queued jobs from the results of the state machine
68
+ });
69
+ exports.startQueue = startQueue;
File without changes
@@ -0,0 +1 @@
1
+ "use strict";
File without changes
@@ -0,0 +1 @@
1
+ "use strict";
File without changes
@@ -0,0 +1 @@
1
+ "use strict";
File without changes
@@ -0,0 +1 @@
1
+ "use strict";
@@ -0,0 +1,11 @@
1
+ import type { OpenAI, ClientOptions } from 'openai';
2
+ import type { ChatCompletionCreateParamsNonStreaming } from 'openai/resources';
3
+ import type { AIDB } from './db/mongo';
4
+ import type PQueue from 'p-queue';
5
+ export type GPTConfig = {
6
+ openai?: OpenAI;
7
+ system?: string;
8
+ model?: ChatCompletionCreateParamsNonStreaming['model'] | 'gpt-4-1106-preview' | 'gpt-3.5-turbo-1106';
9
+ db?: AIDB;
10
+ queue?: PQueue;
11
+ } & ClientOptions;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,9 @@
1
+ import { OpenAI } from 'openai';
2
+ import type { ChatCompletionCreateParamsNonStreaming } from 'openai/resources';
3
+ import { GPTConfig } from '../types';
4
+ export type CompletionInput = GPTConfig & ((({
5
+ user: string;
6
+ } | {
7
+ list: string;
8
+ }) & Partial<ChatCompletionCreateParamsNonStreaming>) | ChatCompletionCreateParamsNonStreaming);
9
+ export declare const chatCompletion: (config: CompletionInput) => Promise<OpenAI.Chat.Completions.ChatCompletion>;
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __rest = (this && this.__rest) || function (s, e) {
12
+ var t = {};
13
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
14
+ t[p] = s[p];
15
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
16
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
17
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
18
+ t[p[i]] = s[p[i]];
19
+ }
20
+ return t;
21
+ };
22
+ Object.defineProperty(exports, "__esModule", { value: true });
23
+ exports.chatCompletion = void 0;
24
+ const openai_1 = require("openai");
25
+ // TODO: add support for list input and parsing
26
+ // TODO: add support for caching w/ seed generation for unit tests
27
+ const chatCompletion = (config) => __awaiter(void 0, void 0, void 0, function* () {
28
+ var _a;
29
+ const { user, system, model, db, queue } = config, rest = __rest(config, ["user", "system", "model", "db", "queue"]);
30
+ const openai = (_a = config.openai) !== null && _a !== void 0 ? _a : new openai_1.OpenAI(rest);
31
+ const prompt = {
32
+ model,
33
+ messages: [{ role: 'user', content: user }],
34
+ };
35
+ if (system)
36
+ prompt.messages.unshift({ role: 'system', content: system });
37
+ const completion = queue
38
+ ? yield queue.add(() => openai.chat.completions.create(prompt))
39
+ : yield openai.chat.completions.create(prompt);
40
+ if (db) {
41
+ db.log(prompt, completion);
42
+ }
43
+ return completion;
44
+ });
45
+ exports.chatCompletion = chatCompletion;
@@ -0,0 +1,10 @@
1
+ import { JSONSchema } from 'json-schema-to-ts';
2
+ export declare const parseStringDescription: (description: string) => JSONSchema;
3
+ /**
4
+ * Given a property description object, generate a JSON schema.
5
+ *
6
+ * @param propDescriptions - A record object with keys as property names
7
+ * and values as descriptions or nested property description objects.
8
+ * @returns A JSON schema object based on the provided descriptions.
9
+ */
10
+ export declare const generateSchema: (propDescriptions: Record<string, string | Record<string, any>>) => JSONSchema;