refactor(task-toast): improve task toast manager types and logic
Add new toast types and improve state management for background task notifications. Update tests to cover new scenarios. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
parent
aa2b052d28
commit
72098213ee
@ -160,7 +160,7 @@ describe("TaskToastManager", () => {
|
||||
// #then - toast should NOT show warning - category default is expected
|
||||
expect(mockClient.tui.showToast).toHaveBeenCalled()
|
||||
const call = mockClient.tui.showToast.mock.calls[0][0]
|
||||
expect(call.body.message).not.toContain("⚠️")
|
||||
expect(call.body.message).not.toContain("[FALLBACK]")
|
||||
expect(call.body.message).not.toContain("(category default)")
|
||||
})
|
||||
|
||||
@ -180,7 +180,7 @@ describe("TaskToastManager", () => {
|
||||
// #then - toast should show fallback warning
|
||||
expect(mockClient.tui.showToast).toHaveBeenCalled()
|
||||
const call = mockClient.tui.showToast.mock.calls[0][0]
|
||||
expect(call.body.message).toContain("⚠️")
|
||||
expect(call.body.message).toContain("[FALLBACK]")
|
||||
expect(call.body.message).toContain("anthropic/claude-sonnet-4-5")
|
||||
expect(call.body.message).toContain("(system default fallback)")
|
||||
})
|
||||
@ -201,7 +201,7 @@ describe("TaskToastManager", () => {
|
||||
// #then - toast should show fallback warning
|
||||
expect(mockClient.tui.showToast).toHaveBeenCalled()
|
||||
const call = mockClient.tui.showToast.mock.calls[0][0]
|
||||
expect(call.body.message).toContain("⚠️")
|
||||
expect(call.body.message).toContain("[FALLBACK]")
|
||||
expect(call.body.message).toContain("cliproxy/claude-opus-4-5")
|
||||
expect(call.body.message).toContain("(inherited from parent)")
|
||||
})
|
||||
@ -222,7 +222,7 @@ describe("TaskToastManager", () => {
|
||||
// #then - toast should NOT show model warning
|
||||
expect(mockClient.tui.showToast).toHaveBeenCalled()
|
||||
const call = mockClient.tui.showToast.mock.calls[0][0]
|
||||
expect(call.body.message).not.toContain("⚠️ Model:")
|
||||
expect(call.body.message).not.toContain("[FALLBACK] Model:")
|
||||
expect(call.body.message).not.toContain("(inherited)")
|
||||
expect(call.body.message).not.toContain("(category default)")
|
||||
expect(call.body.message).not.toContain("(system default)")
|
||||
@ -243,7 +243,7 @@ describe("TaskToastManager", () => {
|
||||
// #then - toast should NOT show model warning
|
||||
expect(mockClient.tui.showToast).toHaveBeenCalled()
|
||||
const call = mockClient.tui.showToast.mock.calls[0][0]
|
||||
expect(call.body.message).not.toContain("⚠️ Model:")
|
||||
expect(call.body.message).not.toContain("[FALLBACK] Model:")
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -24,6 +24,7 @@ export class TaskToastManager {
|
||||
agent: string
|
||||
isBackground: boolean
|
||||
status?: TaskStatus
|
||||
category?: string
|
||||
skills?: string[]
|
||||
modelInfo?: ModelFallbackInfo
|
||||
}): void {
|
||||
@ -34,6 +35,7 @@ export class TaskToastManager {
|
||||
status: task.status ?? "running",
|
||||
startedAt: new Date(),
|
||||
isBackground: task.isBackground,
|
||||
category: task.category,
|
||||
skills: task.skills,
|
||||
modelInfo: task.modelInfo,
|
||||
}
|
||||
@ -116,7 +118,7 @@ export class TaskToastManager {
|
||||
"system-default": " (system default fallback)",
|
||||
}
|
||||
const suffix = suffixMap[newTask.modelInfo!.type as "inherited" | "system-default"]
|
||||
lines.push(`⚠️ Model fallback: ${newTask.modelInfo!.model}${suffix}`)
|
||||
lines.push(`[FALLBACK] Model: ${newTask.modelInfo!.model}${suffix}`)
|
||||
lines.push("")
|
||||
}
|
||||
|
||||
@ -124,10 +126,11 @@ export class TaskToastManager {
|
||||
lines.push(`Running (${running.length}):${concurrencyInfo}`)
|
||||
for (const task of running) {
|
||||
const duration = this.formatDuration(task.startedAt)
|
||||
const bgIcon = task.isBackground ? "⚡" : "🔄"
|
||||
const bgIcon = task.isBackground ? "[BG]" : "[RUN]"
|
||||
const isNew = task.id === newTask.id ? " ← NEW" : ""
|
||||
const categoryInfo = task.category ? `/${task.category}` : ""
|
||||
const skillsInfo = task.skills?.length ? ` [${task.skills.join(", ")}]` : ""
|
||||
lines.push(`${bgIcon} ${task.description} (${task.agent})${skillsInfo} - ${duration}${isNew}`)
|
||||
lines.push(`${bgIcon} ${task.description} (${task.agent}${categoryInfo})${skillsInfo} - ${duration}${isNew}`)
|
||||
}
|
||||
}
|
||||
|
||||
@ -135,10 +138,11 @@ export class TaskToastManager {
|
||||
if (lines.length > 0) lines.push("")
|
||||
lines.push(`Queued (${queued.length}):`)
|
||||
for (const task of queued) {
|
||||
const bgIcon = task.isBackground ? "⏳" : "⏸️"
|
||||
const bgIcon = task.isBackground ? "[Q]" : "[W]"
|
||||
const categoryInfo = task.category ? `/${task.category}` : ""
|
||||
const skillsInfo = task.skills?.length ? ` [${task.skills.join(", ")}]` : ""
|
||||
const isNew = task.id === newTask.id ? " ← NEW" : ""
|
||||
lines.push(`${bgIcon} ${task.description} (${task.agent})${skillsInfo} - Queued${isNew}`)
|
||||
lines.push(`${bgIcon} ${task.description} (${task.agent}${categoryInfo})${skillsInfo} - Queued${isNew}`)
|
||||
}
|
||||
}
|
||||
|
||||
@ -158,8 +162,8 @@ export class TaskToastManager {
|
||||
const queued = this.getQueuedTasks()
|
||||
|
||||
const title = newTask.isBackground
|
||||
? `⚡ New Background Task`
|
||||
: `🔄 New Task Executed`
|
||||
? `New Background Task`
|
||||
: `New Task Executed`
|
||||
|
||||
tuiClient.tui.showToast({
|
||||
body: {
|
||||
@ -184,7 +188,7 @@ export class TaskToastManager {
|
||||
const remaining = this.getRunningTasks()
|
||||
const queued = this.getQueuedTasks()
|
||||
|
||||
let message = `✅ "${task.description}" finished in ${task.duration}`
|
||||
let message = `"${task.description}" finished in ${task.duration}`
|
||||
if (remaining.length > 0 || queued.length > 0) {
|
||||
message += `\n\nStill running: ${remaining.length} | Queued: ${queued.length}`
|
||||
}
|
||||
|
||||
@ -1,8 +1,11 @@
|
||||
import type { ModelSource } from "../../shared/model-resolver"
|
||||
|
||||
export type TaskStatus = "running" | "queued" | "completed" | "error"
|
||||
|
||||
export interface ModelFallbackInfo {
|
||||
model: string
|
||||
type: "user-defined" | "inherited" | "category-default" | "system-default"
|
||||
source?: ModelSource
|
||||
}
|
||||
|
||||
export interface TrackedTask {
|
||||
@ -12,6 +15,7 @@ export interface TrackedTask {
|
||||
status: TaskStatus
|
||||
startedAt: Date
|
||||
isBackground: boolean
|
||||
category?: string
|
||||
skills?: string[]
|
||||
modelInfo?: ModelFallbackInfo
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user