Feat/subagent history - #110
Conversation
|
Thank you for your contribution. Note that I am currently away on a trip as thus this might take some time to fully evaluate. Will go over it and test it when I get the time to, if things fit will be merged. Thank you! |
| want := []string{ | ||
| "researcher-subagent-0", | ||
| "researcher-subagent-1", | ||
| "researcher-subagent-2", | ||
| // The counter is global per parent, NOT per type. | ||
| "coder-subagent-3", | ||
| } |
There was a problem hiding this comment.
I wonder if I should change the naming scheme to:
subagent-[index]-[type]
There was a problem hiding this comment.
I think this is fine as it is as subagent counter should be global.
| By default, subagent conversations are kept in memory and discarded. With `--save-subagent-histories` (or `"save_subagent_histories": true` in the config file), each subagent's history is saved under the session folder — `~/.local/share/late/sessions/<session-id>/subagents/<type>-subagent-<N>.json` — while the parent session files stay in place. `late session delete <id>` removes the subagent folder along with the session. Note that saved transcripts may contain sensitive content (file contents, tool outputs); they are written with user-only permissions. | ||
|
|
There was a problem hiding this comment.
I wonder if this is TMI for the quickstart. I could remove it if it's unnecessary.
There was a problem hiding this comment.
I think a short explanation of the flag is enough inside the table.
|
@jpia Looks good. Two things that stood out (especially regarding the talk we had in the issue):
For the first UUIDs would solve this or you could save the most recent sequence number inside .meta.json. If you use UUIDs you might need to take care of the TUI truncating them (in the statusbar). I don’t have a preference about the implementation, and neither point is necessarily a blocker for me, I wanted to note these though as per the discussion in the issue we have had. |
I'm leaning towards the .meta.json path for the solution here. I'll work on it! |
Summary
Closes #109
Introduces opt-in persistence for subagent conversation histories, restructures sessions into a hierarchical on-disk layout, and fixes a thread-unsafe subagent-ID generation bug that would silently cause file collisions under concurrent spawns.
Changes
1. Hierarchical Storage Layout (
internal/session/paths.go)When persistence is enabled, subagent histories are written under the parent session's folder (
<sessions>/<sessionID>/subagents/<childID>.json). Parent.json/.meta.jsonfiles stay flat and unchanged.SubagentHistoryDir,SubagentHistoryPath, andRemoveSessionFoldermanage the subagent treeisValidPathElementrejects.,.., path separators, and NUL bytes to prevent directory traversallate session deletealso cleans up the subagent folder alongside the parent session2. Thread-Safe ID Generation (
internal/orchestrator/base.go)NextChildID(typePrefix string)counter onBaseOrchestratorNewSubagentOrchestratornow mints the child ID before creating the session, so the path is known at construction timelen(parent.Children())fallback is removed entirely; a subagent must have a*BaseOrchestratorparent3. Opt-In Persistence (
cmd/late/main.go,internal/config/config.go)--save-subagent-histories(defaultfalse)save_subagent_histories(JSON)false)effectiveSessionIDis derived from the actual history path so resumed sessions reuse their original folder.4. Defensive Hardening
effectiveSessionIDis empty or unsafe, subagent histories fall back to in-memory instead of writing outside the session treeTesting
7 test files updated (~1,128 lines) covering:
.., separators, NUL), resolution, and folder cleanupNextChildIDcounter increment and concurrency safetyderiveEffectiveSessionIDedge cases and session-delete cleanup pathBackwards Compatibility
Contributor License Agreement (CLA)
To accept your code, we legally need you to agree to our CLA so we can maintain the project's Business Source License (BSL) and future open-source transitions.
xbetween the brackets like this:[x])