mirror of
https://github.com/Ed1s0nZ/CyberStrikeAI.git
synced 2026-07-13 23:47:24 +02:00
Add files via upload
This commit is contained in:
@@ -200,6 +200,7 @@ func runEinoADKAgentLoop(ctx context.Context, args *einoADKRunLoopArgs, baseMsgs
|
||||
markPendingWithMonitor := func(tc toolCallPendingInfo) {
|
||||
markPending(tc)
|
||||
beginEinoADKFilesystemToolMonitor(
|
||||
ctx,
|
||||
args.FilesystemMonitorAgent,
|
||||
args.FilesystemMonitorRecord,
|
||||
args.MCPExecutionBinder,
|
||||
@@ -342,7 +343,7 @@ func runEinoADKAgentLoop(ctx context.Context, args *einoADKRunLoopArgs, baseMsgs
|
||||
toolCallID = tid
|
||||
}
|
||||
recordPendingExecuteStdoutDup(toolName, content, isErr)
|
||||
recordEinoADKFilesystemToolMonitor(args.FilesystemMonitorAgent, args.FilesystemMonitorRecord, args.MCPExecutionBinder, toolName, toolCallID, runAccumulatedMsgs, content, isErr)
|
||||
recordEinoADKFilesystemToolMonitor(ctx, args.FilesystemMonitorAgent, args.FilesystemMonitorRecord, args.MCPExecutionBinder, toolName, toolCallID, runAccumulatedMsgs, content, isErr)
|
||||
if args.FilesystemMonitorAgent != nil && args.MCPExecutionBinder != nil {
|
||||
if execID := args.MCPExecutionBinder.ExecutionID(toolCallID); execID != "" {
|
||||
args.FilesystemMonitorAgent.UpdateMCPExecutionDisplayResult(execID, content)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package multiagent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"cyberstrike-ai/internal/agent"
|
||||
@@ -9,7 +10,7 @@ import (
|
||||
|
||||
// newEinoExecuteMonitorCallbacks 在 Eino filesystem execute 开始/结束时写入 MCP 监控库并 recorder(executionId),
|
||||
// 与 CallTool 路径一致,使监控页能展示「执行中」状态。
|
||||
func newEinoExecuteMonitorCallbacks(ag *agent.Agent, recorder einomcp.ExecutionRecorder) (
|
||||
func newEinoExecuteMonitorCallbacks(ctx context.Context, ag *agent.Agent, recorder einomcp.ExecutionRecorder) (
|
||||
begin func(toolCallID, command string) string,
|
||||
finish func(executionID, toolCallID, command, stdout string, success bool, invokeErr error),
|
||||
) {
|
||||
@@ -18,7 +19,7 @@ func newEinoExecuteMonitorCallbacks(ag *agent.Agent, recorder einomcp.ExecutionR
|
||||
return ""
|
||||
}
|
||||
args := map[string]interface{}{"command": command}
|
||||
id := ag.BeginLocalToolExecution("execute", args)
|
||||
id := ag.BeginLocalToolExecution(ctx, "execute", args)
|
||||
if id != "" && recorder != nil {
|
||||
recorder(id, toolCallID)
|
||||
}
|
||||
@@ -37,7 +38,7 @@ func newEinoExecuteMonitorCallbacks(ag *agent.Agent, recorder einomcp.ExecutionR
|
||||
}
|
||||
}
|
||||
args := map[string]interface{}{"command": command}
|
||||
id := ag.FinishLocalToolExecution(executionID, "execute", args, stdout, err)
|
||||
id := ag.FinishLocalToolExecution(ctx, executionID, "execute", args, stdout, err)
|
||||
if id != "" && recorder != nil && executionID == "" {
|
||||
recorder(id, toolCallID)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package multiagent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"strings"
|
||||
@@ -65,6 +66,7 @@ func toolCallArgsFromAccumulated(msgs []adk.Message, toolCallID, expectToolName
|
||||
|
||||
// beginEinoADKFilesystemToolMonitor 在 Eino ADK filesystem 工具开始调用时写入 running 状态。
|
||||
func beginEinoADKFilesystemToolMonitor(
|
||||
ctx context.Context,
|
||||
ag *agent.Agent,
|
||||
rec einomcp.ExecutionRecorder,
|
||||
binder *MCPExecutionBinder,
|
||||
@@ -85,7 +87,7 @@ func beginEinoADKFilesystemToolMonitor(
|
||||
return
|
||||
}
|
||||
storedName := "eino_fs::" + strings.ToLower(name)
|
||||
id := ag.BeginLocalToolExecution(storedName, map[string]interface{}{})
|
||||
id := ag.BeginLocalToolExecution(ctx, storedName, map[string]interface{}{})
|
||||
if id == "" {
|
||||
return
|
||||
}
|
||||
@@ -97,6 +99,7 @@ func beginEinoADKFilesystemToolMonitor(
|
||||
|
||||
// recordEinoADKFilesystemToolMonitor 将 Eino ADK filesystem 中间件工具结果写入 MCP 监控(与 execute / MCP 桥芯片一致)。
|
||||
func recordEinoADKFilesystemToolMonitor(
|
||||
ctx context.Context,
|
||||
ag *agent.Agent,
|
||||
rec einomcp.ExecutionRecorder,
|
||||
binder *MCPExecutionBinder,
|
||||
@@ -131,7 +134,7 @@ func recordEinoADKFilesystemToolMonitor(
|
||||
if binder != nil {
|
||||
execID = binder.ExecutionID(toolCallID)
|
||||
}
|
||||
id := ag.FinishLocalToolExecution(execID, storedName, args, resultText, invErr)
|
||||
id := ag.FinishLocalToolExecution(ctx, execID, storedName, args, resultText, invErr)
|
||||
if id != "" && execID == "" {
|
||||
rec(id, toolCallID)
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ func RunEinoSingleChatModelAgent(
|
||||
}
|
||||
|
||||
toolInvokeNotify := einomcp.NewToolInvokeNotifyHolder()
|
||||
einoExecBegin, einoExecFinish := newEinoExecuteMonitorCallbacks(ag, recorder)
|
||||
einoExecBegin, einoExecFinish := newEinoExecuteMonitorCallbacks(ctx, ag, recorder)
|
||||
mainDefs := ag.ToolsForRole(roleTools)
|
||||
mainTools, err := einomcp.ToolsFromDefinitions(ag, holder, mainDefs, recorder, nil, toolInvokeNotify, einoSingleAgentName)
|
||||
if err != nil {
|
||||
@@ -162,6 +162,7 @@ func RunEinoSingleChatModelAgent(
|
||||
Tools: mainToolsForCfg,
|
||||
UnknownToolsHandler: einomcp.UnknownToolReminderHandler(),
|
||||
ToolCallMiddlewares: []compose.ToolMiddleware{
|
||||
localToolRBACMiddleware(),
|
||||
hitlToolCallMiddleware(),
|
||||
softRecoveryToolMiddleware(),
|
||||
},
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
package multiagent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"cyberstrike-ai/internal/authctx"
|
||||
|
||||
"github.com/cloudwego/eino/compose"
|
||||
"github.com/cloudwego/eino/schema"
|
||||
)
|
||||
|
||||
func isLocalPrivilegeTool(name string) bool {
|
||||
switch strings.ToLower(strings.TrimSpace(name)) {
|
||||
case "execute", "ls", "read_file", "write_file", "edit_file", "glob", "grep":
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func localToolPermissionDenied(ctx context.Context, name string) bool {
|
||||
if !isLocalPrivilegeTool(name) {
|
||||
return false
|
||||
}
|
||||
principal, ok := authctx.PrincipalFromContext(ctx)
|
||||
return !ok || !principal.HasPermission("agent:local-execute")
|
||||
}
|
||||
|
||||
func localToolRBACMiddleware() compose.ToolMiddleware {
|
||||
denied := "Permission denied: agent:local-execute is required for local filesystem and shell tools."
|
||||
return compose.ToolMiddleware{
|
||||
Invokable: func(next compose.InvokableToolEndpoint) compose.InvokableToolEndpoint {
|
||||
return func(ctx context.Context, input *compose.ToolInput) (*compose.ToolOutput, error) {
|
||||
if input != nil && localToolPermissionDenied(ctx, input.Name) {
|
||||
return &compose.ToolOutput{Result: denied}, nil
|
||||
}
|
||||
return next(ctx, input)
|
||||
}
|
||||
},
|
||||
Streamable: func(next compose.StreamableToolEndpoint) compose.StreamableToolEndpoint {
|
||||
return func(ctx context.Context, input *compose.ToolInput) (*compose.StreamToolOutput, error) {
|
||||
if input != nil && localToolPermissionDenied(ctx, input.Name) {
|
||||
return &compose.StreamToolOutput{Result: schema.StreamReaderFromArray([]string{denied})}, nil
|
||||
}
|
||||
return next(ctx, input)
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package multiagent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"cyberstrike-ai/internal/authctx"
|
||||
)
|
||||
|
||||
func TestLocalToolPermissionIsSeparateFromAgentExecution(t *testing.T) {
|
||||
agentOnly := authctx.WithPrincipal(context.Background(), authctx.NewPrincipal("robot:u1", "robot", "own", map[string]bool{"agent:execute": true}))
|
||||
if !localToolPermissionDenied(agentOnly, "execute") || !localToolPermissionDenied(agentOnly, "read_file") {
|
||||
t.Fatal("agent:execute alone authorized local privileged tools")
|
||||
}
|
||||
local := authctx.WithPrincipal(context.Background(), authctx.NewPrincipal("u1", "user", "assigned", map[string]bool{"agent:local-execute": true}))
|
||||
if localToolPermissionDenied(local, "execute") || localToolPermissionDenied(local, "write_file") {
|
||||
t.Fatal("agent:local-execute was not honored")
|
||||
}
|
||||
if localToolPermissionDenied(agentOnly, "record_vulnerability") {
|
||||
t.Fatal("non-local tool was incorrectly denied")
|
||||
}
|
||||
}
|
||||
@@ -135,7 +135,7 @@ func RunDeepAgent(
|
||||
mcpIDs = append(mcpIDs, id)
|
||||
mcpIDsMu.Unlock()
|
||||
}
|
||||
einoExecBegin, einoExecFinish := newEinoExecuteMonitorCallbacks(ag, recorder)
|
||||
einoExecBegin, einoExecFinish := newEinoExecuteMonitorCallbacks(ctx, ag, recorder)
|
||||
|
||||
// 与单代理流式一致:在 response_start / response_delta 的 data 中带当前 mcpExecutionIds,供主聊天绑定复制与展示。
|
||||
snapshotMCPIDs := func() []string {
|
||||
@@ -279,6 +279,7 @@ func RunDeepAgent(
|
||||
Tools: subToolsForCfg,
|
||||
UnknownToolsHandler: einomcp.UnknownToolReminderHandler(),
|
||||
ToolCallMiddlewares: []compose.ToolMiddleware{
|
||||
localToolRBACMiddleware(),
|
||||
hitlToolCallMiddleware(),
|
||||
softRecoveryToolMiddleware(),
|
||||
},
|
||||
@@ -438,6 +439,7 @@ func RunDeepAgent(
|
||||
Tools: mainToolsForCfg,
|
||||
UnknownToolsHandler: einomcp.UnknownToolReminderHandler(),
|
||||
ToolCallMiddlewares: []compose.ToolMiddleware{
|
||||
localToolRBACMiddleware(),
|
||||
hitlToolCallMiddleware(),
|
||||
softRecoveryToolMiddleware(),
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user