Bound agent result cache
This commit is contained in:
parent
062642dfd3
commit
6c1de81cf9
|
|
@ -36,7 +36,7 @@ type Agent struct {
|
|||
closed atomic.Bool
|
||||
actionMu sync.Mutex // serializes action registration with shutdown
|
||||
warnedContext bool
|
||||
resultCache sync.Map
|
||||
resultCache resultCache
|
||||
|
||||
// Execution state — owned by the agent, protected by stateMu.
|
||||
state string // "idle", "thinking", "calling: <tool>"
|
||||
|
|
|
|||
|
|
@ -43,6 +43,56 @@ type cachedResult struct {
|
|||
Size int64 // file size at cache time; -1 if no file
|
||||
}
|
||||
|
||||
const (
|
||||
resultCacheMaxEntries = 256
|
||||
resultCacheMaxBytes = 32 * 1024 * 1024
|
||||
)
|
||||
|
||||
type resultCache struct {
|
||||
mu sync.Mutex
|
||||
items map[string]cachedResult
|
||||
bytes int
|
||||
}
|
||||
|
||||
func (c *resultCache) Load(key string) (cachedResult, bool) {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
v, ok := c.items[key]
|
||||
return v, ok
|
||||
}
|
||||
|
||||
func (c *resultCache) Delete(key string) {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
if v, ok := c.items[key]; ok {
|
||||
c.bytes -= len(v.Result)
|
||||
delete(c.items, key)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *resultCache) Store(key string, value cachedResult) {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
if c.items == nil {
|
||||
c.items = make(map[string]cachedResult)
|
||||
}
|
||||
if old, ok := c.items[key]; ok {
|
||||
c.bytes -= len(old.Result)
|
||||
}
|
||||
if len(value.Result) > resultCacheMaxBytes {
|
||||
return
|
||||
}
|
||||
c.items[key] = value
|
||||
c.bytes += len(value.Result)
|
||||
for len(c.items) > resultCacheMaxEntries || c.bytes > resultCacheMaxBytes {
|
||||
for k, v := range c.items {
|
||||
delete(c.items, k)
|
||||
c.bytes -= len(v.Result)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// extractFilePath attempts to pull a "path" field from JSON tool args.
|
||||
func extractFilePath(args json.RawMessage) string {
|
||||
var m map[string]json.RawMessage
|
||||
|
|
@ -533,8 +583,7 @@ func (ag *Agent) execOne(ctx context.Context, call backend.ToolCall) (toolResult
|
|||
readSafe := rt.ToolMeta[call.Name].Scope == "read"
|
||||
if readSafe {
|
||||
key := call.Name + "\x00" + string(call.Arguments)
|
||||
if v, ok := resultCache.Load(key); ok {
|
||||
entry := v.(cachedResult)
|
||||
if entry, ok := resultCache.Load(key); ok {
|
||||
if cacheValid(entry, call.Arguments) {
|
||||
ag.emit(Event{Role: "tool", Name: call.Name, Content: entry.Result, OutputFormat: toolOutputFormat(rt, call.Name)})
|
||||
return toolResult{ToolCallID: call.ID, Name: call.Name, Content: entry.Result}, false
|
||||
|
|
|
|||
Loading…
Reference in New Issue