OpenHands icon indicating copy to clipboard operation
OpenHands copied to clipboard

Thread control and thread forking

Open pcuci opened this issue 6 months ago • 11 comments
trafficstars

Any part of the conversational thread should be editable, so we can guide the agent better, including its own responses and actions.

Forking a thread is fairly slow and cumbersome, re: https://github.com/All-Hands-AI/OpenHands/issues/8555 (that's when I start a new thread, and copy paste only some context I care about, to re-bootstrap the agent on a specific task)

What I would like is more control over the conversational thread, because the whole thing gets fed back on every follow-up response. But, most of the time the agent goes all over the place, and that's not helping it act better on the next turn.

Desired outcome:

  • [ ] ability to edit my messages
  • [ ] ability to edit agent's messages
  • [ ] ability to delete either
  • [ ] ability to delete (or edit?) specific tasks inside agent's response.
  • [ ] ability to instant-fork a conversation from any point in a thread: keep same sandbox, same agent, same context
  • [ ] ability to drop old context, e.g.: scroll up, click "delete everything up to this point"; sometimes I don't need the context from its 100 circular steps, and would rather drop that, and continue with the narrow context of the current activity. This would also dramatically help control costs (to not have to send all history on every turn)
  • [ ] ability to see the rationale of choosing one tool over another (sometimes it chooses the less effective tool, say, a sed text replace, instead of overwriting the short file, but I can't figure out why it's doing that)
  • [ ] ability to insert messages during a live turn, e.g.: "you're doing a great job!" or "delete the file first instead of editing"

If I could replace an action that it did with a correct "toy" action that I think it should've done, in its own response, I believe that will steer the agent better on the next turn.

Thoughts?

👍 to upvote

pcuci avatar May 17 '25 19:05 pcuci

Try Mind Evolution method?

linkerlin avatar May 19 '25 03:05 linkerlin

Great ideas here! Just a few quick notes

Re: ability to drop old context. As you correctly noted, it doesn't exist, but you can use a condenser (the default one will summarize old context)

Re: switching model mid-conversation.

  • with CLI or headless, you can exit the conversation, switch model, restart it (with the same -n parameter, session name, so it reloads the same history with the new model)
  • it used to be possible to switch with UI, though you have to refresh in order to load with the new model. I'm not sure that with the UI, that's possible anymore, worth trying?

Re: see rationale Sorry, why can't you see rationale, isn't the content displayed in the UI? I think it should be.

enyst avatar May 25 '25 16:05 enyst

Re: see rationale

I meant, I don't know how to find out why it chose a specific tool to use; the internal reasoning of the model(?)

What is displayed is the decision, not the thought process.

pcuci avatar May 25 '25 16:05 pcuci

Are you sure? There are several things here

  • openhands may receive a content of a response from the model, thought, and other fields, apart from tool calls
  • as far as I know, we display those, in the UI and in CLI
  • maybe you are using a reasoning model whose specific reasoning field is not handled?
  • maybe you could show an example when openhands receives more from the model, but it doesn't display it?

enyst avatar May 25 '25 17:05 enyst

Trying to think through a user experience here:

  • Open a conversation
  • Click some sort of "Fork" button
  • New conversation started with previous context included. Maybe a link back to the original conversation is also available?

@csmith49 I'd be curious how condenser may play a role in forking a conversation - would you need to run condenser again?

jpelletier1 avatar Jun 11 '25 19:06 jpelletier1

An alternative, rather common, behavior here is

  • user clicks "fork"
  • summarize previous content
  • start a new conversation with that summary.

enyst avatar Jun 11 '25 19:06 enyst

@enyst that's a good point. Also may allow for some of edits to the context before starting the new convo.

jpelletier1 avatar Jun 11 '25 20:06 jpelletier1

^ Agreed

I'd prefer a fork button, which has the option to select either

  1. summarize previous content
  2. start fresh conversation with my current repo + branch
    • optionally also allow me to tweak what was originally my first message in the conversation history, or start from scratch entirely

One concern I have is that if we start a new convo it will not have the previous environment that the agent installed; the summary generated when forking (e.g "agent installed pytest") can conflict with the fresh environment (I don't think it will affect the agent much tbh, just something to think about)

malhotra5 avatar Jun 11 '25 20:06 malhotra5

previous environment that the agent installed

Maybe we can get half the way there with a docker runtime environment fork via docker commit

✅ Clone a running container

docker commit <container_id> my-snapshot:latest

✅ Run a new container from the snapshot

docker run -it --name myclone my-snapshot:latest

🔍 (Optional) Inspect original container config

docker inspect <container_id>

🛠 (Optional) Reuse ports, env, volumes

docker run -d \
  -p 8080:80 \
  -e MY_VAR=value \
  -v myvol:/data \
  --entrypoint /bin/bash \
  my-snapshot:latest

⚠️ Limitations of docker commit

Limitation Detail
❌ No memory/process state RAM, threads, sockets aren't saved (use CRIU if needed)
❌ No volume contents Volumes are not included—must back them up separately
❌ Non-reproducible Image can't be recreated from source—no Dockerfile, no traceability
❌ Hidden dependencies Installed packages/configs during runtime may not be documented
⚠️ Doesn't preserve CMD/Entrypoint reliably You'll need to re-specify --entrypoint or CMD if it’s not set in the base image

pcuci avatar Jun 11 '25 22:06 pcuci

  • Click some sort of "Fork" button

Fairly intuitive in AI Studio (though I find it somewhat slow)

Image

pcuci avatar Jun 11 '25 22:06 pcuci

@jpelletier1

I'd be curious how condenser may play a role in forking a conversation - would you need to run condenser again?

Based on what's proposed here I don't believe you'd have to run the condenser again. The results of condensation are stored in the event stream, so if the fork gets a copy of that to boot-strap the conversation all old condensations will be present.

csmith49 avatar Jun 12 '25 15:06 csmith49

chiming in on this with some related thoughts:

A common problem I run into for more complex (or prototype/spike-style tasks) is that work happens (i.e. new, relevant context is generated) in a variety of places. This could be a scratchpad, an intermediate commit that I make, or a code review comment.

I want to be able to synthesize previous, relevant context with new, updated context, while squashing/discarding irrelevant context.

I think the summary of

user clicks "fork" summarize previous content

^ This is probably the "Crawl" (and I'd guess I can do this today, just by prompting an existing conversation to summarize what it knows so far). "Summarize and condense relevant knowledge from this conversation"

start a new conversation with that summary.

^ this is probably already possible (manually). e.g. prompt an existing conversation with the "Summarize" prompt. Copy/paste that into a new conversation.

Building on the above, I'm envisioning:

  • From any entrypoint (UI, CLI, GitHub/Lab, Slack), specify any conversation to use as a squashed baseline so that the new conversation can retain existing context, but benefit from the new context that the agent was not aware of which happened outside of OH.

gjvoit avatar Jun 27 '25 22:06 gjvoit

This issue is stale because it has been open for 30 days with no activity. Remove stale label or comment or this will be closed in 7 days.

github-actions[bot] avatar Jul 28 '25 02:07 github-actions[bot]

OK, returning back to this ticket. I think this would be a neat feature to get into OpenHands :)

As per @enyst's earlier comment, a reasonable starting point could be this.

Within a conversation:

  1. user clicks a "fork" button
  2. system summarizes conversation and displays that as a summary prompt to user in a modal.
  3. user can modify summary prompt, or just accept it as is
  4. system starts new conversation with the summary prompt

Sound good?

jpelletier1 avatar Jul 28 '25 16:07 jpelletier1

To keep it even simpler, how about just cloning a thread with no summarization?

I would still find this valuable as it would allow me to split work threads.

Say I work on a feature, and I have an idea for a test (or I just want to know what tests might look like, but don't want to pollute the main thread), I fork now (new tab), then develop the tests conversation. Whilst in the main thread I continue the main feature development. Or, I have a new idea mid-thread, and I want to literally git branch off to explore an alternative implementation.

(Today I just "select all" then summarize with Gemini, if I want a new fresh thread with some lingering context; but that's a slightly different use-case than the core basic need)

Later, the "fork/clone" button could blow up into multiple options, including "fork with summary" (needs better wording). I can already see myself clicking on that 😄

What I would appreciate most is a super-fast speedy clone, so it doesn't force me to wait while I'm "in the zone". Some ideas were being explored here: https://github.com/All-Hands-AI/OpenHands/pull/9155

pcuci avatar Jul 29 '25 00:07 pcuci

@pcuci I think a clone makes sense, so assuming the entire contents of the conversation needs to be fed back into the agent so it has the context.

@xingyaoww if we theoretically cloned a conversation, is it feasible for OpenHands to start a new conversation with that conversation history?

Second, I think reusing a runtime is an interesting idea, and potentially feasible with the new nested runtime architecture. But maybe we take that as a follow-on enhancement - i.e., #9155 would give users the ability to configure their container re-use strategy in general.

jpelletier1 avatar Aug 20 '25 18:08 jpelletier1

@xingyaoww if we theoretically cloned a conversation, is it feasible for OpenHands to start a new conversation with that conversation history?

Yes. One way to do this is via one of the coolest features in OpenHands that we seem to forget too often (are we even documenting it?):

  • https://github.com/All-Hands-AI/OpenHands/issues/6049

enyst avatar Aug 20 '25 19:08 enyst

We also need an option to reset a conversation: https://github.com/All-Hands-AI/OpenHands/issues/8989 while keeping the same container.

USE CASE: sometimes the context gets cluttered with old garbage, which is very expensive since every new message resends the entire context to the LLM provider. The condenser is far from perfect (and it will take some time before we implement graph memory + proper context engineering).

This use case is equivalent to: (fork-conversation + keep-container) + edit-context or just edit-context (losing the previous conversation history).

kripper avatar Sep 02 '25 14:09 kripper

it will take some time before we implement graph memory + proper context engineering

Some new ideas being applied here: https://weaviate.io/blog/elysia-agentic-rag

Might they an MCP that OpenHands can just plug into?

Elysia = Agentic RAG → retrieval is still central, but:

  • It adds a decision tree of agents that choose tools and strategies.
  • It understands your dataset first (metadata, schema, display types) instead of blind searching.
  • It optimizes retrieval and generation over time (feedback system, chunk-on-demand).

Wondering how fast it is doing real-time embedding, seems to only store a high-level semantic vector per document, and not pre-chunk and vectorize everything in it (does that later at run-time)

pcuci avatar Sep 02 '25 15:09 pcuci

See: https://github.com/All-Hands-AI/OpenHands/pull/10819

kripper avatar Sep 04 '25 16:09 kripper