PlanTask

PlanTask ไธญ้—ดไปถ

adk/middlewares/plantask

๐Ÿ’ก ๆœฌไธญ้—ดไปถๅœจ v0.8.0 ็‰ˆๆœฌๅผ•ๅ…ฅใ€‚

ๆฆ‚่ฟฐ

plantask ๆ˜ฏไธ€ไธชไปปๅŠก็ฎก็†ไธญ้—ดไปถ๏ผŒ่ฎฉ Agent ๅฏไปฅๅˆ›ๅปบๅ’Œ็ฎก็†ไปปๅŠกๅˆ—่กจใ€‚ไธญ้—ดไปถ้€š่ฟ‡ BeforeAgent ้’ฉๅญๆณจๅ…ฅๅ››ไธชๅทฅๅ…ท๏ผš

  • TaskCreate: ๅˆ›ๅปบไปปๅŠก
  • TaskGet: ๆŸฅ็œ‹ไปปๅŠก่ฏฆๆƒ…
  • TaskUpdate: ๆ›ดๆ–ฐไปปๅŠก
  • TaskList: ๅˆ—ๅ‡บๆ‰€ๆœ‰ไปปๅŠก

ไธป่ฆ็”จ้€”๏ผš

  • ่ทŸ่ธชๅคๆ‚ไปปๅŠก็š„่ฟ›ๅบฆ
  • ๆŠŠๅคงไปปๅŠกๆ‹†ๆˆๅฐๆญฅ้ชค
  • ็ฎก็†ไปปๅŠก้—ด็š„ไพ่ต–ๅ…ณ็ณป

ๆžถๆž„

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                              Agent                                      โ”‚
โ”‚                                                                         โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚  BeforeAgent: ๆณจๅ…ฅไปปๅŠกๅทฅๅ…ท                                         โ”‚  โ”‚
โ”‚  โ”‚    - TaskCreate                                                    โ”‚  โ”‚
โ”‚  โ”‚    - TaskGet                                                       โ”‚  โ”‚
โ”‚  โ”‚    - TaskUpdate                                                    โ”‚  โ”‚
โ”‚  โ”‚    - TaskList                                                      โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ”‚                                                                         โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                    โ”‚
                                    โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                             Backend                                     โ”‚
โ”‚                                                                         โ”‚
โ”‚  ๅญ˜ๅ‚จ็ป“ๆž„:                                                               โ”‚
โ”‚    baseDir/                                                             โ”‚
โ”‚    โ”œโ”€โ”€ .highwatermark    # ID ่ฎกๆ•ฐๅ™จ                                    โ”‚
โ”‚    โ”œโ”€โ”€ 1.json            # ไปปๅŠก #1                                      โ”‚
โ”‚    โ”œโ”€โ”€ 2.json            # ไปปๅŠก #2                                      โ”‚
โ”‚    โ””โ”€โ”€ ...                                                              โ”‚
โ”‚                                                                         โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

้…็ฝฎ

type Config struct {
    Backend Backend  // ๅญ˜ๅ‚จๅŽ็ซฏ๏ผŒๅฟ…ๅกซ
    BaseDir string   // ไปปๅŠกๆ–‡ไปถ็›ฎๅฝ•๏ผŒๅฟ…ๅกซ
}
  • ๆณจๆ„่ฟ™ไธช Backend ็š„ๅฎž็Žฐ๏ผŒๅบ”่ฏฅๆ˜ฏ session ็ปดๅบฆ้š”็ฆป็š„๏ผŒไธๅŒ็š„ session ๅฏนๅบ”ไธๅŒ็š„ Backend๏ผˆไปปๅŠกๅˆ—่กจ๏ผ‰

Backend ๆŽฅๅฃ

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
}

ไปปๅŠก็ป“ๆž„

type task struct {
    ID          string         `json:"id"`          // ไปปๅŠก ID
    Subject     string         `json:"subject"`     // ๆ ‡้ข˜
    Description string         `json:"description"` // ๆ่ฟฐ
    Status      string         `json:"status"`      // ็Šถๆ€
    Blocks      []string       `json:"blocks"`      // ้˜ปๅกžๅ“ชไบ›ไปปๅŠก
    BlockedBy   []string       `json:"blockedBy"`   // ่ขซๅ“ชไบ›ไปปๅŠก้˜ปๅกž
    ActiveForm  string         `json:"activeForm"`  // ่ฟ›่กŒๆ—ถๆ–‡ๆกˆ
    Owner       string         `json:"owner"`       // ่ดŸ่ดฃ agent
    Metadata    map[string]any `json:"metadata"`    // ่‡ชๅฎšไน‰ๆ•ฐๆฎ
}

็Šถๆ€

็Šถๆ€่ฏดๆ˜Ž
pending
ๅพ…ๅค„็†๏ผˆ้ป˜่ฎค๏ผ‰
in_progress
่ฟ›่กŒไธญ
completed
ๅทฒๅฎŒๆˆ
deleted
ๅˆ ้™ค๏ผˆไผšๅˆ ๆމๆ–‡ไปถ๏ผ‰

็Šถๆ€ๆต่ฝฌ๏ผšpending โ†’ in_progress โ†’ completed๏ผŒไปปไฝ•็Šถๆ€้ƒฝๅฏไปฅ็›ดๆŽฅ deletedใ€‚


ๅทฅๅ…ท

TaskCreate

ๅˆ›ๅปบไปปๅŠกใ€‚

ๅ‚ๆ•ฐ็ฑปๅž‹ๅฟ…ๅกซ่ฏดๆ˜Ž
subject
stringๆ˜ฏๆ ‡้ข˜
description
stringๆ˜ฏๆ่ฟฐ
activeForm
stringๅฆ่ฟ›่กŒๆ—ถๆ–‡ๆกˆ๏ผŒๆฏ”ๅฆ‚"ๆญฃๅœจ่ฟ่กŒๆต‹่ฏ•"
metadata
objectๅฆ่‡ชๅฎšไน‰ๆ•ฐๆฎ

ไป€ไนˆๆ—ถๅ€™็”จ๏ผš

  • ไปปๅŠกๆฏ”่พƒๅคๆ‚๏ผŒๆœ‰ 3 ๆญฅไปฅไธŠ
  • ็”จๆˆท็ป™ไบ†ไธ€ๅ †ไบ‹ๆƒ…่ฆๅš
  • ้œ€่ฆ่ฎฉ็”จๆˆท็œ‹ๅˆฐ่ฟ›ๅบฆ

ไป€ไนˆๆ—ถๅ€™ไธ็”จ๏ผš

  • ๅฐฑไธ€ไธช็ฎ€ๅ•ไปปๅŠก
  • ไธ‰ไธคไธ‹ๅฐฑ่ƒฝๆžๅฎš็š„ไบ‹

TaskGet

ๆŸฅ็œ‹ไปปๅŠก่ฏฆๆƒ…ใ€‚

ๅ‚ๆ•ฐ็ฑปๅž‹ๅฟ…ๅกซ่ฏดๆ˜Ž
taskId
stringๆ˜ฏไปปๅŠก ID

่ฟ”ๅ›žไปปๅŠก็š„ๅฎŒๆ•ดไฟกๆฏ๏ผšๆ ‡้ข˜ใ€ๆ่ฟฐใ€็Šถๆ€ใ€ไพ่ต–ๅ…ณ็ณป็ญ‰ใ€‚

TaskUpdate

ๆ›ดๆ–ฐไปปๅŠกใ€‚

ๅ‚ๆ•ฐ็ฑปๅž‹ๅฟ…ๅกซ่ฏดๆ˜Ž
taskId
stringๆ˜ฏไปปๅŠก ID
subject
stringๅฆๆ–ฐๆ ‡้ข˜
description
stringๅฆๆ–ฐๆ่ฟฐ
activeForm
stringๅฆๆ–ฐ็š„่ฟ›่กŒๆ—ถๆ–‡ๆกˆ
status
stringๅฆๆ–ฐ็Šถๆ€
addBlocks
[]stringๅฆๆทปๅŠ ่ขซ้˜ปๅกž็š„ไปปๅŠก
addBlockedBy
[]stringๅฆๆทปๅŠ ้˜ปๅกž่‡ชๅทฑ็š„ไปปๅŠก
owner
stringๅฆ่ดŸ่ดฃ agent
metadata
objectๅฆ่‡ชๅฎšไน‰ๆ•ฐๆฎ๏ผˆ่ฎพ null ๅˆ ้™ค๏ผ‰

ๆณจๆ„๏ผš

  • status: "deleted" ไผš็›ดๆŽฅๅˆ ๆމไปปๅŠกๆ–‡ไปถ
  • ๅŠ ไพ่ต–ๆ—ถไผšๆฃ€ๆŸฅๅพช็Žฏไพ่ต–
  • ๆ‰€ๆœ‰ไปปๅŠก้ƒฝๅฎŒๆˆๅŽไผš่‡ชๅŠจๆธ…็†

TaskList

ๅˆ—ๅ‡บๆ‰€ๆœ‰ไปปๅŠก๏ผŒไธ้œ€่ฆๅ‚ๆ•ฐใ€‚

่ฟ”ๅ›žๆฏไธชไปปๅŠก็š„ๆ‘˜่ฆ๏ผšIDใ€็Šถๆ€ใ€ๆ ‡้ข˜ใ€่ดŸ่ดฃ agentใ€ไพ่ต–ๅ…ณ็ณปใ€‚


ไฝฟ็”จ็คบไพ‹

ctx := context.Background()

// plantask middleware ๆญฃๅธธๆƒ…ๅ†ตไธ‹ๅบ”่ฏฅ session ็ปดๅบฆ็š„
// ไธๅŒ็š„ session ๅฏนๅบ”ไธๅŒ็š„ไปปๅŠกๅˆ—่กจ
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},
})

ๅ…ธๅž‹ๆต็จ‹

1. ๆ”ถๅˆฐๅคๆ‚ไปปๅŠก
       โ”‚
       โ–ผ
2. TaskCreate ๅˆ›ๅปบไปปๅŠก
   - #1: ๅˆ†ๆž้œ€ๆฑ‚
   - #2: ๅ†™ไปฃ็ 
       โ”‚
       โ–ผ
3. TaskUpdate ่ฎพ็ฝฎไพ่ต–
   - #2 ไพ่ต– #1
   - #3 ไพ่ต– #2
       โ”‚
       โ–ผ
4. TaskList ็œ‹็œ‹ๆœ‰ๅ•ฅไปปๅŠก
       โ”‚
       โ–ผ
5. TaskUpdate ๅผ€ๅง‹ๅนฒๆดป
   - #1 ๆ”นๆˆ in_progress
       โ”‚
       โ–ผ
6. ๅนฒๅฎŒไบ† TaskUpdate
   - #1 ๆ”นๆˆ completed
       โ”‚
       โ–ผ
7. ๅพช็Žฏ 4-6 ็›ดๅˆฐๅ…จ้ƒจๅฎŒๆˆ
       โ”‚
       โ–ผ
8. ่‡ชๅŠจๆธ…็†

ไพ่ต–็ฎก็†

  • blocks: ๆˆ‘ๅฎŒๆˆไบ†๏ผŒ่ฟ™ไบ›ไปปๅŠกๆ‰่ƒฝๅผ€ๅง‹
  • blockedBy: ่ฟ™ไบ›ไปปๅŠกๅฎŒๆˆไบ†๏ผŒๆˆ‘ๆ‰่ƒฝๅผ€ๅง‹
Task #1 (blocks: ["2"])  โ”€โ”€โ”€โ”€โ–บ  Task #2 (blockedBy: ["1"])

#1 ๅฎŒๆˆๅŽ #2 ๆ‰่ƒฝๅผ€ๅง‹

ๅพช็Žฏไพ่ต–ไผšๆŠฅ้”™๏ผš

#1 blocks #2
#2 blocks #1  โ† ไธ่กŒ๏ผŒๅพช็Žฏไบ†

่‡ชๅŠจๆธ…็†

ๆ‰€ๆœ‰ไปปๅŠก้ƒฝ completed ๅŽ๏ผŒไผš่‡ชๅŠจๆŠŠไปปๅŠกๆ–‡ไปถ้ƒฝๅˆ ๆމใ€‚


ๆณจๆ„ไบ‹้กน

  • ไปปๅŠกๆ–‡ไปถไปฅ JSON ๆ ผๅผๅญ˜ๅ‚จๅœจ BaseDir ็›ฎๅฝ•ไธ‹๏ผŒๆ–‡ไปถๅไธบ {id}.json
  • .highwatermark ๆ–‡ไปถ็”จไบŽ่ฎฐๅฝ•ๅทฒๅˆ†้…็š„ๆœ€ๅคงไปปๅŠก ID๏ผŒ็กฎไฟ ID ไธ้‡ๅค
  • ๆ‰€ๆœ‰ๅทฅๅ…ทๆ“ไฝœ้ƒฝๆœ‰ไบ’ๆ–ฅ้”ไฟๆŠค๏ผŒๅนถๅ‘ๅฎ‰ๅ…จ
  • ๅทฅๅ…ท็š„ description ้‡Œๅทฒ็ปๅŒ…ๅซไบ†่ฏฆ็ป†็š„ไฝฟ็”จๆŒ‡ๅ—๏ผŒAgent ไผšๆ นๆฎ่ฟ™ไบ›ๆŒ‡ๅ—ๆฅไฝฟ็”จๅทฅๅ…ท

ๅคš่ฏญ่จ€ๆ”ฏๆŒ

ๅทฅๅ…ท็š„ description ๆ”ฏๆŒไธญ่‹ฑๆ–‡ๅˆ‡ๆข๏ผŒ้€š่ฟ‡ adk.SetLanguage() ่ฎพ็ฝฎ๏ผš

// ไฝฟ็”จไธญๆ–‡ description
adk.SetLanguage(adk.LanguageChinese)

// ไฝฟ็”จ่‹ฑๆ–‡ description๏ผˆ้ป˜่ฎค๏ผ‰
adk.SetLanguage(adk.LanguageEnglish)

่ฟ™ไธช่ฎพ็ฝฎๆ˜ฏๅ…จๅฑ€็š„๏ผŒไผšๅฝฑๅ“ๆ‰€ๆœ‰ ADK ๅ†…็ฝฎ็š„ prompt ๅ’Œๅทฅๅ…ท descriptionใ€‚


ๆœ€ๅŽไฟฎๆ”น March 10, 2026: docs(eino): sync docs from feishu 2026-03-09 (#1518) (c2aa4096)