Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

enhancement: Improve message threading and handling to reduce repetition #783

Closed
twilwa opened this issue Dec 2, 2024 · 2 comments
Closed
Labels
enhancement New feature or request

Comments

@twilwa
Copy link
Contributor

twilwa commented Dec 2, 2024

Is your feature request related to a problem? Please describe.

Currently when agents use the CONTINUE action, they can generate multiple separate messages with identical context instead of properly continuing the conversation thread. This leads to "spammy" behavior and redundant responses.

Current Behavior:

Agent generates new separate messages for continuations
Context gets repeated across continuation messages
No proper message threading/revision system
Basic inReplyTo linking that doesn't prevent duplicates

Proposed Solution:

Enhance Content type to support threading:

interface Content {
  text: string;
  action?: string;
  isContinuation?: boolean; 
  parentMessageId?: UUID;
  revision?: number;
}

Update MemoryManager to handle message revisions/updates
Modify CONTINUE action to update existing messages rather than create new ones
Add thread management while preserving room-based organization
Implementation Steps:

Add message threading support to AgentRuntime
Enhance MemoryManager with revision tracking
Update CONTINUE action handler to use thread metadata
Add validation to prevent duplicate continuations
Implement message update logic instead of creating new messages

Files to Modify:

/packages/core/src/runtime.ts
/packages/plugin-bootstrap/src/actions/continue.ts
/packages/core/src/types.ts

Related Components:

MessageManager
MemoryManager
AgentRuntime
ContinueAction

I'll grab this tomorrow if i get a chance

@twilwa twilwa added the enhancement New feature or request label Dec 2, 2024
@augchan42
Copy link
Contributor

was also tracking this issue (discord code, but happens in tg too), here's analysis from Sonnet:

Yes, looking at the flow, the double replies could be happening because of how the callback is handled. Here's the sequence:

  1. First call:
const responseMessages = await callback(responseContent);
  1. Then the callback is passed to processActions:
await this.runtime.processActions(
    memory,
    responseMessages,
    state,
    callback  // <-- Same callback passed here
);
  1. Inside processActions, the action handler might call the callback again:
await action.handler(this, message, state, {}, callback);

To fix this, you could:

  1. Either modify the callback to be single-use:
const createCallback = () => {
    let used = false;
    return async (content: Content, files: any[]) => {
        if (used) {
            elizaLogger.warn("Callback already used, skipping");
            return [];
        }
        used = true;
        // ... rest of callback logic ...
    };
};

const callback = createCallback();
  1. Or create separate callbacks for the initial response and actions:
const responseMessages = await callback(responseContent);

// Create a new callback for actions that doesn't create memories
const actionCallback: HandlerCallback = async (content: Content, files: any[]) => {
    try {
        if (!content?.text.trim()) {
            elizaLogger.warn("Skipping empty content");
            return [];
        }
        return await sendMessageInChunks(
            message.channel as TextChannel,
            content.text,
            message.id,
            files
        );
    } catch (error) {
        console.error("Error in action callback:", error);
        return [];
    }
};

await this.runtime.processActions(
    memory,
    responseMessages,
    state,
    actionCallback
);

The second approach might be better as it makes the distinction between response handling and action handling clearer.

@odilitime
Copy link
Collaborator

isContinuation seems redundant, can’t the parentMessageId be enough?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants