task

package
v1.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 1, 2026 License: Apache-2.0 Imports: 12 Imported by: 0

Documentation

Overview

Package task provides persistent, dependency-aware task decomposition and kanban-style work management. Tasks are domain-agnostic units of cognitive work (research, analysis, writing, decisions, implementation, review, etc.).

Index

Constants

View Source
const (
	TopicTaskCreated   = "task.created"
	TopicTaskClaimed   = "task.claimed"
	TopicTaskReleased  = "task.released"
	TopicTaskCompleted = "task.completed"
	TopicTaskBlocked   = "task.blocked"
	TopicTaskUpdated   = "task.updated"
	TopicTaskDeleted   = "task.deleted"
	TopicBoardUpdated  = "board.updated"
)

Bus topics for task lifecycle events.

Variables

This section is empty.

Functions

func CategoryName

func CategoryName(category loomv1.TaskCategory) string

CategoryName returns the human-readable name of a task category.

func IsTerminal

func IsTerminal(status loomv1.TaskStatus) bool

IsTerminal returns true if the status is a terminal state (DONE, DEFERRED, CANCELLED).

func ParseCategory

func ParseCategory(s string) loomv1.TaskCategory

func ParsePriority

func ParsePriority(s string) loomv1.TaskPriority

func PriorityName

func PriorityName(priority loomv1.TaskPriority) string

PriorityName returns the human-readable name of a task priority.

func StatusName

func StatusName(status loomv1.TaskStatus) string

StatusName returns the human-readable name of a task status.

Types

type DecomposeRequest

type DecomposeRequest struct {
	Goal       string
	Context    string
	BoardID    string
	ParentTask *Task // optional: decompose under this parent
	MaxDepth   int
	Strategy   loomv1.DecomposeStrategy
	AgentID    string
}

DecomposeRequest contains the parameters for task decomposition.

type DecomposeResponse

type DecomposeResponse struct {
	Tasks        []*Task
	Dependencies []*TaskDependency
	Reasoning    string
}

DecomposeResponse contains the decomposition results.

type Decomposer

type Decomposer struct {
	// contains filtered or unexported fields
}

Decomposer uses an LLM to break down a high-level goal into a dependency DAG.

func NewDecomposer

func NewDecomposer(manager *Manager, tracer observability.Tracer, logger *zap.Logger) *Decomposer

NewDecomposer creates a new LLM-assisted task decomposer.

func (*Decomposer) Decompose

Decompose uses an LLM to break a goal into a dependency DAG of tasks, creates them in the store, and wires up dependencies.

type ListTasksOpts

type ListTasksOpts struct {
	BoardID         string
	Status          loomv1.TaskStatus
	Priority        loomv1.TaskPriority
	Category        loomv1.TaskCategory
	AssigneeAgentID string
	ParentID        string
	Query           string // full-text search
	Limit           int
	Offset          int
}

ListTasksOpts configures task list queries.

type Manager

type Manager struct {
	// contains filtered or unexported fields
}

Manager provides business logic on top of TaskStore. It handles cycle detection, auto-status propagation, event publishing, WIP limit enforcement, and task compaction.

func NewManager

func NewManager(store TaskStore, bus *communication.MessageBus, tracer observability.Tracer, logger *zap.Logger) *Manager

NewManager creates a new task manager.

func (*Manager) AddDependency

func (m *Manager) AddDependency(ctx context.Context, dep *TaskDependency) error

AddDependency adds a dependency edge after checking for cycles. If the dependency type is BLOCKS and the blocker is not finished, the from_task is automatically transitioned to BLOCKED (from OPEN or IN_PROGRESS).

func (*Manager) ClaimTask

func (m *Manager) ClaimTask(ctx context.Context, taskID, agentID, sessionID string) (*Task, error)

ClaimTask atomically claims a task for an agent session. Enforces WIP limits if the task's board has a lane with a WIP limit set.

func (*Manager) CloseTask

func (m *Manager) CloseTask(ctx context.Context, taskID, reason string) (*Task, error)

CloseTask marks a task as DONE and auto-completes the parent if all siblings are done.

func (*Manager) CompactClosedTasks

func (m *Manager) CompactClosedTasks(ctx context.Context, boardID string, maxAge time.Duration, summarize func(t *Task) (string, error)) (int, error)

CompactClosedTasks summarizes old closed tasks to reduce context token usage. Tasks older than maxAge with compaction_level=0 get their description and notes replaced with a compact summary. The summary is generated by the provided summarize function (typically an LLM call — wired in Phase 4 Decomposer). Returns the number of tasks compacted.

func (*Manager) CreateBoard

func (m *Manager) CreateBoard(ctx context.Context, board *TaskBoard) (*TaskBoard, error)

CreateBoard creates a new kanban board.

func (*Manager) CreateTask

func (m *Manager) CreateTask(ctx context.Context, t *Task) (*Task, error)

CreateTask creates a task and publishes a task.created event.

func (*Manager) CreateTaskIdempotent

func (m *Manager) CreateTaskIdempotent(ctx context.Context, t *Task) (*Task, bool, error)

CreateTaskIdempotent looks up an existing task by SkillIdempotencyKey and returns it when present; otherwise it creates the task normally. The boolean return is true when the task was newly created (and history + event were emitted) and false when an existing task was returned.

Callers that supply an empty SkillIdempotencyKey degrade to plain CreateTask semantics — the lookup is only meaningful for non-empty keys.

Used by the skills task emitter to dedupe concurrent skill activations for the same (skill, session, step) tuple.

func (*Manager) DeleteTask

func (m *Manager) DeleteTask(ctx context.Context, id string) error

DeleteTask soft-deletes a task and records history + event.

func (*Manager) GetBlockedTasks

func (m *Manager) GetBlockedTasks(ctx context.Context, boardID string) ([]*Task, error)

GetBlockedTasks returns tasks waiting on unfinished dependencies.

func (*Manager) GetBoard

func (m *Manager) GetBoard(ctx context.Context, id string) (*TaskBoard, error)

GetBoard retrieves a board by ID.

func (*Manager) GetHistory

func (m *Manager) GetHistory(ctx context.Context, taskID string) ([]*TaskHistoryEntry, error)

GetHistory retrieves the audit trail for a task.

func (*Manager) GetReadyFront

func (m *Manager) GetReadyFront(ctx context.Context, boardID string, opts ReadyFrontOpts) ([]*Task, error)

GetReadyFront returns tasks with all dependencies satisfied.

func (*Manager) GetTask

func (m *Manager) GetTask(ctx context.Context, id string) (*Task, error)

GetTask retrieves a task by ID and populates ChildIDs.

func (*Manager) GetTaskByIdempotencyKey

func (m *Manager) GetTaskByIdempotencyKey(ctx context.Context, key string) (*Task, error)

GetTaskByIdempotencyKey returns the task that owns the given idempotency key, or (nil, nil) when no such task exists. Pass-through to the store.

func (*Manager) HasOpenSkillTasks

func (m *Manager) HasOpenSkillTasks(ctx context.Context, skillName, sessionID string) (bool, error)

HasOpenSkillTasks returns true when at least one task with the given (skill, session) prefix is still in flight. Used by the skills orchestrator to keep skills sticky while they have open work.

func (*Manager) ListBoards

func (m *Manager) ListBoards(ctx context.Context) ([]*TaskBoard, error)

ListBoards lists all boards.

func (*Manager) ListBySkillRun

func (m *Manager) ListBySkillRun(ctx context.Context, skillName, sessionID string) ([]*Task, error)

ListBySkillRun returns every non-deleted task emitted by the given (skill, session) tuple, regardless of status. Used by the end-of-turn hygiene auditor to inventory the active skill's tasks. Returns an empty slice (never nil) when no tasks match.

func (*Manager) ListTasks

func (m *Manager) ListTasks(ctx context.Context, opts ListTasksOpts) ([]*Task, int, error)

ListTasks lists tasks with filtering and pagination.

func (*Manager) ReleaseTask

func (m *Manager) ReleaseTask(ctx context.Context, taskID, sessionID string) (*Task, error)

ReleaseTask releases a claim, returning the task to OPEN status.

func (*Manager) RemoveDependency

func (m *Manager) RemoveDependency(ctx context.Context, fromTaskID, toTaskID string) error

RemoveDependency removes a dependency edge and checks if the dependent task should be unblocked (transitioned from BLOCKED back to OPEN).

func (*Manager) SetBus

func (m *Manager) SetBus(bus *communication.MessageBus)

SetBus sets the message bus for event publishing. This supports two-phase initialization where the Manager is created before the bus is available.

func (*Manager) SetGraphMemory

func (m *Manager) SetGraphMemory(store memory.GraphMemoryStore)

SetGraphMemory sets the graph memory store for auto-creating memories when tasks are completed. Supports two-phase initialization.

func (*Manager) Store

func (m *Manager) Store() TaskStore

Store returns the underlying TaskStore for direct access when needed.

func (*Manager) TransitionTask

func (m *Manager) TransitionTask(ctx context.Context, taskID string, newStatus loomv1.TaskStatus) (*Task, error)

TransitionTask changes task status with validation.

func (*Manager) UpdateTask

func (m *Manager) UpdateTask(ctx context.Context, t *Task, fields []string) (*Task, error)

UpdateTask updates a task and publishes a task.updated event.

type ReadyFrontOpts

type ReadyFrontOpts struct {
	AgentID     string
	MinPriority loomv1.TaskPriority
	MaxResults  int
}

ReadyFrontOpts configures ready front queries.

type Task

type Task struct {
	ID                 string
	Title              string
	Description        string
	Objective          string
	Approach           string
	AcceptanceCriteria string
	Notes              string
	Status             loomv1.TaskStatus
	Priority           loomv1.TaskPriority
	Category           loomv1.TaskCategory
	Tags               []string
	OwnerAgentID       string
	AssigneeAgentID    string
	ClaimedBySession   string
	CreatedAt          time.Time
	UpdatedAt          time.Time
	ClaimedAt          *time.Time
	ClosedAt           *time.Time
	CloseReason        string
	ParentID           string
	ChildIDs           []string
	EntityIDs          []string
	Metadata           map[string]string
	BoardID            string
	CompactionLevel    int
	CompactedSummary   string
	OutputPolicy       *loomv1.OutputPolicy
	EstimatedEffort    string

	// SkillIdempotencyKey is the optional dedup key set by the skills task
	// emitter. Empty for tasks created by other paths. The persistence layer
	// enforces uniqueness on non-empty values via a partial unique index.
	SkillIdempotencyKey string
}

Task is a domain-agnostic unit of cognitive work.

type TaskBoard

type TaskBoard struct {
	ID         string
	Name       string
	WorkflowID string
	Lanes      []TaskLane
	Metadata   map[string]string
	CreatedAt  time.Time
}

TaskBoard is a kanban board that groups tasks into lanes.

type TaskDependency

type TaskDependency struct {
	FromTaskID string
	ToTaskID   string
	Type       loomv1.TaskDependencyType
	CreatedAt  time.Time
	CreatedBy  string
	Metadata   map[string]string
}

TaskDependency is a directed edge in the task dependency graph.

type TaskHistoryEntry

type TaskHistoryEntry struct {
	ID          string
	TaskID      string
	Action      string
	OldStatus   string
	NewStatus   string
	AgentID     string
	SessionID   string
	Timestamp   time.Time
	DetailsJSON string
}

TaskHistoryEntry records an audit trail event for a task.

type TaskLane

type TaskLane struct {
	Name     string
	Status   loomv1.TaskStatus
	TaskIDs  []string
	WIPLimit int
}

TaskLane is a column in a kanban board mapped to a task status.

type TaskStore

type TaskStore interface {
	// Task CRUD
	CreateTask(ctx context.Context, task *Task) (*Task, error)
	GetTask(ctx context.Context, id string) (*Task, error)
	// GetTaskByIdempotencyKey returns the existing task with the given
	// SkillIdempotencyKey, or (nil, nil) when no such task exists. Empty
	// keys always return (nil, nil); they are not stored as a unique
	// constraint and lookups by empty key are meaningless.
	GetTaskByIdempotencyKey(ctx context.Context, key string) (*Task, error)
	// HasOpenSkillTasks returns true when at least one task with the given
	// (skill, session) prefix in skill_idempotency_key is still in flight
	// (status not DONE and not CANCELLED). Used by the skills orchestrator
	// to keep skills sticky while they have open work on the board.
	HasOpenSkillTasks(ctx context.Context, skillName, sessionID string) (bool, error)
	// ListBySkillRun returns every non-deleted task whose
	// skill_idempotency_key matches the (skill, session) prefix, regardless
	// of status. Used by the end-of-turn hygiene auditor to inventory the
	// active skill's tasks. Returns an empty slice (never nil) when no
	// tasks match. Empty skillName or sessionID returns an empty slice.
	ListBySkillRun(ctx context.Context, skillName, sessionID string) ([]*Task, error)
	UpdateTask(ctx context.Context, task *Task, fields []string) (*Task, error)
	DeleteTask(ctx context.Context, id string) error
	ListTasks(ctx context.Context, opts ListTasksOpts) ([]*Task, int, error)

	// Workflow operations
	ClaimTask(ctx context.Context, taskID, agentID, sessionID string) (*Task, error)
	ReleaseTask(ctx context.Context, taskID, sessionID string) (*Task, error)
	CloseTask(ctx context.Context, taskID, reason string) (*Task, error)
	TransitionTask(ctx context.Context, taskID string, newStatus loomv1.TaskStatus) (*Task, error)

	// Dependencies
	AddDependency(ctx context.Context, dep *TaskDependency) error
	RemoveDependency(ctx context.Context, fromTaskID, toTaskID string) error
	GetDependencies(ctx context.Context, taskID string) ([]*TaskDependency, error)
	GetDependents(ctx context.Context, taskID string) ([]*TaskDependency, error)
	GetReadyFront(ctx context.Context, boardID string, opts ReadyFrontOpts) ([]*Task, error)
	GetBlockedTasks(ctx context.Context, boardID string) ([]*Task, error)

	// Boards
	CreateBoard(ctx context.Context, board *TaskBoard) (*TaskBoard, error)
	GetBoard(ctx context.Context, id string) (*TaskBoard, error)
	ListBoards(ctx context.Context) ([]*TaskBoard, error)

	// History
	RecordHistory(ctx context.Context, entry *TaskHistoryEntry) error
	GetHistory(ctx context.Context, taskID string) ([]*TaskHistoryEntry, error)

	Close() error
}

TaskStore defines the storage interface for task management. Implementations exist for SQLite and PostgreSQL.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL