mirror of
https://github.com/tiennm99/goclaw.git
synced 2026-10-13 10:15:48 +00:00
* feat(collaboration): isolate delegated artifacts and child runs Isolate delegated inputs and outputs behind secure artifact exchange lifecycles. Scope Agent Link tasks by tenant and root agent, and enforce delegation spawn-tree boundaries. Add process-wide child-run admission and preserve logical media paths across native, MCP, and sandbox execution. * fix(collaboration): harden delegated task isolation Enforce tenant and root-agent task scope across migrations and stores. Add exactly-once async completion delivery, delegated sandbox boundaries, and confined artifact and media recovery across runtime surfaces. * fix(collaboration): recover interrupted async tasks * fix(collaboration): normalize persisted child-run status --------- Co-authored-by: ntduc <ntduc@cpp.ai.vn>
56 lines
1.5 KiB
Go
56 lines
1.5 KiB
Go
package tools
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
|
|
"github.com/nextlevelbuilder/goclaw/internal/bus"
|
|
)
|
|
|
|
func TestSubagentDirectAnnouncementDoesNotBlockOnFullInboundBus(t *testing.T) {
|
|
messageBus := bus.New()
|
|
for range 1000 {
|
|
messageBus.PublishInbound(bus.InboundMessage{Content: "fill"})
|
|
}
|
|
manager := NewSubagentManager(nil, nil, "", messageBus, nil, SubagentConfig{})
|
|
taskStore := newRecordingSubagentTaskStore()
|
|
manager.SetTaskStore(taskStore)
|
|
task := &SubagentTask{
|
|
ID: "task-1",
|
|
Label: "probe",
|
|
Status: TaskStatusCompleted,
|
|
Result: "done",
|
|
CreatedAt: time.Now().Add(-time.Second).UnixMilli(),
|
|
OriginChannel: "test",
|
|
OriginChatID: "chat-1",
|
|
OriginTenantID: uuid.New(),
|
|
RootAgentID: uuid.New(),
|
|
RootAgentKey: "root",
|
|
OriginSessionKey: "session-1",
|
|
dbID: uuid.New(),
|
|
}
|
|
|
|
done := make(chan struct{})
|
|
go func() {
|
|
manager.announceTask(context.Background(), task, nil, 1, true)
|
|
close(done)
|
|
}()
|
|
|
|
select {
|
|
case <-done:
|
|
case <-time.After(time.Second):
|
|
t.Fatal("subagent announcement blocked on a full inbound bus")
|
|
}
|
|
select {
|
|
case metadata := <-taskStore.metadata:
|
|
if metadata[asyncCompletionDeliveryKey] != asyncCompletionDeliveryMissed {
|
|
t.Fatalf("announcement metadata = %#v, want undelivered", metadata)
|
|
}
|
|
case <-time.After(time.Second):
|
|
t.Fatal("subagent missed announcement was not recorded after bus saturation")
|
|
}
|
|
}
|