func openMemory(ctx context.Context, root string, clock func() time.Time, summarizer Summarizer, logger *slog.Logger) (*Memory, error) {
log, err := openLog(ctx, root, clock)
if err != nil {
- return nil, err
+ return nil, fmt.Errorf("open memory log: %w", err)
}
m := &Memory{
for id := range m.chat.end {
built, err := m.tree.Built(0, id)
if err != nil {
- return err
+ return fmt.Errorf("check restored leaf: %w", err)
}
if built {
message, err := m.log.Message(id)
if err != nil {
- return err
+ return fmt.Errorf("read restored message: %w", err)
}
leaf, free := freeLeaf(message)
err = m.build(leaf)
if err != nil {
- return err
+ return fmt.Errorf("build restored leaf: %w", err)
}
}
keys, err := m.tree.Keys()
if err != nil {
- return err
+ return fmt.Errorf("read built nodes: %w", err)
}
for _, key := range keys {
err = m.settle(key)
if err != nil {
- return err
+ return fmt.Errorf("settle restored node: %w", err)
}
}
for m.chat.end < m.log.Len() {
message, err := m.log.Message(m.chat.end)
if err != nil {
- return err
+ return fmt.Errorf("read pending message: %w", err)
}
err = m.addMessage(message)
if err != nil {
- return err
+ return fmt.Errorf("add pending message: %w", err)
}
}
- return m.save()
+ err := m.save()
+ if err != nil {
+ return fmt.Errorf("save caught-up memory: %w", err)
+ }
+
+ return nil
}
// dispatch starts the builds that are ready, up to the limit. A build whose
func (m *Memory) build(node Node) error {
err := m.tree.Add(node)
if err != nil {
- return err
+ return fmt.Errorf("add built node: %w", err)
}
m.chat.Refresh(node)
m.cview.Refresh(node)
- return m.settle(NodeKey{node.Level, node.Index})
+ err = m.settle(NodeKey{node.Level, node.Index})
+ if err != nil {
+ return fmt.Errorf("settle built node: %w", err)
+ }
+
+ return nil
}
// settle looks at the parent of the built node key when both children are
parent := NodeKey{key.level + 1, key.index / 2}
ready, err := m.ready(parent)
if err != nil || !ready {
- return err
+ if err != nil {
+ return fmt.Errorf("check parent readiness: %w", err)
+ }
+
+ return nil
}
left, right, err := m.children(parent)
if err != nil {
- return err
+ return fmt.Errorf("read parent children: %w", err)
}
node, free := freeMerge(left, right)
err = m.tree.Add(node)
if err != nil {
- return err
+ return fmt.Errorf("add merged node: %w", err)
}
key = parent
func (m *Memory) addMessage(message Message) error {
built, err := m.tree.Built(0, message.ID)
if err != nil {
- return err
+ return fmt.Errorf("check message leaf: %w", err)
}
leaf, free := freeLeaf(message)
case free:
err = m.build(leaf)
if err != nil {
- return err
+ return fmt.Errorf("build message leaf: %w", err)
}
default:
m.queue.AddLeaf(message.ID)
if key.level == 0 {
message, err := m.log.Message(key.index)
if err != nil {
- return Task{}, err
+ return Task{}, fmt.Errorf("read leaf message: %w", err)
}
task.Input = []string{leafSource(message)}
left, right, err := m.children(key)
if err != nil {
- return Task{}, err
+ return Task{}, fmt.Errorf("read task children: %w", err)
}
for _, child := range []Node{left, right} {
for _, index := range []int{2 * key.index, 2*key.index + 1} {
built, err := m.tree.Built(key.level-1, index)
if err != nil || !built {
- return false, err
+ if err != nil {
+ return false, fmt.Errorf("check child readiness: %w", err)
+ }
+
+ return false, nil
}
}
built, err := m.tree.Built(key.level, key.index)
+ if err != nil {
+ return !built, fmt.Errorf("check parent readiness: %w", err)
+ }
- return !built, err
+ return !built, nil
}
// children reads the two children of the node key.
for n := range children {
child, built, err := m.tree.Node(key.level-1, 2*key.index+n)
if err != nil {
- return Node{}, Node{}, err
+ return Node{}, Node{}, fmt.Errorf("read child node: %w", err)
}
if !built {