subagent: inherit parent context via parent= parameter
Sub-agents now clone the parent agent's conversation history into their initial context. The tool script passes parent=$OLLIE_UNAME automatically. Mechanically identical to session restore — uses RestoreHistoryFromMessages on the parent's Messages().
This commit is contained in:
parent
c25e2e708c
commit
617bb5586a
|
|
@ -290,7 +290,14 @@ func buildSessionChildren(
|
|||
virtfs.FileNode("new", 0666,
|
||||
virtfs.Doc("Create agent. With prompt=, runs as sub-agent: blocks until done, returns reply."),
|
||||
virtfs.Rdwr(func(ctx context.Context, data []byte) ([]byte, error) {
|
||||
params, prompt := parseAgentNewRequest(data)
|
||||
params, prompt, parentID := parseAgentNewRequest(data)
|
||||
|
||||
// Sub-agent inherits parent's context.
|
||||
if prompt != "" && parentID != "" {
|
||||
if parent := s.FindAgent(parentID); parent != nil {
|
||||
params.History = agent.RestoreHistoryFromMessages(parent.Messages())
|
||||
}
|
||||
}
|
||||
|
||||
ag, err := session.CreateAgentWithParams(s.Name(), params)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -84,11 +84,11 @@ var (
|
|||
// - Space-separated key=value (legacy format from GUI)
|
||||
//
|
||||
// A bare word (no =) is treated as the profile name (legacy positional arg).
|
||||
// Returns AgentParams and the prompt (empty if not a sub-agent request).
|
||||
func parseAgentNewRequest(data []byte) (session.AgentParams, string) {
|
||||
// Returns AgentParams, the prompt (empty if not a sub-agent request), and the parent agent ID.
|
||||
func parseAgentNewRequest(data []byte) (session.AgentParams, string, string) {
|
||||
s := strings.TrimSpace(string(data))
|
||||
if s == "" {
|
||||
return session.AgentParams{Profile: "default"}, ""
|
||||
return session.AgentParams{Profile: "default"}, "", ""
|
||||
}
|
||||
|
||||
var tokens []string
|
||||
|
|
@ -99,7 +99,7 @@ func parseAgentNewRequest(data []byte) (session.AgentParams, string) {
|
|||
}
|
||||
|
||||
p := session.AgentParams{Profile: "default"}
|
||||
var prompt string
|
||||
var prompt, parent string
|
||||
for _, tok := range tokens {
|
||||
tok = strings.TrimSpace(tok)
|
||||
if tok == "" {
|
||||
|
|
@ -122,10 +122,12 @@ func parseAgentNewRequest(data []byte) (session.AgentParams, string) {
|
|||
p.Profile = v
|
||||
case "prompt":
|
||||
prompt = v
|
||||
case "parent":
|
||||
parent = v
|
||||
}
|
||||
} else if p.Profile == "default" {
|
||||
p.Profile = tok
|
||||
}
|
||||
}
|
||||
return p, prompt
|
||||
return p, prompt, parent
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ escaped_prompt=$(printf '%s' "$prompt_text" | sed 's/\\/\\\\/g; s/$/\\n/' | tr -
|
|||
# Build the payload.
|
||||
payload="cwd=${cwd}
|
||||
profile=${profile}
|
||||
parent=${OLLIE_UNAME}
|
||||
prompt=${escaped_prompt}"
|
||||
|
||||
[ -n "$name" ] && payload="${payload}
|
||||
|
|
|
|||
|
|
@ -1542,6 +1542,15 @@ landed as pure wiring because:
|
|||
No new abstractions. No new processes. No new protocols. Just connecting
|
||||
existing pieces with 42 lines of glue.
|
||||
|
||||
### Context inheritance
|
||||
|
||||
Sub-agents inherit the parent's conversation history. When `parent=` is
|
||||
specified in the payload, the handler clones the parent agent's messages
|
||||
into the sub-agent's initial context via `RestoreHistoryFromMessages`.
|
||||
This is mechanically identical to session restore — same function, same
|
||||
data path. The sub-agent knows everything the parent knows without
|
||||
rediscovering it.
|
||||
|
||||
### Future work
|
||||
|
||||
- **Shared toolsrv per host** — currently each session spawns its own toolsrv.
|
||||
|
|
|
|||
Loading…
Reference in New Issue