init
This commit is contained in:
1 parent
9793b522d9
commit
b7e0b93023
46 files changed
+3632
-899
No files matched your search
@@ -92,6 +92,7 @@ func (c *ChatAgent) Chat(ctx context.Context, agentKey, sessionID, message strin
|
||||
// visible skills/MCP and lets the DB tools table filter/override. DefaultTools
|
||||
// have no tools-table rows, so they always pass through.
|
||||
base := actool.DefaultTools()
|
||||
ctx = WithRunInfo(ctx, RunInfo{SessionID: sessionID})
|
||||
tools, def, cleanup := AugmentTools(ctx, agentKey, base)
|
||||
defer cleanup()
|
||||
|
||||
|
||||
@@ -85,6 +85,7 @@ func (m *MainAgent) Chat(ctx context.Context, taskID int64, as *db.AssetStore, t
|
||||
tsx.SetNotifyGoal(notifyGoal) // set_goals 新增目标 → 给 planner 记一条「人新增了目标:…」触发
|
||||
// 领域工具 + 基础默认工具集(Read/Write/Edit/MultiEdit/LS/Glob/Grep/Bash)
|
||||
base := append(tsx.MainAgentTools(), actool.DefaultTools()...)
|
||||
ctx = WithRunInfo(ctx, RunInfo{TaskID: taskID, ExplorationID: explorationID(ts)})
|
||||
tools, def, cleanup := AugmentTools(ctx, "mainagent", base)
|
||||
defer cleanup()
|
||||
// 本任务的工作目录 <workDir>/tasks/<taskID>,先建好。
|
||||
|
||||
@@ -273,6 +273,7 @@ func (p *Planner) Plan(ctx context.Context, taskID int64, as *db.AssetStore, ts
|
||||
}
|
||||
// 领域工具 + 基础默认工具集(Read/Write/Edit/MultiEdit/LS/Glob/Grep/Bash)
|
||||
base := append(tsx.PlannerTools(), actool.DefaultTools()...)
|
||||
ctx = WithRunInfo(ctx, RunInfo{TaskID: taskID, ExplorationID: explorationID(ts)})
|
||||
tools, def, cleanup := AugmentTools(ctx, "planner", base)
|
||||
defer cleanup()
|
||||
// 关键态势(刚完成的意图 + 预取的完整图)改放【本轮 user 输入】(见下方 input),system
|
||||
|
||||
+12
-14
@@ -41,9 +41,14 @@ type Config struct {
|
||||
// ContextWindowK is the model's context window in K tokens (user-configured),
|
||||
// used to size compaction thresholds. 0 = default; see CompactionWindow.
|
||||
ContextWindowK int
|
||||
// ReasoningEffort selects the thinking mode: "" = 默认(不发送思考参数);
|
||||
// "off" = 关闭(thinking.type=disabled); "low"/"medium"/"high"/"max" = 开启并设强度.
|
||||
// NewProvider derives the provider-specific request fields from it.
|
||||
// ThinkingType 独立控制思考「开关」字段(thinking.type):
|
||||
// "" = 不发送(默认,兼容不支持该字段的模型); "disabled" = 显式关闭;
|
||||
// "enabled" = 开启. 与 ReasoningEffort 完全解耦——有些接口没有 thinking 字段、
|
||||
// 只靠强度参数就能激活思考,故两者可各自单独设置.
|
||||
ThinkingType string
|
||||
// ReasoningEffort 独立控制思考「强度」字段:
|
||||
// "" = 不发送(默认); "low"/"medium"/"high"/"xhigh"/"max" = 对应强度.
|
||||
// OpenAI 映射为顶层 reasoning_effort;Anthropic 映射为 output_config.effort.
|
||||
ReasoningEffort string
|
||||
}
|
||||
|
||||
@@ -184,17 +189,10 @@ func (c Config) NewProvider() (llm.Provider, error) {
|
||||
Model: c.Model,
|
||||
HTTPClient: client,
|
||||
}
|
||||
// Derive the provider thinking params from the single UI selector:
|
||||
// "" → omit both (provider default); "off" → disable; else → enable + effort.
|
||||
switch c.ReasoningEffort {
|
||||
case "":
|
||||
// leave both empty → omitted from the request
|
||||
case "off":
|
||||
lc.ThinkingType = "disabled"
|
||||
default:
|
||||
lc.ThinkingType = "enabled"
|
||||
lc.ReasoningEffort = c.ReasoningEffort
|
||||
}
|
||||
// 思考开关与强度两个字段各自透传(空 = 该字段不发送)。二者解耦:
|
||||
// 可只发 thinking.type、只发 effort、都发、或都不发。
|
||||
lc.ThinkingType = c.ThinkingType
|
||||
lc.ReasoningEffort = c.ReasoningEffort
|
||||
if c.RatePerSecond > 0 || c.RatePerMinute > 0 {
|
||||
lc.RateLimit = &llm.RateLimit{PerSecond: c.RatePerSecond, PerMinute: c.RatePerMinute}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
package agent
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Autumn-27/artex/db"
|
||||
)
|
||||
|
||||
// RunInfo identifies WHICH run a tool call belongs to. Tool assembly only receives
|
||||
// (ctx, agentKey) — the task/exploration ids live in the caller's arguments, not the
|
||||
// ctx — so anything wired at assembly time (currently the Skill ledger in
|
||||
// server/assembly.go) has no way to attribute a call to a task. Each run attaches
|
||||
// its own RunInfo before calling AugmentTools; the wiring closure reads it once and
|
||||
// captures it, so per-run attribution stays correct without threading parameters
|
||||
// through the tool layer. Same pattern as TaskClock (see taskclock.go).
|
||||
//
|
||||
// Zero value = attribution unknown; every consumer must treat it as optional.
|
||||
type RunInfo struct {
|
||||
TaskID int64 // task registry id; 0 for non-task runs (chat sessions)
|
||||
ExplorationID int64 // exploration id; 0 when unknown
|
||||
IntentID int64 // worker's intent node; 0 for planner/mainagent/chat
|
||||
SessionID string // chat conversation id; empty for task runs
|
||||
}
|
||||
|
||||
// explorationID reads a store's exploration id, tolerating a nil store (planner and
|
||||
// worker runs can be driven without one in tests).
|
||||
func explorationID(ts *db.ExplorationStore) int64 {
|
||||
if ts == nil {
|
||||
return 0
|
||||
}
|
||||
return ts.ID()
|
||||
}
|
||||
|
||||
type runInfoKey struct{}
|
||||
|
||||
// WithRunInfo attaches run attribution to ctx.
|
||||
func WithRunInfo(ctx context.Context, ri RunInfo) context.Context {
|
||||
return context.WithValue(ctx, runInfoKey{}, ri)
|
||||
}
|
||||
|
||||
// RunInfoFrom reads the RunInfo (zero value if none attached).
|
||||
func RunInfoFrom(ctx context.Context) RunInfo {
|
||||
if v, ok := ctx.Value(runInfoKey{}).(RunInfo); ok {
|
||||
return v
|
||||
}
|
||||
return RunInfo{}
|
||||
}
|
||||
@@ -382,7 +382,7 @@ func (t *ToolSet) addTaskScope() actool.CoreTool {
|
||||
var added []map[string]any
|
||||
errs := map[string]string{}
|
||||
for i, e := range items {
|
||||
ts, err := t.as.AddAgentScope(t.taskID, strings.TrimSpace(e.Kind), e.Value, a.Reason)
|
||||
ts, err := t.as.AddAgentScope(t.taskID, strings.TrimSpace(e.Kind), e.Value, a.Reason, "agent")
|
||||
if err != nil {
|
||||
errs[strconv.Itoa(i)] = err.Error()
|
||||
continue
|
||||
|
||||
@@ -265,6 +265,7 @@ func (w *Worker) Execute(ctx context.Context, name string, taskID int64, as *db.
|
||||
// phase, Bash is hidden via Settlement.DisabledTools (no local gating needed).
|
||||
base := append(tsx.WorkerTools(), w.extraTools...)
|
||||
base = append(base, actool.DefaultTools()...)
|
||||
ctx = WithRunInfo(ctx, RunInfo{TaskID: taskID, ExplorationID: explorationID(ts), IntentID: intent.ID})
|
||||
tools, def, cleanup := AugmentTools(ctx, "worker", base)
|
||||
defer cleanup()
|
||||
|
||||
@@ -360,6 +361,18 @@ func (w *Worker) Execute(ctx context.Context, name string, taskID int64, as *db.
|
||||
s := agentcore.NewSession(opts)
|
||||
defer s.Close() // release the session's background-task manager (temp dir + processes)
|
||||
|
||||
// Resume prior conversation if this intent was paused/blocked/exhausted and is
|
||||
// being re-run. The transcript ID is deterministic per intent, so if a prior
|
||||
// session exists the worker continues from where it left off instead of
|
||||
// restarting from scratch.
|
||||
if w.tx != nil {
|
||||
_ = s.Resume(opts.SessionID)
|
||||
if len(s.Messages()) > 0 {
|
||||
seedUnlockFromHistory(s.Messages(), def.UnlockSkill)
|
||||
input = "继续执行。"
|
||||
}
|
||||
}
|
||||
|
||||
// Budgets + settlement are owned by the SDK (MaxTurns/MaxDuration + Settlement):
|
||||
// on hit it runs a wrap-up turn and finishes with ReasonMaxTurns/ReasonTimeout.
|
||||
// We only add a HARD ctx backstop past the soft wall-clock budget, for the rare
|
||||
|
||||
Reference in new issue
Block a user