plan

package
v1.91.0 Latest Latest
Warning

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

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

Documentation

Overview

Package plan provides a toolset that lets two or more agents collaborate on plans addressed by name. Plans persist through a pluggable Storage backend; the default FilesystemStorage keeps them as JSON files in a global shared folder under the docker-agent data directory, so any agent that loads this toolset can write, read, list, and delete the same shared plans, and they persist across sessions. Embedders can inject an alternative backend (e.g. a database or remote store) with WithStorage.

Concurrency: agents that share one ToolSet instance also share its Storage, which serializes their operations. The default FilesystemStorage guards its read-modify-write revision bump with a mutex and writes atomically (write-to-temp + rename), so a reader — including a separate docker-agent process — never observes a partially written plan. Two distinct processes writing the *same* plan at the very same instant can still race on the revision bump (last writer wins); this is acceptable for the intended in-process multi-agent collaboration. Other backends can make the bump atomic.

Index

Constants

View Source
const (
	ToolNameWritePlan          = "write_plan"
	ToolNameReadPlan           = "read_plan"
	ToolNameListPlans          = "list_plans"
	ToolNameDeletePlan         = "delete_plan"
	ToolNameUpdatePlanFromFile = "update_plan_from_file"
	ToolNameExportPlanToFile   = "export_plan_to_file"
	ToolNameSetPlanStatus      = "set_plan_status"
	ToolNameGetPlanStatus      = "get_plan_status"
)

Variables

View Source
var ErrPlanNotFound = errors.New("plan not found")

ErrPlanNotFound is returned by write operations that require an existing plan (set_plan_status) when the named plan does not exist, so callers can tell a missing plan apart from a real backend failure.

Functions

func CreateToolSet

func CreateToolSet() (tools.ToolSet, error)

CreateToolSet is used by the tools registry. It returns a process-wide singleton so that all agents collaborating in the same process share one storage over the global plans folder.

func DefaultDir

func DefaultDir() string

DefaultDir is the global shared folder where plans are stored, under the docker-agent data directory.

Types

type DeletePlanArgs

type DeletePlanArgs struct {
	Name              string `json:"name" jsonschema:"The name of the plan to delete."`
	LastKnownRevision *int   `` /* 183-byte string literal not displayed */
}

type ExportPlanToFileArgs added in v1.89.0

type ExportPlanToFileArgs struct {
	Name string `json:"name" jsonschema:"The name of the plan to export."`
	Path string `` /* 185-byte string literal not displayed */
}

type ExportResult added in v1.89.0

type ExportResult struct {
	Name         string `json:"name"`
	Path         string `json:"path"`
	Title        string `json:"title,omitempty"`
	Status       string `json:"status,omitempty"`
	Revision     int    `json:"revision"`
	BytesWritten int    `json:"bytesWritten"`
}

ExportResult is the result of export_plan_to_file. It deliberately omits the plan content: the content is written to disk, not returned, so materialising a plan on disk before an edit costs no output tokens.

type FilesystemStorage added in v1.88.0

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

FilesystemStorage is the default Storage. It persists each plan as a JSON file named <name>.json in a directory, with atomic temp+rename writes, plan name validation, and unreadable-file warnings on List. A mutex serializes its operations so the read-modify-write revision bump in Upsert is consistent within a process.

func NewFilesystemStorage added in v1.88.0

func NewFilesystemStorage(dir string) *FilesystemStorage

NewFilesystemStorage returns a filesystem-backed Storage rooted at dir. The directory is created lazily on the first write, not here, so a parent that is momentarily unavailable at startup is recovered from automatically.

func (*FilesystemStorage) Delete added in v1.88.0

func (s *FilesystemStorage) Delete(_ context.Context, name string, expectedRevision *int) (bool, error)

func (*FilesystemStorage) Get added in v1.88.0

func (s *FilesystemStorage) Get(_ context.Context, name string) (Plan, bool, error)

func (*FilesystemStorage) List added in v1.88.0

func (s *FilesystemStorage) List(_ context.Context) ([]Summary, []string, error)

func (*FilesystemStorage) String added in v1.88.0

func (s *FilesystemStorage) String() string

String renders the backend for ToolSet.Describe, e.g. "dir=/path/to/plans".

func (*FilesystemStorage) Upsert added in v1.88.0

type GetPlanStatusArgs added in v1.89.0

type GetPlanStatusArgs struct {
	Name string `json:"name" jsonschema:"The name of the plan whose status to read."`
}

type ListResult

type ListResult struct {
	Plans    []Summary `json:"plans"`
	Warnings []string  `json:"warnings,omitempty"`
}

ListResult is the output of list_plans. Warnings lists plan files that could not be read or decoded, so a caller can tell "no plans exist" apart from "some plans failed to load" — important because an agent that mistakes a temporarily unreadable plan for a missing one could recreate and clobber it.

type Option added in v1.88.0

type Option func(*ToolSet)

Option configures a ToolSet.

func WithStorage added in v1.88.0

func WithStorage(storage Storage) Option

WithStorage injects a custom Storage backend in place of the default FilesystemStorage, letting embedders supply their own store and get per-instance isolation. The provided storage must not be nil.

type Plan

type Plan struct {
	Name    string `json:"name"`
	Title   string `json:"title,omitempty"`
	Content string `json:"content"`
	// Author is a free-form label identifying who last wrote the plan
	// (typically the agent name). It helps collaborators see who made the
	// most recent change.
	Author string `json:"author,omitempty"`
	// Status is a free-form lifecycle label (e.g. "idle", "in-progress",
	// "blocked", "done"). There is no fixed vocabulary: agents and users define
	// their own in the system prompt.
	Status string `json:"status,omitempty"`
	// Revision is the plan's monotonically increasing version number, bumped on
	// every write. Callers capture it on a read and pass it back as
	// last_known_revision to detect concurrent modifications (optimistic
	// locking).
	Revision  int    `json:"revision"`
	UpdatedAt string `json:"updatedAt"`
}

Plan is a shared document collaborated on by the agents.

type ReadPlanArgs

type ReadPlanArgs struct {
	Name string `json:"name" jsonschema:"The name of the plan to read."`
}

type SetPlanStatusArgs added in v1.89.0

type SetPlanStatusArgs struct {
	Name              string `json:"name" jsonschema:"The name of the plan whose status to set."`
	Status            string `` /* 131-byte string literal not displayed */
	LastKnownRevision *int   `` /* 182-byte string literal not displayed */
}

type StatusView added in v1.89.0

type StatusView struct {
	Name     string `json:"name"`
	Status   string `json:"status"`
	Revision int    `json:"revision"`
}

StatusView is the lightweight result of set_plan_status and get_plan_status: just the status and the revision, without the plan body, so reading or writing the status never costs the tokens of the full content.

type Storage added in v1.88.0

type Storage interface {
	// Get returns the named plan. The bool is false with a nil error when no
	// such plan exists, so callers can tell a missing plan apart from a real
	// read failure (returned as a non-nil error).
	Get(ctx context.Context, name string) (Plan, bool, error)
	// Upsert creates or updates a plan as described by req: nil fields are
	// preserved from the previous revision, the optimistic-lock check and the
	// must-exist guard are honoured atomically with the write, the revision is
	// bumped and UpdatedAt stamped. It returns a *VersionConflictError on a
	// revision mismatch and ErrPlanNotFound when req.MustExist is set but the
	// plan is absent.
	Upsert(ctx context.Context, req UpsertRequest) (Plan, error)
	// List returns a summary of every stored plan. Warnings carries entries
	// that could not be read, so a caller can tell "no plans" apart from "some
	// plans failed to load".
	List(ctx context.Context) (plans []Summary, warnings []string, err error)
	// Delete removes the named plan. The bool is false with a nil error when
	// there was no such plan to delete. When expectedRevision is non-nil the
	// delete is rejected with a *VersionConflictError unless it matches the
	// plan's current revision.
	Delete(ctx context.Context, name string, expectedRevision *int) (deleted bool, err error)
}

Storage persists the plans a ToolSet operates on. Implementations decide how a plan is stored (files, memory, a database, a remote service) and own the revision bump in Upsert, so a backend can make it atomic. The default FilesystemStorage is used when WithStorage injects nothing else.

type Summary

type Summary struct {
	Name      string `json:"name"`
	Title     string `json:"title,omitempty"`
	Author    string `json:"author,omitempty"`
	Status    string `json:"status,omitempty"`
	Revision  int    `json:"revision"`
	UpdatedAt string `json:"updatedAt"`
}

Summary is a lightweight view of a plan returned by list_plans.

type ToolSet

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

func New

func New(opts ...Option) *ToolSet

New builds a per-instance plan toolset. With no options it uses the default FilesystemStorage rooted at DefaultDir(); pass WithStorage to inject another backend. Each call returns an independent instance — use CreateToolSet for the process-wide singleton shared by collaborating agents.

func (*ToolSet) Describe

func (t *ToolSet) Describe() string

func (*ToolSet) Instructions

func (t *ToolSet) Instructions() string

func (*ToolSet) Tools

func (t *ToolSet) Tools(context.Context) ([]tools.Tool, error)

type UpdatePlanFromFileArgs added in v1.89.0

type UpdatePlanFromFileArgs struct {
	Name              string `json:"name" jsonschema:"The plan name. Lowercase letters, digits, '-' and '_' only."`
	Path              string `` /* 144-byte string literal not displayed */
	Title             string `json:"title,omitempty" jsonschema:"Optional human-readable title. Preserved from the previous revision when omitted."`
	Author            string `` /* 139-byte string literal not displayed */
	Status            string `json:"status,omitempty" jsonschema:"Optional free-form lifecycle status. Preserved from the previous revision when omitted."`
	LastKnownRevision *int   `` /* 182-byte string literal not displayed */
}

type UpsertRequest added in v1.89.0

type UpsertRequest struct {
	Name             string
	Content          *string
	Title            *string
	Author           *string
	Status           *string
	ExpectedRevision *int
	MustExist        bool
}

UpsertRequest describes a create-or-update operation on a plan. Content, Title, Author and Status are pointers so an omitted field (nil) preserves the previous value while an explicit value (including "") overwrites it; this lets a caller change just the status without rewriting the body. ExpectedRevision enables optimistic locking: when non-nil, the write is rejected with a *VersionConflictError unless it equals the plan's current revision. MustExist makes the write fail with ErrPlanNotFound when the plan does not already exist (used by set_plan_status, which must not create a plan).

type VersionConflictError added in v1.89.0

type VersionConflictError struct {
	Name     string
	Expected int
	Current  int
}

VersionConflictError is returned by a write when the caller's last_known_revision does not match the plan's current revision, signalling that another writer changed the plan in the meantime. The caller should re-read the plan and retry against the new revision.

func (*VersionConflictError) Error added in v1.89.0

func (e *VersionConflictError) Error() string

type WritePlanArgs

type WritePlanArgs struct {
	Name              string `json:"name" jsonschema:"The plan name. Lowercase letters, digits, '-' and '_' only (e.g. 'release', 'db-migration')."`
	Content           string `json:"content" jsonschema:"The full plan content (markdown). Replaces the existing plan."`
	Title             string `json:"title,omitempty" jsonschema:"Optional human-readable title. Preserved from the previous revision when omitted."`
	Author            string `` /* 166-byte string literal not displayed */
	Status            string `` /* 164-byte string literal not displayed */
	LastKnownRevision *int   `` /* 219-byte string literal not displayed */
}

Jump to

Keyboard shortcuts

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