openclaw-agent-dashboard 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/.github/workflows/release.yml +56 -0
  2. package/README.md +302 -0
  3. package/docs/CHANGELOG_AGENT_MODIFICATIONS.md +132 -0
  4. package/docs/RELEASE-LATEST.md +189 -0
  5. package/docs/RELEASE-MODEL-CONFIG.md +95 -0
  6. package/docs/release-guide.md +259 -0
  7. package/docs/release-operations-manual.md +167 -0
  8. package/docs/specs/tr3-install-system.md +580 -0
  9. package/docs/windows-collaboration-model-paths-troubleshooting.md +0 -0
  10. package/frontend/index.html +12 -0
  11. package/frontend/package-lock.json +1240 -0
  12. package/frontend/package.json +19 -0
  13. package/frontend/src/App.vue +331 -0
  14. package/frontend/src/components/AgentCard.vue +796 -0
  15. package/frontend/src/components/AgentConfigPanel.vue +539 -0
  16. package/frontend/src/components/AgentDetailPanel.vue +738 -0
  17. package/frontend/src/components/ErrorAnalysisView.vue +546 -0
  18. package/frontend/src/components/ErrorCenterPanel.vue +844 -0
  19. package/frontend/src/components/PerformanceMonitor.vue +515 -0
  20. package/frontend/src/components/SettingsPanel.vue +236 -0
  21. package/frontend/src/components/TokenAnalysisPanel.vue +683 -0
  22. package/frontend/src/components/chain/ChainEdge.vue +85 -0
  23. package/frontend/src/components/chain/ChainNode.vue +166 -0
  24. package/frontend/src/components/chain/TaskChainView.vue +425 -0
  25. package/frontend/src/components/chain/index.ts +3 -0
  26. package/frontend/src/components/chain/types.ts +70 -0
  27. package/frontend/src/components/collaboration/CollaborationFlowSection.vue +1032 -0
  28. package/frontend/src/components/collaboration/CollaborationFlowWrapper.vue +113 -0
  29. package/frontend/src/components/performance/PerformancePanel.vue +119 -0
  30. package/frontend/src/components/performance/PerformanceSection.vue +1137 -0
  31. package/frontend/src/components/tasks/TaskStatusSection.vue +973 -0
  32. package/frontend/src/components/timeline/TimelineConnector.vue +31 -0
  33. package/frontend/src/components/timeline/TimelineRound.vue +135 -0
  34. package/frontend/src/components/timeline/TimelineStep.vue +691 -0
  35. package/frontend/src/components/timeline/TimelineToolLink.vue +109 -0
  36. package/frontend/src/components/timeline/TimelineView.vue +540 -0
  37. package/frontend/src/components/timeline/index.ts +5 -0
  38. package/frontend/src/components/timeline/types.ts +120 -0
  39. package/frontend/src/composables/index.ts +7 -0
  40. package/frontend/src/composables/useDebounce.ts +48 -0
  41. package/frontend/src/composables/useRealtime.ts +52 -0
  42. package/frontend/src/composables/useState.ts +52 -0
  43. package/frontend/src/composables/useThrottle.ts +46 -0
  44. package/frontend/src/composables/useVirtualScroll.ts +106 -0
  45. package/frontend/src/main.ts +4 -0
  46. package/frontend/src/managers/EventDispatcher.ts +127 -0
  47. package/frontend/src/managers/RealtimeDataManager.ts +293 -0
  48. package/frontend/src/managers/StateManager.ts +128 -0
  49. package/frontend/src/managers/index.ts +5 -0
  50. package/frontend/src/types/collaboration.ts +135 -0
  51. package/frontend/src/types/index.ts +20 -0
  52. package/frontend/src/types/performance.ts +105 -0
  53. package/frontend/src/types/task.ts +38 -0
  54. package/frontend/vite.config.ts +18 -0
  55. package/package.json +22 -0
  56. package/plugin/README.md +99 -0
  57. package/plugin/config.json.example +1 -0
  58. package/plugin/index.js +250 -0
  59. package/plugin/openclaw.plugin.json +17 -0
  60. package/plugin/package.json +21 -0
  61. package/scripts/build-plugin.js +67 -0
  62. package/scripts/bundle.sh +62 -0
  63. package/scripts/install-plugin.sh +162 -0
  64. package/scripts/install-python-deps.js +346 -0
  65. package/scripts/install-python-deps.sh +226 -0
  66. package/scripts/install.js +512 -0
  67. package/scripts/install.sh +367 -0
  68. package/scripts/lib/common.js +490 -0
  69. package/scripts/lib/common.sh +137 -0
  70. package/scripts/release-pack.sh +110 -0
  71. package/scripts/start.js +50 -0
  72. package/scripts/test_available_models.py +284 -0
  73. package/scripts/test_websocket_ping.py +44 -0
  74. package/src/backend/agents.py +73 -0
  75. package/src/backend/api/__init__.py +1 -0
  76. package/src/backend/api/agent_config_api.py +90 -0
  77. package/src/backend/api/agents.py +73 -0
  78. package/src/backend/api/agents_config.py +75 -0
  79. package/src/backend/api/chains.py +126 -0
  80. package/src/backend/api/collaboration.py +902 -0
  81. package/src/backend/api/debug_paths.py +39 -0
  82. package/src/backend/api/error_analysis.py +146 -0
  83. package/src/backend/api/errors.py +281 -0
  84. package/src/backend/api/performance.py +784 -0
  85. package/src/backend/api/subagents.py +770 -0
  86. package/src/backend/api/timeline.py +144 -0
  87. package/src/backend/api/websocket.py +251 -0
  88. package/src/backend/collaboration.py +405 -0
  89. package/src/backend/data/__init__.py +1 -0
  90. package/src/backend/data/agent_config_manager.py +270 -0
  91. package/src/backend/data/chain_reader.py +299 -0
  92. package/src/backend/data/config_reader.py +153 -0
  93. package/src/backend/data/error_analyzer.py +430 -0
  94. package/src/backend/data/session_reader.py +445 -0
  95. package/src/backend/data/subagent_reader.py +244 -0
  96. package/src/backend/data/task_history.py +118 -0
  97. package/src/backend/data/timeline_reader.py +981 -0
  98. package/src/backend/errors.py +63 -0
  99. package/src/backend/main.py +89 -0
  100. package/src/backend/mechanism_reader.py +131 -0
  101. package/src/backend/mechanisms.py +32 -0
  102. package/src/backend/performance.py +474 -0
  103. package/src/backend/requirements.txt +5 -0
  104. package/src/backend/session_reader.py +238 -0
  105. package/src/backend/status/__init__.py +1 -0
  106. package/src/backend/status/error_detector.py +122 -0
  107. package/src/backend/status/status_calculator.py +301 -0
  108. package/src/backend/status_calculator.py +121 -0
  109. package/src/backend/subagent_reader.py +229 -0
  110. package/src/backend/watchers/__init__.py +4 -0
  111. package/src/backend/watchers/file_watcher.py +159 -0
@@ -0,0 +1,73 @@
1
+ """
2
+ Agent API 路由
3
+ """
4
+ from fastapi import APIRouter
5
+ from pydantic import BaseModel
6
+ from typing import List, Optional
7
+ import sys
8
+ from pathlib import Path
9
+ sys.path.append(str(Path(__file__).parent.parent))
10
+
11
+ from status.status_calculator import (
12
+ get_agents_with_status,
13
+ format_last_active
14
+ )
15
+
16
+ router = APIRouter()
17
+
18
+
19
+ class AgentStatus(BaseModel):
20
+ id: str
21
+ name: str
22
+ role: str
23
+ status: str # idle/working/down
24
+ currentTask: Optional[str] = None
25
+ lastActiveAt: Optional[int] = None
26
+ lastActiveFormatted: Optional[str] = None
27
+ error: Optional[dict] = None
28
+
29
+
30
+ @router.get("/agents", response_model=List[AgentStatus])
31
+ async def get_agents():
32
+ """获取所有 Agent 列表及状态"""
33
+ agents = get_agents_with_status()
34
+
35
+ # 格式化最后活跃时间
36
+ for agent in agents:
37
+ if agent.get('lastActiveAt'):
38
+ agent['lastActiveFormatted'] = format_last_active(agent['lastActiveAt'])
39
+
40
+ return agents
41
+
42
+
43
+ @router.get("/agents/{agent_id}", response_model=AgentStatus)
44
+ async def get_agent(agent_id: str):
45
+ """获取单个 Agent 详情"""
46
+ agents = get_agents_with_status()
47
+
48
+ for agent in agents:
49
+ if agent['id'] == agent_id:
50
+ if agent.get('lastActiveAt'):
51
+ agent['lastActiveFormatted'] = format_last_active(agent['lastActiveAt'])
52
+ return agent
53
+
54
+ from fastapi import HTTPException
55
+ raise HTTPException(status_code=404, detail=f"Agent {agent_id} not found")
56
+
57
+
58
+ @router.get("/agents/{agent_id}/output")
59
+ async def get_agent_output(agent_id: str, limit: int = 50):
60
+ """
61
+ 获取 Agent 最近会话详情:每轮 user/assistant/toolResult 及 usage
62
+ 用于调试视图展示
63
+ """
64
+ from data.session_reader import get_session_turns
65
+ from data.config_reader import get_agents_list
66
+
67
+ agents = get_agents_list()
68
+ if not any(a.get('id') == agent_id for a in agents):
69
+ from fastapi import HTTPException
70
+ raise HTTPException(status_code=404, detail=f"Agent {agent_id} not found")
71
+
72
+ turns = get_session_turns(agent_id, limit=limit)
73
+ return {"agentId": agent_id, "turns": turns}
@@ -0,0 +1,75 @@
1
+ """
2
+ Agent 配置 API - 直接从 openclaw.json 读取
3
+ 仅依赖 config_reader,无其他模块依赖,作为协作流程的兜底数据源
4
+ """
5
+ from fastapi import APIRouter
6
+ from typing import List, Dict, Any
7
+
8
+ router = APIRouter()
9
+
10
+
11
+ @router.get("/agents-config")
12
+ async def get_agents_config():
13
+ """
14
+ 直接从 ~/.openclaw/openclaw.json 读取 agents.list
15
+ 返回格式与协作流程兼容,用于 API 失败时的兜底展示
16
+ """
17
+ try:
18
+ from data.config_reader import (
19
+ get_agents_list,
20
+ get_main_agent_id,
21
+ get_agent_models,
22
+ )
23
+ agents_list = get_agents_list()
24
+ main_id = get_main_agent_id()
25
+ agent_models: Dict[str, Dict[str, Any]] = {}
26
+ for a in agents_list:
27
+ aid = a.get('id', '')
28
+ if aid:
29
+ agent_models[aid] = get_agent_models(aid)
30
+
31
+ nodes = []
32
+ edges = []
33
+ for agent in agents_list:
34
+ aid = agent.get('id', '')
35
+ if not aid:
36
+ continue
37
+ name = agent.get('name', aid)
38
+ nodes.append({
39
+ 'id': aid,
40
+ 'type': 'agent',
41
+ 'name': name,
42
+ 'status': 'idle',
43
+ 'metadata': agent_models.get(aid),
44
+ })
45
+ if aid != main_id:
46
+ edges.append({
47
+ 'id': f'edge-{main_id}-{aid}',
48
+ 'source': main_id,
49
+ 'target': aid,
50
+ 'type': 'delegates',
51
+ 'label': '委托',
52
+ })
53
+
54
+ return {
55
+ 'nodes': nodes,
56
+ 'edges': edges,
57
+ 'activePath': [],
58
+ 'mainAgentId': main_id,
59
+ 'agentModels': agent_models,
60
+ 'models': [],
61
+ 'recentCalls': [],
62
+ 'lastUpdate': int(__import__('time').time() * 1000),
63
+ }
64
+ except Exception as e:
65
+ return {
66
+ 'nodes': [],
67
+ 'edges': [],
68
+ 'activePath': [],
69
+ 'mainAgentId': 'main',
70
+ 'agentModels': {},
71
+ 'models': [],
72
+ 'recentCalls': [],
73
+ 'lastUpdate': 0,
74
+ '_error': str(e),
75
+ }
@@ -0,0 +1,126 @@
1
+ """
2
+ 任务链路 API 路由
3
+ """
4
+ from fastapi import APIRouter, Query, HTTPException
5
+ from pydantic import BaseModel
6
+ from typing import Optional, List, Dict, Any
7
+ import sys
8
+ from pathlib import Path
9
+ sys.path.append(str(Path(__file__).parent.parent))
10
+
11
+ from data.chain_reader import (
12
+ build_task_chains,
13
+ get_task_chain,
14
+ get_active_chain,
15
+ get_chains_summary
16
+ )
17
+
18
+ router = APIRouter()
19
+
20
+
21
+ class ChainNode(BaseModel):
22
+ agentId: str
23
+ agentName: str
24
+ role: str
25
+ status: str
26
+ startedAt: Optional[int] = None
27
+ endedAt: Optional[int] = None
28
+ duration: Optional[int] = None
29
+ task: Optional[str] = None
30
+ runId: Optional[str] = None
31
+ input: Optional[str] = None
32
+ output: Optional[str] = None
33
+ artifacts: List[str] = []
34
+ toolCallCount: int = 0
35
+ tokenUsage: Dict[str, int] = {"input": 0, "output": 0}
36
+
37
+
38
+ class ChainEdge(BaseModel):
39
+ from_: str
40
+ to: str
41
+
42
+
43
+ class TaskChain(BaseModel):
44
+ chainId: str
45
+ projectId: Optional[str] = None
46
+ rootTask: str
47
+ startedAt: Optional[int] = None
48
+ status: str
49
+ nodes: List[ChainNode]
50
+ edges: List[Dict[str, str]]
51
+ progress: float
52
+ completedNodes: int
53
+ totalNodes: int
54
+ totalDuration: int
55
+
56
+
57
+ class TaskChainListResponse(BaseModel):
58
+ chains: List[TaskChain]
59
+ activeChain: Optional[TaskChain] = None
60
+
61
+
62
+ class ChainSummaryResponse(BaseModel):
63
+ total: int
64
+ running: int
65
+ completed: int
66
+ error: int
67
+ chains: List[Dict[str, Any]]
68
+
69
+
70
+ @router.get("/chains", response_model=TaskChainListResponse)
71
+ async def list_chains(
72
+ limit: int = Query(20, ge=1, le=100, description="返回链路数量")
73
+ ):
74
+ """
75
+ 获取所有任务链路列表
76
+
77
+ 返回 Agent 间的任务派发链路,包括:
78
+ - 链路中的所有节点(Agent)
79
+ - 节点间的派发关系
80
+ - 各节点的状态和进度
81
+ """
82
+ chains = build_task_chains(limit=limit)
83
+ active = get_active_chain()
84
+
85
+ return {
86
+ "chains": chains,
87
+ "activeChain": active
88
+ }
89
+
90
+
91
+ @router.get("/chains/summary", response_model=ChainSummaryResponse)
92
+ async def get_summary():
93
+ """
94
+ 获取任务链路摘要统计
95
+
96
+ 快速查看所有链路的状态分布
97
+ """
98
+ return get_chains_summary()
99
+
100
+
101
+ @router.get("/chains/active")
102
+ async def get_active():
103
+ """
104
+ 获取当前活跃的任务链路
105
+
106
+ 返回正在执行的任务链
107
+ """
108
+ chain = get_active_chain()
109
+ if not chain:
110
+ return {"activeChain": None, "message": "当前没有正在执行的任务链"}
111
+
112
+ return {"activeChain": chain}
113
+
114
+
115
+ @router.get("/chains/{chain_id}")
116
+ async def get_chain(chain_id: str):
117
+ """
118
+ 获取单个任务链的详情
119
+
120
+ 返回完整的链路信息,包括所有节点和边
121
+ """
122
+ chain = get_task_chain(chain_id)
123
+ if not chain:
124
+ raise HTTPException(status_code=404, detail=f"Chain {chain_id} not found")
125
+
126
+ return chain