diff --git a/src/lib/actions/__tests__/continue.test.ts b/src/lib/actions/__tests__/continue.test.ts index 168dcab..42f4363 100644 --- a/src/lib/actions/__tests__/continue.test.ts +++ b/src/lib/actions/__tests__/continue.test.ts @@ -13,6 +13,27 @@ dotenv.config(); const zeroUuid = "00000000-0000-0000-0000-000000000000" as UUID; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +const GetContinueExample1 = (_user_id: UUID) => [ + { + user_id: zeroUuid, + content: + "Hmm, let think for a second, I was going to tell you about something...", + action: "CONTINUE", + }, + { + user_id: zeroUuid, + content: + "I remember now, I was going to tell you about my favorite food, which is pizza.", + action: "CONTINUE", + }, + { + user_id: zeroUuid, + content: "I love pizza, it's so delicious.", + action: "CONTINUE", + }, +]; + describe("User Profile", () => { let user: User; let runtime: BgentRuntime; @@ -54,6 +75,43 @@ describe("User Profile", () => { } // test validate function response + test("Test validate function response", async () => { + const message: Message = { + senderId: user.id as UUID, + agentId: zeroUuid, + userIds: [user.id as UUID, zeroUuid], + content: { + content: "Hello", + }, + room_id: room_id as UUID, + }; + + const validate = action.validate!; + + const result = await validate(runtime, message); + + expect(result).toBe(true); + + // try again with GetContinueExample1, expect to be false + await populateMemories(runtime, user, room_id, [GetContinueExample1]); + + const message2: Message = { + senderId: zeroUuid as UUID, + agentId: zeroUuid, + userIds: [user.id as UUID, zeroUuid], + content: { + content: "Hello", + action: "CONTINUE", + }, + room_id: room_id as UUID, + }; + + const result2 = await validate(runtime, message2); + + console.log("result2", result2); + + expect(result2).toBe(false); + }, 20000); test("Test repetition check on continue", async () => { const message: Message = { @@ -70,27 +128,6 @@ describe("User Profile", () => { const handler = action.handler!; - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const GetContinueExample1 = (_user_id: UUID) => [ - { - user_id: zeroUuid, - content: - "Hmm, let think for a second, I was going to tell you about something...", - action: "CONTINUE", - }, - { - user_id: zeroUuid, - content: - "I remember now, I was going to tell you about my favorite food, which is pizza.", - action: "CONTINUE", - }, - { - user_id: zeroUuid, - content: "I love pizza, it's so delicious.", - action: "CONTINUE", - }, - ]; - await populateMemories(runtime, user, room_id, [GetContinueExample1]); const result = (await handler(runtime, message)) as Content; diff --git a/src/lib/actions/continue.ts b/src/lib/actions/continue.ts index d1f22e2..e66ad20 100644 --- a/src/lib/actions/continue.ts +++ b/src/lib/actions/continue.ts @@ -10,9 +10,8 @@ const maxContinuesInARow = 2; export default { name: "CONTINUE", description: - "Respond with this message, then write another immediately after. If the thought is done or you're waiting for a response, don't use this.", - // eslint-disable-next-line @typescript-eslint/no-unused-vars - validate: async (runtime: BgentRuntime, message: Message, _state: State) => { + "Use the CONTINUE action when the message necessitates a follow up. Do not continue unless following up or adding more to the original thought. Do not use continue when asking a question (use WAIT instead). Do not use continue when the conversation is done or the user does not wish to speak (use IGNORE instead).", + validate: async (runtime: BgentRuntime, message: Message) => { const recentMessagesData = await runtime.messageManager.getMemoriesByIds({ userIds: message.userIds!, count: 10, @@ -22,14 +21,15 @@ export default { (m) => m.user_id === message.agentId, ); - // check if the last messages were all continues + // check if the last messages were all continues= if (agentMessages) { - const lastMessages = agentMessages.slice(maxContinuesInARow); + const lastMessages = agentMessages.slice(0, maxContinuesInARow); if (lastMessages.length >= maxContinuesInARow) { const allContinues = lastMessages.every( (m) => (m.content as Content).action === "CONTINUE", ); if (allContinues) { + console.log("returning all continues"); return false; } } @@ -45,9 +45,6 @@ export default { template: requestHandlerTemplate, }); - console.log("*** context"); - console.log(context); - if (runtime.debugMode) { logger.log(context, { title: "Continued Response Context", @@ -65,8 +62,6 @@ export default { stop: [], }); - console.log("response:", triesLeft, "\n", response); - runtime.supabase .from("logs") .insert({ @@ -99,8 +94,6 @@ export default { return; } - console.log("responseContent", responseContent); - // prevent repetition const messageExists = state.recentMessagesData .filter((m) => m.user_id === message.agentId) @@ -113,7 +106,7 @@ export default { color: "red", }); } - console.log("*** messageExists", messageExists); + return responseContent; } @@ -126,7 +119,7 @@ export default { .filter((m) => m.user_id === message.agentId) .map((m) => (m.content as Content).action); - const lastMessages = agentMessages.slice(maxContinuesInARow); + const lastMessages = agentMessages.slice(0, maxContinuesInARow); if (lastMessages.length >= maxContinuesInARow) { const allContinues = lastMessages.every((m) => m === "CONTINUE"); if (allContinues) { @@ -136,7 +129,6 @@ export default { } await runtime.processActions(message, responseContent); - console.log("returning responseContent", responseContent); return responseContent; }, condition: diff --git a/src/lib/actions/ignore.ts b/src/lib/actions/ignore.ts index 341e51e..6209028 100644 --- a/src/lib/actions/ignore.ts +++ b/src/lib/actions/ignore.ts @@ -1,5 +1,5 @@ import { type BgentRuntime } from "../runtime"; -import { State, type Action, type Message } from "../types"; +import { type Action, type Message } from "../types"; export default { name: "IGNORE", @@ -8,13 +8,11 @@ export default { _runtime: BgentRuntime, // eslint-disable-next-line @typescript-eslint/no-unused-vars _message: Message, - // eslint-disable-next-line @typescript-eslint/no-unused-vars - _state: State, ) => { return true; }, description: - "Ignore the user and do not respond, use this if your role involves being sassy, or mad at user. If the user is mean, aggressive, creepy or is simply done with the conversation, use the ignore action.", + "Ignore the user and do not continue respond. If the user is aggressive, creepy or is simply finished with the conversation, use this action. Or, if both you and the user have already said goodbye, use this action instead of saying bye again. Use IGNORE any time the conversaiton has naturally ended.", handler: async ( runtime: BgentRuntime, message: Message, diff --git a/src/lib/actions/wait.ts b/src/lib/actions/wait.ts index d0b7bc7..612a742 100644 --- a/src/lib/actions/wait.ts +++ b/src/lib/actions/wait.ts @@ -8,7 +8,7 @@ export default { return true; }, description: - "Do nothing and wait for another person to reply to the last message, or to continue their thought", + "Do nothing and wait for another person to reply to the last message, or to continue their thought. For cases such as if the actors have already said goodbye to each other, use the ignore action instead.", handler: async ( runtime: BgentRuntime, // eslint-disable-next-line @typescript-eslint/no-unused-vars diff --git a/src/lib/runtime.ts b/src/lib/runtime.ts index 66c1606..a1e256c 100644 --- a/src/lib/runtime.ts +++ b/src/lib/runtime.ts @@ -247,10 +247,12 @@ export class BgentRuntime { const { senderId, room_id, userIds: user_ids, agentId } = message; for (let triesLeft = 3; triesLeft > 0; triesLeft--) { + console.log("*** context"); const response = await this.completion({ context, stop: [], }); + console.log("*** response"); console.log("*** runtime response"); console.log(response); @@ -292,28 +294,6 @@ export class BgentRuntime { return responseContent; } - async getValidActions(message: Message, state?: State) { - if (!state) state = await this.composeState(message); - const actionPromises = this.getActions().map(async (action: Action) => { - if (!action.handler) { - console.log("no handler"); - return; - } - - const result = await action.validate(this, message, state); - if (result) { - console.log("ACTION", action.name, "VALIDATED"); - return action; - } - console.log("ACTION", action.name, "NOT VALIDATED"); - return null; - }); - - const resolvedActions = await Promise.all(actionPromises); - const actionsData = resolvedActions.filter(Boolean) as Action[]; - return actionsData; - } - async processActions(message: Message, data: Content) { if (!data.action) { return; @@ -530,7 +510,21 @@ export class BgentRuntime { relevantSummarizationsData, }; - const actionsData = await this.getValidActions(message, initialState); + const actionPromises = this.getActions().map(async (action: Action) => { + if (!action.handler) { + console.log("no handler"); + return; + } + + const result = await action.validate(this, message); + if (result) { + return action; + } + return null; + }); + + const resolvedActions = await Promise.all(actionPromises); + const actionsData = resolvedActions.filter(Boolean) as Action[]; const actionState = { actionNames: formatActionNames(actionsData),