Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 15 additions & 9 deletions agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,13 @@ type AgentState struct {
Fragment *Fragment
Error error
Cancel context.CancelFunc
done chan struct{}
inject chan openai.ChatCompletionMessage
// Background reports whether the agent was spawned to run in the background
// (spawn_agent background=true) rather than in the foreground. Embedders use
// it to tell unattended background work apart from a foreground sub-agent
// whose result is consumed inline by the spawn call.
Background bool
done chan struct{}
inject chan openai.ChatCompletionMessage
// detach, when non-nil, lets an embedder promote a running foreground
// agent to the background: a non-blocking send here unblocks the
// spawn_agent call so it returns the agent ID while the goroutine keeps
Expand Down Expand Up @@ -405,13 +410,14 @@ func (r *spawnAgentRunner) Run(args SpawnAgentArgs) (string, any, error) {

// Background: launch goroutine, return ID immediately.
agent := &AgentState{
ID: agentID,
Task: args.Task,
Type: args.AgentType,
Status: AgentStatusRunning,
Cancel: cancel,
done: make(chan struct{}),
inject: make(chan openai.ChatCompletionMessage, 8),
ID: agentID,
Task: args.Task,
Type: args.AgentType,
Status: AgentStatusRunning,
Cancel: cancel,
Background: true,
done: make(chan struct{}),
inject: make(chan openai.ChatCompletionMessage, 8),
}
r.manager.Register(agent)
if r.agentSpawnCallback != nil {
Expand Down
28 changes: 28 additions & 0 deletions agent_background_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package cogito

import (
"context"
"testing"
)

// TestBackgroundSpawnSetsBackgroundFlag verifies that a background spawn marks
// the AgentState so embedders can tell it apart from a foreground sub-agent.
func TestBackgroundSpawnSetsBackgroundFlag(t *testing.T) {
m := NewAgentManager()
llm := newBlockingLLM(make(chan struct{})) // blocks; background spawn returns immediately
runner := &spawnAgentRunner{llm: llm, manager: m, ctx: context.Background()}

_, idAny, err := runner.Run(SpawnAgentArgs{Task: "bg job", Background: true})
if err != nil {
t.Fatalf("background Run: %v", err)
}
id, _ := idAny.(string)
a, ok := m.Get(id)
if !ok {
t.Fatal("background agent should be registered")
}
if !a.Background {
t.Fatal("a background spawn should set AgentState.Background = true")
}
a.Cancel() // unblock the goroutine so the test cleans up
}
Loading