@sprucelabs/sprucebot-llm 15.1.1 → 15.1.3
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/AnthropicAdapter.js +19 -4
- package/build/bots/adapters/MessageBuilder.d.ts +5 -1
- package/build/bots/adapters/MessageBuilder.js +10 -3
- package/build/bots/adapters/MessageSender.d.ts +8 -4
- package/build/bots/adapters/OpenAiAdapter.js +2 -0
- package/build/esm/bots/adapters/AnthropicAdapter.js +19 -4
- package/build/esm/bots/adapters/MessageBuilder.d.ts +5 -1
- package/build/esm/bots/adapters/MessageBuilder.js +10 -3
- package/build/esm/bots/adapters/MessageSender.d.ts +8 -4
- package/build/esm/bots/adapters/OpenAiAdapter.js +2 -0
- package/build/esm/parsingResponses/ResponseParserV2.js +1 -1
- package/build/parsingResponses/ResponseParserV2.js +1 -1
- package/package.json +1 -1
|
@@ -37,11 +37,26 @@ class AnthropicAdapter {
|
|
|
37
37
|
async sendHandler(params, sendOptions) {
|
|
38
38
|
const { messages: openAiMessages, model } = params;
|
|
39
39
|
const messages = [];
|
|
40
|
+
const cacheMarkerIdx = openAiMessages.findIndex((msg) => msg.cache_marker);
|
|
40
41
|
for (const msg of openAiMessages) {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
if (!msg.cache_marker) {
|
|
43
|
+
const m = msg;
|
|
44
|
+
messages.push({
|
|
45
|
+
role: m.role === 'assistant' ? 'assistant' : 'user',
|
|
46
|
+
content: m.content,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
if (cacheMarkerIdx > -1) {
|
|
51
|
+
messages[cacheMarkerIdx - 1].content = [
|
|
52
|
+
{
|
|
53
|
+
type: 'text',
|
|
54
|
+
text: messages[cacheMarkerIdx - 1].content,
|
|
55
|
+
cache_control: {
|
|
56
|
+
type: 'ephemeral',
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
];
|
|
45
60
|
}
|
|
46
61
|
const response = await this.api.messages.create({
|
|
47
62
|
max_tokens: this.maxTokens,
|
|
@@ -6,7 +6,7 @@ export default class MessageBuilder {
|
|
|
6
6
|
protected constructor(bot: SprucebotLlmBot, options?: BuildMessageOptions);
|
|
7
7
|
static Builder(bot: SprucebotLlmBot, options?: BuildMessageOptions): MessageBuilder;
|
|
8
8
|
private get parser();
|
|
9
|
-
buildMessages():
|
|
9
|
+
buildMessages(): MessageBuilderMessage[];
|
|
10
10
|
private buildChatHistoryMessages;
|
|
11
11
|
private mapMessageToCompletion;
|
|
12
12
|
private maxCharsOfPastMessages;
|
|
@@ -23,4 +23,8 @@ export default class MessageBuilder {
|
|
|
23
23
|
interface BuildMessageOptions {
|
|
24
24
|
memoryLimit?: number;
|
|
25
25
|
}
|
|
26
|
+
export interface MessageBuilderCacheMarker {
|
|
27
|
+
cache_marker: true;
|
|
28
|
+
}
|
|
29
|
+
export type MessageBuilderMessage = ChatCompletionMessageParam | MessageBuilderCacheMarker;
|
|
26
30
|
export {};
|
|
@@ -26,6 +26,12 @@ class MessageBuilder {
|
|
|
26
26
|
...this.buildSkillMessages(values.skill),
|
|
27
27
|
...this.buildChatHistoryMessages(values.messages),
|
|
28
28
|
];
|
|
29
|
+
if (!values.skill) {
|
|
30
|
+
const first = allMessages[0];
|
|
31
|
+
allMessages.shift();
|
|
32
|
+
allMessages.unshift({ cache_marker: true });
|
|
33
|
+
allMessages.unshift(first);
|
|
34
|
+
}
|
|
29
35
|
return allMessages;
|
|
30
36
|
}
|
|
31
37
|
buildChatHistoryMessages(messages) {
|
|
@@ -99,9 +105,6 @@ class MessageBuilder {
|
|
|
99
105
|
if (skill.stateSchema) {
|
|
100
106
|
messages.push(this.buildStateSchemaMessage(skill.stateSchema));
|
|
101
107
|
}
|
|
102
|
-
if (skill.state) {
|
|
103
|
-
messages.push(this.buildStateMessage(skill.state));
|
|
104
|
-
}
|
|
105
108
|
if (skill.weAreDoneWhen) {
|
|
106
109
|
messages.push(this.buildWeAreDoneWhenMessage(skill.weAreDoneWhen));
|
|
107
110
|
}
|
|
@@ -111,6 +114,10 @@ class MessageBuilder {
|
|
|
111
114
|
if (skill.pleaseKeepInMindThat) {
|
|
112
115
|
messages.push(this.buildPleaseKeepInMindMessage(skill.pleaseKeepInMindThat));
|
|
113
116
|
}
|
|
117
|
+
messages.push({ cache_marker: true });
|
|
118
|
+
if (skill.state) {
|
|
119
|
+
messages.push(this.buildStateMessage(skill.state));
|
|
120
|
+
}
|
|
114
121
|
return messages;
|
|
115
122
|
}
|
|
116
123
|
buildCallbacksMessage(callbacks) {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Log } from '@sprucelabs/spruce-skill-utils';
|
|
2
|
-
import OpenAI from 'openai';
|
|
3
2
|
import { RequestOptions } from 'openai/internal/request-options';
|
|
4
|
-
import { ReasoningEffort
|
|
3
|
+
import { ReasoningEffort } from 'openai/resources';
|
|
5
4
|
import { SprucebotLlmBot, SendMessageOptions } from '../../llm.types';
|
|
5
|
+
import { MessageBuilderMessage } from './MessageBuilder';
|
|
6
6
|
export default class MessageSenderImpl implements MessageSender {
|
|
7
7
|
static AbortController: {
|
|
8
8
|
new (): AbortController;
|
|
@@ -18,12 +18,16 @@ export default class MessageSenderImpl implements MessageSender {
|
|
|
18
18
|
private send;
|
|
19
19
|
}
|
|
20
20
|
export type MessageSenderSendOptions = SendMessageOptions & {
|
|
21
|
-
messages:
|
|
21
|
+
messages: MessageBuilderMessage[];
|
|
22
22
|
reasoningEffort?: ReasoningEffort;
|
|
23
23
|
model: string;
|
|
24
24
|
abortController: AbortController;
|
|
25
25
|
};
|
|
26
|
-
export
|
|
26
|
+
export interface MessageHandlerSendHandlerParams {
|
|
27
|
+
model: string;
|
|
28
|
+
messages: MessageBuilderMessage[];
|
|
29
|
+
}
|
|
30
|
+
export type MessageSenderSendHandler = (params: MessageHandlerSendHandlerParams, options: RequestOptions) => Promise<string | undefined>;
|
|
27
31
|
export interface MessageSender {
|
|
28
32
|
sendMessage(bot: SprucebotLlmBot, options: MessageSenderSendMessageOptions): Promise<string>;
|
|
29
33
|
}
|
|
@@ -30,6 +30,8 @@ class OpenAiAdapter {
|
|
|
30
30
|
});
|
|
31
31
|
}
|
|
32
32
|
async sendHandler(params, sendOptions) {
|
|
33
|
+
const { messages } = params;
|
|
34
|
+
params.messages = messages.filter((msg) => !msg.cache_marker);
|
|
33
35
|
const response = await this.api.chat.completions.create(params, sendOptions);
|
|
34
36
|
const responseMessage = response.choices?.[0]?.message?.content?.trim();
|
|
35
37
|
return responseMessage;
|
|
@@ -42,11 +42,26 @@ class AnthropicAdapter {
|
|
|
42
42
|
var _a, _b;
|
|
43
43
|
const { messages: openAiMessages, model } = params;
|
|
44
44
|
const messages = [];
|
|
45
|
+
const cacheMarkerIdx = openAiMessages.findIndex((msg) => msg.cache_marker);
|
|
45
46
|
for (const msg of openAiMessages) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
if (!msg.cache_marker) {
|
|
48
|
+
const m = msg;
|
|
49
|
+
messages.push({
|
|
50
|
+
role: m.role === 'assistant' ? 'assistant' : 'user',
|
|
51
|
+
content: m.content,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (cacheMarkerIdx > -1) {
|
|
56
|
+
messages[cacheMarkerIdx - 1].content = [
|
|
57
|
+
{
|
|
58
|
+
type: 'text',
|
|
59
|
+
text: messages[cacheMarkerIdx - 1].content,
|
|
60
|
+
cache_control: {
|
|
61
|
+
type: 'ephemeral',
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
];
|
|
50
65
|
}
|
|
51
66
|
const response = yield this.api.messages.create({
|
|
52
67
|
max_tokens: this.maxTokens,
|
|
@@ -6,7 +6,7 @@ export default class MessageBuilder {
|
|
|
6
6
|
protected constructor(bot: SprucebotLlmBot, options?: BuildMessageOptions);
|
|
7
7
|
static Builder(bot: SprucebotLlmBot, options?: BuildMessageOptions): MessageBuilder;
|
|
8
8
|
private get parser();
|
|
9
|
-
buildMessages():
|
|
9
|
+
buildMessages(): MessageBuilderMessage[];
|
|
10
10
|
private buildChatHistoryMessages;
|
|
11
11
|
private mapMessageToCompletion;
|
|
12
12
|
private maxCharsOfPastMessages;
|
|
@@ -23,4 +23,8 @@ export default class MessageBuilder {
|
|
|
23
23
|
interface BuildMessageOptions {
|
|
24
24
|
memoryLimit?: number;
|
|
25
25
|
}
|
|
26
|
+
export interface MessageBuilderCacheMarker {
|
|
27
|
+
cache_marker: true;
|
|
28
|
+
}
|
|
29
|
+
export type MessageBuilderMessage = ChatCompletionMessageParam | MessageBuilderCacheMarker;
|
|
26
30
|
export {};
|
|
@@ -21,6 +21,12 @@ export default class MessageBuilder {
|
|
|
21
21
|
...this.buildSkillMessages(values.skill),
|
|
22
22
|
...this.buildChatHistoryMessages(values.messages),
|
|
23
23
|
];
|
|
24
|
+
if (!values.skill) {
|
|
25
|
+
const first = allMessages[0];
|
|
26
|
+
allMessages.shift();
|
|
27
|
+
allMessages.unshift({ cache_marker: true });
|
|
28
|
+
allMessages.unshift(first);
|
|
29
|
+
}
|
|
24
30
|
return allMessages;
|
|
25
31
|
}
|
|
26
32
|
buildChatHistoryMessages(messages) {
|
|
@@ -95,9 +101,6 @@ export default class MessageBuilder {
|
|
|
95
101
|
if (skill.stateSchema) {
|
|
96
102
|
messages.push(this.buildStateSchemaMessage(skill.stateSchema));
|
|
97
103
|
}
|
|
98
|
-
if (skill.state) {
|
|
99
|
-
messages.push(this.buildStateMessage(skill.state));
|
|
100
|
-
}
|
|
101
104
|
if (skill.weAreDoneWhen) {
|
|
102
105
|
messages.push(this.buildWeAreDoneWhenMessage(skill.weAreDoneWhen));
|
|
103
106
|
}
|
|
@@ -107,6 +110,10 @@ export default class MessageBuilder {
|
|
|
107
110
|
if (skill.pleaseKeepInMindThat) {
|
|
108
111
|
messages.push(this.buildPleaseKeepInMindMessage(skill.pleaseKeepInMindThat));
|
|
109
112
|
}
|
|
113
|
+
messages.push({ cache_marker: true });
|
|
114
|
+
if (skill.state) {
|
|
115
|
+
messages.push(this.buildStateMessage(skill.state));
|
|
116
|
+
}
|
|
110
117
|
return messages;
|
|
111
118
|
}
|
|
112
119
|
buildCallbacksMessage(callbacks) {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Log } from '@sprucelabs/spruce-skill-utils';
|
|
2
|
-
import OpenAI from 'openai';
|
|
3
2
|
import { RequestOptions } from 'openai/internal/request-options';
|
|
4
|
-
import { ReasoningEffort
|
|
3
|
+
import { ReasoningEffort } from 'openai/resources';
|
|
5
4
|
import { SprucebotLlmBot, SendMessageOptions } from '../../llm.types';
|
|
5
|
+
import { MessageBuilderMessage } from './MessageBuilder';
|
|
6
6
|
export default class MessageSenderImpl implements MessageSender {
|
|
7
7
|
static AbortController: {
|
|
8
8
|
new (): AbortController;
|
|
@@ -18,12 +18,16 @@ export default class MessageSenderImpl implements MessageSender {
|
|
|
18
18
|
private send;
|
|
19
19
|
}
|
|
20
20
|
export type MessageSenderSendOptions = SendMessageOptions & {
|
|
21
|
-
messages:
|
|
21
|
+
messages: MessageBuilderMessage[];
|
|
22
22
|
reasoningEffort?: ReasoningEffort;
|
|
23
23
|
model: string;
|
|
24
24
|
abortController: AbortController;
|
|
25
25
|
};
|
|
26
|
-
export
|
|
26
|
+
export interface MessageHandlerSendHandlerParams {
|
|
27
|
+
model: string;
|
|
28
|
+
messages: MessageBuilderMessage[];
|
|
29
|
+
}
|
|
30
|
+
export type MessageSenderSendHandler = (params: MessageHandlerSendHandlerParams, options: RequestOptions) => Promise<string | undefined>;
|
|
27
31
|
export interface MessageSender {
|
|
28
32
|
sendMessage(bot: SprucebotLlmBot, options: MessageSenderSendMessageOptions): Promise<string>;
|
|
29
33
|
}
|
|
@@ -33,6 +33,8 @@ class OpenAiAdapter {
|
|
|
33
33
|
sendHandler(params, sendOptions) {
|
|
34
34
|
return __awaiter(this, void 0, void 0, function* () {
|
|
35
35
|
var _a, _b, _c, _d;
|
|
36
|
+
const { messages } = params;
|
|
37
|
+
params.messages = messages.filter((msg) => !msg.cache_marker);
|
|
36
38
|
const response = yield this.api.chat.completions.create(params, sendOptions);
|
|
37
39
|
const responseMessage = (_d = (_c = (_b = (_a = response.choices) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.message) === null || _c === void 0 ? void 0 : _c.content) === null || _d === void 0 ? void 0 : _d.trim();
|
|
38
40
|
return responseMessage;
|
|
@@ -98,6 +98,6 @@ export default class ResponseParserV2 {
|
|
|
98
98
|
return 'Updating state works similar to all function calls. Use the following syntax:\n@updateState { "updates": "here" }\n. Make sure to json encode only the fields you want to change. You can update state once and do it at the end of any messages you send. IMPORTANT: JSON must be on a single line. Do NOT use multi-line or formatted JSON.';
|
|
99
99
|
}
|
|
100
100
|
getFunctionCallInstructions() {
|
|
101
|
-
return `A function call is done using the following syntax:\n@callback { "name": "callbackName", "options": {} }\nMake sure to json encode the options and include the name of the callback you want to call. You can call as many callbacks as you want in a single response by including multiple @callback lines. IMPORTANT: JSON must be on a single line. Do NOT use multi-line or formatted JSON
|
|
101
|
+
return `A function call is done using the following syntax:\n@callback { "name": "callbackName", "options": {} }\nMake sure to json encode the options and include the name of the callback you want to call. You can call as many callbacks as you want in a single response by including multiple @callback lines. IMPORTANT: JSON must be on a single line. Do NOT use multi-line or formatted JSON. Also, do NOT call something like @myCallback. You would call it like this: @callback { "name": "myCallback", "options": {} }`;
|
|
102
102
|
}
|
|
103
103
|
}
|
|
@@ -90,7 +90,7 @@ class ResponseParserV2 {
|
|
|
90
90
|
return 'Updating state works similar to all function calls. Use the following syntax:\n@updateState { "updates": "here" }\n. Make sure to json encode only the fields you want to change. You can update state once and do it at the end of any messages you send. IMPORTANT: JSON must be on a single line. Do NOT use multi-line or formatted JSON.';
|
|
91
91
|
}
|
|
92
92
|
getFunctionCallInstructions() {
|
|
93
|
-
return `A function call is done using the following syntax:\n@callback { "name": "callbackName", "options": {} }\nMake sure to json encode the options and include the name of the callback you want to call. You can call as many callbacks as you want in a single response by including multiple @callback lines. IMPORTANT: JSON must be on a single line. Do NOT use multi-line or formatted JSON
|
|
93
|
+
return `A function call is done using the following syntax:\n@callback { "name": "callbackName", "options": {} }\nMake sure to json encode the options and include the name of the callback you want to call. You can call as many callbacks as you want in a single response by including multiple @callback lines. IMPORTANT: JSON must be on a single line. Do NOT use multi-line or formatted JSON. Also, do NOT call something like @myCallback. You would call it like this: @callback { "name": "myCallback", "options": {} }`;
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
96
|
exports.default = ResponseParserV2;
|