(frame RenderFrame)
| 756 | } |
| 757 | |
| 758 | func (b *FullscreenRendererBackend) buildTaskBlocks(frame RenderFrame) []map[string]any { |
| 759 | hasSnapshots := len(frame.Tasks) > 0 |
| 760 | hasActivity := len(frame.TaskActivityEntries) > 0 |
| 761 | if !hasSnapshots && !hasActivity { |
| 762 | if !frame.InputEnabled { |
| 763 | return []map[string]any{{"kind": "animation", "key": "animation", "text": b.animatedTaskLine(frame)}} |
| 764 | } |
| 765 | return []map[string]any{{"kind": "empty", "key": "empty", "text": "Tasks: none"}} |
| 766 | } |
| 767 | var blocks []map[string]any |
| 768 | if !frame.InputEnabled { |
| 769 | blocks = append(blocks, map[string]any{"kind": "animation", "key": "animation", "text": b.animatedTaskLine(frame)}) |
| 770 | } |
| 771 | if hasSnapshots { |
| 772 | blocks = append(blocks, map[string]any{"kind": "snapshot_header", "key": "snapshot_header", "text": "Task Snapshots:"}) |
| 773 | for _, taskID := range sortedStringMapKeys(frame.Tasks) { |
| 774 | record := frame.Tasks[taskID] |
| 775 | label := firstNonEmpty(stringFromAny(record["worker_label"]), taskID) |
| 776 | status := firstNonEmpty(stringFromAny(record["status"]), "unknown") |
| 777 | blocks = append(blocks, map[string]any{ |
| 778 | "kind": "snapshot_line", |
| 779 | "key": taskID, |
| 780 | "text": fmt.Sprintf("- %s [%s] tools=%d usage=%d/%d duration=%dms", label, status, intFromAny(record["tool_use_count"]), intFromAny(record["input_tokens"]), intFromAny(record["output_tokens"]), intFromAny(record["duration_ms"])), |
| 781 | }) |
| 782 | } |
| 783 | } |
| 784 | if hasActivity { |
| 785 | if hasSnapshots { |
| 786 | blocks = append(blocks, map[string]any{"kind": "separator", "key": "snapshot_activity", "text": ""}) |
| 787 | } |
| 788 | blocks = append(blocks, map[string]any{"kind": "activity_header", "key": "activity_header", "text": "Recent Task Activity:"}) |
| 789 | start := maxInt(0, len(frame.TaskActivityEntries)-5) |
| 790 | for idx, entry := range frame.TaskActivityEntries[start:] { |
| 791 | label := firstNonEmpty(stringFromAny(entry["worker_label"]), stringFromAny(entry["task_id"])) |
| 792 | status := firstNonEmpty(stringFromAny(entry["status"]), "unknown") |
| 793 | taskID := stringFromAny(entry["task_id"]) |
| 794 | blocks = append(blocks, map[string]any{ |
| 795 | "kind": "activity_line", |
| 796 | "key": fmt.Sprintf("%s:%d", taskID, idx), |
| 797 | "text": fmt.Sprintf("- %s [%s] %s", label, status, stringFromAny(entry["summary"])), |
| 798 | }) |
| 799 | if b.TaskActivityExpanded && stringFromAny(entry["result_text"]) != "" { |
| 800 | blocks = append(blocks, map[string]any{ |
| 801 | "kind": "activity_detail", |
| 802 | "key": fmt.Sprintf("%s:%d:detail", taskID, idx), |
| 803 | "text": " result: " + truncateString(stringFromAny(entry["result_text"]), 200), |
| 804 | }) |
| 805 | } |
| 806 | } |
| 807 | } |
| 808 | return blocks |
| 809 | } |
| 810 | |
| 811 | func (b *FullscreenRendererBackend) animatedTaskLine(frame RenderFrame) string { |
| 812 | return fmt.Sprintf("%s 正在执行任务%s", fullscreenSpinner(frame.AnimationFrame), animatedDots(frame.AnimationFrame)) |
no test coverage detected