← Writing

Hermes Agent

Is It Still the Same Agent in Another Chat?

Does the same agent in another chat automatically continue the same conversation? Follow Hermes from incoming messages to routing keys, durable sessions, and replaceable execution objects.

You ask an agent to investigate a problem on your computer. It has just found a useful lead when you need to leave. You pick up your phone, open a messaging app, and send: “Keep going in that direction.”

It feels reasonable to expect the conversation to continue. The assistant has the same name and uses the same model. Why explain everything again?

For a system with multiple entry points, however, “that direction” needs an address. Which platform sent the message? Which account, group, or discussion thread does it belong to? Which history should be opened? If somebody else in the group also says “continue,” are you collaborating or running separate tasks?

This path from a chat window to the execution core is a useful place to begin reading Hermes Agent. Different interfaces can reuse its agent capabilities, while session routing determines where context belongs. Understanding that distinction makes its memory, tools, and longer tasks easier to follow.

Many doors, one language for the reception desk

Think of each messaging platform as a door. Telegram, Discord, and Slack have different event formats, connection mechanisms, reply limits, and thread semantics. Put all those differences inside the reasoning loop and the loop soon becomes a collection of platform checks.

Hermes keeps platform adaptation outside that loop. An adapter receives an event and produces a common MessageEvent. Its SessionSource supplies information about the platform, chat, sender, and thread. The Gateway handles admission, session routing, and scheduling before the execution core receives the conversation to work on.

Platform plugins live under plugins/platforms, with shared behavior in gateway/platforms/base.py. The benefit is practical: connecting to a platform or splitting an outgoing reply should not be prerequisite knowledge for calling a tool. A more sophisticated tool loop should not force every adapter to implement that loop again.

Other interfaces, including the CLI, can also use the AIAgent core. But using the same implementation, reusing the same object in memory, and entering the same conversation are three separate things. Entering another door establishes that you reached the system; it does not establish that the receptionist found your existing record.

That gives us a useful division of responsibility. The interface describes the event, the Gateway assigns it, and the agent works on it. The official Gateway guide and implementation explain this architecture, while the routing code supplies the detailed behavior.

Where does the previous conversation live?

Suppose Alice asks a group assistant to investigate an error. A few seconds later, Bob asks an unrelated question in the same group. If history is indexed only by the group ID, they enter the same record. That can be a legitimate choice, but it needs to be an intentional product decision.

Hermes expresses that decision as a deterministic algorithm in build_session_key. Source fields and session options become a session_key. The default namespace is agent:main; a named profile gets its own prefix. The platform participates, so matching chat IDs on two platforms do not merge merely because the IDs happen to match. Slack additionally includes its workspace scope.

Direct messages normally route by chat ID. If that ID is absent, the implementation falls back to the sender ID. If neither is available, an even broader fallback remains. Complete source metadata therefore matters: the routing function cannot invent a reliable identity for an incomplete event.

Groups have a more interesting default. Outside a thread, the participant normally enters the key, giving Alice and Bob separate contexts. Inside a thread, participants share the conversation by default. The thread carries a product assumption: these people are discussing the same topic.

This is configurable. To isolate participants inside threads, enable per-user thread sessions while per-user group isolation is enabled. The actual condition combines group_sessions_per_user and thread_sessions_per_user; an option name alone does not describe every interaction.

Three identities in Hermes: source metadata creates a routing key, the key locates a durable session, and a configuration signature controls agent object reuse
The routing key identifies the destination, the session ID identifies the record, and the in-memory object performs the work.

A smaller branch reveals why routing deserves careful design. A Discord channel message may initiate a new thread. When that first message arrives, its eventual thread source does not yet exist. Hermes can use prospective_thread_id to route it into the future thread and normalize the type slot to thread. Later messages received inside that thread can then produce the same key.

Without this step, the user would see one continuous discussion while the system saw two histories. Routing is more than concatenating strings: it preserves a product promise across different event stages. These behaviors are visible in the session key implementation.

Same address, possibly a different worker

Two more identities sit behind the route. session_key is the lookup address; SessionEntry.session_id identifies the durable conversation; a cached AIAgent is an object currently available to execute it. Their lifetimes are related, but they should not be treated as identical.

Imagine a customer record and the employee handling it. The record can remain when the employee changes shifts. A process restart or a reclaimed cache object does not automatically mean the conversation has disappeared. Equally, a familiar agent object is not proof that a new message belongs to every history that object previously handled.

Hermes places a configuration signature in front of cache reuse. The model, toolsets, temporary prompt, selected runtime settings, user identifiers, and the context-file loading policy all affect it. Compatible construction state allows reuse; relevant changes require rebuilding. Tool names are sorted first, so reordering the same list does not trigger a pointless rebuild.

The presence of user identifiers is especially revealing.

Alice and Bob can intentionally receive the same routing key in a shared thread. Yet a memory integration may bind a user identity during initialization. Reusing the object initialized for Alice could attribute Bob's next message to the wrong memory subject. The signature therefore includes user_id and user_id_alt, allowing the execution object to change even when the shared conversation address stays the same.

This trades some cache warmth for correct attribution while retaining the continuity of the shared discussion. Sharing conversational context does not have to imply sharing a user identity. Comments beside the official agent cache signature explain the memory integration behind this choice.

The signature only helps decide whether an object remains suitable for reuse. It does not authenticate a user or replace tool authorization. Addresses, identities, and permissions answer different questions. Keeping them separate becomes particularly important when connecting an agent to internal business systems.

The second message arrives before the first is ready

People do not wait for initialization to finish before sending another message. They send three short messages in succession or press stop while an agent is researching. The system must coordinate both the creation of a session and ownership of an executing turn.

The session store's get_or_create_session uses single-flight coordination by key. When overlapping requests target one route, one caller owns the retrieval or creation, while the others wait for its result or error. Potentially blocking recovery and storage work are also separated from short periods under the in-memory lock. This avoids competing session creation without placing all slow storage work inside the broadest critical section.

Obtaining the same session still does not make it safe to launch two turns simultaneously. After normal admission handling, the Gateway checks whether the session is already running. Messages arriving during work follow the applicable queue or interruption policy. Starting a fresh turn requires claiming an active slot.

A crucial step is installing _AGENT_PENDING_SENTINEL before slow setup. The actual agent may not exist yet, and history may still need loading, but the claim already exists. Otherwise, an await during initialization could let a second message mistake the session for an idle one.

Messages move from a platform adapter through admission and a pending claim to the agent worker, then return through platform delivery
Claim ownership before setup. Session creation coordination and turn scheduling protect different stages.

Single-flight coordinates overlapping session acquisition. The active slot and pending sentinel coordinate ownership of a turn. Both help prevent duplication, but they protect different objects. Calling the whole design “a lock” hides why locking database access alone would be insufficient. The sequence appears in the inbound message implementation.

Finally, the agent gets the message

The Gateway must keep receiving events while model calls and tools may take considerable time. Hermes schedules synchronous execution work on an executor while maintaining asynchronous orchestration outside it. This prevents a long operation from directly occupying the message reception loop. A worker thread is an execution arrangement, not a security sandbox for tools.

Inside the core, run_conversation organizes request preparation, model calls, response normalization, tool rounds, and text completion. The loop checks iteration budgets and also contains a specific budget-grace path. It should not be understood as unconditionally calling the model until the model happens to stop.

Text deltas, tool progress, and clarification requests connect back to the Gateway through callbacks. Delivery remains responsible for presentation, sending, and whether a response has already streamed to the platform. Turn handling also carries a run generation so relevant late work can be checked against current ownership. A delayed result from an old turn should not automatically take over a newer turn's interface.

This arrangement gives each side a coherent problem to solve. The agent loop decides what to request next, how tool results enter the conversation, and when the turn ends. The messaging side decides who owns the result, where it belongs, and whether it was already delivered. The separate turn execution and conversation loop implementations make that division concrete.

The boundaries worth keeping

To check more than a diagram, I extracted the routing function, its required helpers, and the configuration signature function from the pinned source and ran 22 behavioral checks. They cover default groups and shared threads, per-user isolation, platform and Slack workspace separation, prospective-thread continuity, and signature changes when a shared route receives a different user.

The checks use minimal source objects and a platform enum. They do not start a live Gateway or connect messaging platforms, models, or memory services. Storage concurrency and WhatsApp identifier normalization are outside this test set. These are checks of specific algorithm branches, not an end-to-end certification of the system.

Now return to “keep going in that direction.” Hermes can reuse one agent implementation across entry points, but continuing a conversation across those points needs an explicit session relationship. Matching assistant names do not create that relationship. The design questions are which messages should share history, which participants need distinct attribution, and which changes should replace an execution object while retaining the record.

Once the message reaches the right conversation, the next question becomes useful: as that conversation grows, what should the agent remember, and how should that memory enter the next turn?

继续阅读

Hermes Agent One Click Launch Integration Package!! launch

Hermes Agent is a powerful open-source AI programming assistant. Official installation requires manual configuration of WSL2, Ubuntu, and Python environments, which has a high threshold for non-technical personnel. This project follows the installation plan of u-claw USB flash drive, encapsulating the entire installation process into a double-click. bat file and providing a GUI interface to configure API keys without any command line operations. Hermes Agent is a powerful open-source AI programming assistant. Official installation requires manual configuration of WSL2, Ubuntu, and Python environments, which has a high threshold for non-technical personnel. This project follows the installation plan of u-claw USB flash drive, encapsulating the entire installation process into a double-click. bat file and providing a GUI interface to configure API keys without any command line operations.

↗