@sprucelabs/sprucebot-llm 11.1.20 → 11.3.0
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/build/bots/adapters/OpenAiMessageBuilder.d.ts +2 -0
- package/build/bots/adapters/OpenAiMessageBuilder.js +30 -8
- package/build/bots/templates.d.ts +1 -1
- package/build/bots/templates.js +1 -1
- package/build/esm/bots/adapters/OpenAiMessageBuilder.d.ts +2 -0
- package/build/esm/bots/adapters/OpenAiMessageBuilder.js +31 -8
- package/build/esm/bots/templates.d.ts +1 -1
- package/build/esm/bots/templates.js +1 -1
- package/package.json +1 -1
|
@@ -7,6 +7,8 @@ export default class OpenAiMessageBuilder {
|
|
|
7
7
|
buildMessages(): ChatCompletionMessageParam[];
|
|
8
8
|
private buildChatHistoryMessages;
|
|
9
9
|
private mapMessageToCompletion;
|
|
10
|
+
private maxCharsOfPastMessages;
|
|
11
|
+
private shouldRememberImages;
|
|
10
12
|
private buildFirstMessage;
|
|
11
13
|
private buildSkillMessages;
|
|
12
14
|
private buildCallbacksMessage;
|
|
@@ -23,9 +23,10 @@ class OpenAiMessageBuilder {
|
|
|
23
23
|
if (limit > 0) {
|
|
24
24
|
messagesBeingConsidered = messages.slice(Math.max(messages.length - limit, 0));
|
|
25
25
|
}
|
|
26
|
-
|
|
26
|
+
const total = messagesBeingConsidered.length;
|
|
27
|
+
return messagesBeingConsidered.map((message, idx) => this.mapMessageToCompletion(message, idx === total - 1));
|
|
27
28
|
}
|
|
28
|
-
mapMessageToCompletion(message) {
|
|
29
|
+
mapMessageToCompletion(message, isLast) {
|
|
29
30
|
let content = message.message;
|
|
30
31
|
let role = message.from === 'Me'
|
|
31
32
|
? 'user'
|
|
@@ -34,24 +35,45 @@ class OpenAiMessageBuilder {
|
|
|
34
35
|
: 'developer';
|
|
35
36
|
if (message.imageBase64) {
|
|
36
37
|
role = 'user';
|
|
38
|
+
const shouldBeIncluded = this.shouldRememberImages() || isLast;
|
|
37
39
|
content = [
|
|
38
40
|
{
|
|
39
41
|
type: 'text',
|
|
40
42
|
text: message.message,
|
|
41
43
|
},
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
shouldBeIncluded
|
|
45
|
+
? {
|
|
46
|
+
type: 'image_url',
|
|
47
|
+
image_url: {
|
|
48
|
+
url: `data:image/png;base64,${message.imageBase64}`,
|
|
49
|
+
},
|
|
50
|
+
}
|
|
51
|
+
: {
|
|
52
|
+
type: 'text',
|
|
53
|
+
text: '[Image omitted to save context]',
|
|
46
54
|
},
|
|
47
|
-
},
|
|
48
55
|
];
|
|
49
56
|
}
|
|
57
|
+
const shouldTruncate = typeof content === 'string' &&
|
|
58
|
+
!isLast &&
|
|
59
|
+
this.maxCharsOfPastMessages() > 0 &&
|
|
60
|
+
content.length > this.maxCharsOfPastMessages();
|
|
61
|
+
if (shouldTruncate) {
|
|
62
|
+
content = `[omitted due to length]`;
|
|
63
|
+
}
|
|
50
64
|
return {
|
|
51
65
|
role,
|
|
52
66
|
content,
|
|
53
67
|
};
|
|
54
68
|
}
|
|
69
|
+
maxCharsOfPastMessages() {
|
|
70
|
+
return process.env.OPENAI_PAST_MESSAGE_MAX_CHARS
|
|
71
|
+
? parseInt(process.env.OPENAI_PAST_MESSAGE_MAX_CHARS ?? '1000', 10)
|
|
72
|
+
: -1;
|
|
73
|
+
}
|
|
74
|
+
shouldRememberImages() {
|
|
75
|
+
return process.env.OPENAI_SHOULD_REMEMBER_IMAGES !== 'false';
|
|
76
|
+
}
|
|
55
77
|
buildFirstMessage(youAre) {
|
|
56
78
|
return {
|
|
57
79
|
role: 'developer',
|
|
@@ -131,7 +153,7 @@ class OpenAiMessageBuilder {
|
|
|
131
153
|
buildStateMessage(state) {
|
|
132
154
|
return {
|
|
133
155
|
role: 'developer',
|
|
134
|
-
content: `The current state of this conversation is:\n\n${JSON.stringify(state)}. As the state is being updated, send it back to me in json format (something in can JSON.parse()) at the end of each response (it's not meant for reading, but for parsing, so don't call it out, but send it as we progress), surrounded by
|
|
156
|
+
content: `The current state of this conversation is:\n\n${JSON.stringify(state)}. As the state is being updated, send it back to me in json format (something in can JSON.parse()) at the end of each response (it's not meant for reading, but for parsing, so don't call it out, but send it as we progress), surrounded by the State Boundary (${templates_1.STATE_BOUNDARY}), like this:\n\n${templates_1.STATE_BOUNDARY} { "fieldName": "fieldValue" } ${templates_1.STATE_BOUNDARY}`,
|
|
135
157
|
};
|
|
136
158
|
}
|
|
137
159
|
buildYourJobMessage(yourJob) {
|
package/build/bots/templates.js
CHANGED
|
@@ -5,7 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.PROMPT_TEMPLATE = exports.CALLBACK_BOUNDARY = exports.DONE_TOKEN = exports.STATE_BOUNDARY = void 0;
|
|
7
7
|
const renderPlaceholder_1 = __importDefault(require("../parsingResponses/renderPlaceholder"));
|
|
8
|
-
exports.STATE_BOUNDARY = '
|
|
8
|
+
exports.STATE_BOUNDARY = '*** STATE BOUNDARY ***';
|
|
9
9
|
exports.DONE_TOKEN = `DONE_DONE_DONE`;
|
|
10
10
|
exports.CALLBACK_BOUNDARY = 'xxxxx';
|
|
11
11
|
exports.PROMPT_TEMPLATE = `You are <%= it.youAre %>
|
|
@@ -7,6 +7,8 @@ export default class OpenAiMessageBuilder {
|
|
|
7
7
|
buildMessages(): ChatCompletionMessageParam[];
|
|
8
8
|
private buildChatHistoryMessages;
|
|
9
9
|
private mapMessageToCompletion;
|
|
10
|
+
private maxCharsOfPastMessages;
|
|
11
|
+
private shouldRememberImages;
|
|
10
12
|
private buildFirstMessage;
|
|
11
13
|
private buildSkillMessages;
|
|
12
14
|
private buildCallbacksMessage;
|
|
@@ -22,9 +22,10 @@ export default class OpenAiMessageBuilder {
|
|
|
22
22
|
if (limit > 0) {
|
|
23
23
|
messagesBeingConsidered = messages.slice(Math.max(messages.length - limit, 0));
|
|
24
24
|
}
|
|
25
|
-
|
|
25
|
+
const total = messagesBeingConsidered.length;
|
|
26
|
+
return messagesBeingConsidered.map((message, idx) => this.mapMessageToCompletion(message, idx === total - 1));
|
|
26
27
|
}
|
|
27
|
-
mapMessageToCompletion(message) {
|
|
28
|
+
mapMessageToCompletion(message, isLast) {
|
|
28
29
|
let content = message.message;
|
|
29
30
|
let role = message.from === 'Me'
|
|
30
31
|
? 'user'
|
|
@@ -33,24 +34,46 @@ export default class OpenAiMessageBuilder {
|
|
|
33
34
|
: 'developer';
|
|
34
35
|
if (message.imageBase64) {
|
|
35
36
|
role = 'user';
|
|
37
|
+
const shouldBeIncluded = this.shouldRememberImages() || isLast;
|
|
36
38
|
content = [
|
|
37
39
|
{
|
|
38
40
|
type: 'text',
|
|
39
41
|
text: message.message,
|
|
40
42
|
},
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
shouldBeIncluded
|
|
44
|
+
? {
|
|
45
|
+
type: 'image_url',
|
|
46
|
+
image_url: {
|
|
47
|
+
url: `data:image/png;base64,${message.imageBase64}`,
|
|
48
|
+
},
|
|
49
|
+
}
|
|
50
|
+
: {
|
|
51
|
+
type: 'text',
|
|
52
|
+
text: '[Image omitted to save context]',
|
|
45
53
|
},
|
|
46
|
-
},
|
|
47
54
|
];
|
|
48
55
|
}
|
|
56
|
+
const shouldTruncate = typeof content === 'string' &&
|
|
57
|
+
!isLast &&
|
|
58
|
+
this.maxCharsOfPastMessages() > 0 &&
|
|
59
|
+
content.length > this.maxCharsOfPastMessages();
|
|
60
|
+
if (shouldTruncate) {
|
|
61
|
+
content = `[omitted due to length]`;
|
|
62
|
+
}
|
|
49
63
|
return {
|
|
50
64
|
role,
|
|
51
65
|
content,
|
|
52
66
|
};
|
|
53
67
|
}
|
|
68
|
+
maxCharsOfPastMessages() {
|
|
69
|
+
var _a;
|
|
70
|
+
return process.env.OPENAI_PAST_MESSAGE_MAX_CHARS
|
|
71
|
+
? parseInt((_a = process.env.OPENAI_PAST_MESSAGE_MAX_CHARS) !== null && _a !== void 0 ? _a : '1000', 10)
|
|
72
|
+
: -1;
|
|
73
|
+
}
|
|
74
|
+
shouldRememberImages() {
|
|
75
|
+
return process.env.OPENAI_SHOULD_REMEMBER_IMAGES !== 'false';
|
|
76
|
+
}
|
|
54
77
|
buildFirstMessage(youAre) {
|
|
55
78
|
return {
|
|
56
79
|
role: 'developer',
|
|
@@ -130,7 +153,7 @@ export default class OpenAiMessageBuilder {
|
|
|
130
153
|
buildStateMessage(state) {
|
|
131
154
|
return {
|
|
132
155
|
role: 'developer',
|
|
133
|
-
content: `The current state of this conversation is:\n\n${JSON.stringify(state)}. As the state is being updated, send it back to me in json format (something in can JSON.parse()) at the end of each response (it's not meant for reading, but for parsing, so don't call it out, but send it as we progress), surrounded by
|
|
156
|
+
content: `The current state of this conversation is:\n\n${JSON.stringify(state)}. As the state is being updated, send it back to me in json format (something in can JSON.parse()) at the end of each response (it's not meant for reading, but for parsing, so don't call it out, but send it as we progress), surrounded by the State Boundary (${STATE_BOUNDARY}), like this:\n\n${STATE_BOUNDARY} { "fieldName": "fieldValue" } ${STATE_BOUNDARY}`,
|
|
134
157
|
};
|
|
135
158
|
}
|
|
136
159
|
buildYourJobMessage(yourJob) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import renderPlaceholder from '../parsingResponses/renderPlaceholder.js';
|
|
2
|
-
export const STATE_BOUNDARY = '
|
|
2
|
+
export const STATE_BOUNDARY = '*** STATE BOUNDARY ***';
|
|
3
3
|
export const DONE_TOKEN = `DONE_DONE_DONE`;
|
|
4
4
|
export const CALLBACK_BOUNDARY = 'xxxxx';
|
|
5
5
|
export const PROMPT_TEMPLATE = `You are <%= it.youAre %>
|