Middleware: PlanTask
PlanTask Middleware
adk/middlewares/plantask
π‘ This middleware was introduced in v0.8.0.Beta.
Overview
plantask is a task management middleware that allows Agents to create and manage task lists. The middleware injects four tools through the BeforeAgent hook:
- TaskCreate: Create a task
- TaskGet: View task details
- TaskUpdate: Update a task
- TaskList: List all tasks
Main purposes:
- Track progress of complex tasks
- Break large tasks into smaller steps
- Manage dependencies between tasks
Architecture
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Agent β
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β BeforeAgent: Inject task tools β β
β β - TaskCreate β β
β β - TaskGet β β
β β - TaskUpdate β β
β β - TaskList β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Backend β
β β
β Storage structure: β
β baseDir/ β
β βββ .highwatermark # ID counter β
β βββ 1.json # Task #1 β
β βββ 2.json # Task #2 β
β βββ ... β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Configuration
type Config struct {
Backend Backend // Storage backend, required
BaseDir string // Task file directory, required
}
- Note that the Backend implementation should be isolated by session, with different sessions corresponding to different Backends (task lists)
Backend Interface
type Backend interface {
LsInfo(ctx context.Context, req *LsInfoRequest) ([]FileInfo, error)
Read(ctx context.Context, req *ReadRequest) (string, error)
Write(ctx context.Context, req *WriteRequest) error
Delete(ctx context.Context, req *DeleteRequest) error
}
Task Structure
type task struct {
ID string `json:"id"` // Task ID
Subject string `json:"subject"` // Title
Description string `json:"description"` // Description
Status string `json:"status"` // Status
Blocks []string `json:"blocks"` // Tasks blocked by this one
BlockedBy []string `json:"blockedBy"` // Tasks blocking this one
ActiveForm string `json:"activeForm"` // Active form text
Owner string `json:"owner"` // Responsible agent
Metadata map[string]any `json:"metadata"` // Custom data
}
Status
| Status | Description |
pending | Pending (default) |
in_progress | In progress |
completed | Completed |
deleted | Deleted (will delete the file) |
Status transition: pending β in_progress β completed, any status can be directly deleted.
Tools
TaskCreate
Create a task.
| Parameter | Type | Required | Description |
subject | string | Yes | Title |
description | string | Yes | Description |
activeForm | string | No | Active form text, e.g., "Running tests" |
metadata | object | No | Custom data |
When to use:
- The task is relatively complex with 3 or more steps
- The user has given a list of things to do
- You need to show progress to the user
When not to use:
- It’s just a simple task
- Something that can be done quickly
TaskGet
View task details.
| Parameter | Type | Required | Description |
taskId | string | Yes | Task ID |
Returns complete information about the task: title, description, status, dependencies, etc.
TaskUpdate
Update a task.
| Parameter | Type | Required | Description |
taskId | string | Yes | Task ID |
subject | string | No | New title |
description | string | No | New description |
activeForm | string | No | New active form text |
status | string | No | New status |
addBlocks | []string | No | Add blocked tasks |
addBlockedBy | []string | No | Add tasks blocking this one |
owner | string | No | Responsible agent |
metadata | object | No | Custom data (set to null to delete) |
Notes:
status: "deleted"will directly delete the task file- Circular dependencies are checked when adding dependencies
- Automatic cleanup occurs when all tasks are completed
TaskList
List all tasks, no parameters required.
Returns a summary of each task: ID, status, title, responsible agent, dependencies.
Usage Example
ctx := context.Background()
// The plantask middleware should normally be session-scoped
// Different sessions correspond to different task lists
middleware, err := plantask.New(ctx, &plantask.Config{
Backend: myBackend,
BaseDir: "/tasks",
})
if err != nil {
return err
}
agent, err := adk.NewChatModelAgent(ctx, &adk.ChatModelAgentConfig{
Model: myModel,
Handlers: []adk.ChatModelAgentMiddleware{middleware},
})
Typical Flow
1. Receive complex task
β
βΌ
2. TaskCreate to create tasks
- #1: Analyze requirements
- #2: Write code
β
βΌ
3. TaskUpdate to set dependencies
- #2 depends on #1
- #3 depends on #2
β
βΌ
4. TaskList to see what tasks exist
β
βΌ
5. TaskUpdate to start working
- Change #1 to in_progress
β
βΌ
6. When done, TaskUpdate
- Change #1 to completed
β
βΌ
7. Loop 4-6 until all completed
β
βΌ
8. Automatic cleanup
Dependency Management
- blocks: These tasks can start after I complete
- blockedBy: I can start after these tasks complete
Task #1 (blocks: ["2"]) βββββΊ Task #2 (blockedBy: ["1"])
#2 can only start after #1 completes
Circular dependencies will throw an error:
#1 blocks #2
#2 blocks #1 β Not allowed, circular
Automatic Cleanup
When all tasks are completed, all task files will be automatically deleted.
Notes
- Task files are stored in JSON format in the
BaseDirdirectory, with filenames as{id}.json - The
.highwatermarkfile is used to record the maximum assigned task ID, ensuring IDs don’t repeat - All tool operations are protected by mutex locks and are concurrency-safe
- The tool descriptions contain detailed usage guidelines that the Agent will follow
Multi-language Support
Tool descriptions support Chinese and English switching via adk.SetLanguage():
// Use Chinese descriptions
adk.SetLanguage(adk.LanguageChinese)
// Use English descriptions (default)
adk.SetLanguage(adk.LanguageEnglish)
This setting is global and affects all ADK built-in prompts and tool descriptions.