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.FileNode("new", 0666,
|
||||||
virtfs.Doc("Create agent. With prompt=, runs as sub-agent: blocks until done, returns reply."),
|
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) {
|
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)
|
ag, err := session.CreateAgentWithParams(s.Name(), params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -84,11 +84,11 @@ var (
|
||||||
// - Space-separated key=value (legacy format from GUI)
|
// - Space-separated key=value (legacy format from GUI)
|
||||||
//
|
//
|
||||||
// A bare word (no =) is treated as the profile name (legacy positional arg).
|
// 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).
|
// Returns AgentParams, the prompt (empty if not a sub-agent request), and the parent agent ID.
|
||||||
func parseAgentNewRequest(data []byte) (session.AgentParams, string) {
|
func parseAgentNewRequest(data []byte) (session.AgentParams, string, string) {
|
||||||
s := strings.TrimSpace(string(data))
|
s := strings.TrimSpace(string(data))
|
||||||
if s == "" {
|
if s == "" {
|
||||||
return session.AgentParams{Profile: "default"}, ""
|
return session.AgentParams{Profile: "default"}, "", ""
|
||||||
}
|
}
|
||||||
|
|
||||||
var tokens []string
|
var tokens []string
|
||||||
|
|
@ -99,7 +99,7 @@ func parseAgentNewRequest(data []byte) (session.AgentParams, string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
p := session.AgentParams{Profile: "default"}
|
p := session.AgentParams{Profile: "default"}
|
||||||
var prompt string
|
var prompt, parent string
|
||||||
for _, tok := range tokens {
|
for _, tok := range tokens {
|
||||||
tok = strings.TrimSpace(tok)
|
tok = strings.TrimSpace(tok)
|
||||||
if tok == "" {
|
if tok == "" {
|
||||||
|
|
@ -122,10 +122,12 @@ func parseAgentNewRequest(data []byte) (session.AgentParams, string) {
|
||||||
p.Profile = v
|
p.Profile = v
|
||||||
case "prompt":
|
case "prompt":
|
||||||
prompt = v
|
prompt = v
|
||||||
|
case "parent":
|
||||||
|
parent = v
|
||||||
}
|
}
|
||||||
} else if p.Profile == "default" {
|
} else if p.Profile == "default" {
|
||||||
p.Profile = tok
|
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.
|
# Build the payload.
|
||||||
payload="cwd=${cwd}
|
payload="cwd=${cwd}
|
||||||
profile=${profile}
|
profile=${profile}
|
||||||
|
parent=${OLLIE_UNAME}
|
||||||
prompt=${escaped_prompt}"
|
prompt=${escaped_prompt}"
|
||||||
|
|
||||||
[ -n "$name" ] && payload="${payload}
|
[ -n "$name" ] && payload="${payload}
|
||||||
|
|
|
||||||
|
|
@ -1542,6 +1542,15 @@ landed as pure wiring because:
|
||||||
No new abstractions. No new processes. No new protocols. Just connecting
|
No new abstractions. No new processes. No new protocols. Just connecting
|
||||||
existing pieces with 42 lines of glue.
|
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
|
### Future work
|
||||||
|
|
||||||
- **Shared toolsrv per host** — currently each session spawns its own toolsrv.
|
- **Shared toolsrv per host** — currently each session spawns its own toolsrv.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue