mirror of
https://github.com/Ed1s0nZ/CyberStrikeAI.git
synced 2026-08-29 06:00:52 +02:00
Fix finalization cleanup for pending tool executions
This commit is contained in:
@@ -1,9 +1,18 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
agentpkg "cyberstrike-ai/internal/agent"
|
||||
"cyberstrike-ai/internal/agentfinalizer"
|
||||
"cyberstrike-ai/internal/config"
|
||||
"cyberstrike-ai/internal/database"
|
||||
"cyberstrike-ai/internal/mcp"
|
||||
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
func TestShouldAutoContinueAfterFinalization(t *testing.T) {
|
||||
@@ -57,3 +66,66 @@ func TestRequestRequiresExecutionEvidenceUsesExplicitPolicyOnly(t *testing.T) {
|
||||
t.Fatal("explicit false policy should not require execution evidence")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCleanupPendingToolExecutionsAfterIterationAllowsFinalization(t *testing.T) {
|
||||
logger := zap.NewNop()
|
||||
db, err := database.NewDB(filepath.Join(t.TempDir(), "cleanup-finalization.db"), logger)
|
||||
if err != nil {
|
||||
t.Fatalf("NewDB: %v", err)
|
||||
}
|
||||
t.Cleanup(func() { _ = db.Close() })
|
||||
|
||||
server := mcp.NewServerWithStorage(logger, db)
|
||||
server.ConfigureToolWaitTimeoutSeconds(1)
|
||||
server.RegisterTool(mcp.Tool{Name: "block", InputSchema: map[string]interface{}{"type": "object"}}, func(ctx context.Context, args map[string]interface{}) (*mcp.ToolResult, error) {
|
||||
<-ctx.Done()
|
||||
return nil, ctx.Err()
|
||||
})
|
||||
ag := agentpkg.NewAgent(&config.OpenAIConfig{}, &config.AgentConfig{}, server, nil, logger, 10)
|
||||
h := &AgentHandler{agent: ag, db: db, logger: logger}
|
||||
|
||||
callCtx := mcp.WithMCPConversationID(context.Background(), "conv-cleanup")
|
||||
result, execID, err := server.CallTool(callCtx, "block", nil)
|
||||
if err != nil {
|
||||
t.Fatalf("CallTool: %v", err)
|
||||
}
|
||||
if result == nil || !result.IsError || execID == "" {
|
||||
t.Fatalf("expected background wait result, result=%#v execID=%q", result, execID)
|
||||
}
|
||||
|
||||
decision := agentfinalizer.Decide(db, agentfinalizer.Input{
|
||||
Response: "基于已完成信息的阶段性总结。",
|
||||
MCPExecutionIDs: []string{execID},
|
||||
})
|
||||
if decision.CompletionReason != agentfinalizer.ReasonPendingTools {
|
||||
t.Fatalf("decision reason = %s, want pending tools: %+v", decision.CompletionReason, decision)
|
||||
}
|
||||
|
||||
var eventType string
|
||||
cancelled := h.cleanupPendingToolExecutionsAfterIteration(context.Background(), "conv-cleanup", decision, func(et, _ string, _ interface{}) {
|
||||
eventType = et
|
||||
})
|
||||
if len(cancelled) != 1 || cancelled[0] != execID {
|
||||
t.Fatalf("cancelled = %#v, want [%s]", cancelled, execID)
|
||||
}
|
||||
if eventType != "finalization_pending_tools_cancelled" {
|
||||
t.Fatalf("event type = %q", eventType)
|
||||
}
|
||||
|
||||
deadline := time.Now().Add(time.Second)
|
||||
for time.Now().Before(deadline) {
|
||||
exec, err := db.GetToolExecution(execID)
|
||||
if err == nil && exec != nil && exec.Status == mcp.ToolExecutionStatusCancelled {
|
||||
after := agentfinalizer.Decide(db, agentfinalizer.Input{
|
||||
Response: "基于已完成信息的阶段性总结。",
|
||||
MCPExecutionIDs: []string{execID},
|
||||
})
|
||||
if !after.Finalizable || !after.Finalized {
|
||||
t.Fatalf("decision should finalize after cleanup: %+v", after)
|
||||
}
|
||||
return
|
||||
}
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
}
|
||||
t.Fatal("execution did not become cancelled")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user