|
|
@@ -2260,6 +2260,22 @@ function Task(props: ToolProps) {
|
|
|
(props.metadata.background === true && value !== undefined && value.type !== "idle")
|
|
|
)
|
|
|
})
|
|
|
+ const [progressNow, setProgressNow] = createSignal(Date.now())
|
|
|
+ const progressStartedAt = createMemo(() => (isRunning() ? progress()?.activeSince : undefined))
|
|
|
+ createEffect(() => {
|
|
|
+ if (!progressStartedAt()) return
|
|
|
+ setProgressNow(Date.now())
|
|
|
+ const timer = setInterval(() => setProgressNow(Date.now()), 1000)
|
|
|
+ onCleanup(() => clearInterval(timer))
|
|
|
+ })
|
|
|
+ const progressFooter = createMemo(() => {
|
|
|
+ const value = progress()
|
|
|
+ if (!value) return undefined
|
|
|
+ const elapsed = value.activeSince
|
|
|
+ ? `当前步骤已运行 ${formatResearch67Elapsed(value.activeSince, progressNow())}`
|
|
|
+ : undefined
|
|
|
+ return [value.footer, elapsed].filter(Boolean).join(" · ") || undefined
|
|
|
+ })
|
|
|
const retry = createMemo(() => {
|
|
|
const value = status()
|
|
|
if (value?.type !== "retry") return
|
|
|
@@ -2352,8 +2368,8 @@ function Task(props: ToolProps) {
|
|
|
</text>
|
|
|
)}
|
|
|
</For>
|
|
|
- <Show when={progress()!.footer}>
|
|
|
- <text fg={theme.textMuted}> {progress()!.footer}</text>
|
|
|
+ <Show when={progressFooter()}>
|
|
|
+ <text fg={theme.textMuted}> {progressFooter()}</text>
|
|
|
</Show>
|
|
|
</box>
|
|
|
</InlineTool>
|
|
|
@@ -2364,6 +2380,7 @@ function Task(props: ToolProps) {
|
|
|
type Research67ProgressStatus = "completed" | "running" | "pending" | "failed"
|
|
|
type Research67Progress = {
|
|
|
rows: Array<{ id: string; label: string; status: Research67ProgressStatus; detail?: string; depth: 0 | 1 }>
|
|
|
+ activeSince?: number
|
|
|
footer?: string
|
|
|
}
|
|
|
|
|
|
@@ -2387,7 +2404,18 @@ export function parseResearch67Progress(value: unknown): Research67Progress | un
|
|
|
return [result]
|
|
|
})
|
|
|
if (rows.length === 0) return undefined
|
|
|
- return { rows, footer: stringValue(progress.footer) }
|
|
|
+ const activeSince = numberValue(progress.activeSince)
|
|
|
+ return {
|
|
|
+ rows,
|
|
|
+ activeSince: activeSince && activeSince > 0 ? activeSince : undefined,
|
|
|
+ footer: stringValue(progress.footer),
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+export function formatResearch67Elapsed(activeSince: number, now: number) {
|
|
|
+ const seconds = Math.max(0, Math.floor((now - activeSince) / 1000))
|
|
|
+ if (seconds < 60) return `${seconds} 秒`
|
|
|
+ return `${Math.floor(seconds / 60)} 分 ${seconds % 60} 秒`
|
|
|
}
|
|
|
|
|
|
function isResearch67ProgressStatus(value: string | undefined): value is Research67ProgressStatus {
|