mirror of
https://github.com/RuoJi6/ARTEX.git
synced 2026-10-28 01:03:50 +08:00
99 lines
4.6 KiB
Go
99 lines
4.6 KiB
Go
package agent
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
|
|
"github.com/Autumn-27/artex/db"
|
|
actool "github.com/Autumn-27/norma/tool"
|
|
)
|
|
|
|
// Missing host/setting means off. Rechecked on every write for running sessions.
|
|
var IntelligenceEnabled func() bool
|
|
var IntelligenceRecord func(context.Context, int64, int64, string, db.IntelligenceInput) (int64, error)
|
|
|
|
func intelligenceEnabled() bool { return IntelligenceEnabled != nil && IntelligenceEnabled() }
|
|
func intelligenceSchema() map[string]any {
|
|
return obj(map[string]any{
|
|
"kind": map[string]any{"type": "string", "enum": []string{"credential", "lead", "sensitive_data"}},
|
|
"title": str("简短标题,禁止包含密码、Token 或敏感数据原文"),
|
|
"content": str("实际获取的信息。凭据用 JSON 字符串保存账号/密码/Token 等;敏感数据仅少量样例、数量和文件位置,禁止整库粘贴"),
|
|
"evidence": str("真实来源:命令/请求/响应/文件位置及关键观察,禁止编造"),
|
|
"confidence": map[string]any{"type": "string", "enum": []string{"observed", "inferred"}},
|
|
"status": str("凭据 unverified/verified/invalid;线索 pending/in_progress/dismissed/converted;敏感数据 suspected/confirmed/dismissed。省略时保守默认,verified 需要真实认证成功证据"),
|
|
"asset_ids": map[string]any{"type": "array", "items": map[string]any{"type": "integer"}},
|
|
}, "kind", "title", "content", "evidence", "confidence")
|
|
}
|
|
func (t *ToolSet) saveIntelligence(ctx context.Context, nodeID int64, in db.IntelligenceInput) (int64, error) {
|
|
if !intelligenceEnabled() || IntelligenceRecord == nil {
|
|
return 0, fmt.Errorf("任务情报自动记录已关闭")
|
|
}
|
|
taskID := t.taskID
|
|
if taskID <= 0 {
|
|
taskID = RunInfoFrom(ctx).TaskID
|
|
}
|
|
if taskID <= 0 {
|
|
return 0, fmt.Errorf("任务情报需要当前任务上下文")
|
|
}
|
|
if nodeID <= 0 {
|
|
nodeID = t.ownerNode
|
|
}
|
|
if nodeID <= 0 {
|
|
nodeID = RunInfoFrom(ctx).IntentID
|
|
}
|
|
id, err := IntelligenceRecord(ctx, taskID, nodeID, t.worker, in)
|
|
if err == nil {
|
|
t.writes.Intelligence++
|
|
}
|
|
return id, err
|
|
}
|
|
func (t *ToolSet) recordIntelligence() actool.CoreTool {
|
|
return writeTool("record_intelligence", "记录当前任务实际获取的凭据、重要线索或敏感数据。任务和执行来源由系统绑定;凭据发现不等于验证成功。重复记录会去重。已有 insert_assets.auth 自动登记凭据,无需重复调用。", intelligenceSchema(), func(ctx context.Context, raw json.RawMessage) (actool.Result, error) {
|
|
var in db.IntelligenceInput
|
|
if err := json.Unmarshal(raw, &in); err != nil {
|
|
return actool.Errorf("无效情报参数"), nil
|
|
}
|
|
id, err := t.saveIntelligence(ctx, 0, in)
|
|
if err != nil {
|
|
return actool.Errorf(err.Error()), nil
|
|
}
|
|
return actool.Text(fmt.Sprintf("intelligence recorded: %d", id)), nil
|
|
})
|
|
}
|
|
func intelligenceWorkflow(ctx context.Context, tools []actool.CoreTool) ([]actool.CoreTool, string) {
|
|
enabled := intelligenceEnabled() && RunInfoFrom(ctx).TaskID > 0
|
|
out := make([]actool.CoreTool, 0, len(tools))
|
|
hasRecord := false
|
|
hasFact := false
|
|
for _, tool := range tools {
|
|
if tool.Name() == "record_intelligence" {
|
|
if !enabled {
|
|
continue
|
|
}
|
|
hasRecord = true
|
|
}
|
|
if tool.Name() == "record_fact" {
|
|
raw, _ := json.Marshal(tool.InputSchema())
|
|
var schema map[string]any
|
|
if json.Unmarshal(raw, &schema) == nil {
|
|
props, _ := schema["properties"].(map[string]any)
|
|
if props != nil {
|
|
delete(props, "intelligence")
|
|
if enabled {
|
|
props["intelligence"] = map[string]any{"type": "array", "maxItems": 20, "description": "随事实一次写回情报,字段与 record_intelligence 相同;无需再单独调用该工具", "items": intelligenceSchema()}
|
|
hasFact = true
|
|
}
|
|
}
|
|
tool = DecorateTool(tool, tool.Description(), schema)
|
|
}
|
|
}
|
|
out = append(out, tool)
|
|
}
|
|
guide := ""
|
|
if enabled && (hasRecord || hasFact) {
|
|
guide = "\n\n**任务情报记录已开启**:发现凭据、值得跟进的线索或真实敏感数据时立即结构化写回,不等用户追问;结束前检查遗漏。record_fact 可附 intelligence 数组一起写回,每条事实/批量 facts 的元素均支持;单独记录用 record_intelligence(若可用)。insert_assets.auth 已由后端自动登记,勿重复调用。只记录新增、有价值的信息,普通指纹/端口状态仍仅作 fact。title 禁止包含秘密原文;正文带实际内容和来源。凭据默认未验证,只有真实认证成功才标 verified;推断必须 inferred;敏感数据写类型、数量、少量样例、文件位置,勿粘整库。"
|
|
}
|
|
return out, guide
|
|
}
|