mirror of
https://github.com/Ed1s0nZ/CyberStrikeAI.git
synced 2026-09-30 13:09:40 +02:00
Add files via upload
This commit is contained in:
2 files changed
+97
No files matched your search
@@ -0,0 +1,59 @@
|
|||||||
|
package multiagent
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"cyberstrike-ai/internal/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
const defaultEmptyResponseContinueMaxAttempts = 5
|
||||||
|
|
||||||
|
// IsEinoEmptyResponseResult 判断 Run 是否以「未捕获助手正文」占位结束(非真实用户可见回复)。
|
||||||
|
func IsEinoEmptyResponseResult(result *RunResult) bool {
|
||||||
|
if result == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return isEinoEmptyResponseText(result.Response)
|
||||||
|
}
|
||||||
|
|
||||||
|
func isEinoEmptyResponseText(s string) bool {
|
||||||
|
s = strings.TrimSpace(s)
|
||||||
|
if s == "" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return strings.Contains(s, "no assistant text was captured") ||
|
||||||
|
strings.Contains(s, "未捕获到助手文本输出")
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasEinoResumeTrace 轨迹非空,续跑才有上下文可恢复。
|
||||||
|
func HasEinoResumeTrace(result *RunResult) bool {
|
||||||
|
if result == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
s := strings.TrimSpace(result.LastAgentTraceInput)
|
||||||
|
return s != "" && s != "[]" && s != "null"
|
||||||
|
}
|
||||||
|
|
||||||
|
// EmptyResponseContinueMaxAttemptsFromConfig 无助手正文时 Handler 层退避续跑上限;0=默认 5。
|
||||||
|
func EmptyResponseContinueMaxAttemptsFromConfig(mw *config.MultiAgentEinoMiddlewareConfig) int {
|
||||||
|
if mw != nil && mw.EmptyResponseContinueMaxAttempts > 0 {
|
||||||
|
return mw.EmptyResponseContinueMaxAttempts
|
||||||
|
}
|
||||||
|
return defaultEmptyResponseContinueMaxAttempts
|
||||||
|
}
|
||||||
|
|
||||||
|
// EmptyResponseContinueBackoff 与 run_retry 相同指数退避(2s, 4s, 8s… capped)。
|
||||||
|
func EmptyResponseContinueBackoff(attempt int, mw *config.MultiAgentEinoMiddlewareConfig) time.Duration {
|
||||||
|
maxBackoff := defaultEinoRunRetryMaxBackoff
|
||||||
|
if mw != nil && mw.RunRetryMaxBackoffSec > 0 {
|
||||||
|
maxBackoff = time.Duration(mw.RunRetryMaxBackoffSec) * time.Second
|
||||||
|
}
|
||||||
|
return einoTransientRetryBackoff(attempt, maxBackoff)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FormatEmptyResponseContinueUserMessage 系统自动续跑时注入的 user 轮次(不写入 messages 表气泡)。
|
||||||
|
func FormatEmptyResponseContinueUserMessage() string {
|
||||||
|
return strings.TrimSpace(`【系统自动续跑 / Auto resume】
|
||||||
|
上一轮 Eino 会话未产出可见助手正文(可能流式中断或仅完成工具调用)。请基于已有轨迹与工具结果继续推进,并给出阶段性总结;勿重复已完成步骤。`)
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package multiagent
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestIsEinoEmptyResponseResult(t *testing.T) {
|
||||||
|
empty := &RunResult{
|
||||||
|
Response: "(Eino ADK single-agent session completed but no assistant text was captured. Check process details or logs.) " +
|
||||||
|
"(Eino ADK 单代理会话已完成,但未捕获到助手文本输出。请查看过程详情或日志。)",
|
||||||
|
}
|
||||||
|
if !IsEinoEmptyResponseResult(empty) {
|
||||||
|
t.Fatal("expected empty placeholder response")
|
||||||
|
}
|
||||||
|
ok := &RunResult{Response: "扫描完成,发现 2 个开放端口。"}
|
||||||
|
if IsEinoEmptyResponseResult(ok) {
|
||||||
|
t.Fatalf("expected real response, got placeholder match")
|
||||||
|
}
|
||||||
|
if IsEinoEmptyResponseResult(nil) {
|
||||||
|
t.Fatal("nil result should be false")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHasEinoResumeTrace(t *testing.T) {
|
||||||
|
if HasEinoResumeTrace(nil) {
|
||||||
|
t.Fatal("nil")
|
||||||
|
}
|
||||||
|
if HasEinoResumeTrace(&RunResult{LastAgentTraceInput: "[]"}) {
|
||||||
|
t.Fatal("enable resume on empty trace")
|
||||||
|
}
|
||||||
|
if !HasEinoResumeTrace(&RunResult{LastAgentTraceInput: `[{"role":"user","content":"hi"}]`}) {
|
||||||
|
t.Fatal("expected resume trace")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEmptyResponseContinueMaxAttemptsFromConfig(t *testing.T) {
|
||||||
|
if got := EmptyResponseContinueMaxAttemptsFromConfig(nil); got != defaultEmptyResponseContinueMaxAttempts {
|
||||||
|
t.Fatalf("default: got %d want %d", got, defaultEmptyResponseContinueMaxAttempts)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user