@sprucelabs/sprucebot-llm 15.1.2 → 15.1.4
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 +21 -5
- 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 +24 -8
- 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/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,
|
|
@@ -51,7 +66,8 @@ class AnthropicAdapter {
|
|
|
51
66
|
type: this.isThinkingEnabled ? 'adaptive' : 'disabled',
|
|
52
67
|
},
|
|
53
68
|
}, sendOptions);
|
|
54
|
-
|
|
69
|
+
const { usage } = response;
|
|
70
|
+
this.log?.info(`[TOKEN USAGE] input=${usage.input_tokens} cache_create=${usage.cache_creation_input_tokens ?? 0} cache_read=${usage.cache_read_input_tokens ?? 0} output=${usage.output_tokens}`);
|
|
55
71
|
const text = response.content
|
|
56
72
|
.filter((block) => block.type === 'text')
|
|
57
73
|
?.map((block) => block.text)
|
|
@@ -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;
|
|
@@ -39,14 +39,29 @@ class AnthropicAdapter {
|
|
|
39
39
|
}
|
|
40
40
|
sendHandler(params, sendOptions) {
|
|
41
41
|
return __awaiter(this, void 0, void 0, function* () {
|
|
42
|
-
var _a, _b;
|
|
42
|
+
var _a, _b, _c, _d;
|
|
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,
|
|
@@ -56,9 +71,10 @@ class AnthropicAdapter {
|
|
|
56
71
|
type: this.isThinkingEnabled ? 'adaptive' : 'disabled',
|
|
57
72
|
},
|
|
58
73
|
}, sendOptions);
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
74
|
+
const { usage } = response;
|
|
75
|
+
(_a = this.log) === null || _a === void 0 ? void 0 : _a.info(`[TOKEN USAGE] input=${usage.input_tokens} cache_create=${(_b = usage.cache_creation_input_tokens) !== null && _b !== void 0 ? _b : 0} cache_read=${(_c = usage.cache_read_input_tokens) !== null && _c !== void 0 ? _c : 0} output=${usage.output_tokens}`);
|
|
76
|
+
const text = (_d = response.content
|
|
77
|
+
.filter((block) => block.type === 'text')) === null || _d === void 0 ? void 0 : _d.map((block) => block.text).join('').trim();
|
|
62
78
|
return text;
|
|
63
79
|
});
|
|
64
80
|
}
|
|
@@ -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;
|