yao/trace/state.go
Max af981dc0b0 Update dependencies and enhance logging in the Assistant module
- Add new indirect dependencies including various Charmbracelet packages for improved UI handling.
- Enhance logging in the Assistant module by adding tool completion and start logging for better traceability of tool calls.
- Modify context handling in the RequestLogger to support a stack-based assistant ID management, improving the logging structure for agent requests.
- Implement event service integration for better trace management and debugging capabilities.
2026-02-23 19:22:31 +08:00

148 lines
3.4 KiB
Go

package trace
import (
"fmt"
"github.com/yaoapp/kun/log"
"github.com/yaoapp/yao/trace/types"
)
// managerState holds all mutable state for a trace.
// Protected by manager.mu — all access goes through state* methods which acquire the lock.
type managerState struct {
rootNode *types.TraceNode
currentNodes []*types.TraceNode
spaces map[string]*types.TraceSpace
traceStatus types.TraceStatus
completed bool
updates []*types.TraceUpdate
}
func (m *manager) stateSetRoot(node *types.TraceNode) {
m.mu.Lock()
defer m.mu.Unlock()
m.state.rootNode = node
}
func (m *manager) stateGetRoot() *types.TraceNode {
m.mu.Lock()
defer m.mu.Unlock()
return m.state.rootNode
}
func (m *manager) stateSetCurrentNodes(nodes []*types.TraceNode) {
m.mu.Lock()
defer m.mu.Unlock()
m.state.currentNodes = nodes
}
func (m *manager) stateGetCurrentNodes() []*types.TraceNode {
m.mu.Lock()
defer m.mu.Unlock()
if m.state.currentNodes == nil {
return nil
}
nodes := make([]*types.TraceNode, len(m.state.currentNodes))
copy(nodes, m.state.currentNodes)
return nodes
}
func (m *manager) stateUpdateRootAndCurrent(root *types.TraceNode, current []*types.TraceNode) {
m.mu.Lock()
defer m.mu.Unlock()
m.state.rootNode = root
m.state.currentNodes = current
}
func (m *manager) stateGetSpace(id string) (*types.TraceSpace, bool) {
m.mu.Lock()
defer m.mu.Unlock()
space, ok := m.state.spaces[id]
return space, ok
}
func (m *manager) stateSetSpace(id string, space *types.TraceSpace) {
m.mu.Lock()
defer m.mu.Unlock()
m.state.spaces[id] = space
}
func (m *manager) stateDeleteSpace(id string) {
m.mu.Lock()
defer m.mu.Unlock()
delete(m.state.spaces, id)
}
func (m *manager) stateGetAllSpaces() []*types.TraceSpace {
m.mu.Lock()
defer m.mu.Unlock()
spaces := make([]*types.TraceSpace, 0, len(m.state.spaces))
for _, space := range m.state.spaces {
spaces = append(spaces, space)
}
return spaces
}
func (m *manager) stateSetTraceStatus(status types.TraceStatus) {
m.mu.Lock()
defer m.mu.Unlock()
m.state.traceStatus = status
}
func (m *manager) stateGetTraceStatus() types.TraceStatus {
m.mu.Lock()
defer m.mu.Unlock()
return m.state.traceStatus
}
func (m *manager) stateMarkCompleted() bool {
m.mu.Lock()
defer m.mu.Unlock()
if m.state.completed {
return false
}
m.state.completed = true
return true
}
func (m *manager) stateIsCompleted() bool {
m.mu.Lock()
defer m.mu.Unlock()
return m.state.completed
}
func (m *manager) stateAddUpdate(update *types.TraceUpdate) {
m.mu.Lock()
defer m.mu.Unlock()
m.state.updates = append(m.state.updates, update)
}
func (m *manager) stateGetUpdates(since int64) []*types.TraceUpdate {
m.mu.Lock()
defer m.mu.Unlock()
filtered := make([]*types.TraceUpdate, 0)
for _, update := range m.state.updates {
if update.Timestamp >= since {
filtered = append(filtered, update)
}
}
return filtered
}
func (m *manager) stateSetUpdates(updates []*types.TraceUpdate) {
m.mu.Lock()
defer m.mu.Unlock()
log.Trace("[STATE] stateSetUpdates: setting %d updates for trace %s", len(updates), m.traceID)
m.state.updates = updates
}
// stateExecuteSpaceOp executes a space operation while holding the lock.
func (m *manager) stateExecuteSpaceOp(spaceID string, fn func() error) error {
m.mu.Lock()
defer m.mu.Unlock()
err := fn()
if err != nil {
return fmt.Errorf("trace %s: space op failed: %w", m.traceID, err)
}
return nil
}