@sprucelabs/sprucebot-llm 0.0.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.
Files changed (85) hide show
  1. package/README.md +148 -0
  2. package/build/.spruce/errors/errors.types.d.ts +13 -0
  3. package/build/.spruce/errors/errors.types.js +4 -0
  4. package/build/.spruce/errors/options.types.d.ts +7 -0
  5. package/build/.spruce/errors/options.types.js +2 -0
  6. package/build/.spruce/errors/sprucebotLlm/noBotInstanceSet.schema.d.ts +3 -0
  7. package/build/.spruce/errors/sprucebotLlm/noBotInstanceSet.schema.js +11 -0
  8. package/build/.spruce/schemas/fields/fieldClassMap.d.ts +2 -0
  9. package/build/.spruce/schemas/fields/fieldClassMap.js +4 -0
  10. package/build/.spruce/schemas/fields/fields.types.d.ts +1 -0
  11. package/build/.spruce/schemas/fields/fields.types.js +2 -0
  12. package/build/.spruce/settings.json +13 -0
  13. package/build/bots/PromptGenerator.d.ts +15 -0
  14. package/build/bots/PromptGenerator.js +84 -0
  15. package/build/bots/SprucebotLlmBotImpl.d.ts +18 -0
  16. package/build/bots/SprucebotLlmBotImpl.js +69 -0
  17. package/build/bots/SprucebotLlmFactory.d.ts +9 -0
  18. package/build/bots/SprucebotLlmFactory.js +35 -0
  19. package/build/bots/SprucebotLlmSkillImpl.d.ts +12 -0
  20. package/build/bots/SprucebotLlmSkillImpl.js +39 -0
  21. package/build/bots/adapters/OpenAi.d.ts +10 -0
  22. package/build/bots/adapters/OpenAi.js +32 -0
  23. package/build/bots/adapters/SpyOpenAiApi.d.ts +12 -0
  24. package/build/bots/adapters/SpyOpenAiApi.js +34 -0
  25. package/build/bots/templates.d.ts +4 -0
  26. package/build/bots/templates.js +74 -0
  27. package/build/chat.d.ts +1 -0
  28. package/build/chat.js +60 -0
  29. package/build/errors/SpruceError.d.ts +6 -0
  30. package/build/errors/SpruceError.js +25 -0
  31. package/build/errors/noBotInstanceSet.builder.d.ts +6 -0
  32. package/build/errors/noBotInstanceSet.builder.js +8 -0
  33. package/build/esm/.spruce/errors/errors.types.d.ts +13 -0
  34. package/build/esm/.spruce/errors/errors.types.js +3 -0
  35. package/build/esm/.spruce/errors/options.types.d.ts +7 -0
  36. package/build/esm/.spruce/errors/options.types.js +1 -0
  37. package/build/esm/bots/PromptGenerator.d.ts +15 -0
  38. package/build/esm/bots/PromptGenerator.js +67 -0
  39. package/build/esm/bots/SprucebotLlmBotImpl.d.ts +18 -0
  40. package/build/esm/bots/SprucebotLlmBotImpl.js +76 -0
  41. package/build/esm/bots/SprucebotLlmFactory.d.ts +9 -0
  42. package/build/esm/bots/SprucebotLlmFactory.js +29 -0
  43. package/build/esm/bots/SprucebotLlmSkillImpl.d.ts +12 -0
  44. package/build/esm/bots/SprucebotLlmSkillImpl.js +47 -0
  45. package/build/esm/bots/adapters/OpenAi.d.ts +10 -0
  46. package/build/esm/bots/adapters/OpenAi.js +36 -0
  47. package/build/esm/bots/adapters/SpyOpenAiApi.d.ts +12 -0
  48. package/build/esm/bots/adapters/SpyOpenAiApi.js +42 -0
  49. package/build/esm/bots/templates.d.ts +4 -0
  50. package/build/esm/bots/templates.js +68 -0
  51. package/build/esm/chat.d.ts +1 -0
  52. package/build/esm/chat.js +41 -0
  53. package/build/esm/errors/SpruceError.d.ts +6 -0
  54. package/build/esm/errors/SpruceError.js +19 -0
  55. package/build/esm/errors/noBotInstanceSet.builder.d.ts +6 -0
  56. package/build/esm/errors/noBotInstanceSet.builder.js +6 -0
  57. package/build/esm/examples/buildCallbackSkill.d.ts +2 -0
  58. package/build/esm/examples/buildCallbackSkill.js +28 -0
  59. package/build/esm/examples/buildJokeSkill.d.ts +2 -0
  60. package/build/esm/examples/buildJokeSkill.js +12 -0
  61. package/build/esm/examples/buildProfileSkill.d.ts +2 -0
  62. package/build/esm/examples/buildProfileSkill.js +29 -0
  63. package/build/esm/index.d.ts +0 -0
  64. package/build/esm/index.js +2 -0
  65. package/build/esm/llm.types.d.ts +61 -0
  66. package/build/esm/llm.types.js +6 -0
  67. package/build/esm/parsingResponses/ResponseParser.d.ts +15 -0
  68. package/build/esm/parsingResponses/ResponseParser.js +60 -0
  69. package/build/esm/parsingResponses/renderPlaceholder.d.ts +1 -0
  70. package/build/esm/parsingResponses/renderPlaceholder.js +4 -0
  71. package/build/examples/buildCallbackSkill.d.ts +2 -0
  72. package/build/examples/buildCallbackSkill.js +22 -0
  73. package/build/examples/buildJokeSkill.d.ts +2 -0
  74. package/build/examples/buildJokeSkill.js +15 -0
  75. package/build/examples/buildProfileSkill.d.ts +2 -0
  76. package/build/examples/buildProfileSkill.js +32 -0
  77. package/build/index.d.ts +0 -0
  78. package/build/index.js +2 -0
  79. package/build/llm.types.d.ts +61 -0
  80. package/build/llm.types.js +9 -0
  81. package/build/parsingResponses/ResponseParser.d.ts +15 -0
  82. package/build/parsingResponses/ResponseParser.js +53 -0
  83. package/build/parsingResponses/renderPlaceholder.d.ts +1 -0
  84. package/build/parsingResponses/renderPlaceholder.js +7 -0
  85. package/package.json +101 -0
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.PROMPT_TEMPLATE = exports.CALLBACK_BOUNDARY = exports.DONE_TOKEN = exports.STATE_BOUNDARY = void 0;
7
+ const renderPlaceholder_1 = __importDefault(require("../parsingResponses/renderPlaceholder"));
8
+ exports.STATE_BOUNDARY = '*****';
9
+ exports.DONE_TOKEN = `____ DONE ____`;
10
+ exports.CALLBACK_BOUNDARY = 'xxxxx';
11
+ exports.PROMPT_TEMPLATE = `You are <%= it.youAre %>
12
+
13
+
14
+ For this interaction, every message I send will start with "__Me__:" and I'll prompt you for your response by starting with "__You__:".
15
+
16
+ __Me__: Do you understand?
17
+ __You__: Yes
18
+
19
+ <% if (it.stateSchemaJson) { %>
20
+
21
+ Here is the schema that defines the state for this conversation:
22
+
23
+ <%= it.stateSchemaJson %>
24
+
25
+
26
+ Here is the current state, which is based on the schema above:
27
+
28
+ <%= it.stateJson %>
29
+
30
+
31
+ After each message, send the state in the form:
32
+
33
+ ${exports.STATE_BOUNDARY} <%= it.stateJson %> ${exports.STATE_BOUNDARY}
34
+
35
+ __Me__: Sound good?
36
+ __You__: Yup!
37
+
38
+ ${exports.STATE_BOUNDARY} <%= it.stateJson %> ${exports.STATE_BOUNDARY}
39
+
40
+ When asking me about a "select" field, make sure I only pick a valid choice by showing me their labels!<% } %>
41
+
42
+ <% if (it.skill) { %>
43
+
44
+ Your primary objective for this conversation is <%= it.skill.yourJobIfYouChooseToAcceptItIs %>
45
+ <% if (it.skill.callbacks) { %>
46
+ While we are talking, there are going to be things I don't want you to answer, but instead to respond with a placeholder in the form of ${(0, renderPlaceholder_1.default)('example')}.
47
+
48
+ Here are the placeholders we will be using:
49
+
50
+ <% Object.keys(it.skill.callbacks).forEach((key) => { %>
51
+ Whenever <%= it.skill.callbacks[key].useThisWhenever %>, respond with ${exports.CALLBACK_BOUNDARY} <%= key %> ${exports.CALLBACK_BOUNDARY}
52
+
53
+ <% }) %>
54
+ <% } %>
55
+ <% if (!it.stateSchemaJson && it.skill.weAreDoneWhen) { %>
56
+ We are done when <%= it.skill.weAreDoneWhen %> At that point, send me the following message so I know we are done:
57
+
58
+ ${exports.DONE_TOKEN}
59
+ <% } %>
60
+ <% } %>
61
+ <% if (it.stateSchemaJson) { %>
62
+
63
+ Once you have asked about every field in the schema, send me the following message so I know we're done:
64
+
65
+ ${exports.DONE_TOKEN}
66
+ <% } %>
67
+
68
+ Let's get started:
69
+
70
+ <% it.messages.forEach((message) => { %>
71
+ __<%= message.from %>__: <%= message.message %>
72
+
73
+ <% }) %>
74
+ __You__:`;
@@ -0,0 +1 @@
1
+ export {};
package/build/chat.js ADDED
@@ -0,0 +1,60 @@
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ const node_process_1 = require("node:process");
30
+ const readline = __importStar(require("node:readline/promises"));
31
+ const dotenv_1 = __importDefault(require("dotenv"));
32
+ const OpenAi_1 = require("./bots/adapters/OpenAi");
33
+ const SprucebotLlmFactory_1 = __importDefault(require("./bots/SprucebotLlmFactory"));
34
+ const buildCallbackSkill_1 = __importDefault(require("./examples/buildCallbackSkill"));
35
+ const buildJokeSkill_1 = __importDefault(require("./examples/buildJokeSkill"));
36
+ const buildProfileSkill_1 = __importDefault(require("./examples/buildProfileSkill"));
37
+ dotenv_1.default.config();
38
+ const rl = readline.createInterface({ input: node_process_1.stdin, output: node_process_1.stdout });
39
+ (async () => {
40
+ console.clear();
41
+ const adapter = new OpenAi_1.OpenAi(process.env.OPEN_AI_API_KEY);
42
+ const bots = SprucebotLlmFactory_1.default.Factory();
43
+ const skills = {
44
+ jokes: (0, buildJokeSkill_1.default)(bots),
45
+ profile: (0, buildProfileSkill_1.default)(bots),
46
+ callbacks: (0, buildCallbackSkill_1.default)(bots),
47
+ };
48
+ const bot = bots.Bot({
49
+ adapter,
50
+ skill: skills.callbacks,
51
+ youAre: "a bot named Sprucebot that is in test mode. At the start of every conversation, you introduce yourself and announce that you are in test mode so I don't get confused! You are both hip and adorable. You say things like, 'Jeepers' and 'Golly' or even 'Jeezey peezy'!",
52
+ });
53
+ do {
54
+ const input = await rl.question('Message > ');
55
+ const response = await bot.sendMessage(input);
56
+ console.log('>', response);
57
+ } while (!bot.getIsDone());
58
+ console.log('Signing off...');
59
+ rl.close();
60
+ })();
@@ -0,0 +1,6 @@
1
+ import BaseSpruceError from '@sprucelabs/error';
2
+ import ErrorOptions from "./../.spruce/errors/options.types";
3
+ export default class SpruceError extends BaseSpruceError<ErrorOptions> {
4
+ /** an easy to understand version of the errors */
5
+ friendlyMessage(): string;
6
+ }
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const error_1 = __importDefault(require("@sprucelabs/error"));
7
+ class SpruceError extends error_1.default {
8
+ /** an easy to understand version of the errors */
9
+ friendlyMessage() {
10
+ const { options } = this;
11
+ let message;
12
+ switch (options === null || options === void 0 ? void 0 : options.code) {
13
+ case 'NO_BOT_INSTANCE_SET':
14
+ message = `You must create a bot and set it using 'SprucebotLlmFactory.setInstance(bot)' before you can get an instance of it.`;
15
+ break;
16
+ default:
17
+ message = super.friendlyMessage();
18
+ }
19
+ const fullMessage = options.friendlyMessage
20
+ ? options.friendlyMessage
21
+ : message;
22
+ return fullMessage;
23
+ }
24
+ }
25
+ exports.default = SpruceError;
@@ -0,0 +1,6 @@
1
+ declare const _default: {
2
+ id: string;
3
+ name: string;
4
+ fields: {};
5
+ };
6
+ export default _default;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const schema_1 = require("@sprucelabs/schema");
4
+ exports.default = (0, schema_1.buildErrorSchema)({
5
+ id: 'noBotInstanceSet',
6
+ name: 'No bot instance set',
7
+ fields: {},
8
+ });
@@ -0,0 +1,13 @@
1
+ import { default as SchemaEntity } from '@sprucelabs/schema';
2
+ import * as SpruceSchema from '@sprucelabs/schema';
3
+ export declare namespace SpruceErrors.SprucebotLlm {
4
+ interface NoBotInstanceSet {
5
+ }
6
+ interface NoBotInstanceSetSchema extends SpruceSchema.Schema {
7
+ id: 'noBotInstanceSet';
8
+ namespace: 'SprucebotLlm';
9
+ name: 'No bot instance set';
10
+ fields: {};
11
+ }
12
+ type NoBotInstanceSetEntity = SchemaEntity<SpruceErrors.SprucebotLlm.NoBotInstanceSetSchema>;
13
+ }
@@ -0,0 +1,3 @@
1
+ /* eslint-disable @typescript-eslint/no-namespace */
2
+ /* eslint-disable no-redeclare */
3
+ export {};
@@ -0,0 +1,7 @@
1
+ import { SpruceErrors } from "./errors.types";
2
+ import { ErrorOptions as ISpruceErrorOptions } from "@sprucelabs/error";
3
+ export interface NoBotInstanceSetErrorOptions extends SpruceErrors.SprucebotLlm.NoBotInstanceSet, ISpruceErrorOptions {
4
+ code: 'NO_BOT_INSTANCE_SET';
5
+ }
6
+ type ErrorOptions = NoBotInstanceSetErrorOptions;
7
+ export default ErrorOptions;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,15 @@
1
+ import { LlmMessage, SprucebotLlmBot } from '../llm.types';
2
+ export default class PromptGenerator {
3
+ private bot;
4
+ private eta;
5
+ constructor(bot: SprucebotLlmBot);
6
+ generate(): Promise<string>;
7
+ private stringifyState;
8
+ }
9
+ export declare function setUndefinedToNull(obj: Record<string, any>): void;
10
+ export interface TemplateContext {
11
+ youAre: string;
12
+ messages: LlmMessage[];
13
+ stateSchemaJson?: string;
14
+ stateJson?: string;
15
+ }
@@ -0,0 +1,67 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ var __rest = (this && this.__rest) || function (s, e) {
11
+ var t = {};
12
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
13
+ t[p] = s[p];
14
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
15
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
16
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
17
+ t[p[i]] = s[p[i]];
18
+ }
19
+ return t;
20
+ };
21
+ import { assertOptions, normalizeSchemaValues, } from '@sprucelabs/schema';
22
+ import * as Eta from 'eta';
23
+ import { PROMPT_TEMPLATE } from './templates.js';
24
+ export default class PromptGenerator {
25
+ constructor(bot) {
26
+ this.eta = Eta;
27
+ assertOptions({ bot }, ['bot']);
28
+ this.bot = bot;
29
+ }
30
+ generate() {
31
+ return __awaiter(this, void 0, void 0, function* () {
32
+ const _a = this.bot.serialize(), { stateSchema, state } = _a, rest = __rest(_a, ["stateSchema", "state"]);
33
+ const { stateSchemaJson, stateJson } = this.stringifyState(stateSchema, state);
34
+ return yield this.eta.render(PROMPT_TEMPLATE, Object.assign({ stateSchemaJson,
35
+ stateJson }, rest), {
36
+ async: true,
37
+ autoEscape: false,
38
+ });
39
+ });
40
+ }
41
+ stringifyState(stateSchema, state) {
42
+ if (!stateSchema) {
43
+ return {
44
+ stateSchemaJson: null,
45
+ stateJson: null,
46
+ };
47
+ }
48
+ const normalizedState = normalizeSchemaValues(stateSchema, state !== null && state !== void 0 ? state : {}, {});
49
+ setUndefinedToNull(normalizedState);
50
+ const stateSchemaJson = JSON.stringify(stateSchema);
51
+ const stateJson = JSON.stringify(normalizedState);
52
+ return { stateSchemaJson, stateJson };
53
+ }
54
+ }
55
+ export function setUndefinedToNull(obj) {
56
+ for (const key in obj) {
57
+ // eslint-disable-next-line no-prototype-builtins
58
+ if (obj.hasOwnProperty(key)) {
59
+ if (obj[key] === undefined) {
60
+ obj[key] = null;
61
+ }
62
+ else if (typeof obj[key] === 'object') {
63
+ setUndefinedToNull(obj[key]);
64
+ }
65
+ }
66
+ }
67
+ }
@@ -0,0 +1,18 @@
1
+ import { AbstractEventEmitter } from '@sprucelabs/mercury-event-emitter';
2
+ import { Schema, SchemaValues } from '@sprucelabs/schema';
3
+ import { BotOptions, LlmEventContract, LlmMessage, SerializedBot, SprucebotLlmBot } from '../llm.types';
4
+ export default class SprucebotLlmBotImpl<StateSchema extends Schema = Schema, State extends SchemaValues<StateSchema> = SchemaValues<StateSchema>> extends AbstractEventEmitter<LlmEventContract> implements SprucebotLlmBot<StateSchema, State> {
5
+ private adapter;
6
+ private youAre;
7
+ private stateSchema?;
8
+ protected state?: Partial<State>;
9
+ private isDone;
10
+ protected messages: LlmMessage[];
11
+ private skill?;
12
+ constructor(options: BotOptions<StateSchema, State>);
13
+ markAsDone(): void;
14
+ getIsDone(): boolean;
15
+ serialize(): SerializedBot<StateSchema, State>;
16
+ sendMessage(message: string): Promise<string>;
17
+ updateState(newState: Partial<State>): Promise<void>;
18
+ }
@@ -0,0 +1,76 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { AbstractEventEmitter } from '@sprucelabs/mercury-event-emitter';
11
+ import { assertOptions, defaultSchemaValues, } from '@sprucelabs/schema';
12
+ import { llmEventContract, } from '../llm.types.js';
13
+ import ResponseParser from '../parsingResponses/ResponseParser.js';
14
+ export default class SprucebotLlmBotImpl extends AbstractEventEmitter {
15
+ constructor(options) {
16
+ const { adapter, youAre, stateSchema, state, skill } = options;
17
+ super(llmEventContract);
18
+ this.isDone = false;
19
+ this.messages = [];
20
+ this.adapter = adapter;
21
+ this.youAre = youAre;
22
+ this.stateSchema = stateSchema;
23
+ this.skill = skill;
24
+ this.state = stateSchema
25
+ ? Object.assign(Object.assign({}, defaultSchemaValues(stateSchema)), state)
26
+ : undefined;
27
+ }
28
+ markAsDone() {
29
+ this.isDone = true;
30
+ }
31
+ getIsDone() {
32
+ return this.isDone;
33
+ }
34
+ serialize() {
35
+ var _a, _b, _c;
36
+ const skill = (_a = this.skill) === null || _a === void 0 ? void 0 : _a.serialize();
37
+ return {
38
+ youAre: this.youAre,
39
+ stateSchema: (_b = this.stateSchema) !== null && _b !== void 0 ? _b : skill === null || skill === void 0 ? void 0 : skill.stateSchema,
40
+ state: (_c = this.state) !== null && _c !== void 0 ? _c : skill === null || skill === void 0 ? void 0 : skill.state,
41
+ messages: this.messages,
42
+ skill,
43
+ };
44
+ }
45
+ sendMessage(message) {
46
+ var _a, _b;
47
+ return __awaiter(this, void 0, void 0, function* () {
48
+ assertOptions({ message }, ['message']);
49
+ this.messages.push({
50
+ from: 'Me',
51
+ message,
52
+ });
53
+ const response = yield this.adapter.sendMessage(this);
54
+ const parser = ResponseParser.getInstance();
55
+ const { isDone, message: parsedResponse, state, } = yield parser.parse(response, (_a = this.skill) === null || _a === void 0 ? void 0 : _a.serialize().callbacks);
56
+ this.isDone = isDone;
57
+ if (this.stateSchema && state) {
58
+ yield this.updateState(state);
59
+ }
60
+ else if (state) {
61
+ yield ((_b = this.skill) === null || _b === void 0 ? void 0 : _b.updateState(state));
62
+ }
63
+ this.messages.push({
64
+ from: 'You',
65
+ message: parsedResponse,
66
+ });
67
+ return parsedResponse;
68
+ });
69
+ }
70
+ updateState(newState) {
71
+ return __awaiter(this, void 0, void 0, function* () {
72
+ this.state = Object.assign(Object.assign({}, this.state), newState);
73
+ yield this.emit('did-update-state');
74
+ });
75
+ }
76
+ }
@@ -0,0 +1,9 @@
1
+ import { BotOptions, SkillOptions, SprucebotLlmBot, SprucebotLLmSkill } from '../llm.types';
2
+ export default class SprucebotLlmFactory {
3
+ private instance?;
4
+ Bot(options: BotOptions): SprucebotLlmBot;
5
+ Skill(options: SkillOptions): SprucebotLLmSkill;
6
+ getBotInstance(): SprucebotLlmBot<import("@sprucelabs/schema").Schema, import("@sprucelabs/schema").SchemaStaticValues<import("@sprucelabs/schema").Schema, false, never, import("@sprucelabs/schema").StaticSchemaAllValues<import("@sprucelabs/schema").Schema, false>>>;
7
+ setBotInstance(bot: SprucebotLlmBot): void;
8
+ static Factory(): SprucebotLlmFactory;
9
+ }
@@ -0,0 +1,29 @@
1
+ import { assertOptions } from '@sprucelabs/schema';
2
+ import SpruceError from '../errors/SpruceError.js';
3
+ import SprucebotLlmBotImpl from './SprucebotLlmBotImpl.js';
4
+ import SprucebotLlmSkillImpl from './SprucebotLlmSkillImpl.js';
5
+ export default class SprucebotLlmFactory {
6
+ Bot(options) {
7
+ assertOptions(options, ['youAre', 'adapter']);
8
+ const { Class } = options;
9
+ return Class ? new Class(options) : new SprucebotLlmBotImpl(options);
10
+ }
11
+ Skill(options) {
12
+ assertOptions(options, ['yourJobIfYouChooseToAcceptItIs']);
13
+ return new SprucebotLlmSkillImpl(options);
14
+ }
15
+ getBotInstance() {
16
+ if (!this.instance) {
17
+ throw new SpruceError({
18
+ code: 'NO_BOT_INSTANCE_SET',
19
+ });
20
+ }
21
+ return this.instance;
22
+ }
23
+ setBotInstance(bot) {
24
+ this.instance = bot;
25
+ }
26
+ static Factory() {
27
+ return new this();
28
+ }
29
+ }
@@ -0,0 +1,12 @@
1
+ import { AbstractEventEmitter } from '@sprucelabs/mercury-event-emitter';
2
+ import { Schema, SchemaValues } from '@sprucelabs/schema';
3
+ import { LlmEventContract, SerializedSkill, SkillOptions, SprucebotLLmSkill } from '../llm.types';
4
+ export default class SprucebotLlmSkillImpl<StateSchema extends Schema = Schema, State extends SchemaValues<StateSchema> = SchemaValues<StateSchema>> extends AbstractEventEmitter<LlmEventContract> implements SprucebotLLmSkill<StateSchema, State> {
5
+ private options;
6
+ private state?;
7
+ private stateSchema?;
8
+ constructor(options: SkillOptions<StateSchema, State>);
9
+ updateState(updates: Partial<State>): Promise<void>;
10
+ getState(): Partial<State> | undefined;
11
+ serialize(): SerializedSkill<StateSchema, State>;
12
+ }
@@ -0,0 +1,47 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ var __rest = (this && this.__rest) || function (s, e) {
11
+ var t = {};
12
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
13
+ t[p] = s[p];
14
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
15
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
16
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
17
+ t[p[i]] = s[p[i]];
18
+ }
19
+ return t;
20
+ };
21
+ import { AbstractEventEmitter } from '@sprucelabs/mercury-event-emitter';
22
+ import { defaultSchemaValues } from '@sprucelabs/schema';
23
+ import { llmEventContract, } from '../llm.types.js';
24
+ export default class SprucebotLlmSkillImpl extends AbstractEventEmitter {
25
+ constructor(options) {
26
+ super(llmEventContract);
27
+ this.state = {};
28
+ const { state, stateSchema } = options, rest = __rest(options, ["state", "stateSchema"]);
29
+ this.options = Object.assign(Object.assign({}, rest), { stateSchema });
30
+ this.stateSchema = stateSchema;
31
+ this.state = stateSchema
32
+ ? Object.assign(Object.assign({}, defaultSchemaValues(stateSchema)), state)
33
+ : undefined;
34
+ }
35
+ updateState(updates) {
36
+ return __awaiter(this, void 0, void 0, function* () {
37
+ yield this.emit('did-update-state');
38
+ this.state = Object.assign(Object.assign({}, this.state), updates);
39
+ });
40
+ }
41
+ getState() {
42
+ return this.state;
43
+ }
44
+ serialize() {
45
+ return Object.assign(Object.assign({}, this.options), { stateSchema: this.stateSchema, state: this.state });
46
+ }
47
+ }
@@ -0,0 +1,10 @@
1
+ import { Configuration, OpenAIApi } from 'openai';
2
+ import { LlmAdapter, SprucebotLlmBot } from '../../llm.types';
3
+ export declare class OpenAi implements LlmAdapter {
4
+ static Configuration: typeof Configuration;
5
+ static OpenAIApi: typeof OpenAIApi;
6
+ private api;
7
+ constructor(apiKey: string);
8
+ sendMessage(bot: SprucebotLlmBot): Promise<string>;
9
+ }
10
+ export declare const MESSAGE_RESPONSE_ERROR_MESSAGE = "Oh no! Something went wrong and I can't talk right now!";
@@ -0,0 +1,36 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { assertOptions } from '@sprucelabs/schema';
11
+ import { Configuration, OpenAIApi } from 'openai';
12
+ import PromptGenerator from '../PromptGenerator.js';
13
+ export class OpenAi {
14
+ constructor(apiKey) {
15
+ assertOptions({ apiKey }, ['apiKey']);
16
+ const config = new OpenAi.Configuration({ apiKey });
17
+ this.api = new OpenAi.OpenAIApi(config);
18
+ }
19
+ sendMessage(bot) {
20
+ var _a, _b, _c;
21
+ return __awaiter(this, void 0, void 0, function* () {
22
+ const generator = new PromptGenerator(bot);
23
+ const prompt = yield generator.generate();
24
+ const response = yield this.api.createCompletion({
25
+ prompt,
26
+ model: 'text-davinci-003',
27
+ max_tokens: 100,
28
+ stop: ['__Me__:'],
29
+ });
30
+ return ((_c = (_b = (_a = response.data.choices[0]) === null || _a === void 0 ? void 0 : _a.text) === null || _b === void 0 ? void 0 : _b.trim()) !== null && _c !== void 0 ? _c : MESSAGE_RESPONSE_ERROR_MESSAGE);
31
+ });
32
+ }
33
+ }
34
+ OpenAi.Configuration = Configuration;
35
+ OpenAi.OpenAIApi = OpenAIApi;
36
+ export const MESSAGE_RESPONSE_ERROR_MESSAGE = "Oh no! Something went wrong and I can't talk right now!";
@@ -0,0 +1,12 @@
1
+ import { AxiosResponse } from 'axios';
2
+ import { Configuration, CreateCompletionRequest, CreateCompletionRequestPrompt, CreateCompletionResponse, OpenAIApi } from 'openai';
3
+ export default class SpyOpenAiApi extends OpenAIApi {
4
+ static config?: Configuration;
5
+ static lastMessage?: CreateCompletionRequestPrompt | null;
6
+ static lastModel?: string;
7
+ static responseMessage: string | false;
8
+ constructor(config: Configuration);
9
+ createCompletion(createCompletionRequest: CreateCompletionRequest): Promise<Response>;
10
+ }
11
+ type Response = AxiosResponse<CreateCompletionResponse, any>;
12
+ export {};
@@ -0,0 +1,42 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { OpenAIApi, } from 'openai';
11
+ export default class SpyOpenAiApi extends OpenAIApi {
12
+ constructor(config) {
13
+ super(config);
14
+ SpyOpenAiApi.config = config;
15
+ }
16
+ createCompletion(createCompletionRequest) {
17
+ return __awaiter(this, void 0, void 0, function* () {
18
+ SpyOpenAiApi.lastMessage = createCompletionRequest.prompt;
19
+ SpyOpenAiApi.lastModel = createCompletionRequest.model;
20
+ const choices = [];
21
+ if (SpyOpenAiApi.responseMessage) {
22
+ choices.push({
23
+ text: SpyOpenAiApi.responseMessage,
24
+ });
25
+ }
26
+ return {
27
+ config: {},
28
+ headers: {},
29
+ status: 200,
30
+ statusText: 'OK',
31
+ data: {
32
+ id: 'cmpl-1',
33
+ model: 'text-davinci-003',
34
+ created: 0,
35
+ object: 'text_completion',
36
+ choices,
37
+ },
38
+ };
39
+ });
40
+ }
41
+ }
42
+ SpyOpenAiApi.responseMessage = 'hello!';
@@ -0,0 +1,4 @@
1
+ export declare const STATE_BOUNDARY = "*****";
2
+ export declare const DONE_TOKEN = "____ DONE ____";
3
+ export declare const CALLBACK_BOUNDARY = "xxxxx";
4
+ export declare const PROMPT_TEMPLATE: string;