Skip to content

Commit

Permalink
Export utils and templates, fix tests
Browse files Browse the repository at this point in the history
  • Loading branch information
lalalune committed Mar 2, 2024
1 parent 7ba1c95 commit 0da01a6
Show file tree
Hide file tree
Showing 15 changed files with 402 additions and 32 deletions.
21 changes: 0 additions & 21 deletions docs/docs/classes/BgentRuntime.md
Original file line number Diff line number Diff line change
Expand Up @@ -225,27 +225,6 @@ The number of recent messages to be kept in memory.

___

### handleMessage

**handleMessage**(`message`, `state?`): `Promise`\<[`Content`](../interfaces/Content.md)\>

Handle an incoming message, processing it and returning a response.

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `message` | [`Message`](../interfaces/Message.md) | The message to handle. |
| `state?` | [`State`](../interfaces/State.md) | The state of the agent. |

#### Returns

`Promise`\<[`Content`](../interfaces/Content.md)\>

The response to the message.

___

### processActions

**processActions**(`message`, `content`): `Promise`\<`void`\>
Expand Down
4 changes: 2 additions & 2 deletions docs/docs/functions/getRelationships.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ sidebar_position: 0
custom_edit_url: null
---

**getRelationships**(`«destructured»`): `Promise`\<`Relationship`[]\>
**getRelationships**(`«destructured»`): `Promise`\<[`Relationship`](../interfaces/Relationship.md)[]\>

#### Parameters

Expand All @@ -18,4 +18,4 @@ custom_edit_url: null

#### Returns

`Promise`\<`Relationship`[]\>
`Promise`\<[`Relationship`](../interfaces/Relationship.md)[]\>
27 changes: 27 additions & 0 deletions docs/docs/functions/parseJSONObjectFromText.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
id: "parseJSONObjectFromText"
title: "Function: parseJSONObjectFromText"
sidebar_label: "parseJSONObjectFromText"
sidebar_position: 0
custom_edit_url: null
---

**parseJSONObjectFromText**(`text`): `any`

Parses a JSON object from a given text. The function looks for a JSON block wrapped in triple backticks
with `json` language identifier, and if not found, it searches for an object pattern within the text.
It then attempts to parse the JSON string into a JavaScript object. If parsing is successful and the result
is an object (but not an array), it returns the object; otherwise, it tries to parse an array if the result
is an array, or returns null if parsing is unsuccessful or the result is neither an object nor an array.

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `text` | `string` | The input text from which to extract and parse the JSON object. |

#### Returns

`any`

An object parsed from the JSON string if successful; otherwise, null or the result of parsing an array.
26 changes: 26 additions & 0 deletions docs/docs/functions/parseJsonArrayFromText.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
id: "parseJsonArrayFromText"
title: "Function: parseJsonArrayFromText"
sidebar_label: "parseJsonArrayFromText"
sidebar_position: 0
custom_edit_url: null
---

**parseJsonArrayFromText**(`text`): ``null`` \| `any`[]

Parses a JSON array from a given text. The function looks for a JSON block wrapped in triple backticks
with `json` language identifier, and if not found, it searches for an array pattern within the text.
It then attempts to parse the JSON string into a JavaScript object. If parsing is successful and the result
is an array, it returns the array; otherwise, it returns null.

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `text` | `string` | The input text from which to extract and parse the JSON array. |

#### Returns

``null`` \| `any`[]

An array parsed from the JSON string if successful; otherwise, null.
2 changes: 2 additions & 0 deletions docs/docs/interfaces/Provider.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ sidebar_position: 0
custom_edit_url: null
---

Represents a provider, which is used to retrieve information or perform actions on behalf of the agent, such as fetching data from an external API or service.

## Properties

### get
Expand Down
51 changes: 51 additions & 0 deletions docs/docs/interfaces/Relationship.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
---
id: "Relationship"
title: "Interface: Relationship"
sidebar_label: "Relationship"
sidebar_position: 0
custom_edit_url: null
---

Represents a relationship between two users, including their IDs, the status of the relationship, and the room ID in which the relationship is established.

## Properties

### created\_at

`Optional` **created\_at**: `string`

___

### id

**id**: \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`

___

### room\_id

**room\_id**: \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`

___

### status

**status**: `string`

___

### user\_a

**user\_a**: \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`

___

### user\_b

**user\_b**: \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`

___

### user\_id

**user\_id**: \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`
4 changes: 4 additions & 0 deletions docs/docs/modules.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ custom_edit_url: null
- [MessageExample](interfaces/MessageExample.md)
- [Objective](interfaces/Objective.md)
- [Provider](interfaces/Provider.md)
- [Relationship](interfaces/Relationship.md)
- [State](interfaces/State.md)

## Type Aliases
Expand All @@ -49,6 +50,7 @@ custom_edit_url: null
- [fact](variables/fact.md)
- [goal](variables/goal-1.md)
- [ignore](variables/ignore.md)
- [messageHandlerTemplate](variables/messageHandlerTemplate.md)
- [wait](variables/wait.md)

## Functions
Expand Down Expand Up @@ -83,4 +85,6 @@ custom_edit_url: null
- [getProviders](functions/getProviders.md)
- [getRelationship](functions/getRelationship.md)
- [getRelationships](functions/getRelationships.md)
- [parseJSONObjectFromText](functions/parseJSONObjectFromText.md)
- [parseJsonArrayFromText](functions/parseJsonArrayFromText.md)
- [updateGoal](functions/updateGoal.md)
9 changes: 9 additions & 0 deletions docs/docs/variables/messageHandlerTemplate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
id: "messageHandlerTemplate"
title: "Variable: messageHandlerTemplate"
sidebar_label: "messageHandlerTemplate"
sidebar_position: 0
custom_edit_url: null
---

`Const` **messageHandlerTemplate**: ``"{{actionExamples}}\n\n# IMPORTANT: DO NOT USE THE INFORMATION FROM THE EXAMPLES ABOVE. THE EXAMPLES ARE FOR REFERENCE ONLY.\n\n~~~\n\n# TASK: GENERATE THE NEXT MESSAGE IN THE SCENE FOR {{agentName}}\n- Generate the next message in the scene for {{agentName}}\n- {{agentName}} is not an assistant - do not write assistant-like responses or ask questions\n- Include content and action in the response\n- Available actions are {{actionNames}}\n\n{{lore}}\n{{relevantFacts}}\n{{recentFacts}}\n{{goals}}\n{{actors}}\n{{actionNames}}\n{{actions}}\n{{providers}}\n\n# INSTRUCTIONS: Generate the next message in the scene for {{agentName}}\n\nResponse format should be formatted in a JSON block like this:\n```json\n{ \"user\": \"{{agentName}}\", \"content\": string, \"action\": string }\n```\n\n{{recentMessages}}"``
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "bgent",
"version": "0.0.23",
"version": "0.0.24",
"private": false,
"description": "bgent. because agent was taken.",
"type": "module",
Expand Down
127 changes: 125 additions & 2 deletions src/lib/__tests__/actions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,131 @@ import { TEST_ACTION, TEST_ACTION_FAIL } from "../../test/testAction";
import { zeroUuid } from "../constants";
import { createRelationship, getRelationship } from "../relationships";
import { type BgentRuntime } from "../runtime";
import { type Message } from "../types";
import { Content, State, type Message } from "../types";
import { runAiTest } from "../../test/runAiTest";
import { composeContext } from "../context";
import logger from "../logger";
import { embeddingZeroVector } from "../memory";
import { messageHandlerTemplate } from "../templates";
import { parseJSONObjectFromText } from "../utils";

async function handleMessage(
runtime: BgentRuntime,
message: Message,
state?: State,
) {
const _saveRequestMessage = async (message: Message, state: State) => {
const { content: senderContent, senderId, userIds, room_id } = message;

const _senderContent = (
(senderContent as Content).content ?? senderContent
)?.trim();
if (_senderContent) {
await runtime.messageManager.createMemory({
user_ids: userIds!,
user_id: senderId!,
content: {
content: _senderContent,
action: (message.content as Content)?.action ?? "null",
},
room_id,
embedding: embeddingZeroVector,
});
await runtime.evaluate(message, state);
}
};

await _saveRequestMessage(message, state as State);
if (!state) {
state = (await runtime.composeState(message)) as State;
}

const context = composeContext({
state,
template: messageHandlerTemplate,
});

if (runtime.debugMode) {
logger.log(context, "Response Context", "cyan");
}

let responseContent: Content | null = null;
const { senderId, room_id, userIds: user_ids, agentId } = message;

for (let triesLeft = 3; triesLeft > 0; triesLeft--) {
const response = await runtime.completion({
context,
stop: [],
});

runtime.supabase
.from("logs")
.insert({
body: { message, context, response },
user_id: senderId,
room_id,
user_ids: user_ids!,
agent_id: agentId!,
type: "main_completion",
})
.then(({ error }) => {
if (error) {
console.error("error", error);
}
});

const parsedResponse = parseJSONObjectFromText(
response,
) as unknown as Content;

if (
(parsedResponse.user as string)?.includes(
(state as State).agentName as string,
)
) {
responseContent = {
content: parsedResponse.content,
action: parsedResponse.action,
};
break;
}
}

if (!responseContent) {
responseContent = {
content: "",
action: "IGNORE",
};
}

const _saveResponseMessage = async (
message: Message,
state: State,
responseContent: Content,
) => {
const { agentId, userIds, room_id } = message;

responseContent.content = responseContent.content?.trim();

if (responseContent.content) {
await runtime.messageManager.createMemory({
user_ids: userIds!,
user_id: agentId!,
content: responseContent,
room_id,
embedding: embeddingZeroVector,
});
await runtime.evaluate(message, { ...state, responseContent });
} else {
console.warn("Empty response, skipping");
}
};

await _saveResponseMessage(message, state, responseContent);
await runtime.processActions(message, responseContent);

return responseContent;
}

// use .dev.vars for local testing
dotenv.config({ path: ".dev.vars" });
Expand Down Expand Up @@ -157,7 +280,7 @@ describe("Actions", () => {
room_id,
};

const response = await runtime.handleMessage(message);
const response = await handleMessage(runtime, message);
return response.action === "TEST_ACTION"; // Return true if the expected action matches
});
}, 60000);
Expand Down
1 change: 1 addition & 0 deletions src/lib/__tests__/messages.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ describe("Messages Library", () => {
test("formatActors should format actors into a readable string", () => {
const formattedActors = formatActors({ actors });
actors.forEach((actor) => {
console.log("ACTOR IS", actor)
expect(formattedActors).toContain(actor.name);
});
});
Expand Down
Loading

0 comments on commit 0da01a6

Please sign in to comment.