@suzuke/agend 0.0.1 → 1.0.0
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.
- package/README.md +557 -1
- package/README.zh-TW.md +504 -0
- package/dist/access-path.d.ts +7 -0
- package/dist/access-path.js +12 -0
- package/dist/access-path.js.map +1 -0
- package/dist/approval/approval-server.d.ts +30 -0
- package/dist/approval/approval-server.js +156 -0
- package/dist/approval/approval-server.js.map +1 -0
- package/dist/approval/tmux-prompt-detector.d.ts +34 -0
- package/dist/approval/tmux-prompt-detector.js +264 -0
- package/dist/approval/tmux-prompt-detector.js.map +1 -0
- package/dist/backend/approval-strategy.d.ts +14 -0
- package/dist/backend/approval-strategy.js +2 -0
- package/dist/backend/approval-strategy.js.map +1 -0
- package/dist/backend/claude-code.d.ts +13 -0
- package/dist/backend/claude-code.js +114 -0
- package/dist/backend/claude-code.js.map +1 -0
- package/dist/backend/codex.d.ts +10 -0
- package/dist/backend/codex.js +58 -0
- package/dist/backend/codex.js.map +1 -0
- package/dist/backend/factory.d.ts +2 -0
- package/dist/backend/factory.js +19 -0
- package/dist/backend/factory.js.map +1 -0
- package/dist/backend/gemini-cli.d.ts +10 -0
- package/dist/backend/gemini-cli.js +68 -0
- package/dist/backend/gemini-cli.js.map +1 -0
- package/dist/backend/hook-based-approval.d.ts +20 -0
- package/dist/backend/hook-based-approval.js +41 -0
- package/dist/backend/hook-based-approval.js.map +1 -0
- package/dist/backend/index.d.ts +6 -0
- package/dist/backend/index.js +6 -0
- package/dist/backend/index.js.map +1 -0
- package/dist/backend/opencode.d.ts +10 -0
- package/dist/backend/opencode.js +63 -0
- package/dist/backend/opencode.js.map +1 -0
- package/dist/backend/types.d.ts +26 -0
- package/dist/backend/types.js +2 -0
- package/dist/backend/types.js.map +1 -0
- package/dist/channel/access-manager.d.ts +18 -0
- package/dist/channel/access-manager.js +149 -0
- package/dist/channel/access-manager.js.map +1 -0
- package/dist/channel/adapters/discord.d.ts +45 -0
- package/dist/channel/adapters/discord.js +366 -0
- package/dist/channel/adapters/discord.js.map +1 -0
- package/dist/channel/adapters/telegram.d.ts +58 -0
- package/dist/channel/adapters/telegram.js +569 -0
- package/dist/channel/adapters/telegram.js.map +1 -0
- package/dist/channel/attachment-handler.d.ts +15 -0
- package/dist/channel/attachment-handler.js +55 -0
- package/dist/channel/attachment-handler.js.map +1 -0
- package/dist/channel/factory.d.ts +12 -0
- package/dist/channel/factory.js +38 -0
- package/dist/channel/factory.js.map +1 -0
- package/dist/channel/ipc-bridge.d.ts +26 -0
- package/dist/channel/ipc-bridge.js +170 -0
- package/dist/channel/ipc-bridge.js.map +1 -0
- package/dist/channel/mcp-server.d.ts +10 -0
- package/dist/channel/mcp-server.js +196 -0
- package/dist/channel/mcp-server.js.map +1 -0
- package/dist/channel/mcp-tools.d.ts +909 -0
- package/dist/channel/mcp-tools.js +346 -0
- package/dist/channel/mcp-tools.js.map +1 -0
- package/dist/channel/message-bus.d.ts +17 -0
- package/dist/channel/message-bus.js +86 -0
- package/dist/channel/message-bus.js.map +1 -0
- package/dist/channel/message-queue.d.ts +39 -0
- package/dist/channel/message-queue.js +248 -0
- package/dist/channel/message-queue.js.map +1 -0
- package/dist/channel/tool-router.d.ts +6 -0
- package/dist/channel/tool-router.js +69 -0
- package/dist/channel/tool-router.js.map +1 -0
- package/dist/channel/tool-tracker.d.ts +13 -0
- package/dist/channel/tool-tracker.js +58 -0
- package/dist/channel/tool-tracker.js.map +1 -0
- package/dist/channel/types.d.ts +116 -0
- package/dist/channel/types.js +2 -0
- package/dist/channel/types.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +782 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +8 -0
- package/dist/config.js +85 -0
- package/dist/config.js.map +1 -0
- package/dist/container-manager.d.ts +24 -0
- package/dist/container-manager.js +148 -0
- package/dist/container-manager.js.map +1 -0
- package/dist/context-guardian.d.ts +29 -0
- package/dist/context-guardian.js +123 -0
- package/dist/context-guardian.js.map +1 -0
- package/dist/cost-guard.d.ts +21 -0
- package/dist/cost-guard.js +113 -0
- package/dist/cost-guard.js.map +1 -0
- package/dist/daemon-entry.d.ts +1 -0
- package/dist/daemon-entry.js +29 -0
- package/dist/daemon-entry.js.map +1 -0
- package/dist/daemon.d.ts +88 -0
- package/dist/daemon.js +820 -0
- package/dist/daemon.js.map +1 -0
- package/dist/daily-summary.d.ts +13 -0
- package/dist/daily-summary.js +55 -0
- package/dist/daily-summary.js.map +1 -0
- package/dist/db.d.ts +10 -0
- package/dist/db.js +43 -0
- package/dist/db.js.map +1 -0
- package/dist/event-log.d.ts +22 -0
- package/dist/event-log.js +66 -0
- package/dist/event-log.js.map +1 -0
- package/dist/export-import.d.ts +2 -0
- package/dist/export-import.js +110 -0
- package/dist/export-import.js.map +1 -0
- package/dist/fleet-context.d.ts +36 -0
- package/dist/fleet-context.js +4 -0
- package/dist/fleet-context.js.map +1 -0
- package/dist/fleet-manager.d.ts +115 -0
- package/dist/fleet-manager.js +1742 -0
- package/dist/fleet-manager.js.map +1 -0
- package/dist/fleet-system-prompt.d.ts +11 -0
- package/dist/fleet-system-prompt.js +60 -0
- package/dist/fleet-system-prompt.js.map +1 -0
- package/dist/hang-detector.d.ts +16 -0
- package/dist/hang-detector.js +53 -0
- package/dist/hang-detector.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/install-recorder.d.ts +30 -0
- package/dist/install-recorder.js +159 -0
- package/dist/install-recorder.js.map +1 -0
- package/dist/logger.d.ts +3 -0
- package/dist/logger.js +63 -0
- package/dist/logger.js.map +1 -0
- package/dist/meeting/orchestrator.d.ts +30 -0
- package/dist/meeting/orchestrator.js +355 -0
- package/dist/meeting/orchestrator.js.map +1 -0
- package/dist/meeting/prompt-builder.d.ts +12 -0
- package/dist/meeting/prompt-builder.js +96 -0
- package/dist/meeting/prompt-builder.js.map +1 -0
- package/dist/meeting/role-assigner.d.ts +2 -0
- package/dist/meeting/role-assigner.js +25 -0
- package/dist/meeting/role-assigner.js.map +1 -0
- package/dist/meeting/types.d.ts +21 -0
- package/dist/meeting/types.js +2 -0
- package/dist/meeting/types.js.map +1 -0
- package/dist/meeting-manager.d.ts +10 -0
- package/dist/meeting-manager.js +38 -0
- package/dist/meeting-manager.js.map +1 -0
- package/dist/memory-layer.d.ts +13 -0
- package/dist/memory-layer.js +44 -0
- package/dist/memory-layer.js.map +1 -0
- package/dist/plugin/agend/.claude-plugin/plugin.json +5 -0
- package/dist/plugin/agend/.mcp.json +9 -0
- package/dist/plugin/ccd-channel/.claude-plugin/plugin.json +5 -0
- package/dist/plugin/ccd-channel/.mcp.json +9 -0
- package/dist/process-manager.d.ts +31 -0
- package/dist/process-manager.js +264 -0
- package/dist/process-manager.js.map +1 -0
- package/dist/scheduler/db.d.ts +16 -0
- package/dist/scheduler/db.js +132 -0
- package/dist/scheduler/db.js.map +1 -0
- package/dist/scheduler/db.test.d.ts +1 -0
- package/dist/scheduler/db.test.js +92 -0
- package/dist/scheduler/db.test.js.map +1 -0
- package/dist/scheduler/index.d.ts +4 -0
- package/dist/scheduler/index.js +4 -0
- package/dist/scheduler/index.js.map +1 -0
- package/dist/scheduler/scheduler.d.ts +25 -0
- package/dist/scheduler/scheduler.js +119 -0
- package/dist/scheduler/scheduler.js.map +1 -0
- package/dist/scheduler/scheduler.test.d.ts +1 -0
- package/dist/scheduler/scheduler.test.js +119 -0
- package/dist/scheduler/scheduler.test.js.map +1 -0
- package/dist/scheduler/types.d.ts +47 -0
- package/dist/scheduler/types.js +7 -0
- package/dist/scheduler/types.js.map +1 -0
- package/dist/service-installer.d.ts +14 -0
- package/dist/service-installer.js +91 -0
- package/dist/service-installer.js.map +1 -0
- package/dist/setup-wizard.d.ts +14 -0
- package/dist/setup-wizard.js +517 -0
- package/dist/setup-wizard.js.map +1 -0
- package/dist/stt.d.ts +10 -0
- package/dist/stt.js +33 -0
- package/dist/stt.js.map +1 -0
- package/dist/tmux-manager.d.ts +22 -0
- package/dist/tmux-manager.js +131 -0
- package/dist/tmux-manager.js.map +1 -0
- package/dist/topic-commands.d.ts +22 -0
- package/dist/topic-commands.js +176 -0
- package/dist/topic-commands.js.map +1 -0
- package/dist/transcript-monitor.d.ts +21 -0
- package/dist/transcript-monitor.js +149 -0
- package/dist/transcript-monitor.js.map +1 -0
- package/dist/types.d.ts +153 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/webhook-emitter.d.ts +15 -0
- package/dist/webhook-emitter.js +41 -0
- package/dist/webhook-emitter.js.map +1 -0
- package/package.json +60 -4
- package/templates/launchd.plist.ejs +29 -0
- package/templates/systemd.service.ejs +15 -0
- package/index.js +0 -1
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { MeetingConfig, ParticipantConfig, FleetManagerMeetingAPI, MeetingChannelOutput, MeetingState } from "./types.js";
|
|
2
|
+
import type { InboundMessage } from "../channel/types.js";
|
|
3
|
+
export declare class MeetingOrchestrator {
|
|
4
|
+
private config;
|
|
5
|
+
private fm;
|
|
6
|
+
private output;
|
|
7
|
+
private participants;
|
|
8
|
+
private roundHistory;
|
|
9
|
+
private currentRound;
|
|
10
|
+
private state;
|
|
11
|
+
private userContext;
|
|
12
|
+
private abortController;
|
|
13
|
+
private resolveUserInput;
|
|
14
|
+
private directAddress;
|
|
15
|
+
/** Cancellation signal — the single source of truth for "should we stop?" */
|
|
16
|
+
private get cancelled();
|
|
17
|
+
constructor(config: MeetingConfig, fm: FleetManagerMeetingAPI, output: MeetingChannelOutput);
|
|
18
|
+
start(participantConfigs: ParticipantConfig[]): Promise<void>;
|
|
19
|
+
private runCollabFlow;
|
|
20
|
+
private runDiscussionFlow;
|
|
21
|
+
private runDebateLoop;
|
|
22
|
+
private getSpeakingOrder;
|
|
23
|
+
private generateSummary;
|
|
24
|
+
handleUserMessage(msg: InboundMessage): void;
|
|
25
|
+
addParticipant(config: ParticipantConfig): Promise<void>;
|
|
26
|
+
removeParticipant(label: string): Promise<void>;
|
|
27
|
+
end(): Promise<void>;
|
|
28
|
+
private cleanup;
|
|
29
|
+
getState(): MeetingState;
|
|
30
|
+
}
|
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
import { buildSystemPrompt, buildRoundPrompt, buildSummaryPrompt, buildCollabSystemPrompt, buildCollabSummaryPrompt, buildDiscussionSystemPrompt, buildIndependentAnalysisPrompt, buildCrossDiscussionPrompt, buildConsensusPrompt, roleLabel } from "./prompt-builder.js";
|
|
2
|
+
const ROLE_EMOJI = { pro: "🟢", con: "🔴", arbiter: "⚖️" };
|
|
3
|
+
const REPLY_TIMEOUT_MS = 120_000;
|
|
4
|
+
const REPLY_BUFFER_CAP = 32 * 1024;
|
|
5
|
+
export class MeetingOrchestrator {
|
|
6
|
+
config;
|
|
7
|
+
fm;
|
|
8
|
+
output;
|
|
9
|
+
participants = [];
|
|
10
|
+
roundHistory = [];
|
|
11
|
+
currentRound = 0;
|
|
12
|
+
state = "booting";
|
|
13
|
+
userContext;
|
|
14
|
+
abortController = new AbortController();
|
|
15
|
+
resolveUserInput = null;
|
|
16
|
+
directAddress = null;
|
|
17
|
+
/** Cancellation signal — the single source of truth for "should we stop?" */
|
|
18
|
+
get cancelled() { return this.abortController.signal.aborted; }
|
|
19
|
+
constructor(config, fm, output) {
|
|
20
|
+
this.config = config;
|
|
21
|
+
this.fm = fm;
|
|
22
|
+
this.output = output;
|
|
23
|
+
}
|
|
24
|
+
async start(participantConfigs) {
|
|
25
|
+
this.state = "booting";
|
|
26
|
+
// Spawn instances sequentially to avoid port/IPC race conditions
|
|
27
|
+
for (let i = 0; i < participantConfigs.length; i++) {
|
|
28
|
+
const p = participantConfigs[i];
|
|
29
|
+
try {
|
|
30
|
+
const systemPrompt = this.config.mode === "collab"
|
|
31
|
+
? buildCollabSystemPrompt(p.label, this.config.topic)
|
|
32
|
+
: this.config.mode === "discussion"
|
|
33
|
+
? buildDiscussionSystemPrompt(p.label, this.config.angles?.[i] ?? "general", this.config.topic)
|
|
34
|
+
: buildSystemPrompt(p.role, this.config.topic);
|
|
35
|
+
const instanceName = await this.fm.spawnEphemeralInstance({
|
|
36
|
+
systemPrompt,
|
|
37
|
+
workingDirectory: this.config.mode === "collab" ? this.config.repo ?? "/tmp" : "/tmp",
|
|
38
|
+
lightweight: this.config.mode === "debate" || this.config.mode === "discussion",
|
|
39
|
+
skipPermissions: this.config.mode === "debate" || this.config.mode === "discussion",
|
|
40
|
+
}, this.abortController.signal);
|
|
41
|
+
this.participants.push({ ...p, instanceName });
|
|
42
|
+
}
|
|
43
|
+
catch (err) {
|
|
44
|
+
await this.output.postMessage(`⚠️ Instance 啟動失敗: ${err}`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
if (this.participants.length === 0) {
|
|
48
|
+
await this.output.postMessage("❌ 所有 instance 啟動失敗,會議結束");
|
|
49
|
+
await this.end();
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
this.state = "running";
|
|
53
|
+
const participantList = this.config.mode === "discussion"
|
|
54
|
+
? this.participants.map((p, i) => `${p.label}(${this.config.angles?.[i] ?? "general"})`).join("、")
|
|
55
|
+
: this.participants.map(p => `${p.label}(${roleLabel(p.role)})`).join("、");
|
|
56
|
+
const modeLabel = this.config.mode === "discussion" ? "討論" : this.config.mode === "collab" ? "協作" : "辯論";
|
|
57
|
+
await this.output.postMessage(`📋 ${modeLabel}:${this.config.topic}\n參與者:${participantList}\n輪次:${this.config.maxRounds} | 指令:/end /more /pause`);
|
|
58
|
+
try {
|
|
59
|
+
if (this.config.mode === "collab") {
|
|
60
|
+
await this.runCollabFlow();
|
|
61
|
+
}
|
|
62
|
+
else if (this.config.mode === "discussion") {
|
|
63
|
+
await this.runDiscussionFlow();
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
await this.runDebateLoop();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
if (err.name === "AbortError")
|
|
71
|
+
return;
|
|
72
|
+
throw err;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
async runCollabFlow() {
|
|
76
|
+
// Phase 1: Discussion — each participant proposes their work plan
|
|
77
|
+
await this.output.postMessage("\n━━ 討論分工 ━━");
|
|
78
|
+
for (const participant of this.participants) {
|
|
79
|
+
if (this.cancelled)
|
|
80
|
+
return;
|
|
81
|
+
while (this.state === "paused") {
|
|
82
|
+
await new Promise(resolve => { this.resolveUserInput = resolve; });
|
|
83
|
+
}
|
|
84
|
+
if (this.cancelled)
|
|
85
|
+
return;
|
|
86
|
+
try {
|
|
87
|
+
const prompt = `任務:${this.config.topic}\n\n團隊成員:${this.participants.map(p => p.label).join("、")}\n你是 ${participant.label}。請提出你的分工建議,說明你打算負責哪個部分。用 reply 工具回覆。`;
|
|
88
|
+
const reply = await this.fm.sendAndWaitReply(participant.instanceName, prompt, REPLY_TIMEOUT_MS);
|
|
89
|
+
const cappedReply = reply.length > REPLY_BUFFER_CAP
|
|
90
|
+
? reply.slice(0, REPLY_BUFFER_CAP) + "\n[...truncated]"
|
|
91
|
+
: reply;
|
|
92
|
+
this.roundHistory.push({
|
|
93
|
+
round: 0, speaker: participant.label, role: participant.role, content: cappedReply,
|
|
94
|
+
});
|
|
95
|
+
await this.output.postMessage(`💬 ${participant.label}:\n${cappedReply}`);
|
|
96
|
+
}
|
|
97
|
+
catch (err) {
|
|
98
|
+
if (err.name === "AbortError")
|
|
99
|
+
throw err;
|
|
100
|
+
await this.output.postMessage(`⚠️ ${participant.label} 回覆逾時`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
// Phase 2: Development — tell each participant to start working
|
|
104
|
+
await this.output.postMessage("\n━━ 開始開發 ━━");
|
|
105
|
+
// Collect all plans for context
|
|
106
|
+
const allPlans = this.roundHistory
|
|
107
|
+
.filter(e => e.round === 0)
|
|
108
|
+
.map(e => `[${e.speaker}] ${e.content}`)
|
|
109
|
+
.join("\n\n");
|
|
110
|
+
// Send development instruction to all participants in parallel
|
|
111
|
+
const devPromises = this.participants.map(async (participant) => {
|
|
112
|
+
if (this.cancelled)
|
|
113
|
+
return;
|
|
114
|
+
try {
|
|
115
|
+
const prompt = `以下是所有人的分工計劃:\n\n${allPlans}\n\n請開始你負責的部分。完成後用 reply 工具回報你做了什麼(包含修改了哪些檔案、實作了什麼功能)。`;
|
|
116
|
+
const reply = await this.fm.sendAndWaitReply(participant.instanceName, prompt, 300_000); // 5 min timeout for dev work
|
|
117
|
+
const cappedReply = reply.length > REPLY_BUFFER_CAP
|
|
118
|
+
? reply.slice(0, REPLY_BUFFER_CAP) + "\n[...truncated]"
|
|
119
|
+
: reply;
|
|
120
|
+
this.roundHistory.push({
|
|
121
|
+
round: 1, speaker: participant.label, role: participant.role, content: cappedReply,
|
|
122
|
+
});
|
|
123
|
+
await this.output.postMessage(`✅ ${participant.label} 完成:\n${cappedReply}`);
|
|
124
|
+
}
|
|
125
|
+
catch (err) {
|
|
126
|
+
if (err.name === "AbortError")
|
|
127
|
+
return;
|
|
128
|
+
await this.output.postMessage(`⚠️ ${participant.label} 開發逾時或失敗`);
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
await Promise.allSettled(devPromises);
|
|
132
|
+
if (this.cancelled)
|
|
133
|
+
return;
|
|
134
|
+
await this.generateSummary();
|
|
135
|
+
await this.cleanup();
|
|
136
|
+
}
|
|
137
|
+
async runDiscussionFlow() {
|
|
138
|
+
const angles = this.config.angles ?? this.participants.map((_, i) => `角度 ${i + 1}`);
|
|
139
|
+
// Phase 1: Independent analysis (parallel)
|
|
140
|
+
await this.output.postMessage("\n━━ 獨立分析 ━━");
|
|
141
|
+
const analysisPromises = this.participants.map(async (participant, i) => {
|
|
142
|
+
if (this.cancelled)
|
|
143
|
+
return;
|
|
144
|
+
try {
|
|
145
|
+
const prompt = buildIndependentAnalysisPrompt(this.config.topic, angles[i]);
|
|
146
|
+
const reply = await this.fm.sendAndWaitReply(participant.instanceName, prompt, REPLY_TIMEOUT_MS);
|
|
147
|
+
const cappedReply = reply.length > REPLY_BUFFER_CAP ? reply.slice(0, REPLY_BUFFER_CAP) + "\n[...truncated]" : reply;
|
|
148
|
+
this.roundHistory.push({ round: 0, speaker: participant.label, role: angles[i], content: cappedReply });
|
|
149
|
+
await this.output.postMessage(`💬 ${participant.label}(${angles[i]}):\n${cappedReply}`);
|
|
150
|
+
}
|
|
151
|
+
catch (err) {
|
|
152
|
+
if (err.name === "AbortError")
|
|
153
|
+
return;
|
|
154
|
+
await this.output.postMessage(`⚠️ ${participant.label} 分析逾時`);
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
await Promise.allSettled(analysisPromises);
|
|
158
|
+
if (this.cancelled)
|
|
159
|
+
return;
|
|
160
|
+
// Phase 2: Cross discussion (sequential rounds)
|
|
161
|
+
const independentAnalyses = this.roundHistory.filter(e => e.round === 0);
|
|
162
|
+
for (let round = 1; round <= this.config.maxRounds; round++) {
|
|
163
|
+
if (this.cancelled)
|
|
164
|
+
return;
|
|
165
|
+
this.currentRound = round;
|
|
166
|
+
await this.output.postMessage(`\n━━ 交叉討論 Round ${round} ━━`);
|
|
167
|
+
for (let i = 0; i < this.participants.length; i++) {
|
|
168
|
+
const participant = this.participants[i];
|
|
169
|
+
if (this.cancelled)
|
|
170
|
+
return;
|
|
171
|
+
while (this.state === "paused") {
|
|
172
|
+
await new Promise(resolve => { this.resolveUserInput = resolve; });
|
|
173
|
+
}
|
|
174
|
+
if (this.cancelled)
|
|
175
|
+
return;
|
|
176
|
+
try {
|
|
177
|
+
const prevRoundEntries = round === 1 ? independentAnalyses : this.roundHistory.filter(e => e.round === round - 1);
|
|
178
|
+
const prompt = buildCrossDiscussionPrompt(this.config.topic, angles[i], prevRoundEntries);
|
|
179
|
+
const reply = await this.fm.sendAndWaitReply(participant.instanceName, prompt, REPLY_TIMEOUT_MS);
|
|
180
|
+
const cappedReply = reply.length > REPLY_BUFFER_CAP ? reply.slice(0, REPLY_BUFFER_CAP) + "\n[...truncated]" : reply;
|
|
181
|
+
this.roundHistory.push({ round, speaker: participant.label, role: angles[i], content: cappedReply });
|
|
182
|
+
await this.output.postMessage(`💬 ${participant.label}(${angles[i]}):\n${cappedReply}`);
|
|
183
|
+
}
|
|
184
|
+
catch (err) {
|
|
185
|
+
if (err.name === "AbortError")
|
|
186
|
+
throw err;
|
|
187
|
+
await this.output.postMessage(`⚠️ ${participant.label} 回覆逾時`);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
// Phase 3: Consensus
|
|
192
|
+
await this.output.postMessage("\n━━ 收斂結論 ━━");
|
|
193
|
+
const lastParticipant = this.participants[this.participants.length - 1];
|
|
194
|
+
if (lastParticipant) {
|
|
195
|
+
try {
|
|
196
|
+
const prompt = buildConsensusPrompt(this.config.topic, this.roundHistory);
|
|
197
|
+
const reply = await this.fm.sendAndWaitReply(lastParticipant.instanceName, prompt, REPLY_TIMEOUT_MS);
|
|
198
|
+
await this.output.postMessage(reply);
|
|
199
|
+
}
|
|
200
|
+
catch {
|
|
201
|
+
await this.output.postMessage("⚠️ 結論產生失敗");
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
await this.cleanup();
|
|
205
|
+
}
|
|
206
|
+
async runDebateLoop() {
|
|
207
|
+
for (let round = 1; round <= this.config.maxRounds; round++) {
|
|
208
|
+
if (this.cancelled)
|
|
209
|
+
return;
|
|
210
|
+
this.currentRound = round;
|
|
211
|
+
await this.output.postMessage(`\n━━ Round ${round} ━━`);
|
|
212
|
+
const prevRound = this.roundHistory.filter(e => e.round === round - 1);
|
|
213
|
+
const speakers = this.getSpeakingOrder();
|
|
214
|
+
for (const participant of speakers) {
|
|
215
|
+
if (this.cancelled)
|
|
216
|
+
return;
|
|
217
|
+
while (this.state === "paused") {
|
|
218
|
+
await new Promise(resolve => { this.resolveUserInput = resolve; });
|
|
219
|
+
}
|
|
220
|
+
if (this.cancelled)
|
|
221
|
+
return;
|
|
222
|
+
let prompt;
|
|
223
|
+
if (this.directAddress && this.directAddress.label === participant.label) {
|
|
224
|
+
prompt = this.directAddress.prompt;
|
|
225
|
+
this.directAddress = null;
|
|
226
|
+
}
|
|
227
|
+
else if (this.directAddress) {
|
|
228
|
+
continue;
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
prompt = buildRoundPrompt(this.config.topic, round, prevRound, this.userContext);
|
|
232
|
+
this.userContext = undefined;
|
|
233
|
+
}
|
|
234
|
+
try {
|
|
235
|
+
const reply = await this.fm.sendAndWaitReply(participant.instanceName, prompt, REPLY_TIMEOUT_MS);
|
|
236
|
+
const cappedReply = reply.length > REPLY_BUFFER_CAP
|
|
237
|
+
? reply.slice(0, REPLY_BUFFER_CAP) + "\n[...truncated]"
|
|
238
|
+
: reply;
|
|
239
|
+
this.roundHistory.push({
|
|
240
|
+
round, speaker: participant.label, role: participant.role, content: cappedReply,
|
|
241
|
+
});
|
|
242
|
+
const emoji = ROLE_EMOJI[participant.role] ?? "💬";
|
|
243
|
+
await this.output.postMessage(`${emoji} ${participant.label}(${roleLabel(participant.role)}):\n${cappedReply}`);
|
|
244
|
+
}
|
|
245
|
+
catch (err) {
|
|
246
|
+
if (err.name === "AbortError")
|
|
247
|
+
throw err;
|
|
248
|
+
await this.output.postMessage(`⚠️ ${participant.label} 回覆逾時,跳過本輪`);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
await this.generateSummary();
|
|
253
|
+
await this.cleanup();
|
|
254
|
+
}
|
|
255
|
+
getSpeakingOrder() {
|
|
256
|
+
const order = [];
|
|
257
|
+
order.push(...this.participants.filter(p => p.role === "pro"));
|
|
258
|
+
order.push(...this.participants.filter(p => p.role === "con"));
|
|
259
|
+
order.push(...this.participants.filter(p => p.role === "arbiter"));
|
|
260
|
+
order.push(...this.participants.filter(p => !["pro", "con", "arbiter"].includes(p.role)));
|
|
261
|
+
return order;
|
|
262
|
+
}
|
|
263
|
+
async generateSummary() {
|
|
264
|
+
if (this.cancelled)
|
|
265
|
+
return;
|
|
266
|
+
this.state = "summarizing";
|
|
267
|
+
await this.output.postMessage("\n━━ 會議摘要 ━━");
|
|
268
|
+
const summaryGenerator = this.participants.find(p => p.role === "arbiter") ??
|
|
269
|
+
this.participants[this.participants.length - 1];
|
|
270
|
+
if (!summaryGenerator)
|
|
271
|
+
return;
|
|
272
|
+
try {
|
|
273
|
+
const summaryPrompt = this.config.mode === "collab"
|
|
274
|
+
? buildCollabSummaryPrompt(this.config.topic, this.roundHistory)
|
|
275
|
+
: buildSummaryPrompt(this.config.topic, this.roundHistory);
|
|
276
|
+
const summary = await this.fm.sendAndWaitReply(summaryGenerator.instanceName, summaryPrompt, REPLY_TIMEOUT_MS);
|
|
277
|
+
await this.output.postMessage(summary);
|
|
278
|
+
}
|
|
279
|
+
catch {
|
|
280
|
+
await this.output.postMessage("⚠️ 摘要產生失敗");
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
handleUserMessage(msg) {
|
|
284
|
+
const text = msg.text.trim();
|
|
285
|
+
if (text === "/end") {
|
|
286
|
+
this.state = "ended";
|
|
287
|
+
this.abortController.abort();
|
|
288
|
+
this.generateSummary().then(() => this.cleanup()).catch(() => this.cleanup());
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
if (text === "/pause") {
|
|
292
|
+
this.state = "paused";
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
if (text === "/resume") {
|
|
296
|
+
this.state = "running";
|
|
297
|
+
this.resolveUserInput?.();
|
|
298
|
+
this.resolveUserInput = null;
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
const moreMatch = text.match(/^\/more(?:\s+(\d+))?$/);
|
|
302
|
+
if (moreMatch) {
|
|
303
|
+
this.config.maxRounds += parseInt(moreMatch[1] ?? "1", 10);
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
const kickMatch = text.match(/^\/kick\s+(\S+)$/);
|
|
307
|
+
if (kickMatch) {
|
|
308
|
+
this.removeParticipant(kickMatch[1]);
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
const redirectMatch = text.match(/^\/redirect\s+(\S+)\s+"(.+)"$/);
|
|
312
|
+
if (redirectMatch) {
|
|
313
|
+
this.directAddress = { label: redirectMatch[1], prompt: redirectMatch[2] };
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
const atMatch = text.match(/^@(\S+)\s+(.+)$/);
|
|
317
|
+
if (atMatch) {
|
|
318
|
+
this.directAddress = { label: atMatch[1], prompt: atMatch[2] };
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
this.userContext = text;
|
|
322
|
+
}
|
|
323
|
+
async addParticipant(config) {
|
|
324
|
+
const instanceName = await this.fm.spawnEphemeralInstance({
|
|
325
|
+
systemPrompt: buildSystemPrompt(config.role, this.config.topic),
|
|
326
|
+
workingDirectory: "/tmp",
|
|
327
|
+
lightweight: this.config.mode === "debate",
|
|
328
|
+
skipPermissions: this.config.mode === "debate",
|
|
329
|
+
});
|
|
330
|
+
this.participants.push({ ...config, instanceName });
|
|
331
|
+
await this.output.postMessage(`➕ ${config.label}(${roleLabel(config.role)})加入會議`);
|
|
332
|
+
}
|
|
333
|
+
async removeParticipant(label) {
|
|
334
|
+
const idx = this.participants.findIndex(p => p.label === label);
|
|
335
|
+
if (idx === -1)
|
|
336
|
+
return;
|
|
337
|
+
const [removed] = this.participants.splice(idx, 1);
|
|
338
|
+
await this.fm.destroyEphemeralInstance(removed.instanceName);
|
|
339
|
+
await this.output.postMessage(`➖ ${removed.label}(${roleLabel(removed.role)})已離開會議`);
|
|
340
|
+
}
|
|
341
|
+
async end() {
|
|
342
|
+
if (this.state !== "ended") {
|
|
343
|
+
await this.generateSummary();
|
|
344
|
+
}
|
|
345
|
+
await this.cleanup();
|
|
346
|
+
}
|
|
347
|
+
async cleanup() {
|
|
348
|
+
this.state = "ended";
|
|
349
|
+
this.abortController.abort();
|
|
350
|
+
await Promise.allSettled(this.participants.map(p => this.fm.destroyEphemeralInstance(p.instanceName)));
|
|
351
|
+
await this.output.postMessage("📋 會議結束");
|
|
352
|
+
}
|
|
353
|
+
getState() { return this.state; }
|
|
354
|
+
}
|
|
355
|
+
//# sourceMappingURL=orchestrator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orchestrator.js","sourceRoot":"","sources":["../../src/meeting/orchestrator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { MeetingRole, RoundEntry } from "./types.js";
|
|
2
|
+
export declare function roleLabel(role: MeetingRole): string;
|
|
3
|
+
export declare function buildSystemPrompt(role: MeetingRole, topic: string): string;
|
|
4
|
+
export declare function buildRoundPrompt(topic: string, round: number, previousRounds: RoundEntry[], userContext?: string): string;
|
|
5
|
+
export declare function buildCollabSystemPrompt(label: string, topic: string): string;
|
|
6
|
+
export declare function buildCollabSummaryPrompt(topic: string, allRounds: RoundEntry[]): string;
|
|
7
|
+
export declare function buildAngleGenerationPrompt(topic: string, count: number): string;
|
|
8
|
+
export declare function buildDiscussionSystemPrompt(label: string, angle: string, topic: string): string;
|
|
9
|
+
export declare function buildIndependentAnalysisPrompt(topic: string, angle: string): string;
|
|
10
|
+
export declare function buildCrossDiscussionPrompt(topic: string, myAngle: string, allAnalyses: RoundEntry[]): string;
|
|
11
|
+
export declare function buildConsensusPrompt(topic: string, allRounds: RoundEntry[]): string;
|
|
12
|
+
export declare function buildSummaryPrompt(topic: string, allRounds: RoundEntry[]): string;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
const ROLE_LABELS = { pro: "正方", con: "反方", arbiter: "仲裁" };
|
|
2
|
+
export function roleLabel(role) {
|
|
3
|
+
return ROLE_LABELS[role] ?? role;
|
|
4
|
+
}
|
|
5
|
+
export function buildSystemPrompt(role, topic) {
|
|
6
|
+
const label = roleLabel(role);
|
|
7
|
+
switch (role) {
|
|
8
|
+
case "pro":
|
|
9
|
+
return `你是這場辯論的「${label}」。議題:「${topic}」。\n\n你必須站在【贊成/支持】的立場。無論你個人怎麼想,你的任務就是為這個提案辯護,找出所有支持它的理由。\n\n重要:你必須跟反方持相反立場。如果反方同意你,那代表你們其中一方搞錯立場了。你要積極反駁反方的論點。\n\n用 reply 工具回覆你的論述。`;
|
|
10
|
+
case "con":
|
|
11
|
+
return `你是這場辯論的「${label}」。議題:「${topic}」。\n\n你必須站在【反對/質疑】的立場。無論你個人怎麼想,你的任務就是反對這個提案,找出所有反對它的理由、風險和問題。\n\n重要:你必須跟正方持相反立場。如果正方支持這個提案,你就必須反對。不要附和正方,要挑戰和反駁他的論點。\n\n用 reply 工具回覆你的論述。`;
|
|
12
|
+
case "arbiter":
|
|
13
|
+
return `你是這場辯論的「${label}」。議題:「${topic}」。你的角色是客觀的仲裁者,分析正反雙方論點的優劣,指出各方的盲點和邏輯漏洞,並提出平衡的結論。\n\n用 reply 工具回覆你的分析。`;
|
|
14
|
+
default:
|
|
15
|
+
return `你是這場辯論的「${label}」。議題:「${topic}」。用 reply 工具回覆你的觀點。`;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export function buildRoundPrompt(topic, round, previousRounds, userContext) {
|
|
19
|
+
const parts = [`--- Round ${round} ---`, `議題:${topic}`];
|
|
20
|
+
if (previousRounds.length > 0) {
|
|
21
|
+
parts.push("\n上一輪討論摘要:");
|
|
22
|
+
for (const entry of previousRounds) {
|
|
23
|
+
parts.push(`[${roleLabel(entry.role)} ${entry.speaker}] ${entry.content}`);
|
|
24
|
+
}
|
|
25
|
+
parts.push("\n請針對以上觀點進行回應。");
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
parts.push("\n這是第一輪。請闡述你的立場。");
|
|
29
|
+
}
|
|
30
|
+
if (userContext) {
|
|
31
|
+
parts.push(`\n主持人補充:${userContext}`);
|
|
32
|
+
}
|
|
33
|
+
return parts.join("\n");
|
|
34
|
+
}
|
|
35
|
+
export function buildCollabSystemPrompt(label, topic) {
|
|
36
|
+
return `你是協作任務的參與者「${label}」。任務:「${topic}」。你在獨立的 git branch 上工作。先討論分工,確認後開始開發。完成後用 reply 工具回報進度。`;
|
|
37
|
+
}
|
|
38
|
+
export function buildCollabSummaryPrompt(topic, allRounds) {
|
|
39
|
+
const parts = [`請為以下協作任務產出一份工作摘要。`, `任務:${topic}`, ""];
|
|
40
|
+
for (const entry of allRounds) {
|
|
41
|
+
parts.push(`[${entry.speaker}] ${entry.content}`);
|
|
42
|
+
}
|
|
43
|
+
parts.push("\n請總結:1) 各參與者完成了什麼 2) 未完成的工作 3) 需要注意的衝突或問題。用 reply 工具回覆摘要。");
|
|
44
|
+
return parts.join("\n");
|
|
45
|
+
}
|
|
46
|
+
export function buildAngleGenerationPrompt(topic, count) {
|
|
47
|
+
return `議題:「${topic}」\n\n請為這個議題建議 ${count} 個不同的分析角度。每個角度應該代表一個獨特的切入面向(例如:技術可行性、成本效益、使用者體驗、法規遵循等)。\n\n請用以下格式回覆,每行一個角度,不要編號:\n技術可行性\n成本效益\n...`;
|
|
48
|
+
}
|
|
49
|
+
export function buildDiscussionSystemPrompt(label, angle, topic) {
|
|
50
|
+
return `你是這場討論的參與者「${label}」。議題:「${topic}」。\n\n你的分析角度是「${angle}」。請從這個角度出發,提出你的專業分析。你不需要強制支持或反對,而是從你的角度深入分析這個議題的各個面向。\n\n用 reply 工具回覆。`;
|
|
51
|
+
}
|
|
52
|
+
export function buildIndependentAnalysisPrompt(topic, angle) {
|
|
53
|
+
return `請從「${angle}」的角度,獨立分析以下議題:\n\n「${topic}」\n\n這是獨立分析階段,你還沒看到其他人的觀點。請深入分析,提出你的發現、風險和建議。\n\n用 reply 工具回覆你的分析。`;
|
|
54
|
+
}
|
|
55
|
+
export function buildCrossDiscussionPrompt(topic, myAngle, allAnalyses) {
|
|
56
|
+
const parts = [
|
|
57
|
+
`議題:「${topic}」`,
|
|
58
|
+
`你的角度:「${myAngle}」`,
|
|
59
|
+
`\n以下是所有參與者的獨立分析:\n`,
|
|
60
|
+
];
|
|
61
|
+
for (const entry of allAnalyses) {
|
|
62
|
+
parts.push(`[${entry.speaker}] ${entry.content}\n`);
|
|
63
|
+
}
|
|
64
|
+
parts.push(`請從你的角度(${myAngle})回應其他人的分析。你可以同意、補充、或挑戰他們的觀點。重點指出他們可能忽略的面向。\n\n用 reply 工具回覆。`);
|
|
65
|
+
return parts.join("\n");
|
|
66
|
+
}
|
|
67
|
+
export function buildConsensusPrompt(topic, allRounds) {
|
|
68
|
+
const parts = [
|
|
69
|
+
`議題:「${topic}」`,
|
|
70
|
+
`\n以下是完整的討論過程:\n`,
|
|
71
|
+
];
|
|
72
|
+
let currentRound = -1;
|
|
73
|
+
for (const entry of allRounds) {
|
|
74
|
+
if (entry.round !== currentRound) {
|
|
75
|
+
currentRound = entry.round;
|
|
76
|
+
parts.push(currentRound === 0 ? "\n--- 獨立分析 ---" : `\n--- 交叉討論 Round ${currentRound} ---`);
|
|
77
|
+
}
|
|
78
|
+
parts.push(`[${entry.speaker}] ${entry.content}`);
|
|
79
|
+
}
|
|
80
|
+
parts.push(`\n請綜合所有角度的分析和討論,產出一份共識結論:\n1) 各角度的關鍵發現\n2) 共識點\n3) 仍有分歧的面向\n4) 綜合建議與下一步行動\n\n用 reply 工具回覆。`);
|
|
81
|
+
return parts.join("\n");
|
|
82
|
+
}
|
|
83
|
+
export function buildSummaryPrompt(topic, allRounds) {
|
|
84
|
+
const parts = [`請為以下辯論產出一份會議摘要。`, `議題:${topic}`, ""];
|
|
85
|
+
let currentRound = 0;
|
|
86
|
+
for (const entry of allRounds) {
|
|
87
|
+
if (entry.round !== currentRound) {
|
|
88
|
+
currentRound = entry.round;
|
|
89
|
+
parts.push(`\n--- Round ${currentRound} ---`);
|
|
90
|
+
}
|
|
91
|
+
parts.push(`[${roleLabel(entry.role)} ${entry.speaker}] ${entry.content}`);
|
|
92
|
+
}
|
|
93
|
+
parts.push("\n請總結:1) 各方主要論點 2) 共識點 3) 未解決的分歧 4) 建議的下一步行動。用 reply 工具回覆摘要。");
|
|
94
|
+
return parts.join("\n");
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=prompt-builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-builder.js","sourceRoot":"","sources":["../../src/meeting/prompt-builder.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,GAA2B,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAEpF,MAAM,UAAU,SAAS,CAAC,IAAiB;IACzC,OAAO,WAAW,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAiB,EAAE,KAAa;IAChE,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAC9B,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,KAAK;YACR,OAAO,WAAW,KAAK,SAAS,KAAK,qIAAqI,CAAC;QAC7K,KAAK,KAAK;YACR,OAAO,WAAW,KAAK,SAAS,KAAK,2IAA2I,CAAC;QACnL,KAAK,SAAS;YACZ,OAAO,WAAW,KAAK,SAAS,KAAK,uEAAuE,CAAC;QAC/G;YACE,OAAO,WAAW,KAAK,SAAS,KAAK,qBAAqB,CAAC;IAC/D,CAAC;AACH,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,KAAa,EAAE,KAAa,EAAE,cAA4B,EAAE,WAAoB;IAC/G,MAAM,KAAK,GAAa,CAAC,aAAa,KAAK,MAAM,EAAE,MAAM,KAAK,EAAE,CAAC,CAAC;IAClE,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9B,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACzB,KAAK,MAAM,KAAK,IAAI,cAAc,EAAE,CAAC;YACnC,KAAK,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,OAAO,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QAC7E,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAC/B,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IACjC,CAAC;IACD,IAAI,WAAW,EAAE,CAAC;QAChB,KAAK,CAAC,IAAI,CAAC,WAAW,WAAW,EAAE,CAAC,CAAC;IACvC,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,KAAa,EAAE,KAAa;IAClE,OAAO,cAAc,KAAK,SAAS,KAAK,yDAAyD,CAAC;AACpG,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,KAAa,EAAE,SAAuB;IAC7E,MAAM,KAAK,GAAa,CAAC,mBAAmB,EAAE,MAAM,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;IACjE,KAAK,MAAM,KAAK,IAAI,SAAS,EAAE,CAAC;QAC9B,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,OAAO,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IACpD,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,4DAA4D,CAAC,CAAC;IACzE,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,KAAa,EAAE,KAAa;IACrE,OAAO,OAAO,KAAK,iBAAiB,KAAK,oGAAoG,CAAC;AAChJ,CAAC;AAED,MAAM,UAAU,2BAA2B,CAAC,KAAa,EAAE,KAAa,EAAE,KAAa;IACrF,OAAO,cAAc,KAAK,SAAS,KAAK,iBAAiB,KAAK,wEAAwE,CAAC;AACzI,CAAC;AAED,MAAM,UAAU,8BAA8B,CAAC,KAAa,EAAE,KAAa;IACzE,OAAO,MAAM,KAAK,sBAAsB,KAAK,oEAAoE,CAAC;AACpH,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,KAAa,EAAE,OAAe,EAAE,WAAyB;IAClG,MAAM,KAAK,GAAa;QACtB,OAAO,KAAK,GAAG;QACf,SAAS,OAAO,GAAG;QACnB,oBAAoB;KACrB,CAAC;IACF,KAAK,MAAM,KAAK,IAAI,WAAW,EAAE,CAAC;QAChC,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,OAAO,KAAK,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC;IACtD,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,UAAU,OAAO,6DAA6D,CAAC,CAAC;IAC3F,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,KAAa,EAAE,SAAuB;IACzE,MAAM,KAAK,GAAa;QACtB,OAAO,KAAK,GAAG;QACf,iBAAiB;KAClB,CAAC;IACF,IAAI,YAAY,GAAG,CAAC,CAAC,CAAC;IACtB,KAAK,MAAM,KAAK,IAAI,SAAS,EAAE,CAAC;QAC9B,IAAI,KAAK,CAAC,KAAK,KAAK,YAAY,EAAE,CAAC;YACjC,YAAY,GAAG,KAAK,CAAC,KAAK,CAAC;YAC3B,KAAK,CAAC,IAAI,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,oBAAoB,YAAY,MAAM,CAAC,CAAC;QAC7F,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,OAAO,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IACpD,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,4FAA4F,CAAC,CAAC;IACzG,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,KAAa,EAAE,SAAuB;IACvE,MAAM,KAAK,GAAa,CAAC,iBAAiB,EAAE,MAAM,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;IAC/D,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,KAAK,MAAM,KAAK,IAAI,SAAS,EAAE,CAAC;QAC9B,IAAI,KAAK,CAAC,KAAK,KAAK,YAAY,EAAE,CAAC;YACjC,YAAY,GAAG,KAAK,CAAC,KAAK,CAAC;YAC3B,KAAK,CAAC,IAAI,CAAC,eAAe,YAAY,MAAM,CAAC,CAAC;QAChD,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,OAAO,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IAC7E,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,8DAA8D,CAAC,CAAC;IAC3E,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
const LABELS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");
|
|
2
|
+
export function assignRoles(count, customNames) {
|
|
3
|
+
if (count < 2)
|
|
4
|
+
throw new Error("Meeting requires at least 2 participants");
|
|
5
|
+
const labels = customNames ?? LABELS.slice(0, count);
|
|
6
|
+
if (labels.length < count) {
|
|
7
|
+
throw new Error(`Not enough names: need ${count}, got ${labels.length}`);
|
|
8
|
+
}
|
|
9
|
+
const roles = [];
|
|
10
|
+
if (count === 2) {
|
|
11
|
+
roles.push("pro", "con");
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
const debaters = count - 1;
|
|
15
|
+
const proCount = Math.floor(debaters / 2);
|
|
16
|
+
const conCount = debaters - proCount;
|
|
17
|
+
for (let i = 0; i < proCount; i++)
|
|
18
|
+
roles.push("pro");
|
|
19
|
+
for (let i = 0; i < conCount; i++)
|
|
20
|
+
roles.push("con");
|
|
21
|
+
roles.push("arbiter");
|
|
22
|
+
}
|
|
23
|
+
return labels.slice(0, count).map((label, i) => ({ label, role: roles[i] }));
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=role-assigner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"role-assigner.js","sourceRoot":"","sources":["../../src/meeting/role-assigner.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,GAAG,4BAA4B,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;AAEtD,MAAM,UAAU,WAAW,CAAC,KAAa,EAAE,WAAsB;IAC/D,IAAI,KAAK,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAE3E,MAAM,MAAM,GAAG,WAAW,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IACrD,IAAI,MAAM,CAAC,MAAM,GAAG,KAAK,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,0BAA0B,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IAC3E,CAAC;IAED,MAAM,KAAK,GAAkB,EAAE,CAAC;IAChC,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;QAChB,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAC3B,CAAC;SAAM,CAAC;QACN,MAAM,QAAQ,GAAG,KAAK,GAAG,CAAC,CAAC;QAC3B,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;QAC1C,MAAM,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;QACrC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,CAAC,EAAE;YAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,CAAC,EAAE;YAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrD,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACxB,CAAC;IAED,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAC/E,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export type MeetingRole = "pro" | "con" | "arbiter" | (string & {});
|
|
2
|
+
export type MeetingMode = "debate" | "collab" | "discussion";
|
|
3
|
+
export interface MeetingConfig {
|
|
4
|
+
meetingId: string;
|
|
5
|
+
topic: string;
|
|
6
|
+
mode: MeetingMode;
|
|
7
|
+
maxRounds: number;
|
|
8
|
+
repo?: string;
|
|
9
|
+
angles?: string[];
|
|
10
|
+
}
|
|
11
|
+
export interface EphemeralInstanceConfig {
|
|
12
|
+
systemPrompt: string;
|
|
13
|
+
workingDirectory: string;
|
|
14
|
+
lightweight?: boolean;
|
|
15
|
+
skipPermissions?: boolean;
|
|
16
|
+
backend?: string;
|
|
17
|
+
}
|
|
18
|
+
export type RouteTarget = {
|
|
19
|
+
kind: "instance";
|
|
20
|
+
name: string;
|
|
21
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/meeting/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { FleetContext } from "./fleet-context.js";
|
|
2
|
+
export declare class MeetingManager {
|
|
3
|
+
private ctx;
|
|
4
|
+
private ephemeralTopicMap;
|
|
5
|
+
constructor(ctx: FleetContext);
|
|
6
|
+
/** Get the ephemeral topic ID for an instance (used by fleet-manager for outbound routing) */
|
|
7
|
+
getEphemeralTopicId(instanceName: string): number | undefined;
|
|
8
|
+
/** Clean up ephemeral instance resources (worktree, topic map). Called on topic deletion. */
|
|
9
|
+
cleanupEphemeral(name: string): Promise<void>;
|
|
10
|
+
}
|