devsquad 3.6.0__py3-none-any.whl

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 (95) hide show
  1. devsquad-3.6.0.dist-info/METADATA +944 -0
  2. devsquad-3.6.0.dist-info/RECORD +95 -0
  3. devsquad-3.6.0.dist-info/WHEEL +5 -0
  4. devsquad-3.6.0.dist-info/entry_points.txt +2 -0
  5. devsquad-3.6.0.dist-info/licenses/LICENSE +21 -0
  6. devsquad-3.6.0.dist-info/top_level.txt +2 -0
  7. scripts/__init__.py +0 -0
  8. scripts/ai_semantic_matcher.py +512 -0
  9. scripts/alert_manager.py +505 -0
  10. scripts/api/__init__.py +43 -0
  11. scripts/api/models.py +386 -0
  12. scripts/api/routes/__init__.py +20 -0
  13. scripts/api/routes/dispatch.py +348 -0
  14. scripts/api/routes/lifecycle.py +330 -0
  15. scripts/api/routes/metrics_gates.py +347 -0
  16. scripts/api_server.py +318 -0
  17. scripts/auth.py +451 -0
  18. scripts/cli/__init__.py +1 -0
  19. scripts/cli/cli_visual.py +642 -0
  20. scripts/cli.py +1094 -0
  21. scripts/collaboration/__init__.py +212 -0
  22. scripts/collaboration/_version.py +1 -0
  23. scripts/collaboration/agent_briefing.py +656 -0
  24. scripts/collaboration/ai_semantic_matcher.py +260 -0
  25. scripts/collaboration/anchor_checker.py +281 -0
  26. scripts/collaboration/anti_rationalization.py +470 -0
  27. scripts/collaboration/async_integration_example.py +255 -0
  28. scripts/collaboration/batch_scheduler.py +149 -0
  29. scripts/collaboration/checkpoint_manager.py +561 -0
  30. scripts/collaboration/ci_feedback_adapter.py +351 -0
  31. scripts/collaboration/code_map_generator.py +247 -0
  32. scripts/collaboration/concern_pack_loader.py +352 -0
  33. scripts/collaboration/confidence_score.py +496 -0
  34. scripts/collaboration/config_loader.py +188 -0
  35. scripts/collaboration/consensus.py +244 -0
  36. scripts/collaboration/context_compressor.py +533 -0
  37. scripts/collaboration/coordinator.py +668 -0
  38. scripts/collaboration/dispatcher.py +1636 -0
  39. scripts/collaboration/dual_layer_context.py +128 -0
  40. scripts/collaboration/enhanced_worker.py +539 -0
  41. scripts/collaboration/feature_usage_tracker.py +206 -0
  42. scripts/collaboration/five_axis_consensus.py +334 -0
  43. scripts/collaboration/input_validator.py +401 -0
  44. scripts/collaboration/integration_example.py +287 -0
  45. scripts/collaboration/intent_workflow_mapper.py +350 -0
  46. scripts/collaboration/language_parsers.py +269 -0
  47. scripts/collaboration/lifecycle_protocol.py +1446 -0
  48. scripts/collaboration/llm_backend.py +453 -0
  49. scripts/collaboration/llm_cache.py +448 -0
  50. scripts/collaboration/llm_cache_async.py +347 -0
  51. scripts/collaboration/llm_retry.py +387 -0
  52. scripts/collaboration/llm_retry_async.py +389 -0
  53. scripts/collaboration/mce_adapter.py +597 -0
  54. scripts/collaboration/memory_bridge.py +1607 -0
  55. scripts/collaboration/models.py +537 -0
  56. scripts/collaboration/null_providers.py +297 -0
  57. scripts/collaboration/operation_classifier.py +289 -0
  58. scripts/collaboration/output_slicer.py +225 -0
  59. scripts/collaboration/performance_monitor.py +462 -0
  60. scripts/collaboration/permission_guard.py +865 -0
  61. scripts/collaboration/prompt_assembler.py +756 -0
  62. scripts/collaboration/prompt_variant_generator.py +483 -0
  63. scripts/collaboration/protocols.py +267 -0
  64. scripts/collaboration/report_formatter.py +352 -0
  65. scripts/collaboration/retrospective.py +279 -0
  66. scripts/collaboration/role_matcher.py +92 -0
  67. scripts/collaboration/role_template_market.py +352 -0
  68. scripts/collaboration/rule_collector.py +678 -0
  69. scripts/collaboration/scratchpad.py +346 -0
  70. scripts/collaboration/skill_registry.py +151 -0
  71. scripts/collaboration/skillifier.py +878 -0
  72. scripts/collaboration/standardized_role_template.py +317 -0
  73. scripts/collaboration/task_completion_checker.py +237 -0
  74. scripts/collaboration/test_quality_guard.py +695 -0
  75. scripts/collaboration/unified_gate_engine.py +598 -0
  76. scripts/collaboration/usage_tracker.py +309 -0
  77. scripts/collaboration/user_friendly_error.py +176 -0
  78. scripts/collaboration/verification_gate.py +312 -0
  79. scripts/collaboration/warmup_manager.py +635 -0
  80. scripts/collaboration/worker.py +513 -0
  81. scripts/collaboration/workflow_engine.py +684 -0
  82. scripts/dashboard.py +1088 -0
  83. scripts/generate_benchmark_report.py +786 -0
  84. scripts/history_manager.py +604 -0
  85. scripts/mcp_server.py +289 -0
  86. skills/__init__.py +32 -0
  87. skills/dispatch/handler.py +52 -0
  88. skills/intent/handler.py +59 -0
  89. skills/registry.py +67 -0
  90. skills/retrospective/__init__.py +0 -0
  91. skills/retrospective/handler.py +125 -0
  92. skills/review/handler.py +356 -0
  93. skills/security/handler.py +454 -0
  94. skills/test/__init__.py +0 -0
  95. skills/test/handler.py +78 -0
@@ -0,0 +1,244 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ Consensus - 共识机制
5
+
6
+ 设计决策(门禁2解决):
7
+ - 权重投票:架构师 1.5x,产品经理 1.2x,其他 1.0x
8
+ - 否决权:任何角色可投否决票(weight < 0),一票否决触发升级
9
+ - 升级机制:
10
+ - 简单多数(>51%) → 通过
11
+ - 分裂/有否决 → 升级到人工决策或 Coordinator 裁决
12
+ - 超时 → 按权重倾向决定 + 标记为 ESCALATED
13
+ """
14
+
15
+ from datetime import datetime
16
+ from typing import Dict, List, Optional
17
+
18
+ from .models import (
19
+ Vote,
20
+ DecisionProposal,
21
+ ConsensusRecord,
22
+ DecisionOutcome,
23
+ ROLE_WEIGHTS,
24
+ CONSENSUS_THRESHOLDS,
25
+ )
26
+
27
+
28
+ class ConsensusEngine:
29
+ """
30
+ 共识决策引擎 - 多 Agent 协作中的冲突解决核心
31
+
32
+ 实现加权投票共识机制,支持:
33
+ - 权重投票: 架构师 1.5x, 产品经理 1.2x, 其他 1.0x
34
+ - 否决权: weight < 0 的投票触发升级 (ESCALATED)
35
+ - 多级通过门槛: 全票(1.0) > 绝对多数(0.75) > 简单多数(0.51)
36
+ - 分裂检测: 赞成率在 40%~60% 时标记为 SPLIT
37
+
38
+ 决策结果类型:
39
+ APPROVED: 通过
40
+ REJECTED: 未达门槛
41
+ SPLIT: 意见分裂,需进一步讨论
42
+ ESCALATED: 存在否决票,升级人工
43
+ TIMEOUT: 无投票记录
44
+
45
+ 使用示例:
46
+ engine = ConsensusEngine()
47
+ proposal = engine.create_proposal(
48
+ topic="技术方案选择",
49
+ proposer_id="coord-001",
50
+ content="建议采用微服务架构",
51
+ options=["方案A-微服务", "方案B-单体", "合并", "升级人工"],
52
+ )
53
+ # 各 Worker 投票...
54
+ record = engine.reach_consensus(proposal.proposal_id)
55
+ print(f"决策结果: {record.outcome.value}")
56
+ """
57
+
58
+ def __init__(self):
59
+ """初始化共识引擎(空提案和空记录集合)"""
60
+ self._records: Dict[str, ConsensusRecord] = {}
61
+ self._proposals: Dict[str, DecisionProposal] = {}
62
+
63
+ def create_proposal(self, topic: str, proposer_id: str,
64
+ content: str, options: Optional[List[str]] = None,
65
+ deadline: Optional[datetime] = None) -> DecisionProposal:
66
+ """
67
+ 创建新的决策提案
68
+
69
+ Args:
70
+ topic: 提案主题/标题
71
+ proposer_id: 提案发起者 ID(通常是 Coordinator)
72
+ content: 提案详细内容
73
+ options: 投票选项列表(默认 ["approve", "reject"])
74
+ deadline: 截止时间(预留参数)
75
+
76
+ Returns:
77
+ DecisionProposal: 新创建的提案对象(含自动生成的 proposal_id)
78
+
79
+ Raises:
80
+ 无(始终成功创建)
81
+ """
82
+ proposal = DecisionProposal(
83
+ topic=topic,
84
+ proposer_id=proposer_id,
85
+ proposal_content=content,
86
+ options=options or ["approve", "reject"],
87
+ deadline=deadline,
88
+ )
89
+ self._proposals[proposal.proposal_id] = proposal
90
+ return proposal
91
+
92
+ def cast_vote(self, proposal_id: str, vote: Vote) -> DecisionProposal:
93
+ """
94
+ 为提案投出一票
95
+
96
+ Args:
97
+ proposal_id: 目标提案 ID
98
+ vote: Vote 对象,包含 voter_id、decision (bool)、reason、weight
99
+
100
+ Returns:
101
+ DecisionProposal: 投票后的更新后提案
102
+
103
+ Raises:
104
+ ValueError: 提案不存在或已关闭
105
+ """
106
+ proposal = self._proposals.get(proposal_id)
107
+ if not proposal:
108
+ raise ValueError(f"Proposal {proposal_id} not found")
109
+ if proposal.status != "open":
110
+ raise ValueError(f"Proposal {proposal_id} is {proposal.status}")
111
+ proposal.votes.append(vote)
112
+ return proposal
113
+
114
+ def reach_consensus(self, proposal_id: str) -> ConsensusRecord:
115
+ """
116
+ 对提案进行共识裁决
117
+
118
+ 汇总所有已投票,计算加权赞成/反对比例,
119
+ 根据阈值判定最终结果。裁决后提案自动关闭。
120
+
121
+ 判定逻辑:
122
+ 1. 存在否决票(weight < 0) → ESCALATED
123
+ 2. 无投票 → TIMEOUT
124
+ 3. 权重比 >= 全票门槛(1.0) → APPROVED
125
+ 4. 权重比 >= 绝对多数(0.75) → APPROVED
126
+ 5. 权重比 >= 简单多数(0.51) → APPROVED
127
+ 6. 计数比在 40%~60% → SPLIT
128
+ 7. 其他 → REJECTED
129
+
130
+ Args:
131
+ proposal_id: 要裁决的提案 ID
132
+
133
+ Returns:
134
+ ConsensusRecord: 共识记录,包含 outcome、票数统计、参与者等
135
+
136
+ Raises:
137
+ ValueError: 提案不存在
138
+ """
139
+ proposal = self._proposals.get(proposal_id)
140
+ if not proposal:
141
+ raise ValueError(f"Proposal {proposal_id} not found")
142
+
143
+ votes_for = [v for v in proposal.votes if v.decision]
144
+ votes_against = [v for v in proposal.votes if not v.decision]
145
+ votes_abstain_count = len(proposal.votes) - len(votes_for) - len(votes_against)
146
+
147
+ total_weight_for = sum(v.weight for v in votes_for if v.weight > 0)
148
+ total_weight_against = sum(abs(v.weight) for v in votes_against if v.weight < 0)
149
+ total_weight_normal_against = sum(v.weight for v in votes_against if v.weight > 0)
150
+
151
+ has_veto = any(v.weight < 0 for v in proposal.votes)
152
+
153
+ participants = [v.voter_id for v in proposal.votes]
154
+
155
+ outcome, final_decision, escalation_reason = self._determine_outcome(
156
+ proposal=proposal,
157
+ votes_for=votes_for,
158
+ votes_against=votes_against,
159
+ total_weight_for=total_weight_for,
160
+ total_weight_against=total_weight_against,
161
+ total_weight_normal_against=total_weight_normal_against,
162
+ has_veto=has_veto,
163
+ votes_abstain=votes_abstain_count,
164
+ )
165
+
166
+ record = ConsensusRecord(
167
+ record_id=f"consensus-{proposal_id[:8]}",
168
+ topic=proposal.topic,
169
+ outcome=outcome,
170
+ final_decision=final_decision,
171
+ votes_for=len(votes_for),
172
+ votes_against=len(votes_against),
173
+ votes_abstain=votes_abstain_count,
174
+ total_weight_for=total_weight_for,
175
+ total_weight_against=total_weight_against,
176
+ participants=participants,
177
+ escalation_reason=escalation_reason,
178
+ )
179
+
180
+ self._records[record.record_id] = record
181
+ proposal.status = "closed"
182
+ return record
183
+
184
+ def _determine_outcome(self, proposal, votes_for, votes_against,
185
+ total_weight_for, total_weight_against,
186
+ total_weight_normal_against, has_veto, votes_abstain) -> tuple:
187
+ total_votes = len(votes_for) + len(votes_against) + votes_abstain
188
+
189
+ if has_veto:
190
+ return (
191
+ DecisionOutcome.ESCALATED,
192
+ f"存在否决票,升级到人工决策。赞成权重:{total_weight_for:.1f}, 反对权重:{total_weight_against:.1f}",
193
+ "Veto vote detected",
194
+ )
195
+
196
+ if total_votes == 0:
197
+ return (
198
+ DecisionOutcome.TIMEOUT,
199
+ "无投票记录",
200
+ "No votes cast",
201
+ )
202
+
203
+ weight_ratio = total_weight_for / (total_weight_for + total_weight_normal_against + 0.001)
204
+ count_ratio = len(votes_for) / (len(votes_for) + len(votes_against) + 0.001)
205
+
206
+ if weight_ratio >= CONSENSUS_THRESHOLDS["unanimous"]:
207
+ return DecisionOutcome.APPROVED, proposal.proposal_content, None
208
+ elif weight_ratio >= CONSENSUS_THRESHOLDS["super_majority"]:
209
+ return DecisionOutcome.APPROVED, proposal.proposal_content, None
210
+ elif weight_ratio >= CONSENSUS_THRESHOLDS["simple_majority"]:
211
+ return DecisionOutcome.APPROVED, proposal.proposal_content, None
212
+ elif count_ratio >= 0.4 and count_ratio <= 0.6:
213
+ return (
214
+ DecisionOutcome.SPLIT,
215
+ f"意见分裂 ({count_ratio:.0%}赞成),需要进一步讨论",
216
+ "Split decision",
217
+ )
218
+ else:
219
+ return (
220
+ DecisionOutcome.REJECTED,
221
+ f"未通过共识门槛 (赞成率:{count_ratio:.0%})",
222
+ "Below threshold",
223
+ )
224
+
225
+ def get_record(self, record_id: str) -> Optional[ConsensusRecord]:
226
+ """
227
+ 按 ID 查询单条共识记录
228
+
229
+ Args:
230
+ record_id: 共识记录 ID
231
+
232
+ Returns:
233
+ Optional[ConsensusRecord]: 记录对象,不存在则返回 None
234
+ """
235
+ return self._records.get(record_id)
236
+
237
+ def get_all_records(self) -> List[ConsensusRecord]:
238
+ """
239
+ 获取所有共识记录
240
+
241
+ Returns:
242
+ List[ConsensusRecord]: 所有已完成的共识裁决记录
243
+ """
244
+ return list(self._records.values())