Files
DeepSeek-Reasonix/internal/memory/queue.go
T
SivanCola a6238139c4 fix(goal): harden contextual tool and migration boundaries
Problem:
Context-dependent tools could be called outside their owning Goal, Plan, Jobs, or child-agent context, and failed legacy AutoResearch migration lost its retry identity after restart.

Root cause:
Availability was enforced by scattered execution checks while provider-visible registration, host metadata, mixed batches, and inherited child context used different state. The Goal sidecar writer also fenced every new write without preserving a pending legacy task id.

Fix:
Add a shared ContextualTool execution contract with one-repair run-loop handling, isolate child Goal/Jobs/memory state, project contextual schemas only for host metadata, and retain pending legacy task ids until a Goal-only sidecar is durably committed.

Verification:
go test ./... -count=1
cd desktop && go test ./... -count=1
go test -race ./internal/control ./internal/agent ./internal/tool ./internal/tool/builtin ./internal/jobs ./internal/memory -count=1
go vet ./...
golangci-lint run --timeout=5m
scripts/cache-guard.sh
git diff --check
2026-08-09 09:10:28 +08:00

49 lines
1.6 KiB
Go

package memory
import (
"context"
"encoding/json"
)
// Queue receives a one-line note about a memory change a tool just made, so the
// controller can fold it into the current turn — taking effect this session
// without touching the cache-stable system prefix. The remember/forget tools
// read it from their call context the same way background tools read the job
// manager.
type Queue interface{ QueueMemory(note string) }
type autoMemoryWriteClaimer interface {
ClaimAutoMemoryWrite(args json.RawMessage) bool
}
type queueKey struct{}
type noQueue struct{}
// WithQueue stamps q onto ctx for the remember/forget tools to find.
func WithQueue(ctx context.Context, q Queue) context.Context {
return context.WithValue(ctx, queueKey{}, q)
}
// WithoutQueue shadows an ancestor queue. Child agents may persist memory but
// must not inject turn-tail notes into the parent's live conversation.
func WithoutQueue(ctx context.Context) context.Context {
return context.WithValue(ctx, queueKey{}, noQueue{})
}
// QueueFromContext returns the memory queue the agent stamped, if any.
func QueueFromContext(ctx context.Context) (Queue, bool) {
q, ok := ctx.Value(queueKey{}).(Queue)
return q, ok && q != nil
}
// ClaimAutoMemoryWriteFromContext consumes a host-issued create-only grant.
// Manual/approved writes have no claim and retain the legacy update behavior.
func ClaimAutoMemoryWriteFromContext(ctx context.Context, args json.RawMessage) bool {
q, ok := QueueFromContext(ctx)
if !ok {
return false
}
claimer, ok := q.(autoMemoryWriteClaimer)
return ok && claimer.ClaimAutoMemoryWrite(args)
}