Skip to content

Commit 9888ced

Browse files
committed
Merge remote-tracking branch 'ai16z/develop' into realitySpiral/integration-tests
2 parents 3fab472 + 0a23d6d commit 9888ced

File tree

25 files changed

+23715
-17827
lines changed

25 files changed

+23715
-17827
lines changed

.env.example

+6
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,12 @@ MEDIUM_VENICE_MODEL= # Default: llama-3.3-70b
247247
LARGE_VENICE_MODEL= # Default: llama-3.1-405b
248248
IMAGE_VENICE_MODEL= # Default: fluently-xl
249249

250+
# Akash Chat API Configuration docs: https://chatapi.akash.network/documentation
251+
AKASH_CHAT_API_KEY= # Get from https://chatapi.akash.network/
252+
SMALL_AKASH_CHAT_API_MODEL= # Default: Meta-Llama-3-2-3B-Instruct
253+
MEDIUM_AKASH_CHAT_API_MODEL= # Default: Meta-Llama-3-3-70B-Instruct
254+
LARGE_AKASH_CHAT_API_MODEL= # Default: Meta-Llama-3-1-405B-Instruct-FP8
255+
250256
# fal.ai Configuration
251257
FAL_API_KEY=
252258
FAL_AI_LORA_PATH=

agent/src/index.ts

+5
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,11 @@ export function getTokenForProvider(
299299
character.settings?.secrets?.VENICE_API_KEY ||
300300
settings.VENICE_API_KEY
301301
);
302+
case ModelProviderName.AKASH_CHAT_API:
303+
return (
304+
character.settings?.secrets?.AKASH_CHAT_API_KEY ||
305+
settings.AKASH_CHAT_API_KEY
306+
);
302307
}
303308
}
304309

File renamed without changes.

docker-compose.yaml

-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
services:
22
tee:
3-
command: ["pnpm", "start"]
43
build:
54
context: .
65
dockerfile: Dockerfile

docs/docs/api/functions/composeContext.md

+64-23
Original file line numberDiff line numberDiff line change
@@ -2,44 +2,85 @@
22

33
> **composeContext**(`params`): `string`
44
5-
Composes a context string by replacing placeholders in a template with corresponding values from the state.
6-
7-
This function takes a template string with placeholders in the format `{{placeholder}}` and a state object.
8-
It replaces each placeholder with the value from the state object that matches the placeholder's name.
9-
If a matching key is not found in the state object for a given placeholder, the placeholder is replaced with an empty string.
5+
Composes a context string by replacing placeholders in a template with values from a state object. Supports both simple string replacement and the Handlebars templating engine.
106

117
## Parameters
128

13-
**params**
14-
15-
The parameters for composing the context.
9+
### **params**: `Object`
1610

17-
**params.state**: [`State`](../interfaces/State.md)
11+
An object containing the following properties:
1812

19-
The state object containing values to replace the placeholders in the template.
13+
- **state**: `State`
14+
The state object containing key-value pairs for replacing placeholders in the template.
2015

21-
**params.template**: `string`
16+
- **template**: `string`
17+
A string containing placeholders in the format `{{placeholder}}`.
2218

23-
The template string containing placeholders to be replaced with state values.
19+
- **templatingEngine**: `"handlebars" | undefined` *(optional)*
20+
The templating engine to use. If set to `"handlebars"`, the Handlebars engine is used for template compilation. Defaults to `undefined` (simple string replacement).
2421

2522
## Returns
2623

2724
`string`
2825

29-
The composed context string with placeholders replaced by corresponding state values.
26+
The context string with placeholders replaced by corresponding values from the state object. If a placeholder has no matching key in the state, it is replaced with an empty string.
27+
28+
## Examples
3029

31-
## Example
30+
### Simple Example
3231

33-
```ts
34-
// Given a state object and a template
32+
```javascript
3533
const state = { userName: "Alice", userAge: 30 };
36-
const template = "Hello, {{userName}}! You are {{userAge}} years old";
34+
const template = "Hello, {{userName}}! You are {{userAge}} years old.";
3735

38-
// Composing the context will result in:
39-
// "Hello, Alice! You are 30 years old."
40-
const context = composeContext({ state, template });
41-
```
36+
// Simple string replacement
37+
const contextSimple = composeContext({ state, template });
38+
// Output: "Hello, Alice! You are 30 years old."
4239

43-
## Defined in
40+
// Handlebars templating
41+
const contextHandlebars = composeContext({ state, template, templatingEngine: 'handlebars' });
42+
// Output: "Hello, Alice! You are 30 years old."
43+
```
4444

45-
[packages/core/src/context.ts:24](https://github.com/ai16z/eliza/blob/7fcf54e7fb2ba027d110afcc319c0b01b3f181dc/packages/core/src/context.ts#L24)
45+
### Advanced Example
46+
47+
```javascript
48+
const advancedTemplate = `
49+
{{#if userAge}}
50+
Hello, {{userName}}!
51+
{{#if (gt userAge 18)}}You are an adult.{{else}}You are a minor.{{/if}}
52+
{{else}}
53+
Hello! We don't know your age.
54+
{{/if}}
55+
56+
{{#if favoriteColors.length}}
57+
Your favorite colors are:
58+
{{#each favoriteColors}}
59+
- {{this}}
60+
{{/each}}
61+
{{else}}
62+
You didn't specify any favorite colors.
63+
{{/if}}
64+
`;
65+
66+
const advancedState = {
67+
userName: "Alice",
68+
userAge: 30,
69+
favoriteColors: ["blue", "green", "red"]
70+
};
71+
72+
// Composing the context with Handlebars
73+
const advancedContextHandlebars = composeContext({
74+
state: advancedState,
75+
template: advancedTemplate,
76+
templatingEngine: 'handlebars'
77+
});
78+
// Output:
79+
// Hello, Alice!
80+
// You are an adult.
81+
//
82+
// Your favorite colors are:
83+
// - blue
84+
// - green
85+
// - red
86+
```

packages/client-discord/src/messages.ts

+29-9
Original file line numberDiff line numberDiff line change
@@ -508,24 +508,44 @@ export class MessageManager {
508508
}
509509

510510
private _isMessageForMe(message: DiscordMessage): boolean {
511-
const isMentioned = message.mentions.users?.has(this.client.user?.id as string);
511+
const isMentioned = message.mentions.users?.has(
512+
this.client.user?.id as string
513+
);
512514
const guild = message.guild;
513515
const member = guild?.members.cache.get(this.client.user?.id as string);
514516
const nickname = member?.nickname;
515-
const memberId = member?.id;
516517

517518
// Don't consider role mentions as direct mentions
518-
const hasRoleMentionOnly = message.mentions.roles.size > 0 && !isMentioned;
519+
const hasRoleMentionOnly =
520+
message.mentions.roles.size > 0 && !isMentioned;
519521

520522
// If it's only a role mention and we're in team mode, let team logic handle it
521-
if (hasRoleMentionOnly && this.runtime.character.clientConfig?.discord?.isPartOfTeam) {
523+
if (
524+
hasRoleMentionOnly &&
525+
this.runtime.character.clientConfig?.discord?.isPartOfTeam
526+
) {
522527
return false;
523528
}
524529

525-
return isMentioned || (!this.runtime.character.clientConfig?.discord?.shouldRespondOnlyToMentions && (
526-
message.content.toLowerCase().includes(this.client.user?.username.toLowerCase() as string) ||
527-
message.content.toLowerCase().includes(this.client.user?.tag.toLowerCase() as string) ||
528-
(nickname && message.content.toLowerCase().includes(nickname.toLowerCase()))));
530+
return (
531+
isMentioned ||
532+
(!this.runtime.character.clientConfig?.discord
533+
?.shouldRespondOnlyToMentions &&
534+
(message.content
535+
.toLowerCase()
536+
.includes(
537+
this.client.user?.username.toLowerCase() as string
538+
) ||
539+
message.content
540+
.toLowerCase()
541+
.includes(
542+
this.client.user?.tag.toLowerCase() as string
543+
) ||
544+
(nickname &&
545+
message.content
546+
.toLowerCase()
547+
.includes(nickname.toLowerCase()))))
548+
);
529549
}
530550

531551
async processMessageMedia(
@@ -1287,4 +1307,4 @@ export class MessageManager {
12871307
const data = await response.json();
12881308
return data.username;
12891309
}
1290-
}
1310+
}

packages/client-telegram/src/messageManager.ts

+5-18
Original file line numberDiff line numberDiff line change
@@ -322,12 +322,15 @@ export class MessageManager {
322322
'caption' in message ? (message as any).caption : '';
323323
if (!messageText) return false;
324324

325+
const isReplyToBot = (message as any).reply_to_message?.from?.is_bot === true &&
326+
(message as any).reply_to_message?.from?.username === botUsername;
325327
const isMentioned = messageText.includes(`@${botUsername}`);
326328
const hasUsername = messageText.toLowerCase().includes(botUsername.toLowerCase());
327329

328-
return isMentioned || (!this.runtime.character.clientConfig?.telegram?.shouldRespondOnlyToMentions && hasUsername);
330+
return isReplyToBot || isMentioned || (!this.runtime.character.clientConfig?.telegram?.shouldRespondOnlyToMentions && hasUsername);
329331
}
330332

333+
331334
private _checkInterest(chatId: string): boolean {
332335
const chatState = this.interestChats[chatId];
333336
if (!chatState) return false;
@@ -360,22 +363,6 @@ export class MessageManager {
360363
return true;
361364
}
362365

363-
private _isMessageForMe(message: Message): boolean {
364-
const botUsername = this.bot.botInfo?.username;
365-
if (!botUsername) return false;
366-
367-
const messageText = 'text' in message ? message.text :
368-
'caption' in message ? (message as any).caption : '';
369-
if (!messageText) return false;
370-
371-
const isReplyToBot = (message as any).reply_to_message?.from?.is_bot === true &&
372-
(message as any).reply_to_message?.from?.username === botUsername;
373-
const isMentioned = messageText.includes(`@${botUsername}`);
374-
const hasUsername = messageText.toLowerCase().includes(botUsername.toLowerCase());
375-
376-
return isReplyToBot || isMentioned || (!this.runtime.character.clientConfig?.telegram?.shouldRespondOnlyToMentions && hasUsername);
377-
}
378-
379366
// Process image messages and generate descriptions
380367
private async processImage(
381368
message: Message
@@ -422,7 +409,7 @@ export class MessageManager {
422409
message: Message,
423410
state: State
424411
): Promise<boolean> {
425-
412+
426413
if (this.runtime.character.clientConfig?.telegram?.shouldRespondOnlyToMentions) {
427414
return this._isMessageForMe(message);
428415
}

packages/client-twitter/src/post.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -276,8 +276,11 @@ export class TwitterPostClient {
276276
const removeQuotes = (str: string) =>
277277
str.replace(/^['"](.*)['"]$/, "$1");
278278

279+
const fixNewLines = (str: string) =>
280+
str.replaceAll(/\\n/g, "\n");
281+
279282
// Final cleaning
280-
cleanedContent = removeQuotes(content);
283+
cleanedContent = removeQuotes(fixNewLines(content));
281284

282285
if (this.runtime.getSetting("TWITTER_DRY_RUN") === "true") {
283286
elizaLogger.info(

packages/client-whatsapp/package.json

-23
This file was deleted.

packages/client-whatsapp/src/actions/index.ts

Whitespace-only changes.

packages/client-whatsapp/src/environment.ts

-21
This file was deleted.

packages/client-whatsapp/src/index.ts

-28
This file was deleted.

packages/core/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
"fastestsmallesttextencoderdecoder": "1.0.22",
6565
"gaxios": "6.7.1",
6666
"glob": "11.0.0",
67+
"handlebars": "^4.7.8",
6768
"js-sha1": "0.7.0",
6869
"js-tiktoken": "1.0.15",
6970
"langchain": "0.3.6",

packages/core/src/context.ts

+13-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import handlebars from "handlebars";
12
import { type State } from "./types.ts";
23

34
/**
@@ -7,27 +8,37 @@ import { type State } from "./types.ts";
78
* It replaces each placeholder with the value from the state object that matches the placeholder's name.
89
* If a matching key is not found in the state object for a given placeholder, the placeholder is replaced with an empty string.
910
*
11+
* By default, this function uses a simple string replacement approach. However, when `templatingEngine` is set to `'handlebars'`, it uses Handlebars templating engine instead, compiling the template into a reusable function and evaluating it with the provided state object.
12+
*
1013
* @param {Object} params - The parameters for composing the context.
1114
* @param {State} params.state - The state object containing values to replace the placeholders in the template.
1215
* @param {string} params.template - The template string containing placeholders to be replaced with state values.
16+
* @param {"handlebars" | undefined} [params.templatingEngine] - The templating engine to use for compiling and evaluating the template (optional, default: `undefined`).
1317
* @returns {string} The composed context string with placeholders replaced by corresponding state values.
1418
*
1519
* @example
1620
* // Given a state object and a template
1721
* const state = { userName: "Alice", userAge: 30 };
1822
* const template = "Hello, {{userName}}! You are {{userAge}} years old";
1923
*
20-
* // Composing the context will result in:
24+
* // Composing the context with simple string replacement will result in:
2125
* // "Hello, Alice! You are 30 years old."
22-
* const context = composeContext({ state, template });
26+
* const contextSimple = composeContext({ state, template });
2327
*/
2428
export const composeContext = ({
2529
state,
2630
template,
31+
templatingEngine,
2732
}: {
2833
state: State;
2934
template: string;
35+
templatingEngine?: "handlebars";
3036
}) => {
37+
if (templatingEngine === "handlebars") {
38+
const templateFunction = handlebars.compile(template);
39+
return templateFunction(state);
40+
}
41+
3142
// @ts-expect-error match isn't working as expected
3243
const out = template.replace(/{{\w+}}/g, (match) => {
3344
const key = match.replace(/{{|}}/g, "");

0 commit comments

Comments
 (0)